声音的

该模块允许您从连接到 Microbit 的扬声器播放声音。为了使用音频模块,您需要提供一个声源。

声源是帧的可迭代(序列,如列表或元组,或生成器),每个帧有 32 个样本。该audio 模块以每秒 7812.5 个样本的速率播放样本,这意味着它可以再现高达 3.9kHz 的频率。

职能

audio.play(source, wait=True, pin=pin0, return_pin=None)

播放源完成。

source是一个可迭代的,其中的每个元素都必须是一个AudioFrame

如果waitTrue,则此函数将阻塞,直到源耗尽。

pin指定扬声器连接到哪个引脚。

return_pin指定连接到扬声器而不是接地的差分引脚。

班级

class audio.AudioFrame

一个AudioFrame对象是一个包含 32 个样本的列表,每个样本都是一个有符号字节(-128 到 127 之间的整数)。

播放一帧只需要 4 毫秒多一点。

使用音频

您将需要一个声源,作为play函数的输入。您可以生成自己的,例如在 examples/waveforms.py.

技术细节

笔记

您无需了解本节即可使用该 audio模块。它只是在这里以防您想知道它是如何工作的。

audio 模块以 7812.5 Hz 的频率消耗样本,并使用线性插值以 32.5 kHz 的频率输出 PWM 信号,音质尚可。

该函数在调用下一帧之前play 完全复制每个数据的所有数据,因此声源可以 重复使用相同的数据。AudioFrame next() AudioFrame

audio模块有一个内部 64 个样本缓冲区,从中读取样本。当读取到达缓冲区的开始或中点时,它会触发回调以获取下一个AudioFrame ,然后将其复制到缓冲区中。这意味着声源有不到 4ms 的时间来计算下一个AudioFrame,并且为了可靠的操作需要花费更少的 2ms(这是 32000 个周期,所以应该足够了)。

例子

from microbit import display, sleep, button_a
import audio
import math

def repeated_frame(frame, count):
    for i in range(count):
        yield frame

# Press button A to skip to next wave.
def show_wave(name, frame, duration=1500):
    display.scroll(name + " wave", wait=False,delay=100)
    audio.play(repeated_frame(frame, duration),wait=False)
    for i in range(75):
        sleep(100)
        if button_a.is_pressed():
            display.clear()
            audio.stop()
            break

frame = audio.AudioFrame()

for i in range(len(frame)):
    frame[i] = int(math.sin(math.pi*i/16)*124+128.5)
show_wave("Sine", frame)

triangle = audio.AudioFrame()

QUARTER = len(triangle)//4
for i in range(QUARTER):
    triangle[i] = i*15
    triangle[i+QUARTER] = 248-i*15
    triangle[i+QUARTER*2] = 128-i*15
    triangle[i+QUARTER*3] = i*15+8
show_wave("Triangle", triangle)

square = audio.AudioFrame()

HALF = len(square)//2
for i in range(HALF):
    square[i] = 8
    square[i+HALF] = 248
show_wave("Square", square)
sleep(1000)

for i in range(len(frame)):
    frame[i] = 252-i*8
show_wave("Sawtooth", frame)

del frame

#Generate a waveform that goes from triangle to square wave, reasonably smoothly.
frames = [ None ] * 32
for i in range(32):
    frames[i] = frame = audio.AudioFrame()
    for j in range(len(triangle)):
        frame[j] = (triangle[j]*(32-i) + square[j]*i)>>5

def repeated_frames(frames, count):
    for frame in frames:
        for i in range(count):
            yield frame


display.scroll("Ascending wave", wait=False)
audio.play(repeated_frames(frames, 60))