1 #include <bz/audio/ogg.h>
3 #include <bz/memory/allocator.h>
4 #include <bz/resources/resource.h>
5 #include <bz/types/identifier_internal.h>
7 #include <stb_vorbis.c>
9 struct BZAudioOGGStream {
10 BZAudioOGGStreamDetails details;
13 // uint8_t *dataBlock;
19 BZAudioOGGStream *bzAudioOpenOGGStream(BZAudioOGGStreamDetails *detailsOut, BZMemoryArenaID arena, const char *identifierFmt, ...) {
20 bzMakeIdentifier(identifier, identifierFmt);
22 BZAudioOGGStream *stream = bzMemoryAlloc(arena, sizeof(BZAudioOGGStream));
24 stream->handle = bzResourcesOpenResource("music", "assets/music/%s.ogg", identifier);
26 size_t initialSize = 128;
27 int memoryConsumed, error;
29 bzResourcesSeek(stream->handle, 0);
31 void *initialData = bzMemoryAllocTmp(arena, initialSize);// FIXME, realloc
32 bzResourcesReadBytes(stream->handle, initialData, initialSize);
34 stream->vorbis = stb_vorbis_open_pushdata(initialData, initialSize, &memoryConsumed, &error, NULL); // FIXME, temp memory
35 if (stream->vorbis != NULL) {
38 bzAssert(error == VORBIS_need_more_data);
40 bzMemoryArenaResetTmp(arena);
43 bzResourcesSeek(stream->handle, memoryConsumed);
45 stb_vorbis_info info = stb_vorbis_get_info(stream->vorbis);
47 stream->details = (BZAudioOGGStreamDetails) {
48 .rate = info.sample_rate,
49 .channels = info.channels,
50 .maxSamples = info.max_frame_size,
53 if (detailsOut != NULL) {
54 *detailsOut = stream->details;
57 stream->dataBlockSize = info.temp_memory_required;
59 //*outputSizeOut = stream->dataBlockSize;
61 // stream->dataBlock = bzMemoryAlloc(arena, stream->dataBlockSize);
63 // stream->rate = info.sample_rate;
64 // stream->channels = info.channels;
66 //bzResourcesCloseResource(handle);
70 //size_t *samplesOut, uint32_t *rateOut, uint8_t *channelsOut,
72 void bzAudioResetOGGData(BZAudioOGGStream *stream) {
73 bzResourcesSeek(stream->handle, 0);
74 stb_vorbis_flush_pushdata(stream->vorbis);
77 size_t bzAudioQueryOGGData(BZAudioOGGStream *stream, size_t maxDataSize, float *data) {
81 void *dataBlock = alloca(stream->dataBlockSize); // FIXME
84 size_t offset = bzResourcesTell(stream->handle);
85 bzResourcesReadBytes(stream->handle, dataBlock, stream->dataBlockSize);
86 size_t bytesUsed = stb_vorbis_decode_frame_pushdata(stream->vorbis, dataBlock, stream->dataBlockSize, NULL, &output, &samples);
87 if (bytesUsed == 0 && samples == 0) {
90 //bzAssert(bytesUsed != 0 || samples != 0);
91 bzResourcesSeek(stream->handle, offset + bytesUsed);
97 for (size_t i = 0, out = 0; i < samples; ++i) {
98 for (size_t j = 0; j < stream->details.channels; ++j, ++out) {
99 data[out] = output[j][i];
103 return samples * stream->details.channels * sizeof(float);
106 void bzAudioCloseOGGStream(BZAudioOGGStream *stream) {
107 stb_vorbis_close(stream->vorbis);
108 bzResourcesCloseResource(stream->handle);