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/plugins/rockboy/rbsound.c | 111 ++++++++++++++++++++++++++++++++++------- 1 file changed, 92 insertions(+), 19 deletions(-) (limited to 'apps/plugins/rockboy/rbsound.c') 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 } -- cgit v1.2.3