示例#1
0
void MpodAndroid::audioCallback(int event, void* user, void *info)
{
   //LOGV("MpodAndroid::audioCallback(event=%d)\n", event);
   RTL_BLOCK("MpodAndroid::audioCallback");
   bool lSignal = false;
   if (event != MpAndroidAudioTrack::EVENT_MORE_DATA)
   {
      LOGV("MpodAndroid::audioCallback(event=%d)\n", event);
      return;
   }

   MpAndroidAudioTrack::Buffer *buffer = static_cast<MpAndroidAudioTrack::Buffer *>(info);
   MpodAndroid *pDriver = static_cast<MpodAndroid *>(user);

   // Start accessing non-atomic member variables
   AutoMutex autoLock(pDriver->mLock);

   int samplesToCopy = sipx_min(buffer->frameCount,
                                pDriver->mSamplesPerFrame-pDriver->mSampleBufferIndex);
#ifdef ENABLE_FRAME_TIME_LOGGING
   LOGV("MpodAndroid::audioCallback() buffer=%p samples=%d size=%d toCopy=%d\n",
        buffer->i16, buffer->frameCount, buffer->size, samplesToCopy);
#endif
   RTL_EVENT("MpodAndroid::audioCallback_bufsize", samplesToCopy);
   // Copy data to buffer
   memcpy(buffer->i16, pDriver->mpSampleBuffer+pDriver->mSampleBufferIndex, samplesToCopy*sizeof(short));
   buffer->frameCount = samplesToCopy;
   buffer->size = samplesToCopy*sizeof(short);
   pDriver->mSampleBufferIndex += samplesToCopy;

#ifdef ENABLE_FILE_LOGGING
   fwrite(buffer->i16, 1, buffer->frameCount*sizeof(short), sgOutFile);
#endif // ENABLE_FILE_LOGGING

   if (pDriver->mSampleBufferIndex >= pDriver->mSamplesPerFrame)
   {
      RTL_BLOCK("MpodAndroid::audioCallback_tick");
      if(pDriver->mSampleBufferIndex > pDriver->mSamplesPerFrame)
      {
         LOGE("MpodAndroid::audioCallback() sample index (%d) > samples/frame (%d)\n", (int)pDriver->mSampleBufferIndex, (int)pDriver->mSamplesPerFrame);
      }

      // Return index to the beginning
      pDriver->mSampleBufferIndex = 0;

      // Fire callback. It will call our pushFrame() in turn.
#ifdef ENABLE_FRAME_TIME_LOGGING
      LOGV("MpodAndroid::audioCallback() signal ticker, time %"PRIi64"ns\n", systemTime(SYSTEM_TIME_REALTIME));
#endif
      pDriver->mpTickerNotification->signal(pDriver->mSamplesPerFrame);

      // Update frame time.
      pDriver->mCurFrameTime += pDriver->mSamplesPerFrame;
   }

   // Step forward state
   switch (pDriver->mState) {
    case DRIVER_STARTING:
       pDriver->mState = DRIVER_PLAYING;
       lSignal = true;
       break;
    case DRIVER_STOPPING:
//       pDriver->mState = DRIVER_STOPPED;
//       break;
    case DRIVER_STOPPED:
       LOGV("MpodAndroid::audioCallback() stopping Track\n");
       pDriver->mpAudioTrack->stop();
       LOGV("MpodAndroid::audioCallback() stopped Track\n");
       buffer->size = 0;
       pDriver->mState = DRIVER_IDLE;
       lSignal = true;
       break;
    default:
       break;
   }

   if (lSignal)
   {
      LOGV("MpodAndroid::audioCallback signalling\n");
      pDriver->mWaitCbkCond.signal();
      LOGV("MpodAndroid::audioCallback signalled\n");
   }
}
示例#2
0
void MpOss::soundIoThread()
{
   UtlBoolean bStReader;
   UtlBoolean bStWriter;
   UtlBoolean bShutdown;
   OsStatus status;

   MpAudioSample* isamples;
   const MpAudioSample* osamples;
   int i;

   UtlBoolean bWakeUp = TRUE;
   assert(mModeChanged == TRUE);

   for (;;i++)
   {
      // To reduce latency we use flag handling instead of semaphore locking 
      while (mModeChanged)
      {
         bStReader = mStReader;
         bStWriter = mStWriter;
         bShutdown = mStShutdown;

         // Set we have caught signal
         mModeChanged = FALSE;
         if (!bStWriter && !bStReader && !bShutdown)
         {
            RTL_EVENT("MpOss::io_thread", 10);
            ioctl(mfdDevice, SNDCTL_DSP_SYNC, NULL);

            RTL_EVENT("MpOss::io_thread", 11);
            ossSetTrigger(false);
            
            ossReset();

            sem_post(&mSignalSem);

            RTL_EVENT("MpOss::io_thread", 12);
            // Wait for any IO
            sem_wait(&mSleepSem);

            if (mStShutdown) {
               return;
            }
            bWakeUp = TRUE;
         }
         else if (bShutdown)
         {
            RTL_EVENT("MpOss::io_thread", 0);
            // OSS driver killing
            ossSetTrigger(false);
            
            ossReset();
            return;
         }
         else
         {
            // Signal we have caught modification flag
            sem_post(&mSignalSem);
            RTL_EVENT("MpOss::io_thread", 15);

            int frameSize = ((mStereoOps) ? 2 : 1) * mUsedSamplesPerFrame * 2;

            if (bStWriter || bStReader)
            {
               assert (frameSize > 0 && frameSize < SOUND_MAXBUFFER);
            }

            if (bWakeUp)
            {
               unsigned precharge;
               i = 0;
               RTL_EVENT("MpOss::io_thread", -1);
               ossSetTrigger(true);
               RTL_EVENT("MpOss::io_thread", 16);
               if (mbWriteCap)
               {
                  // Plays out silence to set requested buffer deep
                  precharge = OSS_LATENCY_LENGTH * mUsedSamplesPerSec / 1000;

                  for (unsigned k = 0; k < precharge; k += mUsedSamplesPerFrame)
                  {
                     unsigned sz = precharge - k;
                     if (sz > mUsedSamplesPerFrame)
                         sz = mUsedSamplesPerFrame;

                     //Use small data request unless OSS may be confused
                     if (mbReadCap)
                     {
                        doInputRs(gTrashBuffer, mUsedSamplesPerFrame >> 3);
                        RTL_EVENT("MpOss::io_thread", 18);
                     }                     

                     doOutputRs(gSilenceBuffer, sz);
                     RTL_EVENT("MpOss::io_thread", 17);
                     
                  }
               }

               RTL_EVENT("MpOss::io_thread", 19);
               if ((mbWriteCap) && (mbReadCap))
               {
                  //Compensates output shift due previous data requests
                  doOutputRs(gSilenceBuffer, (mUsedSamplesPerFrame >> 2));
               }

               bWakeUp = FALSE;
               RTL_EVENT("MpOss::io_thread", 16);
            }
         }
      }

      // Produce heart beat for MpMediaLib
      if ((mWriter) && (!mWriter->mNotificationThreadEn))
      {
         RTL_EVENT("MpOss::io_thread", 4);
         mWriter->signalForNextFrame();
      }

      if (mbReadCap)
      {
         RTL_EVENT("MpOss::io_thread", 2);
         isamples = (bStReader) ? mReader->mAudioFrame : gTrashBuffer;
         status = doInputRs(isamples, mUsedSamplesPerFrame);

         if ((status == OS_SUCCESS) && (bStReader))
         {
            RTL_EVENT("MpOss::io_thread", 3);
            mReader->pushFrame();
         }
      }

      if (mbWriteCap)
      {
         osamples = (bStWriter) ? mWriter->mAudioFrame : gSilenceBuffer;
         RTL_EVENT("MpOss::io_thread", 1);
         status = doOutputRs(osamples, mUsedSamplesPerFrame);
      }

   }
示例#3
0
static WAVEHDR* outPrePrep(int n, DWORD bufLen)
{
#ifdef RTL_ENABLED
   RTL_EVENT("SpeakerThreadWnt.outPrePrep", 1);
#endif

   WAVEHDR* pWH;
   int doAlloc = (hOutHdr[n] == NULL);
   MpBufferMsg* msg;
   MpBufferMsg* pFlush;
   MpAudioBufPtr ob;

   static int oPP = 0;

   static int flushes = 0;
   static int skip = 0;

   assert((n > -1) && (n < N_OUT_BUFFERS));

#ifdef DEBUG_WINDOZE /* [ */
   if (1) {
      static int spkQLen[1024];
      int in = oPP % 1024;
      int i, j;

      spkQLen[in] = MpMisc.pSpkQ->numMsgs();
      if (in == 1023) {
         osPrintf("\n\n Speaker Queue lengths [%d,%d]:\n  ", oPP, frameCount);
         for (i=0; i<1024; i+=32) {
            for (j=i; j<(i+32); j++) {
               osPrintf("%3d", spkQLen[j]);
            }
            osPrintf("\n  ");
         }
         osPrintf("\n\n");
      }
   }
#endif /* DEBUG_WINDOZE ] */

   oPP++;

#ifdef DEBUG_WINDOZE /* [ */
   if (0 && (0 == (oPP % 1000))) {
      osPrintf("outPrePrep(): %d playbacks, %d flushes\n", oPP, flushes);
   }
#endif /* DEBUG_WINDOZE ] */
   while (MpMisc.pSpkQ && MpMisc.pSpkQ->numMsgs() > MprToSpkr::MAX_SPKR_BUFFERS) {
      OsStatus  res;
      flushes++;
      res = MpMisc.pSpkQ->receive((OsMsg*&) pFlush, OsTime::NO_WAIT_TIME);
      if (OS_SUCCESS == res) {
         pFlush->releaseMsg();
      } else {
         osPrintf("DmaTask: queue was full, now empty (4)!"
            " (res=%d)\n", res);
      }
      if (flushes > 100) {
         osPrintf("outPrePrep(): %d playbacks, %d flushes\n", oPP, flushes);
         flushes = 0;
      }
   }

   if (MpMisc.pSpkQ) {
      if (  (skip == 0)
         && (MpMisc.pSpkQ->numMsgs() < MprToSpkr::MIN_SPKR_BUFFERS))
      {
         skip = MprToSpkr::SKIP_SPKR_BUFFERS;
         assert(MprToSpkr::MAX_SPKR_BUFFERS >= skip);
#ifdef DEBUG_WINDOZE /* [ */
         osPrintf("Skip(%d,%d)\n", skip, oPP);
#endif /* DEBUG_WINDOZE ] */
      }

      if (MpMisc.pSpkQ->numMsgs() >= skip)
      {
         skip = 0;
         if (MpMisc.pSpkQ->receive((OsMsg*&)msg, OsTime::NO_WAIT_TIME) == OS_SUCCESS)
         {
            ob = (MpAudioBufPtr)(msg->getBuffer());
            msg->releaseMsg();
         }
//         osPrintf("pSpkQ message received\n");
      } else {
//         osPrintf("pSpkQ message skipped\n");
      }
   }

   if (!ob.isValid()) {
      ob = MpMisc.mpFgSilence;
   }

   if (doAlloc) {
      hOutHdr[n] = GlobalAlloc(GPTR, sizeof(WAVEHDR));
      assert(NULL != hOutHdr[n]);
      hOutBuf[n] = GlobalAlloc(GPTR, bufLen);
      assert(NULL != hOutBuf[n]);
   }

   pOutHdr[n] = pWH = (WAVEHDR*) GlobalLock(hOutHdr[n]);
   assert(NULL != pOutHdr[n]);
   pWH->lpData = (char*) GlobalLock(hOutBuf[n]);
   pWH->dwBufferLength = bufLen;
   pWH->dwUser = n;
   pWH->dwBytesRecorded = 0;
   pWH->dwFlags = 0;
   pWH->dwLoops = 0;
   pWH->lpNext = 0;
   pWH->reserved = 0;
   memcpy(pWH->lpData, ob->getSamplesPtr(), bufLen);

#ifdef RTL_ENABLED
   RTL_EVENT("SpeakerThreadWnt.outPrePrep", 0);
#endif
   return pWH;
}
    void testTones()
    {
        RTL_START(1600000);

        CPPUNIT_ASSERT(mpMediaFactory);

        SdpCodecList* sdpCodecList = new SdpCodecList();
        CPPUNIT_ASSERT(sdpCodecList);
        UtlSList utlCodecList;
        sdpCodecList->getCodecs(utlCodecList);

        UtlString localRtpInterfaceAddress("127.0.0.1");
        UtlString locale;
        int tosOptions = 0;
        UtlString stunServerAddress;
        int stunOptions = 0;
        int stunKeepAlivePeriodSecs = 25;
        UtlString turnServerAddress;
        int turnPort = 0 ;
        UtlString turnUser;
        UtlString turnPassword;
        int turnKeepAlivePeriodSecs = 25;
        bool enableIce = false ;


        CpMediaInterface* mediaInterface = 
            mpMediaFactory->createMediaInterface(NULL,
                                                 sdpCodecList,
                                                 NULL, // public mapped RTP IP address
                                                 localRtpInterfaceAddress, 
                                                 locale,
                                                 tosOptions,
                                                 stunServerAddress, 
                                                 stunOptions, 
                                                 stunKeepAlivePeriodSecs,
                                                 turnServerAddress,
                                                 turnPort,
                                                 turnUser,
                                                 turnPassword,
                                                 turnKeepAlivePeriodSecs,
                                                 enableIce);


        // Record the entire "call" - all connections.
        mediaInterface->recordAudio("testTones_call_recording.wav");

        mediaInterface->giveFocus() ;

        RTL_EVENT("Tone set", 0);
        printf("first tone set\n");
        RTL_EVENT("Tone set", 1);
        mediaInterface->startTone(6, true, false) ;OsTask::delay(500) ;
        RTL_EVENT("Tone set", 2);
        mediaInterface->startTone(8, true, false) ;OsTask::delay(500) ;
        RTL_EVENT("Tone set", 3);
        mediaInterface->startTone(4, true, false) ;OsTask::delay(500) ;
        RTL_EVENT("Tone set", 0);
        printf("second tone set\n");        
        OsTask::delay(500) ;
        RTL_EVENT("Tone set", 1);
        mediaInterface->startTone(6, true, false) ;OsTask::delay(500) ;
        RTL_EVENT("Tone set", 2);
        mediaInterface->startTone(8, true, false) ;OsTask::delay(500) ;
        RTL_EVENT("Tone set", 3);
        mediaInterface->startTone(4, true, false) ;OsTask::delay(500) ;
        RTL_EVENT("Tone set", 0);
        printf("third tone set\n");        
        OsTask::delay(500) ;
        RTL_EVENT("Tone set", 1);
        mediaInterface->startTone(9, true, false) ;OsTask::delay(500) ;
        mediaInterface->startTone(5, true, false) ;OsTask::delay(500) ;
        mediaInterface->startTone(5, true, false) ;OsTask::delay(500) ;
        mediaInterface->startTone(4, true, false) ;OsTask::delay(500) ;
        RTL_EVENT("Tone set", 0);
        printf("fourth tone set\n");        
        OsTask::delay(500) ;
        RTL_EVENT("Tone set", 1);
        mediaInterface->startTone(9, true, false) ;OsTask::delay(500) ;
        mediaInterface->startTone(5, true, false) ;OsTask::delay(500) ;
        mediaInterface->startTone(5, true, false) ;OsTask::delay(500) ;
        mediaInterface->startTone(4, true, false) ;OsTask::delay(500) ;
        RTL_EVENT("Tone set", 0);
        printf("tone set done\n");        
        OsTask::delay(1000) ;

        // Stop recording the "call" -- all connections.
        mediaInterface->stopRecording();

        RTL_WRITE("testTones.rtl");
        RTL_STOP;

        // delete interface
        mediaInterface->release(); 

        OsTask::delay(500) ;
        delete sdpCodecList ;
    };
    void testTwoTones()
    {
        RTL_START(2400000);

        // This test creates three flowgraphs.  It streams RTP with tones
        // from the 2nd and 3rd to be received and mixed in the first flowgraph
        // So we test RTP and we test that we can generate 2 different tones in
        // to different flowgraphs to ensure that the ToneGen has no global
        // interactions or dependencies.
        CPPUNIT_ASSERT(mpMediaFactory);

        SdpCodecList* pSdpCodecList = new SdpCodecList();
        CPPUNIT_ASSERT(pSdpCodecList);
        UtlSList utlCodecList;
        pSdpCodecList->getCodecs(utlCodecList);

        UtlString localRtpInterfaceAddress("127.0.0.1");
        OsSocket::getHostIp(&localRtpInterfaceAddress);
        UtlString locale;
        int tosOptions = 0;
        UtlString stunServerAddress;
        int stunOptions = 0;
        int stunKeepAlivePeriodSecs = 25;
        UtlString turnServerAddress;
        int turnPort = 0 ;
        UtlString turnUser;
        UtlString turnPassword;
        int turnKeepAlivePeriodSecs = 25;
        bool enableIce = false ;

        // Create a flowgraph (sink) to receive and mix 2 sources
        CpMediaInterface* mixedInterface = 
            mpMediaFactory->createMediaInterface(NULL,
                                                 pSdpCodecList,
                                                 NULL, // public mapped RTP IP address
                                                 localRtpInterfaceAddress, 
                                                 locale,
                                                 tosOptions,
                                                 stunServerAddress, 
                                                 stunOptions, 
                                                 stunKeepAlivePeriodSecs,
                                                 turnServerAddress,
                                                 turnPort,
                                                 turnUser,
                                                 turnPassword,
                                                 turnKeepAlivePeriodSecs,
                                                 enableIce);

        // Create connections for mixed(sink) flowgraph
        int mixedConnection1Id = -1;
        CPPUNIT_ASSERT(mixedInterface->createConnection(mixedConnection1Id, NULL) == OS_SUCCESS);
        CPPUNIT_ASSERT(mixedConnection1Id > 0);
        int mixedConnection2Id = -1;
        CPPUNIT_ASSERT(mixedInterface->createConnection(mixedConnection2Id, NULL) == OS_SUCCESS);
        CPPUNIT_ASSERT(mixedConnection2Id > 0);
        
        // Get the address of the connections so we can send RTP to them
        // capabilities of first connection on mixed(sink) flowgraph
        const int maxAddresses = 1;
        UtlString rtpHostAddresses1[maxAddresses];
        int rtpAudioPorts1[maxAddresses];
        int rtcpAudioPorts1[maxAddresses];
        int rtpVideoPorts1[maxAddresses];
        int rtcpVideoPorts1[maxAddresses];
        RTP_TRANSPORT transportTypes1[maxAddresses];
        int numActualAddresses1;
        SdpCodecList supportedCodecs1;
        SdpSrtpParameters srtpParameters1;
        int videoBandwidth1;
        int videoFramerate1;
        CPPUNIT_ASSERT_EQUAL(
            mixedInterface->getCapabilitiesEx(mixedConnection1Id, 
                                             maxAddresses,
                                             rtpHostAddresses1, 
                                             rtpAudioPorts1,
                                             rtcpAudioPorts1,
                                             rtpVideoPorts1,
                                             rtcpVideoPorts1,
                                             transportTypes1,
                                             numActualAddresses1,
                                             supportedCodecs1,
                                             srtpParameters1,
                                             videoBandwidth1,
                                             videoFramerate1), 

             OS_SUCCESS);

        // capabilities of second connection on mixed(sink) flowgraph
        UtlString rtpHostAddresses2[maxAddresses];
        int rtpAudioPorts2[maxAddresses];
        int rtcpAudioPorts2[maxAddresses];
        int rtpVideoPorts2[maxAddresses];
        int rtcpVideoPorts2[maxAddresses];
        RTP_TRANSPORT transportTypes2[maxAddresses];
        int numActualAddresses2;
        SdpCodecList supportedCodecs2;
        SdpSrtpParameters srtpParameters2;
        int videoBandwidth2;
        int videoFramerate2;
        CPPUNIT_ASSERT_EQUAL(
            mixedInterface->getCapabilitiesEx(mixedConnection2Id, 
                                             maxAddresses,
                                             rtpHostAddresses2, 
                                             rtpAudioPorts2,
                                             rtcpAudioPorts2,
                                             rtpVideoPorts2,
                                             rtcpVideoPorts2,
                                             transportTypes2,
                                             numActualAddresses2,
                                             supportedCodecs2,
                                             srtpParameters2,
                                             videoBandwidth2,
                                             videoFramerate2), 

             OS_SUCCESS);

        // Prep the sink connections to receive RTP
        UtlSList codec1List;
        supportedCodecs1.getCodecs(codec1List);
        CPPUNIT_ASSERT_EQUAL(
            mixedInterface->startRtpReceive(mixedConnection1Id,
                                            codec1List),
            OS_SUCCESS);

        // Want to hear what is on the mixed flowgraph
        mixedInterface->giveFocus();

        UtlSList codec2List;
        supportedCodecs2.getCodecs(codec2List);
        CPPUNIT_ASSERT_EQUAL(
            mixedInterface->startRtpReceive(mixedConnection2Id,
                                            codec2List),
            OS_SUCCESS);

        // Second flowgraph to be one of two sources
        CpMediaInterface* source1Interface = 
            mpMediaFactory->createMediaInterface(NULL,
                                                 pSdpCodecList,
                                                 NULL, // public mapped RTP IP address
                                                 localRtpInterfaceAddress, 
                                                 locale,
                                                 tosOptions,
                                                 stunServerAddress, 
                                                 stunOptions, 
                                                 stunKeepAlivePeriodSecs,
                                                 turnServerAddress,
                                                 turnPort,
                                                 turnUser,
                                                 turnPassword,
                                                 turnKeepAlivePeriodSecs,
                                                 enableIce);

        // Create connection for source 1 flowgraph
        int source1ConnectionId = -1;
        CPPUNIT_ASSERT(source1Interface->createConnection(source1ConnectionId, NULL) == OS_SUCCESS);
        CPPUNIT_ASSERT(source1ConnectionId > 0);

        // Set the destination for sending RTP from source 1 to connection 1 on
        // the mix flowgraph
        printf("rtpHostAddresses1: \"%s\"\nrtpAudioPorts1: %d\nrtcpAudioPorts1: %d\nrtpVideoPorts1: %d\nrtcpVideoPorts1: %d\n",
            rtpHostAddresses1->data(), 
            *rtpAudioPorts1,
            *rtcpAudioPorts1,
            *rtpVideoPorts1,
            *rtcpVideoPorts1);

        CPPUNIT_ASSERT_EQUAL(
            source1Interface->setConnectionDestination(source1ConnectionId,
                                                       rtpHostAddresses1->data(), 
                                                       *rtpAudioPorts1,
                                                       *rtcpAudioPorts1,
                                                       *rtpVideoPorts1,
                                                       *rtcpVideoPorts1),
            OS_SUCCESS);

        // Start sending RTP from source 1 to the mix flowgraph
        CPPUNIT_ASSERT_EQUAL(
            source1Interface->startRtpSend(source1ConnectionId, 
                                           codec1List),
            OS_SUCCESS);


        // Second flowgraph to be one of two sources
        CpMediaInterface* source2Interface = 
            mpMediaFactory->createMediaInterface(NULL,
                                                 pSdpCodecList,
                                                 NULL, // public mapped RTP IP address
                                                 localRtpInterfaceAddress, 
                                                 locale,
                                                 tosOptions,
                                                 stunServerAddress, 
                                                 stunOptions, 
                                                 stunKeepAlivePeriodSecs,
                                                 turnServerAddress,
                                                 turnPort,
                                                 turnUser,
                                                 turnPassword,
                                                 turnKeepAlivePeriodSecs,
                                                 enableIce);

        // Create connection for source 2 flowgraph
        int source2ConnectionId = -1;
        CPPUNIT_ASSERT(source2Interface->createConnection(source2ConnectionId, NULL) == OS_SUCCESS);
        CPPUNIT_ASSERT(source2ConnectionId > 0);

        // Set the destination for sending RTP from source 2 to connection 2 on
        // the mix flowgraph
        CPPUNIT_ASSERT_EQUAL(
            source2Interface->setConnectionDestination(source2ConnectionId,
                                                       *rtpHostAddresses2, 
                                                       *rtpAudioPorts2,
                                                       *rtcpAudioPorts2,
                                                       *rtpVideoPorts2,
                                                       *rtcpVideoPorts2),
            OS_SUCCESS);

        RTL_EVENT("Tone count", 0);

        // Record the entire "call" - all connections.
        mixedInterface->recordAudio("testTwoTones_call_recording.wav");

        // Start sending RTP from source 2 to the mix flowgraph
        CPPUNIT_ASSERT_EQUAL(
            source2Interface->startRtpSend(source2ConnectionId, 
                                           codec2List),
            OS_SUCCESS);

        RTL_EVENT("Tone count", 1);
        printf("generate tones in source 1\n");
        source1Interface->startTone(1, true, true);

        OsTask::delay(1000);

        RTL_EVENT("Tone count", 2);
        printf("generate tones in source 2 as well\n");
        source2Interface->startTone(2, true, true);

        OsTask::delay(1000);

        RTL_EVENT("Tone count", 1);
        printf("stop tones in source 1\n");

        OsTask::delay(1000);
        RTL_EVENT("Tone count", 0);

        OsTask::delay(1000);
        printf("two tones done\n");        

        // Stop recording the "call" -- all connections.
        mixedInterface->stopRecording();

        // Delete connections
        mixedInterface->deleteConnection(mixedConnection1Id);
        mixedInterface->deleteConnection(mixedConnection2Id);
        source1Interface->deleteConnection(source1ConnectionId);
        source2Interface->deleteConnection(source2ConnectionId);

        // delete interfaces
        mixedInterface->release();
        source1Interface->release();
        source2Interface->release();

        OsTask::delay(500) ;

        RTL_WRITE("testTwoTones.rtl");
        RTL_STOP;

        delete pSdpCodecList ;
    };
示例#6
0
UtlBoolean MprFromMic::doProcessFrame(MpBufPtr inBufs[],
                                      MpBufPtr outBufs[],
                                      int inBufsSize,
                                      int outBufsSize,
                                      UtlBoolean isEnabled,
                                      int samplesPerFrame,
                                      int samplesPerSecond)
{
   MpAudioBufPtr   out;
   MpBufferMsg*    pMsg;

   // We need one output buffer
   if (outBufsSize != 1) 
      return FALSE;

   // Don't waste the time if output is not connected
   if (!isOutputConnected(0))
       return TRUE;

   // One more frame processed
   mNumFrames++;

#ifdef RTL_ENABLED
   RTL_EVENT("FromMic queue", mpMicQ->numMsgs());
#endif

   if (isEnabled) 
   {
      // If the microphone queue (holds unprocessed mic data) has more then
      // the max_mic_buffers threshold, drain the queue until in range)
      while (mpMicQ && mpMicQ->numMsgs() > MpMisc.max_mic_buffers) 
      {
         if (mpMicQ->receive((OsMsg*&)pMsg, OsTime::NO_WAIT_TIME) == OS_SUCCESS) 
         {
            pMsg->releaseMsg();
                osPrintf( "mpMicQ drained. %d msgs in queue now\n"
                        , mpMicQ->numMsgs());
         }
      }

      if (mpMicQ && mpMicQ->numMsgs() > 0)
      {
         if (mpMicQ->receive((OsMsg*&)pMsg, OsTime::NO_WAIT_TIME) == OS_SUCCESS) 
         {
//                osPrintf( "mpMicQ->receive() succeed, %d msgs in queue\n"
//                        , mpMicQ->numMsgs());
            out = pMsg->getBuffer();
            pMsg->releaseMsg();
         }
      }
      else
      {
//         osPrintf("MprFromMic: No data available (total frames=%d)\n", 
//               mNumFrames);
      }

#ifdef INSERT_SAWTOOTH /* [ */
      if (!out.isValid())
      {
         out = MpMisc.RawAudioPool->getBuffer();
            if (!out.isValid())
               return FALSE;
         out->setSamplesNumber(MpMisc.frameSamples);
      }
      MpBuf_insertSawTooth(out);
      out->setSpeechType(MP_SPEECH_ACTIVE);
#endif /* INSERT_SAWTOOTH ] */

      if (s_fnMicDataHook)
      {
         // 
         // Allow an external identity to source microphone data.  Ideally,
         // this should probably become a different resource, but abstracting
         // a new CallFlowGraph is a lot of work.
         //

         if (!out.isValid())
         {
            out = MpMisc.RawAudioPool->getBuffer();
            if (!out.isValid())
               return FALSE;
            out->setSamplesNumber(MpMisc.frameSamples);
         }
         
         if (out.isValid()) 
         {
            int n = 0;
            MpAudioSample* s = NULL;

            s = out->getSamplesWritePtr();
            n = out->getSamplesNumber();
            
            s_fnMicDataHook(n, (short*)s) ;

            out->setSpeechType(MP_SPEECH_UNKNOWN);
         }
      }

      if (out.isValid())
      {
         switch(out->getSpeechType()) 
         {
            case MP_SPEECH_TONE:
               break;
            case MP_SPEECH_MUTED:
               out->setSpeechType(MP_SPEECH_SILENT);
               break;
            default:
               {
                  MpAudioSample* shpTmpFrame;
                  MpAudioBufPtr tpBuf;

                  MpAudioSample *shpSamples;
                  int n = out->getSamplesNumber();
                  shpSamples = out->getSamplesWritePtr();

                  tpBuf = MpMisc.RawAudioPool->getBuffer();
                  if (!out.isValid())
                     return FALSE;
                  tpBuf->setSamplesNumber(n);
                  assert(tpBuf.isValid());
                  shpTmpFrame = tpBuf->getSamplesWritePtr();
                  highpass_filter800(shpSamples, shpTmpFrame, n);

                  out->setSpeechType(speech_detected(shpTmpFrame,n));
               }
               break;
         }
      }
    }
    else
    {
        out = inBufs[0];
    }

   outBufs[0] = out;

   return TRUE;
}