• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
record/playback from RAM
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

record/playback from RAM


  • Subject: record/playback from RAM
  • From: Marcin Rakowski <email@hidden>
  • Date: Mon, 11 Jul 2016 14:50:20 +0000

Hi everybody,

I’m working on low-latency record/playback OSX app. I want to be able to start playback immediately after I stop recording. I gather that writing to hdd is high latency and decided to use fixed length buffers that will store recorded data in the memory and never write to hdd while recording. I’m not sure if the above reasoning is correct.

I'm modifying the Play Through example from “Learning Core Audio” book. I’ve created a static buffer while setting up the input unit. It will receive samples that are also passed to CARingBuffer

Static buffer allocation:

    UInt32 propSizeStaticBuffer = offsetof(AudioBufferList, mBuffers[0]) + (sizeof(AudioBuffer) * player->streamFormat.mChannelsPerFrame);

    player->staticBuffer = (AudioBufferList *)malloc(propSizeStaticBuffer);

    player->staticBuffer->mNumberBuffers = player->streamFormat.mChannelsPerFrame;

     UInt32 staticBufferSizeBytes = 512000 * sizeof(Float32);

    for(UInt32 i = 0; i < player->staticBuffer->mNumberBuffers; i++)

    {

        player->staticBuffer->mBuffers[i].mNumberChannels = 1;

        player->staticBuffer->mBuffers[i].mDataByteSize = staticBufferSizeBytes;

        player->staticBuffer->mBuffers[i].mData = malloc(staticBufferSizeBytes);

    }


In the InputRenderCallback I copy the samples to the buffer:


if(player->staticBufferNumberOfFrames*4 <= 512000 * 4 - 512 )

        {

        

        UInt32 offset = player->staticBufferNumberOfFrames * sizeof(Float32);

        printf("Offset %u\n", player->staticBufferNumberOfFrames * sizeof(Float32));

        

        Float32 *bufferL = (Float32*)player->staticBuffer->mBuffers[0].mData;

        bufferL = bufferL + offset;

        Float32 *bufferR = (Float32*)player->staticBuffer->mBuffers[1].mData;

        bufferR = bufferR + offset;

            printf("Number of frames to copy: %u\n", inNumberFrames);

        if(offset < 512000)

        {

            printf("**Copying into the static buffer.\n");

        memcpy(bufferL, &player->inputBuffer->mBuffers[0], inNumberFrames*sizeof(Float32));

        memcpy(bufferR, &player->inputBuffer->mBuffers[1], inNumberFrames*sizeof(Float32));

        

        player->staticBufferNumberOfFrames += inNumberFrames;

        }

            else

            {

                printf("***********Reached offset 512000: %u************\n", offset);

                player->staticBufferNumberOfFrames = 0;

                playFromMemory = YES;

            }

        

        printf("Number of frames: %u\n", player->staticBufferNumberOfFrames);

        }

 

Once the buffer is full, in the GraphRender function I switch the sample source from CARingBuffer to the static buffer:


 if(playFromMemory != YES)

    {

   

    outputProcErr = player->ringBuffer->Fetch(ioData,

                                              inNumberFrames,

                                              inTimeStamp->mSampleTime + player->inToOutSampleTimeOffset);

    }

    else //play out the memorised sequence

    {

            stopInputRendering = YES;

            printf("Static Buffer Number of Frames For Output: %u\n", player->staticBufferNumberOfFrames);

            UInt32 offset = player->staticBufferNumberOfFrames * sizeof(Float32);

            printf("Output Offset %u\n", player->staticBufferNumberOfFrames * sizeof(Float32));

            

            Float32 *bufferL = (Float32*)player->staticBuffer->mBuffers[0].mData;

            bufferL = bufferL + offset;

            

            Float32 *bufferR = (Float32*)player->staticBuffer->mBuffers[1].mData;

            bufferR = bufferR + offset;

            

            printf("Number of frames on output: %u\n", inNumberFrames);

            if(offset < 512000)

            {

                printf("**Copying out of the static buffer.***\n");

                memcpy(&ioData->mBuffers[0], bufferL, inNumberFrames*sizeof(Float32));

                memcpy(&ioData->mBuffers[1], bufferR, inNumberFrames*sizeof(Float32));

            

            }


        

        player->staticBufferNumberOfFrames += inNumberFrames;

    }

However, after the buffers are switched, I can only hear throughput from the input for the duration of the staticBuffer playback, once it runs out input cuts out. I don’t understand why the samples that were being stored in the buffer are not played back. I also don’t understand why I can hear throughput after I’ve stopped filling CARingBuffer after I switch buffers in the GraphRenderProc.

Thanks for your time.

Marcin



 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

  • Prev by Date: Re: AudioUnitRender results in kAudioUnitErr_TooManyFramesToProcess
  • Next by Date: Re: Major AUMIDISynth memory leak?
  • Previous by thread: Re: Major AUMIDISynth memory leak?
  • Next by thread: kAppleSoftwareAudioCodecManufacturer not on Mac AudioToolbox SDK 10.11
  • Index(es):
    • Date
    • Thread