[PR]
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
プログラミング、3DCGとその他いろいろについて
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
プログラムから音の波のデータを作って、それを再生してみます。
(実はこれをやりたくてOpenALをはじめたんです!)
音は波ですから、波の高さをByteか何かの配列として表し、それを再生することが出来るわけです。
OpenALでは、8bitと16bitのデータの配列を使えるようなので、使うとしたらSystem.ByteかSysytem.UInt16の配列でしょうね。
alGenBuffers
前回と違うのは、音のデータを表すオブジェクト、Bufferをまず自分で作らなければいけないということです。(そしてそのBufferオブジェクトに波のデータ、byte[]をセットします。) Bufferオブジェクトを作るには、alGenBuffers関数を使います。
void alGenBuffers (ALsizei n, ALuint *bufferNames);
これはSourceオブジェクトを生成するalGenSources関数にとても似ています。実際、使い方は同じです。この関数は一度に複数のBufferオブジェクトを作ることが出来ます。引数のnは生成するBufferオブジェクトの数で、bufferNamesに生成されたBufferオブジェクト(の名前:Name)が格納されます。
alBufferData
こうして生成したBufferオブジェクトに音の波の高さを表すbyteかUInt16の配列をセットするには、alBufferData関数を使います。引数がたくさんありますが、C#でラッパークラスを作れば2つまで絞り込めます。
void alBufferData(
ALuint bufferName,
ALenum format,
const ALvoid *data
ALsizei size,
ALsizei frequency
);
この関数はいろいろなタイプの波のデータをセットすることが出来ます(全部で4つ)。モノラルかステレオかという選択と、8-bitか16-bitかという選択で、2 x 2 = 4とおりです。
モノラル | ステレオ | |
8-bit | AL_FORMAT_MONO8 (0x1100) |
AL_FORMAT_STEREO8 (0x1102) |
16-bit | AL_FORMAT_MONO16 (0x1101) |
AL_FORMAT_STEREO16 (0x1103) |
using System; using System.Runtime.InteropServices; using System.Threading; class Program { //OpenAL Utility Toolkit (Alut)の関数をインポート [DllImport("alut.dll")] static extern bool alutInit(IntPtr argcp, string[] argv); [DllImport("alut.dll")] static extern bool alutExit(); //OpenALの関数をインポート //Source関連 [DllImport("OpenAL32.dll")] static extern void alGenSources(int resultSize, int[] result); [DllImport("OpenAL32.dll")] static extern void alSourcei(int sourceName, int propertyType, int value); const int AL_BUFFER = 0x1009; [DllImport("OpenAL32.dll")] static extern void alSourcePlay(int sourceName); [DllImport("OpenAL32.dll")] static extern void alDeleteSources(int nameCount, int[] sourceNames); //Buffer関連 [DllImport("OpenAL32.dll")] static extern void alGenBuffers(int resultSize, int[] result); [DllImport("OpenAL32.dll")] static extern void alBufferData( int bufferName, int soundDataFormat, byte[] data, int size, int samplePerSecond ); const int AL_FORMAT_MONO8 = 0x1100; [DllImport("OpenAL32.dll")] static extern void alDeleteBuffers(int nameCount, int[] bufferNames); static void Main() { alutInit(IntPtr.Zero, null); //Bufferオブジェクト(音のデータ)の初期化 int[] buffers = new int[1]; alGenBuffers(buffers.Length, buffers); byte[] waveData = createAWave(22000); alBufferData(buffers[0], AL_FORMAT_MONO8, waveData, waveData.Length, 22000); //Sourceオブジェクト(音源)の初期化 int[] sources = new int[1]; alGenSources(sources.Length, sources); alSourcei(sources[0], AL_BUFFER, buffers[0]); //再生 alSourcePlay(sources[0]); Thread.Sleep(3000); alDeleteBuffers(buffers.Length, buffers); alDeleteSources(sources.Length, sources); alutExit(); } //3秒間の"ラ"の音を作る //"ラ"の周波数:440ヘルツ static byte[] createAWave(int samplePerSecond) { byte[] soundData = new byte[samplePerSecond * 3]; for (int i = 0; i < soundData.Length; i++) { soundData[i] = (byte)( 255 * Math.Sin((2 * Math.PI * 440) * i / samplePerSecond) ); } return soundData; } }