1 #include "edje_private.h"
3 typedef struct _Multisense_Data
5 Edje_Multisense_Env *msenv;
9 RemixLayer *snd_layer, *player_layer;
11 RemixBase *player_snd;
14 Eina_List *snd_src_list;
16 MULTISENSE_SOUND_PLAYER_GET_FUNC multisense_sound_player_get;
21 #define SND_PROCESS_LENGTH 2048
24 static Ecore_Thread *player_thread = NULL;
25 static int command_pipe[2];
26 static Eina_Bool pipe_initialized = EINA_FALSE;
29 typedef enum _Edje_Sound_Action_Type
39 } Edje_Sound_Action_Type;
41 typedef struct _Edje_Sample_Action Edje_Sample_Action;
42 typedef struct _Edje_Tone_Action Edje_Tone_Action;
43 typedef struct _Edje_Multisense_Sound_Action Edje_Multisense_Sound_Action;
45 struct _Edje_Sample_Action
47 char sample_name[BUF_LEN];
51 struct _Edje_Tone_Action
53 char tone_name[BUF_LEN];
57 struct _Edje_Multisense_Sound_Action
60 Edje_Sound_Action_Type action;
62 Edje_Sample_Action sample;
63 Edje_Tone_Action tone;
68 static Multisense_Data *
69 init_multisense_environment(void)
71 Multisense_Data *msdata;
72 char ms_factory[BUF_LEN];
74 Eina_Module *m = NULL;
75 MULTISENSE_FACTORY_INIT_FUNC multisense_factory_init;
77 msdata = calloc(1, sizeof(Multisense_Data));
78 if (!msdata) goto err;
80 msdata->msenv = calloc(1, sizeof(Edje_Multisense_Env));
81 if (!msdata->msenv) goto err;
83 ms_factory_env = getenv("MULTISENSE_FACTORY");
85 strncpy(ms_factory, ms_factory_env, BUF_LEN);
87 strcpy(ms_factory, "multisense_factory");
89 m = _edje_module_handle_load(ms_factory);
92 msdata->msenv->remixenv = remix_init();
94 multisense_factory_init =
95 eina_module_symbol_get(m, "multisense_factory_init");
96 if (multisense_factory_init) multisense_factory_init(msdata->msenv);
98 msdata->multisense_sound_player_get =
99 eina_module_symbol_get(m, "multisense_sound_player_get");
100 if (!msdata->multisense_sound_player_get) goto err;
102 msdata->deck = remix_deck_new(msdata->msenv->remixenv);
103 msdata->track = remix_track_new(msdata->msenv->remixenv, msdata->deck);
104 msdata->snd_layer = remix_layer_new_ontop(msdata->msenv->remixenv,
107 msdata->player_layer = remix_layer_new_ontop(msdata->msenv->remixenv,
110 msdata->player = msdata->multisense_sound_player_get(msdata->msenv);
111 if (!msdata->player) goto err;
112 msdata->player_snd = remix_sound_new(msdata->msenv->remixenv,
113 msdata->player, msdata->player_layer,
115 REMIX_SAMPLES(REMIX_COUNT_INFINITE));
121 if (msdata->deck) remix_destroy(msdata->msenv->remixenv, msdata->deck);
122 if (msdata->msenv->remixenv) remix_purge(msdata->msenv->remixenv);
123 if (msdata->msenv) free(msdata->msenv);
132 eet_sound_reader_get(Edje_Multisense_Env *msenv, const char *path, const char *sound_id, const double speed)
134 RemixPlugin *sf_plugin = NULL;
135 RemixBase * eet_snd_reader = NULL;
137 int sf_sound_id_key = 0;
138 int sf_speed_key = 0;
139 CDSet *sf_parms = NULL;
140 RemixEnv *env = msenv->remixenv;
142 if (sf_plugin == NULL)
144 sf_plugin = remix_find_plugin(env, "eet_sndfile_reader");
145 if (sf_plugin == NULL)
147 ERR ("Multisense EET Sound reader plugin NULL\n");
151 sf_path_key = remix_get_init_parameter_key(env, sf_plugin, "path");
152 sf_sound_id_key = remix_get_init_parameter_key(env, sf_plugin, "sound_id");
153 sf_speed_key = remix_get_init_parameter_key(env, sf_plugin, "speed");
155 sf_parms = cd_set_replace(env, sf_parms, sf_path_key, CD_STRING(path));
156 sf_parms = cd_set_replace(env, sf_parms, sf_sound_id_key, CD_STRING(sound_id));
157 sf_parms = cd_set_replace(env, sf_parms, sf_speed_key, CD_DOUBLE(speed));
158 eet_snd_reader = remix_new(env, sf_plugin, sf_parms);
160 return eet_snd_reader;
165 edje_remix_sample_create(Multisense_Data *msdata, Edje*ed, Edje_Sample_Action *action)
167 RemixBase *remix_snd = NULL;
168 Edje_Sound_Sample *sample;
172 if ((!ed) || (!ed->file) || (!ed->file->sound_dir))
175 for (i = 0; i < (int)ed->file->sound_dir->samples_count; i++)
177 sample = &ed->file->sound_dir->samples[i];
178 if (!strcmp(sample->name, action->sample_name))
180 snprintf(snd_id_str, sizeof(snd_id_str), "edje/sounds/%i", sample->id);
181 remix_snd = eet_sound_reader_get(msdata->msenv, ed->file->path,
182 snd_id_str, action->speed);
190 edje_remix_tone_create(Multisense_Data *msdata, Edje*ed, Edje_Tone_Action *action)
192 Edje_Sound_Tone *tone;
193 RemixSquareTone *square = NULL;
196 if ((!ed) || (!ed->file) || (!ed->file->sound_dir))
199 for (i = 0; i < ed->file->sound_dir->tones_count; i++)
201 tone = &ed->file->sound_dir->tones[i];
202 if (!strcmp(tone->name, action->tone_name))
204 square = remix_squaretone_new (msdata->msenv->remixenv, tone->value);
212 sound_command_handler(Multisense_Data *msdata)
215 Edje_Multisense_Sound_Action command;
216 RemixBase *base = NULL;
219 if (read(command_pipe[0], &command, sizeof(command)) <= 0) return;
220 switch (command.action)
222 case EDJE_PLAY_SAMPLE:
223 base = edje_remix_sample_create(msdata, command.ed,
224 &command.type.sample);
225 length = remix_length(msdata->msenv->remixenv, base);
228 base = edje_remix_tone_create(msdata, command.ed, &command.type.tone);
229 length = (command.type.tone.duration *
230 remix_get_samplerate(msdata->msenv->remixenv));
233 ERR("Invalid Sound Play Command\n");
238 sound = remix_sound_new(msdata->msenv->remixenv, base, msdata->snd_layer,
239 REMIX_SAMPLES(msdata->offset),
240 REMIX_SAMPLES(length));
241 if (msdata->remaining < length) msdata->remaining = length;
242 msdata->snd_src_list = eina_list_append(msdata->snd_src_list, sound);
243 msdata->snd_src_list = eina_list_append(msdata->snd_src_list, base);
249 // msdata outside of thread due to thread issues in dlsym etc.
250 static Multisense_Data *msdata = NULL;
255 // cleanup msdata outside of thread due to thread issues in dlsym etc.
257 //cleanup Remix stuffs
258 remix_destroy(msdata->msenv->remixenv, msdata->player);
259 remix_destroy(msdata->msenv->remixenv, msdata->deck);
260 remix_purge(msdata->msenv->remixenv);
268 _player_job(void *data __UNUSED__, Ecore_Thread *th)
272 RemixCount process_len;
273 // disable and move outside of thread due to dlsym etc. thread issues
274 // Multisense_Data * msdata = init_multisense_environment();
278 fcntl(command_pipe[0], F_SETFL, O_NONBLOCK);
280 FD_SET(command_pipe[0], &wait_fds);
282 while (!ecore_thread_check(th))
284 if (!msdata->remaining)
288 //Cleanup already played sound sources
289 EINA_LIST_FREE(msdata->snd_src_list, sound)
291 remix_destroy(msdata->msenv->remixenv, sound);
294 err = select(command_pipe[0] + 1, &wait_fds, NULL, NULL, 0);
295 if (ecore_thread_check(th))
298 //read sound command , if any
299 sound_command_handler(msdata);
300 process_len = MIN(msdata->remaining, SND_PROCESS_LENGTH);
301 remix_process(msdata->msenv->remixenv, msdata->deck, process_len,
302 RemixNone, RemixNone);
303 msdata->offset += process_len;
304 msdata->remaining -= process_len;
307 //Cleanup last played sound sources
308 EINA_LIST_FREE(msdata->snd_src_list, sound)
310 remix_destroy(msdata->msenv->remixenv, sound);
317 _player_cancel(void *data __UNUSED__, Ecore_Thread *th __UNUSED__)
319 // cleanup msdata outside of thread due to thread issues in dlsym etc.
321 player_thread = NULL;
327 _player_end(void *data __UNUSED__, Ecore_Thread *th __UNUSED__)
329 // cleanup msdata outside of thread due to thread issues in dlsym etc.
331 player_thread = NULL;
336 _edje_multisense_internal_sound_sample_play(Edje *ed, const char *sample_name, const double speed)
339 #ifdef ENABLE_MULTISENSE
340 Edje_Multisense_Sound_Action command;
342 if ((!pipe_initialized) && (!player_thread)) return EINA_FALSE;
345 ERR("Given Sample Name is NULL\n");
349 command.action = EDJE_PLAY_SAMPLE;
351 strncpy(command.type.sample.sample_name, sample_name, BUF_LEN);
352 command.type.sample.speed = speed;
353 size = write(command_pipe[1], &command, sizeof(command));
360 return (size == sizeof(Edje_Multisense_Sound_Action));
364 _edje_multisense_internal_sound_tone_play(Edje *ed, const char *tone_name, const double duration)
367 #ifdef ENABLE_MULTISENSE
368 Edje_Multisense_Sound_Action command;
370 if ((!pipe_initialized) && (!player_thread)) return EINA_FALSE;
373 ERR("Given Tone Name is NULL\n");
377 command.action = EDJE_PLAY_TONE;
379 strncpy(command.type.tone.tone_name, tone_name, BUF_LEN);
380 command.type.tone.duration = duration;
381 size = write(command_pipe[1], &command, sizeof(command));
388 return (size == sizeof(Edje_Multisense_Sound_Action));
392 /* Initialize the modules in main thread. to avoid dlopen issue in the Threads */
394 _edje_multisense_init(void)
396 #ifdef ENABLE_MULTISENSE
397 if (!pipe_initialized && (pipe(command_pipe) != -1))
398 pipe_initialized = EINA_TRUE;
400 // init msdata outside of thread due to thread issues in dlsym etc.
401 if (!msdata) msdata = init_multisense_environment();
404 player_thread = ecore_thread_feedback_run(_player_job, NULL, _player_end, _player_cancel, NULL, EINA_TRUE);
409 _edje_multisense_shutdown(void)
411 #ifdef ENABLE_MULTISENSE
412 if (player_thread) ecore_thread_cancel(player_thread);
413 if (pipe_initialized)
417 write(command_pipe[1], &i, sizeof (int));
418 close(command_pipe[1]);
419 close(command_pipe[0]);