Beispiel #1
0
string xmlString::getSubTag( const tag &in, unsigned int tabNum )
    {
    string ret;

    string tabs;
    if( (_format&Tabs) != FALSE )
        {
        for( unsigned int x=0; x<tabNum; x++ )
            {
            tabs += "\t";
            }
        }

    if( in.type() == tag::None )
        {
        ret += in.contents().toString();

        /*if( (_format&NewLines) != FALSE )
            {
            ret += "\n";
            }*/
        }
    else
        {
        if( in.type() == tag::Open && in.name() != "" )
            {
            ret += tabs + getOpener( in.name(), in.attributes() );
            }
        else if( in.type() == tag::Empty && in.name() != "" )
            {
            ret += tabs + getOpener( in.name(), in.attributes(), TRUE );
            }

        if( (_format&NewLines) != FALSE && ( in.size() > 1 || ( in.size() > 0 && in[0].type() != tag::None ) ) )
            {
            ret += "\n";
            }

        for( unsigned int x=0; x<in.size(); x++ )
            {
            ret += getSubTag( in[x], tabNum + 1 );
            }

        if( in.type() == tag::Open && in.name() != "" )
            {
            if( in.size() > 1 || ( in.size() > 0 && in[0].type() != tag::None ) )
                {
                ret += tabs;
                }
            ret += getClose( in.name() );
            }

        if( (_format&NewLines) != FALSE )
            {
            ret += "\n";
            }
        }

    return ret;
    }
