diff --git a/playback/audio.cpp b/playback/audio.cpp index 186a6da5b..6de4ae866 100644 --- a/playback/audio.cpp +++ b/playback/audio.cpp @@ -17,6 +17,7 @@ extern "C" { QAudioOutput* audio_output; QIODevice* audio_io_device; bool audio_device_set = false; +QMutex audio_write_lock; qint8 audio_ibuffer[audio_ibuffer_size]; int audio_ibuffer_read = 0; diff --git a/playback/audio.h b/playback/audio.h index 0aaffebb5..e6c9bed78 100644 --- a/playback/audio.h +++ b/playback/audio.h @@ -33,6 +33,7 @@ private: extern QAudioOutput* audio_output; extern QIODevice* audio_io_device; extern AudioSenderThread* audio_thread; +extern QMutex audio_write_lock; #define audio_ibuffer_size 192000 extern qint8 audio_ibuffer[audio_ibuffer_size]; diff --git a/playback/cacher.cpp b/playback/cacher.cpp index 63449a2e4..acb7e93d8 100644 --- a/playback/cacher.cpp +++ b/playback/cacher.cpp @@ -116,7 +116,6 @@ void cache_audio_worker(Clip* c, Clip* nest) { } else { int nb_bytes = av_samples_get_buffer_size(NULL, frame->channels, frame->nb_samples, static_cast(frame->format), 1); - int half_buffer = (audio_ibuffer_size/2); if (c->audio_buffer_write == 0) { c->audio_buffer_write = get_buffer_offset_from_frame(qMax(timeline_in, c->audio_target_frame)); @@ -148,29 +147,31 @@ void cache_audio_worker(Clip* c, Clip* nest) { } long buffer_timeline_out = get_buffer_offset_from_frame(timeline_out); - while (c->frame_sample_index < nb_bytes) { - if (c->audio_buffer_write >= audio_ibuffer_read+half_buffer || c->audio_buffer_write >= buffer_timeline_out) { - written = max_write; - break; - } else { - int upper_byte_index = (c->audio_buffer_write+1)%audio_ibuffer_size; - int lower_byte_index = (c->audio_buffer_write)%audio_ibuffer_size; - qint16 old_sample = static_cast((audio_ibuffer[upper_byte_index] & 0xFF) << 8 | (audio_ibuffer[lower_byte_index] & 0xFF)); - qint16 new_sample = static_cast((frame->data[0][c->frame_sample_index+1] & 0xFF) << 8 | (frame->data[0][c->frame_sample_index] & 0xFF)); - qint32 mixed_sample = static_cast(old_sample) + static_cast(new_sample); - mixed_sample = qMax(qMin(mixed_sample, static_cast(INT16_MAX)), static_cast(INT16_MIN)); + audio_write_lock.lock(); + while (c->frame_sample_index < nb_bytes + && c->audio_buffer_write < audio_ibuffer_read+audio_ibuffer_size + && c->audio_buffer_write < buffer_timeline_out) { + int upper_byte_index = (c->audio_buffer_write+1)%audio_ibuffer_size; + int lower_byte_index = (c->audio_buffer_write)%audio_ibuffer_size; + qint16 old_sample = static_cast((audio_ibuffer[upper_byte_index] & 0xFF) << 8 | (audio_ibuffer[lower_byte_index] & 0xFF)); + qint16 new_sample = static_cast((frame->data[0][c->frame_sample_index+1] & 0xFF) << 8 | (frame->data[0][c->frame_sample_index] & 0xFF)); + qint32 mixed_sample = static_cast(old_sample) + static_cast(new_sample); + mixed_sample = qMax(qMin(mixed_sample, static_cast(INT16_MAX)), static_cast(INT16_MIN)); - audio_ibuffer[upper_byte_index] = static_cast((mixed_sample >> 8) & 0xFF); - audio_ibuffer[lower_byte_index] = static_cast(mixed_sample & 0xFF); + audio_ibuffer[upper_byte_index] = static_cast((mixed_sample >> 8) & 0xFF); + audio_ibuffer[lower_byte_index] = static_cast(mixed_sample & 0xFF); - c->audio_buffer_write+=2; - c->frame_sample_index+=2; - written+=2; - } + c->audio_buffer_write+=2; + c->frame_sample_index+=2; + written+=2; } + audio_write_lock.unlock(); if (c->frame_sample_index == nb_bytes) { c->need_new_audio_frame = true; - } + } else { + // assume we have no more data to send + break; + } } } }