Python RPI: как мне динамически регулировать громкость воспроизводимого в данный момент файла wav

#python #raspberry-pi3 #sensors #pyaudio

#python #raspberry-pi3 #датчики #pyaudio

Вопрос:

В настоящее время используются Raspberry Pi 3, pyaudio, ReSpeaker 2-Mics Pi HAT

Как мне отрегулировать громкость.воспроизведение файла wav с использованием python в RPI? (вывод осуществляется через 3,5-мм аудиоразъем respeaker, подключенный к наушнику)

Мне нужен RPI для динамического воспроизведения и регулировки громкости без необходимости изменять его вручную

Не удается получить доступ к alsamixer с помощью команды в командной строке. Нужен совет о том, как действовать дальше.

Ниже приведен текущий прогресс моего кода (этот код будет воспроизводиться в цикле while) :

             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()
  

Пробовал этот код, но не совсем то, чего я пытаюсь достичь

Попытка изменить его во время воспроизведения, а не изменять его раньше

 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
  

Ответ №1:

В цикле воспроизведения вычислите объем фрагмента (например, используя среднеквадратичное значение), а затем, если оно слишком велико, разделите.

Для 8-битного звука (128 — нейтральное положение динамика)

 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)