Funktionen, Arrays, Audio In/Out

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Antworten
vounesa
User
Beiträge: 6
Registriert: Freitag 22. Juni 2018, 10:44

Hallo!
und zwar muss ich dieses Skript für die Uni erstellen: http://www.directupload.net/file/d/5126 ... 8y_jpg.htm
Mein Problem ist das ich nichtsmit Programmieren zu tun habe, und dies eine Übung ist die nur ein Semester dauert wo diese Abgabe über das Bestehen entscheidet.
Ich tue mir sehr schwer damit und brauche wirklich dringend Hilfe.
Was den ersten Schritt, das einlesen betrifft, ist das kein Problem. Das habe ich so gemacht:

Code: Alles auswählen

from scipy.io import wavfile

fs, data = wavfile.read('Spicy_Funk_Cake_snippet.wav')

data = data / data.max()

wavfile.write('output.wav', fs, data)
Die Funktion die wir benutzen sollen ist diese:

Code: Alles auswählen

import numpy as np

def splitIntoBlocks (data, blockSize, overlap):
    hopSize = blockSize - overlap
    n = data.size
    nBlocks = int(np.ceil((n - blockSize) / hopSize + 1))
    B = np.zeros((nBlocks, blockSize));
    
    for i in range(nBlocks - 1):
        B[i,:] = data[i*hopSize : i*hopSize + blockSize]
    
    #letzter block
    i = nBlocks - 1;
    nLast = data[i*hopSize :].size
    B[nBlocks - 1, range(nLast)] = data[i*hopSize :]
        
    return B
aber ich weiß nicht recht wie verwenden bzw wie weiter arbeiten..

Ich bin über jeden Tipp und Ansatz dankbar!

vounesa
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Text in Bildern auf externen Seiten ist doof zu lesen, darum hier noch mal als *Text*:
Erstellen Sie ein Skript lautend auf applyBRIRs.py welches:
  • die Stereo-Audiodatei ‘Spicy_Funk_Cake_snippet.wav‘ einliest,
  • die beiden Kanäle separat in Blöcke zerlegt
    • unter Verwendung der in der Einheit 11 erstellten Funktion
    • Blocksize 4096 samples
    • Overlap 2048 samples (50%)
    • Jeder Block mit einem Hann-Fenster der Länge 4096 gefenstert
  • die BRIR (binaural room impulse response) ‘h_kk_FL.wav‘ und ‘h_kk_FR.wav‘ einliest
    • diese Stereo-Dateien beinhalten das linke und rechte Ohrsignal für die jeweiligen Lautsprecher (Front-Left und Front-Right)
  • die einzelnen Blöcke entsprechend des Flussdiagramms (siehe unten) mit den Impulsantworten faltet und mittels Overlap-And-Add zusammenfügt
    • Beachten Sie, dass die FFT-Länge blocksize+IRLänge-l sein muss
    • Overlap-Add kann dank des vorherigen Hann-Fensters relativ einfach durchgeführt werden, da sich die einzelnen Blöcke perfekt ergänzen
  • die fertigen Daten als ‘output.wav‘ exportiert
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Irgendwie funktioniert Dein splitIntoBlocks bei mir nicht; kürzer und in der korrekten Schreibweise ließe sich das so schreiben:

Code: Alles auswählen

def split_into_blocks(data, blocksize, overlap):
    hopsize = blocksize - overlap
    nblocks = (len(data) + hopsize - overlap - 1) // hopsize
    result = np.zeros((nblocks, blocksize))
    for i in range(nblocks):
        row = data[i*hopsize : i*hopsize+blocksize]
        result[i, :len(row)] = row
    return result
Dein Thema ist sehr speziell (Signalverarbeitung). Die prinzipielle Vorgehensweise sollte in Deinen Vorlesungsunterlagen erklärt sein, oder Du gehst zu Deinem Betreuer. Die Ausrede "ich brauch das später sowieso nicht mehr" kann hier übrigens niemand leiden.
vounesa
User
Beiträge: 6
Registriert: Freitag 22. Juni 2018, 10:44

Hallo,
bis jetzt habe ich diesen Code geschrieben:

Code: Alles auswählen

from scipy.io import wavfile

fs, data = wavfile.read('Spicy_Funk_Cake_snippet.wav')

data = data / data.max()

wavfile.write('output.wav', fs, data)

channel1=fs, data[:,0] #left
channel2=fs, data[:,1] #right

import numpy as np

def splitIntoBlocks (data, blockSize, overlap):
       
    leftBlock = splitIntoBlocks (channel1 , 4096 , 2048)
    rightBlock = splitIntoBlocks (channel2, 4096, 2048)
blockSize = 4096
overlap = 2048
hopSize = blockSize - overlap

from scipy.fftpack import fft, fftshift
from scipy.signal import hanning

leftHann = data.hanning(4096)
rightHann = channel2.hanning(4096)
sieht dies denn bis jetzt halbwegs richtig aus? Nun habe ich hier das Problem mit den Hann- Fenster, so wie ich es hier machen funktioniert es nicht, hätte wer eine Idee weshalb?

LG
vounesa
Benutzeravatar
ThomasL
User
Beiträge: 1366
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

sieht alles ziemlich durcheinander aus, überall imports die üblicherweise an den Anfang gehören
was ist eigentlich der Body der function SplitIntoBlocks?
die beiden rekursiven Aufrufe für leftBlock und rightBlock doch wohl nicht
bzgl. hanning mal hier schauen https://docs.scipy.org/doc/scipy-1.0.0/ ... nning.html
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Das sieht nach raten aus. `splitIntoBlocks()` wird definiert, aber nicht aufgerufen, wobei die Definition so auch überhaupt keinen Sinn macht.

Statt zu kommentieren das `channel1` und `channel2` links und rechts sind, könnte man statt der nichtssagenden Nummern bei `channel*` auch `left_channel` und `right_channel` als Namen verwenden.

`leftBlock` und `rightBlock` sind etwas irreführend für das Ergebnis einer `splitIntoBlocks()`-Funktion, denn das sind ja wohl mehrere Blöcke und nicht bloss einer.

`numpy` wird als `np` importiert, dann aber gar nicht verwendet. Normalerweise kommen Importe alle an den Anfang eines Moduls, damit man leicht sehen/finden kann, wovon ein Modul abhängt.

`blockSize`, `overlap`, und `hopSize` werden definiert, aber nirgends verwendet. Dafür stehen die Grössen mehrfach als ”magische” Zahlen im Quelltext. Namen für Konstanten werden per Konvention KOMPLETT_GROSS_GESCHRIEBEN. Namen von Funktionen und Werten klein_mit_unterstrichen. Klassen in MixedCase.

`fft` und `fftshift` werden importiert, aber nicht verwendet.

Grundsätzlich wäre es auch immer nett wenn Du schreiben würdest was nicht funktioniert und falls es eine Ausnahme gibt, diese komplett mit Traceback zeigen würdest. Denn ich bin mir ziemlich sicher das `data.hanning` zu einem `AttributeError` führt.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
vounesa
User
Beiträge: 6
Registriert: Freitag 22. Juni 2018, 10:44

Hallo,
ich habe nun den Code strukturierter geschrieben und noch bearbeitet

Code: Alles auswählen

from scipy.fftpack import fft, fftshift
from scipy.signal import hanning
from scipy.io import wavfile
import numpy as np

fs, data = wavfile.read('Spicy_Funk_Cake_snippet.wav')
BRIRL = wavfile.read('h_kk_FL.wav')
BRIRR = wavfile.read('h_kk_FR.wav')

data = data / data.max()

wavfile.write('output.wav', fs, data)


left_channel=fs, data[:,0] 
right_channel=fs, data[:,1] 




def splitIntoBlocks (data, blockSize, overlap):
    hopSize = blockSize - overlap
    n = data.size
    nBlocks = int(np.ceil((n - blockSize) / hopSize + 1))
    B = np.zeros((nBlocks, blockSize));
    
    for i in range(nBlocks - 1):
        B[i,:] = data[i*hopSize : i*hopSize + blockSize]
        hann_window = np.hanning(blockSize)* 1/blockSize
        B[i,:]=B[i,:]*hann_window
    
    #letzter block
    i = nBlocks - 1;
    nLast = data[i*hopSize :].size
    B[nBlocks - 1, range(nLast)] = data[i*hopSize :]
        
    return B



jedoch diese Fehlermeldung..

Code: Alles auswählen

line 29, in splitIntoBlocks
    n = data.size

AttributeError: 'tuple' object has no attribute 'size'
Hat wer einen Tipp für mich wo da der Fehler liegt?

LG
vounesa
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@vounesa: Beim Aufruf der Funktion `splitIntoBlocks()`, der aber nicht in dem gezeigten Code zu sehen ist.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
vounesa
User
Beiträge: 6
Registriert: Freitag 22. Juni 2018, 10:44

Verzeihung, den Aufruf habe ich ausversehen abgeschnitten.

Das wäre dieser hier:

Code: Alles auswählen

eftBlocks = splitIntoBlocks (left_channel, 4096 , 2048)
Benutzeravatar
ThomasL
User
Beiträge: 1366
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Code: Alles auswählen

left_channel=fs, data[:,0]
was ist denn left_channel nach dieser Zuweisung?
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
vounesa
User
Beiträge: 6
Registriert: Freitag 22. Juni 2018, 10:44

Habe den Fehler schon gefunden! das fs davor musste weg, sehr dummer Fehler..

So, nun habe ich bis jetzt die Audiodateien und BRIRs eingelesen und in Blöcke unterteilt. Nun muss ich eine FFT- Transformation durchführen der Audioblöcke und BRIRs und da ist nun mein Problem, ich weiß nicht wie vorgehen..
Mein Code bis jetzt:

Code: Alles auswählen

from scipy.fftpack import fft, fftshift
from scipy.signal import hanning
from scipy.io import wavfile
import numpy as np

fs, data = wavfile.read('Spicy_Funk_Cake_snippet.wav')
BRIRL = wavfile.read('h_kk_FL.wav')
BRIRR = wavfile.read('h_kk_FR.wav')

data = data / data.max()

wavfile.write('output.wav', fs, data)


left_channel= data[:,0] 
right_channel= data[:,1] 

IRLängeL = BRIRL.shape[0]
IRLängeR = BRIRR.shape[0]



def splitIntoBlocks (data, blockSize, overlap):
    hopSize = blockSize - overlap
    n = data.size
    nBlocks = int(np.ceil((n - blockSize) / hopSize + 1))
    B = np.zeros((nBlocks, blockSize));
    
    for i in range(nBlocks - 1):
        B[i,:] = data[i*hopSize : i*hopSize + blockSize]
        hann_window = np.hanning(blockSize)* 1/blockSize
        B[i,:]=B[i,:]*hann_window
    
    #letzter block
    i = nBlocks - 1;
    nLast = data[i*hopSize :].size
    B[nBlocks - 1, range(nLast)] = data[i*hopSize :]
        
    return B


leftBlocks = splitIntoBlocks (left_channel, 4096 , 2048)
rightBlocks = splitIntoBlocks (right_channel, 4096, 2048)


LG
vounesa
Antworten