#include "soundstream.h" #define STB_VORBIS_HEADER_ONLY #include #include #include #include static kinc_a1_sound_stream_t streams[256]; static int nextStream = 0; static uint8_t buffer[1024 * 10]; static int bufferIndex; kinc_a1_sound_stream_t *kinc_a1_sound_stream_create(const char *filename, bool looping) { kinc_a1_sound_stream_t *stream = &streams[nextStream]; stream->decoded = false; stream->myLooping = looping; stream->myVolume = 1; stream->rateDecodedHack = false; stream->end = false; kinc_file_reader_t file; kinc_file_reader_open(&file, filename, KINC_FILE_TYPE_ASSET); stream->buffer = &buffer[bufferIndex]; bufferIndex += (int)kinc_file_reader_size(&file); uint8_t *filecontent = (uint8_t *)malloc(kinc_file_reader_size(&file)); kinc_file_reader_read(&file, filecontent, kinc_file_reader_size(&file)); kinc_file_reader_close(&file); memcpy(stream->buffer, filecontent, kinc_file_reader_size(&file)); free(filecontent); stream->vorbis = stb_vorbis_open_memory(buffer, (int)kinc_file_reader_size(&file), NULL, NULL); if (stream->vorbis != NULL) { stb_vorbis_info info = stb_vorbis_get_info(stream->vorbis); stream->chans = info.channels; stream->rate = info.sample_rate; } else { stream->chans = 2; stream->rate = 22050; } ++nextStream; return stream; } int kinc_a1_sound_stream_channels(kinc_a1_sound_stream_t *stream) { return stream->chans; } int kinc_a1_sound_stream_sample_rate(kinc_a1_sound_stream_t *stream) { return stream->rate; } bool kinc_a1_sound_stream_looping(kinc_a1_sound_stream_t *stream) { return stream->myLooping; } void kinc_a1_sound_stream_set_looping(kinc_a1_sound_stream_t *stream, bool loop) { stream->myLooping = loop; } float kinc_a1_sound_stream_volume(kinc_a1_sound_stream_t *stream) { return stream->myVolume; } void kinc_a1_sound_stream_set_volume(kinc_a1_sound_stream_t *stream, float value) { stream->myVolume = value; } bool kinc_a1_sound_stream_ended(kinc_a1_sound_stream_t *stream) { return stream->end; } float kinc_a1_sound_stream_length(kinc_a1_sound_stream_t *stream) { if (stream->vorbis == NULL) return 0; return stb_vorbis_stream_length_in_seconds(stream->vorbis); } float kinc_a1_sound_stream_position(kinc_a1_sound_stream_t *stream) { if (stream->vorbis == NULL) return 0; return stb_vorbis_get_sample_offset(stream->vorbis) / stb_vorbis_stream_length_in_samples(stream->vorbis) * kinc_a1_sound_stream_length(stream); } void kinc_a1_sound_stream_reset(kinc_a1_sound_stream_t *stream) { if (stream->vorbis != NULL) stb_vorbis_seek_start(stream->vorbis); stream->end = false; stream->rateDecodedHack = false; stream->decoded = false; } float kinc_a1_sound_stream_next_sample(kinc_a1_sound_stream_t *stream) { if (stream->vorbis == NULL) return 0; if (stream->rate == 22050) { if (stream->rateDecodedHack) { if (stream->decoded) { stream->decoded = false; return stream->samples[0]; } else { stream->rateDecodedHack = false; stream->decoded = true; return stream->samples[1]; } } } if (stream->decoded) { stream->decoded = false; if (stream->chans == 1) { return stream->samples[0]; } else { return stream->samples[1]; } } else { int read = stb_vorbis_get_samples_float_interleaved(stream->vorbis, stream->chans, &stream->samples[0], stream->chans); if (read == 0) { if (kinc_a1_sound_stream_looping(stream)) { stb_vorbis_seek_start(stream->vorbis); stb_vorbis_get_samples_float_interleaved(stream->vorbis, stream->chans, &stream->samples[0], stream->chans); } else { stream->end = true; return 0.0f; } } stream->decoded = true; stream->rateDecodedHack = true; return stream->samples[0]; } }