Experimental Schroeder Reverb

It is an experimental Schroeder reverberator implementation. I applied three combo filters and then two all pass filters without any buffer. Reverb tail was added to the end of input signal in a simple way, too. I experimented with different alpha and delay time values to compensate for getting smooth reverb for a simple piano segment. Its impulse response for all pass filter:

(1)   \begin{equation*}  H(z) = {(-\alpha + z^{-N})} / {( 1 - \alpha z^{-N})} \end{equation*}

 

Maybe, I can try to experiment with a real structure impulse response and early reflections later on. Of course, it will be computationally expensive.

import os
import matplotlib.pyplot as plt
import numpy as np
import scipy.io.wavfile as wavfile

def reverb(fileName, alpha = 0.7, delay = 50, gain = 1.1):
 
    #fs: sampling rate of the wav file, x: integer point array
    #delay in milliseconds
        
    if (os.path.isfile(fileName) == False):					
        raise ValueError("Input file is not valid")
            
    fs, x = wavfile.read(fileName)
 
    #we only accept mono and 44.1khz audio files for this implementation  
    
    if (len(x.shape) != 1):                                  
            raise ValueError("Audio file is not mono")
    if (fs != 44100):                                        
            raise ValueError("Sampling rate of input sound is not 44100")
    
    #applying three comb filters in one-go, and then two all pass filters
    #extra samples by delay will be added, too
    
    sigLength = len(x) 
    M = int(0.001 * delay * fs)       
    y = np.zeros(sigLength + M)
      
    y = combFilter(x, y, sigLength, M)  
    y = allPassFilter(x, y, alpha, sigLength, M)
    y = allPassFilter(x, y, alpha, sigLength, M)

    #gain for final output
    y = gain * y

    wavfile.write("Reverb-Audio.wav", 44100, y.astype(np.int16))          
     
    return 

def combFilter(x, y, sigLength, M):

    #Taking first three combo coefficients ->; 0.805+0.827+0.783 = 2.415

    for n in range(0, sigLength + M):
        if n >= M and n < sigLength:           
            y[n] = 3 * x[n] + 2.415 * y[n - M] 
        elif n >= sigLength:
            y[n] = 3 * y[n-M]
        else:
            y[n] = 3 * x[n] 
            
    return y

def allPassFilter(x, y, alpha, sigLength, M):
    for n in range(0, sigLength + M):
        if n >= M and n < sigLength:
            y[n] = -alpha * x[n] + x[n - M] + alpha * y[n - M]
        elif n >= sigLength:
            y[n] = alpha * y[n-M]
        else:
            y[n] = x[n]
            
    return y

#Run it with your test audio file
reverb('C:/Users/[your name]/Desktop/[your file].wav')
[1] Schroeder Reverberators

[2] Latex code editor