@ -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 ;
}