Linux bluetooth development
 help / color / mirror / Atom feed
* Re: [PATCH BlueZ] hog: Fix selecting suspend backend
From: Johan Hedberg @ 2012-10-30 12:12 UTC (permalink / raw)
  To: João Paulo Rechi Vita; +Cc: linux-bluetooth
In-Reply-To: <1351542837-2635-1-git-send-email-jprvita@openbossa.org>

Hi João Paulo,

On Mon, Oct 29, 2012, João Paulo Rechi Vita wrote:
> The dummy backend was always being compiled and the --with-hog-suspend
> option was not being accepted by configure. Now the backend can be
> selected with --with-hog-suspend and the suspend implementation file is
> generated during compile time.
> ---
>  .gitignore   | 1 +
>  Makefile.am  | 5 ++++-
>  acinclude.m4 | 2 +-
>  3 files changed, 6 insertions(+), 2 deletions(-)

Applied. Thanks.

Johan

^ permalink raw reply

* Re: BLE issue: Start_LE_Encryption fails
From: Anderson Lizardo @ 2012-10-30 11:50 UTC (permalink / raw)
  To: Ajay, linux-bluetooth
In-Reply-To: <CAJdJm_MXB71MTcbrViLh486RtpWpx+a7SDvUPdSj2VdOa1fWvw@mail.gmail.com>

[Forgot to reply to the list]

On Tue, Oct 30, 2012 at 7:49 AM, Anderson Lizardo
<anderson.lizardo@openbossa.org> wrote:
> Hi Ajay,
>
> On Sun, Oct 28, 2012 at 1:08 PM, Ajay <ajay.kv@globaledgesoft.com> wrote:
>> Hi,
>>         I am getting le_long_term_key_negative reply  from the remote device
>> , on sending le_start_encryption . I am testing this with 2 ubuntu
>> machines(3.2.5) with IOGEAR dual mode dongles .
>
> To connect to a dual mode dongle, you need to set LE Adv. flags to
> 0x06 (which means general discoverable + BR/EDR not supported) on the
> acceptor side. You can use this command (on the acceptor/slave side):
>
> sudo hcitool -i hci0 cmd 0x08 0x0008 03 02 01 06 \
>     $(perl -e 'print "00 " x 28')
>
> Next, enable LE advertising:
>
> sudo hciconfig hci0 leadv
>
> On the initiator/master side, run "hcitool lescan" and try pairing again.

Regards,
-- 
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil

^ permalink raw reply

* Re: [PATCH] Bluetooth: Notify about device registration before power on
From: Johan Hedberg @ 2012-10-30 11:08 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1351586140-30708-1-git-send-email-marcel@holtmann.org>

Hi Marcel,

On Tue, Oct 30, 2012, Marcel Holtmann wrote:
> It is important that the monitor interface gets notified about
> a new device before its power on procedure has been started.
> 
> For some reason that is no longer working as expected and the power
> on procedure runs first. It is safe to just notify about device
> registration and trigger the power on procedure afterwards.
> 
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
>  net/bluetooth/hci_core.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Acked-by: Johan Hedberg <johan.hedberg@intel.com>

Johan

^ permalink raw reply

* [PATCH v4 16/16] sbc: Update copyrights
From: Frédéric Dalleau @ 2012-10-30  9:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1351589975-22640-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 cd3fd8c..e00b256 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 b189320..0947cf5 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 ffee339..5c4c0af 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 21d7b74..02f23d9 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 01426b8..676b949 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 v4 15/16] sbc: Update sbcinfo for msbc
From: Frédéric Dalleau @ 2012-10-30  9:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1351589975-22640-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..01426b8 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\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 v4 14/16] sbc: Update sbcenc for msbc
From: Frédéric Dalleau @ 2012-10-30  9:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1351589975-22640-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 v4 13/16] sbc: Update sbcdec for msbc
From: Frédéric Dalleau @ 2012-10-30  9:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1351589975-22640-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 v4 12/16] sbc: Add support for mSBC frame header
From: Frédéric Dalleau @ 2012-10-30  9:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1351589975-22640-1-git-send-email-frederic.dalleau@linux.intel.com>

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

diff --git a/sbc/sbc.c b/sbc/sbc.c
index 22fa898..cd3fd8c 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,90 @@ 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 -2;
+	if (data[2] != 0)
+		return -2;
+
+	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)
 {
@@ -790,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];
@@ -889,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(
@@ -897,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);
@@ -906,6 +928,16 @@ 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(unsigned long flags,
 		struct sbc_encoder_state *state, const struct sbc_frame *frame)
 {
@@ -921,10 +953,24 @@ 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 (*unpack_frame)(const uint8_t *data, struct sbc_frame *frame,
+			size_t len);
+	ssize_t (*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->pack_frame = msbc_pack_frame;
+		priv->unpack_frame = msbc_unpack_frame;
+	} else {
+		priv->pack_frame = sbc_pack_frame;
+		priv->unpack_frame = sbc_unpack_frame;
+	}
+
 	sbc->flags = flags;
 	sbc->frequency = SBC_FREQ_44100;
 	sbc->mode = SBC_MODE_STEREO;
@@ -978,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->unpack_frame(input, &priv->frame, input_len);
 
 	if (!priv->init) {
 		sbc_decoder_init(&priv->dec_state, &priv->frame);
@@ -1110,13 +1156,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->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->pack_frame(output,
+				&priv->frame, output_len, 0);
 	}
 
 	if (written)
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v4 11/16] sbc: Add SBC_MSBC flag to enable 15 block encoding
From: Frédéric Dalleau @ 2012-10-30  9:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1351589975-22640-1-git-send-email-frederic.dalleau@linux.intel.com>

---
 sbc/sbc.c |   23 +++++++++++++++--------
 sbc/sbc.h |    3 +++
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/sbc/sbc.c b/sbc/sbc.c
index ffdf05d..22fa898 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 {
@@ -903,12 +906,12 @@ 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,
-					const struct sbc_frame *frame)
+static void sbc_encoder_init(unsigned long flags,
+		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->increment = 4;
+	state->increment = flags & SBC_MSBC ? 1 : 4;
 
 	sbc_init_primitives(state);
 }
