Exemplo n.º 1
0
uint32 FVoiceEngineImpl::SubmitRemoteVoiceData(const FUniqueNetId& RemoteTalkerId, uint8* Data, uint32* Size)
{
	UE_LOG(LogVoiceDecode, VeryVerbose, TEXT("SubmitRemoteVoiceData(%s) Size: %d received!"), *RemoteTalkerId.ToDebugString(), *Size);

	const FUniqueNetIdString& TalkerId = (const FUniqueNetIdString&)RemoteTalkerId;
	FRemoteTalkerDataImpl& QueuedData = RemoteTalkerBuffers.FindOrAdd(TalkerId);

	// new voice packet.
	QueuedData.LastSeen = FPlatformTime::Seconds();

	uint32 BytesWritten = MAX_UNCOMPRESSED_VOICE_BUFFER_SIZE;

	DecompressedVoiceBuffer.Empty(MAX_UNCOMPRESSED_VOICE_BUFFER_SIZE);
	DecompressedVoiceBuffer.AddUninitialized(MAX_UNCOMPRESSED_VOICE_BUFFER_SIZE);
	QueuedData.VoiceDecoder->Decode(Data, *Size, DecompressedVoiceBuffer.GetData(), BytesWritten);

	// If there is no data, return
	if (BytesWritten <= 0)
	{
		*Size = 0;
		return S_OK;
	}

	bool bAudioComponentCreated = false;
	// Generate a streaming wave audio component for voice playback
	if (QueuedData.AudioComponent == nullptr || QueuedData.AudioComponent->IsPendingKill())
	{
		if (SerializeHelper == nullptr)
		{
			SerializeHelper = new FVoiceSerializeHelper(this);
		}

		QueuedData.AudioComponent = CreateVoiceAudioComponent(VOICE_SAMPLE_RATE);
		if (QueuedData.AudioComponent)
		{
			QueuedData.AudioComponent->OnAudioFinishedNative.AddRaw(this, &FVoiceEngineImpl::OnAudioFinished);
		}
	}
	
	if (QueuedData.AudioComponent != nullptr)
	{
		if (!QueuedData.AudioComponent->IsActive())
		{
			QueuedData.AudioComponent->Play();
		}

		USoundWaveStreaming* SoundStreaming = CastChecked<USoundWaveStreaming>(QueuedData.AudioComponent->Sound);

		if (0)
		{
			if (!bAudioComponentCreated && SoundStreaming->GetAvailableAudioByteCount() == 0)
			{
				UE_LOG(LogVoiceDecode, Log, TEXT("VOIP audio component was starved!"));
			}
		}

		SoundStreaming->QueueAudio(DecompressedVoiceBuffer.GetData(), BytesWritten);
	}

	return S_OK;
}
uint32 FVoiceEngineSteam::SubmitRemoteVoiceData(const FUniqueNetId& RemoteTalkerId, uint8* Data, uint32* Size) 
{
	UE_LOG(LogVoiceDecode, VeryVerbose, TEXT("SubmitRemoteVoiceData(%s) Size: %d received!"), *RemoteTalkerId.ToDebugString(), *Size);

	const FUniqueNetIdSteam& SteamId = (const FUniqueNetIdSteam&)RemoteTalkerId;
	FRemoteTalkerDataSteam* QueuedData = RemoteTalkerBuffers.Find(SteamId);

	if (QueuedData == NULL)
	{
		RemoteTalkerBuffers.Add(SteamId, FRemoteTalkerDataSteam());
		QueuedData = RemoteTalkerBuffers.Find(SteamId);
	}

	check(QueuedData);

	// new voice packet.
	QueuedData->LastSeen = FPlatformTime::Seconds();

	uint32 BytesWritten = 0;

	DecompressedVoiceBuffer.Empty(MAX_UNCOMPRESSED_VOICE_BUFFER_SIZE);
	DecompressedVoiceBuffer.AddUninitialized(MAX_UNCOMPRESSED_VOICE_BUFFER_SIZE);
	const EVoiceResult VoiceResult = SteamUserPtr->DecompressVoice(Data, *Size, DecompressedVoiceBuffer.GetData(),
		DecompressedVoiceBuffer.Num(), &BytesWritten, SteamUserPtr->GetVoiceOptimalSampleRate());

	if (VoiceResult != k_EVoiceResultOK)
	{
		UE_LOG(LogVoiceDecode, Warning, TEXT("SubmitRemoteVoiceData: DecompressVoice failure: VoiceResult: %s"), *SteamVoiceResult(VoiceResult));
		*Size = 0;
		return E_FAIL;
	}

	// If there is no data, return
	if (BytesWritten <= 0)
	{
		*Size = 0;
		return S_OK;
	}

	// Generate a streaming wave audio component for voice playback
	if (QueuedData->AudioComponent == NULL || QueuedData->AudioComponent->IsPendingKill())
	{
		if (SerializeHelper == NULL)
		{
			SerializeHelper = new FVoiceSerializeHelper(this);
		}

		QueuedData->AudioComponent = CreateVoiceAudioComponent(SteamUserPtr->GetVoiceOptimalSampleRate());
		if (QueuedData->AudioComponent)
		{
			QueuedData->AudioComponent->OnAudioFinishedNative.AddRaw(this, &FVoiceEngineSteam::OnAudioFinished);
			QueuedData->AudioComponent->Play();
		}
	}

	if (QueuedData->AudioComponent != NULL)
	{
		USoundWaveProcedural* SoundStreaming = CastChecked<USoundWaveProcedural>(QueuedData->AudioComponent->Sound);
		if (SoundStreaming->GetAvailableAudioByteCount() == 0)
		{
			UE_LOG(LogVoiceDecode, Log, TEXT("VOIP audio component was starved!"));
		}
		SoundStreaming->QueueAudio(DecompressedVoiceBuffer.GetData(), BytesWritten);
	}

	return S_OK;
}
bool FTestVoice::Tick(float DeltaTime)
{
	if (VoiceCapture.IsValid())
	{
		if (!IsRunningDedicatedServer() && VoiceComp == NULL)
		{
			VoiceComp = CreateVoiceAudioComponent(VOICE_SAMPLE_RATE);
			VoiceComp->AddToRoot();
			VoiceComp->Play();
		}

		if (VoiceComp)
		{
			static bool bLastHasData = true;
			USoundWaveProcedural* SoundStreaming = CastChecked<USoundWaveProcedural>(VoiceComp->Sound);
			bool bHasData = SoundStreaming->GetAvailableAudioByteCount() != 0;

			if (bHasData != bLastHasData)
			{
				//UE_LOG(LogVoice, Log, TEXT("VOIP audio component %s starved!"), bHasData ? TEXT("is not") : TEXT("is"));
				bLastHasData = bHasData;
			}

			bool bDoWork = false;
			uint32 TotalVoiceBytes = 0;

			if (bUseTestSample)
			{
				SetStaticVoiceData(RawCaptureData, TotalVoiceBytes);
				bDoWork = true;
			}
			else
			{
				uint32 NewVoiceDataBytes = 0;
				EVoiceCaptureState::Type MicState = VoiceCapture->GetCaptureState(NewVoiceDataBytes);
				if (MicState == EVoiceCaptureState::Ok && NewVoiceDataBytes > 0)
				{
					//UE_LOG(LogVoice, Log, TEXT("Getting data! %d"), NewVoiceDataBytes);
					TotalVoiceBytes = NewVoiceDataBytes + LastRemainderSize;
					RawCaptureData.Empty(MaxRawCaptureDataSize);
					RawCaptureData.AddUninitialized(TotalVoiceBytes);

					if (LastRemainderSize > 0)
					{
						FMemory::Memcpy(RawCaptureData.GetData(), Remainder.GetData(), LastRemainderSize);
					}

					MicState = VoiceCapture->GetVoiceData(RawCaptureData.GetData() + LastRemainderSize, NewVoiceDataBytes, NewVoiceDataBytes);
					TotalVoiceBytes = NewVoiceDataBytes + LastRemainderSize;
					bDoWork = MicState == EVoiceCaptureState::Ok;
				}
			}

			if (bDoWork && TotalVoiceBytes > 0)
			{
				// ZERO INPUT
				if (bZeroInput)
				{
					FMemory::Memzero(RawCaptureData.GetData(), TotalVoiceBytes);
				}	
				// ZERO INPUT END

				// COMPRESSION BEGIN
				uint32 CompressedDataSize = MaxCompressedDataSize;
				LastRemainderSize = VoiceEncoder->Encode(RawCaptureData.GetData(), TotalVoiceBytes, CompressedData.GetData(), CompressedDataSize);

				if (LastRemainderSize > 0)
				{
					FMemory::Memcpy(Remainder.GetData(), RawCaptureData.GetData() + (TotalVoiceBytes - LastRemainderSize), LastRemainderSize);
				}
				// COMPRESION END

				// DECOMPRESION BEGIN
				uint32 UncompressedDataSize = MaxUncompressedDataSize;
				VoiceDecoder->Decode(CompressedData.GetData(), CompressedDataSize, 
					UncompressedData.GetData(), UncompressedDataSize);
				// DECOMPRESSION END

				if (bUseDecompressed)
				{
					if (UncompressedDataSize > 0)
					{
						//UE_LOG(LogVoice, Log, TEXT("Queueing uncompressed data! %d"), UncompressedDataSize);
						if (bZeroOutput)
						{
							FMemory::Memzero((uint8*)UncompressedData.GetData(), UncompressedDataSize);
						}

						SoundStreaming->QueueAudio(UncompressedData.GetData(), UncompressedDataSize);
					}
				}
				else
				{
					//UE_LOG(LogVoice, Log, TEXT("Queueing raw data! %d"), TotalVoiceBytes - LastRemainderSize);
					SoundStreaming->QueueAudio(RawCaptureData.GetData(), TotalVoiceBytes - LastRemainderSize);
				}
			}

		}
	}

	return true;
}