How to plot a wav file

前端 未结 8 1037
时光取名叫无心
时光取名叫无心 2020-12-12 10:51

I have just read a wav file with scipy and now I want to make the plot of the file using matplotlib, on the \"y scale\" I want to see the aplitude and over the \"x scale\" I

相关标签:
8条回答
  • 2020-12-12 11:23

    Here is the code to draw a waveform and a frequency spectrum of a wavefile

    import wave
    import numpy as np
    import matplotlib.pyplot as plt
    
    signal_wave = wave.open('voice.wav', 'r')
    sample_rate = 16000
    sig = np.frombuffer(signal_wave.readframes(sample_rate), dtype=np.int16)
    

    For the whole segment of the wave file

    sig = sig[:]
    

    For partial segment of the wave file

    sig = sig[25000:32000]
    

    Separating stereo channels

    left, right = data[0::2], data[1::2]
    

    Plot the waveform (plot_a) and the frequency spectrum (plot_b)

    plt.figure(1)
    
    plot_a = plt.subplot(211)
    plot_a.plot(sig)
    plot_a.set_xlabel('sample rate * time')
    plot_a.set_ylabel('energy')
    
    plot_b = plt.subplot(212)
    plot_b.specgram(sig, NFFT=1024, Fs=sample_rate, noverlap=900)
    plot_b.set_xlabel('Time')
    plot_b.set_ylabel('Frequency')
    
    plt.show()
    

    0 讨论(0)
  • 2020-12-12 11:28

    I suppose I could've put this in a comment, but building slightly on the answers from both @ederwander and @TimSC, I wanted to make something more fine (as in detailed) and aesthetically pleasing. The code below creates what I think is a very nice waveform of a stereo or mono wave file (I didn't need a title so I just commented that out, nor did I need the show method - just needed to save the image file).

    Here's an example of a stereo wav rendered:

    And the code, with the differences I mentioned:

    import matplotlib.pyplot as plt
    import numpy as np
    import wave
    
    file = '/Path/to/my/audio/file/DeadMenTellNoTales.wav'
    
    wav_file = wave.open(file,'r')
    
    #Extract Raw Audio from Wav File
    signal = wav_file.readframes(-1)
    if wav_file.getsampwidth() == 1:
        signal = np.array(np.frombuffer(signal, dtype='UInt8')-128, dtype='Int8')
    elif wav_file.getsampwidth() == 2:
        signal = np.frombuffer(signal, dtype='Int16')
    else:
        raise RuntimeError("Unsupported sample width")
    
    # http://schlameel.com/2017/06/09/interleaving-and-de-interleaving-data-with-python/
    deinterleaved = [signal[idx::wav_file.getnchannels()] for idx in range(wav_file.getnchannels())]
    
    #Get time from indices
    fs = wav_file.getframerate()
    Time=np.linspace(0, len(signal)/wav_file.getnchannels()/fs, num=len(signal)/wav_file.getnchannels())
    plt.figure(figsize=(50,3))
    #Plot
    plt.figure(1)
    #don't care for title
    #plt.title('Signal Wave...')
    for channel in deinterleaved:
        plt.plot(Time,channel, linewidth=.125)
    #don't need to show, just save
    #plt.show()
    plt.savefig('/testing_folder/deadmentellnotales2d.png', dpi=72)
    
    0 讨论(0)
提交回复
热议问题