diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/SOURCES | 5 | ||||
-rw-r--r-- | firmware/export/mp3_playback.h | 40 | ||||
-rw-r--r-- | firmware/export/sound.h | 61 | ||||
-rw-r--r-- | firmware/mp3_playback.c | 642 | ||||
-rw-r--r-- | firmware/mpeg.c | 3 | ||||
-rw-r--r-- | firmware/sound.c | 634 |
6 files changed, 720 insertions, 665 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES index 870026f835..8279f812d1 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES | |||
@@ -111,7 +111,10 @@ bitswap.S | |||
111 | descramble.S | 111 | descramble.S |
112 | #endif | 112 | #endif |
113 | drivers/lcd.S | 113 | drivers/lcd.S |
114 | #if defined(IRIVER_H100) && !defined(SIMULATOR) | 114 | #ifdef IRIVER_H100 |
115 | #ifndef SIMULATOR | ||
115 | drivers/uda1380.c | 116 | drivers/uda1380.c |
116 | pcm_playback.c | 117 | pcm_playback.c |
117 | #endif | 118 | #endif |
119 | #endif | ||
120 | sound.c | ||
diff --git a/firmware/export/mp3_playback.h b/firmware/export/mp3_playback.h index aced6ddc94..4da1ffce6d 100644 --- a/firmware/export/mp3_playback.h +++ b/firmware/export/mp3_playback.h | |||
@@ -30,19 +30,6 @@ void mp3_init(int volume, int bass, int treble, int balance, int loudness, | |||
30 | int mdb_strength, int mdb_harmonics, | 30 | int mdb_strength, int mdb_harmonics, |
31 | int mdb_center, int mdb_shape, bool mdb_enable, | 31 | int mdb_center, int mdb_shape, bool mdb_enable, |
32 | bool superbass); | 32 | bool superbass); |
33 | void mpeg_sound_set(int setting, int value); | ||
34 | int mpeg_sound_min(int setting); | ||
35 | int mpeg_sound_max(int setting); | ||
36 | int mpeg_sound_default(int setting); | ||
37 | void mpeg_sound_channel_config(int configuration); | ||
38 | int mpeg_val2phys(int setting, int value); | ||
39 | const char *mpeg_sound_unit(int setting); | ||
40 | int mpeg_sound_numdecimals(int setting); | ||
41 | int mpeg_sound_steps(int setting); | ||
42 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) || defined(SIMULATOR) | ||
43 | void mpeg_set_pitch(int percent); | ||
44 | #endif | ||
45 | |||
46 | 33 | ||
47 | /* exported just for mpeg.c, to keep the recording there */ | 34 | /* exported just for mpeg.c, to keep the recording there */ |
48 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | 35 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) |
@@ -62,31 +49,4 @@ bool mp3_is_playing(void); | |||
62 | unsigned char* mp3_get_pos(void); | 49 | unsigned char* mp3_get_pos(void); |
63 | void mp3_shutdown(void); | 50 | void mp3_shutdown(void); |
64 | 51 | ||
65 | |||
66 | #define SOUND_VOLUME 0 | ||
67 | #define SOUND_BASS 1 | ||
68 | #define SOUND_TREBLE 2 | ||
69 | #define SOUND_BALANCE 3 | ||
70 | #define SOUND_LOUDNESS 4 | ||
71 | #define SOUND_AVC 5 | ||
72 | #define SOUND_CHANNELS 6 | ||
73 | #define SOUND_STEREO_WIDTH 7 | ||
74 | #define SOUND_LEFT_GAIN 8 | ||
75 | #define SOUND_RIGHT_GAIN 9 | ||
76 | #define SOUND_MIC_GAIN 10 | ||
77 | #define SOUND_MDB_STRENGTH 11 | ||
78 | #define SOUND_MDB_HARMONICS 12 | ||
79 | #define SOUND_MDB_CENTER 13 | ||
80 | #define SOUND_MDB_SHAPE 14 | ||
81 | #define SOUND_MDB_ENABLE 15 | ||
82 | #define SOUND_SUPERBASS 16 | ||
83 | #define SOUND_NUMSETTINGS 17 | ||
84 | |||
85 | #define MPEG_SOUND_STEREO 0 | ||
86 | #define MPEG_SOUND_MONO 1 | ||
87 | #define MPEG_SOUND_CUSTOM 2 | ||
88 | #define MPEG_SOUND_MONO_LEFT 3 | ||
89 | #define MPEG_SOUND_MONO_RIGHT 4 | ||
90 | #define MPEG_SOUND_KARAOKE 5 | ||
91 | |||
92 | #endif /* #ifndef _MP3_PLAYBACK_H_ */ | 52 | #endif /* #ifndef _MP3_PLAYBACK_H_ */ |
diff --git a/firmware/export/sound.h b/firmware/export/sound.h new file mode 100644 index 0000000000..2fa00d88a9 --- /dev/null +++ b/firmware/export/sound.h | |||
@@ -0,0 +1,61 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2005 by Linus Nielsen Feltzing | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #ifndef SOUND_H | ||
20 | #define SOUND_H | ||
21 | |||
22 | #define SOUND_VOLUME 0 | ||
23 | #define SOUND_BASS 1 | ||
24 | #define SOUND_TREBLE 2 | ||
25 | #define SOUND_BALANCE 3 | ||
26 | #define SOUND_LOUDNESS 4 | ||
27 | #define SOUND_AVC 5 | ||
28 | #define SOUND_CHANNELS 6 | ||
29 | #define SOUND_STEREO_WIDTH 7 | ||
30 | #define SOUND_LEFT_GAIN 8 | ||
31 | #define SOUND_RIGHT_GAIN 9 | ||
32 | #define SOUND_MIC_GAIN 10 | ||
33 | #define SOUND_MDB_STRENGTH 11 | ||
34 | #define SOUND_MDB_HARMONICS 12 | ||
35 | #define SOUND_MDB_CENTER 13 | ||
36 | #define SOUND_MDB_SHAPE 14 | ||
37 | #define SOUND_MDB_ENABLE 15 | ||
38 | #define SOUND_SUPERBASS 16 | ||
39 | #define SOUND_NUMSETTINGS 17 | ||
40 | |||
41 | #define SOUND_CHAN_STEREO 0 | ||
42 | #define SOUND_CHAN_MONO 1 | ||
43 | #define SOUND_CHAN_CUSTOM 2 | ||
44 | #define SOUND_CHAN_MONO_LEFT 3 | ||
45 | #define SOUND_CHAN_MONO_RIGHT 4 | ||
46 | #define SOUND_CHAN_KARAOKE 5 | ||
47 | |||
48 | void sound_set(int setting, int value); | ||
49 | int sound_min(int setting); | ||
50 | int sound_max(int setting); | ||
51 | int sound_default(int setting); | ||
52 | void sound_channel_config(int configuration); | ||
53 | int sound_val2phys(int setting, int value); | ||
54 | const char *sound_unit(int setting); | ||
55 | int sound_numdecimals(int setting); | ||
56 | int sound_steps(int setting); | ||
57 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) || defined(SIMULATOR) | ||
58 | void sound_set_pitch(int percent); | ||
59 | #endif | ||
60 | |||
61 | #endif | ||
diff --git a/firmware/mp3_playback.c b/firmware/mp3_playback.c index 16fe544c7a..14e0aa796e 100644 --- a/firmware/mp3_playback.c +++ b/firmware/mp3_playback.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <kernel.h> | 26 | #include <kernel.h> |
27 | #include "mpeg.h" /* ToDo: remove crosslinks */ | 27 | #include "mpeg.h" /* ToDo: remove crosslinks */ |
28 | #include "mp3_playback.h" | 28 | #include "mp3_playback.h" |
29 | #include "sound.h" | ||
29 | #ifndef SIMULATOR | 30 | #ifndef SIMULATOR |
30 | #include "i2c.h" | 31 | #include "i2c.h" |
31 | #include "mas.h" | 32 | #include "mas.h" |
@@ -63,183 +64,12 @@ static long cumulative_ticks; | |||
63 | static void (*callback_for_more)(unsigned char**, int*); | 64 | static void (*callback_for_more)(unsigned char**, int*); |
64 | #endif /* #ifndef SIMULATOR */ | 65 | #endif /* #ifndef SIMULATOR */ |
65 | 66 | ||
66 | static const char* const units[] = | ||
67 | { | ||
68 | "%", /* Volume */ | ||
69 | "dB", /* Bass */ | ||
70 | "dB", /* Treble */ | ||
71 | "%", /* Balance */ | ||
72 | "dB", /* Loudness */ | ||
73 | "", /* AVC */ | ||
74 | "", /* Channels */ | ||
75 | "%", /* Stereo width */ | ||
76 | "dB", /* Left gain */ | ||
77 | "dB", /* Right gain */ | ||
78 | "dB", /* Mic gain */ | ||
79 | "dB", /* MDB Strength */ | ||
80 | "%", /* MDB Harmonics */ | ||
81 | "Hz", /* MDB Center */ | ||
82 | "Hz", /* MDB Shape */ | ||
83 | "", /* MDB Enable */ | ||
84 | "", /* Super bass */ | ||
85 | }; | ||
86 | |||
87 | static const int numdecimals[] = | ||
88 | { | ||
89 | 0, /* Volume */ | ||
90 | 0, /* Bass */ | ||
91 | 0, /* Treble */ | ||
92 | 0, /* Balance */ | ||
93 | 0, /* Loudness */ | ||
94 | 0, /* AVC */ | ||
95 | 0, /* Channels */ | ||
96 | 0, /* Stereo width */ | ||
97 | 1, /* Left gain */ | ||
98 | 1, /* Right gain */ | ||
99 | 1, /* Mic gain */ | ||
100 | 0, /* MDB Strength */ | ||
101 | 0, /* MDB Harmonics */ | ||
102 | 0, /* MDB Center */ | ||
103 | 0, /* MDB Shape */ | ||
104 | 0, /* MDB Enable */ | ||
105 | 0, /* Super bass */ | ||
106 | }; | ||
107 | |||
108 | static const int steps[] = | ||
109 | { | ||
110 | 1, /* Volume */ | ||
111 | 1, /* Bass */ | ||
112 | 1, /* Treble */ | ||
113 | 1, /* Balance */ | ||
114 | 1, /* Loudness */ | ||
115 | 1, /* AVC */ | ||
116 | 1, /* Channels */ | ||
117 | 1, /* Stereo width */ | ||
118 | 1, /* Left gain */ | ||
119 | 1, /* Right gain */ | ||
120 | 1, /* Mic gain */ | ||
121 | 1, /* MDB Strength */ | ||
122 | 1, /* MDB Harmonics */ | ||
123 | 10, /* MDB Center */ | ||
124 | 10, /* MDB Shape */ | ||
125 | 1, /* MDB Enable */ | ||
126 | 1, /* Super bass */ | ||
127 | }; | ||
128 | |||
129 | static const int minval[] = | ||
130 | { | ||
131 | 0, /* Volume */ | ||
132 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | ||
133 | -12, /* Bass */ | ||
134 | -12, /* Treble */ | ||
135 | #else | ||
136 | -15, /* Bass */ | ||
137 | -15, /* Treble */ | ||
138 | #endif | ||
139 | -100, /* Balance */ | ||
140 | 0, /* Loudness */ | ||
141 | -1, /* AVC */ | ||
142 | 0, /* Channels */ | ||
143 | 0, /* Stereo width */ | ||
144 | 0, /* Left gain */ | ||
145 | 0, /* Right gain */ | ||
146 | 0, /* Mic gain */ | ||
147 | 0, /* MDB Strength */ | ||
148 | 0, /* MDB Harmonics */ | ||
149 | 20, /* MDB Center */ | ||
150 | 50, /* MDB Shape */ | ||
151 | 0, /* MDB Enable */ | ||
152 | 0, /* Super bass */ | ||
153 | }; | ||
154 | |||
155 | static const int maxval[] = | ||
156 | { | ||
157 | 100, /* Volume */ | ||
158 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | ||
159 | 12, /* Bass */ | ||
160 | 12, /* Treble */ | ||
161 | #else | ||
162 | 15, /* Bass */ | ||
163 | 15, /* Treble */ | ||
164 | #endif | ||
165 | 100, /* Balance */ | ||
166 | 17, /* Loudness */ | ||
167 | 4, /* AVC */ | ||
168 | 5, /* Channels */ | ||
169 | 255, /* Stereo width */ | ||
170 | 15, /* Left gain */ | ||
171 | 15, /* Right gain */ | ||
172 | 15, /* Mic gain */ | ||
173 | 127, /* MDB Strength */ | ||
174 | 100, /* MDB Harmonics */ | ||
175 | 300, /* MDB Center */ | ||
176 | 300, /* MDB Shape */ | ||
177 | 1, /* MDB Enable */ | ||
178 | 1, /* Super bass */ | ||
179 | }; | ||
180 | |||
181 | static const int defaultval[] = | ||
182 | { | ||
183 | 70, /* Volume */ | ||
184 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | ||
185 | 6, /* Bass */ | ||
186 | 6, /* Treble */ | ||
187 | #else | ||
188 | 7, /* Bass */ | ||
189 | 7, /* Treble */ | ||
190 | #endif | ||
191 | 0, /* Balance */ | ||
192 | 0, /* Loudness */ | ||
193 | 0, /* AVC */ | ||
194 | 0, /* Channels */ | ||
195 | 100, /* Stereo width */ | ||
196 | 8, /* Left gain */ | ||
197 | 8, /* Right gain */ | ||
198 | 2, /* Mic gain */ | ||
199 | 50, /* MDB Strength */ | ||
200 | 48, /* MDB Harmonics */ | ||
201 | 60, /* MDB Center */ | ||
202 | 90, /* MDB Shape */ | ||
203 | 0, /* MDB Enable */ | ||
204 | 0, /* Super bass */ | ||
205 | }; | ||
206 | |||
207 | const char *mpeg_sound_unit(int setting) | ||
208 | { | ||
209 | return units[setting]; | ||
210 | } | ||
211 | |||
212 | int mpeg_sound_numdecimals(int setting) | ||
213 | { | ||
214 | return numdecimals[setting]; | ||
215 | } | ||
216 | |||
217 | int mpeg_sound_steps(int setting) | ||
218 | { | ||
219 | return steps[setting]; | ||
220 | } | ||
221 | |||
222 | int mpeg_sound_min(int setting) | ||
223 | { | ||
224 | return minval[setting]; | ||
225 | } | ||
226 | |||
227 | int mpeg_sound_max(int setting) | ||
228 | { | ||
229 | return maxval[setting]; | ||
230 | } | ||
231 | |||
232 | int mpeg_sound_default(int setting) | ||
233 | { | ||
234 | return defaultval[setting]; | ||
235 | } | ||
236 | |||
237 | /* list of tracks in memory */ | 67 | /* list of tracks in memory */ |
238 | #define MAX_ID3_TAGS (1<<4) /* Must be power of 2 */ | 68 | #define MAX_ID3_TAGS (1<<4) /* Must be power of 2 */ |
239 | #define MAX_ID3_TAGS_MASK (MAX_ID3_TAGS - 1) | 69 | #define MAX_ID3_TAGS_MASK (MAX_ID3_TAGS - 1) |
240 | 70 | ||
241 | #ifndef SIMULATOR | 71 | #ifndef SIMULATOR |
242 | static bool mpeg_is_initialized = false; | 72 | bool audio_is_initialized = false; |
243 | #endif | 73 | #endif |
244 | 74 | ||
245 | #if CONFIG_HWCODEC != MASNONE | 75 | #if CONFIG_HWCODEC != MASNONE |
@@ -249,99 +79,6 @@ static bool mpeg_is_initialized = false; | |||
249 | 79 | ||
250 | unsigned long mas_version_code; | 80 | unsigned long mas_version_code; |
251 | 81 | ||
252 | #if CONFIG_HWCODEC == MAS3507D | ||
253 | |||
254 | static const unsigned int bass_table[] = | ||
255 | { | ||
256 | 0x9e400, /* -15dB */ | ||
257 | 0xa2800, /* -14dB */ | ||
258 | 0xa7400, /* -13dB */ | ||
259 | 0xac400, /* -12dB */ | ||
260 | 0xb1800, /* -11dB */ | ||
261 | 0xb7400, /* -10dB */ | ||
262 | 0xbd400, /* -9dB */ | ||
263 | 0xc3c00, /* -8dB */ | ||
264 | 0xca400, /* -7dB */ | ||
265 | 0xd1800, /* -6dB */ | ||
266 | 0xd8c00, /* -5dB */ | ||
267 | 0xe0400, /* -4dB */ | ||
268 | 0xe8000, /* -3dB */ | ||
269 | 0xefc00, /* -2dB */ | ||
270 | 0xf7c00, /* -1dB */ | ||
271 | 0, | ||
272 | 0x800, /* 1dB */ | ||
273 | 0x10000, /* 2dB */ | ||
274 | 0x17c00, /* 3dB */ | ||
275 | 0x1f800, /* 4dB */ | ||
276 | 0x27000, /* 5dB */ | ||
277 | 0x2e400, /* 6dB */ | ||
278 | 0x35800, /* 7dB */ | ||
279 | 0x3c000, /* 8dB */ | ||
280 | 0x42800, /* 9dB */ | ||
281 | 0x48800, /* 10dB */ | ||
282 | 0x4e400, /* 11dB */ | ||
283 | 0x53800, /* 12dB */ | ||
284 | 0x58800, /* 13dB */ | ||
285 | 0x5d400, /* 14dB */ | ||
286 | 0x61800 /* 15dB */ | ||
287 | }; | ||
288 | |||
289 | static const unsigned int treble_table[] = | ||
290 | { | ||
291 | 0xb2c00, /* -15dB */ | ||
292 | 0xbb400, /* -14dB */ | ||
293 | 0xc1800, /* -13dB */ | ||
294 | 0xc6c00, /* -12dB */ | ||
295 | 0xcbc00, /* -11dB */ | ||
296 | 0xd0400, /* -10dB */ | ||
297 | 0xd5000, /* -9dB */ | ||
298 | 0xd9800, /* -8dB */ | ||
299 | 0xde000, /* -7dB */ | ||
300 | 0xe2800, /* -6dB */ | ||
301 | 0xe7e00, /* -5dB */ | ||
302 | 0xec000, /* -4dB */ | ||
303 | 0xf0c00, /* -3dB */ | ||
304 | 0xf5c00, /* -2dB */ | ||
305 | 0xfac00, /* -1dB */ | ||
306 | 0, | ||
307 | 0x5400, /* 1dB */ | ||
308 | 0xac00, /* 2dB */ | ||
309 | 0x10400, /* 3dB */ | ||
310 | 0x16000, /* 4dB */ | ||
311 | 0x1c000, /* 5dB */ | ||
312 | 0x22400, /* 6dB */ | ||
313 | 0x28400, /* 7dB */ | ||
314 | 0x2ec00, /* 8dB */ | ||
315 | 0x35400, /* 9dB */ | ||
316 | 0x3c000, /* 10dB */ | ||
317 | 0x42c00, /* 11dB */ | ||
318 | 0x49c00, /* 12dB */ | ||
319 | 0x51800, /* 13dB */ | ||
320 | 0x58400, /* 14dB */ | ||
321 | 0x5f800 /* 15dB */ | ||
322 | }; | ||
323 | |||
324 | static const unsigned int prescale_table[] = | ||
325 | { | ||
326 | 0x80000, /* 0db */ | ||
327 | 0x8e000, /* 1dB */ | ||
328 | 0x9a400, /* 2dB */ | ||
329 | 0xa5800, /* 3dB */ | ||
330 | 0xaf400, /* 4dB */ | ||
331 | 0xb8000, /* 5dB */ | ||
332 | 0xbfc00, /* 6dB */ | ||
333 | 0xc6c00, /* 7dB */ | ||
334 | 0xcd000, /* 8dB */ | ||
335 | 0xd25c0, /* 9dB */ | ||
336 | 0xd7800, /* 10dB */ | ||
337 | 0xdc000, /* 11dB */ | ||
338 | 0xdfc00, /* 12dB */ | ||
339 | 0xe3400, /* 13dB */ | ||
340 | 0xe6800, /* 14dB */ | ||
341 | 0xe9400 /* 15dB */ | ||
342 | }; | ||
343 | #endif | ||
344 | |||
345 | bool dma_on; /* The DMA is active */ | 82 | bool dma_on; /* The DMA is active */ |
346 | 83 | ||
347 | #if CONFIG_HWCODEC == MAS3507D | 84 | #if CONFIG_HWCODEC == MAS3507D |
@@ -589,329 +326,6 @@ static void init_playback(void) | |||
589 | } | 326 | } |
590 | #endif /* #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) */ | 327 | #endif /* #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) */ |
591 | 328 | ||
592 | #ifndef SIMULATOR | ||
593 | #if CONFIG_HWCODEC == MAS3507D | ||
594 | /* all values in tenth of dB */ | ||
595 | int current_volume = 0; /* -780..+180 */ | ||
596 | int current_balance = 0; /* -960..+960 */ | ||
597 | int current_treble = 0; /* -150..+150 */ | ||
598 | int current_bass = 0; /* -150..+150 */ | ||
599 | |||
600 | /* convert tenth of dB volume to register value */ | ||
601 | static int tenthdb2reg(int db) { | ||
602 | if (db < -540) | ||
603 | return (db + 780) / 30; | ||
604 | else | ||
605 | return (db + 660) / 15; | ||
606 | } | ||
607 | |||
608 | void set_prescaled_volume(void) | ||
609 | { | ||
610 | int prescale; | ||
611 | int l, r; | ||
612 | |||
613 | prescale = MAX(current_bass, current_treble); | ||
614 | if (prescale < 0) | ||
615 | prescale = 0; /* no need to prescale if we don't boost | ||
616 | bass or treble */ | ||
617 | |||
618 | mas_writereg(MAS_REG_KPRESCALE, prescale_table[prescale/10]); | ||
619 | |||
620 | /* gain up the analog volume to compensate the prescale reduction gain, | ||
621 | * but limit to +18 dB (the maximum the DAC can do */ | ||
622 | if (current_volume + prescale > 180) | ||
623 | prescale = 180 - current_volume; | ||
624 | l = r = current_volume + prescale; | ||
625 | |||
626 | if (current_balance > 0) | ||
627 | { | ||
628 | l -= current_balance; | ||
629 | if (l < -780) | ||
630 | l = -780; | ||
631 | } | ||
632 | if (current_balance < 0) | ||
633 | { | ||
634 | r += current_balance; | ||
635 | if (r < -780) | ||
636 | r = -780; | ||
637 | } | ||
638 | |||
639 | dac_volume(tenthdb2reg(l), tenthdb2reg(r), false); | ||
640 | } | ||
641 | #endif /* MAS3507D */ | ||
642 | #endif /* !SIMULATOR */ | ||
643 | |||
644 | int channel_configuration = MPEG_SOUND_STEREO; | ||
645 | int stereo_width = 100; | ||
646 | |||
647 | #ifndef SIMULATOR | ||
648 | static void set_channel_config(void) | ||
649 | { | ||
650 | /* default values: stereo */ | ||
651 | unsigned long val_ll = 0x80000; | ||
652 | unsigned long val_lr = 0; | ||
653 | unsigned long val_rl = 0; | ||
654 | unsigned long val_rr = 0x80000; | ||
655 | |||
656 | switch(channel_configuration) | ||
657 | { | ||
658 | /* case MPEG_SOUND_STEREO unnecessary */ | ||
659 | |||
660 | case MPEG_SOUND_MONO: | ||
661 | val_ll = 0xc0000; | ||
662 | val_lr = 0xc0000; | ||
663 | val_rl = 0xc0000; | ||
664 | val_rr = 0xc0000; | ||
665 | break; | ||
666 | |||
667 | case MPEG_SOUND_CUSTOM: | ||
668 | { | ||
669 | /* fixed point variables (matching MAS internal format) | ||
670 | integer part: upper 13 bits (inlcuding sign) | ||
671 | fractional part: lower 19 bits */ | ||
672 | long fp_width, fp_straight, fp_cross; | ||
673 | |||
674 | fp_width = (stereo_width << 19) / 100; | ||
675 | if (stereo_width <= 100) | ||
676 | { | ||
677 | fp_straight = - ((1<<19) + fp_width) / 2; | ||
678 | fp_cross = fp_straight + fp_width; | ||
679 | } | ||
680 | else | ||
681 | { | ||
682 | fp_straight = - (1<<19); | ||
683 | fp_cross = ((2 * fp_width / (((1<<19) + fp_width) >> 10)) | ||
684 | << 9) - (1<<19); | ||
685 | } | ||
686 | val_ll = val_rr = fp_straight & 0xFFFFF; | ||
687 | val_lr = val_rl = fp_cross & 0xFFFFF; | ||
688 | } | ||
689 | break; | ||
690 | |||
691 | case MPEG_SOUND_MONO_LEFT: | ||
692 | val_ll = 0x80000; | ||
693 | val_lr = 0x80000; | ||
694 | val_rl = 0; | ||
695 | val_rr = 0; | ||
696 | break; | ||
697 | |||
698 | case MPEG_SOUND_MONO_RIGHT: | ||
699 | val_ll = 0; | ||
700 | val_lr = 0; | ||
701 | val_rl = 0x80000; | ||
702 | val_rr = 0x80000; | ||
703 | break; | ||
704 | |||
705 | case MPEG_SOUND_KARAOKE: | ||
706 | val_ll = 0x80001; | ||
707 | val_lr = 0x7ffff; | ||
708 | val_rl = 0x7ffff; | ||
709 | val_rr = 0x80001; | ||
710 | break; | ||
711 | } | ||
712 | |||
713 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | ||
714 | mas_writemem(MAS_BANK_D0, MAS_D0_OUT_LL, &val_ll, 1); /* LL */ | ||
715 | mas_writemem(MAS_BANK_D0, MAS_D0_OUT_LR, &val_lr, 1); /* LR */ | ||
716 | mas_writemem(MAS_BANK_D0, MAS_D0_OUT_RL, &val_rl, 1); /* RL */ | ||
717 | mas_writemem(MAS_BANK_D0, MAS_D0_OUT_RR, &val_rr, 1); /* RR */ | ||
718 | #elif CONFIG_HWCODEC == MAS3507D | ||
719 | mas_writemem(MAS_BANK_D1, 0x7f8, &val_ll, 1); /* LL */ | ||
720 | mas_writemem(MAS_BANK_D1, 0x7f9, &val_lr, 1); /* LR */ | ||
721 | mas_writemem(MAS_BANK_D1, 0x7fa, &val_rl, 1); /* RL */ | ||
722 | mas_writemem(MAS_BANK_D1, 0x7fb, &val_rr, 1); /* RR */ | ||
723 | #endif | ||
724 | } | ||
725 | #endif /* !SIMULATOR */ | ||
726 | |||
727 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | ||
728 | unsigned long mdb_shape_shadow = 0; | ||
729 | unsigned long loudness_shadow = 0; | ||
730 | #endif | ||
731 | |||
732 | void mpeg_sound_set(int setting, int value) | ||
733 | { | ||
734 | #ifdef SIMULATOR | ||
735 | setting = value; | ||
736 | #else | ||
737 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | ||
738 | int tmp; | ||
739 | #endif | ||
740 | |||
741 | if(!mpeg_is_initialized) | ||
742 | return; | ||
743 | |||
744 | switch(setting) | ||
745 | { | ||
746 | case SOUND_VOLUME: | ||
747 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | ||
748 | tmp = 0x7f00 * value / 100; | ||
749 | mas_codec_writereg(0x10, tmp & 0xff00); | ||
750 | #else | ||
751 | current_volume = -780 + (value * 960 / 100); /* tenth of dB */ | ||
752 | set_prescaled_volume(); | ||
753 | #endif | ||
754 | break; | ||
755 | |||
756 | case SOUND_BALANCE: | ||
757 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | ||
758 | tmp = ((value * 127 / 100) & 0xff) << 8; | ||
759 | mas_codec_writereg(0x11, tmp & 0xff00); | ||
760 | #else | ||
761 | current_balance = value * 960 / 100; /* tenth of dB */ | ||
762 | set_prescaled_volume(); | ||
763 | #endif | ||
764 | break; | ||
765 | |||
766 | case SOUND_BASS: | ||
767 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | ||
768 | tmp = ((value * 8) & 0xff) << 8; | ||
769 | mas_codec_writereg(0x14, tmp & 0xff00); | ||
770 | #else | ||
771 | mas_writereg(MAS_REG_KBASS, bass_table[value+15]); | ||
772 | current_bass = value * 10; | ||
773 | set_prescaled_volume(); | ||
774 | #endif | ||
775 | break; | ||
776 | |||
777 | case SOUND_TREBLE: | ||
778 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | ||
779 | tmp = ((value * 8) & 0xff) << 8; | ||
780 | mas_codec_writereg(0x15, tmp & 0xff00); | ||
781 | #else | ||
782 | mas_writereg(MAS_REG_KTREBLE, treble_table[value+15]); | ||
783 | current_treble = value * 10; | ||
784 | set_prescaled_volume(); | ||
785 | #endif | ||
786 | break; | ||
787 | |||
788 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | ||
789 | case SOUND_LOUDNESS: | ||
790 | loudness_shadow = (loudness_shadow & 0x04) | | ||
791 | (MAX(MIN(value * 4, 0x44), 0) << 8); | ||
792 | mas_codec_writereg(MAS_REG_KLOUDNESS, loudness_shadow); | ||
793 | break; | ||
794 | |||
795 | case SOUND_AVC: | ||
796 | switch (value) { | ||
797 | case 1: /* 20ms */ | ||
798 | tmp = (0x1 << 8) | (0x8 << 12); | ||
799 | break; | ||
800 | case 2: /* 2s */ | ||
801 | tmp = (0x2 << 8) | (0x8 << 12); | ||
802 | break; | ||
803 | case 3: /* 4s */ | ||
804 | tmp = (0x4 << 8) | (0x8 << 12); | ||
805 | break; | ||
806 | case 4: /* 8s */ | ||
807 | tmp = (0x8 << 8) | (0x8 << 12); | ||
808 | break; | ||
809 | case -1: /* turn off and then turn on again to decay quickly */ | ||
810 | tmp = mas_codec_readreg(MAS_REG_KAVC); | ||
811 | mas_codec_writereg(MAS_REG_KAVC, 0); | ||
812 | break; | ||
813 | default: /* off */ | ||
814 | tmp = 0; | ||
815 | break; | ||
816 | } | ||
817 | mas_codec_writereg(MAS_REG_KAVC, tmp); | ||
818 | break; | ||
819 | |||
820 | case SOUND_MDB_STRENGTH: | ||
821 | mas_codec_writereg(MAS_REG_KMDB_STR, (value & 0x7f) << 8); | ||
822 | break; | ||
823 | |||
824 | case SOUND_MDB_HARMONICS: | ||
825 | tmp = value * 127 / 100; | ||
826 | mas_codec_writereg(MAS_REG_KMDB_HAR, (tmp & 0x7f) << 8); | ||
827 | break; | ||
828 | |||
829 | case SOUND_MDB_CENTER: | ||
830 | mas_codec_writereg(MAS_REG_KMDB_FC, (value/10) << 8); | ||
831 | break; | ||
832 | |||
833 | case SOUND_MDB_SHAPE: | ||
834 | mdb_shape_shadow = (mdb_shape_shadow & 0x02) | ((value/10) << 8); | ||
835 | mas_codec_writereg(MAS_REG_KMDB_SWITCH, mdb_shape_shadow); | ||
836 | break; | ||
837 | |||
838 | case SOUND_MDB_ENABLE: | ||
839 | mdb_shape_shadow = (mdb_shape_shadow & ~0x02) | (value?2:0); | ||
840 | mas_codec_writereg(MAS_REG_KMDB_SWITCH, mdb_shape_shadow); | ||
841 | break; | ||
842 | |||
843 | case SOUND_SUPERBASS: | ||
844 | loudness_shadow = (loudness_shadow & ~0x04) | | ||
845 | (value?4:0); | ||
846 | mas_codec_writereg(MAS_REG_KLOUDNESS, loudness_shadow); | ||
847 | break; | ||
848 | #endif | ||
849 | case SOUND_CHANNELS: | ||
850 | channel_configuration = value; | ||
851 | set_channel_config(); | ||
852 | break; | ||
853 | |||
854 | case SOUND_STEREO_WIDTH: | ||
855 | stereo_width = value; | ||
856 | if (channel_configuration == MPEG_SOUND_CUSTOM) | ||
857 | set_channel_config(); | ||
858 | break; | ||
859 | } | ||
860 | #endif /* SIMULATOR */ | ||
861 | } | ||
862 | |||
863 | int mpeg_val2phys(int setting, int value) | ||
864 | { | ||
865 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | ||
866 | int result = 0; | ||
867 | |||
868 | switch(setting) | ||
869 | { | ||
870 | case SOUND_LEFT_GAIN: | ||
871 | case SOUND_RIGHT_GAIN: | ||
872 | result = (value - 2) * 15; | ||
873 | break; | ||
874 | |||
875 | case SOUND_MIC_GAIN: | ||
876 | result = value * 15 + 210; | ||
877 | break; | ||
878 | |||
879 | default: | ||
880 | result = value; | ||
881 | break; | ||
882 | } | ||
883 | return result; | ||
884 | #else | ||
885 | (void)setting; | ||
886 | return value; | ||
887 | #endif | ||
888 | } | ||
889 | |||
890 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | ||
891 | /* This function works by telling the decoder that we have another | ||
892 | crystal frequency than we actually have. It will adjust its internal | ||
893 | parameters and the result is that the audio is played at another pitch. | ||
894 | |||
895 | The pitch value is in tenths of percent. | ||
896 | */ | ||
897 | void mpeg_set_pitch(int pitch) | ||
898 | { | ||
899 | unsigned long val; | ||
900 | |||
901 | /* invert pitch value */ | ||
902 | pitch = 1000000/pitch; | ||
903 | |||
904 | /* Calculate the new (bogus) frequency */ | ||
905 | val = 18432*pitch/1000; | ||
906 | |||
907 | mas_writemem(MAS_BANK_D0, MAS_D0_OFREQ_CONTROL, &val, 1); | ||
908 | |||
909 | /* We must tell the MAS that the frequency has changed. | ||
910 | This will unfortunately cause a short silence. */ | ||
911 | mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1); | ||
912 | } | ||
913 | #endif | ||
914 | |||
915 | void mp3_init(int volume, int bass, int treble, int balance, int loudness, | 329 | void mp3_init(int volume, int bass, int treble, int balance, int loudness, |
916 | int avc, int channel_config, int stereo_width, | 330 | int avc, int channel_config, int stereo_width, |
917 | int mdb_strength, int mdb_harmonics, | 331 | int mdb_strength, int mdb_harmonics, |
@@ -1035,25 +449,25 @@ void mp3_init(int volume, int bass, int treble, int balance, int loudness, | |||
1035 | PACR1 = (PACR1 & 0x3fff) | 0x4000; /* PA15 is IRQ3 */ | 449 | PACR1 = (PACR1 & 0x3fff) | 0x4000; /* PA15 is IRQ3 */ |
1036 | #endif | 450 | #endif |
1037 | 451 | ||
1038 | /* Must be done before calling mpeg_sound_set() */ | 452 | /* Must be done before calling sound_set() */ |
1039 | mpeg_is_initialized = true; | 453 | audio_is_initialized = true; |
1040 | 454 | ||
1041 | mpeg_sound_set(SOUND_BASS, bass); | 455 | sound_set(SOUND_BASS, bass); |
1042 | mpeg_sound_set(SOUND_TREBLE, treble); | 456 | sound_set(SOUND_TREBLE, treble); |
1043 | mpeg_sound_set(SOUND_BALANCE, balance); | 457 | sound_set(SOUND_BALANCE, balance); |
1044 | mpeg_sound_set(SOUND_VOLUME, volume); | 458 | sound_set(SOUND_VOLUME, volume); |
1045 | mpeg_sound_set(SOUND_CHANNELS, channel_config); | 459 | sound_set(SOUND_CHANNELS, channel_config); |
1046 | mpeg_sound_set(SOUND_STEREO_WIDTH, stereo_width); | 460 | sound_set(SOUND_STEREO_WIDTH, stereo_width); |
1047 | 461 | ||
1048 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | 462 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) |
1049 | mpeg_sound_set(SOUND_LOUDNESS, loudness); | 463 | sound_set(SOUND_LOUDNESS, loudness); |
1050 | mpeg_sound_set(SOUND_AVC, avc); | 464 | sound_set(SOUND_AVC, avc); |
1051 | mpeg_sound_set(SOUND_MDB_STRENGTH, mdb_strength); | 465 | sound_set(SOUND_MDB_STRENGTH, mdb_strength); |
1052 | mpeg_sound_set(SOUND_MDB_HARMONICS, mdb_harmonics); | 466 | sound_set(SOUND_MDB_HARMONICS, mdb_harmonics); |
1053 | mpeg_sound_set(SOUND_MDB_CENTER, mdb_center); | 467 | sound_set(SOUND_MDB_CENTER, mdb_center); |
1054 | mpeg_sound_set(SOUND_MDB_SHAPE, mdb_shape); | 468 | sound_set(SOUND_MDB_SHAPE, mdb_shape); |
1055 | mpeg_sound_set(SOUND_MDB_ENABLE, mdb_enable); | 469 | sound_set(SOUND_MDB_ENABLE, mdb_enable); |
1056 | mpeg_sound_set(SOUND_SUPERBASS, superbass); | 470 | sound_set(SOUND_SUPERBASS, superbass); |
1057 | #endif | 471 | #endif |
1058 | #endif /* !SIMULATOR */ | 472 | #endif /* !SIMULATOR */ |
1059 | 473 | ||
@@ -1201,7 +615,7 @@ void mp3_init(int volume, int bass, int treble, int balance, int loudness, | |||
1201 | playstart_tick = 0; | 615 | playstart_tick = 0; |
1202 | cumulative_ticks = 0; | 616 | cumulative_ticks = 0; |
1203 | callback_for_more = 0; | 617 | callback_for_more = 0; |
1204 | mpeg_is_initialized = false; | 618 | audio_is_initialized = false; |
1205 | #endif | 619 | #endif |
1206 | } | 620 | } |
1207 | void mp3_shutdown(void) | 621 | void mp3_shutdown(void) |
@@ -1228,24 +642,6 @@ void mp3_play_pause(bool play) | |||
1228 | (void)play; | 642 | (void)play; |
1229 | } | 643 | } |
1230 | 644 | ||
1231 | void mpeg_sound_set(int setting, int value) | ||
1232 | { | ||
1233 | /* a dummy */ | ||
1234 | (void)setting; | ||
1235 | (void)value; | ||
1236 | } | ||
1237 | bool mp3_is_playing(void) | ||
1238 | { | ||
1239 | /* a dummy */ | ||
1240 | return false; | ||
1241 | } | ||
1242 | |||
1243 | int mpeg_val2phys(int setting, int value) | ||
1244 | { | ||
1245 | (void) setting; | ||
1246 | (void) value; | ||
1247 | return value; /* FIX dummy */ | ||
1248 | } | ||
1249 | unsigned char* mp3_get_pos(void) | 645 | unsigned char* mp3_get_pos(void) |
1250 | { | 646 | { |
1251 | /* a dummy */ | 647 | /* a dummy */ |
diff --git a/firmware/mpeg.c b/firmware/mpeg.c index 250547e24e..d8de1a37b4 100644 --- a/firmware/mpeg.c +++ b/firmware/mpeg.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "mp3data.h" | 31 | #include "mp3data.h" |
32 | #include "buffer.h" | 32 | #include "buffer.h" |
33 | #include "mp3_playback.h" | 33 | #include "mp3_playback.h" |
34 | #include "sound.h" | ||
34 | #ifndef SIMULATOR | 35 | #ifndef SIMULATOR |
35 | #include "i2c.h" | 36 | #include "i2c.h" |
36 | #include "mas.h" | 37 | #include "mas.h" |
@@ -901,7 +902,7 @@ static void track_change(void) | |||
901 | 902 | ||
902 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | 903 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) |
903 | /* Reset the AVC */ | 904 | /* Reset the AVC */ |
904 | mpeg_sound_set(SOUND_AVC, -1); | 905 | sound_set(SOUND_AVC, -1); |
905 | #endif /* #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) */ | 906 | #endif /* #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) */ |
906 | remove_current_tag(); | 907 | remove_current_tag(); |
907 | 908 | ||
diff --git a/firmware/sound.c b/firmware/sound.c new file mode 100644 index 0000000000..ab0ab1ed46 --- /dev/null +++ b/firmware/sound.c | |||
@@ -0,0 +1,634 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2005 by Linus Nielsen Feltzing | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include <stdbool.h> | ||
20 | #include "config.h" | ||
21 | #include "sound.h" | ||
22 | #ifndef SIMULATOR | ||
23 | #include "i2c.h" | ||
24 | #include "mas.h" | ||
25 | #include "dac.h" | ||
26 | #include "system.h" | ||
27 | #include "hwcompat.h" | ||
28 | #endif | ||
29 | |||
30 | #ifndef SIMULATOR | ||
31 | extern bool audio_is_initialized; | ||
32 | #endif | ||
33 | |||
34 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | ||
35 | extern unsigned long shadow_io_control_main; | ||
36 | extern unsigned shadow_codec_reg0; | ||
37 | #endif | ||
38 | |||
39 | static const char* const units[] = | ||
40 | { | ||
41 | "%", /* Volume */ | ||
42 | "dB", /* Bass */ | ||
43 | "dB", /* Treble */ | ||
44 | "%", /* Balance */ | ||
45 | "dB", /* Loudness */ | ||
46 | "", /* AVC */ | ||
47 | "", /* Channels */ | ||
48 | "%", /* Stereo width */ | ||
49 | "dB", /* Left gain */ | ||
50 | "dB", /* Right gain */ | ||
51 | "dB", /* Mic gain */ | ||
52 | "dB", /* MDB Strength */ | ||
53 | "%", /* MDB Harmonics */ | ||
54 | "Hz", /* MDB Center */ | ||
55 | "Hz", /* MDB Shape */ | ||
56 | "", /* MDB Enable */ | ||
57 | "", /* Super bass */ | ||
58 | }; | ||
59 | |||
60 | static const int numdecimals[] = | ||
61 | { | ||
62 | 0, /* Volume */ | ||
63 | 0, /* Bass */ | ||
64 | 0, /* Treble */ | ||
65 | 0, /* Balance */ | ||
66 | 0, /* Loudness */ | ||
67 | 0, /* AVC */ | ||
68 | 0, /* Channels */ | ||
69 | 0, /* Stereo width */ | ||
70 | 1, /* Left gain */ | ||
71 | 1, /* Right gain */ | ||
72 | 1, /* Mic gain */ | ||
73 | 0, /* MDB Strength */ | ||
74 | 0, /* MDB Harmonics */ | ||
75 | 0, /* MDB Center */ | ||
76 | 0, /* MDB Shape */ | ||
77 | 0, /* MDB Enable */ | ||
78 | 0, /* Super bass */ | ||
79 | }; | ||
80 | |||
81 | static const int steps[] = | ||
82 | { | ||
83 | 1, /* Volume */ | ||
84 | 1, /* Bass */ | ||
85 | 1, /* Treble */ | ||
86 | 1, /* Balance */ | ||
87 | 1, /* Loudness */ | ||
88 | 1, /* AVC */ | ||
89 | 1, /* Channels */ | ||
90 | 1, /* Stereo width */ | ||
91 | 1, /* Left gain */ | ||
92 | 1, /* Right gain */ | ||
93 | 1, /* Mic gain */ | ||
94 | 1, /* MDB Strength */ | ||
95 | 1, /* MDB Harmonics */ | ||
96 | 10, /* MDB Center */ | ||
97 | 10, /* MDB Shape */ | ||
98 | 1, /* MDB Enable */ | ||
99 | 1, /* Super bass */ | ||
100 | }; | ||
101 | |||
102 | static const int minval[] = | ||
103 | { | ||
104 | 0, /* Volume */ | ||
105 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | ||
106 | -12, /* Bass */ | ||
107 | -12, /* Treble */ | ||
108 | #else | ||
109 | -15, /* Bass */ | ||
110 | -15, /* Treble */ | ||
111 | #endif | ||
112 | -100, /* Balance */ | ||
113 | 0, /* Loudness */ | ||
114 | -1, /* AVC */ | ||
115 | 0, /* Channels */ | ||
116 | 0, /* Stereo width */ | ||
117 | 0, /* Left gain */ | ||
118 | 0, /* Right gain */ | ||
119 | 0, /* Mic gain */ | ||
120 | 0, /* MDB Strength */ | ||
121 | 0, /* MDB Harmonics */ | ||
122 | 20, /* MDB Center */ | ||
123 | 50, /* MDB Shape */ | ||
124 | 0, /* MDB Enable */ | ||
125 | 0, /* Super bass */ | ||
126 | }; | ||
127 | |||
128 | static const int maxval[] = | ||
129 | { | ||
130 | 100, /* Volume */ | ||
131 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | ||
132 | 12, /* Bass */ | ||
133 | 12, /* Treble */ | ||
134 | #else | ||
135 | 15, /* Bass */ | ||
136 | 15, /* Treble */ | ||
137 | #endif | ||
138 | 100, /* Balance */ | ||
139 | 17, /* Loudness */ | ||
140 | 4, /* AVC */ | ||
141 | 5, /* Channels */ | ||
142 | 255, /* Stereo width */ | ||
143 | 15, /* Left gain */ | ||
144 | 15, /* Right gain */ | ||
145 | 15, /* Mic gain */ | ||
146 | 127, /* MDB Strength */ | ||
147 | 100, /* MDB Harmonics */ | ||
148 | 300, /* MDB Center */ | ||
149 | 300, /* MDB Shape */ | ||
150 | 1, /* MDB Enable */ | ||
151 | 1, /* Super bass */ | ||
152 | }; | ||
153 | |||
154 | static const int defaultval[] = | ||
155 | { | ||
156 | 70, /* Volume */ | ||
157 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | ||
158 | 6, /* Bass */ | ||
159 | 6, /* Treble */ | ||
160 | #else | ||
161 | 7, /* Bass */ | ||
162 | 7, /* Treble */ | ||
163 | #endif | ||
164 | 0, /* Balance */ | ||
165 | 0, /* Loudness */ | ||
166 | 0, /* AVC */ | ||
167 | 0, /* Channels */ | ||
168 | 100, /* Stereo width */ | ||
169 | 8, /* Left gain */ | ||
170 | 8, /* Right gain */ | ||
171 | 2, /* Mic gain */ | ||
172 | 50, /* MDB Strength */ | ||
173 | 48, /* MDB Harmonics */ | ||
174 | 60, /* MDB Center */ | ||
175 | 90, /* MDB Shape */ | ||
176 | 0, /* MDB Enable */ | ||
177 | 0, /* Super bass */ | ||
178 | }; | ||
179 | |||
180 | const char *sound_unit(int setting) | ||
181 | { | ||
182 | return units[setting]; | ||
183 | } | ||
184 | |||
185 | int sound_numdecimals(int setting) | ||
186 | { | ||
187 | return numdecimals[setting]; | ||
188 | } | ||
189 | |||
190 | int sound_steps(int setting) | ||
191 | { | ||
192 | return steps[setting]; | ||
193 | } | ||
194 | |||
195 | int sound_min(int setting) | ||
196 | { | ||
197 | return minval[setting]; | ||
198 | } | ||
199 | |||
200 | int sound_max(int setting) | ||
201 | { | ||
202 | return maxval[setting]; | ||
203 | } | ||
204 | |||
205 | int sound_default(int setting) | ||
206 | { | ||
207 | return defaultval[setting]; | ||
208 | } | ||
209 | |||
210 | #ifndef SIMULATOR | ||
211 | #if CONFIG_HWCODEC == MAS3507D | ||
212 | static const unsigned int bass_table[] = | ||
213 | { | ||
214 | 0x9e400, /* -15dB */ | ||
215 | 0xa2800, /* -14dB */ | ||
216 | 0xa7400, /* -13dB */ | ||
217 | 0xac400, /* -12dB */ | ||
218 | 0xb1800, /* -11dB */ | ||
219 | 0xb7400, /* -10dB */ | ||
220 | 0xbd400, /* -9dB */ | ||
221 | 0xc3c00, /* -8dB */ | ||
222 | 0xca400, /* -7dB */ | ||
223 | 0xd1800, /* -6dB */ | ||
224 | 0xd8c00, /* -5dB */ | ||
225 | 0xe0400, /* -4dB */ | ||
226 | 0xe8000, /* -3dB */ | ||
227 | 0xefc00, /* -2dB */ | ||
228 | 0xf7c00, /* -1dB */ | ||
229 | 0, | ||
230 | 0x800, /* 1dB */ | ||
231 | 0x10000, /* 2dB */ | ||
232 | 0x17c00, /* 3dB */ | ||
233 | 0x1f800, /* 4dB */ | ||
234 | 0x27000, /* 5dB */ | ||
235 | 0x2e400, /* 6dB */ | ||
236 | 0x35800, /* 7dB */ | ||
237 | 0x3c000, /* 8dB */ | ||
238 | 0x42800, /* 9dB */ | ||
239 | 0x48800, /* 10dB */ | ||
240 | 0x4e400, /* 11dB */ | ||
241 | 0x53800, /* 12dB */ | ||
242 | 0x58800, /* 13dB */ | ||
243 | 0x5d400, /* 14dB */ | ||
244 | 0x61800 /* 15dB */ | ||
245 | }; | ||
246 | |||
247 | static const unsigned int treble_table[] = | ||
248 | { | ||
249 | 0xb2c00, /* -15dB */ | ||
250 | 0xbb400, /* -14dB */ | ||
251 | 0xc1800, /* -13dB */ | ||
252 | 0xc6c00, /* -12dB */ | ||
253 | 0xcbc00, /* -11dB */ | ||
254 | 0xd0400, /* -10dB */ | ||
255 | 0xd5000, /* -9dB */ | ||
256 | 0xd9800, /* -8dB */ | ||
257 | 0xde000, /* -7dB */ | ||
258 | 0xe2800, /* -6dB */ | ||
259 | 0xe7e00, /* -5dB */ | ||
260 | 0xec000, /* -4dB */ | ||
261 | 0xf0c00, /* -3dB */ | ||
262 | 0xf5c00, /* -2dB */ | ||
263 | 0xfac00, /* -1dB */ | ||
264 | 0, | ||
265 | 0x5400, /* 1dB */ | ||
266 | 0xac00, /* 2dB */ | ||
267 | 0x10400, /* 3dB */ | ||
268 | 0x16000, /* 4dB */ | ||
269 | 0x1c000, /* 5dB */ | ||
270 | 0x22400, /* 6dB */ | ||
271 | 0x28400, /* 7dB */ | ||
272 | 0x2ec00, /* 8dB */ | ||
273 | 0x35400, /* 9dB */ | ||
274 | 0x3c000, /* 10dB */ | ||
275 | 0x42c00, /* 11dB */ | ||
276 | 0x49c00, /* 12dB */ | ||
277 | 0x51800, /* 13dB */ | ||
278 | 0x58400, /* 14dB */ | ||
279 | 0x5f800 /* 15dB */ | ||
280 | }; | ||
281 | |||
282 | static const unsigned int prescale_table[] = | ||
283 | { | ||
284 | 0x80000, /* 0db */ | ||
285 | 0x8e000, /* 1dB */ | ||
286 | 0x9a400, /* 2dB */ | ||
287 | 0xa5800, /* 3dB */ | ||
288 | 0xaf400, /* 4dB */ | ||
289 | 0xb8000, /* 5dB */ | ||
290 | 0xbfc00, /* 6dB */ | ||
291 | 0xc6c00, /* 7dB */ | ||
292 | 0xcd000, /* 8dB */ | ||
293 | 0xd25c0, /* 9dB */ | ||
294 | 0xd7800, /* 10dB */ | ||
295 | 0xdc000, /* 11dB */ | ||
296 | 0xdfc00, /* 12dB */ | ||
297 | 0xe3400, /* 13dB */ | ||
298 | 0xe6800, /* 14dB */ | ||
299 | 0xe9400 /* 15dB */ | ||
300 | }; | ||
301 | |||
302 | /* all values in tenth of dB */ | ||
303 | int current_volume = 0; /* -780..+180 */ | ||
304 | int current_balance = 0; /* -960..+960 */ | ||
305 | int current_treble = 0; /* -150..+150 */ | ||
306 | int current_bass = 0; /* -150..+150 */ | ||
307 | |||
308 | /* convert tenth of dB volume to register value */ | ||
309 | static int tenthdb2reg(int db) { | ||
310 | if (db < -540) | ||
311 | return (db + 780) / 30; | ||
312 | else | ||
313 | return (db + 660) / 15; | ||
314 | } | ||
315 | |||
316 | void set_prescaled_volume(void) | ||
317 | { | ||
318 | int prescale; | ||
319 | int l, r; | ||
320 | |||
321 | prescale = MAX(current_bass, current_treble); | ||
322 | if (prescale < 0) | ||
323 | prescale = 0; /* no need to prescale if we don't boost | ||
324 | bass or treble */ | ||
325 | |||
326 | mas_writereg(MAS_REG_KPRESCALE, prescale_table[prescale/10]); | ||
327 | |||
328 | /* gain up the analog volume to compensate the prescale reduction gain, | ||
329 | * but limit to +18 dB (the maximum the DAC can do */ | ||
330 | if (current_volume + prescale > 180) | ||
331 | prescale = 180 - current_volume; | ||
332 | l = r = current_volume + prescale; | ||
333 | |||
334 | if (current_balance > 0) | ||
335 | { | ||
336 | l -= current_balance; | ||
337 | if (l < -780) | ||
338 | l = -780; | ||
339 | } | ||
340 | if (current_balance < 0) | ||
341 | { | ||
342 | r += current_balance; | ||
343 | if (r < -780) | ||
344 | r = -780; | ||
345 | } | ||
346 | |||
347 | dac_volume(tenthdb2reg(l), tenthdb2reg(r), false); | ||
348 | } | ||
349 | #endif /* MAS3507D */ | ||
350 | #endif /* !SIMULATOR */ | ||
351 | |||
352 | int channel_configuration = SOUND_CHAN_STEREO; | ||
353 | int stereo_width = 100; | ||
354 | |||
355 | #ifndef SIMULATOR | ||
356 | static void set_channel_config(void) | ||
357 | { | ||
358 | /* default values: stereo */ | ||
359 | unsigned long val_ll = 0x80000; | ||
360 | unsigned long val_lr = 0; | ||
361 | unsigned long val_rl = 0; | ||
362 | unsigned long val_rr = 0x80000; | ||
363 | |||
364 | switch(channel_configuration) | ||
365 | { | ||
366 | /* case SOUND_CHAN_STEREO unnecessary */ | ||
367 | |||
368 | case SOUND_CHAN_MONO: | ||
369 | val_ll = 0xc0000; | ||
370 | val_lr = 0xc0000; | ||
371 | val_rl = 0xc0000; | ||
372 | val_rr = 0xc0000; | ||
373 | break; | ||
374 | |||
375 | case SOUND_CHAN_CUSTOM: | ||
376 | { | ||
377 | /* fixed point variables (matching MAS internal format) | ||
378 | integer part: upper 13 bits (inlcuding sign) | ||
379 | fractional part: lower 19 bits */ | ||
380 | long fp_width, fp_straight, fp_cross; | ||
381 | |||
382 | fp_width = (stereo_width << 19) / 100; | ||
383 | if (stereo_width <= 100) | ||
384 | { | ||
385 | fp_straight = - ((1<<19) + fp_width) / 2; | ||
386 | fp_cross = fp_straight + fp_width; | ||
387 | } | ||
388 | else | ||
389 | { | ||
390 | fp_straight = - (1<<19); | ||
391 | fp_cross = ((2 * fp_width / (((1<<19) + fp_width) >> 10)) | ||
392 | << 9) - (1<<19); | ||
393 | } | ||
394 | val_ll = val_rr = fp_straight & 0xFFFFF; | ||
395 | val_lr = val_rl = fp_cross & 0xFFFFF; | ||
396 | } | ||
397 | break; | ||
398 | |||
399 | case SOUND_CHAN_MONO_LEFT: | ||
400 | val_ll = 0x80000; | ||
401 | val_lr = 0x80000; | ||
402 | val_rl = 0; | ||
403 | val_rr = 0; | ||
404 | break; | ||
405 | |||
406 | case SOUND_CHAN_MONO_RIGHT: | ||
407 | val_ll = 0; | ||
408 | val_lr = 0; | ||
409 | val_rl = 0x80000; | ||
410 | val_rr = 0x80000; | ||
411 | break; | ||
412 | |||
413 | case SOUND_CHAN_KARAOKE: | ||
414 | val_ll = 0x80001; | ||
415 | val_lr = 0x7ffff; | ||
416 | val_rl = 0x7ffff; | ||
417 | val_rr = 0x80001; | ||
418 | break; | ||
419 | } | ||
420 | |||
421 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | ||
422 | mas_writemem(MAS_BANK_D0, MAS_D0_OUT_LL, &val_ll, 1); /* LL */ | ||
423 | mas_writemem(MAS_BANK_D0, MAS_D0_OUT_LR, &val_lr, 1); /* LR */ | ||
424 | mas_writemem(MAS_BANK_D0, MAS_D0_OUT_RL, &val_rl, 1); /* RL */ | ||
425 | mas_writemem(MAS_BANK_D0, MAS_D0_OUT_RR, &val_rr, 1); /* RR */ | ||
426 | #elif CONFIG_HWCODEC == MAS3507D | ||
427 | mas_writemem(MAS_BANK_D1, 0x7f8, &val_ll, 1); /* LL */ | ||
428 | mas_writemem(MAS_BANK_D1, 0x7f9, &val_lr, 1); /* LR */ | ||
429 | mas_writemem(MAS_BANK_D1, 0x7fa, &val_rl, 1); /* RL */ | ||
430 | mas_writemem(MAS_BANK_D1, 0x7fb, &val_rr, 1); /* RR */ | ||
431 | #endif | ||
432 | } | ||
433 | #endif /* !SIMULATOR */ | ||
434 | |||
435 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | ||
436 | unsigned long mdb_shape_shadow = 0; | ||
437 | unsigned long loudness_shadow = 0; | ||
438 | #endif | ||
439 | |||
440 | void sound_set(int setting, int value) | ||
441 | { | ||
442 | #ifdef SIMULATOR | ||
443 | setting = value; | ||
444 | #else | ||
445 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | ||
446 | int tmp; | ||
447 | #endif | ||
448 | |||
449 | if(!audio_is_initialized) | ||
450 | return; | ||
451 | |||
452 | switch(setting) | ||
453 | { | ||
454 | case SOUND_VOLUME: | ||
455 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | ||
456 | tmp = 0x7f00 * value / 100; | ||
457 | mas_codec_writereg(0x10, tmp & 0xff00); | ||
458 | #elif CONFIG_HWCODEC == MAS3507D | ||
459 | current_volume = -780 + (value * 960 / 100); /* tenth of dB */ | ||
460 | set_prescaled_volume(); | ||
461 | #endif | ||
462 | break; | ||
463 | |||
464 | case SOUND_BALANCE: | ||
465 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | ||
466 | tmp = ((value * 127 / 100) & 0xff) << 8; | ||
467 | mas_codec_writereg(0x11, tmp & 0xff00); | ||
468 | #elif CONFIG_HWCODEC == MAS3507D | ||
469 | current_balance = value * 960 / 100; /* tenth of dB */ | ||
470 | set_prescaled_volume(); | ||
471 | #endif | ||
472 | break; | ||
473 | |||
474 | case SOUND_BASS: | ||
475 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | ||
476 | tmp = ((value * 8) & 0xff) << 8; | ||
477 | mas_codec_writereg(0x14, tmp & 0xff00); | ||
478 | #elif CONFIG_HWCODEC == MAS3507D | ||
479 | mas_writereg(MAS_REG_KBASS, bass_table[value+15]); | ||
480 | current_bass = value * 10; | ||
481 | set_prescaled_volume(); | ||
482 | #endif | ||
483 | break; | ||
484 | |||
485 | case SOUND_TREBLE: | ||
486 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | ||
487 | tmp = ((value * 8) & 0xff) << 8; | ||
488 | mas_codec_writereg(0x15, tmp & 0xff00); | ||
489 | #elif CONFIG_HWCODEC == MAS3507D | ||
490 | mas_writereg(MAS_REG_KTREBLE, treble_table[value+15]); | ||
491 | current_treble = value * 10; | ||
492 | set_prescaled_volume(); | ||
493 | #endif | ||
494 | break; | ||
495 | |||
496 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | ||
497 | case SOUND_LOUDNESS: | ||
498 | loudness_shadow = (loudness_shadow & 0x04) | | ||
499 | (MAX(MIN(value * 4, 0x44), 0) << 8); | ||
500 | mas_codec_writereg(MAS_REG_KLOUDNESS, loudness_shadow); | ||
501 | break; | ||
502 | |||
503 | case SOUND_AVC: | ||
504 | switch (value) { | ||
505 | case 1: /* 20ms */ | ||
506 | tmp = (0x1 << 8) | (0x8 << 12); | ||
507 | break; | ||
508 | case 2: /* 2s */ | ||
509 | tmp = (0x2 << 8) | (0x8 << 12); | ||
510 | break; | ||
511 | case 3: /* 4s */ | ||
512 | tmp = (0x4 << 8) | (0x8 << 12); | ||
513 | break; | ||
514 | case 4: /* 8s */ | ||
515 | tmp = (0x8 << 8) | (0x8 << 12); | ||
516 | break; | ||
517 | case -1: /* turn off and then turn on again to decay quickly */ | ||
518 | tmp = mas_codec_readreg(MAS_REG_KAVC); | ||
519 | mas_codec_writereg(MAS_REG_KAVC, 0); | ||
520 | break; | ||
521 | default: /* off */ | ||
522 | tmp = 0; | ||
523 | break; | ||
524 | } | ||
525 | mas_codec_writereg(MAS_REG_KAVC, tmp); | ||
526 | break; | ||
527 | |||
528 | case SOUND_MDB_STRENGTH: | ||
529 | mas_codec_writereg(MAS_REG_KMDB_STR, (value & 0x7f) << 8); | ||
530 | break; | ||
531 | |||
532 | case SOUND_MDB_HARMONICS: | ||
533 | tmp = value * 127 / 100; | ||
534 | mas_codec_writereg(MAS_REG_KMDB_HAR, (tmp & 0x7f) << 8); | ||
535 | break; | ||
536 | |||
537 | case SOUND_MDB_CENTER: | ||
538 | mas_codec_writereg(MAS_REG_KMDB_FC, (value/10) << 8); | ||
539 | break; | ||
540 | |||
541 | case SOUND_MDB_SHAPE: | ||
542 | mdb_shape_shadow = (mdb_shape_shadow & 0x02) | ((value/10) << 8); | ||
543 | mas_codec_writereg(MAS_REG_KMDB_SWITCH, mdb_shape_shadow); | ||
544 | break; | ||
545 | |||
546 | case SOUND_MDB_ENABLE: | ||
547 | mdb_shape_shadow = (mdb_shape_shadow & ~0x02) | (value?2:0); | ||
548 | mas_codec_writereg(MAS_REG_KMDB_SWITCH, mdb_shape_shadow); | ||
549 | break; | ||
550 | |||
551 | case SOUND_SUPERBASS: | ||
552 | loudness_shadow = (loudness_shadow & ~0x04) | | ||
553 | (value?4:0); | ||
554 | mas_codec_writereg(MAS_REG_KLOUDNESS, loudness_shadow); | ||
555 | break; | ||
556 | #endif | ||
557 | case SOUND_CHANNELS: | ||
558 | channel_configuration = value; | ||
559 | set_channel_config(); | ||
560 | break; | ||
561 | |||
562 | case SOUND_STEREO_WIDTH: | ||
563 | stereo_width = value; | ||
564 | if (channel_configuration == SOUND_CHAN_CUSTOM) | ||
565 | set_channel_config(); | ||
566 | break; | ||
567 | } | ||
568 | #endif /* SIMULATOR */ | ||
569 | } | ||
570 | |||
571 | int sound_val2phys(int setting, int value) | ||
572 | { | ||
573 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | ||
574 | int result = 0; | ||
575 | |||
576 | switch(setting) | ||
577 | { | ||
578 | case SOUND_LEFT_GAIN: | ||
579 | case SOUND_RIGHT_GAIN: | ||
580 | result = (value - 2) * 15; | ||
581 | break; | ||
582 | |||
583 | case SOUND_MIC_GAIN: | ||
584 | result = value * 15 + 210; | ||
585 | break; | ||
586 | |||
587 | default: | ||
588 | result = value; | ||
589 | break; | ||
590 | } | ||
591 | return result; | ||
592 | #else | ||
593 | (void)setting; | ||
594 | return value; | ||
595 | #endif | ||
596 | } | ||
597 | |||
598 | #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) | ||
599 | /* This function works by telling the decoder that we have another | ||
600 | crystal frequency than we actually have. It will adjust its internal | ||
601 | parameters and the result is that the audio is played at another pitch. | ||
602 | |||
603 | The pitch value is in tenths of percent. | ||
604 | */ | ||
605 | void sound_set_pitch(int pitch) | ||
606 | { | ||
607 | unsigned long val; | ||
608 | |||
609 | /* invert pitch value */ | ||
610 | pitch = 1000000/pitch; | ||
611 | |||
612 | /* Calculate the new (bogus) frequency */ | ||
613 | val = 18432*pitch/1000; | ||
614 | |||
615 | mas_writemem(MAS_BANK_D0, MAS_D0_OFREQ_CONTROL, &val, 1); | ||
616 | |||
617 | /* We must tell the MAS that the frequency has changed. | ||
618 | This will unfortunately cause a short silence. */ | ||
619 | mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1); | ||
620 | } | ||
621 | #elif defined SIMULATOR | ||
622 | void sound_set_pitch(int pitch) | ||
623 | { | ||
624 | (void)pitch; | ||
625 | } | ||
626 | #endif | ||
627 | |||
628 | #if CONFIG_HWCODEC == MASNONE | ||
629 | bool mp3_is_playing(void) | ||
630 | { | ||
631 | /* a dummy */ | ||
632 | return false; | ||
633 | } | ||
634 | #endif | ||