PortAudio詳解
整理者:赤子玄心
QQ:280604597
Email:280604597@qq.com
大家有什么不明白的地方,或者想要詳細了解的地方可以聯系我,我會認真回復的
1 簡介
PortAudio是一個免費、跨平台、開源的音頻I/O庫。看到I/O可能就想到了文件,但是PortAudio操作的I/O不是文件,而是音頻設備。它能夠簡化C/C++的音頻程序的設計實現,能夠運行在Windows、Macintosh OS X和UNIX之上(Linux的各種版本也不在話下)。使用PortAudio可以在不同的平台上遷移應用程序,比如你可以把你基於PortAudio的應用程序發展一個Android版本啊。
PortAudio的API非常簡單,通過一個一個簡單的回調函數或者阻塞的讀/寫接口來錄制或者播放聲音。PortAudio自帶了很多示例程序,比如播放正弦波形的音頻信號,處理音頻輸入,錄制回放音頻,列舉音頻設備。
PortAudio使用的是自己定義的License,關鍵點在於:
1、允許在你的項目或程序中免費使用PortAudio,商業軟件也是免費使用的。
2、可以不開源你的源碼。
3、禁止刪除PortAudio中的版權信息。
4、如果你修復了PortAudio中的bug,請通知社區。
5、如果你的程序因為PortAudio而崩潰,我們不負任何責任。
PortAudio的最新版本是V19。本文討論的就是該版本。
2 PortAudio V19庫編譯
2.1 准備
PortAudio官網:
PortAudio庫API英文詳解:
http://www.portaudio.com/docs/v19-doxydocs/portaudio_8h.html#a443ad16338191af364e3be988014cbbe
DirectX SDK下載:
http://www.microsoft.com/en-us/download/details.aspx?id=6812
PortAudio下載:
http://portaudio.com/docs/v19-doxydocs/compile_windows.html
ASIO SDK下載:
http://download.csdn.net/detail/linyiqinggood/6778175
PortAudio是采集和播放音頻的開源庫,可以用於Linux和windows,在windows下依賴DirectX庫(Directshow)用於驅動聲卡,所以必須安裝DirectX sdk庫。
安裝DirectX sdk庫參考:
http://blog.sina.com.cn/s/blog_b5c2c06f01016cu5.html
portaudioV19的安裝集合包下載地址:
http://download.csdn.net/detail/yanmy2012/4655561
2.2 編譯方式
Windows編譯參考http://portaudio.com/docs/v19-doxydocs/compile_windows.html
其他的編譯方式http://portaudio.com/docs/v19-doxydocs/pages.html
由於V19 相對於V18改了非常多的地方,所以只編譯V19的庫,例程只有較新的才能在V19中編譯通過,有些會顯示找不到類型和函數申明。
2.3 編譯過程
下面列出的步驟來建立PortAudio成一個dll和lib文件。得到的DLL文件可能包含所有五個目前的win32 PortAudio的API:MME,DirectSound的,WASAPI,WDM / KS和ASIO,根據下面的步驟9中設置的預處理器定義。PortAudio可以被編譯使用Visual C + + Express版是由微軟免費提供。如果你有一個C + +開發環境,只需下載並安裝。這些指令已經成功觀察到使用Visual Studio 2010和。
1) PortAudio為Windows需要的文件dsound.h的和dsconf.h。下載並安裝DirectX SDK 獲得這些文件。如果你安裝了DirectX SDK!的DirectSound的庫和頭文件的自動加到 Visual C + +中。
如果你得到一個錯誤說缺少dsound.h,或dsconf.h的,你可以添加這些路徑。或者,您可以復制dsound.h和dsconf.h,到portaudio\。還應該有一個名為“dsound.lib”C:\Program Files\Microsoft SDKs\Windows\v6.0A\Lib文件。
2) 支持ASIO,下載ASIO SDK在http://www.steinberg.net/en/company/developer.html。 SDK是免費的,但您將需要與斯坦伯格建立一個開發者帳號,所以我提供了下載文件,這個也是從網上收回來的。復制整個ASIOSDK2的到src文件夾\hostapi\ASIO\。重命名它,從ASIOSDK2到ASIOSDK。
3) 如果您的Visual Studio 6.0,7.0(VC.NET/2001)或7.1(VC.2003),打開portaudio.dsp並轉換如果需要的話。
4) 如果你有Visual Studio 2005中的Visual C + + 2008 Express Edition或Visual Studio 2010中,雙擊portaudio.sln的文件位於在build \ MSVC \。這樣做將打開Visual Studio或Visual C + +。點擊“Finish”如果出現一個向導。sln文件中包含四種配置:Win32和Win64的發布和調試的變種。
對於Visual Studio 2005中的Visual C + + 2008 Express版或Visual Studio 2010中
5) 打開項目 - > portaudio“屬性”,在樹視圖中選擇“配置屬性”。
6) 選擇“配置”中的“配置”組合框。選擇“所有平台”
7) 設置幾個選項:
C/C++—〉優化—〉省略框架指針= YES
C/C++—〉代碼生成—〉運行時庫/MT
可選:C/C++—〉代碼生成—〉浮點模型=快速
注:對於大多數用戶來說,它是沒有必要顯式地設置結構成員對齊,默認情況下應該正常工作。然而,一些語言要求,例如,4字節對齊。如果您有portaudio.h結構的成員沒有被正確讀取或寫入的問題,可能有必要顯式地設置這個值由C/C++—〉代碼生成—〉結構成員對齊,將其設置為一個適當的值(四是共同的價值)。如果你的編譯器是可配置的,你應該確保它被設置為使用相同的結構成員對齊值所使用的PortAudio構建。
當你設置完這些參數后點擊“確定”。
預處理器定義
由於預處理器定義是不同的,每個配置和平台,你需要編輯這些單獨為每個配置/平台組合,你想修改的“配置”和“平台”組合框。
8) 為了抑制的PortAudio運行調試控制台輸出項目—〉屬性—〉配置屬性—〉C/C++—〉預處理器。在該領域的預處理器定義,找到PA_ENABLE_DEBUG_OUTPUT並刪除它。控制台將不輸出調試信息。
9) 你需要明確地定義你想使用的音頻API的預處理器定義。對於Windows提供的API定義是:
PA_USE_ASIO
PA_USE_DS(DirectSound的)
PA_USE_WMME(MME)
PA_USE_WASAPI
PA_USE_WDMKS
PA_USE_SKELETON
對於每個這樣的,值為0表示不應列入這個API的支持。值1表示應該包括這個API的支持。
設置預處理器定義時,build是配置每個平台的過程。按照這些說明build你感興趣的每一個配置/平台組合。
以上宏在“項目—〉屬性—〉配置屬性—〉C/C++—〉預處理器—〉預處理器定義”中定義的。
10) 從“生成”菜單上單擊“生成” - >“生成解決方案”。對於32位編譯的dll文件創建的這個過程(portaudio_x86.dll)中可以找到的目錄生成\ MSVC \ WIN32 \發布。64位編譯的DLL文件被稱為portaudio_x64.dll,被發現在目錄中生成\ MSVC \ X64 \發布。
11) 現在,任何項目需要portaudio可以與portaudio_x86.lib(或_x64),包括您可能要添加/刪除一些DLL 相關的頭(portaudio.h,和/或pa_asio.h,pa_x86_plain_converters.h),入口點。現在,這6個項目是不是從portaudio.h:
最后會生成portaudio_x86.lib和portaudio_x86.dll,各兩個分別是Debug和Release的,不同配置下使用不同dll和lib。
安裝完之后就是測試,源代碼文件夾test文件夾下有測試代碼,由於V19 相對於V18改了非常多的地方,所以只編譯V19的庫,例程只有較新的才能在V19中編譯通過,有些會顯示找不到類型和函數申明。
patest_record.c代碼,運行過程中會有5秒的嘟嘟聲(由的算法產生的float點型級別的聲波),這樣就證明了已經安裝成功。
#include "portaudio.h"
#define SAMPLE_RATE (44100)
#define FRAMES_PER_BUFFER (1024)
#define NUM_SECONDS (5)
#define NUM_CHANNELS (2)
#define DITHER_FLAG (0)
#if 1
#define PA_SAMPLE_TYPE paFloat32
typedef float SAMPLE;
#define SAMPLE_SILENCE (0.0f)
#define PRINTF_S_FORMAT "%.8f"
#elif 1
#define PA_SAMPLE_TYPE paInt16
typedef short SAMPLE;
#define SAMPLE_SILENCE (0)
#define PRINTF_S_FORMAT "%d"
#elif 0
#define PA_SAMPLE_TYPE paInt8
typedef char SAMPLE;
#define SAMPLE_SILENCE (0)
#define PRINTF_S_FORMAT "%d"
#else
#define PA_SAMPLE_TYPE paUInt8
typedef unsigned char SAMPLE;
#define SAMPLE_SILENCE (128)
#define PRINTF_S_FORMAT "%d"
#endif
typedef struct
{
int frameIndex;
int maxFrameIndex;
SAMPLE *recordedSamples;
}
paTestData;
static int recordCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
const SAMPLE *rptr = (const SAMPLE*)inputBuffer;
SAMPLE *wptr = &data->recordedSamples[data->frameIndex * NUM_CHANNELS];
long framesToCalc;
long i;
int finished;
unsigned long framesLeft = data->maxFrameIndex - data->frameIndex;
(void) outputBuffer;
(void) timeInfo;
(void) statusFlags;
(void) userData;
if( framesLeft < framesPerBuffer )
{
framesToCalc = framesLeft;
finished = paComplete;
}
else
{
framesToCalc = framesPerBuffer;
finished = paContinue;
}
if( inputBuffer == NULL )
{
for( i=0; i
{
*wptr++ = SAMPLE_SILENCE;
if( NUM_CHANNELS == 2 ) *wptr++ = SAMPLE_SILENCE;
}
}
else
{
for( i=0; i
{
*wptr++ = *rptr++;
if( NUM_CHANNELS == 2 ) *wptr++ = *rptr++;
}
}
data->frameIndex += framesToCalc;
return finished;
}
static int playCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData )
{
paTestData *data = (paTestData*)userData;
SAMPLE *rptr = &data->recordedSamples[data->frameIndex * NUM_CHANNELS];
SAMPLE *wptr = (SAMPLE*)outputBuffer;
unsigned int i;
int finished;
unsigned int framesLeft = data->maxFrameIndex - data->frameIndex;
(void) inputBuffer;
(void) timeInfo;
(void) statusFlags;
(void) userData;
if( framesLeft < framesPerBuffer )
{
for( i=0; i
{
*wptr++ = *rptr++;
if( NUM_CHANNELS == 2 ) *wptr++ = *rptr++;
}
for( ; i
{
*wptr++ = 0;
if( NUM_CHANNELS == 2 ) *wptr++ = 0;
}
data->frameIndex += framesLeft;
finished = paComplete;
}
else
{
for( i=0; i
{
*wptr++ = *rptr++;
if( NUM_CHANNELS == 2 ) *wptr++ = *rptr++;
}
data->frameIndex += framesPerBuffer;
finished = paContinue;
}
return finished;
}
int main(void);
int main(void)
{
PaStreamParameters inputParameters,
outputParameters;
PaStream* stream;
PaError err = paNoError;
paTestData data;
int i;
int totalFrames;
int numSamples;
int numBytes;
SAMPLE max, val;
double average;
printf("patest_record.c\n"); fflush(stdout);
data.maxFrameIndex = totalFrames = NUM_SECONDS * SAMPLE_RATE;
data.frameIndex = 0;
numSamples = totalFrames * NUM_CHANNELS;
numBytes = numSamples * sizeof(SAMPLE);
data.recordedSamples = (SAMPLE *) malloc( numBytes );
if( data.recordedSamples == NULL )
{
printf("Could not allocate record array.\n");
goto done;
}
for( i=0; i
err = Pa_Initialize();
if( err != paNoError ) goto done;
inputParameters.device = Pa_GetDefaultInputDevice();
inputParameters.channelCount = 2;
inputParameters.sampleFormat = PA_SAMPLE_TYPE;
inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
inputParameters.hostApiSpecificStreamInfo = NULL;
err = Pa_OpenStream(
&stream,
&inputParameters,
NULL,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff,
recordCallback,
&data );
if( err != paNoError ) goto done;
err = Pa_StartStream( stream );
if( err != paNoError ) goto done;
printf("Now recording!!\n"); fflush(stdout);
while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
{
Pa_Sleep(1000);
printf("index = %d\n", data.frameIndex ); fflush(stdout);
}
if( err < 0 ) goto done;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto done;
max = 0;
average = 0.0;
for( i=0; i
{
val = data.recordedSamples[i];
if( val < 0 ) val = -val;
if( val > max )
{
max = val;
}
average += val;
}
average = average / (double)numSamples;
printf("sample max amplitude = "PRINTF_S_FORMAT"\n", max );
printf("sample average = %lf\n", average );
#if 0
{
FILE *fid;
fid = fopen("recorded.raw", "wb");
if( fid == NULL )
{
printf("Could not open file.");
}
else
{
fwrite( data.recordedSamples, NUM_CHANNELS * sizeof(SAMPLE), totalFrames, fid );
fclose( fid );
printf("Wrote data to 'recorded.raw'\n");
}
}
#endif
data.frameIndex = 0;
outputParameters.device = Pa_GetDefaultOutputDevice();
outputParameters.channelCount = 2;
outputParameters.sampleFormat = PA_SAMPLE_TYPE;
outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
outputParameters.hostApiSpecificStreamInfo = NULL;
printf("Begin playback.\n"); fflush(stdout);
err = Pa_OpenStream(
&stream,
NULL,
&outputParameters,
SAMPLE_RATE,
FRAMES_PER_BUFFER,
paClipOff,
playCallback,
&data );
if( err != paNoError ) goto done;
if( stream )
{
err = Pa_StartStream( stream );
if( err != paNoError ) goto done;
printf("Waiting for playback to finish.\n"); fflush(stdout);
while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) Pa_Sleep(100);
if( err < 0 ) goto done;
err = Pa_CloseStream( stream );
if( err != paNoError ) goto done;
printf("Done.\n"); fflush(stdout);
}
done:
Pa_Terminate();
if( data.recordedSamples )
free( data.recordedSamples );
if( err != paNoError )
{
fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
err = 1;
}
return err;
}
3 函數庫
3.1 函數模板(未完成)
| 函數名稱 |
xxx |
| 頭文件 |
#include "PortAudio.h" |
| 庫文件 |
#pragma comment(lib, "PortAudio_x86.lib或PortAudio_x64.lib") |
| 函數功能 |
函數主要功能說明。 |
| 函數聲明 |
類型 函數名 ( 類型 參數1, 類型 參數2, …… ); |
| 函數參數 |
參數1,[輸入|輸出|輸入&輸出]: 參數說明。 |
| 參數2,[輸入|輸出|輸入&輸出]: 參數說明。 |
|
| …… |
|
| 返回值 |
返回值1:返回值說明。 返回值2:返回值說明。 …… |
| 錯誤碼 |
EXXXX:錯誤碼說明。 EXXXX:錯誤碼說明。 …… |
| 線程安全 |
是 或 否 或 未知,表示此函數多線程調用是否會產生影響 |
| 原子操作 |
是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合 |
| 其他說明 |
…… …… |
3.2 Pa_Initialize(未完成)
| 函數名稱 |
Pa_Initialize |
| 頭文件 |
#include "PortAudio.h" |
| 庫文件 |
#pragma comment(lib, "PortAudio_x86.lib或PortAudio_x64.lib") |
| 函數功能 |
初始化PortAudio庫。 |
| 函數聲明 |
PaError Pa_Initialize ( void ); |
| 函數參數 |
無 |
| 返回值 |
paNoError枚舉(0x0000):成功。 其他:失敗,返回值就是錯誤碼,調用Pa_GetErrorText()函數查看錯誤碼對應的錯誤信息。 |
| 錯誤碼 |
EXXXX:錯誤碼說明。 EXXXX:錯誤碼說明。 …… |
| 線程安全 |
是 或 否 或 未知,表示此函數多線程調用是否會產生影響 |
| 原子操作 |
是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合 |
| 其他說明 |
使用PortAudio函數庫之前必須調用本函數初始化。 本函數初始化的內部數據結構,並准備底層主機的API使用。除了Pa_GetVersion(),Pa_GetVersionText(),和Pa_GetErrorText()時,該功能必須使用任何其他PortAudio API函數之前調用。 如果本函數被調用多次,每一次成功的調用必須有相應調用Pa_Terminate()函數相匹配。調用Pa_Initialize的對()/ Pa_Terminate()可能會重疊,並且不要求完全嵌套。 如果本函數返回失敗,不需要調用Pa_Terminate()函數來銷毀。 |
3.3 Pa_Terminate(未完成)
| 函數名稱 |
Pa_Terminate |
| 頭文件 |
#include "PortAudio.h" |
| 庫文件 |
#pragma comment(lib, "PortAudio_x86.lib或PortAudio_x64.lib") |
| 函數功能 |
銷毀已經初始化的PortAudio庫。 |
| 函數聲明 |
PaError Pa_Terminate ( void ); |
| 函數參數 |
無 |
| 返回值 |
paNoError枚舉(0x0000):成功。 其他:失敗,返回值就是錯誤碼,調用Pa_GetErrorText()函數查看錯誤碼對應的錯誤信息。 |
| 錯誤碼 |
paNotInitialized枚舉(-10000):沒有初始化PortAudio庫。 EXXXX:錯誤碼說明。 …… |
| 線程安全 |
是 或 否 或 未知,表示此函數多線程調用是否會產生影響 |
| 原子操作 |
是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合 |
| 其他說明 |
本函數會銷毀由PortAudio庫分配的所有資源。 本函數必須在程序退出之前被調用,否則可能會導致嚴重的資源泄漏,如錄音設備或播放設備不可用,除非重新啟動操作系統。 |
3.4 Pa_GetErrorText(未完成)
| 函數名稱 |
Pa_GetErrorText |
| 頭文件 |
#include "PortAudio.h" |
| 庫文件 |
#pragma comment(lib, "PortAudio_x86.lib或PortAudio_x64.lib") |
| 函數功能 |
根據指定的錯誤碼獲取對應的錯誤信息字符串。 |
| 函數聲明 |
const char * Pa_GetErrorText ( PaError errorCode ); |
| 函數參數 |
errorCode,[輸入]: 存放錯誤碼的值。 |
| 返回值 |
錯誤信息字符串的內存指針。 |
| 錯誤碼 |
無 |
| 線程安全 |
是 或 否 或 未知,表示此函數多線程調用是否會產生影響 |
| 原子操作 |
是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合 |
| 其他說明 |
如果指定的錯誤碼是不存在的,返回的錯誤信息字符串為"Invalid error code (value greater than zero)"。 |
3.5 Pa_GetVersion(未完成)
| 函數名稱 |
Pa_GetVersion |
| 頭文件 |
#include "PortAudio.h" |
| 庫文件 |
#pragma comment(lib, "PortAudio_x86.lib或PortAudio_x64.lib") |
| 函數功能 |
以整數方式獲取當前程序正在使用的PortAudio庫的版本號,例如:1900。 |
| 函數聲明 |
int Pa_GetVersion ( void ); |
| 函數參數 |
無 |
| 返回值 |
PortAudio庫的版本號的整數。 |
| 錯誤碼 |
無 |
| 線程安全 |
是 或 否 或 未知,表示此函數多線程調用是否會產生影響 |
| 原子操作 |
是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合 |
| 其他說明 |
|
3.6 Pa_GetVersionText(未完成)
| 函數名稱 |
Pa_GetVersionText |
| 頭文件 |
#include "PortAudio.h" |
| 庫文件 |
#pragma comment(lib, "PortAudio_x86.lib或PortAudio_x64.lib") |
| 函數功能 |
以信息字符串方式獲取當前程序正在使用的PortAudio庫的版本號,例如:"PortAudio V19-devel 13 October 2002"。 |
| 函數聲明 |
int Pa_GetVersionText ( void ); |
| 函數參數 |
無 |
| 返回值 |
PortAudio庫的版本號的信息字符串的內存指針。 |
| 錯誤碼 |
無 |
| 線程安全 |
是 或 否 或 未知,表示此函數多線程調用是否會產生影響 |
| 原子操作 |
是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合 |
| 其他說明 |
獲取到信息字符串所占用的內存由Pa_Terminate()函數自動釋放,不需要手動釋放,否則會出現未知錯誤。 |
3.7 Pa_GetDeviceCount(未完成)
| 函數名稱 |
Pa_GetDeviceCount |
| 頭文件 |
#include "PortAudio.h" |
| 庫文件 |
#pragma comment(lib, "PortAudio_x86.lib或PortAudio_x64.lib") |
| 函數功能 |
獲取可用的音頻設備的數量。 |
| 函數聲明 |
PaDeviceIndex Pa_GetDeviceCount ( void ); |
| 函數參數 |
無 |
| 返回值 |
大於等於0:成功,可用的音頻設備的數量。 小於0:失敗,返回值就是錯誤碼,調用Pa_GetErrorText()函數查看錯誤碼對應的錯誤信息。 |
| 錯誤碼 |
EXXXX:錯誤碼說明。 EXXXX:錯誤碼說明。 …… |
| 線程安全 |
是 或 否 或 未知,表示此函數多線程調用是否會產生影響 |
| 原子操作 |
是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合 |
| 其他說明 |
|
3.8 Pa_GetDeviceInfo(未完成)
| 函數名稱 |
Pa_GetDeviceInfo |
| 頭文件 |
#include "PortAudio.h" |
| 庫文件 |
#pragma comment(lib, "PortAudio_x86.lib或PortAudio_x64.lib") |
| 函數功能 |
根據音頻設備的索引號獲取音頻設備的相關信息。 |
| 函數聲明 |
const PaDeviceInfo * Pa_GetDeviceInfo ( PaDeviceIndex device ); |
| 函數參數 |
device,[輸入]: 存放音頻設備的索引號。 音頻設備的索引號范圍從0開始,到Pa_GetDeviceCount()函數返回的音頻設備的數量減一。 |
| 返回值 |
NULL:失敗,音頻設備的索引號超出范圍。 其他:音頻設備信息結構體的內存指針。 |
| 錯誤碼 |
EXXXX:錯誤碼說明。 EXXXX:錯誤碼說明。 …… |
| 線程安全 |
是 或 否 或 未知,表示此函數多線程調用是否會產生影響 |
| 原子操作 |
是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合 |
| 其他說明 |
獲取到音頻設備信息結構體所占用的內存由Pa_Terminate()函數自動釋放,不需要手動釋放,否則會出現未知錯誤。 如果不知道該用哪個音頻輸入設備,可以調用Pa_GetDefaultInputDevice()函數獲取默認的音頻輸入設備。 如果不知道該用哪個音頻輸出設備,可以調用Pa_GetDefaultOutputDevice()函數獲取默認的音頻輸出設備。 |
3.9 Pa_GetDefaultInputDevice(未完成)
| 函數名稱 |
Pa_GetDefaultInputDevice |
| 頭文件 |
#include "PortAudio.h" |
| 庫文件 |
#pragma comment(lib, "PortAudio_x86.lib或PortAudio_x64.lib") |
| 函數功能 |
獲取操作系統中默認的音頻輸入設備。 |
| 函數聲明 |
PaDeviceIndex Pa_GetDefaultInputDevice ( void ); |
| 函數參數 |
無 |
| 返回值 |
paNoDevice宏(-1):沒有音頻輸入設備。 大於等於0:音頻輸入設備的索引號。 |
| 錯誤碼 |
無 |
| 線程安全 |
是 或 否 或 未知,表示此函數多線程調用是否會產生影響 |
| 原子操作 |
是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合 |
| 其他說明 |
|
3.10 Pa_GetDefaultOutputDevice(未完成)
| 函數名稱 |
Pa_GetDefaultOutputDevice |
| 頭文件 |
#include "PortAudio.h" |
| 庫文件 |
#pragma comment(lib, "PortAudio_x86.lib或PortAudio_x64.lib") |
| 函數功能 |
獲取操作系統中默認的音頻輸入設備。 |
| 函數聲明 |
PaDeviceIndex Pa_GetDefaultOutputDevice ( void ); |
| 函數參數 |
無 |
| 返回值 |
paNoDevice宏(-1):沒有音頻輸出設備。 大於等於0:音頻輸出設備的索引號。 |
| 錯誤碼 |
無 |
| 線程安全 |
是 或 否 或 未知,表示此函數多線程調用是否會產生影響 |
| 原子操作 |
是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合 |
| 其他說明 |
|
3.11 Pa_OpenStream(未完成)
| 函數名稱 |
Pa_OpenStream |
| 頭文件 |
#include "PortAudio.h" |
| 庫文件 |
#pragma comment(lib, "PortAudio_x86.lib或PortAudio_x64.lib") |
| 函數功能 |
使用指定的音頻輸入輸出設備打開一個音頻流句柄,用於 音頻輸入 或 音頻輸出 或 音頻輸入輸出。 |
| 函數聲明 |
PaError Pa_OpenStream ( PaStream ** stream, const PaStreamParameters * inputParameters, const PaStreamParameters * outputParameters, double sampleRate, unsigned long framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallback * streamCallback, void * userData ); |
| 函數參數 |
stream,[輸出]: 存放用於存放音頻流句柄的指針變量的內存指針。 存放音頻流句柄的變量類型為PaStream *。 |
| inputParameters,[輸入]: 。 |
|
| outputParameters,[輸入|輸出|輸入&輸出]: 參數說明。 |
|
| sampleRate,[輸入|輸出|輸入&輸出]: 參數說明。 |
|
| framesPerBuffer,[輸入|輸出|輸入&輸出]: 參數說明。 |
|
| streamFlags,[輸入|輸出|輸入&輸出]: 參數說明。 |
|
| streamCallback,[輸入|輸出|輸入&輸出]: 參數說明。 |
|
| userData,[輸入|輸出|輸入&輸出]: 參數說明。 |
|
| 返回值 |
paNoError枚舉(0x0000):成功。 其他:失敗,返回值就是錯誤碼,調用Pa_GetErrorText()函數查看錯誤碼對應的錯誤信息。 |
| 錯誤碼 |
EXXXX:錯誤碼說明。 EXXXX:錯誤碼說明。 …… |
| 線程安全 |
是 或 否 或 未知,表示此函數多線程調用是否會產生影響 |
| 原子操作 |
是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合 |
| 其他說明 |
…… …… |
3.12 Pa_OpenDefaultStream(未完成)
| 函數名稱 |
Pa_OpenDefaultStream |
| 頭文件 |
#include "PortAudio.h" |
| 庫文件 |
#pragma comment(lib, "PortAudio_x86.lib或PortAudio_x64.lib") |
| 函數功能 |
使用操作系統默認的音頻輸入輸出設備打開一個音頻流句柄,用於 音頻輸入 或 音頻輸出 或 音頻輸入輸出。 |
| 函數聲明 |
PaError Pa_OpenDefaultStream ( PaStream ** stream, int numInputChannels, int numOutputChannels, PaSampleFormat sampleFormat, double sampleRate, unsigned long framesPerBuffer, PaStreamCallback * streamCallback, void * userData ); |
| 函數參數 |
stream,[輸入]: 存放用於存放音頻流句柄的指針變量的內存指針。 存放音頻流句柄的變量類型為PaStream *。 |
| numInputChannels,[輸入]: 存放音頻流的音頻輸入聲道個數,為0表示不需要音頻輸入,為1表示單聲道,為2表示雙聲道立體聲。 |
|
| numOutputChannels,[輸入]: 存放音頻流的音頻輸出聲道個數,為0表示不需要音頻輸出,為1表示單聲道,為2表示雙聲道立體聲。 |
|
| sampleFormat,[輸入]: 存放音頻流的采樣位數和采樣格式。可以為(選一至一個): paFloat32宏(0x0001):用一個32位有符號浮點型存儲每個音頻數據塊。音頻數據范圍最高為1.0,最低為-1.0。 paInt32宏(0x0002):用一個32位有符號整型存儲每個音頻數據塊。音頻數據范圍最高為2147483647,最低為-2147483648。 paInt24宏(0x0004):用一個24位有符號整型存儲每個音頻數據塊。音頻數據范圍最高為8388607,最低為-8388608。 paInt16宏(0x0008):用一個16位有符號整型存儲每個音頻數據塊。音頻數據范圍最高為32767,最低為-32768。 paInt8宏(0x0010):用一個8位有符號整型存儲每個音頻數據塊。音頻數據范圍最高為127,最低為-128。 paUInt8宏(0x0020):用一個8位無符號整型存儲每個音頻數據塊。音頻數據范圍最高為255,最低為0。 paCustomFormat宏(0x10000): paNonInterleaved宏(0x80000000): |
|
| sampleRate,[輸入]: 存放音頻的采樣頻率,單位赫茲。一般可以為:8000、11025、22050、44100。 |
|
| framesPerBuffer,[輸入]: 存放當每次處理完音頻數據時,在音頻數據輸入輸出緩存中存放的每個聲道的音頻數據塊個數。 音頻數據輸入輸出緩存在音頻數據處理回調函數中使用,如果不采用回調函數方式,本參數無意義。 |
|
| streamCallback,[輸入]: 存放音頻數據處理回調函數的內存指針,表示采用回調函數方式進行音頻輸入數據采樣,或播放音頻數據。 音頻數據處理回調函數是程序自己定義的,且會一直在另外一個獨立的新線程中自動被調用執行。參考PaStreamCallback。 如果不采用回調函數方式,本參數就填NULL。
回調函數調用條件: 如果要打開的音頻流只需要音頻輸入,那么每次當音頻輸入數據采樣完畢,就會自動調用一次音頻數據處理回調函數。 如果要打開的音頻流只需要音頻輸出,那么每次當音頻輸出數據播放完畢,就會自動調用一次音頻數據處理回調函數。 如果要打開的音頻流需要音頻輸入和音頻輸出,那么每次當音頻輸入數據采樣完畢,就會自動調用一次音頻數據處理回調函數。因為采樣速度和播放速度是一樣的,所以就只調用一次音頻數據處理回調函數。 |
|
| userData,[輸入]: 存放音頻數據處理回調函數被調用時,傳遞給該函數的一個程序自定義參數。 |
|
| 返回值 |
paNoError枚舉(0x0000):成功。 其他:失敗,返回值就是錯誤碼,調用Pa_GetErrorText()函數查看錯誤碼對應的錯誤信息。 |
| 錯誤碼 |
EXXXX:錯誤碼說明。 EXXXX:錯誤碼說明。 …… |
| 線程安全 |
是 或 否 或 未知,表示此函數多線程調用是否會產生影響 |
| 原子操作 |
是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合 |
| 其他說明 |
打開音頻流句柄后,需要調用Pa_StartStream()函數,才能讓音頻流句柄開始處理音頻數據。 如果不采用回調函數方式,可以調用Pa_ReadStream()函數或Pa_WriteStream()函數處理音頻數據。 |
3.13 Pa_CloseStream(未完成)
| 函數名稱 |
Pa_CloseStream |
| 頭文件 |
#include "PortAudio.h" |
| 庫文件 |
#pragma comment(lib, "PortAudio_x86.lib或PortAudio_x64.lib") |
| 函數功能 |
關閉一個已經打開的音頻流句柄。 |
| 函數聲明 |
PaError Pa_CloseStream ( PaStream * stream ); |
| 函數參數 |
stream,[輸入]: 存放音頻流句柄。 |
| 返回值 |
paNoError枚舉(0x0000):成功。 其他:失敗,返回值就是錯誤碼,調用Pa_GetErrorText()函數查看錯誤碼對應的錯誤信息。 |
| 錯誤碼 |
EXXXX:錯誤碼說明。 EXXXX:錯誤碼說明。 …… |
| 線程安全 |
是 或 否 或 未知,表示此函數多線程調用是否會產生影響 |
| 原子操作 |
是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合 |
| 其他說明 |
…… …… |
3.14 PaStreamCallback(未完成)
| 函數名稱 |
PaStreamCallback |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 頭文件 |
#include "PortAudio.h" |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 庫文件 |
#pragma comment(lib, "PortAudio_x86.lib或PortAudio_x64.lib") |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 函數功能 |
音頻數據處理回調函數。 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 函數聲明 |
int PaStreamCallback ( const void * input, void * output, unsigned long frameCount, const PaStreamCallbackTimeInfo * timeInfo, PaStreamCallbackFlags statusFlags, void * userData ) |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 函數參數 |
input,[輸入]: 存放音頻數據輸入緩存的內存指針,也就是音頻設備采樣到的音頻數據。 音頻數據輸入緩存的長度計算方法(單位字節):聲道個數×每個聲道的音頻數據塊個數×采樣位數÷8。 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| output,[輸出]: 存放音頻數據輸出緩存的內存指針,也就是需要音頻設備播放的音頻數據。 音頻數據輸出緩存的長度計算方法(單位字節):聲道個數×每個聲道的音頻數據塊個數×采樣位數÷8 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| frameCount,[輸入]: 存放音頻數據輸入輸出緩存中存放的每個聲道的音頻數據塊個數。 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| timeInfo,[輸入|輸出|輸入&輸出]: 參數說明。 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| statusFlags,[輸入|輸出|輸入&輸出]: 參數說明。 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| userData,[輸入&輸出]: 存放程序自定義參數。 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 返回值 |
返回值1:返回值說明。 返回值2:返回值說明。 …… |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 錯誤碼 |
EXXXX:錯誤碼說明。 EXXXX:錯誤碼說明。 …… |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 線程安全 |
是 或 否 或 未知,表示此函數多線程調用是否會產生影響 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 原子操作 |
是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 其他說明 |
音頻數據輸入輸出緩存的內存格式:
就是這樣的。 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
3.15 Pa_StartStream(未完成)
| 函數名稱 |
Pa_StartStream |
| 頭文件 |
#include "PortAudio.h" |
| 庫文件 |
#pragma comment(lib, "PortAudio_x86.lib或PortAudio_x64.lib") |
| 函數功能 |
讓一個已經打開的音頻流句柄開始處理音頻數據。 |
| 函數聲明 |
類型 函數名 ( 類型 參數1, 類型 參數2, …… ); |
| 函數參數 |
參數1,[輸入|輸出|輸入&輸出]: 參數說明。 |
| 參數2,[輸入|輸出|輸入&輸出]: 參數說明。 |
|
| …… |
|
| 返回值 |
返回值1:返回值說明。 返回值2:返回值說明。 …… |
| 錯誤碼 |
EXXXX:錯誤碼說明。 EXXXX:錯誤碼說明。 …… |
| 線程安全 |
是 或 否 或 未知,表示此函數多線程調用是否會產生影響 |
| 原子操作 |
是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合 |
| 其他說明 |
停止處理音頻數據需要調用Pa_StopStream()函數。 |
3.16 Pa_StopStream(未完成)
| 函數名稱 |
Pa_StopStream |
| 頭文件 |
#include "PortAudio.h" |
| 庫文件 |
#pragma comment(lib, "PortAudio_x86.lib或PortAudio_x64.lib") |
| 函數功能 |
讓一個已經打開的音頻流句柄停止處理音頻數據。 |
| 函數聲明 |
類型 函數名 ( 類型 參數1, 類型 參數2, …… ); |
| 函數參數 |
參數1,[輸入|輸出|輸入&輸出]: 參數說明。 |
| 參數2,[輸入|輸出|輸入&輸出]: 參數說明。 |
|
| …… |
|
| 返回值 |
返回值1:返回值說明。 返回值2:返回值說明。 …… |
| 錯誤碼 |
EXXXX:錯誤碼說明。 EXXXX:錯誤碼說明。 …… |
| 線程安全 |
是 或 否 或 未知,表示此函數多線程調用是否會產生影響 |
| 原子操作 |
是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合 |
| 其他說明 |
…… …… |
3.17 Pa_ReadStream(未完成)
| 函數名稱 |
Pa_ReadStream |
| 頭文件 |
#include "PortAudio.h" |
| 庫文件 |
#pragma comment(lib, "PortAudio_x86.lib或PortAudio_x64.lib") |
| 函數功能 |
從一個已經打開並開始處理音頻數據的音頻流句柄,阻塞采集指定長度的音頻數據。 |
| 函數聲明 |
PaError Pa_ReadStream ( PaStream * stream, void * buffer, unsigned long frames ); |
| 函數參數 |
stream,[輸入]: 存放音頻流句柄。 |
| buffer,[輸出]: 存放音頻數據輸入緩存的內存指針,也就是音頻設備采樣到的音頻數據。 |
|
| frames,[輸入]: 存放音頻數據輸入緩存中存放的每個聲道的音頻數據塊個數。 音頻數據輸入緩存的長度計算方法(單位字節):聲道個數×每個聲道的音頻數據塊個數×采樣位數÷8。 |
|
| 返回值 |
paNoError枚舉(0x0000):成功。 其他:失敗,返回值就是錯誤碼,調用Pa_GetErrorText()函數查看錯誤碼對應的錯誤信息。 |
| 錯誤碼 |
EXXXX:錯誤碼說明。 EXXXX:錯誤碼說明。 …… |
| 線程安全 |
是 或 否 或 未知,表示此函數多線程調用是否會產生影響 |
| 原子操作 |
是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合 |
| 其他說明 |
…… …… |
3.18 Pa_WriteStream(未完成)
| 函數名稱 |
Pa_WriteStream |
| 頭文件 |
#include "PortAudio.h" |
| 庫文件 |
#pragma comment(lib, "PortAudio_x86.lib或PortAudio_x64.lib") |
| 函數功能 |
從一個已經打開並開始處理音頻數據的音頻流句柄,阻塞播放指定長度的音頻數據。 |
| 函數聲明 |
PaError Pa_WriteStream ( PaStream * stream, const void * buffer, unsigned long frames ); |
| 函數參數 |
stream,[輸入]: 存放音頻流句柄。 |
| buffer,[輸入]: 存放音頻數據輸出緩存的內存指針,也就是音頻設備采樣到的音頻數據。 |
|
| frames,[輸入]: 存放音頻數據輸出緩存中存放的每個聲道的音頻數據塊個數。 音頻數據輸出緩存的長度計算方法(單位字節):聲道個數×每個聲道的音頻數據塊個數×采樣位數÷8。 |
|
| 返回值 |
paNoError枚舉(0x0000):成功。 其他:失敗,返回值就是錯誤碼,調用Pa_GetErrorText()函數查看錯誤碼對應的錯誤信息。 |
| 錯誤碼 |
EXXXX:錯誤碼說明。 EXXXX:錯誤碼說明。 …… |
| 線程安全 |
是 或 否 或 未知,表示此函數多線程調用是否會產生影響 |
| 原子操作 |
是 或 否 或 未知,表示此函數是否是單一操作,不是多個步驟的組合 |
| 其他說明 |
…… …… |
4 結構體庫
4.1 結構體模板(未完成)
| 結構體名稱 |
xxx |
| 頭文件 |
#include "PortAudio.h" |
| 結構體稱呼 |
結構體的中文稱呼。 |
| 結構體說明 |
結構體主要用途說明。 |
| 相關函數 |
Func1()、Func2()、Func3()… |
| 結構體聲明 |
struct xxx { 類型 成員變量1; 類型 成員變量2; …… }; |
| 成員變量 |
成員變量1: 成員變量說明。 |
| 成員變量2: 成員變量說明。 |
|
| …… |
|
| 其他說明 |
…… …… |
4.2 PaDeviceInfo(未完成)
| 結構體名稱 |
PaDeviceInfo |
| 頭文件 |
#include <xxx.h> #include <xxx.h> |
| 結構體說明 |
音頻設備信息結構體,用於存放音頻設備的相關信息。 |
| 相關函數 |
Pa_GetDeviceInfo()、Func2()、Func3()… |
| 結構體聲明 |
typedef struct PaDeviceInfo { int structVersion; const char * name; PaHostApiIndex hostApi; /**< note this is a host API index, not a type id*/
int maxInputChannels; int maxOutputChannels;
/** Default latency values for interactive performance. */ PaTime defaultLowInputLatency; PaTime defaultLowOutputLatency; /** Default latency values for robust non-interactive applications (eg. playing sound files). */ PaTime defaultHighInputLatency; PaTime defaultHighOutputLatency;
double defaultSampleRate; } PaDeviceInfo; |
| 成員變量 |
structVersion: 存放本結構體的版本號,一直為2。 |
| name: 存放音頻設備的名稱字符串的內存指針,例如: "Microsoft 聲音映射器 - Input", "Speakers (Realtek HD Audio output)"。 |
|
| hostApi: note this is a host API index, not a type id. |
|
| maxInputChannels: 存放音頻設備的最大音頻輸入聲道個數,為0表示本設備不支持音頻輸入。 |
|
| maxOutputChannels: 存放音頻設備的最大音頻輸出聲道個數,為0表示本設備不支持音頻輸出。 |
|
| defaultLowInputLatency: Default latency values for interactive performance. |
|
| defaultLowOutputLatency: 成員變量說明。 |
|
| defaultHighInputLatency: Default latency values for robust non-interactive applications (eg. playing sound files). |
|
| defaultHighOutputLatency: 成員變量說明。 |
|
| defaultSampleRate: 存放音頻設備的默認采樣頻率,單位Hz赫茲。 |
|
| 其他說明 |
|
4.3 PaStreamParameters(未完成)
| 結構體名稱 |
PaStreamParameters |
| 頭文件 |
#include "PortAudio.h" |
| 結構體說明 |
結構體主要用途說明。 |
| 相關函數 |
Pa_OpenStream()、Func2()、Func3()… |
| 結構體聲明 |
typedef struct PaStreamParameters { /** A valid device index in the range 0 to (Pa_GetDeviceCount()-1) specifying the device to be used or the special constant paUseHostApiSpecificDeviceSpecification which indicates that the actual device(s) to use are specified in hostApiSpecificStreamInfo. This field must not be set to paNoDevice. */ PaDeviceIndex device;
/** The number of channels of sound to be delivered to the stream callback or accessed by Pa_ReadStream() or Pa_WriteStream(). It can range from 1 to the value of maxInputChannels in the PaDeviceInfo record for the device specified by the device parameter. */ int channelCount;
/** The sample format of the buffer provided to the stream callback, a_ReadStream() or Pa_WriteStream(). It may be any of the formats described by the PaSampleFormat enumeration. */ PaSampleFormat sampleFormat;
/** The desired latency in seconds. Where practical, implementations should configure their latency based on these parameters, otherwise they may choose the closest viable latency instead. Unless the suggested latency is greater than the absolute upper limit for the device implementations should round the suggestedLatency up to the next practical value - ie to provide an equal or higher latency than suggestedLatency wherever possible. Actual latency values for an open stream may be retrieved using the inputLatency and outputLatency fields of the PaStreamInfo structure returned by Pa_GetStreamInfo(). @see default*Latency in PaDeviceInfo, *Latency in PaStreamInfo */ PaTime suggestedLatency;
/** An optional pointer to a host api specific data structure containing additional information for device setup and/or stream processing. hostApiSpecificStreamInfo is never required for correct operation, if not used it should be set to NULL. */ void *hostApiSpecificStreamInfo;
} PaStreamParameters; |
| 成員變量 |
device: 成員變量說明。 |
| channelCount: 成員變量說明。 |
|
| sampleFormat: 成員變量說明。 |
|
| suggestedLatency: 成員變量說明。 |
|
| hostApiSpecificStreamInfo: 成員變量說明。 |
|
| 其他說明 |
…… …… |