@@ -922,6 +925,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;
@@ -1057,12 +1061,13 @@ SBC_EXPORT ssize_t sbc_encode(sbc_t *sbc, const void *input, size_t input_len,
 		priv->frame.subband_mode = sbc->subbands;
 		priv->frame.subbands = sbc->subbands ? 8 : 4;
 		priv->frame.block_mode = sbc->blocks;
-		priv->frame.blocks = 4 + (sbc->blocks * 4);
+		priv->frame.blocks = sbc->flags & SBC_MSBC ?
+					MSBC_BLOCKS : 4 + (sbc->blocks * 4);
 		priv->frame.bitpool = sbc->bitpool;
 		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, &priv->enc_state, &priv->frame);
 		priv->init = 1;
 	} else if (priv->frame.bitpool != sbc->bitpool) {
 		priv->frame.length = sbc_get_frame_length(sbc);
@@ -1141,7 +1146,7 @@ SBC_EXPORT size_t sbc_get_frame_length(sbc_t *sbc)
 		return priv->frame.length;
 
 	subbands = sbc->subbands ? 8 : 4;
-	blocks = 4 + (sbc->blocks * 4);
+	blocks = sbc->flags & SBC_MSBC ? MSBC_BLOCKS : 4 + (sbc->blocks * 4);
 	channels = sbc->mode == SBC_MODE_MONO ? 1 : 2;
 	joint = sbc->mode == SBC_MODE_JOINT_STEREO ? 1 : 0;
 	bitpool = sbc->bitpool;
@@ -1165,7 +1170,8 @@ SBC_EXPORT unsigned sbc_get_frame_duration(sbc_t *sbc)
 	priv = sbc->priv;
 	if (!priv->init) {
 		subbands = sbc->subbands ? 8 : 4;
-		blocks = 4 + (sbc->blocks * 4);
+		blocks = sbc->flags & SBC_MSBC ?
+					MSBC_BLOCKS : 4 + (sbc->blocks * 4);
 	} else {
 		subbands = priv->frame.subbands;
 		blocks = priv->frame.blocks;
@@ -1202,7 +1208,8 @@ SBC_EXPORT size_t sbc_get_codesize(sbc_t *sbc)
 	priv = sbc->priv;
 	if (!priv->init) {
 		subbands = sbc->subbands ? 8 : 4;
-		blocks = 4 + (sbc->blocks * 4);
+		blocks = sbc->flags & SBC_MSBC ?
+					MSBC_BLOCKS : 4 + (sbc->blocks * 4);
 		channels = sbc->mode == SBC_MODE_MONO ? 1 : 2;
 	} else {
 		subbands = priv->frame.subbands;
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 v4 10/16] sbc: simd support for 8 multiples block size
From: Frédéric Dalleau @ 2012-10-30  9:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1351589975-22640-1-git-send-email-frederic.dalleau@linux.intel.com>

---
 sbc/sbc_primitives.c |   37 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/sbc/sbc_primitives.c b/sbc/sbc_primitives.c
index 9311848..b189320 100644
--- a/sbc/sbc_primitives.c
+++ b/sbc/sbc_primitives.c
@@ -309,8 +309,26 @@ 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 (position % 16 == 8) {
+		position -= 8;
+		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);
+		}
+		/* mSBC is designed for 1 channel */
+		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];
@@ -351,6 +369,23 @@ 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 -= 8;
+		if (nchannels > 0) {
+			int16_t *x = &X[0][position];
+			x[-7] = PCM(0 + 7 * nchannels);
+			x[1]  = PCM(0 + 3 * nchannels);
+			x[2]  = PCM(0 + 6 * nchannels);
+			x[3]  = PCM(0 + 0 * nchannels);
+			x[4]  = PCM(0 + 5 * nchannels);
+			x[5]  = PCM(0 + 1 * nchannels);
+			x[6]  = PCM(0 + 4 * nchannels);
+			x[7]  = PCM(0 + 2 * nchannels);
+		}
+		/* mSBC is designed for 1 channel */
 	}
 	#undef PCM
 
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v4 09/16] sbc: Use simd primitive if doing msbc on neon
From: Frédéric Dalleau @ 2012-10-30  9:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1351589975-22640-1-git-send-email-frederic.dalleau@linux.intel.com>

---
 sbc/sbc_primitives.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/sbc/sbc_primitives.c b/sbc/sbc_primitives.c
index a4767ef..9311848 100644
--- a/sbc/sbc_primitives.c
+++ b/sbc/sbc_primitives.c
@@ -568,5 +568,8 @@ void sbc_init_primitives(struct sbc_encoder_state *state)
 #endif
 #ifdef SBC_BUILD_WITH_NEON_SUPPORT
 	sbc_init_primitives_neon(state);
+
+	if (state->increment == 1)
+		state->sbc_analyze_8s = sbc_analyze_1b_8s_simd;
 #endif
 }
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v4 08/16] sbc: Add simd primitive for 1b 8s analysis
From: Frédéric Dalleau @ 2012-10-30  9:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1351589975-22640-1-git-send-email-frederic.dalleau@linux.intel.com>

---
 sbc/sbc_primitives.c |   18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/sbc/sbc_primitives.c b/sbc/sbc_primitives.c
index 0b48ddb..a4767ef 100644
--- a/sbc/sbc_primitives.c
+++ b/sbc/sbc_primitives.c
@@ -209,6 +209,19 @@ 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]);
@@ -525,7 +538,10 @@ void sbc_init_primitives(struct sbc_encoder_state *state)
 
 	/* Default implementation for analyze functions */
 	state->sbc_analyze_4s = sbc_analyze_4b_4s_simd;
-	state->sbc_analyze_8s = sbc_analyze_4b_8s_simd;
+	if (state->increment == 1)
+		state->sbc_analyze_8s = sbc_analyze_1b_8s_simd;
+	else
+		state->sbc_analyze_8s = sbc_analyze_4b_8s_simd;
 
 	/* Default implementation for input reordering / deinterleaving */
 	state->sbc_enc_process_input_4s_le = sbc_enc_process_input_4s_le;
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v4 07/16] sbc: Add iwmmxt primitive for 1b 8s encoding
From: Frédéric Dalleau @ 2012-10-30  9:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1351589975-22640-1-git-send-email-frederic.dalleau@linux.intel.com>

---
 sbc/sbc_primitives_iwmmxt.c |   18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/sbc/sbc_primitives_iwmmxt.c b/sbc/sbc_primitives_iwmmxt.c
index 0c8f329..44bfd47 100644
--- a/sbc/sbc_primitives_iwmmxt.c
+++ b/sbc/sbc_primitives_iwmmxt.c
@@ -294,10 +294,26 @@ static inline void sbc_analyze_4b_8s_iwmmxt(struct sbc_encoder_state *state,
 	sbc_analyze_eight_iwmmxt(x + 0, out, analysis_consts_fixed8_simd_even);
 }
 
+static inline void sbc_analyze_1b_8s_iwmmxt(struct sbc_encoder_state *state,
+		int16_t *x, int32_t *out, int out_stride)
+{
+	if (state->odd)
+		sbc_analyze_eight_iwmmxt(x, out,
+					analysis_consts_fixed8_simd_odd);
+	else
+		sbc_analyze_eight_iwmmxt(x, out,
+					analysis_consts_fixed8_simd_even);
+
+	state->odd = !state->odd;
+}
+
 void sbc_init_primitives_iwmmxt(struct sbc_encoder_state *state)
 {
 	state->sbc_analyze_4s = sbc_analyze_4b_4s_iwmmxt;
-	state->sbc_analyze_8s = sbc_analyze_4b_8s_iwmmxt;
+	if (state->increment == 1)
+		state->sbc_analyze_8s = sbc_analyze_1b_8s_iwmmxt;
+	else
+		state->sbc_analyze_8s = sbc_analyze_4b_8s_iwmmxt;
 	state->implementation_info = "IWMMXT";
 }
 
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v4 06/16] sbc: Add armv6 primitive for 1b 8s analysis
From: Frédéric Dalleau @ 2012-10-30  9:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1351589975-22640-1-git-send-email-frederic.dalleau@linux.intel.com>

---
 sbc/sbc_primitives_armv6.c |   18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/sbc/sbc_primitives_armv6.c b/sbc/sbc_primitives_armv6.c
index 068648a..a2cb2a8 100644
--- a/sbc/sbc_primitives_armv6.c
+++ b/sbc/sbc_primitives_armv6.c
@@ -291,10 +291,26 @@ static void sbc_analyze_4b_8s_armv6(struct sbc_encoder_state *state,
 	sbc_analyze_eight(x + 0, out, analysis_consts_fixed8_simd_even);
 }
 
