Fix synchronization of recorded files when using Monitor application
authorMartin Pycko <martinp@digium.com>
Thu, 28 Aug 2003 20:02:10 +0000 (20:02 +0000)
committerMartin Pycko <martinp@digium.com>
Thu, 28 Aug 2003 20:02:10 +0000 (20:02 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@1446 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channel.c
formats/format_g729.c
formats/format_gsm.c
formats/format_mp3.c
formats/format_pcm.c
formats/format_pcm_alaw.c
formats/format_wav.c
formats/format_wav_gsm.c
include/asterisk/channel.h
include/asterisk/file.h

index 3ec67e2..9081943 100755 (executable)
--- a/channel.c
+++ b/channel.c
 #include <linux/zaptel.h>
 #endif
 
+/* uncomment if you have problems with 'monitoring' synchronized files */
+#if 0
+#define MONITOR_CONSTANT_DELAY
+#define MONITOR_DELAY  150 * 8         /* 150 ms of MONITORING DELAY */
+#endif
 
 static int shutting_down = 0;
 static int uniqueint = 0;
@@ -1088,9 +1093,25 @@ struct ast_frame *ast_read(struct ast_channel *chan)
                        f = &null_frame;
                } else {
                        if (chan->monitor && chan->monitor->read_stream ) {
-                               if( ast_writestream( chan->monitor->read_stream, f ) < 0 ) {
+#ifndef MONITOR_CONSTANT_DELAY
+                               int jump = chan->outsmpl - chan->insmpl - 2 * f->samples;
+                               if (jump >= 0) {
+                                       if (ast_seekstream(chan->monitor->read_stream, jump + f->samples, SEEK_FORCECUR) == -1)
+                                               ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
+                                       chan->insmpl += jump + 2 * f->samples;
+                               } else
+                                       chan->insmpl+= f->samples;
+#else
+                               int jump = chan->outsmpl - chan->insmpl;
+                               if (jump - MONITOR_DELAY >= 0) {
+                                       if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1)
+                                               ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
+                                       chan->insmpl += jump;
+                               } else
+                                       chan->insmpl += f->samples;
+#endif
+                               if (ast_writestream(chan->monitor->read_stream, f) < 0)
                                        ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
-                               }
                        }
                        if (chan->pvt->readtrans) {
                                f = ast_translate(chan->pvt->readtrans, f, 1);
@@ -1360,18 +1381,32 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
                                f = ast_translate(chan->pvt->writetrans, fr, 0);
                        } else
                                f = fr;
-                       if (f)  
-                       {
+                       if (f) {
                                res = chan->pvt->write(chan, f);
                                if( chan->monitor &&
                                                chan->monitor->write_stream &&
                                                f && ( f->frametype == AST_FRAME_VOICE ) ) {
-                                       if( ast_writestream( chan->monitor->write_stream, f ) < 0 ) {
+#ifndef MONITOR_CONSTANT_DELAY
+                                       int jump = chan->insmpl - chan->outsmpl - 2 * f->samples;
+                                       if (jump >= 0) {
+                                               if (ast_seekstream(chan->monitor->write_stream, jump + f->samples, SEEK_FORCECUR) == -1)
+                                                       ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
+                                               chan->outsmpl += jump + 2 * f->samples;
+                                       } else
+                                               chan->outsmpl += f->samples;
+#else
+                                       int jump = chan->insmpl - chan->outsmpl;
+                                       if (jump - MONITOR_DELAY >= 0) {
+                                               if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1)
+                                                       ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
+                                               chan->outsmpl += jump;
+                                       } else
+                                               chan->outsmpl += f->samples;
+#endif
+                               if (ast_writestream(chan->monitor->write_stream, f) < 0)
                                                ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
-                                       }
                                }
-                       }
-                       else
+                       } else
                                res = 0;
                }
        }
index b35ff96..23a3c5a 100755 (executable)
@@ -174,14 +174,16 @@ static int g729_seek(struct ast_filestream *fs, long sample_offset, int whence)
        max = lseek(fs->fd, 0, SEEK_END);
        
        bytes = 20 * (sample_offset / 160);
-       if(whence == SEEK_SET)
+       if (whence == SEEK_SET)
                offset = bytes;
-       if(whence == SEEK_CUR)
+       else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
                offset = cur + bytes;
-       if(whence == SEEK_END)
+       else if (whence == SEEK_END)
                offset = max - bytes;
-       offset = (offset > max)?max:offset;
-       offset = (offset < min)?min:offset;
+       if (whence != SEEK_FORCECUR) {
+               offset = (offset > max)?max:offset;
+               offset = (offset < min)?min:offset;
+       }
        if (lseek(fs->fd, offset, SEEK_SET) < 0)
                return -1;
        return 0;
index 078d79d..ad39c0a 100755 (executable)
@@ -185,12 +185,14 @@ static int gsm_seek(struct ast_filestream *fs, long sample_offset, int whence)
        distance = (sample_offset/160) * 33;
        if(whence == SEEK_SET)
                offset = distance;
-       if(whence == SEEK_CUR)
+       else if(whence == SEEK_CUR || whence == SEEK_FORCECUR)
                offset = distance + cur;
-       if(whence == SEEK_END)
+       else if(whence == SEEK_END)
                offset = max - distance;
