2

http://atastypixel.com/blog/a-simple-fast-circular-buffer-implementation-for-audio-processing/comment-page-からMichaelTysonに提供された、多数のサンプルをaaTPCircularBufferに書き込もうとしています。1 /#comment-4988

これらの記録されたサンプルをリアルタイムで再生することに成功しました。モニターのようなもの。

ただし、後で再生できるようにサンプルをTPCircularBufferに保持したいので、rio->recordingとrio->playingの2つのフラグを実装しました。私の考えは、ボタンを使用して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;
}
4

1 に答える 1

2

私はこの質問に自分で答えます。基本的に、ごみの音は、TPCircularBufferが音を保持するのに十分な大きさではなかったことが原因でした。バッファに有効なオーディオデータが含まれなくなったため、再生コールバックは単にゴミを再生していました。

基本的に、TPCircularBufferを大きくすると、私の問題は解決しました。(えっ!)

橋脚。

于 2012-11-02T06:57:51.077 に答える