Skip to content

Instantly share code, notes, and snippets.

@rechner
Last active November 23, 2015 21:43
Show Gist options
  • Save rechner/4969a8c6f1d759e79300 to your computer and use it in GitHub Desktop.
Save rechner/4969a8c6f1d759e79300 to your computer and use it in GitHub Desktop.
from kivy.app import App
from kivy.clock import Clock
from kivy.uix.widget import Widget
from kivy.graphics import Color, Line
import random, time
import queue, threading
class FFTGraph(Widget):
def draw_graph(self, dt):
try:
samples = self.sound_queue.get(timeout=0.1)
except queue.Empty:
return
# Normalize the samples from screen_height to 0:
height = self.size[1]
samples = [ height - int(s * height) for s in samples ]
# Transform the samples into [(x, y),...] coords:
lines = list(zip(range(len(samples)), samples))
# Flatten the list:
points = [ n for coord in lines for n in coord ]
# Put it on the screen
self.canvas.clear()
with self.canvas:
Color(1., 1., 0)
Line(points=points, width=1)
class TestApp(App):
def build(self):
fft = FFTGraph()
fft.sound_queue = self.sound_queue
Clock.schedule_interval(fft.draw_graph, 1 / 30.)
return fft
def play_sound(fft_queue):
frame_count = 1
while True:
# Fetch audio chunk
fft_bins = [] #...
# Put frame in the queue as often as we want to draw it:
if frame_count == 200:
count = 1
# 512 samples of amplitude between 0 and 1:
fft_bins = [ random.random() for r in range(512) ]
# If .put is too slow for audio, try put_nowait() instead
fft_queue.put(fft_bins)
# Pipe audio to sound card
time.sleep(1.0 / 8000)
frame_count += 1
if __name__ == '__main__':
# Build the kivy app and pass in our Queue for sending fft bins:
app = TestApp()
app.sound_queue = queue.Queue()
# Set up our audio playing thread
stream = threading.Thread(target=play_sound, args=(app.sound_queue,))
stream.daemon = True
stream.start()
# Kick off the GUI event loop
app.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment