UNPKG

@loqalabs/loqa-audio-dsp

Version:

Production-grade Expo native module for audio DSP analysis (FFT, pitch detection, formant extraction, spectral analysis)

89 lines 3.64 kB
// analyzeSpectrum - Spectral analysis API import LoqaAudioDspModule from './LoqaAudioDspModule'; import { NativeModuleError } from './errors'; import { logDebug } from './utils'; import { validateAudioBuffer, validateSampleRate } from './validation'; /** * Analyzes spectral features (centroid, rolloff, tilt) * * This function computes spectral characteristics of audio data, including: * - Spectral centroid: "center of mass" of the spectrum (brightness measure) * - Spectral rolloff: frequency below which 95% of energy is concentrated * - Spectral tilt: overall slope of the spectrum (timbre indicator) * * All features are computed in a single call for efficiency. * * @param audioBuffer - Audio samples (Float32Array or number[]) * @param sampleRate - Sample rate in Hz (8000-48000) * @param options - Spectrum analysis options * @returns Promise resolving to spectrum result with centroid, rolloff, and tilt * @throws ValidationError if buffer or sample rate are invalid * @throws NativeModuleError if native computation fails * * @example * ```typescript * const audioData = new Float32Array(2048); * // ... fill with audio samples ... * * const result = await analyzeSpectrum(audioData, 44100); * * console.log(`Spectral centroid: ${result.centroid} Hz`); * console.log(`Spectral rolloff: ${result.rolloff} Hz`); * console.log(`Spectral tilt: ${result.tilt}`); * ``` */ export async function analyzeSpectrum(audioBuffer, sampleRate, options) { // Step 1: Validate audio buffer and sample rate logDebug('analyzeSpectrum called', { bufferLength: audioBuffer.length, bufferType: audioBuffer instanceof Float32Array ? 'Float32Array' : 'number[]', sampleRate, options, }); validateAudioBuffer(audioBuffer); validateSampleRate(sampleRate); // Step 2: Convert to number[] for React Native bridge // React Native bridge requires plain arrays, not typed arrays const bufferArray = audioBuffer instanceof Float32Array ? Array.from(audioBuffer) : audioBuffer; logDebug('Calling native module for spectrum analysis', { sampleRate, bufferLength: bufferArray.length, }); try { // Step 3: Call native module const nativeResult = await LoqaAudioDspModule.analyzeSpectrum(bufferArray, sampleRate, options || {}); logDebug('Native module returned spectrum result', { centroid: nativeResult.centroid, rolloff: nativeResult.rolloff, tilt: nativeResult.tilt, }); // Step 4: Convert result to SpectrumResult type // Native module returns dictionary/map, convert to proper TypeScript type const result = { centroid: nativeResult.centroid, rolloff: nativeResult.rolloff, tilt: nativeResult.tilt, }; logDebug('analyzeSpectrum completed successfully', { centroid: result.centroid, rolloff: result.rolloff, tilt: result.tilt, }); return result; } catch (error) { // Step 5: Wrap native errors in NativeModuleError with context const errorMessage = error instanceof Error ? error.message : String(error); logDebug('analyzeSpectrum failed', { error: errorMessage, sampleRate, bufferLength: audioBuffer.length, }); throw new NativeModuleError(`Spectrum analysis failed: ${errorMessage}`, { originalError: error, sampleRate, bufferLength: audioBuffer.length, }); } } //# sourceMappingURL=analyzeSpectrum.js.map