How to avoid clipping sounds between loops when generating audio with python? /u/BLCKSLM Python Education

Hi everyone,

I’m working on an audio generation project in Python, and I’ve encountered an issue with clipping sounds when looping the generated audio. Specifically, when the audio transitions from the end of one loop back to the beginning of the next, there’s an audible “click” or “pop,” which I believe is caused by discontinuities in the waveform.

Here’s some context about my setup:

  • Tools/Libraries: I’m using scipy, numpy, soundfile, and others.
  • Audio Details: The audio is generated dynamically, with a sample rate of 22,050 Hz and a duration of X seconds per loop.
  • Problem Scope: The issue only occurs when generating stereo sound. When generating mono audio, there are no such problems, and the loops are seamless.
  • What I’ve Tried: I’ve attempted fading in/out the edges of the loop and normalizing the waveform, but the problem persists.

My questions are:

  1. What techniques can I use to ensure a seamless transition between audio loops in Python?
  2. Are there specific libraries or functions that can help smooth the transitions or eliminate discontinuities in stereo sound?
  3. Could this issue be caused by something in my audio generation process, such as my band-pass filter, stereo conversion, or modulation settings?

Below is a snippet of my code for generating the audio loop:

“`python import argparse import numpy as np from scipy.signal import butter, sosfilt import soundfile as sf import colorednoise as cn

Configuration

SAMPLE_RATE = 22050 # Reduced sample rate to optimize size DURATION = 5 # Duration in seconds

Generate colored noise (pink, brown, etc.)

def generate_colored_noise(duration, sample_rate, exponent=-1): samples = duration * sample_rate return cn.powerlaw_psd_gaussian(exponent, samples)

Band-pass filter

def band_pass_filter(data, lowcut, highcut, sample_rate, order=5): sos = butter(order, [lowcut, highcut], btype=’band’, fs=sample_rate, output=’sos’) return sosfilt(sos, data)

Add low-frequency modulation

def add_modulation(data, sample_rate, depth=0.05, frequency=0.1): t = np.linspace(0, len(data) / sample_rate, len(data), endpoint=False) modulator = 1 + depth * np.sin(2 * np.pi * frequency * t) return data * modulator

Convert mono to stereo

def convert_to_stereo(data, width=0.1, sample_rate=SAMPLE_RATE): delay_samples = int(width * sample_rate) left = data.copy() right = np.roll(data, delay_samples) # Shift data for slight delay on the right channel return np.stack((left, right), axis=1)

Normalize audio

def normalize_audio(data): return data / np.max(np.abs(data))

Main script

if name == “main“: parser = argparse.ArgumentParser(description=”Generate optimized green noise.”) parser.add_argument(“–low”, type=int, default=20, help=”Lower cutoff frequency in Hz (default: 20)”) parser.add_argument(“–high”, type=int, default=500, help=”Upper cutoff frequency in Hz (default: 500)”) parser.add_argument(“–filter”, type=int, default=4, help=”Filter steepness (default: 4)”) parser.add_argument(“–mod_depth”, type=float, default=0.05, help=”Amplitude modulation depth (default: 0.05)”) parser.add_argument(“–mod_freq”, type=float, default=0.1, help=”Amplitude modulation frequency (default: 0.1)”) args = parser.parse_args()

LOW_CUT = args.low HIGH_CUT = args.high FILTER_ORDER = args.filter MOD_DEPTH = args.mod_depth MOD_FREQUENCY = args.mod_freq OUTPUT_FILE = f"low-{LOW_CUT}-high-{HIGH_CUT}-filter-{FILTER_ORDER}.wav" print("Generating pink noise...") pink_noise = generate_colored_noise(DURATION, SAMPLE_RATE, exponent=-1) print("Generating brown noise...") brown_noise = generate_colored_noise(DURATION, SAMPLE_RATE, exponent=-2) print("Blending pink and brown noise...") blended_noise = 0.8 * pink_noise + 0.2 * brown_noise print("Applying band-pass filter...") green_noise = band_pass_filter(blended_noise, LOW_CUT, HIGH_CUT, SAMPLE_RATE, order=FILTER_ORDER) print("Adding modulation...") modulated_green_noise = add_modulation(green_noise, SAMPLE_RATE, depth=MOD_DEPTH, frequency=MOD_FREQUENCY) print("Converting to stereo...") stereo_green_noise = convert_to_stereo(modulated_green_noise) print("Normalizing audio...") final_green_noise = normalize_audio(stereo_green_noise) print(f"Saving as '{OUTPUT_FILE}'...") sf.write(OUTPUT_FILE, final_green_noise, SAMPLE_RATE, subtype='PCM_16') print(f"File saved successfully as '{OUTPUT_FILE}'.") 

“`

“`

Install dependencies:

$ pip install numpy scipy soundfile pydub colorednoise

call the script

$ python main.py –low 20 –high 250 –filter 4 “`

