Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: playing audio inside TIdBytes into a memorystream



Permlink Replies: 2 - Last Post: Dec 19, 2017 9:11 PM Last Post By: madammar ellias
madammar ellias

Posts: 111
Registered: 8/17/17
playing audio inside TIdBytes into a memorystream
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 19, 2017 8:17 AM
i am sending some audio buffer using TidBytes like following
udpreciver.SendBuffer(ipaddr, port, RawToBytes(Buffer^, Buffersize));


then i am trying to load it into a memorystream and play it like following
procedure TForm3.udpreciverUDPRead(AThread: TIdUDPListenerThread;
  const AData: TIdBytes; ABinding: TIdSocketHandle);
var
msload: Tmemorystream;
AudioDataSize: Integer;
AudioDatar : Pointer;
begin
TThread.Synchronize(nil,
procedure
begin
if Assigned(AudioWorkerThread) then
begin
msload := Tmemorystream.create;
try
AudioDataSize := Length(AData);
BytesToRaw(AData, AudioDatar^, AudioDataSize);
msload.Writebuffer(AudioDatar^, AudioDataSize);
msload.Position := 0;
AudioWorkerThread.Queue(msload);
 
except
msload.free;
end;
 
end;
 
end);
 
end;


AudioThread player

procedure TAudioWorkerThread.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;
 
 
Stream.Position := 0;
while Stream.Position < Stream.Size do
begin
AudioDataSize := Stream.Read(AudioStream.Data^, AudioDataset);
 
try
AudioPlay.write(AudioStream, 0, AudioDataSize);
 
AudioPlay.play;//
 
except
//log any exception
 
end;
 
end;
 
end;
 
end;


but i got no sound what i am doing wrong ?
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: playing audio inside TIdBytes into a memorystream
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 19, 2017 1:13 PM   in response to: madammar ellias in response to: madammar ellias
madammar ellias wrote:

i am sending some audio buffer using TidBytes like following

udpreciver.SendBuffer(ipaddr, port, RawToBytes(Buffer^, Buffersize));


then i am trying to load it into a memorystream and play it like
following

If you are going to Synchronize() the entire event handler like that
(which you shouldn't), then you should set the
TIdUDPServer.ThreadedEvent property to False and remove the explicit
call to Synchronize():

procedure TForm3.udpreciverUDPRead(AThread: TIdUDPListenerThread;
  const AData: TIdBytes; ABinding: TIdSocketHandle);
var
  msload: TMemorystream;
begin
  if Assigned(AudioWorkerThread) then
  begin
    msload := Tmemorystream.create;
    try
      msload.WriteBuffer(PByte(AData)^, Length(AData));
      msload.Position := 0;
      AudioWorkerThread.Queue(msload);
    except
      msload.Free;
    end;
  end;
end;


A better option is to set ThreadedEvent=True and only Synchronize() the
call to Queue() and nothing else (preparing the TMemoryStream doesn't
require synchronizing threads):

procedure TForm3.udpreciverUDPRead(AThread: TIdUDPListenerThread; const
AData: TIdBytes; ABinding: TIdSocketHandle);
var
  msload: TMemorystream;
begin
  if Assigned(AudioWorkerThread) then
  begin
    msload := TMemorystream.Create;
    try
      msload.WriteBuffer(PByte(AData)^, Length(AData));
      msload.Position := 0;
      TThread.Synchronize(nil,
        procedure
        begin
          if Assigned(AudioWorkerThread) then
            AudioWorkerThread.Queue(msload);
          else
            msload.Free;
      );
    except
      msload.free;
    end;
  end
end;


Even better, if Queue() is thread-safe (which it should be, since you
have an AudioQueue lock), then you won't really need Synchronize() at
all:

procedure TForm3.udpreciverUDPRead(AThread: TIdUDPListenerThread; const
AData: TIdBytes; ABinding: TIdSocketHandle);
var
  msload: TMemorystream;
begin
  if Assigned(AudioWorkerThread) then
  begin
    msload := TMemorystream.Create;
    try
      msload.WriteBuffer(PByte(AData)^, Length(AData));
      msload.Position := 0;
      AudioWorkerThread.Queue(msload);
    except
      msload.free;
    end;
  end
end;


but i got no sound what i am doing wrong ?

You tell us. Did you validate that you are receiving exactly what you
sent? Did you validate the received audio is valid before playing it?
Did you try saving it to a file and then play it externally? Did you
validate that the device is capable of playing sound? Or that you
initialized AudioPlay correctly? Or that AudioPlay.write() is not
returning an error code? And what is AudioStream defined as?

--
Remy Lebeau (TeamB)
madammar ellias

Posts: 111
Registered: 8/17/17
Re: playing audio inside TIdBytes into a memorystream
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 19, 2017 9:11 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Remy Lebeau (TeamB) wrote:

You tell us. Did you validate that you are receiving exactly what you
sent? Did you validate the received audio is valid before playing it?
Did you try saving it to a file and then play it externally? Did you
validate that the device is capable of playing sound? Or that you
initialized AudioPlay correctly? Or that AudioPlay.write() is not
returning an error code? And what is AudioStream defined as?

--
Remy Lebeau (TeamB)

thank you very much Remy its as always works and in better manner the way that i was populating the memory stream were wrong and your instruction were much helpful as always
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02