diff --git a/src/common/logger.cpp b/src/common/logger.cpp index d08532d..67a2177 100644 --- a/src/common/logger.cpp +++ b/src/common/logger.cpp @@ -24,9 +24,9 @@ void Logger::setLevel(int level) return; } - if (level > static_cast(Level::Verbose)) + if (level > static_cast(Level::Protocol)) { - _level = Level::Verbose; + _level = Level::Protocol; return; } diff --git a/src/pcm_audio.cpp b/src/pcm_audio.cpp index f49a3a2..2d65cec 100644 --- a/src/pcm_audio.cpp +++ b/src/pcm_audio.cpp @@ -3,6 +3,7 @@ #include "protocol/protocol_const.h" #include "settings.h" #include "common/logger.h" +#include // Add sample size (buffer size in samples) to ChannelConfig ChannelConfig PcmAudio::_configTable[] = { @@ -24,6 +25,7 @@ PcmAudio::PcmAudio(const char *name) : _name("default"), { if (name && strlen(name) > 0) _name = name; + log_v("Created %s", _name.c_str()); } PcmAudio::~PcmAudio() @@ -31,12 +33,14 @@ PcmAudio::~PcmAudio() stop(); if (_thread.joinable()) _thread.join(); + log_v("Destroyed %s", _name.c_str()); } void PcmAudio::start(AtomicQueue *data, PcmAudio *fader) { if (_active) stop(); + log_v("Starting %s", _name.c_str()); _fader = fader; _data = data; _active = true; @@ -47,6 +51,7 @@ void PcmAudio::stop() { if (!_active) return; + log_v("Stopping %s", _name.c_str()); _active = false; _data->notify(); } @@ -69,13 +74,11 @@ bool PcmAudio::isZero(const Message *msg) { const uint64_t *p = (const uint64_t *)msg->data(); int n = msg->length() / 8; - for (int i = 0; i < n; ++i) { if (p[i] != 0) return false; } - return true; } @@ -83,9 +86,7 @@ void PcmAudio::fade(bool enable) { _fade.store(enable); if (!_playing) - { _volume = enable ? Settings::audioFade : 1.0; - } } void PcmAudio::fade(uint8_t *data, int32_t length) @@ -95,7 +96,7 @@ void PcmAudio::fade(uint8_t *data, int32_t length) return; int16_t *buf = reinterpret_cast(data); - for (size_t i = 0; i < length / 2; i++) + for (int i = 0; i < length / 2; i++) { if (fade) { @@ -116,15 +117,29 @@ void PcmAudio::play(SDL_AudioDeviceID device, ChannelConfig config, int32_t segm { uint8_t zeroSegments = 0; bool nonZero = false; + int prefill = config.channels == 1 ? Settings::audioDelayCall : Settings::audioDelay; int segmentTimeMs = 1000.0 * segmentSize / (config.rate * config.channels * 2.0); + int waitTimeMs = (prefill + 1) * segmentTimeMs; + log_i("Prepare to play %s %dkHz %s chunk %d ~%dms prefill %d ~%dms", _name.c_str(), + config.rate, + (config.channels == 2 ? "stereo" : "mono"), + segmentSize, + segmentTimeMs, + prefill, + waitTimeMs); - log_i("Prepare to play %s %dkHz %s prefill %d ~%dms chunk %d", _name.c_str(), config.rate, (config.channels == 2 ? "stereo" : "mono"), prefill, segmentTimeMs, segmentSize); - - if (!_data->waitFor(_active, segmentTimeMs * (prefill + 1) * 3, prefill)) + if (!_data->waitFor(_active, AUDIO_RESET_SECONDS * 1000, prefill)) { _data->clear(); - log_w("Not enough data to play %s %dkHz %s prefill %d ~%dms chunk %d", _name.c_str(), config.rate, (config.channels == 2 ? "stereo" : "mono"), prefill, segmentTimeMs, segmentSize); + log_w("Not enough data to play %s %dkHz %s chunk %d ~%dms prefill %d ~%dms", + _name.c_str(), + config.rate, + (config.channels == 2 ? "stereo" : "mono"), + segmentSize, + segmentTimeMs, + prefill, + waitTimeMs); return; } @@ -142,11 +157,15 @@ void PcmAudio::play(SDL_AudioDeviceID device, ChannelConfig config, int32_t segm return; fade(segment->data(), segment->length()); + SDL_QueueAudio(device, segment->data(), segment->length()); - if (!_playing) + if (!_playing && prefill-- <= 0) { - log_d("Start playing %s %dkHz %s", _name.c_str(), config.rate, (config.channels == 2 ? "stereo" : "mono")); + log_d("Start playing %s %dkHz %s", + _name.c_str(), + config.rate, + (config.channels == 2 ? "stereo" : "mono")); SDL_PauseAudioDevice(device, 0); _playing = true; } @@ -169,7 +188,7 @@ void PcmAudio::play(SDL_AudioDeviceID device, ChannelConfig config, int32_t segm } } - if (!_data->waitFor(_active, segmentTimeMs * 3)) + if (!_data->waitFor(_active, waitTimeMs)) return; } } @@ -179,11 +198,12 @@ void PcmAudio::loop() std::string threadName = "audio-" + _name; setThreadName(threadName.c_str()); - log_d("Audio %s thread started", _name.c_str()); + log_d("Started thread %s", _name.c_str()); SDL_AudioDeviceID device = 0; SDL_AudioSpec spec; + time_t playEnd = time(NULL); while (_data->wait(_active)) { const Message *segment = _data->peek(); @@ -213,13 +233,20 @@ void PcmAudio::loop() device = SDL_OpenAudioDevice(nullptr, 0, &spec, nullptr, 0); if (device == 0) { - log_w("Failed to open audio %s > %s", _name.c_str(), SDL_GetError()); + log_w("Failed to open audio %s %dkHz %s samples %d > %s", + _name.c_str(), + config.rate, + (config.channels == 2 ? "stereo" : "mono"), + Settings::audioBuffer * config.scale, SDL_GetError()); SDL_Delay(100); continue; } _config = config; } + if (difftime(time(NULL), playEnd) > AUDIO_RESET_SECONDS) + SDL_ClearQueuedAudio(device); + if (_fader) _fader->fade(true); play(device, config, segment->length()); @@ -227,13 +254,19 @@ void PcmAudio::loop() if (_fader) _fader->fade(false); SDL_PauseAudioDevice(device, 1); - log_i("Stop playing %s", _name.c_str()); + playEnd = time(NULL); + log_d("Stop playing %s %dkHz %s", + _name.c_str(), + config.rate, + (config.channels == 2 ? "stereo" : "mono")); } - if (device) + if (device != 0) { SDL_PauseAudioDevice(device, 1); SDL_ClearQueuedAudio(device); SDL_CloseAudioDevice(device); } + + log_v("Stopped thread %s", _name.c_str()); } diff --git a/src/pcm_audio.h b/src/pcm_audio.h index 585caf1..1518a24 100644 --- a/src/pcm_audio.h +++ b/src/pcm_audio.h @@ -13,6 +13,7 @@ #define FADE_IN_SPEED 0.00001 #define FADE_OUT_SPEED 0.0001 #define FADE_ZERO_SEGMENTS 10 +#define AUDIO_RESET_SECONDS 5 struct ChannelConfig { diff --git a/src/protocol/connection.cpp b/src/protocol/connection.cpp index 53f4b2a..3e06fc4 100644 --- a/src/protocol/connection.cpp +++ b/src/protocol/connection.cpp @@ -183,6 +183,7 @@ void Connection::writeLoop(libusb_device_handle *handler, uint8_t ep) int transferred; libusb_bulk_transfer(handler, ep, message->header(), message->headerSize(), &transferred, 0); + message->setOffset(0); if (message->length() > 0) libusb_bulk_transfer(handler, ep, message->data(), message->length(), &transferred, 0); } diff --git a/src/protocol/connection_reader.cpp b/src/protocol/connection_reader.cpp index 8d910f2..b6ce80b 100644 --- a/src/protocol/connection_reader.cpp +++ b/src/protocol/connection_reader.cpp @@ -25,8 +25,6 @@ ConnectionReader::ConnectionReader() ConnectionReader::~ConnectionReader() { - log_v("Destroying"); - stop(); for (Context &context : _transfers)