Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,71 @@ with the same library loaded elsewhere in the host process.
- Use `LK_LOG_WARN` for non-fatal unexpected conditions.
- Use `Result<T, E>` for operations that can fail with typed errors (e.g., data track publish/subscribe).

### Public API Documentation (Doxygen)

The public API (`include/livekit/*.h`) is what consumers read first and is also
published as a Doxygen site (`docs/Doxyfile`, `.github/workflows/publish-docs.yml`).
Every doc comment in `include/livekit/` must use the rules below, and PRs that
add or modify public symbols are gated on these rules during review.

#### Comment style

- Use triple-slash `///` Doxygen comments. Do **not** use `/** ... */` Javadoc
blocks or `/* ... */` block comments for documentation.
- Apache license headers stay as `/* ... */` block comments — they are not
documentation.
- Section organization comments (e.g. `// ---- Accessors ----`,
`// Read-only properties`) may stay as `//` since they do not document a
specific symbol.
- Implementation comments inside `.cpp` files (non-Doxygen) may use `//`
freely.
- Use Doxygen `@`-prefixed commands (`@param`, `@return`, `@throws`, `@note`,
`@brief`, `@deprecated`, `@ref`, `@p`, `@c`). Do not use the equivalent
`\`-prefixed forms in new code.

#### Required tags

- Document parameters using `@param name Description.`
- Document non-void return values using `@return Description.`
- Document thrown exceptions using `@throws ExceptionType When/why it's
thrown.` Operations that can fail without throwing should return
`Result<T, E>` (see Error Handling above) and the variants should be
documented in the doc block.
- Free-text "Parameters:", "Returns:", "Throws:" sections in legacy comments
must be converted to the corresponding `@param` / `@return` / `@throws`
tags when the comment is touched.

#### Example

```cpp
/// Publish a local track to the room.
///
/// Blocks until the FFI publish response arrives.
///
/// @param track Track to publish. Must be non-null.
/// @param options Publish options (codec, simulcast, etc.).
/// @throws std::runtime_error if the FFI reports an error.
void publishTrack(const std::shared_ptr<Track>& track, const TrackPublishOptions& options);
```

#### Deprecation comments

When superseding a public API, every retained back-compat shim must carry a
Doxygen `/// @deprecated Use <newName>() instead.` line so the generated docs
render a deprecation callout (see "Deprecating a public API" above).

#### Verifying locally

Run Doxygen from the repository root to regenerate the HTML docs:

```bash
doxygen docs/Doxyfile
```

The output lands in `docs/html/`. Doxygen warnings about "is not documented"
indicate undocumented public symbols — adding documentation to them is
encouraged but not strictly required by these rules.

### Integer Types

- Prefer fixed-width integer types from `<cstdint>` (`std::int32_t`, `std::uint64_t`, etc.) over raw primitive integer types when size or signedness matters.
Expand Down
40 changes: 16 additions & 24 deletions include/livekit/audio_frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,38 +29,30 @@ class AudioFrameBufferInfo;
class OwnedAudioFrameBuffer;
} // namespace proto

