Fight Fire With Fire
Fight Fire With Fire

Reputation: 1686

Plot a Wave files Audio Visually In Python

I am trying to figure out how to plot the audio visually of a wav file. In my code if I do a wavefile.readframe(-1) I get the whole wav file plotted, the way my code works now is I just get a silver (one frame!) I'd like to show 24 frames of audio on each image plot from the wave file so I can animate it. Hopefully this is clear.

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy as np
import wave , sys , os , struct

waveFile = wave.open('mono.wav','r')
length = waveFile.getnframes()
for i in range(0,length):
    print i # so we know where we are at.
    waveData = waveFile.readframes(i)
    fs = waveFile.getframerate()
    signal = np.fromstring(waveData, 'Int16')
    Time=np.linspace(0, len(signal)/fs, num=len(signal))
    plt.axis('off')
    plt.plot(Time,signal , 'w')
    plt.savefig('signal' + str(i) + '.png' , facecolor='none', edgecolor='none', transparent=True, frameon=False)
    plt.close

Code generates just this minute sliver of the audio spectrum

waveFile.readframes(-1) gives me the whole wave file audio spectrum

Upvotes: 3

Views: 7476

Answers (2)

Fight Fire With Fire
Fight Fire With Fire

Reputation: 1686

I recoded a bit , the above answered help, but I needed to do more massaging. So if you have a need to plot audio this way in realtime just adjust the readframes for as many frames you would like to take in. To plot each frame I wound up having to make seperate plt.figure id's This code snip will get you where you want to go

wave_file = wave.open('mono.wav', 'r')
data_size = wave_file.getnframes()
sample_rate = wave_file.getframerate()


while True:

    waveData = wave_file.readframes(10000)
    signal = np.fromstring(waveData , 'Int16')
    Time=np.linspace(0, len(signal), num=len(signal))

    plt.figure()
    fig = plt.figure(figsize=(xinch,yinch) , frameon=False)
    #fig = plt.figure(frameon=False)
    ax = fig.add_axes([0, 0, 1, 1])
    #ax.axis('off')

    plt.axis('off')
    line = plt.plot(Time,signal , 'w')
    plt.setp(line, linewidth=10)

    plt.savefig('signal' + str(x) + '.png')
    plt.close

    x+= 1
    if  wave_file.tell() == data_size:
            break

Will result in frames like this: wave form plot real time example

Upvotes: 0

ali_m
ali_m

Reputation: 74262

From the documentation:

Wave_read.readframes(n)

Reads and returns at most n frames of audio, as a string of bytes.

So to read a chunk of 24 frames you simply call

waveData = waveFile.readframes(24)

When you open the file in read ('r') mode, the file pointer starts out at the 0th frame. As you read frames from the file, you will advance the file pointer by the same number of frames. This means that calling waveFile.readframes(24) repeatedly will yield consecutive chunks of 24 frames until you hit the end of the file - there's no need to pass a changing index i.

To keep track of where you are within the file, you can call waveFile.tell(), and to skip forwards or backwards to the kth frame you can use waveFile.setpos(k).

By the way, this behaviour is very consistent with how standard file objects work in Python.

Upvotes: 1

Related Questions