diff --git a/firmware/export/pcm.h b/firmware/export/pcm.h index 5f1509ad97..42931fbf21 100644 --- a/firmware/export/pcm.h +++ b/firmware/export/pcm.h @@ -64,6 +64,7 @@ bool pcm_is_initialized(void); enum pcm_sink_ids pcm_current_sink(void); const struct pcm_sink_caps* pcm_sink_caps(enum pcm_sink_ids sink); +bool pcm_switch_sink(enum pcm_sink_ids sink); /* shortcut for plugins */ const struct pcm_sink_caps* pcm_current_sink_caps(void); diff --git a/firmware/pcm.c b/firmware/pcm.c index eebcf70e1c..1bf0157182 100644 --- a/firmware/pcm.c +++ b/firmware/pcm.c @@ -291,6 +291,40 @@ const struct pcm_sink_caps* pcm_current_sink_caps(void) return pcm_sink_caps(pcm_current_sink()); } +bool pcm_switch_sink(enum pcm_sink_ids sink) +{ + logf("pcm_switch_sink %d to %d", cur_sink, sink); + if(sink >= ARRAYLEN(sinks)) { + return false; + } + + if(cur_sink == sink) { + return true; + } + /* save current sink before switching */ + struct pcm_sink* old_sink = sinks[cur_sink]; + /* update sink index */ + cur_sink = sink; + /* synchronize frequency */ + unsigned long cur_sampr = old_sink->caps.samprs[old_sink->pending_freq]; + pcm_set_frequency(cur_sampr); + pcm_apply_settings(); + /* when playing, continue playing on new sink */ + if(pcm_playing) { + old_sink->ops.stop(); + /* need more */ + const void *start; + size_t size; + if(pcm_get_more_int(&start, &size)) { + pcm_play_dma_start_int(start, size); + } else { + pcm_play_stop_int(); + } + } + + return true; +} + void pcm_play_data(pcm_play_callback_type get_more, pcm_status_callback_type status_cb, const void *start, size_t size)