Python - Get waveform/amplitude of mp3
Question: 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](http://www.makeuseof.com/tag/build-cloud-lamp-
sound-reactive-lightning/) 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)
    


Answer: Using [pydub](https://github.com/jiaaro/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](https://github.com/jiaaro/pydub/blob/master/API.markdown)
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
    

