diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2011-06-29 06:37:04 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2011-06-29 06:37:04 +0000 |
commit | a2b6703a369f6cdbfec1f150c408dadc877631fb (patch) | |
tree | 3145a8c1372c44711d38feefeba39c7d4098f139 /firmware/target/arm/pcm-telechips.c | |
parent | 8411614b8a068a4f274c3841aa55aab1df1bc246 (diff) | |
download | rockbox-a2b6703a369f6cdbfec1f150c408dadc877631fb.tar.gz rockbox-a2b6703a369f6cdbfec1f150c408dadc877631fb.zip |
Commit FS#12150 - Fully-functional audio mixer - and finally whip old limitations about playback of voice and other sounds when paused. Channels are independent in state and amplitude. Fade on stop/pause is handled by the channel's volume control rather than global volume which means it now works from anywhere. Opens up the possibility of plugin sounds during music playback by merely adding an additional channel enum. If any PCM drivers were not properly modified, see one of the last comments in the task for a description of the simple change that is expected. Some params are tunable in firmware/export/pcm-mixer.h as well.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30097 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/pcm-telechips.c')
-rw-r--r-- | firmware/target/arm/pcm-telechips.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/firmware/target/arm/pcm-telechips.c b/firmware/target/arm/pcm-telechips.c index 851ebee7de..aff43171f6 100644 --- a/firmware/target/arm/pcm-telechips.c +++ b/firmware/target/arm/pcm-telechips.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include "sound.h" | 27 | #include "sound.h" |
28 | #include "i2s.h" | 28 | #include "i2s.h" |
29 | #include "pcm.h" | 29 | #include "pcm.h" |
30 | #include "pcm-internal.h" | ||
30 | 31 | ||
31 | struct dma_data | 32 | struct dma_data |
32 | { | 33 | { |
@@ -247,6 +248,8 @@ void fiq_handler(void) | |||
247 | * r0-r3 and r12 is a working register. | 248 | * r0-r3 and r12 is a working register. |
248 | */ | 249 | */ |
249 | asm volatile ( | 250 | asm volatile ( |
251 | "stmfd sp!, { r0-r4, lr } \n" /* stack scratch regs and lr */ | ||
252 | "mov r4, #0 \n" /* Was the callback called? */ | ||
250 | #if defined(CPU_TCC780X) | 253 | #if defined(CPU_TCC780X) |
251 | "mov r8, #0xc000 \n" /* DAI_TX_IRQ_MASK | DAI_RX_IRQ_MASK */ | 254 | "mov r8, #0xc000 \n" /* DAI_TX_IRQ_MASK | DAI_RX_IRQ_MASK */ |
252 | "ldr r9, =0xf3001004 \n" /* CREQ */ | 255 | "ldr r9, =0xf3001004 \n" /* CREQ */ |
@@ -279,33 +282,41 @@ void fiq_handler(void) | |||
279 | "sub r9, r9, #0x10 \n" /* 4 words written */ | 282 | "sub r9, r9, #0x10 \n" /* 4 words written */ |
280 | "stmia r11, { r8-r9 } \n" /* save p and size */ | 283 | "stmia r11, { r8-r9 } \n" /* save p and size */ |
281 | 284 | ||
285 | "cmp r4, #0 \n" /* Callback called? */ | ||
286 | "beq .exit \n" | ||
287 | /* "mov r4, #0 \n" If get_more could be called multiple times! */ | ||
288 | "ldr r2, =pcm_play_dma_started\n" | ||
289 | "ldr r2, [r2] \n" | ||
290 | "cmp r2, #0 \n" | ||
291 | "blxne r2 \n" | ||
292 | |||
282 | ".exit: \n" | 293 | ".exit: \n" |
294 | "ldmfd sp!, { r0-r4, lr } \n" | ||
283 | "subs pc, lr, #4 \n" /* FIQ specific return sequence */ | 295 | "subs pc, lr, #4 \n" /* FIQ specific return sequence */ |
284 | 296 | ||
285 | ".more_data: \n" | 297 | ".more_data: \n" |
286 | "stmfd sp!, { r0-r3, lr } \n" /* stack scratch regs and lr */ | 298 | "mov r4, #1 \n" /* Remember we got more data in this FIQ */ |
287 | "ldr r2, =pcm_play_get_more_callback \n" | 299 | "ldr r2, =pcm_play_get_more_callback \n" |
288 | "mov r0, r11 \n" /* r0 = &p */ | 300 | "mov r0, r11 \n" /* r0 = &p */ |
289 | "add r1, r11, #4 \n" /* r1 = &size */ | 301 | "add r1, r11, #4 \n" /* r1 = &size */ |
290 | "blx r2 \n" /* call pcm_play_get_more_callback */ | 302 | "blx r2 \n" /* call pcm_play_get_more_callback */ |
291 | "ldmia r11, { r8-r9 } \n" /* load new p and size */ | 303 | "ldmia r11, { r8-r9 } \n" /* load new p and size */ |
292 | "cmp r9, #0x10 \n" /* did we actually get enough data? */ | 304 | "cmp r9, #0x10 \n" /* did we actually get enough data? */ |
293 | "ldmfd sp!, { r0-r3, lr } \n" | ||
294 | "bpl .fill_fifo \n" /* not stop and enough? refill */ | 305 | "bpl .fill_fifo \n" /* not stop and enough? refill */ |
295 | "b .exit \n" | 306 | "b .exit \n" |
296 | ".ltorg \n" | 307 | ".ltorg \n" |
297 | ); | 308 | ); |
298 | } | 309 | } |
299 | #else /* C version for reference */ | 310 | #else /* C version for reference */ |
300 | void fiq_handler(void) ICODE_ATTR __attribute__((naked)); | 311 | void fiq_handler(void) ICODE_ATTR; |
301 | void fiq_handler(void) | 312 | void fiq_handler(void) |
302 | { | 313 | { |
303 | asm volatile( "stmfd sp!, {r0-r7, ip, lr} \n" /* Store context */ | 314 | register bool new_buffer = false; |
304 | "sub sp, sp, #8 \n"); /* Reserve stack */ | ||
305 | 315 | ||
306 | if (dma_play_data.size < 16) | 316 | if (dma_play_data.size < 16) |
307 | { | 317 | { |
308 | /* p is empty, get some more data */ | 318 | /* p is empty, get some more data */ |
319 | new_buffer = true; | ||
309 | pcm_play_get_more_callback((void**)&dma_play_data.p, | 320 | pcm_play_get_more_callback((void**)&dma_play_data.p, |
310 | &dma_play_data.size); | 321 | &dma_play_data.size); |
311 | } | 322 | } |
@@ -327,9 +338,8 @@ void fiq_handler(void) | |||
327 | /* Clear FIQ status */ | 338 | /* Clear FIQ status */ |
328 | CREQ = DAI_TX_IRQ_MASK | DAI_RX_IRQ_MASK; | 339 | CREQ = DAI_TX_IRQ_MASK | DAI_RX_IRQ_MASK; |
329 | 340 | ||
330 | asm volatile( "add sp, sp, #8 \n" /* Cleanup stack */ | 341 | if (new_buffer) |
331 | "ldmfd sp!, {r0-r7, ip, lr} \n" /* Restore context */ | 342 | pcm_play_dma_started_callback(); |
332 | "subs pc, lr, #4 \n"); /* Return from FIQ */ | ||
333 | } | 343 | } |
334 | #endif | 344 | #endif |
335 | 345 | ||