Skip to main content
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

SourceGameMicrophoneVoiceChatModulePlatform
LCKUnrealAudioYesYesNoLCKUnrealAudioAll
LCKFMODYesNoNoLCKFMODAll
LCKWwiseYesNoNoLCKWwiseWin64, Android
LCKOboeNoYesNoLCKOboeAndroid
LCKVivoxYesYesNoLCKVivoxAll

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
};
ChannelSources
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:
StructChannelsUse Case
FLCKAudioSourceChannelsGame + MicrophoneFull audio capture
FLCKAudioSourceGameOnlyGame onlyGame audio without mic
FLCKAudioSourceMicOnlyMicrophone onlyMic-only capture
FLCKAudioSourceVoiceChatMicrophone + VoiceChatVoice 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
});

Audio Format

All audio sources provide audio in this format:
PropertyValue
Sample Format32-bit float
ChannelsStereo (2 channels)
LayoutInterleaved (L,R,L,R,…)
Sample RateMatch 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);