void stop_sound(sound_t* sound, bool rewind) { al_set_audio_stream_playing(sound->stream, false); if (rewind) al_rewind_audio_stream(sound->stream); }
static int allua_audio_stream_rewind(lua_State * L) { ALLUA_audio_stream audio_stream = allua_check_audio_stream(L, 1); lua_pushboolean(L, al_rewind_audio_stream(audio_stream)); return 1; }
bool AudioStream::rewind() { al_seek_audio_stream_secs(m_stream, 0); return al_rewind_audio_stream(m_stream); }
/* _al_kcm_feed_stream: * A routine running in another thread that feeds the stream buffers as * neccesary, usually getting data from some file reader backend. */ void *_al_kcm_feed_stream(ALLEGRO_THREAD *self, void *vstream) { ALLEGRO_AUDIO_STREAM *stream = vstream; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_EVENT event; (void)self; ALLEGRO_DEBUG("Stream feeder thread started.\n"); queue = al_create_event_queue(); al_register_event_source(queue, &stream->spl.es); al_lock_mutex(stream->feed_thread_started_mutex); stream->feed_thread_started = true; al_broadcast_cond(stream->feed_thread_started_cond); al_unlock_mutex(stream->feed_thread_started_mutex); stream->quit_feed_thread = false; while (!stream->quit_feed_thread) { char *fragment; ALLEGRO_EVENT event; al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT && !stream->is_draining) { unsigned long bytes; unsigned long bytes_written; ALLEGRO_MUTEX *stream_mutex; fragment = al_get_audio_stream_fragment(stream); if (!fragment) { /* This is not an error. */ continue; } bytes = (stream->spl.spl_data.len) * al_get_channel_count(stream->spl.spl_data.chan_conf) * al_get_audio_depth_size(stream->spl.spl_data.depth); stream_mutex = maybe_lock_mutex(stream->spl.mutex); bytes_written = stream->feeder(stream, fragment, bytes); maybe_unlock_mutex(stream_mutex); if (stream->spl.loop == _ALLEGRO_PLAYMODE_STREAM_ONEDIR) { /* Keep rewinding until the fragment is filled. */ while (bytes_written < bytes && stream->spl.loop == _ALLEGRO_PLAYMODE_STREAM_ONEDIR) { size_t bw; al_rewind_audio_stream(stream); stream_mutex = maybe_lock_mutex(stream->spl.mutex); bw = stream->feeder(stream, fragment + bytes_written, bytes - bytes_written); bytes_written += bw; maybe_unlock_mutex(stream_mutex); } } else if (bytes_written < bytes) { /* Fill the rest of the fragment with silence. */ int silence_samples = (bytes - bytes_written) / (al_get_channel_count(stream->spl.spl_data.chan_conf) * al_get_audio_depth_size(stream->spl.spl_data.depth)); al_fill_silence(fragment + bytes_written, silence_samples, stream->spl.spl_data.depth, stream->spl.spl_data.chan_conf); } if (!al_set_audio_stream_fragment(stream, fragment)) { ALLEGRO_ERROR("Error setting stream buffer.\n"); continue; } /* The streaming source doesn't feed any more, drain buffers and quit. */ if (bytes_written != bytes && stream->spl.loop == _ALLEGRO_PLAYMODE_STREAM_ONCE) { al_drain_audio_stream(stream); stream->quit_feed_thread = true; } } else if (event.type == _KCM_STREAM_FEEDER_QUIT_EVENT_TYPE) { stream->quit_feed_thread = true; } } event.user.type = ALLEGRO_EVENT_AUDIO_STREAM_FINISHED; event.user.timestamp = al_get_time(); al_emit_user_event(&stream->spl.es, &event, NULL); al_destroy_event_queue(queue); ALLEGRO_DEBUG("Stream feeder thread finished.\n"); return NULL; }