Пример #1
0
/**
 * Updates the source specific parameter like e.g. volume and pitch based on the associated
 * wave instance.	
 */
void FSLESSoundSource::Update( void )
{
	SCOPE_CYCLE_COUNTER( STAT_AudioUpdateSources );
	
	if( !WaveInstance || Paused )
	{
		return;
	}
	
	float Volume = WaveInstance->Volume * WaveInstance->VolumeMultiplier;
	if( SetStereoBleed() )
	{
		// Emulate the bleed to rear speakers followed by stereo fold down
		Volume *= 1.25f;
	}
	Volume *= GVolumeMultiplier;
	Volume = FMath::Clamp(Volume, 0.0f, MAX_VOLUME);
	
	const float Pitch = FMath::Clamp<float>(WaveInstance->Pitch, MIN_PITCH, MAX_PITCH);

	// Set whether to apply reverb
	SetReverbApplied(true);

	// Set the HighFrequencyGain value
	SetHighFrequencyGain();
	
	FVector Location;
	FVector	Velocity;
	
	// See file header for coordinate system explanation.
	Location.X = WaveInstance->Location.X;
	Location.Y = WaveInstance->Location.Z; // Z/Y swapped to match UE coordinate system
	Location.Z = WaveInstance->Location.Y; // Z/Y swapped to match UE coordinate system
	
	Velocity.X = WaveInstance->Velocity.X;
	Velocity.Y = WaveInstance->Velocity.Z; // Z/Y swapped to match UE coordinate system
	Velocity.Z = WaveInstance->Velocity.Y; // Z/Y swapped to match UE coordinate system
	
	// We're using a relative coordinate system for un- spatialized sounds.
	if( !WaveInstance->bUseSpatialization )
	{
		Location = FVector( 0.f, 0.f, 0.f );
	}
	
	// Set volume & Pitch
	// also Location & Velocity
	
	// Convert volume to millibels.
	SLmillibel MaxMillibel = 0;
	SLmillibel MinMillibel = -3000;
	(*SL_VolumeInterface)->GetMaxVolumeLevel( SL_VolumeInterface, &MaxMillibel );
	SLmillibel VolumeMillibel = (Volume * (MaxMillibel - MinMillibel)) + MinMillibel;
	VolumeMillibel = FMath::Clamp(VolumeMillibel, MinMillibel, MaxMillibel);
	
	SLresult result = (*SL_VolumeInterface)->SetVolumeLevel(SL_VolumeInterface, VolumeMillibel);
	check(SL_RESULT_SUCCESS == result);

}
	void FMixerSource::UpdateChannelMaps()
	{
		SetStereoBleed();

		SetLFEBleed();

		bool bChanged = false;

		check(Buffer);
		if (Buffer->NumChannels == 1)
		{
			bChanged = ComputeMonoChannelMap();
		}
		else if (Buffer->NumChannels == 2)
		{
			bChanged = ComputeStereoChannelMap();
		}
		else if (Buffer->NumChannels == 4)
		{
			bChanged = ComputeQuadChannelMap();
		}
		else if (Buffer->NumChannels == 6)
		{
			bChanged = ComputeHexChannelMap();
		}
		else
		{
			UE_LOG(LogAudioMixer, Warning, TEXT("Unsupported input audio channels '%d'"), Buffer->NumChannels);
			return;
		}

		if (bChanged)
		{
			MixerSourceVoice->SetChannelMap(ChannelMap);
		}
	}
Пример #3
0
/**
 * Updates the source specific parameter like e.g. volume and pitch based on the associated
 * wave instance.	
 */
