From: <tj...@us...> - 2008-08-30 13:29:11
|
Revision: 10616 http://alleg.svn.sourceforge.net/alleg/?rev=10616&view=rev Author: tjaden Date: 2008-08-30 13:29:20 +0000 (Sat, 30 Aug 2008) Log Message: ----------- Add al_sample_set_data, which allows you to change the sample data of an ALLEGRO_SAMPLE. Make ex_acodec exercise this feature. Modified Paths: -------------- allegro/branches/4.9/addons/acodec/ex_acodec.c allegro/branches/4.9/addons/kcm_audio/allegro5/kcm_audio.h allegro/branches/4.9/addons/kcm_audio/kcm_sample.c Modified: allegro/branches/4.9/addons/acodec/ex_acodec.c =================================================================== --- allegro/branches/4.9/addons/acodec/ex_acodec.c 2008-08-30 13:27:58 UTC (rev 10615) +++ allegro/branches/4.9/addons/acodec/ex_acodec.c 2008-08-30 13:29:20 UTC (rev 10616) @@ -12,6 +12,7 @@ { ALLEGRO_VOICE *voice; ALLEGRO_MIXER *mixer; + ALLEGRO_SAMPLE *sample; int i; if (argc < 2) { @@ -44,13 +45,18 @@ } if (al_voice_attach_mixer(voice, mixer) != 0) { - TRACE("al_voice_attach_mixer failed.\n"); + fprintf(stderr, "al_voice_attach_mixer failed.\n"); return 1; } + sample = al_sample_create(NULL); + if (!sample) { + fprintf(stderr, "al_sample_create failed.\n"); + return 1; + } + for (i = 1; i < argc; ++i) { ALLEGRO_SAMPLE_DATA *sample_data = NULL; - ALLEGRO_SAMPLE *sample = NULL; const char *filename = argv[i]; float sample_time = 0; @@ -62,15 +68,14 @@ continue; } - sample = al_sample_create(sample_data); - if (!sample) { - fprintf(stderr, "al_sample_create failed.\n"); + if (al_sample_set_data(sample, sample_data) != 0) { + fprintf(stderr, "al_sample_set_ptr failed.\n"); continue; } if (al_mixer_attach_sample(mixer, sample) != 0) { fprintf(stderr, "al_mixer_attach_sample failed.\n"); - continue; + return 1; } /* Play sample in looping mode. */ @@ -86,10 +91,11 @@ fprintf(stderr, "\n"); /* Free the memory allocated. */ - al_sample_destroy(sample); + al_sample_set_data(sample, NULL); al_sample_data_destroy(sample_data); } + al_sample_destroy(sample); al_mixer_destroy(mixer); al_voice_destroy(voice); Modified: allegro/branches/4.9/addons/kcm_audio/allegro5/kcm_audio.h =================================================================== --- allegro/branches/4.9/addons/kcm_audio/allegro5/kcm_audio.h 2008-08-30 13:27:58 UTC (rev 10615) +++ allegro/branches/4.9/addons/kcm_audio/allegro5/kcm_audio.h 2008-08-30 13:29:20 UTC (rev 10616) @@ -299,6 +299,7 @@ typedef struct ALLEGRO_VOICE ALLEGRO_VOICE; +/* Sample data functions */ A5_KCM_AUDIO_FUNC(ALLEGRO_SAMPLE_DATA *, al_sample_data_create, (void *buf, unsigned long samples, unsigned long freq, ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf, bool free_buf)); @@ -328,6 +329,8 @@ ALLEGRO_AUDIO_PROPERTY setting, bool val)); A5_KCM_AUDIO_FUNC(int, al_sample_set_ptr, (ALLEGRO_SAMPLE *spl, ALLEGRO_AUDIO_PROPERTY setting, void *ptr)); +A5_KCM_AUDIO_FUNC(int, al_sample_set_data, (ALLEGRO_SAMPLE *spl, + ALLEGRO_SAMPLE_DATA *data)); A5_KCM_AUDIO_FUNC(int, al_sample_play, (ALLEGRO_SAMPLE *spl)); A5_KCM_AUDIO_FUNC(int, al_sample_stop, (ALLEGRO_SAMPLE *spl)); Modified: allegro/branches/4.9/addons/kcm_audio/kcm_sample.c =================================================================== --- allegro/branches/4.9/addons/kcm_audio/kcm_sample.c 2008-08-30 13:27:58 UTC (rev 10615) +++ allegro/branches/4.9/addons/kcm_audio/kcm_sample.c 2008-08-30 13:29:20 UTC (rev 10616) @@ -184,8 +184,10 @@ /* Function: al_sample_create - * Creates a sample stream, using the supplied buffer. This must be attached + * Creates a sample stream, using the supplied data. This must be attached * to a voice or mixer before it can be played. + * The argument may be NULL. You can then set the data later with + * <al_sample_set_data>. */ ALLEGRO_SAMPLE *al_sample_create(ALLEGRO_SAMPLE_DATA *sample_data) { @@ -198,14 +200,16 @@ return NULL; } - spl->spl_data = *sample_data; + if (sample_data) { + spl->spl_data = *sample_data; + } spl->spl_data.free_buf = false; spl->loop = ALLEGRO_PLAYMODE_ONCE; spl->speed = 1.0f; spl->pos = 0; spl->loop_start = 0; - spl->loop_end = sample_data->len; + spl->loop_end = sample_data ? sample_data->len : 0; spl->step = 0; spl->matrix = NULL; @@ -522,9 +526,13 @@ switch (setting) { case ALLEGRO_AUDIOPROP_PLAYING: if (!spl->parent.u.ptr) { - fprintf(stderr, "Sample has no parent\n"); + _al_set_error(ALLEGRO_INVALID_OBJECT, "Sample has no parent"); return 1; } + if (!spl->spl_data.buffer.ptr) { + _al_set_error(ALLEGRO_INVALID_OBJECT, "Sample has no data"); + return 1; + } if (spl->parent.is_voice) { /* parent is voice */ @@ -585,4 +593,87 @@ } +/* Function: al_sample_set_data + * Change the sample data that a sample plays. This can be quite an involved + * process. + * + * First, the sample is stopped if it is not already. + * + * Next, if data is NULL, the sample is detached from its parent (if any). + * + * If data is not NULL, the sample may be detached and reattached to its + * parent (if any). This is not necessary if the old sample data and new + * sample data have the same frequency, depth and channel configuration. + * Reattaching may not always succeed. + * + * On success, the sample remains stopped. The playback position and loop + * end points are reset to their default values. The loop mode remains + * unchanged. + * + * Returns zero on success, non-zero on failure. On failure, the sample will + * be stopped and detached from its parent. + */ +int al_sample_set_data(ALLEGRO_SAMPLE *spl, ALLEGRO_SAMPLE_DATA *data) +{ + sample_parent_t old_parent; + bool need_reattach; + + ASSERT(spl); + + /* Stop the sample if it is playing. */ + if (spl->is_playing) { + if (al_sample_set_bool(spl, ALLEGRO_AUDIOPROP_PLAYING, false) != 0) { + /* Shouldn't happen. */ + ASSERT(false); + return 1; + } + } + + if (!data) { + if (spl->parent.u.ptr) { + _al_kcm_detach_from_parent(spl); + } + spl->spl_data.buffer.ptr = NULL; + return 0; + } + + /* Have data. */ + + need_reattach = false; + if (spl->parent.u.ptr != NULL) { + if (spl->spl_data.frequency != data->frequency || + spl->spl_data.depth != data->depth || + spl->spl_data.chan_conf != data->chan_conf) { + old_parent = spl->parent; + need_reattach = true; + _al_kcm_detach_from_parent(spl); + } + } + + spl->spl_data = *data; + spl->spl_data.free_buf = false; + spl->pos = 0; + spl->loop_start = 0; + spl->loop_end = data->len; + /* Should we reset the loop mode? */ + + if (need_reattach) { + if (old_parent.is_voice) { + if (al_voice_attach_sample(old_parent.u.voice, spl) != 0) { + spl->spl_data.buffer.ptr = NULL; + return 1; + } + } + else { + if (al_mixer_attach_sample(old_parent.u.mixer, spl) != 0) { + spl->spl_data.buffer.ptr = NULL; + return 1; + } + } + } + + return 0; +} + + /* vim: set sts=3 sw=3 et: */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |