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
JavaScript
"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