Fix pdbox makefile to actually take part in dependency generation
[kugel-rb.git] / apps / plugins / pdbox / pdbox.c
blob56371af81fd4c4e6c3d214fee8c5182b62594fa6
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
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 ****************************************************************************/
22 #include "plugin.h"
23 #include "pdbox.h"
25 #include "PDa/src/m_pd.h"
26 #include "PDa/src/s_stuff.h"
28 /* Welcome to the PDBox plugin */
29 PLUGIN_HEADER
30 PLUGIN_IRAM_DECLARE
32 /* Name of the file to open. */
33 char* filename;
35 /* Running time. */
36 uint64_t runningtime = 0;
38 /* Variables for Pure Data. */
39 int sys_verbose;
40 int sys_noloadbang;
41 t_symbol *sys_libdir;
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];
47 t_binbuf* inbinbuf;
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.)
59 /* Quit flag. */
60 bool quit = false;
62 /* Stack sizes for threads. */
63 #define CORESTACKSIZE (1 * 1024 * 1024)
64 #define GUISTACKSIZE (512 * 1024)
66 /* Thread stacks. */
67 void* core_stack;
68 void* gui_stack;
70 /* Thread IDs. */
71 unsigned int core_thread_id;
72 unsigned int gui_thread_id;
75 /* GUI thread */
76 void gui_thread(void)
78 struct pd_widget widget[128];
79 unsigned int widgets = 0;
80 struct datagram dg;
81 bool update;
83 /* Initialize GUI. */
84 pd_gui_init();
86 /* Load PD patch. */
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);
93 /* GUI loop */
94 while(!quit)
96 /* Reset update flag. */
97 update = false;
99 /* Apply timer to widgets. */
100 update |=
101 pd_gui_apply_timeouts(widget, widgets);
103 /* Process buttons. */
104 update |=
105 pd_gui_parse_buttons(widgets);
107 /* Receive and parse datagrams. */
108 while(RECEIVE_FROM_CORE(&dg))
110 update = true;
111 pd_gui_parse_message(&dg, widget, widgets);
114 /* If there is something to update in GUI, do so. */
115 if(update)
116 pd_gui_draw(widget, widgets);
118 rb->sleep(1);
121 rb->thread_exit();
124 /* Core thread */
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. */
134 sys_startgui(NULL);
136 /* Core scheduler loop */
137 while(!quit)
139 /* Receive datagrams. */
140 struct datagram dg;
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);
149 yield();
152 rb->thread_exit();
157 /* Plug-in entry point */
158 enum plugin_status plugin_start(const void* parameter)
160 PLUGIN_IRAM_INIT(rb)
162 /* Memory pool variables. */
163 size_t mem_size;
164 void* mem_pool;
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!");
171 return PLUGIN_ERROR;
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!");
179 return PLUGIN_ERROR;
181 #if 1
182 init_memory_pool(mem_size, mem_pool);
183 #endif
184 #if 0
185 set_memory_pool(mem_pool, mem_size);
186 #endif
188 /* Initialize net. */
189 net_init();
191 /* Initialize Pure Data, as does sys_main in s_main.c */
192 pd_init();
194 /* Set audio API. */
195 sys_set_audio_api(API_ROCKBOX);
197 /* Initialize audio subsystem. */
198 sys_open_audio(0, /* No sound input yet */
199 sys_soundindevlist,
200 0, /* No sound input yet */
201 sys_chinlist,
202 1, /* One sound output device */
203 sys_soundoutdevlist,
204 -1, /* Use the default amount (2) of channels */
205 sys_choutlist,
206 PD_SAMPLERATE, /* Sample rate */
207 DEFAULTADVANCE, /* Scheduler advance */
208 1 /* Enable */);
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!");
216 return PLUGIN_ERROR;
219 /* Boost CPU. */
220 cpu_boost(true);
222 /* Start threads. */
223 core_thread_id =
224 rb->create_thread(&core_thread,
225 core_stack,
226 CORESTACKSIZE,
227 0, /* FIXME Which flags? */
228 "PD core"
229 IF_PRIO(, PRIORITY_REALTIME)
230 IF_COP(, COP));
232 gui_thread_id =
233 rb->create_thread(&gui_thread,
234 gui_stack,
235 GUISTACKSIZE,
236 0, /* FIXME Which flags? */
237 "PD GUI"
238 IF_PRIO(, PRIORITY_USER_INTERFACE)
239 IF_COP(, CPU));
241 /* If having an error creating threads, bail out. */
242 if(core_thread_id == 0 || gui_thread_id == 0)
243 return PLUGIN_ERROR;
245 /* Initialize scheduler time variables. */
246 sys_time = 0;
247 sys_time_per_dsp_tick = (TIMEUNITPERSEC) *
248 ((double) sys_schedblocksize) / sys_dacsr;
251 /* Main loop. */
252 while(!quit)
254 /* Add time slice in milliseconds. */
255 runningtime += (1000 / HZ);
257 /* Sleep to the next time slice. */
258 rb->sleep(1);
261 /* Wait for threads to complete. */
262 rb->thread_wait(gui_thread_id);
263 rb->thread_wait(core_thread_id);
265 /* Unboost CPU. */
266 cpu_boost(false);
268 /* Close audio subsystem. */
269 sys_close_audio();
271 /* Destroy net. */
272 net_destroy();
274 /* Clear memory pool. */
275 #if 1
276 destroy_memory_pool(mem_pool);
277 #endif
278 #if 0
279 clear_memory_pool();
280 #endif
282 return PLUGIN_OK;