ALLEGRO_AUDIO_STREAM *_al_load_ogg_opus_audio_stream_f(ALLEGRO_FILE *file, size_t buffer_count, unsigned int samples) { const int word_size = 2; /* 1 = 8bit, 2 = 16-bit. nothing else */ OggOpusFile* of; int channels; long rate; long total_samples; long total_size; int bitstream; AL_OP_DATA* extra; ALLEGRO_AUDIO_STREAM* stream; if (!init_dynlib()) { return NULL; } extra = al_malloc(sizeof(AL_OP_DATA)); if (extra == NULL) { ALLEGRO_ERROR("Failed to allocate AL_OP_DATA struct.\n"); return NULL; } extra->file = file; of = lib.op_open_callbacks(extra, &callbacks, NULL, 0, NULL); if (!of) { ALLEGRO_WARN("ogg: Input does not appear to be an Ogg bitstream.\n"); return NULL; } extra->of = of; extra->bitstream = -1; bitstream = extra->bitstream; extra->channels = lib.op_channel_count(of, bitstream); channels = extra->channels; rate = 48000; total_samples = lib.op_pcm_total(of, bitstream); total_size = total_samples * channels * word_size; ALLEGRO_DEBUG("channels %d\n", channels); ALLEGRO_DEBUG("word_size %d\n", word_size); ALLEGRO_DEBUG("rate %ld\n", rate); ALLEGRO_DEBUG("total_samples %ld\n", total_samples); ALLEGRO_DEBUG("total_size %ld\n", total_size); stream = al_create_audio_stream(buffer_count, samples, rate, _al_word_size_to_depth_conf(word_size), _al_count_to_channel_conf(channels)); if (!stream) { lib.op_free(of); return NULL; } stream->extra = extra; extra->loop_start = 0.0; extra->loop_end = ogg_stream_get_length(stream); stream->quit_feed_thread = false; stream->feeder = ogg_stream_update; stream->rewind_feeder = ogg_stream_rewind; stream->seek_feeder = ogg_stream_seek; stream->get_feeder_position = ogg_stream_get_position; stream->get_feeder_length = ogg_stream_get_length; stream->set_feeder_loop = ogg_stream_set_loop; stream->unload_feeder = ogg_stream_close; _al_acodec_start_feed_thread(stream); return stream; }
ALLEGRO_AUDIO_STREAM *_al_load_ogg_vorbis_audio_stream_f(ALLEGRO_FILE *file, size_t buffer_count, unsigned int samples) { const int word_size = 2; /* 1 = 8bit, 2 = 16-bit. nothing else */ OggVorbis_File* vf; vorbis_info* vi; int channels; long rate; long total_samples; long total_size; AL_OV_DATA* extra; ALLEGRO_AUDIO_STREAM* stream; if (!init_dynlib()) { return NULL; } extra = al_malloc(sizeof(AL_OV_DATA)); if (extra == NULL) { ALLEGRO_ERROR("Failed to allocate AL_OV_DATA struct.\n"); return NULL; } extra->file = file; vf = al_malloc(sizeof(OggVorbis_File)); if (lib.ov_open_callbacks(extra, vf, NULL, 0, callbacks) < 0) { ALLEGRO_WARN("ogg: Input does not appear to be an Ogg bitstream.\n"); return NULL; } extra->vf = vf; vi = lib.ov_info(vf, -1); channels = vi->channels; rate = vi->rate; total_samples = lib.ov_pcm_total(vf, -1); total_size = total_samples * channels * word_size; extra->vi = vi; extra->bitstream = -1; ALLEGRO_DEBUG("channels %d\n", channels); ALLEGRO_DEBUG("word_size %d\n", word_size); ALLEGRO_DEBUG("rate %ld\n", rate); ALLEGRO_DEBUG("total_samples %ld\n", total_samples); ALLEGRO_DEBUG("total_size %ld\n", total_size); stream = al_create_audio_stream(buffer_count, samples, rate, _al_word_size_to_depth_conf(word_size), _al_count_to_channel_conf(channels)); if (!stream) { lib.ov_clear(vf); al_free(vf); return NULL; } stream->extra = extra; extra->loop_start = 0.0; extra->loop_end = ogg_stream_get_length(stream); stream->feed_thread = al_create_thread(_al_kcm_feed_stream, stream); stream->quit_feed_thread = false; stream->feeder = ogg_stream_update; stream->rewind_feeder = ogg_stream_rewind; stream->seek_feeder = ogg_stream_seek; stream->get_feeder_position = ogg_stream_get_position; stream->get_feeder_length = ogg_stream_get_length; stream->set_feeder_loop = ogg_stream_set_loop; stream->unload_feeder = ogg_stream_close; al_start_thread(stream->feed_thread); return stream; }
ALLEGRO_SAMPLE *_al_load_ogg_opus_f(ALLEGRO_FILE *file) { /* Note: decoding library can return 16-bit or floating-point output, * both using native endian ordering. (TODO: Implement float output, * individual links in the stream...) */ int word_size = 2; /* 2 = 16-bit. */ const int packet_size = 5760; /* suggestion for size to read at a time */ OggOpusFile *of; opus_int16 *buffer; ALLEGRO_SAMPLE *sample; int channels; long rate; ogg_int64_t total_samples; int bitstream; ogg_int64_t total_size; AL_OP_DATA op; ogg_int64_t pos; long read; if (!init_dynlib()) { return NULL; } op.file = file; of = lib.op_open_callbacks(&op, &callbacks, NULL, 0, NULL); if (!of) { ALLEGRO_WARN("Audio file does not appear to be an Ogg bitstream.\n"); return NULL; } bitstream = -1; channels = lib.op_channel_count(of, bitstream); rate = 48000; total_samples = lib.op_pcm_total(of, bitstream); total_size = total_samples * channels * word_size; ALLEGRO_DEBUG("channels %d\n", channels); ALLEGRO_DEBUG("word_size %d\n", word_size); ALLEGRO_DEBUG("rate %ld\n", rate); ALLEGRO_DEBUG("total_samples %ld\n", (long)total_samples); ALLEGRO_DEBUG("total_size %ld\n", (long)total_size); buffer = al_malloc(total_size); if (!buffer) { return NULL; } pos = 0; while (pos < total_samples) { const int read_size = _ALLEGRO_MIN(packet_size, total_samples - pos); ASSERT(pos + read_size <= total_samples); /* XXX error handling */ read = lib.op_read(of, buffer + pos * channels, read_size, NULL); pos += read; if (read == 0) break; } lib.op_free(of); sample = al_create_sample(buffer, total_samples, rate, _al_word_size_to_depth_conf(word_size), _al_count_to_channel_conf(channels), true); if (!sample) { al_free(buffer); } return sample; }
ALLEGRO_SAMPLE *_al_load_ogg_vorbis_f(ALLEGRO_FILE *file) { /* Note: decoding library returns floats. I always return 16-bit (most * commonly supported). */ #ifdef ALLEGRO_LITTLE_ENDIAN const int endian = 0; /* 0 for Little-Endian, 1 for Big-Endian */ #else const int endian = 1; /* 0 for Little-Endian, 1 for Big-Endian */ #endif int word_size = 2; /* 1 = 8bit, 2 = 16-bit. nothing else */ int signedness = 1; /* 0 for unsigned, 1 for signed */ const int packet_size = 4096; /* suggestion for size to read at a time */ OggVorbis_File vf; vorbis_info* vi; char *buffer; long pos; ALLEGRO_SAMPLE *sample; int channels; long rate; long total_samples; int bitstream; long total_size; AL_OV_DATA ov; long read; if (!init_dynlib()) { return NULL; } ov.file = file; if (lib.ov_open_callbacks(&ov, &vf, NULL, 0, callbacks) < 0) { ALLEGRO_WARN("Audio file does not appear to be an Ogg bitstream.\n"); return NULL; } vi = lib.ov_info(&vf, -1); channels = vi->channels; rate = vi->rate; total_samples = lib.ov_pcm_total(&vf, -1); bitstream = -1; total_size = total_samples * channels * word_size; ALLEGRO_DEBUG("channels %d\n", channels); ALLEGRO_DEBUG("word_size %d\n", word_size); ALLEGRO_DEBUG("rate %ld\n", rate); ALLEGRO_DEBUG("total_samples %ld\n", total_samples); ALLEGRO_DEBUG("total_size %ld\n", total_size); buffer = al_malloc(total_size); if (!buffer) { return NULL; } pos = 0; while (pos < total_size) { const int read_size = _ALLEGRO_MIN(packet_size, total_size - pos); ASSERT(pos + read_size <= total_size); /* XXX error handling */ #ifndef TREMOR read = lib.ov_read(&vf, buffer + pos, read_size, endian, word_size, signedness, &bitstream); #else (void)endian; (void)signedness; read = lib.ov_read(&vf, buffer + pos, read_size, &bitstream); #endif pos += read; if (read == 0) break; } lib.ov_clear(&vf); sample = al_create_sample(buffer, total_samples, rate, _al_word_size_to_depth_conf(word_size), _al_count_to_channel_conf(channels), true); if (!sample) { al_free(buffer); } return sample; }