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