Author: sayer
Date: 2008-12-19 18:23:15 +0100 (Fri, 19 Dec 2008)
New Revision: 1203

Modified:
   trunk/apps/examples/mixin_announce/Readme.mixin_announce
   trunk/apps/ivr/IvrAudioMixIn.cpp
   trunk/core/AmAudioMixIn.cpp
   trunk/core/AmAudioMixIn.h
Log:
some more modes for AudioMixIn


Modified: trunk/apps/examples/mixin_announce/Readme.mixin_announce
===================================================================
--- trunk/apps/examples/mixin_announce/Readme.mixin_announce    2008-12-19 
17:13:42 UTC (rev 1202)
+++ trunk/apps/examples/mixin_announce/Readme.mixin_announce    2008-12-19 
17:23:15 UTC (rev 1203)
@@ -6,20 +6,31 @@
 sources, plays the first one, and periodically mixes in the second one.
 The period, i.e. the time between two times mixing in the second audio,
 can be specified, as well as the level with which the second one is
-mixed into the first. The last parameter, a boolean, specifies whether
+mixed into the first. 
+
+The last parameter, a boolean, specifies whether
 playback of the second audio should be finished if the first is finished
 while mixing in the second.
+
+With the mix_once and the mix_immediate it can be specified whether it should
+be mixed in onyl once, and whether it should be mixed in immediately.
+E.g. if there should be some prompt or info tone played into the background
+of a call, mix_once=True and mix_immediate=True are useful.
+
 If level == 0, playback of the first is not continued when playing the 
 second, which means that it continues right where it was before 
 playback of the second started.
 
 IVR usage: 
     init(IvrAudioFile first, IvrAudioFile second, 
-         int interval, float level, boolean finish)
+         int interval, float level, boolean finish, 
+         boolean mix_once, boolean mix_immediate)
 
 C++ usage:
 AmAudioMixIn::
   AmAudioMixIn(AmAudio* A, AmAudioFile* B, 
               unsigned int interval, double level, 
-              bool finish_b_while_mixing = false);
+              int flags);
 
+  where flags definitions can be found in AmAudioMixIn.h
+

Modified: trunk/apps/ivr/IvrAudioMixIn.cpp
===================================================================
--- trunk/apps/ivr/IvrAudioMixIn.cpp    2008-12-19 17:13:42 UTC (rev 1202)
+++ trunk/apps/ivr/IvrAudioMixIn.cpp    2008-12-19 17:23:15 UTC (rev 1203)
@@ -35,11 +35,11 @@
   AmAudioFile* b = NULL;
   int s;
   double l;
-  int finish = 0;
+  int finish = 0, mix_once=0, mix_immediate=0;
 
   PyObject *o_a, *o_b;
 
-  if(!PyArg_ParseTuple(args,"OOid|i", &o_a, &o_b, &s, &l, &finish))
+  if(!PyArg_ParseTuple(args,"OOid|iii", &o_a, &o_b, &s, &l, &finish, 
&mix_once, &mix_immediate))
     return NULL;
 
   if (o_a == Py_None) {
@@ -69,8 +69,13 @@
     delete self->mix;
   }
 
-  self->mix = new AmAudioMixIn(a, b, s, l, finish);
+  int flags = 0;
+  if (finish) flags |=AUDIO_MIXIN_FINISH_B_MIX;
+  if (mix_once) flags |=AUDIO_MIXIN_ONCE;
+  if (mix_immediate) flags |=AUDIO_MIXIN_IMMEDIATE_START;
 
+  self->mix = new AmAudioMixIn(a, b, s, l, flags);
+
   Py_INCREF(Py_None);
   return Py_None;
 }

Modified: trunk/core/AmAudioMixIn.cpp
===================================================================
--- trunk/core/AmAudioMixIn.cpp 2008-12-19 17:13:42 UTC (rev 1202)
+++ trunk/core/AmAudioMixIn.cpp 2008-12-19 17:23:15 UTC (rev 1203)
@@ -28,32 +28,43 @@
 #include "AmAudioMixIn.h"
 #include "SampleArray.h"
 
+#define IS_FINISH_B_MIX    (flags & AUDIO_MIXIN_FINISH_B_MIX) 
+#define IS_ONLY_ONCE       (flags & AUDIO_MIXIN_ONCE)
+#define IS_IMMEDIATE_START (flags & AUDIO_MIXIN_IMMEDIATE_START)
+
 AmAudioMixIn::AmAudioMixIn(AmAudio* A, AmAudioFile* B, 
                           unsigned int s, double l,
-                          bool finish_b_while_mixing) 
+                          unsigned int flags) 
   :   A(A),B(B), s(s), l(l), 
       mixing(false), next_start_ts_i(false),
-      finish_b_while_mixing(finish_b_while_mixing)
+      flags(flags)
 {
 }
