PortAudio はクロスプラットフォームのオーディオAPIライブラリ。
主に Ubuntu 9.04
2010-11-15 自分で pa_stable_v19_20071207.tar.gz からパッケージを作ってみた
http://portaudio.com/download.html から v19_trunk pa_snapshot.tgz を落とす。
(created Sunday, 30-May-2010 21:37:03 PDT)
$ cd portaudio; configure; make $ ./bin/patest_sine
音が出た。
だいたいこんなプログラム。
http://www.portaudio.com/trac/browser/portaudio/branches/v19-devel/test/patest_sine.c?rev=1083
自分でコンパイルしなおしてみる。
$ cd .. $ mkdir myapp $ cd myapp $ cp ../portaudio/test/patest_sine.c $ gcc -I../portaudio/include -L../portaudio/lib -lportaudio patest_sine.c $ ./a.out
これも音が出た。
since 2010-11-26
Ubuntu 10.10 に portaudio19-dev をいれた状態で patest_record.c を動かす。
http://www.portaudio.com/trac/browser/portaudio/trunk/test/patest_record.c?rev=1556
これを手に入れるために svn を使ってみる:
$ svn co https://www.portaudio.com/repos/portaudio/trunk .
コンパイルして実行:
$ cd test $ gcc -lportaudio patest_record.c $ ./a.out
しばらく録音が行われて、その後再生される。
http://www.portaudio.com/trac/wiki/TutorialDir/Compile/Windows
please see the build/msvc/readme.txt と書かれている。
http://www.portaudio.com/trac/browser/portaudio/trunk/build/msvc/readme.txt
since 2010-11-26
コールバックしか使えないという先入観があったが、v19 からはブロッキングAPIが使える。
http://portaudio.com/trac/wiki/TutorialDir/BlockingReadWrite
http://www.portaudio.com/docs/proposals/005-BlockingReadWriteInterface.html
動いたが、変なエラーがでる:
bt_audio_service_open: connect() failed: Connection refused (111)
http://ubuntu-ky.ubuntuforums.org/showthread.php?p=9344433
下記で解決:
$ sudo apt-get remove bluez-alsa
since 2010-11-26
Ubuntu 10.10 で確認。
音声処理の定番である 16bit 16KHz mono の音声取り込み。
メインループは GLUT で書かれている。プログラム全体はいずれ整理して公開したい。
audio.c のスタティック変数:
static PaStream* stream; static short *g_audioin_data = NULL;
初期化の処理:
PaStreamParameters inputParameters; PaError err = paNoError; err = Pa_Initialize(); if( err != paNoError ) goto done; inputParameters.device = Pa_GetDefaultInputDevice(); if (inputParameters.device == paNoDevice) { fprintf(stderr,"Error: No default input device.\n"); goto done; } inputParameters.channelCount = 1; inputParameters.sampleFormat = paInt16; inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency; inputParameters.hostApiSpecificStreamInfo = NULL; err = Pa_OpenStream( &stream, &inputParameters, NULL, /* &outputParameters, */ 16000, // SAMPLE_RATE, 1024, // FRAMES_PER_BUFFER, paClipOff, NULL, // recordCallback, NULL ); // &data ); if( err != paNoError ) goto done; err = Pa_StartStream( stream ); if( err != paNoError ) goto done; done: return;
クローズの処理:
PaError err = paNoError; err = Pa_StopStream( stream ); if( err != paNoError ) goto error; err = Pa_CloseStream( stream ); if( err != paNoError ) goto error; Pa_Terminate(); return; error: printf("audioClose: error\n"); return;
読み込みループの繰り返し処理:
void *dest, *src; int error_flag = 0; PaError err = paNoError; signed long len; if ( g_audioin_data == NULL ) { g_audioin_data = malloc(sizeof(short) * CAPTURESIZE); } len = Pa_GetStreamReadAvailable( stream ); if ( CAPTURESIZE < len ) len = CAPTURESIZE; err = Pa_ReadStream( stream, g_audioin_data, len ); if ( err != paNoError ) return 1; g_audioin_size = len;
Pa_GetStreamReadAvailable() の返した値を Pa_ReadStream() の第3引数に使うのがポイント。 第3引数に大きな値を入れると Pa_ReadStream が遅延を起こす。
ちなみに上記は splibs ではこのような処理の部分:
g_audioin_size = spReadAudio(g_audio, g_audioin_data, CAPTURESIZE);
FRAMES_PER_BUFFER の 1024 には意味があるかどうか未確認。