MpBufSpeech MpBuf_checkSpeech(MpBufPtr buf) { MpBufSpeech ret = MpBuf_getSpeech(buf); switch (ret) { case MP_SPEECH_UNKNOWN: // call silence_detection on buf, then call MpBuf_setSpeech(buf, result) // ret = MP_SPEECH_ACTIVE; Should do this, given no silence detector??? break; case MP_SPEECH_SILENT: case MP_SPEECH_COMFORT_NOISE: case MP_SPEECH_ACTIVE: case MP_SPEECH_TONE: break; case MP_SPEECH_MUTED: // maybe call silence_detection on buf, to update background stats ret = MP_SPEECH_SILENT; break; } return ret; }
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; }
UtlBoolean MprBridge::doProcessFrame(MpBufPtr inBufs[], MpBufPtr outBufs[], int inBufsSize, int outBufsSize, UtlBoolean isEnabled, int samplesPerFrame, int samplesPerSecond) { int i; int inIdx; int outIdx; int n; int scale; int inputs; int N = samplesPerFrame; MpBufPtr in; MpBufPtr out; Sample* input; Sample* output; Sample* outstart; if (0 == outBufsSize) { Zprintf("MprBridge::doPF: outBufsSize = %d! (inBufsSize=%d)\n", outBufsSize, inBufsSize, 0,0,0,0); return FALSE; } if (inBufsSize != outBufsSize) { Zprintf("MprBridge::doPF: outBufsSize(%d) != inBufsSize(%d)\n", outBufsSize, inBufsSize, 0,0,0,0); return FALSE; } if (0 == inBufsSize) return FALSE; // no input buffers, not allowed for (i=0; i < outBufsSize; i++) { outBufs[i] = NULL; } if (!isEnabled) { // Disabled. Mix all remote inputs onto local speaker, and copy // our local microphone to all remote outputs. // First, count how many contributing inputs inputs = 0; for (inIdx=1; inIdx < inBufsSize; inIdx++) { if (isPortActive(inIdx)) { if((MpBuf_getSpeech(inBufs[inIdx]) != MP_SPEECH_SILENT) && (MpBuf_getSpeech(inBufs[inIdx]) != MP_SPEECH_COMFORT_NOISE)) inputs++; } } if (inputs > 0) { // Compute a scale factor to renormalize (approximately) scale = 0; while (inputs > 1) { scale++; inputs = inputs >> 1; } out = MpBuf_getBuf(MpMisc.UcbPool, N, 0, MP_FMT_T12); if (NULL == out) { Zprintf( "MprBridge::doPF(line #%d): MpBuf_getBuf() returned NULL!\n", __LINE__, 0,0,0,0,0); return FALSE; } outstart = MpBuf_getSamples(out); memset((char *) outstart, 0, N * sizeof(Sample)); for (inIdx=1; inIdx < inBufsSize; inIdx++) { if (isPortActive(inIdx)) { output = outstart; //Mix only non-silent audio if((MpBuf_getSpeech(inBufs[inIdx]) != MP_SPEECH_COMFORT_NOISE) && (MpBuf_getSpeech(inBufs[inIdx]) != MP_SPEECH_SILENT) ) { input = MpBuf_getSamples(inBufs[inIdx]); n = min(MpBuf_getNumSamples(inBufs[inIdx]), samplesPerFrame); for (i=0; i<n; i++) *output++ += (*input++) >> scale; } } }