mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +00:00
chore: refine project documentation
This commit is contained in:
+13
-15
@@ -20,12 +20,12 @@
|
||||
unit AudioOutput;
|
||||
|
||||
{
|
||||
PortAudio output — реализация по образцу piHPSDR/portaudio.c (DL1YCF)
|
||||
PortAudio output with a buffered low-latency stereo stream.
|
||||
|
||||
Ключевые особенности:
|
||||
- Pa_Initialize вызывается один раз в Create (до открытия стрима)
|
||||
- suggestedLatency = 0.0 (минимум устройства)
|
||||
- Ring buffer из Double (как в оригинале)
|
||||
- Ring buffer из Double
|
||||
- Callback читает по одному сэмплу, обновляет outpt внутри цикла
|
||||
- Low water mark: вставляет тишину + полбуфера silence
|
||||
- High water mark: удаляет лишние сэмплы
|
||||
@@ -43,10 +43,10 @@ uses
|
||||
Classes, SysUtils, Math, SyncObjs, DynLibs;
|
||||
|
||||
const
|
||||
MY_AUDIO_BUFFER_SIZE = 128; // default PA frames per callback — как piHPSDR
|
||||
MY_RING_BUFFER_SIZE = 9600; // как piHPSDR
|
||||
MY_RING_LOW_WATER = 512; // как piHPSDR
|
||||
MY_RING_HIGH_WATER = 9000; // как piHPSDR
|
||||
MY_AUDIO_BUFFER_SIZE = 128; // default PA frames per callback
|
||||
MY_RING_BUFFER_SIZE = 9600;
|
||||
MY_RING_LOW_WATER = 512;
|
||||
MY_RING_HIGH_WATER = 9000;
|
||||
|
||||
type
|
||||
TPaError = LongInt;
|
||||
@@ -119,8 +119,8 @@ type
|
||||
FPAInited: Boolean; // Pa_Initialize прошла
|
||||
FLastError: string;
|
||||
|
||||
// Ring buffer (interleaved double stereo, как в оригинале)
|
||||
FBuf: array[0..MY_RING_BUFFER_SIZE * 2 - 1] of Double; // как piHPSDR
|
||||
// Ring buffer (interleaved double stereo)
|
||||
FBuf: array[0..MY_RING_BUFFER_SIZE * 2 - 1] of Double;
|
||||
FInPt: Integer; // audio_buffer_inpt (write)
|
||||
FOutPt: Integer; // audio_buffer_outpt (read)
|
||||
FMutex: TCriticalSection;
|
||||
@@ -159,7 +159,7 @@ type
|
||||
// Найти индекс устройства по имени (-1 если не найдено)
|
||||
function FindDeviceByName(const AName: string): Integer;
|
||||
|
||||
// Пишем стерео double сэмплы — как audio_write() в оригинале
|
||||
// Записывает пару стереосэмплов Double в кольцевой буфер.
|
||||
procedure WriteDouble(Left, Right: Double);
|
||||
// Convenience: массив Single
|
||||
procedure Write(const Left, Right: array of Single; Count: Integer);
|
||||
@@ -215,13 +215,12 @@ const
|
||||
PA_CONTINUE = LongInt(0);
|
||||
PA_NO_DEV = TPaDeviceIndex(-1);
|
||||
|
||||
// Callback modeled after pa_out_cb from piHPSDR/portaudio.c
|
||||
// Callback reads interleaved stereo samples from the ring buffer.
|
||||
function PaOutCallback(inputBuffer, outputBuffer: Pointer;
|
||||
framesPerBuffer: LongWord;
|
||||
timeInfo: Pointer;
|
||||
statusFlags: LongWord;
|
||||
userData: Pointer): LongInt; cdecl;
|
||||
// Точная копия pa_out_cb из piHPSDR/portaudio.c
|
||||
var
|
||||
Audio: TAudioOutput;
|
||||
Out_: PSingle;
|
||||
@@ -478,7 +477,7 @@ begin
|
||||
end;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Open — точная последовательность как в audio_open_output()
|
||||
// Open — подготавливает параметры и открывает выходной поток PortAudio.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function TAudioOutput.Open: Boolean;
|
||||
@@ -505,7 +504,7 @@ begin
|
||||
Exit;
|
||||
end;
|
||||
|
||||
// Точно как в оригинале: bzero + suggestedLatency = 0.0
|
||||
// Обнуляем параметры и запрашиваем минимальную задержку устройства.
|
||||
FillChar(OutParam, SizeOf(OutParam), 0);
|
||||
OutParam.channelCount := 2;
|
||||
OutParam.device := Dev;
|
||||
@@ -597,8 +596,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
// WriteDouble — modeled after audio_write() from piHPSDR/portaudio.c
|
||||
// Вызывается per-sample из Write. Мьютекс держится весь цикл в Write.
|
||||
// Вызывается для каждой пары сэмплов из Write. Мьютекс держится весь цикл.
|
||||
procedure TAudioOutput.WriteDouble(Left, Right: Double);
|
||||
var
|
||||
avail: Integer;
|
||||
|
||||
Reference in New Issue
Block a user