summaryrefslogtreecommitdiff
path: root/firmware/target/coldfire/pcm-mixer-coldfire.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/coldfire/pcm-mixer-coldfire.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/coldfire/pcm-mixer-coldfire.c')
-rw-r--r--firmware/target/coldfire/pcm-mixer-coldfire.c134
1 files changed, 134 insertions, 0 deletions
diff --git a/firmware/target/coldfire/pcm-mixer-coldfire.c b/firmware/target/coldfire/pcm-mixer-coldfire.c
new file mode 100644
index 0000000000..d8318fffaf
--- /dev/null
+++ b/firmware/target/coldfire/pcm-mixer-coldfire.c
@@ -0,0 +1,134 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by Michael Sevakis
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#define MIXER_OPTIMIZED_MIX_SAMPLES
23#define MIXER_OPTIMIZED_WRITE_SAMPLES
24static struct emac_context
25{
26 unsigned long r[4];
27} emac_context IBSS_ATTR;
28
29/* Save emac context affected in ISR */
30static FORCE_INLINE void save_emac_context(void)
31{
32 asm volatile (
33 "move.l %%macsr, %%d0 \n"
34 "move.l %%accext01, %%d1 \n"
35 "movclr.l %%acc0, %%a0 \n"
36 "movclr.l %%acc1, %%a1 \n"
37 "movem.l %%d0-%%d1/%%a0-%%a1, (%0) \n"
38 :
39 : "a"(&emac_context)
40 : "d0", "d1", "a0", "a1");
41}
42
43/* Restore emac context affected in ISR */
44static FORCE_INLINE void restore_emac_context(void)
45{
46 asm volatile (
47 "movem.l (%0), %%d0-%%d1/%%a0-%%a1 \n"
48 "move.l %%a1, %%acc1 \n"
49 "move.l %%a0, %%acc0 \n"
50 "move.l %%d1, %%accext01 \n"
51 "move.l %%d0, %%macsr \n"
52 :
53 : "a"(&emac_context)
54 : "d0", "d1", "a0", "a1");
55}
56
57/* Mix channels' samples and apply gain factors */
58static FORCE_INLINE void mix_samples(void *out,
59 void *src0,
60 int32_t src0_amp,
61 void *src1,
62 int32_t src1_amp,
63 size_t size)
64{
65 uint32_t s0, s1, s2, s3;
66 save_emac_context();
67 coldfire_set_macsr(EMAC_ROUND | EMAC_SATURATE);
68
69 asm volatile (
70 "move.l (%1)+, %5 \n"
71 "1: \n"
72 "movea.w %5, %4 \n"
73 "asr.l %10, %5 \n"
74 "mac.l %4, %8, %%acc0 \n"
75 "mac.l %5, %8, (%2)+, %5, %%acc1 \n"
76 "movea.w %5, %4 \n"
77 "asr.l %10, %5 \n"
78 "mac.l %4, %9, %%acc0 \n"
79 "mac.l %5, %9, (%1)+, %5, %%acc1 \n"
80 "movclr.l %%acc0, %6 \n"
81 "movclr.l %%acc1, %7 \n"
82 "swap.w %6 \n"
83 "move.w %6, %7 \n"
84 "move.l %7, (%0)+ \n"
85 "subq.l #4, %3 \n"
86 "bhi.b 1b \n"
87 : "+a"(out), "+a"(src0), "+a"(src1), "+d"(size),
88 "=&a"(s0), "=&d"(s1), "=&d"(s2), "=&d"(s3)
89 : "r"(src0_amp), "r"(src1_amp), "d"(16)
90 );
91
92 restore_emac_context();
93}
94
95/* Write channel's samples and apply gain factor */
96static FORCE_INLINE void write_samples(void *out,
97 void *src,
98 int32_t amp,
99 size_t size)
100{
101 if (LIKELY(amp == MIX_AMP_UNITY))
102 {
103 /* Channel is unity amplitude */
104 memcpy(out, src, size);
105 }
106 else
107 {
108 /* Channel needs amplitude cut */
109 uint32_t s0, s1, s2, s3;
110 save_emac_context();
111 coldfire_set_macsr(EMAC_ROUND | EMAC_SATURATE);
112
113 asm volatile (
114 "move.l (%1)+, %4 \n"
115 "1: \n"
116 "movea.w %4, %3 \n"
117 "asr.l %8, %4 \n"
118 "mac.l %3, %7, %%acc0 \n"
119 "mac.l %4, %7, (%1)+, %4, %%acc1 \n"
120 "movclr.l %%acc0, %5 \n"
121 "movclr.l %%acc1, %6 \n"
122 "swap.w %5 \n"
123 "move.w %5, %6 \n"
124 "move.l %6, (%0)+ \n"
125 "subq.l #4, %2 \n"
126 "bhi.b 1b \n"
127 : "+a"(out), "+a"(src), "+d"(size),
128 "=&a"(s0), "=&d"(s1), "=&d"(s2), "=&d"(s3)
129 : "r"(amp), "d"(16)
130 );
131
132 restore_emac_context();
133 }
134}