void *AcquisitionThread ( void *data )
{
  int doneWaiting = 0;
  audioinSample   *CodecBuffer;
#ifdef FILTER_ON
  long            x;
  long            y;
#endif
#ifdef AUDIOIN_SUPPORT_CALLBACK
  AUDIOIN_H       *phAudioIn = (AUDIOIN_H *)data;
#endif

  pthread_mutex_lock ( &gAudioMutex );

  //signal to tell that our thread is now running.
  if ( pthread_cond_signal ( &gThreadRunning ) != 0 )
  {
    pthread_mutex_unlock ( &gAudioMutex );
    PLogError ( "Audio In Error pthread_cond_signal\n" );
    exit ( 1 );
  }
  gThreadRunningSignaled = 1;

  while( 1 )
  {
    while (!doneWaiting)
    {
      int rc = pthread_cond_wait(&gOpenExCalled, &gAudioMutex);
      switch (rc)
      {
        case 0:
          if (!gOpenExCalledSignaled)
          {
            // Avoid spurious wakeups
            continue;
          }
          else
          {
            gOpenExCalledSignaled = 0;
            doneWaiting = 1;
            break;
          }
          break;
        default:
          PLogError ( "Audio In Error pthread_cond_wait\n" );
          pthread_mutex_unlock(&gAudioMutex);
          return ( (void *)NULL );
      }
    }
    doneWaiting = 0;
    pthread_mutex_unlock(&gAudioMutex);

    if( gTerminateThread == 1 )
      break;

    /* buffer of 16 bits samples */
    CodecBuffer = (audioinSample *)malloc ( gCodecFragmentSizeInFrames * sizeof ( audioinSample ) );

    if ( CodecBuffer == NULL )
    {
      PLogError ( "Audio In Error pthread_cond_signal\n" );
      exit ( 1 );
    }

    while ( !getClose ( ) )
    {
      int iReadFrames  = 0;  /* number of frames acquired by the codec */
      /* NOTE: here a frame is comprised of 1 sample if mono, 2 samples if stereo, etc */
      int iReadSamples = 0;  /* number of samples acquired by the codec */
      if ( ( iReadFrames = snd_pcm_readi ( ghPCM, (void *)CodecBuffer, gCodecFragmentSizeInFrames ) ) < 0 )
      {
        if ( iReadFrames == -EBADFD )
        {
          PLogError ( "Audio In Error PCM Not In The Right State\n" );
        }
        else if ( iReadFrames == -EPIPE )
        {
          snd_pcm_prepare(ghPCM);
          PLogError ( "Audio In Error Overrun\n" );
        }
        else if ( iReadFrames == -ESTRPIPE )
        {
          PLogError ( "Audio In Error Stream Suspended\n" );
        }
      }
      iReadSamples = iReadFrames;

      if ( getRecord ( ) )  /* else continue to read from driver but discard samples */
      {
        if ( iReadSamples < 0 )
        {
          iReadSamples = 0;
          gAudioInInfo.eStatusInfo = AUDIOIN_HWOVERRUN;
        }
        else
        {
#ifdef FILTER_ON
          /* x: index for start of input samples; y: index for output sample */
          for ( x = 0, y = 0; x < iReadSamples; x += pFIR->factor_down )
          {
            FIR_downsample ( pFIR->factor_down, &( CodecBuffer[x] ), &( CodecBuffer[y++] ), pFIR );
          }
          /* update the number samples */
          iReadSamples = y;
#endif
#ifdef SAVE_RAW_AUDIO
          if ( iReadSamples > 0 )
            fwrite ( CodecBuffer, 2, iReadSamples, audio_data );
#endif

          pthread_mutex_lock ( &gAudioMutex );

          if ( gAudioInInfo.u32SamplesAvailable + iReadSamples > SAMPLES_BUFFER_SIZE )
          {
            gAudioInInfo.u32SamplesAvailable = SAMPLES_BUFFER_SIZE;
            gAudioInInfo.eStatusInfo = AUDIOIN_FIFOOVERRUN;
          }
          else
          {
            if ( gAudioInInfo.u32SamplesAvailable + iReadSamples > SAMPLES_BUFFER_HIGH_WATERMARK )
            {
              gAudioInInfo.eStatusInfo = AUDIOIN_HIGHWATERMARK;
            }
            else if ( gAudioInInfo.eStatusInfo != AUDIOIN_FIFOOVERRUN )
            {
              gAudioInInfo.eStatusInfo = AUDIOIN_NORMAL;
            }
            gAudioInInfo.u32SamplesAvailable += iReadSamples;
          }
          if ( gWriteIndexPointer + iReadSamples <= SAMPLES_BUFFER_SIZE )
          {
            memcpy ( &( gSamplesBufferCircularFifo[gWriteIndexPointer] ), CodecBuffer,
                iReadSamples * sizeof ( audioinSample ) );
            gWriteIndexPointer += iReadSamples;

            if ( gWriteIndexPointer >= SAMPLES_BUFFER_SIZE )
              gWriteIndexPointer = 0;
          }
          else
          {
            int NbToCopy;

            NbToCopy = SAMPLES_BUFFER_SIZE - gWriteIndexPointer;
            memcpy ( &( gSamplesBufferCircularFifo [gWriteIndexPointer] ), CodecBuffer,
                NbToCopy * sizeof ( audioinSample ) );
            gWriteIndexPointer = 0;
            memcpy ( gSamplesBufferCircularFifo, &( CodecBuffer [NbToCopy] ),
                ( iReadSamples-NbToCopy ) * sizeof ( audioinSample ) );
            gWriteIndexPointer = iReadSamples - NbToCopy;
          }
#ifdef AUDIOIN_SUPPORT_CALLBACK
          /* Callback notification.  Ideally this audio acquisition thread should be very lean.
             It should simply read from the low level driver, store the filtered samples in  
             the FIFO, then go back to reading from the driver.  The additional data copy 
             for the callback function is ok despite the overhead incurred, but only because 
             there's some buffering done by the low level driver.  This design should be 
             revisited to make it more general purpose.
             */
          while ( ( gpCallback != NULL ) && ( gAudioInInfo.u32SamplesAvailable >= gnCallbackSamples ) )
          {            
            AUDIOIN_WAVEHDR *pwhdr;

            pwhdr = malloc ( sizeof ( AUDIOIN_WAVEHDR ) );

            if ( pwhdr != NULL )
            {            
              pwhdr->nBufferLength  = gnCallbackSamples * sizeof ( audioinSample );
              pwhdr->nBytesRecorded = pwhdr->nBufferLength;
              pwhdr->status = gAudioInInfo.eStatusInfo;
              pwhdr->pData = malloc ( pwhdr->nBufferLength );

              if ( pwhdr->pData != NULL )
              {
                if ( gReadIndexPointer + gnCallbackSamples <= SAMPLES_BUFFER_SIZE )
                { 
                  memcpy ( pwhdr->pData, &( gSamplesBufferCircularFifo [gReadIndexPointer] ),
                      pwhdr->nBufferLength );
                  gReadIndexPointer += gnCallbackSamples;

                  if ( gReadIndexPointer >= SAMPLES_BUFFER_SIZE )
                    gReadIndexPointer = 0;
                }
                else
                { 
                  size_t nSamplesPart1 = SAMPLES_BUFFER_SIZE - gReadIndexPointer;
                  size_t nSamplesPart2 = gnCallbackSamples - nSamplesPart1;

                  memcpy ( pwhdr->pData, &( gSamplesBufferCircularFifo [gReadIndexPointer] ),
                      nSamplesPart1*sizeof ( audioinSample ) );
                  gReadIndexPointer = 0;
                  memcpy ( pwhdr->pData + nSamplesPart1 * sizeof (audioinSample ),
                      gSamplesBufferCircularFifo, nSamplesPart2 * sizeof ( audioinSample ) );
                  gReadIndexPointer = nSamplesPart2;
                }                                         
                gAudioInInfo.u32SamplesAvailable -= gnCallbackSamples;
                /* pass samples to callback function who should deallocate the buffer and structure */
                gpCallback ( *phAudioIn, AUDIOIN_MSG_DATA, gpCallbackInstance, pwhdr, NULL );
              }
              else
              {
                // error
              }
            }
            else
            {
              // error
            }
          }
#endif
          /* samples are available to read */
          pthread_mutex_unlock ( &gAudioMutex );
          timer.tv_sec = 0;
          timer.tv_usec = 200;
          select ( 0, NULL, NULL, NULL, &timer );
        }
      } /* if (getRecord()) */

    } /* while (!getClose()) */

    if ( snd_pcm_close ( ghPCM ) !=0 )
    {
      PLogError ( "Audio In Error Closing Hardware\n" );
    }

    free ( CodecBuffer );

    pthread_mutex_lock ( &gAudioMutex );
    //signal to tell that our thread is now running.
    if ( pthread_cond_signal ( &gCloseCalled ) != 0 )
    {
      pthread_mutex_unlock ( &gAudioMutex );
      PLogError ( "Audio In Error pthread_cond_signal\n" );
      exit ( 1 );
    }
    gCloseCalledSignaled = 1;
  }
  pthread_exit ( (void *)NULL );
  return ( (void *)NULL );
}