diff options
Diffstat (limited to 'main/channel.c')
-rw-r--r-- | main/channel.c | 39 |
1 files changed, 31 insertions, 8 deletions
diff --git a/main/channel.c b/main/channel.c index d18ab3db7..142a15acb 100644 --- a/main/channel.c +++ b/main/channel.c @@ -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" @@ -2610,6 +2611,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 */ @@ -2994,18 +3017,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.codec), 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.codec), 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 @@ -3565,19 +3588,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.codec), 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.codec), 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; } |