core-audio - iOS 核心音频录制缓冲区问题

标签 core-audio recording circular-buffer

我正在尝试将一堆样本写入 TPCircularBuffer,由 Michael Tyson 提供 http://atastypixel.com/blog/a-simple-fast-circular-buffer-implementation-for-audio-processing/comment-page-1/#comment-4988

我成功地实时播放了这些录制的样本。像显示器之类的东西。

但是,我希望将样本保留在 TPCircularBuffer 中以供以后播放,因此我实现了 2 个标志,rio->recording 和 rio->playing。 我的想法是,我将使用按钮将 rio->recording 激活为 YES。记录一段时间,然后通过将标志设置为NO来停止记录。理论上,TPCircularBuffer 会保存我的音频信息。

但是,当我在播放回调中将 rio->playing 激活为 YES 时,我只是听到一些与我录制的声音完全不同的抖动声音。

我是否正确使用了缓冲区?或者这通常是用另一种方式完成的?

谢谢。

码头。

static OSStatus recordingCallback(void *inRefCon, 
                              AudioUnitRenderActionFlags *ioActionFlags, 
                              const AudioTimeStamp *inTimeStamp, 
                              UInt32 inBusNumber, 
                              UInt32 inNumberFrames, 
                              AudioBufferList *ioData) {

RIO *rio = (RIO*)inRefCon;
AudioUnit rioUnit = rio->theAudioUnit;
//ExtAudioFileRef eaf = rio->outEAF;
AudioBufferList abl = rio->audioBufferList;

SInt32 samples[NUMBER_OF_SAMPLES]; // A large enough size to not have to worry about buffer overrun
abl.mNumberBuffers = 1;
abl.mBuffers[0].mData = &samples;
abl.mBuffers[0].mNumberChannels = 1;
abl.mBuffers[0].mDataByteSize = inNumberFrames  * sizeof(SInt16);

OSStatus result;
result = AudioUnitRender(rioUnit, 
                         ioActionFlags, 
                         inTimeStamp,
                         inBusNumber, 
                         inNumberFrames, 
                         &abl);

if (noErr != result) { NSLog(@"Obtain recorded samples error"); }

// React to a recording flag, if recording, save the abl into own buffer, else ignore
if (rio->recording)
{   
    TPCircularBufferProduceBytes(&rio->buffer, abl.mBuffers[0].mData, inNumberFrames  * sizeof(SInt16));
    NSLog(@"Recording!"); 
}
else
{
    NSLog(@"Not Recording!");
}
// once stop recording save the circular buffer to a temp circular buffer

    return noErr;
}

static OSStatus playbackCallback(void *inRefCon, 
                             AudioUnitRenderActionFlags *ioActionFlags, 
                             const AudioTimeStamp *inTimeStamp, 
                             UInt32 inBusNumber, 
                             UInt32 inNumberFrames, 
                             AudioBufferList *ioData) {    

RIO *rio = (RIO*)inRefCon;

int bytesToCopy = ioData->mBuffers[0].mDataByteSize;
SInt16 *targetBuffer = (SInt16*)ioData->mBuffers[0].mData;

// Pull audio from playthrough buffer
int32_t availableBytes;

if (rio->playing)
{
    SInt16 * tempbuffer = TPCircularBufferTail(&rio->buffer, &availableBytes);
    memcpy(targetBuffer, tempbuffer, MIN(bytesToCopy, availableBytes));
    TPCircularBufferConsume(&rio->buffer, MIN(bytesToCopy, availableBytes));
    NSLog(@"Playing!");
}
else
{
   NSLog(@"Playing silence!");

   for (int i = 0 ; i < ioData->mNumberBuffers; i++){
    //get the buffer to be filled
    AudioBuffer buffer = ioData->mBuffers[i];
    UInt32 *frameBuffer = buffer.mData;

    //loop through the buffer and fill the frames
       for (int j = 0; j < inNumberFrames; j++){
           frameBuffer[j] = 0;
       }
   }
}

   return noErr;
}

最佳答案

这个问题我自己来回答。 基本上,垃圾声音是由于 TPCircularBuffer 不够大来容纳声音造成的。播放回调只是播放垃圾,因为缓冲区不再包含有效的音频数据。

基本上,使 TPCircularBuffer 变大解决了我的问题。 (呃!)

码头。

关于core-audio - iOS 核心音频录制缓冲区问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13153511/

相关文章:

c# - 我的简单循环缓冲区无法正常工作

ios - 音频单元录音 : increased volume of buffers

iphone - AudioQueue不输出任何声音

iphone - 录制iPhone应用程序视频(无需模拟器)

c - 使用PACKET_MMAP和PACKET_TX_RING发送数据比 “normal”慢(无)

java - 什么数据结构可以用于循环操作?

ios - 如何在 iOS 上增加 MIDI 合成器音量/增益而不失真?

ios - 如何将代码回调同步到音轨的播放时间?

Android Studio 无法以 1080p 录制屏幕

windows - 是否可以录制声卡上播放的声音?