代码之家  ›  专栏  ›  技术社区  ›  Oyavo

如何获得声音对象的响度(Pygame)

  •  1
  • Oyavo  · 技术社区  · 1 年前

    我正在尝试制作一个程序,接收用户的麦克风输入,然后测量它的响度 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,因为我一直在使用它。

    1 回复  |  直到 1 年前
        1
  •  0
  •   Johnny Cheesecutter    1 年前

    好问题。

    1. 采样率在pygaming初始化期间定义,在麦克风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)