欢迎来到虫虫下载站 | 资源下载 资源专辑 关于我们
虫虫下载站

pa_mac_core.c

基于sip协议的网络电话源码
C
第 1 页 / 共 5 页
字号:
          if( !data )          {             result = paInsufficientMemory;             goto error;          }          /* now we can initialize the ring buffer */          /*assert( 0 ==*/            RingBuffer_Init( &stream->inputRingBuffer,                             ringSize*szfl, data ) /*)*/;          /* advance the read point a little, so we are reading from the             middle of the buffer */          if( stream->outputUnit )             RingBuffer_AdvanceWriteIndex( &stream->inputRingBuffer, ringSize*szfl / RING_BUFFER_ADVANCE_DENOMINATOR );       }    }    /* -- initialize Blio Buffer Processors -- */    if( !streamCallback )    {       long ringSize;       ringSize = computeRingBufferSize( inputParameters,                                         outputParameters,                                         stream->inputFramesPerBuffer,                                         stream->outputFramesPerBuffer,                                         sampleRate );       result = initializeBlioRingBuffers( &stream->blio,              inputParameters?inputParameters->sampleFormat:0 ,              outputParameters?outputParameters->sampleFormat:0 ,              MAX(stream->inputFramesPerBuffer,stream->outputFramesPerBuffer),              ringSize,              inputParameters?inputChannelCount:0 ,              outputParameters?outputChannelCount:0 ) ;       if( result != paNoError )          goto error;    }    /* -- initialize Buffer Processor -- */    {       unsigned long maxHostFrames = stream->inputFramesPerBuffer;       if( stream->outputFramesPerBuffer > maxHostFrames )          maxHostFrames = stream->outputFramesPerBuffer;       result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor,                 inputChannelCount, inputSampleFormat,                 hostInputSampleFormat,                 outputChannelCount, outputSampleFormat,                 hostOutputSampleFormat,                 sampleRate,                 streamFlags,                 framesPerBuffer,                 /* If sample rate conversion takes place, the buffer size                    will not be known. */                 maxHostFrames,                 stream->inputSRConverter                              ? paUtilUnknownHostBufferSize                              : paUtilBoundedHostBufferSize,                 streamCallback ? streamCallback : BlioCallback,                 streamCallback ? userData : &stream->blio );       if( result != paNoError )           goto error;    }    stream->bufferProcessorIsInitialized = TRUE;    /*        IMPLEMENT ME: initialise the following fields with estimated or actual        values.        I think this is okay the way it is br 12/1/05        maybe need to change input latency estimate if IO devs differ    */    stream->streamRepresentation.streamInfo.inputLatency =            PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor)/sampleRate;    stream->streamRepresentation.streamInfo.outputLatency =            PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor)/sampleRate;    stream->streamRepresentation.streamInfo.sampleRate = sampleRate;    stream->sampleRate  = sampleRate;    stream->outDeviceSampleRate = 0;    if( stream->outputUnit ) {       Float64 rate;       UInt32 size = sizeof( rate );       result = ERR( AudioDeviceGetProperty( stream->outputDevice,                                    0,                                    FALSE,                                    kAudioDevicePropertyNominalSampleRate,                                    &size, &rate ) );       if( result )          goto error;       stream->outDeviceSampleRate = rate;    }    stream->inDeviceSampleRate = 0;    if( stream->inputUnit ) {       Float64 rate;       UInt32 size = sizeof( rate );       result = ERR( AudioDeviceGetProperty( stream->inputDevice,                                    0,                                    TRUE,                                    kAudioDevicePropertyNominalSampleRate,                                    &size, &rate ) );       if( result )          goto error;       stream->inDeviceSampleRate = rate;    }    stream->userInChan  = inputChannelCount;    stream->userOutChan = outputChannelCount;    stream->isTimeSet   = FALSE;    stream->state = STOPPED;    stream->xrunFlags = 0;    *s = (PaStream*)stream;    return result;error:    CloseStream( stream );    return result;}PaTime GetStreamTime( PaStream *s ){   /* FIXME: I am not at all sure this timing info stuff is right.             patest_sine_time reports negative latencies, which is wierd.*/    PaMacCoreStream *stream = (PaMacCoreStream*)s;    AudioTimeStamp timeStamp;    VVDBUG(("GetStreamTime()\n"));    if ( !stream->isTimeSet )        return (PaTime)0;    if ( stream->outputDevice ) {        AudioDeviceGetCurrentTime( stream->outputDevice, &timeStamp);        return (PaTime)(timeStamp.mSampleTime - stream->startTime.mSampleTime)/stream->outDeviceSampleRate;    } else if ( stream->inputDevice ) {        AudioDeviceGetCurrentTime( stream->inputDevice, &timeStamp);    return (PaTime)(timeStamp.mSampleTime - stream->startTime.mSampleTime)/stream->inDeviceSampleRate;    } else {        return (PaTime)0;    }}static void setStreamStartTime( PaStream *stream ){   /* FIXME: I am not at all sure this timing info stuff is right.             patest_sine_time reports negative latencies, which is wierd.*/   PaMacCoreStream *s = (PaMacCoreStream *) stream;   VVDBUG(("setStreamStartTime()\n"));   if( s->outputDevice )      AudioDeviceGetCurrentTime( s->outputDevice, &s->startTime);   else if( s->inputDevice )      AudioDeviceGetCurrentTime( s->inputDevice, &s->startTime);   else      bzero( &s->startTime, sizeof( s->startTime ) );   //FIXME: we need a memory barier here   s->isTimeSet = TRUE;}static PaTime TimeStampToSecs(PaMacCoreStream *stream, const AudioTimeStamp* timeStamp){    VVDBUG(("TimeStampToSecs()\n"));    //printf( "ATS: %lu, %g, %g\n", timeStamp->mFlags, timeStamp->mSampleTime, timeStamp->mRateScalar );    if (timeStamp->mFlags & kAudioTimeStampSampleTimeValid)        return (timeStamp->mSampleTime / stream->sampleRate);    else        return 0;}#define RING_BUFFER_EMPTY (1000)static OSStatus ringBufferIOProc( AudioConverterRef inAudioConverter,                              UInt32*ioDataSize,                              void** outData,                              void*inUserData ){   void *dummyData;   long dummySize;   RingBuffer *rb = (RingBuffer *) inUserData;   VVDBUG(("ringBufferIOProc()\n"));   assert( sizeof( UInt32 ) == sizeof( long ) );   if( RingBuffer_GetReadAvailable( rb ) == 0 ) {      *outData = NULL;      *ioDataSize = 0;      return RING_BUFFER_EMPTY;   }   RingBuffer_GetReadRegions( rb, *ioDataSize,                              outData, (long *)ioDataSize,                               &dummyData, &dummySize );         assert( *ioDataSize );   RingBuffer_AdvanceReadIndex( rb, *ioDataSize );   return noErr;}/* * Called by the AudioUnit API to process audio from the sound card. * This is where the magic happens. *//* FEEDBACK: there is a lot of redundant code here because of how all the cases differ. This makes it hard to maintain, so if there are suggestinos for cleaning it up, I'm all ears. */static OSStatus AudioIOProc( void *inRefCon,                               AudioUnitRenderActionFlags *ioActionFlags,                               const AudioTimeStamp *inTimeStamp,                               UInt32 inBusNumber,                               UInt32 inNumberFrames,                               AudioBufferList *ioData ){   unsigned long framesProcessed     = 0;   PaStreamCallbackTimeInfo timeInfo = {0,0,0};   PaMacCoreStream *stream           = (PaMacCoreStream*)inRefCon;   const bool isRender               = inBusNumber == OUTPUT_ELEMENT;   int callbackResult                = paContinue ;   VVDBUG(("AudioIOProc()\n"));   PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer );   /* -----------------------------------------------------------------*\      This output may be useful for debugging,      But printing durring the callback is a bad enough idea that      this is not enabled by enableing the usual debugging calls.   \* -----------------------------------------------------------------*/   /*   static int renderCount = 0;   static int inputCount = 0;   printf( "-------------------  starting reder/input\n" );   if( isRender )      printf("Render callback (%d):\t", ++renderCount);   else      printf("Input callback  (%d):\t", ++inputCount);   printf( "Call totals: %d (input), %d (render)\n", inputCount, renderCount );   printf( "--- inBusNumber: %lu\n", inBusNumber );   printf( "--- inNumberFrames: %lu\n", inNumberFrames );   printf( "--- %x ioData\n", (unsigned) ioData );   if( ioData )   {      int i=0;      printf( "--- ioData.mNumBuffers %lu: \n", ioData->mNumberBuffers );      for( i=0; i<ioData->mNumberBuffers; ++i )         printf( "--- ioData buffer %d size: %lu.\n", i, ioData->mBuffers[i].mDataByteSize );   }      ----------------------------------------------------------------- */   if( !stream->isTimeSet )      setStreamStartTime( stream );   if( isRender ) {      AudioTimeStamp currentTime;      timeInfo.outputBufferDacTime = TimeStampToSecs(stream, inTimeStamp);      AudioDeviceGetCurrentTime(stream->outputDevice, &currentTime);      timeInfo.currentTime = TimeStampToSecs(stream, &currentTime);   }   if( isRender && stream->inputUnit == stream->outputUnit )      timeInfo.inputBufferAdcTime = TimeStampToSecs(stream, inTimeStamp);   if( !isRender ) {      AudioTimeStamp currentTime;      timeInfo.inputBufferAdcTime = TimeStampToSecs(stream, inTimeStamp);      AudioDeviceGetCurrentTime(stream->inputDevice, &currentTime);      timeInfo.currentTime = TimeStampToSecs(stream, &currentTime);   }   //printf( "---%g, %g, %g\n", timeInfo.inputBufferAdcTime, timeInfo.currentTime, timeInfo.outputBufferDacTime );   if( isRender && stream->inputUnit == stream->outputUnit                && !stream->inputSRConverter )   {      /* --------- Full Duplex, One Device, no SR Conversion -------       *       * This is the lowest latency case, and also the simplest.       * Input data and output data are available at the same time.       * we do not use the input SR converter or the input ring buffer.       *       */      OSErr err = 0;      unsigned long frames;      /* -- start processing -- */      PaUtil_BeginBufferProcessing( &(stream->bufferProcessor),                                    &timeInfo,                                    stream->xrunFlags );      stream->xrunFlags = 0;      /* -- compute frames. do some checks -- */      assert( ioData->mNumberBuffers == 1 );      assert( ioData->mBuffers[0].mNumberChannels == stream->userOutChan );      frames = ioData->mBuffers[0].mDataByteSize;      frames /= sizeof( float ) * ioData->mBuffers[0].mNumberChannels;      /* -- copy and process input data -- */      err= AudioUnitRender(stream->inputUnit,                    ioActionFlags,                    inTimeStamp,                    INPUT_ELEMENT,                    inNumberFrames,                    &stream->inputAudioBufferList );      /* FEEDBACK: I'm not sure what to do when this call fails */      assert( !err );      PaUtil_SetInputFrameCount( &(stream->bufferProcessor), frames );      PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor),                          0,                          stream->inputAudioBufferList.mBuffers[0].mData,                          stream->inputAudioBufferList.mBuffers[0].mNumberChannels);      /* -- Copy and process output data -- */      PaUtil_SetOutputFrameCount( &(stream->bufferProcessor), frames );      PaUtil_SetInterleavedOutputChannels( &(stream->bufferProcessor),                                        0,                                        ioData->mBuffers[0].mData,                                        ioData->mBuffers[0].mNumberChannels);      /* -- complete processing -- */      fram

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -