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;
}