![](/img/trans.png)
[英]How is the data in TX/RX buffer of NIC is transferred to dpdk ring buffer rather than kernel ring buffer?
[英]Core Audio Ring Buffer Data comes out blank
我正在編寫“學習核心音頻:Mac 和 iOS 音頻編程實踐指南”一書中的演示。 第 8 章展示了如何設置一個簡單的 AudioUnit 圖形以從 AUHAL 輸入單元播放到 output 單元。 此設置實際上並未連接音頻單元; 相反,兩個單元都使用回調並通過 CARingBuffer 的實例傳遞音頻數據。 我正在為 MacOS 10.15.6 編寫代碼,並直接使用來自發布者的代碼。 這是它如何工作的圖片:
代碼構建並運行,但我沒有音頻。 請注意,稍后,在引入語音合成單元后,我確實可以播放,所以我知道基礎工作正常。
InputRenderProc向 AUHAL 單元請求輸入並將其存儲在環形緩沖區中。
MyAUGraphPlayer *player = (MyAUGraphPlayer*) inRefCon;
// have we ever logged input timing? (for offset calculation)
if (player->firstInputSampleTime < 0.0) {
player->firstInputSampleTime = inTimeStamp->mSampleTime;
if ((player->firstOutputSampleTime > -1.0) &&
(player->inToOutSampleTimeOffset < 0.0)) {
player->inToOutSampleTimeOffset = player->firstInputSampleTime - player->firstOutputSampleTime;
}
}
// render into our buffer
OSStatus inputProcErr = noErr;
inputProcErr = AudioUnitRender(player->inputUnit,
ioActionFlags,
inTimeStamp,
inBusNumber,
inNumberFrames,
player->inputBuffer);
if (! inputProcErr) {
inputProcErr = player->ringBuffer->Store(player->inputBuffer,
inNumberFrames,
inTimeStamp->mSampleTime);
UInt32 sz = sizeof(player->inputBuffer);
printf ("stored %d frames at time %f (%d bytes)\n", inNumberFrames, inTimeStamp->mSampleTime, sz);
for (int i = 0; i < player->inputBuffer->mNumberBuffers; i++ ){
//printf("stored audio string[%d]: %s\n", i, player->inputBuffer->mBuffers[i].mData);
}
}
如果我取消注釋printf
語句,我會看到正在存儲的音頻數據。
stored audio string[1]: #P'\274a\353\273\336^\274x\205 \2741\330B\2747'\274\371\361U\274\346\274\274}\212C\274\334\365%\274\261\367\273\340\307/\274E
stored 512 frames at time 134610.000000 (8 bytes)
但是,當我像這樣從 GraphRenderCallback 中的環形緩沖區中獲取時......
MyAUGraphPlayer *player = (MyAUGraphPlayer*) inRefCon;
// have we ever logged output timing? (for offset calculation)
if (player->firstOutputSampleTime < 0.0) {
player->firstOutputSampleTime = inTimeStamp->mSampleTime;
if ((player->firstInputSampleTime > -1.0) &&
(player->inToOutSampleTimeOffset < 0.0)) {
player->inToOutSampleTimeOffset = player->firstInputSampleTime - player->firstOutputSampleTime;
}
}
// copy samples out of ring buffer
OSStatus outputProcErr = noErr;
// new CARingBuffer doesn't take bool 4th arg
outputProcErr = player->ringBuffer->Fetch(ioData,
inNumberFrames,
inTimeStamp->mSampleTime + player->inToOutSampleTimeOffset);
我什么也沒得到(我知道我不能指望正確的空終止字符串 output,但我想我會看到一些東西)。
fetched 512 frames at time 160776.000000
fetched audio string[0, size 2048]: xx
fetched audio string[1, size 2048]: xx
fetched 512 frames at time 161288.000000
fetched audio string[0, size 2048]: xx
fetched audio string[1, size 2048]: xx
這不是權限問題; 我還有其他可以獲取麥克風輸入的非 AudioUnit 代碼。 此外,我創建了一個 plist,讓這個應用程序每次都提示訪問麥克風,所以我知道這是有效的。 我不明白為什么數據會進入這個環形緩沖區,但永遠不會出來。
這些天你需要聲明你想使用麥克風,提供一個解釋字符串。 2012 年 Learning Core Audio 發布時,情況並非如此。
簡而言之,您現在需要:
NSMicrophoneUsageDescription
字符串添加到您的Info.plist
您使用的示例代碼是一個命令行工具,因此在 Xcode 中添加Info.plist
並不像使用 a.app package 那樣簡單。 此外,如果您從 Xcode 運行該代碼似乎也不起作用。 就我而言,它必須為 Terminal.app 運行。 這可能是因為我的終端具有麥克風權限(可在System Preferences > Security & Privacy > Microphone
中查看)。 您可以並且可能應該通過在AVCaptureDevice
上使用requestAccessForMediaType
來明確請求用戶(在這種情況下是您自己!)的麥克風訪問權限。 沒錯, Core Audio
教程中的AVFoundation
代碼,世界將何去何從。
此答案中有關上述步驟的更多詳細信息
ps 我認為認為捕獲零而不是返回錯誤是個好主意的人可能與發明返回 HTTP 200 並在正文中帶有錯誤代碼的人是好朋友。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.