diff options
Diffstat (limited to 'apps/plugins/pdbox')
-rw-r--r-- | apps/plugins/pdbox/PDa/src/d_ugen.c | 1 | ||||
-rw-r--r-- | apps/plugins/pdbox/PDa/src/m_class.c | 7 | ||||
-rw-r--r-- | apps/plugins/pdbox/PDa/src/s_audio_rockbox.c | 165 | ||||
-rw-r--r-- | apps/plugins/pdbox/pdbox-func.c | 45 | ||||
-rw-r--r-- | apps/plugins/pdbox/pdbox.c | 119 | ||||
-rw-r--r-- | apps/plugins/pdbox/pdbox.h | 26 |
6 files changed, 208 insertions, 155 deletions
diff --git a/apps/plugins/pdbox/PDa/src/d_ugen.c b/apps/plugins/pdbox/PDa/src/d_ugen.c index 6cf0a5a97d..8454b12bb9 100644 --- a/apps/plugins/pdbox/PDa/src/d_ugen.c +++ b/apps/plugins/pdbox/PDa/src/d_ugen.c @@ -313,7 +313,6 @@ void dsp_tick(void) t_int *ip; for (ip = dsp_chain; *ip; ) ip = (*(t_perfroutine)(*ip))(ip); dsp_phase++; -printf("%d\n", dsp_phase); } } diff --git a/apps/plugins/pdbox/PDa/src/m_class.c b/apps/plugins/pdbox/PDa/src/m_class.c index 98fe9be23d..95623fd014 100644 --- a/apps/plugins/pdbox/PDa/src/m_class.c +++ b/apps/plugins/pdbox/PDa/src/m_class.c @@ -507,7 +507,12 @@ t_symbol *dogensym(char *s, t_symbol *oldsym) t_symbol *gensym(char *s) { -printf("gensym: %s\n", s); +// printf("gensym: %s\n", s); +#ifdef ROCKBOX + if(s == NULL) + return dogensym("/", 0); + else +#endif return(dogensym(s, 0)); } diff --git a/apps/plugins/pdbox/PDa/src/s_audio_rockbox.c b/apps/plugins/pdbox/PDa/src/s_audio_rockbox.c index 7f9b0e03e1..8019289205 100644 --- a/apps/plugins/pdbox/PDa/src/s_audio_rockbox.c +++ b/apps/plugins/pdbox/PDa/src/s_audio_rockbox.c @@ -25,25 +25,32 @@ #include "m_pd.h" #include "s_stuff.h" -/* Sound output buffer. */ -#define AUDIO_OUTPUT_BLOCKS 3 -static struct pdbox_audio_block audio_output[AUDIO_OUTPUT_BLOCKS]; -static unsigned int output_head; -static unsigned int output_tail; -static unsigned int output_fill; +/* Extern variables. */ +extern float sys_dacsr; +extern t_sample *sys_soundout; +extern t_sample *sys_soundin; + +/* Output buffer. */ +#define OUTBUFSIZE 3 +static struct audio_buffer outbuf[OUTBUFSIZE]; +static unsigned int outbuf_head; +static unsigned int outbuf_tail; +static unsigned int outbuf_fill; + +/* Playing status. */ +static bool playing; + /* Open audio. */ void rockbox_open_audio(int rate) { unsigned int i; - /* Initialize output buffer. */ - for(i = 0; i < AUDIO_OUTPUT_BLOCKS; i++) - audio_output[i].fill = 0; + /* No sound yet. */ + playing = false; - output_head = 0; - output_tail = 0; - output_fill = 0; + /* Stop playing to reconfigure audio settings. */ + rb->pcm_play_stop(); #if INPUT_SRC_CAPS != 0 /* Select playback */ @@ -53,6 +60,15 @@ void rockbox_open_audio(int rate) /* Set sample rate of the audio buffer. */ rb->pcm_set_frequency(rate); + rb->pcm_apply_settings(); + + /* Initialize output buffer. */ + for(i = 0; i < OUTBUFSIZE; i++) + outbuf[i].fill = 0; + + outbuf_head = 0; + outbuf_tail = 0; + outbuf_fill = 0; } /* Close audio. */ @@ -61,84 +77,115 @@ void rockbox_close_audio(void) /* Stop playback. */ rb->pcm_play_stop(); + /* Reset playing status. */ + playing = false; + /* Restore default sampling rate. */ rb->pcm_set_frequency(HW_SAMPR_DEFAULT); + rb->pcm_apply_settings(); } /* Rockbox audio callback. */ void pdbox_get_more(unsigned char** start, size_t* size) { - if(output_fill > 0) + if(outbuf_fill > 0) { /* Store output data address and size. */ - *start = (unsigned char*) audio_output[output_tail].data; - *size = audio_output[output_tail].fill; - - /* Advance tail index. */ - audio_output[output_tail].fill = 0; - output_fill--; - if(output_tail == AUDIO_OUTPUT_BLOCKS-1) - output_tail = 0; + *start = (unsigned char*) outbuf[outbuf_tail].data; + *size = sizeof(outbuf[outbuf_tail].data); + + /* Free this part of output buffer. */ + outbuf[outbuf_tail].fill = 0; + + /* Advance to the next part of output buffer. */ + if(outbuf_tail == OUTBUFSIZE-1) + outbuf_tail = 0; else - output_tail++; + outbuf_tail++; + + /* Decrease output buffer fill. */ + outbuf_fill--; } else { + /* Reset playing status. */ + playing = false; + /* Nothing to play. */ *start = NULL; *size = 0; - return; } } /* Audio I/O. */ int rockbox_send_dacs(void) { + /* Copy sys_output buffer. */ + t_sample* left = sys_soundout + DEFDACBLKSIZE*0; + t_sample* right = sys_soundout + DEFDACBLKSIZE*1; + unsigned int samples_out = 0; + int16_t* out; + int sample; + + /* Cancel if whole buffer filled. */ + if(outbuf_fill >= OUTBUFSIZE-1) + return SENDDACS_NO; + + /* Write the block of sound. */ +write_block: + for(out = outbuf[outbuf_head].data + + outbuf[outbuf_head].fill * PD_OUT_CHANNELS; + outbuf[outbuf_head].fill < (AUDIOBUFSIZE / PD_OUT_CHANNELS) && + samples_out < DEFDACBLKSIZE; + left++, right++, samples_out++, outbuf[outbuf_head].fill++) + { + /* Copy samples from both channels. */ + sample = SCALE16(*left); + if(sample > 32767) + sample = 32767; + else if(sample < -32767) + sample = -32767; + *out++ = sample; + sample = SCALE16(*right); + if(sample > 32767) + sample = 32767; + else if(sample < -32767) + sample = -32767; + *out++ = sample; + } - - /* Start playback if needed and possible. */ - if(output_fill > 1 && - audio_output[output_tail].fill == PD_AUDIO_BLOCK_SIZE) + /* If part of output buffer filled... */ + if(outbuf[outbuf_head].fill >= (AUDIOBUFSIZE / PD_OUT_CHANNELS)) { - /* Start playback. */ - rb->pcm_play_data(pdbox_get_more, - (unsigned char*) audio_output[output_tail].data, - PD_AUDIO_BLOCK_SIZE); - - /* Advance tail index. */ - audio_output[output_tail].fill = PD_AUDIO_BLOCK_SIZE; - output_fill--; - if(output_tail == AUDIO_OUTPUT_BLOCKS-1) - output_tail = 0; + /* Advance one part of output buffer. */ + if(outbuf_head == OUTBUFSIZE-1) + outbuf_head = 0; else - output_tail++; - } + outbuf_head++; + /* Increase fill counter. */ + outbuf_fill++; + } + /* If needed, fill the next frame. */ + if(samples_out < DEFDACBLKSIZE) + goto write_block; + /* Clear Pure Data output buffer. */ + memset(sys_soundout, + 0, + sizeof(t_sample) * DEFDACBLKSIZE * PD_OUT_CHANNELS); -#if 0 - if (sys_getrealtime() > timebefore + 0.002) + /* If still not playing... */ + if(!playing && outbuf_fill > 0) { - /* post("slept"); */ - return (SENDDACS_SLEPT); - } - else -#endif - return (SENDDACS_YES); -} + /* Start playing. */ + rb->pcm_play_data(pdbox_get_more, NULL, 0); -/* Placeholder. */ -void rockbox_listdevs(void) -{ -} + /* Set status flag. */ + playing = true; + } -#if 0 -/* Scanning for devices */ -void rockbox_getdevs(char *indevlist, int *nindevs, - char *outdevlist, int *noutdevs, int *canmulti, - int maxndev, int devdescsize) -{ + return SENDDACS_YES; } -#endif diff --git a/apps/plugins/pdbox/pdbox-func.c b/apps/plugins/pdbox/pdbox-func.c index ee4a8fd166..d6a2ea750a 100644 --- a/apps/plugins/pdbox/pdbox-func.c +++ b/apps/plugins/pdbox/pdbox-func.c @@ -2307,7 +2307,7 @@ void glob_quit(void* dummy) reentered = true; /* Close audio subsystem. */ - sys_close_audio(); + /* Will be done by the main program: sys_close_audio(); */ /* Stop main loop. */ quit = true; @@ -2318,12 +2318,13 @@ void glob_quit(void* dummy) void glob_evalfile(t_pd *ignore, t_symbol *name, t_symbol *dir); void openit(const char *dirname, const char *filename) { - char dirbuf[MAXPDSTRING], *nameptr; + char* nameptr; + char* dirbuf = getbytes(MAXPDSTRING); /* Workaround: If the file resides in the root directory, add a trailing slash to prevent directory part - of the filename from being removed. */ - char ffilename[MAXPDSTRING]; + of the filename from being removed -- W.B. */ + char* ffilename = getbytes(MAXPDSTRING); ffilename[0] = '/'; ffilename[1] = '\0'; strcat(ffilename, filename); @@ -2337,6 +2338,10 @@ void openit(const char *dirname, const char *filename) } else error("%s: can't open", filename); + + /* Clean up. */ + freebytes(dirbuf, MAXPDSTRING); + freebytes(ffilename, MAXPDSTRING); } @@ -2344,14 +2349,20 @@ void openit(const char *dirname, const char *filename) extern char* filename; char* rb_getcwd(char* buf, ssize_t size) { + /* Initialize buffer. */ + buf[0] = '\0'; + + /* Search for the last slash. */ char* end_of_dir = strrchr(filename, '/'); + int dirlen = end_of_dir - filename; - /* Check whether buffer may hold enough data. */ - if(size < end_of_dir - filename) + /* Check whether length of directory path is correct. + If not, abort. */ + if(size < dirlen || dirlen == 0) return NULL; /* Copy current working directory to buffer. */ - strncpy(buf, filename, end_of_dir - filename); + strncat(buf, filename, dirlen); return buf; } @@ -2369,7 +2380,7 @@ void glob_initfromgui(void *dummy, t_symbol *s, int argc, t_atom *argv) (void) argv; t_namelist *nl; - char cwd[MAXPDSTRING]; + char* cwd = getbytes(MAXPDSTRING); /* Get current working directory. */ rb_getcwd(cwd, MAXPDSTRING); @@ -2377,8 +2388,12 @@ void glob_initfromgui(void *dummy, t_symbol *s, int argc, t_atom *argv) /* open patches specifies with "-open" args */ for(nl = sys_openlist; nl; nl = nl->nl_next) openit(cwd, nl->nl_string); + namelist_free(sys_openlist); sys_openlist = 0; + + /* Clean up. */ + freebytes(cwd, MAXPDSTRING); } /* Fake GUI start. Originally in s_inter.c */ @@ -2390,7 +2405,7 @@ int sys_startgui(const char *guidir) { unsigned int i; t_atom zz[23]; - char cmdbuf[4*MAXPDSTRING]; + char* cmdbuf = getbytes(4*MAXPDSTRING); (void) guidir; @@ -2398,13 +2413,16 @@ int sys_startgui(const char *guidir) if(!rb_getcwd(cmdbuf, MAXPDSTRING)) strcpy(cmdbuf, "."); + SETSYMBOL(zz, gensym(cmdbuf)); for (i = 1; i < 22; i++) SETFLOAT(zz + i, defaultfontshit[i-1]); SETFLOAT(zz+22,0); - glob_initfromgui(0, 0, 23, zz); + /* Clean up. */ + freebytes(cmdbuf, 4*MAXPDSTRING); + return 0; } @@ -2418,11 +2436,14 @@ int sys_getblksize(void) /* Find library directory and set it. */ void sys_findlibdir(const char* filename) { - char sbuf[MAXPDSTRING]; - (void) filename; + char* sbuf = getbytes(MAXPDSTRING); + /* Make current working directory the system library directory. */ rb_getcwd(sbuf, MAXPDSTRING); sys_libdir = gensym(sbuf); + + /* Clean up. */ + freebytes(sbuf, MAXPDSTRING); } diff --git a/apps/plugins/pdbox/pdbox.c b/apps/plugins/pdbox/pdbox.c index 0f3728e586..38c12c279b 100644 --- a/apps/plugins/pdbox/pdbox.c +++ b/apps/plugins/pdbox/pdbox.c @@ -40,79 +40,34 @@ int sys_verbose; int sys_noloadbang; t_symbol *sys_libdir; t_namelist *sys_openlist; -int sys_nsoundin = 0; int sys_soundindevlist[MAXAUDIOINDEV]; -int sys_nchin = 0; int sys_chinlist[MAXAUDIOINDEV]; -int sys_nsoundout = 1; int sys_soundoutdevlist[MAXAUDIOOUTDEV]; -int sys_nchout = 2; int sys_choutlist[MAXAUDIOOUTDEV]; -static int sys_main_srate = PD_SAMPLERATE; -static int sys_main_advance = PD_SAMPLES_PER_HZ; /* References for scheduler variables and functions. */ extern t_time sys_time; extern t_time sys_time_per_dsp_tick; extern void sched_tick(t_time next_sys_time); -#define SAMPLES_SIZE 1000 -t_sample samples[SAMPLES_SIZE]; +/* LATER consider making this variable. It's now the LCM of all sample +rates we expect to see: 32000, 44100, 48000, 88200, 96000. */ +#define TIMEUNITPERSEC (32.*441000.) + /* Quit flag. */ bool quit = false; /* Thread IDs. */ -unsigned int core_thread_id; unsigned int gui_thread_id; unsigned int time_thread_id; /* Stacks for threads. */ #define STACK_SIZE 16384 -uint32_t core_stack[STACK_SIZE / sizeof(uint32_t)]; uint32_t gui_stack[STACK_SIZE / sizeof(uint32_t)]; uint32_t time_stack[256 / sizeof(uint32_t)]; -/* Core thread, scheduler. */ -void core_thread(void) -{ -/* struct datagram ping; */ - - /* LATER consider making this variable. It's now the LCM of all sample - rates we expect to see: 32000, 44100, 48000, 88200, 96000. */ - #define TIMEUNITPERSEC (32.*441000.) - - sys_time = 0; - sys_time_per_dsp_tick = (TIMEUNITPERSEC) * - ((double)sys_schedblocksize) / sys_dacsr; - - - /* Main loop */ - while(!quit) - { -#if 0 - /* Wait for request. */ - while(!RECEIVE_TO_CORE(&ping)) - rb->yield(); - - if(memcmp("Ping!", ping.data, ping.size) == 0) - { - SEND_FROM_CORE("Pong!"); - break; - } -#endif - - /* Use sys_send_dacs() function as timer. */ - if(sys_send_dacs() != SENDDACS_NO) - sched_tick(sys_time + sys_time_per_dsp_tick); - - rb->sleep(1); - } - - rb->thread_exit(); -} - /* GUI thread */ void gui_thread(void) { @@ -138,6 +93,8 @@ void gui_thread(void) break; } #endif + if(rb->button_get(false) == BUTTON_OFF) + quit = true; rb->sleep(1); } @@ -168,8 +125,13 @@ enum plugin_status plugin_start(const void* parameter) size_t mem_size; void* mem_pool; - /* Get the file name. */ + /* Get the file name; check whether parameter contains no file name. */ filename = (char*) parameter; + if(strlen(filename) == 0) + { + rb->splash(HZ, "Play a .pd file!"); + return PLUGIN_ERROR; + } /* Allocate memory; check it's size; add to the pool. */ mem_pool = rb->plugin_get_audio_buffer(&mem_size); @@ -186,23 +148,31 @@ enum plugin_status plugin_start(const void* parameter) /* Initialize Pure Data, as does sys_main in s_main.c */ pd_init(); + /* Set audio API. */ + sys_set_audio_api(API_ROCKBOX); + + /* Initialize audio subsystem. */ + sys_open_audio(0, /* No sound input yet */ + sys_soundindevlist, + 0, /* No sound input yet */ + sys_chinlist, + 1, /* One sound output device */ + sys_soundoutdevlist, + -1, /* Use the default amount (2) of channels */ + sys_choutlist, + PD_SAMPLERATE, /* Sample rate */ + DEFAULTADVANCE, /* Scheduler advance */ + 1 /* Enable */); + /* Add the directory the called .pd resides in to lib directories. */ sys_findlibdir(filename); /* Open the parameter file. */ sys_openlist = namelist_append(sys_openlist, filename); - /* Set audio API. */ - sys_set_audio_api(API_ROCKBOX); - /* Fake a GUI start. */ sys_startgui(NULL); - /* Initialize audio subsystem. */ - sys_open_audio(sys_nsoundin, sys_soundindevlist, sys_nchin, sys_chinlist, - sys_nsoundout, sys_soundoutdevlist, sys_nchout, sys_choutlist, - sys_main_srate, sys_main_advance, 1); - /* Start threads. */ time_thread_id = rb->create_thread(&time_thread, @@ -212,15 +182,7 @@ enum plugin_status plugin_start(const void* parameter) "PD running time" IF_PRIO(, PRIORITY_REALTIME) IF_COP(, COP)); - core_thread_id = - rb->create_thread(&core_thread, - core_stack, - sizeof(core_stack), - 0, /* FIXME Which flags? */ - "PD core" - IF_PRIO(, MAX(PRIORITY_USER_INTERFACE / 2, - PRIORITY_REALTIME + 1)) - IF_COP(, COP)); + gui_thread_id = rb->create_thread(&gui_thread, gui_stack, @@ -231,18 +193,33 @@ enum plugin_status plugin_start(const void* parameter) IF_COP(, CPU)); /* If having an error creating threads, bail out. */ - if(core_thread_id == 0 || gui_thread_id == 0) + if(time_thread_id == 0 || gui_thread_id == 0) return PLUGIN_ERROR; - /* Wait for quit flag. */ + /* Initialize scheduler time variables. */ + sys_time = 0; + sys_time_per_dsp_tick = (TIMEUNITPERSEC) * + ((double) sys_schedblocksize) / sys_dacsr; + + + /* Main loop. */ while(!quit) - yield(); + { + /* Use sys_send_dacs() function as timer. */ + while(sys_send_dacs() != SENDDACS_NO) + sched_tick(sys_time + sys_time_per_dsp_tick); + + /* Sleep to the next time slice. */ + rb->sleep(1); + } /* Wait for threads to complete. */ rb->thread_wait(gui_thread_id); - rb->thread_wait(core_thread_id); rb->thread_wait(time_thread_id); + /* Close audio subsystem. */ + sys_close_audio(); + /* Destroy net. */ net_destroy(); diff --git a/apps/plugins/pdbox/pdbox.h b/apps/plugins/pdbox/pdbox.h index fbca4989dc..e7587927dc 100644 --- a/apps/plugins/pdbox/pdbox.h +++ b/apps/plugins/pdbox/pdbox.h @@ -37,21 +37,21 @@ /* Audio declarations. */ -#define PD_SAMPLERATE 32000 -#define PD_SAMPLES_QUOT (PD_SAMPLERATE / HZ) -#define PD_SAMPLES_REM (PD_SAMPLERATE % HZ) -#if PD_SAMPLES_REM == 0 - #define PD_SAMPLES_PER_HZ (PD_SAMPLES_QUOT) +#define PD_SAMPLERATE 22050 +#define PD_SAMPLES_PER_HZ ((PD_SAMPLERATE / HZ) + \ + (PD_SAMPLERATE % HZ > 0 ? 1 : 0)) +#define PD_OUT_CHANNELS 2 + +/* Audio buffer part. Contains data for one HZ period. */ +#ifdef SIMULATOR +#define AUDIOBUFSIZE (PD_SAMPLES_PER_HZ * PD_OUT_CHANNELS * 4) #else - #define PD_SAMPLES_PER_HZ (PD_SAMPLES_QUOT + 1) +#define AUDIOBUFSIZE (PD_SAMPLES_PER_HZ * PD_OUT_CHANNELS) #endif - -/* Audio data types. */ -#define PD_AUDIO_BLOCK_SIZE PD_SAMPLES_PER_HZ -struct pdbox_audio_block +struct audio_buffer { + int16_t data[AUDIOBUFSIZE]; unsigned int fill; - int32_t data[PD_AUDIO_BLOCK_SIZE]; }; @@ -139,6 +139,10 @@ void pd_init(void); /* Redefinitons of ANSI C functions. */ #include "lib/wrappers.h" +#define strncmp rb->strncmp +#define atoi rb->atoi +#define write rb->write + #define strncat rb_strncat #define floor rb_floor #define atof rb_atof |