+static void sbc_analyze_1b_8s_armv6(struct sbc_encoder_state *state,
+		int16_t *x, int32_t *out, int out_stride)
+{
+	if (state->odd)
+		sbc_analyze_eight_armv6(x, out,
+					analysis_consts_fixed8_simd_odd);
+	else
+		sbc_analyze_eight_armv6(x, out,
+					analysis_consts_fixed8_simd_even);
+
+	state->odd = !state->odd;
+}
+
 void sbc_init_primitives_armv6(struct sbc_encoder_state *state)
 {
 	state->sbc_analyze_4s = sbc_analyze_4b_4s_armv6;
-	state->sbc_analyze_8s = sbc_analyze_4b_8s_armv6;
+	if (state->increment == 1)
+		state->sbc_analyze_8s = sbc_analyze_1b_8s_armv6;
+	else
+		state->sbc_analyze_8s = sbc_analyze_4b_8s_armv6;
 	state->implementation_info = "ARMv6 SIMD";
 }
 
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v4 05/16] sbc: Add mmx primitive for 1b 8s analysis
From: Frédéric Dalleau @ 2012-10-30  9:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1351589975-22640-1-git-send-email-frederic.dalleau@linux.intel.com>

---
 sbc/sbc_primitives_mmx.c |   18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/sbc/sbc_primitives_mmx.c b/sbc/sbc_primitives_mmx.c
index 03070f5..21d7b74 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],
@@ -366,7 +379,10 @@ void sbc_init_primitives_mmx(struct sbc_encoder_state *state)
 {
 	if (check_mmx_support()) {
 		state->sbc_analyze_4s = sbc_analyze_4b_4s_mmx;
-		state->sbc_analyze_8s = sbc_analyze_4b_8s_mmx;
+		if (state->increment == 1)
+			state->sbc_analyze_8s = sbc_analyze_1b_8s_mmx;
+		else
+			state->sbc_analyze_8s = sbc_analyze_4b_8s_mmx;
 		state->sbc_calc_scalefactors = sbc_calc_scalefactors_mmx;
 		state->implementation_info = "MMX";
 	}
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v4 04/16] sbc: add odd member variable to sbc_encoder_state
From: Frédéric Dalleau @ 2012-10-30  9:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1351589975-22640-1-git-send-email-frederic.dalleau@linux.intel.com>

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

