オーディオ

このモジュールは micro:bit でサウンドを再生できるようにします。

デフォルトでサウンドはエッジコネクタの端子 0 と V2内蔵スピーカー に出力します。端子 0 と GND に有線ヘッドフォンやスピーカーを繋いでサウンドを鳴らせます。

audio モジュールは import audio でインポートするか、 microbit モジュールの microbit.audio にアクセスすることで利用できるようになります。

関数

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

音源を最後まで再生します。

パラメータ:
  • source --

    source: Sound: microbit モジュールには audio.play() に渡すことのできる内蔵のサウンドがあります。

    AudioFrame: 引数 source には、後述する AudioFrame を要素とするイテラブル(iterable)オブジェクトを渡すこともできます。

  • wait -- waitTrue の場合、音源の再生が終わるまでこの関数から戻りません。
  • pin -- pin: 出力端子をデフォルトの pin0 から変えるためのオプション引数です。音を鳴らしたくない場合は pin=None を指定します。
  • return_pin -- スピーカーの2本ある線の一方を接続する先である GND を別の端子にしたい場合に使います。 V2 ではこの指定を無視します。
audio.is_playing()
戻り値:オーディオを再生中であれば True、再生していなければ False を返します。
audio.stop()

すべてのオーディオ再生を停止します。

クラス

class audio.AudioFrame

AudioFrame オブジェクトは32項目のリストです。各項目の値は符号なしバイト(0と255の間の整数)です。

1フレームを再生するのには4ミリ秒以上かかります。

copyfrom(other)

この AudioFrame のデータを、別の AudioFrame インスタンスのデータで上書きします。

パラメータ:other -- コピーするデータを持つ AudioFrame インスタンス。

オーディオの使い方

play 関数への入力として音源が必要になります。V2 には microbit モジュールに内蔵のサウンドである microbit.Sound があります。音源を自作することもでき、 examples/waveforms.py に自作の例があります。

V2 に内蔵のサウンド

以下の内蔵のサウンドは audio.play(Sound.NAME) のようにして再生できます。

  • Sound.GIGGLE
  • Sound.HAPPY
  • Sound.HELLO
  • Sound.MYSTERIOUS
  • Sound.SAD
  • Sound.SLIDE
  • Sound.SOARING
  • Sound.SPRING
  • Sound.TWINKLE
  • Sound.YAWN

技術的な詳細

注釈

audio モジュールを使うのにこのセクションを理解する必要はありません。このモジュールがどのように機能するのか知りたい方のためにあります。

audio モジュールは AudioFrame インスタンスのイテラブル(リストやタプルなどのシーケンス、またはジェネレータ)を巡回し、各回 7812.5 Hz で 32 項目を採取し、線形補間を使用して 32.5 kHz の PWM 信号を出力します。これにより、許容できる音質が得られます。

関数 play は、次のフレームを得るのに next() 呼び出す前に、 各 AudioFrame からすべてのデータを完全にコピーするので、音源は同じ AudioFrame を繰り返し使用できます。

audio モジュールには64個のサンプルバッファがあり、そこからサンプルを読み取ります。読み取りがバッファの開始点または中間点に達すると、次の AudioFrame を取り込むコールバックをトリガして、バッファにコピーします。これは、音源が次の AudioFrame を処理するのに 4ms 以下かかり、信頼できる操作のために 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

# 次の波形に行くには A ボタンを押します。
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

#三角波から方形波になる波形を、適度になめらかに生成。
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))