Skip to main content

utilities

Overview of all shared utility helpers, data structures, and DSP primitives available in react-native-audio-api. Covers C++ utilities in common/cpp/audioapi/utils/, common/cpp/audioapi/core/utils/, common/cpp/audioapi/dsp/, and TypeScript utilities in src/utils/. Use this skill before writing new math, buffer management, or cross-thread code — check if a utility already exists. Trigger phrases: "add a new utility", "what helpers are available", "cross-thread communication", "audio buffer", "DSP math", "circular buffer", "lock-free queue", "off-thread", "SIMD buffer", "time conversion", "parameter automation", "audio constants", "TypeScript utils".

Informações da origem

Repositório
software-mansion/react-native-audio-api
Última atividade na origem
6 de outubro de 2026 às 14:47
Idioma detectado do SKILL.md
inglês
Estrelas
848
Forks
94

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Explorador de arquivos
3 arquivos

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
utilities
description
Overview of all shared utility helpers, data structures, and DSP primitives available in react-native-audio-api. Covers C++ utilities in common/cpp/audioapi/utils/, common/cpp/audioapi/core/utils/, common/cpp/audioapi/dsp/, and TypeScript utilities in src/utils/. Use this skill before writing new math, buffer management, or cross-thread code — check if a utility already exists. Trigger phrases: "add a new utility", "what helpers are available", "cross-thread communication", "audio buffer", "DSP math", "circular buffer", "lock-free queue", "off-thread", "SIMD buffer", "time conversion", "parameter automation", "audio constants", "TypeScript utils".
# Skill: Utilities ## `common/cpp/audioapi/utils/` — Core data structures & primitives ### `AudioArray.h` — float audio array (read header for full API) Single-channel float buffer. The foundational data type. Use for any per-channel audio data. Key operations: `zero()`, `sum(source, gain)`, `multiply(source)`, `copy(source)`, `copyReverse(...)`, `copyTo(float*)`, `copyWithin(...)`, `scale(float)`, `normalize()`, `getMaxAbsValue()`, `computeConvolution(kernel)`. Access: `operator[]`, `begin()`/`end()`, `span()`, `subSpan(length, offset)`. Constructors copy data — `AudioArray` always owns its buffer. --- ### `AudioBuffer.h` — multi-channel container (read header for full API) Holds N channels of `AudioArrayBuffer`. Handles up/down-mixing automatically on `sum()` and `copy()`. Key operations: `getChannel(index)`, `getSharedChannel(index)`, `zero()`, `sum(source, interpretation)`, `copy(source)`, `deinterleaveFrom(float*, frames)`, `interleaveTo(float*, frames)`, `normalize()`, `scale(float)`. Channel layout constants: `ChannelMono=0`, `ChannelLeft=0`, `ChannelRight=1`, `ChannelCenter=2`, `ChannelLFE=3`, `ChannelSurroundLeft=4`, `ChannelSurroundRight=5`. `getChannel()` returns a non-owning `AudioArray*`. `getSharedChannel()` returns `shared_ptr<AudioArrayBuffer>` (use for JSI transfer). --- ### `AudioArrayBuffer.hpp` — JSI-transferable audio array `AudioArray` + `jsi::MutableBuffer`. Allows zero-copy transfer of audio data to JS as an `ArrayBuffer`. Use in `getChannelData()` patterns. ```cpp // Typical usage in HostObject — no copy, JS sees the native memory auto audioArrayBuffer = audioBuffer_->getSharedChannel(channel); auto arrayBuffer = jsi::ArrayBuffer(runtime, audioArrayBuffer); auto float32Array = runtime.global() .getPropertyAsFunction(runtime, "Float32Array") .callAsConstructor(runtime, arrayBuffer) .getObject(runtime); float32Array.setExternalMemoryPressure(runtime, audioArrayBuffer->size()); ``` --- ### `CircularAudioArray.h` — circular float buffer (read header) `AudioArray` subclass acting as a circular queue for streaming audio. **Not thread-safe** — use only from one thread. Key operations: - `push_back(AudioArray&, size)` / `push_back(float*, size)` — write frames - `pop_front(AudioArray&, size)` / `pop_front(float*, size)` — read oldest frames - `pop_back(AudioArray&, size, offset)` — read newest frames - `getNumberOfAvailableFrames()` — how many frames ready to read Used in delay lines and streaming buffers. --- ### `CircularOverflowableAudioArray.h` — overwritable circular buffer Like `CircularAudioArray` but overwrites oldest data when full instead of rejecting. Use for recording input where you always want the latest data, not the oldest. --- ### `SpscChannel.hpp` — lock-free SPSC channel Bounded single-producer, single-consumer queue built on aligned atomics. **Do not use directly — prefer `CrossThreadEventScheduler` or `TaskOffloader`** unless you need fine-grained control. For full API see [api.md](api.md#spscchannelhpp--lock-free-spsc-channel). --- ### `CrossThreadEventScheduler.hpp` — JS→audio event queue High-level wrapper over `SpscChannel` for scheduling lambdas from the JS thread to be executed on the audio thread. This is **the standard way** to send updates from JS to audio. For full API see [api.md](api.md#crossthreadeventschedulerhpp--jsaudio-event-queue). --- ### `AlignedAllocator.hpp` — aligned STL allocator STL-compatible allocator that guarantees `N`-byte alignment (default 16 bytes, SIMD-friendly). Use when creating buffers that will be processed by SIMD code in `VectorMath`. For full API see [api.md](api.md#alignedallocatorhpp--aligned-stl-allocator). --- ### `MoveOnlyFunction.hpp` — non-copyable function wrapper Backport of C++23 `std::move_only_function`. Use instead of `std::function` when the callable captures a move-only type (e.g. a `unique_ptr`). For full API see [api.md](api.md#moveonlyfunctionhpp--non-copyable-function-wrapper). --- ### `Result.hpp` — Rust-style Result<T,E> Represents either success (`Ok`) or error (`Err`). Use at API boundaries (e.g. `AudioRecorder::start()`). Use `NoneType` / `None` for void variants. For full API see [api.md](api.md#resulthpp--rust-style-resultte). --- ### `BoundedPriorityQueue.hpp` — fixed-capacity sorted queue Non-thread-safe `std::multiset` backed by an in-object block pool. Fixed compile-time capacity, node recycling, zero heap allocation — safe to use on the audio thread. `push` returns `false` when full instead of growing. Used by `ParamQueueBase` (AudioParam automation) and `DeferredEventQueue`. **Do not back this with `std::pmr`.** A `monotonic_buffer_resource` + `unsynchronized_pool_resource` needs a buffer whose size depends on the standard library's private bookkeeping, and libstdc++ needs far more of it than libc++ — a buffer sized against libc++ threw `std::bad_alloc` short of capacity on the Linux CI runner while passing locally on macOS. The block pool needs exactly `Capacity * SLOT_SIZE` bytes everywhere. For full API see [api.md](api.md#boundedpriorityqueuehpp--fixed-capacity-sorted-queue). --- ### `TaskOffloader.hpp` — worker thread with SPSC input Spawns a dedicated worker thread that processes items from a SPSC channel. Use when you need to offload a recurring task (e.g. file writing, decoding) to a dedicated thread. For full API see [api.md](api.md#taskoffloaderhpp--worker-thread-with-spsc-input). --- ### `Benchmark.hpp` — timing utilities (dev/debug only) Use `getExecutionTime()` for one-shot nanosecond timing. **Do not leave `logAvgExecutionTime` in production code.** For full API see [api.md](api.md#benchmarkhpp--timing-utilities-devdebug-only). --- ### `Path.h` — path strings and file:// URLs ```cpp audioapi::path::lowercaseExtension(path) // "wav" for "/tmp/Take.WAV", "" when none audioapi::path::hasExtension(path, {"m4a", "mp4"}) // lowercase, no leading dot audioapi::path::hasNonFileProtocol(path) // http://, content://, ... audioapi::path::normalizeFilePath(pathOrFileUrl) // strips file:// and percent-decodes ``` Pure string work, never touches the disk (that is `FileSystem.hpp`). The extension comes from the file name only, so a dot in a directory name is not mistaken for one. `decoding::pathHasExtension` is a different, older suffix match used by the decoder. ### `FileSystem.hpp` — path queries without `stat` ```cpp audioapi::file_system::fileExists(path) // false also when the path cannot be inspected audioapi::file_system::fileSizeBytes(path) // 0 when missing or unreadable audioapi::file_system::removeFile(path) // no-op when missing ``` Both wrap `std::filesystem` with an `error_code`, so they never throw. Use them instead of a local `::stat` helper; `fstat` on an fd you already opened is a different job and stays inline. ### `UnitConversion.h` — byte unit constants ```cpp audioapi::KB_IN_BYTES // 1024.0 audioapi::MB_IN_BYTES // 1024 * 1024.0 audioapi::GB_IN_BYTES // 1024^3.0 ``` ### `AudioLayout.h` — sample rate + channel count `AudioLayout { float sampleRate; int channelCount; }` with a defaulted `operator==`. It is the file stream in `AudioFileProperties::stream` / `EncoderSettings::stream` and the `layout` of a `StreamFormat` (`encoding/StreamFormat.h`, which adds `maxFramesPerBuffer`). Hold a new pair of these as one `AudioLayout` and compare whole layouts (`inputLayout != outputLayout_`) rather than two fields. Storage typed for a native API stays native: the remux `TrackInfo` structs (`int32_t` from `AMediaFormat_getInt32`, `UInt32` from an ASBD) and the integer rates the Android encoder backends write into WAV headers and `MediaCodec` formats. --- ## `common/cpp/audioapi/core/utils/` — Node and context utilities ### `Constants.h` — global audio constants ```cpp RENDER_QUANTUM_SIZE = 128 // frames per render block — never hardcode 128 MAX_FFT_SIZE = 32768 MAX_CHANNEL_COUNT = 32 OCTAVE_RANGE = 1200 // cents per octave PI = std::numbers::pi_v<float> MOST_POSITIVE_SINGLE_FLOAT / MOST_NEGATIVE_SINGLE_FLOAT PROMISE_VENDOR_THREAD_POOL_WORKER_COUNT = 4 ``` --- ### `AudioDestructor.hpp` — off-thread destruction Offloads `shared_ptr` destruction to a dedicated worker thread. Use for any object whose destructor may block or deallocate large buffers — both are forbidden on the audio thread. For full API see [api.md](api.md#audiodestructorhpp--off-thread-destruction). --- ### `ParamChangeEvent.hpp` — AudioParam automation event Represents a single Web Audio API automation command (`setValueAtTime`, `linearRampToValueAtTime`, etc.). Move-only. Used exclusively within `AudioParamEventQueue` — do not construct outside of `AudioParam` scheduling methods. For full API see [api.md](api.md#paramchangeeventhpp--audioparam-automation-event). --- ### `AudioParamEventQueue.h` — sorted automation event queue Stores and processes `ParamChangeEvent` objects in time order on the audio thread. Read the header for full API. --- ### `AudioGraphManager.h` — thread-safe graph mutation queue Queues connect/disconnect operations from the JS thread for application before each render pass. Do not call its methods directly — go through `AudioNode::connect()`/`disconnect()`. Read the header for implementation details. --- ### `Locker.h` — nullable mutex RAII wrapper RAII mutex wrapper that can hold `nullptr` (no-op). Supports `Locker::tryLock(mutex)` for non-blocking acquisition. **Do not use on the audio thread.** Locks are forbidden in `processNode()`. --- ### Other `core/utils/` classes - **`AudioDecoder.h`** — decodes audio files to `AudioBuffer` (FFmpeg, conditional). Read the header. - **`AudioFileWriter.h`** — writes PCM to audio files. Read the header. - **`AudioRecorderCallback.h`** — callback adapter for the platform recorder. Internal. - **`worklets/WorkletsRunner.h`** — manages JS worklet execution on the audio thread. Internal. --- ## `common/cpp/audioapi/dsp/` — DSP helpers ### `AudioUtils.h` — inline DSP math Provides `timeToSampleFrame()`, `sampleFrameToTime()`, `linearInterpolate()`, `linearToDecibels()`, `decibelsToLinear()`, `uint8ToFloat()` (LE int16 bytes → float). For full API see [api.md](api.md#audioutilshpp--inline-dsp-math). --- ### `AudioBufferPool.hpp` — preallocated planar buffers by pointer `AudioBufferPool<N>` owns N `AudioBuffer`s and hands them out as `AudioBufferLease`s, a `unique_ptr` whose deleter returns the buffer to the pool through a lock-free `SlotFreeList` (any thread, never blocks, no allocation). Use it wherever the audio thread fills a buffer for a worker (`AudioFileWriter`, `AudioRecorderCallback`): the lease travels through the `TaskOffloader` message by move, dropping it anywhere returns the buffer, and a null lease is the shutdown message, so the message struct needs a defaulted `operator==`. Not `shared_ptr`: its control block would allocate on the audio thread. --- ### `VectorMath.h` — SIMD-optimized vector math SIMD-accelerated array operations (Apple Accelerate/vDSP when `HAVE_ACCELERATE` is set by the podspec, otherwise ARM NEON / x86 SSE2). Use for per-channel hot-path processing. Read the header for available functions before writing manual loops. `interleave`/`deinterleave` handle any channel count (planar pointers <-> channel-interleaved); on Accelerate stereo goes through `vDSP_ctoz`/`vDSP_ztoc` and N channels through one strided `vDSP_vsadd` per channel, so platform code should call these rather than hand-roll a repack. The recorder pipeline is planar end to end (`AudioRecorder::onAudioFrames`, `AudioFileWriter`, `AudioRecorderCallback`, `AudioEncoder::encode` all take one pointer per channel); the only repacks are Oboe's interleaved input on Android and the encoder backends' fused interleave-while-quantize. --- ### `FFT.h` / `Convolver.h` / `Resampler.h` / `WaveShaper.h` / `Windows.hpp` Higher-level DSP blocks. Read each header before use. --- ### `SpectrumAnalyser.h` — shared windowed-FFT magnitude spectrum Owns FFT scratch state (Blackman window, temp array, complex scratch, magnitude output) for the windowed-FFT → linear-magnitude → exponential-smoothing pipeline. Shared by `AnalyserNode` (`core/analysis/`) and `WorkletNode` (`react-native-audio-worklets`, frequency-domain mode) to avoid duplicating that math — each node keeps its own input buffering/threading and just calls `analyze(timeDomain, smoothingTimeConstant)`, then reads `getMagnitudeData()`. Exported via `StableAPI.h` for the worklets extension package. Not thread-safe; call `analyze()`/`setFFTSize()` from a single thread. --- ## `src/utils/` — TypeScript utilities ### `index.ts` ```ts import { clamp, toFloat32Array, assertFiniteSequence } from './utils'; clamp(value, min, max) // clamp a number to [min, max] toFloat32Array(values) // number[] → Float32Array (passthrough if already) toFloat32Array(undefined) // → undefined (overload) assertFiniteSequence(values, errorMessage) // throws TypeError if any value is non-finite ``` Use `toFloat32Array` when accepting `number[] | Float32Array` options. Use `assertFiniteSequence` in options validators (e.g. PeriodicWave `real`/`imag`). ### `paths.ts` ```ts import { isRemoteSource, isBase64Source, isDataBlobString } from './utils/paths'; isRemoteSource(url) // true if starts with http:// or https:// isBase64Source(data) // true if 'data:audio/...;base64,...' isDataBlobString(data) // true if starts with 'blob:' ``` Use before passing a URL/path to decoder or streaming APIs to determine the source type. --- ### `filePresets.ts` ```ts import FilePreset from './utils/filePresets';
Ver no GitHub
Este SKILL.md e muito grande, entao o SkillsMP mostra aqui apenas a primeira secao. Ver no GitHub