Untitled
unknown
plain_text
2 months ago
4.6 kB
2
Indexable
import pyaudio import wave import numpy as np import matplotlib.pyplot as plt from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg import tkinter as tk from tkinter import messagebox import threading import time class SimpleDAW: def __init__(self, root): self.root = root self.root.title("Simple DAW") self.chunk = 1024 # Audio chunk size self.sample_rate = 44100 # Standard sample rate self.format = pyaudio.paInt16 self.channels = 2 # Stereo self.audio = pyaudio.PyAudio() self.recording = False self.playing = False self.frames = [] # Store recorded audio frames self.audio_file = "output.wav" # Temp file for saving recordings # GUI Setup self.setup_gui() def setup_gui(self): # Control Buttons self.btn_record = tk.Button(self.root, text="Record", command=self.start_recording) self.btn_record.pack(pady=5) self.btn_stop = tk.Button(self.root, text="Stop", command=self.stop) self.btn_stop.pack(pady=5) self.btn_play = tk.Button(self.root, text="Play", command=self.play_recording) self.btn_play.pack(pady=5) # Timeline (simulated with a label for now) self.timeline_label = tk.Label(self.root, text="Timeline: [Empty]") self.timeline_label.pack(pady=5) # Waveform Plot self.fig, self.ax = plt.subplots() self.canvas = FigureCanvasTkAgg(self.fig, master=self.root) self.canvas.get_tk_widget().pack(pady=10) def start_recording(self): if not self.recording: self.recording = True self.frames = [] self.btn_record.config(text="Recording...") threading.Thread(target=self.record_audio, daemon=True).start() def record_audio(self): stream = self.audio.open(format=self.format, channels=self.channels, rate=self.sample_rate, input=True, frames_per_buffer=self.chunk) while self.recording: data = stream.read(self.chunk) self.frames.append(data) stream.stop_stream() stream.close() self.btn_record.config(text="Record") self.save_recording() def save_recording(self): wf = wave.open(self.audio_file, 'wb') wf.setnchannels(self.channels) wf.setsampwidth(self.audio.get_sample_size(self.format)) wf.setframerate(self.sample_rate) wf.writeframes(b''.join(self.frames)) wf.close() self.update_waveform() self.timeline_label.config(text=f"Timeline: {self.audio_file} [Recorded]") def stop(self): self.recording = False self.playing = False def play_recording(self): if not self.playing and self.frames: self.playing = True threading.Thread(target=self.play_audio, daemon=True).start() def play_audio(self): wf = wave.open(self.audio_file, 'rb') stream = self.audio.open(format=self.audio.get_format_from_width(wf.getsampwidth()), channels=wf.getnchannels(), rate=wf.getframerate(), output=True) data = wf.readframes(self.chunk) while data and self.playing: stream.write(data) data = wf.readframes(self.chunk) stream.stop_stream() stream.close() wf.close() self.playing = False def update_waveform(self): wf = wave.open(self.audio_file, 'rb') signal = wf.readframes(-1) signal = np.frombuffer(signal, dtype=np.int16) wf.close() # Normalize for visualization signal = signal / np.max(np.abs(signal)) if np.max(np.abs(signal)) > 0 else signal time_axis = np.linspace(0, len(signal) / self.sample_rate, num=len(signal)) self.ax.clear() self.ax.plot(time_axis, signal) self.ax.set_title("Waveform") self.ax.set_xlabel("Time (s)") self.ax.set_ylabel("Amplitude") self.canvas.draw() def on_closing(self): self.stop() self.audio.terminate() self.root.destroy() def main(): root = tk.Tk() app = SimpleDAW(root) root.protocol("WM_DELETE_WINDOW", app.on_closing) root.mainloop() if __name__ == "__main__": main()
Editor is loading...
Leave a Comment