finished portaudio switch

This may have bugs in it, but as far as I can tell it's fully functional.
This commit is contained in:
itsmattkc
2021-10-01 15:41:24 -07:00
parent 7b65ecace5
commit f49aa7d974
7 changed files with 147 additions and 219 deletions
+1 -1
View File
@@ -317,7 +317,7 @@ jobs:
brew update brew update
brew upgrade brew upgrade
brew tap olive-editor/homebrew brew tap olive-editor/homebrew
brew install -f qt5 ffmpeg-olive openimageio-olive opencolorio opentimelineio brew install -f qt5 ffmpeg-olive openimageio-olive opencolorio opentimelineio portaudio
echo "/usr/local/opt/qt@5/bin" >> $GITHUB_PATH echo "/usr/local/opt/qt@5/bin" >> $GITHUB_PATH
- name: Acquire Google Crashpad - name: Acquire Google Crashpad
+81 -91
View File
@@ -28,18 +28,6 @@ namespace olive {
AudioManager* AudioManager::instance_ = nullptr; AudioManager* AudioManager::instance_ = nullptr;
QString AudioManager::GetAudioBackendName(AudioManager::Backend b)
{
switch (b) {
case kAudioBackendQt:
return tr("Qt");
case kAudioBackendCount:
break;
}
return tr("Unknown");
}
void AudioManager::CreateInstance() void AudioManager::CreateInstance()
{ {
if (instance_ == nullptr) { if (instance_ == nullptr) {
@@ -87,17 +75,57 @@ bool AudioManager::IsRefreshingInputs()
return is_refreshing_inputs_; return is_refreshing_inputs_;
} }
void AudioManager::PushToOutput(const QByteArray &samples) void AudioManager::SetOutputNotifyInterval(int n)
{ {
if (!output_stream_) { output_buffer_->set_notify_interval(n);
// Start output with no callback so it'll be in "push" mode
StartOutputStream();
}
Pa_WriteStream(output_stream_, samples.constData(), output_params_.bytes_to_samples(samples.size()));
} }
static PaSampleFormat GetPortAudioSampleFormat(AudioParams::Format fmt) int OutputCallback(const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData)
{
PreviewAudioDevice *device = static_cast<PreviewAudioDevice*>(userData);
qint64 max_read = frameCount * device->bytes_per_frame();
qint64 read_count = device->read(reinterpret_cast<char*>(output), max_read);
if (read_count < max_read) {
memset(reinterpret_cast<uint8_t*>(output) + read_count, 0, max_read - read_count);
}
return paContinue;
}
void AudioManager::PushToOutput(const AudioParams &params, const QByteArray &samples)
{
if (output_params_ != params || output_stream_ == nullptr) {
output_params_ = params;
CloseOutputStream();
PaStreamParameters p;
p.channelCount = output_params_.channel_count();
p.device = output_device_;
p.hostApiSpecificStreamInfo = nullptr;
p.sampleFormat = GetPortAudioSampleFormat(output_params_.format());
p.suggestedLatency = Pa_GetDeviceInfo(output_device_)->defaultLowOutputLatency;
Pa_OpenStream(&output_stream_, nullptr, &p, output_params_.sample_rate(), paFramesPerBufferUnspecified, paNoFlag, OutputCallback, output_buffer_.get());
output_buffer_->set_bytes_per_frame(output_params_.samples_to_bytes(1));
}
output_buffer_->write(samples);
if (!Pa_IsStreamActive(output_stream_)) {
Pa_StartStream(output_stream_);
}
}
void AudioManager::ClearBufferedOutput()
{
output_buffer_->clear();
}
PaSampleFormat AudioManager::GetPortAudioSampleFormat(AudioParams::Format fmt)
{ {
switch (fmt) { switch (fmt) {
case AudioParams::kFormatUnsigned8: case AudioParams::kFormatUnsigned8:
@@ -118,38 +146,34 @@ static PaSampleFormat GetPortAudioSampleFormat(AudioParams::Format fmt)
return 0; return 0;
} }
int OutputCallback(const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData) void AudioManager::CloseOutputStream()
{ {
PreviewAudioDevice *device = static_cast<PreviewAudioDevice*>(userData); if (output_stream_) {
if (Pa_IsStreamActive(output_stream_)) {
device->read(reinterpret_cast<char*>(output), frameCount * device->bytes_per_frame()); StopOutput();
}
return paContinue; Pa_CloseStream(output_stream_);
} output_stream_ = nullptr;
}
void AudioManager::StartOutput(std::shared_ptr<PreviewAudioDevice> device)
{
// First stop any current device
StopOutputStream();
// Store device
output_device_ = device;
// Start output stream that pulls from this device
StartOutputStream(OutputCallback);
} }
void AudioManager::StopOutput() void AudioManager::StopOutput()
{ {
// Stop playback first so the callback won't get called again // Abort the stream so playback stops immediately
StopOutputStream(); if (output_stream_) {
Pa_AbortStream(output_stream_);
// Then clear our reference to the output devicec ClearBufferedOutput();
output_device_ = nullptr; }
} }
void AudioManager::SetOutputDevice(const QAudioDeviceInfo &info) void AudioManager::SetOutputDevice(PaDeviceIndex device)
{ {
qInfo() << "Setting output audio device to" << Pa_GetDeviceInfo(device)->name;
output_device_ = device;
CloseOutputStream();
/*qInfo() << "Setting output audio device to" << info.deviceName(); /*qInfo() << "Setting output audio device to" << info.deviceName();
StopOutput(); StopOutput();
@@ -178,21 +202,11 @@ void AudioManager::SetOutputDevice(const QAudioDeviceInfo &info)
}*/ }*/
} }
void AudioManager::SetOutputParams(const AudioParams &params) void AudioManager::SetInputDevice(PaDeviceIndex device)
{ {
if (output_params_ != params) { qInfo() << "Setting input audio device to" << Pa_GetDeviceInfo(device)->name;
// If an output stream is running, stop it now
StopOutputStream();
// Update parameters input_device_ = device;
output_params_ = params;
}
}
void AudioManager::SetInputDevice(const QAudioDeviceInfo &info)
{
input_ = std::unique_ptr<QAudioInput>(new QAudioInput(info, QAudioFormat(), this));
input_device_info_ = info;
} }
const QList<QAudioDeviceInfo> &AudioManager::ListInputDevices() const QList<QAudioDeviceInfo> &AudioManager::ListInputDevices()
@@ -208,51 +222,27 @@ const QList<QAudioDeviceInfo> &AudioManager::ListOutputDevices()
AudioManager::AudioManager() : AudioManager::AudioManager() :
is_refreshing_inputs_(false), is_refreshing_inputs_(false),
is_refreshing_outputs_(false), is_refreshing_outputs_(false),
output_stream_(nullptr), output_stream_(nullptr)
input_(nullptr),
input_file_(nullptr)
{ {
//RefreshDevices(); //RefreshDevices();
Pa_Initialize(); Pa_Initialize();
output_ = Pa_GetDefaultOutputDevice(); SetOutputDevice(Pa_GetDefaultOutputDevice());
SetInputDevice(Pa_GetDefaultInputDevice());
output_buffer_ = std::make_unique<PreviewAudioDevice>();
output_buffer_->open(PreviewAudioDevice::ReadWrite);
connect(output_buffer_.get(), &PreviewAudioDevice::Notify, this, &AudioManager::OutputNotify);
} }
AudioManager::~AudioManager() AudioManager::~AudioManager()
{ {
StopOutputStream(); CloseOutputStream();
Pa_Terminate(); Pa_Terminate();
} }
void AudioManager::StartOutputStream(PaStreamCallback *streamCallback)
{
if (output_stream_) {
StopOutputStream();
}
PaStreamParameters p;
p.channelCount = output_params_.channel_count();
p.device = output_;
p.hostApiSpecificStreamInfo = nullptr;
p.sampleFormat = GetPortAudioSampleFormat(output_params_.format());
p.suggestedLatency = Pa_GetDeviceInfo(output_)->defaultLowOutputLatency;
Pa_OpenStream(&output_stream_, nullptr, &p, output_params_.sample_rate(), paFramesPerBufferUnspecified, paNoFlag, streamCallback, output_device_.get());
Pa_StartStream(output_stream_);
}
void AudioManager::StopOutputStream()
{
if (output_stream_) {
Pa_AbortStream(output_stream_);
Pa_CloseStream(output_stream_);
output_stream_ = nullptr;
}
}
void AudioManager::OutputDevicesRefreshed() void AudioManager::OutputDevicesRefreshed()
{ {
/*QFutureWatcher< QList<QAudioDeviceInfo> >* watcher = static_cast<QFutureWatcher< QList<QAudioDeviceInfo> >*>(sender()); /*QFutureWatcher< QList<QAudioDeviceInfo> >* watcher = static_cast<QFutureWatcher< QList<QAudioDeviceInfo> >*>(sender());
@@ -282,7 +272,7 @@ void AudioManager::OutputDevicesRefreshed()
void AudioManager::InputDevicesRefreshed() void AudioManager::InputDevicesRefreshed()
{ {
QFutureWatcher< QList<QAudioDeviceInfo> >* watcher = static_cast<QFutureWatcher< QList<QAudioDeviceInfo> >*>(sender()); /*QFutureWatcher< QList<QAudioDeviceInfo> >* watcher = static_cast<QFutureWatcher< QList<QAudioDeviceInfo> >*>(sender());
input_devices_ = watcher->result(); input_devices_ = watcher->result();
watcher->deleteLater(); watcher->deleteLater();
@@ -304,7 +294,7 @@ void AudioManager::InputDevicesRefreshed()
} }
} }
emit InputListReady(); emit InputListReady();*/
} }
} }
+13 -26
View File
@@ -45,13 +45,6 @@ class AudioManager : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
enum Backend {
kAudioBackendQt,
kAudioBackendCount
};
static QString GetAudioBackendName(Backend b);
static void CreateInstance(); static void CreateInstance();
static void DestroyInstance(); static void DestroyInstance();
@@ -63,23 +56,17 @@ public:
bool IsRefreshingInputs(); bool IsRefreshingInputs();
void PushToOutput(const QByteArray& samples); void SetOutputNotifyInterval(int n);
/** void PushToOutput(const AudioParams &params, const QByteArray& samples);
* @brief Start playing audio from AudioPlaybackCache
*/ void ClearBufferedOutput();
void StartOutput(std::shared_ptr<PreviewAudioDevice> device);
/**
* @brief Stop audio output immediately
*/
void StopOutput(); void StopOutput();
void SetOutputDevice(const QAudioDeviceInfo& info); void SetOutputDevice(PaDeviceIndex device);
void SetOutputParams(const AudioParams& params); void SetInputDevice(PaDeviceIndex device);
void SetInputDevice(const QAudioDeviceInfo& info);
const QList<QAudioDeviceInfo>& ListInputDevices(); const QList<QAudioDeviceInfo>& ListInputDevices();
const QList<QAudioDeviceInfo>& ListOutputDevices(); const QList<QAudioDeviceInfo>& ListOutputDevices();
@@ -87,6 +74,8 @@ public:
signals: signals:
void OutputListReady(); void OutputListReady();
void OutputNotify();
void InputListReady(); void InputListReady();
private: private:
@@ -94,9 +83,9 @@ private:
virtual ~AudioManager() override; virtual ~AudioManager() override;
void StartOutputStream(PaStreamCallback *streamCallback = nullptr); static PaSampleFormat GetPortAudioSampleFormat(AudioParams::Format fmt);
void StopOutputStream(); void CloseOutputStream();
QList<QAudioDeviceInfo> input_devices_; QList<QAudioDeviceInfo> input_devices_;
QList<QAudioDeviceInfo> output_devices_; QList<QAudioDeviceInfo> output_devices_;
@@ -106,14 +95,12 @@ private:
static AudioManager* instance_; static AudioManager* instance_;
PaDeviceIndex output_; PaDeviceIndex output_device_;
PaStream *output_stream_; PaStream *output_stream_;
AudioParams output_params_; AudioParams output_params_;
std::shared_ptr<QIODevice> output_device_; std::unique_ptr<PreviewAudioDevice> output_buffer_;
std::unique_ptr<QAudioInput> input_; PaDeviceIndex input_device_;
QAudioDeviceInfo input_device_info_;
QIODevice* input_file_;
private slots: private slots:
void OutputDevicesRefreshed(); void OutputDevicesRefreshed();
+10 -48
View File
@@ -22,17 +22,10 @@
namespace olive { namespace olive {
PreviewAudioDevice::PreviewAudioDevice(int bytes_per_frame, QObject *parent) : PreviewAudioDevice::PreviewAudioDevice(QObject *parent) :
bytes_per_frame_(bytes_per_frame),
notify_interval_(0), notify_interval_(0),
bytes_read_(0) bytes_read_(0)
{ {
// These pointers are always valid
using_ = &internal_buffer_[0];
pushing_ = &internal_buffer_[1];
// Default to swap being true because we'll have nothing in the main buffer at first
swap_requested_ = true;
} }
PreviewAudioDevice::~PreviewAudioDevice() PreviewAudioDevice::~PreviewAudioDevice()
@@ -47,13 +40,9 @@ bool PreviewAudioDevice::isSequential() const
qint64 PreviewAudioDevice::readData(char *data, qint64 maxSize) qint64 PreviewAudioDevice::readData(char *data, qint64 maxSize)
{ {
if (swap_requested_) { QMutexLocker locker(&lock_);
SwapBuffers(kFullLock);
swap_requested_ = false;
}
// This function should NEVER touch the buffer in `pushing_` qint64 copy_length = qMin(maxSize, qint64(buffer_.size()));
qint64 copy_length = qMin(maxSize, qint64(using_->size()));
if (copy_length) { if (copy_length) {
qint64 new_bytes_read = bytes_read_ + copy_length; qint64 new_bytes_read = bytes_read_ + copy_length;
@@ -66,13 +55,8 @@ qint64 PreviewAudioDevice::readData(char *data, qint64 maxSize)
bytes_read_ = new_bytes_read; bytes_read_ = new_bytes_read;
memcpy(data, using_->constData(), copy_length); memcpy(data, buffer_.constData(), copy_length);
*using_ = using_->mid(copy_length); buffer_ = buffer_.mid(copy_length);
}
if (using_->isEmpty() && !SwapBuffers(kTryLock)) {
// Ask push function to swap if it can. If it can't, we'll catch it next read.
swap_requested_ = true;
} }
return copy_length; return copy_length;
@@ -80,41 +64,19 @@ qint64 PreviewAudioDevice::readData(char *data, qint64 maxSize)
qint64 PreviewAudioDevice::writeData(const char *data, qint64 length) qint64 PreviewAudioDevice::writeData(const char *data, qint64 length)
{ {
// This function should NEVER touch the buffer in `using_`
QMutexLocker locker(&lock_); QMutexLocker locker(&lock_);
pushing_->append(data, length);
// If swap requested, do this now buffer_.append(data, length);
if (swap_requested_) {
SwapBuffers(kDontLock);
swap_requested_ = false;
}
return length; return length;
} }
bool PreviewAudioDevice::SwapBuffers(LockMethod m) void PreviewAudioDevice::clear()
{ {
switch (m) { QMutexLocker locker(&lock_);
case kDontLock:
break;
case kTryLock:
if (!lock_.tryLock()) {
return false;
}
break;
case kFullLock:
lock_.lock();
break;
}
std::swap(using_, pushing_); buffer_.clear();
bytes_read_ = 0;
if (m != kDontLock) {
lock_.unlock();
}
return true;
} }
} }
+9 -15
View File
@@ -29,7 +29,7 @@ class PreviewAudioDevice : public QIODevice
{ {
Q_OBJECT Q_OBJECT
public: public:
PreviewAudioDevice(int bytes_per_frame, QObject *parent = nullptr); PreviewAudioDevice(QObject *parent = nullptr);
virtual ~PreviewAudioDevice() override; virtual ~PreviewAudioDevice() override;
@@ -46,31 +46,25 @@ public:
return bytes_per_frame_; return bytes_per_frame_;
} }
void set_bytes_per_frame(int b)
{
bytes_per_frame_ = b;
}
void set_notify_interval(qint64 i) void set_notify_interval(qint64 i)
{ {
notify_interval_ = i; notify_interval_ = i;
} }
void clear();
signals: signals:
void Notify(); void Notify();
private: private:
enum LockMethod {
kDontLock,
kTryLock,
kFullLock
};
bool SwapBuffers(LockMethod m);
QMutex lock_; QMutex lock_;
QByteArray internal_buffer_[2]; QByteArray buffer_;
QByteArray *using_;
QByteArray *pushing_;
QAtomicInt swap_requested_;
int bytes_per_frame_; int bytes_per_frame_;
+32 -35
View File
@@ -58,8 +58,7 @@ ViewerWidget::ViewerWidget(QWidget *parent) :
color_menu_enabled_(true), color_menu_enabled_(true),
time_changed_from_timer_(false), time_changed_from_timer_(false),
prequeuing_video_(false), prequeuing_video_(false),
prequeuing_audio_(0), prequeuing_audio_(0)
audio_playback_device_(nullptr)
{ {
// Set up main layout // Set up main layout
QVBoxLayout* layout = new QVBoxLayout(this); QVBoxLayout* layout = new QVBoxLayout(this);
@@ -409,14 +408,6 @@ void ViewerWidget::ClearVideoAutoCacherQueue()
auto_cacher_.CancelVideoTasks(); auto_cacher_.CancelVideoTasks();
} }
void ViewerWidget::StartAudioOutput()
{
AudioManager::instance()->SetOutputParams(GetConnectedNode()->GetAudioParams());
AudioManager::instance()->StartOutput(audio_playback_device_);
AudioMonitor::StartWaveformOnAll(&GetConnectedNode()->audio_playback_cache()->visual(),
GetTime(), playback_speed_);
}
void ViewerWidget::QueueNextAudioBuffer() void ViewerWidget::QueueNextAudioBuffer()
{ {
rational queue_end = audio_playback_queue_time_ + (kAudioPlaybackInterval * playback_speed_); rational queue_end = audio_playback_queue_time_ + (kAudioPlaybackInterval * playback_speed_);
@@ -444,7 +435,7 @@ void ViewerWidget::ReceivedAudioBufferForPlayback()
if (watcher->HasResult()) { if (watcher->HasResult()) {
SampleBufferPtr samples = watcher->Get().value<SampleBufferPtr>(); SampleBufferPtr samples = watcher->Get().value<SampleBufferPtr>();
if (samples && audio_playback_device_) { if (samples) {
// If the samples must be reversed, reverse them now // If the samples must be reversed, reverse them now
if (playback_speed_ < 0) { if (playback_speed_ < 0) {
samples->reverse(); samples->reverse();
@@ -464,14 +455,18 @@ void ViewerWidget::ReceivedAudioBufferForPlayback()
// TempoProcessor may have emptied the array // TempoProcessor may have emptied the array
if (!pack.isEmpty()) { if (!pack.isEmpty()) {
audio_playback_device_->write(pack);
if (prequeuing_audio_) { if (prequeuing_audio_) {
// Add to prequeued audio buffer
prequeuing_audio_--; prequeuing_audio_--;
prequeued_audio_.append(pack);
if (!prequeuing_audio_) { if (!prequeuing_audio_) {
FinishPlayPreprocess(); FinishPlayPreprocess();
} }
} else {
// Push directly to audio manager
AudioManager::instance()->PushToOutput(GetConnectedNode()->GetAudioParams(), pack);
} }
} }
} }
@@ -499,8 +494,8 @@ void ViewerWidget::ReceivedAudioBufferForScrubbing()
}*/ }*/
QByteArray data = packed_processor_.Convert(samples); QByteArray data = packed_processor_.Convert(samples);
AudioManager::instance()->SetOutputParams(samples->audio_params()); AudioManager::instance()->ClearBufferedOutput();
AudioManager::instance()->PushToOutput(data); AudioManager::instance()->PushToOutput(samples->audio_params(), data);
AudioMonitor::PushBytesOnAll(data); AudioMonitor::PushBytesOnAll(data);
} }
} }
@@ -668,20 +663,17 @@ void ViewerWidget::PlayInternal(int speed, bool in_to_out_only)
AudioParams ap = GetConnectedNode()->GetAudioParams(); AudioParams ap = GetConnectedNode()->GetAudioParams();
if (ap.is_valid()) { if (ap.is_valid()) {
audio_playback_device_ = std::make_shared<PreviewAudioDevice>(ap.bytes_per_sample_per_channel() * ap.channel_count()); AudioManager::instance()->SetOutputNotifyInterval(ap.time_to_bytes(kAudioPlaybackInterval));
audio_playback_device_->set_notify_interval(ap.time_to_bytes(kAudioPlaybackInterval)); connect(AudioManager::instance(), &AudioManager::OutputNotify, this, &ViewerWidget::QueueNextAudioBuffer);
connect(audio_playback_device_.get(), &PreviewAudioDevice::Notify, this, &ViewerWidget::QueueNextAudioBuffer, Qt::QueuedConnection);
if (audio_playback_device_->open(QIODevice::ReadWrite)) { if (std::abs(playback_speed_) > 1) {
if (std::abs(playback_speed_) > 1) { tempo_processor_.Open(GetConnectedNode()->GetAudioParams(), std::abs(playback_speed_));
tempo_processor_.Open(GetConnectedNode()->GetAudioParams(), std::abs(playback_speed_)); }
}
prequeuing_audio_ = 2; // Queue two buffers ahead of time prequeuing_audio_ = 2; // Queue two buffers ahead of time
audio_playback_queue_time_ = GetTime(); audio_playback_queue_time_ = GetTime();
for (int i=0; i<prequeuing_audio_; i++) { for (int i=0; i<prequeuing_audio_; i++) {
QueueNextAudioBuffer(); QueueNextAudioBuffer();
}
} }
} }
} }
@@ -689,9 +681,6 @@ void ViewerWidget::PlayInternal(int speed, bool in_to_out_only)
void ViewerWidget::PauseInternal() void ViewerWidget::PauseInternal()
{ {
if (IsPlaying()) { if (IsPlaying()) {
AudioManager::instance()->StopOutput();
AudioMonitor::StopOnAll();
playback_speed_ = 0; playback_speed_ = 0;
controls_->ShowPlayButton(); controls_->ShowPlayButton();
@@ -707,8 +696,11 @@ void ViewerWidget::PauseInternal()
playback_queue_.clear(); playback_queue_.clear();
playback_backup_timer_.stop(); playback_backup_timer_.stop();
disconnect(audio_playback_device_.get(), &PreviewAudioDevice::Notify, this, &ViewerWidget::QueueNextAudioBuffer); // Handle audio
audio_playback_device_ = nullptr; AudioManager::instance()->StopOutput();
AudioMonitor::StopOnAll();
prequeued_audio_.clear();
disconnect(AudioManager::instance(), &AudioManager::OutputNotify, this, &ViewerWidget::QueueNextAudioBuffer);
qDeleteAll(audio_playback_queue_); qDeleteAll(audio_playback_queue_);
audio_playback_queue_.clear(); audio_playback_queue_.clear();
if (tempo_processor_.IsOpen()) { if (tempo_processor_.IsOpen()) {
@@ -730,7 +722,7 @@ void ViewerWidget::PushScrubbedAudio()
if (params.is_valid()) { if (params.is_valid()) {
// NOTE: Hardcoded scrubbing interval (20ms) // NOTE: Hardcoded scrubbing interval (20ms)
rational interval = rational(50, 1000); rational interval = rational(20, 1000);
RenderTicketWatcher *watcher = new RenderTicketWatcher(); RenderTicketWatcher *watcher = new RenderTicketWatcher();
connect(watcher, &RenderTicketWatcher::Finished, this, &ViewerWidget::ReceivedAudioBufferForScrubbing); connect(watcher, &RenderTicketWatcher::Finished, this, &ViewerWidget::ReceivedAudioBufferForScrubbing);
@@ -837,8 +829,13 @@ void ViewerWidget::FinishPlayPreprocess()
int64_t playback_start_time = GetTimestamp(); int64_t playback_start_time = GetTimestamp();
if (audio_playback_device_) { // Start audio waveform playback
StartAudioOutput(); if (!prequeued_audio_.isEmpty()) {
AudioManager::instance()->PushToOutput(GetConnectedNode()->GetAudioParams(), prequeued_audio_);
prequeued_audio_.clear();
AudioMonitor::StartWaveformOnAll(&GetConnectedNode()->audio_playback_cache()->visual(),
GetTime(), playback_speed_);
} }
playback_timer_.Start(playback_start_time, playback_speed_, timebase_dbl()); playback_timer_.Start(playback_start_time, playback_speed_, timebase_dbl());
+1 -3
View File
@@ -256,11 +256,11 @@ private:
QVector<RenderTicketWatcher*> queue_watchers_; QVector<RenderTicketWatcher*> queue_watchers_;
std::shared_ptr<PreviewAudioDevice> audio_playback_device_;
std::list<RenderTicketWatcher*> audio_playback_queue_; std::list<RenderTicketWatcher*> audio_playback_queue_;
rational audio_playback_queue_time_; rational audio_playback_queue_time_;
PackedProcessor packed_processor_; PackedProcessor packed_processor_;
TempoProcessor tempo_processor_; TempoProcessor tempo_processor_;
QByteArray prequeued_audio_;
static const int kAudioPlaybackInterval; static const int kAudioPlaybackInterval;
static QVector<ViewerWidget*> instances_; static QVector<ViewerWidget*> instances_;
@@ -308,8 +308,6 @@ private slots:
void Dropped(QDropEvent* event); void Dropped(QDropEvent* event);
void StartAudioOutput();
void QueueNextAudioBuffer(); void QueueNextAudioBuffer();
void ReceivedAudioBufferForPlayback(); void ReceivedAudioBufferForPlayback();