submitted by /u/BLCKSLM
[link] [comments]

​r/learnpython Hi everyone, I’m working on an audio generation project in Python, and I’ve encountered an issue with clipping sounds when looping the generated audio. Specifically, when the audio transitions from the end of one loop back to the beginning of the next, there’s an audible “click” or “pop,” which I believe is caused by discontinuities in the waveform. Here’s some context about my setup: Tools/Libraries: I’m using scipy, numpy, soundfile, and others. Audio Details: The audio is generated dynamically, with a sample rate of 22,050 Hz and a duration of X seconds per loop. Problem Scope: The issue only occurs when generating stereo sound. When generating mono audio, there are no such problems, and the loops are seamless. What I’ve Tried: I’ve attempted fading in/out the edges of the loop and normalizing the waveform, but the problem persists. My questions are: What techniques can I use to ensure a seamless transition between audio loops in Python? Are there specific libraries or functions that can help smooth the transitions or eliminate discontinuities in stereo sound? Could this issue be caused by something in my audio generation process, such as my band-pass filter, stereo conversion, or modulation settings? Below is a snippet of my code for generating the audio loop: “`python import argparse import numpy as np from scipy.signal import butter, sosfilt import soundfile as sf import colorednoise as cn Configuration SAMPLE_RATE = 22050 # Reduced sample rate to optimize size DURATION = 5 # Duration in seconds Generate colored noise (pink, brown, etc.) def generate_colored_noise(duration, sample_rate, exponent=-1): samples = duration * sample_rate return cn.powerlaw_psd_gaussian(exponent, samples) Band-pass filter def band_pass_filter(data, lowcut, highcut, sample_rate, order=5): sos = butter(order, [lowcut, highcut], btype=’band’, fs=sample_rate, output=’sos’) return sosfilt(sos, data) Add low-frequency modulation def add_modulation(data, sample_rate, depth=0.05, frequency=0.1): t = np.linspace(0, len(data) / sample_rate, len(data), endpoint=False) modulator = 1 + depth * np.sin(2 * np.pi * frequency * t) return data * modulator Convert mono to stereo def convert_to_stereo(data, width=0.1, sample_rate=SAMPLE_RATE): delay_samples = int(width * sample_rate) left = data.copy() right = np.roll(data, delay_samples) # Shift data for slight delay on the right channel return np.stack((left, right), axis=1) Normalize audio def normalize_audio(data): return data / np.max(np.abs(data)) Main script if name == “main”: parser = argparse.ArgumentParser(description=”Generate optimized green noise.”) parser.add_argument(“–low”, type=int, default=20, help=”Lower cutoff frequency in Hz (default: 20)”) parser.add_argument(“–high”, type=int, default=500, help=”Upper cutoff frequency in Hz (default: 500)”) parser.add_argument(“–filter”, type=int, default=4, help=”Filter steepness (default: 4)”) parser.add_argument(“–mod_depth”, type=float, default=0.05, help=”Amplitude modulation depth (default: 0.05)”) parser.add_argument(“–mod_freq”, type=float, default=0.1, help=”Amplitude modulation frequency (default: 0.1)”) args = parser.parse_args() LOW_CUT = args.low HIGH_CUT = args.high FILTER_ORDER = args.filter MOD_DEPTH = args.mod_depth MOD_FREQUENCY = args.mod_freq OUTPUT_FILE = f”low-{LOW_CUT}-high-{HIGH_CUT}-filter-{FILTER_ORDER}.wav” print(“Generating pink noise…”) pink_noise = generate_colored_noise(DURATION, SAMPLE_RATE, exponent=-1) print(“Generating brown noise…”) brown_noise = generate_colored_noise(DURATION, SAMPLE_RATE, exponent=-2) print(“Blending pink and brown noise…”) blended_noise = 0.8 * pink_noise + 0.2 * brown_noise print(“Applying band-pass filter…”) green_noise = band_pass_filter(blended_noise, LOW_CUT, HIGH_CUT, SAMPLE_RATE, order=FILTER_ORDER) print(“Adding modulation…”) modulated_green_noise = add_modulation(green_noise, SAMPLE_RATE, depth=MOD_DEPTH, frequency=MOD_FREQUENCY) print(“Converting to stereo…”) stereo_green_noise = convert_to_stereo(modulated_green_noise) print(“Normalizing audio…”) final_green_noise = normalize_audio(stereo_green_noise) print(f”Saving as ‘{OUTPUT_FILE}’…”) sf.write(OUTPUT_FILE, final_green_noise, SAMPLE_RATE, subtype=’PCM_16’) print(f”File saved successfully as ‘{OUTPUT_FILE}’.”) “` “` Install dependencies: $ pip install numpy scipy soundfile pydub colorednoise call the script $ python main.py –low 20 –high 250 –filter 4 “` submitted by /u/BLCKSLM [link] [comments] 

Hi everyone,

