summaryrefslogtreecommitdiffstats
path: root/apps/plugins/pdbox
diff options
context:
space:
mode:
authorPeter D'Hoye <peter.dhoye@gmail.com>2009-07-12 18:44:26 +0000
committerPeter D'Hoye <peter.dhoye@gmail.com>2009-07-12 18:44:26 +0000
commit66a0492ab7931df48689e4aa53caaafd025087c3 (patch)
tree4d17a3b7ae37ab0465abff054c106f42ded7ee04 /apps/plugins/pdbox
parenta3a8708cdff7350e90b2a1224561a0f54faa41cd (diff)
downloadrockbox-66a0492ab7931df48689e4aa53caaafd025087c3.tar.gz
rockbox-66a0492ab7931df48689e4aa53caaafd025087c3.tar.bz2
rockbox-66a0492ab7931df48689e4aa53caaafd025087c3.zip
More work on PDBox by Wincent Balin. The PDBox plug-in is now working with the pdpod_test.pd file from the PureData.zip archive
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21816 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/pdbox')
-rw-r--r--apps/plugins/pdbox/PDa/src/d_ugen.c1
-rw-r--r--apps/plugins/pdbox/PDa/src/m_class.c7
-rw-r--r--apps/plugins/pdbox/PDa/src/s_audio_rockbox.c165
-rw-r--r--apps/plugins/pdbox/pdbox-func.c45
-rw-r--r--apps/plugins/pdbox/pdbox.c119
-rw-r--r--apps/plugins/pdbox/pdbox.h26
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