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
);