Module: LCKAudio | Version: 1.0 | Platforms: All
Overview
The LCK SDK features a modular audio capture system that supports multiple audio sources including game audio, microphone input, and voice chat. Audio sources implement a common interface and register via Unreal’s modular features system for automatic discovery.
Audio Source Plugins
LCKUnrealAudio Unreal Engine native audio capture for game audio and microphone
LCKOboe High-performance Android microphone capture via Google Oboe
LCKVivox Vivox voice chat audio capture for multiplayer games
LCKFMOD FMOD Studio game audio integration
LCKWwise Audiokinetic Wwise game audio integration
Architecture
┌─────────────────────────────────────────────────────────────┐
│ LCK Recording System │
├─────────────────────────────────────────────────────────────┤
│ FLCKAudioMix │
│ (Audio Mixer) │
├─────────────────────────────────────────────────────────────┤
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ ILCKAudio │ │ ILCKAudio │ │ ILCKAudio │ │
│ │ Source │ │ Source │ │ Source │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │ │
└─────────┼─────────────────┼─────────────────┼───────────────┘
│ │ │
┌─────────▼─────┐ ┌───────▼───────┐ ┌─────▼────────┐
│ LCKUnreal │ │ LCKFMOD │ │ LCKVivox │
│ Audio │ │ Source │ │ Source │
└───────────────┘ └───────────────┘ └──────────────┘
Plugin Capabilities
Source Game Microphone VoiceChat Module Platform LCKUnrealAudio Yes Yes No LCKUnrealAudio All LCKFMOD Yes No No LCKFMOD All LCKWwise Yes No No LCKWwise Win64, Android LCKOboe No Yes No LCKOboe Android LCKVivox Yes Yes No LCKVivox All
Audio Configuration Validation
Before recording starts, the audio system validates the configuration to ensure audio sources are properly set up. Use FLCKAudioConfigValidation to inspect the current state:
FLCKAudioConfigValidation Validation = AudioSystem -> ValidateConfig ();
if ( ! Validation . bIsValid )
{
for ( const FString & Warning : Validation . Warnings )
{
UE_LOG (LogLCKAudio, Warning, TEXT ( " %s " ), * Warning);
}
}
// Check microphone configuration
if ( Validation . bHasMicrophoneSource )
{
UE_LOG (LogLCKAudio, Log, TEXT ( "Mic sources: %d enabled, %d total" ),
Validation . EnabledMicrophoneSources . Num (),
Validation . MicrophoneSourceCount );
}
See FLCKAudioConfigValidation in the types reference.
Audio Plugin Discovery
Use FLCKAudioPluginInfo to query registered audio plugins at runtime:
TArray < FLCKAudioPluginInfo > Plugins = AudioSystem -> GetPluginInfo ();
for ( const FLCKAudioPluginInfo & Plugin : Plugins)
{
UE_LOG (LogLCKAudio, Log, TEXT ( "Plugin: %s ( %s ) - Loaded: %s , Game: %s , Mic: %s " ),
* Plugin . DisplayName ,
* Plugin . ModuleName ,
Plugin . bIsLoaded ? TEXT ( "Yes" ) : TEXT ( "No" ),
Plugin . bGameAudioEnabled ? TEXT ( "Yes" ) : TEXT ( "No" ),
Plugin . bMicrophoneEnabled ? TEXT ( "Yes" ) : TEXT ( "No" ));
}
See FLCKAudioPluginInfo in the types reference.
Audio Channel System
Channel Types
enum ELCKAudioChannel : uint64
{
None = 0 , // No audio channel
Game = 1 , // Game audio output
Microphone = 1 << 1 , // Microphone input
VoiceChat = 1 << 2 , // Voice chat audio (reserved)
Max = 1 << 3 // Maximum value marker
};
Channel Sources GameUnrealAudio, FMOD, Wwise, Vivox (incoming) MicrophoneUnrealAudio, Oboe, Vivox (outgoing) VoiceChatReserved for future use
LCKVivox maps incoming voice chat to Game channel and outgoing microphone to Microphone channel for unified handling.
Channel Masks
// Create a channel mask for multiple channels
TLCKAudioChannelsMask Channels = ELCKAudioChannel ::Game | ELCKAudioChannel ::Microphone;
// Start capture with specific channels
AudioSource -> StartCapture (Channels);
// Check if mask contains a channel
bool HasMicrophone = (Channels & ELCKAudioChannel ::Microphone) != 0 ;
Channel Source Configuration Types
The SDK provides helper structs for common channel configurations:
Struct Channels Use Case FLCKAudioSourceChannelsGame + Microphone Full audio capture FLCKAudioSourceGameOnlyGame only Game audio without mic FLCKAudioSourceMicOnlyMicrophone only Mic-only capture FLCKAudioSourceVoiceChatMicrophone + VoiceChat Voice chat recording
See Audio Source Channel Types in the types reference.
ILCKAudioSource Interface
All audio sources implement this interface:
class ILCKAudioSource : public IModularFeature , public TSharedFromThis < ILCKAudioSource >
{
public:
static FName GetModularFeatureName () noexcept ;
// Audio data delegate (single delegate, NOT multicast)
DECLARE_MULTICAST_DELEGATE_FourParams ( FDelegateRenderAudio ,
TArrayView < const float > /*PCM-interleaved*/ , int32 /*Channels*/ , int32 /*SampleRate*/ , ELCKAudioChannel /*SourceChannel*/ );
typedef FDelegateRenderAudio ::FDelegate FOnRenderAudioDelegate;
FOnRenderAudioDelegate OnAudioDataDelegate;
// Control methods
virtual bool StartCapture () noexcept = 0 ;
virtual bool StartCapture ( TLCKAudioChannelsMask Channels ) noexcept = 0 ;
virtual void StopCapture () noexcept = 0 ;
// Query methods
virtual float GetVolume () const noexcept = 0 ;
virtual const FString & GetSourceName () const noexcept = 0 ;
TLCKAudioChannelsMask GetSupportedChannels () const noexcept ;
protected:
TLCKAudioChannelsMask SupportedChannels;
};
OnAudioDataDelegate is a single delegate , not multicast. Only one listener can be bound at a time using BindLambda(). The FLCKAudioMix class internally manages binding to multiple sources.
Discovering Audio Sources
#include "Features/IModularFeatures.h"
// Find all registered audio sources
TArray < ILCKAudioSource *> AudioSources;
IModularFeatures :: Get (). GetModularFeatureImplementations < ILCKAudioSource > (
ILCKAudioSource :: GetModularFeatureName (),
AudioSources
);
for (ILCKAudioSource * Source : AudioSources)
{
UE_LOG (LogTemp, Log, TEXT ( "Found audio source: %s " ), * Source -> GetSourceName ());
// Check supported channels
if ( Source -> GetSupportedChannels () & ELCKAudioChannel ::Game)
{
UE_LOG (LogTemp, Log, TEXT ( " - Supports game audio" ));
}
if ( Source -> GetSupportedChannels () & ELCKAudioChannel ::Microphone)
{
UE_LOG (LogTemp, Log, TEXT ( " - Supports microphone" ));
}
}
Listening to Audio Data
ILCKAudioSource * Source = /* obtained via modular features */ ;
// Use BindLambda for single delegate (replaces any existing binding)
Source -> OnAudioDataDelegate . BindLambda ([](
TArrayView < const float > PCM ,
int32 Channels ,
int32 SampleRate ,
ELCKAudioChannel SourceChannel )
{
// PCM: Interleaved float audio samples
// Channels: Number of channels (typically 2 for stereo)
// SampleRate: Audio sample rate in Hz (typically 48000)
// SourceChannel: Which audio channel this data represents
});
All audio sources provide audio in this format:
Property Value Sample Format 32-bit float Channels Stereo (2 channels) Layout Interleaved (L,R,L,R,…) Sample Rate Match encoder (typically 48000 Hz)
Thread Safety
OnAudioDataDelegate may be called from any thread
Implementers should use thread-safe data structures
The encoder handles cross-thread data marshaling
Log Category
DECLARE_LOG_CATEGORY_EXTERN (LogLCKAudio, Log, All);