忍者ブログ

Memeplexes

プログラミング、3DCGとその他いろいろについて

OpenTKからOpenALを使ってラの音を再生する

P/Invokeを使うのは面倒なので、すでにライブラリになったOpenTKを使ってOpenALをC#から使ってみます。


サンプルコード

using System;
using OpenAL = OpenTK.Audio.OpenAL;

class Program
{
    const int bufferFrequency = 44100;
    const int bufferSeconds = 3;

    static void Main(string[] args)
    {
        //初期化
        var device = OpenAL.Alc.OpenDevice(null);
        var context = OpenAL.Alc.CreateContext(device, (int[])null);
        OpenAL.Alc.MakeContextCurrent(context);

        //うるさすぎないよう音のボリュームを下げる
        setVolume(0.2f);

        //ラの音を出す音源を作成
        var source = OpenAL.AL.GenSource();
        int buffer = createBuffer();
        OpenAL.AL.BindBufferToSource(source, buffer);

        //再生
        OpenAL.AL.SourcePlay(source);
        System.Threading.Thread.Sleep(bufferSeconds * 1000 + 1000);

        //使わなくなったデータをクリーンアップ
        OpenAL.AL.DeleteSource(source);
        OpenAL.AL.DeleteBuffer(buffer);
        OpenAL.Alc.MakeContextCurrent(OpenTK.ContextHandle.Zero);
        OpenAL.Alc.DestroyContext(context);
        OpenAL.Alc.CloseDevice(device);
    }

    private static void setVolume(float value)
    {
        OpenAL.AL.Listener(OpenAL.ALListenerf.Gain, value);
    }

    private static int createBuffer()
    {
        var buffer = OpenAL.AL.GenBuffer();
        var bufferData = new byte[bufferFrequency * bufferSeconds];

        for (var i = 0; i < bufferData.Length; i++)
        {
            var time = (double)i / bufferFrequency;
            var frequency = 440;
            var data = Math.Sin(time * frequency * Math.PI * 2);
            bufferData[i] = (byte)Math.Round(
                byte.MaxValue * (data + 1) / 2
                );
        }

        OpenAL.AL.BufferData(
            buffer,
            OpenAL.ALFormat.Mono8,
            bufferData,
            bufferData.Length,
            bufferFrequency
            );
        return buffer;
    }
}

解説

このプログラムを実行すると、スピーカーからラの音が3秒間流れます。

Youtubeのこれと同じ音です:

拍手[1回]

PR