[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)
...