Example #1
0
UtlBoolean MpBuf_isActiveAudio(MpBufPtr buf)
{
   MpBufSpeech speech;
   UtlBoolean ret = TRUE;

   assert(!MpBuf_invalid(buf, FALSE, TRUE));

   if (MpBuf_isPoolSilent(buf)) {
      return FALSE;
   }

   speech = MpBuf_getSpeech(buf);
   switch (speech) {
   case MP_SPEECH_UNKNOWN:
      MpBuf_doVAD(buf);
      speech = MpBuf_getSpeech(buf);
      assert(MP_SPEECH_UNKNOWN != speech);
      ret = MpBuf_isActiveAudio(buf);
      break;
   case MP_SPEECH_ACTIVE:
   case MP_SPEECH_TONE:
      break;
   case MP_SPEECH_SILENT:
   case MP_SPEECH_COMFORT_NOISE:
   case MP_SPEECH_MUTED:
      ret = FALSE;
      break;
   }
   return ret;
}
Example #2
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;
}
Example #3
0
UtlBoolean MpBuf_isSilence(MpBufPtr buf)
{
   return !MpBuf_isActiveAudio(buf);
}
Example #4
0
UtlBoolean MprRecorder::doProcessFrame(MpBufPtr inBufs[],
                                   MpBufPtr outBufs[],
                                   int inBufsSize,
                                   int outBufsSize,
                                   UtlBoolean isEnabled,
                                   int samplesPerFrame,
                                   int samplesPerSecond)
{
   int numBytes = 0;
   int numSamples = 0;
   MpBufPtr in = NULL;
   Sample* input;

   // Lock so that mFileDescriptor and file contents cannot be changed out
   // from under us while we are updating the file.
   OsLock lock(mMutex);

   //try to pass along first input
   if (inBufsSize > 0)
   {
      in = *inBufs;
   }

   if (numOutputs() > 0)
   {
      if (inBufsSize > 0) *inBufs = NULL;
      *outBufs = in;
   }

   if (!isEnabled) {
      return TRUE;
   }

   if (mFileDescriptor < 0)
   {
      OsSysLog::add(FAC_MP, PRI_DEBUG, "MprRecorder::doProcessFrame to disable recording because mFileDescriptor=%d, mStatus=%d",
            mFileDescriptor, mStatus);
      disable(RECORD_STOPPED); // just in case...
   }

   if (inBufsSize == 0) {
      // no input buffers, indicate config error
      disable(INVALID_SETUP);
      return TRUE;
   }

   // maximum record time reached or final silence timeout.
   if ((0 >= mFramesToRecord--) || (mSilenceLength <= mConsecutiveInactive)) {
      // Get previous MinVoiceEnergy for debug printouts, and reset it to MIN_SPEECH_ENERGY_THRESHOLD.
      unsigned long prevValue = MpBuf_setMVE(MIN_SPEECH_ENERGY_THRESHOLD);

      OsSysLog::add(FAC_MP, PRI_INFO,
         "MprRecorder::doProcessFrame to disable recording because"
         " mFramesToRecord=%d, mStatus=%d mSilenceLength=%d,"
         " mConsecutiveInactive=%d, MinVoiceEnergy=%lu", mFramesToRecord,
         mStatus, mSilenceLength, mConsecutiveInactive, prevValue);
      disable(RECORD_FINISHED);
   } else {

      int bytesWritten = 0;

      //now write the buffer out

      if (NULL == in) {
         in = MpBuf_getFgSilence();
      } else {
        MpBuf_addRef(in);
      }

      if (MpBuf_isActiveAudio(in)) {
        mConsecutiveInactive = 0;
      } else {
        mConsecutiveInactive++;
      }

      input = MpBuf_getSamples(in);
      numSamples = MpBuf_getNumSamples(in);
      numBytes = numSamples * sizeof(Sample);
      if (mFileDescriptor > -1)
      {
#ifdef __BIG_ENDIAN__
         //We are running on a big endian processor - 16-bit samples are in the big endian
         //byte order - convert them to little endian before writing them to the file.
         unsigned short *pData;
         int index;

         for ( index = 0, pData = (unsigned short *)input; index < numSamples; index++, pData++ )
             *pData = htoles(*pData);
#endif
         bytesWritten = write(mFileDescriptor, (char *)input, numBytes);
#ifdef __BIG_ENDIAN__
         if (numOutputs() > 1)
         {
             //There is more than one output - convert the samples back to big endian
             for ( index = 0, pData = (unsigned short *)input; index < numSamples; index++, pData++ )
                 *pData = letohs(*pData);
         }
#endif
      }

      if (bytesWritten != numBytes) {
         disable(WRITE_ERROR);
      } else {
         mTotalBytesWritten += numBytes;
         mTotalSamplesWritten += samplesPerFrame;
      }
      MpBuf_delRef(in);
   }
   return TRUE;
}