Hii,
I’m coding a Capture Audio Function : The goal for it is to capture the audio coming from my mic and playing the sample recorded, amplify it and play it 3 seconds after.
This function is called in my Player BP each time I press V :
void AAudioCaptureActor::CaptureAudio()
{
// Create the Audio Capture Component
UClass* AudioCaptureComponentClass = UMyCaptureComponent::StaticClass();
UMyCaptureComponent* AudioCapture = Cast<UMyCaptureComponent>(AddComponentByClass(AudioCaptureComponentClass, false, FTransform::Identity, false));
// Assign a submix and start capturing audio
USoundSubmix* Submix = NewObject<USoundSubmix>();
AudioCapture->SoundSubmix = Submix;
AudioCapture->Start();
// Start recording
Audio::FMixerDevice* MixerDevice = FAudioDeviceManager::GetAudioMixerDeviceFromWorldContext(GetWorld());
MixerDevice->RegisterSoundSubmix(Submix);
MixerDevice->StartRecording(Submix, 0);
// Mute echo
Submix->SetSubmixOutputVolume(GetWorld(), 0);
// Stop recording after a few seconds
FTimerHandle TimerHandle;
FTimerDelegate TimerDelegate = FTimerDelegate::CreateLambda([&, MixerDevice, Submix, this]() mutable
{
float Channels = 2.0;
float SampleRate = 44100.0;
Audio::FAlignedFloatBuffer Buffer = MixerDevice->StopRecording(Submix, Channels, SampleRate);
// Wrap the buffer so the PCM writer can understand it
Audio::FSampleBuffer SampleBuffer(Buffer, Channels, SampleRate);
Audio::FSoundWavePCMWriter Writer;
// Write the sound wave
USoundWave* CapturedSoundWave = Writer.SynchronouslyWriteSoundWave(SampleBuffer, nullptr, nullptr);
// Amplify the sound wave
if (CapturedSoundWave)
{
// Amplify each sample by multiplying by 10
TArray<int16> AmplifiedSamples;
auto SampleBufferView = SampleBuffer.GetArrayView();
for (int32 SampleIndex = 0; SampleIndex < SampleBuffer.GetNumSamples(); ++SampleIndex)
{
float Sample = SampleBufferView[SampleIndex];
int16 AmplifiedSample = FMath::Clamp(static_cast<int32>(Sample * 10), static_cast<int32>(INT16_MIN), static_cast<int32>(INT16_MAX));
AmplifiedSamples.Add(AmplifiedSample);
}
// Create a new sound wave
USoundWave* TransformedSoundWave = NewObject<USoundWave>(GetTransientPackage(), NAME_None, RF_Transient);
if (TransformedSoundWave)
{
TransformedSoundWave->SetSampleRate(SampleRate);
TransformedSoundWave->NumChannels = Channels;
TransformedSoundWave->Duration = CapturedSoundWave->Duration;
TransformedSoundWave->SoundGroup = SOUNDGROUP_Default;
TransformedSoundWave->bLooping = false;
// Set the PCM data buffer
// Set the PCM data buffer
TransformedSoundWave->RawData.Lock(LOCK_READ_WRITE);
uint8* RawDataPtr = (uint8*)TransformedSoundWave->RawData.Realloc(AmplifiedSamples.Num() * sizeof(int16));
FMemory::Memcpy(RawDataPtr, AmplifiedSamples.GetData(), AmplifiedSamples.Num() * sizeof(int16));
TransformedSoundWave->RawData.Unlock();
// Play the sound wave
UGameplayStatics::PlaySound2D(GetWorld(), TransformedSoundWave);
UE_LOG(LogTemp, Warning, TEXT("Transformed SoundWave played"));
}
else
{
UE_LOG(LogTemp, Error, TEXT("Failed to create USoundWave object"));
}
}
else
{
UE_LOG(LogTemp, Error, TEXT("Failed to capture sound"));
}
});
GetWorld()->GetTimerManager().SetTimer(TimerHandle, TimerDelegate, 3, false);
}
But I’m getting this error when it tries to play TransformedSoundWave :
Only mono or stereo 16 bit waves allowed: SoundWave /Engine/Transient.SoundWave_11 (278528 bytes)
Does anyone have a clue on how to fix this issue ?
Sofiane