Binärdaten effektiv verarbeiten ?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
snakeseven
User
Beiträge: 408
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

Hallo,
ich will binäre Audiodaten mischen und verwende zum Einlesen 'rb' und zum Verarbeiten struct.unpack() und struct.pack(). Das stellt sich aber als sehr langsam heraus. Gibt es eine Möglichkeit, mehr Effizienz in meine Misch-Routine zu bekommen ? Hier die betreffende For-Schleife:

Code: Alles auswählen

result = wave1[:44]                         #WAV-Header
for i in range(44,length):                  #length= Länge des Audio-Datenblocks
    value = struct.unpack('b',wave1[i])[0] + struct.unpack('b',wave2[i])[0]  #wave1,2 = WAV-Dateien
    result = result + struct.pack('b ',value/2)
Schön wäre es, die WAV-Dateien [44:] in einem Rutsch 'unpacken' zu können, also nicht in einer For-Schleife. Habe aber nichts dazu gefunden !? Picklen klappe auch nicht.

Fröhliches Eiersuchen !
Seven
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Hi

Code: Alles auswählen

value = struct.unpack('44b',wave1[44:])
Gibt einen Array von 44 Byte Elementen. Aber für solche Sachen würde ich mal numpy (http://numeric.scipy.org/) anschauen. Das hat eine Funktion from_string und ist recht schnell bei berechnungen.

Gruss
snakeseven
User
Beiträge: 408
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

rayo hat geschrieben:

Code: Alles auswählen

value = struct.unpack('44b',wave1[44:])
Hi,
das klappt schonmal gut und hat die Verarbeitungsgeschwindigkeit verdoppelt. Jetzt ist mir noch der Rückweg versperrt. Wie kann ich die veränderten Werte wieder in eine Binärdatei packen ? Wenn ich die zu packenden Daten direkt übergebe klappts:

Code: Alles auswählen

a = struct.pack('10b',-45,-1,-49,-1,0,0,65,0,112,0)
=> ÓÿÏÿ
Wenn ich die Daten in einer Variable als String übergebe, klappts natürlich nicht:

Code: Alles auswählen

arg = '-45,-1,-49,-1,0,0,65,0,112,0'
a = struct.pack('10b',arg)
=> struct.error: required argument is not an integer
Gibt es eine Form der Parameterübergabe, wo die Zahlen als Integer und nicht als Strings interpretiert werden ? Dann könnte ich die veränderten Audiodaten auf einen Schlag zurück konvertieren, was ebenfalls effektiver wäre, als die For-Schleife mit 111000 struct.pack() Anweisungen.

Gruss, Seven
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Hi

Klas das kannst du so machen:

Code: Alles auswählen

a = struct.pack('10b',*arg)
Beachte das *, das bewirkt dass eine Liste als einzelne Parameter übergeben werden.

Gruss
BlackJack

Reichen für den Anfang vielleicht auch erstmal die Module `wave` und `audioop` aus der Standardbibliothek? Ansonsten würde ich auch Numpy empfehlen oder Pyrex um den "Low-Level" Teil zu beschleunigen.
snakeseven
User
Beiträge: 408
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

rayo hat geschrieben:Beachte das *, das bewirkt dass eine Liste als einzelne Parameter übergeben werden.
Hi, genau das wars.

Code: Alles auswählen

>>> v = [-45,-1,-49,-1,0,0,65,0,112,0]
>>> e = struct.pack('10b',*v)
>>> print e
ÓÿÏÿ
Werde aber Numpy auf jeden Fall ausprobieren, muss mich nur erstmal durch die Dokumentation arbeiten.

@BlackJack: 'audioop' ist sehr schnell, hat aber den Nachteil, daß man nur gleichlange Dateien miteinander mischen kann, das finde ich unvorteilhaft. 'wave' bietet alles zum Lesen, Schreiben und Analysieren von WAV-Dateien. Funktionen zur Datenmanipulation bietet es leider nicht.
'Pyrex' scheint mir auch ein sehr interessanter Kandidat zur Optimierung !

Gruss, Seven
snakeseven
User
Beiträge: 408
Registriert: Freitag 7. Oktober 2005, 14:37
Wohnort: Berlin
Kontaktdaten:

So, habe das Ergebnis der Arbeit in den Codesnippes gepostet:
http://www.python-forum.de/post-35085.html#35085
Seven
Antworten