forked from len0rd/rockbox
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
This commit is contained in:
parent
a3a8708cdf
commit
66a0492ab7
6 changed files with 208 additions and 155 deletions
|
@ -313,7 +313,6 @@ void dsp_tick(void)
|
||||||
t_int *ip;
|
t_int *ip;
|
||||||
for (ip = dsp_chain; *ip; ) ip = (*(t_perfroutine)(*ip))(ip);
|
for (ip = dsp_chain; *ip; ) ip = (*(t_perfroutine)(*ip))(ip);
|
||||||
dsp_phase++;
|
dsp_phase++;
|
||||||
printf("%d\n", dsp_phase);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -507,7 +507,12 @@ t_symbol *dogensym(char *s, t_symbol *oldsym)
|
||||||
|
|
||||||
t_symbol *gensym(char *s)
|
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));
|
return(dogensym(s, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,25 +25,32 @@
|
||||||
#include "m_pd.h"
|
#include "m_pd.h"
|
||||||
#include "s_stuff.h"
|
#include "s_stuff.h"
|
||||||
|
|
||||||
/* Sound output buffer. */
|
/* Extern variables. */
|
||||||
#define AUDIO_OUTPUT_BLOCKS 3
|
extern float sys_dacsr;
|
||||||
static struct pdbox_audio_block audio_output[AUDIO_OUTPUT_BLOCKS];
|
extern t_sample *sys_soundout;
|
||||||
static unsigned int output_head;
|
extern t_sample *sys_soundin;
|
||||||
static unsigned int output_tail;
|
|
||||||
static unsigned int output_fill;
|
/* 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. */
|
/* Open audio. */
|
||||||
void rockbox_open_audio(int rate)
|
void rockbox_open_audio(int rate)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
/* Initialize output buffer. */
|
/* No sound yet. */
|
||||||
for(i = 0; i < AUDIO_OUTPUT_BLOCKS; i++)
|
playing = false;
|
||||||
audio_output[i].fill = 0;
|
|
||||||
|
|
||||||
output_head = 0;
|
/* Stop playing to reconfigure audio settings. */
|
||||||
output_tail = 0;
|
rb->pcm_play_stop();
|
||||||
output_fill = 0;
|
|
||||||
|
|
||||||
#if INPUT_SRC_CAPS != 0
|
#if INPUT_SRC_CAPS != 0
|
||||||
/* Select playback */
|
/* Select playback */
|
||||||
|
@ -53,6 +60,15 @@ void rockbox_open_audio(int rate)
|
||||||
|
|
||||||
/* Set sample rate of the audio buffer. */
|
/* Set sample rate of the audio buffer. */
|
||||||
rb->pcm_set_frequency(rate);
|
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. */
|
/* Close audio. */
|
||||||
|
@ -61,84 +77,115 @@ void rockbox_close_audio(void)
|
||||||
/* Stop playback. */
|
/* Stop playback. */
|
||||||
rb->pcm_play_stop();
|
rb->pcm_play_stop();
|
||||||
|
|
||||||
|
/* Reset playing status. */
|
||||||
|
playing = false;
|
||||||
|
|
||||||
/* Restore default sampling rate. */
|
/* Restore default sampling rate. */
|
||||||
rb->pcm_set_frequency(HW_SAMPR_DEFAULT);
|
rb->pcm_set_frequency(HW_SAMPR_DEFAULT);
|
||||||
|
rb->pcm_apply_settings();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Rockbox audio callback. */
|
/* Rockbox audio callback. */
|
||||||
void pdbox_get_more(unsigned char** start, size_t* size)
|
void pdbox_get_more(unsigned char** start, size_t* size)
|
||||||
{
|
{
|
||||||
if(output_fill > 0)
|
if(outbuf_fill > 0)
|
||||||
{
|
{
|
||||||
/* Store output data address and size. */
|
/* Store output data address and size. */
|
||||||
*start = (unsigned char*) audio_output[output_tail].data;
|
*start = (unsigned char*) outbuf[outbuf_tail].data;
|
||||||
*size = audio_output[output_tail].fill;
|
*size = sizeof(outbuf[outbuf_tail].data);
|
||||||
|
|
||||||
/* Advance tail index. */
|
/* Free this part of output buffer. */
|
||||||
audio_output[output_tail].fill = 0;
|
outbuf[outbuf_tail].fill = 0;
|
||||||
output_fill--;
|
|
||||||
if(output_tail == AUDIO_OUTPUT_BLOCKS-1)
|
/* Advance to the next part of output buffer. */
|
||||||
output_tail = 0;
|
if(outbuf_tail == OUTBUFSIZE-1)
|
||||||
|
outbuf_tail = 0;
|
||||||
else
|
else
|
||||||
output_tail++;
|
outbuf_tail++;
|
||||||
|
|
||||||
|
/* Decrease output buffer fill. */
|
||||||
|
outbuf_fill--;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Reset playing status. */
|
||||||
|
playing = false;
|
||||||
|
|
||||||
/* Nothing to play. */
|
/* Nothing to play. */
|
||||||
*start = NULL;
|
*start = NULL;
|
||||||
*size = 0;
|
*size = 0;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Audio I/O. */
|
/* Audio I/O. */
|
||||||
int rockbox_send_dacs(void)
|
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;
|
||||||
|
|
||||||
/* Start playback if needed and possible. */
|
/* Write the block of sound. */
|
||||||
if(output_fill > 1 &&
|
write_block:
|
||||||
audio_output[output_tail].fill == PD_AUDIO_BLOCK_SIZE)
|
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++)
|
||||||
{
|
{
|
||||||
/* Start playback. */
|
/* Copy samples from both channels. */
|
||||||
rb->pcm_play_data(pdbox_get_more,
|
sample = SCALE16(*left);
|
||||||
(unsigned char*) audio_output[output_tail].data,
|
if(sample > 32767)
|
||||||
PD_AUDIO_BLOCK_SIZE);
|
sample = 32767;
|
||||||
|
else if(sample < -32767)
|
||||||
/* Advance tail index. */
|
sample = -32767;
|
||||||
audio_output[output_tail].fill = PD_AUDIO_BLOCK_SIZE;
|
*out++ = sample;
|
||||||
output_fill--;
|
sample = SCALE16(*right);
|
||||||
if(output_tail == AUDIO_OUTPUT_BLOCKS-1)
|
if(sample > 32767)
|
||||||
output_tail = 0;
|
sample = 32767;
|
||||||
else
|
else if(sample < -32767)
|
||||||
output_tail++;
|
sample = -32767;
|
||||||
|
*out++ = sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If part of output buffer filled... */
|
||||||
|
if(outbuf[outbuf_head].fill >= (AUDIOBUFSIZE / PD_OUT_CHANNELS))
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (sys_getrealtime() > timebefore + 0.002)
|
|
||||||
{
|
{
|
||||||
/* post("slept"); */
|
/* Advance one part of output buffer. */
|
||||||
return (SENDDACS_SLEPT);
|
if(outbuf_head == OUTBUFSIZE-1)
|
||||||
}
|
outbuf_head = 0;
|
||||||
else
|
else
|
||||||
#endif
|
outbuf_head++;
|
||||||
return (SENDDACS_YES);
|
|
||||||
|
/* 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 still not playing... */
|
||||||
|
if(!playing && outbuf_fill > 0)
|
||||||
|
{
|
||||||
|
/* Start playing. */
|
||||||
|
rb->pcm_play_data(pdbox_get_more, NULL, 0);
|
||||||
|
|
||||||
|
/* Set status flag. */
|
||||||
|
playing = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SENDDACS_YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Placeholder. */
|
|
||||||
void rockbox_listdevs(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* Scanning for devices */
|
|
||||||
void rockbox_getdevs(char *indevlist, int *nindevs,
|
|
||||||
char *outdevlist, int *noutdevs, int *canmulti,
|
|
||||||
int maxndev, int devdescsize)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
|
@ -2307,7 +2307,7 @@ void glob_quit(void* dummy)
|
||||||
reentered = true;
|
reentered = true;
|
||||||
|
|
||||||
/* Close audio subsystem. */
|
/* Close audio subsystem. */
|
||||||
sys_close_audio();
|
/* Will be done by the main program: sys_close_audio(); */
|
||||||
|
|
||||||
/* Stop main loop. */
|
/* Stop main loop. */
|
||||||
quit = true;
|
quit = true;
|
||||||
|
@ -2318,12 +2318,13 @@ void glob_quit(void* dummy)
|
||||||
void glob_evalfile(t_pd *ignore, t_symbol *name, t_symbol *dir);
|
void glob_evalfile(t_pd *ignore, t_symbol *name, t_symbol *dir);
|
||||||
void openit(const char *dirname, const char *filename)
|
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,
|
/* Workaround: If the file resides in the root directory,
|
||||||
add a trailing slash to prevent directory part
|
add a trailing slash to prevent directory part
|
||||||
of the filename from being removed. */
|
of the filename from being removed -- W.B. */
|
||||||
char ffilename[MAXPDSTRING];
|
char* ffilename = getbytes(MAXPDSTRING);
|
||||||
ffilename[0] = '/';
|
ffilename[0] = '/';
|
||||||
ffilename[1] = '\0';
|
ffilename[1] = '\0';
|
||||||
strcat(ffilename, filename);
|
strcat(ffilename, filename);
|
||||||
|
@ -2337,6 +2338,10 @@ void openit(const char *dirname, const char *filename)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
error("%s: can't open", filename);
|
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;
|
extern char* filename;
|
||||||
char* rb_getcwd(char* buf, ssize_t size)
|
char* rb_getcwd(char* buf, ssize_t size)
|
||||||
{
|
{
|
||||||
char* end_of_dir = strrchr(filename, '/');
|
/* Initialize buffer. */
|
||||||
|
buf[0] = '\0';
|
||||||
|
|
||||||
/* Check whether buffer may hold enough data. */
|
/* Search for the last slash. */
|
||||||
if(size < end_of_dir - filename)
|
char* end_of_dir = strrchr(filename, '/');
|
||||||
|
int dirlen = end_of_dir - filename;
|
||||||
|
|
||||||
|
/* Check whether length of directory path is correct.
|
||||||
|
If not, abort. */
|
||||||
|
if(size < dirlen || dirlen == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Copy current working directory to buffer. */
|
/* Copy current working directory to buffer. */
|
||||||
strncpy(buf, filename, end_of_dir - filename);
|
strncat(buf, filename, dirlen);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2369,7 +2380,7 @@ void glob_initfromgui(void *dummy, t_symbol *s, int argc, t_atom *argv)
|
||||||
(void) argv;
|
(void) argv;
|
||||||
|
|
||||||
t_namelist *nl;
|
t_namelist *nl;
|
||||||
char cwd[MAXPDSTRING];
|
char* cwd = getbytes(MAXPDSTRING);
|
||||||
|
|
||||||
/* Get current working directory. */
|
/* Get current working directory. */
|
||||||
rb_getcwd(cwd, MAXPDSTRING);
|
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 */
|
/* open patches specifies with "-open" args */
|
||||||
for(nl = sys_openlist; nl; nl = nl->nl_next)
|
for(nl = sys_openlist; nl; nl = nl->nl_next)
|
||||||
openit(cwd, nl->nl_string);
|
openit(cwd, nl->nl_string);
|
||||||
|
|
||||||
namelist_free(sys_openlist);
|
namelist_free(sys_openlist);
|
||||||
sys_openlist = 0;
|
sys_openlist = 0;
|
||||||
|
|
||||||
|
/* Clean up. */
|
||||||
|
freebytes(cwd, MAXPDSTRING);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fake GUI start. Originally in s_inter.c */
|
/* Fake GUI start. Originally in s_inter.c */
|
||||||
|
@ -2390,7 +2405,7 @@ int sys_startgui(const char *guidir)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
t_atom zz[23];
|
t_atom zz[23];
|
||||||
char cmdbuf[4*MAXPDSTRING];
|
char* cmdbuf = getbytes(4*MAXPDSTRING);
|
||||||
|
|
||||||
(void) guidir;
|
(void) guidir;
|
||||||
|
|
||||||
|
@ -2398,13 +2413,16 @@ int sys_startgui(const char *guidir)
|
||||||
|
|
||||||
if(!rb_getcwd(cmdbuf, MAXPDSTRING))
|
if(!rb_getcwd(cmdbuf, MAXPDSTRING))
|
||||||
strcpy(cmdbuf, ".");
|
strcpy(cmdbuf, ".");
|
||||||
|
|
||||||
SETSYMBOL(zz, gensym(cmdbuf));
|
SETSYMBOL(zz, gensym(cmdbuf));
|
||||||
for (i = 1; i < 22; i++)
|
for (i = 1; i < 22; i++)
|
||||||
SETFLOAT(zz + i, defaultfontshit[i-1]);
|
SETFLOAT(zz + i, defaultfontshit[i-1]);
|
||||||
SETFLOAT(zz+22,0);
|
SETFLOAT(zz+22,0);
|
||||||
|
|
||||||
glob_initfromgui(0, 0, 23, zz);
|
glob_initfromgui(0, 0, 23, zz);
|
||||||
|
|
||||||
|
/* Clean up. */
|
||||||
|
freebytes(cmdbuf, 4*MAXPDSTRING);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2418,11 +2436,14 @@ int sys_getblksize(void)
|
||||||
/* Find library directory and set it. */
|
/* Find library directory and set it. */
|
||||||
void sys_findlibdir(const char* filename)
|
void sys_findlibdir(const char* filename)
|
||||||
{
|
{
|
||||||
char sbuf[MAXPDSTRING];
|
|
||||||
|
|
||||||
(void) filename;
|
(void) filename;
|
||||||
|
|
||||||
|
char* sbuf = getbytes(MAXPDSTRING);
|
||||||
|
|
||||||
/* Make current working directory the system library directory. */
|
/* Make current working directory the system library directory. */
|
||||||
rb_getcwd(sbuf, MAXPDSTRING);
|
rb_getcwd(sbuf, MAXPDSTRING);
|
||||||
sys_libdir = gensym(sbuf);
|
sys_libdir = gensym(sbuf);
|
||||||
|
|
||||||
|
/* Clean up. */
|
||||||
|
freebytes(sbuf, MAXPDSTRING);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,79 +40,34 @@ int sys_verbose;
|
||||||
int sys_noloadbang;
|
int sys_noloadbang;
|
||||||
t_symbol *sys_libdir;
|
t_symbol *sys_libdir;
|
||||||
t_namelist *sys_openlist;
|
t_namelist *sys_openlist;
|
||||||
int sys_nsoundin = 0;
|
|
||||||
int sys_soundindevlist[MAXAUDIOINDEV];
|
int sys_soundindevlist[MAXAUDIOINDEV];
|
||||||
int sys_nchin = 0;
|
|
||||||
int sys_chinlist[MAXAUDIOINDEV];
|
int sys_chinlist[MAXAUDIOINDEV];
|
||||||
int sys_nsoundout = 1;
|
|
||||||
int sys_soundoutdevlist[MAXAUDIOOUTDEV];
|
int sys_soundoutdevlist[MAXAUDIOOUTDEV];
|
||||||
int sys_nchout = 2;
|
|
||||||
int sys_choutlist[MAXAUDIOOUTDEV];
|
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. */
|
/* References for scheduler variables and functions. */
|
||||||
extern t_time sys_time;
|
extern t_time sys_time;
|
||||||
extern t_time sys_time_per_dsp_tick;
|
extern t_time sys_time_per_dsp_tick;
|
||||||
extern void sched_tick(t_time next_sys_time);
|
extern void sched_tick(t_time next_sys_time);
|
||||||
|
|
||||||
#define SAMPLES_SIZE 1000
|
/* LATER consider making this variable. It's now the LCM of all sample
|
||||||
t_sample samples[SAMPLES_SIZE];
|
rates we expect to see: 32000, 44100, 48000, 88200, 96000. */
|
||||||
|
#define TIMEUNITPERSEC (32.*441000.)
|
||||||
|
|
||||||
|
|
||||||
/* Quit flag. */
|
/* Quit flag. */
|
||||||
bool quit = false;
|
bool quit = false;
|
||||||
|
|
||||||
/* Thread IDs. */
|
/* Thread IDs. */
|
||||||
unsigned int core_thread_id;
|
|
||||||
unsigned int gui_thread_id;
|
unsigned int gui_thread_id;
|
||||||
unsigned int time_thread_id;
|
unsigned int time_thread_id;
|
||||||
|
|
||||||
/* Stacks for threads. */
|
/* Stacks for threads. */
|
||||||
#define STACK_SIZE 16384
|
#define STACK_SIZE 16384
|
||||||
uint32_t core_stack[STACK_SIZE / sizeof(uint32_t)];
|
|
||||||
uint32_t gui_stack[STACK_SIZE / sizeof(uint32_t)];
|
uint32_t gui_stack[STACK_SIZE / sizeof(uint32_t)];
|
||||||
uint32_t time_stack[256 / 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 */
|
/* GUI thread */
|
||||||
void gui_thread(void)
|
void gui_thread(void)
|
||||||
{
|
{
|
||||||
|
@ -138,6 +93,8 @@ void gui_thread(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if(rb->button_get(false) == BUTTON_OFF)
|
||||||
|
quit = true;
|
||||||
|
|
||||||
rb->sleep(1);
|
rb->sleep(1);
|
||||||
}
|
}
|
||||||
|
@ -168,8 +125,13 @@ enum plugin_status plugin_start(const void* parameter)
|
||||||
size_t mem_size;
|
size_t mem_size;
|
||||||
void* mem_pool;
|
void* mem_pool;
|
||||||
|
|
||||||
/* Get the file name. */
|
/* Get the file name; check whether parameter contains no file name. */
|
||||||
filename = (char*) parameter;
|
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. */
|
/* Allocate memory; check it's size; add to the pool. */
|
||||||
mem_pool = rb->plugin_get_audio_buffer(&mem_size);
|
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 */
|
/* Initialize Pure Data, as does sys_main in s_main.c */
|
||||||
pd_init();
|
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. */
|
/* Add the directory the called .pd resides in to lib directories. */
|
||||||
sys_findlibdir(filename);
|
sys_findlibdir(filename);
|
||||||
|
|
||||||
/* Open the parameter file. */
|
/* Open the parameter file. */
|
||||||
sys_openlist = namelist_append(sys_openlist, filename);
|
sys_openlist = namelist_append(sys_openlist, filename);
|
||||||
|
|
||||||
/* Set audio API. */
|
|
||||||
sys_set_audio_api(API_ROCKBOX);
|
|
||||||
|
|
||||||
/* Fake a GUI start. */
|
/* Fake a GUI start. */
|
||||||
sys_startgui(NULL);
|
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. */
|
/* Start threads. */
|
||||||
time_thread_id =
|
time_thread_id =
|
||||||
rb->create_thread(&time_thread,
|
rb->create_thread(&time_thread,
|
||||||
|
@ -212,15 +182,7 @@ enum plugin_status plugin_start(const void* parameter)
|
||||||
"PD running time"
|
"PD running time"
|
||||||
IF_PRIO(, PRIORITY_REALTIME)
|
IF_PRIO(, PRIORITY_REALTIME)
|
||||||
IF_COP(, COP));
|
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 =
|
gui_thread_id =
|
||||||
rb->create_thread(&gui_thread,
|
rb->create_thread(&gui_thread,
|
||||||
gui_stack,
|
gui_stack,
|
||||||
|
@ -231,18 +193,33 @@ enum plugin_status plugin_start(const void* parameter)
|
||||||
IF_COP(, CPU));
|
IF_COP(, CPU));
|
||||||
|
|
||||||
/* If having an error creating threads, bail out. */
|
/* 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;
|
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)
|
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. */
|
/* Wait for threads to complete. */
|
||||||
rb->thread_wait(gui_thread_id);
|
rb->thread_wait(gui_thread_id);
|
||||||
rb->thread_wait(core_thread_id);
|
|
||||||
rb->thread_wait(time_thread_id);
|
rb->thread_wait(time_thread_id);
|
||||||
|
|
||||||
|
/* Close audio subsystem. */
|
||||||
|
sys_close_audio();
|
||||||
|
|
||||||
/* Destroy net. */
|
/* Destroy net. */
|
||||||
net_destroy();
|
net_destroy();
|
||||||
|
|
||||||
|
|
|
@ -37,21 +37,21 @@
|
||||||
|
|
||||||
|
|
||||||
/* Audio declarations. */
|
/* Audio declarations. */
|
||||||
#define PD_SAMPLERATE 32000
|
#define PD_SAMPLERATE 22050
|
||||||
#define PD_SAMPLES_QUOT (PD_SAMPLERATE / HZ)
|
#define PD_SAMPLES_PER_HZ ((PD_SAMPLERATE / HZ) + \
|
||||||
#define PD_SAMPLES_REM (PD_SAMPLERATE % HZ)
|
(PD_SAMPLERATE % HZ > 0 ? 1 : 0))
|
||||||
#if PD_SAMPLES_REM == 0
|
#define PD_OUT_CHANNELS 2
|
||||||
#define PD_SAMPLES_PER_HZ (PD_SAMPLES_QUOT)
|
|
||||||
#else
|
|
||||||
#define PD_SAMPLES_PER_HZ (PD_SAMPLES_QUOT + 1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Audio data types. */
|
/* Audio buffer part. Contains data for one HZ period. */
|
||||||
#define PD_AUDIO_BLOCK_SIZE PD_SAMPLES_PER_HZ
|
#ifdef SIMULATOR
|
||||||
struct pdbox_audio_block
|
#define AUDIOBUFSIZE (PD_SAMPLES_PER_HZ * PD_OUT_CHANNELS * 4)
|
||||||
|
#else
|
||||||
|
#define AUDIOBUFSIZE (PD_SAMPLES_PER_HZ * PD_OUT_CHANNELS)
|
||||||
|
#endif
|
||||||
|
struct audio_buffer
|
||||||
{
|
{
|
||||||
|
int16_t data[AUDIOBUFSIZE];
|
||||||
unsigned int fill;
|
unsigned int fill;
|
||||||
int32_t data[PD_AUDIO_BLOCK_SIZE];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -139,6 +139,10 @@ void pd_init(void);
|
||||||
/* Redefinitons of ANSI C functions. */
|
/* Redefinitons of ANSI C functions. */
|
||||||
#include "lib/wrappers.h"
|
#include "lib/wrappers.h"
|
||||||
|
|
||||||
|
#define strncmp rb->strncmp
|
||||||
|
#define atoi rb->atoi
|
||||||
|
#define write rb->write
|
||||||
|
|
||||||
#define strncat rb_strncat
|
#define strncat rb_strncat
|
||||||
#define floor rb_floor
|
#define floor rb_floor
|
||||||
#define atof rb_atof
|
#define atof rb_atof
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue