Ich akzeptiere gerne Vorschläge in R oder Matlab, aber der Code, den ich unten präsentiere, ist R-only.
Die unten angehängte Audiodatei ist eine kurze Unterhaltung zwischen zwei Personen. Mein Ziel ist es, ihre Sprache so zu verzerren, dass der emotionale Inhalt nicht mehr erkennbar ist. Die Schwierigkeit besteht darin, dass ich für diese Verzerrung einen parametrischen Bereich benötige, sagen wir mal von 1 bis 5, wobei 1 "stark erkennbare Emotion" und 5 "nicht erkennbare Emotion" ist. Es gibt drei Möglichkeiten, wie ich das mit R erreichen könnte.
Download ‚glücklich‘ Audio-Welle , die von hier .
Laden Sie 'angry' Audio Wave von hier herunter .
Der erste Ansatz bestand darin, die Gesamtverständlichkeit durch Einführung von Rauschen zu verringern. Diese Lösung wird im Folgenden vorgestellt (danke an @ carl-witthoft für seine Vorschläge). Dies verringert sowohl die Verständlichkeit als auch den emotionalen Inhalt der Sprache, aber es ist sehr "schmutzig" - es ist schwierig, den parametrischen Raum richtig zu bestimmen, da der einzige Aspekt, den Sie steuern können, eine Amplitude (Lautstärke) des Rauschens ist.
require(seewave)
require(tuneR)
require(signal)
h <- readWave("happy.wav")
h <- cutw(h.norm,f=44100,from=0,to=2)#cut down to 2 sec
n <- noisew(d=2,f=44100)#create 2-second white noise
h.n <- h + n #combine audio wave with noise
oscillo(h.n,f=44100)#visualize wave with noise(black)
par(new=T)
oscillo(h,f=44100,colwave=2)#visualize original wave(red)
Der zweite Ansatz wäre, das Rauschen irgendwie anzupassen, um die Sprache nur in den spezifischen Frequenzbändern zu verzerren. Ich dachte, ich könnte dies tun, indem ich die Amplitudenhüllkurve aus der ursprünglichen Audiowelle extrahiere, Rauschen aus dieser Hüllkurve generiere und das Rauschen dann erneut auf die Audiowelle anwende. Der folgende Code zeigt, wie das geht. Es macht etwas anderes als das Geräusch selbst, bringt den Klang zum Knacken, aber es geht auf den gleichen Punkt zurück - dass ich hier nur die Amplitude des Geräusches ändern kann.
n.env <- setenv(n, h,f=44100)#set envelope of noise 'n'
h.n.env <- h + n.env #combine audio wave with 'envelope noise'
par(mfrow=c(1,2))
spectro(h,f=44100,flim=c(0,10),scale=F)#spectrogram of normal wave (left)
spectro(h.n.env,f=44100,flim=c(0,10),scale=F,flab="")#spectrogram of wave with 'envelope noise' (right)
Der endgültige Ansatz könnte der Schlüssel zur Lösung sein, ist aber recht knifflig. Ich fand diese Methode in einem Bericht, der in Science von Shannon et al. (1996) . Sie verwendeten ein ziemlich trickreiches Muster der Spektralreduktion, um etwas zu erreichen, das sich wahrscheinlich ziemlich roboterhaft anhört. Gleichzeitig gehe ich aus der Beschreibung davon aus, dass sie möglicherweise die Lösung gefunden haben, die mein Problem beantworten könnte. Die wichtigen Informationen finden Sie im zweiten Absatz im Text und in Anmerkung Nr. 7 unter Referenzen und Anmerkungen- Dort wird die gesamte Methode beschrieben. Meine Versuche, es zu replizieren, waren bisher erfolglos. Nachstehend ist der Code aufgeführt, den ich zusammen mit meiner Interpretation der Vorgehensweise gefunden habe. Ich denke, dass fast alle Puzzles da sind, aber ich kann noch nicht das ganze Bild bekommen.
###signal was passed through preemphasis filter to whiten the spectrum
#low-pass below 1200Hz, -6 dB per octave
h.f <- ffilter(h,to=1200)#low-pass filter up to 1200 Hz (but -6dB?)
###then signal was split into frequency bands (third-order elliptical IIR filters)
#adjacent filters overlapped at the point at which the output from each filter
#was 15dB down from the level in the pass-band
#I have just a bunch of options I've found in 'signal'
ellip()#generate an Elliptic or Cauer filter
decimate()#downsample a signal by a factor, using an FIR or IIR filter
FilterOfOrder()#IIR filter specifications, including order, frequency cutoff, type...
cutspec()#This function can be used to cut a specific part of a frequency spectrum
###amplitude envelope was extracted from each band by half-wave rectification
#and low-pass filtering
###low-pass filters (elliptical IIR filters) with cut-off frequencies of:
#16, 50, 160 and 500 Hz (-6 dB per octave) were used to extract the envelope
###envelope signal was then used to modulate white noise, which was then
#spectrally limited by the same bandpass filter used for the original signal
Wie soll das Ergebnis also klingen? Es sollte etwas zwischen Heiserkeit, einem lauten Knacken, aber nicht so viel Roboter sein. Es wäre gut, wenn der Dialog einigermaßen verständlich bleiben würde. Ich weiß - es ist alles ein bisschen subjektiv, aber mach dir keine Sorgen - wilde Vorschläge und lose Interpretationen sind sehr willkommen.
Verweise:
- Shannon, RV, Zeng, FG, Kamath, V., Wygonski, J. & Ekelid, M. (1995). Spracherkennung mit vorwiegend zeitlichen Hinweisen. Science , 270 (5234), 303. Herunterladen von http://www.cogsci.msu.edu/DSS/2007-2008/Shannon/temporal_cues.pdf
noisy <- audio + k*white_noise
für eine Vielzahl von Werten von k das, was man will? Natürlich ist "verständlich" höchst subjektiv. Oh, und Sie möchten wahrscheinlich ein paar Dutzend verschiedene white_noise
Samples, um zufällige Effekte aufgrund einer falschen Korrelation zwischen audio
einer einzelnen Zufallswertdatei zu vermeiden noise
.