I’m working on an audio generation project in Python, and I’ve encountered an issue with clipping sounds when looping the generated audio. Specifically, when the audio transitions from the end of one loop back to the beginning of the next, there’s an audible “click” or “pop,” which I believe is caused by discontinuities in the waveform.

Here’s some context about my setup:

  • Tools/Libraries: I’m using scipy, numpy, soundfile, and others.
  • Audio Details: The audio is generated dynamically, with a sample rate of 22,050 Hz and a duration of X seconds per loop.
  • Problem Scope: The issue only occurs when generating stereo sound. When generating mono audio, there are no such problems, and the loops are seamless.
  • What I’ve Tried: I’ve attempted fading in/out the edges of the loop and normalizing the waveform, but the problem persists.

My questions are:

  1. What techniques can I use to ensure a seamless transition between audio loops in Python?
  2. Are there specific libraries or functions that can help smooth the transitions or eliminate discontinuities in stereo sound?
  3. Could this issue be caused by something in my audio generation process, such as my band-pass filter, stereo conversion, or modulation settings?

Below is a snippet of my code for generating the audio loop:

“`python import argparse import numpy as np from scipy.signal import butter, sosfilt import soundfile as sf import colorednoise as cn

Configuration

SAMPLE_RATE = 22050 # Reduced sample rate to optimize size DURATION = 5 # Duration in seconds

Generate colored noise (pink, brown, etc.)

def generate_colored_noise(duration, sample_rate, exponent=-1): samples = duration * sample_rate return cn.powerlaw_psd_gaussian(exponent, samples)

Band-pass filter

def band_pass_filter(data, lowcut, highcut, sample_rate, order=5): sos = butter(order, [lowcut, highcut], btype=’band’, fs=sample_rate, output=’sos’) return sosfilt(sos, data)

Add low-frequency modulation

def add_modulation(data, sample_rate, depth=0.05, frequency=0.1): t = np.linspace(0, len(data) / sample_rate, len(data), endpoint=False) modulator = 1 + depth * np.sin(2 * np.pi * frequency * t) return data * modulator

Convert mono to stereo

def convert_to_stereo(data, width=0.1, sample_rate=SAMPLE_RATE): delay_samples = int(width * sample_rate) left = data.copy() right = np.roll(data, delay_samples) # Shift data for slight delay on the right channel return np.stack((left, right), axis=1)

Normalize audio

def normalize_audio(data): return data / np.max(np.abs(data))

Main script

if name == “main“: parser = argparse.ArgumentParser(description=”Generate optimized green noise.”) parser.add_argument(“–low”, type=int, default=20, help=”Lower cutoff frequency in Hz (default: 20)”) parser.add_argument(“–high”, type=int, default=500, help=”Upper cutoff frequency in Hz (default: 500)”) parser.add_argument(“–filter”, type=int, default=4, help=”Filter steepness (default: 4)”) parser.add_argument(“–mod_depth”, type=float, default=0.05, help=”Amplitude modulation depth (default: 0.05)”) parser.add_argument(“–mod_freq”, type=float, default=0.1, help=”Amplitude modulation frequency (default: 0.1)”) args = parser.parse_args()

LOW_CUT = args.low HIGH_CUT = args.high FILTER_ORDER = args.filter MOD_DEPTH = args.mod_depth MOD_FREQUENCY = args.mod_freq OUTPUT_FILE = f"low-{LOW_CUT}-high-{HIGH_CUT}-filter-{FILTER_ORDER}.wav" print("Generating pink noise...") pink_noise = generate_colored_noise(DURATION, SAMPLE_RATE, exponent=-1) print("Generating brown noise...") brown_noise = generate_colored_noise(DURATION, SAMPLE_RATE, exponent=-2) print("Blending pink and brown noise...") blended_noise = 0.8 * pink_noise + 0.2 * brown_noise print("Applying band-pass filter...") green_noise = band_pass_filter(blended_noise, LOW_CUT, HIGH_CUT, SAMPLE_RATE, order=FILTER_ORDER) print("Adding modulation...") modulated_green_noise = add_modulation(green_noise, SAMPLE_RATE, depth=MOD_DEPTH, frequency=MOD_FREQUENCY) print("Converting to stereo...") stereo_green_noise = convert_to_stereo(modulated_green_noise) print("Normalizing audio...") final_green_noise = normalize_audio(stereo_green_noise) print(f"Saving as '{OUTPUT_FILE}'...") sf.write(OUTPUT_FILE, final_green_noise, SAMPLE_RATE, subtype='PCM_16') print(f"File saved successfully as '{OUTPUT_FILE}'.") 

“`

“`

Install dependencies:

$ pip install numpy scipy soundfile pydub colorednoise

call the script

$ python main.py –low 20 –high 250 –filter 4 “`

submitted by /u/BLCKSLM
[link] [comments] 

Leave a Reply

Your email address will not be published. Required fields are marked *