Пример #1
0
int LoopBack(int on) {
   MpBufferMsg*    pMsg;
   int save = MpMisc.doLoopBack;

   MpMisc.doLoopBack = on;
   while (0 < MpMisc.pLoopBackQ->numMsgs()) {
      if (OS_SUCCESS == MpMisc.pLoopBackQ->receive((OsMsg*&) pMsg,
                                                    OsTime::NO_WAIT_TIME)) {
         pMsg->releaseMsg();
      }
   }
   return save;
}
Пример #2
0
   void testEnabledWithData()
   {
       MprToSpkr*        pToSpkr    = NULL;
       OsMsgQ*           pSpkQ      = NULL;
       OsMsgQ*           pEchoQ     = NULL;
       MpBufferMsg*      pSpkMsg    = NULL;
       MpBufferMsg*      pEchoMsg   = NULL;
       MpBufPtr          pBuf;
       OsStatus          res;

       // Create message queues to get data from MprToSpkr
       pSpkQ = new OsMsgQ(MSG_Q_LEN);
       CPPUNIT_ASSERT(pSpkQ != NULL);
       pEchoQ = new OsMsgQ(MSG_Q_LEN);
       CPPUNIT_ASSERT(pEchoQ != NULL);

       pToSpkr = new MprToSpkr("MprToSpkr",
                               pSpkQ, pEchoQ);
       CPPUNIT_ASSERT(pToSpkr != NULL);

       setupFramework(pToSpkr);

       // pToSpkr enabled, there are buffers on the input 0, message queue
       // is not full.
       CPPUNIT_ASSERT(mpSourceResource->enable());
       CPPUNIT_ASSERT(pToSpkr->enable());

       res = mpFlowGraph->processNextFrame();
       CPPUNIT_ASSERT(res == OS_SUCCESS);

       // Get messages from the queues (wait for 1 second)
       res = pSpkQ->receive((OsMsg*&)pSpkMsg, OsTime(1000));
       CPPUNIT_ASSERT(res == OS_SUCCESS);
       res = pEchoQ->receive((OsMsg*&)pEchoMsg, OsTime(1000));
       CPPUNIT_ASSERT(res == OS_SUCCESS);

       // Store output buffer for convenience
       pBuf = mpSourceResource->mLastDoProcessArgs.outBufs[0];

       // Buffer is sent to queues and to output
       CPPUNIT_ASSERT(  (mpSinkResource->mLastDoProcessArgs.inBufs[0] == pBuf)
                     && (pSpkMsg->getBuffer().isValid())
                     && (pEchoMsg->getBuffer() == pBuf)
                     );

       // Free received message and stored buffer
       pSpkMsg->releaseMsg();
       pEchoMsg->releaseMsg();
       pBuf.release();

       // Stop flowgraph
       haltFramework();

       // Free message queue
       delete pSpkQ;
       delete pEchoQ;
   }
