From e069b829bf7fff588d51d1bb916591b4ab89fb87 Mon Sep 17 00:00:00 2001 From: Daniel Willmann Date: Mon, 28 Jan 2013 15:15:20 +0000 Subject: [PATCH] edje-multisense: Replace sound handling with ecore_audio The speed keyword is not yet implemented. Signed-off-by: Daniel Willmann SVN revision: 83380 --- src/lib/edje/edje_multisense.c | 475 +++++++++------------------------ 1 file changed, 123 insertions(+), 352 deletions(-) diff --git a/src/lib/edje/edje_multisense.c b/src/lib/edje/edje_multisense.c index 454d50271c..d6ad283bdb 100644 --- a/src/lib/edje/edje_multisense.c +++ b/src/lib/edje/edje_multisense.c @@ -1,391 +1,176 @@ #include "edje_private.h" +#include "Ecore_Audio.h" +#include -typedef struct _Multisense_Data +static Ecore_Audio_Object *out = NULL; + +static Eina_Bool _play_finished(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) { - Edje_Multisense_Env *msenv; -#ifdef HAVE_LIBREMIX - RemixDeck *deck; - RemixTrack *track; - RemixLayer *snd_layer, *player_layer; - RemixBase *player; - RemixBase *player_snd; - int remaining; - int offset; - Eina_List *snd_src_list; + Ecore_Audio_Object *in = (Ecore_Audio_Object *)event; + ecore_audio_input_del(in); + return EINA_FALSE; +} - MULTISENSE_SOUND_PLAYER_GET_FUNC multisense_sound_player_get; -#endif -}Multisense_Data; - -#define BUF_LEN 64 -#define SND_PROCESS_LENGTH 2048 - -#ifdef HAVE_LIBREMIX -static Ecore_Thread *player_thread = NULL; -static int command_pipe[2]; -static Eina_Bool pipe_initialized = EINA_FALSE; -#endif - -typedef enum _Edje_Sound_Action_Type +struct _edje_multisense_eet_data { - EDJE_PLAY_SAMPLE = 0, - EDJE_PLAY_TONE, - /* - EDJE_PLAY_PATTERN, - EDJE_PLAY_INSTRUMENT, - EDJE_PLAY_SONG, - */ - EDJE_SOUND_LAST -} Edje_Sound_Action_Type; - -typedef struct _Edje_Sample_Action Edje_Sample_Action; -typedef struct _Edje_Tone_Action Edje_Tone_Action; -typedef struct _Edje_Multisense_Sound_Action Edje_Multisense_Sound_Action; - -struct _Edje_Sample_Action -{ - char sample_name[BUF_LEN]; - double speed; + sf_count_t offset, length; + const char *data; + Ecore_Audio_Vio vio; }; -struct _Edje_Tone_Action +static int +eet_snd_file_get_length(Ecore_Audio_Object *in) { - char tone_name[BUF_LEN]; - double duration; -}; - -struct _Edje_Multisense_Sound_Action -{ - Edje *ed; - Edje_Sound_Action_Type action; - union { - Edje_Sample_Action sample; - Edje_Tone_Action tone; - } type; -}; - -#ifdef HAVE_LIBREMIX -static Multisense_Data * -init_multisense_environment(void) -{ - Multisense_Data *msdata; - char ms_factory[BUF_LEN]; - char *ms_factory_env; - Eina_Module *m = NULL; - MULTISENSE_FACTORY_INIT_FUNC multisense_factory_init; - - msdata = calloc(1, sizeof(Multisense_Data)); - if (!msdata) goto err; - - msdata->msenv = calloc(1, sizeof(Edje_Multisense_Env)); - if (!msdata->msenv) goto err; - - ms_factory_env = getenv("MULTISENSE_FACTORY"); - if (ms_factory_env) - strncpy(ms_factory, ms_factory_env, BUF_LEN); - else - strcpy(ms_factory, "multisense_factory"); - - m = _edje_module_handle_load(ms_factory); - if (!m) goto err; - - msdata->msenv->remixenv = remix_init(); - - multisense_factory_init = - eina_module_symbol_get(m, "multisense_factory_init"); - if (multisense_factory_init) multisense_factory_init(msdata->msenv); - - msdata->multisense_sound_player_get = - eina_module_symbol_get(m, "multisense_sound_player_get"); - if (!msdata->multisense_sound_player_get) goto err; - - msdata->deck = remix_deck_new(msdata->msenv->remixenv); - msdata->track = remix_track_new(msdata->msenv->remixenv, msdata->deck); - msdata->snd_layer = remix_layer_new_ontop(msdata->msenv->remixenv, - msdata->track, - REMIX_TIME_SAMPLES); - msdata->player_layer = remix_layer_new_ontop(msdata->msenv->remixenv, - msdata->track, - REMIX_TIME_SAMPLES); - msdata->player = msdata->multisense_sound_player_get(msdata->msenv); - if (!msdata->player) goto err; - msdata->player_snd = remix_sound_new(msdata->msenv->remixenv, - msdata->player, msdata->player_layer, - REMIX_SAMPLES(0), - REMIX_SAMPLES(REMIX_COUNT_INFINITE)); - return msdata; - -err: - if (msdata) - { - if (msdata->deck) remix_destroy(msdata->msenv->remixenv, msdata->deck); - if (msdata->msenv->remixenv) remix_purge(msdata->msenv->remixenv); - if (msdata->msenv) free(msdata->msenv); - free(msdata); - } - return NULL; -} -#endif - -#ifdef HAVE_LIBREMIX -static RemixBase * -eet_sound_reader_get(Edje_Multisense_Env *msenv, const char *path, const char *sound_id, const double speed) -{ - RemixPlugin *sf_plugin = NULL; - RemixBase * eet_snd_reader = NULL; - int sf_path_key = 0; - int sf_sound_id_key = 0; - int sf_speed_key = 0; - CDSet *sf_parms = NULL; - RemixEnv *env = msenv->remixenv; - - if (sf_plugin == NULL) - { - sf_plugin = remix_find_plugin(env, "eet_sndfile_reader"); - if (sf_plugin == NULL) - { - ERR ("Multisense EET Sound reader plugin NULL\n"); - return NULL; - } - - sf_path_key = remix_get_init_parameter_key(env, sf_plugin, "path"); - sf_sound_id_key = remix_get_init_parameter_key(env, sf_plugin, "sound_id"); - sf_speed_key = remix_get_init_parameter_key(env, sf_plugin, "speed"); - } - sf_parms = cd_set_replace(env, sf_parms, sf_path_key, CD_STRING(path)); - sf_parms = cd_set_replace(env, sf_parms, sf_sound_id_key, CD_STRING(sound_id)); - sf_parms = cd_set_replace(env, sf_parms, sf_speed_key, CD_DOUBLE(speed)); - eet_snd_reader = remix_new(env, sf_plugin, sf_parms); - - return eet_snd_reader; + struct _edje_multisense_eet_data *vf = ecore_audio_input_userdata_get(in); + return vf->length; } - -static RemixBase * -edje_remix_sample_create(Multisense_Data *msdata, Edje*ed, Edje_Sample_Action *action) +static int +eet_snd_file_seek(Ecore_Audio_Object *in, int offset, int whence) { - RemixBase *remix_snd = NULL; - Edje_Sound_Sample *sample; - int i; - char snd_id_str[16]; + struct _edje_multisense_eet_data *vf = ecore_audio_input_userdata_get(in); - if ((!ed) || (!ed->file) || (!ed->file->sound_dir)) - return NULL; - - for (i = 0; i < (int)ed->file->sound_dir->samples_count; i++) - { - sample = &ed->file->sound_dir->samples[i]; - if (!strcmp(sample->name, action->sample_name)) - { - snprintf(snd_id_str, sizeof(snd_id_str), "edje/sounds/%i", sample->id); - remix_snd = eet_sound_reader_get(msdata->msenv, ed->file->path, - snd_id_str, action->speed); - break; - } - } - return remix_snd; -} - -static RemixBase * -edje_remix_tone_create(Multisense_Data *msdata, Edje*ed, Edje_Tone_Action *action) -{ - Edje_Sound_Tone *tone; - RemixSquareTone *square = NULL; - unsigned int i; - - if ((!ed) || (!ed->file) || (!ed->file->sound_dir)) - return NULL; - - for (i = 0; i < ed->file->sound_dir->tones_count; i++) - { - tone = &ed->file->sound_dir->tones[i]; - if (!strcmp(tone->name, action->tone_name)) - { - square = remix_squaretone_new (msdata->msenv->remixenv, tone->value); - break; - } - } - return square; -} - -static void -sound_command_handler(Multisense_Data *msdata) -{ - RemixCount length; - Edje_Multisense_Sound_Action command; - RemixBase *base = NULL; - RemixBase *sound; - - if (read(command_pipe[0], &command, sizeof(command)) <= 0) return; - switch (command.action) - { - case EDJE_PLAY_SAMPLE: - base = edje_remix_sample_create(msdata, command.ed, - &command.type.sample); - length = remix_length(msdata->msenv->remixenv, base); + switch (whence) + { + case SEEK_SET: + vf->offset = offset; + break; + case SEEK_CUR: + vf->offset += offset; break; - case EDJE_PLAY_TONE: - base = edje_remix_tone_create(msdata, command.ed, &command.type.tone); - length = (command.type.tone.duration * - remix_get_samplerate(msdata->msenv->remixenv)); - break; - default: - ERR("Invalid Sound Play Command\n"); - break; - } - if (base) - { - sound = remix_sound_new(msdata->msenv->remixenv, base, msdata->snd_layer, - REMIX_SAMPLES(msdata->offset), - REMIX_SAMPLES(length)); - if (msdata->remaining < length) msdata->remaining = length; - msdata->snd_src_list = eina_list_append(msdata->snd_src_list, sound); - msdata->snd_src_list = eina_list_append(msdata->snd_src_list, base); - } + case SEEK_END: + vf->offset = vf->length + offset; + break; + default: + break; + } + return vf->offset; } -#endif -#ifdef HAVE_LIBREMIX -// msdata outside of thread due to thread issues in dlsym etc. -static Multisense_Data *msdata = NULL; - -static void -_msdata_free(void) +static int +eet_snd_file_read(Ecore_Audio_Object *in, void *buffer, int count) { - // cleanup msdata outside of thread due to thread issues in dlsym etc. - if (!msdata) return; - //cleanup Remix stuffs - remix_destroy(msdata->msenv->remixenv, msdata->player); - remix_destroy(msdata->msenv->remixenv, msdata->deck); - remix_purge(msdata->msenv->remixenv); + struct _edje_multisense_eet_data *vf = ecore_audio_input_userdata_get(in); - free(msdata->msenv); - free(msdata); - msdata = NULL; + if ((vf->offset + count) > vf->length) + count = vf->length - vf->offset; + memcpy(buffer, vf->data + vf->offset, count); + vf->offset += count; + return count; } -static void -_player_job(void *data EINA_UNUSED, Ecore_Thread *th) +static int +eet_snd_file_tell(Ecore_Audio_Object *in) { - fd_set wait_fds; - RemixBase *sound; - RemixCount process_len; -// disable and move outside of thread due to dlsym etc. thread issues -// Multisense_Data * msdata = init_multisense_environment(); + struct _edje_multisense_eet_data *vf = ecore_audio_input_userdata_get(in); - if (!msdata) return; - - fcntl(command_pipe[0], F_SETFL, O_NONBLOCK); - FD_ZERO(&wait_fds); - FD_SET(command_pipe[0], &wait_fds); - - while (!ecore_thread_check(th)) - { - if (!msdata->remaining) - { - int err; - - //Cleanup already played sound sources - EINA_LIST_FREE(msdata->snd_src_list, sound) - { - remix_destroy(msdata->msenv->remixenv, sound); - } - //wait for new sound - err = select(command_pipe[0] + 1, &wait_fds, NULL, NULL, 0); - if (ecore_thread_check(th)) - break; - } - //read sound command , if any - sound_command_handler(msdata); - process_len = MIN(msdata->remaining, SND_PROCESS_LENGTH); - remix_process(msdata->msenv->remixenv, msdata->deck, process_len, - RemixNone, RemixNone); - msdata->offset += process_len; - msdata->remaining -= process_len; - } - - //Cleanup last played sound sources - EINA_LIST_FREE(msdata->snd_src_list, sound) - { - remix_destroy(msdata->msenv->remixenv, sound); - } + return vf->offset; } -#endif - -#ifdef HAVE_LIBREMIX -static void -_player_cancel(void *data EINA_UNUSED, Ecore_Thread *th EINA_UNUSED) -{ - // cleanup msdata outside of thread due to thread issues in dlsym etc. - _msdata_free(); - player_thread = NULL; -} -#endif - -#ifdef HAVE_LIBREMIX -static void -_player_end(void *data EINA_UNUSED, Ecore_Thread *th EINA_UNUSED) -{ - // cleanup msdata outside of thread due to thread issues in dlsym etc. - _msdata_free(); - player_thread = NULL; -} -#endif Eina_Bool -_edje_multisense_internal_sound_sample_play(Edje *ed, const char *sample_name, const double speed) +_edje_multisense_internal_sound_sample_play(Edje *ed, const char *sample_name, const double speed EINA_UNUSED) { - ssize_t size = 0; -#ifdef ENABLE_MULTISENSE - Edje_Multisense_Sound_Action command; + #ifdef ENABLE_MULTISENSE + Ecore_Audio_Object *in; + Edje_Sound_Sample *sample; + char snd_id_str[255]; + int i; - if ((!pipe_initialized) && (!player_thread)) return EINA_FALSE; - if (!sample_name) + if (!sample_name) + { + ERR("Given Sample Name is NULL\n"); + return EINA_FALSE; + } + + if ((!ed) || (!ed->file) || (!ed->file->sound_dir)) + return EINA_FALSE; + + for(i=0; i<(int)ed->file->sound_dir->samples_count; i++) { - ERR("Given Sample Name is NULL\n"); - return EINA_FALSE; - } + sample = &ed->file->sound_dir->samples[i]; + if (!strcmp(sample->name, sample_name)) + { + struct _edje_multisense_eet_data *eet_data; + Eet_File *ef; - command.action = EDJE_PLAY_SAMPLE; - command.ed = ed; - strncpy(command.type.sample.sample_name, sample_name, BUF_LEN); - command.type.sample.speed = speed; - size = write(command_pipe[1], &command, sizeof(command)); + snprintf(snd_id_str, sizeof(snd_id_str), "edje/sounds/%i", sample->id); + in = ecore_audio_input_add(ECORE_AUDIO_TYPE_SNDFILE); + ecore_audio_input_name_set(in, snd_id_str); + + eet_data = calloc(1, sizeof(struct _edje_multisense_eet_data)); + ef = eet_open(ed->file->path, EET_FILE_MODE_READ); + + eet_data->data = eet_read(ef, snd_id_str, (int *)&eet_data->length); + eet_close(ef); + + /* action->speed */ + + eet_data->vio.get_length = eet_snd_file_get_length; + eet_data->vio.seek = eet_snd_file_seek; + eet_data->vio.read = eet_snd_file_read; + eet_data->vio.tell = eet_snd_file_tell; + + eet_data->offset = 0; + + ecore_audio_input_userdata_set(in, eet_data); + ecore_audio_input_sndfile_vio_set(in, &eet_data->vio); + + if (!out) + out = ecore_audio_output_add(ECORE_AUDIO_TYPE_PULSE); + + ecore_audio_output_input_add(out, in); + } + } + return EINA_TRUE; #else // warning shh (void) ed; (void) sample_name; (void) speed; + return EINA_FALSE; #endif - return (size == sizeof(Edje_Multisense_Sound_Action)); } Eina_Bool _edje_multisense_internal_sound_tone_play(Edje *ed, const char *tone_name, const double duration) { - ssize_t size = 0; #ifdef ENABLE_MULTISENSE - Edje_Multisense_Sound_Action command; + unsigned int i; + Edje_Sound_Tone *tone; - if ((!pipe_initialized) && (!player_thread)) return EINA_FALSE; + Ecore_Audio_Object *in; if (!tone_name) { ERR("Given Tone Name is NULL\n"); return EINA_FALSE; } + if ((!ed) || (!ed->file) || (!ed->file->sound_dir)) + return EINA_FALSE; - command.action = EDJE_PLAY_TONE; - command.ed = ed; - strncpy(command.type.tone.tone_name, tone_name, BUF_LEN); - command.type.tone.duration = duration; - size = write(command_pipe[1], &command, sizeof(command)); + for (i=0; ifile->sound_dir->tones_count; i++) + { + tone = &ed->file->sound_dir->tones[i]; + if (!strcmp(tone->name, tone_name)) + { + in = ecore_audio_input_add(ECORE_AUDIO_TYPE_TONE); + ecore_audio_input_name_set(in, "tone"); + ecore_audio_input_tone_frequency_set(in, tone->value); + ecore_audio_input_tone_duration_set(in, duration); + + if (!out) + out = ecore_audio_output_add(ECORE_AUDIO_TYPE_PULSE); + + ecore_audio_output_input_add(out, in); + } + } + return EINA_TRUE; #else // warning shh (void) ed; (void) duration; (void) tone_name; + return EINA_FALSE; #endif - return (size == sizeof(Edje_Multisense_Sound_Action)); } @@ -394,14 +179,8 @@ void _edje_multisense_init(void) { #ifdef ENABLE_MULTISENSE - if (!pipe_initialized && (pipe(command_pipe) != -1)) - pipe_initialized = EINA_TRUE; - - // init msdata outside of thread due to thread issues in dlsym etc. - if (!msdata) msdata = init_multisense_environment(); - - if (!player_thread) - player_thread = ecore_thread_feedback_run(_player_job, NULL, _player_end, _player_cancel, NULL, EINA_TRUE); + ecore_audio_init(); + ecore_event_handler_add(ECORE_AUDIO_INPUT_ENDED, _play_finished, NULL); #endif } @@ -409,14 +188,6 @@ void _edje_multisense_shutdown(void) { #ifdef ENABLE_MULTISENSE - if (player_thread) ecore_thread_cancel(player_thread); - if (pipe_initialized) - { - int i = 42; - - write(command_pipe[1], &i, sizeof (int)); - close(command_pipe[1]); - close(command_pipe[0]); - } + ecore_audio_shutdown(); #endif }