Kwint wrote:
Hi, Jaroslav

In your patch for call recording you've forgotten to include diff for files,
where you add ON_MPRRECORDER_ENABLED and ON_MPRRECORDER_DISABLED messages to
enum and where these messages are posted from.

_______________________________________________
sipxtapi-dev mailing list
[email protected]
List Archive: http://list.sipfoundry.org/archive/sipxtapi-dev/

This one should be ok.

Jaroslav Libak
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 21:28:22 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       Mon Mar  5 21:32:51 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;
@@ -541,6 +538,20 @@
      *  @returns <b>TRUE</b> if the message was handled
      *  @returns <b>FALSE</b> otherwise.
      */
+
+   /// Handle the ON_MPRRECORDER_ENABLED message.
+   UtlBoolean handleOnMprRecorderEnabled(MpFlowGraphMsg& rMsg);
+   /**<
+   *  @returns <b>TRUE</b> if the message was handled
+   *  @returns <b>FALSE</b> otherwise.
+   */
+
+   /// Handle the ON_MPRRECORDER_ENABLED message.
+   UtlBoolean handleOnMprRecorderDisabled(MpFlowGraphMsg& rMsg);
+   /**<
+   *  @returns <b>TRUE</b> if the message was handled
+   *  @returns <b>FALSE</b> otherwise.
+   */
 
 #ifdef DEBUG_POSTPONE /* [ */
      /// sends a message requesting a delay for race condition detection...
diff -ru old/sipXmediaLib/include/mp/MpFlowGraphMsg.h 
new/sipXmediaLib/include/mp/MpFlowGraphMsg.h
--- old/sipXmediaLib/include/mp/MpFlowGraphMsg.h        Thu Mar  8 13:22:43 2007
+++ new/sipXmediaLib/include/mp/MpFlowGraphMsg.h        Mon Mar  5 17:48:16 2007
@@ -71,7 +71,10 @@
 
       FLOWGRAPH_SET_DTMF_NOTIFY,
 
-      RESOURCE_SPECIFIC_START = 100     ///< start of resource-specific 
messages
+      RESOURCE_SPECIFIC_START = 100,     ///< start of resource-specific 
messages
+
+      ON_MPRRECORDER_ENABLED,
+      ON_MPRRECORDER_DISABLED
    } MpFlowGraphMsgType;
 
 /* ============================ CREATORS ================================== */
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 21:28:36 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 through mpSpeakerCallrecSplitter
+
+   res = addLink(*mpBridge, 0, *mpSpeakerCallrecSplitter, 0);
+   assert(res == OS_SUCCESS);
+
+   res = addLink(*mpSpeakerCallrecSplitter, 0, *mpTFsBridgeMixer, 1);
    assert(res == OS_SUCCESS);
 
    //////////////////////////////////////////////////////////////////////////
-   // connect Bridge -> TFsBridgeMixer
+   // connect mpSpeakerCallrecSplitter and mpMicCallrecSplitter into 
mpCallrecMixer
+   res = addLink(*mpMicCallrecSplitter, 1, *mpCallrecMixer, 0);
+   assert(res == OS_SUCCESS);
 
-   res = addLink(*mpBridge, 0, *mpTFsBridgeMixer, 1);
+   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]);
@@ -850,7 +913,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 +953,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 +973,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 +1023,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 +1067,54 @@
   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) {
+      setupRecorder(RECORDER_CALL, callName,
+                    timeMS, silenceLength, completion, format);
+   }
    return startRecording(playName, repeat, toneOptions, completion);
 }
 
@@ -1101,6 +1163,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);
 }
 
@@ -1727,6 +1795,12 @@
       case MpFlowGraphMsg::FLOWGRAPH_SET_DTMF_NOTIFY:
          retCode = handleSetDtmfNotify(*pMsg);
          break;
+      case MpFlowGraphMsg::ON_MPRRECORDER_ENABLED:
+         retCode = handleOnMprRecorderEnabled(*pMsg);
+         break;
+      case MpFlowGraphMsg::ON_MPRRECORDER_DISABLED:
+         retCode = handleOnMprRecorderDisabled(*pMsg);
+         break;
       default:
          retCode = MpFlowGraphBase::handleMessage(*pMsg);
          break;
@@ -2071,6 +2145,61 @@
    mpFromStream->destroy(handle) ;
 
    return TRUE ;
+}
+
+UtlBoolean MpCallFlowGraph::handleOnMprRecorderEnabled(MpFlowGraphMsg& rMsg)
+{
+   UtlBoolean boolRes; 
+   int status = rMsg.getInt1();
+   MprRecorder* pRecorder = (MprRecorder*) rMsg.getPtr1() ;
+
+   // if this call recorder, also enable required resources
+   if (pRecorder && pRecorder == mpRecorders[RECORDER_CALL])
+   {
+      boolRes = mpCallrecMixer->enable();
+      assert(boolRes);
+
+      boolRes = mpMicCallrecSplitter->enable();
+      assert(boolRes);
+
+      boolRes = mpSpeakerCallrecSplitter->enable();
+      assert(boolRes);
+   }
+
+   return TRUE;
+}
+
+UtlBoolean MpCallFlowGraph::handleOnMprRecorderDisabled(MpFlowGraphMsg& rMsg)
+{
+   UtlBoolean boolRes;
+   int status = rMsg.getInt1();
+   MprRecorder* pRecorder = (MprRecorder*) rMsg.getPtr1() ;
+
+   if (pRecorder && pRecorder == mpRecorders[RECORDER_CALL])
+   {
+      // also disable mpCallrecMixer and splitters
+
+      /* checks just in case this gets called when
+      the resources have already been deleted
+      */
+      if (mpCallrecMixer)
+      {
+         boolRes = mpCallrecMixer->disable();
+         assert(boolRes);
+      }
+      if (mpMicCallrecSplitter)
+      {
+         boolRes = mpMicCallrecSplitter->disable();
+         assert(boolRes);
+      }
+      if (mpSpeakerCallrecSplitter)
+      {
+         boolRes = mpSpeakerCallrecSplitter->disable();
+         assert(boolRes);
+      }
+   }
+
+   return TRUE;
 }
 
 /* ============================ FUNCTIONS ================================= */
diff -ru old/sipXmediaLib/src/mp/MprRecorder.cpp 
new/sipXmediaLib/src/mp/MprRecorder.cpp
--- old/sipXmediaLib/src/mp/MprRecorder.cpp     Thu Mar  8 13:17:20 2007
+++ new/sipXmediaLib/src/mp/MprRecorder.cpp     Mon Mar  5 17:52:13 2007
@@ -122,7 +122,19 @@
    if (mFileDescriptor > -1) {
       mStatus = RECORDING;
       OsSysLog::add(FAC_MP, PRI_DEBUG, "MprRecorder::enable\n");
-      return MpResource::enable();
+      UtlBoolean res = MpResource::enable();
+
+      if (res && mpFlowGraph)
+      {
+         /* resource is enabled, we started recording, inform flowgraph
+         so it can send media event to sipxtapi and enable some resources
+         if this is call recorder */
+         MpFlowGraphMsg msg(MpFlowGraphMsg::ON_MPRRECORDER_ENABLED,
+                            NULL, (void*) this, NULL, mStatus);
+         postMessage(msg);
+      }
+
+      return res;
    } else {
       OsSysLog::add(FAC_MP, PRI_DEBUG, "MprRecorder::enable (No file 
designated!)\n");
    }
@@ -171,6 +183,16 @@
          mFileDescriptor = -1;
       }
       res = (MpResource::disable() && (mFileDescriptor == -1));
+   }
+
+   if (res && mpFlowGraph)
+   {
+      /* resource is disabled, we stopped started recording, inform flowgraph
+      so it can send media event to sipxtapi and disable some resources
+      if this is call recorder */
+      MpFlowGraphMsg msg(MpFlowGraphMsg::ON_MPRRECORDER_DISABLED,
+         NULL, (void*) this, NULL, mStatus);
+      postMessage(msg);
    }
 
    return res;
_______________________________________________
sipxtapi-dev mailing list
[email protected]
List Archive: http://list.sipfoundry.org/archive/sipxtapi-dev/

Reply via email to