1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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 ****************************************************************************/
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
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
[] =
67 static int numdecimals
[] =
102 static int defaultval
[] =
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)
152 static struct id3tag
*id3tags
[MAX_ID3_TAGS
];
154 static unsigned int current_track_counter
= 0;
155 static unsigned int last_track_counter
= 0;
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
;
169 static void debug_tags(void)
174 for(i
= 0;i
< MAX_ID3_TAGS
;i
++)
176 DEBUGF("id3tags[%d]: %08x", i
, id3tags
[i
]);
178 DEBUGF(" - %s", id3tags
[i
]->id3
.path
);
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());
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
;
197 DEBUGF("Tag memory is full\n");
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
;
213 id3tags
[oldidx
] = NULL
;
219 static void remove_all_tags(void)
223 for(i
= 0;i
< MAX_ID3_TAGS
;i
++)
224 remove_current_tag();
230 static bool playing
= false;
231 static bool play_pending
= false;
233 static int last_dma_tick
= 0;
234 static int pause_tick
= 0;
238 static unsigned long mas_version_code
;
240 static unsigned int bass_table
[] =
275 static unsigned int treble_table
[] =
310 static unsigned int prescale_table
[] =
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)
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
)
405 count
= FREQ
/ 1000 / 8 * interval_in_ms
;
409 panicf("Error! The MAS poll interval is too long (%d ms)\n",
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 */
422 TCR1
= 0x23; /* Clear at GRA match, sysclock/8 */
424 /* Enable interrupt on level 5 */
425 IPRC
= (IPRC
& ~0x000f) | 0x0005;
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
;
437 space
= mp3buflen
+ space
;
441 static void init_dma(void)
443 SAR3
= (unsigned int) mp3buf
+ mp3buf_read
;
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)
459 static void stop_dma(void)
465 static void dma_tick(void)
469 /* Start DMA if it is disabled and the DEMAND pin is high */
470 if(!dma_on
&& (PBDR
& 0x4000))
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
)
487 data
[i
] = big_fliptable
[data
[i
]];
491 static void reset_mp3_buffer(void)
495 mp3buf_swapwrite
= 0;
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
)
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
)
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
557 DTCR3
= last_dma_chunk_size
& 0xffff;
558 SAR3
= (unsigned int)mp3buf
+ mp3buf_read
;
562 DEBUGF("No more MP3 data. Stopping.\n");
563 queue_post(&mpeg_queue
, MPEG_TRACK_CHANGE
, 0);
564 CHCR3
= 0; /* Stop DMA interrupt */
569 CHCR3
&= ~0x0002; /* Clear DMA interrupt */
579 static void add_track_to_tag_list(char *filename
)
583 /* grab id3 tag of new file and
584 remember where in memory it starts */
585 t
= malloc(sizeof(struct id3tag
));
588 mp3info(&(t
->id3
), filename
);
589 t
->mempos
= mp3buf_write
;
594 DEBUGF("Tag list is full\n");
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
)
609 trackname
= playlist_next( steps
);
613 DEBUGF("playing %s\n", trackname
);
615 mpeg_file
= open(trackname
, O_RDONLY
);
617 DEBUGF("Couldn't open file: %s\n",trackname
);
621 add_track_to_tag_list(trackname
);
623 } while ( mpeg_file
< 0 );
628 static void stop_playing(void)
630 /* Stop the current stream */
640 static void track_change(void)
642 DEBUGF("Track change\n");
646 mpeg_sound_set(SOUND_AVC
, -1);
648 remove_current_tag();
650 current_track_counter
++;
653 static void mpeg_thread(void)
658 int unplayed_space_left
;
663 play_pending
= false;
669 DEBUGF("S R:%x W:%x SW:%x\n",
670 mp3buf_read
, mp3buf_write
, mp3buf_swapwrite
);
672 queue_wait(&mpeg_queue
, &ev
);
676 DEBUGF("MPEG_PLAY %s\n",ev
.data
);
677 /* Stop the current stream */
678 play_pending
= false;
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 )
695 add_track_to_tag_list((char *)ev
.data
);
697 /* Make it read more data */
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 */
705 current_track_counter
++;
709 DEBUGF("MPEG_STOP\n");
714 DEBUGF("MPEG_PAUSE\n");
715 /* Stop the current stream */
717 pause_tick
= current_tick
;
722 DEBUGF("MPEG_RESUME\n");
723 /* Continue the current stream */
725 last_dma_tick
+= current_tick
- pause_tick
;
731 DEBUGF("MPEG_NEXT\n");
732 /* stop the current stream */
733 play_pending
= false;
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
;
742 last_dma_tick
= current_tick
;
744 /* should we start reading more data? */
745 if(!filling
&& (get_unplayed_space() < MPEG_LOW_WATER
)) {
747 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
760 /* Open the next file */
764 if (new_file(1) < 0) {
765 DEBUGF("No more files to play\n");
768 /* Make it read more data */
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 */
776 current_track_counter
++;
782 int numtracks
= num_tracks_in_memory();
783 DEBUGF("MPEG_PREV\n");
784 /* stop the current stream */
785 play_pending
= false;
792 /* Open the next file */
796 if (new_file(-numtracks
) < 0) {
797 DEBUGF("No more files to play\n");
800 /* Make it read more data */
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 */
808 current_track_counter
++;
814 free_space_left
= mp3buf_write
- mp3buf_swapwrite
;
816 if(free_space_left
== 0)
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
,
827 amount_to_swap
= MIN(mp3buf_write
- mp3buf_swapwrite
,
830 DEBUGF("B %x\n", amount_to_swap
);
832 bitswap((unsigned short *)(mp3buf
+ mp3buf_swapwrite
),
833 (amount_to_swap
+1)/2);
835 DEBUGF("time: %d\n", t2
- t1
);
837 mp3buf_swapwrite
+= amount_to_swap
;
838 if(mp3buf_swapwrite
>= mp3buflen
)
840 mp3buf_swapwrite
= 0;
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. */
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
) ||
858 play_pending
= false;
861 last_dma_tick
= current_tick
;
865 /* Tell ourselves that we need more data */
866 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
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
)
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
,
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. */
911 len
= read(mpeg_file
, mp3buf
+mp3buf_write
, amount_to_read
);
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;
926 if(mp3buf_write
>= mp3buflen
)
932 /* Tell ourselves that we want more data */
933 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
939 DEBUGF("MPEG read error\n");
945 /* Make sure that the write pointer is at a word
947 mp3buf_write
= (mp3buf_write
+ 1) & 0xfffffffe;
951 /* No more data to play */
952 DEBUGF("No more files to play\n");
957 /* Tell ourselves that we want more data */
958 queue_post(&mpeg_queue
, MPEG_NEED_DATA
, 0);
964 case MPEG_TRACK_CHANGE
:
968 case SYS_USB_CONNECTED
:
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
);
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 */
990 /* Disable serial port */
993 /* Synchronous, no prescale */
996 /* Set baudrate 1Mbit/s */
999 /* use SCK as serial clock output */
1002 /* Clear FER and PER */
1005 /* Set interrupt ITU2 and SCI0 priority to 0 */
1008 /* set IRQ6 and IRQ7 to edge detect */
1011 /* set PB15 and PB14 to inputs */
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!) */
1024 #endif /* SIMULATOR */
1027 static struct mp3entry taginfo
;
1030 struct mp3entry
* mpeg_current_track(void)
1035 if(num_tracks_in_memory())
1036 return &(id3tags
[tag_read_idx
]->id3
);
1042 bool mpeg_has_changed_track(void)
1044 if(last_track_counter
!= current_track_counter
)
1046 last_track_counter
= current_track_counter
;
1052 void mpeg_play(char* trackname
)
1055 mp3info(&taginfo
, trackname
);
1058 queue_post(&mpeg_queue
, MPEG_PLAY
, trackname
);
1062 void mpeg_stop(void)
1065 queue_post(&mpeg_queue
, MPEG_STOP
, NULL
);
1071 void mpeg_pause(void)
1074 queue_post(&mpeg_queue
, MPEG_PAUSE
, NULL
);
1080 void mpeg_resume(void)
1083 queue_post(&mpeg_queue
, MPEG_RESUME
, NULL
);
1089 void mpeg_next(void)
1092 queue_post(&mpeg_queue
, MPEG_NEXT
, NULL
);
1094 char* file
= playlist_next(1);
1095 mp3info(&taginfo
, file
);
1096 current_track_counter
++;
1101 void mpeg_prev(void)
1104 queue_post(&mpeg_queue
, MPEG_PREV
, NULL
);
1106 char* file
= playlist_next(-1);
1107 mp3info(&taginfo
, file
);
1108 current_track_counter
--;
1113 bool mpeg_is_playing(void)
1115 return playing
|| play_pending
;
1119 #ifdef HAVE_MAS3507D
1120 int current_volume
=0; /* all values in tenth of dB */
1121 int current_treble
=0;
1123 int current_balance
=0;
1125 /* convert tenth of dB volume to register value */
1126 static int tenthdb2reg(int db
) {
1128 return (db
+ 780) / 30;
1130 return (db
+ 660) / 15;
1133 void set_prescaled_volume(void)
1138 prescale
= MAX(current_bass
, current_treble
);
1140 prescale
= 0; /* no need to prescale if we don't boost
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
;
1149 if (current_balance
>= 0)
1150 l
-= current_balance
;
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
)
1169 value
*= 2; /* Convert to percent */
1171 #ifdef HAVE_MAS3587F
1172 tmp
= 0x7f00 * value
/ 100;
1173 mas_codec_writereg(0x10, tmp
& 0xff00);
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();
1185 #ifdef HAVE_MAS3587F
1186 tmp
= (((value
-12) * 8) & 0xff) << 8;
1187 mas_codec_writereg(0x14, tmp
& 0xff00);
1189 mas_writereg(MAS_REG_KBASS
, bass_table
[value
]);
1190 current_bass
= (value
-15) * 10;
1191 set_prescaled_volume();
1196 #ifdef HAVE_MAS3587F
1197 tmp
= (((value
-12) * 8) & 0xff) << 8;
1198 mas_codec_writereg(0x15, tmp
& 0xff00);
1200 mas_writereg(MAS_REG_KTREBLE
, treble_table
[value
]);
1201 current_treble
= (value
-15) * 10;
1202 set_prescaled_volume();
1206 #ifdef HAVE_MAS3587F
1207 case SOUND_SUPERBASS
:
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 */
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 */
1228 case SOUND_LOUDNESS
:
1229 tmp
= MAX(MIN(value
* 4, 0x44), 0);
1230 mas_codec_writereg(MAS_REG_KLOUDNESS
, (tmp
& 0xff) << 8);
1236 tmp
= (0x2 << 8) | (0x8 << 12);
1239 tmp
= (0x4 << 8) | (0x8 << 12);
1242 tmp
= (0x8 << 8) | (0x8 << 12);
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);
1252 mas_codec_writereg(MAS_REG_KAVC
, tmp
);
1256 #endif /* SIMULATOR */
1259 int mpeg_val2phys(int setting
, int value
)
1270 #ifdef HAVE_MAS3587F
1271 result
= value
- 12;
1273 result
= value
- 15;
1278 #ifdef HAVE_MAS3587F
1279 result
= value
- 12;
1281 result
= value
- 15;
1285 #ifdef HAVE_MAS3587F
1286 case SOUND_LOUDNESS
:
1290 case SOUND_SUPERBASS
:
1291 result
= value
* 10;
1298 void mpeg_init(int volume
, int bass
, int treble
, int loudness
, int bass_boost
, int avc
)
1301 volume
= bass
= treble
= loudness
= bass_boost
= avc
;
1304 #ifdef HAVE_MAS3587F
1307 loudness
= bass_boost
= avc
;
1312 #ifdef HAVE_MAS3587F
1315 /* Enable the audio CODEC and the DSP core, max analog voltage range */
1316 rc
= mas_direct_config_write(MAS_CONTROL
, 0x8c00);
1318 panicf("mas_ctrl_w: %d", rc
);
1320 rc
= mas_direct_config_read(MAS_CONTROL
);
1322 panicf("mas_ctrl_r: %d", rc
);
1324 /* Max volume on both ears */
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 */
1337 mas_writemem(MAS_BANK_D0
,0x7f2,&val
,1);
1339 /* Set Demand mode and validate all settings */
1341 mas_writemem(MAS_BANK_D0
,0x7f1,&val
,1);
1343 /* Start the Layer2/3 decoder applications */
1345 mas_writemem(MAS_BANK_D0
,0x7f6,&val
,1);
1348 #ifdef HAVE_MAS3507D
1349 mas_writereg(0x3b, 0x20); /* Don't ask why. The data sheet doesn't say */
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? */
1363 mas_writemem(MAS_BANK_D0
, 0x32d, &val
, 1);
1365 mas_writemem(MAS_BANK_D0
, 0x32e, &val
, 1);
1367 mas_writemem(MAS_BANK_D0
, 0x32f, &val
, 1);
1373 mas_writemem(MAS_BANK_D0
, 0x36d, &val
, 1);
1375 mas_writemem(MAS_BANK_D0
, 0x36e, &val
, 1);
1377 mas_writemem(MAS_BANK_D0
, 0x36f, &val
, 1);
1382 mp3buflen
= mp3end
- mp3buf
;
1386 queue_init(&mpeg_queue
);
1387 create_thread(mpeg_thread
, mpeg_stack
,
1388 sizeof(mpeg_stack
), mpeg_thread_name
);
1391 #ifdef HAVE_MAS3507D
1392 mas_writereg(MAS_REG_KPRESCALE
, 0xe9400);
1393 dac_config(0x04); /* DAC on, all else off */
1396 mas_writemem(MAS_BANK_D1
, 0x7f8, &val
, 1);
1397 mas_writemem(MAS_BANK_D1
, 0x7fb, &val
, 1);
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
);
1409 #endif /* !SIMULATOR */
1411 memset(id3tags
, sizeof(id3tags
), 0);