Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCHv3 03/18] Bluetooth: Remove unnecessary intermediate function
From: Mat Martineau @ 2012-10-18 17:58 UTC (permalink / raw)
  To: linux-bluetooth, gustavo; +Cc: sunnyk, marcel, andrei.emeltchenko.news
In-Reply-To: <1350583130-3241-1-git-send-email-mathewm@codeaurora.org>

Resolves a conflict resolution issue in "Bluetooth: Fix L2CAP coding
style".

Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/l2cap_core.c | 13 ++-----------
 1 file changed, 2 insertions(+), 11 deletions(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 73ce337..ec2b4d9 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -3537,7 +3537,7 @@ static int l2cap_connect_req(struct l2cap_conn *conn,
 	return 0;
 }
 
-static inline int l2cap_connect_rsp(struct l2cap_conn *conn,
+static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
 				    struct l2cap_cmd_hdr *cmd, u8 *data)
 {
 	struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data;
@@ -4091,15 +4091,6 @@ static int l2cap_create_channel_req(struct l2cap_conn *conn,
 	return 0;
 }
 
-static inline int l2cap_create_channel_rsp(struct l2cap_conn *conn,
-					   struct l2cap_cmd_hdr *cmd,
-					   void *data)
-{
-	BT_DBG("conn %p", conn);
-
-	return l2cap_connect_rsp(conn, cmd, data);
-}
-
 static void l2cap_send_move_chan_rsp(struct l2cap_conn *conn, u8 ident,
 				     u16 icid, u16 result)
 {
@@ -4306,7 +4297,7 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn,
 
 	case L2CAP_CONN_RSP:
 	case L2CAP_CREATE_CHAN_RSP:
-		err = l2cap_connect_rsp(conn, cmd, data);
+		err = l2cap_connect_create_rsp(conn, cmd, data);
 		break;
 
 	case L2CAP_CONF_REQ:
-- 
1.7.12.3

--
Mat Martineau

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

^ permalink raw reply related

* [PATCHv3 02/18] Bluetooth: Add L2CAP create channel request handling
From: Mat Martineau @ 2012-10-18 17:58 UTC (permalink / raw)
  To: linux-bluetooth, gustavo
  Cc: sunnyk, marcel, andrei.emeltchenko.news, Andrei Emeltchenko
In-Reply-To: <1350583130-3241-1-git-send-email-mathewm@codeaurora.org>

The L2CAP create channel request is very similar to an L2CAP connect
request, but it has an additional parameter for the controller ID.  If
the controller id is 0, the channel is set up on the BR/EDR controller
(just like a connect request).  Using a valid high speed controller ID
will cause the channel to be initially created on that high speed
controller.  While the L2CAP data will be initially routed over the
AMP controller, the L2CAP fixed signaling channel only uses BR/EDR.

When a create channel request is received for a high speed controller,
a pending response is always sent first.  After the high speed
physical and logical links are complete a success response will be
sent.

Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/l2cap_core.c | 62 +++++++++++++++++++++++++++++++++++-----------
 1 file changed, 47 insertions(+), 15 deletions(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index f8d78f5..73ce337 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -3400,8 +3400,9 @@ static inline int l2cap_command_rej(struct l2cap_conn *conn,
 	return 0;
 }
 
-static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
-			  u8 *data, u8 rsp_code, u8 amp_id)
+static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
+					struct l2cap_cmd_hdr *cmd,
+					u8 *data, u8 rsp_code, u8 amp_id)
 {
 	struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
 	struct l2cap_conn_rsp rsp;
@@ -3452,6 +3453,7 @@ static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
 	bacpy(&bt_sk(sk)->dst, conn->dst);
 	chan->psm  = psm;
 	chan->dcid = scid;
+	chan->local_amp_id = amp_id;
 
 	__l2cap_chan_add(conn, chan);
 
@@ -3469,8 +3471,16 @@ static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
 				status = L2CAP_CS_AUTHOR_PEND;
 				chan->ops->defer(chan);
 			} else {
-				__l2cap_state_change(chan, BT_CONFIG);
-				result = L2CAP_CR_SUCCESS;
+				/* Force pending result for AMP controllers.
+				 * The connection will succeed after the
+				 * physical link is up. */
+				if (amp_id) {
+					__l2cap_state_change(chan, BT_CONNECT2);
+					result = L2CAP_CR_PEND;
+				} else {
+					__l2cap_state_change(chan, BT_CONFIG);
+					result = L2CAP_CR_SUCCESS;
+				}
 				status = L2CAP_CS_NO_INFO;
 			}
 		} else {
@@ -3516,6 +3526,8 @@ sendresp:
 			       l2cap_build_conf_req(chan, buf), buf);
 		chan->num_conf_req++;
 	}
+
+	return chan;
 }
 
 static int l2cap_connect_req(struct l2cap_conn *conn,
@@ -4028,12 +4040,12 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn,
 	return 0;
 }
 
