audiocapturemgr is a userspace daemon that captures live audio from the platform audio subsystem and exposes control and clip-ready notifications over the IARM inter-process communication bus. Audio payloads are delivered to clients via local IPC endpoints (for example UNIX domain sockets) rather than over IARM.

The service exposes audio capture sessions on a per-client basis. Each session is associated with the primary audio source and a delivery mode chosen at session open time: a buffered mode that maintains a rolling precapture queue and extracts audio clips on demand, or a realtime streaming mode that pushes live audio directly to the requesting client over a local socket connection. Clients are notified asynchronously over the bus when a requested audio clip becomes available.

Internally, a central capture manager owns the connection to the audio hardware, maintains data queues, and distributes incoming audio to all active client sessions. Each delivery mode is handled by a dedicated subsystem responsible for either managing the precapture buffer and scheduling clip extraction, or forwarding live audio buffers to a connected socket consumer.

```mermaid
flowchart LR

classDef Apps  stroke:#00B9F1,fill:#E6F7FD,stroke-width:2px;
classDef RDKMW stroke:#75D701,fill:#F1FFE6,stroke-width:2px;
classDef VL stroke:#808080,fill:#F2F2F2,stroke-width:2px;

subgraph Apps["Apps & Runtimes"]
    ClientApps["Client Applications"]
end

subgraph RDKMW["RDK Core Middleware"]
    IARMClients["IARM Clients"]
    ACM["audiocapturemgr\n(standalone daemon)"]
    IARM["IARM Bus"]
end

subgraph VL["Vendor Layer"]
    RMF["RMF AudioCapture HAL\n(media-utils)"]
end

ClientApps -->|Firebolt APS| IARMClients
IARMClients --> IARM
IARM --> ACM
ACM -->|API Calls| RMF
RMF -->|Service Interaction| ACM
ACM -->|Event Notification| IARM
```

Key Features & Responsibilities:


Design

The component is organized around a single capture source manager (q_mgr) with a client registration model. Audio data arrives via the RMF capture callback (q_mgr::data_callback) registered in q_mgr::start() (via RMF_AudioCapture_Start() settings) and is enqueued as audio_buffer objects with reference counting. A dedicated data_processor_thread swaps incoming and outgoing queues under mutex protection and dispatches buffer pointers to all registered clients, while update_buffer_references() adjusts refcounts based on active clients. A data_monitor thread runs independently to detect and log periods where inflow byte count stops advancing. Session orchestration in acm_session_mgr separates control-plane concerns (IARM method dispatch, session lookup, result mapping) from data-plane processing (capture, queuing, conversion, output transport). Queue overflow is bounded by MAX_QMGR_BUFFER_DURATION_S = 30 seconds, beyond which the incoming queue is flushed.

Northbound interaction flows exclusively through IARM, where clients invoke named calls and receive result codes and events. Southbound interaction uses the RMF AudioCapture APIs currently exercised by this component — Open, GetDefaultSettings, Start, Stop, and Close (primary source only).

IPC mechanisms include IARM call registration and event broadcast for control and asynchronous notifications, UNIX domain sockets (AF_UNIX, SOCK_STREAM) for realtime PCM streaming (ip_out_client) and socket-delivery clip output (music_id_client/socket_adaptor), and internal control pipes combined with select() loops to shut down listener threads in ip_out_client.

Buffered clip output (opened with BUFFERED_FILE_OUTPUT) is currently delivered over a UNIX domain socket (the session API constructs music_id_client in SOCKET_OUTPUT mode, and dataLocator is the socket path). File-mode delivery via std::ofstream exists in music_id_client but is not wired into the session manager.

```mermaid
graph LR

subgraph Proc["audiocapturemgr process (C++)"]
    direction TB
    subgraph Control["Control Plane"]
        Main["acm_main\nmain / launcher"]
        SessionMgr["acm_session_mgr\nIARM method handlers\nsession list management"]
    end
    subgraph Capture["Capture & Queuing"]
        QMgr["q_mgr\nRMF capture device\nqueue manager / client fan-out"]
        Buf["audio_buffer\nrefcounted PCM buffer"]
    end
    subgraph Delivery["Output Delivery"]
        MID["music_id_client\nrolling precapture queue\nclip extraction worker"]
        IPO["ip_out_client\nrealtime UNIX socket writer\nlistener thread"]
        Conv["audio_converter\ndownmix / downsample\nsink abstraction"]
        Sock["socket_adaptor\nUNIX socket listener\nconnected-callback dispatch"]
    end
end

subgraph External["External Systems"]
    direction TB
    IARMBus[("IARM Bus")]
    RMFHAL[("RMF AudioCapture HAL\n(media-utils)")]
    UDSClients[("UNIX Domain\nSocket Clients")]
end

Main --> SessionMgr
SessionMgr -->|Event Notification| IARMBus
IARMBus --> SessionMgr
SessionMgr --> MID
SessionMgr --> IPO
QMgr --> RMFHAL
RMFHAL -->|Service Interaction| QMgr
QMgr --> Buf
MID --> QMgr
MID --> Conv
MID --> Sock
IPO --> QMgr
IPO --> UDSClients
Sock --> UDSClients
```

