From 0039340fd53cc20e70f6e1ff2cc81f37c9753a7e Mon Sep 17 00:00:00 2001 From: Green Sky Date: Tue, 1 Oct 2024 18:30:20 +0200 Subject: [PATCH] further small reframer fixes, workaround distortion bug by wrapping sdl input with reframer (magic fix, someone pls tell my why) --- .../audio_stream_pop_reframer.hpp | 56 +++++++++++-------- .../sdl/sdl_audio2_frame_stream2.cpp | 20 +++++-- src/frame_streams/test_pop_reframer.cpp | 8 +-- src/tox_av_voip_model.cpp | 3 +- 4 files changed, 49 insertions(+), 38 deletions(-) diff --git a/src/frame_streams/audio_stream_pop_reframer.hpp b/src/frame_streams/audio_stream_pop_reframer.hpp index a1734f78..fdb44bdb 100644 --- a/src/frame_streams/audio_stream_pop_reframer.hpp +++ b/src/frame_streams/audio_stream_pop_reframer.hpp @@ -30,41 +30,49 @@ struct AudioStreamPopReFramer : public FrameStream2I { ~AudioStreamPopReFramer(void) {} + size_t getDesiredSize(void) const { + return _frame_length_ms * _sample_rate * _channels / 1000; + } + int32_t size(void) override { return -1; } std::optional pop(void) override { - auto new_in = _stream.pop(); - if (new_in.has_value()) { - auto& new_value = new_in.value(); + do { + auto new_in = _stream.pop(); + if (new_in.has_value()) { + auto& new_value = new_in.value(); - // changed - if (_sample_rate != new_value.sample_rate || _channels != new_value.channels) { - if (_channels != 0) { - //std::cerr << "ReFramer warning: reconfiguring, dropping buffer\n"; + // changed + if (_sample_rate != new_value.sample_rate || _channels != new_value.channels) { + //if (_channels != 0) { + // std::cerr << "ReFramer warning: reconfiguring, dropping buffer\n"; + //} + _sample_rate = new_value.sample_rate; + _channels = new_value.channels; + + // buffer does not exist or config changed and we discard + _buffer = {}; } - _sample_rate = new_value.sample_rate; - _channels = new_value.channels; - // buffer does not exist or config changed and we discard - _buffer = {}; - } + //std::cout << "new incoming frame is " << new_value.getSpan().size/new_value.channels*1000/new_value.sample_rate << "ms\n"; + auto new_span = new_value.getSpan(); - //std::cout << "new incoming frame is " << new_value.getSpan().size/new_value.channels*1000/new_value.sample_rate << "ms\n"; - - auto new_span = new_value.getSpan(); - - if (_buffer.empty()) { - _buffer = {new_span.cbegin(), new_span.cend()}; + if (_buffer.empty()) { + _buffer = {new_span.cbegin(), new_span.cend()}; + } else { + _buffer.insert(_buffer.cend(), new_span.cbegin(), new_span.cend()); + } + } else if (_buffer.empty()) { + // first pop might result in invalid state + return std::nullopt; } else { - _buffer.insert(_buffer.cend(), new_span.cbegin(), new_span.cend()); + // inner stream pop did not give a new value + break; // out of loop } - } else if (_buffer.empty()) { - // first pop might result in invalid state - return std::nullopt; - } + } while (_buffer.size() < getDesiredSize()); - const size_t desired_size {_frame_length_ms * _sample_rate * _channels / 1000}; + const auto desired_size = getDesiredSize(); // > threshold? if (_buffer.size() < desired_size) { diff --git a/src/frame_streams/sdl/sdl_audio2_frame_stream2.cpp b/src/frame_streams/sdl/sdl_audio2_frame_stream2.cpp index 792f76ba..b70e4207 100644 --- a/src/frame_streams/sdl/sdl_audio2_frame_stream2.cpp +++ b/src/frame_streams/sdl/sdl_audio2_frame_stream2.cpp @@ -4,6 +4,8 @@ #include #include +#include "../audio_stream_pop_reframer.hpp" + // "thin" wrapper around sdl audio streams // we dont needs to get fance, as they already provide everything we need struct SDLAudio2StreamReader : public AudioFrame2Stream2I { @@ -58,7 +60,7 @@ struct SDLAudio2StreamReader : public AudioFrame2Stream2I { return std::nullopt; } - return AudioFrame2 { + return AudioFrame2{ _sample_rate, _channels, Span(_buffer.data(), read_bytes/sizeof(int16_t)), }; @@ -127,11 +129,17 @@ std::shared_ptr> SDLAudio2InputDevice::subscribe(void // error check SDL_BindAudioStream(_virtual_device_id, sdl_stream); - auto new_stream = std::make_shared(); - // TODO: move to ctr - new_stream->_stream = {sdl_stream, &SDL_DestroyAudioStream}; - new_stream->_sample_rate = spec.freq; - new_stream->_channels = spec.channels; + //auto new_stream = std::make_shared(); + //// TODO: move to ctr + //new_stream->_stream = {sdl_stream, &SDL_DestroyAudioStream}; + //new_stream->_sample_rate = spec.freq; + //new_stream->_channels = spec.channels; + + auto new_stream = std::make_shared>(); + new_stream->_stream._stream = {sdl_stream, &SDL_DestroyAudioStream}; + new_stream->_stream._sample_rate = spec.freq; + new_stream->_stream._channels = spec.channels; + new_stream->_frame_length_ms = 5; // WHY DOES THIS FIX MY ISSUE !!! _streams.emplace_back(new_stream); diff --git a/src/frame_streams/test_pop_reframer.cpp b/src/frame_streams/test_pop_reframer.cpp index 31fc9c4c..54ae6add 100644 --- a/src/frame_streams/test_pop_reframer.cpp +++ b/src/frame_streams/test_pop_reframer.cpp @@ -81,15 +81,9 @@ int main(void) { } stream.push(f1); - - { - auto ret_opt = stream.pop(); - assert(!ret_opt); - } - - // push the other half stream.push(f2); + // supposed to combine both auto ret_opt = stream.pop(); assert(ret_opt); diff --git a/src/tox_av_voip_model.cpp b/src/tox_av_voip_model.cpp index 2a65e904..9da602a1 100644 --- a/src/tox_av_voip_model.cpp +++ b/src/tox_av_voip_model.cpp @@ -58,7 +58,8 @@ struct ToxAVCallAudioSink : public FrameStream2SinkI { return nullptr; } - _writer = std::make_shared>>(); + // 20ms for now, 10ms would work too, further investigate stutters at 5ms (probably too slow interval rate) + _writer = std::make_shared>>(20); return _writer; }