* [RFCv2 06/12] Bluetooth: AMP: Process Disc Logical Link
From: Andrei Emeltchenko @ 2012-10-30 15:52 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1351612384-12392-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Add processing for HCI Disconnection Logical Link Complete
Event.
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
---
include/net/bluetooth/amp.h | 1 +
net/bluetooth/amp.c | 7 +++++++
net/bluetooth/hci_event.c | 28 ++++++++++++++++++++++++++++
3 files changed, 36 insertions(+)
diff --git a/include/net/bluetooth/amp.h b/include/net/bluetooth/amp.h
index 70d5c15..405fb9c 100644
--- a/include/net/bluetooth/amp.h
+++ b/include/net/bluetooth/amp.h
@@ -47,5 +47,6 @@ void amp_accept_phylink(struct hci_dev *hdev, struct amp_mgr *mgr,
void amp_write_remote_assoc(struct hci_dev *hdev, u8 handle);
void amp_write_rem_assoc_continue(struct hci_dev *hdev, u8 handle);
void amp_create_logical_link(struct l2cap_chan *chan);
+void amp_destroy_logical_link(struct hci_chan *hchan, u8 reason);
#endif /* __AMP_H */
diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c
index fbb6360..0f3fef3 100644
--- a/net/bluetooth/amp.c
+++ b/net/bluetooth/amp.c
@@ -421,3 +421,10 @@ void amp_create_logical_link(struct l2cap_chan *chan)
done:
hci_dev_put(hdev);
}
+
+void amp_destroy_logical_link(struct hci_chan *hchan, u8 reason)
+{
+ BT_DBG("hchan %p", hchan);
+
+ hci_chan_del(hchan);
+}
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 9963ec9..036cd8d 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3742,6 +3742,30 @@ static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
}
}
+static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
+ struct sk_buff *skb)
+{
+ struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
+ struct hci_chan *hchan;
+
+ BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
+ le16_to_cpu(ev->handle), ev->status);
+
+ if (ev->status)
+ return;
+
+ hci_dev_lock(hdev);
+
+ hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
+ if (!hchan)
+ goto unlock;
+
+ amp_destroy_logical_link(hchan, ev->reason);
+
+unlock:
+ hci_dev_unlock(hdev);
+}
+
static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_ev_le_conn_complete *ev = (void *) skb->data;
@@ -4077,6 +4101,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
hci_loglink_complete_evt(hdev, skb);
break;
+ case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
+ hci_disconn_loglink_complete_evt(hdev, skb);
+ break;
+
case HCI_EV_NUM_COMP_BLOCKS:
hci_num_comp_blocks_evt(hdev, skb);
break;
--
1.7.9.5
^ permalink raw reply related
* [RFCv2 05/12] Bluetooth: AMP: Add Logical Link Create function
From: Andrei Emeltchenko @ 2012-10-30 15:52 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1351612384-12392-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
After physical link is created logical link needs to be created.
The process starts after L2CAP channel is created and L2CAP
Configuration Response with result PENDING is received.
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
---
include/net/bluetooth/amp.h | 1 +
net/bluetooth/amp.c | 49 +++++++++++++++++++++++++++++++++++++++++++
net/bluetooth/hci_event.c | 9 ++++++++
net/bluetooth/l2cap_core.c | 19 ++++++++++++-----
4 files changed, 73 insertions(+), 5 deletions(-)
diff --git a/include/net/bluetooth/amp.h b/include/net/bluetooth/amp.h
index 2e7c79e..70d5c15 100644
--- a/include/net/bluetooth/amp.h
+++ b/include/net/bluetooth/amp.h
@@ -46,5 +46,6 @@ void amp_accept_phylink(struct hci_dev *hdev, struct amp_mgr *mgr,
struct hci_conn *hcon);
void amp_write_remote_assoc(struct hci_dev *hdev, u8 handle);
void amp_write_rem_assoc_continue(struct hci_dev *hdev, u8 handle);
+void amp_create_logical_link(struct l2cap_chan *chan);
#endif /* __AMP_H */
diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c
index 231d7ef..fbb6360 100644
--- a/net/bluetooth/amp.c
+++ b/net/bluetooth/amp.c
@@ -372,3 +372,52 @@ void amp_accept_phylink(struct hci_dev *hdev, struct amp_mgr *mgr,
hci_send_cmd(hdev, HCI_OP_ACCEPT_PHY_LINK, sizeof(cp), &cp);
}
+
+void amp_create_logical_link(struct l2cap_chan *chan)
+{
+ struct hci_cp_create_accept_logical_link cp;
+ struct hci_conn *hcon;
+ struct hci_dev *hdev;
+
+ BT_DBG("chan %p", chan);
+
+ if (!chan->hs_hcon)
+ return;
+
+ hdev = hci_dev_hold(chan->hs_hcon->hdev);
+ if (!hdev)
+ return;
+
+ BT_DBG("chan %p ctrl_id %d dst %pMR", chan, chan->ctrl_id,
+ chan->conn->dst);
+
+ hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, chan->conn->dst);
+ if (!hcon)
+ goto done;
+
+ cp.phy_handle = hcon->handle;
+
+ cp.tx_flow_spec.id = chan->local_id;
+ cp.tx_flow_spec.stype = chan->local_stype;
+ cp.tx_flow_spec.msdu = cpu_to_le16(chan->local_msdu);
+ cp.tx_flow_spec.sdu_itime = cpu_to_le32(chan->local_sdu_itime);
+ cp.tx_flow_spec.acc_lat = cpu_to_le32(chan->local_acc_lat);
+ cp.tx_flow_spec.flush_to = cpu_to_le32(chan->local_flush_to);
+
+ cp.rx_flow_spec.id = chan->remote_id;
+ cp.rx_flow_spec.stype = chan->remote_stype;
+ cp.rx_flow_spec.msdu = cpu_to_le16(chan->remote_msdu);
+ cp.rx_flow_spec.sdu_itime = cpu_to_le32(chan->remote_sdu_itime);
+ cp.rx_flow_spec.acc_lat = cpu_to_le32(chan->remote_acc_lat);
+ cp.rx_flow_spec.flush_to = cpu_to_le32(chan->remote_flush_to);
+
+ if (hcon->out)
+ hci_send_cmd(hdev, HCI_OP_CREATE_LOGICAL_LINK, sizeof(cp),
+ &cp);
+ else
+ hci_send_cmd(hdev, HCI_OP_ACCEPT_LOGICAL_LINK, sizeof(cp),
+ &cp);
+
+done:
+ hci_dev_put(hdev);
+}
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index aa79ed2..9963ec9 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1836,6 +1836,11 @@ static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
amp_write_remote_assoc(hdev, cp->phy_handle);
}
+static void hci_cs_create_logical_link(struct hci_dev *hdev, u8 status)
+{
+ BT_DBG("%s status 0x%2.2x", hdev->name, status);
+}
+
static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
__u8 status = *((__u8 *) skb->data);
@@ -2670,6 +2675,10 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_cs_accept_phylink(hdev, ev->status);
break;
+ case HCI_OP_CREATE_LOGICAL_LINK:
+ hci_cs_create_logical_link(hdev, ev->status);
+ break;
+
default:
BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
break;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 782e49c..ecc5020 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -38,6 +38,7 @@
#include <net/bluetooth/l2cap.h>
#include <net/bluetooth/smp.h>
#include <net/bluetooth/a2mp.h>
+#include <net/bluetooth/amp.h>
bool disable_ertm;
@@ -1013,6 +1014,12 @@ static bool __amp_capable(struct l2cap_chan *chan)
return false;
}
+static bool l2cap_check_efs(struct l2cap_chan *chan)
+{
+ /* Check EFS parameters */
+ return true;
+}
+
void l2cap_send_conn_req(struct l2cap_chan *chan)
{
struct l2cap_conn *conn = chan->conn;
@@ -3957,13 +3964,15 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn,
goto done;
}
- /* check compatibility */
-
- if (!chan->ctrl_id)
+ if (!chan->ctrl_id) {
l2cap_send_efs_conf_rsp(chan, buf, cmd->ident,
0);
- else
- chan->ident = cmd->ident;
+ } else {
+ if (l2cap_check_efs(chan)) {
+ amp_create_logical_link(chan);
+ chan->ident = cmd->ident;
+ }
+ }
}
goto done;
--
1.7.9.5
^ permalink raw reply related
* [RFCv2 04/12] Bluetooth: Derive remote and local amp id from chan struct
From: Andrei Emeltchenko @ 2012-10-30 15:52 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1351612384-12392-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
l2cap_chan already keeps information about *_amp_id.
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
net/bluetooth/l2cap_core.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index d51741f..782e49c 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -4573,9 +4573,11 @@ static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result)
l2cap_ertm_send(chan);
}
-void l2cap_physical_cfm(struct l2cap_chan *chan, int result, u8 local_amp_id,
- u8 remote_amp_id)
+void l2cap_physical_cfm(struct l2cap_chan *chan, int result)
{
+ u8 local_amp_id = chan->local_amp_id;
+ u8 remote_amp_id = chan->ctrl_id;
+
BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d",
chan, result, local_amp_id, remote_amp_id);
--
1.7.9.5
^ permalink raw reply related
* [RFCv2 03/12] Bluetooth: Return correct L2CAP response type
From: Andrei Emeltchenko @ 2012-10-30 15:52 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1351612384-12392-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Return L2CAP_CREATE_CHAN_RSP for Create Channel Request and
L2CAP_CONN_RSP for Create Connection Request.
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
net/bluetooth/l2cap_core.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 4ef85d2..d51741f 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -3478,12 +3478,21 @@ void __l2cap_connect_rsp_defer(struct l2cap_chan *chan)
struct l2cap_conn_rsp rsp;
struct l2cap_conn *conn = chan->conn;
u8 buf[128];
+ u8 rsp_code;
rsp.scid = cpu_to_le16(chan->dcid);
rsp.dcid = cpu_to_le16(chan->scid);
rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
- l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp);
+
+ if (chan->hs_hcon)
+ rsp_code = L2CAP_CREATE_CHAN_RSP;
+ else
+ rsp_code = L2CAP_CONN_RSP;
+
+ BT_DBG("chan %p rsp_code %u", chan, rsp_code);
+
+ l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp);
if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state))
return;
--
1.7.9.5
^ permalink raw reply related
* [RFCv2 02/12] Bluetooth: Save hs_hchan instead of hs_hcon in loglink complete
From: Andrei Emeltchenko @ 2012-10-30 15:52 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1351612384-12392-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
When logical link creation is completed we need to save hs_hchan
which represents logical link instead of hs_hcon representing
physical link. hs_hcon shall be saved when receiving physical link
complete event.
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
net/bluetooth/l2cap_core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index c2fbaf9..4ef85d2 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -4375,7 +4375,7 @@ static void l2cap_logical_finish_create(struct l2cap_chan *chan,
{
struct l2cap_conf_rsp rsp;
- chan->hs_hcon = hchan->conn;
+ chan->hs_hchan = hchan;
chan->hs_hcon->l2cap_data = chan->conn;
l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0);
--
1.7.9.5
^ permalink raw reply related
* [RFCv2 01/12] Bluetooth: trivial: Fix braces style and remove empty line
From: Andrei Emeltchenko @ 2012-10-30 15:52 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1351612384-12392-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
net/bluetooth/l2cap_core.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index d1728af..c2fbaf9 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -6252,9 +6252,9 @@ void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
conn = l2cap_conn_add(hcon, status);
if (conn)
l2cap_conn_ready(conn);
- } else
+ } else {
l2cap_conn_del(hcon, bt_to_errno(status));
-
+ }
}
int l2cap_disconn_ind(struct hci_conn *hcon)
--
1.7.9.5
^ permalink raw reply related
* [RFCv2 00/12] Handling physical and logical link
From: Andrei Emeltchenko @ 2012-10-30 15:52 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1350493622.26318.114.camel@aeonflux>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Set of patches adding handling for physical and logical link
complete events.
Changes:
* rfcv2: Added several new patches, fixing style issues.
* rfcv1: Rebased on top of Mat's patches, preserve Marcel's ack for
not-changed-much patches only.
* rfcv0: original
Andrei Emeltchenko (12):
Bluetooth: trivial: Fix braces style and remove empty line
Bluetooth: Save hs_hchan instead of hs_hcon in loglink complete
Bluetooth: Return correct L2CAP response type
Bluetooth: Derive remote and local amp id from chan struct
Bluetooth: AMP: Add Logical Link Create function
Bluetooth: AMP: Process Disc Logical Link
Bluetooth: AMP: Process Disc Physical Link Complete evt
Bluetooth: AMP: Remove hci_conn receiving error command status
Bluetooth: Disconnect logical link when deleteing chan
Bluetooth: AMP: Check for hs_hcon instead of ctrl_id
Bluetooth: AMP: Use l2cap_physical_cfm in phylink complete evt
Bluetooth: Process Create Chan Request
include/net/bluetooth/amp.h | 4 ++
include/net/bluetooth/l2cap.h | 1 +
net/bluetooth/amp.c | 94 ++++++++++++++++++++++++++++++++++++++++
net/bluetooth/hci_event.c | 95 +++++++++++++++++++++++++++++++++--------
net/bluetooth/l2cap_core.c | 82 ++++++++++++++++++++++++++---------
5 files changed, 238 insertions(+), 38 deletions(-)
--
1.7.9.5
^ permalink raw reply
* Re: BLE issue: Start_LE_Encryption fails
From: Anderson Lizardo @ 2012-10-30 14:15 UTC (permalink / raw)
To: Ajay; +Cc: linux-bluetooth
In-Reply-To: <508DDCE7.6030708@globaledgesoft.com>
Hi Ajay,
On Sun, Oct 28, 2012 at 9:33 PM, Ajay <ajay.kv@globaledgesoft.com> wrote:
> ya , i got your point ,advertiser is informing the remote device , that it
> is not BR/EDR capable .That is done and device is connecting now.
> But still i dont know, how to do le specific pairing and
> start_encryption enable(part of le pairing) . Is there any tool in bluez
> providing LE pairing before connecting the devices (want to try with 2
> ubuntu pc's ).
We use the "simple-agent" script from test/ directory in BlueZ for pairing.
On the slave side run:
test/simple-agent hci0
on the master side, after "hcitool lescan", run:
test/simple-agent hci0 <slave-address>
This should trigger Just Works SMP pairing.
Regards,
--
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil
^ permalink raw reply
* Re: BLE issue: Start_LE_Encryption fails
From: Anderson Lizardo @ 2012-10-30 13:12 UTC (permalink / raw)
To: Ajay; +Cc: linux-bluetooth
In-Reply-To: <508DCE10.40801@globaledgesoft.com>
Hi Ajay,
On Sun, Oct 28, 2012 at 8:30 PM, Ajay <ajay.kv@globaledgesoft.com> wrote:
> Thanks, but "sudo hcitool -i hci0 cmd 0x08 0x0008 03 02 01 06 " , this
> command only sets the advertising data to zero right . so how do i set the
> adv flag as 0x06 . Which hci command is used for this purpose .
No, this sets adv. data to have "Flags" AD set to 0x06. But you missed
the second line of the command:
sudo hcitool -i hci0 cmd 0x08 0x0008 03 02 01 06 \
$(perl -e 'print "00 " x 28')
The second line is important because it fills the other bytes with
zero (which some controllers require).
Regards,
--
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil
^ permalink raw reply
* Re: [PATCH BlueZ] hog: Fix selecting suspend backend
From: Johan Hedberg @ 2012-10-30 12:12 UTC (permalink / raw)
To: João Paulo Rechi Vita; +Cc: linux-bluetooth
In-Reply-To: <1351542837-2635-1-git-send-email-jprvita@openbossa.org>
Hi João Paulo,
On Mon, Oct 29, 2012, João Paulo Rechi Vita wrote:
> The dummy backend was always being compiled and the --with-hog-suspend
> option was not being accepted by configure. Now the backend can be
> selected with --with-hog-suspend and the suspend implementation file is
> generated during compile time.
> ---
> .gitignore | 1 +
> Makefile.am | 5 ++++-
> acinclude.m4 | 2 +-
> 3 files changed, 6 insertions(+), 2 deletions(-)
Applied. Thanks.
Johan
^ permalink raw reply
* Re: BLE issue: Start_LE_Encryption fails
From: Anderson Lizardo @ 2012-10-30 11:50 UTC (permalink / raw)
To: Ajay, linux-bluetooth
In-Reply-To: <CAJdJm_MXB71MTcbrViLh486RtpWpx+a7SDvUPdSj2VdOa1fWvw@mail.gmail.com>
[Forgot to reply to the list]
On Tue, Oct 30, 2012 at 7:49 AM, Anderson Lizardo
<anderson.lizardo@openbossa.org> wrote:
> Hi Ajay,
>
> On Sun, Oct 28, 2012 at 1:08 PM, Ajay <ajay.kv@globaledgesoft.com> wrote:
>> Hi,
>> I am getting le_long_term_key_negative reply from the remote device
>> , on sending le_start_encryption . I am testing this with 2 ubuntu
>> machines(3.2.5) with IOGEAR dual mode dongles .
>
> To connect to a dual mode dongle, you need to set LE Adv. flags to
> 0x06 (which means general discoverable + BR/EDR not supported) on the
> acceptor side. You can use this command (on the acceptor/slave side):
>
> sudo hcitool -i hci0 cmd 0x08 0x0008 03 02 01 06 \
> $(perl -e 'print "00 " x 28')
>
> Next, enable LE advertising:
>
> sudo hciconfig hci0 leadv
>
> On the initiator/master side, run "hcitool lescan" and try pairing again.
Regards,
--
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil
^ permalink raw reply
* Re: [PATCH] Bluetooth: Notify about device registration before power on
From: Johan Hedberg @ 2012-10-30 11:08 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1351586140-30708-1-git-send-email-marcel@holtmann.org>
Hi Marcel,
On Tue, Oct 30, 2012, Marcel Holtmann wrote:
> It is important that the monitor interface gets notified about
> a new device before its power on procedure has been started.
>
> For some reason that is no longer working as expected and the power
> on procedure runs first. It is safe to just notify about device
> registration and trigger the power on procedure afterwards.
>
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
> net/bluetooth/hci_core.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
Acked-by: Johan Hedberg <johan.hedberg@intel.com>
Johan
^ permalink raw reply
* [PATCH v4 16/16] sbc: Update copyrights
From: Frédéric Dalleau @ 2012-10-30 9:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1351589975-22640-1-git-send-email-frederic.dalleau@linux.intel.com>
---
sbc/sbc.c | 1 +
sbc/sbc_primitives.c | 1 +
sbc/sbc_primitives.h | 1 +
sbc/sbc_primitives_mmx.c | 1 +
src/sbcdec.c | 1 +
src/sbcenc.c | 1 +
src/sbcinfo.c | 1 +
7 files changed, 7 insertions(+)
diff --git a/sbc/sbc.c b/sbc/sbc.c
index cd3fd8c..e00b256 100644
--- a/sbc/sbc.c
+++ b/sbc/sbc.c
@@ -6,6 +6,7 @@
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
* Copyright (C) 2004-2005 Henryk Ploetz <henryk@ploetzli.ch>
* Copyright (C) 2005-2008 Brad Midgley <bmidgley@xmission.com>
+ * Copyright (C) 2012 Intel Corporation
*
*
* This library is free software; you can redistribute it and/or
diff --git a/sbc/sbc_primitives.c b/sbc/sbc_primitives.c
index b189320..0947cf5 100644
--- a/sbc/sbc_primitives.c
+++ b/sbc/sbc_primitives.c
@@ -6,6 +6,7 @@
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
* Copyright (C) 2004-2005 Henryk Ploetz <henryk@ploetzli.ch>
* Copyright (C) 2005-2006 Brad Midgley <bmidgley@xmission.com>
+ * Copyright (C) 2012 Intel Corporation
*
*
* This library is free software; you can redistribute it and/or
diff --git a/sbc/sbc_primitives.h b/sbc/sbc_primitives.h
index ffee339..5c4c0af 100644
--- a/sbc/sbc_primitives.h
+++ b/sbc/sbc_primitives.h
@@ -6,6 +6,7 @@
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
* Copyright (C) 2004-2005 Henryk Ploetz <henryk@ploetzli.ch>
* Copyright (C) 2005-2006 Brad Midgley <bmidgley@xmission.com>
+ * Copyright (C) 2012 Intel Corporation
*
*
* This library is free software; you can redistribute it and/or
diff --git a/sbc/sbc_primitives_mmx.c b/sbc/sbc_primitives_mmx.c
index 21d7b74..02f23d9 100644
--- a/sbc/sbc_primitives_mmx.c
+++ b/sbc/sbc_primitives_mmx.c
@@ -6,6 +6,7 @@
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
* Copyright (C) 2004-2005 Henryk Ploetz <henryk@ploetzli.ch>
* Copyright (C) 2005-2006 Brad Midgley <bmidgley@xmission.com>
+ * Copyright (C) 2012 Intel Corporation
*
*
* This library is free software; you can redistribute it and/or
diff --git a/src/sbcdec.c b/src/sbcdec.c
index 37d2e98..908292c 100644
--- a/src/sbcdec.c
+++ b/src/sbcdec.c
@@ -4,6 +4,7 @@
*
* Copyright (C) 2008-2010 Nokia Corporation
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2012 Intel Corporation
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/sbcenc.c b/src/sbcenc.c
index 71ad6bb..0156b74 100644
--- a/src/sbcenc.c
+++ b/src/sbcenc.c
@@ -4,6 +4,7 @@
*
* Copyright (C) 2008-2010 Nokia Corporation
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2012 Intel Corporation
*
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/sbcinfo.c b/src/sbcinfo.c
index 01426b8..676b949 100644
--- a/src/sbcinfo.c
+++ b/src/sbcinfo.c
@@ -4,6 +4,7 @@
*
* Copyright (C) 2008-2010 Nokia Corporation
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2012 Intel Corporation
*
*
* This program is free software; you can redistribute it and/or modify
--
1.7.9.5
^ permalink raw reply related
* [PATCH v4 15/16] sbc: Update sbcinfo for msbc
From: Frédéric Dalleau @ 2012-10-30 9:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1351589975-22640-1-git-send-email-frederic.dalleau@linux.intel.com>
---
src/sbcinfo.c | 51 ++++++++++++++++++++++++++++++++++++---------------
1 file changed, 36 insertions(+), 15 deletions(-)
diff --git a/src/sbcinfo.c b/src/sbcinfo.c
index 8cfb54a..01426b8 100644
--- a/src/sbcinfo.c
+++ b/src/sbcinfo.c
@@ -61,12 +61,11 @@ struct sbc_frame_hdr {
#error "Unknown byte order"
#endif
-static int calc_frame_len(struct sbc_frame_hdr *hdr)
+static int calc_frame_len(struct sbc_frame_hdr *hdr, int nrof_blocks)
{
- int tmp, nrof_subbands, nrof_blocks;
+ int tmp, nrof_subbands;
nrof_subbands = (hdr->subbands + 1) * 4;
- nrof_blocks = (hdr->blocks + 1) * 4;
switch (hdr->channel_mode) {
case 0x00:
@@ -89,13 +88,12 @@ static int calc_frame_len(struct sbc_frame_hdr *hdr)
return (nrof_subbands + ((tmp + 7) / 8));
}
-static double calc_bit_rate(struct sbc_frame_hdr *hdr)
+static double calc_bit_rate(struct sbc_frame_hdr *hdr, int nrof_blocks)
{
- int nrof_subbands, nrof_blocks;
+ int nrof_subbands;
double f;
nrof_subbands = (hdr->subbands + 1) * 4;
- nrof_blocks = (hdr->blocks + 1) * 4;
switch (hdr->sampling_frequency) {
case 0:
@@ -114,7 +112,7 @@ static double calc_bit_rate(struct sbc_frame_hdr *hdr)
return 0;
}
- return ((8 * (calc_frame_len(hdr) + 4) * f) /
+ return ((8 * (calc_frame_len(hdr, nrof_blocks) + 4) * f) /
(nrof_subbands * nrof_blocks));
}
@@ -175,7 +173,7 @@ static int analyze_file(char *filename)
double rate;
int bitpool[SIZE], frame_len[SIZE];
int subbands, blocks, freq, method;
- int n, p1, p2, fd, size, num;
+ int n, p1, p2, fd, size, num, msbc;
ssize_t len;
unsigned int count;
@@ -191,17 +189,30 @@ static int analyze_file(char *filename)
fd = fileno(stdin);
len = __read(fd, &hdr, sizeof(hdr));
- if (len != sizeof(hdr) || hdr.syncword != 0x9c) {
+ if (len != sizeof(hdr) || !(hdr.syncword == 0x9c ||
+ hdr.syncword == 0xad)) {
fprintf(stderr, "Not a SBC audio file\n");
return -1;
}
+ msbc = (hdr.syncword == 0xad) ? 1 : 0;
+
+ if (msbc) {
+ hdr.subbands = 1; /* 8 */
+ hdr.sampling_frequency = 0x00; /* 16000 */
+ hdr.allocation_method = 0; /* Loudness */
+ hdr.bitpool = 26;
+ hdr.channel_mode = 0x00; /* Mono */
+
+ blocks = 15;
+ } else {
+ blocks = (hdr.blocks + 1) * 4;
+ }
subbands = (hdr.subbands + 1) * 4;
- blocks = (hdr.blocks + 1) * 4;
freq = hdr.sampling_frequency;
method = hdr.allocation_method;
- count = calc_frame_len(&hdr);
+ count = calc_frame_len(&hdr, blocks);
bitpool[0] = hdr.bitpool;
frame_len[0] = count + 4;
@@ -213,7 +224,7 @@ static int analyze_file(char *filename)
if (lseek(fd, 0, SEEK_SET) < 0) {
num = 1;
- rate = calc_bit_rate(&hdr);
+ rate = calc_bit_rate(&hdr, blocks);
while (count) {
size = count > sizeof(buf) ? sizeof(buf) : count;
len = __read(fd, buf, size);
@@ -237,14 +248,23 @@ static int analyze_file(char *filename)
if (len == 0)
break;
- if ((size_t) len < sizeof(hdr) || hdr.syncword != 0x9c) {
+ if ((size_t) len < sizeof(hdr) || !(hdr.syncword == 0x9c ||
+ hdr.syncword == 0xad)) {
fprintf(stderr, "Corrupted SBC stream "
"(len %zd syncword 0x%02x)\n",
len, hdr.syncword);
break;
}
- count = calc_frame_len(&hdr);
+ if (msbc) {
+ hdr.subbands = 1; /* 8 */
+ hdr.sampling_frequency = 0x00; /* 16000 */
+ hdr.allocation_method = 0; /* Loudness */
+ hdr.bitpool = 26;
+ hdr.channel_mode = 0x00; /* Mono */
+ }
+
+ count = calc_frame_len(&hdr, blocks);
len = count + 4;
p1 = -1;
@@ -273,10 +293,11 @@ static int analyze_file(char *filename)
count -= len;
}
- rate += calc_bit_rate(&hdr);
+ rate += calc_bit_rate(&hdr, blocks);
num++;
}
+ printf("mSBC\t\t\t%d\n", msbc);
printf("Subbands\t\t%d\n", subbands);
printf("Block length\t\t%d\n", blocks);
printf("Sampling frequency\t%s\n", freq2str(freq));
--
1.7.9.5
^ permalink raw reply related
* [PATCH v4 14/16] sbc: Update sbcenc for msbc
From: Frédéric Dalleau @ 2012-10-30 9:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1351589975-22640-1-git-send-email-frederic.dalleau@linux.intel.com>
---
src/sbcenc.c | 25 ++++++++++++++++++++-----
1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/src/sbcenc.c b/src/sbcenc.c
index a723b03..71ad6bb 100644
--- a/src/sbcenc.c
+++ b/src/sbcenc.c
@@ -45,7 +45,7 @@ static int verbose = 0;
static unsigned char input[BUF_SIZE], output[BUF_SIZE + BUF_SIZE / 4];
static void encode(char *filename, int subbands, int bitpool, int joint,
- int dualchannel, int snr, int blocks)
+ int dualchannel, int snr, int blocks, int msbc)
{
struct au_header au_hdr;
sbc_t sbc;
@@ -87,7 +87,7 @@ static void encode(char *filename, int subbands, int bitpool, int joint,
goto done;
}
- sbc_init(&sbc, 0L);
+ sbc_init(&sbc, msbc ? SBC_MSBC : 0L);
switch (BE_INT(au_hdr.sample_rate)) {
case 16000:
@@ -215,6 +215,7 @@ static void usage(void)
printf("Options:\n"
"\t-h, --help Display help\n"
"\t-v, --verbose Verbose mode\n"
+ "\t-m, --msbc mSBC codec\n"
"\t-s, --subbands Number of subbands to use (4 or 8)\n"
"\t-b, --bitpool Bitpool value (default is 32)\n"
"\t-j, --joint Joint stereo\n"
@@ -227,6 +228,7 @@ static void usage(void)
static struct option main_options[] = {
{ "help", 0, 0, 'h' },
{ "verbose", 0, 0, 'v' },
+ { "msbc", 0, 0, 'm' },
{ "subbands", 1, 0, 's' },
{ "bitpool", 1, 0, 'b' },
{ "joint", 0, 0, 'j' },
@@ -239,9 +241,9 @@ static struct option main_options[] = {
int main(int argc, char *argv[])
{
int i, opt, subbands = 8, bitpool = 32, joint = 0, dualchannel = 0;
- int snr = 0, blocks = 16;
+ int snr = 0, blocks = 16, msbc = 0;
- while ((opt = getopt_long(argc, argv, "+hvs:b:jdSB:",
+ while ((opt = getopt_long(argc, argv, "+hmvs:b:jdSB:",
main_options, NULL)) != -1) {
switch(opt) {
case 'h':
@@ -252,6 +254,10 @@ int main(int argc, char *argv[])
verbose = 1;
break;
+ case 'm':
+ msbc = 1;
+ break;
+
case 's':
subbands = atoi(optarg);
if (subbands != 8 && subbands != 4) {
@@ -300,9 +306,18 @@ int main(int argc, char *argv[])
exit(1);
}
+ if (msbc) {
+ subbands = 8;
+ bitpool = 26;
+ joint = 0;
+ dualchannel = 0;
+ snr = 0;
+ blocks = 15;
+ }
+
for (i = 0; i < argc; i++)
encode(argv[i], subbands, bitpool, joint, dualchannel,
- snr, blocks);
+ snr, blocks, msbc);
return 0;
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH v4 13/16] sbc: Update sbcdec for msbc
From: Frédéric Dalleau @ 2012-10-30 9:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1351589975-22640-1-git-send-email-frederic.dalleau@linux.intel.com>
---
src/sbcdec.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/src/sbcdec.c b/src/sbcdec.c
index 0077a82..37d2e98 100644
--- a/src/sbcdec.c
+++ b/src/sbcdec.c
@@ -44,7 +44,7 @@
static int verbose = 0;
-static void decode(char *filename, char *output, int tofile)
+static void decode(char *filename, char *output, int tofile, int msbc)
{
unsigned char buf[BUF_SIZE], *stream;
struct stat st;
@@ -98,7 +98,7 @@ static void decode(char *filename, char *output, int tofile)
goto free;
}
- sbc_init(&sbc, 0L);
+ sbc_init(&sbc, msbc ? SBC_MSBC : 0L);
sbc.endian = SBC_BE;
framelen = sbc_decode(&sbc, stream, streamlen, buf, sizeof(buf), &len);
@@ -228,14 +228,16 @@ static void usage(void)
printf("Options:\n"
"\t-h, --help Display help\n"
- "\t-v, --verbose Verbose mode\n"
"\t-d, --device <dsp> Sound device\n"
+ "\t-v, --verbose Verbose mode\n"
+ "\t-m, --msbc mSBC codec\n"
"\t-f, --file <file> Decode to a file\n"
"\n");
}
static struct option main_options[] = {
{ "help", 0, 0, 'h' },
+ { "msbc", 0, 0, 'm' },
{ "device", 1, 0, 'd' },
{ "verbose", 0, 0, 'v' },
{ "file", 1, 0, 'f' },
@@ -246,8 +248,9 @@ int main(int argc, char *argv[])
{
char *output = NULL;
int i, opt, tofile = 0;
+ int msbc = 0;
- while ((opt = getopt_long(argc, argv, "+hvd:f:",
+ while ((opt = getopt_long(argc, argv, "+hmvd:f:",
main_options, NULL)) != -1) {
switch(opt) {
case 'h':
@@ -258,6 +261,10 @@ int main(int argc, char *argv[])
verbose = 1;
break;
+ case 'm':
+ msbc = 1;
+ break;
+
case 'd':
free(output);
output = strdup(optarg);
@@ -285,7 +292,7 @@ int main(int argc, char *argv[])
}
for (i = 0; i < argc; i++)
- decode(argv[i], output ? output : "/dev/dsp", tofile);
+ decode(argv[i], output ? output : "/dev/dsp", tofile, msbc);
free(output);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v4 12/16] sbc: Add support for mSBC frame header
From: Frédéric Dalleau @ 2012-10-30 9:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1351589975-22640-1-git-send-email-frederic.dalleau@linux.intel.com>
---
sbc/sbc.c | 228 +++++++++++++++++++++++++++++++++++++------------------------
1 file changed, 138 insertions(+), 90 deletions(-)
diff --git a/sbc/sbc.c b/sbc/sbc.c
index 22fa898..cd3fd8c 100644
--- a/sbc/sbc.c
+++ b/sbc/sbc.c
@@ -377,8 +377,8 @@ static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8])
* -3 CRC8 incorrect
* -4 Bitpool value out of bounds
*/
-static int sbc_unpack_frame(const uint8_t *data, struct sbc_frame *frame,
- size_t len)
+static int sbc_unpack_frame_internal(const uint8_t *data,
+ struct sbc_frame *frame, size_t len)
{
unsigned int consumed;
/* Will copy the parts of the header that are relevant to crc
@@ -393,59 +393,6 @@ static int sbc_unpack_frame(const uint8_t *data, struct sbc_frame *frame,
int bits[2][8]; /* bits distribution */
uint32_t levels[2][8]; /* levels derived from that */
- if (len < 4)
- return -1;
-
- if (data[0] != SBC_SYNCWORD)
- return -2;
-
- frame->frequency = (data[1] >> 6) & 0x03;
-
- frame->block_mode = (data[1] >> 4) & 0x03;
- switch (frame->block_mode) {
- case SBC_BLK_4:
- frame->blocks = 4;
- break;
- case SBC_BLK_8:
- frame->blocks = 8;
- break;
- case SBC_BLK_12:
- frame->blocks = 12;
- break;
- case SBC_BLK_16:
- frame->blocks = 16;
- break;
- }
-
- frame->mode = (data[1] >> 2) & 0x03;
- switch (frame->mode) {
- case MONO:
- frame->channels = 1;
- break;
- case DUAL_CHANNEL: /* fall-through */
- case STEREO:
- case JOINT_STEREO:
- frame->channels = 2;
- break;
- }
-
- frame->allocation = (data[1] >> 1) & 0x01;
-
- frame->subband_mode = (data[1] & 0x01);
- frame->subbands = frame->subband_mode ? 8 : 4;
-
- frame->bitpool = data[2];
-
- if ((frame->mode == MONO || frame->mode == DUAL_CHANNEL) &&
- frame->bitpool > 16 * frame->subbands)
- return -4;
-
- if ((frame->mode == STEREO || frame->mode == JOINT_STEREO) &&
- frame->bitpool > 32 * frame->subbands)
- return -4;
-
- /* data[3] is crc, we're checking it later */
-
consumed = 32;
crc_header[0] = data[1];
@@ -546,6 +493,90 @@ static int sbc_unpack_frame(const uint8_t *data, struct sbc_frame *frame,
return consumed >> 3;
}
+static int sbc_unpack_frame(const uint8_t *data,
+ struct sbc_frame *frame, size_t len)
+{
+ if (len < 4)
+ return -1;
+
+ if (data[0] != SBC_SYNCWORD)
+ return -2;
+
+ frame->frequency = (data[1] >> 6) & 0x03;
+ frame->block_mode = (data[1] >> 4) & 0x03;
+
+ switch (frame->block_mode) {
+ case SBC_BLK_4:
+ frame->blocks = 4;
+ break;
+ case SBC_BLK_8:
+ frame->blocks = 8;
+ break;
+ case SBC_BLK_12:
+ frame->blocks = 12;
+ break;
+ case SBC_BLK_16:
+ frame->blocks = 16;
+ break;
+ }
+
+ frame->mode = (data[1] >> 2) & 0x03;
+
+ switch (frame->mode) {
+ case MONO:
+ frame->channels = 1;
+ break;
+ case DUAL_CHANNEL: /* fall-through */
+ case STEREO:
+ case JOINT_STEREO:
+ frame->channels = 2;
+ break;
+ }
+
+ frame->allocation = (data[1] >> 1) & 0x01;
+
+ frame->subband_mode = (data[1] & 0x01);
+ frame->subbands = frame->subband_mode ? 8 : 4;
+
+ frame->bitpool = data[2];
+
+ if ((frame->mode == MONO || frame->mode == DUAL_CHANNEL) &&
+ frame->bitpool > 16 * frame->subbands)
+ return -4;
+
+ if ((frame->mode == STEREO || frame->mode == JOINT_STEREO) &&
+ frame->bitpool > 32 * frame->subbands)
+ return -4;
+
+ return sbc_unpack_frame_internal(data, frame, len);
+}
+
+static int msbc_unpack_frame(const uint8_t *data,
+ struct sbc_frame *frame, size_t len)
+{
+ if (len < 4)
+ return -1;
+
+ if (data[0] != MSBC_SYNCWORD)
+ return -2;
+ if (data[1] != 0)
+ return -2;
+ if (data[2] != 0)
+ return -2;
+
+ frame->frequency = SBC_FREQ_16000;
+ frame->block_mode = SBC_BLK_4;
+ frame->blocks = MSBC_BLOCKS;
+ frame->allocation = LOUDNESS;
+ frame->mode = MONO;
+ frame->channels = 1;
+ frame->subband_mode = 1;
+ frame->subbands = 8;
+ frame->bitpool = 26;
+
+ return sbc_unpack_frame_internal(data, frame, len);
+}
+
static void sbc_decoder_init(struct sbc_decoder_state *state,
const struct sbc_frame *frame)
{
@@ -790,38 +821,6 @@ static SBC_ALWAYS_INLINE ssize_t sbc_pack_frame_internal(uint8_t *data,
uint32_t levels[2][8]; /* levels are derived from that */
uint32_t sb_sample_delta[2][8];
- data[0] = SBC_SYNCWORD;
-
- data[1] = (frame->frequency & 0x03) << 6;
-
- data[1] |= (frame->block_mode & 0x03) << 4;
-
- data[1] |= (frame->mode & 0x03) << 2;
-
- data[1] |= (frame->allocation & 0x01) << 1;
-
- switch (frame_subbands) {
- case 4:
- /* Nothing to do */
- break;
- case 8:
- data[1] |= 0x01;
- break;
- default:
- return -4;
- break;
- }
-
- data[2] = frame->bitpool;
-
- if ((frame->mode == MONO || frame->mode == DUAL_CHANNEL) &&
- frame->bitpool > frame_subbands << 4)
- return -5;
-
- if ((frame->mode == STEREO || frame->mode == JOINT_STEREO) &&
- frame->bitpool > frame_subbands << 5)
- return -5;
-
/* Can't fill in crc yet */
crc_header[0] = data[1];
@@ -889,6 +888,28 @@ static SBC_ALWAYS_INLINE ssize_t sbc_pack_frame_internal(uint8_t *data,
static ssize_t sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len,
int joint)
{
+ int frame_subbands = 4;
+
+ data[0] = SBC_SYNCWORD;
+
+ data[1] = (frame->frequency & 0x03) << 6;
+ data[1] |= (frame->block_mode & 0x03) << 4;
+ data[1] |= (frame->mode & 0x03) << 2;
+ data[1] |= (frame->allocation & 0x01) << 1;
+
+ data[2] = frame->bitpool;
+
+ if (frame->subbands != 4)
+ frame_subbands = 8;
+
+ if ((frame->mode == MONO || frame->mode == DUAL_CHANNEL) &&
+ frame->bitpool > frame_subbands << 4)
+ return -5;
+
+ if ((frame->mode == STEREO || frame->mode == JOINT_STEREO) &&
+ frame->bitpool > frame_subbands << 5)
+ return -5;
+
if (frame->subbands == 4) {
if (frame->channels == 1)
return sbc_pack_frame_internal(
@@ -897,6 +918,7 @@ static ssize_t sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len
return sbc_pack_frame_internal(
data, frame, len, 4, 2, joint);
} else {
+ data[1] |= 0x01;
if (frame->channels == 1)
return sbc_pack_frame_internal(
data, frame, len, 8, 1, joint);
@@ -906,6 +928,16 @@ static ssize_t sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len
}
}
+static ssize_t msbc_pack_frame(uint8_t *data, struct sbc_frame *frame,
+ size_t len, int joint)
+{
+ data[0] = MSBC_SYNCWORD;
+ data[1] = 0;
+ data[2] = 0;
+
+ return sbc_pack_frame_internal(data, frame, len, 8, 1, joint);
+}
+
static void sbc_encoder_init(unsigned long flags,
struct sbc_encoder_state *state, const struct sbc_frame *frame)
{
@@ -921,10 +953,24 @@ struct sbc_priv {
struct SBC_ALIGNED sbc_frame frame;
struct SBC_ALIGNED sbc_decoder_state dec_state;
struct SBC_ALIGNED sbc_encoder_state enc_state;
+ int (*unpack_frame)(const uint8_t *data, struct sbc_frame *frame,
+ size_t len);
+ ssize_t (*pack_frame)(uint8_t *data, struct sbc_frame *frame,
+ size_t len, int joint);
};
static void sbc_set_defaults(sbc_t *sbc, unsigned long flags)
{
+ struct sbc_priv *priv = sbc->priv;
+
+ if (flags & SBC_MSBC) {
+ priv->pack_frame = msbc_pack_frame;
+ priv->unpack_frame = msbc_unpack_frame;
+ } else {
+ priv->pack_frame = sbc_pack_frame;
+ priv->unpack_frame = sbc_unpack_frame;
+ }
+
sbc->flags = flags;
sbc->frequency = SBC_FREQ_44100;
sbc->mode = SBC_MODE_STEREO;
@@ -978,7 +1024,7 @@ SBC_EXPORT ssize_t sbc_decode(sbc_t *sbc, const void *input, size_t input_len,
priv = sbc->priv;
- framelen = sbc_unpack_frame(input, &priv->frame, input_len);
+ framelen = priv->unpack_frame(input, &priv->frame, input_len);
if (!priv->init) {
sbc_decoder_init(&priv->dec_state, &priv->frame);
@@ -1110,13 +1156,15 @@ SBC_EXPORT ssize_t sbc_encode(sbc_t *sbc, const void *input, size_t input_len,
int j = priv->enc_state.sbc_calc_scalefactors_j(
priv->frame.sb_sample_f, priv->frame.scale_factor,
priv->frame.blocks, priv->frame.subbands);
- framelen = sbc_pack_frame(output, &priv->frame, output_len, j);
+ framelen = priv->pack_frame(output,
+ &priv->frame, output_len, j);
} else {
priv->enc_state.sbc_calc_scalefactors(
priv->frame.sb_sample_f, priv->frame.scale_factor,
priv->frame.blocks, priv->frame.channels,
priv->frame.subbands);
- framelen = sbc_pack_frame(output, &priv->frame, output_len, 0);
+ framelen = priv->pack_frame(output,
+ &priv->frame, output_len, 0);
}
if (written)
--
1.7.9.5
^ permalink raw reply related
* [PATCH v4 11/16] sbc: Add SBC_MSBC flag to enable 15 block encoding
From: Frédéric Dalleau @ 2012-10-30 9:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1351589975-22640-1-git-send-email-frederic.dalleau@linux.intel.com>
---
sbc/sbc.c | 23 +++++++++++++++--------
sbc/sbc.h | 3 +++
2 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/sbc/sbc.c b/sbc/sbc.c
index ffdf05d..22fa898 100644
--- a/sbc/sbc.c
+++ b/sbc/sbc.c
@@ -52,6 +52,9 @@
#define SBC_SYNCWORD 0x9C
+#define MSBC_SYNCWORD 0xAD
+#define MSBC_BLOCKS 15
+
/* This structure contains an unpacked SBC frame.
Yes, there is probably quite some unused space herein */
struct sbc_frame {
@@ -903,12 +906,12 @@ static ssize_t sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len
}
}
-static void sbc_encoder_init(struct sbc_encoder_state *state,
- const struct sbc_frame *frame)
+static void sbc_encoder_init(unsigned long flags,
+ struct sbc_encoder_state *state, const struct sbc_frame *frame)
{
memset(&state->X, 0, sizeof(state->X));
state->position = (SBC_X_BUFFER_SIZE - frame->subbands * 9) & ~7;
- state->increment = 4;
+ state->increment = flags & SBC_MSBC ? 1 : 4;
sbc_init_primitives(state);
}
@@ -922,6 +925,7 @@ struct sbc_priv {
static void sbc_set_defaults(sbc_t *sbc, unsigned long flags)
{
+ sbc->flags = flags;
sbc->frequency = SBC_FREQ_44100;
sbc->mode = SBC_MODE_STEREO;
sbc->subbands = SBC_SB_8;
@@ -1057,12 +1061,13 @@ SBC_EXPORT ssize_t sbc_encode(sbc_t *sbc, const void *input, size_t input_len,
priv->frame.subband_mode = sbc->subbands;
priv->frame.subbands = sbc->subbands ? 8 : 4;
priv->frame.block_mode = sbc->blocks;
- priv->frame.blocks = 4 + (sbc->blocks * 4);
+ priv->frame.blocks = sbc->flags & SBC_MSBC ?
+ MSBC_BLOCKS : 4 + (sbc->blocks * 4);
priv->frame.bitpool = sbc->bitpool;
priv->frame.codesize = sbc_get_codesize(sbc);
priv->frame.length = sbc_get_frame_length(sbc);
- sbc_encoder_init(&priv->enc_state, &priv->frame);
+ sbc_encoder_init(sbc->flags, &priv->enc_state, &priv->frame);
priv->init = 1;
} else if (priv->frame.bitpool != sbc->bitpool) {
priv->frame.length = sbc_get_frame_length(sbc);
@@ -1141,7 +1146,7 @@ SBC_EXPORT size_t sbc_get_frame_length(sbc_t *sbc)
return priv->frame.length;
subbands = sbc->subbands ? 8 : 4;
- blocks = 4 + (sbc->blocks * 4);
+ blocks = sbc->flags & SBC_MSBC ? MSBC_BLOCKS : 4 + (sbc->blocks * 4);
channels = sbc->mode == SBC_MODE_MONO ? 1 : 2;
joint = sbc->mode == SBC_MODE_JOINT_STEREO ? 1 : 0;
bitpool = sbc->bitpool;
@@ -1165,7 +1170,8 @@ SBC_EXPORT unsigned sbc_get_frame_duration(sbc_t *sbc)
priv = sbc->priv;
if (!priv->init) {
subbands = sbc->subbands ? 8 : 4;
- blocks = 4 + (sbc->blocks * 4);
+ blocks = sbc->flags & SBC_MSBC ?
+ MSBC_BLOCKS : 4 + (sbc->blocks * 4);
} else {
subbands = priv->frame.subbands;
blocks = priv->frame.blocks;
@@ -1202,7 +1208,8 @@ SBC_EXPORT size_t sbc_get_codesize(sbc_t *sbc)
priv = sbc->priv;
if (!priv->init) {
subbands = sbc->subbands ? 8 : 4;
- blocks = 4 + (sbc->blocks * 4);
+ blocks = sbc->flags & SBC_MSBC ?
+ MSBC_BLOCKS : 4 + (sbc->blocks * 4);
channels = sbc->mode == SBC_MODE_MONO ? 1 : 2;
} else {
subbands = priv->frame.subbands;
diff --git a/sbc/sbc.h b/sbc/sbc.h
index bbd45da..3511119 100644
--- a/sbc/sbc.h
+++ b/sbc/sbc.h
@@ -64,6 +64,9 @@ extern "C" {
#define SBC_LE 0x00
#define SBC_BE 0x01
+/* Additional features */
+#define SBC_MSBC 0x01
+
struct sbc_struct {
unsigned long flags;
--
1.7.9.5
^ permalink raw reply related
* [PATCH v4 10/16] sbc: simd support for 8 multiples block size
From: Frédéric Dalleau @ 2012-10-30 9:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1351589975-22640-1-git-send-email-frederic.dalleau@linux.intel.com>
---
sbc/sbc_primitives.c | 37 ++++++++++++++++++++++++++++++++++++-
1 file changed, 36 insertions(+), 1 deletion(-)
diff --git a/sbc/sbc_primitives.c b/sbc/sbc_primitives.c
index 9311848..b189320 100644
--- a/sbc/sbc_primitives.c
+++ b/sbc/sbc_primitives.c
@@ -309,8 +309,26 @@ static SBC_ALWAYS_INLINE int sbc_encoder_process_input_s8_internal(
#define PCM(i) (big_endian ? \
unaligned16_be(pcm + (i) * 2) : unaligned16_le(pcm + (i) * 2))
+ if (position % 16 == 8) {
+ position -= 8;
+ nsamples -= 8;
+ if (nchannels > 0) {
+ int16_t *x = &X[0][position];
+ x[0] = PCM(0 + (15-8) * nchannels);
+ x[2] = PCM(0 + (14-8) * nchannels);
+ x[3] = PCM(0 + (8-8) * nchannels);
+ x[4] = PCM(0 + (13-8) * nchannels);
+ x[5] = PCM(0 + (9-8) * nchannels);
+ x[6] = PCM(0 + (12-8) * nchannels);
+ x[7] = PCM(0 + (10-8) * nchannels);
+ x[8] = PCM(0 + (11-8) * nchannels);
+ }
+ /* mSBC is designed for 1 channel */
+ pcm += 16 * nchannels;
+ }
+
/* copy/permutate audio samples */
- while ((nsamples -= 16) >= 0) {
+ while (nsamples >= 16) {
position -= 16;
if (nchannels > 0) {
int16_t *x = &X[0][position];
@@ -351,6 +369,23 @@ static SBC_ALWAYS_INLINE int sbc_encoder_process_input_s8_internal(
x[15] = PCM(1 + 2 * nchannels);
}
pcm += 32 * nchannels;
+ nsamples -= 16;
+ }
+
+ if (nsamples == 8) {
+ position -= 8;
+ if (nchannels > 0) {
+ int16_t *x = &X[0][position];
+ x[-7] = PCM(0 + 7 * nchannels);
+ x[1] = PCM(0 + 3 * nchannels);
+ x[2] = PCM(0 + 6 * nchannels);
+ x[3] = PCM(0 + 0 * nchannels);
+ x[4] = PCM(0 + 5 * nchannels);
+ x[5] = PCM(0 + 1 * nchannels);
+ x[6] = PCM(0 + 4 * nchannels);
+ x[7] = PCM(0 + 2 * nchannels);
+ }
+ /* mSBC is designed for 1 channel */
}
#undef PCM
--
1.7.9.5
^ permalink raw reply related
* [PATCH v4 09/16] sbc: Use simd primitive if doing msbc on neon
From: Frédéric Dalleau @ 2012-10-30 9:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1351589975-22640-1-git-send-email-frederic.dalleau@linux.intel.com>
---
sbc/sbc_primitives.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/sbc/sbc_primitives.c b/sbc/sbc_primitives.c
index a4767ef..9311848 100644
--- a/sbc/sbc_primitives.c
+++ b/sbc/sbc_primitives.c
@@ -568,5 +568,8 @@ void sbc_init_primitives(struct sbc_encoder_state *state)
#endif
#ifdef SBC_BUILD_WITH_NEON_SUPPORT
sbc_init_primitives_neon(state);
+
+ if (state->increment == 1)
+ state->sbc_analyze_8s = sbc_analyze_1b_8s_simd;
#endif
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH v4 08/16] sbc: Add simd primitive for 1b 8s analysis
From: Frédéric Dalleau @ 2012-10-30 9:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1351589975-22640-1-git-send-email-frederic.dalleau@linux.intel.com>
---
sbc/sbc_primitives.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/sbc/sbc_primitives.c b/sbc/sbc_primitives.c
index 0b48ddb..a4767ef 100644
--- a/sbc/sbc_primitives.c
+++ b/sbc/sbc_primitives.c
@@ -209,6 +209,19 @@ static inline void sbc_analyze_4b_8s_simd(struct sbc_encoder_state *state,
sbc_analyze_eight_simd(x + 0, out, analysis_consts_fixed8_simd_even);
}
+static inline void sbc_analyze_1b_8s_simd(struct sbc_encoder_state *state,
+ int16_t *x, int32_t *out, int out_stride)
+{
+ if (state->odd)
+ sbc_analyze_eight_simd(x, out,
+ analysis_consts_fixed8_simd_odd);
+ else
+ sbc_analyze_eight_simd(x, out,
+ analysis_consts_fixed8_simd_even);
+
+ state->odd = !state->odd;
+}
+
static inline int16_t unaligned16_be(const uint8_t *ptr)
{
return (int16_t) ((ptr[0] << 8) | ptr[1]);
@@ -525,7 +538,10 @@ void sbc_init_primitives(struct sbc_encoder_state *state)
/* Default implementation for analyze functions */
state->sbc_analyze_4s = sbc_analyze_4b_4s_simd;
- state->sbc_analyze_8s = sbc_analyze_4b_8s_simd;
+ if (state->increment == 1)
+ state->sbc_analyze_8s = sbc_analyze_1b_8s_simd;
+ else
+ state->sbc_analyze_8s = sbc_analyze_4b_8s_simd;
/* Default implementation for input reordering / deinterleaving */
state->sbc_enc_process_input_4s_le = sbc_enc_process_input_4s_le;
--
1.7.9.5
^ permalink raw reply related
* [PATCH v4 07/16] sbc: Add iwmmxt primitive for 1b 8s encoding
From: Frédéric Dalleau @ 2012-10-30 9:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1351589975-22640-1-git-send-email-frederic.dalleau@linux.intel.com>
---
sbc/sbc_primitives_iwmmxt.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/sbc/sbc_primitives_iwmmxt.c b/sbc/sbc_primitives_iwmmxt.c
index 0c8f329..44bfd47 100644
--- a/sbc/sbc_primitives_iwmmxt.c
+++ b/sbc/sbc_primitives_iwmmxt.c
@@ -294,10 +294,26 @@ static inline void sbc_analyze_4b_8s_iwmmxt(struct sbc_encoder_state *state,
sbc_analyze_eight_iwmmxt(x + 0, out, analysis_consts_fixed8_simd_even);
}
+static inline void sbc_analyze_1b_8s_iwmmxt(struct sbc_encoder_state *state,
+ int16_t *x, int32_t *out, int out_stride)
+{
+ if (state->odd)
+ sbc_analyze_eight_iwmmxt(x, out,
+ analysis_consts_fixed8_simd_odd);
+ else
+ sbc_analyze_eight_iwmmxt(x, out,
+ analysis_consts_fixed8_simd_even);
+
+ state->odd = !state->odd;
+}
+
void sbc_init_primitives_iwmmxt(struct sbc_encoder_state *state)
{
state->sbc_analyze_4s = sbc_analyze_4b_4s_iwmmxt;
- state->sbc_analyze_8s = sbc_analyze_4b_8s_iwmmxt;
+ if (state->increment == 1)
+ state->sbc_analyze_8s = sbc_analyze_1b_8s_iwmmxt;
+ else
+ state->sbc_analyze_8s = sbc_analyze_4b_8s_iwmmxt;
state->implementation_info = "IWMMXT";
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH v4 06/16] sbc: Add armv6 primitive for 1b 8s analysis
From: Frédéric Dalleau @ 2012-10-30 9:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1351589975-22640-1-git-send-email-frederic.dalleau@linux.intel.com>
---
sbc/sbc_primitives_armv6.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/sbc/sbc_primitives_armv6.c b/sbc/sbc_primitives_armv6.c
index 068648a..a2cb2a8 100644
--- a/sbc/sbc_primitives_armv6.c
+++ b/sbc/sbc_primitives_armv6.c
@@ -291,10 +291,26 @@ static void sbc_analyze_4b_8s_armv6(struct sbc_encoder_state *state,
sbc_analyze_eight(x + 0, out, analysis_consts_fixed8_simd_even);
}
+static void sbc_analyze_1b_8s_armv6(struct sbc_encoder_state *state,
+ int16_t *x, int32_t *out, int out_stride)
+{
+ if (state->odd)
+ sbc_analyze_eight_armv6(x, out,
+ analysis_consts_fixed8_simd_odd);
+ else
+ sbc_analyze_eight_armv6(x, out,
+ analysis_consts_fixed8_simd_even);
+
+ state->odd = !state->odd;
+}
+
void sbc_init_primitives_armv6(struct sbc_encoder_state *state)
{
state->sbc_analyze_4s = sbc_analyze_4b_4s_armv6;
- state->sbc_analyze_8s = sbc_analyze_4b_8s_armv6;
+ if (state->increment == 1)
+ state->sbc_analyze_8s = sbc_analyze_1b_8s_armv6;
+ else
+ state->sbc_analyze_8s = sbc_analyze_4b_8s_armv6;
state->implementation_info = "ARMv6 SIMD";
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH v4 05/16] sbc: Add mmx primitive for 1b 8s analysis
From: Frédéric Dalleau @ 2012-10-30 9:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1351589975-22640-1-git-send-email-frederic.dalleau@linux.intel.com>
---
sbc/sbc_primitives_mmx.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/sbc/sbc_primitives_mmx.c b/sbc/sbc_primitives_mmx.c
index 03070f5..21d7b74 100644
--- a/sbc/sbc_primitives_mmx.c
+++ b/sbc/sbc_primitives_mmx.c
@@ -276,6 +276,19 @@ static inline void sbc_analyze_4b_8s_mmx(struct sbc_encoder_state *state,
__asm__ volatile ("emms\n");
}
+static inline void sbc_analyze_1b_8s_mmx(struct sbc_encoder_state *state,
+ int16_t *x, int32_t *out, int out_stride)
+{
+ if (state->odd)
+ sbc_analyze_eight_mmx(x, out, analysis_consts_fixed8_simd_odd);
+ else
+ sbc_analyze_eight_mmx(x, out, analysis_consts_fixed8_simd_even);
+
+ state->odd = !state->odd;
+
+ __asm__ volatile ("emms\n");
+}
+
static void sbc_calc_scalefactors_mmx(
int32_t sb_sample_f[16][2][8],
uint32_t scale_factor[2][8],
@@ -366,7 +379,10 @@ void sbc_init_primitives_mmx(struct sbc_encoder_state *state)
{
if (check_mmx_support()) {
state->sbc_analyze_4s = sbc_analyze_4b_4s_mmx;
- state->sbc_analyze_8s = sbc_analyze_4b_8s_mmx;
+ if (state->increment == 1)
+ state->sbc_analyze_8s = sbc_analyze_1b_8s_mmx;
+ else
+ state->sbc_analyze_8s = sbc_analyze_4b_8s_mmx;
state->sbc_calc_scalefactors = sbc_calc_scalefactors_mmx;
state->implementation_info = "MMX";
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH v4 04/16] sbc: add odd member variable to sbc_encoder_state
From: Frédéric Dalleau @ 2012-10-30 9:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Frédéric Dalleau
In-Reply-To: <1351589975-22640-1-git-send-email-frederic.dalleau@linux.intel.com>
---
sbc/sbc_primitives.c | 2 ++
sbc/sbc_primitives.h | 1 +
2 files changed, 3 insertions(+)
diff --git a/sbc/sbc_primitives.c b/sbc/sbc_primitives.c
index dce0ed2..0b48ddb 100644
--- a/sbc/sbc_primitives.c
+++ b/sbc/sbc_primitives.c
@@ -521,6 +521,8 @@ static int sbc_calc_scalefactors_j(
*/
void sbc_init_primitives(struct sbc_encoder_state *state)
{
+ state->odd = 1;
+
/* Default implementation for analyze functions */
state->sbc_analyze_4s = sbc_analyze_4b_4s_simd;
state->sbc_analyze_8s = sbc_analyze_4b_8s_simd;
diff --git a/sbc/sbc_primitives.h b/sbc/sbc_primitives.h
index 267c277..ffee339 100644
--- a/sbc/sbc_primitives.h
+++ b/sbc/sbc_primitives.h
@@ -40,6 +40,7 @@ struct sbc_encoder_state {
int position;
/* Number of consecutive blocks handled by the encoder */
int increment;
+ int odd;
int16_t SBC_ALIGNED X[2][SBC_X_BUFFER_SIZE];
/* Polyphase analysis filter for 4 subbands configuration,
* it handles "increment" blocks at once */
--
1.7.9.5
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox