Hello, When I try to apply this patch with Tortoise SVN it says, "The line Index was not found, either this is not a diff file or the diff is empty.".
What am I missing? Thanks, Hitesh ----- Original Message ----- From: <[EMAIL PROTECTED]> To: <[email protected]> Sent: Monday, March 05, 2007 4:52 PM Subject: [sipxtapi-dev] call recording patch > I'm sending my call recording patch. > > It adds 2 splitters to flowgraph, one between MprMixer and MprBridge on > the mic side and one on the speaker side. 2nd output from these > splitters goes into new MprMixer which will enable us to hear input from > our mic, our dtmf, any files we play to other side and sound from the > other party. After this mixer I plug a MprRecorder[RECORDER_CALL]. These > resources are initially disabled, so they pass input to output 0 > (original path). They are enabled when we start recording and disabled > when we stop under normal condition (closeRecorders is called in > MpCallFlowGraph). > They are not stopped if MprRecorder is disabled internally for example > due to DTMF event or long silence. This will have to be handled by > another patch. I would like the MprRecorder to send a message to flow > graph when it is enabled or disabled, and here we could also enable and > disable splitters used for call recording and send media event to > sipxtapi informing user that call recording started or stopped. This > will be done in another patch. > > > -------------------------------------------------------------------------------- > diff -ru > old/sipXmediaAdapterLib/sipXmediaMediaProcessing/src/CpPhoneMediaInterface.cpp > > new/sipXmediaAdapterLib/sipXmediaMediaProcessing/src/CpPhoneMediaInterface.cpp > --- > old/sipXmediaAdapterLib/sipXmediaMediaProcessing/src/CpPhoneMediaInterface.cpp > > Mon Mar 5 11:57:41 2007 > +++ > new/sipXmediaAdapterLib/sipXmediaMediaProcessing/src/CpPhoneMediaInterface.cpp > > Mon Mar 5 01:28:25 2007 > @@ -1207,14 +1207,15 @@ > // TODO:: This API is designed to record the audio from a single > channel. > // If the connectionId is -1, record all. > > - // > - // Also -- not sure of the if the spkr is the correct place to > record -- > - // this probably doesn't include mic data... > - /// > - > - double duration = 0 ; > + double duration = 0 ; // this means it will record for very long time > int dtmf = 0 ; > - return mpFlowGraph->record(1, -1, NULL, NULL, szFile) ; > + > + /* use new call recorder > + from now on, call recorder records both mic, speaker and local > dtmf > + we don't want raw pcm, but wav pcm, raw pcm should be passed to a > callback > + meant for recording, for example for conversion to mp3 or other > format */ > + return mpFlowGraph->record(0, -1, NULL, NULL, NULL, NULL, NULL, NULL, > + NULL, NULL, szFile, 0, 0, NULL, > MprRecorder::WAV_PCM_16) ; > } > > OsStatus CpPhoneMediaInterface::stopRecordChannelAudio(int connectionId) > diff -ru old/sipXmediaLib/include/mp/MpCallFlowGraph.h > new/sipXmediaLib/include/mp/MpCallFlowGraph.h > --- old/sipXmediaLib/include/mp/MpCallFlowGraph.h Mon Mar 5 11:56:12 2007 > +++ new/sipXmediaLib/include/mp/MpCallFlowGraph.h Sun Mar 4 22:34:53 2007 > @@ -113,6 +113,7 @@ > RECORDER_SPKR32K, > RECORDER_ECHO_IN32, > #endif // HIGH_SAMPLERATE_AUDIO ] > + RECORDER_CALL, > MAX_RECORDERS = 10 > }; > > @@ -170,14 +171,7 @@ > OsProtectedEvent* recordEvent = NULL); > > > - OsStatus record(int timeMS, int silenceLength, const char* micName = > NULL, > - const char* echoOutName = NULL, const char* spkrName = > NULL, > - const char* mic32Name = NULL, const char* spkr32Name = > NULL, > - const char* echoIn8Name = NULL, const char* > echoIn32Name = NULL, > - const char* playName = NULL, > - int toneOptions = 0, > - int repeat = 0, OsNotification* completion = NULL, > - MprRecorder::RecordFileFormat format = > MprRecorder::RAW_PCM_16); > + OsStatus record(int timeMS, int silenceLength, const char* micName = > NULL, const char* echoOutName = NULL, const char* spkrName = NULL, > const char* mic32Name = NULL, const char* spkr32Name = NULL, const > char* echoIn8Name = NULL, const char* echoIn32Name = NULL, const char* > playName = NULL, const char* callName = NULL, int toneOptions = 0, > int repeat = 0, OsNotification* completion = NULL, > MprRecorder::RecordFileFormat format = MprRecorder::RAW_PCM_16); > > > OsStatus startRecording(const char* audioFileName, UtlBoolean repeat, > @@ -469,6 +463,9 @@ > #endif > MprMixer* mpTFsMicMixer; > MprMixer* mpTFsBridgeMixer; > + MprMixer* mpCallrecMixer; > + MprSplitter* mpMicCallrecSplitter; > + MprSplitter* mpSpeakerCallrecSplitter; > MprSplitter* mpToneFileSplitter; > MprToSpkr* mpToSpkr; > MprToneGen* mpToneGen; > diff -ru old/sipXmediaLib/src/mp/MpCallFlowGraph.cpp > new/sipXmediaLib/src/mp/MpCallFlowGraph.cpp > --- old/sipXmediaLib/src/mp/MpCallFlowGraph.cpp Mon Mar 5 11:56:40 2007 > +++ new/sipXmediaLib/src/mp/MpCallFlowGraph.cpp Mon Mar 5 01:58:48 2007 > @@ -165,8 +165,14 @@ > samplesPerFrame, samplesPerSec); > mpTFsBridgeMixer = new MprMixer("TFsBridgeMixer", 2, > samplesPerFrame, samplesPerSec); > + mpCallrecMixer = new MprMixer("CallrecMixer", 2, > + samplesPerFrame, samplesPerSec); > mpToneFileSplitter = new MprSplitter("ToneFileSplitter", 2, > samplesPerFrame, samplesPerSec); > + mpMicCallrecSplitter = new MprSplitter("MicCallrecSplitter", 2, > + samplesPerFrame, samplesPerSec); > + mpSpeakerCallrecSplitter = new MprSplitter("SpeakerCallrecSplitter", > 2, > + samplesPerFrame, samplesPerSec); > #ifndef DISABLE_LOCAL_AUDIO // [ > mpToSpkr = new MprToSpkr("ToSpkr", > samplesPerFrame, samplesPerSec, > @@ -195,7 +201,10 @@ > #endif // DISABLE_LOCAL_AUDIO ] > res = addResource(*mpTFsMicMixer); assert(res == OS_SUCCESS); > res = addResource(*mpTFsBridgeMixer); assert(res == OS_SUCCESS); > + res = addResource(*mpCallrecMixer); assert(res == OS_SUCCESS); > res = addResource(*mpToneFileSplitter); assert(res == OS_SUCCESS); > + res = addResource(*mpMicCallrecSplitter); assert(res == OS_SUCCESS); > + res = addResource(*mpSpeakerCallrecSplitter); assert(res == > OS_SUCCESS); > #ifndef DISABLE_LOCAL_AUDIO > res = addResource(*mpToSpkr); assert(res == OS_SUCCESS); > #endif > @@ -233,14 +242,29 @@ > assert(res == OS_SUCCESS); > #endif > > - // connect TFsMicMixer -> Bridge > - res = addLink(*mpTFsMicMixer, 0, *mpBridge, 0); > + // connect TFsMicMixer -> mpMicCallrecSplitter > + res = addLink(*mpTFsMicMixer, 0, *mpMicCallrecSplitter, 0); > + assert(res == OS_SUCCESS); > + > + // connect mpMicCallrecSplitter -> Bridge > + res = addLink(*mpMicCallrecSplitter, 0, *mpBridge, 0); > assert(res == OS_SUCCESS); > > > ////////////////////////////////////////////////////////////////////////// > - // connect Bridge -> TFsBridgeMixer > + // connect Bridge -> TFsBridgeMixer through mpSpeakerCallrecSplitter > + > + res = addLink(*mpBridge, 0, *mpSpeakerCallrecSplitter, 0); > + assert(res == OS_SUCCESS); > > - res = addLink(*mpBridge, 0, *mpTFsBridgeMixer, 1); > + res = addLink(*mpSpeakerCallrecSplitter, 0, *mpTFsBridgeMixer, 1); > + assert(res == OS_SUCCESS); > + > + > ////////////////////////////////////////////////////////////////////////// > + // connect mpSpeakerCallrecSplitter and mpMicCallrecSplitter into > mpCallrecMixer > + res = addLink(*mpMicCallrecSplitter, 1, *mpCallrecMixer, 0); > + assert(res == OS_SUCCESS); > + > + res = addLink(*mpSpeakerCallrecSplitter, 1, *mpCallrecMixer, 1); > assert(res == OS_SUCCESS); > > > ////////////////////////////////////////////////////////////////////////// > @@ -282,6 +306,11 @@ > // disable the from file > boolRes = mpFromFile->disable(); assert(boolRes); > > + // disable mpCallrecMixer and splitters, they are enabled when we want > to start recording > + boolRes = mpCallrecMixer->disable(); assert(boolRes); > + boolRes = mpMicCallrecSplitter->disable(); assert(boolRes); > + boolRes = mpSpeakerCallrecSplitter->disable(); assert(boolRes); > + > #ifndef DISABLE_LOCAL_AUDIO // [ > // disable the FromMic, EchoCancel, PreProcess and ToSpkr -- we cannot > have focus yet... > boolRes = mpFromMic->disable(); assert(boolRes); > @@ -303,6 +332,12 @@ > boolRes = mpTFsBridgeMixer->setWeight(0, 0); assert(boolRes); > boolRes = mpTFsBridgeMixer->setWeight(1, 1); assert(boolRes); > > + // set up weights for callrec mixer as they are zeroed in constructor > + // input 0 is from mic > + boolRes = mpCallrecMixer->setWeight(1, 0); assert(boolRes); > + // input 1 is speaker > + boolRes = mpCallrecMixer->setWeight(1, 1); assert(boolRes); > + > #ifdef INCLUDE_RTCP /* [ */ > // All the Media Resource seemed to have been started successfully. > // Let's now create an RTCP Session so that we may be prepared to > @@ -361,6 +396,14 @@ > *mpEchoCancel, 1); > assert(res == OS_SUCCESS); > > + // create Call recorder and connect it to mpCallrecMixer > + mpRecorders[RECORDER_CALL] = > + new MprRecorder("RecordCall", samplesPerFrame, samplesPerSec); > + res = addResource(*(mpRecorders[RECORDER_CALL])); > + assert(res == OS_SUCCESS); > + res = addLink(*mpCallrecMixer, 0, *(mpRecorders[RECORDER_CALL]), 0); > + assert(res == OS_SUCCESS); > + > #ifdef HIGH_SAMPLERATE_AUDIO // [ > mpRecorders[RECORDER_ECHO_IN32] = > new MprRecorder("RecordEchoIn32", samplesPerFrame, samplesPerSec); > @@ -479,6 +522,13 @@ > res = removeLink(*mpToneFileSplitter, 0); assert(res == OS_SUCCESS); > res = removeLink(*mpToneFileSplitter, 1); assert(res == OS_SUCCESS); > > + // remove links of call recording > + res = removeLink(*mpCallrecMixer, 0); assert(res == OS_SUCCESS); > + res = removeLink(*mpMicCallrecSplitter, 0); assert(res == OS_SUCCESS); > + res = removeLink(*mpMicCallrecSplitter, 1); assert(res == OS_SUCCESS); > + res = removeLink(*mpSpeakerCallrecSplitter, 0); assert(res == > OS_SUCCESS); > + res = removeLink(*mpSpeakerCallrecSplitter, 1); assert(res == > OS_SUCCESS); > + > // now remove (and destroy) the resources > #ifndef DISABLE_LOCAL_AUDIO > res = removeResource(*mpFromMic); > @@ -523,6 +573,19 @@ > assert(res == OS_SUCCESS); > delete mpFromFile; > > + // kill call recording resources > + res = removeResource(*mpMicCallrecSplitter); > + assert(res == OS_SUCCESS); > + delete mpMicCallrecSplitter; > + > + res = removeResource(*mpSpeakerCallrecSplitter); > + assert(res == OS_SUCCESS); > + delete mpSpeakerCallrecSplitter; > + > + res = removeResource(*mpCallrecMixer); > + assert(res == OS_SUCCESS); > + delete mpCallrecMixer; > + > for (i=0; i<MAX_RECORDERS; i++) { > if (NULL != mpRecorders[i]) { > res = removeResource(*mpRecorders[i]); > @@ -719,6 +782,11 @@ > ret++; > } > } > + // also disable mpCallrecMixer and splitters > + mpCallrecMixer->disable(); > + mpMicCallrecSplitter->disable(); > + mpSpeakerCallrecSplitter->disable(); > + > return ret; > } > > @@ -850,7 +918,7 @@ > res = record(ms, 999999, created_micNamePtr, created_echoOutNamePtr, > created_spkrNamePtr, created_mic32NamePtr, > created_spkr32NamePtr, > created_echoIn8NamePtr, created_echoIn32NamePtr, > - playFilename, 0, 0, NULL); > + playFilename, NULL, 0, 0, NULL); > playIndex++; > > strcpy(saved_playFilename,playFilename); > @@ -890,7 +958,7 @@ > } > > return record(ms, silenceLength, NULL, NULL, fileName, > - NULL, NULL, NULL, NULL, NULL, 0, 0, recordEvent, > format); > + NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, recordEvent, > format); > > } > > @@ -910,7 +978,7 @@ > OsTime maxEventTime(timeoutSecs, 0); > > record(ms, silenceLength, fileName, NULL, NULL, > - NULL, NULL, NULL, NULL, NULL, 0, 0, > + NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, > NULL, MprRecorder::WAV_PCM_16); > > // Wait until the call sets the number of connections > @@ -960,7 +1028,7 @@ > > > record(ms, silenceLength, NULL, NULL, fileName, > - NULL, NULL, NULL, NULL, NULL, 0, > + NULL, NULL, NULL, NULL, NULL, NULL, 0, > 0, recordEvent,format); > > if (dtmfTerm) > @@ -1004,55 +1072,60 @@ > return ret; > } > > -OsStatus MpCallFlowGraph::record(int ms, int silenceLength, const char* > micName, > - const char* echoOutName, const char* spkrName, > - const char* mic32Name, const char* spkr32Name, > - const char* echoIn8Name, const char* echoIn32Name, > - const char* playName, int toneOptions, > - int repeat, OsNotification* completion, > - MprRecorder::RecordFileFormat format) > +OsStatus MpCallFlowGraph::record(int timeMS, int silenceLength, const > char* micName /*= NULL*/, const char* echoOutName /*= NULL*/, const > char* spkrName /*= NULL*/, const char* mic32Name /*= NULL*/, const > char* spkr32Name /*= NULL*/, const char* echoIn8Name /*= NULL*/, const > char* echoIn32Name /*= NULL*/, const char* playName /*= NULL*/, const > char* callName /*= NULL*/, int toneOptions /*= 0*/, int repeat /*= > 0*/, OsNotification* completion /*= NULL*/, > MprRecorder::RecordFileFormat format /*= MprRecorder::RAW_PCM_16*/) > { > if (NULL == this) { > MpMediaTask* pMT = MpMediaTask::getMediaTask(0); > MpCallFlowGraph* pIF = (MpCallFlowGraph*) pMT->getFocus(); > if (NULL != pIF) { > - return pIF-> record(ms, silenceLength, micName, echoOutName, > spkrName, > + return pIF-> record(timeMS, silenceLength, micName, echoOutName, > spkrName, > mic32Name, spkr32Name, echoIn8Name, echoIn32Name, > - playName, toneOptions, repeat, completion); > + playName, callName, toneOptions, repeat, completion); > } > return OS_INVALID; > } > > if (NULL != micName) { > setupRecorder(RECORDER_MIC, micName, > - ms, silenceLength, completion, format); > + timeMS, silenceLength, completion, format); > } > if (NULL != echoOutName) { > setupRecorder(RECORDER_ECHO_OUT, echoOutName, > - ms, silenceLength, completion, format); > + timeMS, silenceLength, completion, format); > } > if (NULL != spkrName) { > setupRecorder(RECORDER_SPKR, spkrName, > - ms, silenceLength, completion, format); > + timeMS, silenceLength, completion, format); > } > if (NULL != echoIn8Name) { > setupRecorder(RECORDER_ECHO_IN8, echoIn8Name, > - ms, silenceLength, completion, format); > + timeMS, silenceLength, completion, format); > } > #ifdef HIGH_SAMPLERATE_AUDIO // [ > if (NULL != mic32Name) { > setupRecorder(RECORDER_MIC32K, mic32Name, > - ms, silenceLength, completion, format); > + timeMS, silenceLength, completion, format); > } > if (NULL != spkr32Name) { > setupRecorder(RECORDER_SPKR32K,spkr32Name, > - ms, silenceLength, completion, format); > + timeMS, silenceLength, completion, format); > } > if (NULL != echoIn32Name) { > setupRecorder(RECORDER_ECHO_IN32, > - echoIn32Name, ms, silenceLength, completion, format); > + echoIn32Name, timeMS, silenceLength, completion, > format); > } > #endif // HIGH_SAMPLERATE_AUDIO ] > + // set up call recorder > + if (NULL != callName) { > + // also enable callrec mixer > + if(setupRecorder(RECORDER_CALL, callName, > + timeMS, silenceLength, completion, format)) > + { > + mpCallrecMixer->enable(); > + mpMicCallrecSplitter->enable(); > + mpSpeakerCallrecSplitter->enable(); > + } > + } > return startRecording(playName, repeat, toneOptions, completion); > } > > @@ -1100,6 +1173,12 @@ > } > > res = mpRecorders[which]->setup(file, format, timeMS, silenceLength, > (OsEvent*)event); > + } > + else > + { > + OsSysLog::add(FAC_AUDIO, PRI_ERR, > + "setupRecorder failed to open file %s, error code is %i", > + audioFileName, errno); > } > return (file != -1); > } > -------------------------------------------------------------------------------- > _______________________________________________ > sipxtapi-dev mailing list > [email protected] > List Archive: http://list.sipfoundry.org/archive/sipxtapi-dev/ _______________________________________________ sipxtapi-dev mailing list [email protected] List Archive: http://list.sipfoundry.org/archive/sipxtapi-dev/
