Linux bluetooth development
 help / color / mirror / Atom feed
* Re: [PATCH 04/11] Add msbc encoding and decoding flag
From: Marcel Holtmann @ 2012-10-18 16:47 UTC (permalink / raw)
  To: Frédéric Dalleau; +Cc: linux-bluetooth
In-Reply-To: <1350576911-14678-5-git-send-email-frederic.dalleau@linux.intel.com>

Hi Fred,

>  sbc/sbc.c |   16 ++++++++++++++++
>  sbc/sbc.h |    3 +++
>  2 files changed, 19 insertions(+)
> 
> diff --git a/sbc/sbc.c b/sbc/sbc.c
> index 6fff132..c40aa15 100644
> --- a/sbc/sbc.c
> +++ b/sbc/sbc.c
> @@ -52,6 +52,9 @@
>  
>  #define SBC_SYNCWORD	0x9C
>  
> +#define MSBC_SYNCWORD       0xAD
> +#define MSBC_BLOCKS         15
> +
>  /* This structure contains an unpacked SBC frame.
>     Yes, there is probably quite some unused space herein */
>  struct sbc_frame {
> @@ -920,6 +923,7 @@ struct sbc_priv {
>  
>  static void sbc_set_defaults(sbc_t *sbc, unsigned long flags)
>  {
> +	sbc->flags = flags;
>  	sbc->frequency = SBC_FREQ_44100;
>  	sbc->mode = SBC_MODE_STEREO;
>  	sbc->subbands = SBC_SB_8;
> @@ -982,6 +986,8 @@ SBC_EXPORT ssize_t sbc_decode(sbc_t *sbc, const void *input, size_t input_len,
>  		sbc->mode = priv->frame.mode;
>  		sbc->subbands = priv->frame.subband_mode;
>  		sbc->blocks = priv->frame.block_mode;
> +		if (sbc->flags & SBC_MSBC)
> +			sbc->blocks = MSBC_BLOCKS;

Why are we doing this for every single call of sbc_decode.

And even we wanted to do that, why do we first assign it to
priv->frame.block_mode so we overwrite it one line later.

>  		sbc->allocation = priv->frame.allocation;
>  		sbc->bitpool = priv->frame.bitpool;
>  
> @@ -1056,6 +1062,8 @@ SBC_EXPORT ssize_t sbc_encode(sbc_t *sbc, const void *input, size_t input_len,
>  		priv->frame.subbands = sbc->subbands ? 8 : 4;
>  		priv->frame.block_mode = sbc->blocks;
>  		priv->frame.blocks = 4 + (sbc->blocks * 4);
> +		if (sbc->flags & SBC_MSBC)
> +			priv->frame.blocks = MSBC_BLOCKS;

Same here.

>  		priv->frame.bitpool = sbc->bitpool;
>  		priv->frame.codesize = sbc_get_codesize(sbc);
>  		priv->frame.length = sbc_get_frame_length(sbc);
> @@ -1140,6 +1148,8 @@ SBC_EXPORT size_t sbc_get_frame_length(sbc_t *sbc)
>  
>  	subbands = sbc->subbands ? 8 : 4;
>  	blocks = 4 + (sbc->blocks * 4);
> +	if (sbc->flags & SBC_MSBC)
> +		blocks = MSBC_BLOCKS;

And here again.

>  	channels = sbc->mode == SBC_MODE_MONO ? 1 : 2;
>  	joint = sbc->mode == SBC_MODE_JOINT_STEREO ? 1 : 0;
>  	bitpool = sbc->bitpool;
> @@ -1169,6 +1179,9 @@ SBC_EXPORT unsigned sbc_get_frame_duration(sbc_t *sbc)
>  		blocks = priv->frame.blocks;
>  	}
>  
> +	if (sbc->flags & SBC_MSBC)
> +		blocks = MSBC_BLOCKS;
> +
>  	switch (sbc->frequency) {
>  	case SBC_FREQ_16000:
>  		frequency = 16000;
> @@ -1208,6 +1221,9 @@ SBC_EXPORT size_t sbc_get_codesize(sbc_t *sbc)
>  		channels = priv->frame.channels;
>  	}
>  
> +	if (sbc->flags & SBC_MSBC)
> +		blocks = MSBC_BLOCKS;
> +
>  	return subbands * blocks * channels * 2;
>  }
>  
> diff --git a/sbc/sbc.h b/sbc/sbc.h
> index bbd45da..3511119 100644
> --- a/sbc/sbc.h
> +++ b/sbc/sbc.h
> @@ -64,6 +64,9 @@ extern "C" {
>  #define SBC_LE			0x00
>  #define SBC_BE			0x01
>  
> +/* Additional features */
> +#define SBC_MSBC		0x01
> +
>  struct sbc_struct {
>  	unsigned long flags;
>  

I think you get the idea. Just corrected an already assigned value in
case of mSBC is a bad idea. It is either an if clause or we assign the
proper value once in the private structure.

Regards

Marcel



^ permalink raw reply

* Re: [PATCH 05/11] Add simd primitive for 1b 8s analyse
From: Marcel Holtmann @ 2012-10-18 16:43 UTC (permalink / raw)
  To: Frédéric Dalleau; +Cc: linux-bluetooth
In-Reply-To: <1350576911-14678-6-git-send-email-frederic.dalleau@linux.intel.com>

Hi Fred,

> ---
>  sbc/sbc.c            |   12 +++++++---
>  sbc/sbc_primitives.c |   63 +++++++++++++++++++++++++++++++++++++++++++++++++-
>  sbc/sbc_primitives.h |    2 ++
>  3 files changed, 73 insertions(+), 4 deletions(-)
> 
> diff --git a/sbc/sbc.c b/sbc/sbc.c
> index c40aa15..fa90e07 100644
> --- a/sbc/sbc.c
> +++ b/sbc/sbc.c
> @@ -708,6 +708,10 @@ static int sbc_analyze_audio(struct sbc_encoder_state *state,
>  		for (ch = 0; ch < frame->channels; ch++) {
>  			x = &state->X[ch][state->position - 8 * state->inc +
>  							frame->blocks * 8];
> +
> +			if (state->pending == state->position)
> +				x += 8;
> +
>  			for (blk = 0; blk < frame->blocks; blk += state->inc) {
>  				state->sbc_analyze_4b_8s(
>  					state, x,
> @@ -904,13 +908,14 @@ static ssize_t sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len
>  	}
>  }
>  
> -static void sbc_encoder_init(struct sbc_encoder_state *state,
> +static void sbc_encoder_init(int msbc, struct sbc_encoder_state *state,
>  					const struct sbc_frame *frame)
>  {

why not just unsigned long flags here instead of int msbc.

Regards

Marcel



^ permalink raw reply

* [PATCH 11/11] Update copyrights
From: Frédéric Dalleau @ 2012-10-18 16:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1350576911-14678-1-git-send-email-frederic.dalleau@linux.intel.com>

---
 sbc/sbc.c                |    1 +
 sbc/sbc_primitives.c     |    1 +
 sbc/sbc_primitives.h     |    1 +
 sbc/sbc_primitives_mmx.c |    1 +
 src/sbcdec.c             |    1 +
 src/sbcenc.c             |    1 +
 src/sbcinfo.c            |    1 +
 7 files changed, 7 insertions(+)

diff --git a/sbc/sbc.c b/sbc/sbc.c
index 8539bc6..1a18dfc 100644
--- a/sbc/sbc.c
+++ b/sbc/sbc.c
@@ -6,6 +6,7 @@
  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
  *  Copyright (C) 2004-2005  Henryk Ploetz <henryk@ploetzli.ch>
  *  Copyright (C) 2005-2008  Brad Midgley <bmidgley@xmission.com>
+ *  Copyright (C) 2012       Intel Corporation
  *
  *
  *  This library is free software; you can redistribute it and/or
diff --git a/sbc/sbc_primitives.c b/sbc/sbc_primitives.c
index bfaafd7..09cf2a8 100644
--- a/sbc/sbc_primitives.c
+++ b/sbc/sbc_primitives.c
@@ -6,6 +6,7 @@
  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
  *  Copyright (C) 2004-2005  Henryk Ploetz <henryk@ploetzli.ch>
  *  Copyright (C) 2005-2006  Brad Midgley <bmidgley@xmission.com>
+ *  Copyright (C) 2012       Intel Corporation
  *
  *
  *  This library is free software; you can redistribute it and/or
diff --git a/sbc/sbc_primitives.h b/sbc/sbc_primitives.h
index 130ad25..29a9230 100644
--- a/sbc/sbc_primitives.h
+++ b/sbc/sbc_primitives.h
@@ -6,6 +6,7 @@
  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
  *  Copyright (C) 2004-2005  Henryk Ploetz <henryk@ploetzli.ch>
  *  Copyright (C) 2005-2006  Brad Midgley <bmidgley@xmission.com>
+ *  Copyright (C) 2012       Intel Corporation
  *
  *
  *  This library is free software; you can redistribute it and/or
diff --git a/sbc/sbc_primitives_mmx.c b/sbc/sbc_primitives_mmx.c
index 6a18c5e..fa288bc 100644
--- a/sbc/sbc_primitives_mmx.c
+++ b/sbc/sbc_primitives_mmx.c
@@ -6,6 +6,7 @@
  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
  *  Copyright (C) 2004-2005  Henryk Ploetz <henryk@ploetzli.ch>
  *  Copyright (C) 2005-2006  Brad Midgley <bmidgley@xmission.com>
+ *  Copyright (C) 2012       Intel Corporation
  *
  *
  *  This library is free software; you can redistribute it and/or
diff --git a/src/sbcdec.c b/src/sbcdec.c
index 37d2e98..908292c 100644
--- a/src/sbcdec.c
+++ b/src/sbcdec.c
@@ -4,6 +4,7 @@
  *
  *  Copyright (C) 2008-2010  Nokia Corporation
  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2012       Intel Corporation
  *
  *
  *  This program is free software; you can redistribute it and/or modify
diff --git a/src/sbcenc.c b/src/sbcenc.c
index 71ad6bb..0156b74 100644
--- a/src/sbcenc.c
+++ b/src/sbcenc.c
@@ -4,6 +4,7 @@
  *
  *  Copyright (C) 2008-2010  Nokia Corporation
  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2012       Intel Corporation
  *
  *
  *  This program is free software; you can redistribute it and/or modify
diff --git a/src/sbcinfo.c b/src/sbcinfo.c
index 52ca458..4d5f451 100644
--- a/src/sbcinfo.c
+++ b/src/sbcinfo.c
@@ -4,6 +4,7 @@
  *
  *  Copyright (C) 2008-2010  Nokia Corporation
  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2012       Intel Corporation
  *
  *
  *  This program is free software; you can redistribute it and/or modify
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 10/11] update sbcinfo for msbc
From: Frédéric Dalleau @ 2012-10-18 16:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1350576911-14678-1-git-send-email-frederic.dalleau@linux.intel.com>

---
 src/sbcinfo.c |   51 ++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 36 insertions(+), 15 deletions(-)

diff --git a/src/sbcinfo.c b/src/sbcinfo.c
index 8cfb54a..52ca458 100644
--- a/src/sbcinfo.c
+++ b/src/sbcinfo.c
@@ -61,12 +61,11 @@ struct sbc_frame_hdr {
 #error "Unknown byte order"
 #endif
 
-static int calc_frame_len(struct sbc_frame_hdr *hdr)
+static int calc_frame_len(struct sbc_frame_hdr *hdr, int nrof_blocks)
 {
-	int tmp, nrof_subbands, nrof_blocks;
+	int tmp, nrof_subbands;
 
 	nrof_subbands = (hdr->subbands + 1) * 4;
-	nrof_blocks = (hdr->blocks + 1) * 4;
 
 	switch (hdr->channel_mode) {
 	case 0x00:
@@ -89,13 +88,12 @@ static int calc_frame_len(struct sbc_frame_hdr *hdr)
 	return (nrof_subbands + ((tmp + 7) / 8));
 }
 
-static double calc_bit_rate(struct sbc_frame_hdr *hdr)
+static double calc_bit_rate(struct sbc_frame_hdr *hdr, int nrof_blocks)
 {
-	int nrof_subbands, nrof_blocks;
+	int nrof_subbands;
 	double f;
 
 	nrof_subbands = (hdr->subbands + 1) * 4;
-	nrof_blocks = (hdr->blocks + 1) * 4;
 
 	switch (hdr->sampling_frequency) {
 	case 0:
@@ -114,7 +112,7 @@ static double calc_bit_rate(struct sbc_frame_hdr *hdr)
 		return 0;
 	}
 
-	return ((8 * (calc_frame_len(hdr) + 4) * f) /
+	return ((8 * (calc_frame_len(hdr, nrof_blocks) + 4) * f) /
 			(nrof_subbands * nrof_blocks));
 }
 
@@ -175,7 +173,7 @@ static int analyze_file(char *filename)
 	double rate;
 	int bitpool[SIZE], frame_len[SIZE];
 	int subbands, blocks, freq, method;
-	int n, p1, p2, fd, size, num;
+	int n, p1, p2, fd, size, num, msbc;
 	ssize_t len;
 	unsigned int count;
 
@@ -191,17 +189,30 @@ static int analyze_file(char *filename)
 		fd = fileno(stdin);
 
 	len = __read(fd, &hdr, sizeof(hdr));
-	if (len != sizeof(hdr) || hdr.syncword != 0x9c) {
+	if (len != sizeof(hdr) || !(hdr.syncword == 0x9c ||
+			hdr.syncword == 0xad)) {
 		fprintf(stderr, "Not a SBC audio file\n");
 		return -1;
 	}
+	msbc = (hdr.syncword == 0xad) ? 1 : 0;
+
+	if (msbc) {
+		hdr.subbands = 1; /* 8 */
+		hdr.sampling_frequency = 0x00; /* 16000 */
+		hdr.allocation_method = 0; /* Loudness */
+		hdr.bitpool = 26;
+		hdr.channel_mode = 0x00; /* Mono */
+
+		blocks = 15;
+	} else {
+		blocks = (hdr.blocks + 1) * 4;
+	}
 
 	subbands = (hdr.subbands + 1) * 4;
-	blocks = (hdr.blocks + 1) * 4;
 	freq = hdr.sampling_frequency;
 	method = hdr.allocation_method;
 
-	count = calc_frame_len(&hdr);
+	count = calc_frame_len(&hdr, blocks);
 
 	bitpool[0] = hdr.bitpool;
 	frame_len[0] = count + 4;
@@ -213,7 +224,7 @@ static int analyze_file(char *filename)
 
 	if (lseek(fd, 0, SEEK_SET) < 0) {
 		num = 1;
-		rate = calc_bit_rate(&hdr);
+		rate = calc_bit_rate(&hdr, blocks);
 		while (count) {
 			size = count > sizeof(buf) ? sizeof(buf) : count;
 			len = __read(fd, buf, size);
@@ -237,14 +248,23 @@ static int analyze_file(char *filename)
 		if (len == 0)
 			break;
 
-		if ((size_t) len < sizeof(hdr) || hdr.syncword != 0x9c) {
+		if ((size_t) len < sizeof(hdr) || !(hdr.syncword == 0x9c ||
+				hdr.syncword == 0xad)) {
 			fprintf(stderr, "Corrupted SBC stream "
 					"(len %zd syncword 0x%02x)\n",
 					len, hdr.syncword);
 			break;
 		}
 
-		count = calc_frame_len(&hdr);
+		if (msbc) {
+			hdr.subbands = 1; /* 8 */
+			hdr.sampling_frequency = 0x00; /* 16000 */
+			hdr.allocation_method = 0; /* Loudness */
+			hdr.bitpool = 26;
+			hdr.channel_mode = 0x00; /* Mono */
+		}
+
+		count = calc_frame_len(&hdr, blocks);
 		len = count + 4;
 
 		p1 = -1;
@@ -273,10 +293,11 @@ static int analyze_file(char *filename)
 			count -= len;
 		}
 
-		rate += calc_bit_rate(&hdr);
+		rate += calc_bit_rate(&hdr, blocks);
 		num++;
 	}
 
+	printf("mSBC    \t\t%d\n", msbc);
 	printf("Subbands\t\t%d\n", subbands);
 	printf("Block length\t\t%d\n", blocks);
 	printf("Sampling frequency\t%s\n", freq2str(freq));
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 09/11] update sbcenc for msbc
From: Frédéric Dalleau @ 2012-10-18 16:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1350576911-14678-1-git-send-email-frederic.dalleau@linux.intel.com>

---
 src/sbcenc.c |   25 ++++++++++++++++++++-----
 1 file changed, 20 insertions(+), 5 deletions(-)

diff --git a/src/sbcenc.c b/src/sbcenc.c
index a723b03..71ad6bb 100644
--- a/src/sbcenc.c
+++ b/src/sbcenc.c
@@ -45,7 +45,7 @@ static int verbose = 0;
 static unsigned char input[BUF_SIZE], output[BUF_SIZE + BUF_SIZE / 4];
 
 static void encode(char *filename, int subbands, int bitpool, int joint,
-					int dualchannel, int snr, int blocks)
+				int dualchannel, int snr, int blocks, int msbc)
 {
 	struct au_header au_hdr;
 	sbc_t sbc;
@@ -87,7 +87,7 @@ static void encode(char *filename, int subbands, int bitpool, int joint,
 		goto done;
 	}
 
-	sbc_init(&sbc, 0L);
+	sbc_init(&sbc, msbc ? SBC_MSBC : 0L);
 
 	switch (BE_INT(au_hdr.sample_rate)) {
 	case 16000:
@@ -215,6 +215,7 @@ static void usage(void)
 	printf("Options:\n"
 		"\t-h, --help           Display help\n"
 		"\t-v, --verbose        Verbose mode\n"
+		"\t-m, --msbc           mSBC codec\n"
 		"\t-s, --subbands       Number of subbands to use (4 or 8)\n"
 		"\t-b, --bitpool        Bitpool value (default is 32)\n"
 		"\t-j, --joint          Joint stereo\n"
@@ -227,6 +228,7 @@ static void usage(void)
 static struct option main_options[] = {
 	{ "help",	0, 0, 'h' },
 	{ "verbose",	0, 0, 'v' },
+	{ "msbc",	0, 0, 'm' },
 	{ "subbands",	1, 0, 's' },
 	{ "bitpool",	1, 0, 'b' },
 	{ "joint",	0, 0, 'j' },
@@ -239,9 +241,9 @@ static struct option main_options[] = {
 int main(int argc, char *argv[])
 {
 	int i, opt, subbands = 8, bitpool = 32, joint = 0, dualchannel = 0;
-	int snr = 0, blocks = 16;
+	int snr = 0, blocks = 16, msbc = 0;
 
-	while ((opt = getopt_long(argc, argv, "+hvs:b:jdSB:",
+	while ((opt = getopt_long(argc, argv, "+hmvs:b:jdSB:",
 						main_options, NULL)) != -1) {
 		switch(opt) {
 		case 'h':
@@ -252,6 +254,10 @@ int main(int argc, char *argv[])
 			verbose = 1;
 			break;
 
+		case 'm':
+			msbc = 1;
+			break;
+
 		case 's':
 			subbands = atoi(optarg);
 			if (subbands != 8 && subbands != 4) {
@@ -300,9 +306,18 @@ int main(int argc, char *argv[])
 		exit(1);
 	}
 
+	if (msbc) {
+		subbands = 8;
+		bitpool = 26;
+		joint = 0;
+		dualchannel = 0;
+		snr = 0;
+		blocks = 15;
+	}
+
 	for (i = 0; i < argc; i++)
 		encode(argv[i], subbands, bitpool, joint, dualchannel,
-								snr, blocks);
+							snr, blocks, msbc);
 
 	return 0;
 }
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 08/11] update sbcdec for msbc
From: Frédéric Dalleau @ 2012-10-18 16:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1350576911-14678-1-git-send-email-frederic.dalleau@linux.intel.com>

---
 src/sbcdec.c |   17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/src/sbcdec.c b/src/sbcdec.c
index 0077a82..37d2e98 100644
--- a/src/sbcdec.c
+++ b/src/sbcdec.c
@@ -44,7 +44,7 @@
 
 static int verbose = 0;
 
-static void decode(char *filename, char *output, int tofile)
+static void decode(char *filename, char *output, int tofile, int msbc)
 {
 	unsigned char buf[BUF_SIZE], *stream;
 	struct stat st;
@@ -98,7 +98,7 @@ static void decode(char *filename, char *output, int tofile)
 		goto free;
 	}
 
-	sbc_init(&sbc, 0L);
+	sbc_init(&sbc, msbc ? SBC_MSBC : 0L);
 	sbc.endian = SBC_BE;
 
 	framelen = sbc_decode(&sbc, stream, streamlen, buf, sizeof(buf), &len);
@@ -228,14 +228,16 @@ static void usage(void)
 
 	printf("Options:\n"
 		"\t-h, --help           Display help\n"
-		"\t-v, --verbose        Verbose mode\n"
 		"\t-d, --device <dsp>   Sound device\n"
+		"\t-v, --verbose        Verbose mode\n"
+		"\t-m, --msbc           mSBC codec\n"
 		"\t-f, --file <file>    Decode to a file\n"
 		"\n");
 }
 
 static struct option main_options[] = {
 	{ "help",	0, 0, 'h' },
+	{ "msbc",	0, 0, 'm' },
 	{ "device",	1, 0, 'd' },
 	{ "verbose",	0, 0, 'v' },
 	{ "file",	1, 0, 'f' },
@@ -246,8 +248,9 @@ int main(int argc, char *argv[])
 {
 	char *output = NULL;
 	int i, opt, tofile = 0;
+	int msbc = 0;
 
-	while ((opt = getopt_long(argc, argv, "+hvd:f:",
+	while ((opt = getopt_long(argc, argv, "+hmvd:f:",
 						main_options, NULL)) != -1) {
 		switch(opt) {
 		case 'h':
@@ -258,6 +261,10 @@ int main(int argc, char *argv[])
 			verbose = 1;
 			break;
 
+		case 'm':
+			msbc = 1;
+			break;
+
 		case 'd':
 			free(output);
 			output = strdup(optarg);
@@ -285,7 +292,7 @@ int main(int argc, char *argv[])
 	}
 
 	for (i = 0; i < argc; i++)
-		decode(argv[i], output ? output : "/dev/dsp", tofile);
+		decode(argv[i], output ? output : "/dev/dsp", tofile, msbc);
 
 	free(output);
 
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 07/11] Add mmx primitive for 1b 8s analyse
From: Frédéric Dalleau @ 2012-10-18 16:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1350576911-14678-1-git-send-email-frederic.dalleau@linux.intel.com>

---
 sbc/sbc_primitives_mmx.c |   15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/sbc/sbc_primitives_mmx.c b/sbc/sbc_primitives_mmx.c
index cbacb4e..6a18c5e 100644
--- a/sbc/sbc_primitives_mmx.c
+++ b/sbc/sbc_primitives_mmx.c
@@ -276,6 +276,19 @@ static inline void sbc_analyze_4b_8s_mmx(struct sbc_encoder_state *state,
 	__asm__ volatile ("emms\n");
 }
 
+static inline void sbc_analyze_1b_8s_mmx(struct sbc_encoder_state *state,
+		int16_t *x, int32_t *out, int out_stride)
+{
+	if (state->odd)
+		sbc_analyze_eight_mmx(x, out, analysis_consts_fixed8_simd_odd);
+	else
+		sbc_analyze_eight_mmx(x, out, analysis_consts_fixed8_simd_even);
+
+	state->odd = !state->odd;
+
+	__asm__ volatile ("emms\n");
+}
+
 static void sbc_calc_scalefactors_mmx(
 	int32_t sb_sample_f[16][2][8],
 	uint32_t scale_factor[2][8],
@@ -367,6 +380,8 @@ void sbc_init_primitives_mmx(struct sbc_encoder_state *state)
 	if (check_mmx_support()) {
 		state->sbc_analyze_4b_4s = sbc_analyze_4b_4s_mmx;
 		state->sbc_analyze_4b_8s = sbc_analyze_4b_8s_mmx;
+		if (state->inc == 1)
+			state->sbc_analyze_4b_8s = sbc_analyze_1b_8s_mmx;
 		state->sbc_calc_scalefactors = sbc_calc_scalefactors_mmx;
 		state->implementation_info = "MMX";
 	}
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 06/11] Add support for mSBC frame header
From: Frédéric Dalleau @ 2012-10-18 16:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1350576911-14678-1-git-send-email-frederic.dalleau@linux.intel.com>

---
 sbc/sbc.c |  225 ++++++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 135 insertions(+), 90 deletions(-)

diff --git a/sbc/sbc.c b/sbc/sbc.c
index fa90e07..8539bc6 100644
--- a/sbc/sbc.c
+++ b/sbc/sbc.c
@@ -377,8 +377,8 @@ static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8])
  *  -3   CRC8 incorrect
  *  -4   Bitpool value out of bounds
  */
-static int sbc_unpack_frame(const uint8_t *data, struct sbc_frame *frame,
-								size_t len)
+static int sbc_unpack_frame_internal(const uint8_t *data,
+		struct sbc_frame *frame, size_t len)
 {
 	unsigned int consumed;
 	/* Will copy the parts of the header that are relevant to crc
@@ -393,59 +393,6 @@ static int sbc_unpack_frame(const uint8_t *data, struct sbc_frame *frame,
 	int bits[2][8];		/* bits distribution */
 	uint32_t levels[2][8];	/* levels derived from that */
 
-	if (len < 4)
-		return -1;
-
-	if (data[0] != SBC_SYNCWORD)
-		return -2;
-
-	frame->frequency = (data[1] >> 6) & 0x03;
-
-	frame->block_mode = (data[1] >> 4) & 0x03;
-	switch (frame->block_mode) {
-	case SBC_BLK_4:
-		frame->blocks = 4;
-		break;
-	case SBC_BLK_8:
-		frame->blocks = 8;
-		break;
-	case SBC_BLK_12:
-		frame->blocks = 12;
-		break;
-	case SBC_BLK_16:
-		frame->blocks = 16;
-		break;
-	}
-
-	frame->mode = (data[1] >> 2) & 0x03;
-	switch (frame->mode) {
-	case MONO:
-		frame->channels = 1;
-		break;
-	case DUAL_CHANNEL:	/* fall-through */
-	case STEREO:
-	case JOINT_STEREO:
-		frame->channels = 2;
-		break;
-	}
-
-	frame->allocation = (data[1] >> 1) & 0x01;
-
-	frame->subband_mode = (data[1] & 0x01);
-	frame->subbands = frame->subband_mode ? 8 : 4;
-
-	frame->bitpool = data[2];
-
-	if ((frame->mode == MONO || frame->mode == DUAL_CHANNEL) &&
-			frame->bitpool > 16 * frame->subbands)
-		return -4;
-
-	if ((frame->mode == STEREO || frame->mode == JOINT_STEREO) &&
-			frame->bitpool > 32 * frame->subbands)
-		return -4;
-
-	/* data[3] is crc, we're checking it later */
-
 	consumed = 32;
 
 	crc_header[0] = data[1];
@@ -546,6 +493,88 @@ static int sbc_unpack_frame(const uint8_t *data, struct sbc_frame *frame,
 	return consumed >> 3;
 }
 
+static int sbc_unpack_frame(const uint8_t *data,
+		struct sbc_frame *frame, size_t len)
+{
+	if (len < 4)
+		return -1;
+	if (data[0] != SBC_SYNCWORD)
+		return -2;
+
+	frame->frequency = (data[1] >> 6) & 0x03;
+	frame->block_mode = (data[1] >> 4) & 0x03;
+
+	switch (frame->block_mode) {
+	case SBC_BLK_4:
+		frame->blocks = 4;
+		break;
+	case SBC_BLK_8:
+		frame->blocks = 8;
+		break;
+	case SBC_BLK_12:
+		frame->blocks = 12;
+		break;
+	case SBC_BLK_16:
+		frame->blocks = 16;
+		break;
+	}
+
+	frame->mode = (data[1] >> 2) & 0x03;
+	switch (frame->mode) {
+	case MONO:
+		frame->channels = 1;
+		break;
+	case DUAL_CHANNEL:	/* fall-through */
+	case STEREO:
+	case JOINT_STEREO:
+		frame->channels = 2;
+		break;
+	}
+
+	frame->allocation = (data[1] >> 1) & 0x01;
+
+	frame->subband_mode = (data[1] & 0x01);
+	frame->subbands = frame->subband_mode ? 8 : 4;
+
+	frame->bitpool = data[2];
+
+	if ((frame->mode == MONO || frame->mode == DUAL_CHANNEL) &&
+			frame->bitpool > 16 * frame->subbands)
+		return -4;
+
+	if ((frame->mode == STEREO || frame->mode == JOINT_STEREO) &&
+			frame->bitpool > 32 * frame->subbands)
+		return -4;
+
+	return sbc_unpack_frame_internal(data, frame, len);
+}
+
+static int msbc_unpack_frame(const uint8_t *data,
+		struct sbc_frame *frame, size_t len)
+{
+	if (len < 4)
+		return -1;
+
+	if (data[0] != MSBC_SYNCWORD)
+		return -2;
+	if (data[1] != 0)
+		return -5;
+	if (data[2] != 0)
+		return -6;
+
+	frame->frequency = SBC_FREQ_16000;
+	frame->block_mode = SBC_BLK_4;
+	frame->blocks = MSBC_BLOCKS;
+	frame->allocation = LOUDNESS;
+	frame->mode = MONO;
+	frame->channels = 1;
+	frame->subband_mode = 1;
+	frame->subbands = 8;
+	frame->bitpool = 26;
+
+	return sbc_unpack_frame_internal(data, frame, len);
+}
+
 static void sbc_decoder_init(struct sbc_decoder_state *state,
 					const struct sbc_frame *frame)
 {
@@ -792,38 +821,6 @@ static SBC_ALWAYS_INLINE ssize_t sbc_pack_frame_internal(uint8_t *data,
 	uint32_t levels[2][8];	/* levels are derived from that */
 	uint32_t sb_sample_delta[2][8];
 
-	data[0] = SBC_SYNCWORD;
-
-	data[1] = (frame->frequency & 0x03) << 6;
-
-	data[1] |= (frame->block_mode & 0x03) << 4;
-
-	data[1] |= (frame->mode & 0x03) << 2;
-
-	data[1] |= (frame->allocation & 0x01) << 1;
-
-	switch (frame_subbands) {
-	case 4:
-		/* Nothing to do */
-		break;
-	case 8:
-		data[1] |= 0x01;
-		break;
-	default:
-		return -4;
-		break;
-	}
-
-	data[2] = frame->bitpool;
-
-	if ((frame->mode == MONO || frame->mode == DUAL_CHANNEL) &&
-			frame->bitpool > frame_subbands << 4)
-		return -5;
-
-	if ((frame->mode == STEREO || frame->mode == JOINT_STEREO) &&
-			frame->bitpool > frame_subbands << 5)
-		return -5;
-
 	/* Can't fill in crc yet */
 
 	crc_header[0] = data[1];
@@ -891,6 +888,28 @@ static SBC_ALWAYS_INLINE ssize_t sbc_pack_frame_internal(uint8_t *data,
 static ssize_t sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len,
 								int joint)
 {
+	int frame_subbands = 4;
+
+	data[0] = SBC_SYNCWORD;
+
+	data[1] = (frame->frequency & 0x03) << 6;
+	data[1] |= (frame->block_mode & 0x03) << 4;
+	data[1] |= (frame->mode & 0x03) << 2;
+	data[1] |= (frame->allocation & 0x01) << 1;
+
+	data[2] = frame->bitpool;
+
+	if (frame->subbands != 4)
+		frame_subbands = 8;
+
+	if ((frame->mode == MONO || frame->mode == DUAL_CHANNEL) &&
+			frame->bitpool > frame_subbands << 4)
+		return -5;
+
+	if ((frame->mode == STEREO || frame->mode == JOINT_STEREO) &&
+			frame->bitpool > frame_subbands << 5)
+		return -5;
+
 	if (frame->subbands == 4) {
 		if (frame->channels == 1)
 			return sbc_pack_frame_internal(
@@ -899,6 +918,7 @@ static ssize_t sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len
 			return sbc_pack_frame_internal(
 				data, frame, len, 4, 2, joint);
 	} else {
+		data[1] |= 0x01;
 		if (frame->channels == 1)
 			return sbc_pack_frame_internal(
 				data, frame, len, 8, 1, joint);
@@ -908,6 +928,17 @@ static ssize_t sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len
 	}
 }
 
+static ssize_t msbc_pack_frame(uint8_t *data, struct sbc_frame *frame,
+		size_t len, int joint)
+{
+	data[0] = MSBC_SYNCWORD;
+	data[1] = 0;
+	data[2] = 0;
+
+	return sbc_pack_frame_internal(
+		data, frame, len, 8, 1, joint);
+}
+
 static void sbc_encoder_init(int msbc, struct sbc_encoder_state *state,
 					const struct sbc_frame *frame)
 {
@@ -924,10 +955,22 @@ struct sbc_priv {
 	struct SBC_ALIGNED sbc_frame frame;
 	struct SBC_ALIGNED sbc_decoder_state dec_state;
 	struct SBC_ALIGNED sbc_encoder_state enc_state;
+	int (*sbc_unpack_frame)(const uint8_t *data, struct sbc_frame *frame,
+			size_t len);
+	ssize_t (*sbc_pack_frame)(uint8_t *data, struct sbc_frame *frame,
+			size_t len, int joint);
 };
 
 static void sbc_set_defaults(sbc_t *sbc, unsigned long flags)
 {
+	struct sbc_priv *priv = sbc->priv;
+	if (flags & SBC_MSBC) {
+		priv->sbc_pack_frame = msbc_pack_frame;
+		priv->sbc_unpack_frame = msbc_unpack_frame;
+	} else {
+		priv->sbc_pack_frame = sbc_pack_frame;
+		priv->sbc_unpack_frame = sbc_unpack_frame;
+	}
 	sbc->flags = flags;
 	sbc->frequency = SBC_FREQ_44100;
 	sbc->mode = SBC_MODE_STEREO;
@@ -981,7 +1024,7 @@ SBC_EXPORT ssize_t sbc_decode(sbc_t *sbc, const void *input, size_t input_len,
 
 	priv = sbc->priv;
 
-	framelen = sbc_unpack_frame(input, &priv->frame, input_len);
+	framelen = priv->sbc_unpack_frame(input, &priv->frame, input_len);
 
 	if (!priv->init) {
 		sbc_decoder_init(&priv->dec_state, &priv->frame);
@@ -1117,13 +1160,15 @@ SBC_EXPORT ssize_t sbc_encode(sbc_t *sbc, const void *input, size_t input_len,
 		int j = priv->enc_state.sbc_calc_scalefactors_j(
 			priv->frame.sb_sample_f, priv->frame.scale_factor,
 			priv->frame.blocks, priv->frame.subbands);
-		framelen = sbc_pack_frame(output, &priv->frame, output_len, j);
+		framelen = priv->sbc_pack_frame(output,
+				&priv->frame, output_len, j);
 	} else {
 		priv->enc_state.sbc_calc_scalefactors(
 			priv->frame.sb_sample_f, priv->frame.scale_factor,
 			priv->frame.blocks, priv->frame.channels,
 			priv->frame.subbands);
-		framelen = sbc_pack_frame(output, &priv->frame, output_len, 0);
+		framelen = priv->sbc_pack_frame(output,
+				&priv->frame, output_len, 0);
 	}
 
 	if (written)
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 05/11] Add simd primitive for 1b 8s analyse
From: Frédéric Dalleau @ 2012-10-18 16:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1350576911-14678-1-git-send-email-frederic.dalleau@linux.intel.com>

---
 sbc/sbc.c            |   12 +++++++---
 sbc/sbc_primitives.c |   63 +++++++++++++++++++++++++++++++++++++++++++++++++-
 sbc/sbc_primitives.h |    2 ++
 3 files changed, 73 insertions(+), 4 deletions(-)

diff --git a/sbc/sbc.c b/sbc/sbc.c
index c40aa15..fa90e07 100644
--- a/sbc/sbc.c
+++ b/sbc/sbc.c
@@ -708,6 +708,10 @@ static int sbc_analyze_audio(struct sbc_encoder_state *state,
 		for (ch = 0; ch < frame->channels; ch++) {
 			x = &state->X[ch][state->position - 8 * state->inc +
 							frame->blocks * 8];
+
+			if (state->pending == state->position)
+				x += 8;
+
 			for (blk = 0; blk < frame->blocks; blk += state->inc) {
 				state->sbc_analyze_4b_8s(
 					state, x,
@@ -904,13 +908,14 @@ static ssize_t sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len
 	}
 }
 
-static void sbc_encoder_init(struct sbc_encoder_state *state,
+static void sbc_encoder_init(int msbc, struct sbc_encoder_state *state,
 					const struct sbc_frame *frame)
 {
 	memset(&state->X, 0, sizeof(state->X));
 	state->position = (SBC_X_BUFFER_SIZE - frame->subbands * 9) & ~7;
 	state->inc = 4;
-
+	if (msbc)
+		state->inc = 1;
 	sbc_init_primitives(state);
 }
 
@@ -1068,7 +1073,8 @@ SBC_EXPORT ssize_t sbc_encode(sbc_t *sbc, const void *input, size_t input_len,
 		priv->frame.codesize = sbc_get_codesize(sbc);
 		priv->frame.length = sbc_get_frame_length(sbc);
 
-		sbc_encoder_init(&priv->enc_state, &priv->frame);
+		sbc_encoder_init(sbc->flags & SBC_MSBC,
+					&priv->enc_state, &priv->frame);
 		priv->init = 1;
 	} else if (priv->frame.bitpool != sbc->bitpool) {
 		priv->frame.length = sbc_get_frame_length(sbc);
diff --git a/sbc/sbc_primitives.c b/sbc/sbc_primitives.c
index 7ba0589..bfaafd7 100644
--- a/sbc/sbc_primitives.c
+++ b/sbc/sbc_primitives.c
@@ -209,6 +209,17 @@ static inline void sbc_analyze_4b_8s_simd(struct sbc_encoder_state *state,
 	sbc_analyze_eight_simd(x + 0, out, analysis_consts_fixed8_simd_even);
 }
 
+static inline void sbc_analyze_1b_8s_simd(struct sbc_encoder_state *state,
+		int16_t *x, int32_t *out, int out_stride)
+{
+	if (state->odd)
+		sbc_analyze_eight_simd(x, out, analysis_consts_fixed8_simd_odd);
+	else
+		sbc_analyze_eight_simd(x, out, analysis_consts_fixed8_simd_even);
+
+	state->odd = !state->odd;
+}
+
 static inline int16_t unaligned16_be(const uint8_t *ptr)
 {
 	return (int16_t) ((ptr[0] << 8) | ptr[1]);
@@ -298,8 +309,25 @@ static SBC_ALWAYS_INLINE int sbc_encoder_process_input_s8_internal(
 	#define PCM(i) (big_endian ? \
 		unaligned16_be(pcm + (i) * 2) : unaligned16_le(pcm + (i) * 2))
 
+	if (state->pending >= 0) {
+		state->pending = -1;
+		nsamples -= 8;
+		if (nchannels > 0) {
+			int16_t *x = &X[0][position];
+			x[0]  = PCM(0 + (15-8) * nchannels);
+			x[2]  = PCM(0 + (14-8) * nchannels);
+			x[3]  = PCM(0 + (8-8) * nchannels);
+			x[4]  = PCM(0 + (13-8) * nchannels);
+			x[5]  = PCM(0 + (9-8) * nchannels);
+			x[6]  = PCM(0 + (12-8) * nchannels);
+			x[7]  = PCM(0 + (10-8) * nchannels);
+			x[8]  = PCM(0 + (11-8) * nchannels);
+		}
+		pcm += 16 * nchannels;
+	}
+
 	/* copy/permutate audio samples */
-	while ((nsamples -= 16) >= 0) {
+	while (nsamples >= 16) {
 		position -= 16;
 		if (nchannels > 0) {
 			int16_t *x = &X[0][position];
@@ -340,6 +368,33 @@ static SBC_ALWAYS_INLINE int sbc_encoder_process_input_s8_internal(
 			x[15] = PCM(1 + 2 * nchannels);
 		}
 		pcm += 32 * nchannels;
+		nsamples -= 16;
+	}
+
+	if (nsamples == 8) {
+		position -= 16;
+		state->pending = position;
+
+		if (nchannels > 0) {
+			int16_t *x = &X[0][position];
+			x[0]  = 0;
+			x[1]  = PCM(0 + 7 * nchannels);
+			x[2]  = 0;
+			x[3]  = 0;
+			x[4]  = 0;
+			x[5]  = 0;
+			x[6]  = 0;
+			x[7]  = 0;
+			x[8]  = 0;
+			x[9]  = PCM(0 + 3 * nchannels);
+			x[10] = PCM(0 + 6 * nchannels);
+			x[11] = PCM(0 + 0 * nchannels);
+			x[12] = PCM(0 + 5 * nchannels);
+			x[13] = PCM(0 + 1 * nchannels);
+			x[14] = PCM(0 + 4 * nchannels);
+			x[15] = PCM(0 + 2 * nchannels);
+		}
+		pcm += 16 * nchannels;
 	}
 	#undef PCM
 
@@ -523,10 +578,16 @@ static int sbc_calc_scalefactors_j(
  */
 void sbc_init_primitives(struct sbc_encoder_state *state)
 {
+	state->pending = -1;
+	state->odd = 1;
+
 	/* Default implementation for analyze functions */
 	state->sbc_analyze_4b_4s = sbc_analyze_4b_4s_simd;
 	state->sbc_analyze_4b_8s = sbc_analyze_4b_8s_simd;
 
+	if (state->inc == 1)
+		state->sbc_analyze_4b_8s = sbc_analyze_1b_8s_simd;
+
 	/* Default implementation for input reordering / deinterleaving */
 	state->sbc_enc_process_input_4s_le = sbc_enc_process_input_4s_le;
 	state->sbc_enc_process_input_4s_be = sbc_enc_process_input_4s_be;
diff --git a/sbc/sbc_primitives.h b/sbc/sbc_primitives.h
index 39cfbf2..130ad25 100644
--- a/sbc/sbc_primitives.h
+++ b/sbc/sbc_primitives.h
@@ -39,6 +39,8 @@
 struct sbc_encoder_state {
 	int position;
 	int inc;
+	int pending;
+	int odd;
 	int16_t SBC_ALIGNED X[2][SBC_X_BUFFER_SIZE];
 	/* Polyphase analysis filter for 4 subbands configuration,
 	 * it handles "inc" blocks at once */
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 04/11] Add msbc encoding and decoding flag
From: Frédéric Dalleau @ 2012-10-18 16:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1350576911-14678-1-git-send-email-frederic.dalleau@linux.intel.com>

---
 sbc/sbc.c |   16 ++++++++++++++++
 sbc/sbc.h |    3 +++
 2 files changed, 19 insertions(+)

diff --git a/sbc/sbc.c b/sbc/sbc.c
index 6fff132..c40aa15 100644
--- a/sbc/sbc.c
+++ b/sbc/sbc.c
@@ -52,6 +52,9 @@
 
 #define SBC_SYNCWORD	0x9C
 
+#define MSBC_SYNCWORD       0xAD
+#define MSBC_BLOCKS         15
+
 /* This structure contains an unpacked SBC frame.
    Yes, there is probably quite some unused space herein */
 struct sbc_frame {
@@ -920,6 +923,7 @@ struct sbc_priv {
 
 static void sbc_set_defaults(sbc_t *sbc, unsigned long flags)
 {
+	sbc->flags = flags;
 	sbc->frequency = SBC_FREQ_44100;
 	sbc->mode = SBC_MODE_STEREO;
 	sbc->subbands = SBC_SB_8;
@@ -982,6 +986,8 @@ SBC_EXPORT ssize_t sbc_decode(sbc_t *sbc, const void *input, size_t input_len,
 		sbc->mode = priv->frame.mode;
 		sbc->subbands = priv->frame.subband_mode;
 		sbc->blocks = priv->frame.block_mode;
+		if (sbc->flags & SBC_MSBC)
+			sbc->blocks = MSBC_BLOCKS;
 		sbc->allocation = priv->frame.allocation;
 		sbc->bitpool = priv->frame.bitpool;
 
@@ -1056,6 +1062,8 @@ SBC_EXPORT ssize_t sbc_encode(sbc_t *sbc, const void *input, size_t input_len,
 		priv->frame.subbands = sbc->subbands ? 8 : 4;
 		priv->frame.block_mode = sbc->blocks;
 		priv->frame.blocks = 4 + (sbc->blocks * 4);
+		if (sbc->flags & SBC_MSBC)
+			priv->frame.blocks = MSBC_BLOCKS;
 		priv->frame.bitpool = sbc->bitpool;
 		priv->frame.codesize = sbc_get_codesize(sbc);
 		priv->frame.length = sbc_get_frame_length(sbc);
@@ -1140,6 +1148,8 @@ SBC_EXPORT size_t sbc_get_frame_length(sbc_t *sbc)
 
 	subbands = sbc->subbands ? 8 : 4;
 	blocks = 4 + (sbc->blocks * 4);
+	if (sbc->flags & SBC_MSBC)
+		blocks = MSBC_BLOCKS;
 	channels = sbc->mode == SBC_MODE_MONO ? 1 : 2;
 	joint = sbc->mode == SBC_MODE_JOINT_STEREO ? 1 : 0;
 	bitpool = sbc->bitpool;
@@ -1169,6 +1179,9 @@ SBC_EXPORT unsigned sbc_get_frame_duration(sbc_t *sbc)
 		blocks = priv->frame.blocks;
 	}
 
+	if (sbc->flags & SBC_MSBC)
+		blocks = MSBC_BLOCKS;
+
 	switch (sbc->frequency) {
 	case SBC_FREQ_16000:
 		frequency = 16000;
@@ -1208,6 +1221,9 @@ SBC_EXPORT size_t sbc_get_codesize(sbc_t *sbc)
 		channels = priv->frame.channels;
 	}
 
+	if (sbc->flags & SBC_MSBC)
+		blocks = MSBC_BLOCKS;
+
 	return subbands * blocks * channels * 2;
 }
 
diff --git a/sbc/sbc.h b/sbc/sbc.h
index bbd45da..3511119 100644
--- a/sbc/sbc.h
+++ b/sbc/sbc.h
@@ -64,6 +64,9 @@ extern "C" {
 #define SBC_LE			0x00
 #define SBC_BE			0x01
 
+/* Additional features */
+#define SBC_MSBC		0x01
+
 struct sbc_struct {
 	unsigned long flags;
 
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 03/11] Make increment variable
From: Frédéric Dalleau @ 2012-10-18 16:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1350576911-14678-1-git-send-email-frederic.dalleau@linux.intel.com>

---
 sbc/sbc.c            |   13 +++++++------
 sbc/sbc_primitives.h |    5 +++--
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/sbc/sbc.c b/sbc/sbc.c
index 08b4993..6fff132 100644
--- a/sbc/sbc.c
+++ b/sbc/sbc.c
@@ -688,30 +688,30 @@ static int sbc_analyze_audio(struct sbc_encoder_state *state,
 	switch (frame->subbands) {
 	case 4:
 		for (ch = 0; ch < frame->channels; ch++) {
-			x = &state->X[ch][state->position - 16 +
+			x = &state->X[ch][state->position - 4 * state->inc +
 							frame->blocks * 4];
-			for (blk = 0; blk < frame->blocks; blk += 4) {
+			for (blk = 0; blk < frame->blocks; blk += state->inc) {
 				state->sbc_analyze_4b_4s(
 					state, x,
 					frame->sb_sample_f[blk][ch],
 					frame->sb_sample_f[blk + 1][ch] -
 					frame->sb_sample_f[blk][ch]);
-				x -= 16;
+				x -= 4 * state->inc;
 			}
 		}
 		return frame->blocks * 4;
 
 	case 8:
 		for (ch = 0; ch < frame->channels; ch++) {
-			x = &state->X[ch][state->position - 32 +
+			x = &state->X[ch][state->position - 8 * state->inc +
 							frame->blocks * 8];
-			for (blk = 0; blk < frame->blocks; blk += 4) {
+			for (blk = 0; blk < frame->blocks; blk += state->inc) {
 				state->sbc_analyze_4b_8s(
 					state, x,
 					frame->sb_sample_f[blk][ch],
 					frame->sb_sample_f[blk + 1][ch] -
 					frame->sb_sample_f[blk][ch]);
-				x -= 32;
+				x -= 8 * state->inc;
 			}
 		}
 		return frame->blocks * 8;
@@ -906,6 +906,7 @@ static void sbc_encoder_init(struct sbc_encoder_state *state,
 {
 	memset(&state->X, 0, sizeof(state->X));
 	state->position = (SBC_X_BUFFER_SIZE - frame->subbands * 9) & ~7;
+	state->inc = 4;
 
 	sbc_init_primitives(state);
 }
diff --git a/sbc/sbc_primitives.h b/sbc/sbc_primitives.h
index 47363db..39cfbf2 100644
--- a/sbc/sbc_primitives.h
+++ b/sbc/sbc_primitives.h
@@ -38,13 +38,14 @@
 
 struct sbc_encoder_state {
 	int position;
+	int inc;
 	int16_t SBC_ALIGNED X[2][SBC_X_BUFFER_SIZE];
 	/* Polyphase analysis filter for 4 subbands configuration,
-	 * it handles 4 blocks at once */
+	 * it handles "inc" blocks at once */
 	void (*sbc_analyze_4b_4s)(struct sbc_encoder_state *state,
 			int16_t *x, int32_t *out, int out_stride);
 	/* Polyphase analysis filter for 8 subbands configuration,
-	 * it handles 4 blocks at once */
+	 * it handles "inc" blocks at once */
 	void (*sbc_analyze_4b_8s)(struct sbc_encoder_state *state,
 			int16_t *x, int32_t *out, int out_stride);
 	/* Process input data (deinterleave, endian conversion, reordering),
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 02/11] Add encoder_state parameter to analysis functions
From: Frédéric Dalleau @ 2012-10-18 16:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1350576911-14678-1-git-send-email-frederic.dalleau@linux.intel.com>

---
 sbc/sbc.c                   |    4 ++--
 sbc/sbc_primitives.c        |    8 ++++----
 sbc/sbc_primitives.h        |    6 ++++--
 sbc/sbc_primitives_armv6.c  |    6 ++++--
 sbc/sbc_primitives_iwmmxt.c |    8 ++++----
 sbc/sbc_primitives_mmx.c    |    8 ++++----
 sbc/sbc_primitives_neon.c   |    8 ++++----
 7 files changed, 26 insertions(+), 22 deletions(-)

diff --git a/sbc/sbc.c b/sbc/sbc.c
index 76acf43..08b4993 100644
--- a/sbc/sbc.c
+++ b/sbc/sbc.c
@@ -692,7 +692,7 @@ static int sbc_analyze_audio(struct sbc_encoder_state *state,
 							frame->blocks * 4];
 			for (blk = 0; blk < frame->blocks; blk += 4) {
 				state->sbc_analyze_4b_4s(
-					x,
+					state, x,
 					frame->sb_sample_f[blk][ch],
 					frame->sb_sample_f[blk + 1][ch] -
 					frame->sb_sample_f[blk][ch]);
@@ -707,7 +707,7 @@ static int sbc_analyze_audio(struct sbc_encoder_state *state,
 							frame->blocks * 8];
 			for (blk = 0; blk < frame->blocks; blk += 4) {
 				state->sbc_analyze_4b_8s(
-					x,
+					state, x,
 					frame->sb_sample_f[blk][ch],
 					frame->sb_sample_f[blk + 1][ch] -
 					frame->sb_sample_f[blk][ch]);
diff --git a/sbc/sbc_primitives.c b/sbc/sbc_primitives.c
index e137604..7ba0589 100644
--- a/sbc/sbc_primitives.c
+++ b/sbc/sbc_primitives.c
@@ -183,8 +183,8 @@ static inline void sbc_analyze_eight_simd(const int16_t *in, int32_t *out,
 			(SBC_COS_TABLE_FIXED8_SCALE - SCALE_OUT_BITS);
 }
 
-static inline void sbc_analyze_4b_4s_simd(int16_t *x,
-						int32_t *out, int out_stride)
+static inline void sbc_analyze_4b_4s_simd(struct sbc_encoder_state *state,
+		int16_t *x, int32_t *out, int out_stride)
 {
 	/* Analyze blocks */
 	sbc_analyze_four_simd(x + 12, out, analysis_consts_fixed4_simd_odd);
@@ -196,8 +196,8 @@ static inline void sbc_analyze_4b_4s_simd(int16_t *x,
 	sbc_analyze_four_simd(x + 0, out, analysis_consts_fixed4_simd_even);
 }
 
-static inline void sbc_analyze_4b_8s_simd(int16_t *x,
-					  int32_t *out, int out_stride)
+static inline void sbc_analyze_4b_8s_simd(struct sbc_encoder_state *state,
+		int16_t *x, int32_t *out, int out_stride)
 {
 	/* Analyze blocks */
 	sbc_analyze_eight_simd(x + 24, out, analysis_consts_fixed8_simd_odd);
diff --git a/sbc/sbc_primitives.h b/sbc/sbc_primitives.h
index c80337e..47363db 100644
--- a/sbc/sbc_primitives.h
+++ b/sbc/sbc_primitives.h
@@ -41,10 +41,12 @@ struct sbc_encoder_state {
 	int16_t SBC_ALIGNED X[2][SBC_X_BUFFER_SIZE];
 	/* Polyphase analysis filter for 4 subbands configuration,
 	 * it handles 4 blocks at once */
-	void (*sbc_analyze_4b_4s)(int16_t *x, int32_t *out, int out_stride);
+	void (*sbc_analyze_4b_4s)(struct sbc_encoder_state *state,
+			int16_t *x, int32_t *out, int out_stride);
 	/* Polyphase analysis filter for 8 subbands configuration,
 	 * it handles 4 blocks at once */
-	void (*sbc_analyze_4b_8s)(int16_t *x, int32_t *out, int out_stride);
+	void (*sbc_analyze_4b_8s)(struct sbc_encoder_state *state,
+			int16_t *x, int32_t *out, int out_stride);
 	/* Process input data (deinterleave, endian conversion, reordering),
 	 * depending on the number of subbands and input data byte order */
 	int (*sbc_enc_process_input_4s_le)(struct sbc_encoder_state *state,
diff --git a/sbc/sbc_primitives_armv6.c b/sbc/sbc_primitives_armv6.c
index b321272..6ad94c6 100644
--- a/sbc/sbc_primitives_armv6.c
+++ b/sbc/sbc_primitives_armv6.c
@@ -265,7 +265,8 @@ static void __attribute__((naked)) sbc_analyze_eight_armv6()
 	((void (*)(int16_t *, int32_t *, const FIXED_T*)) \
 		sbc_analyze_eight_armv6)((in), (out), (consts))
 
-static void sbc_analyze_4b_4s_armv6(int16_t *x, int32_t *out, int out_stride)
+static void sbc_analyze_4b_4s_armv6(struct sbc_encoder_state *state,
+		int16_t *x, int32_t *out, int out_stride)
 {
 	/* Analyze blocks */
 	sbc_analyze_four(x + 12, out, analysis_consts_fixed4_simd_odd);
@@ -277,7 +278,8 @@ static void sbc_analyze_4b_4s_armv6(int16_t *x, int32_t *out, int out_stride)
 	sbc_analyze_four(x + 0, out, analysis_consts_fixed4_simd_even);
 }
 
-static void sbc_analyze_4b_8s_armv6(int16_t *x, int32_t *out, int out_stride)
+static void sbc_analyze_4b_8s_armv6(struct sbc_encoder_state *state,
+		int16_t *x, int32_t *out, int out_stride)
 {
 	/* Analyze blocks */
 	sbc_analyze_eight(x + 24, out, analysis_consts_fixed8_simd_odd);
diff --git a/sbc/sbc_primitives_iwmmxt.c b/sbc/sbc_primitives_iwmmxt.c
index e0bd060..39cc390 100644
--- a/sbc/sbc_primitives_iwmmxt.c
+++ b/sbc/sbc_primitives_iwmmxt.c
@@ -268,8 +268,8 @@ static inline void sbc_analyze_eight_iwmmxt(const int16_t *in, int32_t *out,
 		  "wcgr0", "memory");
 }
 
-static inline void sbc_analyze_4b_4s_iwmmxt(int16_t *x, int32_t *out,
-						int out_stride)
+static inline void sbc_analyze_4b_4s_iwmmxt(struct sbc_encoder_state *state,
+		int16_t *x, int32_t *out, int out_stride)
 {
 	/* Analyze blocks */
 	sbc_analyze_four_iwmmxt(x + 12, out, analysis_consts_fixed4_simd_odd);
@@ -281,8 +281,8 @@ static inline void sbc_analyze_4b_4s_iwmmxt(int16_t *x, int32_t *out,
 	sbc_analyze_four_iwmmxt(x + 0, out, analysis_consts_fixed4_simd_even);
 }
 
-static inline void sbc_analyze_4b_8s_iwmmxt(int16_t *x, int32_t *out,
-						int out_stride)
+static inline void sbc_analyze_4b_8s_iwmmxt(struct sbc_encoder_state *state,
+		int16_t *x, int32_t *out, int out_stride)
 {
 	/* Analyze blocks */
 	sbc_analyze_eight_iwmmxt(x + 24, out, analysis_consts_fixed8_simd_odd);
diff --git a/sbc/sbc_primitives_mmx.c b/sbc/sbc_primitives_mmx.c
index 27e9a56..cbacb4e 100644
--- a/sbc/sbc_primitives_mmx.c
+++ b/sbc/sbc_primitives_mmx.c
@@ -246,8 +246,8 @@ static inline void sbc_analyze_eight_mmx(const int16_t *in, int32_t *out,
 		: "cc", "memory");
 }
 
-static inline void sbc_analyze_4b_4s_mmx(int16_t *x, int32_t *out,
-						int out_stride)
+static inline void sbc_analyze_4b_4s_mmx(struct sbc_encoder_state *state,
+		int16_t *x, int32_t *out, int out_stride)
 {
 	/* Analyze blocks */
 	sbc_analyze_four_mmx(x + 12, out, analysis_consts_fixed4_simd_odd);
@@ -261,8 +261,8 @@ static inline void sbc_analyze_4b_4s_mmx(int16_t *x, int32_t *out,
 	__asm__ volatile ("emms\n");
 }
 
-static inline void sbc_analyze_4b_8s_mmx(int16_t *x, int32_t *out,
-						int out_stride)
+static inline void sbc_analyze_4b_8s_mmx(struct sbc_encoder_state *state,
+		int16_t *x, int32_t *out, int out_stride)
 {
 	/* Analyze blocks */
 	sbc_analyze_eight_mmx(x + 24, out, analysis_consts_fixed8_simd_odd);
diff --git a/sbc/sbc_primitives_neon.c b/sbc/sbc_primitives_neon.c
index 83277ae..5b38060 100644
--- a/sbc/sbc_primitives_neon.c
+++ b/sbc/sbc_primitives_neon.c
@@ -211,8 +211,8 @@ static inline void _sbc_analyze_eight_neon(const int16_t *in, int32_t *out,
 			"d18", "d19");
 }
 
-static inline void sbc_analyze_4b_4s_neon(int16_t *x,
-						int32_t *out, int out_stride)
+static inline void sbc_analyze_4b_4s_neon(struct sbc_encoder_state *state,
+		int16_t *x, int32_t *out, int out_stride)
 {
 	/* Analyze blocks */
 	_sbc_analyze_four_neon(x + 12, out, analysis_consts_fixed4_simd_odd);
@@ -224,8 +224,8 @@ static inline void sbc_analyze_4b_4s_neon(int16_t *x,
 	_sbc_analyze_four_neon(x + 0, out, analysis_consts_fixed4_simd_even);
 }
 
-static inline void sbc_analyze_4b_8s_neon(int16_t *x,
-						int32_t *out, int out_stride)
+static inline void sbc_analyze_4b_8s_neon(struct sbc_encoder_state *state,
+		int16_t *x, int32_t *out, int out_stride)
 {
 	/* Analyze blocks */
 	_sbc_analyze_eight_neon(x + 24, out, analysis_consts_fixed8_simd_odd);
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 01/11] Pass encoder_state to process input functions
From: Frédéric Dalleau @ 2012-10-18 16:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1350576911-14678-1-git-send-email-frederic.dalleau@linux.intel.com>

---
 sbc/sbc.c                 |    4 ++--
 sbc/sbc_primitives.c      |   30 ++++++++++++++++--------------
 sbc/sbc_primitives.h      |    8 ++++----
 sbc/sbc_primitives_neon.c |   32 ++++++++++++++++----------------
 4 files changed, 38 insertions(+), 36 deletions(-)

diff --git a/sbc/sbc.c b/sbc/sbc.c
index f0c77c7..76acf43 100644
--- a/sbc/sbc.c
+++ b/sbc/sbc.c
@@ -1034,7 +1034,7 @@ SBC_EXPORT ssize_t sbc_encode(sbc_t *sbc, const void *input, size_t input_len,
 	struct sbc_priv *priv;
 	int samples;
 	ssize_t framelen;
-	int (*sbc_enc_process_input)(int position,
+	int (*sbc_enc_process_input)(struct sbc_encoder_state *state,
 			const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
 			int nsamples, int nchannels);
 
@@ -1092,7 +1092,7 @@ SBC_EXPORT ssize_t sbc_encode(sbc_t *sbc, const void *input, size_t input_len,
 	}
 
 	priv->enc_state.position = sbc_enc_process_input(
-		priv->enc_state.position, (const uint8_t *) input,
+		&priv->enc_state, (const uint8_t *) input,
 		priv->enc_state.X, priv->frame.subbands * priv->frame.blocks,
 		priv->frame.channels);
 
diff --git a/sbc/sbc_primitives.c b/sbc/sbc_primitives.c
index ad780d0..e137604 100644
--- a/sbc/sbc_primitives.c
+++ b/sbc/sbc_primitives.c
@@ -227,10 +227,11 @@ static inline int16_t unaligned16_le(const uint8_t *ptr)
  */
 
 static SBC_ALWAYS_INLINE int sbc_encoder_process_input_s4_internal(
-	int position,
+	struct sbc_encoder_state *state,
 	const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
 	int nsamples, int nchannels, int big_endian)
 {
+	int position = state->position;
 	/* handle X buffer wraparound */
 	if (position < nsamples) {
 		if (nchannels > 0)
@@ -278,10 +279,11 @@ static SBC_ALWAYS_INLINE int sbc_encoder_process_input_s4_internal(
 }
 
 static SBC_ALWAYS_INLINE int sbc_encoder_process_input_s8_internal(
-	int position,
+	struct sbc_encoder_state *state,
 	const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
 	int nsamples, int nchannels, int big_endian)
 {
+	int position = state->position;
 	/* handle X buffer wraparound */
 	if (position < nsamples) {
 		if (nchannels > 0)
@@ -356,52 +358,52 @@ static SBC_ALWAYS_INLINE int sbc_encoder_process_input_s8_internal(
  * to the top of the buffer on buffer wraparound.
  */
 
-static int sbc_enc_process_input_4s_le(int position,
+static int sbc_enc_process_input_4s_le(struct sbc_encoder_state *state,
 		const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
 		int nsamples, int nchannels)
 {
 	if (nchannels > 1)
 		return sbc_encoder_process_input_s4_internal(
-			position, pcm, X, nsamples, 2, 0);
+			state, pcm, X, nsamples, 2, 0);
 	else
 		return sbc_encoder_process_input_s4_internal(
-			position, pcm, X, nsamples, 1, 0);
+			state, pcm, X, nsamples, 1, 0);
 }
 
-static int sbc_enc_process_input_4s_be(int position,
+static int sbc_enc_process_input_4s_be(struct sbc_encoder_state *state,
 		const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
 		int nsamples, int nchannels)
 {
 	if (nchannels > 1)
 		return sbc_encoder_process_input_s4_internal(
-			position, pcm, X, nsamples, 2, 1);
+			state, pcm, X, nsamples, 2, 1);
 	else
 		return sbc_encoder_process_input_s4_internal(
-			position, pcm, X, nsamples, 1, 1);
+			state, pcm, X, nsamples, 1, 1);
 }
 
-static int sbc_enc_process_input_8s_le(int position,
+static int sbc_enc_process_input_8s_le(struct sbc_encoder_state *state,
 		const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
 		int nsamples, int nchannels)
 {
 	if (nchannels > 1)
 		return sbc_encoder_process_input_s8_internal(
-			position, pcm, X, nsamples, 2, 0);
+			state, pcm, X, nsamples, 2, 0);
 	else
 		return sbc_encoder_process_input_s8_internal(
-			position, pcm, X, nsamples, 1, 0);
+			state, pcm, X, nsamples, 1, 0);
 }
 
-static int sbc_enc_process_input_8s_be(int position,
+static int sbc_enc_process_input_8s_be(struct sbc_encoder_state *state,
 		const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
 		int nsamples, int nchannels)
 {
 	if (nchannels > 1)
 		return sbc_encoder_process_input_s8_internal(
-			position, pcm, X, nsamples, 2, 1);
+			state, pcm, X, nsamples, 2, 1);
 	else
 		return sbc_encoder_process_input_s8_internal(
-			position, pcm, X, nsamples, 1, 1);
+			state, pcm, X, nsamples, 1, 1);
 }
 
 /* Supplementary function to count the number of leading zeros */
diff --git a/sbc/sbc_primitives.h b/sbc/sbc_primitives.h
index 17ad4f7..c80337e 100644
--- a/sbc/sbc_primitives.h
+++ b/sbc/sbc_primitives.h
@@ -47,16 +47,16 @@ struct sbc_encoder_state {
 	void (*sbc_analyze_4b_8s)(int16_t *x, int32_t *out, int out_stride);
 	/* Process input data (deinterleave, endian conversion, reordering),
 	 * depending on the number of subbands and input data byte order */
-	int (*sbc_enc_process_input_4s_le)(int position,
+	int (*sbc_enc_process_input_4s_le)(struct sbc_encoder_state *state,
 			const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
 			int nsamples, int nchannels);
-	int (*sbc_enc_process_input_4s_be)(int position,
+	int (*sbc_enc_process_input_4s_be)(struct sbc_encoder_state *state,
 			const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
 			int nsamples, int nchannels);
-	int (*sbc_enc_process_input_8s_le)(int position,
+	int (*sbc_enc_process_input_8s_le)(struct sbc_encoder_state *state,
 			const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
 			int nsamples, int nchannels);
-	int (*sbc_enc_process_input_8s_be)(int position,
+	int (*sbc_enc_process_input_8s_be)(struct sbc_encoder_state *state,
 			const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
 			int nsamples, int nchannels);
 	/* Scale factors calculation */
diff --git a/sbc/sbc_primitives_neon.c b/sbc/sbc_primitives_neon.c
index 5d4d0e3..83277ae 100644
--- a/sbc/sbc_primitives_neon.c
+++ b/sbc/sbc_primitives_neon.c
@@ -845,36 +845,36 @@ static SBC_ALWAYS_INLINE int sbc_enc_process_input_8s_neon_internal(
 #undef PERM_BE
 #undef PERM_LE
 
-static int sbc_enc_process_input_4s_be_neon(int position, const uint8_t *pcm,
-					int16_t X[2][SBC_X_BUFFER_SIZE],
-					int nsamples, int nchannels)
+static int sbc_enc_process_input_4s_be_neon(struct sbc_encoder_state *state,
+		const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
+		int nsamples, int nchannels)
 {
 	return sbc_enc_process_input_4s_neon_internal(
-		position, pcm, X, nsamples, nchannels, 1);
+		state->position, pcm, X, nsamples, nchannels, 1);
 }
 
-static int sbc_enc_process_input_4s_le_neon(int position, const uint8_t *pcm,
-					int16_t X[2][SBC_X_BUFFER_SIZE],
-					int nsamples, int nchannels)
+static int sbc_enc_process_input_4s_le_neon(struct sbc_encoder_state *state,
+		const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
+		int nsamples, int nchannels)
 {
 	return sbc_enc_process_input_4s_neon_internal(
-		position, pcm, X, nsamples, nchannels, 0);
+		state->position, pcm, X, nsamples, nchannels, 0);
 }
 
-static int sbc_enc_process_input_8s_be_neon(int position, const uint8_t *pcm,
-					int16_t X[2][SBC_X_BUFFER_SIZE],
-					int nsamples, int nchannels)
+static int sbc_enc_process_input_8s_be_neon(struct sbc_encoder_state *state,
+		const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
+		int nsamples, int nchannels)
 {
 	return sbc_enc_process_input_8s_neon_internal(
-		position, pcm, X, nsamples, nchannels, 1);
+		state->position, pcm, X, nsamples, nchannels, 1);
 }
 
-static int sbc_enc_process_input_8s_le_neon(int position, const uint8_t *pcm,
-					int16_t X[2][SBC_X_BUFFER_SIZE],
-					int nsamples, int nchannels)
+static int sbc_enc_process_input_8s_le_neon(struct sbc_encoder_state *state,
+		const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE],
+		int nsamples, int nchannels)
 {
 	return sbc_enc_process_input_8s_neon_internal(
-		position, pcm, X, nsamples, nchannels, 0);
+		state->position, pcm, X, nsamples, nchannels, 0);
 }
 
 void sbc_init_primitives_neon(struct sbc_encoder_state *state)
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 00/11] mSBC tests
From: Frédéric Dalleau @ 2012-10-18 16:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau

Hi folks,

For version 2, I figured out what the SIMD code is doing and managed to make it
work using 15 blocks. Marcel's comments were taken into account.
The accuracy may not be perfect, but the result is hearable. So good time to post.

How to use:
sample.au should be an .au audio file 16000hz 16bits 1 channel pcm.
$ src/sbcenc  -m -b26 -B16 -s8   sample.au > sample.au.msbc
$ src/sbcinfo sample.au.msbc
$ src/sbcdec  -m -f sample.au.msbc.au sample.au.msbc
$ mplayer sample.au.msbc.au

Regards,
Frederic


Frédéric Dalleau (11):
  Pass encoder_state to process input functions
  Add encoder_state parameter to analysis functions
  Make increment variable
  Add msbc encoding and decoding flag
  Add simd primitive for 1b 8s analyse
  Add support for mSBC frame header
  Add mmx primitive for 1b 8s analyse
  update sbcdec for msbc
  update sbcenc for msbc
  update sbcinfo for msbc
  Update copyrights

 sbc/sbc.c                   |  275 +++++++++++++++++++++++++++----------------
 sbc/sbc.h                   |    3 +
 sbc/sbc_primitives.c        |  102 +++++++++++++---
 sbc/sbc_primitives.h        |   22 ++--
 sbc/sbc_primitives_armv6.c  |    6 +-
 sbc/sbc_primitives_iwmmxt.c |    8 +-
 sbc/sbc_primitives_mmx.c    |   24 +++-
 sbc/sbc_primitives_neon.c   |   40 +++----
 src/sbcdec.c                |   18 ++-
 src/sbcenc.c                |   26 +++-
 src/sbcinfo.c               |   52 +++++---
 11 files changed, 391 insertions(+), 185 deletions(-)

-- 
1.7.9.5


^ permalink raw reply

* Re: [PATCHv2 17/19] Bluetooth: Send create channel request instead of connect for AMP
From: Mat Martineau @ 2012-10-18 16:04 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth, gustavo, sunnyk, marcel
In-Reply-To: <20121018094027.GG13545@aemeltch-MOBL1>


Andrei -

On Thu, 18 Oct 2012, Andrei Emeltchenko wrote:

> On Tue, Oct 16, 2012 at 04:36:31PM -0700, Mat Martineau wrote:
>> When the channel policy is set to prefer AMP, then an L2CAP channel is
>> set up using the "create channel" command rather than the "connect"
>> command.  A physical link is also set up before sending "create
>> channel".
>
> I feel that this patch doing something else that commit message implies.
> So it is better to skip it for now.

I think you're right and we should skip this patch in this series. 
The logical and physical link handling has changed a bit, so some of 
these changes might not fit any more.

>>
>> Behavior is unchanged if enable_hs is false.
>>
>> Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
>> ---
>>  net/bluetooth/l2cap_core.c | 42 ++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 42 insertions(+)
>>
>> diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
>> index 7e8fe84..17d917b 100644
>> --- a/net/bluetooth/l2cap_core.c
>> +++ b/net/bluetooth/l2cap_core.c
>> @@ -58,6 +58,9 @@ static void l2cap_send_disconn_req(struct l2cap_conn *conn,
>>  static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
>>  		     struct sk_buff_head *skbs, u8 event);
>>
>> +static void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan,
>> +			      u8 status);
>> +
>>  /* ---- L2CAP channels ---- */
>>
>>  static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
>> @@ -576,6 +579,13 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
>>  			mgr->bredr_chan = NULL;
>>  	}
>>
>> +	if (chan->hs_hchan) {
>> +		chan->hs_hchan = NULL;
>> +		chan->hs_hcon = NULL;
>> +
>> +		/* Placeholder - free logical link */
>> +	}
>> +
>
> Here we free logical link
>
>>  	chan->ops->teardown(chan, err);
>>
>>  	if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state))
>> @@ -1126,6 +1136,7 @@ static void l2cap_start_connection(struct l2cap_chan *chan)
>>  {
>>  	if (__amp_capable(chan)) {
>>  		BT_DBG("chan %p AMP capable: discover AMPs", chan);
>> +		set_bit(CONF_CONNECT_PEND, &chan->conf_state);
>>  		a2mp_discover_amp(chan);
>>  	} else {
>>  		l2cap_send_conn_req(chan);
>> @@ -1271,6 +1282,16 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
>>  				rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
>>  			}
>>
>> +			if (rsp.result == __constant_cpu_to_le16(L2CAP_CR_SUCCESS) &&
>> +			    chan->local_amp_id) {
>> +				/* Placeholder - uncomment when amp functions
>> +				 * are available
>> +				amp_accept_physical(chan, chan->local_amp_id);
>> +				 */
>> +				l2cap_chan_unlock(chan);
>> +				continue;
>> +			}
>> +
>>  			l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
>>  				       sizeof(rsp), &rsp);
>>
>> @@ -3359,6 +3380,18 @@ done:
>>  			rfc.mode = chan->mode;
>>  		}
>>
>> +		if (test_bit(CONF_LOC_CONF_PEND, &chan->conf_state) &&
>> +		    chan->local_amp_id) {
>> +			struct hci_chan *hchan = NULL;
>> +
>> +			/* Placeholder - get hci_chan for logical link */
>> +
>> +			if (hchan && hchan->state == BT_CONNECTED) {
>> +				l2cap_logical_cfm(chan, hchan,
>> +						  L2CAP_MR_SUCCESS);
>> +			}
>> +		}
>> +
>
> this is configuration phase which is happening after channel is created
>
>
>>  		if (result == L2CAP_CONF_SUCCESS)
>>  			set_bit(CONF_OUTPUT_DONE, &chan->conf_state);
>>  	}
>> @@ -6367,6 +6400,15 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
>>  					stat = L2CAP_CS_AUTHOR_PEND;
>>  					chan->ops->defer(chan);
>>  				} else {
>> +					if (chan->local_amp_id) {
>> +						/* Placeholder - accept physical
>> +						 * link
>> +						amp_accept_physical(chan,
>> +							chan->local_amp_id);
>> +						*/
>> +						continue;
>> +					}
>> +
>
> here is accept physical link

Regards,

--
Mat Martineau

Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply

* Re: [PATCHv2 04/19] Bluetooth: Lookup channel structure based on DCID
From: Mat Martineau @ 2012-10-18 15:51 UTC (permalink / raw)
  To: Andrei Emeltchenko; +Cc: linux-bluetooth, gustavo, sunnyk, marcel
In-Reply-To: <20121018073050.GC13545@aemeltch-MOBL1>


Andrei -

On Thu, 18 Oct 2012, Andrei Emeltchenko wrote:

> Hi Mat,
>
> On Tue, Oct 16, 2012 at 04:36:18PM -0700, Mat Martineau wrote:
>> Processing a move channel request involves getting the channel
>> structure using the destination channel ID.  Previous code could only
>> look up using the source channel ID.
>>
>> Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
>> ---
>>  net/bluetooth/l2cap_core.c | 17 +++++++++++++++++
>>  1 file changed, 17 insertions(+)
>>
>> diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
>> index ec2b4d9..b5b849b 100644
>> --- a/net/bluetooth/l2cap_core.c
>> +++ b/net/bluetooth/l2cap_core.c
>> @@ -100,6 +100,22 @@ static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn,
>>  	return c;
>>  }
>>
>> +/* Find channel with given DCID.
>> + * Returns locked channel. */
>> +static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn,
>> +						 u16 cid)
>> +{
>> +	struct l2cap_chan *c;
>> +
>> +	mutex_lock(&conn->chan_lock);
>> +	c = __l2cap_get_chan_by_dcid(conn, cid);
>> +	if (c)
>> +		l2cap_chan_lock(c);
>> +	mutex_unlock(&conn->chan_lock);
>> +
>> +	return c;
>> +}
>> +
>>  static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn,
>>  						    u8 ident)
>>  {
>> @@ -4139,6 +4155,7 @@ static inline int l2cap_move_channel_req(struct l2cap_conn *conn,
>>  					 u16 cmd_len, void *data)
>>  {
>>  	struct l2cap_move_chan_req *req = data;
>> +	struct l2cap_chan *chan;
>
> This line seems do not belong to the patch.

Yes, this line should be moved to patch 5 with the other changes to 
this function.

--
Mat Martineau

Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply

* Re: [PATCH BlueZ] AVDTP: Do not keep a internal reference
From: Luiz Augusto von Dentz @ 2012-10-18 14:57 UTC (permalink / raw)
  To: Ludek Finstrle; +Cc: linux-bluetooth
In-Reply-To: <20121018142011.GA13482@pzkagis.cz>

Hi Ludek,

On Thu, Oct 18, 2012 at 5:20 PM, Ludek Finstrle <luf@pzkagis.cz> wrote:
> Hello Luiz,
>
> Wed, Oct 17, 2012 at 02:49:32PM +0300, Luiz Augusto von Dentz napsal(a):
>> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>>
>> Don't initialize reference with 1, instead always start disconnect timer
>> when reference drops to 0, so in case nobody reclaims the session it
>> automatically disconnect after 1 second and frees the memory.
>> ---
>>  audio/avdtp.c | 220 ++++++++++++++++++++++++++--------------------------------
>>  1 file changed, 97 insertions(+), 123 deletions(-)
>>
>> diff --git a/audio/avdtp.c b/audio/avdtp.c
>> index bd91cb6..6bfeb9b 100644
>> --- a/audio/avdtp.c
>> +++ b/audio/avdtp.c
>> @@ -387,8 +387,7 @@ struct avdtp_stream {
>>  /* Structure describing an AVDTP connection between two devices */
>>
>>  struct avdtp {
>> -     int ref;
>> -     int free_lock;
>> +     unsigned int ref;
>>
>>       uint16_t version;
>>
>> @@ -657,50 +656,6 @@ static gboolean stream_open_timeout(gpointer user_data)
>>       return FALSE;
>>  }
>>
>> -static gboolean disconnect_timeout(gpointer user_data)
>> -{
>> -     struct avdtp *session = user_data;
>> -     struct audio_device *dev;
>> -     gboolean stream_setup;
>> -
>> -     session->dc_timer = 0;
>> -     stream_setup = session->stream_setup;
>> -     session->stream_setup = FALSE;
>> -
>> -     dev = manager_get_device(&session->server->src, &session->dst, FALSE);
>> -
>> -     if (dev && dev->sink && stream_setup)
>> -             sink_setup_stream(dev->sink, session);
>> -     else if (dev && dev->source && stream_setup)
>> -             source_setup_stream(dev->source, session);
>> -     else
>> -             connection_lost(session, ETIMEDOUT);
>> -
>> -     return FALSE;
>> -}
>> -
>> -static void remove_disconnect_timer(struct avdtp *session)
>> -{
>> -     g_source_remove(session->dc_timer);
>> -     session->dc_timer = 0;
>> -     session->stream_setup = FALSE;
>> -}
>> -
>> -static void set_disconnect_timer(struct avdtp *session)
>> -{
>> -     if (session->dc_timer)
>> -             remove_disconnect_timer(session);
>> -
>> -     if (session->device_disconnect) {
>> -             session->dc_timer = g_idle_add(disconnect_timeout, session);
>> -             return;
>> -     }
>> -
>> -     session->dc_timer = g_timeout_add_seconds(DISCONNECT_TIMEOUT,
>> -                                             disconnect_timeout,
>> -                                             session);
>> -}
>> -
>>  void avdtp_error_init(struct avdtp_error *err, uint8_t category, int id)
>>  {
>>       err->category = category;
>> @@ -780,8 +735,9 @@ static void avdtp_set_state(struct avdtp *session,
>>       }
>>  }
>>
>> -static void stream_free(struct avdtp_stream *stream)
>> +static void stream_free(void *data)
>>  {
>> +     struct avdtp_stream *stream = data;
>>       struct avdtp_remote_sep *rsep;
>>
>>       stream->lsep->info.inuse = 0;
>> @@ -1144,37 +1100,42 @@ static int avdtp_cancel_authorization(struct avdtp *session)
>>               return err;
>>
>>       session->auth_id = 0;
>> +     avdtp_unref(session);
>>
>>       return 0;
>>  }
>>
>> -static void connection_lost(struct avdtp *session, int err)
>> +static void sep_free(gpointer data)
>>  {
>> -     char address[18];
>> +     struct avdtp_remote_sep *sep = data;
>>
>> -     ba2str(&session->dst, address);
>> -     DBG("Disconnected from %s", address);
>> +     g_slist_free_full(sep->caps, g_free);
>> +     g_free(sep);
>> +}
>>
>> -     if (err != EACCES)
>> -             avdtp_cancel_authorization(session);
>> +static void remove_disconnect_timer(struct avdtp *session)
>> +{
>> +     g_source_remove(session->dc_timer);
>> +     session->dc_timer = 0;
>> +     session->stream_setup = FALSE;
>> +}
>>
>> -     session->free_lock = 1;
>> +static void avdtp_free(void *data)
>> +{
>> +     struct avdtp *session = data;
>>
>> -     finalize_discovery(session, err);
>> +     DBG("%p", session);
>>
>> -     g_slist_foreach(session->streams, (GFunc) release_stream, session);
>> -     session->streams = NULL;
>> +     g_slist_free_full(session->streams, stream_free);
>>
>> -     session->free_lock = 0;
>> +     if (session->state != AVDTP_SESSION_STATE_DISCONNECTED)
>> +             avdtp_set_state(session, AVDTP_SESSION_STATE_DISCONNECTED);
>>
>>       if (session->io) {
>>               g_io_channel_shutdown(session->io, FALSE, NULL);
>>               g_io_channel_unref(session->io);
>> -             session->io = NULL;
>>       }
>>
>> -     avdtp_set_state(session, AVDTP_SESSION_STATE_DISCONNECTED);
>> -
>>       if (session->io_id) {
>>               g_source_remove(session->io_id);
>>               session->io_id = 0;
>> @@ -1183,69 +1144,95 @@ static void connection_lost(struct avdtp *session, int err)
>>       if (session->dc_timer)
>>               remove_disconnect_timer(session);
>>
>> -     if (session->ref != 1)
>> -             error("connection_lost: ref count not 1 after all callbacks");
>> -     else
>> -             avdtp_unref(session);
>> +     avdtp_cancel_authorization(session);
>> +
>> +     if (session->req)
>> +             pending_req_free(session->req);
>> +
>> +     g_slist_free_full(session->seps, sep_free);
>> +
>> +     g_free(session->buf);
>> +
>> +     g_free(session);
>>  }
>>
>> -static void sep_free(gpointer data)
>> +static gboolean disconnect_timeout(gpointer user_data)
>>  {
>> -     struct avdtp_remote_sep *sep = data;
>> +     struct avdtp *session = user_data;
>> +     struct audio_device *dev;
>> +     gboolean stream_setup;
>>
>> -     g_slist_free_full(sep->caps, g_free);
>> -     g_free(sep);
>> +     session->dc_timer = 0;
>> +
>> +     if (session->ref == 0) {
>> +             struct avdtp_server *server = session->server;
>> +
>> +             server->sessions = g_slist_remove(server->sessions, session);
>> +             avdtp_free(session);
>> +             return FALSE;
>> +     }
>> +
>> +     stream_setup = session->stream_setup;
>> +     session->stream_setup = FALSE;
>> +
>> +     dev = manager_get_device(&session->server->src, &session->dst, FALSE);
>> +
>> +     if (dev && dev->sink && stream_setup)
>> +             sink_setup_stream(dev->sink, session);
>> +     else if (dev && dev->source && stream_setup)
>> +             source_setup_stream(dev->source, session);
>> +     else
>> +             connection_lost(session, ETIMEDOUT);
>> +
>> +     return FALSE;
>>  }
>>
>> -void avdtp_unref(struct avdtp *session)
>> +static void set_disconnect_timer(struct avdtp *session)
>>  {
>> -     struct avdtp_server *server;
>> +     if (session->dc_timer)
>> +             remove_disconnect_timer(session);
>>
>> -     if (!session)
>> +     if (session->device_disconnect) {
>> +             session->dc_timer = g_idle_add(disconnect_timeout, session);
>>               return;
>> +     }
>>
>> -     session->ref--;
>> -
>> -     DBG("%p: ref=%d", session, session->ref);
>> +     session->dc_timer = g_timeout_add_seconds(DISCONNECT_TIMEOUT,
>> +                                             disconnect_timeout,
>> +                                             session);
>> +}
>>
>> -     if (session->ref == 1) {
>> -             if (session->state == AVDTP_SESSION_STATE_CONNECTING &&
>> -                                                             session->io) {
>> -                     avdtp_cancel_authorization(session);
>> -                     g_io_channel_shutdown(session->io, TRUE, NULL);
>> -                     g_io_channel_unref(session->io);
>> -                     session->io = NULL;
>> -                     avdtp_set_state(session,
>> -                                     AVDTP_SESSION_STATE_DISCONNECTED);
>> -             }
>> +static void connection_lost(struct avdtp *session, int err)
>> +{
>> +     char address[18];
>>
>> -             if (session->io)
>> -                     set_disconnect_timer(session);
>> -             else if (!session->free_lock) /* Drop the local ref if we
>> -                                              aren't connected */
>> -                     session->ref--;
>> -     }
>> +     ba2str(&session->dst, address);
>> +     DBG("Disconnected from %s", address);
>>
>> -     if (session->ref > 0)
>> -             return;
>> +     if (err != EACCES)
>> +             avdtp_cancel_authorization(session);
>>
>> -     server = session->server;
>> +     g_slist_foreach(session->streams, (GFunc) release_stream, session);
>> +     session->streams = NULL;
>>
>> -     DBG("%p: freeing session and removing from list", session);
>> +     finalize_discovery(session, err);
>>
>> -     if (session->dc_timer)
>> -             remove_disconnect_timer(session);
>> +     avdtp_set_state(session, AVDTP_SESSION_STATE_DISCONNECTED);
>> +}
>>
>> -     server->sessions = g_slist_remove(server->sessions, session);
>> +void avdtp_unref(struct avdtp *session)
>> +{
>> +     if (!session)
>> +             return;
>>
>> -     if (session->req)
>> -             pending_req_free(session->req);
>> +     session->ref--;
>>
>> -     g_slist_free_full(session->seps, sep_free);
>> +     DBG("%p: ref=%d", session, session->ref);
>>
>> -     g_free(session->buf);
>> +     if (session->ref > 0)
>> +             return;
>>
>> -     g_free(session);
>> +     set_disconnect_timer(session);
>>  }
>>
>>  struct avdtp *avdtp_ref(struct avdtp *session)
>> @@ -2231,12 +2218,6 @@ static gboolean session_cb(GIOChannel *chan, GIOCondition cond,
>>                       goto failed;
>>               }
>>
>> -             if (session->ref == 1 && !session->streams && !session->req)
>> -                     set_disconnect_timer(session);
>> -
>> -             if (session->streams && session->dc_timer)
>> -                     remove_disconnect_timer(session);
>> -
>>               if (session->req && session->req->collided) {
>>                       DBG("Collision detected");
>>                       goto next;
>> @@ -2383,7 +2364,7 @@ static struct avdtp *avdtp_get_internal(const bdaddr_t *src, const bdaddr_t *dst
>>
>>       session->server = server;
>>       bacpy(&session->dst, dst);
>> -     session->ref = 1;
>> +     set_disconnect_timer(session);
>>       /* We don't use avdtp_set_state() here since this isn't a state change
>>        * but just setting of the initial state */
>>       session->state = AVDTP_SESSION_STATE_DISCONNECTED;
>> @@ -2490,6 +2471,8 @@ static void auth_cb(DBusError *derr, void *user_data)
>>       struct avdtp *session = user_data;
>>       GError *err = NULL;
>>
>> +     avdtp_unref(session);
>> +
>>       if (derr && dbus_error_is_set(derr)) {
>>               error("Access denied: %s", derr->message);
>>               connection_lost(session, EACCES);
>> @@ -2578,10 +2561,12 @@ static void avdtp_confirm_cb(GIOChannel *chan, gpointer data)
>>                                                       auth_cb, session);
>>       if (session->auth_id == 0) {
>>               avdtp_set_state(session, AVDTP_SESSION_STATE_DISCONNECTED);
>> -             avdtp_unref(session);
>>               goto drop;
>>       }
>>
>> +     /* Disable disconnect timer while authorizing */
>> +     avdtp_ref(session);
>> +
>>       dev->auto_connect = auto_connect;
>>
>>       return;
>> @@ -3949,23 +3934,12 @@ proceed:
>>  void avdtp_exit(const bdaddr_t *src)
>>  {
>>       struct avdtp_server *server;
>> -     GSList *l;
>>
>>       server = find_server(servers, src);
>>       if (!server)
>>               return;
>>
>> -     l = server->sessions;
>> -     while (l) {
>> -             struct avdtp *session = l->data;
>> -
>> -             l = l->next;
>> -             /* value of l pointer should be updated before invoking
>> -              * connection_lost since it internally uses avdtp_unref
>> -              * which operates on server->session list as well
>> -              */
>> -             connection_lost(session, -ECONNABORTED);
>> -     }
>> +     g_slist_free_full(server->sessions, avdtp_free);
>>
>>       servers = g_slist_remove(servers, server);
>>
>> --
>> 1.7.11.4
>
> I tried this patch (againist patched 4.99) and it contains bug.
>
> What happens:
> I try to connect from N900 bluez-4.99 to RHEL 6 bleuz-4.66 using:
> dbus-send --system --print-reply --dest=org.bluez /org/bluez/`pidof bluetoothd`/hci0/dev_<BT ID> org.bluez.AudioSource.Connect
>
> Until first first successful connect the RHEL machine asked me to Grant/Reject the conneciton.
> But after first connect/disconnect it stop asking me and the connection failed.
>
> I could connect/disconnect several times prior applying the patch (if it doesn't crash bluetoothd).
>
> I'll try to find the reason. I just want to give you the info.

We would need to know the PulseAudio version as well, in fact this
could be because the old unix socket IPC is in use in N900 and that
may take much more time to PulseAudio to notice the connection so I
don't think this is a valid use case, things have changed quite a bit
since N900 times. In the other hand with Media API we got PA involved
pretty early and once the transport object is create it will keep a
reference to the AVDTP session.

-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: [PATCH v5 02/15] adapter: Read name in storage at init
From: Frederic Danis @ 2012-10-18 14:41 UTC (permalink / raw)
  To: Daniel Wagner; +Cc: linux-bluetooth
In-Reply-To: <50800C6B.30000@monom.org>

Hello Daniel,

On 18/10/2012 16:04, Daniel Wagner wrote:
> On 18.10.2012 11:00, Frédéric Danis wrote:
>> ---
>>   src/adapter.c |   13 +++++++++++++
>>   1 file changed, 13 insertions(+)
>>
>> diff --git a/src/adapter.c b/src/adapter.c
>> index 3b24816..233527a 100644
>> --- a/src/adapter.c
>> +++ b/src/adapter.c
>> @@ -2506,6 +2506,18 @@ void btd_adapter_unref(struct btd_adapter
>> *adapter)
>>       g_free(path);
>>   }
>>
>> +static void load_config(struct btd_adapter *adapter)
>> +{
>> +    char name[MAX_NAME_LENGTH + 1];
>> +
>> +    /* Get name */
>> +    if (read_local_name(&adapter->bdaddr, name) < 0)
>> +        adapter->name = NULL;
>> +    else
>> +        adapter->name = g_strdup(name);
>> +
>> +}
>
> Why is this function called load_config when then comment above says
> 'Get name'? Or is there more code added in the next patches?

This function grows in following patches while it reads more settings 
during adapter initialization.

Regards

Fred

-- 
Frederic Danis                            Open Source Technology Center
frederic.danis@intel.com                              Intel Corporation


^ permalink raw reply

* Re: [PATCH v5 01/15] doc: Add settings storage documentation
From: Frederic Danis @ 2012-10-18 14:31 UTC (permalink / raw)
  To: Daniel Wagner; +Cc: linux-bluetooth
In-Reply-To: <50800C08.6040100@monom.org>

Hello Daniel,

On 18/10/2012 16:02, Daniel Wagner wrote:
> Hi Frédéric,
>
> On 18.10.2012 11:00, Frédéric Danis wrote:
>> ---
>>   doc/settings-storage.txt |  106
>> ++++++++++++++++++++++++++++++++++++++++++++++
>>   1 file changed, 106 insertions(+)
>>   create mode 100644 doc/settings-storage.txt
>>
>> diff --git a/doc/settings-storage.txt b/doc/settings-storage.txt
>> new file mode 100644
>> index 0000000..bc9ac66
>> --- /dev/null
>> +++ b/doc/settings-storage.txt
>> @@ -0,0 +1,106 @@
>> +Information related to local adapters and remote devices are stored
>> in storage
>> +directory (default: /var/lib/bluetooth).
>> +Files are in ini-file format.
>> +
>> +There is one directory per adapter, named by its bluetooth address,
>> which
>> +contains:
>> + - a settings file for the local adapter
>> + - an attribute_db file containing attributes of supported LE services
>> + - names file containing names of all devices already seen
>> + - one directory per remote device, named by remote device address,
>> which
>> +   contains:
>> +    - a settings file
>> +    - a key file accessible only by root
>> +    - an attribute_db file containing attributes of remote LE services
>> +
>> +So the directory structure should be:
>
> "should be" -> "is"?

You're right, I will change it.
Thanks

Regards

Fred


-- 
Frederic Danis                            Open Source Technology Center
frederic.danis@intel.com                              Intel Corporation


^ permalink raw reply

* Re: [PATCH BlueZ] AVDTP: Do not keep a internal reference
From: Ludek Finstrle @ 2012-10-18 14:20 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1350474572-29066-1-git-send-email-luiz.dentz@gmail.com>

Hello Luiz,

Wed, Oct 17, 2012 at 02:49:32PM +0300, Luiz Augusto von Dentz napsal(a):
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
> 
> Don't initialize reference with 1, instead always start disconnect timer
> when reference drops to 0, so in case nobody reclaims the session it
> automatically disconnect after 1 second and frees the memory.
> ---
>  audio/avdtp.c | 220 ++++++++++++++++++++++++++--------------------------------
>  1 file changed, 97 insertions(+), 123 deletions(-)
> 
> diff --git a/audio/avdtp.c b/audio/avdtp.c
> index bd91cb6..6bfeb9b 100644
> --- a/audio/avdtp.c
> +++ b/audio/avdtp.c
> @@ -387,8 +387,7 @@ struct avdtp_stream {
>  /* Structure describing an AVDTP connection between two devices */
>  
>  struct avdtp {
> -	int ref;
> -	int free_lock;
> +	unsigned int ref;
>  
>  	uint16_t version;
>  
> @@ -657,50 +656,6 @@ static gboolean stream_open_timeout(gpointer user_data)
>  	return FALSE;
>  }
>  
> -static gboolean disconnect_timeout(gpointer user_data)
> -{
> -	struct avdtp *session = user_data;
> -	struct audio_device *dev;
> -	gboolean stream_setup;
> -
> -	session->dc_timer = 0;
> -	stream_setup = session->stream_setup;
> -	session->stream_setup = FALSE;
> -
> -	dev = manager_get_device(&session->server->src, &session->dst, FALSE);
> -
> -	if (dev && dev->sink && stream_setup)
> -		sink_setup_stream(dev->sink, session);
> -	else if (dev && dev->source && stream_setup)
> -		source_setup_stream(dev->source, session);
> -	else
> -		connection_lost(session, ETIMEDOUT);
> -
> -	return FALSE;
> -}
> -
> -static void remove_disconnect_timer(struct avdtp *session)
> -{
> -	g_source_remove(session->dc_timer);
> -	session->dc_timer = 0;
> -	session->stream_setup = FALSE;
> -}
> -
> -static void set_disconnect_timer(struct avdtp *session)
> -{
> -	if (session->dc_timer)
> -		remove_disconnect_timer(session);
> -
> -	if (session->device_disconnect) {
> -		session->dc_timer = g_idle_add(disconnect_timeout, session);
> -		return;
> -	}
> -
> -	session->dc_timer = g_timeout_add_seconds(DISCONNECT_TIMEOUT,
> -						disconnect_timeout,
> -						session);
> -}
> -
>  void avdtp_error_init(struct avdtp_error *err, uint8_t category, int id)
>  {
>  	err->category = category;
> @@ -780,8 +735,9 @@ static void avdtp_set_state(struct avdtp *session,
>  	}
>  }
>  
> -static void stream_free(struct avdtp_stream *stream)
> +static void stream_free(void *data)
>  {
> +	struct avdtp_stream *stream = data;
>  	struct avdtp_remote_sep *rsep;
>  
>  	stream->lsep->info.inuse = 0;
> @@ -1144,37 +1100,42 @@ static int avdtp_cancel_authorization(struct avdtp *session)
>  		return err;
>  
>  	session->auth_id = 0;
> +	avdtp_unref(session);
>  
>  	return 0;
>  }
>  
> -static void connection_lost(struct avdtp *session, int err)
> +static void sep_free(gpointer data)
>  {
> -	char address[18];
> +	struct avdtp_remote_sep *sep = data;
>  
> -	ba2str(&session->dst, address);
> -	DBG("Disconnected from %s", address);
> +	g_slist_free_full(sep->caps, g_free);
> +	g_free(sep);
> +}
>  
> -	if (err != EACCES)
> -		avdtp_cancel_authorization(session);
> +static void remove_disconnect_timer(struct avdtp *session)
> +{
> +	g_source_remove(session->dc_timer);
> +	session->dc_timer = 0;
> +	session->stream_setup = FALSE;
> +}
>  
> -	session->free_lock = 1;
> +static void avdtp_free(void *data)
> +{
> +	struct avdtp *session = data;
>  
> -	finalize_discovery(session, err);
> +	DBG("%p", session);
>  
> -	g_slist_foreach(session->streams, (GFunc) release_stream, session);
> -	session->streams = NULL;
> +	g_slist_free_full(session->streams, stream_free);
>  
> -	session->free_lock = 0;
> +	if (session->state != AVDTP_SESSION_STATE_DISCONNECTED)
> +		avdtp_set_state(session, AVDTP_SESSION_STATE_DISCONNECTED);
>  
>  	if (session->io) {
>  		g_io_channel_shutdown(session->io, FALSE, NULL);
>  		g_io_channel_unref(session->io);
> -		session->io = NULL;
>  	}
>  
> -	avdtp_set_state(session, AVDTP_SESSION_STATE_DISCONNECTED);
> -
>  	if (session->io_id) {
>  		g_source_remove(session->io_id);
>  		session->io_id = 0;
> @@ -1183,69 +1144,95 @@ static void connection_lost(struct avdtp *session, int err)
>  	if (session->dc_timer)
>  		remove_disconnect_timer(session);
>  
> -	if (session->ref != 1)
> -		error("connection_lost: ref count not 1 after all callbacks");
> -	else
> -		avdtp_unref(session);
> +	avdtp_cancel_authorization(session);
> +
> +	if (session->req)
> +		pending_req_free(session->req);
> +
> +	g_slist_free_full(session->seps, sep_free);
> +
> +	g_free(session->buf);
> +
> +	g_free(session);
>  }
>  
> -static void sep_free(gpointer data)
> +static gboolean disconnect_timeout(gpointer user_data)
>  {
> -	struct avdtp_remote_sep *sep = data;
> +	struct avdtp *session = user_data;
> +	struct audio_device *dev;
> +	gboolean stream_setup;
>  
> -	g_slist_free_full(sep->caps, g_free);
> -	g_free(sep);
> +	session->dc_timer = 0;
> +
> +	if (session->ref == 0) {
> +		struct avdtp_server *server = session->server;
> +
> +		server->sessions = g_slist_remove(server->sessions, session);
> +		avdtp_free(session);
> +		return FALSE;
> +	}
> +
> +	stream_setup = session->stream_setup;
> +	session->stream_setup = FALSE;
> +
> +	dev = manager_get_device(&session->server->src, &session->dst, FALSE);
> +
> +	if (dev && dev->sink && stream_setup)
> +		sink_setup_stream(dev->sink, session);
> +	else if (dev && dev->source && stream_setup)
> +		source_setup_stream(dev->source, session);
> +	else
> +		connection_lost(session, ETIMEDOUT);
> +
> +	return FALSE;
>  }
>  
> -void avdtp_unref(struct avdtp *session)
> +static void set_disconnect_timer(struct avdtp *session)
>  {
> -	struct avdtp_server *server;
> +	if (session->dc_timer)
> +		remove_disconnect_timer(session);
>  
> -	if (!session)
> +	if (session->device_disconnect) {
> +		session->dc_timer = g_idle_add(disconnect_timeout, session);
>  		return;
> +	}
>  
> -	session->ref--;
> -
> -	DBG("%p: ref=%d", session, session->ref);
> +	session->dc_timer = g_timeout_add_seconds(DISCONNECT_TIMEOUT,
> +						disconnect_timeout,
> +						session);
> +}
>  
> -	if (session->ref == 1) {
> -		if (session->state == AVDTP_SESSION_STATE_CONNECTING &&
> -								session->io) {
> -			avdtp_cancel_authorization(session);
> -			g_io_channel_shutdown(session->io, TRUE, NULL);
> -			g_io_channel_unref(session->io);
> -			session->io = NULL;
> -			avdtp_set_state(session,
> -					AVDTP_SESSION_STATE_DISCONNECTED);
> -		}
> +static void connection_lost(struct avdtp *session, int err)
> +{
> +	char address[18];
>  
> -		if (session->io)
> -			set_disconnect_timer(session);
> -		else if (!session->free_lock) /* Drop the local ref if we
> -						 aren't connected */
> -			session->ref--;
> -	}
> +	ba2str(&session->dst, address);
> +	DBG("Disconnected from %s", address);
>  
> -	if (session->ref > 0)
> -		return;
> +	if (err != EACCES)
> +		avdtp_cancel_authorization(session);
>  
> -	server = session->server;
> +	g_slist_foreach(session->streams, (GFunc) release_stream, session);
> +	session->streams = NULL;
>  
> -	DBG("%p: freeing session and removing from list", session);
> +	finalize_discovery(session, err);
>  
> -	if (session->dc_timer)
> -		remove_disconnect_timer(session);
> +	avdtp_set_state(session, AVDTP_SESSION_STATE_DISCONNECTED);
> +}
>  
> -	server->sessions = g_slist_remove(server->sessions, session);
> +void avdtp_unref(struct avdtp *session)
> +{
> +	if (!session)
> +		return;
>  
> -	if (session->req)
> -		pending_req_free(session->req);
> +	session->ref--;
>  
> -	g_slist_free_full(session->seps, sep_free);
> +	DBG("%p: ref=%d", session, session->ref);
>  
> -	g_free(session->buf);
> +	if (session->ref > 0)
> +		return;
>  
> -	g_free(session);
> +	set_disconnect_timer(session);
>  }
>  
>  struct avdtp *avdtp_ref(struct avdtp *session)
> @@ -2231,12 +2218,6 @@ static gboolean session_cb(GIOChannel *chan, GIOCondition cond,
>  			goto failed;
>  		}
>  
> -		if (session->ref == 1 && !session->streams && !session->req)
> -			set_disconnect_timer(session);
> -
> -		if (session->streams && session->dc_timer)
> -			remove_disconnect_timer(session);
> -
>  		if (session->req && session->req->collided) {
>  			DBG("Collision detected");
>  			goto next;
> @@ -2383,7 +2364,7 @@ static struct avdtp *avdtp_get_internal(const bdaddr_t *src, const bdaddr_t *dst
>  
>  	session->server = server;
>  	bacpy(&session->dst, dst);
> -	session->ref = 1;
> +	set_disconnect_timer(session);
>  	/* We don't use avdtp_set_state() here since this isn't a state change
>  	 * but just setting of the initial state */
>  	session->state = AVDTP_SESSION_STATE_DISCONNECTED;
> @@ -2490,6 +2471,8 @@ static void auth_cb(DBusError *derr, void *user_data)
>  	struct avdtp *session = user_data;
>  	GError *err = NULL;
>  
> +	avdtp_unref(session);
> +
>  	if (derr && dbus_error_is_set(derr)) {
>  		error("Access denied: %s", derr->message);
>  		connection_lost(session, EACCES);
> @@ -2578,10 +2561,12 @@ static void avdtp_confirm_cb(GIOChannel *chan, gpointer data)
>  							auth_cb, session);
>  	if (session->auth_id == 0) {
>  		avdtp_set_state(session, AVDTP_SESSION_STATE_DISCONNECTED);
> -		avdtp_unref(session);
>  		goto drop;
>  	}
>  
> +	/* Disable disconnect timer while authorizing */
> +	avdtp_ref(session);
> +
>  	dev->auto_connect = auto_connect;
>  
>  	return;
> @@ -3949,23 +3934,12 @@ proceed:
>  void avdtp_exit(const bdaddr_t *src)
>  {
>  	struct avdtp_server *server;
> -	GSList *l;
>  
>  	server = find_server(servers, src);
>  	if (!server)
>  		return;
>  
> -	l = server->sessions;
> -	while (l) {
> -		struct avdtp *session = l->data;
> -
> -		l = l->next;
> -		/* value of l pointer should be updated before invoking
> -		 * connection_lost since it internally uses avdtp_unref
> -		 * which operates on server->session list as well
> -		 */
> -		connection_lost(session, -ECONNABORTED);
> -	}
> +	g_slist_free_full(server->sessions, avdtp_free);
>  
>  	servers = g_slist_remove(servers, server);
>  
> -- 
> 1.7.11.4

I tried this patch (againist patched 4.99) and it contains bug.

What happens:
I try to connect from N900 bluez-4.99 to RHEL 6 bleuz-4.66 using:
dbus-send --system --print-reply --dest=org.bluez /org/bluez/`pidof bluetoothd`/hci0/dev_<BT ID> org.bluez.AudioSource.Connect

Until first first successful connect the RHEL machine asked me to Grant/Reject the conneciton.
But after first connect/disconnect it stop asking me and the connection failed.

I could connect/disconnect several times prior applying the patch (if it doesn't crash bluetoothd).

I'll try to find the reason. I just want to give you the info.

Luf

^ permalink raw reply

* Re: [PATCH v5 02/15] adapter: Read name in storage at init
From: Daniel Wagner @ 2012-10-18 14:04 UTC (permalink / raw)
  To: Frédéric Danis; +Cc: linux-bluetooth
In-Reply-To: <1350550858-12239-3-git-send-email-frederic.danis@linux.intel.com>

On 18.10.2012 11:00, Frédéric Danis wrote:
> ---
>   src/adapter.c |   13 +++++++++++++
>   1 file changed, 13 insertions(+)
>
> diff --git a/src/adapter.c b/src/adapter.c
> index 3b24816..233527a 100644
> --- a/src/adapter.c
> +++ b/src/adapter.c
> @@ -2506,6 +2506,18 @@ void btd_adapter_unref(struct btd_adapter *adapter)
>   	g_free(path);
>   }
>
> +static void load_config(struct btd_adapter *adapter)
> +{
> +	char name[MAX_NAME_LENGTH + 1];
> +
> +	/* Get name */
> +	if (read_local_name(&adapter->bdaddr, name) < 0)
> +		adapter->name = NULL;
> +	else
> +		adapter->name = g_strdup(name);
> +
> +}

Why is this function called load_config when then comment above says 
'Get name'? Or is there more code added in the next patches?


^ permalink raw reply

* Re: [PATCH v5 01/15] doc: Add settings storage documentation
From: Daniel Wagner @ 2012-10-18 14:02 UTC (permalink / raw)
  To: Frédéric Danis; +Cc: linux-bluetooth
In-Reply-To: <1350550858-12239-2-git-send-email-frederic.danis@linux.intel.com>

Hi Frédéric,

On 18.10.2012 11:00, Frédéric Danis wrote:
> ---
>   doc/settings-storage.txt |  106 ++++++++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 106 insertions(+)
>   create mode 100644 doc/settings-storage.txt
>
> diff --git a/doc/settings-storage.txt b/doc/settings-storage.txt
> new file mode 100644
> index 0000000..bc9ac66
> --- /dev/null
> +++ b/doc/settings-storage.txt
> @@ -0,0 +1,106 @@
> +Information related to local adapters and remote devices are stored in storage
> +directory (default: /var/lib/bluetooth).
> +Files are in ini-file format.
> +
> +There is one directory per adapter, named by its bluetooth address, which
> +contains:
> + - a settings file for the local adapter
> + - an attribute_db file containing attributes of supported LE services
> + - names file containing names of all devices already seen
> + - one directory per remote device, named by remote device address, which
> +   contains:
> +    - a settings file
> +    - a key file accessible only by root
> +    - an attribute_db file containing attributes of remote LE services
> +
> +So the directory structure should be:

"should be" -> "is"?

cheers,
daniel

^ permalink raw reply

* [PATCH v6 16/16] hcitool: Retrieve names from cache directory
From: Frédéric Danis @ 2012-10-18 13:01 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1350565311-18330-1-git-send-email-frederic.danis@linux.intel.com>

---
 Makefile.tools  |    2 +-
 tools/hcitool.c |   31 ++++++++++++++++++++++++++-----
 2 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/Makefile.tools b/Makefile.tools
index e1f693c..a6adbed 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -28,7 +28,7 @@ tools_hciconfig_LDADD = lib/libbluetooth-private.la
 
 tools_hcitool_SOURCES = tools/hcitool.c src/oui.h src/oui.c \
 						src/textfile.h src/textfile.c
-tools_hcitool_LDADD = lib/libbluetooth-private.la
+tools_hcitool_LDADD = lib/libbluetooth-private.la @GLIB_LIBS@
 
 tools_sdptool_SOURCES = tools/sdptool.c src/sdp-xml.h src/sdp-xml.c
 tools_sdptool_LDADD = lib/libbluetooth-private.la @GLIB_LIBS@
diff --git a/tools/hcitool.c b/tools/hcitool.c
index aefbd68..a05e31f 100644
--- a/tools/hcitool.c
+++ b/tools/hcitool.c
@@ -40,6 +40,8 @@
 #include <sys/socket.h>
 #include <signal.h>
 
+#include <glib.h>
+
 #include <bluetooth/bluetooth.h>
 #include <bluetooth/hci.h>
 #include <bluetooth/hci_lib.h>
@@ -409,13 +411,32 @@ static char *major_classes[] = {
 
 static char *get_device_name(const bdaddr_t *local, const bdaddr_t *peer)
 {
-	char filename[PATH_MAX + 1], addr[18];
+	char filename[PATH_MAX + 1];
+	char local_addr[18], peer_addr[18];
+	GKeyFile *key_file;
+	char *str = NULL;
+	int len;
+
+	ba2str(local, local_addr);
+	ba2str(peer, peer_addr);
+
+	snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", local_addr,
+			peer_addr);
+	filename[PATH_MAX] = '\0';
+	key_file = g_key_file_new();
+
+	if (g_key_file_load_from_file(key_file, filename, 0, NULL)) {
+		str = g_key_file_get_string(key_file, "General", "Name", NULL);
+		if (str) {
+			len = strlen(str);
+			if (len > HCI_MAX_NAME_LENGTH)
+				str[HCI_MAX_NAME_LENGTH] = '\0';
+		}
+	}
 
-	ba2str(local, addr);
-	create_name(filename, PATH_MAX, STORAGEDIR, addr, "names");
+	g_key_file_free(key_file);
 
-	ba2str(peer, addr);
-	return textfile_get(filename, addr);
+	return str;
 }
 
 /* Display local devices */
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v6 15/16] input: Retrieve device name from cache directory
From: Frédéric Danis @ 2012-10-18 13:01 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1350565311-18330-1-git-send-email-frederic.danis@linux.intel.com>

---
 profiles/input/device.c |   26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/profiles/input/device.c b/profiles/input/device.c
index 997235b..f4f4f65 100644
--- a/profiles/input/device.c
+++ b/profiles/input/device.c
@@ -37,6 +37,7 @@
 #include <bluetooth/sdp_lib.h>
 #include <bluetooth/uuid.h>
 
+#include <glib.h>
 #include <gdbus.h>
 
 #include "log.h"
@@ -762,7 +763,9 @@ static struct input_device *input_device_new(struct btd_device *device,
 {
 	struct btd_adapter *adapter = device_get_adapter(device);
 	struct input_device *idev;
-	char name[249], src_addr[18], dst_addr[18];
+	char src_addr[18], dst_addr[18];
+	char filename[PATH_MAX + 1];
+	GKeyFile *key_file;
 
 	idev = g_new0(struct input_device, 1);
 	bacpy(&idev->src, adapter_get_address(adapter));
@@ -775,9 +778,24 @@ static struct input_device *input_device_new(struct btd_device *device,
 	ba2str(&idev->src, src_addr);
 	ba2str(&idev->dst, dst_addr);
 
-	if (read_device_name(src_addr, dst_addr, device_get_addr_type(device),
-				name) == 0)
-		idev->name = g_strdup(name);
+	snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", src_addr,
+			dst_addr);
+	filename[PATH_MAX] = '\0';
+	key_file = g_key_file_new();
+
+	if (g_key_file_load_from_file(key_file, filename, 0, NULL)) {
+		int len;
+
+		idev->name = g_key_file_get_string(key_file, "General",
+								"Name", NULL);
+		if (idev->name) {
+			len = strlen(idev->name);
+			if (len > HCI_MAX_NAME_LENGTH)
+				idev->name[HCI_MAX_NAME_LENGTH] = '\0';
+		}
+	}
+
+	g_key_file_free(key_file);
 
 	if (g_dbus_register_interface(btd_get_dbus_connection(),
 					idev->path, INPUT_DEVICE_INTERFACE,
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v6 14/16] dbusoob: Store device name in cache directory
From: Frédéric Danis @ 2012-10-18 13:01 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1350565311-18330-1-git-send-email-frederic.danis@linux.intel.com>

---
 plugins/dbusoob.c |   26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/plugins/dbusoob.c b/plugins/dbusoob.c
index 5c5b6ef..82d512c 100644
--- a/plugins/dbusoob.c
+++ b/plugins/dbusoob.c
@@ -31,6 +31,7 @@
 
 #include <errno.h>
 #include <gdbus.h>
+#include <sys/stat.h>
 
 #include <bluetooth/bluetooth.h>
 #include <bluetooth/hci.h>
@@ -194,6 +195,11 @@ static gboolean parse_data(DBusMessageIter *data, struct oob_data *remote_data)
 static gboolean store_data(struct btd_adapter *adapter, struct oob_data *data)
 {
 	bdaddr_t bdaddr;
+	char filename[PATH_MAX + 1];
+	char s_addr[18];
+	GKeyFile *key_file;
+	char *str;
+	gsize length = 0;
 
 	str2ba(data->addr, &bdaddr);
 
@@ -207,9 +213,23 @@ static gboolean store_data(struct btd_adapter *adapter, struct oob_data *data)
 		write_remote_class(adapter_get_address(adapter), &bdaddr,
 								data->class);
 
-	if (data->name)
-		write_device_name(adapter_get_address(adapter), &bdaddr, 0,
-								data->name);
+	if (data->name) {
+		ba2str(adapter_get_address(adapter), s_addr);
+		snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s",
+				s_addr, data->addr);
+		filename[PATH_MAX] = '\0';
+		create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+
+		key_file = g_key_file_new();
+		g_key_file_load_from_file(key_file, filename, 0, NULL);
+		g_key_file_set_string(key_file, "General", "Name", data->name);
+
+		str = g_key_file_to_data(key_file, &length, NULL);
+		g_file_set_contents(filename, str, length, NULL);
+		g_free(str);
+
+		g_key_file_free(key_file);
+	}
 
 	return TRUE;
 }
-- 
1.7.9.5


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox