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); }
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; }
bool Sound::LoadOggVorbis(Deserializer& source) { unsigned dataSize = source.GetSize(); SharedArrayPtr<signed char> data(new signed char[dataSize]); source.Read(data.Get(), dataSize); // Check for validity of data int error; stb_vorbis* vorbis = stb_vorbis_open_memory((unsigned char*)data.Get(), dataSize, &error, 0); if (!vorbis) { LOGERROR("Could not read Ogg Vorbis data from " + source.GetName()); return false; } // Store length, frequency and stereo flag stb_vorbis_info info = stb_vorbis_get_info(vorbis); compressedLength_ = stb_vorbis_stream_length_in_seconds(vorbis); frequency_ = info.sample_rate; stereo_ = info.channels > 1; stb_vorbis_close(vorbis); data_ = data; dataSize_ = dataSize; sixteenBit_ = true; compressed_ = true; SetMemoryUse(dataSize); return true; }
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 show_info(stb_vorbis *v) { if (v) { stb_vorbis_info info = stb_vorbis_get_info(v); printf("%d channels, %d samples/sec\n", info.channels, info.sample_rate); printf("Predicted memory needed: %d (%d + %d)\n", info.setup_memory_required + info.temp_memory_required, info.setup_memory_required, info.temp_memory_required); } }
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; }
// 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; }
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); }
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; }
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 InitializeVorbisPlayer(VorbisPlayer *self,const void *bytes,size_t length,bool loop) { self->loop=loop; self->currentframe=NULL; self->framepos=0; self->framelength=0; int error; self->vorbis=stb_vorbis_open_memory((void *)bytes,(int)length,&error,NULL); if(!self->vorbis) { InitializeAudioSource(&self->source,NULL); return false; } stb_vorbis_info info=stb_vorbis_get_info(self->vorbis); uint32_t globalrate=AudioGraphSampleRate(); if(info.sample_rate==globalrate) { switch(info.channels) { case 1: InitializeAudioSource(&self->source,MixMonoVorbisSamples); return true; case 2: InitializeAudioSource(&self->source,MixStereoVorbisSamples); return true; default: InitializeAudioSource(&self->source,NULL); return false; } } else if(info.sample_rate/2==globalrate) { switch(info.channels) { case 1: InitializeAudioSource(&self->source,MixHalfRateMonoVorbisSamples); return true; case 2: InitializeAudioSource(&self->source,MixHalfRateStereoVorbisSamples); return true; default: InitializeAudioSource(&self->source,NULL); return false; } } else { InitializeAudioSource(&self->source,NULL); return false; } }
static unsigned char *loadSound_ogg( String path,int *length,int *channels,int *format,int *hertz ){ FILE *f=fopenFile( path,"rb" ); if( !f ) return 0; int error; stb_vorbis *v=stb_vorbis_open_file( f,0,&error,0 ); if( !v ){ fclose( f ); return 0; } stb_vorbis_info info=stb_vorbis_get_info( v ); int limit=info.channels*4096; int offset=0,data_len=0,total=limit; short *data=(short*)malloc( total*sizeof(short) ); for(;;){ int n=stb_vorbis_get_frame_short_interleaved( v,info.channels,data+offset,total-offset ); if( !n ) break; data_len+=n; offset+=n*info.channels; if( offset+limit>total ){ total*=2; data=(short*)realloc( data,total*sizeof(short) ); } } *length=data_len; *channels=info.channels; *format=2; *hertz=info.sample_rate; stb_vorbis_close(v); fclose( f ); return (unsigned char*)data; }
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); }
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; }
void LoadSoundStream(SoundStream* stream, const char * file_path) { FILE *file = Global::platform()->OpenFile(file_path, "rb"); int error; stb_vorbis *v = stb_vorbis_open_file(file, false, &error, nullptr); if (v == nullptr) return; stb_vorbis_info info = stb_vorbis_get_info(v); stream->mChannels = info.channels; stream->mSampleRate = info.sample_rate; for (;;) { float** frame_data; int n = stb_vorbis_get_frame_float(v, &(info.channels), &frame_data); if (n == 0) break; for (int idx = 0; idx < n; ++idx) { for (int channel_idx = 0; channel_idx < info.channels; ++channel_idx) { stream->mAudio.push_back(frame_data[channel_idx][idx]); } } } stb_vorbis_close(v); }
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; }
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; }
VorbisFile::VorbisFile(const common::DataPtr& inFile) { data = NULL; int err; stb_vorbis* oggfile = stb_vorbis_open_memory((unsigned char*)inFile->bytes.get(), inFile->size, &err, NULL); if(!oggfile) { EOUT("throwing from here"); lost::common::StringStream os; os << "couldn't open ogg file '"; throw std::runtime_error(os.str().c_str()); } stb_vorbis_info info = stb_vorbis_get_info(oggfile); stb_vorbis_close(oggfile); sampleRate = info.sample_rate; numSamples = stb_vorbis_decode_memory((unsigned char*)(inFile->bytes.get()), inFile->size, &channels, &data); DOUT("decoded to "<<numSamples*2 <<" bytes"); buffer.reset(new al::Buffer); buffer->bufferData((channels == 2) ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16, data, numSamples*2, sampleRate); }
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; }
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; }
//---------------------------------------------------------------------------- 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; }
S32 PCMAudioManager::playStreamingSound(const char *assetName, S16 loops, F32 leftVol, F32 rightVol, F32 rate) { if (leftVol < 0) { leftVol = 0; } else if (leftVol > 1) { leftVol = 1; } if (rightVol < 0) { rightVol = 0; } else if (rightVol > 1) { rightVol = 1; } S32 streamId = -1; //char buf[50]; //sprintf(buf, "Playing sound %i", soundId); //logmsg(buf); // create a stream BOOL32 success = FALSE; for (S32 i = 0; i < streamCount; i++) { PCMStream *stream = &pcmStreams[i]; if (!stream->isPlaying && !stream->audioHandle) { //sprintf(buf, "Using Stream %i", i); //logmsg(buf); // use this stream; stream->isStreaming = TRUE; stream->pcmSound = NULL; stream->loopsRemaining = loops; stream->bufferPosition = 0; stream->overallPosition = 0; streamId = ++lastStreamId; stream->streamId = streamId; stream->volumeLeft = leftVol; stream->volumeRight = rightVol; stream->assetName = strDuplicate(assetName); stream->channels = 0; stream->playbackRate = rate; stream->filePosition = 0; stream->assetLength = _platform_get_asset_length(assetName); if (stream->assetLength > 0) { // get vorbis handle and read info // fill both audio buffers if (!stream->audioBuf) { stream->audioBuf = new S16*[PCM_AUDIO_STREAM_BUFFERS]; for (S32 j = 0; j < PCM_AUDIO_STREAM_BUFFERS; j++) { stream->audioBuf[j] = new S16[PCM_AUDIO_STREAM_BUFFER_SIZE]; } } unsigned char buf[CHUNKED_READ_BUFFER_SIZE]; BOOL32 eof = FALSE; S32 bytesRead = _platform_read_asset_chunk(assetName, 0, buf, CHUNKED_READ_BUFFER_SIZE, &eof); S32 bytesConsumed; S32 error; // start vorbis pushdata stb_vorbis *vorb = stb_vorbis_open_pushdata(buf, bytesRead, &bytesConsumed, &error, NULL); stb_vorbis_info info = stb_vorbis_get_info(vorb); stream->channels = info.channels; stream->sampleRate = info.sample_rate; stream->maxFrameSize = info.max_frame_size; stream->length = 0; // unknown until we hit eof stream->tempLength = 0; stream->filePosition = bytesConsumed; stream->audioHandle = vorb; stream->resampleActiveRate = stream->sampleRate * stream->playbackRate; stream->resampleInt = stream->resampleActiveRate / PCM_AUDIO_PLAYBACK_RATE; stream->resampleFrac = stream->resampleActiveRate % PCM_AUDIO_PLAYBACK_RATE; stream->resampleFracAccumulated = 0; for (S32 j = 0; j < PCM_AUDIO_STREAM_BUFFERS; j++) { fillStreamingBuffer(stream, j); } stream->activeAudioBuf = 0; // set isPlaying to true last stream->isPlaying = TRUE; } success = TRUE; break; } } if (!success) { logmsg("No streams left to play on"); } return streamId; }
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); } }