summaryrefslogtreecommitdiff
path: root/firmware/target/arm/pcm-telechips.c
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2011-06-29 06:37:04 +0000
committerMichael Sevakis <jethead71@rockbox.org>2011-06-29 06:37:04 +0000
commita2b6703a369f6cdbfec1f150c408dadc877631fb (patch)
tree3145a8c1372c44711d38feefeba39c7d4098f139 /firmware/target/arm/pcm-telechips.c
parent8411614b8a068a4f274c3841aa55aab1df1bc246 (diff)
downloadrockbox-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.c26
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
31struct dma_data 32struct 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 */
300void fiq_handler(void) ICODE_ATTR __attribute__((naked)); 311void fiq_handler(void) ICODE_ATTR;
301void fiq_handler(void) 312void 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