view demo/workspace/reverb.py @ 13:16066f0a7127 tip

fixed the problem with brat
author Emmanouil Theofanis Chourdakis <e.t.chourdakis@qmul.ac.uk>
date Sat, 08 Dec 2018 11:02:40 +0000
parents 90155bdd5dd6
children
line wrap: on
line source
import pandas as pd
import numpy as np
from numpy.core._internal import _gcd as gcd


def zafar(lx, rx, d1, g1, m, fc, G, da=0.007, fs=44100.):
    """ Rafii & Pardo Reverberator (2009) controlled by High Level parameters
        Inputs:
            lx : left channel input
            rx : right channel input
            d1 : delay of first comb filter in seconds
            g1 : gain of first comb filters
            da : delay of allpass filter in seconds
            G  : dry/wet mix gain
            fc : lowpass filter cuttoff Hz
            m  : difference between left and right channel phases
            fs : sampling rate

        Outputs:
            ly: left channel output
            ry: right channel output
            """

    d1 = int(d1 * fs)
    m = int(m * fs)
    da = int(da * fs)

    def calculate_parameters(d1, g1):

        d2 = int(round((1.5) ** (-1) * d1))

        while gcd(d2, d1) != 1:
            d2 += 1

        d3 = int(round((1.5) ** (-2) * d1))

        while gcd(d3, d2) != 1 or gcd(d3, d1) != 1:
            d3 += 1

        d4 = int(round((1.5) ** (-3) * d1))

        while gcd(d4, d3) != 1 or gcd(d4, d2) != 1 or gcd(d4, d1) != 1:
            d4 += 1

        d5 = int(round((1.5) ** (-4) * d1))

        while gcd(d5, d4) != 1 or gcd(d5, d3) != 1 or gcd(d5, d2) != 1 or gcd(d5, d1) != 1:
            d5 += 1

        d6 = int(round((1.5) ** (-5) * d1))
        while gcd(d6, d5) != 1 or gcd(d6, d4) != 1 or gcd(d6, d3) != 1 or gcd(d6, d2) != 1 or gcd(d6, d1) != 1:
            d6 += 1
        g2 = g1 ** (1.5) ** (-1) * g1
        g3 = g1 ** (1.5) ** (-2) * g1
        g4 = g1 ** (1.5) ** (-3) * g1
        g5 = g1 ** (1.5) ** (-4) * g1
        g6 = g1 ** (1.5) ** (-5) * g1

        return (d1, d2, d3, d4, d5, d6, g1, g2, g3, g4, g5, g6)

    def comb_array(x, g1, d1):

        (d1, d2, d3, d4, d5, d6, g1, g2, g3, g4, g5, g6) = calculate_parameters(d1, g1)

        c1out = comb(x, g1, d1)
        c2out = comb(x, g2, d2)
        c3out = comb(x, g3, d3)
        c4out = comb(x, g4, d4)
        c5out = comb(x, g5, d5)
        c6out = comb(x, g6, d6)

        Lc1 = len(c1out)
        Lc2 = len(c2out)
        Lc3 = len(c3out)
        Lc4 = len(c4out)
        Lc5 = len(c5out)
        Lc6 = len(c6out)

        Lc = max(Lc1, Lc2, Lc3, Lc4, Lc5, Lc6)

        y = np.zeros((Lc,))

        y[0:Lc1] = c1out
        y[0:Lc2] += c2out
        y[0:Lc3] += c3out
        y[0:Lc4] += c4out
        y[0:Lc5] += c5out
        y[0:Lc6] += c6out

        return y

    def comb(x, g, d):
        LEN = len(x) + d
        #    print d
        y = np.zeros((LEN,))
        for n in range(0, LEN):
            if n - d < 0:
                y[n] = 0
            else:
                y[n] = x[n - d] + g * y[n - d]

        return y

    def allpass(x, g, d):
        LENx = len(x)
        LENy = LENx + d
        y = np.zeros((LENy,))
        for n in range(0, LENy):
            if n - d < 0:
                y[n] = -g * x[n]
            elif n >= LENx:
                y[n] = x[n - d] + g * y[n - d]
            else:
                y[n] = x[n - d] - g * x[n] + g * y[n - d]

        return y

    def lowpass(x, g):
        LEN = len(x)
        y = np.zeros((LEN,))

        for n in range(0, LEN):
            if n - 1 < 0:
                y[n] = (1 - g) * x[n]
            else:
                y[n] = (1 - g) * x[n] + g * y[n - 1]

        return y

    ga = 1. / np.sqrt(2.)

    cin = 0.5 * lx + 0.5 * rx
    cout = comb_array(cin, g1, d1)

    ra = allpass(cout, ga, da + m // 2)
    la = allpass(cout, ga, da - m // 2)

    gc = 2 - np.cos(2 * np.pi * fc / fs) - np.sqrt((np.cos(2 * np.pi * fc / fs) - 2) ** 2 - 1)

    ral = lowpass(ra, gc)
    lal = lowpass(la, gc)

    ralg = G * ral
    lalg = G * lal

    ry = ralg[0:len(rx)] + (1 - G) * rx
    ly = lalg[0:len(lx)] + (1 - G) * lx

    return np.vstack([ry, ly])

def get_reverb_from_tags(x, tags, fs=44100):
    reverb_csv = 'contributions.csv'
    df = pd.read_csv(reverb_csv)
    df = df.fillna("")
    params = []
    for n in range(len(df)):
        if all([t in df['agreed'].iloc[n].split(',') for t in tags]):
            params.append(df['param'].iloc[n])
    d1, g1, m, fc, G = [float(f) for f in params[0].split(',')]
    y = zafar(x, x, d1, g1, m, fc, G, fs=fs)
    return y