[Python-de] AIFF-Dateien interpretieren

Dinu Gherman gherman at darwin.in-berlin.de
Don Apr 22 17:29:48 CEST 2004


Hallo,

ich weiss nicht, ob sich hier jemand damit auskennt, aber wir werden
ja sehen. Ich lese mit dem Modul "aifc" der Standardbibliothek AIFF-,
d.h. Audiodateien (nicht komprimiert).

Ein Ziel dabei ist die weitere Verarbeitung der Audiodaten, d.h. ich
moechte z.B. irgendwo eine Art Klangkurve darstellen koennen, wie man
es in einigen Soundeditor-Programmen sehen kann - kein Equalizer-Ding,
sondern einfach nur etwas Lautstaerke-aehnliches.

Nun habe ich mit aifc Zugriff auf das, was ich brauche, glaube ich,
aber es kommen partout keine "sinnvollen" Tondaten dabei heraus, d.h.
mit Blick auf solch eine Kurve. Dabei habe ich schon einiges an Byte-
Verdrehungen ausprobiert... Aber vielleicht mache ich da auch einen
systematischen Fehler, was die Interpretation der Sample-Punkte an-
geht...?

Unten ein bischen Code, der erklaert, was ich tue... Dabei habe ich
es immer mit numChannels, sampleWidth = 2, 2 zu tun...

Hat jemand eine Idee, wo mein Denkfehler sein koennte?

Gruss,

Dinu


import aifc


def readAudio(path=None):
     f = aifc.open(path or "xxx.aiff", "rb")
     params = f.getparams()
     numChannels, sampleWidth, frameRate, numFrames, compType, compName 
= params
     print params
     secs = float(numFrames) / frameRate
     mins, secs60 = divmod(secs, 60)
     print "length: %4.2f sec" % secs
     print "length: %d:%02d min" % (int(mins), int(secs60))
     bytes = f.readframes(numFrames)
     print "length: %d bytes" % len(bytes)
     print "length: %d frames" % numFrames
     frameLength = numChannels * sampleWidth
     print "bytes/frame: %d" % frameLength
     print "bytes/sec: %d" % (frameRate * frameLength)
     return bytes, frameLength


def addAudioView(data, frameLength, canvas, x0, y0, width, height):
     "Add vertical bar for each sample point."
     canvas.setLineWidth(0.0)
     lines = []
     j = -1
     for i in xrange(0, len(data), frameLength):
         j += 1
         if j % 2**12 != 0: continue
         # if j > 10000: break
         sample = data[i:i+frameLength]
         ll1, ll0, rr1, rr0 = map(ord, sample)
         left = ll0*256 + ll1
         right = rr0*256 + rr1
         x = x0 + (float(i)/len(data) * width)
         x1, y1 = x, y0
         x2, y2 = x, y0 + left*height/2**16
         canvas.line(x1, y1, x2, y2)


...
data, frameLength = readAudio()
addAudioView(data, frameLength, canvas, x0, y0, width, height)
...