SoundWave Not playing

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

It’s solved to anyone having the same issue DO NOT WRITE in the RawData of a SoundWave like I did here’s the correct way :

Use a FSampleBuffer and a FSoundWavePCMWriter instead :slight_smile:

USoundWave* TransformedSoundWave = NewObject<USoundWave>();

// Write the audio data to the sound wave
Audio::FSoundWavePCMWriter Writer;
Audio::FSampleBuffer TransformedBuffer(InputAudio.data(), InputAudio.size(), 2, 32000);
TransformedSoundWave = Writer.SynchronouslyWriteSoundWave(TransformedBuffer, nullptr, nullptr);

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.