Threading Model

Prerequisites and Dependencies

Platform and Integration Requirements


Component State Flow

Initialization to Active State

```mermaid
sequenceDiagram
    participant System as systemd
    participant Comp as audiocapturemgr
    participant IARM as IARM Bus
    participant Q as q_mgr
    participant RMF as RMF AudioCapture

    System->>Comp: ExecStart /usr/bin/audiocapturemgr
    Comp->>IARM: IARM_Bus_Init("audiocapturemgr")
    Comp->>IARM: IARM_Bus_Connect()
    Comp->>IARM: IARM_Bus_RegisterEvent(IARMBUS_MAX_ACM_EVENT)
    Comp->>IARM: IARM_Bus_RegisterCall(open, close, start, stop, requestSample, ...)
    Note over Comp: Control plane active — IARM methods available

    IARM->>Comp: open(source=0, output_type)
    Comp->>Comp: create session + create client (music_id or ip_out) bound to existing q_mgr
    Note over Comp,Q: q_mgr performs RMF Open + GetDefaultSettings during acm_session_mgr initialization

    IARM->>Comp: start(session_id)
    Comp->>Q: register_client + start()
    Q->>RMF: Start capture with settings and data callback
    RMF-->>Q: audio data via callback

    Q-->>Comp: clip ready (callback)
    Comp->>IARM: BroadcastEvent DATA_CAPTURE_IARM_EVENT_AUDIO_CLIP_READY

    System->>Comp: terminate (signal)
    Comp->>IARM: IARM_Bus_Disconnect + Term
```

Runtime State Changes

State Change Triggers (all via IARM calls):

Context Switching Scenarios:


Call Flows

Initialization Call Flow

```mermaid
sequenceDiagram
    participant Main as acm_main
    participant Mgr as acm_session_mgr
    participant IARM as IARM Bus

    Main->>Mgr: get_instance()->activate()
    Mgr->>IARM: IARM_Bus_Init("audiocapturemgr")
    Mgr->>IARM: IARM_Bus_Connect()
    Mgr->>IARM: IARM_Bus_RegisterEvent(IARMBUS_MAX_ACM_EVENT)
    Mgr->>IARM: IARM_Bus_RegisterCall(requestSample)
    Mgr->>IARM: IARM_Bus_RegisterCall(open)
    Mgr->>IARM: IARM_Bus_RegisterCall(close)
    Mgr->>IARM: IARM_Bus_RegisterCall(start)
    Mgr->>IARM: IARM_Bus_RegisterCall(stop)
    Mgr->>IARM: IARM_Bus_RegisterCall(getDefaultAudioProperties)
    Mgr->>IARM: IARM_Bus_RegisterCall(getAudioProperties)
    Mgr->>IARM: IARM_Bus_RegisterCall(getOutputProperties)
    Mgr->>IARM: IARM_Bus_RegisterCall(setAudioProperties)
    Mgr->>IARM: IARM_Bus_RegisterCall(setOutputProperties)
    Main->>Main: pause()
```

Request Processing Call Flow

```mermaid
%%{init: { 'sequence': { 'actorMargin': 80, 'width': 200, 'messageMargin': 50, 'noteMargin': 25, 'mirrorActors': true, 'messageFontSize': 24, 'noteFontSize': 22, 'actorFontSize': 22 } } }%%
sequenceDiagram
    participant Client as IARM Client
    participant IARM as IARM Bus
    participant Mgr as acm_session_mgr
    participant MID as music_id_client
    participant Q as q_mgr

    Client->>IARM: IARM_Bus_Call(requestSample, {duration, is_precapture})
    IARM->>Mgr: get_sample_handler()

    Note over Client,Q: Branch on is_precapture flag

    alt is_precapture == true
        Note over Mgr,Q: Precapture path — serve from rolling buffer
        Mgr->>MID: grab_precaptured_sample(filename)
        MID->>Q: use buffered audio_buffer queue
        MID-->>Mgr: result (immediate)

    else is_precapture == false
        Note over Mgr,MID: Fresh capture path — defer until audio is collected
        Mgr->>MID: grab_fresh_sample(seconds, filename, callback)
        Note over MID: worker thread decrements timer, fulfills on completion
        MID-->>Mgr: async via request_callback
    end

    Note over Mgr,Client: Common path — notify client with clip location
    Mgr->>IARM: IARM_Bus_BroadcastEvent(DATA_CAPTURE_IARM_EVENT_AUDIO_CLIP_READY,{dataLocator})
    IARM-->>Client: event payload with dataLocator
```

Internal Modules

Module / ClassDescriptionKey Files
acm_mainProcess entry point. Calls acm_session_mgr::activate(), blocks in pause(), and calls deactivate() on exit. Optionally drops root privileges when built with DROP_ROOT_PRIV.src/acm_main.cpp
acm_session_mgrIARM API surface that manages the session list (m_sessions), dispatches all IARM method handlers, creates/destroys client and source objects, and issues BroadcastEvent calls. Singleton via g_singleton.src/acm_session_mgr.cpp, include/acm_session_mgr.h
q_mgrOwns the RMF capture device handle, dual buffer queues, processing thread (semaphore-driven), data-monitor thread, and the list of registered audio_capture_client objects. Calls RMF_AudioCapture_Open, RMF_AudioCapture_GetDefaultSettings, RMF_AudioCapture_Start, RMF_AudioCapture_Stop, and RMF_AudioCapture_Close.src/audio_capture_manager.cpp, include/audio_capture_manager.h
music_id_clientBuffered clip extraction client. Maintains a rolling std::list<audio_buffer*> queue sized by precapture duration. Fulfills clip requests immediately (precapture) or via a worker thread timer (fresh sample). Supports file-output and socket-output delivery modes, using socket_adaptor for the latter.src/music_id.cpp, include/music_id.h
ip_out_clientRealtime UNIX socket streaming client. Opens a listening UNIX socket on a path prefixed /tmp/acm_ip_out_. Accepts one connection (MAX_CONNECTIONS = 1) via a pthread-based listener thread controlled by a non-blocking pipe. Writes live PCM buffers on each data_callback invocation.src/ip_out.cpp, include/ip_out.h
audio_converterDetermines the required conversion operation (passthrough, downmix, downsample, or combined) from input/output audio_properties_t structs and applies it to a std::list<audio_buffer*>. Writes converted output via an audio_converter_sink abstraction (file or memory).src/audio_converter.cpp, include/audio_converter.h
audio_bufferRefcounted PCM buffer object. Created by q_mgr per incoming capture callback and freed when refcount reaches zero via unref_audio_buffer(). A global mutex protects refcount operations.src/audio_buffer.cpp, include/audio_buffer.h
socket_adaptorUNIX domain socket listener helper for music_id_client socket-delivery mode. Starts listening on a supplied path, accepts one connection on a std::thread, and invokes a registered data-ready callback.src/socket_adaptor.cpp, include/socket_adaptor.h
acm_iarm_interfaceLegacy IARM interface (original enableCapture / requestSample API). Kept alongside the session manager for backward compatibility.src/acm_iarm_interface.cpp

Component Interactions

Interaction Matrix

Target Component / LayerInteraction PurposeKey APIs / Topics
HAL

RMF AudioCaptureOpen, configure, and control the capture device; receive PCM audio data via callback.RMF_AudioCapture_Open, RMF_AudioCapture_GetDefaultSettings, RMF_AudioCapture_Start, RMF_AudioCapture_Stop, RMF_AudioCapture_Close
Component APIs

IARM BusReceive control calls from clients and publish clip-ready events.IARM_Bus_Init, IARM_Bus_Connect, IARM_Bus_RegisterEvent, IARM_Bus_RegisterCall, IARM_Bus_BroadcastEvent, IARM_Bus_Disconnect, IARM_Bus_Term
External Systems

UNIX domain socket clientsReceive realtime PCM stream (ip_out) or audio clip bytes (music_id socket mode).socket, bind, listen, accept, write on paths under /tmp/

Events Published

Event NameIARM / JSON-RPC TopicTrigger ConditionSubscriber Components
DATA_CAPTURE_IARM_EVENT_AUDIO_CLIP_READYIARM event on bus audiocapturemgr (index 0)request_callback invoked after clip generation completes (immediate precapture or fresh-sample timeout)Any IARM client that registers a handler for this event

IPC Flow Patterns

Primary Request / Response Flow:

```mermaid
sequenceDiagram
    participant Client as Client Application
    participant IARM as IARM Bus
    participant ACM as audiocapturemgr
    participant RMF as RMF AudioCapture

    Client->>IARM: IARM_Bus_Call("audiocapturemgr", method, payload)
    IARM->>ACM: Dispatch to registered handler
    ACM->>RMF: Start, stop, or configure capture as needed
    RMF-->>ACM: Status or callback data
    ACM-->>IARM: Result code written into payload struct
    IARM-->>Client: Call return with populated payload
```

