From 451dd48adc2ef29fd2f900693393cc9b9b4a849b Mon Sep 17 00:00:00 2001 From: Michiel Van Der Kolk Date: Mon, 28 Mar 2005 00:00:24 +0000 Subject: Sound api improvements, rockboy sound, contributed by xshock. Playback of sound currently only works in boost mode, needs fixing. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6226 a1c6a512-1295-4272-9138-f99709370657 --- apps/debug_menu.c | 35 ++++++------- apps/main.c | 7 +++ apps/plugin.c | 8 +-- apps/plugin.h | 7 ++- apps/plugins/rockboy/pcm.h | 2 +- apps/plugins/rockboy/rbsound.c | 111 ++++++++++++++++++++++++++++++++++------- apps/plugins/rockboy/rockboy.c | 4 +- apps/plugins/rockboy/sound.c | 12 ++--- 8 files changed, 137 insertions(+), 49 deletions(-) (limited to 'apps') diff --git a/apps/debug_menu.c b/apps/debug_menu.c index 9d5028af7c..74d1cb94fb 100644 --- a/apps/debug_menu.c +++ b/apps/debug_menu.c @@ -169,27 +169,29 @@ static void test_get_more(unsigned char **ptr, long *size) bool uda1380_test(void) { long button; - int vol = 0x7f; + int vol = 0x50; bool done = false; lcd_setmargins(0, 0); lcd_clear_display(); lcd_update(); + cpu_boost(true); if (load_wave("/sample.wav") == -1) goto exit; audio_pos = 0; + puts("Playing.."); puts("uda1380_init"); if (uda1380_init() == -1) { - puts("Init failed.."); - goto exit; + puts("UDA1380 init failed"); } - puts("Playing.."); audio_pos = 0; + pcm_set_frequency(44100); + pcm_set_volume(0xff - vol); pcm_play_data(audio_buffer, CHUNK_SIZE, test_get_more); @@ -224,6 +226,7 @@ bool uda1380_test(void) exit: sleep(HZ >> 1); /* Sleep 1/2 second to fade out sound */ + cpu_boost(false); return false; } @@ -1247,10 +1250,9 @@ bool view_battery(void) lcd_puts(0, 3, buf); #endif #ifdef HAVE_CHARGE_CTRL - snprintf(buf, 30, "Chgr: %s %s", - charger_inserted() ? "present" : "absent", - charger_enabled ? "on" : "off"); - lcd_puts(0, 3, buf); + snprintf(buf, 30, "Charging: %s", + charger_enabled ? "yes" : "no"); + lcd_puts(0, 4, buf); snprintf(buf, 30, "short delta: %d", short_delta); lcd_puts(0, 5, buf); snprintf(buf, 30, "long delta: %d", long_delta); @@ -1272,7 +1274,7 @@ bool view_battery(void) } break; - case 3: /* remaining time estimation: */ + case 3: /* remeining time estimation: */ lcd_clear_display(); #ifdef HAVE_CHARGE_CTRL @@ -1284,24 +1286,23 @@ bool view_battery(void) snprintf(buf, 30, "Lvl@cyc st: %d%%", powermgmt_last_cycle_level); lcd_puts(0, 2, buf); - - snprintf(buf, 30, "P=%2d I=%2d", pid_p, pid_i); - lcd_puts(0, 3, buf); - - snprintf(buf, 30, "Trickle sec: %d/60", trickle_sec); - lcd_puts(0, 4, buf); #endif snprintf(buf, 30, "Last PwrHist: %d.%02d V", power_history[0] / 100, power_history[0] % 100); - lcd_puts(0, 5, buf); + lcd_puts(0, 3, buf); snprintf(buf, 30, "battery level: %d%%", battery_level()); - lcd_puts(0, 6, buf); + lcd_puts(0, 5, buf); snprintf(buf, 30, "Est. remain: %d m", battery_time()); + lcd_puts(0, 6, buf); + +#ifdef HAVE_CHARGE_CTRL + snprintf(buf, 30, "Trickle sec: %d/60", trickle_sec); lcd_puts(0, 7, buf); +#endif break; } diff --git a/apps/main.c b/apps/main.c index c5e5492337..36f26c9154 100644 --- a/apps/main.c +++ b/apps/main.c @@ -58,6 +58,10 @@ #include "power.h" #include "talk.h" #include "plugin.h" + + +#include "uda1380.h" + #ifdef CONFIG_TUNER #include "radio.h" #endif @@ -261,6 +265,9 @@ void init(void) } } #endif /* #ifdef AUTOROCK */ + + uda1380_init(); + } int main(void) diff --git a/apps/plugin.c b/apps/plugin.c index b4239bb8d9..ecd5025e2c 100644 --- a/apps/plugin.c +++ b/apps/plugin.c @@ -44,7 +44,7 @@ #include "mp3data.h" #include "powermgmt.h" #include "system.h" -#if (CONFIG_HWCODEC == MASNONE) && !defined(SIMULATOR) +#if (CONFIG_HWCODEC == MASNONE) #include "pcm_playback.h" #endif @@ -271,10 +271,12 @@ static const struct plugin_api rockbox_api = { #if CONFIG_KEYPAD == IRIVER_H100_PAD button_hold, #endif -#if (CONFIG_HWCODEC == MASNONE) && !defined(SIMULATOR) - pcm_play_data, +#if (CONFIG_HWCODEC == MASNONE) + pcm_play_data, pcm_play_stop, + pcm_set_frequency, pcm_is_playing, + pcm_set_volume #endif }; diff --git a/apps/plugin.h b/apps/plugin.h index 3755018d6d..30ecfc7963 100644 --- a/apps/plugin.h +++ b/apps/plugin.h @@ -43,6 +43,7 @@ #include "id3.h" #include "mpeg.h" #include "mp3_playback.h" +#include "pcm_playback.h" #include "settings.h" #include "thread.h" #include "playlist.h" @@ -317,11 +318,13 @@ struct plugin_api { #if CONFIG_KEYPAD == IRIVER_H100_PAD bool (*button_hold)(void); #endif -#if (CONFIG_HWCODEC == MASNONE) && !defined(SIMULATOR) +#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_play_stop)(void); + void (*pcm_set_frequency)(unsigned int frequency); bool (*pcm_is_playing)(void); + void (*pcm_set_volume)(int volume); #endif }; diff --git a/apps/plugins/rockboy/pcm.h b/apps/plugins/rockboy/pcm.h index 3719933520..742f0e5a95 100644 --- a/apps/plugins/rockboy/pcm.h +++ b/apps/plugins/rockboy/pcm.h @@ -9,7 +9,7 @@ struct pcm { int hz, len; int stereo; - byte *buf; + short *buf; int pos; }; diff --git a/apps/plugins/rockboy/rbsound.c b/apps/plugins/rockboy/rbsound.c index 6d1b24fd9a..92f824aa3b 100644 --- a/apps/plugins/rockboy/rbsound.c +++ b/apps/plugins/rockboy/rbsound.c @@ -1,47 +1,120 @@ - - - #include "rockmacros.h" #include "defs.h" #include "pcm.h" #include "rc.h" +#define RBSOUND struct pcm pcm; -static byte buf[4096]; +#define BUF_SIZE (8192) +#define DMA_PORTION (1024) + +static short buf1_unal[(BUF_SIZE / sizeof(short)) + 2]; // to make sure 4 byte aligned +static short* buf1; +static short front_buf[512]; + +static short* last_back_pos; + +static bool newly_started; +static int turns; rcvar_t pcm_exports[] = { - RCV_END + RCV_END }; - void pcm_init(void) { - pcm.hz = 44100; - pcm.stereo = 1; - pcm.buf = buf; - pcm.len = sizeof buf; - pcm.pos = 0; + buf1 = (signed short*)((((unsigned int)buf1_unal) >> 2) << 2); /* here i just make sure that buffer is aligned to 4 bytes*/ + newly_started = true; + last_back_pos = buf1; + turns = 0; + + pcm.hz = 11025; + pcm.stereo = 1; + pcm.buf = front_buf; + pcm.len = (sizeof(front_buf)) / sizeof(short); /* length in shorts, not bytes */ + pcm.pos = 0; + + + rb->pcm_play_stop(); + rb->pcm_set_frequency(11025); + rb->pcm_set_volume(200); } void pcm_close(void) { - memset(&pcm, 0, sizeof pcm); + memset(&pcm, 0, sizeof pcm); + newly_started = true; + last_back_pos = buf1; + rb->pcm_play_stop(); } +void get_more(unsigned char** start, long* size) +{ + int length; + unsigned int sar = (unsigned int)SAR0; + length = ((unsigned int)buf1) + BUF_SIZE - sar; + + if(turns > 0) + { + newly_started = true; + last_back_pos = buf1; + turns = 0; + return; + } /* sound will stop if no one feeds data*/ + + if(length <= 0) + { + *start = (unsigned char*)buf1; + *size = DMA_PORTION; + turns++; + } + else + { + *start = (unsigned char*)sar; + if(length > DMA_PORTION) + *size = DMA_PORTION; + else + *size = length; + } + +} + int pcm_submit(void) { -#ifdef RBSOUND - rb->pcm_play_data(pcm.buf,pcm.pos,NULL); - while(rb->pcm_is_playing()); /* spinlock */ - pcm.pos = 0; - return 1; +#ifdef RBSOUND + while( (turns < 0) && ((((unsigned int)last_back_pos) + pcm.pos * sizeof(short)) > ((unsigned int)SAR0)) && !newly_started) rb->yield(); /* wait until data is passed through DAC or until exit*/ + int shorts_left = ((((unsigned int)buf1) + BUF_SIZE) - ((unsigned int)last_back_pos)) / sizeof(short); + if( shorts_left >= pcm.pos ) + { + memcpy(last_back_pos,pcm.buf,pcm.pos * sizeof(short)); + last_back_pos = &last_back_pos[pcm.pos]; + } + else + { + int last_pos = shorts_left; + memcpy(last_back_pos,pcm.buf,shorts_left * sizeof(short)); + last_back_pos = buf1; + shorts_left = pcm.pos - shorts_left; + memcpy(last_back_pos,&pcm.buf[last_pos],shorts_left * sizeof(short)); + last_back_pos = &buf1[shorts_left]; + turns--; + } + + if(newly_started) + { + rb->pcm_play_data((unsigned char*)buf1,pcm.pos * sizeof(short),&get_more); + newly_started = false; + } + + pcm.pos = 0; + return 1; #else - pcm.pos = 0; - return 0; + pcm.pos = 0; + return 0; #endif } diff --git a/apps/plugins/rockboy/rockboy.c b/apps/plugins/rockboy/rockboy.c index a34fd7bf69..c6d006a131 100644 --- a/apps/plugins/rockboy/rockboy.c +++ b/apps/plugins/rockboy/rockboy.c @@ -51,6 +51,7 @@ struct plugin_api* rb; int shut,cleanshut; char *errormsg; int gnuboy_main(char *rom); +void pcm_close(void); void die(char *message, ...) { @@ -124,10 +125,11 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) rb->splash(HZ*2, true, errormsg); return PLUGIN_ERROR; } - + pcm_close(); rb->splash(HZ*2, true, "Shutting down.. byebye ^^"); cleanup(); + return PLUGIN_OK; } diff --git a/apps/plugins/rockboy/sound.c b/apps/plugins/rockboy/sound.c index edf31d81b7..10fc504063 100644 --- a/apps/plugins/rockboy/sound.c +++ b/apps/plugins/rockboy/sound.c @@ -60,9 +60,9 @@ int pcm_submit(void); #define S4 (snd.ch[3]) rcvar_t sound_exports[] = - { - RCV_END - }; +{ + RCV_END +}; static void s1_freq_d(int d) @@ -275,10 +275,10 @@ void sound_mix(void) pcm_submit(); if (pcm.stereo) { - pcm.buf[pcm.pos++] = l+128; - pcm.buf[pcm.pos++] = r+128; + pcm.buf[pcm.pos++] = (signed short)(l * 256); + pcm.buf[pcm.pos++] = (signed short)(r * 256); } - else pcm.buf[pcm.pos++] = ((l+r)>>1)+128; + else pcm.buf[pcm.pos++] = (signed short)((r+l) * 128); } } R_NR52 = (R_NR52&0xf0) | S1.on | (S2.on<<1) | (S3.on<<2) | (S4.on<<3); -- cgit v1.2.3