unit AudioPool;
interface
uses System.SysUtils,
System.Classes,
System.SyncObjs,
System.Generics.Collections, AndroidApi.JNI,
Androidapi.JNI.Media, Androidapi.JNI.GraphicsContentViewText,
Androidapi.JNI.Net,
Androidapi.JNIBridge,
Androidapi.JNI.JavaTypes;
{Thread Audio }
type
TAUDIOBOOLThread = class(TThread)
Private
Enable_Play: Boolean;
AudioPlay: JAudioTrack;
AudioStream: TJavaArray<Byte>;
Audiodataset: Integer;
AudioQueue: TQueue<TMemoryStream>;
AudioInQueue: TEvent;
protected
procedure Execute; override;
procedure TerminatedSet; override;
Public
constructor Create(CreateSuspended: Boolean); reintroduce;
destructor Destroy; override;
procedure Queue(var Stream: TMemoryStream);
end;
var
AUDIOBOOLThread: TAUDIOBOOLThread;
implementation
{ TAudioWorkerThread }
constructor TAUDIOBOOLThread.Create(CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);
FreeOnTerminate := False;
Enable_Play := False;
Audiodataset := TJAudioTrack.JavaClass.getMinBufferSize(8000,
TJAudioFormat.JavaClass.CHANNEL_OUT_MONO,
TJAudioFormat.JavaClass.ENCODING_PCM_16BIT);
AudioStream:= TJavaArray<Byte>.Create(Audiodataset);
AudioPlay:= TJAudioTrack.JavaClass.init(TJAudioManager.JavaClass.STREAM_MUSIC,
8000,
TJAudioFormat.JavaClass.CHANNEL_OUT_MONO,
TJAudioFormat.JavaClass.ENCODING_PCM_16BIT,
Audiodataset,
TJAudioTrack.JavaClass.MODE_STREAM);
AudioQueue := TQueue<TMemoryStream>.Create;
AudioInQueue := TEvent.Create;
end;
destructor TAUDIOBOOLThread.Destroy;
begin
inherited;
end;
procedure TAUDIOBOOLThread.Execute;
var
AudioDataSize : integer;
Stream: TMemoryStream;
begin
while not Terminated do
begin
AudioInQueue.WaitFor;
if Terminated then
begin
Exit;
end;
TMonitor.Enter(AudioQueue);
try
Stream := AudioQueue.Dequeue;
if AudioQueue.Count = 0 then
begin
AudioInQueue.ResetEvent;
end;
finally
TMonitor.Exit(AudioQueue);
end;
if not Enable_Play then
begin
AudioPlay.play();
Enable_Play := True;
end;
Stream.Position := 0;
while Stream.Position < Stream.Size do
begin
AudioDataSize := Stream.Read(AudioStream.Data^, AudioDataset);
try
AudioPlay.write(AudioStream, 0, AudioDataSize);
except
//log any exception
end;
end;
end;
end;
procedure TAUDIOBOOLThread.Queue(var Stream: TMemoryStream);
begin
if Terminated then
begin
Exit;
end;
TMonitor.Enter(AudioQueue);
try
AudioQueue.Enqueue(Stream);
Stream := nil;
if AudioQueue.Count = 1 then
begin
AudioInQueue.SetEvent;
end;
finally
TMonitor.Exit(AudioQueue);
end;
end;
procedure TAUDIOBOOLThread.TerminatedSet;
begin
inherited;
AudioInQueue.SetEvent;
end;
end.