{"version":3,"sources":["../src/constants.ts","../src/processor.ts","../src/utils.ts"],"sourcesContent":["import type { AudioConfig } from './types';\n\n/**\n * Default configuration for audio processing\n */\nexport const DEFAULT_AUDIO_CONFIG: AudioConfig = {\n  bufferSize: 1024,\n  skipInitialFrames: 0,\n  inputBitsPerSample: 32, // Default 32-bit\n  inputChannels: 1, // Default mono\n};\n\n/**\n * Common buffer sizes for audio processing\n */\nexport const COMMON_BUFFER_SIZES = [256, 512, 1024, 2048, 4096, 8192] as const;\n\n/**\n * Audio processing constants\n */\nexport const AUDIO_CONSTANTS = {\n  /** Maximum buffer size allowed */\n  MAX_BUFFER_SIZE: 16384,\n  /** Minimum buffer size allowed */\n  MIN_BUFFER_SIZE: 64,\n  /** Maximum skip frames allowed */\n  MAX_SKIP_FRAMES: 100,\n  /** Sample rate normalization factor for 32-bit integers */\n  INT32_NORMALIZATION_FACTOR: 1 / 2147483647,\n  /** Conversion factor for [-1, 1] to [0, 255] range */\n  UINT8_CONVERSION_FACTOR: 127.5,\n} as const;\n","import { AUDIO_CONSTANTS } from './constants';\nimport type { AudioConfig, AudioDataInput, AudioDataPacket } from './types';\n\n/**\n * Simple audio processor with minimal state for skip frames functionality\n */\nexport class AudioProcessor {\n  private frameCount = 0;\n  private config: AudioConfig;\n\n  constructor(config: AudioConfig) {\n    this.config = config;\n  }\n\n  /**\n   * Process raw audio data and convert to visualization format\n   * Handles skip frames logic internally\n   */\n  process(rawData: AudioDataInput): AudioDataPacket | null {\n    this.frameCount++;\n\n    // Skip initial frames if configured\n    if (this.config.skipInitialFrames && this.frameCount <= this.config.skipInitialFrames) {\n      return null; // Skip this frame\n    }\n\n    try {\n      let timeDomainData: Uint8Array;\n\n      if (rawData instanceof Buffer) {\n        // Use new one-step conversion function\n        timeDomainData = convertBufferToWaveData(\n          rawData,\n          this.config.inputBitsPerSample || 32,\n          this.config.inputChannels || 1,\n          this.config.bufferSize\n        );\n      } else {\n        // Float32Array input (Web Audio, etc.)\n        const samples = rawData as Float32Array;\n        timeDomainData = new Uint8Array(samples.length);\n        for (let i = 0; i < samples.length; i++) {\n          const normalized = Math.max(-1, Math.min(1, samples[i]));\n          timeDomainData[i] = Math.floor(128 + normalized * 127);\n        }\n      }\n\n      return {\n        timeDomainData,\n        timestamp: Date.now(),\n        bufferSize: this.config.bufferSize,\n      };\n    } catch (error) {\n      console.error('Error processing audio data:', error);\n      return null;\n    }\n  }\n\n  /**\n   * Reset frame counter (call when starting new audio stream)\n   */\n  reset(): void {\n    this.frameCount = 0;\n  }\n\n  /**\n   * Update configuration\n   */\n  updateConfig(config: AudioConfig): void {\n    this.config = config;\n  }\n}\n\n/**\n * Stateless audio processing function (for cases without skip frames)\n *\n * @param rawData - Raw audio data (Buffer or Float32Array)\n * @param config - Audio processing configuration\n * @returns Processed audio packet or null if processing fails\n */\nexport function process(rawData: AudioDataInput, config: AudioConfig): AudioDataPacket | null {\n  try {\n    let timeDomainData: Uint8Array;\n\n    if (rawData instanceof Buffer) {\n      // Use new one-step conversion function\n      timeDomainData = convertBufferToWaveData(\n        rawData,\n        config.inputBitsPerSample || 32,\n        config.inputChannels || 1,\n        config.bufferSize\n      );\n    } else {\n      // Float32Array input (Web Audio, etc.)\n      const samples = rawData as Float32Array;\n      timeDomainData = new Uint8Array(samples.length);\n      for (let i = 0; i < samples.length; i++) {\n        const normalized = Math.max(-1, Math.min(1, samples[i]));\n        timeDomainData[i] = Math.floor(128 + normalized * 127);\n      }\n    }\n\n    return {\n      timeDomainData,\n      timestamp: Date.now(),\n      bufferSize: config.bufferSize,\n    };\n  } catch (error) {\n    console.error('Error processing audio data:', error);\n    return null;\n  }\n}\n\n/**\n * Convert Buffer directly to wave data (Uint8Array) for AudioWave visualization\n * One-step conversion: format parsing + channel mixing + resampling + amplitude mapping\n */\nexport function convertBufferToWaveData(\n  buffer: Buffer,\n  bitsPerSample: number,\n  channels: number,\n  targetSize: number\n): Uint8Array {\n  const bytesPerSample = bitsPerSample / 8;\n  const sourceSamples = buffer.length / (bytesPerSample * channels);\n  const result = new Uint8Array(targetSize);\n  const maxValue = 2 ** (bitsPerSample - 1) - 1;\n  const samplesPerBin = sourceSamples / targetSize;\n\n  for (let i = 0; i < targetSize; i++) {\n    const startIndex = Math.floor(i * samplesPerBin);\n    const endIndex = Math.min(Math.floor((i + 1) * samplesPerBin), sourceSamples);\n\n    let maxAmplitude = 0;\n    let representativeSample = 0;\n\n    // Find maximum amplitude (suitable for waveform display)\n    for (let j = startIndex; j < endIndex; j++) {\n      let mixedSample = 0;\n\n      // Mix channels\n      for (let ch = 0; ch < channels; ch++) {\n        const byteIndex = (j * channels + ch) * bytesPerSample;\n        let sample = 0;\n\n        switch (bitsPerSample) {\n          case 8:\n            sample = buffer.readInt8(byteIndex);\n            break;\n          case 16:\n            sample = buffer.readInt16LE(byteIndex);\n            break;\n          case 32:\n            sample = buffer.readInt32LE(byteIndex);\n            break;\n          default:\n            throw new Error(`Unsupported bits per sample: ${bitsPerSample}`);\n        }\n\n        mixedSample += sample;\n      }\n\n      mixedSample = mixedSample / channels;\n      const amplitude = Math.abs(mixedSample);\n\n      if (amplitude > maxAmplitude) {\n        maxAmplitude = amplitude;\n        representativeSample = mixedSample;\n      }\n    }\n\n    // Convert to AudioWave format: 128 as center, symmetric mapping\n    const normalized = representativeSample / maxValue; // [-1, 1]\n    result[i] = Math.floor(128 + normalized * 127);\n  }\n\n  return result;\n}\n\n/**\n * Validate audio configuration\n */\nexport function validateAudioConfig(config: AudioConfig): boolean {\n  if (!config || typeof config !== 'object') {\n    return false;\n  }\n\n  if (\n    typeof config.bufferSize !== 'number' ||\n    config.bufferSize < AUDIO_CONSTANTS.MIN_BUFFER_SIZE ||\n    config.bufferSize > AUDIO_CONSTANTS.MAX_BUFFER_SIZE\n  ) {\n    return false;\n  }\n\n  if (\n    config.skipInitialFrames !== undefined &&\n    (typeof config.skipInitialFrames !== 'number' ||\n      config.skipInitialFrames < 0 ||\n      config.skipInitialFrames > AUDIO_CONSTANTS.MAX_SKIP_FRAMES)\n  ) {\n    return false;\n  }\n\n  return true;\n}\n","import { DEFAULT_AUDIO_CONFIG } from './constants';\nimport type { AudioConfig } from './types';\n\n/**\n * Create audio configuration with defaults\n */\nexport function createAudioConfig(config: Partial<AudioConfig> = {}): AudioConfig {\n  return {\n    ...DEFAULT_AUDIO_CONFIG,\n    ...config,\n  };\n}\n\n/**\n * Check if buffer size is a power of 2 (recommended for FFT)\n */\nexport function isPowerOfTwo(n: number): boolean {\n  return n > 0 && (n & (n - 1)) === 0;\n}\n\n/**\n * Get the nearest power of 2 buffer size\n */\nexport function getNearestPowerOfTwo(size: number): number {\n  return 2 ** Math.round(Math.log2(size));\n}\n\n/**\n * Validate buffer data format for 32-bit samples\n */\nexport function isValidAudioBuffer(buffer: Buffer): boolean {\n  return buffer.length % 4 === 0;\n}\n"],"mappings":"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","names":[]}