OsStatus MpBuf_setContentLen(MpBufPtr b, int numBytes) { if (MpBuf_invalid(b, TRUE, TRUE)) { return OS_INVALID_ARGUMENT; } if ((numBytes < 0) || (numBytes > MpBuf_getByteLen(b))) { Zprintf("MpBuf_setContentLen(0x%X, %d): contentLen invalid (max=%d)\n", (int) b, numBytes, MpBuf_getByteLen(b), 0,0,0); return OS_INVALID_ARGUMENT; } b->contentLen = numBytes; 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 */
OsStatus MpBuf_setNumSamples(MpBufPtr b, int num) { if (MpBuf_invalid(b, TRUE, TRUE)) { return OS_INVALID_ARGUMENT; } if ((num < 0) || (num > MpBuf_getByteLen(b))) { Zprintf("MpBuf_setNumSamples(0x%X, %d): numSamples invalid (max=%d)\n", (int) b, num, MpBuf_getByteLen(b), 0,0,0); return OS_INVALID_ARGUMENT; } // $$$ Should we make sure that the num is consistent with the // alignment requirements of the payload type? b->numSamples = num; return OS_SUCCESS; }
OsStatus MpBuf_setOffset(MpBufPtr b, int offset) { if (MpBuf_invalid(b, TRUE, TRUE)) { return OS_INVALID_ARGUMENT; } if ((offset < 0) || (offset > MpBuf_getByteLen(b))) { Zprintf("MpBuf_setOffset(0x%X, %d): Offset invalid (max=%d)\n", (int) b, offset, MpBuf_getByteLen(b), 0,0,0); return OS_INVALID_ARGUMENT; } // $$$ Should we make sure that the offset is consistent with the // alignment requirements of the payload type? b->pSamples = (Sample *) (MpBuf_getStorage(b) + offset); b->offset = offset; return OS_SUCCESS; }
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; }
/*************************************************************************/ 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; } #ifdef BUFFER_INSTRUMENTATION /* [ */ volatile int bufHang, doHang = 1; int we_are_logging = 0; int bufUnHang(int x) { int was = bufHang; bufHang = 0; doHang = x; return was; } int forceLogging(int on) { int was = we_are_logging; we_are_logging = on; return was; } int incr_time_stamp() { OsLock lock(*spCounterMutex); return buffer_time_stamp++; } #endif /* BUFFER_INSTRUMENTATION ] */ void MpBuf_insertSawTooth(MpBufPtr b) { int i, n; Sample *s; if (NULL == b) return; if (!MpBuf_invalid(b, TRUE, TRUE)) { s = MpBuf_getSamples(b); n = MpBuf_getNumSamples(b); for (i=0; i<n; i++) *s++ = ((0xf & i) << 12); } } #ifdef BUFFER_INSTRUMENTATION /* [ */ MpBufPtr MpBuf_getBufX(MpBufPoolPtr Pool, int initSamples, int initOffset, MpBufFormat initFormat, int line) #else /* BUFFER_INSTRUMENTATION ] [ */ MpBufPtr MpBuf_getBufY(MpBufPoolPtr Pool, int initSamples, int initOffset, MpBufFormat initFormat) #endif /* BUFFER_INSTRUMENTATION ] */ { int i; int n; MpBufPtr ret, t; MpBufPoolPtr l = Pool; OsLock lock(*(Pool->mpMutex)); #ifdef BUFFER_INSTRUMENTATION /* [ */ int this_time = incr_time_stamp(); #endif /* BUFFER_INSTRUMENTATION ] */ ret = NULL; n = l->lastTaken; t = &(l->table[n]); for (i=0; ((NULL==ret) && (i<l->allocCnt)); i++) { if (n >= l->allocCnt) { n = 0; t = l->table; } if (0 == t->status) { n++; if (n >= l->allocCnt) { n = 0; } l->lastTaken = n; ret = t; ret->status = 1; ret->speech = MP_SPEECH_UNKNOWN; ret->refCnt = 1; MpBuf_setFormat(ret, initFormat); MpBuf_setOffset(ret, initOffset); MpBuf_setNumSamples(ret, initSamples); MpBuf_setOsTC(ret, 0); #define CLEAR_BUFFER #undef CLEAR_BUFFER #ifdef CLEAR_BUFFER /* [ */ memset(MpBuf_getStorage(ret), 0, MpBuf_getByteLen(ret)); #endif /* CLEAR_BUFFER ] */ #define INSERT_SAWTOOTH #undef INSERT_SAWTOOTH #ifdef INSERT_SAWTOOTH /* [ */ MpBuf_insertSawTooth(ret); #endif /* INSERT_SAWTOOTH ] */ #ifdef BUFFER_INSTRUMENTATION /* [ */ ret->line_taken = line; ret->time_taken = this_time; #endif /* BUFFER_INSTRUMENTATION ] */ } t++; n++; } #ifdef BUFFER_INSTRUMENTATION /* [ */ if (NULL != ret) l->nfree--; if (l->nfree < l->minfree) { l->minfree = l->nfree; if (2 < (l->allocCnt)) { showBufs(Pool, line); } if (15 < (l->allocCnt - l->nfree)) { /* dumpBufs(0); */ } } #endif /* BUFFER_INSTRUMENTATION ] */ Nprintf(" +%02d(%d)\n", i-1, line, 0,0,0,0); Nprintf("take: 0x%08X (%d), at %d\n", (int) ret, i-1, line, 0,0,0); /* printf("take: 0x%08X (%d)\n", (int) ret, i-1); */ return ret; }
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); }