PortAudioを使ったアプリケーションのビルドをUbuntu 20.04 LTSで試してみました。
事の起こりは、ふと思い立ってプラットフォーム独立のオーディオライブラリを探してみたことです。するとdakiyamaさんが適当実装ブログに「最新のPortAudioを試す」と題してportaudioを紹介していらっしゃいました。dakiyamaさんは上記エントリでWindows上でのビルド方法を紹介し、続いて「MacでのPortAudio」「Ubuntu studioでのPortAudio」と続けます。
さて、dakiyamaさんはUbuntu Sutdioでビルドするにあたり、portaudioパッケージをダウンロードしています。しかしながら、手元のUbuntu 20.04 LTSおよび16.04 LTSではパッケージ管理を使うことでもっと簡単にportaudioを導入できます。
パッケージの導入とビルド、実行には以下の3行で済みます。
sudo apt-get install portaudio19-dev gcc main.c -lportaudio -lm ./a.out
gccの代わりにclangを使ってもビルドできます。clangを使う場合のコマンドライン・オプションもgccの場合と同じです。
sudo apt-get install portaudio19-dev clang clang main.c -lportaudio -lm ./a.out
試験にはdakiyamaさんが書いたプログラムをそのままコピーして使いました。ソースコードは以下の通りです。
#include<stdio.h> #include<math.h> #include"portaudio.h" #define Fs 44100 //サンプリング周波数 #define FRAMES_PER_BUFFER 128 //バッファサイズ #define pi 3.14159265358979323 /*ユーザ定義データ*/ typedef struct{ float freq; //正弦波の周波数 float index; }padata; /* オーディオ処理コールバック関数*/ static int dsp(const void *inputBuffer, //入力 void *outputBuffer, //出力 unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData //ユーザ定義データ ){ padata *data = (padata *)userData; float *out = (float *)outputBuffer; long i; for( i=0; i<framesPerBuffer; i++){ *out++ = 0.7 * sin( 2 * pi * data->freq * data->index / Fs ); //チャンネル1(左) *out++ = 0.7 * sin( 2 * pi * data->freq * data->index / Fs ); //チャンネル2(右) data->index+=1.f; } return 0; } int main(void){ PaStreamParameters outParam; //出力の定義 PaStream *stream; PaError err; padata data; //ユーザ定義データ data.freq = 800.f; data.index = 0.f; //PortAudio初期化 Pa_Initialize(); //出力の設定 outParam.device = Pa_GetDefaultOutputDevice(); //デフォルトのオーディオデバイス outParam.channelCount = 2; outParam.sampleFormat = paFloat32; //32bit floatで処理 outParam.suggestedLatency = Pa_GetDeviceInfo( outParam.device )->defaultLowOutputLatency; outParam.hostApiSpecificStreamInfo = NULL; //PortAudioオープン Pa_OpenStream( &stream, NULL, &outParam, Fs, FRAMES_PER_BUFFER, paClipOff, dsp, &data); //PortAudioスタート Pa_StartStream(stream); //エンターキーが押されるまで待機 getchar(); //PortAudio終了 Pa_StopStream(stream); Pa_CloseStream(stream); Pa_Terminate(); return 0; }