summaryrefslogtreecommitdiff
path: root/firmware/pcm.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/pcm.c')
-rw-r--r--firmware/pcm.c195
1 files changed, 92 insertions, 103 deletions
diff --git a/firmware/pcm.c b/firmware/pcm.c
index 94b0d6eefb..6bf0e12c8d 100644
--- a/firmware/pcm.c
+++ b/firmware/pcm.c
@@ -86,7 +86,7 @@
86static bool pcm_is_ready = false; 86static bool pcm_is_ready = false;
87 87
88/* The registered callback function to ask for more mp3 data */ 88/* The registered callback function to ask for more mp3 data */
89static volatile pcm_play_callback_type 89volatile pcm_play_callback_type
90 pcm_callback_for_more SHAREDBSS_ATTR = NULL; 90 pcm_callback_for_more SHAREDBSS_ATTR = NULL;
91/* The registered callback function to inform of DMA status */ 91/* The registered callback function to inform of DMA status */
92volatile pcm_status_callback_type 92volatile pcm_status_callback_type
@@ -102,9 +102,89 @@ unsigned long pcm_sampr SHAREDBSS_ATTR = HW_SAMPR_DEFAULT;
102/* samplerate frequency selection index */ 102/* samplerate frequency selection index */
103int pcm_fsel SHAREDBSS_ATTR = HW_FREQ_DEFAULT; 103int pcm_fsel SHAREDBSS_ATTR = HW_FREQ_DEFAULT;
104 104
105/* Called internally by functions to reset the state */ 105static void pcm_play_data_start_int(const void *addr, size_t size);
106static void pcm_play_stopped(void) 106static void pcm_play_pause_int(bool play);
107void pcm_play_stop_int(void);
108
109#ifndef HAVE_SW_VOLUME_CONTROL
110/** Standard hw volume control functions - otherwise, see pcm_sw_volume.c **/
111static inline void pcm_play_dma_start_int(const void *addr, size_t size)
112{
113 pcm_play_dma_start(addr, size);
114}
115
116static inline void pcm_play_dma_pause_int(bool pause)
117{
118 if (pause || pcm_get_bytes_waiting() > 0)
119 {
120 pcm_play_dma_pause(pause);
121 }
122 else
123 {
124 logf(" no data");
125 pcm_play_data_start_int(NULL, 0);
126 }
127}
128
129static inline void pcm_play_dma_stop_int(void)
130{
131 pcm_play_dma_stop();
132}
133
134static inline const void * pcm_play_dma_get_peak_buffer_int(int *count)
135{
136 return pcm_play_dma_get_peak_buffer(count);
137}
138
139bool pcm_play_dma_complete_callback(enum pcm_dma_status status,
140 const void **addr, size_t *size)
141{
142 /* Check status callback first if error */
143 if (status < PCM_DMAST_OK)
144 status = pcm_play_dma_status_callback(status);
145
146 if (status >= PCM_DMAST_OK && pcm_get_more_int(addr, size))
147 return true;
148
149 /* Error, callback missing or no more DMA to do */
150 pcm_play_stop_int();
151 return false;
152}
153#endif /* ndef HAVE_SW_VOLUME_CONTROL */
154
155static void pcm_play_data_start_int(const void *addr, size_t size)
107{ 156{
157 ALIGN_AUDIOBUF(addr, size);
158
159 if ((addr && size) || pcm_get_more_int(&addr, &size))
160 {
161 pcm_apply_settings();
162 logf(" pcm_play_dma_start_int");
163 pcm_play_dma_start_int(addr, size);
164 pcm_playing = true;
165 pcm_paused = false;
166 }
167 else
168 {
169 /* Force a stop */
170 logf(" pcm_play_stop_int");
171 pcm_play_stop_int();
172 }
173}
174
175static void pcm_play_pause_int(bool play)
176{
177 if (play)
178 pcm_apply_settings();
179
180 logf(" pcm_play_dma_pause_int");
181 pcm_play_dma_pause_int(!play);
182 pcm_paused = !play && pcm_playing;
183}
184
185void pcm_play_stop_int(void)
186{
187 pcm_play_dma_stop_int();
108 pcm_callback_for_more = NULL; 188 pcm_callback_for_more = NULL;
109 pcm_play_status_callback = NULL; 189 pcm_play_status_callback = NULL;
110 pcm_paused = false; 190 pcm_paused = false;
@@ -195,7 +275,7 @@ void pcm_calculate_peaks(int *left, int *right)
195 static struct pcm_peaks peaks; 275 static struct pcm_peaks peaks;
196 276
197 int count; 277 int count;
198 const void *addr = pcm_play_dma_get_peak_buffer(&count); 278 const void *addr = pcm_play_dma_get_peak_buffer_int(&count);
199 279
200 pcm_do_peak_calculation(&peaks, pcm_playing && !pcm_paused, 280 pcm_do_peak_calculation(&peaks, pcm_playing && !pcm_paused,
201 addr, count); 281 addr, count);
@@ -207,9 +287,9 @@ void pcm_calculate_peaks(int *left, int *right)
207 *right = peaks.right; 287 *right = peaks.right;
208} 288}
209 289
210const void* pcm_get_peak_buffer(int * count) 290const void * pcm_get_peak_buffer(int *count)
211{ 291{
212 return pcm_play_dma_get_peak_buffer(count); 292 return pcm_play_dma_get_peak_buffer_int(count);
213} 293}
214 294
215bool pcm_is_playing(void) 295bool pcm_is_playing(void)
@@ -233,8 +313,6 @@ void pcm_init(void)
233{ 313{
234 logf("pcm_init"); 314 logf("pcm_init");
235 315
236 pcm_play_stopped();
237
238 pcm_set_frequency(HW_SAMPR_DEFAULT); 316 pcm_set_frequency(HW_SAMPR_DEFAULT);
239 317
240 logf(" pcm_play_dma_init"); 318 logf(" pcm_play_dma_init");
@@ -258,41 +336,6 @@ bool pcm_is_initialized(void)
258 return pcm_is_ready; 336 return pcm_is_ready;
259} 337}
260 338
261/* Common code to pcm_play_data and pcm_play_pause */
262static void pcm_play_data_start(const void *addr, size_t size)
263{
264 ALIGN_AUDIOBUF(addr, size);
265
266 if (!(addr && size))
267 {
268 pcm_play_callback_type get_more = pcm_callback_for_more;
269 addr = NULL;
270 size = 0;
271
272 if (get_more)
273 {
274 logf(" get_more");
275 get_more(&addr, &size);
276 ALIGN_AUDIOBUF(addr, size);
277 }
278 }
279
280 if (addr && size)
281 {
282 logf(" pcm_play_dma_start");
283 pcm_apply_settings();
284 pcm_play_dma_start(addr, size);
285 pcm_playing = true;
286 pcm_paused = false;
287 return;
288 }
289
290 /* Force a stop */
291 logf(" pcm_play_dma_stop");
292 pcm_play_dma_stop();
293 pcm_play_stopped();
294}
295
296void pcm_play_data(pcm_play_callback_type get_more, 339void pcm_play_data(pcm_play_callback_type get_more,
297 pcm_status_callback_type status_cb, 340 pcm_status_callback_type status_cb,
298 const void *start, size_t size) 341 const void *start, size_t size)
@@ -304,41 +347,12 @@ void pcm_play_data(pcm_play_callback_type get_more,
304 pcm_callback_for_more = get_more; 347 pcm_callback_for_more = get_more;
305 pcm_play_status_callback = status_cb; 348 pcm_play_status_callback = status_cb;
306 349
307 logf(" pcm_play_data_start"); 350 logf(" pcm_play_data_start_int");
308 pcm_play_data_start(start, size); 351 pcm_play_data_start_int(start, size);
309 352
310 pcm_play_unlock(); 353 pcm_play_unlock();
311} 354}
312 355
313bool pcm_play_dma_complete_callback(enum pcm_dma_status status,
314 const void **addr, size_t *size)
315{
316 /* Check status callback first if error */
317 if (status < PCM_DMAST_OK)
318 status = pcm_play_dma_status_callback(status);
319
320 pcm_play_callback_type get_more = pcm_callback_for_more;
321
322 if (get_more && status >= PCM_DMAST_OK)
323 {
324 *addr = NULL;
325 *size = 0;
326
327 /* Call registered callback to obtain next buffer */
328 get_more(addr, size);
329 ALIGN_AUDIOBUF(*addr, *size);
330
331 if (*addr && *size)
332 return true;
333 }
334
335 /* Error, callback missing or no more DMA to do */
336 pcm_play_dma_stop();
337 pcm_play_stopped();
338
339 return false;
340}
341
342void pcm_play_pause(bool play) 356void pcm_play_pause(bool play)
343{ 357{
344 logf("pcm_play_pause: %s", play ? "play" : "pause"); 358 logf("pcm_play_pause: %s", play ? "play" : "pause");
@@ -347,28 +361,8 @@ void pcm_play_pause(bool play)
347 361
348 if (play == pcm_paused && pcm_playing) 362 if (play == pcm_paused && pcm_playing)
349 { 363 {
350 if (!play) 364 logf(" pcm_play_pause_int");
351 { 365 pcm_play_pause_int(play);
352 logf(" pcm_play_dma_pause");
353 pcm_play_dma_pause(true);
354 pcm_paused = true;
355 }
356 else if (pcm_get_bytes_waiting() > 0)
357 {
358 logf(" pcm_play_dma_pause");
359 pcm_apply_settings();
360 pcm_play_dma_pause(false);
361 pcm_paused = false;
362 }
363 else
364 {
365 logf(" pcm_play_dma_start: no data");
366 pcm_play_data_start(NULL, 0);
367 }
368 }
369 else
370 {
371 logf(" no change");
372 } 366 }
373 367
374 pcm_play_unlock(); 368 pcm_play_unlock();
@@ -382,13 +376,8 @@ void pcm_play_stop(void)
382 376
383 if (pcm_playing) 377 if (pcm_playing)
384 { 378 {
385 logf(" pcm_play_dma_stop"); 379 logf(" pcm_play_stop_int");
386 pcm_play_dma_stop(); 380 pcm_play_stop_int();
387 pcm_play_stopped();
388 }
389 else
390 {
391 logf(" not playing");
392 } 381 }
393 382
394 pcm_play_unlock(); 383 pcm_play_unlock();