dashboard: media bongo cat
This commit is contained in:
parent
07954a4ed8
commit
cf965934ac
3 changed files with 102 additions and 0 deletions
BIN
assets/bongocat.gif
Normal file
BIN
assets/bongocat.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.3 KiB |
73
assets/realtime-beat-detector.py
Executable file
73
assets/realtime-beat-detector.py
Executable file
|
|
@ -0,0 +1,73 @@
|
||||||
|
#!/bin/python
|
||||||
|
|
||||||
|
import pyaudio
|
||||||
|
import numpy as np
|
||||||
|
import aubio
|
||||||
|
import signal
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from typing import List, Tuple
|
||||||
|
|
||||||
|
|
||||||
|
class BeatDetector:
|
||||||
|
def __init__(self, buf_size: int):
|
||||||
|
self.buf_size: int = buf_size
|
||||||
|
|
||||||
|
# Set up pyaudio and aubio beat detector
|
||||||
|
self.audio: pyaudio.PyAudio = pyaudio.PyAudio()
|
||||||
|
samplerate: int = 44100
|
||||||
|
|
||||||
|
self.stream: pyaudio.Stream = self.audio.open(
|
||||||
|
format=pyaudio.paFloat32,
|
||||||
|
channels=1,
|
||||||
|
rate=samplerate,
|
||||||
|
input=True,
|
||||||
|
frames_per_buffer=self.buf_size,
|
||||||
|
stream_callback=self._pyaudio_callback
|
||||||
|
)
|
||||||
|
|
||||||
|
fft_size: int = self.buf_size * 2
|
||||||
|
|
||||||
|
# tempo detection
|
||||||
|
self.tempo: aubio.tempo = aubio.tempo("default", fft_size, self.buf_size, samplerate)
|
||||||
|
|
||||||
|
# this one is called every time enough audio data (buf_size) has been read by the stream
|
||||||
|
def _pyaudio_callback(self, in_data, frame_count, time_info, status):
|
||||||
|
# Interpret a buffer as a 1-dimensional array (aubio do not work with raw data)
|
||||||
|
audio_data = np.frombuffer(in_data, dtype=np.float32)
|
||||||
|
# true if beat present
|
||||||
|
beat = self.tempo(audio_data)
|
||||||
|
|
||||||
|
# if beat detected, calculate BPM and send to OSC
|
||||||
|
if beat[0]:
|
||||||
|
print(self.tempo.get_bpm(), flush=True)
|
||||||
|
|
||||||
|
return None, pyaudio.paContinue # Tell pyAudio to continue
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
self.stream.close()
|
||||||
|
self.audio.terminate()
|
||||||
|
print('--- Stopped ---')
|
||||||
|
|
||||||
|
|
||||||
|
# main
|
||||||
|
def main():
|
||||||
|
bd = BeatDetector(512)
|
||||||
|
|
||||||
|
# capture ctrl+c to stop gracefully process
|
||||||
|
def signal_handler(none, frame):
|
||||||
|
bd.stream.stop_stream()
|
||||||
|
bd.stream.close()
|
||||||
|
bd.audio.terminate()
|
||||||
|
print(' ===> Ctrl + C')
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
signal.signal(signal.SIGINT, signal_handler)
|
||||||
|
|
||||||
|
# Audio processing happens in separate thread, so put this thread to sleep
|
||||||
|
signal.pause()
|
||||||
|
|
||||||
|
|
||||||
|
# main run
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
import "root:/widgets"
|
import "root:/widgets"
|
||||||
import "root:/services"
|
import "root:/services"
|
||||||
import "root:/config"
|
import "root:/config"
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
import Quickshell.Widgets
|
import Quickshell.Widgets
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Shapes
|
import QtQuick.Shapes
|
||||||
|
|
@ -210,6 +212,33 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AnimatedImage {
|
||||||
|
id: bongocat
|
||||||
|
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.bottomMargin: Appearance.padding.large
|
||||||
|
anchors.margins: Appearance.padding.large * 2
|
||||||
|
|
||||||
|
playing: false
|
||||||
|
source: "root:/assets/bongocat.gif"
|
||||||
|
asynchronous: true
|
||||||
|
fillMode: AnimatedImage.PreserveAspectFit
|
||||||
|
z: -1
|
||||||
|
|
||||||
|
Process {
|
||||||
|
running: true
|
||||||
|
command: [`${Quickshell.shellRoot}/assets/realtime-beat-detector.py`]
|
||||||
|
stdout: SplitParser {
|
||||||
|
onRead: data => {
|
||||||
|
if (Players.active?.isPlaying)
|
||||||
|
bongocat.currentFrame++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
component Control: StyledRect {
|
component Control: StyledRect {
|
||||||
id: control
|
id: control
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue