OsStatus mpStartUp(int sampleRate, int samplesPerFrame, int numAudioBuffers, OsConfigDb* pConfigDb, const size_t numCodecPaths, const UtlString codecPaths[]) { // TODO: // This should be broken down into separate arguments for: // Max number of flowgraphs // Max number of calls // Max calls/streams per flowgraph // Buffers used/stream or used/flowgraph // Approximate based upon current media interface initialization int maxCalls = numAudioBuffers / 16; #ifdef _VXWORKS int defSilenceSuppressLevel = 10000; #else int defSilenceSuppressLevel = 0; #endif OsStatus resCode; UtlBoolean silenceSuppressFlag; UtlString silenceSuppressEnable; int silenceSuppressLevel; assert(samplesPerFrame >= 8); showMpMisc(TRUE); RTL_START(100000000); setExternalRtlCollector(sRealtimeLogCollector); // First initialize static codecs mpStaticCodecInitializer(); MpCodecFactory* pcf = MpCodecFactory::getMpCodecFactory(); if(numCodecPaths != 0) { size_t i; for(i = 0; i < numCodecPaths; i++) { pcf->loadAllDynCodecs(codecPaths[i].data(), CODEC_PLUGINS_FILTER); } } else { pcf->loadAllDynCodecs(CODEC_PLUGIN_PATH, CODEC_PLUGINS_FILTER); } #ifdef _VXWORKS /* [ */ /* Rashly assumes page size is a power of two */ MpMisc.mem_page_size = goGetThePageSize(); MpMisc.mem_page_mask = MpMisc.mem_page_size - 1; #endif /* _VXWORKS ] */ MpMisc.sampleBytes = sizeof(MpAudioSample); MpMisc.frameSamples = samplesPerFrame; MpMisc.frameBytes = MpMisc.sampleBytes * MpMisc.frameSamples; MpMisc.rtpMaxBytes = /* sizeof(struct RtpHeader) */ 12 + (((sampleRate + 24) / 25) * MpMisc.sampleBytes); // Create buffer for audio data in mediagraph MpMisc.RawAudioPool = new MpBufPool( samplesPerFrame*sizeof(MpAudioSample) + MpArrayBuf::getHeaderSize(), numAudioBuffers, "RawAudioPool"); Nprintf( "mpStartUp: MpMisc.RawAudioPool = 0x%X\n" , (int) MpMisc.RawAudioPool, 0,0,0,0,0); if (NULL == MpMisc.RawAudioPool) { return OS_NO_MEMORY; } // Create buffer for audio headers int audioBuffers = MpMisc.RawAudioPool->getNumBlocks(); MpMisc.AudioHeadersPool = new MpBufPool(sizeof(MpAudioBuf), audioBuffers, "AudioHeadersPool"); Nprintf( "mpStartUp: MpMisc.AudioHeadersPool = 0x%X\n" , (int) MpMisc.AudioHeadersPool, 0,0,0,0,0); if (NULL == MpMisc.AudioHeadersPool) { // TODO:: Think about proper resource deallocation on fail in mpStartUp() return OS_NO_MEMORY; } MpAudioBuf::smpDefaultPool = MpMisc.AudioHeadersPool; /* * 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. */ { MpAudioBufPtr sb = MpMisc.RawAudioPool->getBuffer(); if (!sb.isValid()) { Zprintf("\n\mpStartUp:" " MpBufPool::getBuffer() failed, quitting!\n\n\n", 0,0,0,0,0,0); delete MpMisc.RawAudioPool; MpMisc.RawAudioPool = NULL; return OS_LIMIT_REACHED; } sb->setSamplesNumber(samplesPerFrame); memset(sb->getSamplesWritePtr(), 0, sb->getSamplesNumber()*sizeof(MpAudioSample)); sb->setSpeechType(MP_SPEECH_SILENT); MpMisc.mpFgSilence = sb; Zprintf("mpStartUp: MpMisc.silence = 0x%X\n", (int) MpMisc.mpFgSilence, 0,0,0,0,0); }
OsStatus mpStartUp(int sampleRate, int samplesPerFrame, int numAudioBuffers, OsConfigDb* pConfigDb) { #ifdef _VXWORKS int defSilenceSuppressLevel = 10000; #else int defSilenceSuppressLevel = 0; #endif OsStatus resCode; UtlBoolean silenceSuppressFlag; UtlString silenceSuppressEnable; int silenceSuppressLevel; if (samplesPerFrame < 8) samplesPerFrame = 80; samplesPerFrame = min(samplesPerFrame, FRAME_SAMPS); showMpMisc(TRUE); MpMisc.micMuteStatus = MpMisc.spkrMuteStatus = 0; #ifdef _VXWORKS /* [ */ /* Rashly assumes page size is a power of two */ MpMisc.mem_page_size = goGetThePageSize(); MpMisc.mem_page_mask = MpMisc.mem_page_size - 1; #endif /* _VXWORKS ] */ MpMisc.sampleBytes = sizeof(short); MpMisc.frameSamples = samplesPerFrame; MpMisc.frameBytes = MpMisc.sampleBytes * MpMisc.frameSamples; MpMisc.rtpMaxBytes = /* sizeof(struct rtpHeader) */ 12 + (((sampleRate + 24) / 25) * MpMisc.sampleBytes); MpMisc.audio_on = 0; if (OS_SUCCESS != MpBuf_init(samplesPerFrame, numAudioBuffers)) { return OS_UNSPECIFIED; } // Use the config database to determine the silence supression level silenceSuppressFlag = FALSE; silenceSuppressLevel = defSilenceSuppressLevel; if (pConfigDb) { resCode = pConfigDb->get("PHONESET_SILENCE_SUPPRESSION", silenceSuppressEnable); if (resCode == OS_SUCCESS) { silenceSuppressFlag = (silenceSuppressEnable.compareTo("enable", UtlString::ignoreCase) == 0); } resCode = pConfigDb->get("PHONESET_SILENCE_SUPPRESSION_LEVEL", silenceSuppressLevel); if ((resCode != OS_SUCCESS) || (silenceSuppressLevel < 0) || (silenceSuppressLevel > 20000)) { silenceSuppressLevel = defSilenceSuppressLevel; } } if (silenceSuppressFlag) MpBuf_setMVE(silenceSuppressLevel); else MpBuf_setMVE(0); #ifdef WIN32 /* [ */ // Adjust initial audio latency if specified in config files: if (pConfigDb) { UtlString latency; static const int MS_PER_FRAME = 10; int frames; resCode = pConfigDb->get("PHONESET_INITIAL_OUTPUT_LATENCY_MS", latency); if (resCode == OS_SUCCESS) { frames = atoi(latency.data()) / MS_PER_FRAME; DmaTask_setSpkrQPreload(frames); } resCode = pConfigDb->get("PHONESET_INITIAL_INPUT_LATENCY_MS", latency); if (resCode == OS_SUCCESS) { frames = atoi(latency.data()) / MS_PER_FRAME; DmaTask_setMicQPreload(frames); } } #endif /* WIN32 ] */ #ifdef _VXWORKS /* [ */ if (OS_SUCCESS != MpCodecOpen(sampleRate, START_GAIN, START_VOLUME)) { return OS_UNSPECIFIED; } #endif /* _VXWORKS ] */ if (NULL != MpMisc.pMicQ) { OsMsgQ* q = MpMisc.pMicQ; MpMisc.pMicQ = NULL; delete q; } if (NULL != MpMisc.pSpkQ) { OsMsgQ* q = MpMisc.pSpkQ; MpMisc.pSpkQ = NULL; delete q; } if (NULL != MpMisc.pEchoQ) { OsMsgQ* q = MpMisc.pEchoQ; MpMisc.pEchoQ = NULL; delete q; } #ifdef _VXWORKS /* [ */ if (NULL != MpMisc.pLoopBackQ) { OsMsgQ* q = MpMisc.pLoopBackQ; MpMisc.pLoopBackQ = NULL; delete q; } #endif /* _VXWORKS ] */ assert( (MIC_BUFFER_Q_LEN+SPK_BUFFER_Q_LEN+MIC_BUFFER_Q_LEN) < (MpBufPool_getNumBufs(MpMisc.UcbPool)-3)); MpMisc.pMicQ = new OsMsgQ("mpStartUp::MpMisc.pMicQ", MIC_BUFFER_Q_LEN); MpMisc.pSpkQ = new OsMsgQ("mpStartUp::MpMisc.pSpkQ", SPK_BUFFER_Q_LEN); MpMisc.pEchoQ = new OsMsgQ("mpStartUp::MpMisc.pEchoQ", MIC_BUFFER_Q_LEN); #ifdef _VXWORKS /* [ */ MpMisc.doLoopBack = 0; MpMisc.pLoopBackQ = new OsMsgQ("mpStartUp::MpMisc.pLoopBackQ", MIC_BUFFER_Q_LEN); #endif /* _VXWORKS ] */ assert(MprFromMic::MAX_MIC_BUFFERS > 0); assert(MprToSpkr::MAX_SPKR_BUFFERS > 0); assert(MprDecode::MIN_RTP_PACKETS > 0); setMaxMic(MprFromMic::MAX_MIC_BUFFERS - 1); setMaxSpkr(MprToSpkr::MAX_SPKR_BUFFERS); setMinRtp(MprDecode::MIN_RTP_PACKETS); mpStopSawTooth(); return OS_SUCCESS; }