audio: master-clock playback timing, output clock compensation, buffer config, interpolated speed

- playback timer uses the audio output device as its master clock: the
  PortAudio callback counts consumed frames (including underrun
  zero-fill) so video cannot drift away from what is heard; wall clock
  remains as fallback when no clocked output is running
- output clock compensates for device output latency; new Preferences >
  Audio buffer size setting (0 = auto)
- SampleBuffer::speed() now uses linear interpolation instead of
  nearest-neighbor sampling
- regression tests: audio-clock driven timer (fwd/rev/speed), wall
  clock fallback, interpolation correctness
This commit is contained in:
2026-07-19 21:44:34 +08:00
parent 0c02ff0d77
commit a7ddc0f114
16 changed files with 266 additions and 8 deletions
@@ -124,6 +124,20 @@ PreferencesAudioTab::PreferencesAudioTab()
.toStdString()));
output_param_layout->addWidget(output_fmt_combo_, output_row,
1);
output_row++;
output_param_layout->addWidget(
new QLabel(tr("Buffer Size:")), output_row, 0);
output_buffer_size_ = new QSpinBox();
output_buffer_size_->setRange(0, 65536);
output_buffer_size_->setSpecialValueText(tr("Auto"));
output_buffer_size_->setSuffix(tr(" frames"));
output_buffer_size_->setValue(
OAK_CONFIG("AudioOutputBufferSize").toInt());
output_param_layout->addWidget(output_buffer_size_, output_row,
1);
}
}
@@ -222,6 +236,7 @@ void PreferencesAudioTab::accept(MultiUndoCommand *command)
QVariant::fromValue(output_ch_layout_combo_->get_channel_layout());
OAK_CONFIG("AudioOutputSampleFormat") = QString::fromStdString(
output_fmt_combo_->get_sample_format().to_string());
OAK_CONFIG("AudioOutputBufferSize") = output_buffer_size_->value();
OAK_CONFIG("AudioRecordingFormat") = record_format_combo_->get_format();
OAK_CONFIG("AudioRecordingCodec") = record_options_->get_codec();
@@ -25,6 +25,7 @@
#include <QComboBox>
#include <QPushButton>
#include <QCheckBox>
#include <QSpinBox>
#include "dialog/configbase/configdialogbase.h"
#include "dialog/export/exportaudiotab.h"
@@ -68,6 +69,11 @@ private:
ChannelLayoutComboBox *output_ch_layout_combo_;
SampleFormatComboBox *output_fmt_combo_;
/**
* @brief UI widget for the output buffer size in frames (0 = auto)
*/
QSpinBox *output_buffer_size_;
ExportFormatComboBox *record_format_combo_;
ExportAudioTab *record_options_;