From 2127848d6c09a59d10844c12ec2175c4c820b46d Mon Sep 17 00:00:00 2001 From: Richard Mudgett Date: Mon, 14 Oct 2013 22:52:42 +0000 Subject: [PATCH] chan_dahdi: Add config support for hwgain settings. * Add hwtxgain and hwrxgain config options to chan_dahdi.conf with documentation in chan_dahdi.conf.sample. (closes issue ASTERISK-22429) Reported by: Jaco Kroon Patches: jira_asterisk_22429_hwgain_trunk.patch (license #5621) patch uploaded by rmudgett git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@400950 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/chan_dahdi.c | 79 ++++++++++++++++++++++++++++------ channels/chan_dahdi.h | 8 ++++ configs/chan_dahdi.conf.sample | 68 +++++++++++++++++++---------- 3 files changed, 120 insertions(+), 35 deletions(-) diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c index 9f1f1a586c..cc82f156f8 100644 --- a/channels/chan_dahdi.c +++ b/channels/chan_dahdi.c @@ -4526,6 +4526,15 @@ void dahdi_ec_disable(struct dahdi_pvt *p) p->echocanon = 0; } +static int set_hwgain(int fd, float gain, int tx_direction) +{ + struct dahdi_hwgain hwgain; + + hwgain.newgain = gain * 10.0; + hwgain.tx = tx_direction; + return ioctl(fd, DAHDI_SET_HWGAIN, &hwgain) < 0; +} + /* perform a dynamic range compression transform on the given sample */ static int drc_sample(int sample, float drc) { @@ -12451,6 +12460,10 @@ static struct dahdi_pvt *mkintf(int channel, const struct dahdi_chan_conf *conf, } } } + tmp->hwrxgain_enabled = conf->chan.hwrxgain_enabled; + tmp->hwtxgain_enabled = conf->chan.hwtxgain_enabled; + tmp->hwrxgain = conf->chan.hwrxgain; + tmp->hwtxgain = conf->chan.hwtxgain; tmp->cid_rxgain = conf->chan.cid_rxgain; tmp->rxgain = conf->chan.rxgain; tmp->txgain = conf->chan.txgain; @@ -12458,6 +12471,12 @@ static struct dahdi_pvt *mkintf(int channel, const struct dahdi_chan_conf *conf, tmp->rxdrc = conf->chan.rxdrc; tmp->tonezone = conf->chan.tonezone; if (tmp->subs[SUB_REAL].dfd > -1) { + if (tmp->hwrxgain_enabled) { + tmp->hwrxgain_enabled = !set_hwgain(tmp->subs[SUB_REAL].dfd, tmp->hwrxgain, 0); + } + if (tmp->hwtxgain_enabled) { + tmp->hwtxgain_enabled = !set_hwgain(tmp->subs[SUB_REAL].dfd, tmp->hwtxgain, 1); + } set_actual_gain(tmp->subs[SUB_REAL].dfd, tmp->rxgain, tmp->txgain, tmp->rxdrc, tmp->txdrc, tmp->law); if (tmp->dsp) ast_dsp_set_digitmode(tmp->dsp, DSP_DIGITMODE_DTMF | tmp->dtmfrelax); @@ -15010,6 +15029,8 @@ static char *dahdi_show_channel(struct ast_cli_entry *e, int cmd, struct ast_cli struct dahdi_confinfo ci; struct dahdi_params ps; int x; + char hwrxgain[15]; + char hwtxgain[15]; switch (cmd) { case CLI_INIT: @@ -15083,7 +15104,18 @@ static char *dahdi_show_channel(struct ast_cli_entry *e, int cmd, struct ast_cli ast_cli(a->fd, "Default law: %s\n", tmp->law_default == DAHDI_LAW_MULAW ? "ulaw" : tmp->law_default == DAHDI_LAW_ALAW ? "alaw" : "unknown"); ast_cli(a->fd, "Fax Handled: %s\n", tmp->faxhandled ? "yes" : "no"); ast_cli(a->fd, "Pulse phone: %s\n", tmp->pulsedial ? "yes" : "no"); - ast_cli(a->fd, "Gains (RX/TX): %.2f/%.2f\n", tmp->rxgain, tmp->txgain); + if (tmp->hwrxgain_enabled) { + snprintf(hwrxgain, sizeof(hwrxgain), "%.1f", tmp->hwrxgain); + } else { + ast_copy_string(hwrxgain, "Disabled", sizeof(hwrxgain)); + } + if (tmp->hwtxgain_enabled) { + snprintf(hwtxgain, sizeof(hwtxgain), "%.1f", tmp->hwtxgain); + } else { + ast_copy_string(hwtxgain, "Disabled", sizeof(hwtxgain)); + } + ast_cli(a->fd, "HW Gains (RX/TX): %s/%s\n", hwrxgain, hwtxgain); + ast_cli(a->fd, "SW Gains (RX/TX): %.2f/%.2f\n", tmp->rxgain, tmp->txgain); ast_cli(a->fd, "Dynamic Range Compression (RX/TX): %.2f/%.2f\n", tmp->rxdrc, tmp->txdrc); ast_cli(a->fd, "DND: %s\n", dahdi_dnd(tmp, -1) ? "yes" : "no"); ast_cli(a->fd, "Echo Cancellation:\n"); @@ -15349,9 +15381,8 @@ static char *dahdi_show_version(struct ast_cli_entry *e, int cmd, struct ast_cli static char *dahdi_set_hwgain(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { int channel; - int gain; + float gain; int tx; - struct dahdi_hwgain hwgain; struct dahdi_pvt *tmp = NULL; switch (cmd) { @@ -15359,7 +15390,8 @@ static char *dahdi_set_hwgain(struct ast_cli_entry *e, int cmd, struct ast_cli_a e->command = "dahdi set hwgain {rx|tx}"; e->usage = "Usage: dahdi set hwgain \n" - " Sets the hardware gain on a given channel. Changes take effect\n" + " Sets the hardware gain on a given channel and overrides the\n" + " value provided at module loadtime. Changes take effect\n" " immediately whether the channel is in use or not.\n" "\n" " which direction do you want to change (relative to our module)\n" @@ -15367,7 +15399,6 @@ static char *dahdi_set_hwgain(struct ast_cli_entry *e, int cmd, struct ast_cli_a " is the gain in dB (e.g. -3.5 for -3.5dB)\n" "\n" " Please note:\n" - " * This is currently the only way to set hwgain by the channel driver.\n" " * hwgain is only supportable by hardware with analog ports because\n" " hwgain works on the analog side of an analog-digital conversion.\n"; return NULL; @@ -15386,7 +15417,7 @@ static char *dahdi_set_hwgain(struct ast_cli_entry *e, int cmd, struct ast_cli_a return CLI_SHOWUSAGE; channel = atoi(a->argv[4]); - gain = atof(a->argv[5])*10.0; + gain = atof(a->argv[5]); ast_mutex_lock(&iflock); @@ -15398,15 +15429,21 @@ static char *dahdi_set_hwgain(struct ast_cli_entry *e, int cmd, struct ast_cli_a if (tmp->subs[SUB_REAL].dfd == -1) break; - hwgain.newgain = gain; - hwgain.tx = tx; - if (ioctl(tmp->subs[SUB_REAL].dfd, DAHDI_SET_HWGAIN, &hwgain) < 0) { + if (set_hwgain(tmp->subs[SUB_REAL].dfd, gain, tx)) { ast_cli(a->fd, "Unable to set the hardware gain for channel %d: %s\n", channel, strerror(errno)); ast_mutex_unlock(&iflock); return CLI_FAILURE; } - ast_cli(a->fd, "hardware %s gain set to %d (%.1f dB) on channel %d\n", - tx ? "tx" : "rx", gain, (float)gain/10.0, channel); + ast_cli(a->fd, "Hardware %s gain set to %.1f dB on channel %d.\n", + tx ? "tx" : "rx", gain, channel); + + if (tx) { + tmp->hwtxgain_enabled = 1; + tmp->hwtxgain = gain; + } else { + tmp->hwrxgain_enabled = 1; + tmp->hwrxgain = gain; + } break; } @@ -15478,7 +15515,7 @@ static char *dahdi_set_swgain(struct ast_cli_entry *e, int cmd, struct ast_cli_a return CLI_FAILURE; } - ast_cli(a->fd, "software %s gain set to %.1f on channel %d\n", + ast_cli(a->fd, "Software %s gain set to %.2f dB on channel %d.\n", tx ? "tx" : "rx", gain, channel); if (tx) { @@ -17082,6 +17119,24 @@ static int process_dahdi(struct dahdi_chan_conf *confp, const char *cat, struct if (ast_true(v->value)) { confp->chan.mwimonitor_fsk = 1; } + } else if (!strcasecmp(v->name, "hwrxgain")) { + confp->chan.hwrxgain_enabled = 0; + if (strcasecmp(v->value, "disabled")) { + if (sscanf(v->value, "%30f", &confp->chan.hwrxgain) == 1) { + confp->chan.hwrxgain_enabled = 1; + } else { + ast_log(LOG_WARNING, "Invalid hwrxgain: %s at line %d.\n", v->value, v->lineno); + } + } + } else if (!strcasecmp(v->name, "hwtxgain")) { + confp->chan.hwtxgain_enabled = 0; + if (strcasecmp(v->value, "disabled")) { + if (sscanf(v->value, "%30f", &confp->chan.hwtxgain) == 1) { + confp->chan.hwtxgain_enabled = 1; + } else { + ast_log(LOG_WARNING, "Invalid hwtxgain: %s at line %d.\n", v->value, v->lineno); + } + } } else if (!strcasecmp(v->name, "cid_rxgain")) { if (sscanf(v->value, "%30f", &confp->chan.cid_rxgain) != 1) { ast_log(LOG_WARNING, "Invalid cid_rxgain: %s at line %d.\n", v->value, v->lineno); diff --git a/channels/chan_dahdi.h b/channels/chan_dahdi.h index eb0a5fbb13..91c961910d 100644 --- a/channels/chan_dahdi.h +++ b/channels/chan_dahdi.h @@ -147,6 +147,10 @@ struct dahdi_pvt { int outsigmod; /*!< Outbound Signalling style (modifier) */ int oprmode; /*!< "Operator Services" mode */ struct dahdi_pvt *oprpeer; /*!< "Operator Services" peer tech_pvt ptr */ + /*! \brief Hardware Rx gain set by chan_dahdi.conf */ + float hwrxgain; + /*! \brief Hardware Tx gain set by chan_dahdi.conf */ + float hwtxgain; /*! \brief Amount of gain to increase during caller id */ float cid_rxgain; /*! \brief Software Rx gain set by chan_dahdi.conf */ @@ -402,6 +406,10 @@ struct dahdi_pvt { * \note Applies to all channels */ unsigned int manages_span_alarms:1; + /*! \brief TRUE if hardware Rx gain set by Asterisk */ + unsigned int hwrxgain_enabled; + /*! \brief TRUE if hardware Tx gain set by Asterisk */ + unsigned int hwtxgain_enabled; #if defined(HAVE_PRI) struct sig_pri_span *pri; diff --git a/configs/chan_dahdi.conf.sample b/configs/chan_dahdi.conf.sample index 63be70d71f..7eb270b9ac 100644 --- a/configs/chan_dahdi.conf.sample +++ b/configs/chan_dahdi.conf.sample @@ -808,32 +808,54 @@ echocancelwhenbridged=yes ; ;relaxdtmf=yes ; -; You may also set the default receive and transmit gains (in dB) -; -; Gain Settings: increasing / decreasing the volume level on a channel. -; The values are in db (decibells). A positive number -; increases the volume level on a channel, and a -; negavive value decreases volume level. -; -; Dynamic Range Compression: you can also enable dynamic range compression -; on a channel. This will amplify quiet sounds while leaving -; louder sounds untouched. This is useful in situations where -; a linear gain setting would cause clipping. Acceptable values -; are in the range of 0.0 to around 6.0 with higher values -; causing more compression to be done. -; -; There are several independent gain settings: -; rxgain: gain for the rx (receive - into Asterisk) channel. Default: 0.0 -; txgain: gain for the tx (transmit - out of Asterisk Asterisk) channel. -; Default: 0.0 -; cid_rxgain: set the gain just for the caller ID sounds Asterisk -; emits. Default: 5.0 . -; rxdrc: dynamic range compression for the rx channel. Default: 0.0 -; txdrc: dynamic range compression for the tx channel. Default: 0.0 - +; Hardware gain settings increase/decrease the analog volume level on a channel. +; The values are in db (decibels) and can be adjusted in 0.1 dB increments. +; A positive number increases the volume level on a channel, and a negavive +; value decreases volume level. +; +; Hardware gain settings are only possible on hardware with analog ports +; because the gain is done on the analog side of the analog/digital conversion. +; +; When hardware gains are disabled, Asterisk will NOT touch the gain setting +; already configured in hardware. +; +; hwrxgain: Hardware receive gain for the channel (into Asterisk). +; Default: disabled +; hwtxgain: Hardware transmit gain for the channel (out of Asterisk). +; Default: disabled +; +;hwrxgain=disabled +;hwtxgain=disabled +;hwrxgain=2.0 +;hwtxgain=3.0 +; +; Software gain settings digitally increase/decrease the volume level on a channel. +; The values are in db (decibels). A positive number increases the volume +; level on a channel, and a negavive value decreases volume level. +; +; Software gains work on the digital side of the analog/digital conversion +; and thus can also work with T1/E1 cards. +; +; rxgain: Software receive gain for the channel (into Asterisk). Default: 0.0 +; txgain: Software transmit gain for the channel (out of Asterisk). +; Default: 0.0 +; +; cid_rxgain: Add this gain to rxgain when Asterisk expects to receive +; a Caller ID stream. +; Default: 5.0 . +; ;rxgain=2.0 ;txgain=3.0 ; +; Dynamic Range Compression: You can also enable dynamic range compression +; on a channel. This will digitally amplify quiet sounds while leaving louder +; sounds untouched. This is useful in situations where a linear gain setting +; would cause clipping. Acceptable values are in the range of 0.0 to around +; 6.0 with higher values causing more compression to be done. +; +; rxdrc: dynamic range compression for the rx channel. Default: 0.0 +; txdrc: dynamic range compression for the tx channel. Default: 0.0 +; ;rxdrc=1.0 ;txdrc=4.0 ;