diff --git a/apps/debug_menu.c b/apps/debug_menu.c index f978bc1a54..71f730d2c5 100644 --- a/apps/debug_menu.c +++ b/apps/debug_menu.c @@ -59,212 +59,6 @@ #endif #include "logfdisp.h" -#ifdef IRIVER_H100 -#include "uda1380.h" -#include "pcm_playback.h" -#include "buffer.h" - -#define CHUNK_SIZE 0x100000 /* Transfer CHUNK_SIZE bytes on - each DMA transfer */ - -static unsigned char line = 0; -static unsigned char *audio_buffer; -static int audio_pos; -static int audio_size; - -static void puts(const char *fmt, ...) -{ - char buf[80]; - - if (line > 15) - { - lcd_clear_display(); - line = 0; - } - - va_list ap; - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf)-1, fmt, ap); - va_end(ap); - - lcd_puts(0, line, buf); - lcd_update(); - - line++; -} - -/* Very basic WAVE-file support.. Just for testing purposes.. */ -int load_wave(char *filename) -{ - int f, i, num; - unsigned char buf[32]; - unsigned short *p, *end; - - puts("Loading %s..", filename); - - f = open(filename, O_RDONLY); - if (f == -1) - { - puts("File not found"); - return -1; - } - - memset(buf,0,32); - read(f, buf, 32); - if (memcmp(buf, "RIFF", 4) != 0 || memcmp(buf+8, "WAVE", 4) != 0) - { - puts("Not WAVE"); - return -1; - } - if (buf[12+8] != 1 || buf[12+9] != 0 || /* Check PCM format */ - buf[12+10] != 2 || buf[12+11] != 0) /* Check stereo */ - { - puts("Unsupported format"); - return -1; - } - - audio_size = filesize(f) - 0x30; - if (audio_size > 8*1024*1024) - audio_size = 8*1024*1024; - - audio_buffer = audiobuf; - - puts("Reading %d bytes..", audio_size); - - lseek(f, 0x30, SEEK_SET); /* Skip wave header */ - - read(f, audio_buffer, audio_size); - close(f); - - puts("Changing byte order.."); - end = (unsigned short *)(audio_buffer + audio_size); - p = (unsigned short *)audio_buffer; - while(p < end) - { - /* Swap 128k at a time, to allow the other threads to run */ - num = MIN(0x20000, (int)(end - p)); - for(i = 0;i < num;i++) - { - *p = SWAB16(*p); - p++; - } - yield(); - } - - return 0; -} - -/* - Test routined of the UDA1380 codec - - Loads a WAVE file and plays it.. - - Control play/stop, master volume and analog mixer volume - -*/ - -int test_tracknum; -static void test_trackchange(void) -{ - test_tracknum++; -} - -extern int pcmbuf_unplayed_bytes; - -bool uda1380_test(void) -{ - long button; - int vol = 0x50; - bool done = false; - char buf[80]; - bool play = true; - int sz; - char *ptr; - - lcd_setmargins(0, 0); - lcd_clear_display(); - lcd_update(); - - test_tracknum = 1; - - line = 0; - - if (load_wave("/sample.wav") == -1) - goto exit; - - audio_pos = 0; - - puts("Playing.."); - - audio_pos = 0; - pcm_play_init(); - pcm_set_frequency(44100); - pcm_set_volume(0xff - vol); - - ptr = audio_buffer; - for(sz = 0;sz < audio_size;sz += CHUNK_SIZE) - { - if(!pcm_play_add_chunk(ptr, CHUNK_SIZE, test_trackchange)) - break; - ptr += MIN(CHUNK_SIZE, (audio_size - sz)); - } - - pcm_play_start(); - - while(!done) - { - snprintf(buf, sizeof(buf), "SAR0: %08lx", SAR0); - lcd_puts(0, line, buf); - snprintf(buf, sizeof(buf), "DAR0: %08lx", DAR0); - lcd_puts(0, line+1, buf); - snprintf(buf, sizeof(buf), "BCR0: %08lx", BCR0); - lcd_puts(0, line+2, buf); - snprintf(buf, sizeof(buf), "DCR0: %08lx", DCR0); - lcd_puts(0, line+3, buf); - snprintf(buf, sizeof(buf), "DSR0: %02x", DSR0); - lcd_puts(0, line+4, buf); - snprintf(buf, sizeof(buf), "Track: %d", test_tracknum); - lcd_puts(0, line+5, buf); - snprintf(buf, sizeof(buf), "Unplayed: %08x", pcmbuf_unplayed_bytes); - lcd_puts(0, line+6, buf); - lcd_update(); - - button = button_get_w_tmo(HZ/2); - switch(button) - { - case BUTTON_ON: - play = !play; - pcm_play_pause(play); - break; - - case BUTTON_UP: - if (vol) - vol--; - - uda1380_setvol(vol); - break; - case BUTTON_DOWN: - if (vol < 255) - vol++; - - uda1380_setvol(vol); - break; - case BUTTON_OFF: - done = true; - break; - } - - if(!pcm_is_playing()) - done = true; - } - - pcm_play_stop(); - -exit: - sleep(HZ >> 1); /* Sleep 1/2 second to fade out sound */ - - return false; -} -#endif - /*---------------------------------------------------*/ /* SPECIAL DEBUG STUFF */ /*---------------------------------------------------*/ @@ -469,7 +263,7 @@ static unsigned flash_read_word(unsigned addr) { Only chips which could be reprogrammed in system will return values. (The mode switch addresses vary between flash manufacturers, hence addr1/2) */ /* In IRAM to avoid problems when running directly from Flash */ -bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device, +bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device, unsigned addr1, unsigned addr2) __attribute__ ((section (".icode"))); bool dbg_flash_id(unsigned* p_manufacturer, unsigned* p_device, @@ -2006,9 +1800,6 @@ bool debug_menu(void) #ifdef HAVE_ADJUSTABLE_CPU_FREQ { "CPU frequency", dbg_cpufreq }, #endif -#ifdef IRIVER_H100 - { "Audio test", uda1380_test }, -#endif #if CONFIG_CPU == SH7034 #ifdef HAVE_LCD_BITMAP #ifdef HAVE_RTC diff --git a/apps/plugin.c b/apps/plugin.c index b4a3d5c5c0..90b64efa66 100644 --- a/apps/plugin.c +++ b/apps/plugin.c @@ -136,6 +136,7 @@ static const struct plugin_api rockbox_api = { backlight_set_timeout, splash, #ifdef HAVE_REMOTE_LCD + /* remote lcd */ lcd_remote_clear_display, lcd_remote_puts, lcd_remote_puts_scroll, @@ -158,9 +159,7 @@ static const struct plugin_api rockbox_api = { lcd_remote_getstringsize, lcd_remote_update, lcd_remote_update_rect, - //id (*scrollbar)(int x, int y, int width, int height, int items, - // int min_shown, int max_shown, int orientation); - //void (*remote_checkbox)(int x, int y, int width, int height, bool checked); + lcd_remote_backlight_on, lcd_remote_backlight_off, &lcd_remote_framebuffer[0][0], @@ -170,6 +169,9 @@ static const struct plugin_api rockbox_api = { button_get_w_tmo, button_status, button_clear_queue, +#if CONFIG_KEYPAD == IRIVER_H100_PAD + button_hold, +#endif /* file */ (open_func)PREFIX(open), @@ -193,6 +195,7 @@ static const struct plugin_api rockbox_api = { PREFIX(opendir), PREFIX(closedir), PREFIX(readdir), + PREFIX(mkdir), /* kernel/ system */ PREFIX(sleep), @@ -205,6 +208,10 @@ static const struct plugin_api rockbox_api = { reset_poweroff_timer, #ifndef SIMULATOR system_memory_guard, + &cpu_frequency, +#ifdef HAVE_ADJUSTABLE_CPU_FREQ + cpu_boost, +#endif #endif /* strings and memory */ @@ -223,6 +230,7 @@ static const struct plugin_api rockbox_api = { strchr, strcat, memcmp, + strcasestr, /* sound */ sound_set, @@ -234,8 +242,15 @@ static const struct plugin_api rockbox_api = { #if CONFIG_HWCODEC != MASNONE bitswap, #endif +#if CONFIG_HWCODEC == MASNONE + pcm_play_data, + pcm_play_stop, + pcm_set_frequency, + pcm_is_playing, + pcm_play_pause, #endif - +#endif + /* playback control */ PREFIX(audio_play), audio_stop, @@ -270,6 +285,12 @@ static const struct plugin_api rockbox_api = { #endif #endif /* !simulator and HWCODEC != MASNONE */ + /* tag database */ + &tagdbheader, + &tagdb_fd, + &tagdb_initialized, + tagdb_init, + /* misc */ srand, rand, @@ -299,35 +320,13 @@ static const struct plugin_api rockbox_api = { peak_meter_set_use_dbfs, peak_meter_get_use_dbfs, #endif - - /* new stuff at the end, sort into place next time - the API gets incompatible */ -#ifndef SIMULATOR - &cpu_frequency, -#ifdef HAVE_ADJUSTABLE_CPU_FREQ - cpu_boost, -#endif -#endif - PREFIX(mkdir), -#if CONFIG_KEYPAD == IRIVER_H100_PAD - button_hold, -#endif -#if (CONFIG_HWCODEC == MASNONE) && !defined(SIMULATOR) - pcm_play_data, - pcm_play_stop, - pcm_set_frequency, - pcm_is_playing, - pcm_set_volume, - pcm_play_pause, -#endif #ifdef HAVE_LCD_BITMAP read_bmp_file, #endif - &tagdbheader, - &tagdb_fd, - &tagdb_initialized, - tagdb_init, - strcasestr, + + /* new stuff at the end, sort into place next time + the API gets incompatible */ + }; #if CONFIG_HWCODEC == MASNONE diff --git a/apps/plugin.h b/apps/plugin.h index b4c1189635..3990ffeed4 100644 --- a/apps/plugin.h +++ b/apps/plugin.h @@ -78,12 +78,12 @@ #endif /* increase this every time the api struct changes */ -#define PLUGIN_API_VERSION 39 +#define PLUGIN_API_VERSION 40 /* update this to latest version if a change to the api struct breaks backwards compatibility (and please take the opportunity to sort in any new function which are "waiting" at the end of the function table) */ -#define PLUGIN_MIN_API_VERSION 32 +#define PLUGIN_MIN_API_VERSION 40 /* plugin return codes */ enum plugin_status { @@ -177,6 +177,7 @@ struct plugin_api { void (*splash)(int ticks, bool center, const char *fmt, ...); #ifdef HAVE_REMOTE_LCD + /* remote lcd */ void (*remote_clear_display)(void); void (*remote_puts)(int x, int y, const unsigned char *string); void (*remote_lcd_puts_scroll)(int x, int y, const unsigned char* string); @@ -202,12 +203,10 @@ struct plugin_api { int (*remote_getstringsize)(const unsigned char *str, int *w, int *h); void (*remote_update)(void); void (*remote_update_rect)(int x, int y, int width, int height); -// void (*remote_scrollbar)(int x, int y, int width, int height, int items, -// int min_shown, int max_shown, int orientation); - //void (*remote_checkbox)(int x, int y, int width, int height, bool checked); + void (*remote_backlight_on)(void); - void (*remote_backlight_off)(void); - unsigned char* lcd_remote_framebuffer; + void (*remote_backlight_off)(void); + unsigned char* lcd_remote_framebuffer; #endif /* button */ @@ -215,6 +214,9 @@ struct plugin_api { long (*button_get_w_tmo)(int ticks); int (*button_status)(void); void (*button_clear_queue)(void); +#if CONFIG_KEYPAD == IRIVER_H100_PAD + bool (*button_hold)(void); +#endif /* file */ int (*PREFIX(open))(const char* pathname, int flags); @@ -238,6 +240,7 @@ struct plugin_api { DIR* (*PREFIX(opendir))(const char* name); int (*PREFIX(closedir))(DIR* dir); struct dirent* (*PREFIX(readdir))(DIR* dir); + int (*PREFIX(mkdir))(const char *name, int mode); /* kernel/ system */ void (*PREFIX(sleep))(int ticks); @@ -250,6 +253,10 @@ struct plugin_api { void (*reset_poweroff_timer)(void); #ifndef SIMULATOR int (*system_memory_guard)(int newmode); + long *cpu_frequency; +#ifdef HAVE_ADJUSTABLE_CPU_FREQ + void (*cpu_boost)(bool on_off); +#endif #endif /* strings and memory */ @@ -268,6 +275,7 @@ struct plugin_api { char *(*strchr)(const char *s, int c); char *(*strcat)(char *s1, const char *s2); int (*memcmp)(const void *s1, const void *s2, size_t n); + char *(*strcasestr) (const char* phaystack, const char* pneedle); /* sound */ void (*sound_set)(int setting, int value); @@ -279,7 +287,15 @@ struct plugin_api { #if CONFIG_HWCODEC != MASNONE void (*bitswap)(unsigned char *data, int length); #endif +#if CONFIG_HWCODEC == MASNONE + void (*pcm_play_data)(const unsigned char *start, int size, + void (*get_more)(unsigned char** start, long*size)); + void (*pcm_play_stop)(void); + void (*pcm_set_frequency)(unsigned int frequency); + bool (*pcm_is_playing)(void); + void (*pcm_play_pause)(bool play); #endif +#endif /* !SIMULATOR */ /* playback control */ void (*PREFIX(audio_play))(int offset); @@ -315,6 +331,12 @@ struct plugin_api { #endif #endif + /* tag database */ + struct tagdb_header *tagdbheader; + int *tagdb_fd; + int *tagdb_initialized; + int (*tagdb_init) (void); + /* misc */ void (*srand)(unsigned int seed); int (*rand)(void); @@ -351,37 +373,14 @@ struct plugin_api { void (*peak_meter_set_use_dbfs)(int use); int (*peak_meter_get_use_dbfs)(void); #endif - - /* new stuff at the end, sort into place next time - the API gets incompatible */ -#ifndef SIMULATOR - long *cpu_frequency; -#ifdef HAVE_ADJUSTABLE_CPU_FREQ - void (*cpu_boost)(bool on_off); -#endif -#endif - int (*PREFIX(mkdir))(const char *name, int mode); -#if CONFIG_KEYPAD == IRIVER_H100_PAD - bool (*button_hold)(void); -#endif -#if (CONFIG_HWCODEC == MASNONE) && !defined(SIMULATOR) - void (*pcm_play_data)(const unsigned char *start, int size, - void (*get_more)(unsigned char** start, long*size)); - void (*pcm_play_stop)(void); - void (*pcm_set_frequency)(unsigned int frequency); - bool (*pcm_is_playing)(void); - void (*pcm_set_volume)(int volume); - void (*pcm_play_pause)(bool play); -#endif #ifdef HAVE_LCD_BITMAP int (*read_bmp_file)(char* filename, int *get_width, int *get_height, char *bitmap, int maxsize); #endif - struct tagdb_header *tagdbheader; - int *tagdb_fd; - int *tagdb_initialized; - int (*tagdb_init) (void); - char *(*strcasestr) (const char* phaystack, const char* pneedle); + + /* new stuff at the end, sort into place next time + the API gets incompatible */ + }; /* defined by the plugin loader (plugin.c) */ diff --git a/firmware/drivers/uda1380.c b/firmware/drivers/uda1380.c index 7170b707e4..23d917f8ae 100644 --- a/firmware/drivers/uda1380.c +++ b/firmware/drivers/uda1380.c @@ -85,33 +85,15 @@ int uda1380_write_reg(unsigned char reg, unsigned short value) } /** - * Sets the master volume - * - * \param vol Range [0..255] 0=max, 255=mute - * + * Sets left and right master volume (0(max) to 252(muted)) */ -int uda1380_setvol(int vol) +int uda1380_setvol(int vol_l, int vol_r) { - int vol_l, vol_r; - - uda1380_volume = vol; - /* Simple linear volume crossfade curves */ - vol_l = MAX(uda1380_balance*(255 - vol)/100 + vol, vol); - vol_r = MAX(-uda1380_balance*(255 - vol)/100 + vol, vol); return uda1380_write_reg(REG_MASTER_VOL, MASTER_VOL_LEFT(vol_l) | MASTER_VOL_RIGHT(vol_r)); } /** - * Sets stereo balance - */ -void uda1380_set_balance(int bal) -{ - uda1380_balance = bal; - uda1380_setvol(uda1380_volume); -} - -/** * Sets the bass value (0-15) */ void uda1380_set_bass(int value) diff --git a/firmware/export/pcm_playback.h b/firmware/export/pcm_playback.h index c78936a3f2..874ed6ac6c 100644 --- a/firmware/export/pcm_playback.h +++ b/firmware/export/pcm_playback.h @@ -31,7 +31,6 @@ void pcm_play_data(const unsigned char* start, int size, void pcm_play_stop(void); void pcm_play_pause(bool play); bool pcm_is_playing(void); -void pcm_set_volume(int volume); /* These functions are for playing chained buffers of PCM data */ void pcm_play_init(void); diff --git a/firmware/export/uda1380.h b/firmware/export/uda1380.h index b09d271808..503b59d102 100644 --- a/firmware/export/uda1380.h +++ b/firmware/export/uda1380.h @@ -22,8 +22,7 @@ extern int uda1380_init(void); extern void uda1380_enable_output(bool enable); -extern int uda1380_setvol(int vol); -extern void uda1380_set_balance(int bal); +extern int uda1380_setvol(int vol_l, int vol_r); extern void uda1380_set_bass(int value); extern void uda1380_set_treble(int value); extern int uda1380_mute(int mute); diff --git a/firmware/pcm_playback.c b/firmware/pcm_playback.c index 45e91ac3be..eab6fe1f15 100644 --- a/firmware/pcm_playback.c +++ b/firmware/pcm_playback.c @@ -123,20 +123,6 @@ static void dma_stop(void) IIS2CONFIG = 0x800; } -/* set volume of the main channel */ -void pcm_set_volume(int volume) -{ - if(volume > 0) - { - uda1380_mute(0); - uda1380_setvol(0xff - volume); - } - else - { - uda1380_mute(1); - } -} - /* sets frequency of input to DAC */ void pcm_set_frequency(unsigned int frequency) { diff --git a/firmware/sound.c b/firmware/sound.c index 7dd1fbf98e..cd6448c754 100644 --- a/firmware/sound.c +++ b/firmware/sound.c @@ -334,7 +334,7 @@ static int tenthdb2reg(int db) { return (db + 660) / 15; } -void set_prescaled_volume(void) +static void set_prescaled_volume(void) { int prescale; int l, r; @@ -367,7 +367,47 @@ void set_prescaled_volume(void) dac_volume(tenthdb2reg(l), tenthdb2reg(r), false); } -#endif /* MAS3507D */ +#elif CONFIG_HWCODEC == MASNONE +#ifdef HAVE_UDA1380 /* iriver H1x0 + H3x0 */ +/* all values in tenth of dB */ +int current_volume = 0; /* -840..0 */ +int current_balance = 0; /* -840..+840 */ + +/* convert tenth of dB volume to register value */ +static int tenthdb2reg(int db) { + if (db < -720) /* 1.5 dB steps */ + return (2940 - db) / 15; + else if (db < -660) /* 0.75 dB steps */ + return (1110 - db) * 2 / 15; + else if (db < -520) /* 0.5 dB steps */ + return (520 - db) / 5; + else /* 0.25 dB steps */ + return -db * 2 / 5; +} + +static void set_volume(void) +{ + int l, r; + + l = r = current_volume; + + if (current_balance > 0) + { + l -= current_balance; + if (l < -840) + l = -840; + } + if (current_balance < 0) + { + r += current_balance; + if (r < -840) + r = -840; + } + + uda1380_setvol(tenthdb2reg(l), tenthdb2reg(r)); +} +#endif +#endif /* MASNONE */ #endif /* !SIMULATOR */ int channel_configuration = SOUND_CHAN_STEREO; @@ -480,7 +520,8 @@ void sound_set(int setting, int value) current_volume = -780 + (value * 960 / 100); /* tenth of dB */ set_prescaled_volume(); #elif CONFIG_HWCODEC == MASNONE - pcm_set_volume((value*167117) >> 16); + current_volume = -840 + (value * 840 / 100); /* tenth of dB */ + set_volume(); #endif break; @@ -492,7 +533,8 @@ void sound_set(int setting, int value) current_balance = value * 960 / 100; /* tenth of dB */ set_prescaled_volume(); #elif defined(HAVE_UDA1380) - uda1380_set_balance(value); + current_balance = value * 840 / 100; /* tenth of dB */ + set_volume(); #endif break; @@ -500,12 +542,12 @@ void sound_set(int setting, int value) #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) tmp = ((value * 8) & 0xff) << 8; mas_codec_writereg(0x14, tmp & 0xff00); -#elif defined(HAVE_UDA1380) - uda1380_set_bass(value >> 1); #elif CONFIG_HWCODEC == MAS3507D mas_writereg(MAS_REG_KBASS, bass_table[value+15]); current_bass = value * 10; set_prescaled_volume(); +#elif defined(HAVE_UDA1380) + uda1380_set_bass(value >> 1); #endif break; @@ -513,12 +555,12 @@ void sound_set(int setting, int value) #if (CONFIG_HWCODEC == MAS3587F) || (CONFIG_HWCODEC == MAS3539F) tmp = ((value * 8) & 0xff) << 8; mas_codec_writereg(0x15, tmp & 0xff00); -#elif defined(HAVE_UDA1380) - uda1380_set_treble(value >> 1); #elif CONFIG_HWCODEC == MAS3507D mas_writereg(MAS_REG_KTREBLE, treble_table[value+15]); current_treble = value * 10; set_prescaled_volume(); +#elif defined(HAVE_UDA1380) + uda1380_set_treble(value >> 1); #endif break;