Battery blinks if >BATTERY_LEVEL_DANGEROUS
[kugel-rb.git] / firmware / mpeg.c
blobefe7570bffb0f2211783c19aa4efc7714daf9334
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 by Linus Nielsen Feltzing
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.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
19 #include <stdbool.h>
20 #include "config.h"
21 #include "debug.h"
22 #include "panic.h"
23 #include "id3.h"
24 #include "mpeg.h"
25 #include "ata.h"
26 #include "malloc.h"
27 #include "string.h"
28 #ifndef SIMULATOR
29 #include "i2c.h"
30 #include "mas.h"
31 #include "dac.h"
32 #include "system.h"
33 #include "kernel.h"
34 #include "thread.h"
35 #include "usb.h"
36 #include "file.h"
37 #endif
39 #define MPEG_CHUNKSIZE 0x180000
40 #define MPEG_SWAP_CHUNKSIZE 0x8000
41 #define MPEG_HIGH_WATER 2
42 #define MPEG_LOW_WATER 0x40000
43 #define MPEG_LOW_WATER_CHUNKSIZE 0x10000
45 #define MPEG_PLAY 1
46 #define MPEG_STOP 2
47 #define MPEG_PAUSE 3
48 #define MPEG_RESUME 4
49 #define MPEG_NEXT 5
50 #define MPEG_PREV 6
51 #define MPEG_NEED_DATA 100
52 #define MPEG_SWAP_DATA 101
53 #define MPEG_TRACK_CHANGE 102
55 extern char* playlist_next(int steps);
57 static char *units[] =
59 "%", /* Volume */
60 "dB", /* Bass */
61 "dB", /* Treble */
62 "", /* Balance */
63 "dB", /* Loudness */
64 "%" /* Bass boost */
67 static int numdecimals[] =
69 0, /* Volume */
70 0, /* Bass */
71 0, /* Treble */
72 0, /* Balance */
73 0, /* Loudness */
74 0 /* Bass boost */
77 static int minval[] =
79 0, /* Volume */
80 0, /* Bass */
81 0, /* Treble */
82 0, /* Balance */
83 0, /* Loudness */
84 0 /* Bass boost */
87 static int maxval[] =
89 50, /* Volume */
90 #ifdef HAVE_MAS3587F
91 24, /* Bass */
92 24, /* Treble */
93 #else
94 30, /* Bass */
95 30, /* Treble */
96 #endif
97 100, /* Balance */
98 17, /* Loudness */
99 10 /* Bass boost */
102 static int defaultval[] =
104 70/2, /* 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 50, /* Balance */
113 0, /* Loudness */
114 0 /* Bass boost */
117 char *mpeg_sound_unit(int setting)
119 return units[setting];
122 int mpeg_sound_numdecimals(int setting)
124 return numdecimals[setting];
127 int mpeg_sound_min(int setting)
129 return minval[setting];
132 int mpeg_sound_max(int setting)
134 return maxval[setting];
137 int mpeg_sound_default(int setting)
139 return defaultval[setting];
142 /* list of tracks in memory */
143 #define MAX_ID3_TAGS (1<<4) /* Must be power of 2 */
144 #define MAX_ID3_TAGS_MASK (MAX_ID3_TAGS - 1)
146 struct id3tag
148 struct mp3entry id3;
149 int mempos;
152 static struct id3tag *id3tags[MAX_ID3_TAGS];
154 static unsigned int current_track_counter = 0;
155 static unsigned int last_track_counter = 0;
157 #ifndef SIMULATOR
159 static int tag_read_idx = 0;
160 static int tag_write_idx = 0;
162 static int num_tracks_in_memory(void)
164 return (tag_write_idx - tag_read_idx) & MAX_ID3_TAGS_MASK;
166 #endif
168 #ifndef SIMULATOR
169 static void debug_tags(void)
171 #ifdef DEBUG
172 int i;
174 for(i = 0;i < MAX_ID3_TAGS;i++)
176 DEBUGF("id3tags[%d]: %08x", i, id3tags[i]);
177 if(id3tags[i])
178 DEBUGF(" - %s", id3tags[i]->id3.path);
179 DEBUGF("\n");
181 DEBUGF("read: %d, write :%d\n", tag_read_idx, tag_write_idx);
182 DEBUGF("num_tracks_in_memory: %d\n", num_tracks_in_memory());
183 #endif
186 static bool append_tag(struct id3tag *tag)
188 if(num_tracks_in_memory() < MAX_ID3_TAGS - 1)
190 id3tags[tag_write_idx] = tag;
191 tag_write_idx = (tag_write_idx+1) & MAX_ID3_TAGS_MASK;
192 debug_tags();
193 return true;
195 else
197 DEBUGF("Tag memory is full\n");
198 return false;
202 static void remove_current_tag(void)
204 int oldidx = tag_read_idx;
205 struct id3tag *tag = id3tags[tag_read_idx];
207 if(num_tracks_in_memory() > 0)
209 /* First move the index, so nobody tries to access the tag */
210 tag_read_idx = (tag_read_idx+1) & MAX_ID3_TAGS_MASK;
212 /* Now delete it */
213 id3tags[oldidx] = NULL;
214 free(tag);
215 debug_tags();
219 static void remove_all_tags(void)
221 int i;
223 for(i = 0;i < MAX_ID3_TAGS;i++)
224 remove_current_tag();
225 debug_tags();
227 #endif
229 #ifdef SIMULATOR
230 static bool playing = false;
231 static bool play_pending = false;
232 #else
233 static int last_dma_tick = 0;
234 static int pause_tick = 0;
236 #ifdef HAVE_MAS3507D
238 static unsigned long mas_version_code;
240 static unsigned int bass_table[] =
242 0x9e400, /* -15dB */
243 0xa2800, /* -14dB */
244 0xa7400, /* -13dB */
245 0xac400, /* -12dB */
246 0xb1800, /* -11dB */
247 0xb7400, /* -10dB */
248 0xbd400, /* -9dB */
249 0xc3c00, /* -8dB */
250 0xca400, /* -7dB */
251 0xd1800, /* -6dB */
252 0xd8c00, /* -5dB */
253 0xe0400, /* -4dB */
254 0xe8000, /* -3dB */
255 0xefc00, /* -2dB */
256 0xf7c00, /* -1dB */
258 0x800, /* 1dB */
259 0x10000, /* 2dB */
260 0x17c00, /* 3dB */
261 0x1f800, /* 4dB */
262 0x27000, /* 5dB */
263 0x2e400, /* 6dB */
264 0x35800, /* 7dB */
265 0x3c000, /* 8dB */
266 0x42800, /* 9dB */
267 0x48800, /* 10dB */
268 0x4e400, /* 11dB */
269 0x53800, /* 12dB */
270 0x58800, /* 13dB */
271 0x5d400, /* 14dB */
272 0x61800 /* 15dB */
275 static unsigned int treble_table[] =
277 0xb2c00, /* -15dB */
278 0xbb400, /* -14dB */
279 0xc1800, /* -13dB */
280 0xc6c00, /* -12dB */
281 0xcbc00, /* -11dB */
282 0xd0400, /* -10dB */
283 0xd5000, /* -9dB */
284 0xd9800, /* -8dB */
285 0xde000, /* -7dB */
286 0xe2800, /* -6dB */
287 0xe7e00, /* -5dB */
288 0xec000, /* -4dB */
289 0xf0c00, /* -3dB */
290 0xf5c00, /* -2dB */
291 0xfac00, /* -1dB */
293 0x5400, /* 1dB */
294 0xac00, /* 2dB */
295 0x10400, /* 3dB */
296 0x16000, /* 4dB */
297 0x1c000, /* 5dB */
298 0x22400, /* 6dB */
299 0x28400, /* 7dB */
300 0x2ec00, /* 8dB */
301 0x35400, /* 9dB */
302 0x3c000, /* 10dB */
303 0x42c00, /* 11dB */
304 0x49c00, /* 12dB */
305 0x51800, /* 13dB */
306 0x58400, /* 14dB */
307 0x5f800 /* 15dB */
310 static unsigned int prescale_table[] =
312 0x80000, /* 0db */
313 0x8e000, /* 1dB */
314 0x9a400, /* 2dB */
315 0xa5800, /* 3dB */
316 0xaf400, /* 4dB */
317 0xb8000, /* 5dB */
318 0xbfc00, /* 6dB */
319 0xc6c00, /* 7dB */
320 0xcd000, /* 8dB */
321 0xd25c0, /* 9dB */
322 0xd7800, /* 10dB */
323 0xdc000, /* 11dB */
324 0xdfc00, /* 12dB */
325 0xe3400, /* 13dB */
326 0xe6800, /* 14dB */
327 0xe9400 /* 15dB */
329 #endif
331 static unsigned char fliptable[] =
333 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
334 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
335 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
336 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
337 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
338 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
339 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
340 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
341 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
342 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
343 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
344 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
345 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
346 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
347 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
348 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
349 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
350 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
351 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
352 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
353 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
354 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
355 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
356 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
357 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
358 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
359 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
360 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
361 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
362 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
363 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
364 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
367 static unsigned short big_fliptable[65536];
369 static struct event_queue mpeg_queue;
370 static char mpeg_stack[DEFAULT_STACK_SIZE + 0x1000];
371 static char mpeg_thread_name[] = "mpeg";
373 /* defined in linker script */
374 extern unsigned char mp3buf[];
375 extern unsigned char mp3end[];
377 static int mp3buflen;
378 static int mp3buf_write;
379 static int mp3buf_swapwrite;
380 static int mp3buf_read;
382 static int last_dma_chunk_size;
384 static bool dma_on; /* The DMA is active */
385 static bool playing; /* We are playing an MP3 stream */
386 static bool play_pending; /* We are about to start playing */
387 static bool filling; /* We are filling the buffer with data from disk */
389 static int mpeg_file;
391 static void create_fliptable(void)
393 int i;
395 for(i = 0;i < 65536;i++)
397 big_fliptable[i] = fliptable[i & 0xff] | (fliptable[i >> 8] << 8);
401 static void mas_poll_start(int interval_in_ms)
403 unsigned int count;
405 count = FREQ / 1000 / 8 * interval_in_ms;
407 if(count > 0xffff)
409 panicf("Error! The MAS poll interval is too long (%d ms)\n",
410 interval_in_ms);
411 return;
414 /* We are using timer 1 */
416 TSTR &= ~0x02; /* Stop the timer */
417 TSNC &= ~0x02; /* No synchronization */
418 TMDR &= ~0x02; /* Operate normally */
420 TCNT1 = 0; /* Start counting at 0 */
421 GRA1 = count;
422 TCR1 = 0x23; /* Clear at GRA match, sysclock/8 */
424 /* Enable interrupt on level 5 */
425 IPRC = (IPRC & ~0x000f) | 0x0005;
427 TSR1 &= ~0x02;
428 TIER1 = 0xf9; /* Enable GRA match interrupt */
430 TSTR |= 0x02; /* Start timer 2 */
433 static int get_unplayed_space(void)
435 int space = mp3buf_write - mp3buf_read;
436 if (space < 0)
437 space = mp3buflen + space;
438 return space;
441 static void init_dma(void)
443 SAR3 = (unsigned int) mp3buf + mp3buf_read;
444 DAR3 = 0x5FFFEC3;
445 CHCR3 &= ~0x0002; /* Clear interrupt */
446 CHCR3 = 0x1504; /* Single address destination, TXI0, IE=1 */
447 last_dma_chunk_size = MIN(65536, get_unplayed_space());
448 DTCR3 = last_dma_chunk_size & 0xffff;
449 DMAOR = 0x0001; /* Enable DMA */
450 CHCR3 |= 0x0001; /* Enable DMA IRQ */
453 static void start_dma(void)
455 SCR0 |= 0x80;
456 dma_on = true;
459 static void stop_dma(void)
461 SCR0 &= 0x7f;
462 dma_on = false;
465 static void dma_tick(void)
467 if(playing)
469 /* Start DMA if it is disabled and the DEMAND pin is high */
470 if(!dma_on && (PBDR & 0x4000))
472 if(!(SCR0 & 0x80))
473 start_dma();
475 id3tags[tag_read_idx]->id3.elapsed +=
476 (current_tick - last_dma_tick) * 1000 / HZ;
477 last_dma_tick = current_tick;
481 static void bitswap(unsigned short *data, int length) __attribute__ ((section (".icode")));
482 static void bitswap(unsigned short *data, int length)
484 int i = length;
485 while(i--)
487 data[i] = big_fliptable[data[i]];
491 static void reset_mp3_buffer(void)
493 mp3buf_read = 0;
494 mp3buf_write = 0;
495 mp3buf_swapwrite = 0;
498 #pragma interrupt
499 void IRQ6(void)
501 stop_dma();
504 #pragma interrupt
505 void DEI3(void)
507 if(playing)
509 int unplayed_space_left;
510 int space_until_end_of_buffer;
511 int track_offset = (tag_read_idx+1) & MAX_ID3_TAGS_MASK;
513 mp3buf_read += last_dma_chunk_size;
514 if(mp3buf_read >= mp3buflen)
515 mp3buf_read = 0;
517 /* First, check if we are on a track boundary */
518 if (num_tracks_in_memory() > 0)
520 if (mp3buf_read == id3tags[track_offset]->mempos)
522 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
523 track_offset = (track_offset+1) & MAX_ID3_TAGS_MASK;
527 unplayed_space_left = get_unplayed_space();
529 space_until_end_of_buffer = mp3buflen - mp3buf_read;
531 if(!filling && unplayed_space_left < MPEG_LOW_WATER)
533 filling = true;
534 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
537 if(unplayed_space_left)
539 last_dma_chunk_size = MIN(65536, unplayed_space_left);
540 last_dma_chunk_size = MIN(last_dma_chunk_size,
541 space_until_end_of_buffer);
543 /* several tracks loaded? */
544 if (num_tracks_in_memory() > 1)
546 /* will we move across the track boundary? */
547 if (( mp3buf_read < id3tags[track_offset]->mempos ) &&
548 ((mp3buf_read+last_dma_chunk_size) >
549 id3tags[track_offset]->mempos ))
551 /* Make sure that we end exactly on the boundary */
552 last_dma_chunk_size = id3tags[track_offset]->mempos
553 - mp3buf_read;
557 DTCR3 = last_dma_chunk_size & 0xffff;
558 SAR3 = (unsigned int)mp3buf + mp3buf_read;
560 else
562 DEBUGF("No more MP3 data. Stopping.\n");
563 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
564 CHCR3 = 0; /* Stop DMA interrupt */
565 playing = false;
569 CHCR3 &= ~0x0002; /* Clear DMA interrupt */
572 #pragma interrupt
573 void IMIA1(void)
575 dma_tick();
576 TSR1 &= ~0x01;
579 static void add_track_to_tag_list(char *filename)
581 struct id3tag *t;
583 /* grab id3 tag of new file and
584 remember where in memory it starts */
585 t = malloc(sizeof(struct id3tag));
586 if(t)
588 mp3info(&(t->id3), filename);
589 t->mempos = mp3buf_write;
590 t->id3.elapsed = 0;
591 if(!append_tag(t))
593 free(t);
594 DEBUGF("Tag list is full\n");
597 else
599 DEBUGF("No memory available for id3 tag");
603 /* If next_track is true, opens the next track, if false, opens prev track */
604 static int new_file(int steps)
606 char *trackname;
608 do {
609 trackname = playlist_next( steps );
610 if ( !trackname )
611 return -1;
613 DEBUGF("playing %s\n", trackname);
615 mpeg_file = open(trackname, O_RDONLY);
616 if(mpeg_file < 0) {
617 DEBUGF("Couldn't open file: %s\n",trackname);
619 else
621 add_track_to_tag_list(trackname);
623 } while ( mpeg_file < 0 );
625 return 0;
628 static void stop_playing(void)
630 /* Stop the current stream */
631 playing = false;
632 filling = false;
633 if(mpeg_file >= 0)
634 close(mpeg_file);
635 mpeg_file = -1;
636 stop_dma();
637 remove_all_tags();
640 static void track_change(void)
642 DEBUGF("Track change\n");
644 #ifdef HAVE_MAS3587F
645 /* Reset the AVC */
646 mpeg_sound_set(SOUND_AVC, -1);
647 #endif
648 remove_current_tag();
650 current_track_counter++;
653 static void mpeg_thread(void)
655 struct event ev;
656 int len;
657 int free_space_left;
658 int unplayed_space_left;
659 int amount_to_read;
660 int amount_to_swap;
661 int t1, t2;
663 play_pending = false;
664 playing = false;
665 mpeg_file = -1;
667 while(1)
669 DEBUGF("S R:%x W:%x SW:%x\n",
670 mp3buf_read, mp3buf_write, mp3buf_swapwrite);
671 yield();
672 queue_wait(&mpeg_queue, &ev);
673 switch(ev.id)
675 case MPEG_PLAY:
676 DEBUGF("MPEG_PLAY %s\n",ev.data);
677 /* Stop the current stream */
678 play_pending = false;
679 playing = false;
680 stop_dma();
682 reset_mp3_buffer();
683 remove_all_tags();
685 if(mpeg_file >= 0)
686 close(mpeg_file);
688 mpeg_file = open((char*)ev.data, O_RDONLY);
689 while (mpeg_file < 0) {
690 DEBUGF("Couldn't open file: %s\n",ev.data);
691 if ( new_file(1) == -1 )
692 return;
695 add_track_to_tag_list((char *)ev.data);
697 /* Make it read more data */
698 filling = true;
699 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
701 /* Tell the file loading code that we want to start playing
702 as soon as we have some data */
703 play_pending = true;
705 current_track_counter++;
706 break;
708 case MPEG_STOP:
709 DEBUGF("MPEG_STOP\n");
710 stop_playing();
711 break;
713 case MPEG_PAUSE:
714 DEBUGF("MPEG_PAUSE\n");
715 /* Stop the current stream */
716 playing = false;
717 pause_tick = current_tick;
718 stop_dma();
719 break;
721 case MPEG_RESUME:
722 DEBUGF("MPEG_RESUME\n");
723 /* Continue the current stream */
724 playing = true;
725 last_dma_tick += current_tick - pause_tick;
726 pause_tick = 0;
727 start_dma();
728 break;
730 case MPEG_NEXT:
731 DEBUGF("MPEG_NEXT\n");
732 /* stop the current stream */
733 play_pending = false;
734 playing = false;
735 stop_dma();
737 /* is next track in ram? */
738 if ( num_tracks_in_memory() > 1 ) {
739 int track_offset = (tag_read_idx+1) & MAX_ID3_TAGS_MASK;
740 mp3buf_read = id3tags[track_offset]->mempos;
741 init_dma();
742 last_dma_tick = current_tick;
744 /* should we start reading more data? */
745 if(!filling && (get_unplayed_space() < MPEG_LOW_WATER)) {
746 filling = true;
747 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
748 play_pending = true;
749 } else {
750 playing = true;
751 start_dma();
754 track_change();
756 else {
757 reset_mp3_buffer();
758 remove_all_tags();
760 /* Open the next file */
761 if (mpeg_file >= 0)
762 close(mpeg_file);
764 if (new_file(1) < 0) {
765 DEBUGF("No more files to play\n");
766 filling = false;
767 } else {
768 /* Make it read more data */
769 filling = true;
770 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
772 /* Tell the file loading code that we want to start playing
773 as soon as we have some data */
774 play_pending = true;
776 current_track_counter++;
779 break;
781 case MPEG_PREV: {
782 int numtracks = num_tracks_in_memory();
783 DEBUGF("MPEG_PREV\n");
784 /* stop the current stream */
785 play_pending = false;
786 playing = false;
787 stop_dma();
789 reset_mp3_buffer();
790 remove_all_tags();
792 /* Open the next file */
793 if (mpeg_file >= 0)
794 close(mpeg_file);
796 if (new_file(-numtracks) < 0) {
797 DEBUGF("No more files to play\n");
798 filling = false;
799 } else {
800 /* Make it read more data */
801 filling = true;
802 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
804 /* Tell the file loading code that we want to start playing
805 as soon as we have some data */
806 play_pending = true;
808 current_track_counter++;
810 break;
813 case MPEG_SWAP_DATA:
814 free_space_left = mp3buf_write - mp3buf_swapwrite;
816 if(free_space_left == 0)
817 break;
819 if(free_space_left < 0)
820 free_space_left = mp3buflen + free_space_left;
822 amount_to_swap = MIN(MPEG_SWAP_CHUNKSIZE, free_space_left);
823 if(mp3buf_write < mp3buf_swapwrite)
824 amount_to_swap = MIN(mp3buflen - mp3buf_swapwrite,
825 amount_to_swap);
826 else
827 amount_to_swap = MIN(mp3buf_write - mp3buf_swapwrite,
828 amount_to_swap);
830 DEBUGF("B %x\n", amount_to_swap);
831 t1 = current_tick;
832 bitswap((unsigned short *)(mp3buf + mp3buf_swapwrite),
833 (amount_to_swap+1)/2);
834 t2 = current_tick;
835 DEBUGF("time: %d\n", t2 - t1);
837 mp3buf_swapwrite += amount_to_swap;
838 if(mp3buf_swapwrite >= mp3buflen)
840 mp3buf_swapwrite = 0;
841 DEBUGF("BW\n");
844 /* Tell ourselves that we must swap more data */
845 queue_post(&mpeg_queue, MPEG_SWAP_DATA, 0);
847 /* And while we're at it, see if we have started
848 playing yet. If not, do it. */
849 if(play_pending)
851 /* If the filling has stopped, and we still haven't reached
852 the watermark, the file must be smaller than the
853 watermark. We must still play it. */
854 if(((mp3buf_swapwrite - mp3buf_read) >= MPEG_LOW_WATER) ||
855 !filling)
857 DEBUGF("P\n");
858 play_pending = false;
859 playing = true;
861 last_dma_tick = current_tick;
862 init_dma();
863 start_dma();
865 /* Tell ourselves that we need more data */
866 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
870 break;
872 case MPEG_NEED_DATA:
873 free_space_left = mp3buf_read - mp3buf_write;
875 /* We interpret 0 as "empty buffer" */
876 if(free_space_left <= 0)
877 free_space_left = mp3buflen + free_space_left;
879 unplayed_space_left = mp3buflen - free_space_left;
881 /* Make sure that we don't fill the entire buffer */
882 free_space_left -= 2;
884 /* do we have any more buffer space to fill? */
885 if(free_space_left <= MPEG_HIGH_WATER)
887 DEBUGF("0\n");
888 filling = false;
889 ata_sleep();
890 break;
893 /* Read small chunks while we are below the low water mark */
894 if(unplayed_space_left < MPEG_LOW_WATER)
895 amount_to_read = MIN(MPEG_LOW_WATER_CHUNKSIZE,
896 free_space_left);
897 else
898 amount_to_read = MIN(MPEG_CHUNKSIZE, free_space_left);
900 /* Don't read more than until the end of the buffer */
901 amount_to_read = MIN(mp3buflen - mp3buf_write, amount_to_read);
903 /* Read in a few seconds worth of MP3 data. We don't want to
904 read too large chunks because the bitswapping will take
905 too much time. We must keep the DMA happy and also give
906 the other threads a chance to run. */
907 if(mpeg_file >= 0)
909 DEBUGF("R\n");
910 t1 = current_tick;
911 len = read(mpeg_file, mp3buf+mp3buf_write, amount_to_read);
912 if(len > 0)
914 t2 = current_tick;
915 DEBUGF("time: %d\n", t2 - t1);
916 DEBUGF("R: %x\n", len);
917 /* Tell ourselves that we need to swap some data */
918 queue_post(&mpeg_queue, MPEG_SWAP_DATA, 0);
920 /* Make sure that the write pointer is at a word
921 boundary when we reach the end of the file */
922 if(len < amount_to_read)
923 len = (len + 1) & 0xfffffffe;
925 mp3buf_write += len;
926 if(mp3buf_write >= mp3buflen)
928 mp3buf_write = 0;
929 DEBUGF("W\n");
932 /* Tell ourselves that we want more data */
933 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
935 else
937 if(len < 0)
939 DEBUGF("MPEG read error\n");
942 close(mpeg_file);
943 mpeg_file = -1;
945 /* Make sure that the write pointer is at a word
946 boundary */
947 mp3buf_write = (mp3buf_write + 1) & 0xfffffffe;
949 if(new_file(1) < 0)
951 /* No more data to play */
952 DEBUGF("No more files to play\n");
953 filling = false;
955 else
957 /* Tell ourselves that we want more data */
958 queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
962 break;
964 case MPEG_TRACK_CHANGE:
965 track_change();
966 break;
968 case SYS_USB_CONNECTED:
969 stop_playing();
971 /* Tell the USB thread that we are safe */
972 DEBUGF("mpeg_thread got SYS_USB_CONNECTED\n");
973 usb_acknowledge(SYS_USB_CONNECTED_ACK);
975 /* Wait until the USB cable is extracted again */
976 usb_wait_for_disconnect(&mpeg_queue);
977 break;
982 static void setup_sci0(void)
984 /* PB15 is I/O, PB14 is IRQ6, PB12 is SCK0 */
985 PBCR1 = (PBCR1 & 0x0cff) | 0x1200;
987 /* Set PB12 to output */
988 PBIOR |= 0x1000;
990 /* Disable serial port */
991 SCR0 = 0x00;
993 /* Synchronous, no prescale */
994 SMR0 = 0x80;
996 /* Set baudrate 1Mbit/s */
997 BRR0 = 0x03;
999 /* use SCK as serial clock output */
1000 SCR0 = 0x01;
1002 /* Clear FER and PER */
1003 SSR0 &= 0xe7;
1005 /* Set interrupt ITU2 and SCI0 priority to 0 */
1006 IPRD &= 0x0ff0;
1008 /* set IRQ6 and IRQ7 to edge detect */
1009 ICR |= 0x03;
1011 /* set PB15 and PB14 to inputs */
1012 PBIOR &= 0x7fff;
1013 PBIOR &= 0xbfff;
1015 /* set IRQ6 prio 8 and IRQ7 prio 0 */
1016 IPRB = ( IPRB & 0xff00 ) | 0x0080;
1018 /* Enable End of DMA interrupt at prio 8 */
1019 IPRC = (IPRC & 0xf0ff) | 0x0800;
1021 /* Enable Tx (only!) */
1022 SCR0 |= 0x20;
1024 #endif /* SIMULATOR */
1026 #ifdef SIMULATOR
1027 static struct mp3entry taginfo;
1028 #endif
1030 struct mp3entry* mpeg_current_track(void)
1032 #ifdef SIMULATOR
1033 return &taginfo;
1034 #else
1035 if(num_tracks_in_memory())
1036 return &(id3tags[tag_read_idx]->id3);
1037 else
1038 return NULL;
1039 #endif
1042 bool mpeg_has_changed_track(void)
1044 if(last_track_counter != current_track_counter)
1046 last_track_counter = current_track_counter;
1047 return true;
1049 return false;
1052 void mpeg_play(char* trackname)
1054 #ifdef SIMULATOR
1055 mp3info(&taginfo, trackname);
1056 playing = true;
1057 #else
1058 queue_post(&mpeg_queue, MPEG_PLAY, trackname);
1059 #endif
1062 void mpeg_stop(void)
1064 #ifndef SIMULATOR
1065 queue_post(&mpeg_queue, MPEG_STOP, NULL);
1066 #else
1067 playing = false;
1068 #endif
1071 void mpeg_pause(void)
1073 #ifndef SIMULATOR
1074 queue_post(&mpeg_queue, MPEG_PAUSE, NULL);
1075 #else
1076 playing = false;
1077 #endif
1080 void mpeg_resume(void)
1082 #ifndef SIMULATOR
1083 queue_post(&mpeg_queue, MPEG_RESUME, NULL);
1084 #else
1085 playing = true;
1086 #endif
1089 void mpeg_next(void)
1091 #ifndef SIMULATOR
1092 queue_post(&mpeg_queue, MPEG_NEXT, NULL);
1093 #else
1094 char* file = playlist_next(1);
1095 mp3info(&taginfo, file);
1096 current_track_counter++;
1097 playing = true;
1098 #endif
1101 void mpeg_prev(void)
1103 #ifndef SIMULATOR
1104 queue_post(&mpeg_queue, MPEG_PREV, NULL);
1105 #else
1106 char* file = playlist_next(-1);
1107 mp3info(&taginfo, file);
1108 current_track_counter--;
1109 playing = true;
1110 #endif
1113 bool mpeg_is_playing(void)
1115 return playing || play_pending;
1118 #ifndef SIMULATOR
1119 #ifdef HAVE_MAS3507D
1120 int current_volume=0; /* all values in tenth of dB */
1121 int current_treble=0;
1122 int current_bass=0;
1123 int current_balance=0;
1125 /* convert tenth of dB volume to register value */
1126 static int tenthdb2reg(int db) {
1127 if (db < -540)
1128 return (db + 780) / 30;
1129 else
1130 return (db + 660) / 15;
1133 void set_prescaled_volume(void)
1135 int prescale;
1136 int l, r;
1138 prescale = MAX(current_bass, current_treble);
1139 if (prescale < 0)
1140 prescale = 0; /* no need to prescale if we don't boost
1141 bass or treble */
1143 mas_writereg(MAS_REG_KPRESCALE, prescale_table[prescale/10]);
1145 /* gain up the analog volume to compensate the prescale reduction gain */
1146 r = l = current_volume + prescale;
1148 /* balance */
1149 if (current_balance >= 0)
1150 l -= current_balance;
1151 else
1152 r += current_balance;
1154 dac_volume(tenthdb2reg(l), tenthdb2reg(r), false);
1156 #endif /* HAVE_MAS3507D */
1157 #endif /* !SIMULATOR */
1159 void mpeg_sound_set(int setting, int value)
1161 #ifdef SIMULATOR
1162 setting = value;
1163 #else
1164 int tmp;
1166 switch(setting)
1168 case SOUND_VOLUME:
1169 value *= 2; /* Convert to percent */
1171 #ifdef HAVE_MAS3587F
1172 tmp = 0x7f00 * value / 100;
1173 mas_codec_writereg(0x10, tmp & 0xff00);
1174 #else
1175 tmp = 0x38 * value / 100;
1177 /* store volume in tenth of dB */
1178 current_volume = ( tmp < 0x08 ? tmp*30 - 780 : tmp*15 - 660 );
1180 set_prescaled_volume();
1181 #endif
1182 break;
1184 case SOUND_BASS:
1185 #ifdef HAVE_MAS3587F
1186 tmp = (((value-12) * 8) & 0xff) << 8;
1187 mas_codec_writereg(0x14, tmp & 0xff00);
1188 #else
1189 mas_writereg(MAS_REG_KBASS, bass_table[value]);
1190 current_bass = (value-15) * 10;
1191 set_prescaled_volume();
1192 #endif
1193 break;
1195 case SOUND_TREBLE:
1196 #ifdef HAVE_MAS3587F
1197 tmp = (((value-12) * 8) & 0xff) << 8;
1198 mas_codec_writereg(0x15, tmp & 0xff00);
1199 #else
1200 mas_writereg(MAS_REG_KTREBLE, treble_table[value]);
1201 current_treble = (value-15) * 10;
1202 set_prescaled_volume();
1203 #endif
1204 break;
1206 #ifdef HAVE_MAS3587F
1207 case SOUND_SUPERBASS:
1208 if (value) {
1209 tmp = MAX(MIN(value * 12, 0x7f), 0);
1210 mas_codec_writereg(MAS_REG_KMDB_STR, (tmp & 0xff) << 8);
1211 tmp = 0x30; /* MDB_HAR: Space for experiment here */
1212 mas_codec_writereg(MAS_REG_KMDB_HAR, (tmp & 0xff) << 8);
1213 tmp = 60 / 10; /* calculate MDB_FC, 60hz - experiment here,
1214 this would depend on the earphones...
1215 perhaps make it tunable? */
1216 mas_codec_writereg(MAS_REG_KMDB_FC, (tmp & 0xff) << 8);
1217 tmp = (3 * tmp) / 2; /* calculate MDB_SHAPE */
1218 mas_codec_writereg(MAS_REG_KMDB_SWITCH,
1219 ((tmp & 0xff) << 8) /* MDB_SHAPE */
1220 | 2); /* MDB_SWITCH enable */
1221 } else {
1222 mas_codec_writereg(MAS_REG_KMDB_STR, 0);
1223 mas_codec_writereg(MAS_REG_KMDB_HAR, 0);
1224 mas_codec_writereg(MAS_REG_KMDB_SWITCH, 0); /* MDB_SWITCH disable */
1226 break;
1228 case SOUND_LOUDNESS:
1229 tmp = MAX(MIN(value * 4, 0x44), 0);
1230 mas_codec_writereg(MAS_REG_KLOUDNESS, (tmp & 0xff) << 8);
1231 break;
1233 case SOUND_AVC:
1234 switch (value) {
1235 case 1: /* 2s */
1236 tmp = (0x2 << 8) | (0x8 << 12);
1237 break;
1238 case 2: /* 4s */
1239 tmp = (0x4 << 8) | (0x8 << 12);
1240 break;
1241 case 3: /* 8s */
1242 tmp = (0x8 << 8) | (0x8 << 12);
1243 break;
1244 case -1: /* turn off and then turn on again to decay quickly */
1245 tmp = mas_codec_readreg(MAS_REG_KAVC);
1246 mas_codec_writereg(MAS_REG_KAVC, 0);
1247 break;
1248 default: /* off */
1249 tmp = 0;
1250 break;
1252 mas_codec_writereg(MAS_REG_KAVC, tmp);
1253 break;
1254 #endif
1256 #endif /* SIMULATOR */
1259 int mpeg_val2phys(int setting, int value)
1261 int result = 0;
1263 switch(setting)
1265 case SOUND_VOLUME:
1266 result = value * 2;
1267 break;
1269 case SOUND_BASS:
1270 #ifdef HAVE_MAS3587F
1271 result = value - 12;
1272 #else
1273 result = value - 15;
1274 #endif
1275 break;
1277 case SOUND_TREBLE:
1278 #ifdef HAVE_MAS3587F
1279 result = value - 12;
1280 #else
1281 result = value - 15;
1282 #endif
1283 break;
1285 #ifdef HAVE_MAS3587F
1286 case SOUND_LOUDNESS:
1287 result = value;
1288 break;
1290 case SOUND_SUPERBASS:
1291 result = value * 10;
1292 break;
1293 #endif
1295 return result;
1298 void mpeg_init(int volume, int bass, int treble, int loudness, int bass_boost, int avc)
1300 #ifdef SIMULATOR
1301 volume = bass = treble = loudness = bass_boost = avc;
1302 #else
1303 unsigned long val;
1304 #ifdef HAVE_MAS3587F
1305 int rc;
1306 #else
1307 loudness = bass_boost = avc;
1308 #endif
1310 setup_sci0();
1312 #ifdef HAVE_MAS3587F
1313 mas_reset();
1315 /* Enable the audio CODEC and the DSP core, max analog voltage range */
1316 rc = mas_direct_config_write(MAS_CONTROL, 0x8c00);
1317 if(rc < 0)
1318 panicf("mas_ctrl_w: %d", rc);
1320 rc = mas_direct_config_read(MAS_CONTROL);
1321 if(rc < 0)
1322 panicf("mas_ctrl_r: %d", rc);
1324 /* Max volume on both ears */
1325 val = 0x80000;
1326 mas_writemem(MAS_BANK_D0,0x7fc,&val,1);
1327 mas_writemem(MAS_BANK_D0,0x7ff,&val,1);
1329 /* Enable the D/A Converter */
1330 mas_codec_writereg(0x0, 0x0001);
1332 /* DSP scale 100% */
1333 mas_codec_writereg(7, 0x4000);
1335 /* Disable SDO and SDI */
1336 val = 0x0d;
1337 mas_writemem(MAS_BANK_D0,0x7f2,&val,1);
1339 /* Set Demand mode and validate all settings */
1340 val = 0x25;
1341 mas_writemem(MAS_BANK_D0,0x7f1,&val,1);
1343 /* Start the Layer2/3 decoder applications */
1344 val = 0x0c;
1345 mas_writemem(MAS_BANK_D0,0x7f6,&val,1);
1346 #endif
1348 #ifdef HAVE_MAS3507D
1349 mas_writereg(0x3b, 0x20); /* Don't ask why. The data sheet doesn't say */
1350 mas_run(1);
1351 sleep(HZ);
1353 mas_readmem(MAS_BANK_D1, 0xff7, &mas_version_code, 1);
1355 /* Clear the upper 12 bits of the 32-bit samples */
1356 mas_writereg(0xc5, 0);
1357 mas_writereg(0xc6, 0);
1359 /* We need to set the PLL for a 14.1318MHz crystal */
1360 if(mas_version_code == 0x0601) /* Version F10? */
1362 val = 0x5d9e8;
1363 mas_writemem(MAS_BANK_D0, 0x32d, &val, 1);
1364 val = 0xfffceb8d;
1365 mas_writemem(MAS_BANK_D0, 0x32e, &val, 1);
1366 val = 0x0;
1367 mas_writemem(MAS_BANK_D0, 0x32f, &val, 1);
1368 mas_run(0x475);
1370 else
1372 val = 0x5d9e8;
1373 mas_writemem(MAS_BANK_D0, 0x36d, &val, 1);
1374 val = 0xfffceb8d;
1375 mas_writemem(MAS_BANK_D0, 0x36e, &val, 1);
1376 val = 0x0;
1377 mas_writemem(MAS_BANK_D0, 0x36f, &val, 1);
1378 mas_run(0xfcb);
1380 #endif
1382 mp3buflen = mp3end - mp3buf;
1384 create_fliptable();
1386 queue_init(&mpeg_queue);
1387 create_thread(mpeg_thread, mpeg_stack,
1388 sizeof(mpeg_stack), mpeg_thread_name);
1389 mas_poll_start(2);
1391 #ifdef HAVE_MAS3507D
1392 mas_writereg(MAS_REG_KPRESCALE, 0xe9400);
1393 dac_config(0x04); /* DAC on, all else off */
1395 val = 0x80000;
1396 mas_writemem(MAS_BANK_D1, 0x7f8, &val, 1);
1397 mas_writemem(MAS_BANK_D1, 0x7fb, &val, 1);
1398 #endif
1400 mpeg_sound_set(SOUND_BASS, bass);
1401 mpeg_sound_set(SOUND_TREBLE, treble);
1402 mpeg_sound_set(SOUND_VOLUME, volume);
1404 #ifdef HAVE_MAS3587F
1405 mpeg_sound_set(SOUND_LOUDNESS, loudness);
1406 mpeg_sound_set(SOUND_SUPERBASS, bass_boost);
1407 mpeg_sound_set(SOUND_AVC, avc);
1408 #endif
1409 #endif /* !SIMULATOR */
1411 memset(id3tags, sizeof(id3tags), 0);