void GuiSound::Play() { if(IsPlaying()) return; if(voice < 0 || voice >= 16) return; SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice); if(!decoder) return; if(decoder->IsEOF()) { ASND_StopVoice(voice); decoder->ClearBuffer(); decoder->Rewind(); decoder->Decode(); } u8 * curbuffer = decoder->GetBuffer(); int bufsize = decoder->GetBufferSize(); decoder->LoadNext(); SoundHandler::Instance()->ThreadSignal(); ASND_SetVoice(voice, decoder->GetFormat(), decoder->GetSampleRate(), 0, curbuffer, bufsize, volume, volume, SoundCallback); }
bool GuiSound::Load(const u8 * snd, s32 len, bool isallocated) { FreeMemory(); if(!snd) return false; sound = (u8 *) snd; length = len; allocated = isallocated; SoundHandler::Instance()->AddDecoder(voice, sound, length); SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice); if(!decoder) return false; if(!decoder->IsBufferReady()) { SoundHandler::Instance()->RemoveDecoder(voice); return false; } SetLoop(loop); return true; }
void GuiSound::Rewind() { SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice); if(!decoder) return; decoder->Rewind(); }
void GuiSound::SetLoop(u8 l) { loop = l; SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice); if(!decoder) return; decoder->SetLoop(l == 1); }
void GuiSound::Stop() { if(voice < 0 || voice >= 16) return; ASND_StopVoice(voice); SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice); if(!decoder) return; decoder->ClearBuffer(); Rewind(); SoundHandler::Instance()->ThreadSignal(); }
extern "C" void SoundCallback(s32 voice) { SoundDecoder * decoder = SoundHandler::Instance()->Decoder(voice); if(!decoder) return; if(decoder->IsBufferReady()) { if(ASND_AddVoice(voice, decoder->GetBuffer(), decoder->GetBufferSize()) == SND_OK) { decoder->LoadNext(); SoundHandler::Instance()->ThreadSignal(); } } else if(decoder->IsEOF()) { ASND_StopVoice(voice); //if(voice == 0) //MusicPlayer::Instance()->SetPlaybackFinished(true); //see if next music must be played } else { SoundHandler::Instance()->ThreadSignal(); } }
void SoundHandler::RemoveDecoder(int voice) { if(voice < 0 || voice >= MAX_DECODERS) return; if(DecoderList[voice] != NULL) { if(voiceList[voice]->getState() != Voice::STATE_STOPPED) { if(voiceList[voice]->getState() != Voice::STATE_STOP) voiceList[voice]->setState(Voice::STATE_STOP); while(voiceList[voice]->getState() != Voice::STATE_STOPPED) usleep(1000); } SoundDecoder *decoder = DecoderList[voice]; decoder->Lock(); DecoderList[voice] = NULL; decoder->Unlock(); delete decoder; } }
bool SoundResource::load( const char *data, int size ) { if( !Resource::load( data, size ) ) return false; SoundDecoder *decoder = SoundManager::instance()->getDecoder( data, (size_t)size ); if( decoder == 0x0 ) return raiseError( "failed to retrieve decoder" ); const char *error; if( ( error = decoder->init( data, size, _soundInfo ) ) != 0x0 ) { SoundManager::instance()->releaseDecoder( decoder ); return raiseError( "failed to initialize decoder : " + std::string( error ) ); } //calculate the size needed to store the decoded sound data size_t sizeNeeded = (size_t)( _soundInfo.runtime * ( _soundInfo.samplingRate * ( _soundInfo.bitDepth / 8 ) * _soundInfo.channels ) ); char *decodedData = new char[sizeNeeded]; size_t sizeDecoded = decoder->decodeData( decodedData, sizeNeeded ); //we are done decoding, release the decoder SoundManager::instance()->releaseDecoder( decoder ); ALenum format = 0; if( _soundInfo.bitDepth == 8 ) { switch( _soundInfo.channels ) { case 1: format = AL_FORMAT_MONO8; break; case 2: format = AL_FORMAT_STEREO8; break; case 4: format = alGetEnumValue( "AL_FORMAT_QUAD8" ); break; case 6: format = alGetEnumValue( "AL_FORMAT_51CHN8" ); break; case 7: format = alGetEnumValue( "AL_FORMAT_61CHN8" ); break; case 8: format = alGetEnumValue( "AL_FORMAT_71CHN8" ); break; } } else if( _soundInfo.bitDepth == 16 ) { switch( _soundInfo.channels ) { case 1: format = AL_FORMAT_MONO16; break; case 2: format = AL_FORMAT_STEREO16; break; case 4: format = alGetEnumValue( "AL_FORMAT_QUAD16" ); break; case 6: format = alGetEnumValue( "AL_FORMAT_51CHN16" ); break; case 7: format = alGetEnumValue( "AL_FORMAT_61CHN16" ); break; case 8: format = alGetEnumValue( "AL_FORMAT_71CHN16" ); break; } } if( !format ) { delete[] decodedData; return raiseError( "sound has invalid bitdepth or unsupported number of channels" ); } //fill the buffer with our decoded sound data alBufferData( _buffer, format, decodedData, (ALsizei)sizeDecoded, (ALsizei)_soundInfo.samplingRate ); SoundManager::instance()->checkALError( "filling buffer with data for Sound resource '%s'", _name.c_str() ); delete[] decodedData; return true; }
void SoundHandler::axFrameCallback(void) { for (u32 i = 0; i < MAX_DECODERS; i++) { Voice *voice = handlerInstance->getVoice(i); switch (voice->getState()) { default: case Voice::STATE_STOPPED: break; case Voice::STATE_START: { SoundDecoder * decoder = handlerInstance->getDecoder(i); decoder->Lock(); if(decoder->IsBufferReady()) { const u8 *buffer = decoder->GetBuffer(); const u32 bufferSize = decoder->GetBufferSize(); decoder->LoadNext(); const u8 *nextBuffer = NULL; u32 nextBufferSize = 0; if(decoder->IsBufferReady()) { nextBuffer = decoder->GetBuffer(); nextBufferSize = decoder->GetBufferSize(); decoder->LoadNext(); } voice->play(buffer, bufferSize, nextBuffer, nextBufferSize, decoder->GetFormat() & 0xff, decoder->GetSampleRate()); handlerInstance->ThreadSignal(); voice->setState(Voice::STATE_PLAYING); } decoder->Unlock(); break; } case Voice::STATE_PLAYING: if(voice->getInternState() == 1) { if(voice->isBufferSwitched()) { SoundDecoder * decoder = handlerInstance->getDecoder(i); decoder->Lock(); if(decoder->IsBufferReady()) { voice->setNextBuffer(decoder->GetBuffer(), decoder->GetBufferSize()); decoder->LoadNext(); handlerInstance->ThreadSignal(); } else if(decoder->IsEOF()) { voice->setState(Voice::STATE_STOP); } decoder->Unlock(); } } else { voice->setState(Voice::STATE_STOPPED); } break; case Voice::STATE_STOP: if(voice->getInternState() != 0) voice->stop(); voice->setState(Voice::STATE_STOPPED); break; } } }