diff options
author | Jörg Hohensohn <hohensoh@rockbox.org> | 2004-01-05 20:42:51 +0000 |
---|---|---|
committer | Jörg Hohensohn <hohensoh@rockbox.org> | 2004-01-05 20:42:51 +0000 |
commit | f993365447d8dc5bb28c76a003cecd045c3abaf7 (patch) | |
tree | 19d4a2cfebd7e0f43c85559c2e88114fd4ba3223 /firmware | |
parent | 974c2f0d43c1ebc786854f48f15ccaea7803d8f0 (diff) | |
download | rockbox-f993365447d8dc5bb28c76a003cecd045c3abaf7.tar.gz rockbox-f993365447d8dc5bb28c76a003cecd045c3abaf7.zip |
Moved the low-level playback functionality into a new, separate module "mp3_playback". This e.g. allows to export a memory playback API to the plugins, opens the door to games with sound, UI sounds, etc.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4192 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/export/mp3_playback.h | 73 | ||||
-rw-r--r-- | firmware/export/mpeg.h | 34 | ||||
-rw-r--r-- | firmware/mp3_playback.c | 939 | ||||
-rw-r--r-- | firmware/mpeg.c | 922 |
4 files changed, 1056 insertions, 912 deletions
diff --git a/firmware/export/mp3_playback.h b/firmware/export/mp3_playback.h new file mode 100644 index 0000000000..2767092b75 --- /dev/null +++ b/firmware/export/mp3_playback.h | |||
@@ -0,0 +1,73 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Code that has been in mpeg.c/h before, now creating an encapsulated play | ||
11 | * data module, to be used by other sources than file playback as well. | ||
12 | * | ||
13 | * Copyright (C) 2004 by Linus Nielsen Feltzing | ||
14 | * | ||
15 | * All files in this archive are subject to the GNU General Public License. | ||
16 | * See the file COPYING in the source tree root for full license agreement. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | #ifndef _MP3_PLAYBACK_H_ | ||
23 | #define _MP3_PLAYBACK_H_ | ||
24 | |||
25 | #include <stdbool.h> | ||
26 | |||
27 | /* functions formerly in mpeg.c */ | ||
28 | void mp3_init(int volume, int bass, int treble, int balance, | ||
29 | int loudness, int bass_boost, int avc, int channel_config); | ||
30 | void mpeg_sound_set(int setting, int value); | ||
31 | int mpeg_sound_min(int setting); | ||
32 | int mpeg_sound_max(int setting); | ||
33 | int mpeg_sound_default(int setting); | ||
34 | void mpeg_sound_channel_config(int configuration); | ||
35 | int mpeg_val2phys(int setting, int value); | ||
36 | int mpeg_phys2val(int setting, int value); | ||
37 | char *mpeg_sound_unit(int setting); | ||
38 | int mpeg_sound_numdecimals(int setting); | ||
39 | #if defined(HAVE_MAS3587F) || defined(SIMULATOR) | ||
40 | void mpeg_set_pitch(int percent); | ||
41 | #endif | ||
42 | |||
43 | /* new functions, to be exported to plugin API */ | ||
44 | void mp3_play_init(void); | ||
45 | void mp3_play_data(unsigned char* start, int size, | ||
46 | void (*get_more)(unsigned char** start, int* size) /* callback fn */ | ||
47 | ); | ||
48 | void mp3_play_pause(bool play); | ||
49 | void mp3_play_stop(void); | ||
50 | |||
51 | |||
52 | #define SOUND_VOLUME 0 | ||
53 | #define SOUND_BASS 1 | ||
54 | #define SOUND_TREBLE 2 | ||
55 | #define SOUND_BALANCE 3 | ||
56 | #define SOUND_LOUDNESS 4 | ||
57 | #define SOUND_SUPERBASS 5 | ||
58 | #define SOUND_AVC 6 | ||
59 | #define SOUND_CHANNELS 7 | ||
60 | #define SOUND_LEFT_GAIN 8 | ||
61 | #define SOUND_RIGHT_GAIN 9 | ||
62 | #define SOUND_MIC_GAIN 10 | ||
63 | #define SOUND_NUMSETTINGS 11 | ||
64 | |||
65 | #define MPEG_SOUND_STEREO 0 | ||
66 | #define MPEG_SOUND_STEREO_NARROW 1 | ||
67 | #define MPEG_SOUND_MONO 2 | ||
68 | #define MPEG_SOUND_MONO_LEFT 3 | ||
69 | #define MPEG_SOUND_MONO_RIGHT 4 | ||
70 | #define MPEG_SOUND_KARAOKE 5 | ||
71 | #define MPEG_SOUND_STEREO_WIDE 6 | ||
72 | |||
73 | #endif /* #ifndef _MP3_PLAYBACK_H_ */ | ||
diff --git a/firmware/export/mpeg.h b/firmware/export/mpeg.h index bbace28ecd..2a629f4b45 100644 --- a/firmware/export/mpeg.h +++ b/firmware/export/mpeg.h | |||
@@ -61,8 +61,7 @@ struct mpeg_debug | |||
61 | int lowest_watermark_level; | 61 | int lowest_watermark_level; |
62 | }; | 62 | }; |
63 | 63 | ||
64 | void mpeg_init(int volume, int bass, int treble, int balance, | 64 | void mpeg_init(void); |
65 | int loudness, int bass_boost, int avc, int channel_config); | ||
66 | void mpeg_play(int offset); | 65 | void mpeg_play(int offset); |
67 | void mpeg_stop(void); | 66 | void mpeg_stop(void); |
68 | void mpeg_pause(void); | 67 | void mpeg_pause(void); |
@@ -71,20 +70,10 @@ void mpeg_next(void); | |||
71 | void mpeg_prev(void); | 70 | void mpeg_prev(void); |
72 | void mpeg_ff_rewind(int newtime); | 71 | void mpeg_ff_rewind(int newtime); |
73 | void mpeg_flush_and_reload_tracks(void); | 72 | void mpeg_flush_and_reload_tracks(void); |
74 | void mpeg_sound_set(int setting, int value); | ||
75 | int mpeg_sound_min(int setting); | ||
76 | int mpeg_sound_max(int setting); | ||
77 | int mpeg_sound_default(int setting); | ||
78 | void mpeg_sound_channel_config(int configuration); | ||
79 | int mpeg_val2phys(int setting, int value); | ||
80 | int mpeg_phys2val(int setting, int value); | ||
81 | char *mpeg_sound_unit(int setting); | ||
82 | int mpeg_sound_numdecimals(int setting); | ||
83 | struct mp3entry* mpeg_current_track(void); | 73 | struct mp3entry* mpeg_current_track(void); |
84 | bool mpeg_has_changed_track(void); | 74 | bool mpeg_has_changed_track(void); |
85 | int mpeg_status(void); | 75 | int mpeg_status(void); |
86 | #if defined(HAVE_MAS3587F) || defined(SIMULATOR) | 76 | #if defined(HAVE_MAS3587F) || defined(SIMULATOR) |
87 | void mpeg_set_pitch(int percent); | ||
88 | void mpeg_init_recording(void); | 77 | void mpeg_init_recording(void); |
89 | void mpeg_init_playback(void); | 78 | void mpeg_init_playback(void); |
90 | void mpeg_record(char *filename); | 79 | void mpeg_record(char *filename); |
@@ -101,27 +90,6 @@ void mpeg_set_buffer_margin(int seconds); | |||
101 | unsigned int mpeg_error(void); | 90 | unsigned int mpeg_error(void); |
102 | void mpeg_error_clear(void); | 91 | void mpeg_error_clear(void); |
103 | 92 | ||
104 | #define SOUND_VOLUME 0 | ||
105 | #define SOUND_BASS 1 | ||
106 | #define SOUND_TREBLE 2 | ||
107 | #define SOUND_BALANCE 3 | ||
108 | #define SOUND_LOUDNESS 4 | ||
109 | #define SOUND_SUPERBASS 5 | ||
110 | #define SOUND_AVC 6 | ||
111 | #define SOUND_CHANNELS 7 | ||
112 | #define SOUND_LEFT_GAIN 8 | ||
113 | #define SOUND_RIGHT_GAIN 9 | ||
114 | #define SOUND_MIC_GAIN 10 | ||
115 | #define SOUND_NUMSETTINGS 11 | ||
116 | |||
117 | #define MPEG_SOUND_STEREO 0 | ||
118 | #define MPEG_SOUND_STEREO_NARROW 1 | ||
119 | #define MPEG_SOUND_MONO 2 | ||
120 | #define MPEG_SOUND_MONO_LEFT 3 | ||
121 | #define MPEG_SOUND_MONO_RIGHT 4 | ||
122 | #define MPEG_SOUND_KARAOKE 5 | ||
123 | #define MPEG_SOUND_STEREO_WIDE 6 | ||
124 | |||
125 | #define MPEG_STATUS_PLAY 1 | 93 | #define MPEG_STATUS_PLAY 1 |
126 | #define MPEG_STATUS_PAUSE 2 | 94 | #define MPEG_STATUS_PAUSE 2 |
127 | #define MPEG_STATUS_RECORD 4 | 95 | #define MPEG_STATUS_RECORD 4 |
diff --git a/firmware/mp3_playback.c b/firmware/mp3_playback.c new file mode 100644 index 0000000000..9ded720248 --- /dev/null +++ b/firmware/mp3_playback.c | |||
@@ -0,0 +1,939 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Code that has been in mpeg.c before, now creating an encapsulated play | ||
11 | * data module, to be used by other sources than file playback as well. | ||
12 | * | ||
13 | * Copyright (C) 2004 by Linus Nielsen Feltzing | ||
14 | * | ||
15 | * All files in this archive are subject to the GNU General Public License. | ||
16 | * See the file COPYING in the source tree root for full license agreement. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | #include <stdbool.h> | ||
23 | #include "config.h" | ||
24 | #include "debug.h" | ||
25 | #include "panic.h" | ||
26 | #include <kernel.h> | ||
27 | #include "mpeg.h" /* ToDo: remove crosslinks */ | ||
28 | #include "mp3_playback.h" | ||
29 | #ifndef SIMULATOR | ||
30 | #include "i2c.h" | ||
31 | #include "mas.h" | ||
32 | #include "dac.h" | ||
33 | #include "system.h" | ||
34 | #include "hwcompat.h" | ||
35 | #endif | ||
36 | |||
37 | static char *units[] = | ||
38 | { | ||
39 | "%", /* Volume */ | ||
40 | "dB", /* Bass */ | ||
41 | "dB", /* Treble */ | ||
42 | "%", /* Balance */ | ||
43 | "dB", /* Loudness */ | ||
44 | "%", /* Bass boost */ | ||
45 | "", /* AVC */ | ||
46 | "", /* Channels */ | ||
47 | "dB", /* Left gain */ | ||
48 | "dB", /* Right gain */ | ||
49 | "dB", /* Mic gain */ | ||
50 | }; | ||
51 | |||
52 | static int numdecimals[] = | ||
53 | { | ||
54 | 0, /* Volume */ | ||
55 | 0, /* Bass */ | ||
56 | 0, /* Treble */ | ||
57 | 0, /* Balance */ | ||
58 | 0, /* Loudness */ | ||
59 | 0, /* Bass boost */ | ||
60 | 0, /* AVC */ | ||
61 | 0, /* Channels */ | ||
62 | 1, /* Left gain */ | ||
63 | 1, /* Right gain */ | ||
64 | 1, /* Mic gain */ | ||
65 | }; | ||
66 | |||
67 | static int minval[] = | ||
68 | { | ||
69 | 0, /* Volume */ | ||
70 | 0, /* Bass */ | ||
71 | 0, /* Treble */ | ||
72 | -50, /* Balance */ | ||
73 | 0, /* Loudness */ | ||
74 | 0, /* Bass boost */ | ||
75 | -1, /* AVC */ | ||
76 | 0, /* Channels */ | ||
77 | 0, /* Left gain */ | ||
78 | 0, /* Right gain */ | ||
79 | 0, /* Mic gain */ | ||
80 | }; | ||
81 | |||
82 | static int maxval[] = | ||
83 | { | ||
84 | 100, /* Volume */ | ||
85 | #ifdef HAVE_MAS3587F | ||
86 | 24, /* Bass */ | ||
87 | 24, /* Treble */ | ||
88 | #else | ||
89 | 30, /* Bass */ | ||
90 | 30, /* Treble */ | ||
91 | #endif | ||
92 | 50, /* Balance */ | ||
93 | 17, /* Loudness */ | ||
94 | 10, /* Bass boost */ | ||
95 | 3, /* AVC */ | ||
96 | 6, /* Channels */ | ||
97 | 15, /* Left gain */ | ||
98 | 15, /* Right gain */ | ||
99 | 15, /* Mic gain */ | ||
100 | }; | ||
101 | |||
102 | static int defaultval[] = | ||
103 | { | ||
104 | 70, /* Volume */ | ||
105 | #ifdef HAVE_MAS3587F | ||
106 | 12+6, /* Bass */ | ||
107 | 12+6, /* Treble */ | ||
108 | #else | ||
109 | 15+7, /* Bass */ | ||
110 | 15+7, /* Treble */ | ||
111 | #endif | ||
112 | 0, /* Balance */ | ||
113 | 0, /* Loudness */ | ||
114 | 0, /* Bass boost */ | ||
115 | 0, /* AVC */ | ||
116 | 0, /* Channels */ | ||
117 | 8, /* Left gain */ | ||
118 | 8, /* Right gain */ | ||
119 | 2, /* Mic gain */ | ||
120 | }; | ||
121 | |||
122 | char *mpeg_sound_unit(int setting) | ||
123 | { | ||
124 | return units[setting]; | ||
125 | } | ||
126 | |||
127 | int mpeg_sound_numdecimals(int setting) | ||
128 | { | ||
129 | return numdecimals[setting]; | ||
130 | } | ||
131 | |||
132 | int mpeg_sound_min(int setting) | ||
133 | { | ||
134 | return minval[setting]; | ||
135 | } | ||
136 | |||
137 | int mpeg_sound_max(int setting) | ||
138 | { | ||
139 | return maxval[setting]; | ||
140 | } | ||
141 | |||
142 | int mpeg_sound_default(int setting) | ||
143 | { | ||
144 | return defaultval[setting]; | ||
145 | } | ||
146 | |||
147 | /* list of tracks in memory */ | ||
148 | #define MAX_ID3_TAGS (1<<4) /* Must be power of 2 */ | ||
149 | #define MAX_ID3_TAGS_MASK (MAX_ID3_TAGS - 1) | ||
150 | |||
151 | #ifndef SIMULATOR | ||
152 | static bool mpeg_is_initialized = false; | ||
153 | #endif | ||
154 | |||
155 | #ifndef SIMULATOR | ||
156 | |||
157 | unsigned long mas_version_code; | ||
158 | |||
159 | #ifdef HAVE_MAS3507D | ||
160 | |||
161 | static unsigned int bass_table[] = | ||
162 | { | ||
163 | 0x9e400, /* -15dB */ | ||
164 | 0xa2800, /* -14dB */ | ||
165 | 0xa7400, /* -13dB */ | ||
166 | 0xac400, /* -12dB */ | ||
167 | 0xb1800, /* -11dB */ | ||
168 | 0xb7400, /* -10dB */ | ||
169 | 0xbd400, /* -9dB */ | ||
170 | 0xc3c00, /* -8dB */ | ||
171 | 0xca400, /* -7dB */ | ||
172 | 0xd1800, /* -6dB */ | ||
173 | 0xd8c00, /* -5dB */ | ||
174 | 0xe0400, /* -4dB */ | ||
175 | 0xe8000, /* -3dB */ | ||
176 | 0xefc00, /* -2dB */ | ||
177 | 0xf7c00, /* -1dB */ | ||
178 | 0, | ||
179 | 0x800, /* 1dB */ | ||
180 | 0x10000, /* 2dB */ | ||
181 | 0x17c00, /* 3dB */ | ||
182 | 0x1f800, /* 4dB */ | ||
183 | 0x27000, /* 5dB */ | ||
184 | 0x2e400, /* 6dB */ | ||
185 | 0x35800, /* 7dB */ | ||
186 | 0x3c000, /* 8dB */ | ||
187 | 0x42800, /* 9dB */ | ||
188 | 0x48800, /* 10dB */ | ||
189 | 0x4e400, /* 11dB */ | ||
190 | 0x53800, /* 12dB */ | ||
191 | 0x58800, /* 13dB */ | ||
192 | 0x5d400, /* 14dB */ | ||
193 | 0x61800 /* 15dB */ | ||
194 | }; | ||
195 | |||
196 | static unsigned int treble_table[] = | ||
197 | { | ||
198 | 0xb2c00, /* -15dB */ | ||
199 | 0xbb400, /* -14dB */ | ||
200 | 0xc1800, /* -13dB */ | ||
201 | 0xc6c00, /* -12dB */ | ||
202 | 0xcbc00, /* -11dB */ | ||
203 | 0xd0400, /* -10dB */ | ||
204 | 0xd5000, /* -9dB */ | ||
205 | 0xd9800, /* -8dB */ | ||
206 | 0xde000, /* -7dB */ | ||
207 | 0xe2800, /* -6dB */ | ||
208 | 0xe7e00, /* -5dB */ | ||
209 | 0xec000, /* -4dB */ | ||
210 | 0xf0c00, /* -3dB */ | ||
211 | 0xf5c00, /* -2dB */ | ||
212 | 0xfac00, /* -1dB */ | ||
213 | 0, | ||
214 | 0x5400, /* 1dB */ | ||
215 | 0xac00, /* 2dB */ | ||
216 | 0x10400, /* 3dB */ | ||
217 | 0x16000, /* 4dB */ | ||
218 | 0x1c000, /* 5dB */ | ||
219 | 0x22400, /* 6dB */ | ||
220 | 0x28400, /* 7dB */ | ||
221 | 0x2ec00, /* 8dB */ | ||
222 | 0x35400, /* 9dB */ | ||
223 | 0x3c000, /* 10dB */ | ||
224 | 0x42c00, /* 11dB */ | ||
225 | 0x49c00, /* 12dB */ | ||
226 | 0x51800, /* 13dB */ | ||
227 | 0x58400, /* 14dB */ | ||
228 | 0x5f800 /* 15dB */ | ||
229 | }; | ||
230 | |||
231 | static unsigned int prescale_table[] = | ||
232 | { | ||
233 | 0x80000, /* 0db */ | ||
234 | 0x8e000, /* 1dB */ | ||
235 | 0x9a400, /* 2dB */ | ||
236 | 0xa5800, /* 3dB */ | ||
237 | 0xaf400, /* 4dB */ | ||
238 | 0xb8000, /* 5dB */ | ||
239 | 0xbfc00, /* 6dB */ | ||
240 | 0xc6c00, /* 7dB */ | ||
241 | 0xcd000, /* 8dB */ | ||
242 | 0xd25c0, /* 9dB */ | ||
243 | 0xd7800, /* 10dB */ | ||
244 | 0xdc000, /* 11dB */ | ||
245 | 0xdfc00, /* 12dB */ | ||
246 | 0xe3400, /* 13dB */ | ||
247 | 0xe6800, /* 14dB */ | ||
248 | 0xe9400 /* 15dB */ | ||
249 | }; | ||
250 | #endif | ||
251 | |||
252 | bool dma_on; /* The DMA is active */ | ||
253 | |||
254 | #ifdef HAVE_MAS3507D | ||
255 | static void mas_poll_start(int interval_in_ms) | ||
256 | { | ||
257 | unsigned int count; | ||
258 | |||
259 | count = (FREQ * interval_in_ms) / 1000 / 8; | ||
260 | |||
261 | if(count > 0xffff) | ||
262 | { | ||
263 | panicf("Error! The MAS poll interval is too long (%d ms)\n", | ||
264 | interval_in_ms); | ||
265 | return; | ||
266 | } | ||
267 | |||
268 | /* We are using timer 1 */ | ||
269 | |||
270 | TSTR &= ~0x02; /* Stop the timer */ | ||
271 | TSNC &= ~0x02; /* No synchronization */ | ||
272 | TMDR &= ~0x02; /* Operate normally */ | ||
273 | |||
274 | TCNT1 = 0; /* Start counting at 0 */ | ||
275 | GRA1 = count; | ||
276 | TCR1 = 0x23; /* Clear at GRA match, sysclock/8 */ | ||
277 | |||
278 | /* Enable interrupt on level 5 */ | ||
279 | IPRC = (IPRC & ~0x000f) | 0x0005; | ||
280 | |||
281 | TSR1 &= ~0x02; | ||
282 | TIER1 = 0xf9; /* Enable GRA match interrupt */ | ||
283 | |||
284 | TSTR |= 0x02; /* Start timer 1 */ | ||
285 | } | ||
286 | #endif | ||
287 | |||
288 | /* the registered callback function ta ask for more mp3 data */ | ||
289 | static void (*callback_for_more)(unsigned char**, int*); | ||
290 | |||
291 | #pragma interrupt | ||
292 | void DEI3(void) | ||
293 | { | ||
294 | unsigned char* start; | ||
295 | int size = 0; | ||
296 | |||
297 | if (callback_for_more != NULL) | ||
298 | { | ||
299 | callback_for_more(&start, &size); | ||
300 | } | ||
301 | |||
302 | if (size > 0) | ||
303 | { | ||
304 | DTCR3 = size & 0xffff; | ||
305 | SAR3 = (unsigned int) start; | ||
306 | } | ||
307 | else | ||
308 | { | ||
309 | CHCR3 &= ~0x0001; /* Disable the DMA interrupt */ | ||
310 | } | ||
311 | |||
312 | CHCR3 &= ~0x0002; /* Clear DMA interrupt */ | ||
313 | } | ||
314 | |||
315 | #pragma interrupt | ||
316 | void IRQ6(void) /* PB14: MAS stop demand IRQ */ | ||
317 | { | ||
318 | mp3_play_pause(false); | ||
319 | } | ||
320 | |||
321 | static void setup_sci0(void) | ||
322 | { | ||
323 | /* PB15 is I/O, PB14 is IRQ6, PB12 is SCK0, PB9 is TxD0 */ | ||
324 | PBCR1 = (PBCR1 & 0x0cff) | 0x1208; | ||
325 | |||
326 | /* Set PB12 to output */ | ||
327 | or_b(0x10, &PBIORH); | ||
328 | |||
329 | /* Disable serial port */ | ||
330 | SCR0 = 0x00; | ||
331 | |||
332 | /* Synchronous, no prescale */ | ||
333 | SMR0 = 0x80; | ||
334 | |||
335 | /* Set baudrate 1Mbit/s */ | ||
336 | BRR0 = 0x03; | ||
337 | |||
338 | /* use SCK as serial clock output */ | ||
339 | SCR0 = 0x01; | ||
340 | |||
341 | /* Clear FER and PER */ | ||
342 | SSR0 &= 0xe7; | ||
343 | |||
344 | /* Set interrupt ITU2 and SCI0 priority to 0 */ | ||
345 | IPRD &= 0x0ff0; | ||
346 | |||
347 | /* set PB15 and PB14 to inputs */ | ||
348 | and_b(~0x80, &PBIORH); | ||
349 | and_b(~0x40, &PBIORH); | ||
350 | |||
351 | /* Enable End of DMA interrupt at prio 8 */ | ||
352 | IPRC = (IPRC & 0xf0ff) | 0x0800; | ||
353 | |||
354 | /* Enable Tx (only!) */ | ||
355 | SCR0 |= 0x20; | ||
356 | } | ||
357 | #endif /* SIMULATOR */ | ||
358 | |||
359 | #ifdef HAVE_MAS3587F | ||
360 | static void init_playback(void) | ||
361 | { | ||
362 | unsigned long val; | ||
363 | int rc; | ||
364 | |||
365 | mp3_play_pause(false); | ||
366 | |||
367 | mas_reset(); | ||
368 | |||
369 | /* Enable the audio CODEC and the DSP core, max analog voltage range */ | ||
370 | rc = mas_direct_config_write(MAS_CONTROL, 0x8c00); | ||
371 | if(rc < 0) | ||
372 | panicf("mas_ctrl_w: %d", rc); | ||
373 | |||
374 | /* Stop the current application */ | ||
375 | val = 0; | ||
376 | mas_writemem(MAS_BANK_D0,0x7f6,&val,1); | ||
377 | do | ||
378 | { | ||
379 | mas_readmem(MAS_BANK_D0, 0x7f7, &val, 1); | ||
380 | } while(val); | ||
381 | |||
382 | /* Enable the D/A Converter */ | ||
383 | mas_codec_writereg(0x0, 0x0001); | ||
384 | |||
385 | /* ADC scale 0%, DSP scale 100% */ | ||
386 | mas_codec_writereg(6, 0x0000); | ||
387 | mas_codec_writereg(7, 0x4000); | ||
388 | |||
389 | /* Disable SDO and SDI */ | ||
390 | val = 0x0d; | ||
391 | mas_writemem(MAS_BANK_D0,0x7f2,&val,1); | ||
392 | |||
393 | /* Set Demand mode and validate all settings */ | ||
394 | val = 0x25; | ||
395 | mas_writemem(MAS_BANK_D0,0x7f1,&val,1); | ||
396 | |||
397 | /* Start the Layer2/3 decoder applications */ | ||
398 | val = 0x0c; | ||
399 | mas_writemem(MAS_BANK_D0,0x7f6,&val,1); | ||
400 | do | ||
401 | { | ||
402 | mas_readmem(MAS_BANK_D0, 0x7f7, &val, 1); | ||
403 | } while((val & 0x0c) != 0x0c); | ||
404 | |||
405 | mpeg_sound_channel_config(MPEG_SOUND_STEREO); | ||
406 | |||
407 | /* set IRQ6 to edge detect */ | ||
408 | ICR |= 0x02; | ||
409 | |||
410 | /* set IRQ6 prio 8 */ | ||
411 | IPRB = ( IPRB & 0xff0f ) | 0x0080; | ||
412 | |||
413 | DEBUGF("MAS Decoding application started\n"); | ||
414 | } | ||
415 | #endif /* #ifdef HAVE_MAS3587F */ | ||
416 | |||
417 | #ifndef SIMULATOR | ||
418 | #ifdef HAVE_MAS3507D | ||
419 | int current_left_volume = 0; /* all values in tenth of dB */ | ||
420 | int current_right_volume = 0; /* all values in tenth of dB */ | ||
421 | int current_treble = 0; | ||
422 | int current_bass = 0; | ||
423 | int current_balance = 0; | ||
424 | |||
425 | /* convert tenth of dB volume to register value */ | ||
426 | static int tenthdb2reg(int db) { | ||
427 | if (db < -540) | ||
428 | return (db + 780) / 30; | ||
429 | else | ||
430 | return (db + 660) / 15; | ||
431 | } | ||
432 | |||
433 | void set_prescaled_volume(void) | ||
434 | { | ||
435 | int prescale; | ||
436 | int l, r; | ||
437 | |||
438 | prescale = MAX(current_bass, current_treble); | ||
439 | if (prescale < 0) | ||
440 | prescale = 0; /* no need to prescale if we don't boost | ||
441 | bass or treble */ | ||
442 | |||
443 | mas_writereg(MAS_REG_KPRESCALE, prescale_table[prescale/10]); | ||
444 | |||
445 | /* gain up the analog volume to compensate the prescale reduction gain */ | ||
446 | l = current_left_volume + prescale; | ||
447 | r = current_right_volume + prescale; | ||
448 | |||
449 | dac_volume(tenthdb2reg(l), tenthdb2reg(r), false); | ||
450 | } | ||
451 | #endif /* HAVE_MAS3507D */ | ||
452 | #endif /* !SIMULATOR */ | ||
453 | |||
454 | void mpeg_sound_set(int setting, int value) | ||
455 | { | ||
456 | #ifdef SIMULATOR | ||
457 | setting = value; | ||
458 | #else | ||
459 | #ifdef HAVE_MAS3507D | ||
460 | int l, r; | ||
461 | #else | ||
462 | int tmp; | ||
463 | #endif | ||
464 | |||
465 | if(!mpeg_is_initialized) | ||
466 | return; | ||
467 | |||
468 | switch(setting) | ||
469 | { | ||
470 | case SOUND_VOLUME: | ||
471 | #ifdef HAVE_MAS3587F | ||
472 | tmp = 0x7f00 * value / 100; | ||
473 | mas_codec_writereg(0x10, tmp & 0xff00); | ||
474 | #else | ||
475 | l = value; | ||
476 | r = value; | ||
477 | |||
478 | if(current_balance > 0) | ||
479 | { | ||
480 | l -= current_balance; | ||
481 | if(l < 0) | ||
482 | l = 0; | ||
483 | } | ||
484 | |||
485 | if(current_balance < 0) | ||
486 | { | ||
487 | r += current_balance; | ||
488 | if(r < 0) | ||
489 | r = 0; | ||
490 | } | ||
491 | |||
492 | l = 0x38 * l / 100; | ||
493 | r = 0x38 * r / 100; | ||
494 | |||
495 | /* store volume in tenth of dB */ | ||
496 | current_left_volume = ( l < 0x08 ? l*30 - 780 : l*15 - 660 ); | ||
497 | current_right_volume = ( r < 0x08 ? r*30 - 780 : r*15 - 660 ); | ||
498 | |||
499 | set_prescaled_volume(); | ||
500 | #endif | ||
501 | break; | ||
502 | |||
503 | case SOUND_BALANCE: | ||
504 | #ifdef HAVE_MAS3587F | ||
505 | tmp = ((value * 127 / 100) & 0xff) << 8; | ||
506 | mas_codec_writereg(0x11, tmp & 0xff00); | ||
507 | #else | ||
508 | /* Convert to percent */ | ||
509 | current_balance = value * 2; | ||
510 | #endif | ||
511 | break; | ||
512 | |||
513 | case SOUND_BASS: | ||
514 | #ifdef HAVE_MAS3587F | ||
515 | tmp = (((value-12) * 8) & 0xff) << 8; | ||
516 | mas_codec_writereg(0x14, tmp & 0xff00); | ||
517 | #else | ||
518 | mas_writereg(MAS_REG_KBASS, bass_table[value]); | ||
519 | current_bass = (value-15) * 10; | ||
520 | set_prescaled_volume(); | ||
521 | #endif | ||
522 | break; | ||
523 | |||
524 | case SOUND_TREBLE: | ||
525 | #ifdef HAVE_MAS3587F | ||
526 | tmp = (((value-12) * 8) & 0xff) << 8; | ||
527 | mas_codec_writereg(0x15, tmp & 0xff00); | ||
528 | #else | ||
529 | mas_writereg(MAS_REG_KTREBLE, treble_table[value]); | ||
530 | current_treble = (value-15) * 10; | ||
531 | set_prescaled_volume(); | ||
532 | #endif | ||
533 | break; | ||
534 | |||
535 | #ifdef HAVE_MAS3587F | ||
536 | case SOUND_SUPERBASS: | ||
537 | if (value) { | ||
538 | tmp = MAX(MIN(value * 12, 0x7f), 0); | ||
539 | mas_codec_writereg(MAS_REG_KMDB_STR, (tmp & 0xff) << 8); | ||
540 | tmp = 0x30; /* MDB_HAR: Space for experiment here */ | ||
541 | mas_codec_writereg(MAS_REG_KMDB_HAR, (tmp & 0xff) << 8); | ||
542 | tmp = 60 / 10; /* calculate MDB_FC, 60hz - experiment here, | ||
543 | this would depend on the earphones... | ||
544 | perhaps make it tunable? */ | ||
545 | mas_codec_writereg(MAS_REG_KMDB_FC, (tmp & 0xff) << 8); | ||
546 | tmp = (3 * tmp) / 2; /* calculate MDB_SHAPE */ | ||
547 | mas_codec_writereg(MAS_REG_KMDB_SWITCH, | ||
548 | ((tmp & 0xff) << 8) /* MDB_SHAPE */ | ||
549 | | 2); /* MDB_SWITCH enable */ | ||
550 | } else { | ||
551 | mas_codec_writereg(MAS_REG_KMDB_STR, 0); | ||
552 | mas_codec_writereg(MAS_REG_KMDB_HAR, 0); | ||
553 | mas_codec_writereg(MAS_REG_KMDB_SWITCH, 0); /* MDB_SWITCH disable */ | ||
554 | } | ||
555 | break; | ||
556 | |||
557 | case SOUND_LOUDNESS: | ||
558 | tmp = MAX(MIN(value * 4, 0x44), 0); | ||
559 | mas_codec_writereg(MAS_REG_KLOUDNESS, (tmp & 0xff) << 8); | ||
560 | break; | ||
561 | |||
562 | case SOUND_AVC: | ||
563 | switch (value) { | ||
564 | case 1: /* 2s */ | ||
565 | tmp = (0x2 << 8) | (0x8 << 12); | ||
566 | break; | ||
567 | case 2: /* 4s */ | ||
568 | tmp = (0x4 << 8) | (0x8 << 12); | ||
569 | break; | ||
570 | case 3: /* 8s */ | ||
571 | tmp = (0x8 << 8) | (0x8 << 12); | ||
572 | break; | ||
573 | case -1: /* turn off and then turn on again to decay quickly */ | ||
574 | tmp = mas_codec_readreg(MAS_REG_KAVC); | ||
575 | mas_codec_writereg(MAS_REG_KAVC, 0); | ||
576 | break; | ||
577 | default: /* off */ | ||
578 | tmp = 0; | ||
579 | break; | ||
580 | } | ||
581 | mas_codec_writereg(MAS_REG_KAVC, tmp); | ||
582 | break; | ||
583 | #endif | ||
584 | case SOUND_CHANNELS: | ||
585 | mpeg_sound_channel_config(value); | ||
586 | break; | ||
587 | } | ||
588 | #endif /* SIMULATOR */ | ||
589 | } | ||
590 | |||
591 | int mpeg_val2phys(int setting, int value) | ||
592 | { | ||
593 | int result = 0; | ||
594 | |||
595 | switch(setting) | ||
596 | { | ||
597 | case SOUND_VOLUME: | ||
598 | result = value; | ||
599 | break; | ||
600 | |||
601 | case SOUND_BALANCE: | ||
602 | result = value * 2; | ||
603 | break; | ||
604 | |||
605 | case SOUND_BASS: | ||
606 | #ifdef HAVE_MAS3587F | ||
607 | result = value - 12; | ||
608 | #else | ||
609 | result = value - 15; | ||
610 | #endif | ||
611 | break; | ||
612 | |||
613 | case SOUND_TREBLE: | ||
614 | #ifdef HAVE_MAS3587F | ||
615 | result = value - 12; | ||
616 | #else | ||
617 | result = value - 15; | ||
618 | #endif | ||
619 | break; | ||
620 | |||
621 | #ifdef HAVE_MAS3587F | ||
622 | case SOUND_LOUDNESS: | ||
623 | result = value; | ||
624 | break; | ||
625 | |||
626 | case SOUND_SUPERBASS: | ||
627 | result = value * 10; | ||
628 | break; | ||
629 | |||
630 | case SOUND_LEFT_GAIN: | ||
631 | case SOUND_RIGHT_GAIN: | ||
632 | result = (value - 2) * 15; | ||
633 | break; | ||
634 | |||
635 | case SOUND_MIC_GAIN: | ||
636 | result = value * 15 + 210; | ||
637 | break; | ||
638 | #endif | ||
639 | } | ||
640 | return result; | ||
641 | } | ||
642 | |||
643 | int mpeg_phys2val(int setting, int value) | ||
644 | { | ||
645 | int result = 0; | ||
646 | |||
647 | switch(setting) | ||
648 | { | ||
649 | case SOUND_VOLUME: | ||
650 | result = value; | ||
651 | break; | ||
652 | |||
653 | case SOUND_BALANCE: | ||
654 | result = value / 2; | ||
655 | break; | ||
656 | |||
657 | case SOUND_BASS: | ||
658 | #ifdef HAVE_MAS3587F | ||
659 | result = value + 12; | ||
660 | #else | ||
661 | result = value + 15; | ||
662 | #endif | ||
663 | break; | ||
664 | |||
665 | case SOUND_TREBLE: | ||
666 | #ifdef HAVE_MAS3587F | ||
667 | result = value + 12; | ||
668 | #else | ||
669 | result = value + 15; | ||
670 | #endif | ||
671 | break; | ||
672 | |||
673 | #ifdef HAVE_MAS3587F | ||
674 | case SOUND_SUPERBASS: | ||
675 | result = value / 10; | ||
676 | break; | ||
677 | |||
678 | case SOUND_LOUDNESS: | ||
679 | case SOUND_AVC: | ||
680 | case SOUND_LEFT_GAIN: | ||
681 | case SOUND_RIGHT_GAIN: | ||
682 | case SOUND_MIC_GAIN: | ||
683 | result = value; | ||
684 | break; | ||
685 | #endif | ||
686 | } | ||
687 | |||
688 | return result; | ||
689 | } | ||
690 | |||
691 | |||
692 | void mpeg_sound_channel_config(int configuration) | ||
693 | { | ||
694 | #ifdef SIMULATOR | ||
695 | (void)configuration; | ||
696 | #else | ||
697 | unsigned long val_ll = 0x80000; | ||
698 | unsigned long val_lr = 0; | ||
699 | unsigned long val_rl = 0; | ||
700 | unsigned long val_rr = 0x80000; | ||
701 | |||
702 | switch(configuration) | ||
703 | { | ||
704 | case MPEG_SOUND_STEREO: | ||
705 | val_ll = 0x80000; | ||
706 | val_lr = 0; | ||
707 | val_rl = 0; | ||
708 | val_rr = 0x80000; | ||
709 | break; | ||
710 | |||
711 | case MPEG_SOUND_MONO: | ||
712 | val_ll = 0xc0000; | ||
713 | val_lr = 0xc0000; | ||
714 | val_rl = 0xc0000; | ||
715 | val_rr = 0xc0000; | ||
716 | break; | ||
717 | |||
718 | case MPEG_SOUND_MONO_LEFT: | ||
719 | val_ll = 0x80000; | ||
720 | val_lr = 0x80000; | ||
721 | val_rl = 0; | ||
722 | val_rr = 0; | ||
723 | break; | ||
724 | |||
725 | case MPEG_SOUND_MONO_RIGHT: | ||
726 | val_ll = 0; | ||
727 | val_lr = 0; | ||
728 | val_rl = 0x80000; | ||
729 | val_rr = 0x80000; | ||
730 | break; | ||
731 | |||
732 | case MPEG_SOUND_STEREO_NARROW: | ||
733 | val_ll = 0xa0000; | ||
734 | val_lr = 0xe0000; | ||
735 | val_rl = 0xe0000; | ||
736 | val_rr = 0xa0000; | ||
737 | break; | ||
738 | |||
739 | case MPEG_SOUND_STEREO_WIDE: | ||
740 | val_ll = 0x80000; | ||
741 | val_lr = 0x40000; | ||
742 | val_rl = 0x40000; | ||
743 | val_rr = 0x80000; | ||
744 | break; | ||
745 | |||
746 | case MPEG_SOUND_KARAOKE: | ||
747 | val_ll = 0x80001; | ||
748 | val_lr = 0x7ffff; | ||
749 | val_rl = 0x7ffff; | ||
750 | val_rr = 0x80001; | ||
751 | break; | ||
752 | } | ||
753 | |||
754 | #ifdef HAVE_MAS3587F | ||
755 | mas_writemem(MAS_BANK_D0, 0x7fc, &val_ll, 1); /* LL */ | ||
756 | mas_writemem(MAS_BANK_D0, 0x7fd, &val_lr, 1); /* LR */ | ||
757 | mas_writemem(MAS_BANK_D0, 0x7fe, &val_rl, 1); /* RL */ | ||
758 | mas_writemem(MAS_BANK_D0, 0x7ff, &val_rr, 1); /* RR */ | ||
759 | #else | ||
760 | mas_writemem(MAS_BANK_D1, 0x7f8, &val_ll, 1); /* LL */ | ||
761 | mas_writemem(MAS_BANK_D1, 0x7f9, &val_lr, 1); /* LR */ | ||
762 | mas_writemem(MAS_BANK_D1, 0x7fa, &val_rl, 1); /* RL */ | ||
763 | mas_writemem(MAS_BANK_D1, 0x7fb, &val_rr, 1); /* RR */ | ||
764 | #endif | ||
765 | #endif | ||
766 | } | ||
767 | |||
768 | #ifdef HAVE_MAS3587F | ||
769 | /* This function works by telling the decoder that we have another | ||
770 | crystal frequency than we actually have. It will adjust its internal | ||
771 | parameters and the result is that the audio is played at another pitch. | ||
772 | |||
773 | The pitch value is in tenths of percent. | ||
774 | */ | ||
775 | void mpeg_set_pitch(int pitch) | ||
776 | { | ||
777 | unsigned long val; | ||
778 | |||
779 | /* invert pitch value */ | ||
780 | pitch = 1000000/pitch; | ||
781 | |||
782 | /* Calculate the new (bogus) frequency */ | ||
783 | val = 18432*pitch/1000; | ||
784 | |||
785 | mas_writemem(MAS_BANK_D0,0x7f3,&val,1); | ||
786 | |||
787 | /* We must tell the MAS that the frequency has changed. | ||
788 | This will unfortunately cause a short silence. */ | ||
789 | val = 0x25; | ||
790 | mas_writemem(MAS_BANK_D0,0x7f1,&val,1); | ||
791 | } | ||
792 | #endif | ||
793 | |||
794 | void mp3_init(int volume, int bass, int treble, int balance, int loudness, | ||
795 | int bass_boost, int avc, int channel_config) | ||
796 | { | ||
797 | #ifdef SIMULATOR | ||
798 | volume = bass = treble = balance = loudness | ||
799 | = bass_boost = avc = channel_config; | ||
800 | #else | ||
801 | #ifdef HAVE_MAS3507D | ||
802 | unsigned long val; | ||
803 | loudness = bass_boost = avc; | ||
804 | #endif | ||
805 | |||
806 | setup_sci0(); | ||
807 | |||
808 | #ifdef HAVE_MAS3587F | ||
809 | or_b(0x08, &PAIORH); /* output for /PR */ | ||
810 | init_playback(); | ||
811 | |||
812 | mas_version_code = mas_readver(); | ||
813 | DEBUGF("MAS3587 derivate %d, version B%d\n", | ||
814 | (mas_version_code & 0xff00) >> 8, mas_version_code & 0xff); | ||
815 | #endif | ||
816 | |||
817 | #ifdef HAVE_DAC3550A | ||
818 | dac_init(); | ||
819 | #endif | ||
820 | |||
821 | #ifdef HAVE_MAS3507D | ||
822 | and_b(~0x20, &PBDRL); | ||
823 | sleep(HZ/5); | ||
824 | or_b(0x20, &PBDRL); | ||
825 | sleep(HZ/5); | ||
826 | |||
827 | /* set IRQ6 to edge detect */ | ||
828 | ICR |= 0x02; | ||
829 | |||
830 | /* set IRQ6 prio 8 */ | ||
831 | IPRB = ( IPRB & 0xff0f ) | 0x0080; | ||
832 | |||
833 | mas_readmem(MAS_BANK_D1, 0xff7, &mas_version_code, 1); | ||
834 | |||
835 | mas_writereg(0x3b, 0x20); /* Don't ask why. The data sheet doesn't say */ | ||
836 | mas_run(1); | ||
837 | sleep(HZ); | ||
838 | |||
839 | /* Clear the upper 12 bits of the 32-bit samples */ | ||
840 | mas_writereg(0xc5, 0); | ||
841 | mas_writereg(0xc6, 0); | ||
842 | |||
843 | /* We need to set the PLL for a 14.1318MHz crystal */ | ||
844 | if(mas_version_code == 0x0601) /* Version F10? */ | ||
845 | { | ||
846 | val = 0x5d9d0; | ||
847 | mas_writemem(MAS_BANK_D0, 0x32d, &val, 1); | ||
848 | val = 0xfffceceb; | ||
849 | mas_writemem(MAS_BANK_D0, 0x32e, &val, 1); | ||
850 | val = 0x0; | ||
851 | mas_writemem(MAS_BANK_D0, 0x32f, &val, 1); | ||
852 | mas_run(0x475); | ||
853 | } | ||
854 | else | ||
855 | { | ||
856 | val = 0x5d9d0; | ||
857 | mas_writemem(MAS_BANK_D0, 0x36d, &val, 1); | ||
858 | val = 0xfffceceb; | ||
859 | mas_writemem(MAS_BANK_D0, 0x36e, &val, 1); | ||
860 | val = 0x0; | ||
861 | mas_writemem(MAS_BANK_D0, 0x36f, &val, 1); | ||
862 | mas_run(0xfcb); | ||
863 | } | ||
864 | |||
865 | #endif | ||
866 | |||
867 | #ifdef HAVE_MAS3507D | ||
868 | mas_poll_start(1); | ||
869 | |||
870 | mas_writereg(MAS_REG_KPRESCALE, 0xe9400); | ||
871 | dac_enable(true); | ||
872 | |||
873 | mpeg_sound_channel_config(channel_config); | ||
874 | #endif | ||
875 | |||
876 | #ifdef HAVE_MAS3587F | ||
877 | ICR &= ~0x0010; /* IRQ3 level sensitive */ | ||
878 | PACR1 = (PACR1 & 0x3fff) | 0x4000; /* PA15 is IRQ3 */ | ||
879 | #endif | ||
880 | |||
881 | /* Must be done before calling mpeg_sound_set() */ | ||
882 | mpeg_is_initialized = true; | ||
883 | |||
884 | mpeg_sound_set(SOUND_BASS, bass); | ||
885 | mpeg_sound_set(SOUND_TREBLE, treble); | ||
886 | mpeg_sound_set(SOUND_BALANCE, balance); | ||
887 | mpeg_sound_set(SOUND_VOLUME, volume); | ||
888 | |||
889 | #ifdef HAVE_MAS3587F | ||
890 | mpeg_sound_channel_config(channel_config); | ||
891 | mpeg_sound_set(SOUND_LOUDNESS, loudness); | ||
892 | mpeg_sound_set(SOUND_SUPERBASS, bass_boost); | ||
893 | mpeg_sound_set(SOUND_AVC, avc); | ||
894 | #endif | ||
895 | #endif /* !SIMULATOR */ | ||
896 | } | ||
897 | |||
898 | |||
899 | /* new functions, to be exported to plugin API */ | ||
900 | |||
901 | void mp3_play_init(void) | ||
902 | { | ||
903 | #ifdef HAVE_MAS3587F | ||
904 | init_playback(); | ||
905 | #endif | ||
906 | callback_for_more = NULL; | ||
907 | } | ||
908 | |||
909 | void mp3_play_data(unsigned char* start, int size, | ||
910 | void (*get_more)(unsigned char** start, int* size) /* callback fn */ | ||
911 | ) | ||
912 | { | ||
913 | /* init DMA */ | ||
914 | DAR3 = 0x5FFFEC3; | ||
915 | CHCR3 &= ~0x0002; /* Clear interrupt */ | ||
916 | CHCR3 = 0x1504; /* Single address destination, TXI0, IE=1 */ | ||
917 | DMAOR = 0x0001; /* Enable DMA */ | ||
918 | |||
919 | callback_for_more = get_more; | ||
920 | |||
921 | SAR3 = (unsigned int)start; | ||
922 | DTCR3 = size & 0xffff; | ||
923 | |||
924 | CHCR3 |= 0x0001; /* Enable DMA IRQ */ | ||
925 | } | ||
926 | |||
927 | void mp3_play_pause(bool play) | ||
928 | { | ||
929 | if (play) | ||
930 | SCR0 |= 0x80; | ||
931 | else | ||
932 | SCR0 &= 0x7f; | ||
933 | } | ||
934 | |||
935 | void mp3_play_stop(void) | ||
936 | { | ||
937 | mp3_play_pause(false); | ||
938 | CHCR3 &= ~0x0001; /* Disable the DMA interrupt */ | ||
939 | } | ||
diff --git a/firmware/mpeg.c b/firmware/mpeg.c index 43da221800..1dd489a290 100644 --- a/firmware/mpeg.c +++ b/firmware/mpeg.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "errno.h" | 29 | #include "errno.h" |
30 | #include "mp3data.h" | 30 | #include "mp3data.h" |
31 | #include "buffer.h" | 31 | #include "buffer.h" |
32 | #include "mp3_playback.h" | ||
32 | #ifndef SIMULATOR | 33 | #ifndef SIMULATOR |
33 | #include "i2c.h" | 34 | #include "i2c.h" |
34 | #include "mas.h" | 35 | #include "mas.h" |
@@ -43,7 +44,6 @@ extern void bitswap(unsigned char *data, int length); | |||
43 | 44 | ||
44 | #ifdef HAVE_MAS3587F | 45 | #ifdef HAVE_MAS3587F |
45 | static void init_recording(void); | 46 | static void init_recording(void); |
46 | static void init_playback(void); | ||
47 | static void start_prerecording(void); | 47 | static void start_prerecording(void); |
48 | static void start_recording(void); | 48 | static void start_recording(void); |
49 | static void stop_recording(void); | 49 | static void stop_recording(void); |
@@ -87,116 +87,6 @@ extern int playlist_next(int steps); | |||
87 | extern int playlist_amount(void); | 87 | extern int playlist_amount(void); |
88 | extern void update_file_pos( int id, int pos ); | 88 | extern void update_file_pos( int id, int pos ); |
89 | 89 | ||
90 | static char *units[] = | ||
91 | { | ||
92 | "%", /* Volume */ | ||
93 | "dB", /* Bass */ | ||
94 | "dB", /* Treble */ | ||
95 | "%", /* Balance */ | ||
96 | "dB", /* Loudness */ | ||
97 | "%", /* Bass boost */ | ||
98 | "", /* AVC */ | ||
99 | "", /* Channels */ | ||
100 | "dB", /* Left gain */ | ||
101 | "dB", /* Right gain */ | ||
102 | "dB", /* Mic gain */ | ||
103 | }; | ||
104 | |||
105 | static int numdecimals[] = | ||
106 | { | ||
107 | 0, /* Volume */ | ||
108 | 0, /* Bass */ | ||
109 | 0, /* Treble */ | ||
110 | 0, /* Balance */ | ||
111 | 0, /* Loudness */ | ||
112 | 0, /* Bass boost */ | ||
113 | 0, /* AVC */ | ||
114 | 0, /* Channels */ | ||
115 | 1, /* Left gain */ | ||
116 | 1, /* Right gain */ | ||
117 | 1, /* Mic gain */ | ||
118 | }; | ||
119 | |||
120 | static int minval[] = | ||
121 | { | ||
122 | 0, /* Volume */ | ||
123 | 0, /* Bass */ | ||
124 | 0, /* Treble */ | ||
125 | -50, /* Balance */ | ||
126 | 0, /* Loudness */ | ||
127 | 0, /* Bass boost */ | ||
128 | -1, /* AVC */ | ||
129 | 0, /* Channels */ | ||
130 | 0, /* Left gain */ | ||
131 | 0, /* Right gain */ | ||
132 | 0, /* Mic gain */ | ||
133 | }; | ||
134 | |||
135 | static int maxval[] = | ||
136 | { | ||
137 | 100, /* Volume */ | ||
138 | #ifdef HAVE_MAS3587F | ||
139 | 24, /* Bass */ | ||
140 | 24, /* Treble */ | ||
141 | #else | ||
142 | 30, /* Bass */ | ||
143 | 30, /* Treble */ | ||
144 | #endif | ||
145 | 50, /* Balance */ | ||
146 | 17, /* Loudness */ | ||
147 | 10, /* Bass boost */ | ||
148 | 3, /* AVC */ | ||
149 | 6, /* Channels */ | ||
150 | 15, /* Left gain */ | ||
151 | 15, /* Right gain */ | ||
152 | 15, /* Mic gain */ | ||
153 | }; | ||
154 | |||
155 | static int defaultval[] = | ||
156 | { | ||
157 | 70, /* Volume */ | ||
158 | #ifdef HAVE_MAS3587F | ||
159 | 12+6, /* Bass */ | ||
160 | 12+6, /* Treble */ | ||
161 | #else | ||
162 | 15+7, /* Bass */ | ||
163 | 15+7, /* Treble */ | ||
164 | #endif | ||
165 | 0, /* Balance */ | ||
166 | 0, /* Loudness */ | ||
167 | 0, /* Bass boost */ | ||
168 | 0, /* AVC */ | ||
169 | 0, /* Channels */ | ||
170 | 8, /* Left gain */ | ||
171 | 8, /* Right gain */ | ||
172 | 2, /* Mic gain */ | ||
173 | }; | ||
174 | |||
175 | char *mpeg_sound_unit(int setting) | ||
176 | { | ||
177 | return units[setting]; | ||
178 | } | ||
179 | |||
180 | int mpeg_sound_numdecimals(int setting) | ||
181 | { | ||
182 | return numdecimals[setting]; | ||
183 | } | ||
184 | |||
185 | int mpeg_sound_min(int setting) | ||
186 | { | ||
187 | return minval[setting]; | ||
188 | } | ||
189 | |||
190 | int mpeg_sound_max(int setting) | ||
191 | { | ||
192 | return maxval[setting]; | ||
193 | } | ||
194 | |||
195 | int mpeg_sound_default(int setting) | ||
196 | { | ||
197 | return defaultval[setting]; | ||
198 | } | ||
199 | |||
200 | /* list of tracks in memory */ | 90 | /* list of tracks in memory */ |
201 | #define MAX_ID3_TAGS (1<<4) /* Must be power of 2 */ | 91 | #define MAX_ID3_TAGS (1<<4) /* Must be power of 2 */ |
202 | #define MAX_ID3_TAGS_MASK (MAX_ID3_TAGS - 1) | 92 | #define MAX_ID3_TAGS_MASK (MAX_ID3_TAGS - 1) |
@@ -216,8 +106,6 @@ static unsigned int last_track_counter = 0; | |||
216 | 106 | ||
217 | #ifndef SIMULATOR | 107 | #ifndef SIMULATOR |
218 | 108 | ||
219 | static bool mpeg_is_initialized = false; | ||
220 | |||
221 | static int tag_read_idx = 0; | 109 | static int tag_read_idx = 0; |
222 | static int tag_write_idx = 0; | 110 | static int tag_write_idx = 0; |
223 | 111 | ||
@@ -371,100 +259,7 @@ static bool playing = false; | |||
371 | #else | 259 | #else |
372 | static int last_dma_tick = 0; | 260 | static int last_dma_tick = 0; |
373 | 261 | ||
374 | static unsigned long mas_version_code; | 262 | extern unsigned long mas_version_code; |
375 | |||
376 | #ifdef HAVE_MAS3507D | ||
377 | |||
378 | static unsigned int bass_table[] = | ||
379 | { | ||
380 | 0x9e400, /* -15dB */ | ||
381 | 0xa2800, /* -14dB */ | ||
382 | 0xa7400, /* -13dB */ | ||
383 | 0xac400, /* -12dB */ | ||
384 | 0xb1800, /* -11dB */ | ||
385 | 0xb7400, /* -10dB */ | ||
386 | 0xbd400, /* -9dB */ | ||
387 | 0xc3c00, /* -8dB */ | ||
388 | 0xca400, /* -7dB */ | ||
389 | 0xd1800, /* -6dB */ | ||
390 | 0xd8c00, /* -5dB */ | ||
391 | 0xe0400, /* -4dB */ | ||
392 | 0xe8000, /* -3dB */ | ||
393 | 0xefc00, /* -2dB */ | ||
394 | 0xf7c00, /* -1dB */ | ||
395 | 0, | ||
396 | 0x800, /* 1dB */ | ||
397 | 0x10000, /* 2dB */ | ||
398 | 0x17c00, /* 3dB */ | ||
399 | 0x1f800, /* 4dB */ | ||
400 | 0x27000, /* 5dB */ | ||
401 | 0x2e400, /* 6dB */ | ||
402 | 0x35800, /* 7dB */ | ||
403 | 0x3c000, /* 8dB */ | ||
404 | 0x42800, /* 9dB */ | ||
405 | 0x48800, /* 10dB */ | ||
406 | 0x4e400, /* 11dB */ | ||
407 | 0x53800, /* 12dB */ | ||
408 | 0x58800, /* 13dB */ | ||
409 | 0x5d400, /* 14dB */ | ||
410 | 0x61800 /* 15dB */ | ||
411 | }; | ||
412 | |||
413 | static unsigned int treble_table[] = | ||
414 | { | ||
415 | 0xb2c00, /* -15dB */ | ||
416 | 0xbb400, /* -14dB */ | ||
417 | 0xc1800, /* -13dB */ | ||
418 | 0xc6c00, /* -12dB */ | ||
419 | 0xcbc00, /* -11dB */ | ||
420 | 0xd0400, /* -10dB */ | ||
421 | 0xd5000, /* -9dB */ | ||
422 | 0xd9800, /* -8dB */ | ||
423 | 0xde000, /* -7dB */ | ||
424 | 0xe2800, /* -6dB */ | ||
425 | 0xe7e00, /* -5dB */ | ||
426 | 0xec000, /* -4dB */ | ||
427 | 0xf0c00, /* -3dB */ | ||
428 | 0xf5c00, /* -2dB */ | ||
429 | 0xfac00, /* -1dB */ | ||
430 | 0, | ||
431 | 0x5400, /* 1dB */ | ||
432 | 0xac00, /* 2dB */ | ||
433 | 0x10400, /* 3dB */ | ||
434 | 0x16000, /* 4dB */ | ||
435 | 0x1c000, /* 5dB */ | ||
436 | 0x22400, /* 6dB */ | ||
437 | 0x28400, /* 7dB */ | ||
438 | 0x2ec00, /* 8dB */ | ||
439 | 0x35400, /* 9dB */ | ||
440 | 0x3c000, /* 10dB */ | ||
441 | 0x42c00, /* 11dB */ | ||
442 | 0x49c00, /* 12dB */ | ||
443 | 0x51800, /* 13dB */ | ||
444 | 0x58400, /* 14dB */ | ||
445 | 0x5f800 /* 15dB */ | ||
446 | }; | ||
447 | |||
448 | static unsigned int prescale_table[] = | ||
449 | { | ||
450 | 0x80000, /* 0db */ | ||
451 | 0x8e000, /* 1dB */ | ||
452 | 0x9a400, /* 2dB */ | ||
453 | 0xa5800, /* 3dB */ | ||
454 | 0xaf400, /* 4dB */ | ||
455 | 0xb8000, /* 5dB */ | ||
456 | 0xbfc00, /* 6dB */ | ||
457 | 0xc6c00, /* 7dB */ | ||
458 | 0xcd000, /* 8dB */ | ||
459 | 0xd25c0, /* 9dB */ | ||
460 | 0xd7800, /* 10dB */ | ||
461 | 0xdc000, /* 11dB */ | ||
462 | 0xdfc00, /* 12dB */ | ||
463 | 0xe3400, /* 13dB */ | ||
464 | 0xe6800, /* 14dB */ | ||
465 | 0xe9400 /* 15dB */ | ||
466 | }; | ||
467 | #endif | ||
468 | 263 | ||
469 | static struct event_queue mpeg_queue; | 264 | static struct event_queue mpeg_queue; |
470 | static char mpeg_stack[DEFAULT_STACK_SIZE + 0x1000]; | 265 | static char mpeg_stack[DEFAULT_STACK_SIZE + 0x1000]; |
@@ -477,7 +272,6 @@ static int mp3buf_read; | |||
477 | 272 | ||
478 | static int last_dma_chunk_size; | 273 | static int last_dma_chunk_size; |
479 | 274 | ||
480 | static bool dma_on; /* The DMA is active */ | ||
481 | static bool playing; /* We are playing an MP3 stream */ | 275 | static bool playing; /* We are playing an MP3 stream */ |
482 | static bool play_pending; /* We are about to start playing */ | 276 | static bool play_pending; /* We are about to start playing */ |
483 | static bool is_playing; /* We are (attempting to) playing MP3 files */ | 277 | static bool is_playing; /* We are (attempting to) playing MP3 files */ |
@@ -562,7 +356,7 @@ void mpeg_get_debugdata(struct mpeg_debug *dbgdata) | |||
562 | 356 | ||
563 | dbgdata->last_dma_chunk_size = last_dma_chunk_size; | 357 | dbgdata->last_dma_chunk_size = last_dma_chunk_size; |
564 | 358 | ||
565 | dbgdata->dma_on = dma_on; | 359 | dbgdata->dma_on = (SCR0 & 0x80) != 0; |
566 | dbgdata->playing = playing; | 360 | dbgdata->playing = playing; |
567 | dbgdata->play_pending = play_pending; | 361 | dbgdata->play_pending = play_pending; |
568 | dbgdata->is_playing = is_playing; | 362 | dbgdata->is_playing = is_playing; |
@@ -577,39 +371,7 @@ void mpeg_get_debugdata(struct mpeg_debug *dbgdata) | |||
577 | dbgdata->lowest_watermark_level = lowest_watermark_level; | 371 | dbgdata->lowest_watermark_level = lowest_watermark_level; |
578 | } | 372 | } |
579 | 373 | ||
580 | #ifdef HAVE_MAS3507D | 374 | #ifndef HAVE_MAS3507D |
581 | static void mas_poll_start(int interval_in_ms) | ||
582 | { | ||
583 | unsigned int count; | ||
584 | |||
585 | count = (FREQ * interval_in_ms) / 1000 / 8; | ||
586 | |||
587 | if(count > 0xffff) | ||
588 | { | ||
589 | panicf("Error! The MAS poll interval is too long (%d ms)\n", | ||
590 | interval_in_ms); | ||
591 | return; | ||
592 | } | ||
593 | |||
594 | /* We are using timer 1 */ | ||
595 | |||
596 | TSTR &= ~0x02; /* Stop the timer */ | ||
597 | TSNC &= ~0x02; /* No synchronization */ | ||
598 | TMDR &= ~0x02; /* Operate normally */ | ||
599 | |||
600 | TCNT1 = 0; /* Start counting at 0 */ | ||
601 | GRA1 = count; | ||
602 | TCR1 = 0x23; /* Clear at GRA match, sysclock/8 */ | ||
603 | |||
604 | /* Enable interrupt on level 5 */ | ||
605 | IPRC = (IPRC & ~0x000f) | 0x0005; | ||
606 | |||
607 | TSR1 &= ~0x02; | ||
608 | TIER1 = 0xf9; /* Enable GRA match interrupt */ | ||
609 | |||
610 | TSTR |= 0x02; /* Start timer 1 */ | ||
611 | } | ||
612 | #else | ||
613 | static void postpone_dma_tick(void) | 375 | static void postpone_dma_tick(void) |
614 | { | 376 | { |
615 | unsigned int count; | 377 | unsigned int count; |
@@ -712,31 +474,6 @@ static int get_unsaved_space(void) | |||
712 | } | 474 | } |
713 | #endif | 475 | #endif |
714 | 476 | ||
715 | static void init_dma(void) | ||
716 | { | ||
717 | SAR3 = (unsigned int) mp3buf + mp3buf_read; | ||
718 | DAR3 = 0x5FFFEC3; | ||
719 | CHCR3 &= ~0x0002; /* Clear interrupt */ | ||
720 | CHCR3 = 0x1504; /* Single address destination, TXI0, IE=1 */ | ||
721 | last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song()); | ||
722 | DTCR3 = last_dma_chunk_size & 0xffff; | ||
723 | DMAOR = 0x0001; /* Enable DMA */ | ||
724 | CHCR3 |= 0x0001; /* Enable DMA IRQ */ | ||
725 | dma_underrun = false; | ||
726 | } | ||
727 | |||
728 | static void start_dma(void) | ||
729 | { | ||
730 | SCR0 |= 0x80; | ||
731 | dma_on = true; | ||
732 | } | ||
733 | |||
734 | static void stop_dma(void) | ||
735 | { | ||
736 | SCR0 &= 0x7f; | ||
737 | dma_on = false; | ||
738 | } | ||
739 | |||
740 | #ifdef HAVE_MAS3587F | 477 | #ifdef HAVE_MAS3587F |
741 | #ifdef DEBUG | 478 | #ifdef DEBUG |
742 | static long timing_info_index = 0; | 479 | static long timing_info_index = 0; |
@@ -746,7 +483,7 @@ static bool inverted_pr; | |||
746 | static unsigned long num_rec_bytes; | 483 | static unsigned long num_rec_bytes; |
747 | static unsigned long num_recorded_frames; | 484 | static unsigned long num_recorded_frames; |
748 | 485 | ||
749 | void drain_dma_buffer(void) | 486 | static void drain_dma_buffer(void) |
750 | { | 487 | { |
751 | if(inverted_pr) | 488 | if(inverted_pr) |
752 | { | 489 | { |
@@ -784,7 +521,8 @@ void drain_dma_buffer(void) | |||
784 | } | 521 | } |
785 | } | 522 | } |
786 | } | 523 | } |
787 | #endif | 524 | |
525 | #endif /* #ifdef HAVE_MAS3587F */ | ||
788 | 526 | ||
789 | static void dma_tick (void) __attribute__ ((section (".icode"))); | 527 | static void dma_tick (void) __attribute__ ((section (".icode"))); |
790 | static void dma_tick(void) | 528 | static void dma_tick(void) |
@@ -796,10 +534,9 @@ static void dma_tick(void) | |||
796 | if(playing && !paused) | 534 | if(playing && !paused) |
797 | { | 535 | { |
798 | /* Start DMA if it is disabled and the DEMAND pin is high */ | 536 | /* Start DMA if it is disabled and the DEMAND pin is high */ |
799 | if(!dma_on && (PBDR & 0x4000)) | 537 | if(!(SCR0 & 0x80) && (PBDR & 0x4000)) |
800 | { | 538 | { |
801 | if(!(SCR0 & 0x80)) | 539 | mp3_play_pause(true); |
802 | start_dma(); | ||
803 | } | 540 | } |
804 | id3tags[tag_read_idx]->id3.elapsed += | 541 | id3tags[tag_read_idx]->id3.elapsed += |
805 | (current_tick - last_dma_tick) * 1000 / HZ; | 542 | (current_tick - last_dma_tick) * 1000 / HZ; |
@@ -807,7 +544,7 @@ static void dma_tick(void) | |||
807 | } | 544 | } |
808 | #ifdef HAVE_MAS3587F | 545 | #ifdef HAVE_MAS3587F |
809 | } | 546 | } |
810 | else | 547 | else /* MPEG_ENCODER */ |
811 | { | 548 | { |
812 | int i; | 549 | int i; |
813 | int num_bytes; | 550 | int num_bytes; |
@@ -845,7 +582,7 @@ static void dma_tick(void) | |||
845 | /* No wait for /RTW, cause it's not necessary */ | 582 | /* No wait for /RTW, cause it's not necessary */ |
846 | } | 583 | } |
847 | } | 584 | } |
848 | else | 585 | else /* !inverted_pr */ |
849 | { | 586 | { |
850 | i = 0; | 587 | i = 0; |
851 | while((*((volatile unsigned char *)PBDR_ADDR) & 0x40) | 588 | while((*((volatile unsigned char *)PBDR_ADDR) & 0x40) |
@@ -923,8 +660,8 @@ static void reset_mp3_buffer(void) | |||
923 | lowest_watermark_level = mp3buflen; | 660 | lowest_watermark_level = mp3buflen; |
924 | } | 661 | } |
925 | 662 | ||
926 | #pragma interrupt | 663 | /* DMA transfer end interrupt callback */ |
927 | void DEI3(void) | 664 | static void transfer_end(unsigned char** ppbuf, int* psize) |
928 | { | 665 | { |
929 | if(playing && !paused) | 666 | if(playing && !paused) |
930 | { | 667 | { |
@@ -976,8 +713,8 @@ void DEI3(void) | |||
976 | } | 713 | } |
977 | } | 714 | } |
978 | 715 | ||
979 | DTCR3 = last_dma_chunk_size & 0xffff; | 716 | *psize = last_dma_chunk_size & 0xffff; |
980 | SAR3 = (unsigned int)mp3buf + mp3buf_read; | 717 | *ppbuf = mp3buf + mp3buf_read; |
981 | id3tags[tag_read_idx]->id3.offset += last_dma_chunk_size; | 718 | id3tags[tag_read_idx]->id3.offset += last_dma_chunk_size; |
982 | 719 | ||
983 | /* Update the watermark debug level */ | 720 | /* Update the watermark debug level */ |
@@ -1007,11 +744,10 @@ void DEI3(void) | |||
1007 | playing = false; | 744 | playing = false; |
1008 | is_playing = false; | 745 | is_playing = false; |
1009 | } | 746 | } |
1010 | CHCR3 &= ~0x0001; /* Disable the DMA interrupt */ | 747 | *psize = 0; /* no more transfer */ |
1011 | } | 748 | } |
1012 | } | 749 | } |
1013 | 750 | ||
1014 | CHCR3 &= ~0x0002; /* Clear DMA interrupt */ | ||
1015 | wake_up_thread(); | 751 | wake_up_thread(); |
1016 | } | 752 | } |
1017 | 753 | ||
@@ -1033,7 +769,7 @@ static void demand_irq_enable(bool on) | |||
1033 | #endif | 769 | #endif |
1034 | 770 | ||
1035 | #pragma interrupt | 771 | #pragma interrupt |
1036 | void IMIA1(void) | 772 | void IMIA1(void) /* Timer 1 interrupt */ |
1037 | { | 773 | { |
1038 | dma_tick(); | 774 | dma_tick(); |
1039 | TSR1 &= ~0x01; | 775 | TSR1 &= ~0x01; |
@@ -1043,15 +779,9 @@ void IMIA1(void) | |||
1043 | #endif | 779 | #endif |
1044 | } | 780 | } |
1045 | 781 | ||
1046 | #pragma interrupt | ||
1047 | void IRQ6(void) | ||
1048 | { | ||
1049 | stop_dma(); | ||
1050 | } | ||
1051 | |||
1052 | #ifdef HAVE_MAS3587F | 782 | #ifdef HAVE_MAS3587F |
1053 | #pragma interrupt | 783 | #pragma interrupt |
1054 | void IRQ3(void) | 784 | void IRQ3(void) /* PA15: MAS demand IRQ */ |
1055 | { | 785 | { |
1056 | /* Begin with setting the IRQ to edge sensitive */ | 786 | /* Begin with setting the IRQ to edge sensitive */ |
1057 | ICR |= 0x0010; | 787 | ICR |= 0x0010; |
@@ -1170,7 +900,7 @@ static void stop_playing(void) | |||
1170 | if(mpeg_file >= 0) | 900 | if(mpeg_file >= 0) |
1171 | close(mpeg_file); | 901 | close(mpeg_file); |
1172 | mpeg_file = -1; | 902 | mpeg_file = -1; |
1173 | stop_dma(); | 903 | mp3_play_pause(false); |
1174 | remove_all_tags(); | 904 | remove_all_tags(); |
1175 | } | 905 | } |
1176 | 906 | ||
@@ -1237,11 +967,14 @@ static void start_playback_if_ready(void) | |||
1237 | play_pending = false; | 967 | play_pending = false; |
1238 | playing = true; | 968 | playing = true; |
1239 | 969 | ||
1240 | init_dma(); | 970 | last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song()); |
971 | mp3_play_data(mp3buf + mp3buf_read, last_dma_chunk_size, transfer_end); | ||
972 | dma_underrun = false; | ||
973 | |||
1241 | if (!paused) | 974 | if (!paused) |
1242 | { | 975 | { |
1243 | last_dma_tick = current_tick; | 976 | last_dma_tick = current_tick; |
1244 | start_dma(); | 977 | mp3_play_pause(true); |
1245 | #ifdef HAVE_MAS3587F | 978 | #ifdef HAVE_MAS3587F |
1246 | demand_irq_enable(true); | 979 | demand_irq_enable(true); |
1247 | #endif | 980 | #endif |
@@ -1376,7 +1109,7 @@ static void mpeg_thread(void) | |||
1376 | play_pending = false; | 1109 | play_pending = false; |
1377 | playing = false; | 1110 | playing = false; |
1378 | paused = false; | 1111 | paused = false; |
1379 | stop_dma(); | 1112 | mp3_play_pause(false); |
1380 | 1113 | ||
1381 | reset_mp3_buffer(); | 1114 | reset_mp3_buffer(); |
1382 | remove_all_tags(); | 1115 | remove_all_tags(); |
@@ -1435,7 +1168,7 @@ static void mpeg_thread(void) | |||
1435 | playing = false; | 1168 | playing = false; |
1436 | pause_tick = current_tick; | 1169 | pause_tick = current_tick; |
1437 | pause_track = current_track_counter; | 1170 | pause_track = current_track_counter; |
1438 | stop_dma(); | 1171 | mp3_play_pause(false); |
1439 | break; | 1172 | break; |
1440 | 1173 | ||
1441 | case MPEG_RESUME: | 1174 | case MPEG_RESUME: |
@@ -1450,7 +1183,7 @@ static void mpeg_thread(void) | |||
1450 | else | 1183 | else |
1451 | last_dma_tick = current_tick; | 1184 | last_dma_tick = current_tick; |
1452 | pause_tick = 0; | 1185 | pause_tick = 0; |
1453 | start_dma(); | 1186 | mp3_play_pause(true); |
1454 | } | 1187 | } |
1455 | break; | 1188 | break; |
1456 | 1189 | ||
@@ -1463,11 +1196,13 @@ static void mpeg_thread(void) | |||
1463 | /* stop the current stream */ | 1196 | /* stop the current stream */ |
1464 | play_pending = false; | 1197 | play_pending = false; |
1465 | playing = false; | 1198 | playing = false; |
1466 | stop_dma(); | 1199 | mp3_play_pause(false); |
1467 | 1200 | ||
1468 | track_change(); | 1201 | track_change(); |
1469 | mp3buf_read = id3tags[tag_read_idx]->mempos; | 1202 | mp3buf_read = id3tags[tag_read_idx]->mempos; |
1470 | init_dma(); | 1203 | last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song()); |
1204 | mp3_play_data(mp3buf + mp3buf_read, last_dma_chunk_size, transfer_end); | ||
1205 | dma_underrun = false; | ||
1471 | last_dma_tick = current_tick; | 1206 | last_dma_tick = current_tick; |
1472 | 1207 | ||
1473 | unplayed_space_left = get_unplayed_space(); | 1208 | unplayed_space_left = get_unplayed_space(); |
@@ -1486,7 +1221,7 @@ static void mpeg_thread(void) | |||
1486 | } else { | 1221 | } else { |
1487 | playing = true; | 1222 | playing = true; |
1488 | if (!paused) | 1223 | if (!paused) |
1489 | start_dma(); | 1224 | mp3_play_pause(true); |
1490 | } | 1225 | } |
1491 | } | 1226 | } |
1492 | else { | 1227 | else { |
@@ -1496,7 +1231,7 @@ static void mpeg_thread(void) | |||
1496 | /* stop the current stream */ | 1231 | /* stop the current stream */ |
1497 | play_pending = false; | 1232 | play_pending = false; |
1498 | playing = false; | 1233 | playing = false; |
1499 | stop_dma(); | 1234 | mp3_play_pause(false); |
1500 | 1235 | ||
1501 | reset_mp3_buffer(); | 1236 | reset_mp3_buffer(); |
1502 | remove_all_tags(); | 1237 | remove_all_tags(); |
@@ -1532,7 +1267,7 @@ static void mpeg_thread(void) | |||
1532 | /* stop the current stream */ | 1267 | /* stop the current stream */ |
1533 | play_pending = false; | 1268 | play_pending = false; |
1534 | playing = false; | 1269 | playing = false; |
1535 | stop_dma(); | 1270 | mp3_play_pause(false); |
1536 | 1271 | ||
1537 | reset_mp3_buffer(); | 1272 | reset_mp3_buffer(); |
1538 | remove_all_tags(); | 1273 | remove_all_tags(); |
@@ -1685,7 +1420,11 @@ static void mpeg_thread(void) | |||
1685 | else | 1420 | else |
1686 | { | 1421 | { |
1687 | /* resume will start at new position */ | 1422 | /* resume will start at new position */ |
1688 | init_dma(); | 1423 | last_dma_chunk_size = |
1424 | MIN(0x2000, get_unplayed_space_current_song()); | ||
1425 | mp3_play_data(mp3buf + mp3buf_read, | ||
1426 | last_dma_chunk_size, transfer_end); | ||
1427 | dma_underrun = false; | ||
1689 | } | 1428 | } |
1690 | } | 1429 | } |
1691 | else | 1430 | else |
@@ -2261,7 +2000,9 @@ static void mpeg_thread(void) | |||
2261 | break; | 2000 | break; |
2262 | 2001 | ||
2263 | case MPEG_INIT_PLAYBACK: | 2002 | case MPEG_INIT_PLAYBACK: |
2264 | init_playback(); | 2003 | mp3_play_init(); |
2004 | mpeg_mode = MPEG_DECODER; | ||
2005 | |||
2265 | init_playback_done = true; | 2006 | init_playback_done = true; |
2266 | break; | 2007 | break; |
2267 | 2008 | ||
@@ -2288,43 +2029,6 @@ static void mpeg_thread(void) | |||
2288 | #endif | 2029 | #endif |
2289 | } | 2030 | } |
2290 | } | 2031 | } |
2291 | |||
2292 | static void setup_sci0(void) | ||
2293 | { | ||
2294 | /* PB15 is I/O, PB14 is IRQ6, PB12 is SCK0, PB9 is TxD0 */ | ||
2295 | PBCR1 = (PBCR1 & 0x0cff) | 0x1208; | ||
2296 | |||
2297 | /* Set PB12 to output */ | ||
2298 | or_b(0x10, &PBIORH); | ||
2299 | |||
2300 | /* Disable serial port */ | ||
2301 | SCR0 = 0x00; | ||
2302 | |||
2303 | /* Synchronous, no prescale */ | ||
2304 | SMR0 = 0x80; | ||
2305 | |||
2306 | /* Set baudrate 1Mbit/s */ | ||
2307 | BRR0 = 0x03; | ||
2308 | |||
2309 | /* use SCK as serial clock output */ | ||
2310 | SCR0 = 0x01; | ||
2311 | |||
2312 | /* Clear FER and PER */ | ||
2313 | SSR0 &= 0xe7; | ||
2314 | |||
2315 | /* Set interrupt ITU2 and SCI0 priority to 0 */ | ||
2316 | IPRD &= 0x0ff0; | ||
2317 | |||
2318 | /* set PB15 and PB14 to inputs */ | ||
2319 | and_b(~0x80, &PBIORH); | ||
2320 | and_b(~0x40, &PBIORH); | ||
2321 | |||
2322 | /* Enable End of DMA interrupt at prio 8 */ | ||
2323 | IPRC = (IPRC & 0xf0ff) | 0x0800; | ||
2324 | |||
2325 | /* Enable Tx (only!) */ | ||
2326 | SCR0 |= 0x20; | ||
2327 | } | ||
2328 | #endif /* SIMULATOR */ | 2032 | #endif /* SIMULATOR */ |
2329 | 2033 | ||
2330 | #ifdef SIMULATOR | 2034 | #ifdef SIMULATOR |
@@ -2364,66 +2068,6 @@ void mpeg_init_playback(void) | |||
2364 | wake_up_thread(); | 2068 | wake_up_thread(); |
2365 | } | 2069 | } |
2366 | 2070 | ||
2367 | static void init_playback(void) | ||
2368 | { | ||
2369 | unsigned long val; | ||
2370 | int rc; | ||
2371 | |||
2372 | if(mpeg_mode == MPEG_ENCODER) | ||
2373 | stop_recording(); | ||
2374 | |||
2375 | stop_dma(); | ||
2376 | |||
2377 | mas_reset(); | ||
2378 | |||
2379 | /* Enable the audio CODEC and the DSP core, max analog voltage range */ | ||
2380 | rc = mas_direct_config_write(MAS_CONTROL, 0x8c00); | ||
2381 | if(rc < 0) | ||
2382 | panicf("mas_ctrl_w: %d", rc); | ||
2383 | |||
2384 | /* Stop the current application */ | ||
2385 | val = 0; | ||
2386 | mas_writemem(MAS_BANK_D0,0x7f6,&val,1); | ||
2387 | do | ||
2388 | { | ||
2389 | mas_readmem(MAS_BANK_D0, 0x7f7, &val, 1); | ||
2390 | } while(val); | ||
2391 | |||
2392 | /* Enable the D/A Converter */ | ||
2393 | mas_codec_writereg(0x0, 0x0001); | ||
2394 | |||
2395 | /* ADC scale 0%, DSP scale 100% */ | ||
2396 | mas_codec_writereg(6, 0x0000); | ||
2397 | mas_codec_writereg(7, 0x4000); | ||
2398 | |||
2399 | /* Disable SDO and SDI */ | ||
2400 | val = 0x0d; | ||
2401 | mas_writemem(MAS_BANK_D0,0x7f2,&val,1); | ||
2402 | |||
2403 | /* Set Demand mode and validate all settings */ | ||
2404 | val = 0x25; | ||
2405 | mas_writemem(MAS_BANK_D0,0x7f1,&val,1); | ||
2406 | |||
2407 | /* Start the Layer2/3 decoder applications */ | ||
2408 | val = 0x0c; | ||
2409 | mas_writemem(MAS_BANK_D0,0x7f6,&val,1); | ||
2410 | do | ||
2411 | { | ||
2412 | mas_readmem(MAS_BANK_D0, 0x7f7, &val, 1); | ||
2413 | } while((val & 0x0c) != 0x0c); | ||
2414 | |||
2415 | mpeg_sound_channel_config(MPEG_SOUND_STEREO); | ||
2416 | |||
2417 | mpeg_mode = MPEG_DECODER; | ||
2418 | |||
2419 | /* set IRQ6 to edge detect */ | ||
2420 | ICR |= 0x02; | ||
2421 | |||
2422 | /* set IRQ6 prio 8 */ | ||
2423 | IPRB = ( IPRB & 0xff0f ) | 0x0080; | ||
2424 | |||
2425 | DEBUGF("MAS Decoding application started\n"); | ||
2426 | } | ||
2427 | 2071 | ||
2428 | /**************************************************************************** | 2072 | /**************************************************************************** |
2429 | ** | 2073 | ** |
@@ -2965,383 +2609,6 @@ void mpeg_error_clear(void) | |||
2965 | mpeg_errno = 0; | 2609 | mpeg_errno = 0; |
2966 | } | 2610 | } |
2967 | 2611 | ||
2968 | #ifndef SIMULATOR | ||
2969 | #ifdef HAVE_MAS3507D | ||
2970 | int current_left_volume = 0; /* all values in tenth of dB */ | ||
2971 | int current_right_volume = 0; /* all values in tenth of dB */ | ||
2972 | int current_treble = 0; | ||
2973 | int current_bass = 0; | ||
2974 | int current_balance = 0; | ||
2975 | |||
2976 | /* convert tenth of dB volume to register value */ | ||
2977 | static int tenthdb2reg(int db) { | ||
2978 | if (db < -540) | ||
2979 | return (db + 780) / 30; | ||
2980 | else | ||
2981 | return (db + 660) / 15; | ||
2982 | } | ||
2983 | |||
2984 | void set_prescaled_volume(void) | ||
2985 | { | ||
2986 | int prescale; | ||
2987 | int l, r; | ||
2988 | |||
2989 | prescale = MAX(current_bass, current_treble); | ||
2990 | if (prescale < 0) | ||
2991 | prescale = 0; /* no need to prescale if we don't boost | ||
2992 | bass or treble */ | ||
2993 | |||
2994 | mas_writereg(MAS_REG_KPRESCALE, prescale_table[prescale/10]); | ||
2995 | |||
2996 | /* gain up the analog volume to compensate the prescale reduction gain */ | ||
2997 | l = current_left_volume + prescale; | ||
2998 | r = current_right_volume + prescale; | ||
2999 | |||
3000 | dac_volume(tenthdb2reg(l), tenthdb2reg(r), false); | ||
3001 | } | ||
3002 | #endif /* HAVE_MAS3507D */ | ||
3003 | #endif /* !SIMULATOR */ | ||
3004 | |||
3005 | void mpeg_sound_set(int setting, int value) | ||
3006 | { | ||
3007 | #ifdef SIMULATOR | ||
3008 | setting = value; | ||
3009 | #else | ||
3010 | #ifdef HAVE_MAS3507D | ||
3011 | int l, r; | ||
3012 | #else | ||
3013 | int tmp; | ||
3014 | #endif | ||
3015 | |||
3016 | if(!mpeg_is_initialized) | ||
3017 | return; | ||
3018 | |||
3019 | switch(setting) | ||
3020 | { | ||
3021 | case SOUND_VOLUME: | ||
3022 | #ifdef HAVE_MAS3587F | ||
3023 | tmp = 0x7f00 * value / 100; | ||
3024 | mas_codec_writereg(0x10, tmp & 0xff00); | ||
3025 | #else | ||
3026 | l = value; | ||
3027 | r = value; | ||
3028 | |||
3029 | if(current_balance > 0) | ||
3030 | { | ||
3031 | l -= current_balance; | ||
3032 | if(l < 0) | ||
3033 | l = 0; | ||
3034 | } | ||
3035 | |||
3036 | if(current_balance < 0) | ||
3037 | { | ||
3038 | r += current_balance; | ||
3039 | if(r < 0) | ||
3040 | r = 0; | ||
3041 | } | ||
3042 | |||
3043 | l = 0x38 * l / 100; | ||
3044 | r = 0x38 * r / 100; | ||
3045 | |||
3046 | /* store volume in tenth of dB */ | ||
3047 | current_left_volume = ( l < 0x08 ? l*30 - 780 : l*15 - 660 ); | ||
3048 | current_right_volume = ( r < 0x08 ? r*30 - 780 : r*15 - 660 ); | ||
3049 | |||
3050 | set_prescaled_volume(); | ||
3051 | #endif | ||
3052 | break; | ||
3053 | |||
3054 | case SOUND_BALANCE: | ||
3055 | #ifdef HAVE_MAS3587F | ||
3056 | tmp = ((value * 127 / 100) & 0xff) << 8; | ||
3057 | mas_codec_writereg(0x11, tmp & 0xff00); | ||
3058 | #else | ||
3059 | /* Convert to percent */ | ||
3060 | current_balance = value * 2; | ||
3061 | #endif | ||
3062 | break; | ||
3063 | |||
3064 | case SOUND_BASS: | ||
3065 | #ifdef HAVE_MAS3587F | ||
3066 | tmp = (((value-12) * 8) & 0xff) << 8; | ||
3067 | mas_codec_writereg(0x14, tmp & 0xff00); | ||
3068 | #else | ||
3069 | mas_writereg(MAS_REG_KBASS, bass_table[value]); | ||
3070 | current_bass = (value-15) * 10; | ||
3071 | set_prescaled_volume(); | ||
3072 | #endif | ||
3073 | break; | ||
3074 | |||
3075 | case SOUND_TREBLE: | ||
3076 | #ifdef HAVE_MAS3587F | ||
3077 | tmp = (((value-12) * 8) & 0xff) << 8; | ||
3078 | mas_codec_writereg(0x15, tmp & 0xff00); | ||
3079 | #else | ||
3080 | mas_writereg(MAS_REG_KTREBLE, treble_table[value]); | ||
3081 | current_treble = (value-15) * 10; | ||
3082 | set_prescaled_volume(); | ||
3083 | #endif | ||
3084 | break; | ||
3085 | |||
3086 | #ifdef HAVE_MAS3587F | ||
3087 | case SOUND_SUPERBASS: | ||
3088 | if (value) { | ||
3089 | tmp = MAX(MIN(value * 12, 0x7f), 0); | ||
3090 | mas_codec_writereg(MAS_REG_KMDB_STR, (tmp & 0xff) << 8); | ||
3091 | tmp = 0x30; /* MDB_HAR: Space for experiment here */ | ||
3092 | mas_codec_writereg(MAS_REG_KMDB_HAR, (tmp & 0xff) << 8); | ||
3093 | tmp = 60 / 10; /* calculate MDB_FC, 60hz - experiment here, | ||
3094 | this would depend on the earphones... | ||
3095 | perhaps make it tunable? */ | ||
3096 | mas_codec_writereg(MAS_REG_KMDB_FC, (tmp & 0xff) << 8); | ||
3097 | tmp = (3 * tmp) / 2; /* calculate MDB_SHAPE */ | ||
3098 | mas_codec_writereg(MAS_REG_KMDB_SWITCH, | ||
3099 | ((tmp & 0xff) << 8) /* MDB_SHAPE */ | ||
3100 | | 2); /* MDB_SWITCH enable */ | ||
3101 | } else { | ||
3102 | mas_codec_writereg(MAS_REG_KMDB_STR, 0); | ||
3103 | mas_codec_writereg(MAS_REG_KMDB_HAR, 0); | ||
3104 | mas_codec_writereg(MAS_REG_KMDB_SWITCH, 0); /* MDB_SWITCH disable */ | ||
3105 | } | ||
3106 | break; | ||
3107 | |||
3108 | case SOUND_LOUDNESS: | ||
3109 | tmp = MAX(MIN(value * 4, 0x44), 0); | ||
3110 | mas_codec_writereg(MAS_REG_KLOUDNESS, (tmp & 0xff) << 8); | ||
3111 | break; | ||
3112 | |||
3113 | case SOUND_AVC: | ||
3114 | switch (value) { | ||
3115 | case 1: /* 2s */ | ||
3116 | tmp = (0x2 << 8) | (0x8 << 12); | ||
3117 | break; | ||
3118 | case 2: /* 4s */ | ||
3119 | tmp = (0x4 << 8) | (0x8 << 12); | ||
3120 | break; | ||
3121 | case 3: /* 8s */ | ||
3122 | tmp = (0x8 << 8) | (0x8 << 12); | ||
3123 | break; | ||
3124 | case -1: /* turn off and then turn on again to decay quickly */ | ||
3125 | tmp = mas_codec_readreg(MAS_REG_KAVC); | ||
3126 | mas_codec_writereg(MAS_REG_KAVC, 0); | ||
3127 | break; | ||
3128 | default: /* off */ | ||
3129 | tmp = 0; | ||
3130 | break; | ||
3131 | } | ||
3132 | mas_codec_writereg(MAS_REG_KAVC, tmp); | ||
3133 | break; | ||
3134 | #endif | ||
3135 | case SOUND_CHANNELS: | ||
3136 | mpeg_sound_channel_config(value); | ||
3137 | break; | ||
3138 | } | ||
3139 | #endif /* SIMULATOR */ | ||
3140 | } | ||
3141 | |||
3142 | int mpeg_val2phys(int setting, int value) | ||
3143 | { | ||
3144 | int result = 0; | ||
3145 | |||
3146 | switch(setting) | ||
3147 | { | ||
3148 | case SOUND_VOLUME: | ||
3149 | result = value; | ||
3150 | break; | ||
3151 | |||
3152 | case SOUND_BALANCE: | ||
3153 | result = value * 2; | ||
3154 | break; | ||
3155 | |||
3156 | case SOUND_BASS: | ||
3157 | #ifdef HAVE_MAS3587F | ||
3158 | result = value - 12; | ||
3159 | #else | ||
3160 | result = value - 15; | ||
3161 | #endif | ||
3162 | break; | ||
3163 | |||
3164 | case SOUND_TREBLE: | ||
3165 | #ifdef HAVE_MAS3587F | ||
3166 | result = value - 12; | ||
3167 | #else | ||
3168 | result = value - 15; | ||
3169 | #endif | ||
3170 | break; | ||
3171 | |||
3172 | #ifdef HAVE_MAS3587F | ||
3173 | case SOUND_LOUDNESS: | ||
3174 | result = value; | ||
3175 | break; | ||
3176 | |||
3177 | case SOUND_SUPERBASS: | ||
3178 | result = value * 10; | ||
3179 | break; | ||
3180 | |||
3181 | case SOUND_LEFT_GAIN: | ||
3182 | case SOUND_RIGHT_GAIN: | ||
3183 | result = (value - 2) * 15; | ||
3184 | break; | ||
3185 | |||
3186 | case SOUND_MIC_GAIN: | ||
3187 | result = value * 15 + 210; | ||
3188 | break; | ||
3189 | #endif | ||
3190 | } | ||
3191 | return result; | ||
3192 | } | ||
3193 | |||
3194 | int mpeg_phys2val(int setting, int value) | ||
3195 | { | ||
3196 | int result = 0; | ||
3197 | |||
3198 | switch(setting) | ||
3199 | { | ||
3200 | case SOUND_VOLUME: | ||
3201 | result = value; | ||
3202 | break; | ||
3203 | |||
3204 | case SOUND_BALANCE: | ||
3205 | result = value / 2; | ||
3206 | break; | ||
3207 | |||
3208 | case SOUND_BASS: | ||
3209 | #ifdef HAVE_MAS3587F | ||
3210 | result = value + 12; | ||
3211 | #else | ||
3212 | result = value + 15; | ||
3213 | #endif | ||
3214 | break; | ||
3215 | |||
3216 | case SOUND_TREBLE: | ||
3217 | #ifdef HAVE_MAS3587F | ||
3218 | result = value + 12; | ||
3219 | #else | ||
3220 | result = value + 15; | ||
3221 | #endif | ||
3222 | break; | ||
3223 | |||
3224 | #ifdef HAVE_MAS3587F | ||
3225 | case SOUND_SUPERBASS: | ||
3226 | result = value / 10; | ||
3227 | break; | ||
3228 | |||
3229 | case SOUND_LOUDNESS: | ||
3230 | case SOUND_AVC: | ||
3231 | case SOUND_LEFT_GAIN: | ||
3232 | case SOUND_RIGHT_GAIN: | ||
3233 | case SOUND_MIC_GAIN: | ||
3234 | result = value; | ||
3235 | break; | ||
3236 | #endif | ||
3237 | } | ||
3238 | |||
3239 | return result; | ||
3240 | } | ||
3241 | |||
3242 | |||
3243 | void mpeg_sound_channel_config(int configuration) | ||
3244 | { | ||
3245 | #ifdef SIMULATOR | ||
3246 | (void)configuration; | ||
3247 | #else | ||
3248 | unsigned long val_ll = 0x80000; | ||
3249 | unsigned long val_lr = 0; | ||
3250 | unsigned long val_rl = 0; | ||
3251 | unsigned long val_rr = 0x80000; | ||
3252 | |||
3253 | switch(configuration) | ||
3254 | { | ||
3255 | case MPEG_SOUND_STEREO: | ||
3256 | val_ll = 0x80000; | ||
3257 | val_lr = 0; | ||
3258 | val_rl = 0; | ||
3259 | val_rr = 0x80000; | ||
3260 | break; | ||
3261 | |||
3262 | case MPEG_SOUND_MONO: | ||
3263 | val_ll = 0xc0000; | ||
3264 | val_lr = 0xc0000; | ||
3265 | val_rl = 0xc0000; | ||
3266 | val_rr = 0xc0000; | ||
3267 | break; | ||
3268 | |||
3269 | case MPEG_SOUND_MONO_LEFT: | ||
3270 | val_ll = 0x80000; | ||
3271 | val_lr = 0x80000; | ||
3272 | val_rl = 0; | ||
3273 | val_rr = 0; | ||
3274 | break; | ||
3275 | |||
3276 | case MPEG_SOUND_MONO_RIGHT: | ||
3277 | val_ll = 0; | ||
3278 | val_lr = 0; | ||
3279 | val_rl = 0x80000; | ||
3280 | val_rr = 0x80000; | ||
3281 | break; | ||
3282 | |||
3283 | case MPEG_SOUND_STEREO_NARROW: | ||
3284 | val_ll = 0xa0000; | ||
3285 | val_lr = 0xe0000; | ||
3286 | val_rl = 0xe0000; | ||
3287 | val_rr = 0xa0000; | ||
3288 | break; | ||
3289 | |||
3290 | case MPEG_SOUND_STEREO_WIDE: | ||
3291 | val_ll = 0x80000; | ||
3292 | val_lr = 0x40000; | ||
3293 | val_rl = 0x40000; | ||
3294 | val_rr = 0x80000; | ||
3295 | break; | ||
3296 | |||
3297 | case MPEG_SOUND_KARAOKE: | ||
3298 | val_ll = 0x80001; | ||
3299 | val_lr = 0x7ffff; | ||
3300 | val_rl = 0x7ffff; | ||
3301 | val_rr = 0x80001; | ||
3302 | break; | ||
3303 | } | ||
3304 | |||
3305 | #ifdef HAVE_MAS3587F | ||
3306 | mas_writemem(MAS_BANK_D0, 0x7fc, &val_ll, 1); /* LL */ | ||
3307 | mas_writemem(MAS_BANK_D0, 0x7fd, &val_lr, 1); /* LR */ | ||
3308 | mas_writemem(MAS_BANK_D0, 0x7fe, &val_rl, 1); /* RL */ | ||
3309 | mas_writemem(MAS_BANK_D0, 0x7ff, &val_rr, 1); /* RR */ | ||
3310 | #else | ||
3311 | mas_writemem(MAS_BANK_D1, 0x7f8, &val_ll, 1); /* LL */ | ||
3312 | mas_writemem(MAS_BANK_D1, 0x7f9, &val_lr, 1); /* LR */ | ||
3313 | mas_writemem(MAS_BANK_D1, 0x7fa, &val_rl, 1); /* RL */ | ||
3314 | mas_writemem(MAS_BANK_D1, 0x7fb, &val_rr, 1); /* RR */ | ||
3315 | #endif | ||
3316 | #endif | ||
3317 | } | ||
3318 | |||
3319 | #ifdef HAVE_MAS3587F | ||
3320 | /* This function works by telling the decoder that we have another | ||
3321 | crystal frequency than we actually have. It will adjust its internal | ||
3322 | parameters and the result is that the audio is played at another pitch. | ||
3323 | |||
3324 | The pitch value is in tenths of percent. | ||
3325 | */ | ||
3326 | void mpeg_set_pitch(int pitch) | ||
3327 | { | ||
3328 | unsigned long val; | ||
3329 | |||
3330 | /* invert pitch value */ | ||
3331 | pitch = 1000000/pitch; | ||
3332 | |||
3333 | /* Calculate the new (bogus) frequency */ | ||
3334 | val = 18432*pitch/1000; | ||
3335 | |||
3336 | mas_writemem(MAS_BANK_D0,0x7f3,&val,1); | ||
3337 | |||
3338 | /* We must tell the MAS that the frequency has changed. | ||
3339 | This will unfortunately cause a short silence. */ | ||
3340 | val = 0x25; | ||
3341 | mas_writemem(MAS_BANK_D0,0x7f1,&val,1); | ||
3342 | } | ||
3343 | #endif | ||
3344 | |||
3345 | #ifdef SIMULATOR | 2612 | #ifdef SIMULATOR |
3346 | static char mpeg_stack[DEFAULT_STACK_SIZE]; | 2613 | static char mpeg_stack[DEFAULT_STACK_SIZE]; |
3347 | static char mpeg_thread_name[] = "mpeg"; | 2614 | static char mpeg_thread_name[] = "mpeg"; |
@@ -3364,82 +2631,9 @@ static void mpeg_thread(void) | |||
3364 | } | 2631 | } |
3365 | #endif | 2632 | #endif |
3366 | 2633 | ||
3367 | void mpeg_init(int volume, int bass, int treble, int balance, int loudness, | 2634 | void mpeg_init(void) |
3368 | int bass_boost, int avc, int channel_config) | ||
3369 | { | 2635 | { |
3370 | mpeg_errno = 0; | 2636 | mpeg_errno = 0; |
3371 | |||
3372 | #ifdef SIMULATOR | ||
3373 | volume = bass = treble = balance = loudness | ||
3374 | = bass_boost = avc = channel_config; | ||
3375 | create_thread(mpeg_thread, mpeg_stack, | ||
3376 | sizeof(mpeg_stack), mpeg_thread_name); | ||
3377 | #else | ||
3378 | #ifdef HAVE_MAS3507D | ||
3379 | unsigned long val; | ||
3380 | loudness = bass_boost = avc; | ||
3381 | #endif | ||
3382 | |||
3383 | setup_sci0(); | ||
3384 | |||
3385 | #ifdef HAVE_MAS3587F | ||
3386 | or_b(0x08, &PAIORH); /* output for /PR */ | ||
3387 | init_playback(); | ||
3388 | |||
3389 | mas_version_code = mas_readver(); | ||
3390 | DEBUGF("MAS3587 derivate %d, version B%d\n", | ||
3391 | (mas_version_code & 0xff00) >> 8, mas_version_code & 0xff); | ||
3392 | #endif | ||
3393 | |||
3394 | #ifdef HAVE_DAC3550A | ||
3395 | dac_init(); | ||
3396 | #endif | ||
3397 | |||
3398 | #ifdef HAVE_MAS3507D | ||
3399 | and_b(~0x20, &PBDRL); | ||
3400 | sleep(HZ/5); | ||
3401 | or_b(0x20, &PBDRL); | ||
3402 | sleep(HZ/5); | ||
3403 | |||
3404 | /* set IRQ6 to edge detect */ | ||
3405 | ICR |= 0x02; | ||
3406 | |||
3407 | /* set IRQ6 prio 8 */ | ||
3408 | IPRB = ( IPRB & 0xff0f ) | 0x0080; | ||
3409 | |||
3410 | mas_readmem(MAS_BANK_D1, 0xff7, &mas_version_code, 1); | ||
3411 | |||
3412 | mas_writereg(0x3b, 0x20); /* Don't ask why. The data sheet doesn't say */ | ||
3413 | mas_run(1); | ||
3414 | sleep(HZ); | ||
3415 | |||
3416 | /* Clear the upper 12 bits of the 32-bit samples */ | ||
3417 | mas_writereg(0xc5, 0); | ||
3418 | mas_writereg(0xc6, 0); | ||
3419 | |||
3420 | /* We need to set the PLL for a 14.1318MHz crystal */ | ||
3421 | if(mas_version_code == 0x0601) /* Version F10? */ | ||
3422 | { | ||
3423 | val = 0x5d9d0; | ||
3424 | mas_writemem(MAS_BANK_D0, 0x32d, &val, 1); | ||
3425 | val = 0xfffceceb; | ||
3426 | mas_writemem(MAS_BANK_D0, 0x32e, &val, 1); | ||
3427 | val = 0x0; | ||
3428 | mas_writemem(MAS_BANK_D0, 0x32f, &val, 1); | ||
3429 | mas_run(0x475); | ||
3430 | } | ||
3431 | else | ||
3432 | { | ||
3433 | val = 0x5d9d0; | ||
3434 | mas_writemem(MAS_BANK_D0, 0x36d, &val, 1); | ||
3435 | val = 0xfffceceb; | ||
3436 | mas_writemem(MAS_BANK_D0, 0x36e, &val, 1); | ||
3437 | val = 0x0; | ||
3438 | mas_writemem(MAS_BANK_D0, 0x36f, &val, 1); | ||
3439 | mas_run(0xfcb); | ||
3440 | } | ||
3441 | |||
3442 | #endif | ||
3443 | 2637 | ||
3444 | mp3buflen = mp3end - mp3buf; | 2638 | mp3buflen = mp3end - mp3buf; |
3445 | 2639 | ||
@@ -3447,36 +2641,6 @@ void mpeg_init(int volume, int bass, int treble, int balance, int loudness, | |||
3447 | create_thread(mpeg_thread, mpeg_stack, | 2641 | create_thread(mpeg_thread, mpeg_stack, |
3448 | sizeof(mpeg_stack), mpeg_thread_name); | 2642 | sizeof(mpeg_stack), mpeg_thread_name); |
3449 | 2643 | ||
3450 | #ifdef HAVE_MAS3507D | ||
3451 | mas_poll_start(1); | ||
3452 | |||
3453 | mas_writereg(MAS_REG_KPRESCALE, 0xe9400); | ||
3454 | dac_enable(true); | ||
3455 | |||
3456 | mpeg_sound_channel_config(channel_config); | ||
3457 | #endif | ||
3458 | |||
3459 | #ifdef HAVE_MAS3587F | ||
3460 | ICR &= ~0x0010; /* IRQ3 level sensitive */ | ||
3461 | PACR1 = (PACR1 & 0x3fff) | 0x4000; /* PA15 is IRQ3 */ | ||
3462 | #endif | ||
3463 | |||
3464 | /* Must be done before calling mpeg_sound_set() */ | ||
3465 | mpeg_is_initialized = true; | ||
3466 | |||
3467 | mpeg_sound_set(SOUND_BASS, bass); | ||
3468 | mpeg_sound_set(SOUND_TREBLE, treble); | ||
3469 | mpeg_sound_set(SOUND_BALANCE, balance); | ||
3470 | mpeg_sound_set(SOUND_VOLUME, volume); | ||
3471 | |||
3472 | #ifdef HAVE_MAS3587F | ||
3473 | mpeg_sound_channel_config(channel_config); | ||
3474 | mpeg_sound_set(SOUND_LOUDNESS, loudness); | ||
3475 | mpeg_sound_set(SOUND_SUPERBASS, bass_boost); | ||
3476 | mpeg_sound_set(SOUND_AVC, avc); | ||
3477 | #endif | ||
3478 | #endif /* !SIMULATOR */ | ||
3479 | |||
3480 | memset(id3tags, sizeof(id3tags), 0); | 2644 | memset(id3tags, sizeof(id3tags), 0); |
3481 | memset(_id3tags, sizeof(id3tags), 0); | 2645 | memset(_id3tags, sizeof(id3tags), 0); |
3482 | 2646 | ||