-static inline int l2cap_create_channel_req(struct l2cap_conn *conn,
-					   struct l2cap_cmd_hdr *cmd,
-					   u16 cmd_len, void *data)
+static int l2cap_create_channel_req(struct l2cap_conn *conn,
+				    struct l2cap_cmd_hdr *cmd,
+				    u16 cmd_len, void *data)
 {
 	struct l2cap_create_chan_req *req = data;
-	struct l2cap_create_chan_rsp rsp;
+	struct l2cap_chan *chan;
 	u16 psm, scid;
 
 	if (cmd_len != sizeof(*req))
@@ -4047,14 +4059,34 @@ static inline int l2cap_create_channel_req(struct l2cap_conn *conn,
 
 	BT_DBG("psm 0x%2.2x, scid 0x%4.4x, amp_id %d", psm, scid, req->amp_id);
 
-	/* Placeholder: Always reject */
-	rsp.dcid = 0;
-	rsp.scid = cpu_to_le16(scid);
-	rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM);
-	rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
+	if (req->amp_id) {
+		struct hci_dev *hdev;
 
-	l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
-		       sizeof(rsp), &rsp);
+		/* Validate AMP controller id */
+		hdev = hci_dev_get(req->amp_id);
+		if (!hdev || hdev->dev_type != HCI_AMP ||
+		    !test_bit(HCI_UP, &hdev->flags)) {
+			struct l2cap_create_chan_rsp rsp;
+
+			rsp.dcid = 0;
+			rsp.scid = cpu_to_le16(scid);
+			rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP);
+			rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
+
+			l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP,
+				       sizeof(rsp), &rsp);
+
+			if (hdev)
+				hci_dev_put(hdev);
+
+			return 0;
+		}
+
+		hci_dev_put(hdev);
+	}
+
+	chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP,
+			     req->amp_id);
 
 	return 0;
 }
-- 
1.7.12.3

--
Mat Martineau

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

^ permalink raw reply related

* [PATCHv3 01/18] Bluetooth: Add new l2cap_chan struct members for high speed channels
From: Mat Martineau @ 2012-10-18 17:58 UTC (permalink / raw)
  To: linux-bluetooth, gustavo
  Cc: sunnyk, marcel, andrei.emeltchenko.news, Andrei Emeltchenko
In-Reply-To: <1350583130-3241-1-git-send-email-mathewm@codeaurora.org>

An L2CAP channel using high speed continues to be associated with a
BR/EDR l2cap_conn, while also tracking an additional hci_conn
(representing a physical link on a high speed controller) and hci_chan
(representing a logical link).  There may only be one physical link
between two high speed controllers.  Each physical link may contain
several logical links, with each logical link representing a channel
with specific quality of service.

During a channel move, the destination channel id, current move state,
and role (initiator vs. responder) are tracked and used by the channel
move state machine.  The ident value associated with a move request
must also be stored in order to use it in later move responses.

