Belaで色々作ってみる。(1)

成果

  • Lチカ
  • スイッチを含めたLチカ

所見

  • 以前Arduinoを弄ってたときは正直スイッチの仕組みすら理解できてなかったので、
    一度おさらいとして電流がどのような仕組みで流れるかを確認した。
    そのおかげか、コーディングはもとより、ブレットボードの配置もそれほど困らずに済んだ。
  • Belaの秒数の考え方はオーディオ中心のため、44100/22050Hz等を中心に時間管理をするのが一番確実。
    ピンの発光もフレームに同期するように発光が可能(しかもそっちが早い)ため、フレームカウントやオーディオバッファを下敷きに各種時間管理をしていくのが一番理解が進む。
    (つまりオーディオバッファの単位で時間計測を行い、オーディオ再生時点ではなく、あらかじめ特定タイミングでのピンに電圧を流すという考えでいい。ここはWindowsとか他のOSより楽)
  • アナログ入出力を使う場合、ピンのモードを変更する必要はない。その代わり入出力の場所は決まっている。
    逆にデジタル入出力はどこでもOKだけど事前にInput/Outputの機能を定義しておく必要がある。

コード

アナログ出力のピンから電流を流して、
LEDが徐々に光るように制御するコード。

#include <Bela.h>

const int kLedPin = 0;
float out=0;
int cnt=0;
const float kMinimumAmplitude = (1.5 / 5.0);
const float kAmplitudeRange = 1.0 - kMinimumAmplitude;

//事前準備。基本的にはrender関数内で動的にメモリを確保するのはご法度みたい。
bool setup(BelaContext *context, void *userData)
{
    //アナログフレーム定義とアナログフレームがオーディオフレームを超えてたら強制終了
    if(context->analogFrames == 0 || context->analogFrames > context->audioFrames) {
        rt_fprintf(stderr, "analog setting is NG.\n");
        return false;
    }
    return true;
}

//レンダー関数。オーディオデータを生成するのに用いる。
//今回はLチカの命令を書く。
void render(BelaContext *context, void *userData)
{
    //オーディオバッファの数だけ処理する。
    for(unsigned int n = 0; n < context->analogFrames; n++)
    {
        //電流の流量を自前計算して流す。
        out = kMinimumAmplitude + kAmplitudeRange * 0.5f
              * ( (float)(cnt%44100)/44100.0f)*2;
        //アナログ出力のアウトプット。
        //特定フレーム数に同期するように出力されるため、即時出力ではないのに注意。
        //オーディオバッファの内、nフレーム目が再生・処理されたときにピンに電流が流れるみたい
        analogWriteOnce(context, n, kLedPin, out);

        //カウントを加算
        cnt++;

        //1秒で処理がループするようにカウンタをリセットする
        if( cnt>44100){
            cnt-=44100;
        }
    }

    //注意:
    //デバッグ用のprintfみたいな命令を書くときはfor文の外の方がいい。
    //レンダリング中に書くとBela自体のIDEからの終了処理がうまく呼ばれないケースがある。(あった)
}

//やることなし。
void cleanup(BelaContext *context, void *userData)
{
// Nothing to do here
}