Пример #3
0
UtlBoolean MprFromMic::doProcessFrame(MpBufPtr inBufs[],
                                     MpBufPtr outBufs[],
                                     int inBufsSize,
                                     int outBufsSize,
                                     UtlBoolean isEnabled,
                                     int samplesPerFrame,
                                     int samplesPerSecond)
{
	MpBufPtr        out = NULL ;
	MpBufferMsg*    pMsg;

	if (0 == outBufsSize) 
	{
		return FALSE;
	}
	

	// Clear the the number of empty frames every 512 frames
	mNumFrames++;
	if (0 == (mNumFrames & 0x1ff)) 
	{
		mNumEmpties = 0;
	}

	if (isEnabled) 
	{
		// If the microphone queue (holds unprocessed mic data) has more then
		// the max_mic_buffers threshold, drain the queue until in range)
		OsMsgQ* pMicOutQ;
		pMicOutQ = MpMisc.pMicQ;
		while (pMicOutQ && MpMisc.max_mic_buffers < pMicOutQ->numMsgs()) 
		{
	        if (OS_SUCCESS == pMicOutQ->receive((OsMsg*&) pMsg,
					OsTime::NO_WAIT)) 
			{
				MpBuf_delRef(pMsg->getTag());
				MpBuf_delRef(pMsg->getTag(1));
				pMsg->releaseMsg();
			}
		}

		if (pMicOutQ && pMicOutQ->numMsgs() <= 0)
		{
//			osPrintf("MprFromMic: No data available (total frames=%d, starved frames=%d)\n", 
//					mNumFrames, mNumEmpties);
		}
		else
		{
			if (pMicOutQ && OS_SUCCESS == pMicOutQ->receive((OsMsg*&) pMsg, 
					OsTime::NO_WAIT)) 
			{
				out = pMsg->getTag();
				pMsg->releaseMsg();
				
				if (NULL != out) 
				{
#ifdef REAL_SILENCE_DETECTION /* [ */
					Sample* shpTmpFrame;
					MpBufPtr tpBuf;
					int n;
#endif /* REAL_SILENCE_DETECTION ] */

					switch(MpBuf_getSpeech(out)) 
					{
						case MP_SPEECH_TONE:
							break;
						case MP_SPEECH_MUTED:
							MpBuf_setSpeech(out, MP_SPEECH_SILENT);
							break;
						default:
#ifdef REAL_SILENCE_DETECTION /* [ */
							Sample *shpSamples;
							n = MpBuf_getNumSamples(out);
							shpSamples = MpBuf_getSamples(out);

							tpBuf = MpBuf_getBuf(MpMisc.UcbPool, n, 0, MP_FMT_T12);
							assert(NULL != tpBuf);
							shpTmpFrame = MpBuf_getSamples(tpBuf);
							highpass_filter800(shpSamples, shpTmpFrame, n);

							if(0 == speech_detected(shpTmpFrame,n)) 
							{
								MpBuf_setSpeech(out, MP_SPEECH_SILENT);
							}
							else 
							{
								MpBuf_setSpeech(out, MP_SPEECH_ACTIVE);
							}
							MpBuf_delRef(tpBuf);
#else /* REAL_SILENCE_DETECTION ] [ */
							// 24 April 2001 (HZM)  I am disabling this because it takes
							// too long to recognize the beginning of a talk spurt, and
							// causes the bridge mixer to drop the start of each word.																
							MpBuf_isActiveAudio(out);
#endif /* REAL_SILENCE_DETECTION ] */
							break;
					}
				}
			}
		} 

#ifdef INSERT_SAWTOOTH /* [ */
		if (NULL == out)
		{
			out = MpBuf_getBuf(MpMisc.UcbPool, MpMisc.frameSamples, 0, MP_FMT_T12);
		}
		MpBuf_insertSawTooth(out);
		MpBuf_setSpeech(out, 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 (NULL == out) 
			{
				out = MpBuf_getBuf(MpMisc.UcbPool, MpMisc.frameSamples, 0, MP_FMT_T12);
			}
			
			if (NULL != out) 
			{
	            int n = 0;
				Sample* s = NULL;

				s = MpBuf_getSamples(out);
				n = MpBuf_getNumSamples(out);
				
				s_fnMicDataHook(n, s) ;

				MpBuf_setSpeech(out, MP_SPEECH_UNKNOWN);
				MpBuf_isActiveAudio(out);
			}
		}

		if (NULL == out)
		{
			out = MpBuf_getFgSilence();
		}
	}

	*outBufs = out;

	return TRUE;
}
Пример #4
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;
}
Пример #5
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;
}
Пример #6
0
static WAVEHDR* outPrePrep(int n, DWORD bufLen)
{
   WAVEHDR* pWH;
   int doAlloc = (hOutHdr[n] == NULL);
   MpBufferMsg* msg;
   MpBufferMsg* pFlush;
   MpBufPtr     ob;

   static int oPP = 0;
   static MpBufPtr prev = NULL; // prev is for future concealment use
   static int concealed = 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 && MprToSpkr::MAX_SPKR_BUFFERS < MpMisc.pSpkQ->numMsgs()) {
      OsStatus  res;
      flushes++;
      res = MpMisc.pSpkQ->receive((OsMsg*&) pFlush, OsTime::NO_WAIT);
      if (OS_SUCCESS == res) {
         MpBuf_delRef(pFlush->getTag());
         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 && (skip == 0) && (MprToSpkr::MIN_SPKR_BUFFERS > MpMisc.pSpkQ->numMsgs())) {
      skip = MprToSpkr::SKIP_SPKR_BUFFERS;
      assert(MprToSpkr::MAX_SPKR_BUFFERS >= skip);
#ifdef DEBUG_WINDOZE /* [ */
      osPrintf("Skip(%d,%d)\n", skip, oPP);
#endif /* DEBUG_WINDOZE ] */
   }

   ob = NULL;
   if (0 == skip) {
      if (MpMisc.pSpkQ && OS_SUCCESS == MpMisc.pSpkQ->receive((OsMsg*&)msg, OsTime::NO_WAIT)) {
         ob = msg->getTag();
         msg->releaseMsg();
      }
   } else {
      if (MpMisc.pSpkQ && MpMisc.pSpkQ->numMsgs() >= skip) skip = 0;
   }

   if (NULL == ob) {
      ob = conceal(prev, concealed);
      concealed++;
   } else {
      concealed = 0;
   }

   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, MpBuf_getSamples(ob), bufLen);
   MpBuf_delRef(prev);
   prev = ob;
   return pWH;
}