From 674eaca5ef59625f90088da006eca4d10e2bea56 Mon Sep 17 00:00:00 2001 From: Linus Nielsen Feltzing Date: Fri, 1 Apr 2005 13:41:03 +0000 Subject: Moved the mpeg_sound_xxx() functions to sound.c and renamed them to sound_xxx() git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6240 a1c6a512-1295-4272-9138-f99709370657 --- firmware/SOURCES | 5 +- firmware/export/mp3_playback.h | 40 --- firmware/export/sound.h | 61 ++++ firmware/mp3_playback.c | 642 ++--------------------------------------- firmware/mpeg.c | 3 +- firmware/sound.c | 634 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 720 insertions(+), 665 deletions(-) create mode 100644 firmware/export/sound.h create mode 100644 firmware/sound.c (limited to 'firmware') diff --git a/firmware/SOURCES b/firmware/SOURCES index 870026f835..8279f812d1 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -111,7 +111,10 @@ bitswap.S descramble.S #endif drivers/lcd.S -#if defined(IRIVER_H100) && !defined(SIMULATOR) +#ifdef IRIVER_H100 +#ifndef SIMULATOR drivers/uda1380.c pcm_playback.c #endif +#endif +sound.c diff --git a/firmware/export/mp3_playback.h b/firmware/export/mp3_playback.h index aced6ddc94..4da1ffce6d 100644 --- a/firmware/export/mp3_playback.h +++ b/firmware/export/mp3_playback.h @@ -30,19 +30,6 @@ void mp3_init(int volume, int bass, int treble, int balance, int loudness, int mdb_strength, int mdb_harmonics, int mdb_center, int mdb_shape, bool mdb_enable, bool superbass); -void mpeg_sound_set(int setting, int value); -int mpeg_sound_min(int setting); -int mpeg_sound_max(int setting); -int mpeg_sound_default(int setting); -void mpeg_sound_channel_config(int configuration); -int mpeg_val2phys(int setting, int value); -const char *mpeg_sound_unit(int setting); -int mpeg_sound_numdecimals(int setting); -int mpeg_sound_steps(int setting); -#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) || defined(SIMULATOR) -void mpeg_set_pitch(int percent); -#endif - /* exported just for mpeg.c, to keep the recording there */ #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) @@ -62,31 +49,4 @@ bool mp3_is_playing(void); unsigned char* mp3_get_pos(void); void mp3_shutdown(void); - -#define SOUND_VOLUME 0 -#define SOUND_BASS 1 -#define SOUND_TREBLE 2 -#define SOUND_BALANCE 3 -#define SOUND_LOUDNESS 4 -#define SOUND_AVC 5 -#define SOUND_CHANNELS 6 -#define SOUND_STEREO_WIDTH 7 -#define SOUND_LEFT_GAIN 8 -#define SOUND_RIGHT_GAIN 9 -#define SOUND_MIC_GAIN 10 -#define SOUND_MDB_STRENGTH 11 -#define SOUND_MDB_HARMONICS 12 -#define SOUND_MDB_CENTER 13 -#define SOUND_MDB_SHAPE 14 -#define SOUND_MDB_ENABLE 15 -#define SOUND_SUPERBASS 16 -#define SOUND_NUMSETTINGS 17 - -#define MPEG_SOUND_STEREO 0 -#define MPEG_SOUND_MONO 1 -#define MPEG_SOUND_CUSTOM 2 -#define MPEG_SOUND_MONO_LEFT 3 -#define MPEG_SOUND_MONO_RIGHT 4 -#define MPEG_SOUND_KARAOKE 5 - #endif /* #ifndef _MP3_PLAYBACK_H_ */ diff --git a/firmware/export/sound.h b/firmware/export/sound.h new file mode 100644 index 0000000000..2fa00d88a9 --- /dev/null +++ b/firmware/export/sound.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2005 by Linus Nielsen Feltzing + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#ifndef SOUND_H +#define SOUND_H + +#define SOUND_VOLUME 0 +#define SOUND_BASS 1 +#define SOUND_TREBLE 2 +#define SOUND_BALANCE 3 +#define SOUND_LOUDNESS 4 +#define SOUND_AVC 5 +#define SOUND_CHANNELS 6 +#define SOUND_STEREO_WIDTH 7 +#define SOUND_LEFT_GAIN 8 +#define SOUND_RIGHT_GAIN 9 +#define SOUND_MIC_GAIN 10 +#define SOUND_MDB_STRENGTH 11 +#define SOUND_MDB_HARMONICS 12 +#define SOUND_MDB_CENTER 13 +#define SOUND_MDB_SHAPE 14 +#define SOUND_MDB_ENABLE 15 +#define SOUND_SUPERBASS 16 +#define SOUND_NUMSETTINGS 17 + +#define SOUND_CHAN_STEREO 0 +#define SOUND_CHAN_MONO 1 +#define SOUND_CHAN_CUSTOM 2 +#define SOUND_CHAN_MONO_LEFT 3 +#define SOUND_CHAN_MONO_RIGHT 4 +#define SOUND_CHAN_KARAOKE 5 + +void sound_set(int setting, int value); +int sound_min(int setting); +int sound_max(int setting); +int sound_default(int setting); +void sound_channel_config(int configuration); +int sound_val2phys(int setting, int value); +const char *sound_unit(int setting); +int sound_numdecimals(int setting); +int sound_steps(int setting); +#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) || defined(SIMULATOR) +void sound_set_pitch(int percent); +#endif + +#endif diff --git a/firmware/mp3_playback.c b/firmware/mp3_playback.c index 16fe544c7a..14e0aa796e 100644 --- a/firmware/mp3_playback.c +++ b/firmware/mp3_playback.c @@ -26,6 +26,7 @@ #include #include "mpeg.h" /* ToDo: remove crosslinks */ #include "mp3_playback.h" +#include "sound.h" #ifndef SIMULATOR #include "i2c.h" #include "mas.h" @@ -63,183 +64,12 @@ static long cumulative_ticks; static void (*callback_for_more)(unsigned char**, int*); #endif /* #ifndef SIMULATOR */ -static const char* const units[] = -{ - "%", /* Volume */ - "dB", /* Bass */ - "dB", /* Treble */ - "%", /* Balance */ - "dB", /* Loudness */ - "", /* AVC */ - "", /* Channels */ - "%", /* Stereo width */ - "dB", /* Left gain */ - "dB", /* Right gain */ - "dB", /* Mic gain */ - "dB", /* MDB Strength */ - "%", /* MDB Harmonics */ - "Hz", /* MDB Center */ - "Hz", /* MDB Shape */ - "", /* MDB Enable */ - "", /* Super bass */ -}; - -static const int numdecimals[] = -{ - 0, /* Volume */ - 0, /* Bass */ - 0, /* Treble */ - 0, /* Balance */ - 0, /* Loudness */ - 0, /* AVC */ - 0, /* Channels */ - 0, /* Stereo width */ - 1, /* Left gain */ - 1, /* Right gain */ - 1, /* Mic gain */ - 0, /* MDB Strength */ - 0, /* MDB Harmonics */ - 0, /* MDB Center */ - 0, /* MDB Shape */ - 0, /* MDB Enable */ - 0, /* Super bass */ -}; - -static const int steps[] = -{ - 1, /* Volume */ - 1, /* Bass */ - 1, /* Treble */ - 1, /* Balance */ - 1, /* Loudness */ - 1, /* AVC */ - 1, /* Channels */ - 1, /* Stereo width */ - 1, /* Left gain */ - 1, /* Right gain */ - 1, /* Mic gain */ - 1, /* MDB Strength */ - 1, /* MDB Harmonics */ - 10, /* MDB Center */ - 10, /* MDB Shape */ - 1, /* MDB Enable */ - 1, /* Super bass */ -}; - -static const int minval[] = -{ - 0, /* Volume */ -#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) - -12, /* Bass */ - -12, /* Treble */ -#else - -15, /* Bass */ - -15, /* Treble */ -#endif - -100, /* Balance */ - 0, /* Loudness */ - -1, /* AVC */ - 0, /* Channels */ - 0, /* Stereo width */ - 0, /* Left gain */ - 0, /* Right gain */ - 0, /* Mic gain */ - 0, /* MDB Strength */ - 0, /* MDB Harmonics */ - 20, /* MDB Center */ - 50, /* MDB Shape */ - 0, /* MDB Enable */ - 0, /* Super bass */ -}; - -static const int maxval[] = -{ - 100, /* Volume */ -#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) - 12, /* Bass */ - 12, /* Treble */ -#else - 15, /* Bass */ - 15, /* Treble */ -#endif - 100, /* Balance */ - 17, /* Loudness */ - 4, /* AVC */ - 5, /* Channels */ - 255, /* Stereo width */ - 15, /* Left gain */ - 15, /* Right gain */ - 15, /* Mic gain */ - 127, /* MDB Strength */ - 100, /* MDB Harmonics */ - 300, /* MDB Center */ - 300, /* MDB Shape */ - 1, /* MDB Enable */ - 1, /* Super bass */ -}; - -static const int defaultval[] = -{ - 70, /* Volume */ -#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) - 6, /* Bass */ - 6, /* Treble */ -#else - 7, /* Bass */ - 7, /* Treble */ -#endif - 0, /* Balance */ - 0, /* Loudness */ - 0, /* AVC */ - 0, /* Channels */ - 100, /* Stereo width */ - 8, /* Left gain */ - 8, /* Right gain */ - 2, /* Mic gain */ - 50, /* MDB Strength */ - 48, /* MDB Harmonics */ - 60, /* MDB Center */ - 90, /* MDB Shape */ - 0, /* MDB Enable */ - 0, /* Super bass */ -}; - -const char *mpeg_sound_unit(int setting) -{ - return units[setting]; -} - -int mpeg_sound_numdecimals(int setting) -{ - return numdecimals[setting]; -} - -int mpeg_sound_steps(int setting) -{ - return steps[setting]; -} - -int mpeg_sound_min(int setting) -{ - return minval[setting]; -} - -int mpeg_sound_max(int setting) -{ - return maxval[setting]; -} - -int mpeg_sound_default(int setting) -{ - return defaultval[setting]; -} - /* list of tracks in memory */ #define MAX_ID3_TAGS (1<<4) /* Must be power of 2 */ #define MAX_ID3_TAGS_MASK (MAX_ID3_TAGS - 1) #ifndef SIMULATOR -static bool mpeg_is_initialized = false; +bool audio_is_initialized = false; #endif #if CONFIG_HWCODEC != MASNONE @@ -249,99 +79,6 @@ static bool mpeg_is_initialized = false; unsigned long mas_version_code; -#if CONFIG_HWCODEC == MAS3507D - -static const unsigned int bass_table[] = -{ - 0x9e400, /* -15dB */ - 0xa2800, /* -14dB */ - 0xa7400, /* -13dB */ - 0xac400, /* -12dB */ - 0xb1800, /* -11dB */ - 0xb7400, /* -10dB */ - 0xbd400, /* -9dB */ - 0xc3c00, /* -8dB */ - 0xca400, /* -7dB */ - 0xd1800, /* -6dB */ - 0xd8c00, /* -5dB */ - 0xe0400, /* -4dB */ - 0xe8000, /* -3dB */ - 0xefc00, /* -2dB */ - 0xf7c00, /* -1dB */ - 0, - 0x800, /* 1dB */ - 0x10000, /* 2dB */ - 0x17c00, /* 3dB */ - 0x1f800, /* 4dB */ - 0x27000, /* 5dB */ - 0x2e400, /* 6dB */ - 0x35800, /* 7dB */ - 0x3c000, /* 8dB */ - 0x42800, /* 9dB */ - 0x48800, /* 10dB */ - 0x4e400, /* 11dB */ - 0x53800, /* 12dB */ - 0x58800, /* 13dB */ - 0x5d400, /* 14dB */ - 0x61800 /* 15dB */ -}; - -static const unsigned int treble_table[] = -{ - 0xb2c00, /* -15dB */ - 0xbb400, /* -14dB */ - 0xc1800, /* -13dB */ - 0xc6c00, /* -12dB */ - 0xcbc00, /* -11dB */ - 0xd0400, /* -10dB */ - 0xd5000, /* -9dB */ - 0xd9800, /* -8dB */ - 0xde000, /* -7dB */ - 0xe2800, /* -6dB */ - 0xe7e00, /* -5dB */ - 0xec000, /* -4dB */ - 0xf0c00, /* -3dB */ - 0xf5c00, /* -2dB */ - 0xfac00, /* -1dB */ - 0, - 0x5400, /* 1dB */ - 0xac00, /* 2dB */ - 0x10400, /* 3dB */ - 0x16000, /* 4dB */ - 0x1c000, /* 5dB */ - 0x22400, /* 6dB */ - 0x28400, /* 7dB */ - 0x2ec00, /* 8dB */ - 0x35400, /* 9dB */ - 0x3c000, /* 10dB */ - 0x42c00, /* 11dB */ - 0x49c00, /* 12dB */ - 0x51800, /* 13dB */ - 0x58400, /* 14dB */ - 0x5f800 /* 15dB */ -}; - -static const unsigned int prescale_table[] = -{ - 0x80000, /* 0db */ - 0x8e000, /* 1dB */ - 0x9a400, /* 2dB */ - 0xa5800, /* 3dB */ - 0xaf400, /* 4dB */ - 0xb8000, /* 5dB */ - 0xbfc00, /* 6dB */ - 0xc6c00, /* 7dB */ - 0xcd000, /* 8dB */ - 0xd25c0, /* 9dB */ - 0xd7800, /* 10dB */ - 0xdc000, /* 11dB */ - 0xdfc00, /* 12dB */ - 0xe3400, /* 13dB */ - 0xe6800, /* 14dB */ - 0xe9400 /* 15dB */ -}; -#endif - bool dma_on; /* The DMA is active */ #if CONFIG_HWCODEC == MAS3507D @@ -589,329 +326,6 @@ static void init_playback(void) } #endif /* #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) */ -#ifndef SIMULATOR -#if CONFIG_HWCODEC == MAS3507D -/* all values in tenth of dB */ -int current_volume = 0; /* -780..+180 */ -int current_balance = 0; /* -960..+960 */ -int current_treble = 0; /* -150..+150 */ -int current_bass = 0; /* -150..+150 */ - -/* convert tenth of dB volume to register value */ -static int tenthdb2reg(int db) { - if (db < -540) - return (db + 780) / 30; - else - return (db + 660) / 15; -} - -void set_prescaled_volume(void) -{ - int prescale; - int l, r; - - prescale = MAX(current_bass, current_treble); - if (prescale < 0) - prescale = 0; /* no need to prescale if we don't boost - bass or treble */ - - mas_writereg(MAS_REG_KPRESCALE, prescale_table[prescale/10]); - - /* gain up the analog volume to compensate the prescale reduction gain, - * but limit to +18 dB (the maximum the DAC can do */ - if (current_volume + prescale > 180) - prescale = 180 - current_volume; - l = r = current_volume + prescale; - - if (current_balance > 0) - { - l -= current_balance; - if (l < -780) - l = -780; - } - if (current_balance < 0) - { - r += current_balance; - if (r < -780) - r = -780; - } - - dac_volume(tenthdb2reg(l), tenthdb2reg(r), false); -} -#endif /* MAS3507D */ -#endif /* !SIMULATOR */ - -int channel_configuration = MPEG_SOUND_STEREO; -int stereo_width = 100; - -#ifndef SIMULATOR -static void set_channel_config(void) -{ - /* default values: stereo */ - unsigned long val_ll = 0x80000; - unsigned long val_lr = 0; - unsigned long val_rl = 0; - unsigned long val_rr = 0x80000; - - switch(channel_configuration) - { - /* case MPEG_SOUND_STEREO unnecessary */ - - case MPEG_SOUND_MONO: - val_ll = 0xc0000; - val_lr = 0xc0000; - val_rl = 0xc0000; - val_rr = 0xc0000; - break; - - case MPEG_SOUND_CUSTOM: - { - /* fixed point variables (matching MAS internal format) - integer part: upper 13 bits (inlcuding sign) - fractional part: lower 19 bits */ - long fp_width, fp_straight, fp_cross; - - fp_width = (stereo_width << 19) / 100; - if (stereo_width <= 100) - { - fp_straight = - ((1<<19) + fp_width) / 2; - fp_cross = fp_straight + fp_width; - } - else - { - fp_straight = - (1<<19); - fp_cross = ((2 * fp_width / (((1<<19) + fp_width) >> 10)) - << 9) - (1<<19); - } - val_ll = val_rr = fp_straight & 0xFFFFF; - val_lr = val_rl = fp_cross & 0xFFFFF; - } - break; - - case MPEG_SOUND_MONO_LEFT: - val_ll = 0x80000; - val_lr = 0x80000; - val_rl = 0; - val_rr = 0; - break; - - case MPEG_SOUND_MONO_RIGHT: - val_ll = 0; - val_lr = 0; - val_rl = 0x80000; - val_rr = 0x80000; - break; - - case MPEG_SOUND_KARAOKE: - val_ll = 0x80001; - val_lr = 0x7ffff; - val_rl = 0x7ffff; - val_rr = 0x80001; - break; - } - -#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) - mas_writemem(MAS_BANK_D0, MAS_D0_OUT_LL, &val_ll, 1); /* LL */ - mas_writemem(MAS_BANK_D0, MAS_D0_OUT_LR, &val_lr, 1); /* LR */ - mas_writemem(MAS_BANK_D0, MAS_D0_OUT_RL, &val_rl, 1); /* RL */ - mas_writemem(MAS_BANK_D0, MAS_D0_OUT_RR, &val_rr, 1); /* RR */ -#elif CONFIG_HWCODEC == MAS3507D - mas_writemem(MAS_BANK_D1, 0x7f8, &val_ll, 1); /* LL */ - mas_writemem(MAS_BANK_D1, 0x7f9, &val_lr, 1); /* LR */ - mas_writemem(MAS_BANK_D1, 0x7fa, &val_rl, 1); /* RL */ - mas_writemem(MAS_BANK_D1, 0x7fb, &val_rr, 1); /* RR */ -#endif -} -#endif /* !SIMULATOR */ - -#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) -unsigned long mdb_shape_shadow = 0; -unsigned long loudness_shadow = 0; -#endif - -void mpeg_sound_set(int setting, int value) -{ -#ifdef SIMULATOR - setting = value; -#else -#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) - int tmp; -#endif - - if(!mpeg_is_initialized) - return; - - switch(setting) - { - case SOUND_VOLUME: -#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) - tmp = 0x7f00 * value / 100; - mas_codec_writereg(0x10, tmp & 0xff00); -#else - current_volume = -780 + (value * 960 / 100); /* tenth of dB */ - set_prescaled_volume(); -#endif - break; - - case SOUND_BALANCE: -#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) - tmp = ((value * 127 / 100) & 0xff) << 8; - mas_codec_writereg(0x11, tmp & 0xff00); -#else - current_balance = value * 960 / 100; /* tenth of dB */ - set_prescaled_volume(); -#endif - break; - - case SOUND_BASS: -#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) - tmp = ((value * 8) & 0xff) << 8; - mas_codec_writereg(0x14, tmp & 0xff00); -#else - mas_writereg(MAS_REG_KBASS, bass_table[value+15]); - current_bass = value * 10; - set_prescaled_volume(); -#endif - break; - - case SOUND_TREBLE: -#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) - tmp = ((value * 8) & 0xff) << 8; - mas_codec_writereg(0x15, tmp & 0xff00); -#else - mas_writereg(MAS_REG_KTREBLE, treble_table[value+15]); - current_treble = value * 10; - set_prescaled_volume(); -#endif - break; - -#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) - case SOUND_LOUDNESS: - loudness_shadow = (loudness_shadow & 0x04) | - (MAX(MIN(value * 4, 0x44), 0) << 8); - mas_codec_writereg(MAS_REG_KLOUDNESS, loudness_shadow); - break; - - case SOUND_AVC: - switch (value) { - case 1: /* 20ms */ - tmp = (0x1 << 8) | (0x8 << 12); - break; - case 2: /* 2s */ - tmp = (0x2 << 8) | (0x8 << 12); - break; - case 3: /* 4s */ - tmp = (0x4 << 8) | (0x8 << 12); - break; - case 4: /* 8s */ - tmp = (0x8 << 8) | (0x8 << 12); - break; - case -1: /* turn off and then turn on again to decay quickly */ - tmp = mas_codec_readreg(MAS_REG_KAVC); - mas_codec_writereg(MAS_REG_KAVC, 0); - break; - default: /* off */ - tmp = 0; - break; - } - mas_codec_writereg(MAS_REG_KAVC, tmp); - break; - - case SOUND_MDB_STRENGTH: - mas_codec_writereg(MAS_REG_KMDB_STR, (value & 0x7f) << 8); - break; - - case SOUND_MDB_HARMONICS: - tmp = value * 127 / 100; - mas_codec_writereg(MAS_REG_KMDB_HAR, (tmp & 0x7f) << 8); - break; - - case SOUND_MDB_CENTER: - mas_codec_writereg(MAS_REG_KMDB_FC, (value/10) << 8); - break; - - case SOUND_MDB_SHAPE: - mdb_shape_shadow = (mdb_shape_shadow & 0x02) | ((value/10) << 8); - mas_codec_writereg(MAS_REG_KMDB_SWITCH, mdb_shape_shadow); - break; - - case SOUND_MDB_ENABLE: - mdb_shape_shadow = (mdb_shape_shadow & ~0x02) | (value?2:0); - mas_codec_writereg(MAS_REG_KMDB_SWITCH, mdb_shape_shadow); - break; - - case SOUND_SUPERBASS: - loudness_shadow = (loudness_shadow & ~0x04) | - (value?4:0); - mas_codec_writereg(MAS_REG_KLOUDNESS, loudness_shadow); - break; -#endif - case SOUND_CHANNELS: - channel_configuration = value; - set_channel_config(); - break; - - case SOUND_STEREO_WIDTH: - stereo_width = value; - if (channel_configuration == MPEG_SOUND_CUSTOM) - set_channel_config(); - break; - } -#endif /* SIMULATOR */ -} - -int mpeg_val2phys(int setting, int value) -{ -#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) - int result = 0; - - switch(setting) - { - case SOUND_LEFT_GAIN: - case SOUND_RIGHT_GAIN: - result = (value - 2) * 15; - break; - - case SOUND_MIC_GAIN: - result = value * 15 + 210; - break; - - default: - result = value; - break; - } - return result; -#else - (void)setting; - return value; -#endif -} - -#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) -/* This function works by telling the decoder that we have another - crystal frequency than we actually have. It will adjust its internal - parameters and the result is that the audio is played at another pitch. - - The pitch value is in tenths of percent. -*/ -void mpeg_set_pitch(int pitch) -{ - unsigned long val; - - /* invert pitch value */ - pitch = 1000000/pitch; - - /* Calculate the new (bogus) frequency */ - val = 18432*pitch/1000; - - mas_writemem(MAS_BANK_D0, MAS_D0_OFREQ_CONTROL, &val, 1); - - /* We must tell the MAS that the frequency has changed. - This will unfortunately cause a short silence. */ - mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1); -} -#endif - void mp3_init(int volume, int bass, int treble, int balance, int loudness, int avc, int channel_config, int stereo_width, int mdb_strength, int mdb_harmonics, @@ -1035,25 +449,25 @@ void mp3_init(int volume, int bass, int treble, int balance, int loudness, PACR1 = (PACR1 & 0x3fff) | 0x4000; /* PA15 is IRQ3 */ #endif - /* Must be done before calling mpeg_sound_set() */ - mpeg_is_initialized = true; + /* Must be done before calling sound_set() */ + audio_is_initialized = true; - mpeg_sound_set(SOUND_BASS, bass); - mpeg_sound_set(SOUND_TREBLE, treble); - mpeg_sound_set(SOUND_BALANCE, balance); - mpeg_sound_set(SOUND_VOLUME, volume); - mpeg_sound_set(SOUND_CHANNELS, channel_config); - mpeg_sound_set(SOUND_STEREO_WIDTH, stereo_width); + sound_set(SOUND_BASS, bass); + sound_set(SOUND_TREBLE, treble); + sound_set(SOUND_BALANCE, balance); + sound_set(SOUND_VOLUME, volume); + sound_set(SOUND_CHANNELS, channel_config); + sound_set(SOUND_STEREO_WIDTH, stereo_width); #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) - mpeg_sound_set(SOUND_LOUDNESS, loudness); - mpeg_sound_set(SOUND_AVC, avc); - mpeg_sound_set(SOUND_MDB_STRENGTH, mdb_strength); - mpeg_sound_set(SOUND_MDB_HARMONICS, mdb_harmonics); - mpeg_sound_set(SOUND_MDB_CENTER, mdb_center); - mpeg_sound_set(SOUND_MDB_SHAPE, mdb_shape); - mpeg_sound_set(SOUND_MDB_ENABLE, mdb_enable); - mpeg_sound_set(SOUND_SUPERBASS, superbass); + sound_set(SOUND_LOUDNESS, loudness); + sound_set(SOUND_AVC, avc); + sound_set(SOUND_MDB_STRENGTH, mdb_strength); + sound_set(SOUND_MDB_HARMONICS, mdb_harmonics); + sound_set(SOUND_MDB_CENTER, mdb_center); + sound_set(SOUND_MDB_SHAPE, mdb_shape); + sound_set(SOUND_MDB_ENABLE, mdb_enable); + sound_set(SOUND_SUPERBASS, superbass); #endif #endif /* !SIMULATOR */ @@ -1201,7 +615,7 @@ void mp3_init(int volume, int bass, int treble, int balance, int loudness, playstart_tick = 0; cumulative_ticks = 0; callback_for_more = 0; - mpeg_is_initialized = false; + audio_is_initialized = false; #endif } void mp3_shutdown(void) @@ -1228,24 +642,6 @@ void mp3_play_pause(bool play) (void)play; } -void mpeg_sound_set(int setting, int value) -{ - /* a dummy */ - (void)setting; - (void)value; -} -bool mp3_is_playing(void) -{ - /* a dummy */ - return false; -} - -int mpeg_val2phys(int setting, int value) -{ - (void) setting; - (void) value; - return value; /* FIX dummy */ -} unsigned char* mp3_get_pos(void) { /* a dummy */ diff --git a/firmware/mpeg.c b/firmware/mpeg.c index 250547e24e..d8de1a37b4 100644 --- a/firmware/mpeg.c +++ b/firmware/mpeg.c @@ -31,6 +31,7 @@ #include "mp3data.h" #include "buffer.h" #include "mp3_playback.h" +#include "sound.h" #ifndef SIMULATOR #include "i2c.h" #include "mas.h" @@ -901,7 +902,7 @@ static void track_change(void) #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) /* Reset the AVC */ - mpeg_sound_set(SOUND_AVC, -1); + sound_set(SOUND_AVC, -1); #endif /* #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) */ remove_current_tag(); diff --git a/firmware/sound.c b/firmware/sound.c new file mode 100644 index 0000000000..ab0ab1ed46 --- /dev/null +++ b/firmware/sound.c @@ -0,0 +1,634 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2005 by Linus Nielsen Feltzing + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include +#include "config.h" +#include "sound.h" +#ifndef SIMULATOR +#include "i2c.h" +#include "mas.h" +#include "dac.h" +#include "system.h" +#include "hwcompat.h" +#endif + +#ifndef SIMULATOR +extern bool audio_is_initialized; +#endif + +#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) +extern unsigned long shadow_io_control_main; +extern unsigned shadow_codec_reg0; +#endif + +static const char* const units[] = +{ + "%", /* Volume */ + "dB", /* Bass */ + "dB", /* Treble */ + "%", /* Balance */ + "dB", /* Loudness */ + "", /* AVC */ + "", /* Channels */ + "%", /* Stereo width */ + "dB", /* Left gain */ + "dB", /* Right gain */ + "dB", /* Mic gain */ + "dB", /* MDB Strength */ + "%", /* MDB Harmonics */ + "Hz", /* MDB Center */ + "Hz", /* MDB Shape */ + "", /* MDB Enable */ + "", /* Super bass */ +}; + +static const int numdecimals[] = +{ + 0, /* Volume */ + 0, /* Bass */ + 0, /* Treble */ + 0, /* Balance */ + 0, /* Loudness */ + 0, /* AVC */ + 0, /* Channels */ + 0, /* Stereo width */ + 1, /* Left gain */ + 1, /* Right gain */ + 1, /* Mic gain */ + 0, /* MDB Strength */ + 0, /* MDB Harmonics */ + 0, /* MDB Center */ + 0, /* MDB Shape */ + 0, /* MDB Enable */ + 0, /* Super bass */ +}; + +static const int steps[] = +{ + 1, /* Volume */ + 1, /* Bass */ + 1, /* Treble */ + 1, /* Balance */ + 1, /* Loudness */ + 1, /* AVC */ + 1, /* Channels */ + 1, /* Stereo width */ + 1, /* Left gain */ + 1, /* Right gain */ + 1, /* Mic gain */ + 1, /* MDB Strength */ + 1, /* MDB Harmonics */ + 10, /* MDB Center */ + 10, /* MDB Shape */ + 1, /* MDB Enable */ + 1, /* Super bass */ +}; + +static const int minval[] = +{ + 0, /* Volume */ +#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) + -12, /* Bass */ + -12, /* Treble */ +#else + -15, /* Bass */ + -15, /* Treble */ +#endif + -100, /* Balance */ + 0, /* Loudness */ + -1, /* AVC */ + 0, /* Channels */ + 0, /* Stereo width */ + 0, /* Left gain */ + 0, /* Right gain */ + 0, /* Mic gain */ + 0, /* MDB Strength */ + 0, /* MDB Harmonics */ + 20, /* MDB Center */ + 50, /* MDB Shape */ + 0, /* MDB Enable */ + 0, /* Super bass */ +}; + +static const int maxval[] = +{ + 100, /* Volume */ +#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) + 12, /* Bass */ + 12, /* Treble */ +#else + 15, /* Bass */ + 15, /* Treble */ +#endif + 100, /* Balance */ + 17, /* Loudness */ + 4, /* AVC */ + 5, /* Channels */ + 255, /* Stereo width */ + 15, /* Left gain */ + 15, /* Right gain */ + 15, /* Mic gain */ + 127, /* MDB Strength */ + 100, /* MDB Harmonics */ + 300, /* MDB Center */ + 300, /* MDB Shape */ + 1, /* MDB Enable */ + 1, /* Super bass */ +}; + +static const int defaultval[] = +{ + 70, /* Volume */ +#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) + 6, /* Bass */ + 6, /* Treble */ +#else + 7, /* Bass */ + 7, /* Treble */ +#endif + 0, /* Balance */ + 0, /* Loudness */ + 0, /* AVC */ + 0, /* Channels */ + 100, /* Stereo width */ + 8, /* Left gain */ + 8, /* Right gain */ + 2, /* Mic gain */ + 50, /* MDB Strength */ + 48, /* MDB Harmonics */ + 60, /* MDB Center */ + 90, /* MDB Shape */ + 0, /* MDB Enable */ + 0, /* Super bass */ +}; + +const char *sound_unit(int setting) +{ + return units[setting]; +} + +int sound_numdecimals(int setting) +{ + return numdecimals[setting]; +} + +int sound_steps(int setting) +{ + return steps[setting]; +} + +int sound_min(int setting) +{ + return minval[setting]; +} + +int sound_max(int setting) +{ + return maxval[setting]; +} + +int sound_default(int setting) +{ + return defaultval[setting]; +} + +#ifndef SIMULATOR +#if CONFIG_HWCODEC == MAS3507D +static const unsigned int bass_table[] = +{ + 0x9e400, /* -15dB */ + 0xa2800, /* -14dB */ + 0xa7400, /* -13dB */ + 0xac400, /* -12dB */ + 0xb1800, /* -11dB */ + 0xb7400, /* -10dB */ + 0xbd400, /* -9dB */ + 0xc3c00, /* -8dB */ + 0xca400, /* -7dB */ + 0xd1800, /* -6dB */ + 0xd8c00, /* -5dB */ + 0xe0400, /* -4dB */ + 0xe8000, /* -3dB */ + 0xefc00, /* -2dB */ + 0xf7c00, /* -1dB */ + 0, + 0x800, /* 1dB */ + 0x10000, /* 2dB */ + 0x17c00, /* 3dB */ + 0x1f800, /* 4dB */ + 0x27000, /* 5dB */ + 0x2e400, /* 6dB */ + 0x35800, /* 7dB */ + 0x3c000, /* 8dB */ + 0x42800, /* 9dB */ + 0x48800, /* 10dB */ + 0x4e400, /* 11dB */ + 0x53800, /* 12dB */ + 0x58800, /* 13dB */ + 0x5d400, /* 14dB */ + 0x61800 /* 15dB */ +}; + +static const unsigned int treble_table[] = +{ + 0xb2c00, /* -15dB */ + 0xbb400, /* -14dB */ + 0xc1800, /* -13dB */ + 0xc6c00, /* -12dB */ + 0xcbc00, /* -11dB */ + 0xd0400, /* -10dB */ + 0xd5000, /* -9dB */ + 0xd9800, /* -8dB */ + 0xde000, /* -7dB */ + 0xe2800, /* -6dB */ + 0xe7e00, /* -5dB */ + 0xec000, /* -4dB */ + 0xf0c00, /* -3dB */ + 0xf5c00, /* -2dB */ + 0xfac00, /* -1dB */ + 0, + 0x5400, /* 1dB */ + 0xac00, /* 2dB */ + 0x10400, /* 3dB */ + 0x16000, /* 4dB */ + 0x1c000, /* 5dB */ + 0x22400, /* 6dB */ + 0x28400, /* 7dB */ + 0x2ec00, /* 8dB */ + 0x35400, /* 9dB */ + 0x3c000, /* 10dB */ + 0x42c00, /* 11dB */ + 0x49c00, /* 12dB */ + 0x51800, /* 13dB */ + 0x58400, /* 14dB */ + 0x5f800 /* 15dB */ +}; + +static const unsigned int prescale_table[] = +{ + 0x80000, /* 0db */ + 0x8e000, /* 1dB */ + 0x9a400, /* 2dB */ + 0xa5800, /* 3dB */ + 0xaf400, /* 4dB */ + 0xb8000, /* 5dB */ + 0xbfc00, /* 6dB */ + 0xc6c00, /* 7dB */ + 0xcd000, /* 8dB */ + 0xd25c0, /* 9dB */ + 0xd7800, /* 10dB */ + 0xdc000, /* 11dB */ + 0xdfc00, /* 12dB */ + 0xe3400, /* 13dB */ + 0xe6800, /* 14dB */ + 0xe9400 /* 15dB */ +}; + +/* all values in tenth of dB */ +int current_volume = 0; /* -780..+180 */ +int current_balance = 0; /* -960..+960 */ +int current_treble = 0; /* -150..+150 */ +int current_bass = 0; /* -150..+150 */ + +/* convert tenth of dB volume to register value */ +static int tenthdb2reg(int db) { + if (db < -540) + return (db + 780) / 30; + else + return (db + 660) / 15; +} + +void set_prescaled_volume(void) +{ + int prescale; + int l, r; + + prescale = MAX(current_bass, current_treble); + if (prescale < 0) + prescale = 0; /* no need to prescale if we don't boost + bass or treble */ + + mas_writereg(MAS_REG_KPRESCALE, prescale_table[prescale/10]); + + /* gain up the analog volume to compensate the prescale reduction gain, + * but limit to +18 dB (the maximum the DAC can do */ + if (current_volume + prescale > 180) + prescale = 180 - current_volume; + l = r = current_volume + prescale; + + if (current_balance > 0) + { + l -= current_balance; + if (l < -780) + l = -780; + } + if (current_balance < 0) + { + r += current_balance; + if (r < -780) + r = -780; + } + + dac_volume(tenthdb2reg(l), tenthdb2reg(r), false); +} +#endif /* MAS3507D */ +#endif /* !SIMULATOR */ + +int channel_configuration = SOUND_CHAN_STEREO; +int stereo_width = 100; + +#ifndef SIMULATOR +static void set_channel_config(void) +{ + /* default values: stereo */ + unsigned long val_ll = 0x80000; + unsigned long val_lr = 0; + unsigned long val_rl = 0; + unsigned long val_rr = 0x80000; + + switch(channel_configuration) + { + /* case SOUND_CHAN_STEREO unnecessary */ + + case SOUND_CHAN_MONO: + val_ll = 0xc0000; + val_lr = 0xc0000; + val_rl = 0xc0000; + val_rr = 0xc0000; + break; + + case SOUND_CHAN_CUSTOM: + { + /* fixed point variables (matching MAS internal format) + integer part: upper 13 bits (inlcuding sign) + fractional part: lower 19 bits */ + long fp_width, fp_straight, fp_cross; + + fp_width = (stereo_width << 19) / 100; + if (stereo_width <= 100) + { + fp_straight = - ((1<<19) + fp_width) / 2; + fp_cross = fp_straight + fp_width; + } + else + { + fp_straight = - (1<<19); + fp_cross = ((2 * fp_width / (((1<<19) + fp_width) >> 10)) + << 9) - (1<<19); + } + val_ll = val_rr = fp_straight & 0xFFFFF; + val_lr = val_rl = fp_cross & 0xFFFFF; + } + break; + + case SOUND_CHAN_MONO_LEFT: + val_ll = 0x80000; + val_lr = 0x80000; + val_rl = 0; + val_rr = 0; + break; + + case SOUND_CHAN_MONO_RIGHT: + val_ll = 0; + val_lr = 0; + val_rl = 0x80000; + val_rr = 0x80000; + break; + + case SOUND_CHAN_KARAOKE: + val_ll = 0x80001; + val_lr = 0x7ffff; + val_rl = 0x7ffff; + val_rr = 0x80001; + break; + } + +#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) + mas_writemem(MAS_BANK_D0, MAS_D0_OUT_LL, &val_ll, 1); /* LL */ + mas_writemem(MAS_BANK_D0, MAS_D0_OUT_LR, &val_lr, 1); /* LR */ + mas_writemem(MAS_BANK_D0, MAS_D0_OUT_RL, &val_rl, 1); /* RL */ + mas_writemem(MAS_BANK_D0, MAS_D0_OUT_RR, &val_rr, 1); /* RR */ +#elif CONFIG_HWCODEC == MAS3507D + mas_writemem(MAS_BANK_D1, 0x7f8, &val_ll, 1); /* LL */ + mas_writemem(MAS_BANK_D1, 0x7f9, &val_lr, 1); /* LR */ + mas_writemem(MAS_BANK_D1, 0x7fa, &val_rl, 1); /* RL */ + mas_writemem(MAS_BANK_D1, 0x7fb, &val_rr, 1); /* RR */ +#endif +} +#endif /* !SIMULATOR */ + +#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) +unsigned long mdb_shape_shadow = 0; +unsigned long loudness_shadow = 0; +#endif + +void sound_set(int setting, int value) +{ +#ifdef SIMULATOR + setting = value; +#else +#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) + int tmp; +#endif + + if(!audio_is_initialized) + return; + + switch(setting) + { + case SOUND_VOLUME: +#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) + tmp = 0x7f00 * value / 100; + mas_codec_writereg(0x10, tmp & 0xff00); +#elif CONFIG_HWCODEC == MAS3507D + current_volume = -780 + (value * 960 / 100); /* tenth of dB */ + set_prescaled_volume(); +#endif + break; + + case SOUND_BALANCE: +#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) + tmp = ((value * 127 / 100) & 0xff) << 8; + mas_codec_writereg(0x11, tmp & 0xff00); +#elif CONFIG_HWCODEC == MAS3507D + current_balance = value * 960 / 100; /* tenth of dB */ + set_prescaled_volume(); +#endif + break; + + case SOUND_BASS: +#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) + tmp = ((value * 8) & 0xff) << 8; + mas_codec_writereg(0x14, tmp & 0xff00); +#elif CONFIG_HWCODEC == MAS3507D + mas_writereg(MAS_REG_KBASS, bass_table[value+15]); + current_bass = value * 10; + set_prescaled_volume(); +#endif + break; + + case SOUND_TREBLE: +#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) + tmp = ((value * 8) & 0xff) << 8; + mas_codec_writereg(0x15, tmp & 0xff00); +#elif CONFIG_HWCODEC == MAS3507D + mas_writereg(MAS_REG_KTREBLE, treble_table[value+15]); + current_treble = value * 10; + set_prescaled_volume(); +#endif + break; + +#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) + case SOUND_LOUDNESS: + loudness_shadow = (loudness_shadow & 0x04) | + (MAX(MIN(value * 4, 0x44), 0) << 8); + mas_codec_writereg(MAS_REG_KLOUDNESS, loudness_shadow); + break; + + case SOUND_AVC: + switch (value) { + case 1: /* 20ms */ + tmp = (0x1 << 8) | (0x8 << 12); + break; + case 2: /* 2s */ + tmp = (0x2 << 8) | (0x8 << 12); + break; + case 3: /* 4s */ + tmp = (0x4 << 8) | (0x8 << 12); + break; + case 4: /* 8s */ + tmp = (0x8 << 8) | (0x8 << 12); + break; + case -1: /* turn off and then turn on again to decay quickly */ + tmp = mas_codec_readreg(MAS_REG_KAVC); + mas_codec_writereg(MAS_REG_KAVC, 0); + break; + default: /* off */ + tmp = 0; + break; + } + mas_codec_writereg(MAS_REG_KAVC, tmp); + break; + + case SOUND_MDB_STRENGTH: + mas_codec_writereg(MAS_REG_KMDB_STR, (value & 0x7f) << 8); + break; + + case SOUND_MDB_HARMONICS: + tmp = value * 127 / 100; + mas_codec_writereg(MAS_REG_KMDB_HAR, (tmp & 0x7f) << 8); + break; + + case SOUND_MDB_CENTER: + mas_codec_writereg(MAS_REG_KMDB_FC, (value/10) << 8); + break; + + case SOUND_MDB_SHAPE: + mdb_shape_shadow = (mdb_shape_shadow & 0x02) | ((value/10) << 8); + mas_codec_writereg(MAS_REG_KMDB_SWITCH, mdb_shape_shadow); + break; + + case SOUND_MDB_ENABLE: + mdb_shape_shadow = (mdb_shape_shadow & ~0x02) | (value?2:0); + mas_codec_writereg(MAS_REG_KMDB_SWITCH, mdb_shape_shadow); + break; + + case SOUND_SUPERBASS: + loudness_shadow = (loudness_shadow & ~0x04) | + (value?4:0); + mas_codec_writereg(MAS_REG_KLOUDNESS, loudness_shadow); + break; +#endif + case SOUND_CHANNELS: + channel_configuration = value; + set_channel_config(); + break; + + case SOUND_STEREO_WIDTH: + stereo_width = value; + if (channel_configuration == SOUND_CHAN_CUSTOM) + set_channel_config(); + break; + } +#endif /* SIMULATOR */ +} + +int sound_val2phys(int setting, int value) +{ +#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) + int result = 0; + + switch(setting) + { + case SOUND_LEFT_GAIN: + case SOUND_RIGHT_GAIN: + result = (value - 2) * 15; + break; + + case SOUND_MIC_GAIN: + result = value * 15 + 210; + break; + + default: + result = value; + break; + } + return result; +#else + (void)setting; + return value; +#endif +} + +#if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) +/* This function works by telling the decoder that we have another + crystal frequency than we actually have. It will adjust its internal + parameters and the result is that the audio is played at another pitch. + + The pitch value is in tenths of percent. +*/ +void sound_set_pitch(int pitch) +{ + unsigned long val; + + /* invert pitch value */ + pitch = 1000000/pitch; + + /* Calculate the new (bogus) frequency */ + val = 18432*pitch/1000; + + mas_writemem(MAS_BANK_D0, MAS_D0_OFREQ_CONTROL, &val, 1); + + /* We must tell the MAS that the frequency has changed. + This will unfortunately cause a short silence. */ + mas_writemem(MAS_BANK_D0, MAS_D0_IO_CONTROL_MAIN, &shadow_io_control_main, 1); +} +#elif defined SIMULATOR +void sound_set_pitch(int pitch) +{ + (void)pitch; +} +#endif + +#if CONFIG_HWCODEC == MASNONE +bool mp3_is_playing(void) +{ + /* a dummy */ + return false; +} +#endif -- cgit v1.2.3