void FCoreAudioSoundSource::Update( void )
{
	SCOPE_CYCLE_COUNTER( STAT_AudioUpdateSources );

	if( !WaveInstance || Paused || !AudioChannel )
	{	
		return;
	}

	float Volume = WaveInstance->GetActualVolume();
	
	if( Buffer->NumChannels < 3 )
	{
		float Azimuth = 0.0f;
		float Elevation = 0.0f;

		if( SetStereoBleed() )
		{
			// Emulate the bleed to rear speakers followed by stereo fold down
			Volume *= 1.25f;
		}
		
		// apply global multiplier (ie to disable sound when not the foreground app)
		Volume *= GVolumeMultiplier;
		Volume = FMath::Clamp<float>( Volume, 0.0f, MAX_VOLUME );
		
		// Convert to dB
		Volume = 20.0 * log10(Volume);
		Volume = FMath::Clamp<float>( Volume, -120.0f, 20.0f );

		const float Pitch = FMath::Clamp<float>( WaveInstance->Pitch, MIN_PITCH, MAX_PITCH );
		
		// Set the HighFrequencyGain value
		SetHighFrequencyGain();
		
		if( WaveInstance->bApplyRadioFilter )
		{
			Volume = WaveInstance->RadioFilterVolume;
		}
		else if( WaveInstance->bUseSpatialization )
		{
			FRotator Rotation = AudioDevice->InverseTransform.TransformPosition( WaveInstance->Location ).SafeNormal().Rotation();
			Azimuth = Rotation.Yaw;
			Elevation = Rotation.Pitch;
		}

		// Apply any debug settings
		{
			bool bMuteDry, bMuteReverb, bMuteRadio;
			switch( AudioDevice->GetMixDebugState() )
			{
			case DEBUGSTATE_IsolateReverb:		bMuteDry = true;	bMuteReverb = false;	bMuteRadio = false;	break;
			case DEBUGSTATE_IsolateDryAudio:	bMuteDry = false;	bMuteReverb = true;		bMuteRadio = true;	break;
			default:							bMuteDry = false;	bMuteReverb = false;	bMuteRadio = false;	break;
			};

			// Dry audio or EQ node
			if( bMuteDry != bDryMuted )
			{
				if( bMuteDry )
				{
					if( StreamSplitterUnit )
					{
						for( int32 OutputChannelIndex = 0; OutputChannelIndex < AudioDevice->Mixer3DFormat.mChannelsPerFrame; ++OutputChannelIndex )
						{
							SAFE_CA_CALL( AudioUnitSetParameter( StreamSplitterUnit, kMatrixMixerParam_Volume, kAudioUnitScope_Output, OutputChannelIndex, 0.0, 0 ) );
						}
					}
					else
					{
						SAFE_CA_CALL( AudioUnitSetParameter( AudioDevice->GetMixer3DUnit(), k3DMixerParam_Gain, kAudioUnitScope_Input, MixerInputNumber, 0.0, 0 ) );
					}
					bDryMuted = true;
				}
				else
				{
					if( StreamSplitterUnit )
					{
						for( int32 OutputChannelIndex = 0; OutputChannelIndex < AudioDevice->Mixer3DFormat.mChannelsPerFrame; ++OutputChannelIndex )
						{
							SAFE_CA_CALL( AudioUnitSetParameter( StreamSplitterUnit, kMatrixMixerParam_Volume, kAudioUnitScope_Output, OutputChannelIndex, 1.0, 0 ) );
						}
					}
					bDryMuted = false;
				}
			}

			if( ReverbNode && bMuteReverb != bReverbMuted )
			{
				int ReverbNodeBaseIndex = AudioDevice->Mixer3DFormat.mChannelsPerFrame;
				if( bMuteReverb )
				{
					for( int32 OutputChannelIndex = 0; OutputChannelIndex < AudioDevice->Mixer3DFormat.mChannelsPerFrame; ++OutputChannelIndex )
					{
						SAFE_CA_CALL( AudioUnitSetParameter( StreamSplitterUnit, kMatrixMixerParam_Volume, kAudioUnitScope_Output, ReverbNodeBaseIndex + OutputChannelIndex, 0.0, 0 ) );
					}
					bReverbMuted = true;
				}
				else
				{
					for( int32 OutputChannelIndex = 0; OutputChannelIndex < AudioDevice->Mixer3DFormat.mChannelsPerFrame; ++OutputChannelIndex )
					{
						SAFE_CA_CALL( AudioUnitSetParameter( StreamSplitterUnit, kMatrixMixerParam_Volume, kAudioUnitScope_Output, ReverbNodeBaseIndex + OutputChannelIndex, 1.0, 0 ) );
					}
					bReverbMuted = false;
				}
			}

			if( RadioNode && bMuteRadio != bRadioMuted )
			{
				int RadioNodeBaseIndex = ( 1 + ( ReverbNode ? 1 : 0 ) ) * AudioDevice->Mixer3DFormat.mChannelsPerFrame;
				if( bMuteRadio )
				{
					for( int32 OutputChannelIndex = 0; OutputChannelIndex < AudioDevice->Mixer3DFormat.mChannelsPerFrame; ++OutputChannelIndex )
					{
						SAFE_CA_CALL( AudioUnitSetParameter( StreamSplitterUnit, kMatrixMixerParam_Volume, kAudioUnitScope_Output, RadioNodeBaseIndex + OutputChannelIndex, 0.0, 0 ) );
					}
					bRadioMuted = true;
				}
				else
				{
					for( int32 OutputChannelIndex = 0; OutputChannelIndex < AudioDevice->Mixer3DFormat.mChannelsPerFrame; ++OutputChannelIndex )
					{
						SAFE_CA_CALL( AudioUnitSetParameter( StreamSplitterUnit, kMatrixMixerParam_Volume, kAudioUnitScope_Output, RadioNodeBaseIndex + OutputChannelIndex, 1.0, 0 ) );
					}
					bRadioMuted = false;
				}
			}
		}

		if( !bDryMuted || StreamSplitterUnit )
		{
			SAFE_CA_CALL( AudioUnitSetParameter( AudioDevice->GetMixer3DUnit(), k3DMixerParam_Gain, kAudioUnitScope_Input, MixerInputNumber, Volume, 0 ) );
		}

		SAFE_CA_CALL( AudioUnitSetParameter( AudioDevice->GetMixer3DUnit(), k3DMixerParam_PlaybackRate, kAudioUnitScope_Input, MixerInputNumber, Pitch, 0 ) );
		SAFE_CA_CALL( AudioUnitSetParameter( AudioDevice->GetMixer3DUnit(), k3DMixerParam_Azimuth, kAudioUnitScope_Input, MixerInputNumber, Azimuth, 0 ) );
		SAFE_CA_CALL( AudioUnitSetParameter( AudioDevice->GetMixer3DUnit(), k3DMixerParam_Elevation, kAudioUnitScope_Input, MixerInputNumber, Elevation, 0 ) );
	}
	else
	{
		// apply global multiplier (ie to disable sound when not the foreground app)
		Volume *= GVolumeMultiplier;
		Volume = FMath::Clamp<float>( Volume, 0.0f, MAX_VOLUME );
		
		if( AudioDevice->GetMixDebugState() == DEBUGSTATE_IsolateReverb )
		{
			Volume = 0.0f;
		}

		AudioDevice->SetMatrixMixerInputVolume( MixerInputNumber, Volume );
	}
}