Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting amplitude value of mp3 file played in Python on Raspberry Pi

Tags:

python

audio

I am playing an mp3 file with Python on a Raspberry Pi:

output_file = "sound.mp3"
pygame.mixer.init()
pygame.mixer.music.load(output_file)
pygame.mixer.music.play()
while pygame.mixer.music.get_busy():
    pass
sleep(0.2)

Now while the mp3 file is playing, I would like to get the current amplitude of the sound played. Is there a way to do this? The only examples I was able to find work on a microphone input but not with a file being played.

like image 456
Reto Avatar asked Oct 16 '25 19:10

Reto


1 Answers

There's a VU meter code on github working with microphone. You can easily change its input stream to wave file. If you want to work with .mp3 files, check this SO link for converting .mp3 to .wav on air without storing data on storage.

import wave

def main():
    audio = pyaudio.PyAudio()
    try:
        # from wav file
        chunk = 1024
        wf = wave.open("kimi_no_shiranai.wav", 'rb')
        stream = audio.open(format =
                audio.get_format_from_width(wf.getsampwidth()),
                channels = wf.getnchannels(),
                rate = wf.getframerate(),
                output = True)
        
        data = wf.readframes(chunk)
        maximal = Amplitude()
        while data:
            # writing to the stream is what *actually* plays the sound.
            stream.write(data)
            data = wf.readframes(chunk)
            
            amp = Amplitude.from_data(data)
            if amp > maximal:
                maximal = amp
            amp.display(scale=100, mark=maximal)
        
        # from microphone
        # stream = audio.open(format=pyaudio.paInt16,
        #                     channels=2,
        #                     rate=RATE,
        #                     input=True,
        #                     frames_per_buffer=INPUT_FRAMES_PER_BLOCK
        #                    )

        # maximal = Amplitude()
        # while True:
        #     data = stream.read(INPUT_FRAMES_PER_BLOCK)
        #     amp = Amplitude.from_data(data)
        #     if amp > maximal:
        #         maximal = amp
        #     amp.display(scale=100, mark=maximal)
    finally:
        stream.stop_stream()
        stream.close()
        audio.terminate()

Edit:

for converting .mp3 to .wav use this code. It doesn't have syncing problem. It stores converted wave into BytesIO buffer.

from pydub import AudioSegment

sound = AudioSegment.from_mp3("kimi_no_shiranai.mp3")
wav_form = sound.export(format="wav")
wf = wave.open(wav_form, 'rb')

stream = audio.open(format =
            audio.get_format_from_width(sound.sample_width),
            channels = sound.channels,
            rate = sound.frame_rate,
            output = True)

SO link 1 SO link 2

like image 104
Ali Ent Avatar answered Oct 18 '25 09:10

Ali Ent