代码之家  ›  专栏  ›  技术社区  ›  William Lombard

测试电脑扬声器?

  •  0
  • William Lombard  · 技术社区  · 6 年前

    我试图用Python3.6编写一些代码,以帮助测试作为IT技术人员通过我手中的计算机硬件。

    我想要一个脚本,在左扬声器上播放一个简单的正弦波音调,然后在右扬声器上,然后两个扬声器一起播放。

    我在上找到了一个可能有用的脚本 Pyaudio How to get sound on only one speaker 但实际上运行它的一些代码却丢失了——主要是用于生成sin-wave音调的代码。我在网上到处找过,也试过把它反向工程到那页的代码中去,但数学对我来说有点高!对不起的。

    谢谢,

    威尔

    更新: 我想我已经找到了一个针对python 3的带有sounddevice的部分解决方案(尽管是冗长的解决方案)

    #!/usr/bin/env python3
    import argparse
    import logging
    
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("filename", help="audio file to be played back")
    parser.add_argument("-d", "--device", type=int, help="device ID")
    args = parser.parse_args()
    
    
    try:
        import sounddevice as sd
        import soundfile as sf
        data, fs = sf.read(args.filename, dtype='float32')
        sd.play(data, fs, device=args.device, blocking=True, mapping=[1])
        status = sd.get_status()
        if status:
            logging.warning(str(status))
    except BaseException as e:
        # This avoids printing the traceback, especially if Ctrl-C is used.
        raise SystemExit(str(e))
    

    代码的主要部分会重复两次,但将“mapping=[1]”更改为“mapping=[2]”,以测试正确的说话人,最后使用“mapping=[?]“删除在最后一块测试两个扬声器。

    我在那边找到这个 https://python-sounddevice.readthedocs.io/en/0.2.1/examples.html 是的。

    当然,如果有人知道一个更快和优雅的方式来完成这件事,请分享!

    1 回复  |  直到 6 年前
        1
  •  2
  •   Matthias    6 年前

    可以在python中直接生成正弦音调,而不是从文件中加载它。我写了一些关于创建简单正弦音调的教程:

    那些教程使用numpy,因为它使操作音频缓冲区变得非常容易。但如果您愿意的话,当然也可以使用纯python。 下面是一个例子:

    #!/usr/bin/env python3
    import math
    import sounddevice as sd
    
    sd.default.device = None
    sd.default.samplerate = samplerate = 48000
    
    duration = 1.5
    volume = 0.3
    frequency = 440
    
    # fade time in seconds:
    fade_in = 0.01
    fade_out = 0.3
    
    buffer = memoryview(bytearray(int(duration * samplerate) * 4)).cast('f')
    
    for i in range(len(buffer)):
        buffer[i] = volume * math.cos(2 * math.pi * frequency * i / samplerate)
    
    fade_in_samples = int(fade_in * samplerate)
    for i in range(fade_in_samples):
        buffer[i] *= i / fade_in_samples
    
    fade_out_samples = int(fade_out * samplerate)
    for i in range(fade_out_samples):
        buffer[-(i + 1)] *= i / fade_out_samples
    
    for mapping in ([1], [2], [1, 2]):
        sd.play(buffer, blocking=True, mapping=mapping)
        sd.sleep(500)
    

    注意,这段代码使用32位浮点数(每个浮点数使用4个字节),这就是为什么我们在 bytearray 超过所需的样本数。