jeudi 13 août 2015

Pause/restart and volume control buttons in a GUI to control the audio recording by using python

I currently have a program to collect sound signal from a mic and play the wave form at real-time on python.I am thinking to add some buttons in a GUI for it. Something like pause and restart buttons. Users can control the sound recording by mouse click on these buttons to stop or restart real-time wave display. And the volume control buttons to increase or reduce the volume of output.

Here is the code:

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()



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire