Directsound with streaming buffer - blocking does not end! Using Ported DirectX Headers for Delphi

Right, I'm working on implementing DirectSound in our Delphi voip application (the application allows multiple users to use radio stations over a network connection). The data comes through UDP broadcasts. As now, we descend to the raw data level and ourselves do audio mixing from several sources and have a centralized component that is used to reproduce all this.

The application itself is a Delphi 5 application, and I have been instructed to port it to Delphi 2010. As soon as I got to this part of the audio playback, we came to the conclusion that it is best if we can get rid of this old code and replace it with directsound.

So the idea is to have one SecondaryBuffer for each radio (we have one “panel” for each radio connection, based on the set of components that we create for each specific radio), and just let them add data to their respective SecondaryBuffers whenever they receive data, it only pauses to fill half the value of the audio data in the buffer if it runs out of data.

Now I'm stuck in the part where I am adding data to the buffers in my test application, where I am just trying to get this to work correctly before starting to write the component to use it the way we want.

I use ported DirectX headers for Delphi ( http://www.clootie.ru/delphi/download_dx92.html )

The point of these headers is to migrate through the regular DirectSound interface to Delphi, so I hope programmers who are not in Delphi with DirectSound can know what is causing my problem.

My SecondaryBuffer (IDirectSoundBuffer) was created as follows:

var
  BufferDesc: DSBUFFERDESC;
  wfx: tWAVEFORMATEX;


wfx.wFormatTag := WAVE_FORMAT_PCM;
wfx.nChannels := 1;
wfx.nSamplesPerSec := 8000;
wfx.wBitsPerSample := 16;
wfx.nBlockAlign := 2; // Channels * (BitsPerSample/2)
wfx.nAvgBytesPerSec := 8000 * 2; // SamplesPerSec * BlockAlign

BufferDesc.dwSize := SizeOf(DSBUFFERDESC);
BufferDesc.dwFlags := (DSBCAPS_GLOBALFOCUS or DSBCAPS_GETCURRENTPOSITION2 or DSBCAPS_CTRLPOSITIONNOTIFY);
BufferDesc.dwBufferBytes := wfx.nAvgBytesPerSec * 4; //Which should land at 64000
BufferDesc.lpwfxFormat  := @wfx;


case DSInterface.CreateSoundBuffer(BufferDesc, DSCurrentBuffer, nil) of
  DS_OK: ;
  DSERR_BADFORMAT: ShowMessage('DSERR_BADFORMAT');
  DSERR_INVALIDPARAM: ShowMessage('DSERR_INVALIDPARAM');
  end;

, PrimaryBuffer ( , MSDN , ) DSInterface, , IDirectSoundInterface.

, , (, , ), :

DSCurrentBuffer.Lock(0, 512, @FirstPart, @FirstLength, @SecondPart, @SecondLength, DSBLOCK_FROMWRITECURSOR);
Move(AudioData, FirstPart^, FirstLength);
if SecondLength > 0 then
  Move(AudioData[FirstLength], SecondPart^, SecondLength);

DSCurrentBuffer.GetStatus(Status);
DSCurrentBuffer.GetCurrentPosition(@PlayCursorPosition, @WriteCursorPosition);
if (FirstPart <> nil) or (SecondPart <> nil) then
  begin
    Memo1.Lines.Add('FirstLength = ' + IntToStr(FirstLength));
    Memo1.Lines.Add('PlayCursorPosition = ' + IntToStr(PlayCursorPosition));
    Memo1.Lines.Add('WriteCursorPosition = ' + IntToStr(WriteCursorPosition));
  end;
DSCurrentBuffer.Unlock(@FirstPart, FirstLength, @SecondPart, SecondLength);

AudioData . 512 . Memo1.Lines.Add, ( , directsound )

, DSCurrentBuffer ( hte MSDN docs , ), , , Memo , ... .

SecondPart . , , , .

, , , , - .

, , , . , :/

, , , , Lock and Unlock . , ( , , )

!

+3
2

, ^^;

.

DSCurrentBuffer.Unlock(@FirstPart, FirstLength, @SecondPart, SecondLength);

, , Lock().

DSCurrentBuffer.Unlock(FirstPart, FirstLength, SecondPart, SecondLength);

, .

, , ^^;

+2

, :

:

  DSCurrentBuffer.Lock(0, 512, @FirstPart, @FirstLength, @SecondPart, @SecondLength, DSBLOCK_FROMWRITECURSOR);
  try
    //...
  finally
    DSCurrentBuffer.Unlock(@FirstPart, FirstLength, @SecondPart, SecondLength);
  end;

-

+1

Source: https://habr.com/ru/post/1729543/


All Articles