Event Notification Flow:

```mermaid
sequenceDiagram
    participant Client as IARM Client
    participant ACM as audiocapturemgr
    participant IARM as IARM Bus

    Client->>IARM: IARM_Bus_Call(requestSample, {duration, is_precapture})
    IARM->>ACM: Dispatch to registered handler
    ACM->>ACM: generate clip (immediate or deferred)
    ACM->>IARM: IARM_Bus_BroadcastEvent(DATA_CAPTURE_IARM_EVENT_AUDIO_CLIP_READY)
    IARM-->>Client: event payload {dataLocator}
```

Implementation Details

Major HAL APIs Integration

HAL APIPurposeImplementation File
RMF_AudioCapture_Open()Opens the capture device for the primary audio source and obtains a handle during q_mgr construction.src/audio_capture_manager.cpp
RMF_AudioCapture_GetDefaultSettings()Retrieves default RMF_AudioCapture_Settings (used to seed/restore capture settings before (re)starting capture).src/audio_capture_manager.cpp
RMF_AudioCapture_Open_Type()Available in the RMF HAL to open the capture device for a specified source type (RMF_AC_TYPE_PRIMARY or RMF_AC_TYPE_AUXILIARY); not currently used by audiocapturemgr.rmfAudioCapture.h
RMF_AudioCapture_GetCurrentSettings()Available in the RMF HAL to retrieve the RMF_AudioCapture_Settings currently in effect on a started handle; not currently used by audiocapturemgr.rmfAudioCapture.h
RMF_AudioCapture_GetStatus()Available in the RMF HAL to query the RMF_AudioCapture_Status struct (started flag, format, sampling rate, FIFO depth, overflow/underflow counts); not currently used by audiocapturemgr.rmfAudioCapture.h
RMF_AudioCapture_Start()Starts capture with current settings and registers q_mgr::data_callback as the data handler.src/audio_capture_manager.cpp
RMF_AudioCapture_Stop()Stops active audio capture, called on IARM stop or before property reconfiguration.src/audio_capture_manager.cpp
RMF_AudioCapture_Close()Releases the capture handle and all hardware resources, called in q_mgr destructor.src/audio_capture_manager.cpp

Key Implementation Logic


Configuration

Key Configuration Parameters

ParameterTypeDefaultDescription
AUDIOCAPTUREMGR_FILENAME_PREFIXstring macro"audio_sample"Filename prefix constant used in session manager request naming paths. Defined in include/audiocapturemgr_iarm.h.
AUDIOCAPTUREMGR_FILE_PATHstring macro"/opt/"Base path constant used alongside the filename prefix. Defined in include/audiocapturemgr_iarm.h.
DEFAULT_PRECAPTURE_DURATION_SECunsigned int constant6Default precapture rolling window in seconds. Set via music_id_client::set_precapture_duration(). Defined in src/music_id.cpp.
MAX_QMGR_BUFFER_DURATION_Sunsigned int constant30Maximum queued audio duration in seconds before the incoming queue is flushed. Defined in src/audio_capture_manager.cpp.
SOCKNAME_PREFIX (ip_out)std::string"/tmp/acm_ip_out_"Base path for the realtime output UNIX socket. Defined in src/ip_out.cpp.
SOCKET_PATH (music_id)string constant"/tmp/acm-songid"Base path for the music-id UNIX socket. Suffix appended per instance. Defined in src/music_id.cpp.
DEFAULT_FIFO_SIZEsize_t constant65536 (64 KiB)Default RMF capture FIFO size in bytes. Defined in src/audio_capture_manager.cpp.
DEFAULT_THRESHOLDsize_t constant8192 (8 KiB)Default RMF capture callback threshold in bytes. Defined in src/audio_capture_manager.cpp.

Runtime Configuration

Runtime behavior is changed via IARM calls.

# Open a session (source=0, output_type=BUFFERED_FILE_OUTPUT or REALTIME_SOCKET)
IARM_Bus_Call("audiocapturemgr", "open", iarmbus_open_args)

# Change audio capture properties for an open session
IARM_Bus_Call("audiocapturemgr", "setAudioProperties", iarmbus_acm_arg_t)

# Change output delivery properties (e.g., precapture buffer duration)
IARM_Bus_Call("audiocapturemgr", "setOutputProperties", iarmbus_acm_arg_t)

Configuration Persistence

Configuration changes are not persisted across reboots.