Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,17 @@ include(FetchContent)
set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG" CACHE STRING "" FORCE)
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG" CACHE STRING "" FORCE)

set(SENDSPIN_ENABLE_PLAYER ON CACHE BOOL "" FORCE)
set(SENDSPIN_ENABLE_CONTROLLER OFF CACHE BOOL "" FORCE)
set(SENDSPIN_ENABLE_METADATA OFF CACHE BOOL "" FORCE)
set(SENDSPIN_ENABLE_COLOR OFF CACHE BOOL "" FORCE)
set(SENDSPIN_ENABLE_ARTWORK OFF CACHE BOOL "" FORCE)
set(SENDSPIN_ENABLE_VISUALIZER OFF CACHE BOOL "" FORCE)

FetchContent_Declare(
sendspin-cpp
GIT_REPOSITORY https://github.com/Sendspin/sendspin-cpp.git
GIT_TAG v0.1.0
GIT_TAG v0.4.0
GIT_SHALLOW TRUE
EXCLUDE_FROM_ALL # do not build sendspin-cpp's own examples
)
Expand Down
6 changes: 6 additions & 0 deletions config/sendspin-armv6.conf
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,9 @@ device = plughw:0,0
# too quiet. The server may override this once a connection is established.
# Leave commented out to let the server control volume from the start.
#initial_volume = 80

# Optional: Initial static playback delay in milliseconds (0–5000).
# Adds a fixed delay before playback starts, which can help keep multiple
# players in sync across the network. The server may adjust this at runtime.
# Leave commented out for no initial static delay.
#initial_static_delay = 200
13 changes: 13 additions & 0 deletions src/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,19 @@ bool load_config(const std::string& path, Config& config) {
fprintf(stderr, "%s:%d: invalid initial_volume value '%s', ignoring\n",
path.c_str(), line_num, value.c_str());
}
} else if (key == "initial_static_delay") {
try {
int v = std::stoi(value);
if (v < 0 || v > 5000) {
fprintf(stderr, "%s:%d: initial_static_delay must be 0-5000 (ms), ignoring\n",
path.c_str(), line_num);
} else {
config.initial_static_delay_ms = v;
}
} catch (const std::exception&) {
fprintf(stderr, "%s:%d: invalid initial_static_delay value '%s', ignoring\n",
path.c_str(), line_num, value.c_str());
}
} else {
fprintf(stderr, "%s:%d: unknown key '%s'\n", path.c_str(), line_num,
key.c_str());
Expand Down
7 changes: 4 additions & 3 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@

/// Configuration loaded from /etc/sendspin-armv6.conf
struct Config {
std::string server_url; // e.g. ws://192.168.1.10:8928/sendspin
std::string server_url; // e.g. ws://192.168.1.10:8928/sendspin
std::string name = "sendspin-armv6";
std::string log_level = "info";
std::string device; // ALSA device, e.g. plughw:1,0 (empty = system default)
int initial_volume = -1; // 0-100 to override hardware volume on startup; -1 = server default
std::string device; // ALSA device, e.g. plughw:1,0 (empty = system default)
int initial_volume = -1; // 0-100 to override hardware volume on startup; -1 = server default
int initial_static_delay_ms = -1; // 0-5000 ms; -1 = no initial delay
};

/// Parse a simple key=value config file.
Expand Down
10 changes: 9 additions & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ int main(int argc, char* argv[]) {
SendspinClient client(std::move(client_config));

// Add player role with supported audio formats
PlayerRole::Config player_config;
PlayerRoleConfig player_config;
player_config.audio_formats = {
{SendspinCodecFormat::FLAC, 2, 44100, 16},
{SendspinCodecFormat::FLAC, 2, 48000, 16},
Expand All @@ -124,6 +124,10 @@ int main(int argc, char* argv[]) {
// playback time already accounts for the hardware buffer. No additional
// fixed delay compensation is required.
player_config.fixed_delay_us = AlsaPipeSink::PIPELINE_DELAY_US;
if (cfg.initial_static_delay_ms >= 0) {
player_config.initial_static_delay_ms =
static_cast<uint16_t>(cfg.initial_static_delay_ms);
}
auto& player = client.add_player(std::move(player_config));

// Audio output via aplay pipe
Expand Down Expand Up @@ -166,6 +170,9 @@ int main(int argc, char* argv[]) {

void on_volume_changed(uint8_t vol) override { sink.set_volume(vol); }
void on_mute_changed(bool muted) override { sink.set_muted(muted); }
void on_static_delay_changed(uint16_t delay_ms) override {
fprintf(stderr, ">>> Static delay changed to %u ms\n", delay_ms);
}
};

struct ArmClientListener : SendspinClientListener {
Expand All @@ -189,6 +196,7 @@ int main(int argc, char* argv[]) {
HostNetworkProvider network_provider;

player.set_listener(&player_listener);
player.set_static_delay_adjustable(true);
client.set_listener(&client_listener);
client.set_network_provider(&network_provider);

Expand Down