0

I am seeing an issue in the magnitude response between reading a wav file with soundfile and wavefile. Here are the different plots:

enter image description here

Can you tell me what I would need to adjust in the wavefile.read to get the same magnitude as the soundfile.read?

Here is the code that I use:

import os
import matplotlib.pyplot as plt
from matplotlib import transforms
import numpy as np
import soundfile as sf

import scipy.io.wavfile as wavfile

from matplotlib.gridspec import GridSpec

input_file1 = (r'G:/file.wav')

plt.subplot(211)
a, b = sf.read(input_file1);

pxx, fs = plt.psd(a, 512, b)
plt.semilogx(fs, 10*np.log10(pxx))
plt.title('Sound File Read')
plt.grid(which='major', axis='both', color='g', linestyle='-', alpha=0.4)
plt.grid(which='minor', axis='x', color='g', linestyle='-', alpha=0.1)

  
plt.subplot(212)
sample_rate, signal1 = wavfile.read(input_file1)
Pxx, freq = plt.psd(signal1, 512, sample_rate)
plt.semilogx(freq, 10*np.log10(Pxx))
plt.grid(which='major', axis='both', color='g', linestyle='-', alpha=0.4)
plt.grid(which='minor', axis='x', color='g', linestyle='-', alpha=0.1)
plt.title('Wavfile File Read')
plt.ylabel('PSD')

plt.xlabel('Frequency (Hz)')

# set the spacing between subplots
plt.tight_layout()

plt.show()

Here is a link to an example .wav file.

Thanks!

Joe
  • 357
  • 2
  • 10
  • 32
  • 1
    From what I could read, wavfile.io.read and soundfile.read do pretty much the same thing except for one default behavior: wavfile determines its array's dtype from the file, while soundfile has a default `float64`. Typically, `float_` arrays for sound are normalized between -1 and 1, while `int_` arrays keep the signal between the integer's minimum and maximum. Check your arrays' `.dtype` and the `.min()` and `.max()` values. – BatWannaBe Aug 19 '21 at 18:53
  • @BatWannaBe, thanks for your input. I do see that the ndarray (using the first data point), for the `soundfile` the value is -0.00225866, where as for the `wavfile`, the number is -4850432. Is there a way to convert these `wavfile` numbers to `float_`? – Joe Aug 19 '21 at 19:10

1 Answers1

1

By the two values you reported, it really does seem like soundfile.read gave you a float64 array between -1 and 1 while wavfile.io.read gave you a int32 array between -2147483648 and 2147483647 (-4850432/2147483648 = -0.00225866). You can make a normalized float_ array from either int_ or float_ array with the following:

def normalize(signal1):
    try:
        intinfo = np.iinfo(signal1.dtype)
        return signal1 / max( intinfo.max, -intinfo.min )

    except ValueError: # array is not integer dtype
        return signal1 / max( signal1.max(), -signal1.min() )
BatWannaBe
  • 4,330
  • 1
  • 14
  • 23