Created
August 31, 2023 14:45
-
-
Save EricsonWillians/f79de24dbeefdb313ffa563410b469fd to your computer and use it in GitHub Desktop.
Compressor Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy as np | |
from scipy.io import wavfile | |
from math import pow | |
def dB_to_ratio(dB): | |
return pow(10, dB / 20) | |
def compress_audio(sample_rate, audio, threshold, ratio, attack_time, release_time): | |
compressed_audio = np.zeros_like(audio, dtype=np.float32) | |
gain_reduction = 0 | |
attack_coeff = np.exp(-1 / (sample_rate * attack_time)) | |
release_coeff = np.exp(-1 / (sample_rate * release_time)) | |
for i in range(len(audio)): | |
# Threshold and Ratio for Compression | |
if abs(audio[i]) > threshold: | |
new_gr = 1.0 - (1.0 / ratio) | |
else: | |
new_gr = 0.0 | |
# Attack and Release | |
if new_gr < gain_reduction: | |
gain_reduction = attack_coeff * (gain_reduction - new_gr) + new_gr | |
else: | |
gain_reduction = release_coeff * (gain_reduction - new_gr) + new_gr | |
# Apply compression | |
compressed_audio[i] = audio[i] * (1.0 - gain_reduction) | |
return compressed_audio | |
def apply_noisegate(audio, threshold): | |
return np.where(abs(audio) < threshold, 0, audio) | |
def apply_gain(audio, gain_dB): | |
gain_ratio = dB_to_ratio(gain_dB) | |
return audio * gain_ratio | |
def apply_limiter(audio, threshold): | |
return np.clip(audio, -threshold, threshold) | |
# Read WAV file | |
sample_rate, audio = wavfile.read("input.wav") | |
audio = np.float32(audio) | |
# Noise Gate | |
audio = apply_noisegate(audio, 1000) | |
# Compressor with Attack and Release | |
compressed_audio = compress_audio( | |
sample_rate, | |
audio, | |
threshold=0.2 * np.max(np.abs(audio)), | |
ratio=4, | |
attack_time=0.001, | |
release_time=0.1 | |
) | |
# Gain in dB | |
compressed_audio = apply_gain(compressed_audio, 2) | |
# Limiter | |
final_audio = apply_limiter(compressed_audio, 0.9 * np.max(np.abs(audio))) | |
# Convert to int16 for saving | |
final_audio = np.int16(final_audio) | |
# Save output | |
wavfile.write("output.wav", sample_rate, final_audio) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment