UNPKG

react-audio-recorder-hook

Version:

A powerful TypeScript-based React hook that provides complete audio recording capabilities with pause/resume functionality, recording management, and audio processing

204 lines 7.76 kB
"use strict"; /** * Audio effects utilities for use with the useAudioRecorder hook */ Object.defineProperty(exports, "__esModule", { value: true }); exports.AudioEffectType = void 0; exports.applyAudioEffect = applyAudioEffect; /** * Available effects that can be applied to audio */ var AudioEffectType; (function (AudioEffectType) { AudioEffectType["None"] = "none"; AudioEffectType["Reverb"] = "reverb"; AudioEffectType["Echo"] = "echo"; AudioEffectType["Distortion"] = "distortion"; AudioEffectType["LowPass"] = "lowpass"; AudioEffectType["HighPass"] = "highpass"; AudioEffectType["Telephone"] = "telephone"; })(AudioEffectType || (exports.AudioEffectType = AudioEffectType = {})); /** * Connect audio source to destination with effects */ function applyAudioEffect(audioContext, sourceNode, destinationNode, effect) { var _a, _b; // Default to direct connection if no effect is selected if (effect.type === AudioEffectType.None) { sourceNode.connect(destinationNode); return; } // Set default mix if not provided const mix = (_a = effect.mix) !== null && _a !== void 0 ? _a : 0.5; const params = (_b = effect.params) !== null && _b !== void 0 ? _b : {}; // Create effect chain based on the selected effect type switch (effect.type) { case AudioEffectType.Reverb: createReverbEffect(audioContext, sourceNode, destinationNode, mix, params); break; case AudioEffectType.Echo: createEchoEffect(audioContext, sourceNode, destinationNode, mix, params); break; case AudioEffectType.Distortion: createDistortionEffect(audioContext, sourceNode, destinationNode, mix, params); break; case AudioEffectType.LowPass: createLowPassFilter(audioContext, sourceNode, destinationNode, mix, params); break; case AudioEffectType.HighPass: createHighPassFilter(audioContext, sourceNode, destinationNode, mix, params); break; case AudioEffectType.Telephone: createTelephoneEffect(audioContext, sourceNode, destinationNode, mix, params); break; default: // Fallback to direct connection sourceNode.connect(destinationNode); } } // Private implementations of each effect type function createReverbEffect(context, source, destination, mix, params) { // Create convolver node for reverb const convolver = context.createConvolver(); // Create impulse response (simplified version) const { decay = 2 } = params; const { sampleRate } = context; const impulse = context.createBuffer(2, sampleRate * decay, sampleRate); // Fill the buffer with an impulse response for (let channel = 0; channel < impulse.numberOfChannels; channel++) { const impulseData = impulse.getChannelData(channel); for (let i = 0; i < impulseData.length; i++) { // Simple exponential decay impulseData[i] = (Math.random() * 2 - 1) * Math.pow(1 - i / impulseData.length, decay); } } convolver.buffer = impulse; // Create dry/wet mixer const dryGain = context.createGain(); const wetGain = context.createGain(); dryGain.gain.value = 1 - mix; wetGain.gain.value = mix; // Connect the nodes source.connect(dryGain); dryGain.connect(destination); source.connect(convolver); convolver.connect(wetGain); wetGain.connect(destination); } function createEchoEffect(context, source, destination, mix, params) { // Create delay node const delay = context.createDelay(); delay.delayTime.value = params.delayTime || 0.3; // Create feedback gain node const feedback = context.createGain(); feedback.gain.value = params.feedback || 0.4; // Create dry/wet mixer const dryGain = context.createGain(); const wetGain = context.createGain(); dryGain.gain.value = 1 - mix; wetGain.gain.value = mix; // Connect the nodes source.connect(dryGain); dryGain.connect(destination); source.connect(delay); delay.connect(wetGain); wetGain.connect(destination); // Create feedback loop delay.connect(feedback); feedback.connect(delay); } function createDistortionEffect(context, source, destination, mix, params) { // Create waveshaper node for distortion const distortion = context.createWaveShaper(); // Set curve amount const amount = params.amount || 20; // Create the curve const curve = new Float32Array(context.sampleRate); const deg = Math.PI / 180; for (let i = 0; i < curve.length; i++) { const x = (i * 2) / curve.length - 1; curve[i] = ((3 + amount) * x * 20 * deg) / (Math.PI + amount * Math.abs(x)); } distortion.curve = curve; distortion.oversample = '4x'; // Create dry/wet mixer const dryGain = context.createGain(); const wetGain = context.createGain(); dryGain.gain.value = 1 - mix; wetGain.gain.value = mix; // Connect the nodes source.connect(dryGain); dryGain.connect(destination); source.connect(distortion); distortion.connect(wetGain); wetGain.connect(destination); } function createLowPassFilter(context, source, destination, mix, params) { // Create filter node const filter = context.createBiquadFilter(); filter.type = 'lowpass'; filter.frequency.value = params.frequency || 800; filter.Q.value = params.Q || 1; // Create dry/wet mixer const dryGain = context.createGain(); const wetGain = context.createGain(); dryGain.gain.value = 1 - mix; wetGain.gain.value = mix; // Connect the nodes source.connect(dryGain); dryGain.connect(destination); source.connect(filter); filter.connect(wetGain); wetGain.connect(destination); } function createHighPassFilter(context, source, destination, mix, params) { // Create filter node const filter = context.createBiquadFilter(); filter.type = 'highpass'; filter.frequency.value = params.frequency || 1500; filter.Q.value = params.Q || 1; // Create dry/wet mixer const dryGain = context.createGain(); const wetGain = context.createGain(); dryGain.gain.value = 1 - mix; wetGain.gain.value = mix; // Connect the nodes source.connect(dryGain); dryGain.connect(destination); source.connect(filter); filter.connect(wetGain); wetGain.connect(destination); } function createTelephoneEffect(context, source, destination, mix, params) { // Telephone effect: combine highpass and lowpass filters // Create filters const highpass = context.createBiquadFilter(); highpass.type = 'highpass'; highpass.frequency.value = params.highpassFreq || 700; const lowpass = context.createBiquadFilter(); lowpass.type = 'lowpass'; lowpass.frequency.value = params.lowpassFreq || 2500; // Create distortion for telephone effect const distortion = context.createWaveShaper(); const curve = new Float32Array(context.sampleRate); for (let i = 0; i < curve.length; i++) { const x = (i * 2) / curve.length - 1; curve[i] = (1.5 * x) / (1 + Math.abs(x)); } distortion.curve = curve; // Create dry/wet mixer const dryGain = context.createGain(); const wetGain = context.createGain(); dryGain.gain.value = 1 - mix; wetGain.gain.value = mix; // Connect the nodes source.connect(dryGain); dryGain.connect(destination); // Connect the effect chain source.connect(highpass); highpass.connect(lowpass); lowpass.connect(distortion); distortion.connect(wetGain); wetGain.connect(destination); } //# sourceMappingURL=audioEffects.js.map