4
我以編程方式生成音頻。我聽到我的緩衝區之間的沉默的差距。當我將手機掛在示波器上時,我發現每個緩衝區的前幾個樣本都丟失了,而且它們的位置是靜音。這種沉默的長度從幾乎沒有變化到20毫秒。AudioQueue吃了我的緩衝區(前15毫秒)
我的第一個想法是,我原來的回調函數需要太多的時間。我用盡可能最短的一個替換它 - 它一遍又一遍地重新排列相同的緩衝區。我觀察到同樣的行爲。
AudioQueueRef aq;
AudioQueueBufferRef aq_buffer;
AudioStreamBasicDescription asbd;
void aq_callback (void *aqData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer) {
OSStatus s = AudioQueueEnqueueBuffer(aq, aq_buffer, 0, NULL);
}
void aq_init(void) {
OSStatus s;
asbd.mSampleRate = AUDIO_SAMPLES_PER_S;
asbd.mFormatID = kAudioFormatLinearPCM;
asbd.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
asbd.mBytesPerPacket = 1;
asbd.mFramesPerPacket = 1;
asbd.mBytesPerFrame = 1;
asbd.mChannelsPerFrame = 1;
asbd.mBitsPerChannel = 8;
asbd.mReserved = 0;
int PPM_PACKETS_PER_SECOND = 50;
// one buffer is as long as one PPM frame
int BUFFER_SIZE_BYTES = asbd.mSampleRate/PPM_PACKETS_PER_SECOND*asbd.mBytesPerFrame;
s = AudioQueueNewOutput(&asbd, aq_callback, NULL, CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &aq);
s = AudioQueueAllocateBuffer(aq, BUFFER_SIZE_BYTES, &aq_buffer);
// put samples in the buffer
buffer_data(my_data, aq_buffer);
s = AudioQueueStart(aq, NULL);
s = AudioQueueEnqueueBuffer(aq, aq_buffer, 0, NULL);
}
感謝您指出我在初始化排隊超過一個緩衝區() - 這個重要的事實已經躲避我。實施這個建議以及回調的改變改善了我的情況,但是沒有解決它。我仍然錯過了一些緩衝區的前幾個ms。現在這種情況只發生在7個或8個數據包上,而我錯過了更少的樣本,但它仍然很明顯。 – iter 2010-04-02 06:15:14
在這個簡單的例子中,它似乎並不重要,但以防萬一:有超過2個緩衝區有幫助(如果你還沒有嘗試過)?另外,你確定'buffer_data()是用一個完整的1/50秒的數據包填充一個緩衝區嗎? AUDIO_SAMPLES_PER_S的價值是什麼? – 2010-04-02 06:41:57
感謝您的持續支持。如果我使用3個緩衝區而不是2個,我會停止丟失樣本。這看起來很神奇......我不舒服的那種魔法,因爲我無法解釋它。我想知道是否有某種雙緩衝正在進行。我之前曾嘗試使用我的緩衝區大小,使它們長達1秒('PPM_PACKETS_PER_SECOND = 1')。有2長緩衝區,我仍然失去樣本。使用3個短緩衝區,我可以找回所有放入的文件。 – iter 2010-04-02 07:27:17