Как получить громкость звукового объекта

Я пытаюсь создать программу, которая принимает входной сигнал пользователя с микрофона, а затем измеряет его громкость. Код представляет собой комбинацию This script и Pyloudnorm;

import pygame as pg
import time
import soundfile as sf
import pyloudnorm as pyln

from pygame._sdl2 import (
    get_audio_device_names,
    AudioDevice,
    AUDIO_F32,
    AUDIO_ALLOW_FORMAT_CHANGE,
)
from pygame._sdl2.mixer import set_post_mix


pg.mixer.pre_init(44100, 32, 2, 512)
pg.init()

# init_subsystem(INIT_AUDIO)
names = get_audio_device_names(True)
print(names)

sounds = []
sound_chunks = []


def callback(audiodevice, audiomemoryview):
    # print(type(audiomemoryview), len(audiomemoryview))
    # print(audiodevice)
    sound_chunks.append(bytes(audiomemoryview))


def postmix_callback(postmix, audiomemoryview):
    print(type(audiomemoryview), len(audiomemoryview))
    print(postmix)


set_post_mix(postmix_callback)

audio = AudioDevice(
    devicename=names[0],
    iscapture=True,
    frequency=44100,
    audioformat=AUDIO_F32,
    numchannels=2,
    chunksize=512,
    allowed_changes=AUDIO_ALLOW_FORMAT_CHANGE,
    callback=callback,
)
# start recording.
audio.pause(0)

time.sleep(2.5)


sound = pg.mixer.Sound(buffer=b"".join(sound_chunks))

data, rate = sound
meter = pyln.Meter(rate) #
loudness = meter.integrated_loudness(data)
print(loudness)

Однако это приводит к ошибке «невозможно распаковать неповторяемый звуковой объект», поскольку исходная версия была разработана для прямого анализа аудиофайлов. Попытка проанализировать необработанные фрагменты или данные байтовой строки с помощью sound.get_raw() также приводит к ошибкам.

Есть ли способ применить этот анализ к сгенерированному звуковому объекту или, если нет, способ преобразовать звуковой объект в аудиофайл? Насколько мне известно, Pygame не позволяет сохранять аудиофайлы. Я бы также предпочел не использовать Pyaudio, так как у меня с ним возникли проблемы.

Как вы определяете «громкость»? Необработанные данные здесь будут представлять собой массив 32-битных значений с плавающей запятой. Вы можете использовать array или struct для преобразования байтовой строки в массив чисел с плавающей запятой. Диапазон от -1,0 до 1,0, поэтому вы можете выяснить, насколько близко вы к 1,0.

Tim Roberts 09.06.2024 00:11
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
1
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

хороший вопрос.

  1. Частота дискретизации была определена во время инициализации pygaming и еще раз во второй раз во время инициализации класса mic AudioDevice (см. атрибут frequency).
  2. входные данные для pyln.Meter должны быть массивом, а не звуковым объектом байтов.

Подводя итог, вам нужно использовать что-то вроде этого:

sound: Sound = pg.mixer.Sound(buffer=b"".join(sound_chunks))

rate, _, _ = pygame.mixer.get_init()
print (f"Rate {rate}")

data = pygame.sndarray.samples(sound)
print (data.shape)
meter = pyln.Meter(rate) 
loudness = meter.integrated_loudness(data)
print(loudness)    

Отлично работает, большое спасибо! Рад, что звуковой объект можно использовать как есть.

Oyavo 09.06.2024 00:38

И NB pygame позволяет сохранять данные в виде файла. Ссылка здесь stackoverflow.com/questions/17292444/…

Johnny Cheesecutter 09.06.2024 00:39

Другие вопросы по теме