# -*- coding: utf-8 -*- """ AudioRecorder – minimaler Recorder mit sounddevice (16kHz mono WAV). """ import os import tempfile import wave class AudioRecorder: """ Minimaler Recorder mit sounddevice. Speichert als 16kHz mono WAV (16-bit PCM). """ def __init__(self, samplerate=16000, channels=1): self.samplerate = samplerate self.channels = channels self._stream = None self._frames = [] self._recording = False def start(self): try: import sounddevice as sd except Exception as e: raise RuntimeError( "Python-Paket 'sounddevice' fehlt.\n\n" "Installiere es mit:\n" " py -3.11 -m pip install sounddevice\n\n" f"Details: {e}" ) self._frames = [] self._recording = True def callback(indata, frames, time_info, status): if self._recording: self._frames.append(indata.copy()) self._stream = sd.InputStream( samplerate=self.samplerate, channels=self.channels, callback=callback, dtype="float32", blocksize=0, ) self._stream.start() def stop_and_save_wav(self) -> str: if not self._stream: raise RuntimeError("Recorder wurde nicht gestartet.") self._recording = False self._stream.stop() self._stream.close() self._stream = None if not self._frames: raise RuntimeError("Keine Audio-Daten aufgenommen (leer).") import numpy as np audio = np.concatenate(self._frames, axis=0) audio = np.clip(audio, -1.0, 1.0) pcm16 = (audio * 32767.0).astype(np.int16) fd, path = tempfile.mkstemp(suffix=".wav", prefix="kg_rec_") os.close(fd) with wave.open(path, "wb") as wf: wf.setnchannels(self.channels) wf.setsampwidth(2) wf.setframerate(self.samplerate) wf.writeframes(pcm16.tobytes()) return path