TPCircularBuffer icon indicating copy to clipboard operation
TPCircularBuffer copied to clipboard

TPCircularBuffer cause noise

Open orklann opened this issue 6 years ago • 1 comments

I am playing raw PCM data over Bluetooth, and I do a lost of tests, and finally found that when TPCircularBuffer produce bytes, the noise happen, here is the two part of my code (One get PCM data from Bluetooth device, one use Portaudio to render the PCM).

Produce bytes ->:

- (void)a2dpSink:(A2DPSink *)sink channel:(IOBluetoothL2CAPChannel *)channel rawRTPdataReceived:(NSData *)data
{
    NSData *mediaPayload = getMediaPayloadInRTP(data);
    getSBCFramesInMediaPayload(mediaPayload);
    recordCount++;

    if (recordCount == 50) {
        long index = 0;
        uint16 i;
        long size = 0;
        for (i = 0; i < [sbcFrames count]; i++) {
            size = [[sbcFrames objectAtIndex:i] length];
            memcpy((unsigned char*)buf + index, (unsigned char*)[[sbcFrames objectAtIndex:i] bytes], size);
            index += size;
        }

        [sbcFrames removeAllObjects];

        // Start decode
        int pcmBytes = 0;
        decodeSBCFramesBuffer(buf, (int)index, pcm, &pcmBytes);
        
        TPCircularBufferProduceBytes(&paData.buffer, pcm, pcmBytes);
      
        if (!played) {
            framesPerBuffer = pcmBytes / 4;
            playPortAudio();
            played = YES;
        }

        if (!Pa_IsStreamActive(stream)) {
            e = Pa_StartStream(stream);
            if( e != paNoError ) {
                NSLog(@"start stream error!");
            } else {
                NSLog(@"start stream OK!");
            }
        }
        recordCount = 0;
    }
}

Consume bytes ->

static int patestCallback( const void *inputBuffer, void *outputBuffer,
                          unsigned long framesPerBuffer,
                          const PaStreamCallbackTimeInfo* timeInfo,
                          PaStreamCallbackFlags statusFlags,
                          void *userData )
{
    paTestData *data = (paTestData*)userData;
    short *out = (short*)outputBuffer;
    unsigned long i, j;

    (void) timeInfo; /* Prevent unused variable warnings. */
    (void) statusFlags;
    (void) inputBuffer;

    uint32_t availableBytes = 0;
    unsigned char *b = TPCircularBufferTail(&data->buffer, &availableBytes);

    uint32_t frames = availableBytes / 2 / 2;
    if (b == NULL) return paContinue;
    uint32_t availableFrames = (uint32_t) MIN(frames, framesPerBuffer);
    uint32_t index = 0;
    for(i = 0; i < availableFrames; i++){
        for( j = 0; j < CHANNEL_COUNT; ++j ){
            unsigned char high = b[index];
            unsigned char low =  b[index+1];
            short s = low + (high << 8);
            *out++ = s;
            index += 2;
        }
    }
    TPCircularBufferConsume(&data->buffer, (uint32_t)index);
    return paContinue;
}

If I increase the recordCount to like 200

 if (recordCount == 50)

then the noise occur in a long period.

So I think the noise is just happen when TPCircularBufferProduceBytes(&paData.buffer, pcm, pcmBytes); is called, any idea? I am testing this issue for a few days.

orklann avatar Oct 03 '18 06:10 orklann

I think I’m experimenting the same thing

pablogeek avatar Apr 07 '19 12:04 pablogeek