UtlBoolean MprToneGen::doProcessFrame(MpBufPtr inBufs[], MpBufPtr outBufs[], int inBufsSize, int outBufsSize, UtlBoolean isEnabled, int samplesPerFrame, int samplesPerSecond) { MpBufPtr out = NULL; int16_t *outbuf; int count; OsStatus ret; if (0 == outBufsSize) return FALSE; *outBufs = NULL; if (0 == samplesPerFrame) return FALSE; if (isEnabled) { out = MpBuf_getBuf(MpMisc.UcbPool, samplesPerFrame, 0, MP_FMT_T12); assert(NULL != out); count = min(samplesPerFrame, MpBuf_getNumSamples(out)); MpBuf_setNumSamples(out, count); outbuf = (int16_t*)MpBuf_getSamples(out); ret = MpToneGen_getNextBuff(mpToneGenState, outbuf, count); switch (ret) { case OS_WAIT_TIMEOUT: /* one-shot tone completed */ ((MpCallFlowGraph*)getFlowGraph())->stopTone(); MpBuf_setSpeech(out, MP_SPEECH_TONE); break; case OS_NO_MORE_DATA: /* silent */ MpBuf_delRef(out); out = NULL; // Will replace with silence before returning... break; case OS_SUCCESS: default: MpBuf_setSpeech(out, MP_SPEECH_TONE); break; } } else { if (0 < inBufsSize) out = *inBufs; *inBufs = NULL; } if (NULL == out) { out = MpBuf_getFgSilence(); } *outBufs = out; return (NULL != mpToneGenState); }
MpBufSpeech MpBuf_doVAD(MpBufPtr buf) { int num, i = 1; Sample prev; Sample* data; unsigned long energy = 0; unsigned long t; MpBufSpeech ret = MP_SPEECH_SILENT; assert(!MpBuf_invalid(buf, FALSE, TRUE)); num = MpBuf_getNumSamples(buf); data = MpBuf_getSamples(buf); while ((i < num) && (MP_SPEECH_SILENT == ret)) { i++; prev = *data++; t = (prev - *data) >> 1; energy += t * t; if (energy >= MinVoiceEnergy) ret = MP_SPEECH_ACTIVE; } #ifdef DEBUG if (20 > numVads++) osPrintf(" %d %ld\n", i, energy); #endif MpBuf_setSpeech(buf, ret); 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; }
OsStatus MpBuf_init(int samplesPerFrame, int numAudioBuffers) { LowBufTable = 0xffffffff; HighBufTable = 0; #ifdef BUFFER_INSTRUMENTATION /* [ */ spCounterMutex = new OsMutex(OsMutex::Q_PRIORITY); #endif /* BUFFER_INSTRUMENTATION ] */ MpMisc.UcbPool = MpBufPool_MpBufPool(0, samplesPerFrame*sizeof(Sample), numAudioBuffers, 0); Nprintf("MpBuf_init: MpMisc.UcbPool = 0x%X\n", (int) MpMisc.UcbPool, 0,0,0,0,0); if (NULL == MpMisc.UcbPool) { return OS_NO_MEMORY; } MpMisc.DMAPool = MpBufPool_MpBufPool(0, 8*samplesPerFrame*sizeof(Sample), 64, 32); Nprintf("MpBuf_init: MpMisc.DMAPool = 0x%X\n", (int) MpMisc.DMAPool, 0,0,0,0,0); if (NULL == MpMisc.DMAPool) { return OS_NO_MEMORY; } /*************************************************************************/ /* * Go get a buffer and fill with silence. We will use this for muting * either or both of input and output, and whenever we are starved for * audio data. */ #ifdef N_SPARE_BUFS /* [ */ /* For debugging... get a few buffers and set them aside... */ { MpBufPtr sb; int i, j, n; Sample* dst; for (i=0; i<N_SPARE_BUFS; i++) { sb = MpBuf_getBuf(MpMisc.UcbPool, samplesPerFrame, 0, MP_FMT_T12); if (NULL == sb) { Zprintf("\n\nMpBuf_init: MpBuf_getBuf failed, quitting!\n\n\n", 0,0,0,0,0,0); MpBufPool_delete(MpMisc.UcbPool, 1); MpMisc.UcbPool = NULL; return OS_LIMIT_REACHED; } dst = MpBuf_getSamples(sb); n = MpBuf_getByteLen(sb) / sizeof(Sample); MpBuf_setNumSamples(sb, n); for (j=0; j<n; j++) { *dst++ = (i<<8) + j; } MpBuf_setSpeech(sb, (enum MpBufSpeech) MP_SPEECH_SPARE); spareBufs[i] = sb; } showSpareBufs(0, "MpBuf_Init: "); } #endif /* N_SPARE_BUFS ] */ { MpBufPtr sb; sb = MpBuf_getBuf(MpMisc.UcbPool, samplesPerFrame, 0, MP_FMT_T12); if (NULL == sb) { Zprintf("\n\nMpBuf_init: MpBuf_getBuf failed, quitting!\n\n\n", 0,0,0,0,0,0); MpBufPool_delete(MpMisc.UcbPool, 1); MpMisc.UcbPool = NULL; return OS_LIMIT_REACHED; } memset(MpBuf_getSamples(sb), 0, MpBuf_getByteLen(sb)); MpBuf_setSpeech(sb, MP_SPEECH_SILENT); MpMisc.XXXsilence = sb; Zprintf("MpBuf_init: MpMisc.silence = 0x%X\n", (int) MpMisc.XXXsilence, 0,0,0,0,0); } /*************************************************************************/ /* * Go get a DMA buffer and fill with silence. We will use this for muting * either or both of input and output, and whenever we are starved for * audio data. */ { MpBufPtr sb; sb = MpBuf_getBuf(MpMisc.DMAPool, 8*samplesPerFrame, 0, MP_FMT_T12); if (NULL == sb) { Zprintf("\n\nMpBuf_init: MpBuf_getBuf failed (DMA), quitting!\n\n\n", 0,0,0,0,0,0); MpBufPool_delete(MpMisc.DMAPool, 1); MpMisc.DMAPool = NULL; return OS_LIMIT_REACHED; } memset(MpBuf_getSamples(sb), 0, MpBuf_getByteLen(sb)); MpBuf_setSpeech(sb, MP_SPEECH_SILENT); MpMisc.XXXlongSilence = sb; Zprintf("MpBuf_init: MpMisc.longSilence = 0x%X\n", (int) MpMisc.XXXlongSilence, 0,0,0,0,0); } /*************************************************************************/ /* * generate a buffer called comfort noise buffer. Even though the zero * initiation is not necessary, we do it as the silence buffer for safety. */ { MpBufPtr cnb; cnb = MpBuf_getBuf(MpMisc.UcbPool, samplesPerFrame, 0, MP_FMT_T12); if (NULL == cnb) { Zprintf("\n\nMpBuf_init: MpBuf_getBuf failed, quitting!\n\n\n", 0,0,0,0,0,0); MpBufPool_delete(MpMisc.UcbPool, 1); MpMisc.UcbPool = NULL; return OS_LIMIT_REACHED; } memset(MpBuf_getSamples(cnb), 0, MpBuf_getByteLen(cnb)); MpBuf_setSpeech(cnb, MP_SPEECH_COMFORT_NOISE); MpMisc.comfortNoise = cnb; Zprintf("MpBuf_init: MpMisc.comfortNoise = 0x%X\n", (int) MpMisc.comfortNoise, 0,0,0,0,0); } /*************************************************************************/ MpMisc.RtpPool = MpBufPool_MpBufPool(0, NETWORK_MTU, rtpNBufs, 0); Nprintf("MpBuf_init: MpMisc.RtpPool = 0x%X\n", (int) MpMisc.RtpPool, 0,0,0,0,0); if (NULL == MpMisc.RtpPool) { MpBufPool_delete(MpMisc.UcbPool, 1); MpMisc.UcbPool = NULL; return OS_NO_MEMORY; } MpMisc.RtcpPool = MpBufPool_MpBufPool(0, MAX_RTCP_PACKET_LEN, rtcpNBufs, 0); Nprintf("MpBuf_init: MpMisc.RtcpPool = 0x%X\n", (int) MpMisc.RtcpPool, 0,0,0,0,0); if (NULL == MpMisc.RtcpPool) { MpBufPool_delete(MpMisc.UcbPool, 1); MpMisc.UcbPool = NULL; MpBufPool_delete(MpMisc.RtpPool, 1); MpMisc.RtpPool = NULL; return OS_NO_MEMORY; } return OS_SUCCESS; }
UtlBoolean MprFromStream::doProcessFrame(MpBufPtr inBufs[], MpBufPtr outBufs[], int inBufsSize, int outBufsSize, UtlBoolean isEnabled, int samplesPerFrame, int samplesPerSecond) { UtlBoolean bSentData = FALSE ; MpBufPtr out = NULL; Sample *outbuf; int count; // Check params for sanity if (0 == outBufsSize) return FALSE; *outBufs = NULL; if (0 == samplesPerFrame) return FALSE; if (isEnabled) { // Get ready to give data out = MpBuf_getBuf(MpMisc.UcbPool, samplesPerFrame, 0, MP_FMT_T12); assert(NULL != out); count = MpBuf_getByteLen(out) / sizeof(Sample); count = min(samplesPerFrame, count); MpBuf_setNumSamples(out, count); if (mpStreamRenderer) { mbStreamChange = FALSE ; if (!mpStreamRenderer->isMarkedPaused()) { MpBuf_setSpeech(out, MP_SPEECH_TONE); outbuf = MpBuf_getSamples(out); if (mpStreamRenderer->getFrame((uint16_t*)outbuf) == OS_SUCCESS) { bSentData = TRUE ; if (mEventState != FeederStreamPlayingEvent) { #ifdef MP_STREAM_DEBUG /* [ */ osPrintf("MprFromStream: FeederEvent=FeederStreamPlayingEvent\n") ; #endif /* MP_STREAM_DEBUG ] */ mEventState = FeederStreamPlayingEvent ; mpStreamRenderer->fromStreamUpdate(FeederStreamPlayingEvent) ; } } else { if ( (mEventState != FeederStreamStoppedEvent) && (mEventState != FeederStreamAbortedEvent)) { #ifdef MP_STREAM_DEBUG /* [ */ osPrintf("MprFromStream: FeederEvent=FeederStreamStoppedEvent\n") ; #endif /* MP_STREAM_DEBUG ] */ mEventState = FeederStreamStoppedEvent ; mpStreamRenderer->fromStreamUpdate(FeederStreamStoppedEvent) ; } disable(); } } else { if (mEventState != FeederStreamPausedEvent) { #ifdef MP_STREAM_DEBUG /* [ */ osPrintf("MprFromStream: FeederEvent=FeederStreamPausedEvent\n") ; #endif /* MP_STREAM_DEBUG ] */ mEventState = FeederStreamPausedEvent ; mpStreamRenderer->fromStreamUpdate(FeederStreamPausedEvent) ; } } } if (!bSentData) { outbuf = MpBuf_getSamples(out); memset(outbuf, 0, MpBuf_getByteLen(out)); MpBuf_setSpeech(out, MP_SPEECH_SILENT); } } if (NULL == out) { out = *inBufs; *inBufs = NULL; } *outBufs = out; return (TRUE); }
UtlBoolean MprDecode::doProcessFrame(MpBufPtr inBufs[], MpBufPtr outBufs[], int inBufsSize, int outBufsSize, UtlBoolean isEnabled, int samplesPerFrame, int samplesPerSecond) { #ifdef DEBUG_DECODING /* [ */ static int numFramesForWarnings = 0; static int numWarnings = 0; #endif /* DEBUG_DECODING ] */ MpBufPtr rtp; MpBufPtr out; #ifdef DEBUG_DECODING /* [ */ numFramesForWarnings++; #endif /* DEBUG_DECODING ] */ MpDecoderBase* pCurDec; Sample* pSamples = NULL; mFrameCounter++; if (0 == outBufsSize) return FALSE; if (!isEnabled) { mPreloading = 1; *outBufs = MpBuf_getFgSilence(); return TRUE; } { MprDejitter* pDej = getMyDejitter(); int packetLen; int pt; while (NULL != (rtp = pDej->pullPacket())) { pt = MprDejitter::getPayloadType(rtp); pCurDec = mpConnection->mapPayloadType(pt); if (NULL != pCurDec) { unsigned char* pRtpH; pRtpH = ((unsigned char*) MpBuf_getStorage(rtp)) + 1; if (0x80 == (0x80 & *pRtpH)) { if ((mFrameLastMarkerNotice + MARKER_WAIT_FRAMES) < mFrameCounter) { mNumMarkerNotices = 0; } if (mNumMarkerNotices++ < MAX_MARKER_NOTICES) { // osPrintf("MprDecode: RTP marker bit ON\n"); mFrameLastMarkerNotice = mFrameCounter; } } packetLen = pCurDec->decodeIn(rtp); if (packetLen > 0) { pushIntoJitterBuffer(rtp, packetLen); } } MpBuf_delRef(rtp); } } out = MpBuf_getBuf(MpMisc.UcbPool, samplesPerFrame, 0, MP_FMT_T12); if (out) { pSamples = MpBuf_getSamples(out); memset(pSamples, 0, samplesPerFrame * sizeof(Sample)); MpBuf_setSpeech(out, MP_SPEECH_SILENT); } JB_inst* pJBState = mpConnection->getJBinst(); if (pJBState) { // This should be a JB_something or other. However the only // current choices is a short or long equivalant and this needs // to be a plain old int: int outLen; int res; res = JB_RecOut(pJBState, pSamples, &outLen); MpBuf_setSpeech(out, MP_SPEECH_UNKNOWN); } *outBufs = out; Nprintf("Decode_doPF: returning 0x%p\n", out, 0,0,0,0,0); return TRUE; }