IsInGameThread Exception thrown

Hii,
I’m trying to convert an audio signal using threads here’s how it works :

I have an Actor named AAudioActor and when I press the vKey, I call the start imitation Function of it :

void AAudioCaptureActor::StartImitation()
{
  if (_bIsRunning)
    return;
  
  _bIsRunning = true;
  _thread = FRunnableThread::Create(new AudioProcessorWorker(this), TEXT("AudioProcessorWorker"), 0, TPri_Highest);
}

As you see, it instantiates a worker inheriting from FRunnable :

class AudioProcessorWorker : public FRunnable
{
private:
	AAudioCaptureActor* _instance;

public:
	AudioProcessorWorker(AAudioCaptureActor* instance) : _instance(instance){}

	virtual ~AudioProcessorWorker() {
		if (_instance->_thread)
			_instance->_thread->Kill();
		delete _instance->_thread;
	}

	virtual bool Init() override { return true; }
	virtual void Stop() override { _instance->_bIsRunning = false; }
	virtual void Exit() override {}

	virtual uint32 Run() override
	{
		UE_LOG(LogTemp, Warning, TEXT("AudioProcessorWorker::BeforeLoop"));
		while (_instance->_bIsRunning)
		{
			FAudioData AudioData;
			AudioData.Samples =_instance->CaptureAudioData();
			if (_instance->AudioDataQueue.Dequeue(AudioData))
			{
				UE_LOG(LogTemp, Warning, TEXT("AudioProcessorWorker::DataDetected"));
				// Process audio data
				_instance->ProcessAudioData(AudioData.Samples);
			}
			FPlatformProcess::Sleep(0.01f); // Adjust sleep duration as needed
			UE_LOG(LogTemp, Warning, TEXT("AudioProcessorWorker::InLoop"));
			_instance->PlayAudioData(AudioData.Samples);
		}
		UE_LOG(LogTemp, Warning, TEXT("AudioProcessorWorker::AfterLoop"));
		return 0;
	}
};

My issue occurs in the Run() function of my thread, when I call the CaptureAudioData function of my actor :

std::vector<int16> AAudioCaptureActor::CaptureAudioData()
{

  UClass* AudioCaptureComponentClass = UMyCaptureComponent::StaticClass();
  UMyCaptureComponent* AudioCapture = Cast<UMyCaptureComponent>(AddComponentByClass(AudioCaptureComponentClass, false, FTransform::Identity, false));

  // Initialize variables for audio capture
  float SampleRate = 32000.0f;
  float NumChannels = 2; // Assuming stereo audio
  const int32 NumSamplesPerFrame = 320; // 10 ms per frame at 32 kHz sample rate

  //// 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 audio
  Audio::FAlignedFloatBuffer Buffer = MixerDevice->StopRecording(Submix, NumChannels, SampleRate);

  // Convert captured audio data to int16 format
  std::vector<int16> InputAudio;
  InputAudio.reserve(Buffer.Num() / NumChannels);
  for (float Sample : Buffer)
  {
    // Scale floating-point sample to int16 range
    int16 ScaledSample = static_cast<int16>(Sample);
    InputAudio.push_back(ScaledSample);
  }
  return InputAudio;
}

This line:

Audio::FMixerDevice* MixerDevice = FAudioDeviceManager::GetAudioMixerDeviceFromWorldContext(GetWorld());

tells me that the current thread I’m trying to use an Unreal’s function without being in the game thread could anyone suggest me on how I could fix my code to work in the game thread ?

You can’t use GetWorld from within your frunnable. It is already a separate thread and calling GetWrold is not thread safe. You need to pass in only thread-safe variables from your thread manager that invokes the thread.

The goal of this class is to process in real time the audio (first I capture it from my mic, then I process it and then play it) so I don’t really see how I could move the capture audio out of my thread thank you for your answer I’ll try to find an alternative way

You could try encapsulating the code in

if(IsInGameThread()){
   if (GIsGameThreadIdInitialized){
     // code here
   }
}

Though I’m sure it will fire inside of FRunnable on a different thread. You would have to check with a breakpoint

You’d probably need
include “CoreGlobals.h”
if it’s not included by default.

Yeah I already checked using

check(IsInGameThread())

And yes you’re right sadly the FRunnable thread doesn’t run on the game’s thread I’ll see if I can my AudioIn in an other way

perhaps you could access the audio thread directly through FAudioThread?

AudioCaptureBlueprintLibrary also seems to have code that works with FAudioThread

Solved I recorded my audio samples using the JUCE Library which runs in its own thread

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