bool AEAudioStreamUpdate(AEAudioStream* self){ ALint processed=0; alGetSourcei(self->source, AL_BUFFERS_PROCESSED, &processed); while(processed--){ ALuint buffer=0; alSourceUnqueueBuffers(self->source, 1, &buffer); if(not AEAudioStreamStream(self, buffer)){ bool shouldExit=true; if(self->shouldLoop){ stb_vorbis_seek_start(self->stream); self->totalSamplesLeft=stb_vorbis_stream_length_in_samples(self->stream) * self->info.channels; shouldExit=not AEAudioStreamStream(self, buffer); } if(shouldExit) return false; } alSourceQueueBuffers(self->source, 1, &buffer); } return true; }
static void punp_sound_load_stbv(Sound *sound, stb_vorbis *stream) { stb_vorbis_info info = stb_vorbis_get_info(stream); sound->volume = PUNP_SOUND_DEFAULT_SOUND_VOLUME; sound->rate = info.sample_rate; sound->samples_count = stb_vorbis_stream_length_in_samples(stream); sound->samples = (i16 *)bank_push(CORE->storage, PUNP_SOUND_SAMPLES_TO_BYTES(sound->samples_count)); { static i16 buffer[1024]; i16 *it = sound->samples; int samples_read_per_channel; for (; ;) { int samples_read_per_channel = stb_vorbis_get_samples_short_interleaved(stream, PUNP_SOUND_CHANNELS, buffer, 1024); if (samples_read_per_channel == 0) { break; } // 2 channels, 16 bits per sample. memcpy(it, buffer, PUNP_SOUND_SAMPLES_TO_BYTES(samples_read_per_channel)); it += samples_read_per_channel * PUNP_SOUND_CHANNELS; } } stb_vorbis_close(stream); }
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"); } }
// 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; } }
// Get current music time played (in seconds) float GetMusicTimePlayed() { int totalSamples = stb_vorbis_stream_length_in_samples(currentMusic.stream) * currentMusic.channels; int samplesPlayed = totalSamples - currentMusic.totalSamplesLeft; float secondsPlayed = (float)samplesPlayed / (currentMusic.sampleRate * currentMusic.channels); return secondsPlayed; }
// 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; }
result Wav::loadogg(File *aReader) { aReader->seek(0); MemoryFile memoryFile; memoryFile.openFileToMem(aReader); int e = 0; stb_vorbis *vorbis = 0; vorbis = stb_vorbis_open_memory(memoryFile.getMemPtr(), memoryFile.length(), &e, 0); if (0 == vorbis) { return FILE_LOAD_FAILED; } stb_vorbis_info info = stb_vorbis_get_info(vorbis); mBaseSamplerate = (float)info.sample_rate; int samples = stb_vorbis_stream_length_in_samples(vorbis); int readchannels = 1; if (info.channels > 1) { readchannels = 2; mChannels = 2; } mData = new float[samples * readchannels]; mSampleCount = samples; samples = 0; while(1) { float **outputs; int n = stb_vorbis_get_frame_float(vorbis, NULL, &outputs); if (n == 0) { break; } if (readchannels == 1) { memcpy(mData + samples, outputs[0],sizeof(float) * n); } else { memcpy(mData + samples, outputs[0],sizeof(float) * n); memcpy(mData + samples + mSampleCount, outputs[1],sizeof(float) * n); } samples += n; } stb_vorbis_close(vorbis); return 0; }
nVorbisStream::nVorbisStream(QIODevice * dev, QObject *parent) : nSoundStream(parent), _device(dev), m_error(false), _totalFrames(0), _channels(0), _frequency(0), _format(SF_16BIT_STEREO) { if(!dev->isOpen()) dev->open(QIODevice::ReadOnly); _qtBuf = dev->readAll(); dev->close(); if(_qtBuf.size()) { _bufSize = _qtBuf.size(); _buf = _qtBuf.data(); int err = VORBIS__no_error; _vorbis = stb_vorbis_open_memory((unsigned char*)_buf, _bufSize, &err, 0 ); if(!_vorbis || err != VORBIS__no_error) { qDebug(QStringLiteral("[nVorbisStream] Error initializing vorbis stream: %1").arg(err).toLocal8Bit()); } stb_vorbis_info info = stb_vorbis_get_info(_vorbis); _totalFrames = stb_vorbis_stream_length_in_samples(_vorbis); _channels = _vorbis->channels; _frequency = _vorbis->sample_rate; switch (channels()) { case 1: _format = SF_16BIT_MONO; break; case 2: _format = SF_16BIT_STEREO; break; default: _format = SF_UNDEFINED; break; } } else { qDebug("[nVorbisStream] Error reading QIODevice"); } }
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); }
// Update (re-fill) music buffers if data already processed extern void UpdateMusicStream() { ALuint buffer = 0; ALint processed = 0; bool active = true; if (musicEnabled) { // Get the number of already processed buffers (if any) alGetSourcei(currentMusic.source, AL_BUFFERS_PROCESSED, &processed); while (processed > 0) { // Recover processed buffer for refill alSourceUnqueueBuffers(currentMusic.source, 1, &buffer); // Refill buffer active = BufferMusicStream(buffer); // If no more data to stream, restart music (if loop) if ((!active) && (currentMusic.loop)) { if (currentMusic.loop) { stb_vorbis_seek_start(currentMusic.stream); currentMusic.totalSamplesLeft = stb_vorbis_stream_length_in_samples(currentMusic.stream) * currentMusic.channels; active = BufferMusicStream(buffer); } } // Add refilled buffer to queue again... don't let the music stop! alSourceQueueBuffers(currentMusic.source, 1, &buffer); if(alGetError() != AL_NO_ERROR) TraceLog(WARNING, "Ogg playing, error buffering data..."); processed--; } ALenum state; alGetSourcei(currentMusic.source, AL_SOURCE_STATE, &state); if ((state != AL_PLAYING) && active) alSourcePlay(currentMusic.source); if (!active) StopMusicStream(); } }
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; }
void AudioStream::Update() { //Hacer con variable auxiliar ALint buffersProcessed; alGetSourcei(source->GetID(), AL_BUFFERS_PROCESSED, &buffersProcessed); while (buffersProcessed--) { uint32 buffer; alSourceUnqueueBuffers(source->GetID(), 1, &buffer); if (Stream(buffer)) { alSourceQueueBuffers(source->GetID(), 1, &buffer); } else if (shouldLoop) { stb_vorbis_seek_start(stream); samplesLeft = stb_vorbis_stream_length_in_samples(stream) * info.channels; if (Stream(buffer)) alSourceQueueBuffers(source->GetID(), 1, &buffer); } } }
result Wav::loadogg(MemoryFile *aReader) { int e = 0; stb_vorbis *vorbis = 0; vorbis = stb_vorbis_open_memory(aReader->getMemPtr(), aReader->length(), &e, 0); if (0 == vorbis) { return FILE_LOAD_FAILED; } stb_vorbis_info info = stb_vorbis_get_info(vorbis); mBaseSamplerate = (float)info.sample_rate; int samples = stb_vorbis_stream_length_in_samples(vorbis); if (info.channels > MAX_CHANNELS) { mChannels = MAX_CHANNELS; } else { mChannels = info.channels; } mData = new float[samples * mChannels]; mSampleCount = samples; samples = 0; while(1) { float **outputs; int n = stb_vorbis_get_frame_float(vorbis, NULL, &outputs); if (n == 0) { break; } unsigned int ch; for (ch = 0; ch < mChannels; ch++) memcpy(mData + samples + mSampleCount * ch, outputs[ch], sizeof(float) * n); samples += n; } stb_vorbis_close(vorbis); return 0; }
void WavStream::loadogg(FILE * fp) { fseek(fp,0,SEEK_SET); int e; stb_vorbis *v = stb_vorbis_open_file(fp, 0, &e, NULL); if (!v) return; stb_vorbis_info info = stb_vorbis_get_info(v); if (info.channels > 1) { mChannels = 2; } mBaseSamplerate = (float)info.sample_rate; int samples = stb_vorbis_stream_length_in_samples(v); stb_vorbis_close(v); mOgg = 1; mSampleCount = samples; }
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 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; }
result WavStream::loadogg(File * fp) { fp->seek(0); int e; stb_vorbis *v; v = stb_vorbis_open_file((Soloud_Filehack *)fp, 0, &e, 0); if (v == NULL) return FILE_LOAD_FAILED; stb_vorbis_info info = stb_vorbis_get_info(v); if (info.channels > 1) { mChannels = 2; } mBaseSamplerate = (float)info.sample_rate; int samples = stb_vorbis_stream_length_in_samples(v); stb_vorbis_close(v); mOgg = 1; mSampleCount = samples; return 0; }
int Wav::loadogg(stb_vorbis *aVorbis) { stb_vorbis_info info = stb_vorbis_get_info(aVorbis); mBaseSamplerate = (float)info.sample_rate; int samples = stb_vorbis_stream_length_in_samples(aVorbis); int readchannels = 1; if (info.channels > 1) { readchannels = 2; mChannels = 2; } mData = new float[samples * readchannels]; mSampleCount = samples; samples = 0; while(1) { float **outputs; int n = stb_vorbis_get_frame_float(aVorbis, NULL, &outputs); if (n == 0) { break; } if (readchannels == 1) { memcpy(mData + samples, outputs[0],sizeof(float) * n); } else { memcpy(mData + samples, outputs[0],sizeof(float) * n); memcpy(mData + samples + mSampleCount, outputs[1],sizeof(float) * n); } samples += n; } stb_vorbis_close(aVorbis); return 0; }
bool cSoundFileOgg::OpenRead( const char* Data, std::size_t SizeInBytes, 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 unsigned char* Buffer = reinterpret_cast<unsigned char*>( const_cast<char*>( Data ) ); int Length = static_cast<int>( SizeInBytes ); mStream = stb_vorbis_open_memory( Buffer, Length, NULL, NULL ); if ( NULL == mStream ) { eePRINTL( "Failed to read sound file from memory (cannot open the file)" ); 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; }
SGAudioBuffer* SG_CALL sgAudioBufferCreateStream(SGStream* stream, SGbool delstream) { if(!stream || !stream->read || !stream->seek || !stream->tell) return NULL; SGAudioBuffer* buffer = malloc(sizeof(SGAudioBuffer)); if(!buffer) goto error; buffer->stream = stream; buffer->del = delstream; buffer->handle = malloc(sizeof(ALuint)); if(!buffer->handle) goto error; alGenBuffers(1, buffer->handle); SGuint channels; SGuint format; SGuint frequency; void* data = NULL; SGuint datalen; SGuint nsamples; void* buf = NULL; int error = 0; stb_vorbis* stb = NULL; stb_vorbis_info info; SGlong pos = sgStreamTell(stream); SGlong size = sgStreamTellSize(stream); size -= pos; if(pos < 0 || size < 0) goto lderr; buf = malloc(size); if(sgStreamRead(stream, buf, 1, size) != size) goto lderr; stb = stb_vorbis_open_memory(buf, size, &error, NULL); if(!stb) goto lderr; info = stb_vorbis_get_info(stb); channels = info.channels; frequency = info.sample_rate; format = SG_AUDIO_FORMAT_S16; // or SG_AUDIO_FORMAT_F nsamples = stb_vorbis_stream_length_in_samples(stb); datalen = 2 * nsamples * channels; data = malloc(datalen); datalen = 2 * stb_vorbis_get_samples_short_interleaved(stb, info.channels, data, datalen / 2); sgAudioBufferSetData(buffer, channels, format, frequency, data, datalen); free(data); end: if(stb) stb_vorbis_close(stb); if(buf) free(buf); return buffer; lderr: if(buffer) { free(buffer); buffer = NULL; goto end; } error: if(buffer) free(buffer); return NULL; }
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); } } }
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); } }
sInt sOGGDecoder::GetTuneLength() { return stb_vorbis_stream_length_in_samples(dec); }