1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2009 Wincent Balin
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
25 #include "PDa/src/m_pd.h"
26 #include "PDa/src/s_stuff.h"
28 /* Welcome to the PDBox plugin */
32 /* Name of the file to open. */
36 uint64_t runningtime
= 0;
38 /* Variables for Pure Data. */
42 t_namelist
*sys_openlist
;
43 int sys_soundindevlist
[MAXAUDIOINDEV
];
44 int sys_chinlist
[MAXAUDIOINDEV
];
45 int sys_soundoutdevlist
[MAXAUDIOOUTDEV
];
46 int sys_choutlist
[MAXAUDIOOUTDEV
];
49 /* References for scheduler variables and functions. */
50 extern t_time sys_time
;
51 extern t_time sys_time_per_dsp_tick
;
52 extern void sched_tick(t_time next_sys_time
);
54 /* LATER consider making this variable. It's now the LCM of all sample
55 rates we expect to see: 32000, 44100, 48000, 88200, 96000. */
56 #define TIMEUNITPERSEC (32.*441000.)
62 /* Stack sizes for threads. */
63 #define CORESTACKSIZE (1 * 1024 * 1024)
64 #define GUISTACKSIZE (512 * 1024)
71 unsigned int core_thread_id
;
72 unsigned int gui_thread_id
;
78 struct pd_widget widget
[128];
79 unsigned int widgets
= 0;
87 widgets
= pd_gui_load_patch(widget
,
88 sizeof(widget
) / sizeof(struct pd_widget
));
90 /* Draw initial state of UI. */
91 pd_gui_draw(widget
, widgets
);
96 /* Reset update flag. */
99 /* Apply timer to widgets. */
101 pd_gui_apply_timeouts(widget
, widgets
);
103 /* Process buttons. */
105 pd_gui_parse_buttons(widgets
);
107 /* Receive and parse datagrams. */
108 while(RECEIVE_FROM_CORE(&dg
))
111 pd_gui_parse_message(&dg
, widget
, widgets
);
114 /* If there is something to update in GUI, do so. */
116 pd_gui_draw(widget
, widgets
);
125 void core_thread(void)
127 /* Add the directory the called .pd resides in to lib directories. */
128 sys_findlibdir(filename
);
130 /* Open the PD design file. */
131 sys_openlist
= namelist_append(sys_openlist
, filename
);
133 /* Fake a GUI start. */
136 /* Core scheduler loop */
139 /* Receive datagrams. */
142 while(RECEIVE_TO_CORE(&dg
))
143 rockbox_receive_callback(&dg
);
145 /* Use sys_send_dacs() function as timer. */
146 while(sys_send_dacs() != SENDDACS_NO
)
147 sched_tick(sys_time
+ sys_time_per_dsp_tick
);
157 /* Plug-in entry point */
158 enum plugin_status
plugin_start(const void* parameter
)
162 /* Memory pool variables. */
166 /* Get the file name; check whether parameter contains no file name. */
167 filename
= (char*) parameter
;
168 if(strlen(filename
) == 0)
170 rb
->splash(HZ
, "Play a .pd file!");
174 /* Initialize memory pool. */
175 mem_pool
= rb
->plugin_get_audio_buffer(&mem_size
);
176 if(mem_size
< MIN_MEM_SIZE
)
178 rb
->splash(HZ
, "Not enough memory!");
182 init_memory_pool(mem_size
, mem_pool
);
185 set_memory_pool(mem_pool
, mem_size
);
188 /* Initialize net. */
191 /* Initialize Pure Data, as does sys_main in s_main.c */
195 sys_set_audio_api(API_ROCKBOX
);
197 /* Initialize audio subsystem. */
198 sys_open_audio(0, /* No sound input yet */
200 0, /* No sound input yet */
202 1, /* One sound output device */
204 -1, /* Use the default amount (2) of channels */
206 PD_SAMPLERATE
, /* Sample rate */
207 DEFAULTADVANCE
, /* Scheduler advance */
210 /* Create stacks for threads. */
211 core_stack
= getbytes(CORESTACKSIZE
);
212 gui_stack
= getbytes(GUISTACKSIZE
);
213 if(core_stack
== NULL
|| gui_stack
== NULL
)
215 rb
->splash(HZ
, "Not enough memory!");
224 rb
->create_thread(&core_thread
,
227 0, /* FIXME Which flags? */
229 IF_PRIO(, PRIORITY_REALTIME
)
233 rb
->create_thread(&gui_thread
,
236 0, /* FIXME Which flags? */
238 IF_PRIO(, PRIORITY_USER_INTERFACE
)
241 /* If having an error creating threads, bail out. */
242 if(core_thread_id
== 0 || gui_thread_id
== 0)
245 /* Initialize scheduler time variables. */
247 sys_time_per_dsp_tick
= (TIMEUNITPERSEC
) *
248 ((double) sys_schedblocksize
) / sys_dacsr
;
254 /* Add time slice in milliseconds. */
255 runningtime
+= (1000 / HZ
);
257 /* Sleep to the next time slice. */
261 /* Wait for threads to complete. */
262 rb
->thread_wait(gui_thread_id
);
263 rb
->thread_wait(core_thread_id
);
268 /* Close audio subsystem. */
274 /* Clear memory pool. */
276 destroy_memory_pool(mem_pool
);