0

I am trying to plot a spectrogram of a .wav file. The strange thing about the way the below code behaves is that it works on some .wav files and fails on others. I suspect that this is because some .wav files have a different number of channels compared to others. However I have no idea how to determine how many channels a .wav file contains. I've looked at this stack overflow post prior to posting my question: What is a channel in a .wav file format?Do all channels play simultaneaously when a wav file is played?

I've pasted one of my methods below which tries to convert a a filepath(myAudio) into a jpg with filepath(fileNameToSaveTo).

def individualWavToSpectrogram(myAudio, fileNameToSaveTo):
print(myAudio)
#Read file and get sampling freq [ usually 44100 Hz ]  and sound object
samplingFreq, mySound = wavfile.read(myAudio)

#Check if wave file is 16bit or 32 bit. 24bit is not supported
mySoundDataType = mySound.dtype

#We can convert our sound array to floating point values ranging from -1 to 1 as follows

mySound = mySound / (2.**15)

#Check sample points and sound channel for duel channel(5060, 2) or  (5060, ) for mono channel

mySoundShape = mySound.shape
samplePoints = float(mySound.shape[0])

#Get duration of sound file
signalDuration =  mySound.shape[0] / samplingFreq

#If two channels, then select only one channel
mySoundOneChannel = mySound[:,0]

#Plotting the tone

# We can represent sound by plotting the pressure values against time axis.
#Create an array of sample point in one dimension
timeArray = numpy.arange(0, samplePoints, 1)

#
timeArray = timeArray / samplingFreq

#Scale to milliSeconds
timeArray = timeArray * 1000

#Plot the tone
plt.plot(timeArray, mySoundOneChannel, color='Black')
#plt.xlabel('Time (ms)')
#plt.ylabel('Amplitude')
print("trying to save")
plt.savefig('/Users/billybobjoe/Desktop/SavedSpecs' + fileNameToSaveTo + '.jpg')
print("saved")
plt.show()

This produces the following error on some of my .wav files line 57, in individualWavToSpectrogram mySoundOneChannel = mySound[:,0] IndexError: too many indices for array

The line of code that fails is

mySoundOneChannel = mySound[:,0]

How do I check the number of channels that a .wav file has, and how do I set mySoundOneChannel accordingly?

Sreehari R
  • 919
  • 4
  • 11
  • 21

1 Answers1

0

As far as I can tell, the data array mySound will have shape (nSamples, nChannels) if there are multiple channels. If there is one channel, mySound will have shape (nSamples,).

Here, your audio file must have only one channel, and therefore you cannot index it as if it is a 2D array.

Hence, you should be able to replace

mySoundOneChannel = mySound[:,0]

with something like

if len(mySound.shape) > 1:
    mySoundOneChannel = mySound[:,0]
else:
    mySoundOneChannel = mySound

To get the number of channels, you should be able to do:

if len(mySound.shape) > 1:
    nChannels = mySound.shape[1]
else:
    nChannels = 1
jpeoples
  • 121
  • 5