5

Currently using Raspberry Pi 3, pyaudio , ReSpeaker 2-Mics Pi HAT

How do I adjust the volume of the .wav file playing using python in RPI? ( the output is through respeaker 3.5mm audio jack connected by an earpiece)

I need the RPI to play and adjust the volume dynamically without needing me to change it manually

Not accessing the alsamixer using the command in command prompt. Need some advice on how to proceed.

Below is the current progress of my code ( this code will be in a while loop playing ) :

            filename ="output.wav"
            
            RESPEAKER_RATE = 16000
            RESPEAKER_CHANNELS = 2
            RESPEAKER_WIDTH = 2
            RESPEAKER_INDEX = 0  
            chunk = 1024
            wf = wave.open(filename, 'rb')
            p = pyaudio.PyAudio()
            stream = p.open(
                    format = p.get_format_from_width(RESPEAKER_WIDTH),
                    channels = RESPEAKER_CHANNELS,
                    rate = RESPEAKER_RATE,
                    output = True
                )
            
           
            
            data = wf.readframes(chunk)
            while data != '':
                stream.write(data)
                data = wf.readframes(chunk)
            
            stream.stop_stream()
            stream.close()
            p.terminate()

Tried this code but not really what I am trying to achieve

Trying to change it whilst it is playing rather than changing it before

from pydub import AudioSegment

song = AudioSegment.from_wav("output.wav")
song = song - 60
quieter_song_data = song.get_array_of_samples()
quieter_song_fs = song.frame_rate4
JustASimpleGuy
  • 171
  • 1
  • 1
  • 11

1 Answers1

0

In your play loop, compute the volume of the chunk (using root-mean-square, e.g.) and then if it is too high, divide.

For 8-bit audio (128 is neutral speaker position)

data = wf.readframes(chunk)
while data != '':
    data2 = (data-128)/128) # now from -1 to 1
    volume = sum(data2 ** 2) ** .5
    if volume > .6:
        data = data2/volume * .6
        data = data*128 + 128
        data = [max(min(int(d),255),0) for d in data]
        # convert data back to type stream is happy with here if needed
    stream.write(data)
    data = wf.readframes(chunk)
mCoding
  • 4,059
  • 1
  • 5
  • 11