I was hoping I could find a way to get the amplitude data from an mp3 in python. Similar to audacity but I do not want a visual, a simple array of values will do. I want my code to react to sound at certain points when it gets louder. I am using pygame to play the audio and was trying to convert it to a sndarray but it was only giving me the first 0.00018 seconds. Anyway I can get the whole mp3? It does not have to be real time as I would like to be able to react ahead of time anyway and will keep track of my position using pygame.
I am building this cloud using a raspberry pi instead for other features. I already have the lighting work and need it to react to the lightning, lightshowpi is not an option sadly. Any help would be greatly appreciated
Edit: So this is what I have so far thanks to coder-don. It works, but i hangs on the while loop. I do not know why. The mp3 I am using is rather long, could that be the issue?
import os, sys
from gi.repository import Gst, GObject
Gst.init()
GObject.threads_init()
def get_peaks(filename):
global do_run
pipeline_txt = (
'filesrc location="%s" ! decodebin ! audioconvert ! '
'audio/x-raw,channels=1,rate=22050,endianness=1234,'
'width=32,depth=32,signed=(bool)TRUE !'
'level name=level interval=1000000000 !'
'fakesink' % filename)
pipeline = Gst.parse_launch(pipeline_txt)
level = pipeline.get_by_name('level')
bus = pipeline.get_bus()
bus.add_signal_watch()
peaks = []
do_run = True
def show_peak(bus, message):
global do_run
if message.type == Gst.MESSAGE_EOS:
pipeline.set_state(Gst.State.NULL)
do_run = False
return
# filter only on level messages
if message.src is not level or \
not message.structure.has_key('peak'):
return
peaks.append(message.structure['peak'][0])
# connect the callback
bus.connect('message', show_peak)
# run the pipeline until we got eos
pipeline.set_state(Gst.State.PLAYING)
ctx = GObject.MainContext()
while ctx and do_run:
ctx.iteration()
return peaks
def normalize(peaks):
_min = min(peaks)
print(_min)
_max = max(peaks)
print(_max)
d = _max - _min
return [(x - _min) / d for x in peaks]
if __name__ == '__main__':
filename = os.path.realpath(sys.argv[1])
peaks = get_peaks(filename)
print('Sample is %d seconds' % len(peaks))
print('Minimum is', min(peaks))
print('Maximum is', max(peaks))
peaks = normalize(peaks)
print(peaks)