diff --git a/sbc/sbc_primitives.c b/sbc/sbc_primitives.c
index dce0ed2..0b48ddb 100644
--- a/sbc/sbc_primitives.c
+++ b/sbc/sbc_primitives.c
@@ -521,6 +521,8 @@ static int sbc_calc_scalefactors_j(
  */
 void sbc_init_primitives(struct sbc_encoder_state *state)
 {
+	state->odd = 1;
+
 	/* Default implementation for analyze functions */
 	state->sbc_analyze_4s = sbc_analyze_4b_4s_simd;
 	state->sbc_analyze_8s = sbc_analyze_4b_8s_simd;
diff --git a/sbc/sbc_primitives.h b/sbc/sbc_primitives.h
index 267c277..ffee339 100644
--- a/sbc/sbc_primitives.h
+++ b/sbc/sbc_primitives.h
@@ -40,6 +40,7 @@ struct sbc_encoder_state {
 	int position;
 	/* Number of consecutive blocks handled by the encoder */
 	int increment;
+	int odd;
 	int16_t SBC_ALIGNED X[2][SBC_X_BUFFER_SIZE];
 	/* Polyphase analysis filter for 4 subbands configuration,
 	 * it handles "increment" blocks at once */
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v4 03/16] sbc: Rename sbc_analyze_4b_xx to sbc_analyze_xx
From: Frédéric Dalleau @ 2012-10-30  9:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1351589975-22640-1-git-send-email-frederic.dalleau@linux.intel.com>

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

diff --git a/sbc/sbc.c b/sbc/sbc.c
index 4a7dd2e..ffdf05d 100644
--- a/sbc/sbc.c
+++ b/sbc/sbc.c
@@ -692,7 +692,7 @@ static int sbc_analyze_audio(struct sbc_encoder_state *state,
 					state->increment + frame->blocks * 4];
 			for (blk = 0; blk < frame->blocks;
 						blk += state->increment) {
-				state->sbc_analyze_4b_4s(
+				state->sbc_analyze_4s(
 					state, x,
 					frame->sb_sample_f[blk][ch],
 					frame->sb_sample_f[blk + 1][ch] -
@@ -708,7 +708,7 @@ static int sbc_analyze_audio(struct sbc_encoder_state *state,
 					state->increment + frame->blocks * 8];
 			for (blk = 0; blk < frame->blocks;
 						blk += state->increment) {
-				state->sbc_analyze_4b_8s(
+				state->sbc_analyze_8s(
 					state, x,
 					frame->sb_sample_f[blk][ch],
 					frame->sb_sample_f[blk + 1][ch] -
diff --git a/sbc/sbc_primitives.c b/sbc/sbc_primitives.c
index f8cc4b6..dce0ed2 100644
--- a/sbc/sbc_primitives.c
+++ b/sbc/sbc_primitives.c
@@ -522,8 +522,8 @@ static int sbc_calc_scalefactors_j(
 void sbc_init_primitives(struct sbc_encoder_state *state)
 {
 	/* 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;
+	state->sbc_analyze_4s = sbc_analyze_4b_4s_simd;
+	state->sbc_analyze_8s = sbc_analyze_4b_8s_simd;
 
 	/* Default implementation for input reordering / deinterleaving */
 	state->sbc_enc_process_input_4s_le = sbc_enc_process_input_4s_le;
diff --git a/sbc/sbc_primitives.h b/sbc/sbc_primitives.h
index 2a7d4a1..267c277 100644
--- a/sbc/sbc_primitives.h
+++ b/sbc/sbc_primitives.h
@@ -43,11 +43,11 @@ struct sbc_encoder_state {
 	int16_t SBC_ALIGNED X[2][SBC_X_BUFFER_SIZE];
 	/* Polyphase analysis filter for 4 subbands configuration,
 	 * it handles "increment" blocks at once */
-	void (*sbc_analyze_4b_4s)(struct sbc_encoder_state *state,
+	void (*sbc_analyze_4s)(struct sbc_encoder_state *state,
 			int16_t *x, int32_t *out, int out_stride);
 	/* Polyphase analysis filter for 8 subbands configuration,
 	 * it handles "increment" blocks at once */
-	void (*sbc_analyze_4b_8s)(struct sbc_encoder_state *state,
+	void (*sbc_analyze_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 */
diff --git a/sbc/sbc_primitives_armv6.c b/sbc/sbc_primitives_armv6.c
index 6ad94c6..068648a 100644
--- a/sbc/sbc_primitives_armv6.c
+++ b/sbc/sbc_primitives_armv6.c
@@ -293,8 +293,8 @@ static void sbc_analyze_4b_8s_armv6(struct sbc_encoder_state *state,
 
 void sbc_init_primitives_armv6(struct sbc_encoder_state *state)
 {
-	state->sbc_analyze_4b_4s = sbc_analyze_4b_4s_armv6;
-	state->sbc_analyze_4b_8s = sbc_analyze_4b_8s_armv6;
+	state->sbc_analyze_4s = sbc_analyze_4b_4s_armv6;
+	state->sbc_analyze_8s = sbc_analyze_4b_8s_armv6;
 	state->implementation_info = "ARMv6 SIMD";
 }
 
diff --git a/sbc/sbc_primitives_iwmmxt.c b/sbc/sbc_primitives_iwmmxt.c
index 39cc390..0c8f329 100644
--- a/sbc/sbc_primitives_iwmmxt.c
+++ b/sbc/sbc_primitives_iwmmxt.c
@@ -296,8 +296,8 @@ static inline void sbc_analyze_4b_8s_iwmmxt(struct sbc_encoder_state *state,
 
 void sbc_init_primitives_iwmmxt(struct sbc_encoder_state *state)
 {
-	state->sbc_analyze_4b_4s = sbc_analyze_4b_4s_iwmmxt;
-	state->sbc_analyze_4b_8s = sbc_analyze_4b_8s_iwmmxt;
+	state->sbc_analyze_4s = sbc_analyze_4b_4s_iwmmxt;
+	state->sbc_analyze_8s = sbc_analyze_4b_8s_iwmmxt;
 	state->implementation_info = "IWMMXT";
 }
 
diff --git a/sbc/sbc_primitives_mmx.c b/sbc/sbc_primitives_mmx.c
index cbacb4e..03070f5 100644
--- a/sbc/sbc_primitives_mmx.c
+++ b/sbc/sbc_primitives_mmx.c
@@ -365,8 +365,8 @@ static int check_mmx_support(void)
 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;
+		state->sbc_analyze_4s = sbc_analyze_4b_4s_mmx;
+		state->sbc_analyze_8s = sbc_analyze_4b_8s_mmx;
 		state->sbc_calc_scalefactors = sbc_calc_scalefactors_mmx;
 		state->implementation_info = "MMX";
 	}
diff --git a/sbc/sbc_primitives_neon.c b/sbc/sbc_primitives_neon.c
index aeca8df..eda4ed3 100644
--- a/sbc/sbc_primitives_neon.c
+++ b/sbc/sbc_primitives_neon.c
@@ -879,8 +879,8 @@ static int sbc_enc_process_input_8s_le_neon(int position, const uint8_t *pcm,
 
 void sbc_init_primitives_neon(struct sbc_encoder_state *state)
 {
-	state->sbc_analyze_4b_4s = sbc_analyze_4b_4s_neon;
-	state->sbc_analyze_4b_8s = sbc_analyze_4b_8s_neon;
+	state->sbc_analyze_4s = sbc_analyze_4b_4s_neon;
+	state->sbc_analyze_8s = sbc_analyze_4b_8s_neon;
 	state->sbc_calc_scalefactors = sbc_calc_scalefactors_neon;
 	state->sbc_calc_scalefactors_j = sbc_calc_scalefactors_j_neon;
 	state->sbc_enc_process_input_4s_le = sbc_enc_process_input_4s_le_neon;
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v4 02/16] sbc: Break 4 blocks processing to variable steps
From: Frédéric Dalleau @ 2012-10-30  9:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1351589975-22640-1-git-send-email-frederic.dalleau@linux.intel.com>

Until now SBC processed 4 blocks at a time. If we want to process 15 blocks,
then we need to break this processing in one block steps. 4 blocks is still
default increment.
---
 sbc/sbc.c            |   19 +++++++++++--------
 sbc/sbc_primitives.h |    6 ++++--
 2 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/sbc/sbc.c b/sbc/sbc.c
index e51ed57..4a7dd2e 100644
--- a/sbc/sbc.c
+++ b/sbc/sbc.c
@@ -688,30 +688,32 @@ 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 +
-							frame->blocks * 4];
-			for (blk = 0; blk < frame->blocks; blk += 4) {
+			x = &state->X[ch][state->position - 4 *
+					state->increment + frame->blocks * 4];
+			for (blk = 0; blk < frame->blocks;
+						blk += state->increment) {
 				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->increment;
 			}
 		}
 		return frame->blocks * 4;
 
 	case 8:
 		for (ch = 0; ch < frame->channels; ch++) {
-			x = &state->X[ch][state->position - 32 +
-							frame->blocks * 8];
-			for (blk = 0; blk < frame->blocks; blk += 4) {
+			x = &state->X[ch][state->position - 8 *
+					state->increment + frame->blocks * 8];
+			for (blk = 0; blk < frame->blocks;
+						blk += state->increment) {
 				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->increment;
 			}
 		}
 		return frame->blocks * 8;
@@ -906,6 +908,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->increment = 4;
 
 	sbc_init_primitives(state);
 }
diff --git a/sbc/sbc_primitives.h b/sbc/sbc_primitives.h
index a7bbef1..2a7d4a1 100644
--- a/sbc/sbc_primitives.h
+++ b/sbc/sbc_primitives.h
@@ -38,13 +38,15 @@
 
 struct sbc_encoder_state {
 	int position;
+	/* Number of consecutive blocks handled by the encoder */
+	int increment;
 	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 "increment" 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 "increment" 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 v4 01/16] sbc: Add encoder_state to analysis functions
From: Frédéric Dalleau @ 2012-10-30  9:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1351589975-22640-1-git-send-email-frederic.dalleau@linux.intel.com>

Until now, SIMD analysis used to process 4 blocks of 8 samples at a time. This
was implemented using two constant tables: odd and even. This mean we can only
process 4, 8, 12, or 16 blocks par SBC packets.
mSBC requires 15 blocks, so to be able to analyse 1 block, it will be necessary
to know if we are processing an odd or even block. This will be done with a
new member to encoder_state.
---
 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 f0c77c7..e51ed57 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 ad780d0..f8cc4b6 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 17ad4f7..a7bbef1 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)(int position,
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 5d4d0e3..aeca8df 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 v4 00/16] mSBC tests
From: Frédéric Dalleau @ 2012-10-30  9:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Frédéric Dalleau

Hi,

v4 integrate latest comments from Siarhei:
 - remove state->pending field from sbc_encoder_state
 - add armv6 and iwmmxt primitives
 - use simd primitive instead of neon
 - reorder patches so that the SBC_MSBC flag is exposed to users only when
implementation is complete.

I could only build armv6 code.

Regards,
Frederic


Frédéric Dalleau (16):
  sbc: Add encoder_state to analysis functions
  sbc: Break 4 blocks processing to variable steps
  sbc: Rename sbc_analyze_4b_xx to sbc_analyze_xx
  sbc: add odd member variable to sbc_encoder_state
  sbc: Add mmx primitive for 1b 8s analysis
  sbc: Add armv6 primitive for 1b 8s analysis
  sbc: Add iwmmxt primitive for 1b 8s encoding
  sbc: Add simd primitive for 1b 8s analysis
  sbc: Use simd primitive if doing msbc on neon
  sbc: simd support for 8 multiples block size
  sbc: Add SBC_MSBC flag to enable 15 block encoding
  sbc: Add support for mSBC frame header
  sbc: Update sbcdec for msbc
  sbc: Update sbcenc for msbc
  sbc: Update sbcinfo for msbc
  sbc: Update copyrights

 sbc/sbc.c                   |  277 ++++++++++++++++++++++++++-----------------
 sbc/sbc.h                   |    3 +
 sbc/sbc_primitives.c        |   71 +++++++++--
 sbc/sbc_primitives.h        |   14 ++-
 sbc/sbc_primitives_armv6.c  |   26 +++-
 sbc/sbc_primitives_iwmmxt.c |   28 ++++-
 sbc/sbc_primitives_mmx.c    |   29 ++++-
 sbc/sbc_primitives_neon.c   |   12 +-
 src/sbcdec.c                |   18 ++-
 src/sbcenc.c                |   26 +++-
 src/sbcinfo.c               |   52 +++++---
 11 files changed, 389 insertions(+), 167 deletions(-)

-- 
1.7.9.5


^ permalink raw reply

* Re: [RFC v2 obexd 04/11] fuse: Add request helpers and setpath operation
From: Luiz Augusto von Dentz @ 2012-10-30  9:35 UTC (permalink / raw)
  To: Michał Poczwardowski; +Cc: linux-bluetooth
In-Reply-To: <1351384166-15586-4-git-send-email-dmp0x7c5@gmail.com>

Hi Michal,

On Sun, Oct 28, 2012 at 2:29 AM, Michał Poczwardowski
<dmp0x7c5@gmail.com> wrote:
> ---
>  fuse/helpers.c |  108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 108 insertions(+), 0 deletions(-)
>
> diff --git a/fuse/helpers.c b/fuse/helpers.c
> index 856e1d5..1b8082f 100644
> --- a/fuse/helpers.c
> +++ b/fuse/helpers.c
> @@ -273,3 +273,111 @@ void gobexhlp_disconnect(struct gobexhlp_session* session)
>
>         g_free(session);
>  }
> +
> +void request_new(struct gobexhlp_session *session,
> +                                       gchar *name)
> +{
> +       g_print("REQUEST %s\n", name);
> +
> +       if (session->request != NULL)
> +               g_error("Another request (%s) active!\n",
> +                                       session->request->name);
> +
> +       session->status = 0;
> +       session->request = g_malloc0(sizeof(struct gobexhlp_request));
> +       session->request->name = name;
> +
> +       /*
> +        * suspend/resume operations recreates g_io_add_watch(),
> +        * it fixes obex->io freeze during transfer
> +        */
> +       g_obex_suspend(session->obex);
> +       g_obex_resume(session->obex);

It seems the issue here is that the mainloop is blocked then you have
to force the io checking by doing g_io_add_watch in a different
thread, we have dealt with this kind of problem before using
g_main_context_iteration. I would have been better if fuse supported
async io, but apparently all operations are blocking.

-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: [RFC v2 obexd 03/11] fuse: Add obexhlp_connect/disconnect functions with helpers
From: Luiz Augusto von Dentz @ 2012-10-30  9:08 UTC (permalink / raw)
  To: Michał Poczwardowski; +Cc: linux-bluetooth
In-Reply-To: <1351384166-15586-3-git-send-email-dmp0x7c5@gmail.com>

Hi Michal,

On Sun, Oct 28, 2012 at 2:29 AM, Michał Poczwardowski
<dmp0x7c5@gmail.com> wrote:
> ---
>  fuse/helpers.c  |  221 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  fuse/helpers.h  |    4 +
>  fuse/obexfuse.c |   40 ++++++++++
>  3 files changed, 265 insertions(+), 0 deletions(-)
>
> diff --git a/fuse/helpers.c b/fuse/helpers.c
> index c36072d..856e1d5 100644
> --- a/fuse/helpers.c
> +++ b/fuse/helpers.c
> @@ -43,6 +43,9 @@
>
>  #define OBEX_FTP_LS "x-obex/folder-listing"
>
> +static GCond *gobexhlp_cond;
> +static GMutex *gobexhlp_mutex;
> +
>  struct gobexhlp_request {
>         gchar *name;
>         gboolean complete;
> @@ -52,3 +55,221 @@ struct gobexhlp_location {
>         gchar *dir;
>         gchar *file;
>  };
> +
> +static uint16_t find_rfcomm_uuid(void *user_data)
> +{
> +       sdp_list_t *pds = (sdp_list_t*) user_data;
> +       uint16_t channel = 0;
> +
> +       for (;pds;pds = pds->next) {
> +               sdp_data_t *d = (sdp_data_t*)pds->data;
> +               int proto = 0;
> +               for (; d; d = d->next) {
> +                       switch(d->dtd) {
> +                       case SDP_UUID16:
> +                       case SDP_UUID32:
> +                       case SDP_UUID128:
> +                               proto = sdp_uuid_to_proto(&d->val.uuid);
> +                       break;
> +                       case SDP_UINT8:
> +                               if (proto == RFCOMM_UUID)
> +                                       channel = d->val.int8;
> +                               break;
> +                       }
> +               }
> +       }
> +       return channel;
> +}
> +
> +static uint16_t get_ftp_channel(bdaddr_t *src, bdaddr_t *dst)
> +{
> +       sdp_session_t *sdp;
> +       sdp_list_t *r, *search_list, *attrid_list;
> +       sdp_list_t *response_list = NULL;
> +       uuid_t uuid;
> +
> +       /* FTP_SDP_UUID "00001106-0000-1000-8000-00805f9b34fb" */
> +       uint8_t uuid_int[] = {0, 0, 0x11, 0x06, 0, 0, 0x10, 0, 0x80,
> +                                       0, 0, 0x80, 0x5f, 0x9b, 0x34, 0xfb};
> +       uint32_t range = 0x0000ffff;
> +       uint16_t channel = 0;
> +
> +       sdp = sdp_connect(src, dst, SDP_RETRY_IF_BUSY );
> +       if (sdp == NULL)
> +               return channel;
> +
> +       sdp_uuid128_create(&uuid, uuid_int);
> +       search_list = sdp_list_append(NULL, &uuid);
> +       attrid_list = sdp_list_append(NULL, &range);
> +       sdp_service_search_attr_req(sdp, search_list, SDP_ATTR_REQ_RANGE,
> +                                       attrid_list, &response_list);
> +       r = response_list;
> +
> +       for (; r;r = r->next) {
> +               sdp_record_t *rec = (sdp_record_t*) r->data;
> +               sdp_list_t *proto_list;
> +
> +               if (sdp_get_access_protos(rec, &proto_list ) == 0) {
> +                       sdp_list_t *p = proto_list;
> +                       for (; p; p = p->next) {
> +                               sdp_list_t *pds = (sdp_list_t*) p->data;
> +                               channel = find_rfcomm_uuid(pds);
> +                               sdp_list_free((sdp_list_t*) p->data, 0);

You dont really need to iterate in the list of protos there exist a
function that does that for you take a look at sdp_get_proto_port, btw
there exist a similar code in client/bluetooth.c

> +                       }
> +                       sdp_list_free(proto_list, 0);
> +               }
> +               sdp_record_free(rec);
> +       }
> +       sdp_close(sdp);
> +
> +       g_free(search_list);
> +       g_free(attrid_list);
> +       g_free(response_list);
> +
> +       return channel;
> +}
> +
> +/* taken from client/bluetooth.c - bluetooth_getpacketopt */
> +static int get_packet_opt(GIOChannel *io, int *tx_mtu, int *rx_mtu)
> +{
> +       int sk = g_io_channel_unix_get_fd(io);
> +       int type;
> +       int omtu = -1;
> +       int imtu = -1;
> +       socklen_t len = sizeof(int);
> +
> +       if (getsockopt(sk, SOL_SOCKET, SO_TYPE, &type, &len) < 0)
> +               return -errno;
> +
> +       if (type != SOCK_SEQPACKET)
> +               return -EINVAL;
> +
> +       if (!bt_io_get(io, BT_IO_L2CAP, NULL, BT_IO_OPT_OMTU, &omtu,
> +                                               BT_IO_OPT_IMTU, &imtu,
> +                                               BT_IO_OPT_INVALID))
> +               return -EINVAL;
> +
> +       if (tx_mtu)
> +               *tx_mtu = omtu;
> +
> +       if (rx_mtu)
> +               *rx_mtu = imtu;
> +
> +       return 0;
> +}
> +
> +static void obex_callback(GObex *obex, GError *err, GObexPacket *rsp,
> +                                                       gpointer user_data)
> +{
> +       if (err != NULL) {
> +               g_debug("Connect failed: %s\n", err->message);
> +               g_error_free(err);
> +       } else {
> +               g_debug("Connect succeeded\n");
> +       }
> +}
> +
> +static void bt_io_callback(GIOChannel *io, GError *err, gpointer user_data)
> +{
> +       struct gobexhlp_session *session = user_data;
> +       GObexTransportType type;
> +       int tx_mtu = -1;
> +       int rx_mtu = -1;
> +
> +       if (err != NULL) {
> +               g_printerr("%s\n", err->message);
> +               g_error_free(err);
> +               return;
> +       }
> +
> +       g_debug("Bluetooth socket connected\n");
> +
> +       g_io_channel_set_flags(session->io, G_IO_FLAG_NONBLOCK, NULL);
> +       g_io_channel_set_close_on_unref(session->io, TRUE);
> +
> +       if (get_packet_opt(session->io, &tx_mtu, &rx_mtu) == 0) {
> +               type = G_OBEX_TRANSPORT_PACKET;
> +               g_debug("PACKET transport tx:%d rx:%d\n", tx_mtu, rx_mtu);
> +       } else {
> +               type = G_OBEX_TRANSPORT_STREAM;
> +               g_debug("STREAM transport\n");
> +       }
> +
> +       session->obex = g_obex_new(io, type, tx_mtu, rx_mtu);
> +       g_obex_connect(session->obex, obex_callback, session, NULL,
> +                               G_OBEX_HDR_TARGET, OBEX_FTP_UUID,
> +                               OBEX_FTP_UUID_LEN, G_OBEX_HDR_INVALID);
> +}
> +
> +struct gobexhlp_session* gobexhlp_connect(const char *srcstr,
> +                                               const char *dststr)
> +{
> +       struct gobexhlp_session *session;
> +       uint16_t channel;
> +       bdaddr_t src, dst;
> +
> +       session = g_try_malloc0(sizeof(struct gobexhlp_session));
> +       if (session == NULL)
> +               return NULL;
> +
> +       if (srcstr == NULL)
> +               bacpy(&src, BDADDR_ANY);
> +       else
> +               str2ba(srcstr, &src);
> +
> +       str2ba(dststr, &dst);
> +       channel = get_ftp_channel(&src, &dst);
> +
> +       if (channel == 0)
> +               return NULL;

Currently you are not checking for L2CAP psm just RFCOMM channel so
the code bellow would never be used.

> +       if (channel > 31)
> +               session->io = bt_io_connect(BT_IO_L2CAP, bt_io_callback,
> +                               session, NULL, &session->err,
> +                               BT_IO_OPT_SOURCE_BDADDR, &src,
> +                               BT_IO_OPT_DEST_BDADDR, &dst,
> +                               BT_IO_OPT_PSM, channel,
> +                               BT_IO_OPT_MODE, BT_IO_MODE_ERTM,
> +                               BT_IO_OPT_OMTU, BT_TX_MTU,
> +                               BT_IO_OPT_IMTU, BT_RX_MTU,
> +                               BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
> +                               BT_IO_OPT_INVALID);
> +       else
> +               session->io = bt_io_connect(BT_IO_RFCOMM, bt_io_callback,
> +                               session, NULL, &session->err,
> +                               BT_IO_OPT_SOURCE_BDADDR, &src,
> +                               BT_IO_OPT_DEST_BDADDR, &dst,
> +                               BT_IO_OPT_CHANNEL, channel,
> +                               BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
> +                               BT_IO_OPT_INVALID);
> +
> +       if (session->err != NULL)
> +               return NULL;
> +
> +       session->file_stat = g_hash_table_new_full( g_str_hash, g_str_equal,
> +                                       g_free, g_free);
> +       session->setpath = g_strdup("/");
> +
> +       gobexhlp_mutex = g_mutex_new();
> +       gobexhlp_cond = g_cond_new();
> +
> +       return session;
> +}
> +
> +void gobexhlp_disconnect(struct gobexhlp_session* session)
> +{
> +       if (session == NULL)
> +               return;
> +
> +       g_obex_unref(session->obex);
> +       g_free(session->io);
> +
> +       g_hash_table_remove_all(session->file_stat);
> +       g_list_free_full(session->lsfiles, g_free);
> +       g_free(session->setpath);
> +
> +       g_mutex_free(gobexhlp_mutex);
> +       g_cond_free(gobexhlp_cond);
> +
> +       g_free(session);
> +}
> diff --git a/fuse/helpers.h b/fuse/helpers.h
> index 142403f..29dc6cf 100644
> --- a/fuse/helpers.h
> +++ b/fuse/helpers.h
> @@ -46,3 +46,7 @@ struct gobexhlp_session {
>         int status;
>         GError *err;
>  };
> +
> +struct gobexhlp_session* gobexhlp_connect(const char *srcstr,
> +                                               const char *dstsrc);
> +void gobexhlp_disconnect(struct gobexhlp_session* session);
> diff --git a/fuse/obexfuse.c b/fuse/obexfuse.c
> index fe4f4da..79eb990 100644
> --- a/fuse/obexfuse.c
> +++ b/fuse/obexfuse.c
> @@ -33,6 +33,10 @@
>
>  #include "helpers.h"
>
> +struct gobexhlp_session* session = NULL;
> +static GMainLoop *main_loop;
> +static GThread *main_gthread;
> +
>  struct options {
>         char* dststr;
>         char* srcstr;
> @@ -60,7 +64,34 @@ static struct fuse_opt obexfuse_opts[] =
>         FUSE_OPT_END
>  };
>
> +gpointer main_loop_func(gpointer user_data)
> +{
> +       main_loop = g_main_loop_new(NULL, FALSE);
> +       g_main_loop_run(main_loop);
> +
> +       return 0;
> +}
> +
> +void* obexfuse_init(struct fuse_conn_info *conn)
> +{
> +       main_gthread = g_thread_create(main_loop_func, NULL, TRUE, NULL);
> +
> +       conn->async_read = 0;
> +       conn->want &= ~FUSE_CAP_ASYNC_READ;
> +
> +       return 0;
> +}
> +
> +void obexfuse_destroy()
> +{
> +       gobexhlp_disconnect(session);
> +       g_main_loop_quit(main_loop);
> +       g_thread_join(main_gthread);
> +}
> +
>  static struct fuse_operations obexfuse_oper = {
> +       .init = obexfuse_init,
> +       .destroy = obexfuse_destroy,
>  };
>
>  static int obexfuse_opt_proc(void *data, const char *arg, int key,
> @@ -111,6 +142,15 @@ int main(int argc, char *argv[])
>
>         g_thread_init(NULL);
>

I would suggest not mixing gobex prefix with your helper functions, in
fact it is probably fine to just use obexfuse e.g. obexfuse_connect.

> +       session = gobexhlp_connect(options.srcstr, options.dststr);
> +       if (session == NULL || session->io == NULL) {
> +               g_printerr("Connection to %s failed\n", options.dststr);
> +               gobexhlp_disconnect(session);
> +               return -EHOSTUNREACH;
> +       } else {
> +               g_print("Connected\nMounting %s\n", options.dststr);
> +       }
> +
>         fuse_opt_add_arg(&args, "-s"); /* force single threaded mode */
>         retfuse = fuse_main(args.argc, args.argv, &obexfuse_oper, NULL);
>
> --
> 1.7.8.6
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: [PATCH BlueZ 3/7] player: Add support for SetProperty
From: Luiz Augusto von Dentz @ 2012-10-30  8:49 UTC (permalink / raw)
  To: Lucas De Marchi; +Cc: linux-bluetooth
In-Reply-To: <CAMOw1v4xDW3fRjjb=i=nOhc3oYuv_A4M7pctdFvpC7rPHHgyiA@mail.gmail.com>

Hi Lucas,

On Mon, Oct 29, 2012 at 4:41 PM, Lucas De Marchi
<lucas.demarchi@profusion.mobi> wrote:
> On Mon, Oct 29, 2012 at 12:41 PM, Luiz Augusto von Dentz
> <luiz.dentz@gmail.com> wrote:
>> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>>
>> Properties Equalizer, Repeat, Shuffle and Scan can be set by user
>> application.
>> ---
>>  audio/avrcp.c  | 129 ++++++++++++++++++++++++++++++++++++++++++++++-
>>  audio/player.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
>>  audio/player.h |   9 ++++
>>  3 files changed, 288 insertions(+), 4 deletions(-)
>>
>> diff --git a/audio/avrcp.c b/audio/avrcp.c
>> index 7c26491..724e139 100644
>> --- a/audio/avrcp.c
>> +++ b/audio/avrcp.c
>> @@ -449,6 +449,60 @@ static const char *attr_to_str(uint8_t attr)
>>         return NULL;
>>  }
>>
>> +static int attrval_to_val(uint8_t attr, const char *value)
>> +{
>> +       int ret;
>> +
>> +       switch (attr) {
>> +       case AVRCP_ATTRIBUTE_EQUALIZER:
>> +               if (!strcmp(value, "off"))
>> +                       ret = AVRCP_EQUALIZER_OFF;
>> +               else if (!strcmp(value, "on"))
>> +                       ret = AVRCP_EQUALIZER_ON;
>> +               else
>> +                       ret = -EINVAL;
>> +
>> +               return ret;
>> +       case AVRCP_ATTRIBUTE_REPEAT_MODE:
>> +               if (!strcmp(value, "off"))
>> +                       ret = AVRCP_REPEAT_MODE_OFF;
>> +               else if (!strcmp(value, "singletrack"))
>> +                       ret = AVRCP_REPEAT_MODE_SINGLE;
>> +               else if (!strcmp(value, "alltracks"))
>> +                       ret = AVRCP_REPEAT_MODE_ALL;
>> +               else if (!strcmp(value, "group"))
>> +                       ret = AVRCP_REPEAT_MODE_GROUP;
>> +               else
>> +                       ret = -EINVAL;
>> +
>> +               return ret;
>> +       case AVRCP_ATTRIBUTE_SHUFFLE:
>> +               if (!strcmp(value, "off"))
>> +                       ret = AVRCP_SHUFFLE_OFF;
>> +               else if (!strcmp(value, "alltracks"))
>> +                       ret = AVRCP_SHUFFLE_ALL;
>> +               else if (!strcmp(value, "group"))
>> +                       ret = AVRCP_SHUFFLE_GROUP;
>> +               else
>> +                       ret = -EINVAL;
>> +
>> +               return ret;
>> +       case AVRCP_ATTRIBUTE_SCAN:
>> +               if (!strcmp(value, "off"))
>> +                       ret = AVRCP_SCAN_OFF;
>> +               else if (!strcmp(value, "alltracks"))
>> +                       ret = AVRCP_SCAN_ALL;
>> +               else if (!strcmp(value, "group"))
>> +                       ret = AVRCP_SCAN_GROUP;
>> +               else
>> +                       ret = -EINVAL;
>> +
>> +               return ret;
>> +       }
>> +
>> +       return -EINVAL;
>> +}
>> +
>>  static int attr_to_val(const char *str)
>>  {
>>         if (!strcasecmp(str, "Equalizer"))
>> @@ -1528,6 +1582,22 @@ static void avrcp_get_play_status(struct avrcp *session)
>>                                         session);
>>  }
>>
>> +static const char *status_to_str(uint8_t status)
>> +{
>> +       switch (status) {
>> +       case AVRCP_STATUS_INVALID_COMMAND:
>> +               return "Invalid Command";
>> +       case AVRCP_STATUS_INVALID_PARAM:
>> +               return "Invalid Parameter";
>> +       case AVRCP_STATUS_INTERNAL_ERROR:
>> +               return "Internal Error";
>> +       case AVRCP_STATUS_SUCCESS:
>> +               return "Success";
>> +       default:
>> +               return "Unknown";
>> +       }
>> +}
>> +
>>  static gboolean avrcp_player_value_rsp(struct avctp *conn,
>>                                         uint8_t code, uint8_t subunit,
>>                                         uint8_t *operands, size_t operand_count,
>> @@ -1540,8 +1610,11 @@ static gboolean avrcp_player_value_rsp(struct avctp *conn,
>>         uint8_t count;
>>         int i;
>>
>> -       if (code == AVC_CTYPE_REJECTED)
>> +       if (code == AVC_CTYPE_REJECTED) {
>> +               media_player_set_setting(mp, "Error",
>> +                                       status_to_str(pdu->params[0]));
>>                 return FALSE;
>> +       }
>>
>>         count = pdu->params[0];
>>
>> @@ -1811,6 +1884,59 @@ static void avrcp_register_notification(struct avrcp *session, uint8_t event)
>>                                         avrcp_handle_event, session);
>>  }
>>
>> +static void avrcp_set_player_value(struct avrcp *session, uint8_t attr,
>> +                                                               uint8_t val)
>> +{
>> +       uint8_t buf[AVRCP_HEADER_LENGTH + 3];
>> +       struct avrcp_header *pdu = (void *) buf;
>> +       uint8_t length;
>> +
>> +       memset(buf, 0, sizeof(buf));
>> +
>> +       set_company_id(pdu->company_id, IEEEID_BTSIG);
>> +       pdu->pdu_id = AVRCP_SET_PLAYER_VALUE;
>> +       pdu->packet_type = AVRCP_PACKET_TYPE_SINGLE;
>> +       pdu->params[0] = 1;
>> +       pdu->params[1] = attr;
>> +       pdu->params[2] = val;
>> +       pdu->params_len = htons(3);
>> +
>> +       length = AVRCP_HEADER_LENGTH + ntohs(pdu->params_len);
>> +
>> +       avctp_send_vendordep_req(session->conn, AVC_CTYPE_NOTIFY,
>> +                                       AVC_SUBUNIT_PANEL, buf, length,
>> +                                       avrcp_player_value_rsp, session);
>> +}
>> +
>> +static bool ct_set_setting(struct media_player *mp, const char *key,
>> +                                       const char *value, void *user_data)
>> +{
>> +       struct avrcp_player *player = user_data;
>> +       int attr = attr_to_val(key);
>> +       int val = attrval_to_val(attr, value);
>> +       struct avrcp *session;
>> +
>> +       session = player->sessions->data;
>> +       if (session == NULL)
>> +               return false;
>> +
>> +       attr = attr_to_val(key);
>> +       if (attr < 0)
>> +               return false;
>> +
>> +       val = attrval_to_val(attr, value);
>> +       if (val < 0)
>> +               return false;
>> +
>> +       avrcp_set_player_value(session, attr, val);
>> +
>> +       return true;
>> +}
>> +
>> +static const struct media_player_callback ct_cbs = {
>> +       .set_setting = ct_set_setting,
>> +};
>> +
>>  static gboolean avrcp_get_capabilities_resp(struct avctp *conn,
>>                                         uint8_t code, uint8_t subunit,
>>                                         uint8_t *operands, size_t operand_count,
>> @@ -1845,6 +1971,7 @@ static gboolean avrcp_get_capabilities_resp(struct avctp *conn,
>>
>>         path = device_get_path(session->dev->btd_dev);
>>         mp = media_player_controller_create(path);
>> +       media_player_set_callbacks(mp, &ct_cbs, player);
>>         player->user_data = mp;
>>         player->destroy = (GDestroyNotify) media_player_destroy;
>>
>> diff --git a/audio/player.c b/audio/player.c
>> index 1957594..e83b761 100644
>> --- a/audio/player.c
>> +++ b/audio/player.c
>> @@ -49,6 +49,12 @@ struct player_callback {
>>         void *user_data;
>>  };
>>
>> +struct pending_req {
>> +       DBusMessage *msg;
>> +       const char *key;
>> +       const char *value;
>> +};
>> +
>>  struct media_player {
>>         char                    *path;          /* Player object path */
>>         GHashTable              *settings;      /* Player settings */
>> @@ -58,6 +64,7 @@ struct media_player {
>>         GTimer                  *progress;
>>         guint                   process_id;
>>         struct player_callback  *cb;
>> +       GSList                  *pending;
>>  };
>>
>>  static void append_settings(void *key, void *value, void *user_data)
>> @@ -142,10 +149,96 @@ static DBusMessage *media_player_get_track(DBusConnection *conn,
>>         return reply;
>>  }
>>
>> +static struct pending_req *find_pending(struct media_player *mp,
>> +                                                       const char *key)
>> +{
>> +       GSList *l;
>> +
>> +       for (l = mp->pending; l; l = l->next) {
>> +               struct pending_req *p = l->data;
>> +
>> +               if (strcasecmp(key, p->key) == 0)
>> +                       return p;
>> +       }
>> +
>> +       return NULL;
>> +}
>> +
>> +static struct pending_req *pending_new(DBusMessage *msg, const char *key,
>> +                                                       const char *value)
>> +{
>> +       struct pending_req *p;
>> +
>> +       p = g_new0(struct pending_req, 1);
>> +       p->msg = dbus_message_ref(msg);
>> +       p->key = key;
>> +       p->value = value;
>> +
>> +       return p;
>> +}
>> +
>> +static DBusMessage *player_set_setting(struct media_player *mp,
>> +                                       DBusMessage *msg, const char *key,
>> +                                       const char *value)
>> +{
>> +       struct player_callback *cb = mp->cb;
>> +       struct pending_req *p;
>> +
>> +       if (cb == NULL || cb->cbs->set_setting == NULL)
>> +               return btd_error_not_supported(msg);
>> +
>> +       p = find_pending(mp, key);
>> +       if (p != NULL)
>> +               return btd_error_in_progress(msg);
>> +
>> +       if (!cb->cbs->set_setting(mp, key, value, cb->user_data))
>> +               return btd_error_invalid_args(msg);
>> +
>> +       p = pending_new(msg, key, value);
>> +
>> +       mp->pending = g_slist_append(mp->pending, p);
>> +
>> +       return NULL;
>> +}
>> +
>>  static DBusMessage *media_player_set_property(DBusConnection *conn,
>>                                                 DBusMessage *msg, void *data)
>>  {
>> -       return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
>> +       struct media_player *mp = data;
>> +       DBusMessageIter iter;
>> +       DBusMessageIter var;
>> +       const char *key, *value, *curval;
>> +
>> +       if (!dbus_message_iter_init(msg, &iter))
>> +               return btd_error_invalid_args(msg);
>> +
>> +       if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
>> +               return btd_error_invalid_args(msg);
>> +
>> +       dbus_message_iter_get_basic(&iter, &key);
>> +       dbus_message_iter_next(&iter);
>> +
>> +       if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
>> +               return btd_error_invalid_args(msg);
>> +
>> +       dbus_message_iter_recurse(&iter, &var);
>> +
>> +       if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_STRING)
>> +               return btd_error_invalid_args(msg);
>> +
>> +       dbus_message_iter_get_basic(&var, &value);
>> +
>> +       if (g_strcmp0(key, "Equalizer") != 0 &&
>> +                               g_strcmp0(key, "Repeat") != 0 &&
>> +                               g_strcmp0(key, "Shuffle") != 0 &&
>> +                               g_strcmp0(key, "Scan") != 0)
>> +               return btd_error_invalid_args(msg);
>> +
>> +       curval = g_hash_table_lookup(mp->settings, key);
>> +       if (g_strcmp0(curval, value) == 0)
>> +               return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
>> +
>> +       return player_set_setting(mp, msg, key, value);
>>  }
>>
>>  static const GDBusMethodTable media_player_methods[] = {
>> @@ -155,7 +248,7 @@ static const GDBusMethodTable media_player_methods[] = {
>>         { GDBUS_METHOD("GetTrack",
>>                         NULL, GDBUS_ARGS({ "metadata", "a{sv}" }),
>>                         media_player_get_track) },
>> -       { GDBUS_METHOD("SetProperty",
>> +       { GDBUS_ASYNC_METHOD("SetProperty",
>
> Why not using the DBus.Properties interface?

This is to align with what we currently have for target players, Im
planning to move everything related to MediaPlayer interface to
player.c then we can convert to use proper properties and change the
related tools such as mpris-player/simple-player.

-- 
Luiz Augusto von Dentz

^ permalink raw reply

* [PATCH] Bluetooth: Notify about device registration before power on
From: Marcel Holtmann @ 2012-10-30  8:35 UTC (permalink / raw)
  To: linux-bluetooth

It is important that the monitor interface gets notified about
a new device before its power on procedure has been started.

For some reason that is no longer working as expected and the power
on procedure runs first. It is safe to just notify about device
registration and trigger the power on procedure afterwards.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/hci_core.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 8a0ce70..a0a2f97 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1754,11 +1754,11 @@ int hci_register_dev(struct hci_dev *hdev)
 	if (hdev->dev_type != HCI_AMP)
 		set_bit(HCI_AUTO_OFF, &hdev->dev_flags);
 
-	schedule_work(&hdev->power_on);
-
 	hci_notify(hdev, HCI_DEV_REG);
 	hci_dev_hold(hdev);
 
+	schedule_work(&hdev->power_on);
+
 	return id;
 
 err_wqueue:
-- 
1.7.11.7


^ permalink raw reply related

* Re: [PATCH v3 06/10] sbc: Add mmx primitive for 1b 8s analyse
From: Dalleau, Frederic @ 2012-10-30  5:26 UTC (permalink / raw)
  To: Siarhei Siamashka; +Cc: Frédéric Dalleau, linux-bluetooth
In-Reply-To: <20121030034633.2242d317@i7>

Hi Siarhei,

On Tue, Oct 30, 2012 at 2:46 AM, Siarhei Siamashka
<siarhei.siamashka@gmail.com> wrote:
> On Mon, 29 Oct 2012 08:42:08 +0100
> "Dalleau, Frederic" <frederic.dalleau@intel.com> wrote:

> So I still think that it is safer and cleaner to have
> "sbc_init_primitives" function performing the following in order:
> 1. Initialize function pointers with C implementations.
> 2. Allow to override them with various platform specific
> implementations (which would work fine for old SBC formats).
> 3. At the end of the function have a check if we are actually dealing
> with mSBC format and restore all the function pointers back to C
> implementations in this case.

That's only ok for simd, but as soon as mmx gets in there would be
a 4th category where implementation supporting msbc would override
the already defined pointer.

Imho, the definitive clean solution is to add the missing primitives.

> Well, I just don't quite like that after the patches
>     [PATCH 04/10] sbc: Add msbc flag and generic C primitive
>     [PATCH 05/10] sbc: Add support for mSBC frame header
> we already have a complete mSBC support in C code, which is still
> unusable (as in buggy) if run on mmx, iwmmxt, armv6 or arm neon capable
> systems.

This is experimental feature and the time of commit, it is unused.
And btw, you just suggested to split this patch, and this will also lead to a
transitional state where some new functionality can be broken.

> The sbc-1.0 library is already starting to get packaged in some linux
> distributions. If somebody tries to run some application to do mSBC
> encoding/decoding, but happens to have an old sbc-1.0 library in his

I may be mistaking but most projects uses sbc statically, so checking is mostly
done at compile time. So as I often hear in open source : we'll cross the bridge
when we get to it :)

Regards,
Frédéric

^ permalink raw reply


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