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 ?