void MusicPlayer::play(const char *filename) { #ifdef USE_OGG stb_vorbis_close(v); stb_vorbis_alloc t; t.alloc_buffer=this->buf; t.alloc_buffer_length_in_bytes=STB_BUFSIZE; // stb_vorbis has char* pointer even though it is not really writing to buffer v = stb_vorbis_open_filename((char *)filename, &error, &t); #endif #ifdef USE_MP3 mpg123_close(mh); error = mpg123_open(mh, filename); if (!error) { error = mpg123_getformat(mh, &rate, &channels, &encoding); rate = AUDIO_FREQUENCY; channels = 2; mpg123_format_none(mh); mpg123_format(mh, rate, channels, encoding); } #endif }
Sound::Sound(const std::string& fileName) : _channel_count(0), _sample_count(0), _sample_rate(0) { stb_vorbis* file = stb_vorbis_open_filename(const_cast<char*>(fileName.c_str()), 0, 0); if (file) { stb_vorbis_info info = stb_vorbis_get_info(file); _channel_count = info.channels; _sample_rate = info.sample_rate; int samples = stb_vorbis_stream_length_in_samples(file) * _channel_count; _sample_count = samples; _samples.resize(samples); stb_vorbis_get_samples_short_interleaved(file, _channel_count, &_samples.front(), samples); stb_vorbis_close(file); } else { throw std::runtime_error("Unable to open audio file"); } }
void play_file_from_filename(const std::string name) { currently_playing = std::string(name); if (audiobuf) linearFree(audiobuf); if (name.rfind(".flac") != std::string::npos) { if (!FLAC_decoder) { FLAC_decoder = FLAC__stream_decoder_new(); FLAC__stream_decoder_set_md5_checking(FLAC_decoder, true); } audiobuf_index = 0; decode_mode = AUDIO_MODE_FLAC; FLAC__StreamDecoderInitStatus init_status = FLAC__stream_decoder_init_file(FLAC_decoder, name.c_str(), FLAC_write_callback, FLAC_metadata_callback, FLAC_error_callback, NULL); if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK) { printf("ERROR: initializing decoder: %s\n", FLAC__StreamDecoderInitStatusString[init_status]); } FLAC__stream_decoder_process_until_end_of_metadata(FLAC_decoder); } else { decode_mode = AUDIO_MODE_VORBIS; v = stb_vorbis_open_filename(name.c_str(), &error, NULL); info = stb_vorbis_get_info(v); Samples = info.sample_rate; audiobuf_size = Samples * sizeof(s16) * 2; audiobuf = (s16*)linearAlloc(audiobuf_size); } paused = false; }
// Start music playing (open stream) void PlayMusicStream(char *fileName) { if (strcmp(GetExtension(fileName),"ogg") == 0) { // Stop current music, clean buffers, unload current stream StopMusicStream(); // Open audio stream currentMusic.stream = stb_vorbis_open_filename(fileName, NULL, NULL); if (currentMusic.stream == NULL) { TraceLog(WARNING, "[%s] OGG audio file could not be opened", fileName); } else { // Get file info stb_vorbis_info info = stb_vorbis_get_info(currentMusic.stream); currentMusic.channels = info.channels; currentMusic.sampleRate = info.sample_rate; TraceLog(INFO, "[%s] Ogg sample rate: %i", fileName, info.sample_rate); TraceLog(INFO, "[%s] Ogg channels: %i", fileName, info.channels); TraceLog(INFO, "[%s] Temp memory required: %i", fileName, info.temp_memory_required); if (info.channels == 2) currentMusic.format = AL_FORMAT_STEREO16; else currentMusic.format = AL_FORMAT_MONO16; currentMusic.loop = true; // We loop by default musicEnabled = true; // Create an audio source alGenSources(1, ¤tMusic.source); // Generate pointer to audio source alSourcef(currentMusic.source, AL_PITCH, 1); alSourcef(currentMusic.source, AL_GAIN, 1); alSource3f(currentMusic.source, AL_POSITION, 0, 0, 0); alSource3f(currentMusic.source, AL_VELOCITY, 0, 0, 0); //alSourcei(currentMusic.source, AL_LOOPING, AL_TRUE); // ERROR: Buffers do not queue! // Generate two OpenAL buffers alGenBuffers(2, currentMusic.buffers); // Fill buffers with music... BufferMusicStream(currentMusic.buffers[0]); BufferMusicStream(currentMusic.buffers[1]); // Queue buffers and start playing alSourceQueueBuffers(currentMusic.source, 2, currentMusic.buffers); alSourcePlay(currentMusic.source); // NOTE: Regularly, we must check if a buffer has been processed and refill it: MusicStreamUpdate() currentMusic.totalSamplesLeft = stb_vorbis_stream_length_in_samples(currentMusic.stream) * currentMusic.channels; } } else TraceLog(WARNING, "[%s] Music extension not recognized, it can't be loaded", fileName); }
void LoadTestChannel(ShadertoyTestResource *channel_data, ShadertoyState *state, ShadertoyInputs *inputs, ShadertoyOutputs *outputs, ShadertoyPass pass, int channel_id) { ImageFile *image = &image_files[channel_id][pass]; memset(image->filepath, 0, sizeof(image->filepath)); switch (channel_data->type) { case SHADERTOY_RESOURCE_TEXTURE: { GetFilePath(image->filepath, channel_data->filename[0]); LoadTexture(state, image->filepath, pass, channel_id); break; } case SHADERTOY_RESOURCE_CUBE_MAP: { char *cubemap_paths[6]; for (int j = 0; j < 6; ++j) { cubemap_paths[j] = new char[1024]; GetFilePath(cubemap_paths[j], channel_data->filename[j]); if (j == 0) { strcpy(image->filepath, cubemap_paths[j]); } } LoadTexture(state, cubemap_paths, pass, channel_id); for (int j = 0; j < 6; ++j) { delete[] cubemap_paths[j]; } break; } case SHADERTOY_RESOURCE_MUSIC: { AudioFile *file = &audio_files[channel_id]; memset(file->filepath, 0, sizeof(file->filepath)); GetFilePath(file->filepath, channel_data->filename[0]); int ogg_error; stb_vorbis *ogg_data = stb_vorbis_open_filename(file->filepath, &ogg_error, NULL); file->channels = ogg_data->channels; file->samples_count = stb_vorbis_stream_length_in_samples(ogg_data) * ogg_data->channels; file->samples = (float*)malloc(sizeof(float) * file->samples_count); stb_vorbis_get_samples_float_interleaved(ogg_data, ogg_data->channels, file->samples, file->samples_count); audio_data[channel_id] = { &inputs->audio_played_samples[channel_id], &file->samples, (int)ogg_data->sample_rate, ogg_data->channels, file->samples_count / ogg_data->channels }; ShadertoyLoadAudio(state, audio_data + channel_id, SHADERTOY_IMAGE_PASS, channel_id); outputs->music_data_param[channel_id] = init_audio_output(ogg_data->channels, ogg_data->sample_rate, 32, file->samples_count * sizeof(float)); stb_vorbis_close(ogg_data); break; } case SHADERTOY_RESOURCE_MICROPHONE: { // 512 * sizeof(float) == FFT sampling data, so should be fine to use inputs->micro_data_param = init_audio_input(2, 44100, 32, 2048 * sizeof(float)); break; } case SHADERTOY_RESOURCE_KEYBOARD: case SHADERTOY_RESOURCE_NONE: break; } }
void sound_load(Sound *sound, const char *path) { int error = 0; stb_vorbis *stream; memset(sound, 0, sizeof(Sound)); stream = stb_vorbis_open_filename(path, &error, 0); ASSERT(!error && stream); punp_sound_load_stbv(sound, stream); }
void test_get_frame_short_interleaved(FILE *g, char *filename) { short sbuffer[8000]; int n, error; stb_vorbis *v = stb_vorbis_open_filename(filename, &error, NULL); if (!v) stb_fatal("Couldn't open {%s}", filename); show_info(v); while (0 != (n=stb_vorbis_get_frame_short_interleaved(v, 2, sbuffer, 8000))) { fwrite(sbuffer, 2, n*2, g); } stb_vorbis_close(v); }
bool cSoundFileOgg::IsFileSupported( const std::string& Filename, bool Read ) { if ( Read ) { // Open the vorbis stream stb_vorbis* Stream = stb_vorbis_open_filename( const_cast<char*>( Filename.c_str() ), NULL, NULL ); if ( NULL != Stream ) { stb_vorbis_close( Stream ); return true; } else return false; } else // No support for writing ogg files yet... return false; }
// Load OGG file into Wave structure // NOTE: Using stb_vorbis library static Wave LoadOGG(char *fileName) { Wave wave; stb_vorbis *oggFile = stb_vorbis_open_filename(fileName, NULL, NULL); if (oggFile == NULL) { TraceLog(WARNING, "[%s] OGG file could not be opened", fileName); wave.data = NULL; } else { stb_vorbis_info info = stb_vorbis_get_info(oggFile); wave.sampleRate = info.sample_rate; wave.bitsPerSample = 16; wave.channels = info.channels; TraceLog(DEBUG, "[%s] Ogg sample rate: %i", fileName, info.sample_rate); TraceLog(DEBUG, "[%s] Ogg channels: %i", fileName, info.channels); int totalSamplesLength = (stb_vorbis_stream_length_in_samples(oggFile) * info.channels); wave.dataSize = totalSamplesLength*sizeof(short); // Size must be in bytes TraceLog(DEBUG, "[%s] Samples length: %i", fileName, totalSamplesLength); float totalSeconds = stb_vorbis_stream_length_in_seconds(oggFile); TraceLog(DEBUG, "[%s] Total seconds: %f", fileName, totalSeconds); if (totalSeconds > 10) TraceLog(WARNING, "[%s] Ogg audio lenght is larger than 10 seconds (%f), that's a big file in memory, consider music streaming", fileName, totalSeconds); int totalSamples = totalSeconds*info.sample_rate*info.channels; TraceLog(DEBUG, "[%s] Total samples calculated: %i", fileName, totalSamples); wave.data = malloc(sizeof(short)*totalSamplesLength); int samplesObtained = stb_vorbis_get_samples_short_interleaved(oggFile, info.channels, wave.data, totalSamplesLength); TraceLog(DEBUG, "[%s] Samples obtained: %i", fileName, samplesObtained); TraceLog(INFO, "[%s] OGG file loaded successfully (SampleRate: %i, BitRate: %i, Channels: %i)", fileName, wave.sampleRate, wave.bitsPerSample, wave.channels); stb_vorbis_close(oggFile); } return wave; }
AudioStream::AudioStream(const String & filename, AudioSource * source) { buffers[0] = buffers[1] = 0; AudioStream::source = source; stream = stb_vorbis_open_filename(filename.ToCString(), nullptr, nullptr); if (!stream) return; info = stb_vorbis_get_info(stream); samplesLeft = stb_vorbis_stream_length_in_samples(stream) * info.channels; alGenBuffers(2, buffers); Stream(buffers[0]); Stream(buffers[1]); alSourceQueueBuffers(AudioStream::source->GetID(), 2, buffers); streams.Add(this); }
void test_get_samples_short_interleaved(FILE *g, char *filename) { int error; stb_vorbis *v = stb_vorbis_open_filename(filename, &error, NULL); if (!v) stb_fatal("Couldn't open {%s}", filename); show_info(v); for(;;) { int16 sbuffer[333]; int n; n = stb_vorbis_get_samples_short_interleaved(v, 2, sbuffer, 333); if (n == 0) break; fwrite(sbuffer, 2, n*2, g); } stb_vorbis_close(v); }
bool AEAudioStreamOpen(AEAudioStream* self, const char* filename){ self->stream = stb_vorbis_open_filename((char*)filename, NULL, NULL); if(not self->stream) return false; // Get file info self->info = stb_vorbis_get_info(self->stream); if(self->info.channels == 2) self->format = AL_FORMAT_STEREO16; else self->format = AL_FORMAT_MONO16; if(not AEAudioStreamStream(self, self->buffers[0])) return false; if(not AEAudioStreamStream(self, self->buffers[1])) return false; alSourceQueueBuffers(self->source, 2, self->buffers); alSourcePlay(self->source); self->totalSamplesLeft=stb_vorbis_stream_length_in_samples(self->stream) * self->info.channels; return true; }
bool cSoundFileOgg::OpenRead( const std::string& Filename, std::size_t& SamplesCount, unsigned int& ChannelCount, unsigned int& SampleRate ) { // Close the file if already opened if ( NULL != mStream ) stb_vorbis_close( mStream ); // Open the vorbis stream mStream = stb_vorbis_open_filename( const_cast<char*>( Filename.c_str() ), NULL, NULL ); if ( NULL == mStream ) { eePRINTL( "Failed to read sound file %s (cannot open the file)", Filename.c_str() ); return false; } // Get the music parameters stb_vorbis_info Infos = stb_vorbis_get_info( mStream ); ChannelCount = mChannelCount = Infos.channels; SampleRate = Infos.sample_rate; SamplesCount = static_cast<std::size_t>( stb_vorbis_stream_length_in_samples( mStream ) * ChannelCount ); return true; }
void test_get_frame_float(FILE *g, char *filename) { int error; stb_vorbis *v = stb_vorbis_open_filename(filename, &error, NULL); if (!v) stb_fatal("Couldn't open {%s}", filename); show_info(v); for(;;) { int n; float *left, *right; float **outputs; int num_c; n = stb_vorbis_get_frame_float(v, &num_c, &outputs); if (n == 0) break; left = outputs[0]; right = outputs[num_c > 1]; write_floats(g, n, left, right); } stb_vorbis_close(v); }
void MusicOGG::play(bool loop) { if (m_isPlaying) return; m_loop = loop; for (auto pBuffer : m_buffers) delete pBuffer; m_buffers.clear(); m_bufferCount = 0; m_pStream = stb_vorbis_open_filename((char*)m_filename.c_str(), NULL, NULL); if (!m_pStream) return; m_info = stb_vorbis_get_info(m_pStream); m_sampleCount = stb_vorbis_stream_length_in_samples(m_pStream); m_isPlaying = true; m_paused = false; m_samplingT = 0.0f; // We will buffer 5 seconds m_engineChannelCount = m_pStream->channels; m_bufferMax = oAudioEngine->getSampleRate() * m_engineChannelCount; for (int i = 0; i < MUSIC_BUFFER_COUNT; ++i) { auto pBuffer = new Buffer(); pBuffer->data.assign(m_bufferMax, 0.0f); m_buffers.push_back(pBuffer); } m_bufferCount = 0; if (m_thread.joinable()) m_thread.join(); m_thread = std::thread(std::bind(&MusicOGG::run, this)); m_musicSampleRate = (int)m_pStream->sample_rate; m_musicChannelCount = (int)m_pStream->channels; m_pSamplings = new float[4 * m_pStream->channels]; memset(m_pSamplings, 0, sizeof(float) * 4 * m_pStream->channels); oAudioEngine->addInstance(OThis); }
ALuint AEAudioContextBufferLoad(AEAudioContext* self, const char* filename){ ALuint buffer=0; alGenBuffers(1, &buffer); stb_vorbis *stream = stb_vorbis_open_filename((char*)filename, NULL, NULL); if(not stream) return 0; stb_vorbis_info info = stb_vorbis_get_info(stream); ALenum format; if(info.channels == 2) format = AL_FORMAT_STEREO16; else format = AL_FORMAT_MONO16; size_t sampleCount = stb_vorbis_stream_length_in_samples(stream) * info.channels; void* data = malloc(sizeof(ALushort)*sampleCount); stb_vorbis_get_samples_short_interleaved(stream, info.channels, data, (int)sampleCount); stb_vorbis_close(stream); alBufferData(buffer, format, data, sampleCount * sizeof(ALushort), info.sample_rate); free(data); return buffer; }
//***** Streaming int snd_LoadStreaming( const char* fileName, bool loops, unsigned int group ) { assert( group >= 0 ); assert( group < sb_Count( sbSoundGroups ) ); int newIdx = -1; for( int i = 0; i < MAX_STREAMING_SOUNDS; ++i ) { if( streamingSounds[i].access == NULL ) { newIdx = i; break; } } if( newIdx < 0 ) { llog( LOG_ERROR, "Unable to find empty slot for streaming sound %s", fileName ); return -1; } int error; streamingSounds[newIdx].access = stb_vorbis_open_filename( fileName, &error, NULL ); if( streamingSounds[newIdx].access == NULL ) { llog( LOG_ERROR, "Unable to acquire a handle to streaming sound %s", fileName ); return -1; } streamingSounds[newIdx].playing = false; streamingSounds[newIdx].loops = loops; streamingSounds[newIdx].group = group; streamingSounds[newIdx].channels = (Uint8)( streamingSounds[newIdx].access->channels ); if( streamingSounds[newIdx].channels > 2 ) { streamingSounds[newIdx].channels = 2; } return newIdx; }
OGGStream(String file, bool _loop) { loop = _loop; finished = true; valid = false; std::string name = ToStdString(file); //cout << "Load OGG " << name << endl; //OGG file int error = 0; ogg = stb_vorbis_open_filename(&name[0], &error, NULL); if (!ogg) {cout << " VORBIS FAIL" << endl; return;} info = stb_vorbis_get_info(ogg); //Info output.channels = info.channels; output.rate = info.sample_rate; //Woot! valid = true; finished = false; }
int main(int argc, char **argv) { int num_chan, samprate; int i, j, test, phase; short *output; if (argc == 1) { fprintf(stderr, "Usage: vorbseek {vorbisfile} [{vorbisfile]*]\n"); fprintf(stderr, "Tests various seek offsets to make sure they're sample exact.\n"); return 0; } #if 0 { // check that outofmem occurs correctly stb_vorbis_alloc va; va.alloc_buffer = malloc(1024*1024); for (i=0; i < 1024*1024; i += 10) { int error=0; stb_vorbis *v; va.alloc_buffer_length_in_bytes = i; v = stb_vorbis_open_filename(argv[1], &error, &va); if (v != NULL) break; printf("Error %d at %d\n", error, i); } } #endif for (j=1; j < argc; ++j) { unsigned int successes=0, attempts = 0; unsigned int num_samples = stb_vorbis_decode_filename(argv[j], &num_chan, &samprate, &output); break; if (num_samples == 0xffffffff) { fprintf(stderr, "Error: couldn't open file or not vorbis file: %s\n", argv[j]); goto fail; } if (num_chan != 2) { fprintf(stderr, "vorbseek testing only works with files with 2 channels, %s has %d\n", argv[j], num_chan); goto fail; } for (test=0; test < 5; ++test) { int error; stb_vorbis *v = stb_vorbis_open_filename(argv[j], &error, NULL); if (v == NULL) { fprintf(stderr, "Couldn't re-open %s for test #%d\n", argv[j], test); goto fail; } for (phase=0; phase < 3; ++phase) { unsigned int base = phase == 0 ? 0 : phase == 1 ? num_samples - test_count[test]*test_spacing[test] : num_samples/3; for (i=0; i < test_count[test]; ++i) { unsigned int pos = base + i*test_spacing[test]; if (pos > num_samples) // this also catches underflows continue; successes += try_seeking(v, pos, output, num_samples); attempts += 1; } } stb_vorbis_close(v); } printf("%d of %d seeks failed in %s (%d samples)\n", attempts-successes, attempts, argv[j], num_samples); free(output); } return 0; fail: return 1; }
AudioBuffer::AudioBuffer(const String & filename):alBuffer(0) { if (filename.ExtractExt() == "wav") { alGenBuffers(1, &alBuffer); File file(filename, FILE_READ); file.Seek(16); uint32 fmtChunkSize; file.ReadBytes(&fmtChunkSize, 4); uint16 audioFormat; file.ReadBytes(&audioFormat, 2); uint16 channels; file.ReadBytes(&channels, 2); file.Seek(24); uint32 sampleRate; file.ReadBytes(&sampleRate, 4); file.Seek(34); uint16 bitsPerSample; file.ReadBytes(&bitsPerSample, 2); uint16 extraParamSize; if (fmtChunkSize != 16) { file.ReadBytes(&extraParamSize, 2); file.Seek(38 + extraParamSize); } char texto[5]; texto[4] = '\0'; while (String(texto) != "data") { file.ReadBytes(texto, 4); } uint32 dataSize; uint32* data; file.ReadBytes(&dataSize, 4); data = (uint32*)malloc(dataSize); file.ReadBytes(data, dataSize); ALenum format; if (bitsPerSample == 8) { if (channels == 1) { format = AL_FORMAT_MONO8; } else { format = AL_FORMAT_STEREO8; } } if (bitsPerSample == 16) { if (channels == 1) { format = AL_FORMAT_MONO16; } else { format = AL_FORMAT_STEREO16; } } alBufferData(alBuffer, format, data, dataSize, sampleRate); free(data); } else if (filename.ExtractExt() == "ogg") { stb_vorbis* stb_vorbis; stb_vorbis = stb_vorbis_open_filename(filename.ToCString(), nullptr, nullptr); if (stb_vorbis == nullptr) return; stb_vorbis_info info = stb_vorbis_get_info(stb_vorbis); uint32 dataSize = stb_vorbis_stream_length_in_samples(stb_vorbis) * info.channels; int16* buffer = (int16*)malloc(dataSize * sizeof(uint16)); stb_vorbis_get_samples_short_interleaved(stb_vorbis, info.channels,(short *) buffer, dataSize); alGenBuffers(1, &alBuffer); ALenum format; if (info.channels == 1) { format = AL_FORMAT_MONO16; } else { format = AL_FORMAT_STEREO16; } alBufferData(alBuffer, format, buffer, dataSize * sizeof(int16), info.sample_rate); free(buffer); stb_vorbis_close(stb_vorbis); } }
//---------------------------------------------------------------------------- int main(int argc, char **argv) { //---------------------------------------------------------------------------- PrintConsole topScreen; ndspWaveBuf waveBuf[2]; gfxInitDefault(); consoleInit(GFX_TOP, &topScreen); consoleSelect(&topScreen); printf("libctru streaming audio\n"); stb_vorbis_info info; int error; vorbisFile = stb_vorbis_open_filename("/mau5.ogg", &error, NULL); info = stb_vorbis_get_info(vorbisFile); Samples = info.sample_rate; u32 *audioBuffer = (u32*)linearAlloc(Samples*sizeof(s16)*2); bool fillBlock = false; ndspInit(); ndspSetOutputMode(NDSP_OUTPUT_STEREO); ndspChnSetInterp(0, NDSP_INTERP_LINEAR); ndspChnSetRate(0, Samples); ndspChnSetFormat(0, NDSP_FORMAT_STEREO_PCM16); float mix[12]; memset(mix, 0, sizeof(mix)); mix[0] = 1.0; mix[1] = 1.0; ndspChnSetMix(0, mix); int note = 4; memset(waveBuf,0,sizeof(waveBuf)); waveBuf[0].data_vaddr = &audioBuffer[0]; waveBuf[0].nsamples = Samples; waveBuf[1].data_vaddr = &audioBuffer[Samples]; waveBuf[1].nsamples = Samples; ndspChnWaveBufAdd(0, &waveBuf[0]); ndspChnWaveBufAdd(0, &waveBuf[1]); printf("Press up/down to change tone\n"); while(aptMainLoop()) { gfxSwapBuffers(); gfxFlushBuffers(); gspWaitForVBlank(); hidScanInput(); u32 kDown = hidKeysDown(); if (kDown & KEY_START) break; // break in order to return to hbmenu if (waveBuf[fillBlock].status == NDSP_WBUF_DONE) { fill_buffer(waveBuf[fillBlock].data_pcm16, waveBuf[fillBlock].nsamples); ndspChnWaveBufAdd(0, &waveBuf[fillBlock]); fillBlock = !fillBlock; } } ndspExit(); linearFree(audioBuffer); gfxExit(); return 0; }
AudioBuffer::AudioBuffer(const String &filename) { if (filename.ExtractExt() == "wav") { m_alBuffer = 0; File * file = new File(filename, FILE_READ); int32 chunkId = file->ReadInt(); int32 riffChunkSize = file->ReadInt(); int32 format = file->ReadInt(); int32 subChunkId = file->ReadInt(); int32 fmtChunkSize = file->ReadInt(); int16 audioFormat = file->ReadInt16(); int16 channels = file->ReadInt16(); int32 sampleRate = file->ReadInt(); int32 byteRate = file->ReadInt(); int16 blockAlign = file->ReadInt16(); int16 bitsPerSample = file->ReadInt16(); if (fmtChunkSize > 16) { int16 extraParamsSize = file->ReadInt16(); file->Seek(file->Pos() + extraParamsSize); } char text[5] = ""; file->ReadBytes(text, 4); while (String(text) != "data" && !file->Eof()) { file->ReadBytes(text, 4); if (String(text) == "data") break; file->Seek(file->Pos() + 4); } int32 dataSize = file->ReadInt(); uint32 * data = (uint32 *)malloc(dataSize); file->ReadBytes(data, dataSize); ALenum bufferFormat; if (bitsPerSample == 8) { if (channels == 1) bufferFormat = AL_FORMAT_MONO8; else bufferFormat = AL_FORMAT_STEREO8; } else { if (channels == 1) bufferFormat = AL_FORMAT_MONO16; else bufferFormat = AL_FORMAT_STEREO16; } alGenBuffers(1, &m_alBuffer); alBufferData(m_alBuffer, bufferFormat, data, dataSize, sampleRate); delete file; free(data); } else if (filename.ExtractExt() == "ogg") { stb_vorbis * file = stb_vorbis_open_filename(filename.ToCString(), nullptr, nullptr); if (file) { stb_vorbis_info info = stb_vorbis_get_info(file); uint32 size = stb_vorbis_stream_length_in_samples(file) * info.channels; int16 * buffer = (int16 *)malloc(size * sizeof(int16)); stb_vorbis_get_samples_short_interleaved(file, info.channels, buffer, size); alGenBuffers(1, &m_alBuffer); ALenum bufferFormat; if (info.channels == 1) bufferFormat = AL_FORMAT_MONO16; else bufferFormat = AL_FORMAT_STEREO16; alBufferData(m_alBuffer, bufferFormat, buffer, size, info.sample_rate); stb_vorbis_close(file); free(buffer); } } }