Space Panda

UE 4.23에서 마이크에서 들어오는 PCM 데이터 C++에서 접근하기 본문

Unreal Engine

UE 4.23에서 마이크에서 들어오는 PCM 데이터 C++에서 접근하기

Space Panda 2019. 10. 2. 18:48

1. 마이크 인풋을 위해서 해야될 설정

 

윈도우 개발 환경에서 마이크 인풋을 얻기 위해서 "프로젝트폴더\Config\WindowsEngine.ini" 파일에 아래의 코드(?)를 추가해줘야합니다.

[Audio]
AudioDeviceModuleName=AudioMixerXAudio2

 

 

2. 마이크 인풋 확인

 

위의 설정이 끝났다면 마이크 인풋을 확인해봅시다.

 

   1) Actor를 하나 만들고 AudioCaptureComponent를 추가합니다

 

   2) AudioCaptureComponent의 디테일 패널에서 AutoActivate를 체크(true) 해줍니다.

 

   3) 만들어준 액터를 레벨에 올리고 플레이합니다.

 

위의 과정을 거치면 마이크 인풋이 들어오는 상황이면 음성이 스피커로 들리는 것을 확인할 수 있습니다.

 

 

3. AudioCaptureComponent 상속받기

 

AudioCaptureComponent가 마이크 인풋을 받는 역할을 하는 것을 2번에서 확인하였습니다.

PCM 데이터의 접근을 위해서 AudioCaptureComponent.h 헤더 파일의 정의를 살펴봤으나... CaptureAudioData라는 Tarray<float>형 변수가 있기는 하지만 private 접근 제한자로 제한되어 있는것으로 확인 되었습니다.

 

접근할 방법을 찾으며 cpp파일을 찾아보다가, 아래의 함수의 OutAudio를 통해서 PCM 데이터가 전해진다는것을 확인하게 되었습니다. (디버깅을 통해보니 아래의 함수는 틱(?)마다 호출되는 것으로 보입니다.)

protected:
virtual int32 OnGenerateAudio(float* OutAudio, int32 NumSamples) override;

 

참고로 상속을 위한 DependencyModuleName은 "AudioCapture", "AudioMixer" 두가지입니다

 

 

4. OnGenerateAudio 가상함수 구현

 

이제 OnGenerateAudio를 통해서 PCM 데이터에 접근이 가능한데 코드는 다음과 같습니다.

#pragma once

#include "CoreMinimal.h"
#include "AudioCaptureComponent.h"
#include "MicAudioComponent.generated.h"

/**
 * 
 */
UCLASS(ClassGroup = Synth, meta = (BlueprintSpawnableComponent))
class UMicAudioComponent : public UAudioCaptureComponent
{
	GENERATED_BODY()

protected:

	UMicAudioSendComponent(const FObjectInitializer& ObjectInitializer);
	virtual int32 OnGenerateAudio(float* OutAudio, int32 NumSamples) override;
};

MicAudioComponent.h

 

#include "MicAudioComponent.h"
#include "Misc/DateTime.h"

UMicAudioComponent::UMicAudioComponent(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
}

int32 UMicAudioComponent::OnGenerateAudio(float* OutAudio, int32 NumSamples)
{
    int32 OutputSamplesGenerated = 0;
    OutputSamplesGenerated = Super::OnGenerateAudio(OutAudio, NumSamples);
    
    TArray<float> pcmData;
    pcmData.Init(0.f, OutputSamplesGenerated);
    FMemory::Memcpy(pcmData.GetData(), OutAudio, OutputSamplesGenerated * sizeof(float));
    
    //여기에서 pcmData로 원하는 작업!!
    FDateTime currentTime = FDateTime::Now();
    UE_LOG(LogTemp, Log, TEXT("[%d : %d]PCM Data"), currentTime.GetSecond(), currentTime.GetMillisecond());
    //
    
	return OutputSamplesGenerated;
}

MicAudioComponent.cpp

 

 

아래 cpp 파일의 주석부분에서 원하는데로 pcm데이터를 사용할수있습니다.

 

 

 

 

위의 과정을 거치고 언리얼 엔진 에디터에서 확인하면 위와 같이 로그가 제대로 찍히는 것을 알수있습니다.

 

 

 

Comments