From fe3c397b64df43f0f13898db1fbaeea07e255307 Mon Sep 17 00:00:00 2001 From: Phil Schatzmann Date: Sat, 18 Nov 2023 20:12:36 +0100 Subject: [PATCH] timed_stream --- .gitignore | 1 + CMakeLists.txt | 27 +++++++++++++++++++-------- README.md | 2 +- desktop-client/CMakeLists.txt | 11 +++++++++-- desktop-client/SnapClient.cpp | 12 +++++++++--- src/api/SnapOutput.h | 13 +++++++++---- src/api/SnapProcessor.h | 3 +-- 7 files changed, 49 insertions(+), 20 deletions(-) diff --git a/.gitignore b/.gitignore index e524d79..d7a6005 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .vscode/ build/ +miniaudio.h \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index ff1b8b4..39a4ca0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,13 +28,11 @@ if(NOT arduino-audio-tools_POPULATED) endif() # opus -if(CODEC==opus) - FetchContent_Declare(arduino_libopus GIT_REPOSITORY https://github.com/pschatzmann/arduino-libopus.git GIT_TAG main ) - FetchContent_GetProperties(arduino_libopus) - if(NOT arduino_libopus_POPULATED) - FetchContent_Populate(arduino_libopus) - add_subdirectory(${arduino_libopus_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/arduino_libopus) - endif() +FetchContent_Declare(arduino_libopus GIT_REPOSITORY https://github.com/pschatzmann/arduino-libopus.git GIT_TAG main ) +FetchContent_GetProperties(arduino_libopus) +if(NOT arduino_libopus_POPULATED) + FetchContent_Populate(arduino_libopus) + add_subdirectory(${arduino_libopus_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/arduino_libopus) endif() # flac @@ -47,6 +45,16 @@ if(CODEC==flac) endif() endif() +# ogg +if(CODEC==ogg) + FetchContent_Declare(arduino_libvorbis GIT_REPOSITORY https://github.com/pschatzmann/arduino-libvorbis-idec GIT_TAG main ) + FetchContent_GetProperties(arduino_libvorbis) + if(NOT arduino_libvorbis_POPULATED) + FetchContent_Populate(arduino_libvorbis) + add_subdirectory(${arduino_libvorbis_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/arduino_libvorbis) + endif() +endif() + add_library(snapclient INTERFACE) @@ -58,7 +66,10 @@ if(CODEC==opus) target_link_libraries(snapclient INTERFACE arduino-audio-tools arduino_emulator arduino_libopus) endif() if(CODEC==flac) - target_link_libraries(snapclient INTERFACE arduino-audio-tools arduino_emulator arduino_libflac) + target_link_libraries(snapclient INTERFACE arduino-audio-tools arduino_emulator arduino_libopus arduino_libflac) +endif() +if(CODEC==ogg) + target_link_libraries(snapclient INTERFACE arduino-audio-tools arduino_emulator arduino_libopus arduino_libvorbis) endif() target_compile_definitions(snapclient INTERFACE -DARDUINO -DEXIT_ON_STOP -DIS_DESKTOP -DCONFIG_USE_RTOS=0 -DCONFIG_USE_PSRAM=0 -DCONFIG_SNAPCLIENT_SNTP_ENABLE=0 -DCONFIG_SNAPCLIENT_USE_MDNS=0) diff --git a/README.md b/README.md index d4a37bb..fffde9a 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ### Feature list - Header only C++ implementation -- PCM, Opus and FLAC decoding are supported +- PCM, Opus, FLAC and Ogg decoding is supported - Auto connect to snapcast server on network - The functionality has been tested on an ESP32 - Memory efficient implementation, so that PSRAM is not needed diff --git a/desktop-client/CMakeLists.txt b/desktop-client/CMakeLists.txt index 5a95b8e..dda38bf 100644 --- a/desktop-client/CMakeLists.txt +++ b/desktop-client/CMakeLists.txt @@ -17,6 +17,13 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/.. ${CMAKE_CURRENT_BINARY_DIR}/snapclient ) endif() +FetchContent_Declare(arduino_libvorbis GIT_REPOSITORY https://github.com/pschatzmann/arduino-libvorbis-tremor.git GIT_TAG main ) +FetchContent_GetProperties(arduino_libvorbis) +if(NOT arduino_libvorbis_POPULATED) + FetchContent_Populate(arduino_libvorbis) + add_subdirectory(${arduino_libvorbis_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/arduino_libvorbis) +endif() + # build sketch as executable add_executable (desktop-client SnapClient.cpp) @@ -25,7 +32,7 @@ add_executable (desktop-client SnapClient.cpp) target_compile_definitions(desktop-client PUBLIC -DARDUINO -DEXIT_ON_STOP -DIS_DESKTOP -DCONFIG_USE_PSRAM=0 -DCONFIG_SNAPCLIENT_SNTP_ENABLE=0 -DCONFIG_SNAPCLIENT_USE_MDNS=0) # specify libraries -target_link_libraries(desktop-client snapclient arduino-audio-tools arduino_emulator arduino_libvorbis) +target_link_libraries(desktop-client snapclient arduino-audio-tools arduino_emulator arduino_libopus arduino_libvorbis) # to find include for miniaudio -target_include_directories(desktop-client PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) \ No newline at end of file +target_include_directories(desktop-client PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/desktop-client/SnapClient.cpp b/desktop-client/SnapClient.cpp index 13d2517..a7ed91e 100644 --- a/desktop-client/SnapClient.cpp +++ b/desktop-client/SnapClient.cpp @@ -6,18 +6,23 @@ #include "AudioTools.h" #include "SnapClient.h" #include "AudioLibs/MiniAudioStream.h" -#include "AudioCodecs/CodecOpus.h" +//#include "AudioCodecs/CodecOpus.h" //#include "AudioCodecs/CodecFLAC.h" // https://github.com/pschatzmann/arduino-libflac.git +#include "AudioCodecs/CodecVorbis.h" //https://github.com/pschatzmann/arduino-libvorbis-idec +#include "AudioLibs/StdioStream.h" //CsvOutput out; +//StdioStream out; MiniAudioStream out; -OpusAudioDecoder opus; +//OpusAudioDecoder opus; +VorbisDecoder ogg; //FLACDecoder flac; WiFiClient wifi; -SnapClient client(wifi, out, opus); +SnapClient client(wifi, out, ogg); void setup() { Serial.begin(115200); + //AudioLogger::instance().begin(Serial, AudioLogger::Info); // login to wifi WiFi.begin(CONFIG_WIFI_SSID, CONFIG_WIFI_PASSWORD); Serial.print("Connecting to WiFi .."); @@ -30,6 +35,7 @@ void setup() { Serial.println(); Serial.println(WiFi.localIP()); + // start snap client client.begin(); } diff --git a/src/api/SnapOutput.h b/src/api/SnapOutput.h index 1154328..cd35d83 100644 --- a/src/api/SnapOutput.h +++ b/src/api/SnapOutput.h @@ -89,7 +89,8 @@ friend SnapProcessor; this->out = &output; // final output resample.setStream(output); vol_stream.setStream(resample); // adjust volume - decoder_stream.setStream(&vol_stream); // decode to pcm + timed_stream.setStream(vol_stream); + decoder_stream.setStream(&timed_stream); // decode to pcm } /// Defines the decoder class @@ -103,6 +104,7 @@ friend SnapProcessor; if (is_audio_begin_called){ vol_stream.setAudioInfo(info); out->setAudioInfo(info); + timed_stream.setAudioInfo(info); } } @@ -129,6 +131,7 @@ friend SnapProcessor; EncodedAudioStream decoder_stream; VolumeStream vol_stream; ResampleStream resample; + TimedStream timed_stream; float vol = 1.0; // volume in the range 0.0 - 1.0 float vol_factor = 1.0; // bool is_mute = false; @@ -149,8 +152,6 @@ friend SnapProcessor; auto vol_cfg = vol_stream.defaultConfig(); vol_cfg.copyFrom(audio_info); vol_cfg.allow_boost = true; - vol_cfg.channels = 2; - vol_cfg.bits_per_sample = 16; vol_stream.begin(vol_cfg); // open final output @@ -169,6 +170,9 @@ friend SnapProcessor; res_cfg.copyFrom(audio_info); resample.begin(res_cfg); + // set up timed stream + timed_stream.begin(audio_info); + ESP_LOGD(TAG, "end"); is_audio_begin_called = true; return true; @@ -245,7 +249,8 @@ friend SnapProcessor; } else { // wait for the audio to become valid ESP_LOGI(TAG, "starting after %d ms", delay_ms); - delay(delay_ms); + // replaced delay(delay_ms); with timed_stream + timed_stream.setStartMs(delay_ms); is_sync_started = true; result = true; } diff --git a/src/api/SnapProcessor.h b/src/api/SnapProcessor.h index a56b0bb..be37af7 100644 --- a/src/api/SnapProcessor.h +++ b/src/api/SnapProcessor.h @@ -7,7 +7,6 @@ #include "SnapProcessor.h" #include "SnapProtocol.h" #include "SnapTime.h" -#include "opus.h" #include "vector" /** @@ -367,7 +366,7 @@ class SnapProcessor { ESP_LOGD(TAG, "start"); start = &send_receive_buffer[0]; SnapMessageWireChunk wire_chunk_message; - memset(&wire_chunk_message, 0, sizeof(wire_chunk_message)); + memset((void*)&wire_chunk_message, 0, sizeof(wire_chunk_message)); int result = wire_chunk_message.deserialize(start, size); if (result) { ESP_LOGI(TAG, "Failed to read wire chunk: %d", result);