0

I have been playing with scipy audio for the last couple days. the code below works in terms of that it takes an audio file and an impulse response. then applies convolution and saves the file. so far so good.

when reimporting the file and applying deconvolution to it, to regenerate the initial file. it still works perfectly.

BUT, when any other file is passed to the deconvolution function, the returned array holds lots of NaN and 0s.

even if I load the file and run it thru the convolution function with an impulse response of a single 1 (flat filter). in order to get a file that went thru the same process.

The array with NaN and zeros eventually ends in an error when trying to write the file to disk after deconvolution.

Any ideas? Hints?

Im new to coding and this is my first post. please be gentle.

import scipy
import numpy as np
import librosa
from scipy import signal


def main():
    #samplerate
    sr = 44100
    #file path
    dryFile = "/Users/davidhefti/Dropbox/DPsync/dh prog/python/thinkDsp2.0/audio2/original2_01.wav"
    irFile = "/Users/davidhefti/Dropbox/DPsync/dh prog/python/thinkDsp2.0/audio2/IR2_01.wav"
    convolutionOut = "/Users/davidhefti/Dropbox/DPsync/dh prog/python/thinkDsp2.0/dump/convolved1.wav"
    filtered = "/Users/davidhefti/Dropbox/DPsync/dh prog/python/thinkDsp2.0/dump/convolved1.wav"
    deConvolutionOut = "/Users/davidhefti/Dropbox/DPsync/dh prog/python/thinkDsp2.0/dump/DEconvolved1.wav"

    do_Convolution(dryFile, irFile, convolutionOut, sr)

    do_Deconvolution(filtered, irFile, deConvolutionOut, sr)


"""FUNCTIONS"""

def print_properties(name, array):
    print("Name {}".format(name))
    print("Shape: {}".format(array.shape))
    print("Type: {}".format(array.dtype))
    print("Min Value: {}".format(array.min()))
    print("Max Value: {}".format(array.max()))
    print()


def do_Convolution(sourcePath, irPath, outPath, samplerate):
    """load INFILE 1"""
    source, sSR = librosa.load(sourcePath, sr=samplerate)
    source64 = source.astype(np.float64)
    print_properties("input file before convolution", source64)

    """load IR"""
    ir, irSR = librosa.load(irPath, sr=samplerate)
    ir64 = ir.astype(np.float64)
    print_properties("Impulse response", ir64)

    """CONVOLVE AND WRITE 64bit"""
    convolve = signal.convolve(source64, ir64)
    print_properties("CONVOLUTION", convolve)
    librosa.output.write_wav(outPath, convolve, sr=samplerate)


def do_Deconvolution(sourcePath, irPath, outPath, samplerate):
    """load convolutioned file NEEDS TO BE 64 BIT MONO?"""
    relSR, reloaded = scipy.io.wavfile.read(sourcePath)
    print_properties("reloaded", reloaded)

    """Load IR"""
    ir, irSR = librosa.load(irPath, sr=samplerate)

    """DECONVOLVE"""
    deconvolve, remainder = signal.deconvolve(reloaded, ir)
    print_properties("DECONVOLUTION", deconvolve)
    librosa.output.write_wav(outPath, deconvolve, samplerate)


if __name__ == "__main__":
    main()
tr909
  • 9
  • 3
  • So, call your variable `impulse_response`. You can get a text editor with autocomplete functionality so that you won't have to worry about typing long variable names. And then people like me who are reading your code will be much happier :D – Max Paymar Apr 21 '17 at 21:19
  • Also, I would name your functions differently. A function should be a verb, like `convolve` or `deconvolve`. If you have to write 'do' in front of your function name, you can probably name it better. – Max Paymar Apr 21 '17 at 21:26
  • Lastly, you are using a mixture of `# comments` and `"""strings"""` for your comments. I would use `# comments` for noting small things in your code like `# load convolutioned file NEEDS TO BE 64 BIT MONO?`. Use """ for explanations of your functions. like so: http://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html – Max Paymar Apr 21 '17 at 21:31
  • 1
    use numpy.nan_to_num to convert NaN values to e.g. zero before writing to file (btw, the other comments are very helpful, just not on topic) – xaedes Jan 08 '21 at 18:57

0 Answers0