108 lines
2.5 KiB
Python
108 lines
2.5 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import wave
|
|
|
|
|
|
class WaveLoader:
|
|
def __init__(self, filename):
|
|
self.soundfile = wave.open(filename, 'rb')
|
|
|
|
self.channels = self.soundfile.getnchannels()
|
|
self.sampleWidth = self.soundfile.getsampwidth()
|
|
self.frameCount = self.soundfile.getnframes()
|
|
self.frameRate = self.soundfile.getframerate()
|
|
self.filename = filename
|
|
self.amplitudeMax = 2 ** (self.sampleWidth * 8)
|
|
self.levelData = {}
|
|
self.amplitudeData = {}
|
|
|
|
def __del__(self):
|
|
self.soundfile.close()
|
|
|
|
def getCurrentLevelRealtime(self, seconds):
|
|
frameIndex = int(round(seconds * self.frameRate))
|
|
|
|
if frameIndex >= self.frameCount:
|
|
return 0
|
|
|
|
self.soundfile.setpos(frameIndex)
|
|
|
|
level = int.from_bytes(self.soundfile.readframes(1)[0:self.sampleWidth], 'little')
|
|
|
|
if level > self.amplitudeMax * 0.5:
|
|
level -= self.amplitudeMax
|
|
|
|
return abs(level) / (self.amplitudeMax * 0.5)
|
|
|
|
def getLevel(self, channel = 0):
|
|
if channel < self.channels:
|
|
return self.levelData[channel].copy()
|
|
|
|
def getAmplitude(self, channel = 0):
|
|
if channel < self.channels:
|
|
return self.amplitudeData[channel].copy()
|
|
|
|
def getLevelSum(self):
|
|
if self.channels == 1:
|
|
return self.levelData[0].copy()
|
|
|
|
levelSum = []
|
|
|
|
for f in range(self.frameCount):
|
|
amplitudeSum = 0
|
|
|
|
for c in range(self.channels):
|
|
amplitudeSum += self.levelData[c][f]
|
|
|
|
levelSum.append(amplitudeSum / self.channels)
|
|
|
|
return levelSum
|
|
|
|
def getCurrentLevel(self, seconds):
|
|
frameIndex = int(round(seconds * self.frameRate))
|
|
|
|
if frameIndex >= self.frameCount:
|
|
return 0
|
|
|
|
level = self.levelData[0][frameIndex]
|
|
return level
|
|
|
|
level = 0
|
|
|
|
for c in range(self.channels):
|
|
level += self.levelData[c][frameIndex]
|
|
|
|
return level / self.channels
|
|
|
|
def loadData(self):
|
|
self.levelReset()
|
|
self.amplitudeReset()
|
|
soundfile = wave.open(self.filename, 'rb')
|
|
|
|
for f in range(self.frameCount):
|
|
frame = soundfile.readframes(1)
|
|
|
|
for c in range(self.channels):
|
|
byteOffset = c * self.sampleWidth
|
|
amplitude = int.from_bytes(frame[byteOffset:byteOffset + self.sampleWidth], 'little')
|
|
|
|
if amplitude > self.amplitudeMax * 0.5:
|
|
amplitude -= self.amplitudeMax
|
|
|
|
self.amplitudeData[c].append(amplitude / (self.amplitudeMax * 0.5))
|
|
self.levelData[c].append(abs(amplitude) / (self.amplitudeMax * 0.5))
|
|
|
|
soundfile.close()
|
|
|
|
def levelReset(self):
|
|
self.levelData = {}
|
|
|
|
for c in range(self.channels):
|
|
self.levelData[c] = []
|
|
|
|
def amplitudeReset(self):
|
|
self.amplitudeData = {}
|
|
|
|
for c in range(self.channels):
|
|
self.amplitudeData[c] = []
|