Я пытаюсь создать программу, которая принимает входной сигнал пользователя с микрофона, а затем измеряет его громкость. Код представляет собой комбинацию 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, так как у меня с ним возникли проблемы.






хороший вопрос.
frequency).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)
Отлично работает, большое спасибо! Рад, что звуковой объект можно использовать как есть.
И NB pygame позволяет сохранять данные в виде файла. Ссылка здесь stackoverflow.com/questions/17292444/…
Как вы определяете «громкость»? Необработанные данные здесь будут представлять собой массив 32-битных значений с плавающей запятой. Вы можете использовать
arrayилиstructдля преобразования байтовой строки в массив чисел с плавающей запятой. Диапазон от -1,0 до 1,0, поэтому вы можете выяснить, насколько близко вы к 1,0.