2012-10-31 3 views
2

내가 A A TPCircularBuffer에 샘플의 무리를 쓰기 위해 노력하고있어, 실시간으로이 기록 된 샘플을 재생에 http://atastypixel.com/blog/a-simple-fast-circular-buffer-implementation-for-audio-processing/comment-page-1/#comment-4988아이폰 OS 코어 오디오 녹음 버퍼는 문제

내가 성공 오전에 의해 마이클 타이슨을 제공했다. 모니터 같은 것.

그러나 나중에 샘플을 TPCircularBuffer에 저장하여 나중에 재생하려고하므로 리오 -> 녹음 및 리오 - 재생 중 2 개의 플래그를 구현했습니다. 제 아이디어는 버튼을 사용하여 YES로 설정하려면 녹음을 활성화하는 것입니다. 잠시 동안 기록한 다음 플래그를 아니오로 설정하여 기록을 중지하십시오. 이론적으로 TPCircularBuffer는 내 오디오 정보를 저장합니다.

그러나 재생 콜백에서 rio-> playing을 활성화하면 녹음 된 내용과 비슷한 소리가 들리지 않습니다.

버퍼를 올바르게 사용하고 있습니까? 아니면 보통 다른 방법으로 수행됩니까?

감사합니다.

부두.

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; 
} 

답변

2

나는이 질문에 스스로 대답 할 것이다. 기본적으로 쓰레기 소리는 TPCircularBuffer가 소리를 유지하기에 충분히 크지 않기 때문입니다. 버퍼에 유효한 오디오 데이터가 더 이상 포함되어 있지 않으므로 재생 콜백은 단순히 쓰레기를 재생하는 것입니다.

기본적으로 TPCircularBuffer를 크게 만들면 문제가 해결됩니다. (duh!)

부두.