/**
* @brief Represents a raw PCM audio frame with interleaved int16 samples.
*
* AudioFrame holds decoded audio data along with metadata such as sample rate,
* number of channels, and samples per channel. It is used for capturing and
* processing audio in the LiveKit SDK.
*/
/// @brief Represents a raw PCM audio frame with interleaved int16 samples.
///
/// AudioFrame holds decoded audio data along with metadata such as sample rate,
/// number of channels, and samples per channel. It is used for capturing and
/// processing audio in the LiveKit SDK.
class LIVEKIT_API AudioFrame {
public:
/**
* Construct an AudioFrame from raw PCM samples.
*
* @param data Interleaved PCM samples (int16).
* @param sample_rate Sample rate (Hz).
* @param num_channels Number of channels.
* @param samples_per_channel Number of samples per channel.
*
* Throws std::invalid_argument if the data size is inconsistent with
* num_channels * samples_per_channel.
*/
/// Construct an AudioFrame from raw PCM samples.
///
/// @param data Interleaved PCM samples (int16).
/// @param sample_rate Sample rate (Hz).
/// @param num_channels Number of channels.
/// @param samples_per_channel Number of samples per channel.
///
/// @throws std::invalid_argument if the data size is inconsistent with
/// num_channels * samples_per_channel.
AudioFrame(std::vector<std::int16_t> data, int sample_rate, int num_channels, int samples_per_channel);
AudioFrame(); // Default constructor
virtual ~AudioFrame() = default;

/**
* Create a new zero-initialized AudioFrame instance.
*/
/// Create a new zero-initialized AudioFrame instance.
static AudioFrame create(int sample_rate, int num_channels, int samples_per_channel);

/**
* Construct an AudioFrame by copying data out of an OwnedAudioFrameBuffer.
*/
/// Construct an AudioFrame by copying data out of an OwnedAudioFrameBuffer.
static AudioFrame fromOwnedInfo(const proto::OwnedAudioFrameBuffer& owned);

// ---- Accessors ----
Expand Down
162 changes: 74 additions & 88 deletions include/livekit/audio_processing_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,25 @@

namespace livekit {

/**
* @brief WebRTC Audio Processing Module (APM) for real-time audio enhancement.
*
* AudioProcessingModule exposes WebRTC's built-in audio processing capabilities
* including echo cancellation, noise suppression, automatic gain control, and
* high-pass filtering.
*
* This class is designed for scenarios where you need explicit control over
* audio processing, separate from the built-in processing in AudioSource.
*
* Typical usage pattern for echo cancellation:
* 1. Create an APM with desired features enabled
* 2. Call processReverseStream() with speaker/playback audio (reference signal)
* 3. Call processStream() with microphone audio (near-end signal)
* 4. The processed microphone audio will have echo removed
*
* Note: Audio frames must be exactly 10ms in duration.
*/
/// @brief WebRTC Audio Processing Module (APM) for real-time audio enhancement.
///
/// AudioProcessingModule exposes WebRTC's built-in audio processing capabilities
/// including echo cancellation, noise suppression, automatic gain control, and
/// high-pass filtering.
///
/// This class is designed for scenarios where you need explicit control over
/// audio processing, separate from the built-in processing in AudioSource.
///
/// Typical usage pattern for echo cancellation:
/// 1. Create an APM with desired features enabled
/// 2. Call processReverseStream() with speaker/playback audio (reference signal)
/// 3. Call processStream() with microphone audio (near-end signal)
/// 4. The processed microphone audio will have echo removed
///
/// @note Audio frames must be exactly 10ms in duration.
class LIVEKIT_API AudioProcessingModule {
public:
/**
* @brief Configuration options for the Audio Processing Module.
*/
/// @brief Configuration options for the Audio Processing Module.
struct Options {
/// Enable acoustic echo cancellation (AEC3).
/// Removes acoustic echo in two-way communication scenarios.
Expand All @@ -68,20 +64,16 @@ class LIVEKIT_API AudioProcessingModule {
Options() = default;
};

/**
* @brief Create a new Audio Processing Module with default options (all
* disabled).
*
* @throws std::runtime_error if the APM could not be created.
*/
/// @brief Create a new Audio Processing Module with default options (all
/// disabled).
///
/// @throws std::runtime_error if the APM could not be created.
AudioProcessingModule();

/**
* @brief Create a new Audio Processing Module with the specified options.
*
* @param options Configuration for which processing features to enable.
* @throws std::runtime_error if the APM could not be created.
*/
/// @brief Create a new Audio Processing Module with the specified options.
///
/// @param options Configuration for which processing features to enable.
/// @throws std::runtime_error if the APM could not be created.
explicit AudioProcessingModule(const Options& options);

virtual ~AudioProcessingModule() = default;
Expand All @@ -94,65 +86,59 @@ class LIVEKIT_API AudioProcessingModule {
AudioProcessingModule(AudioProcessingModule&&) noexcept = default;
AudioProcessingModule& operator=(AudioProcessingModule&&) noexcept = default;

/**
* @brief Process the forward (near-end/microphone) audio stream.
*
* This method processes audio captured from the local microphone. It applies
* the enabled processing features (noise suppression, gain control, etc.)
* and removes echo based on the reference signal provided via
* processReverseStream().
*
* The audio data is modified in-place.
*
* @param frame The audio frame to process (modified in-place).
*
* @throws std::runtime_error if processing fails.
*
* @note The frame must contain exactly 10ms of audio.
*/
/// @brief Process the forward (near-end/microphone) audio stream.
///
/// This method processes audio captured from the local microphone. It applies
/// the enabled processing features (noise suppression, gain control, etc.)
/// and removes echo based on the reference signal provided via
/// processReverseStream().
///
/// The audio data is modified in-place.
///
/// @param frame The audio frame to process (modified in-place).
///
/// @throws std::runtime_error if processing fails.
///
/// @note The frame must contain exactly 10ms of audio.
void processStream(AudioFrame& frame);

/**
* @brief Process the reverse (far-end/speaker) audio stream.
*
* This method provides the reference signal for echo cancellation. Call this
* with the audio that is being played through the speakers, so the APM can
* learn the acoustic characteristics and remove the echo from the microphone
* signal.
*
* The audio data is modified in-place.
*
* @param frame The audio frame to process (modified in-place).
*
* @throws std::runtime_error if processing fails.
*
* @note The frame must contain exactly 10ms of audio.
*/
/// @brief Process the reverse (far-end/speaker) audio stream.
///
/// This method provides the reference signal for echo cancellation. Call this
/// with the audio that is being played through the speakers, so the APM can
/// learn the acoustic characteristics and remove the echo from the microphone
/// signal.
///
/// The audio data is modified in-place.
///
/// @param frame The audio frame to process (modified in-place).
///
/// @throws std::runtime_error if processing fails.
///
/// @note The frame must contain exactly 10ms of audio.
void processReverseStream(AudioFrame& frame);

/**
* @brief Set the estimated delay between the reverse and forward streams.
*
* This must be called if and only if echo processing is enabled.
*
* Sets the delay in ms between processReverseStream() receiving a far-end
* frame and processStream() receiving a near-end frame containing the
* corresponding echo. On the client-side this can be expressed as:
*
* delay = (t_render - t_analyze) + (t_process - t_capture)
*
* where:
* - t_analyze is the time a frame is passed to processReverseStream() and
* t_render is the time the first sample of the same frame is rendered by
* the audio hardware.
* - t_capture is the time the first sample of a frame is captured by the
* audio hardware and t_process is the time the same frame is passed to
* processStream().
*
* @param delay_ms Delay in milliseconds.
*
* @throws std::runtime_error if setting the delay fails.
*/
/// @brief Set the estimated delay between the reverse and forward streams.
///
/// This must be called if and only if echo processing is enabled.
///
/// Sets the delay in ms between processReverseStream() receiving a far-end
/// frame and processStream() receiving a near-end frame containing the
/// corresponding echo. On the client-side this can be expressed as:
///
/// delay = (t_render - t_analyze) + (t_process - t_capture)
///
/// where:
/// - t_analyze is the time a frame is passed to processReverseStream() and
/// t_render is the time the first sample of the same frame is rendered by
/// the audio hardware.
/// - t_capture is the time the first sample of a frame is captured by the
/// audio hardware and t_process is the time the same frame is passed to
/// processStream().
///
/// @param delay_ms Delay in milliseconds.
///
/// @throws std::runtime_error if setting the delay fails.
void setStreamDelayMs(int delay_ms);

private:
Expand Down
Loading
Loading