The Synthesis Toolkit in C++とちがって,PortAudio(以下PA)は簡単にVisualStudio(VS)に導入できます.
流れ
- オーディオ処理が必要なときにPAのコールバック関数を記述します。
- PAライブラリを初期化し、オーディオI/O用のストリームを開きます。
- ストリームを開始します。 コールバック関数はバックグラウンドでPAによって繰り返し実行されます。(コールバックでは、inputBufferからオーディオデータを読み込んだり、outputBufferにデータを書き込んだりすることができます。)
- コールバックから1を返すか、stop関数を呼び出すことによってストリームを停止します。
- ストリームを閉じてライブラリを終了します。
のこぎり波を生成する例
PAをVSで使うには「portaudio.h」をインクルードする必要があります.作成するコールバック関数はintを返し,下で示すようなパラメータを受け入れるようなものでないとダメです.
typedef int PaStreamCallback( const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData );
以下が,のこぎり波を生成するサンプルです.
信号は-1.0と1.0の間でないとダメです.
#include <stdio.h> #include <stdlib.h> #include "portaudio.h" #define SAMPLE_RATE (44100) #define NUM_SECONDS (5) typedef struct { float left_phase; float right_phase; } paTestData; static int patestCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData); static paTestData data; int main(void) { PaStream *stream; PaError err; /* PA初期化 */ if (err = Pa_Initialize() != paNoError) { printf("PortAudio error: %s\n", Pa_GetErrorText(err)); return 1; } /* ストリームを開く */ /* 引数は,ポインタ,入力チャンネル数,出力チャンネル数, 出力のフォーマット,サンプリングレート,バッファごとのフレーム数, コールバック関数名,コールバック関数を通るポインタ */ if (err = Pa_OpenDefaultStream(&stream, 0, 2, paFloat32, SAMPLE_RATE, 256, patestCallback, &data) != paNoError) { printf("PortAudio error: %s\n", Pa_GetErrorText(err)); return 1; } /* ストリームを開始 */ if (err = Pa_StartStream(stream) != paNoError) { printf("PortAudio error: %s\n", Pa_GetErrorText(err)); return 1; } /* 数秒待機 */ Pa_Sleep(NUM_SECONDS * 1000); /* ストリームを停止 */ if (err = Pa_StopStream(stream) != paNoError) { printf("PortAudio error: %s\n", Pa_GetErrorText(err)); return 1; } /* ストリームを閉じる */ if (err = Pa_CloseStream(stream) != paNoError) { printf("PortAudio error: %s\n", Pa_GetErrorText(err)); return 1; } /* PA終了 */ if (err = Pa_Terminate() != paNoError) { printf("PortAudio error: %s\n", Pa_GetErrorText(err)); return 1; } system("pause"); return 0; } static int patestCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData) { /* データを構造体にキャスト */ paTestData *data = (paTestData*)userData; float *out = (float*)outputBuffer; unsigned int i; (void)inputBuffer; /* 使ってない変数による警告を避けるため */ for (i = 0; i<framesPerBuffer; i++) { *out++ = data->left_phase; /* 左 */ *out++ = data->right_phase; /* 右 */ /* のこぎり波を生成 */ data->left_phase += 0.01f; /* 範囲を超えたらしたに下げる */ if (data->left_phase >= 1.0f) data->left_phase -= 2.0f; /* 左右で音の高さが変わるように */ data->right_phase += 0.03f; if (data->right_phase >= 1.0f) data->right_phase -= 2.0f; } return 0; }