1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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.
13 * Copyright (C) 2004 by Linus Nielsen Feltzing
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.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ****************************************************************************/
27 #include "mpeg.h" /* ToDo: remove crosslinks */
28 #include "mp3_playback.h"
37 /* hacking into mpeg.c, recording is still there */
38 #if CONFIG_HWCODEC == MAS3587F
44 #endif /* #ifdef MAS3587F */
46 #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
47 extern unsigned long shadow_io_control_main
;
48 extern unsigned shadow_codec_reg0
;
53 /* own version, independent of mpeg.c */
54 static bool paused
; /* playback is paused */
55 static bool playing
; /* We are playing an MP3 stream */
58 /* for measuring the play time */
59 static long playstart_tick
;
60 static long cumulative_ticks
;
62 /* the registered callback function to ask for more mp3 data */
63 static void (*callback_for_more
)(unsigned char**, int*);
64 #endif /* #ifndef SIMULATOR */
66 static const char* const units
[] =
75 "%", /* Stereo width */
77 "dB", /* Right gain */
79 "dB", /* MDB Strength */
80 "%", /* MDB Harmonics */
81 "Hz", /* MDB Center */
87 static const int numdecimals
[] =
100 0, /* MDB Strength */
101 0, /* MDB Harmonics */
108 static const int steps
[] =
117 1, /* Stereo width */
121 1, /* MDB Strength */
122 1, /* MDB Harmonics */
129 static const int minval
[] =
132 #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
143 0, /* Stereo width */
147 0, /* MDB Strength */
148 0, /* MDB Harmonics */
155 static const int maxval
[] =
158 #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
169 255, /* Stereo width */
173 127, /* MDB Strength */
174 100, /* MDB Harmonics */
175 300, /* MDB Center */
181 static const int defaultval
[] =
184 #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
195 100, /* Stereo width */
199 50, /* MDB Strength */
200 48, /* MDB Harmonics */
207 const char *mpeg_sound_unit(int setting
)
209 return units
[setting
];
212 int mpeg_sound_numdecimals(int setting
)
214 return numdecimals
[setting
];
217 int mpeg_sound_steps(int setting
)
219 return steps
[setting
];
222 int mpeg_sound_min(int setting
)
224 return minval
[setting
];
227 int mpeg_sound_max(int setting
)
229 return maxval
[setting
];
232 int mpeg_sound_default(int setting
)
234 return defaultval
[setting
];
237 /* list of tracks in memory */
238 #define MAX_ID3_TAGS (1<<4) /* Must be power of 2 */
239 #define MAX_ID3_TAGS_MASK (MAX_ID3_TAGS - 1)
242 static bool mpeg_is_initialized
= false;
247 unsigned long mas_version_code
;
249 #if CONFIG_HWCODEC == MAS3507D
251 static const unsigned int bass_table
[] =
286 static const unsigned int treble_table
[] =
321 static const unsigned int prescale_table
[] =
342 bool dma_on
; /* The DMA is active */
344 #if CONFIG_HWCODEC == MAS3507D
345 static void mas_poll_start(void)
349 count
= 9 * FREQ
/ 10000 / 8; /* 0.9 ms */
351 /* We are using timer 1 */
353 TSTR
&= ~0x02; /* Stop the timer */
354 TSNC
&= ~0x02; /* No synchronization */
355 TMDR
&= ~0x02; /* Operate normally */
357 TCNT1
= 0; /* Start counting at 0 */
359 TCR1
= 0x23; /* Clear at GRA match, sysclock/8 */
361 /* Enable interrupt on level 5 */
362 IPRC
= (IPRC
& ~0x000f) | 0x0005;
365 TIER1
= 0xf9; /* Enable GRA match interrupt */
367 TSTR
|= 0x02; /* Start timer 1 */
370 static void postpone_dma_tick(void)
374 count
= 8 * FREQ
/ 10000 / 8; /* 0.8 ms */
376 /* We are using timer 1 */
378 TSTR
&= ~0x02; /* Stop the timer */
379 TSNC
&= ~0x02; /* No synchronization */
380 TMDR
&= ~0x02; /* Operate normally */
382 TCNT1
= 0; /* Start counting at 0 */
384 TCR1
= 0x23; /* Clear at GRA match, sysclock/8 */
386 /* Enable interrupt on level 5 */
387 IPRC
= (IPRC
& ~0x000f) | 0x0005;
390 TIER1
= 0xf9; /* Enable GRA match interrupt */
392 TSTR
|= 0x02; /* Start timer 1 */
397 #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
398 void demand_irq_enable(bool on
)
400 int oldlevel
= set_irq_level(HIGHEST_IRQ_LEVEL
);
404 IPRA
= (IPRA
& 0xfff0) | 0x000b;
405 ICR
&= ~0x0010; /* IRQ3 level sensitive */
410 set_irq_level(oldlevel
);
412 #endif /* #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) */
417 if(playing
&& !paused
)
419 /* Start DMA if it is disabled and the DEMAND pin is high */
420 if(!(SCR0
& 0x80) && (PBDR
& 0x4000))
425 playback_tick(); /* dirty call to mpeg.c */
432 unsigned char* start
;
435 if (callback_for_more
!= NULL
)
437 callback_for_more(&start
, &size
);
442 DTCR3
= size
& 0xffff;
443 SAR3
= (unsigned int) start
;
447 CHCR3
&= ~0x0001; /* Disable the DMA interrupt */
450 CHCR3
&= ~0x0002; /* Clear DMA interrupt */
454 void IMIA1(void) /* Timer 1 interrupt */
459 #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
460 /* Disable interrupt */
466 void IRQ6(void) /* PB14: MAS stop demand IRQ */
471 #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
473 void IRQ3(void) /* PA15: MAS demand IRQ */
475 /* Begin with setting the IRQ to edge sensitive */
478 #if CONFIG_HWCODEC == MAS3587F
479 if(mpeg_mode
== MPEG_ENCODER
)
485 #endif /* #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) */
487 static void setup_sci0(void)
489 /* PB15 is I/O, PB14 is IRQ6, PB12 is SCK0, PB9 is TxD0 */
490 PBCR1
= (PBCR1
& 0x0cff) | 0x1208;
492 /* Set PB12 to output */
495 /* Disable serial port */
498 /* Synchronous, no prescale */
501 /* Set baudrate 1Mbit/s */
504 /* use SCK as serial clock output */
507 /* Clear FER and PER */
510 /* Set interrupt ITU2 and SCI0 priority to 0 */
513 /* set PB15 and PB14 to inputs */
514 and_b(~0x80, &PBIORH
);
515 and_b(~0x40, &PBIORH
);
517 /* Enable End of DMA interrupt at prio 8 */
518 IPRC
= (IPRC
& 0xf0ff) | 0x0800;
520 /* Enable Tx (only!) */
523 #endif /* SIMULATOR */
525 #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
526 static void init_playback(void)
531 mp3_play_pause(false);
535 /* Enable the audio CODEC and the DSP core, max analog voltage range */
536 rc
= mas_direct_config_write(MAS_CONTROL
, 0x8c00);
538 panicf("mas_ctrl_w: %d", rc
);
540 /* Stop the current application */
542 mas_writemem(MAS_BANK_D0
, MAS_D0_APP_SELECT
, &val
, 1);
545 mas_readmem(MAS_BANK_D0
, MAS_D0_APP_RUNNING
, &val
, 1);
548 /* Enable the D/A Converter */
549 shadow_codec_reg0
= 0x0001;
550 mas_codec_writereg(0x0, shadow_codec_reg0
);
552 /* ADC scale 0%, DSP scale 100% */
553 mas_codec_writereg(6, 0x0000);
554 mas_codec_writereg(7, 0x4000);
556 #ifdef HAVE_SPDIF_OUT
557 val
= 0x09; /* Disable SDO and SDI, low impedance S/PDIF outputs */
559 val
= 0x2d; /* Disable SDO and SDI, disable S/PDIF output */
561 mas_writemem(MAS_BANK_D0
, MAS_D0_INTERFACE_CONTROL
, &val
, 1);
563 /* Set Demand mode and validate all settings */
564 shadow_io_control_main
= 0x25;
565 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
567 /* Start the Layer2/3 decoder applications */
569 mas_writemem(MAS_BANK_D0
, MAS_D0_APP_SELECT
, &val
, 1);
572 mas_readmem(MAS_BANK_D0
, MAS_D0_APP_RUNNING
, &val
, 1);
573 } while((val
& 0x0c) != 0x0c);
575 #if CONFIG_HWCODEC == MAS3587F
576 mpeg_mode
= MPEG_DECODER
;
579 /* set IRQ6 to edge detect */
582 /* set IRQ6 prio 8 */
583 IPRB
= ( IPRB
& 0xff0f ) | 0x0080;
585 DEBUGF("MAS Decoding application started\n");
587 #endif /* #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) */
590 #if CONFIG_HWCODEC == MAS3507D
591 int current_left_volume
= 0; /* all values in tenth of dB */
592 int current_right_volume
= 0; /* all values in tenth of dB */
593 int current_treble
= 0;
594 int current_bass
= 0;
595 int current_balance
= 0;
597 /* convert tenth of dB volume to register value */
598 static int tenthdb2reg(int db
) {
600 return (db
+ 780) / 30;
602 return (db
+ 660) / 15;
605 void set_prescaled_volume(void)
610 prescale
= MAX(current_bass
, current_treble
);
612 prescale
= 0; /* no need to prescale if we don't boost
615 mas_writereg(MAS_REG_KPRESCALE
, prescale_table
[prescale
/10]);
617 /* gain up the analog volume to compensate the prescale reduction gain */
618 l
= current_left_volume
+ prescale
;
619 r
= current_right_volume
+ prescale
;
621 dac_volume(tenthdb2reg(l
), tenthdb2reg(r
), false);
623 #endif /* MAS3507D */
624 #endif /* !SIMULATOR */
626 int channel_configuration
= MPEG_SOUND_STEREO
;
627 int stereo_width
= 100;
630 static void set_channel_config(void)
632 /* default values: stereo */
633 unsigned long val_ll
= 0x80000;
634 unsigned long val_lr
= 0;
635 unsigned long val_rl
= 0;
636 unsigned long val_rr
= 0x80000;
638 switch(channel_configuration
)
640 /* case MPEG_SOUND_STEREO unnecessary */
642 case MPEG_SOUND_MONO
:
649 case MPEG_SOUND_CUSTOM
:
651 /* fixed point variables (matching MAS internal format)
652 integer part: upper 13 bits (inlcuding sign)
653 fractional part: lower 19 bits */
654 long fp_width
, fp_straight
, fp_cross
;
656 fp_width
= (stereo_width
<< 19) / 100;
657 if (stereo_width
<= 100)
659 fp_straight
= - ((1<<19) + fp_width
) / 2;
660 fp_cross
= fp_straight
+ fp_width
;
664 fp_straight
= - (1<<19);
665 fp_cross
= ((2 * fp_width
/ (((1<<19) + fp_width
) >> 10))
668 val_ll
= val_rr
= fp_straight
& 0xFFFFF;
669 val_lr
= val_rl
= fp_cross
& 0xFFFFF;
673 case MPEG_SOUND_MONO_LEFT
:
680 case MPEG_SOUND_MONO_RIGHT
:
687 case MPEG_SOUND_KARAOKE
:
695 #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
696 mas_writemem(MAS_BANK_D0
, MAS_D0_OUT_LL
, &val_ll
, 1); /* LL */
697 mas_writemem(MAS_BANK_D0
, MAS_D0_OUT_LR
, &val_lr
, 1); /* LR */
698 mas_writemem(MAS_BANK_D0
, MAS_D0_OUT_RL
, &val_rl
, 1); /* RL */
699 mas_writemem(MAS_BANK_D0
, MAS_D0_OUT_RR
, &val_rr
, 1); /* RR */
700 #elif CONFIG_HWCODEC == MAS3507D
701 mas_writemem(MAS_BANK_D1
, 0x7f8, &val_ll
, 1); /* LL */
702 mas_writemem(MAS_BANK_D1
, 0x7f9, &val_lr
, 1); /* LR */
703 mas_writemem(MAS_BANK_D1
, 0x7fa, &val_rl
, 1); /* RL */
704 mas_writemem(MAS_BANK_D1
, 0x7fb, &val_rr
, 1); /* RR */
707 #endif /* !SIMULATOR */
709 #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
710 unsigned long mdb_shape_shadow
= 0;
711 unsigned long loudness_shadow
= 0;
714 void mpeg_sound_set(int setting
, int value
)
719 #if CONFIG_HWCODEC == MAS3507D
725 if(!mpeg_is_initialized
)
731 #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
732 tmp
= 0x7f00 * value
/ 100;
733 mas_codec_writereg(0x10, tmp
& 0xff00);
738 if(current_balance
> 0)
740 l
-= current_balance
;
745 if(current_balance
< 0)
747 r
+= current_balance
;
755 /* store volume in tenth of dB */
756 current_left_volume
= ( l
< 0x08 ? l
*30 - 780 : l
*15 - 660 );
757 current_right_volume
= ( r
< 0x08 ? r
*30 - 780 : r
*15 - 660 );
759 set_prescaled_volume();
764 #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
765 tmp
= ((value
* 127 / 100) & 0xff) << 8;
766 mas_codec_writereg(0x11, tmp
& 0xff00);
768 current_balance
= value
;
773 #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
774 tmp
= ((value
* 8) & 0xff) << 8;
775 mas_codec_writereg(0x14, tmp
& 0xff00);
777 mas_writereg(MAS_REG_KBASS
, bass_table
[value
+15]);
778 current_bass
= (value
) * 10;
779 set_prescaled_volume();
784 #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
785 tmp
= ((value
* 8) & 0xff) << 8;
786 mas_codec_writereg(0x15, tmp
& 0xff00);
788 mas_writereg(MAS_REG_KTREBLE
, treble_table
[value
+15]);
789 current_treble
= (value
) * 10;
790 set_prescaled_volume();
794 #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
796 loudness_shadow
= (loudness_shadow
& 0x04) |
797 (MAX(MIN(value
* 4, 0x44), 0) << 8);
798 mas_codec_writereg(MAS_REG_KLOUDNESS
, loudness_shadow
);
804 tmp
= (0x1 << 8) | (0x8 << 12);
807 tmp
= (0x2 << 8) | (0x8 << 12);
810 tmp
= (0x4 << 8) | (0x8 << 12);
813 tmp
= (0x8 << 8) | (0x8 << 12);
815 case -1: /* turn off and then turn on again to decay quickly */
816 tmp
= mas_codec_readreg(MAS_REG_KAVC
);
817 mas_codec_writereg(MAS_REG_KAVC
, 0);
823 mas_codec_writereg(MAS_REG_KAVC
, tmp
);
826 case SOUND_MDB_STRENGTH
:
827 mas_codec_writereg(MAS_REG_KMDB_STR
, (value
& 0x7f) << 8);
830 case SOUND_MDB_HARMONICS
:
831 tmp
= value
* 127 / 100;
832 mas_codec_writereg(MAS_REG_KMDB_HAR
, (tmp
& 0x7f) << 8);
835 case SOUND_MDB_CENTER
:
836 mas_codec_writereg(MAS_REG_KMDB_FC
, (value
/10) << 8);
839 case SOUND_MDB_SHAPE
:
840 mdb_shape_shadow
= (mdb_shape_shadow
& 0x02) | ((value
/10) << 8);
841 mas_codec_writereg(MAS_REG_KMDB_SWITCH
, mdb_shape_shadow
);
844 case SOUND_MDB_ENABLE
:
845 mdb_shape_shadow
= (mdb_shape_shadow
& ~0x02) | (value
?2:0);
846 mas_codec_writereg(MAS_REG_KMDB_SWITCH
, mdb_shape_shadow
);
849 case SOUND_SUPERBASS
:
850 loudness_shadow
= (loudness_shadow
& ~0x04) |
852 mas_codec_writereg(MAS_REG_KLOUDNESS
, loudness_shadow
);
856 channel_configuration
= value
;
857 set_channel_config();
860 case SOUND_STEREO_WIDTH
:
861 stereo_width
= value
;
862 if (channel_configuration
== MPEG_SOUND_CUSTOM
)
863 set_channel_config();
866 #endif /* SIMULATOR */
869 int mpeg_val2phys(int setting
, int value
)
871 #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
876 case SOUND_LEFT_GAIN
:
877 case SOUND_RIGHT_GAIN
:
878 result
= (value
- 2) * 15;
882 result
= value
* 15 + 210;
896 #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
897 /* This function works by telling the decoder that we have another
898 crystal frequency than we actually have. It will adjust its internal
899 parameters and the result is that the audio is played at another pitch.
901 The pitch value is in tenths of percent.
903 void mpeg_set_pitch(int pitch
)
907 /* invert pitch value */
908 pitch
= 1000000/pitch
;
910 /* Calculate the new (bogus) frequency */
911 val
= 18432*pitch
/1000;
913 mas_writemem(MAS_BANK_D0
, MAS_D0_OFREQ_CONTROL
, &val
, 1);
915 /* We must tell the MAS that the frequency has changed.
916 This will unfortunately cause a short silence. */
917 mas_writemem(MAS_BANK_D0
, MAS_D0_IO_CONTROL_MAIN
, &shadow_io_control_main
, 1);
921 void mp3_init(int volume
, int bass
, int treble
, int balance
, int loudness
,
922 int avc
, int channel_config
, int stereo_width
,
923 int mdb_strength
, int mdb_harmonics
,
924 int mdb_center
, int mdb_shape
, bool mdb_enable
,
934 (void)channel_config
;
943 #if CONFIG_HWCODEC == MAS3507D
957 #ifdef HAVE_MAS_SIBI_CONTROL
958 and_b(~0x01, &PBDRH
); /* drive SIBI low */
959 or_b(0x01, &PBIORH
); /* output for PB8 */
962 #if CONFIG_HWCODEC == MAS3507D
964 #elif CONFIG_HWCODEC == MAS3587F
965 or_b(0x08, &PAIORH
); /* output for /PR */
968 mas_version_code
= mas_readver();
969 DEBUGF("MAS3587 derivate %d, version %c%d\n",
970 (mas_version_code
& 0xf000) >> 12,
971 'A' + ((mas_version_code
& 0x0f00) >> 8), mas_version_code
& 0xff);
972 #elif CONFIG_HWCODEC == MAS3539F
973 or_b(0x08, &PAIORH
); /* output for /PR */
976 mas_version_code
= mas_readver();
977 DEBUGF("MAS3539 derivate %d, version %c%d\n",
978 (mas_version_code
& 0xf000) >> 12,
979 'A' + ((mas_version_code
& 0x0f00) >> 8), mas_version_code
& 0xff);
986 #if CONFIG_HWCODEC == MAS3507D
987 and_b(~0x20, &PBDRL
);
992 /* set IRQ6 to edge detect */
995 /* set IRQ6 prio 8 */
996 IPRB
= ( IPRB
& 0xff0f ) | 0x0080;
998 mas_readmem(MAS_BANK_D1
, 0xff7, &mas_version_code
, 1);
1000 mas_writereg(0x3b, 0x20); /* Don't ask why. The data sheet doesn't say */
1004 /* Clear the upper 12 bits of the 32-bit samples */
1005 mas_writereg(0xc5, 0);
1006 mas_writereg(0xc6, 0);
1008 /* We need to set the PLL for a 14.31818MHz crystal */
1009 if(mas_version_code
== 0x0601) /* Version F10? */
1012 mas_writemem(MAS_BANK_D0
, 0x32d, &val
, 1);
1014 mas_writemem(MAS_BANK_D0
, 0x32e, &val
, 1);
1016 mas_writemem(MAS_BANK_D0
, 0x32f, &val
, 1);
1022 mas_writemem(MAS_BANK_D0
, 0x36d, &val
, 1);
1024 mas_writemem(MAS_BANK_D0
, 0x36e, &val
, 1);
1026 mas_writemem(MAS_BANK_D0
, 0x36f, &val
, 1);
1032 #if CONFIG_HWCODEC == MAS3507D
1035 mas_writereg(MAS_REG_KPRESCALE
, 0xe9400);
1039 #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
1040 ICR
&= ~0x0010; /* IRQ3 level sensitive */
1041 PACR1
= (PACR1
& 0x3fff) | 0x4000; /* PA15 is IRQ3 */
1044 /* Must be done before calling mpeg_sound_set() */
1045 mpeg_is_initialized
= true;
1047 mpeg_sound_set(SOUND_BASS
, bass
);
1048 mpeg_sound_set(SOUND_TREBLE
, treble
);
1049 mpeg_sound_set(SOUND_BALANCE
, balance
);
1050 mpeg_sound_set(SOUND_VOLUME
, volume
);
1051 mpeg_sound_set(SOUND_CHANNELS
, channel_config
);
1052 mpeg_sound_set(SOUND_STEREO_WIDTH
, stereo_width
);
1054 #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
1055 mpeg_sound_set(SOUND_LOUDNESS
, loudness
);
1056 mpeg_sound_set(SOUND_AVC
, avc
);
1057 mpeg_sound_set(SOUND_MDB_STRENGTH
, mdb_strength
);
1058 mpeg_sound_set(SOUND_MDB_HARMONICS
, mdb_harmonics
);
1059 mpeg_sound_set(SOUND_MDB_CENTER
, mdb_center
);
1060 mpeg_sound_set(SOUND_MDB_SHAPE
, mdb_shape
);
1061 mpeg_sound_set(SOUND_MDB_ENABLE
, mdb_enable
);
1062 mpeg_sound_set(SOUND_SUPERBASS
, superbass
);
1064 #endif /* !SIMULATOR */
1070 void mp3_shutdown(void)
1073 #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
1074 unsigned long val
= 1;
1075 mas_writemem(MAS_BANK_D0
, MAS_D0_SOFT_MUTE
, &val
, 1); /* Mute */
1078 #if CONFIG_HWCODEC == MAS3507D
1079 dac_volume(0, 0, false);
1085 /* new functions, to be exported to plugin API */
1089 void mp3_play_init(void)
1091 #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
1096 callback_for_more
= NULL
;
1097 mp3_reset_playtime();
1100 void mp3_play_data(const unsigned char* start
, int size
,
1101 void (*get_more
)(unsigned char** start
, int* size
) /* callback fn */
1106 CHCR3
&= ~0x0002; /* Clear interrupt */
1107 CHCR3
= 0x1504; /* Single address destination, TXI0, IE=1 */
1108 DMAOR
= 0x0001; /* Enable DMA */
1110 callback_for_more
= get_more
;
1112 SAR3
= (unsigned int)start
;
1113 DTCR3
= size
& 0xffff;
1118 CHCR3
|= 0x0001; /* Enable DMA IRQ */
1120 #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
1121 demand_irq_enable(true);
1125 void mp3_play_pause(bool play
)
1128 { /* resume playback */
1131 playstart_tick
= current_tick
;
1133 else if (!paused
&& !play
)
1134 { /* stop playback */
1137 cumulative_ticks
+= current_tick
- playstart_tick
;
1141 void mp3_play_stop(void)
1144 mp3_play_pause(false);
1145 CHCR3
&= ~0x0001; /* Disable the DMA interrupt */
1146 #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F)
1147 demand_irq_enable(false);
1151 long mp3_get_playtime(void)
1154 return cumulative_ticks
;
1156 return cumulative_ticks
+ current_tick
- playstart_tick
;
1159 void mp3_reset_playtime(void)
1161 cumulative_ticks
= 0;
1162 playstart_tick
= current_tick
;
1166 bool mp3_is_playing(void)
1172 /* returns the next byte position which would be transferred */
1173 unsigned char* mp3_get_pos(void)
1175 return (unsigned char*)SAR3
;
1179 #endif /* #ifndef SIMULATOR */