Phase 6.5 Advanced Effects: - Add Pitch Shifter with semitones and cents adjustment - Add Time Stretch with pitch preservation using overlap-add - Add Distortion with soft/hard/tube types and tone control - Add Bitcrusher with bit depth and sample rate reduction - Add AdvancedParameterDialog with real-time waveform visualization - Add 4 professional presets per effect type Improvements: - Fix undefined parameter errors by adding nullish coalescing operators - Add global custom scrollbar styling with color-mix transparency - Add custom-scrollbar utility class for side panel - Improve theme-aware scrollbar appearance in light/dark modes - Fix parameter initialization when switching effect types Integration: - All advanced effects support undo/redo via EffectCommand - Effects accessible via command palette and side panel - Selection-based processing support - Toast notifications for all effects 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
53 lines
1.3 KiB
TypeScript
53 lines
1.3 KiB
TypeScript
/**
|
|
* Gain/Volume adjustment effect
|
|
*/
|
|
|
|
import { getAudioContext } from '../context';
|
|
|
|
/**
|
|
* Apply gain to an audio buffer
|
|
* @param buffer - Source audio buffer
|
|
* @param gainValue - Gain multiplier (1.0 = no change, 0.5 = -6dB, 2.0 = +6dB)
|
|
* @returns New audio buffer with gain applied
|
|
*/
|
|
export function applyGain(buffer: AudioBuffer, gainValue: number): AudioBuffer {
|
|
const audioContext = getAudioContext();
|
|
const outputBuffer = audioContext.createBuffer(
|
|
buffer.numberOfChannels,
|
|
buffer.length,
|
|
buffer.sampleRate
|
|
);
|
|
|
|
// Apply gain to each channel
|
|
for (let channel = 0; channel < buffer.numberOfChannels; channel++) {
|
|
const inputData = buffer.getChannelData(channel);
|
|
const outputData = outputBuffer.getChannelData(channel);
|
|
|
|
for (let i = 0; i < buffer.length; i++) {
|
|
outputData[i] = inputData[i] * gainValue;
|
|
// Clamp to prevent distortion
|
|
outputData[i] = Math.max(-1, Math.min(1, outputData[i]));
|
|
}
|
|
}
|
|
|
|
return outputBuffer;
|
|
}
|
|
|
|
/**
|
|
* Convert dB to gain multiplier
|
|
* @param db - Decibels
|
|
* @returns Gain multiplier
|
|
*/
|
|
export function dbToGain(db: number): number {
|
|
return Math.pow(10, db / 20);
|
|
}
|
|
|
|
/**
|
|
* Convert gain multiplier to dB
|
|
* @param gain - Gain multiplier
|
|
* @returns Decibels
|
|
*/
|
|
export function gainToDb(gain: number): number {
|
|
return 20 * Math.log10(gain);
|
|
}
|