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();
	}
}
예제 #7
0
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;
    }
}
예제 #8
0
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;
}
예제 #9
0
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;
        }
    }
}