Issue #5374 - Enable internal timing of generators (cmantunes)

Thanks everyone involved for hard work, testing and testing!


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@16473 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.4
Olle Johansson 19 years ago
parent 2c4ebe356e
commit 50f0b12880

@ -788,6 +788,8 @@ samples: adsi
echo ";astctlowner = root" ; \
echo ";astctlgroup = apache" ; \
echo ";astctl = asterisk.ctl" ; \
echo ";[options]" ; \
echo ";internal_timing = yes" ; \
) > $(DESTDIR)$(ASTCONFPATH) ; \
else \
echo "Skipping asterisk.conf creation"; \

@ -71,20 +71,27 @@ static int milliwatt_generate(struct ast_channel *chan, void *data, int len, int
{
struct ast_frame wf;
unsigned char buf[AST_FRIENDLY_OFFSET + 640];
int i,*indexp = (int *) data;
if (len + AST_FRIENDLY_OFFSET > sizeof(buf))
{
ast_log(LOG_WARNING,"Only doing %d bytes (%d bytes requested)\n",(int)(sizeof(buf) - AST_FRIENDLY_OFFSET),len);
len = sizeof(buf) - AST_FRIENDLY_OFFSET;
const int maxsamples = sizeof (buf) / sizeof (buf[0]);
int i, *indexp = (int *) data;
/* Instead of len, use samples, because channel.c generator_force
* generate(chan, tmp, 0, 160) ignores len. In any case, len is
* a multiple of samples, given by number of samples times bytes per
* sample. In the case of ulaw, len = samples. for signed linear
* len = 2 * samples */
if (samples > maxsamples) {
ast_log(LOG_WARNING, "Only doing %d samples (%d requested)\n", maxsamples, samples);
samples = maxsamples;
}
len = samples * sizeof (buf[0]);
wf.frametype = AST_FRAME_VOICE;
wf.subclass = AST_FORMAT_ULAW;
wf.offset = AST_FRIENDLY_OFFSET;
wf.mallocd = 0;
wf.data = buf + AST_FRIENDLY_OFFSET;
wf.datalen = len;
wf.samples = wf.datalen;
wf.samples = samples;
wf.src = "app_milliwatt";
wf.delivery.tv_sec = 0;
wf.delivery.tv_usec = 0;

@ -1177,32 +1177,31 @@ static int sms_generate (struct ast_channel *chan, void *data, int len, int samp
{
struct ast_frame f = { 0 };
unsigned char waste[AST_FRIENDLY_OFFSET];
#define MAXSAMPLES (800)
#ifdef OUTALAW
unsigned char buf[800];
unsigned char buf[MAXSAMPLES];
#else
signed short buf[800];
signed short buf[MAXSAMPLES];
#endif
#define SAMPLE2LEN (sizeof (buf[0]))
sms_t *h = data;
int i;
if (len > sizeof (buf)) {
ast_log (LOG_WARNING, "Only doing %d bytes (%d bytes requested)\n", (int)(sizeof (buf) / sizeof (signed short)), len);
len = sizeof (buf);
#ifdef OUTALAW
samples = len;
#else
samples = len / 2;
#endif
if (samples > MAXSAMPLES) {
ast_log (LOG_WARNING, "Only doing %d samples (%d requested)\n",
MAXSAMPLES, samples);
samples = MAXSAMPLES;
}
len = samples * SAMPLE2LEN;
waste[0] = 0; /* make compiler happy */
f.frametype = AST_FRAME_VOICE;
#ifdef OUTALAW
f.subclass = AST_FORMAT_ALAW;
f.datalen = samples;
#else
f.subclass = AST_FORMAT_SLINEAR;
f.datalen = samples * 2;
#endif
f.datalen = len;
f.offset = AST_FRIENDLY_OFFSET;
f.mallocd = 0;
f.data = buf;
@ -1254,6 +1253,8 @@ static int sms_generate (struct ast_channel *chan, void *data, int len, int samp
return -1;
}
return 0;
#undef SAMPLE2LEN
#undef MAXSAMPLES
}
static void sms_process (sms_t * h, int samples, signed short *data)

@ -9,7 +9,7 @@
asterisk \- All-purpose telephony server.
.SH SYNOPSIS
\fBasterisk\fR [ \fB-tThfdvVqpRgcin\fR ] [ \fB-C \fIfile\fB\fR ] [ \fB-U \fIuser\fB\fR ] [ \fB-G \fIgroup\fB\fR ] [ \fB-x \fIcommand\fB\fR ] [ \fB-M \fIvalue\fB\fR ]
\fBasterisk\fR [ \fB-tThfdvVqpRgciIn\fR ] [ \fB-C \fIfile\fB\fR ] [ \fB-U \fIuser\fB\fR ] [ \fB-G \fIgroup\fB\fR ] [ \fB-x \fIcommand\fB\fR ] [ \fB-M \fIvalue\fB\fR ]
\fBasterisk -r\fR [ \fB-v\fR ] [ \fB-x \fIcommand\fB\fR ]
@ -114,6 +114,12 @@ to a running Asterisk process and provide a console interface
for controlling it. Additionally, if connection to the Asterisk
process is lost, attempt to reconnect for as long as 30 seconds.
.TP
\fB-I\fR
Enable internal timing if Zaptel timer is available
The default behaviour is that outbound packets are phase locked
to inbound packets. Enabling this switch causes them to be
locked to the internal Zaptel timer instead.
.TP
\fB-t\fR
When recording files, write them first into a temporary holding directory,
then move them into the final location when done.

@ -161,6 +161,9 @@ int option_debug = 0; /*!< Debug level */
double option_maxload = 0.0; /*!< Max load avg on system */
int option_maxcalls = 0; /*!< Max number of active calls */
int option_internal_timing = 0;
/*! @} */
char record_cache_dir[AST_CACHE_DIR_LEN] = AST_TMP_DIR;
@ -1970,6 +1973,9 @@ static void ast_readconfig(void)
/* Transmit SLINEAR silence while a channel is being recorded */
} else if (!strcasecmp(v->name, "transmit_silence_during_record")) {
ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSMIT_SILENCE);
/* Enable internal timing */
} else if (!strcasecmp(v->name, "internal_timing")) {
option_internal_timing = ast_true(v->value);
} else if (!strcasecmp(v->name, "maxcalls")) {
if ((sscanf(v->value, "%d", &option_maxcalls) != 1) || (option_maxcalls < 0)) {
option_maxcalls = 0;
@ -2049,7 +2055,7 @@ int main(int argc, char *argv[])
}
*/
/* Check for options */
while((c=getopt(argc, argv, "tThfdvVqprRgcinx:U:G:C:L:M:")) != -1) {
while((c=getopt(argc, argv, "tThfdvVqprRgciInx:U:G:C:L:M:")) != -1) {
switch(c) {
case 'd':
option_debug++;
@ -2088,6 +2094,7 @@ int main(int argc, char *argv[])
case 'q':
ast_set_flag(&ast_options, AST_OPT_FLAG_QUIET);
break;
break;
case 't':
ast_set_flag(&ast_options, AST_OPT_FLAG_CACHE_RECORD_FILES);
break;
@ -2102,6 +2109,9 @@ int main(int argc, char *argv[])
ast_copy_string(ast_config_AST_CONFIG_FILE, optarg, sizeof(ast_config_AST_CONFIG_FILE));
ast_set_flag(&ast_options, AST_OPT_FLAG_OVERRIDE_CONFIG);
break;
case 'I':
option_internal_timing = 1;
break;
case 'i':
ast_set_flag(&ast_options, AST_OPT_FLAG_INIT_KEYS);
break;

@ -21,7 +21,7 @@
<refsynopsisdiv>
<cmdsynopsis>
<command>asterisk</command>
<arg><option>-tThfdvVqpRgcin</option></arg>
<arg><option>-tThfdvVqpRgciIn</option></arg>
<arg><option>-C </option><replaceable class="parameter">file</replaceable></arg>
<arg><option>-U </option><replaceable class="parameter">user</replaceable></arg>
<arg><option>-G </option><replaceable class="parameter">group</replaceable></arg>
@ -38,7 +38,7 @@
</refsynopsisdiv>
<refsect1>
<refsect1info>
<date>2004-07-01</date>
<date>2006-03-29</date>
</refsect1info>
<title>DESCRIPTION</title>
<para>
@ -153,6 +153,17 @@
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>-I</term>
<listitem>
<para>
Enable internal timing if Zaptel timing is available.
The default behaviour is that outbound packets are phase locked
to inbound packets. Enabling this switch causes them to be
locked to the internal Zaptel timer instead.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>-L <replaceable class="parameter">loadaverage</replaceable></term>
<listitem>

@ -1976,29 +1976,33 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
f = &ast_null_frame;
}
/* Run any generator sitting on the channel */
if (chan->generatordata) {
/* Mask generator data temporarily and apply. If there is a timing function, it
will be calling the generator instead */
/* Run generator sitting on the line if timing device not available
* and synchronous generation of outgoing frames is necessary */
if (chan->generatordata && !ast_internal_timing_enabled(chan)) {
void *tmp;
int res;
int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples);
if (chan->timingfunc) {
if (option_debug > 1)
ast_log(LOG_DEBUG, "Generator got voice, switching to phase locked mode\n");
ast_settimeout(chan, 0, NULL, NULL);
}
tmp = chan->generatordata;
chan->generatordata = NULL;
generate = chan->generator->generate;
res = generate(chan, tmp, f->datalen, f->samples);
chan->generatordata = tmp;
if (res) {
if (option_debug > 1)
ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
ast_deactivate_generator(chan);
}
} else if (f->frametype == AST_FRAME_CNG) {
if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) {
if (option_debug > 1)
ast_log(LOG_DEBUG, "Generator got CNG, switching to timed mode\n");
ast_settimeout(chan, 160, generator_force, chan);
}
@ -2027,6 +2031,14 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
return f;
}
int ast_internal_timing_enabled(struct ast_channel *chan)
{
int ret = option_internal_timing && chan->timingfd > -1;
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Internal timing is %s (option_internal_timing=%d chan->timingfd=%d)\n", ret? "enabled": "disabled", option_internal_timing, chan->timingfd);
return ret;
}
struct ast_frame *ast_read(struct ast_channel *chan)
{
return __ast_read(chan, 0);

@ -4699,6 +4699,7 @@ static int add_sdp(struct sip_request *resp, struct sip_pvt *p)
debug);
}
if(!ast_internal_timing_enabled(p->owner))
ast_build_string(&a_audio_next, &a_audio_left, "a=silenceSupp:off - - - -\r\n");
if ((m_audio_left < 2) || (m_video_left < 2) || (a_audio_left == 0) || (a_video_left == 0))

@ -52,6 +52,7 @@ timestamp = yes | no ; Force timestamping on log entries to console (-T)
runuser = asterisk ; User to run asterisk as (-U) NOTE: will require changes to
; directory and device permisions
rungroup = asterisk ; Group to run asterisk as (-G)
internal_timing = yes | no ; Enable internal timing support (-I)
;These options have no command line equivalent
cache_record_files = yes | no ; Cache record() files in another directory until completion

@ -1124,6 +1124,16 @@ struct ast_silence_generator *ast_channel_start_silence_generator(struct ast_cha
*/
void ast_channel_stop_silence_generator(struct ast_channel *chan, struct ast_silence_generator *state);
/*!
\brief Check if the channel can run in internal timing mode.
\param chan The channel to check
\return boolean
This function will return 1 if internal timing is enabled and the timing
device is available.
*/
int ast_internal_timing_enabled(struct ast_channel *chan);
/* Misc. functions below */
/* if fd is a valid descriptor, set *pfd with the descriptor

@ -101,10 +101,10 @@ enum ast_option_flags {
extern struct ast_flags ast_options;
extern int option_verbose;
extern int option_debug;
extern int option_maxcalls;
extern int option_debug; /*!< Debugging */
extern int option_maxcalls; /*!< Maximum number of simultaneous channels */
extern double option_maxload;
extern int option_internal_timing; /*!< Flag for internal timing (RTP) */
extern char defaultlanguage[];
extern time_t ast_startuptime;

Loading…
Cancel
Save