Reputation: 397
I have a code for handle audio data from a sound device.
My code construct the GUI through tkinter and handles audio data through the sounddevice library when the button is pressed.
When I run the code, it actually works perfectly. However, GUI freezing occurs, making it impossible to click the button.
So I tried to solve this problem through thread, but I failed repeatedly.
Please review my code and give me some advice.
This is my Code:
import sounddevice as sd
import numpy as np
import tkinter as tk
from tkinter import ttk
from threading import Thread
class Stream(Thread):
def __init__(self):
super().__init__()
self.input_device_index = 2
self.output_device_index = 4
self.BLOCK_SHIFT = 128
self.SAMPLING_RATE = 16000
self.BLOCK_LEN = 512
self.SOUND_DEVICE_LATENCY = 0.2
self.start_streaming()
def start_streaming(self):
try:
with sd.Stream(device=(self.input_device_index, self.output_device_index),
samplerate=self.SAMPLING_RATE, blocksize=self.BLOCK_SHIFT,
dtype=np.float32, latency=self.SOUND_DEVICE_LATENCY,
channels=1, callback=self.callback):
input()
except Exception as ex:
print(str(type(ex).__name__ + ': ' + str(ex)))
@staticmethod
def callback(indata, outdata, frames, time, status):
outdata[:] = indata
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("Please Help Me")
self.geometry("400x300")
self.resizable(0, 0)
start_button = tk.Button(self, overrelief="solid", width=15,
command=lambda: Function.start_button_clicked(),
text="Start", repeatdelay=1000, repeatinterval=100)
start_button.grid(column=0, row=5)
class Function:
@staticmethod
def start_button_clicked():
stream = Stream()
stream.start()
if __name__ == "__main__":
app = App()
app.mainloop()
Upvotes: 0
Views: 124
Reputation: 46688
You used Thread
inheritance in a wrong way. You should override run()
method in your class. So change start_streaming()
to run()
and remove calling start_streaming()
inside __init__()
:
class Stream(Thread):
def __init__(self):
...
# should not call start_streaming() here
#self.start_streaming()
# rename start_streaming() to run()
def run(self):
...
Upvotes: 1