예제 #1
0
void OpenALStream::InitializeSoundLoop()
{
#ifdef AL_FORMAT_51CHN16
	bool surroundsupported = SupportSurroundOutput();
	format = surroundsupported ? AL_FORMAT_51CHN16 : AL_FORMAT_STEREO16;
#else
	bool surroundsupported = false;
	format = AL_FORMAT_STEREO16;
#endif
	samplesize = surroundsupported ? SOUND_SAMPLES_SURROUND : SOUND_SAMPLES_STEREO;
	ulFrequency = m_mixer->GetSampleRate();
	numBuffers = SConfig::GetInstance().iLatency + SOUND_BUFFER_COUNT; // OpenAL requires a minimum of two buffers

	memset(uiBuffers, 0, numBuffers * sizeof(ALuint));
	uiSource = 0;
	// Generate a Source to playback the Buffers
	alGenSources(1, &uiSource);
	// Generate some AL Buffers for streaming
	alGenBuffers(numBuffers, (ALuint *)uiBuffers);
	// Set the default sound volume as saved in the config file.
	alSourcef(uiSource, AL_GAIN, fVolume);
	s16* temp = new s16[SOUND_FRAME_SIZE * samplesize];
	memset(temp, 0, SOUND_FRAME_SIZE * samplesize * sizeof(u16));
	for (u8 i = 0; i < numBuffers; i++)
	{
		alBufferData(uiBuffers[i], format, temp, SOUND_FRAME_SIZE * samplesize * sizeof(u16), ulFrequency);
	}
	delete[] temp;
	alSourceQueueBuffers(uiSource, numBuffers, uiBuffers);
	alSourcePlay(uiSource);
}
예제 #2
0
// The audio thread.
void SoundStream::SoundLoop()
{
	Common::SetCurrentThreadName("Audio thread");
	InitializeSoundLoop();
	bool surroundSupported = SupportSurroundOutput() && SConfig::GetInstance().bDPL2Decoder;
	memset(realtimeBuffer, 0, SOUND_MAX_FRAME_SIZE * sizeof(u16));
	memset(dpl2buffer, 0, SOUND_MAX_FRAME_SIZE * sizeof(soundtouch::SAMPLETYPE));
	memset(samplebuffer, 0, SOUND_MAX_FRAME_SIZE * sizeof(soundtouch::SAMPLETYPE));
	u32 channelmultiplier = surroundSupported ? SOUND_SAMPLES_SURROUND : SOUND_SAMPLES_STEREO;
	CMixer* mixer = GetMixer();
	if (SConfig::GetInstance().bTimeStretching)
	{
		float ratemultiplier = 1.0f;
		soundtouch::SoundTouch sTouch;
		sTouch.setChannels(2);
		sTouch.setSampleRate(mixer->GetSampleRate());
		sTouch.setTempo(1.0);
		sTouch.setSetting(SETTING_USE_QUICKSEEK, 0);
		sTouch.setSetting(SETTING_USE_AA_FILTER, 1);
		while (threadData.load())
		{
			u32 availablesamples = mixer->AvailableSamples();
			u32 numsamples = std::min(availablesamples, 400u);
			if (numsamples == 400u)
			{
				float rate = mixer->GetCurrentSpeed();
				if (rate <= 0)
				{
					rate = 1.0f;
				}
				numsamples = mixer->Mix(samplebuffer, numsamples);
				rate *= ratemultiplier;
				rate = rate < 0.5f ? 0.5f : rate;
				rate = roundf(rate * 16.0f) / 16.0f;
				sTouch.setTempo(rate);
				sTouch.putSamples(samplebuffer, numsamples);
			}
			u32 samplesneeded = SamplesNeeded();
			availablesamples = sTouch.numSamples();
			if (samplesneeded >= SOUND_FRAME_SIZE && availablesamples > 0)
			{
				ratemultiplier = std::fmaxf(std::fminf((float)availablesamples / (float)samplesneeded, 1.1f), 0.9f);
				numsamples = std::min(availablesamples, SOUND_FRAME_SIZE);
				if (surroundSupported)
				{
					numsamples = sTouch.receiveSamples(dpl2buffer, numsamples);
					DPL2Decode(dpl2buffer, numsamples, samplebuffer);
				}
				else
				{
					numsamples = sTouch.receiveSamples(samplebuffer, numsamples);
				}
				floatTos16(realtimeBuffer, samplebuffer, numsamples, channelmultiplier);
				WriteSamples(realtimeBuffer, numsamples);
			}
			else
			{
				Common::SleepCurrentThread(1);
			}
		}
	}
	else
	{
		while (threadData.load())
		{
			u32 neededsamples = std::min(SamplesNeeded(), SOUND_FRAME_SIZE);
			u32 availablesamples = mixer->AvailableSamples() & (~(0xF));
			if (neededsamples == SOUND_FRAME_SIZE && availablesamples > 0)
			{
				u32 numsamples = std::min(availablesamples, neededsamples);
				if (surroundSupported)
				{
					numsamples = mixer->Mix(dpl2buffer, numsamples);
					DPL2Decode(dpl2buffer, numsamples, samplebuffer);
					floatTos16(realtimeBuffer, samplebuffer, numsamples, channelmultiplier);
				}
				else
				{
					numsamples = mixer->Mix(realtimeBuffer, numsamples);
				}
				WriteSamples(realtimeBuffer, numsamples);
			}
			else
			{
				Common::SleepCurrentThread(1);
			}
		}
	}
}