chore: refine project documentation

This commit is contained in:
2026-08-25 22:44:36 +03:00
parent 8237f03930
commit 98d90e1e5a
45 changed files with 457 additions and 516 deletions
+13 -15
View File
@@ -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;