[Error] Waiting data to play cause strange sound

edited May 2013

Hi,

I have used playthroughchannel source to make a simple flow Record - Transfer Via Network - Play
Right after I get audio data from Record Callback, I transfer it via network and then after I get back I put to circular buffer to play it.

Here is piece of code:

Record & Transfer To Network:

static void inputCallback(id receiver,
AEAudioController audioController,
void *source,
const AudioTimeStamp *time,
UInt32 frames,
AudioBufferList *audio){
myPlaythroughChannel
THIS = receiver;

//encode & serialize data 
unsigned char* encode_data = (unsigned char*) malloc(sizeof(encode_data));
int* encode_size = (int*) malloc(sizeof(encode_size));
[THIS->_serializer serialize:audio time:time output:&encode_data sizeInByte:encode_size];
//send vai network
[THIS->_serverController send:encode_data sizeInByte:*encode_size];

free(encode_size);
free(encode_data);

....

and then when I receive data from network I put data to buffer (dont use AudioTimeStamp at this moment)

AudioBufferList* decode_audio = (AudioBufferList*) malloc(sizeof(decode_audio));
AudioTimeStamp* decode_ts = (AudioTimeStamp*) malloc(sizeof(decode_ts));
[self->_serializer deserialize:(unsigned char*)encoded_data size:size audio:decode_audio timestamp:decode_ts];
if(true == true){
    TPCircularBufferCopyAudioBufferList(&_buffer, decode_audio , NULL, kTPCircularBufferCopyAll, NULL);
}

And copy into audio to play it:

static OSStatus renderCallback(id channel,
AEAudioController audioController,
const AudioTimeStamp *time,
UInt32 frames,
AudioBufferList *audio){
myPlaythroughChannel
THIS = channel;
while(1){
//discard incompatible format
AudioBufferList nextBuffer = TPCircularBufferNextBufferList(&THIS->_buffer, NULL);
if( !nextBuffer){
//usleep(100
1000); // ******* if sleep here, I would hear what I talk again *********
break;
}
if( nextBuffer->mNumberBuffers== audio->mNumberBuffers) break;
TPCircularBufferConsumeNextBufferList(&THIS->_buffer);
}

        AudioStreamBasicDescription audioDescription = [THIS audioDescription];
    UInt32 fillCount = TPCircularBufferPeek(&THIS->_buffer, NULL,&audioDescription);
    if(fillCount >= frames + THIS->_bufferMaxLatencyInFrames){
        UInt32 skip = fillCount - frames;

        TPCircularBufferDequeueBufferListFrames(&THIS->_buffer, &skip, NULL, NULL, &audioDescription);
    }
    //deque data to audio to play
   TPCircularBufferDequeueBufferListFrames(&THIS->_buffer,
                                            &frames,
                                            audio,
                                            NULL,
                                            &audioDescription); 
return noErr;

}

There are two problems:

  1. if I sleep to wait until I get audio data (which is transfered from network) then I would hear back from what I talk .
  2. I don't know how to wait until I get next buffer. I have assumed that function: TPCircularBufferDequeueBufferListFrames would deque nothing incase buffer is empty.

I think that I need to check if there has any data to dequeue before calling TPCircularBufferDequeueBufferListFames function, for ex:

if(TPCircularBufferAvailable( &THIS->_buffer) == true){
//deque data to audio to play
TPCircularBufferDequeueBufferListFrames(&THIS->_buffer,
&frames,
audio,
NULL,
&audioDescription);
}

But I don't find out any similar function or how to make this function.

Thanks.

Sign In or Register to comment.