-       offset = (offset > max)?max:offset;
-       offset = (offset < min)?min:offset;
+       if (whence != SEEK_FORCECUR) {
+               offset = (offset > max)?max:offset;
+               offset = (offset < min)?min:offset;
+       }
        return lseek(fs->fd, offset, SEEK_SET);
 }
 
index bff51d6..832110e 100755 (executable)
@@ -41,8 +41,9 @@ struct ast_filestream {
        struct timeval last;
 };
 
-
+#if 0
 static struct ast_filestream *glist = NULL;
+#endif
 static ast_mutex_t mp3_lock = AST_MUTEX_INITIALIZER;
 static int glistcnt = 0;
 
index ebc9bf8..038de17 100755 (executable)
@@ -163,14 +163,16 @@ static int pcm_seek(struct ast_filestream *fs, long sample_offset, int whence)
        min = 0;
        cur = lseek(fs->fd, 0, SEEK_CUR);
        max = lseek(fs->fd, 0, SEEK_END);
-       if(whence == SEEK_SET)
+       if (whence == SEEK_SET)
                offset = sample_offset;
-       if(whence == SEEK_CUR)
+       else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
                offset = sample_offset + cur;
-       if(whence == SEEK_END)
+       else if (whence == SEEK_END)
                offset = max - sample_offset;
-       offset = (offset > max)?max:offset;
-       offset = (offset < min)?min:offset;
+       if (whence != SEEK_FORCECUR) {
+               offset = (offset > max)?max:offset;
+               offset = (offset < min)?min:offset;
+       }
        return lseek(fs->fd, offset, SEEK_SET);
 }
 
index 8e96b41..54d79bb 100755 (executable)
@@ -242,14 +242,16 @@ static int pcm_seek(struct ast_filestream *fs, long sample_offset, int whence)
        min = 0;
        cur = lseek(fs->fd, 0, SEEK_CUR);
        max = lseek(fs->fd, 0, SEEK_END);
-       if(whence == SEEK_SET)
+       if (whence == SEEK_SET)
                offset = sample_offset;
-       if(whence == SEEK_CUR)
+       else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
                offset = sample_offset + cur;
-       if(whence == SEEK_END)
+       else if (whence == SEEK_END)
                offset = max - sample_offset;
-       offset = (offset > max)?max:offset;
-       offset = (offset < min)?min:offset;
+       if (whence != SEEK_FORCECUR) {
+               offset = (offset > max)?max:offset;
+               offset = (offset < min)?min:offset;
+       }
        return lseek(fs->fd, offset, SEEK_SET);
 }
 
index 3771df3..2a549b7 100755 (executable)
@@ -499,14 +499,16 @@ static int wav_seek(struct ast_filestream *fs, long sample_offset, int whence)
        min = 44; /* wav header is 44 bytes */
        cur = lseek(fs->fd, 0, SEEK_CUR);
        max = lseek(fs->fd, 0, SEEK_END);
-       if(whence == SEEK_SET)
+       if (whence == SEEK_SET)
                offset = samples + min;
-       if(whence == SEEK_CUR)
+       else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
                offset = samples + cur;
-       if(whence == SEEK_END)
-               offset = max - samples; 
-       offset = (offset > max)?max:offset;
-       offset = (offset < min)?min:offset;
+       else if (whence == SEEK_END)
+               offset = max - samples;
+        if (whence != SEEK_FORCECUR) {
+               offset = (offset > max)?max:offset;
+               offset = (offset < min)?min:offset;
+       }
        return lseek(fs->fd,offset,SEEK_SET);
 }
 
index fbb97d6..55a607d 100755 (executable)
@@ -478,12 +478,14 @@ static int wav_seek(struct ast_filestream *fs, long sample_offset, int whence)
        distance = (sample_offset/320) * 65;
        if(whence == SEEK_SET)
                offset = distance + min;
-       if(whence == SEEK_CUR)
+       else if(whence == SEEK_CUR || whence == SEEK_FORCECUR)
                offset = distance + cur;
-       if(whence == SEEK_END)
+       else if(whence == SEEK_END)
                offset = max - distance;
-       offset = (offset < min)?min:offset;
-       offset = (offset > max)?max:offset;
+       if (whence != SEEK_FORCECUR) {
+               offset = (offset < min)?min:offset;
+               offset = (offset > max)?max:offset;
+       }
        fs->secondhalf = 0;
        return lseek(fs->fd, offset, SEEK_SET);
 }
index 7cd2470..5a39a67 100755 (executable)
@@ -199,6 +199,10 @@ struct ast_channel {
        /* Channel monitoring */
        struct ast_channel_monitor *monitor;
 
+       /*! Track the read/written samples for monitor use */
+       unsigned long insmpl;
+       unsigned long outsmpl;
+
        /* Frames in/out counters */
        unsigned int fin;
        unsigned int fout;
index da3723d..f7808e4 100755 (executable)
@@ -27,6 +27,8 @@ extern "C" {
 //! Convenient for waiting
 #define AST_DIGIT_ANY "0123456789#*"
 
+#define SEEK_FORCECUR  10
+       
 /* Defined by individual formats.  First item MUST be a
    pointer for use by the stream manager */
 struct ast_filestream;