diff options
Diffstat (limited to 'firmware/pcm_mixer.c')
-rw-r--r-- | firmware/pcm_mixer.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/firmware/pcm_mixer.c b/firmware/pcm_mixer.c index cddff431ec..34852e97e9 100644 --- a/firmware/pcm_mixer.c +++ b/firmware/pcm_mixer.c | |||
@@ -45,6 +45,7 @@ struct mixer_channel | |||
45 | pcm_play_callback_type get_more; /* Registered callback */ | 45 | pcm_play_callback_type get_more; /* Registered callback */ |
46 | enum channel_status status; /* Playback status */ | 46 | enum channel_status status; /* Playback status */ |
47 | uint32_t amplitude; /* Amp. factor: 0x0000 = mute, 0x10000 = unity */ | 47 | uint32_t amplitude; /* Amp. factor: 0x0000 = mute, 0x10000 = unity */ |
48 | chan_buffer_hook_fn_type buffer_hook; /* Callback for new buffer */ | ||
48 | }; | 49 | }; |
49 | 50 | ||
50 | /* Forget about boost here for the moment */ | 51 | /* Forget about boost here for the moment */ |
@@ -106,6 +107,12 @@ static void mixer_pcm_callback(const void **addr, size_t *size) | |||
106 | *size = next_size; | 107 | *size = next_size; |
107 | } | 108 | } |
108 | 109 | ||
110 | static inline void chan_call_buffer_hook(struct mixer_channel *chan) | ||
111 | { | ||
112 | if (UNLIKELY(chan->buffer_hook)) | ||
113 | chan->buffer_hook(chan->start, chan->size); | ||
114 | } | ||
115 | |||
109 | /* Buffering callback - calls sub-callbacks and mixes the data for next | 116 | /* Buffering callback - calls sub-callbacks and mixes the data for next |
110 | buffer to be sent from mixer_pcm_callback() */ | 117 | buffer to be sent from mixer_pcm_callback() */ |
111 | static enum pcm_dma_status MIXER_CALLBACK_ICODE | 118 | static enum pcm_dma_status MIXER_CALLBACK_ICODE |
@@ -149,6 +156,8 @@ fill_frame: | |||
149 | channel_stopped(chan); | 156 | channel_stopped(chan); |
150 | continue; | 157 | continue; |
151 | } | 158 | } |
159 | |||
160 | chan_call_buffer_hook(chan); | ||
152 | } | 161 | } |
153 | 162 | ||
154 | /* Channel will play for at least part of this frame */ | 163 | /* Channel will play for at least part of this frame */ |
@@ -298,6 +307,7 @@ void mixer_channel_play_data(enum pcm_mixer_channel channel, | |||
298 | chan->get_more = get_more; | 307 | chan->get_more = get_more; |
299 | 308 | ||
300 | mixer_activate_channel(chan); | 309 | mixer_activate_channel(chan); |
310 | chan_call_buffer_hook(chan); | ||
301 | mixer_start_pcm(); | 311 | mixer_start_pcm(); |
302 | } | 312 | } |
303 | else | 313 | else |
@@ -406,6 +416,18 @@ void mixer_adjust_channel_address(enum pcm_mixer_channel channel, | |||
406 | pcm_play_unlock(); | 416 | pcm_play_unlock(); |
407 | } | 417 | } |
408 | 418 | ||
419 | /* Set a hook that is called upon getting a new source buffer for a channel | ||
420 | NOTE: Called for each buffer, not each mixer chunk */ | ||
421 | void mixer_channel_set_buffer_hook(enum pcm_mixer_channel channel, | ||
422 | chan_buffer_hook_fn_type fn) | ||
423 | { | ||
424 | struct mixer_channel *chan = &channels[channel]; | ||
425 | |||
426 | pcm_play_lock(); | ||
427 | chan->buffer_hook = fn; | ||
428 | pcm_play_unlock(); | ||
429 | } | ||
430 | |||
409 | /* Stop ALL channels and PCM and reset state */ | 431 | /* Stop ALL channels and PCM and reset state */ |
410 | void mixer_reset(void) | 432 | void mixer_reset(void) |
411 | { | 433 | { |