Audioframe manipulieren
Verfasst: Dienstag 29. Dezember 2020, 15:35
Guten Tag,
ich beschäftige mich seit einiger Zeit mit der Manipulation von Audioframes um dessen Qualität steigern zu können um in meinem Fall die Erkennung von Sprache-zu-Text (Vosk) zu verbessern.
Geplant ist:
- Rauschen entfernen
- Stille anhängen um das zerhacken des streams zu vermeiden
- Komressor Funktion um die stimme anheben zu können
- Weitere verbesserungen
Mein Scrit sieht derzeit so aus:
Jedoch sobald ich versuche das ganze über audioop, Pydub oder eigenen funktionen zu manipulieren bekomme ich gleich fehler wie "int found need byte like"
Mein Grundgedanke ist das ich ersmal die byteorder berücksichten sollte So das man mit Little Endian arbeitet doch wie gehts weiter?
Mir gehen langsam die Ideen aus und hoffe ihr könnt mir dabei weiterhelfen.
MfG
Toaster1337
ich beschäftige mich seit einiger Zeit mit der Manipulation von Audioframes um dessen Qualität steigern zu können um in meinem Fall die Erkennung von Sprache-zu-Text (Vosk) zu verbessern.
Geplant ist:
- Rauschen entfernen
- Stille anhängen um das zerhacken des streams zu vermeiden
- Komressor Funktion um die stimme anheben zu können
- Weitere verbesserungen
Mein Scrit sieht derzeit so aus:
Code: Alles auswählen
from array import array
from io import BytesIO
import json
import os
from pyaudio import PyAudio, paInt16
import time
from pydub import *
from audioop import *
LANG = de-de
DEBUG = True
# Mic Settings
THRESHOLD = 5
RATE = 16000
TIMEOUT_LENGTH = 1
CHUNK = 4000
SHORT_NORMALIZE = (1.0 / 32768.0)
NORMALIZE = 1 / 32768
class AudioDetection:
def __init__(self):
p = PyAudio()
self.stream = p.open(rate=RATE,
channels=1,
format=paInt16,
input=True,
output=True,
input_device_index=None, # None use default
output_device_index=None, # None use default
frames_per_buffer=8000)
self.stream.start_stream()
self.stt = Vosk(LANG)
@staticmethod
def rms(frame):
shorts = array('h', frame)
sum_squares = sum(
(sample * NORMALIZE) ** 2
for sample in shorts
)
return (sum_squares / len(shorts)) ** 0.5 * 1000
def detect(self, frame):
if DEBUG:
print("Noise detected")
rec = [frame]
current = time.time()
end = time.time() + TIMEOUT_LENGTH
while current <= end:
data = self.stream.read(CHUNK)
if self.rms(data) >= THRESHOLD:
end = time.time() + TIMEOUT_LENGTH
current = time.time()
rec.append(data)
# rec = AudioSegment.silent(rec)
if DEBUG:
print("Play Stream")
self.stream.write(b''.join(rec))
text = self.stt.run(b''.join(rec))
if DEBUG:
print("Listened: ", text)
print('Listening...')
def run(self):
print("Listening...")
while True:
mic_input = self.stream.read(CHUNK)
rms_val = self.rms(mic_input)
if rms_val >= THRESHOLD:
self.detect(mic_input)
class Vosk:
def __init__(self, language):
from vosk import Model, KaldiRecognizer
if not os.path.exists("models/vosk/" + language):
print("Please download the model from https://alphacephei.com/vosk/models and unpack as "
"'" + language + "' in 'models/vosk'.")
exit(1)
model = Model("models/vosk/" + language)
self.rec = KaldiRecognizer(model, RATE)
def run(self, audiostream):
audiostream = BytesIO(audiostream)
while True:
data = audiostream.read(4000)
if len(data) == 0:
break
if self.rec.AcceptWaveform(data):
if DEBUG:
res = json.loads(self.rec.Result())
print("DEBUG: " + res['text'])
fres = json.loads(self.rec.FinalResult())
return fres['text']
if __name__ == '__main__':
recorder = AudioDetection()
recorder.run()
Mein Grundgedanke ist das ich ersmal die byteorder berücksichten sollte So das man mit Little Endian arbeitet doch wie gehts weiter?
Mir gehen langsam die Ideen aus und hoffe ihr könnt mir dabei weiterhelfen.
MfG
Toaster1337