void MpBuf_close() { #ifdef BUFFER_INSTRUMENTATION /* [ */ delete spCounterMutex; spCounterMutex = NULL; #ifdef _VXWORKS /* [ */ StartLogging(); #endif /* _VXWORKS ] */ dumpBufs(1); #ifdef _VXWORKS /* [ */ while (0<msgQNumMsgs(MpMisc.LogQ)) taskDelay(1); taskDelay(12); #endif /* _VXWORKS ] */ #endif /* BUFFER_INSTRUMENTATION ] */ MpBuf_delRef(MpMisc.XXXsilence); MpMisc.XXXsilence = NULL; MpBuf_delRef(MpMisc.XXXlongSilence); MpMisc.XXXlongSilence = NULL; MpBufPool_delete(MpMisc.UcbPool, TRUE); MpMisc.UcbPool = NULL; MpBufPool_delete(MpMisc.RtpPool, TRUE); MpMisc.RtpPool = NULL; MpBufPool_delete(MpMisc.RtcpPool, TRUE); MpMisc.RtcpPool = NULL; MpBufPool_delete(MpMisc.DMAPool, TRUE); MpMisc.DMAPool = NULL; }
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)) { MpBuf_delRef(pMsg->getTag()); MpBuf_delRef(pMsg->getTag(1)); pMsg->releaseMsg(); } } return save; }
//Add a buffer containing an incoming RTP packet to the dejitter pool OsStatus MprDejitter::pushPacket(MpBufPtr pRtp) { int index; MpBuf_touch(pRtp); mRtpLock.acquire(); index = getSeqNum(pRtp) % MAX_RTP_PACKETS; if (NULL != mpPackets[index]) { mNumDiscarded++; #ifdef MP_STREAM_DEBUG /* [ */ if (mNumDiscarded < 40) { osPrintf("Dej: discard#%d Seq: %d -> %d at 0x%X\n", mNumDiscarded, getSeqNum(mpPackets[index]), getSeqNum(pRtp), *pOsTC); } #endif /* MP_STREAM_DEBUG ] */ MpBuf_delRef(mpPackets[index]); mpPackets[index] = NULL; mNumPackets--; } mpPackets[index] = pRtp; mNumPackets++; mRtpLock.release(); return OS_SUCCESS; }
MpBufPtr MpBuf_allowMods(MpBufPtr b) { MpBufPtr t; if (NULL == b) { return NULL; } if (MpBuf_invalid(b, FALSE, TRUE)) { Zprintf("MpBuf_allowMod(0x%X): invalid!\n", (int) b, 0,0,0,0,0); return NULL; } if (1 == b->refCnt) { return b; } t = MpBuf_getBuf(b->pPool, MpBuf_getNumSamples(b), MpBuf_getOffset(b), MpBuf_getFormat(b)); if (NULL == t) { return NULL; } memcpy((void*) MpBuf_getSamples(t), (void*) MpBuf_getSamples(b), MpBuf_getByteLen(t)); MpBuf_setOsTC(t, MpBuf_getOsTC(b)); MpBuf_setContentLen(t, MpBuf_getContentLen(b)); MpBuf_delRef(b); return t; } /* MpBuf_allowMods */
// Destructor MprDejitter::~MprDejitter() { int i; mRtpLock.acquire(); for (i=0; i<MAX_RTP_PACKETS; i++) { MpBuf_delRef(mpPackets[i]); mpPackets[i] = NULL; } mRtpLock.release(); }
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); }
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 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; }
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; }
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; }