0

I want to make a program to display the real time input audio signals in the forms of FFT and Amplitute via a USB audio card in raspberry pi. So it supposes to have a user interface to display the wave spectrum.

The code is showing below

import pyaudio
import tkinter as tk
import wave
import threading
import queue

import matplotlib.pyplot as plt
import matplotlib.animation as animation
import matplotlib.lines as line
import numpy as np
from scipy import fftpack
from scipy import signal

CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "output.wav"
data =[]
Recording=False
FFT_LEN = 128
frames=[]
counter=1

#GUI
class Application(tk.Frame):
    def __init__(self,master=None):
        tk.Frame.__init__(self,master)
        self.grid()
        self.creatWidgets()

    def creatWidgets(self):
        self.quitButton=tk.Button(self,text='quit',command=root.destroy)
        self.quitButton.grid(column=1,row=3)


#Matplotlib
fig = plt.figure()
rt_ax = plt.subplot(212,xlim=(0,CHUNK), ylim=(-10000,10000))
fft_ax = plt.subplot(211)
fft_ax.set_yscale('log')
fft_ax.set_xlim(0,CHUNK/2 + 1)
fft_ax.set_ylim(1,100000000)
rt_ax.set_title("Real Time")
fft_ax.set_title("FFT Time")
rt_line = line.Line2D([],[])
fft_line = line.Line2D([],[])

rt_data=np.arange(0,CHUNK,1)
fft_data=np.arange(0,CHUNK/2 + 1,1)
rt_x_data=np.arange(0,CHUNK,1)
fft_x_data=np.arange(0,CHUNK/2 + 1,1)

def plot_init():
    rt_ax.add_line(rt_line)
    fft_ax.add_line(fft_line)
    return fft_line,rt_line,

def plot_update(i):
    global rt_data
    global fft_data

    rt_line.set_xdata(rt_x_data)
    rt_line.set_ydata(rt_data)

    fft_line.set_xdata(fft_x_data)
    fft_line.set_ydata(fft_data)
    return fft_line,rt_line,


ani = animation.FuncAnimation(fig, plot_update,
                              init_func=plot_init, 
                              frames=1,
                              interval=30,
                              blit=True)


# pyaudio
p = pyaudio.PyAudio()
q = queue.Queue()

def audio_callback(in_data, frame_count, time_info, status):
    global ad_rdy_ev

    q.put(in_data)
    ad_rdy_ev.set()
    if counter <= 0:
        return (None,pyaudio.paComplete)
    else:
        return (None,pyaudio.paContinue)


stream = p.open(format=FORMAT,
        channels=CHANNELS,
        rate=RATE,
        input=True,
        output=False,
        frames_per_buffer=CHUNK,
        stream_callback=audio_callback)


if Recording:
    wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
    wf.setnchannels(CHANNELS)
    wf.setsampwidth(p.get_sample_size(FORMAT))
    wf.setframerate(RATE)

print("Start Recording")
stream.start_stream()

#processing block

window = signal.hamming(CHUNK)

def read_audio_thead(q,stream,frames,ad_rdy_ev):
    global rt_data
    global fft_data

    while stream.is_active():
        ad_rdy_ev.wait(timeout=1000)
        if not q.empty():
            #process audio data here
            data=q.get()
            while not q.empty():
                q.get()
            rt_data = np.frombuffer(data,np.dtype('<i2'))
            rt_data = rt_data * window
            fft_temp_data=fftpack.fft(rt_data,rt_data.size,overwrite_x=True)
            fft_data=np.abs(fft_temp_data)[0:fft_temp_data.size/2+1]
            if Recording :
                frames.append(data)
        ad_rdy_ev.clear()

ad_rdy_ev=threading.Event()

t=threading.Thread(target=read_audio_thead,args=(q,stream,frames,ad_rdy_ev))

t.daemon=True
t.start()

plt.show()
root=tk.Tk()
app=Application(master=root)
app.master.title("Test")
app.mainloop()

stream.stop_stream()
stream.close()
p.terminate()

print("* done recording")
if Recording:
    wf.writeframes(b''.join(frames))
    wf.close()

The error shows:

trackback (most recent call last):
File "/home/pi/GUI2.py", line 102, in <module>
stream_callback=audio_callback)
File "/usr/lib/pymodules/python2.7/pyaudio.py", line 714, in open
stream=Stream(self, *args, **kwargs)
TypeError: _init_() got an unexpected keyword argument 'stream_callback'

Thank you very much for any help.

  • related question, possibly duplicate: stackoverflow.com/questions/19123085/… . Check if your PyAudio version handles the stream_callback argument, it seems it doesn't. – Frepa Jul 26 '15 at 16:53
  • @Frepa Thank you very much. That solved my problem. – Sid Jul 29 '15 at 10:41
1

Update the version of pyaudio and portaudio solved the problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.