static bool ogg_stream_seek(ALLEGRO_AUDIO_STREAM *stream, double time) { AL_OV_DATA *extra = (AL_OV_DATA *) stream->extra; if (time >= extra->loop_end) return false; #if !defined(ALLEGRO_GP2XWIZ) && !defined(ALLEGRO_IPHONE) return (ov_time_seek_lap(extra->vf, time) != -1); #else return ov_time_seek(extra->vf, time*1000) != -1; #endif }
static void* player_thread(void* _minfo) { ogg_t* minfo = (ogg_t*) _minfo; log_debug("ogg player started"); long current_position_in_ms = 0; long previous_position_in_ms = -1; long guard_position_in_ms = -1; el_bool playing = el_false; post_event(minfo->client_notification, AUDIO_READY, current_position_in_ms); audio_event_t *event; event = audio_event_fifo_dequeue(minfo->player_control); while (event->state != INTERNAL_CMD_DESTROY) { audio_state_t event_state = event->state; long event_position = event->position_in_ms; audio_event_destroy(event); switch (event_state) { case INTERNAL_CMD_LOAD_FILE: { playing = el_false; if (minfo->is_open) { ov_clear(&minfo->vf); fclose(minfo->fh); aodev_close(minfo->ao_handle); } minfo->fh = fopen(minfo->file_or_url, "rb"); if (minfo->fh != NULL) { if (ov_open_callbacks(minfo->fh , &minfo->vf, NULL, 0, OV_CALLBACKS_NOCLOSE) < 0) { fclose(minfo->fh); post_event(minfo->client_notification, AUDIO_NOT_SUPPORTED, -1); minfo->is_open = el_false; } else { minfo->is_open = el_true; minfo->can_seek = ov_seekable(&minfo->vf); minfo->length = (long) (ov_time_total(&minfo->vf, -1) * 1000.0); psem_post(minfo->length_set); minfo->current_section = 0; vorbis_info* vi = ov_info(&minfo->vf, -1); aodev_set_format(minfo->ao_handle, 16, vi->rate, vi->channels); aodev_set_endian(minfo->ao_handle, AO_FMT_LITTLE); aodev_open(minfo->ao_handle); } } else { post_event(minfo->client_notification, AUDIO_IO_ERROR, -1); minfo->is_open = el_false; } current_position_in_ms = 0; guard_position_in_ms = -1; log_debug("Stream initialized"); } break; case INTERNAL_CMD_LOAD_URL: { } break; case INTERNAL_CMD_SEEK: { ov_time_seek_lap(&minfo->vf, ((double) event_position / 1000.0)); } break; case INTERNAL_CMD_PLAY: { playing = el_true; } break; case INTERNAL_CMD_PAUSE: { playing = el_false; } break; case INTERNAL_CMD_GUARD: { guard_position_in_ms = event_position; } break; case INTERNAL_CMD_SET_VOLUME: { double scale = ((double) event_position) / 1000.0; minfo->volume_scale = scale; log_debug2("setting volume to %lf", scale); } break; case INTERNAL_CMD_NONE: break; default: break; } if (guard_position_in_ms >= 0 && current_position_in_ms >= guard_position_in_ms) { guard_position_in_ms = -1; post_event(minfo->client_notification, AUDIO_GUARD_REACHED, current_position_in_ms); } else if (playing) { if (minfo->is_file) { int n = ov_read_filter(&minfo->vf, minfo->buffer, BUFFER_SIZE(minfo), 0, 2, 1, &minfo->current_section, adjust_volume, minfo ); if (n > 0) { aodev_play_buffer(minfo->ao_handle, minfo->buffer, n); //log_debug("buffer played"); double tm = ov_time_tell(&minfo->vf); current_position_in_ms = (long) (tm * 1000.0); if ((current_position_in_ms - previous_position_in_ms) >= STATE_REPORT_THRESHOLD) { post_event(minfo->client_notification, AUDIO_PLAYING, current_position_in_ms); } previous_position_in_ms = current_position_in_ms; } else { post_event(minfo->client_notification, AUDIO_EOS, current_position_in_ms); playing = el_false; } } else { // Stream playing post_event(minfo->client_notification, AUDIO_STATE_ERROR, -1); playing = el_false; } } if (playing) { if (audio_event_fifo_peek(minfo->player_control) != NULL) { event = audio_event_fifo_dequeue(minfo->player_control); } else { event = (audio_event_t*) mc_malloc(sizeof(audio_event_t)); event->state = INTERNAL_CMD_NONE; event->position_in_ms = -1; } } else { event = audio_event_fifo_dequeue(minfo->player_control); } } // destroy event received audio_event_destroy(event); // exit thread return NULL; }