Fix red in bootloaders
[maemo-rb.git] / apps / plugins / pdbox / pdbox.c
blob0f3728e5865d9a58c0d5146872ba92dbb6ae3ea5
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 "m_pd.h"
26 #include "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_nsoundin = 0;
44 int sys_soundindevlist[MAXAUDIOINDEV];
45 int sys_nchin = 0;
46 int sys_chinlist[MAXAUDIOINDEV];
47 int sys_nsoundout = 1;
48 int sys_soundoutdevlist[MAXAUDIOOUTDEV];
49 int sys_nchout = 2;
50 int sys_choutlist[MAXAUDIOOUTDEV];
51 static int sys_main_srate = PD_SAMPLERATE;
52 static int sys_main_advance = PD_SAMPLES_PER_HZ;
54 /* References for scheduler variables and functions. */
55 extern t_time sys_time;
56 extern t_time sys_time_per_dsp_tick;
57 extern void sched_tick(t_time next_sys_time);
59 #define SAMPLES_SIZE 1000
60 t_sample samples[SAMPLES_SIZE];
62 /* Quit flag. */
63 bool quit = false;
65 /* Thread IDs. */
66 unsigned int core_thread_id;
67 unsigned int gui_thread_id;
68 unsigned int time_thread_id;
70 /* Stacks for threads. */
71 #define STACK_SIZE 16384
72 uint32_t core_stack[STACK_SIZE / sizeof(uint32_t)];
73 uint32_t gui_stack[STACK_SIZE / sizeof(uint32_t)];
74 uint32_t time_stack[256 / sizeof(uint32_t)];
77 /* Core thread, scheduler. */
78 void core_thread(void)
80 /* struct datagram ping; */
82 /* LATER consider making this variable. It's now the LCM of all sample
83 rates we expect to see: 32000, 44100, 48000, 88200, 96000. */
84 #define TIMEUNITPERSEC (32.*441000.)
86 sys_time = 0;
87 sys_time_per_dsp_tick = (TIMEUNITPERSEC) *
88 ((double)sys_schedblocksize) / sys_dacsr;
91 /* Main loop */
92 while(!quit)
94 #if 0
95 /* Wait for request. */
96 while(!RECEIVE_TO_CORE(&ping))
97 rb->yield();
99 if(memcmp("Ping!", ping.data, ping.size) == 0)
101 SEND_FROM_CORE("Pong!");
102 break;
104 #endif
106 /* Use sys_send_dacs() function as timer. */
107 if(sys_send_dacs() != SENDDACS_NO)
108 sched_tick(sys_time + sys_time_per_dsp_tick);
110 rb->sleep(1);
113 rb->thread_exit();
116 /* GUI thread */
117 void gui_thread(void)
119 /* struct datagram pong; */
121 /* GUI loop */
122 while(!quit)
124 #if 0
125 /* Send ping to the core. */
126 SEND_TO_CORE("Ping!");
127 rb->splash(HZ, "Sent ping.");
129 /* Wait for answer. */
130 while(!RECEIVE_FROM_CORE(&pong))
131 rb->yield();
133 /* If got a pong -- everything allright. */
134 if(memcmp("Pong!", pong.data, pong.size) == 0)
136 rb->splash(HZ, "Got pong!");
137 quit = true;
138 break;
140 #endif
142 rb->sleep(1);
145 rb->thread_exit();
148 /* Running time thread. */
149 void time_thread(void)
151 while(!quit)
153 /* Add time slice in milliseconds. */
154 runningtime += (1000 / HZ);
155 rb->sleep(1);
158 rb->thread_exit();
162 /* Plug-in entry point */
163 enum plugin_status plugin_start(const void* parameter)
165 PLUGIN_IRAM_INIT(rb)
167 /* Memory pool variables. */
168 size_t mem_size;
169 void* mem_pool;
171 /* Get the file name. */
172 filename = (char*) parameter;
174 /* Allocate memory; check it's size; add to the 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 add_pool(mem_pool, mem_size);
183 /* Initialize net. */
184 net_init();
186 /* Initialize Pure Data, as does sys_main in s_main.c */
187 pd_init();
189 /* Add the directory the called .pd resides in to lib directories. */
190 sys_findlibdir(filename);
192 /* Open the parameter file. */
193 sys_openlist = namelist_append(sys_openlist, filename);
195 /* Set audio API. */
196 sys_set_audio_api(API_ROCKBOX);
198 /* Fake a GUI start. */
199 sys_startgui(NULL);
201 /* Initialize audio subsystem. */
202 sys_open_audio(sys_nsoundin, sys_soundindevlist, sys_nchin, sys_chinlist,
203 sys_nsoundout, sys_soundoutdevlist, sys_nchout, sys_choutlist,
204 sys_main_srate, sys_main_advance, 1);
206 /* Start threads. */
207 time_thread_id =
208 rb->create_thread(&time_thread,
209 time_stack,
210 sizeof(time_stack),
211 0, /* FIXME Which flags? */
212 "PD running time"
213 IF_PRIO(, PRIORITY_REALTIME)
214 IF_COP(, COP));
215 core_thread_id =
216 rb->create_thread(&core_thread,
217 core_stack,
218 sizeof(core_stack),
219 0, /* FIXME Which flags? */
220 "PD core"
221 IF_PRIO(, MAX(PRIORITY_USER_INTERFACE / 2,
222 PRIORITY_REALTIME + 1))
223 IF_COP(, COP));
224 gui_thread_id =
225 rb->create_thread(&gui_thread,
226 gui_stack,
227 sizeof(gui_stack),
228 0, /* FIXME Which flags? */
229 "PD GUI"
230 IF_PRIO(, PRIORITY_USER_INTERFACE)
231 IF_COP(, CPU));
233 /* If having an error creating threads, bail out. */
234 if(core_thread_id == 0 || gui_thread_id == 0)
235 return PLUGIN_ERROR;
237 /* Wait for quit flag. */
238 while(!quit)
239 yield();
241 /* Wait for threads to complete. */
242 rb->thread_wait(gui_thread_id);
243 rb->thread_wait(core_thread_id);
244 rb->thread_wait(time_thread_id);
246 /* Destroy net. */
247 net_destroy();
249 return PLUGIN_OK;