Files
UnrealEngine/Engine/Source/Runtime/AudioCaptureImplementations/AudioCaptureRtAudio/Private/RtAudioWrapper.cpp
2025-05-18 13:04:45 +08:00

250 lines
6.0 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "RtAudioWrapper.h"
#include "AudioCaptureCoreLog.h"
#if PLATFORM_MICROSOFT || PLATFORM_MAC
#include "RtAudio.h"
#include "Templates/PimplPtr.h"
#include "Containers/UnrealString.h"
THIRD_PARTY_INCLUDES_START
#include <stdexcept>
#include <string>
THIRD_PARTY_INCLUDES_END
namespace Audio
{
FRtAudioInputWrapper::FRtAudioInputWrapper()
: Impl(MakePimpl<RtAudio>())
{
}
// Returns ID of default input device
uint32 FRtAudioInputWrapper::GetDefaultInputDevice()
{
static const TCHAR* Action = TEXT("get default input device");
try
{
return Impl->getDefaultInputDevice();
}
catch (const std::exception& e)
{
FString Message(e.what());
UE_LOG(LogAudioCaptureCore, Error, TEXT("Failed to %s: %s."), Action, *Message);
}
catch (...)
{
UE_LOG(LogAudioCaptureCore, Error, TEXT("Failed to %s."), Action);
}
return InvalidDeviceID;
}
// Returns info about device.
FRtAudioInputWrapper::FDeviceInfo FRtAudioInputWrapper::GetDeviceInfo(uint32 InDeviceID)
{
static const TCHAR* Action = TEXT("get device info");
try
{
RtAudio::DeviceInfo RtInfo = Impl->getDeviceInfo(InDeviceID);
return FDeviceInfo {static_cast<float>(RtInfo.preferredSampleRate), RtInfo.inputChannels};
}
catch (const std::exception& e)
{
FString Message(e.what());
UE_LOG(LogAudioCaptureCore, Error, TEXT("Failed to %s: %s."), Action, *Message);
}
catch (...)
{
UE_LOG(LogAudioCaptureCore, Error, TEXT("Failed to %s."), Action);
}
return FDeviceInfo{};
}
// Suppress deprecation warning for use of FAudioCallback
PRAGMA_DISABLE_DEPRECATION_WARNINGS
// Opens an audio stream. Returns true on success, false on error.
bool FRtAudioInputWrapper::OpenStream(const FStreamParameters& InStreamParams, float InDesiredSampleRate, uint32* InOutDesiredBufferNumFrames, FAudioCallback Callback, void* InUserData)
{
static const TCHAR* Action = TEXT("open RtAudio stream");
try
{
RtAudio::StreamParameters RtStreamParams;
RtStreamParams.deviceId = InStreamParams.DeviceID;
RtStreamParams.nChannels = InStreamParams.NumChannels;
RtStreamParams.firstChannel = 0;
Impl->openStream(nullptr, &RtStreamParams, RTAUDIO_SINT16, InDesiredSampleRate, InOutDesiredBufferNumFrames, Callback, InUserData);
}
catch (const std::exception& e)
{
FString Message(e.what());
UE_LOG(LogAudioCaptureCore, Error, TEXT("Failed to %s: %s."), Action, *Message);
return false;
}
catch (...)
{
UE_LOG(LogAudioCaptureCore, Error, TEXT("Failed to %s."), Action);
return false;
}
return true;
}
PRAGMA_ENABLE_DEPRECATION_WARNINGS
// Starts an open stream
void FRtAudioInputWrapper::StartStream()
{
static const TCHAR* Action = TEXT("start RtAudio stream");
try
{
Impl->startStream();
}
catch (const std::exception& e)
{
FString Message(e.what());
UE_LOG(LogAudioCaptureCore, Error, TEXT("Failed to %s: %s."), Action, *Message);
}
catch (...)
{
UE_LOG(LogAudioCaptureCore, Error, TEXT("Failed to %s."), Action);
}
}
// Returns true if the stream is open.
bool FRtAudioInputWrapper::IsStreamOpen()
{
static const TCHAR* Action = TEXT("check if RtAudio stream is open");
try
{
return Impl->isStreamOpen();
}
catch (const std::exception& e)
{
FString Message(e.what());
UE_LOG(LogAudioCaptureCore, Error, TEXT("Failed to %s: %s."), Action, *Message);
}
catch (...)
{
UE_LOG(LogAudioCaptureCore, Error, TEXT("Failed to %s."), Action);
}
return false;
}
// Stops stream, discarding any remaining samples
void FRtAudioInputWrapper::AbortStream()
{
static const TCHAR* Action = TEXT("abort RtAudio stream");
try
{
Impl->abortStream();
}
catch (const std::exception& e)
{
FString Message(e.what());
UE_LOG(LogAudioCaptureCore, Error, TEXT("Failed to %s: %s."), Action, *Message);
}
catch (...)
{
UE_LOG(LogAudioCaptureCore, Error, TEXT("Failed to %s."), Action);
}
}
// Stops stream, allowing any remaining samples to be played.
void FRtAudioInputWrapper::StopStream()
{
static const TCHAR* Action = TEXT("stop RtAudio stream");
try
{
Impl->stopStream();
}
catch (const std::exception& e)
{
FString Message(e.what());
UE_LOG(LogAudioCaptureCore, Error, TEXT("Failed to %s: %s."), Action, *Message);
}
catch (...)
{
UE_LOG(LogAudioCaptureCore, Error, TEXT("Failed to %s."), Action);
}
}
// Close stream and free associated memory.
void FRtAudioInputWrapper::CloseStream()
{
static const TCHAR* Action = TEXT("close RtAudio stream");
try
{
Impl->closeStream();
}
catch (const std::exception& e)
{
FString Message(e.what());
UE_LOG(LogAudioCaptureCore, Error, TEXT("Failed to %s: %s."), Action, *Message);
}
catch (...)
{
UE_LOG(LogAudioCaptureCore, Error, TEXT("Failed to %s."), Action);
}
}
}
#else
namespace Audio
{
FRtAudioInputWrapper::FRtAudioInputWrapper()
{
UE_LOG(LogAudioCaptureCore, Error, TEXT("RtAudio is not supported on this platform"));
}
// Returns ID of default input device
uint32 FRtAudioInputWrapper::GetDefaultInputDevice()
{
return InvalidDeviceID;
}
// Returns info about device.
FRtAudioInputWrapper::FDeviceInfo FRtAudioInputWrapper::GetDeviceInfo(uint32 InDeviceID)
{
return FDeviceInfo{};
}
// Opens an audio stream. Returns true on success, false on error.
bool FRtAudioInputWrapper::OpenStream(const FStreamParameters& InStreamParams, float InDesiredSampleRate, uint32* InOutDesiredBufferNumFrames, FAudioCallback Callback, void* InUserData)
{
return false;
}
// Starts an open stream
void FRtAudioInputWrapper::StartStream()
{
}
// Returns true if the stream is open.
bool FRtAudioInputWrapper::IsStreamOpen()
{
return false;
}
// Stops stream, discarding any remaining samples
void FRtAudioInputWrapper::AbortStream()
{
}
// Stops stream, allowing any remaining samples to be played.
void FRtAudioInputWrapper::StopStream()
{
}
// Close stream and free associated memory.
void FRtAudioInputWrapper::CloseStream()
{
}
}
#endif // #if PLATFORM_MICROSOFT || PLATFORM_MAC