]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Merged revisions 246899 via svnmerge from
authorDavid Vossel <dvossel@digium.com>
Tue, 16 Feb 2010 17:13:03 +0000 (17:13 +0000)
committerDavid Vossel <dvossel@digium.com>
Tue, 16 Feb 2010 17:13:03 +0000 (17:13 +0000)
https://origsvn.digium.com/svn/asterisk/trunk

........
  r246899 | dvossel | 2010-02-16 11:07:41 -0600 (Tue, 16 Feb 2010) | 16 lines

  fixes sample rate conversion issue with Monitor application

  When using ast_seekstream with the read/write streams of a monitor,
  the number of samples we are seeking must be of the same rate as the
  stream or the jump calculation will be incorrect.  This patch adds logic
  to correctly convert the number of samples to jump to the sample rate
  the read/write stream is using.

  For example, if the call is G722 (16khz) and the read/write stream is
  recording a 8khz wav, seeking 320 samples of 16khz audio is not the
  same as seeking 320 samples of 8khz audio when performing the ast_seekstream
  on the stream.

  ABE-2044
........

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.6.1@246902 65c4cc65-6c06-0410-ace0-fbb531ad65f3

main/channel.c

index b7b8e1b62461c7c430a342023e6abaaf20e762ac..5f1a9b3f789fb1425dd6d44ef7b3cba2b589dad4 100644 (file)
@@ -37,6 +37,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 
 #include "asterisk/pbx.h"
 #include "asterisk/frame.h"
+#include "asterisk/mod_format.h"
 #include "asterisk/sched.h"
 #include "asterisk/channel.h"
 #include "asterisk/musiconhold.h"
@@ -2583,6 +2584,28 @@ static inline int should_skip_dtmf(struct ast_channel *chan)
        return 0;
 }
 
+/*!
+ * \brief calculates the number of samples to jump forward with in a monitor stream.
+ * \note When using ast_seekstream() with the read and write streams of a monitor,
+ * the number of samples to seek forward must be of the same sample rate as the stream
+ * or else the jump will not be calculated correctly.
+ *
+ * \retval number of samples to seek forward after rate conversion.
+ */
+static inline int calc_monitor_jump(int samples, int sample_rate, int seek_rate)
+{
+       int diff = sample_rate - seek_rate;
+
+       if (diff > 0) {
+               samples = samples / (float) (sample_rate / seek_rate);
+       } else if (diff < 0) {
+               samples = samples * (float) (seek_rate / sample_rate);
+       }
+
+       return samples;
+}
+
 static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
 {
        struct ast_frame *f = NULL;     /* the return value */
@@ -2967,18 +2990,18 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
 #ifndef MONITOR_CONSTANT_DELAY
                                        int jump = chan->outsmpl - chan->insmpl - 4 * f->samples;
                                        if (jump >= 0) {
-                                               jump = chan->outsmpl - chan->insmpl;
+                                               jump = calc_monitor_jump((chan->outsmpl - chan->insmpl), ast_format_rate(f->subclass), ast_format_rate(chan->monitor->read_stream->fmt->format));
                                                if (ast_seekstream(chan->monitor->read_stream, jump, 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 + f->samples;
+                                               chan->insmpl += (chan->outsmpl - chan->insmpl) + f->samples;
                                        } else
                                                chan->insmpl+= f->samples;
 #else
-                                       int jump = chan->outsmpl - chan->insmpl;
+                                       int jump = calc_monitor_jump((chan->outsmpl - chan->insmpl), ast_format_rate(f->subclass), ast_format_rate(chan->monitor->read_stream->fmt->format));
                                        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;
+                                               chan->insmpl += chan->outsmpl - chan->insmpl;
                                        } else
                                                chan->insmpl += f->samples;
 #endif
@@ -3537,19 +3560,19 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
 #ifndef MONITOR_CONSTANT_DELAY
                                int jump = chan->insmpl - chan->outsmpl - 4 * cur->samples;
                                if (jump >= 0) {
-                                       jump = chan->insmpl - chan->outsmpl;
+                                       jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(f->subclass), ast_format_rate(chan->monitor->read_stream->fmt->format));
                                        if (ast_seekstream(chan->monitor->write_stream, jump, 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 + cur->samples;
+                                       chan->outsmpl += (chan->insmpl - chan->outsmpl) + cur->samples;
                                } else {
                                        chan->outsmpl += cur->samples;
                                }
 #else
-                               int jump = chan->insmpl - chan->outsmpl;
+                               int jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(f->subclass), ast_format_rate(chan->monitor->read_stream->fmt->format));
                                if (jump - MONITOR_DELAY >= 0) {
                                        if (ast_seekstream(chan->monitor->write_stream, jump - cur->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;
+                                       chan->outsmpl += chan->insmpl - chan->outsmpl;
                                } else {
                                        chan->outsmpl += cur->samples;
                                }