+
 AmAudioMixIn::~AmAudioMixIn() { }
 
 int AmAudioMixIn::get(unsigned int user_ts, unsigned char* buffer, 
-                      unsigned int nb_samples) {
+                     unsigned int nb_samples) {
   if (!mixing) {
     if (!next_start_ts_i) {
       next_start_ts_i = true;
+      next_start_ts = IS_IMMEDIATE_START ? 
+       user_ts : user_ts + s*DEFAULT_SAMPLE_RATE;
+    }
+    if (!ts_less()(user_ts, next_start_ts)) {
+      DBG("starting mix-in\n");
+      mixing = true;
       next_start_ts = user_ts + s*DEFAULT_SAMPLE_RATE;
-    } else {
-      if (ts_less()(next_start_ts, user_ts)) {
-       DBG("starting mix-in\n");
-       mixing = true;
-       next_start_ts = user_ts + s*DEFAULT_SAMPLE_RATE;
-      }
     }
   } 
   
-  if (!mixing) {
+  if (NULL == A)
+    return -1;
+
+  B_mut.lock();
+
+  if (!mixing || NULL == B) {
+    B_mut.unlock();
     return A->get(user_ts, buffer, nb_samples);
   } else {
     if (l < 0.01) { // epsilon 
@@ -62,8 +73,12 @@
       if (res <= 0) { // B empty
        res = A->get(user_ts, buffer, nb_samples);
        mixing = false;
-       B->rewind();
+       if (IS_ONLY_ONCE)
+         B = NULL;
+       else
+         B->rewind();
       }
+      B_mut.unlock();
       return  res;
     } else {      // mix the two
       int res = 0;
@@ -71,10 +86,11 @@
       // get audio from A
       int len = A->get(user_ts, (unsigned char*)mix_buf, nb_samples);
 
-      if ((len<0) && !finish_b_while_mixing) { // A finished
+      if ((len<0) && !IS_FINISH_B_MIX) { // A finished
+       B_mut.unlock();
        return len;
       }
-      for (int i=0;i<len;i++) {
+      for (int i=0; i<(PCM16_B2S(len)); i++) {
        pdest[i]=(short)(((double)mix_buf[i])*(1.0-l));
       }
 
@@ -85,29 +101,42 @@
       if (res>0)
        len_from_a=(unsigned int)res;
       
-      if (nb_samples<<1 != len_from_a)
+      if (PCM16_S2B(nb_samples) != len_from_a)
        memset((void*)&pdest[len_from_a>>1], 0, 
               (nb_samples<<1) - len_from_a);
-
+      
       // add audio from B
       len = B->get(user_ts, (unsigned char*)mix_buf, nb_samples);
-
       if (len<0) { // B finished
        mixing = false;
-       B->rewind();
+       
+       if (IS_ONLY_ONCE)
+         B = NULL;
+       else
+         B->rewind();
       } else {
-       for (int i=0;i<len;i++) {
-         pdest[i]+=(short)(((double)mix_buf[i])*l);
-       }
-       if (len>res) // audio from B is longer than from A
-         res = len;
+       for (int i=0; i<(PCM16_B2S(len)); i++)  {
+           pdest[i]+=(short)(((double)mix_buf[i])*l);
+         }
+              if (len>res) // audio from B is longer than from A
+                res = len;
+            }
+       B_mut.unlock();
+       
+       return res;
       }
-      return res;
     }
   }
-}
 
-int AmAudioMixIn::put(unsigned int user_ts, unsigned char* buffer, unsigned 
int size) {
-  ERROR("writing not supported\n");
-  return -1;
-}
+  int AmAudioMixIn::put(unsigned int user_ts, unsigned char* buffer, unsigned 
int size) {
+    ERROR("writing not supported\n");
+    return -1;
+  }
+
+  void AmAudioMixIn::mixin(AmAudioFile* f) {
+    B_mut.lock();
+    B = f;
+    mixing = next_start_ts_i = false; /* so that mix in will re-start */
+    B_mut.unlock();
+  }
+

Modified: trunk/core/AmAudioMixIn.h
===================================================================
--- trunk/core/AmAudioMixIn.h   2008-12-19 17:13:42 UTC (rev 1202)
+++ trunk/core/AmAudioMixIn.h   2008-12-19 17:23:15 UTC (rev 1203)
@@ -32,7 +32,7 @@
 #include "AmAudioFile.h"
 
 
-#define MAX_PACKETLENGTH_MS   30
+#define MAX_PACKETLENGTH_MS   80
 #define MAX_BUF_SAMPLES  SYSTEM_SAMPLERATE * MAX_PACKETLENGTH_MS / 1000
 #define DEFAULT_SAMPLE_RATE SYSTEM_SAMPLERATE // eh...
 
@@ -46,15 +46,21 @@
  * playback of B started.
  *
  */
+#define AUDIO_MIXIN_FINISH_B_MIX      1       /* when A ends while mixing in 
B, end playback only after B has ended */
+#define AUDIO_MIXIN_ONCE              1 << 1  /* only mix in once */
+#define AUDIO_MIXIN_IMMEDIATE_START   1 << 2  /* start mixing in immediately, 
or wait s seconds before */
+
 class AmAudioMixIn : public AmAudio {
   AmAudio* A;
   AmAudioFile* B;
   unsigned int s;
   double l;
-  bool finish_b_while_mixing;
+  int flags;
 
   bool mixing;
 
+  AmMutex B_mut;
+
   unsigned int next_start_ts;
   bool next_start_ts_i;
 
@@ -64,8 +70,11 @@
  public:
   AmAudioMixIn(AmAudio* A, AmAudioFile* B, 
               unsigned int s, double l, 
-              bool finish_b_while_mixing = false);
+              unsigned int flags = 0);
   ~AmAudioMixIn();
+
+  void mixin(AmAudioFile* f);
+
  protected:
   // not used
   int read(unsigned int user_ts, unsigned int size){ return -1; }

_______________________________________________
Semsdev mailing list
[email protected]
http://lists.iptel.org/mailman/listinfo/semsdev

Reply via email to