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)
Using pydub, you can get loudness and highest amplitude of an mp3 file very easily. You can then use one of these parameters to make code/light react to that.
From the pydub website,
AudioSegment(…).max
The highest amplitude of any sample in the AudioSegment. Useful for things like normalization (which is provided in pydub.effects.normalize).
from pydub import AudioSegment
sound = AudioSegment.from_file("/path/to/sound.mp3", format="mp3")
peak_amplitude = sound.max
AudioSegment(…).dBFS
Returns the loudness of the AudioSegment in dBFS (db relative to the maximum possible loudness). A Square wave at maximum amplitude will be roughly 0 dBFS (maximum loudness), whereas a Sine Wave at maximum amplitude will be roughly -3 dBFS.
from pydub import AudioSegment
sound = AudioSegment.from_file("/path/to/sound.mp3", format="mp3")
loudness = sound.dBFS
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With