HaaS100主芯片是一块高性能SoC,其内置了蓝牙4.2双模芯片,支持经典蓝牙和BLE低功耗蓝牙。那能不能用HaaS100打造一台蓝牙音箱呢?
答案是肯定的。本文就将介绍如何使用HaaS100来动手打造一台蓝牙音箱。
HaaS100开发板内置了内置了蓝牙4.2双模芯片,手机可以通过蓝牙与HaaS100建立蓝牙连接。只要在HaaS100上实现蓝牙中A2DP Profile(这是一个专门用蓝牙来传输音频的Profile,苹果手机和Android手机都默认支持这个功能),就可以接收手机传过来的蓝牙音频数据,然后在外接一个喇叭,就能将音乐播放出来啦。
如下图所示。
HaaS100的软件包里面包含了双模蓝牙协议栈,位于如下路径:
components/wireless/bluetooth/bt_stack
用户可以使用这个蓝牙协议栈来操作蓝牙模块,打造自己的蓝牙音箱。
要在自己的应用中使用蓝牙模块,需要如下几步
之后,即可以在应用中调用协议栈的接口来开启蓝牙音频。协议栈的接口基本位于
host/bluedroid/api,接口类似yoc_XXX。
与蓝牙音频相关的接口包括如下:
通过调用这些接口组合,即可让我们的HaaS开发板有了蓝牙音频能力。但蓝牙协议栈复杂,接口众多,需要调用大量的API才能实现蓝牙音频播放。
有没有简单的方法打造一台蓝牙音箱呢?请继续往下看。
为了方便开发者试用,我们已经为开发者准备了一个蓝牙音箱的demo,位于如下路径
application/example/classicBT_demo
用户执行如下指令进行编译
aos make classicBT_demo@haas100 -c config
aos make
编译后生成的固件烧录进开发板。
经典蓝牙初始化
经典蓝牙初始化,包括如下几个步骤,
使用蓝牙协议栈时,需要先做如下调用。
参考代码如下:
err = yoc_bluedroid_init();
if (err != BT_OK) {
EXAMPLE_TRACE_ERROR("yoc_bluedroid_init err= %d", err);
return;
}
err = yoc_bt_gap_register_callback(example_classicBT_gap_cb);
if (err){
EXAMPLE_TRACE_ERROR("gap register error, error code = %x", err);
return;
}
err = yoc_bluedroid_enable();
if (err != BT_OK) {
EXAMPLE_TRACE_ERROR("yoc_bluedroid_enable err= %d", err);
return;
}
用于设置蓝牙名称,长度不超过255字节,读者可自行设置。
参考代码如下:
/* device name */
#define EXAMPLE_CLASSICBT_DEV_NAME "HaaS BT"
char *device_name = EXAMPLE_CLASSICBT_DEV_NAME;
yoc_bt_dev_set_device_name(device_name);
设置为可发现可连接模式,否则无法在手机上搜索并连接设备,读者可以根据应用场景来设置可连接性与可发现性,比如需要在某个按键操作下才可以进入此状态。
参考代码如下
/* scan mode set */
{
yoc_bt_connection_mode_t conn;
yoc_bt_discovery_mode_t disc;
conn = YOC_BT_CONNECTABLE;
disc = YOC_BT_GENERAL_DISCOVERABLE;
err = yoc_bt_gap_set_scan_mode(conn, disc);
if (err != BT_OK) {
EXAMPLE_TRACE_ERROR("scan mode set err= %d", err);
}
}
A2DP服务是即蓝牙音乐服务,使用此服务时需要在协议栈中初始化
yoc_a2d_register_callback(example_classicBT_a2dp_cb);
yoc_a2d_sink_register_data_callback(example_classicBT_a2dp_data_cb);
yoc_a2d_sink_init();
蓝牙协议栈是基于事件回调的,应用层可以根据应用需求处理GAP的回调和A2DP的回调,参考用例中,回调基本用于状态记录以及打印,读者可以根据应用场景增加LED灯,然后根据返回状态闪烁不同的灯。
如下代码A2DP状态回调,其中event =YOC_A2D_CONNECTION_STATE_EVT代表,A2DP连接事件,可据根据p_param中的参数获取是连接还是断开。
static void example_classicBT_a2dp_cb(uint16_t event, void *p_param)
{
yoc_a2d_cb_param_t *a2d = NULL;
EXAMPLE_TRACE_DEBUG("%s evt %d", __func__, event);
switch (event) {
case YOC_A2D_CONNECTION_STATE_EVT:
{
uint8_t *bda;
a2d = (yoc_a2d_cb_param_t *)(p_param);
bda = a2d->conn_stat.remote_bda;
EXAMPLE_TRACE_DEBUG("A2DP connection state: %d, [%02x:%02x:%02x:%02x:%02x:%02x]",
a2d->conn_stat.state, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
if (a2d->conn_stat.state == YOC_A2D_CONNECTION_STATE_DISCONNECTED) {
if (a2d->conn_stat.disc_rsn == YOC_A2D_DISC_RSN_NORMAL) {
example_classicBT_a2dp_state_cb(EXAMPLE_CLASSICBT_A2DP_DISCONNECTED, bda);
} else {
example_classicBT_a2dp_state_cb(EXAMPLE_CLASSICBT_A2DP_LINK_LOSS, bda);
}
} else if (a2d->conn_stat.state == YOC_A2D_CONNECTION_STATE_CONNECTED) {
example_classicBT_a2dp_state_cb(EXAMPLE_CLASSICBT_A2DP_CONNECTED, bda);
} else if (a2d->conn_stat.state == YOC_A2D_CONNECTION_STATE_CONNECTING) {
example_classicBT_a2dp_state_cb(EXAMPLE_CLASSICBT_A2DP_CONNECTING, bda);
}
break;
}
软件编译烧录后,是不是就可以播放了呢?硬件还有注意点:
首先,需要接上蓝牙天线,不接容易引发卡顿,连接不畅等问题,接线方式如下图所示
另外,HaaS100上缺乏喇叭,声音无法输出,我们需要找一个,这类喇叭可以在淘宝等网站较为容易的找到,建议找功率在2W左右。
然后我们根据HaaS的接线图,找到排针接口的26PIN和28PIN,如下图
这2根引脚是音频功放的输出,可以直接接到喇叭的输入,如下图
这样硬件准备工作就做好了。
程序启动后,蓝牙初始化成功并等待用户手机连接。
手机打开系统蓝牙设置界面,搜索周边蓝牙设备,可看到“HaaS BT”的蓝牙设备,如下图所示。
点击连接,弹出配对提示框,点击配对后蓝牙连接成功。
打开手机的音乐播放器,播放音乐,即可听到音乐在HaaS100的开发板上播放了。
这一章节,我们介绍一下蓝牙的音频协议A2DP。
蓝牙音频协议A2DP是蓝牙的高质量音频传输协议,有约20年历史的协议标准了,使用广泛,各类无线耳机,音箱,车载都使用了A2DP协议。到苹果airpods热卖后,蓝牙音频更是一片火热。
事实上,蓝牙诞生20多年,协议标准从1.0到5.2,A2DP协议并没有太多的技术升级,A2DP的整体架构如下
A2DP定义了Source和Sink2个角色,其中Source是音频的传输端,一般就是手机,电脑;Sink是音频的接收端,一般就是各类耳机和音箱了。
A2DP协议是一个上层协议,其利用AVDTP作为传输通道,利用SDP作为服务发现通道。而作为A2DP业务承载的AVDTP传输通道又分为Signalling信令通道和Stream音频流通道。信令通道传输控制与播放参数协商命令,而音频流通道则用于音频数据的传输。
A2DP音频原本是作为蓝牙的高质量音频协议存在的,但早期蓝牙标准组织为了保证传输带宽的平稳,同时也为了降低耳机的解码难度,选择了SBC作为音频编解码传输的主要标准。SBC带宽占用较大而音质效果一般,达不到高质量标准,虽然A2DP也支持一些可选的编解码器比如MP3,TRACK3等,但支持度都比较差,效果也有限,之后不少厂商提出了私有的新编解码器来提升音质,比如高通的APTX,索尼的LDAC等,并将编码器集成进了android新版本中。目前很多android手机均支持这些编码器,只要耳机音箱支持,即可开启这些编码器来提升音质。
目前HaaS仅支持SBC作为编解码器,后续可以根据业务需求实现诸如LDAC等高品质音频。
如需更多技术支持,可加入钉钉开发者群,或者关注微信公众号
更多技术与解决方案介绍,请访问阿里云AIoT首页https://iot.aliyun.com/