The active channel is stored in local_amp_id.

Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/l2cap.h | 29 +++++++++++++++++++++++++++++
 net/bluetooth/l2cap_core.c    |  5 +++++
 2 files changed, 34 insertions(+)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 6e23afd..6d3615e 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -434,6 +434,8 @@ struct l2cap_chan {
 	struct sock *sk;
 
 	struct l2cap_conn	*conn;
+	struct hci_conn		*hs_hcon;
+	struct hci_chan		*hs_hchan;
 	struct kref	kref;
 
 	__u8		state;
@@ -477,6 +479,11 @@ struct l2cap_chan {
 	unsigned long	conn_state;
 	unsigned long	flags;
 
+	__u8		local_amp_id;
+	__u8		move_id;
+	__u8		move_state;
+	__u8		move_role;
+
 	__u16		next_tx_seq;
 	__u16		expected_ack_seq;
 	__u16		expected_tx_seq;
@@ -644,6 +651,9 @@ enum {
 enum {
 	L2CAP_RX_STATE_RECV,
 	L2CAP_RX_STATE_SREJ_SENT,
+	L2CAP_RX_STATE_MOVE,
+	L2CAP_RX_STATE_WAIT_P,
+	L2CAP_RX_STATE_WAIT_F,
 };
 
 enum {
@@ -674,6 +684,25 @@ enum {
 	L2CAP_EV_RECV_FRAME,
 };
 
+enum {
+	L2CAP_MOVE_ROLE_NONE,
+	L2CAP_MOVE_ROLE_INITIATOR,
+	L2CAP_MOVE_ROLE_RESPONDER,
+};
+
+enum {
+	L2CAP_MOVE_STABLE,
+	L2CAP_MOVE_WAIT_REQ,
+	L2CAP_MOVE_WAIT_RSP,
+	L2CAP_MOVE_WAIT_RSP_SUCCESS,
+	L2CAP_MOVE_WAIT_CONFIRM,
+	L2CAP_MOVE_WAIT_CONFIRM_RSP,
+	L2CAP_MOVE_WAIT_LOGICAL_COMP,
+	L2CAP_MOVE_WAIT_LOGICAL_CFM,
+	L2CAP_MOVE_WAIT_LOCAL_BUSY,
+	L2CAP_MOVE_WAIT_PREPARE,
+};
+
 void l2cap_chan_hold(struct l2cap_chan *c);
 void l2cap_chan_put(struct l2cap_chan *c);
 
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index f873619..f8d78f5 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -2788,6 +2788,11 @@ int l2cap_ertm_init(struct l2cap_chan *chan)
 
 	skb_queue_head_init(&chan->tx_q);
 
+	chan->local_amp_id = 0;
+	chan->move_id = 0;
+	chan->move_state = L2CAP_MOVE_STABLE;
+	chan->move_role = L2CAP_MOVE_ROLE_NONE;
+
 	if (chan->mode != L2CAP_MODE_ERTM)
 		return 0;
 
-- 
1.7.12.3

--
Mat Martineau

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

^ permalink raw reply related

* [PATCHv3 00/18] L2CAP signaling for AMP channel create/move
From: Mat Martineau @ 2012-10-18 17:58 UTC (permalink / raw)
  To: linux-bluetooth, gustavo; +Cc: sunnyk, marcel, andrei.emeltchenko.news

Here are the changes that process commands on the L2CAP signaling
channel for setting up AMP channels.  There's still a lot of
integration to do as other AMP functionality is implemented.  I've
marked places that require this integration with "Placeholder"
comments (look for that string).

Changes:
  * PATCHv3 - Dropped patch 17, fixed style issues in 5, 7, and 9.
              Split up a large function in patch 10.
  * PATCHv2 - Fixed formatting and style issues, added acks
  * PATCHv1 - Rebased after AMP physical link patch set, incorporated
              mailing list feedback.
  * RFCv1 - Finished commit messages, fixed formatting/style issues
  * RFCv0 - Initial post

Mat Martineau (18):
  Bluetooth: Add new l2cap_chan struct members for high speed channels
  Bluetooth: Add L2CAP create channel request handling
  Bluetooth: Remove unnecessary intermediate function
  Bluetooth: Lookup channel structure based on DCID
  Bluetooth: Channel move request handling
  Bluetooth: Add new ERTM receive states for channel move
  Bluetooth: Add move channel confirm handling
  Bluetooth: Add state to hci_chan
  Bluetooth: Move channel response
  Bluetooth: Add logical link confirm
  Bluetooth: Add move confirm response handling
  Bluetooth: Handle physical link completion
  Bluetooth: Flag ACL frames as complete for AMP controllers
  Bluetooth: Do not send data during channel move
  Bluetooth: Configure appropriate timeouts for AMP controllers
  Bluetooth: Ignore BR/EDR packet size constraints when fragmenting for
    AMP
  Bluetooth: Do not retransmit data during a channel move
  Bluetooth: Start channel move when socket option is changed

 include/net/bluetooth/hci_core.h |   1 +
 include/net/bluetooth/l2cap.h    |  32 ++
 net/bluetooth/hci_conn.c         |   1 +
 net/bluetooth/l2cap_core.c       | 939 +++++++++++++++++++++++++++++++++++++--
 net/bluetooth/l2cap_sock.c       |   5 +
 5 files changed, 938 insertions(+), 40 deletions(-)

-- 
1.7.12.3

--
Mat Martineau

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

^ permalink raw reply

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

Hi Fred,

>  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);

please use tabs for all of it and not just spaces.

>  	printf("Subbands\t\t%d\n", subbands);
>  	printf("Block length\t\t%d\n", blocks);
>  	printf("Sampling frequency\t%s\n", freq2str(freq));

Regards

Marcel



^ permalink raw reply

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

Hi Fred,

> ---
>  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;

empty line here.

> +	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;

another empty line.

> +	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;

We have these newly invented error return code, why?

> +
> +	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)

Indent this further to the back so it does not overlap with the function
name.

> +{
> +	data[0] = MSBC_SYNCWORD;
> +	data[1] = 0;
> +	data[2] = 0;
> +
> +	return sbc_pack_frame_internal(
> +		data, frame, len, 8, 1, joint);

Don't start the second line with no argument in the first one. Break
this up a little bit nicer.

> +}
> +
>  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);

No need for a sbc_ prefix here. Just call it unpack_frame and
pack_frame.

>  };
>  
>  static void sbc_set_defaults(sbc_t *sbc, unsigned long flags)
>  {
> +	struct sbc_priv *priv = sbc->priv;

empty line,

> +	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;
> +	}

and here.

>  	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)

Regards

Marcel



^ permalink raw reply

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

Hi Fred,

> ---
>  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(-)

I am failing to see why we do this. Please add a commit explaining the
reason for this change.

Regards

Marcel



^ permalink raw reply

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

Hi Fred,

> ---
>  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(-)

you need to explain why we need that. Please use commit messages that
explain the reasoning behind the change.

Regards

Marcel



^ permalink raw reply

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

Hi Fred,

>  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;

I dislike the name, it is a bit short. Using ->increment seems to be a
bit better.

And what about documenting what it is for.

Regards

Marcel



^ permalink raw reply

* 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


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