[svn-commits] dcb: trunk r451 - in /trunk: chan_mobile.c configs/mobile.conf.sample
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Sun Sep 23 03:28:41 CDT 2007
Author: dcb
Date: Sun Sep 23 03:28:40 2007
New Revision: 451
URL: http://svn.digium.com/view/asterisk-addons?view=rev&rev=451
Log:
* Added support for detecting misalined sco audio data from the bluetooth adapter.
See alignmentdetection=yes in configs/mobile.conf.sample.
Modified:
trunk/chan_mobile.c
trunk/configs/mobile.conf.sample
Modified: trunk/chan_mobile.c
URL: http://svn.digium.com/view/asterisk-addons/trunk/chan_mobile.c?view=diff&rev=451&r1=450&r2=451
==============================================================================
--- trunk/chan_mobile.c (original)
+++ trunk/chan_mobile.c Sun Sep 23 03:28:40 2007
@@ -119,6 +119,7 @@
char id[31]; /* the 'name' from mobile.conf */
bdaddr_t addr; /* adddress of adapter */
unsigned int inuse:1; /* are we in use ? */
+ unsigned int alignment_detection:1; /* do alignment detection on this adpater? */
int sco_socket;
AST_LIST_ENTRY(adapter_pvt) entry;
};
@@ -157,6 +158,10 @@
unsigned int no_callsetup:1;
unsigned int has_sms:1;
unsigned int sent_answer:1;
+ unsigned int do_alignment_detection:1;
+ unsigned int alignment_detection_triggered:1;
+ short alignment_samples[4];
+ int alignment_count;
char sms_txt[160];
struct ast_dsp *dsp;
struct ast_frame *dsp_fr;
@@ -219,6 +224,8 @@
static int mbl_write(struct ast_channel *ast, struct ast_frame *frame);
static int mbl_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
static int mbl_devicestate(void *data);
+
+static void do_alignment_detection(struct mbl_pvt *pvt, char *buf, int buflen);
static int rfcomm_connect(bdaddr_t src, bdaddr_t dst, int remote_channel);
static int rfcomm_write(struct mbl_pvt *pvt, char *buf);
@@ -491,6 +498,12 @@
pvt->io_save_len = 0;
pvt->sent_answer = 0;
pvt->skip_frames = 0;
+ pvt->alignment_count = 0;
+ pvt->alignment_detection_triggered = 0;
+ if (pvt->adapter->alignment_detection)
+ pvt->do_alignment_detection = 1;
+ else
+ pvt->do_alignment_detection = 0;
chn = ast_channel_alloc(1, state, cid_num, pvt->id, 0, 0, pvt->context, 0, "Mobile/%s-%04lx", pvt->id, ast_random() & 0xffff);
if (chn) {
@@ -777,6 +790,8 @@
memcpy(pvt->io_save_buf + pvt->io_save_len, frame->data, io_need);
sco_write(pvt->sco_socket, pvt->io_save_buf, DEVICE_FRAME_SIZE);
if ((r = sco_read(pvt->sco_socket, buf, DEVICE_FRAME_SIZE))) {
+ if (pvt->do_alignment_detection)
+ do_alignment_detection(pvt, buf, r);
sco_write(pvt->io_pipe[1], buf, r);
}
}
@@ -787,6 +802,8 @@
for (i=0; i<num_frames; i++) {
sco_write(pvt->sco_socket, pfr, DEVICE_FRAME_SIZE);
if ((r = sco_read(pvt->sco_socket, buf, DEVICE_FRAME_SIZE))) {
+ if (pvt->do_alignment_detection)
+ do_alignment_detection(pvt, buf, r);
sco_write(pvt->io_pipe[1], buf, r);
}
pfr += DEVICE_FRAME_SIZE;
@@ -839,6 +856,72 @@
}
return res;
+
+}
+
+/*
+
+ Callback helpers
+
+*/
+
+/*
+
+ do_alignment_detection()
+
+ This routine attempts to detect where we get misaligned sco audio data from the bluetooth adaptor.
+
+ Its enabled by alignmentdetect=yes under the adapter entry in mobile.conf
+
+ Some adapters suffer a problem where occasionally they will byte shift the audio stream one byte to the right.
+ The result is static or white noise on the inbound (from the adapter) leg of the call.
+ This is characterised by a sudden jump in magnitude of the value of the 16 bit samples.
+
+ Here we look at the first 4 48 byte frames. We average the absolute values of each sample in the frame,
+ then average the sum of the averages of frames 1, 2, and 3.
+ Frame zero is usually zero.
+ If the end result > 100, and it usually is if we have the problem, set a flag and compensate by shifting the bytes
+ for each subsequent frame during the call.
+
+ If the result is <= 100 then clear the flag so we dont come back in here...
+
+ This seems to work OK....
+
+*/
+
+static void do_alignment_detection(struct mbl_pvt *pvt, char *buf, int buflen)
+{
+
+ int i;
+ short a, *s;
+ char *p;
+
+ if (pvt->alignment_detection_triggered) {
+ for (i=buflen, p=buf+buflen-1; i>0; i--, p--)
+ *p = *(p-1);
+ *(p+1) = 0;
+ return;
+ }
+
+ if (pvt->alignment_count < 4) {
+ s = (short *)buf;
+ for (i=0, a=0; i<buflen/2; i++) {
+ a += *s++;
+ a /= i+1;
+ }
+ pvt->alignment_samples[pvt->alignment_count++] = a;
+ return;
+ }
+
+ ast_debug(1, "Alignment Detection result is [%-d %-d %-d %-d]\n", pvt->alignment_samples[0], pvt->alignment_samples[1], pvt->alignment_samples[2], pvt->alignment_samples[3]);
+
+ a = abs(pvt->alignment_samples[1]) + abs(pvt->alignment_samples[2]) + abs(pvt->alignment_samples[3]);
+ a /= 3;
+ if (a > 100) {
+ pvt->alignment_detection_triggered = 1;
+ ast_debug(1, "Alignment Detection Triggered.\n");
+ } else
+ pvt->do_alignment_detection = 0;
}
@@ -1752,7 +1835,7 @@
struct ast_config *cfg = NULL;
char *cat = NULL;
struct ast_variable *var;
- const char *id, *address, *useadapter, *port, *context, *type, *skip, *group, *master, *nocallsetup;
+ const char *id, *address, *useadapter, *port, *context, *type, *skip, *group, *master, *nocallsetup, *aligndetect;
struct mbl_pvt *pvt;
struct adapter_pvt *adapter;
uint16_t vs;
@@ -1776,12 +1859,18 @@
id = ast_variable_retrieve(cfg, cat, "id");
address = ast_variable_retrieve(cfg, cat, "address");
master = ast_variable_retrieve(cfg, cat, "forcemaster");
+ aligndetect = ast_variable_retrieve(cfg, cat, "alignmentdetection");
ast_debug(1, "Loading adapter %s %s.\n", id, address);
if (!ast_strlen_zero(id) && !ast_strlen_zero(address)) {
if ((adapter = ast_malloc(sizeof(struct adapter_pvt)))) {
ast_copy_string(adapter->id, id, sizeof(adapter->id));
str2ba(address, &adapter->addr);
adapter->inuse = 0;
+ adapter->alignment_detection = 0;
+ if (!ast_strlen_zero(aligndetect)) {
+ if (*aligndetect == 'Y' || *aligndetect == 'y')
+ adapter->alignment_detection = 1;
+ }
adapter->dev_id = hci_devid(address);
adapter->hci_socket = hci_open_dev(adapter->dev_id);
if (adapter->dev_id < 0 || adapter->hci_socket < 0) {
Modified: trunk/configs/mobile.conf.sample
URL: http://svn.digium.com/view/asterisk-addons/trunk/configs/mobile.conf.sample?view=diff&rev=451&r1=450&r2=451
==============================================================================
--- trunk/configs/mobile.conf.sample (original)
+++ trunk/configs/mobile.conf.sample Sun Sep 23 03:28:40 2007
@@ -15,6 +15,9 @@
id=blue
address=00:09:DD:60:01:A3
;forcemaster=yes ; attempt to force adapter into master mode. default is no.
+;alignmentdetection=yes ; enable this if you sometimes get 'white noise' on asterisk side of the call
+ ; its a bug in the bluetooth adapter firmware, enabling this will compensate for it.
+ ; default is no.
[adapter]
id=dlink
More information about the svn-commits
mailing list