Skip to content

Phaser, Flanger & Chorus

TimBorchert edited this page Apr 3, 2025 · 1 revision

This documentation refers to the following code: Phaser, Flanger, Chorus

This code provides a Python implementation of three common audio effects: phaser, flanger, and chorus. The implementation uses the numpy library for signal processing, scipy.io.wavfile for handling WAV files, and pygame.mixer for playing back the processed audio.

Why Use Audio Effects?

Audio effects can enhance or alter the characteristics of a sound. They are used for creative sound manipulation, improving audio quality, and creating immersive experiences.

This implementation provides a simple way to apply phaser, flanger, and chorus effects to an audio file and listen to the modified output.

Required Libraries

Ensure you have the following Python libraries installed:

  • numpy: For numerical operations.

  • pygame: To handle audio playback.

  • ipywidgets: For interactive widgets in Jupyter Notebooks.

  • scipy.io.wavfile: To read and write WAV files.

pip install numpy pygame ipywidgets scipy

Code Overview

Initialization

import tempfile
import os
import numpy as np
import pygame
import ipywidgets as widgets
from IPython.display import display, Audio
from scipy.io import wavfile

The necessary modules are imported, and pygame.mixer is initialized to handle audio playback.

pygame.mixer.init()

A temporary directory is created to store the processed output file.

output_file = os.path.join(temp_dir, "output.wav")

Applying Audio Effects

The apply_effect function takes an input WAV file, applies an audio effect (phaser, flanger, or chorus), and saves the modified audio file.

    sample_rate, audio_data = wavfile.read(input_file)
    audio_float = audio_data.astype(np.float32) / np.iinfo(audio_data.dtype).max
    
    if effect_type == "phaser":
        effect = phaser(audio_float, sample_rate, **effect_params)
    elif effect_type == "flanger":
        effect = flanger(audio_float, sample_rate, **effect_params)
    elif effect_type == "chorus":
        effect = chorus(audio_float, sample_rate, **effect_params)
    else:
        raise ValueError("Invalid effect type")
    
    effect = (effect * np.iinfo(np.int16).max).astype(np.int16)
    wavfile.write(output_file, sample_rate, effect)

Phaser Effect

The phaser function modulates the phase of the signal by introducing a time-varying delay.

    length = len(audio)
    lfo = np.sin(2 * np.pi * rate * np.arange(length) / sample_rate)
    delay = np.interp(lfo, [-1, 1], [0, depth * sample_rate / 1000])
    indices = np.arange(length) - delay
    indices = np.clip(indices, 0, length - 1).astype(int)
    delayed = audio[indices]
    output = audio + feedback * delayed
    return output / np.max(np.abs(output))

Flanger Effect

The flanger effect is similar to phaser but introduces periodic variations in delay, creating a sweeping effect.

    length = len(audio)
    lfo = np.sin(2 * np.pi * rate * np.arange(length) / sample_rate)
    delay = np.interp(lfo, [-1, 1], [0, depth * sample_rate / 1000])
    indices = np.arange(length) - delay
    indices = np.clip(indices, 0, length - 1).astype(int)
    delayed = audio[indices]
    output = audio + feedback * delayed
    return output / np.max(np.abs(output))

Chorus Effect

The chorus effect creates multiple slightly delayed and detuned copies of the original signal, giving a richer sound.

    length = len(audio)
    output = np.zeros_like(audio)
    for i in range(voices):
        lfo = np.sin(2 * np.pi * rate * np.arange(length) / sample_rate + (i * np.pi / voices))
        delay = np.interp(lfo, [-1, 1], [0, depth * sample_rate / 1000])
        indices = np.arange(length) - delay
        indices = np.clip(indices, 0, length - 1).astype(int)
        output += audio[indices]
    return output / np.max(np.abs(output))

How to Use the Code

  1. Prepare an Audio File: Ensure you have a WAV file to process.

  2. Apply an Effect: Call apply_effect with the desired effect type and parameters.

  3. Play the Processed Audio: Use pygame.mixer to play the modified audio file.

Example usage:

pygame.mixer.music.load(output_file)
pygame.mixer.music.play()

Conclusion

This implementation allows for real-time audio effect processing using Python. The modular structure makes it easy to add new effects or adjust parameters to suit different applications.

For further reading on audio signal processing, refer to:

https://pythonaudio.com/

https://docs.scipy.org/doc/scipy/reference/io.html

https://pygame.readthedocs.io/en/latest/

Clone this wiki locally