// Handle messages for this resource. UtlBoolean MprRecorder::handleSetup(int file, int timeMS, int silenceLength, OsProtectedEvent* event) { int iMsPerFrame = (1000 * getSamplesPerFrame()) / getSamplesPerSec(); if (isEnabled()) { OsSysLog::add(FAC_MP, PRI_DEBUG, "MprRecorder::handleSetup" " -- attempt to setup while enabled!!\n"); return TRUE; } if (timeMS > 0) { mFramesToRecord = timeMS / iMsPerFrame; } else { mFramesToRecord = 2000000000; } if (silenceLength > 0) { mSilenceLength = 1000 * silenceLength / iMsPerFrame; } else { mSilenceLength = 5000 / iMsPerFrame; /*5 seconds */ } unsigned long prevValue = MpBuf_setMVE(MIN_SPEECH_ENERGY_THRESHOLD); // any energy lower than this will be regarded as silence OsSysLog::add(FAC_MP, PRI_INFO, "MprRecorder::handleSetup, set MinVoiceEnergy to %d, was %lu\n", MIN_SPEECH_ENERGY_THRESHOLD, prevValue); { OsLock lock(mMutex); mFileDescriptor = file; mpEvent = event; } mStatus = RECORD_IDLE; OsSysLog::add(FAC_MP, PRI_DEBUG, "MprRecorder::handleSetup(%d, %d, 0x%p)... #frames=%d\n", file, timeMS, event, mFramesToRecord); return TRUE; }
void testToneAuthenticity() { MprToneGen* pToneGen = NULL; OsStatus res; int framesToProcess = 3; // Create the Goertzel DTMF detector -- sample rate and goertzel_n doesn't // really matter here, since we'll be resetting it in the loop. // But to illustrate, here is what should be used for 8khz MpDtmfDetector dtmfDetector(8000, framesToProcess*80); size_t i; for(i = 0; i < sNumRates; i++) { //printf("Testing frequency authenticity at %d Hz\n", sSampleRates[i]); // For this test, we want to modify the sample rate and samples per frame // so we need to de-inititialize what has already been initialized for us // by cppunit, or by a previous loop. tearDown(); // Set the sample rates setSamplesPerSec(sSampleRates[i]); setSamplesPerFrame(sSampleRates[i]/100); dtmfDetector.setSamplesPerSec(sSampleRates[i]); dtmfDetector.setNumProcessSamples(framesToProcess*getSamplesPerFrame()); setUp(); pToneGen = new MprToneGen("MprToneGen", ""); CPPUNIT_ASSERT(pToneGen != NULL); // This sets up to have some input to our resource, and something to collect // output at the end. In case of tone gen, the input doesn't matter, // as it only uses the input when it is in a disabled state (passing // the input directly to output - no changes). setupFramework(pToneGen); // pToneGen enabled, there are buffers on the input 0 CPPUNIT_ASSERT(mpSourceResource->enable()); CPPUNIT_ASSERT(pToneGen->enable()); // Tell our MprToneGen to generate a '4' DTMF tone playing. MprToneGen::startTone("MprToneGen", *(mpFlowGraph->getMsgQ()), '4'); UtlBoolean dtmfDetected = FALSE; int j; for(j = 0; j < framesToProcess; j++) { // Process a frame. res = mpFlowGraph->processNextFrame(); CPPUNIT_ASSERT(res == OS_SUCCESS); // Now analyze the newly processed output. // A new buffer should be generated. CPPUNIT_ASSERT(mpSourceResource->mLastDoProcessArgs.outBufs[0] != mpSinkResource->mLastDoProcessArgs.inBufs[0]); MpAudioBufPtr paBuf = mpSinkResource->mLastDoProcessArgs.inBufs[0]; CPPUNIT_ASSERT(paBuf.isValid()); // SANITY CHECK: Make sure that the number of samples in the // tone gen output frame is equal to the samples per frame that // we set during this run. CPPUNIT_ASSERT_EQUAL(getSamplesPerFrame(), paBuf->getSamplesNumber()); UtlBoolean dtmfDetected = FALSE; // Now grab audio samples and run them through the dtmf detector. unsigned k; for(k = 0; k < paBuf->getSamplesNumber(); k++) { const MpAudioSample* pSamples = paBuf->getSamplesPtr(); dtmfDetected = dtmfDetector.processSample(pSamples[k]); // If we are at the last sample we will process, then, based on how // we configured the dtmf detector, a tone should have been detected. if( k == paBuf->getSamplesNumber()-1 && j == framesToProcess-1) { CPPUNIT_ASSERT_EQUAL(TRUE, dtmfDetected); } else { CPPUNIT_ASSERT_EQUAL(FALSE, dtmfDetected); } } // Free up buffers.. paBuf.release(); } // Now for the real test that we were building up for -- // the DTMF detector should have detected a '4' tone. // If it didn't then something went wrong -- one thing that could // have gone wrong in that case, is that the generation was assuming // a different sample rate than I. char detectedDTMF = dtmfDetector.getLastDetectedDTMF(); CPPUNIT_ASSERT_EQUAL('4', detectedDTMF); // Stop flowgraph haltFramework(); // No need to delete tone gen, as haltFramework deletes all resources // in the flowgraph. } }
/** * @brief Test MprFromFile file or buffer playing at a given samples per * frame and sample rate. * * How flowgraph is set up: * * A test input resource, connected to an MprFromFile resource, * connected to test output resource. * * This test does the following: * * If /p source is /p MpfftFile: * * MprFromFile loads and plays a very short audio file with DTMF digit * '5' recorded at 48kHz using playFile * * processes a few frames of this data, * for each frame of data, it passes this on to a goertzel dtmf detector * * once a few frames are gathered, a result is received from the DTMF * detector. This then is checked to make sure it detected '5'. * * If /p source is /p MpfftBuffer: * * MprFromFile plays a very short audio clip with DTMF digit '5' recorded * at 48kHz using playBuffer * * The rest is the same as described in #1. * */ void testPlayToneDetectHelper(TestAudioSource source, unsigned sampleRate, unsigned samplesPerFrame) { OsStatus res = OS_SUCCESS; int framesToProcess = 3; UtlString ffResName = "MprFromFile"; MprFromFile* pFromFile = new MprFromFile(ffResName); CPPUNIT_ASSERT(pFromFile != NULL); // Create the Goertzel DTMF detector with current sample rate and samples // per frame figured in. MpDtmfDetector dtmfDetector(sampleRate, framesToProcess*samplesPerFrame); setupFramework(pFromFile); if(source == MpfftFile) { // Specify to play the dtmf '5' file. CPPUNIT_ASSERT_EQUAL( OS_SUCCESS, MprFromFile::playFile(ffResName, *mpFlowGraph->getMsgQ(), mpFlowGraph->getSamplesPerSec(), DTMF5_FN, FALSE)); } else { // Specify to play the dtmf '5' buffer. CPPUNIT_ASSERT_EQUAL( OS_SUCCESS, MprFromFile::playBuffer(ffResName, *mpFlowGraph->getMsgQ(), (const char*)dtmf5_48khz_16b_signed, dtmf5_48khz_16b_signed_in_bytes, 48000, mpFlowGraph->getSamplesPerSec(), 0, FALSE, NULL)); } // pMixer enabled, there are buffers on the input 0 CPPUNIT_ASSERT(mpSourceResource->enable()); CPPUNIT_ASSERT(pFromFile->enable()); int j; for(j = 0; j < framesToProcess; j++) { // Process a frame. res = mpFlowGraph->processNextFrame(); CPPUNIT_ASSERT(res == OS_SUCCESS); // Now analyze the newly processed output. // A new buffer should be generated. CPPUNIT_ASSERT(mpSourceResource->mLastDoProcessArgs.outBufs[0] != mpSinkResource->mLastDoProcessArgs.inBufs[0]); MpAudioBufPtr paBuf = mpSinkResource->mLastDoProcessArgs.inBufs[0]; CPPUNIT_ASSERT(paBuf.isValid()); // Make sure that the number of samples in the from file output frame // is equal to the samples per frame that we set during this run. CPPUNIT_ASSERT_EQUAL(getSamplesPerFrame(), paBuf->getSamplesNumber()); UtlBoolean dtmfDetected = FALSE; // Now grab audio samples and run them through the dtmf detector. unsigned k; for(k = 0; k < paBuf->getSamplesNumber(); k++) { const MpAudioSample* pSamples = paBuf->getSamplesPtr(); dtmfDetected = dtmfDetector.processSample(pSamples[k]); // If we are at the last sample we will process, then, based on how // we configured the dtmf detector, a tone should have been detected. if( k == paBuf->getSamplesNumber()-1 && j == framesToProcess-1) { CPPUNIT_ASSERT_EQUAL(TRUE, dtmfDetected); } else { CPPUNIT_ASSERT_EQUAL(FALSE, dtmfDetected); } } // Free up buffers.. paBuf.release(); } // Now for the real test that we were building up for -- // the DTMF detector should have detected a '5' tone. // If it didn't then something went wrong -- one thing that could // have gone wrong in that case, is that the generation was assuming // a different sample rate than the detector, thus indicating a bug in // wideband support in FromFile. char detectedDTMF = dtmfDetector.getLastDetectedDTMF(); CPPUNIT_ASSERT_EQUAL((int)'5', (int)detectedDTMF); // Stop flowgraph haltFramework(); }