您尚未登录。

楼主 #1 2017-10-16 22:22:30

goodgoodstudy
会员
注册时间: 2017-09-15
已发帖子: 61
积分: 61

ESP32 的 A2DP只有 SINK例程, 为什么没有Source例程,我们公司急需一个蓝牙喇叭发射端(Source)

有没有哪位大神搞定的,
酬谢!

离线

#2 2018-05-03 09:01:36

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,223
积分: 9197

Re: ESP32 的 A2DP只有 SINK例程, 为什么没有Source例程,我们公司急需一个蓝牙喇叭发射端(Source)

QQ20180503090010.png

// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "common/bt_target.h"
#include <string.h>
#include "esp_err.h"
#include "esp_a2dp_api.h"
#include "esp_bt_main.h"
#include "btc/btc_manage.h"
#include "btc_av.h"

#if BTC_AV_INCLUDED

#if BTC_AV_SINK_INCLUDED
esp_err_t esp_a2d_sink_init(void)
{
    if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
        return ESP_ERR_INVALID_STATE;
    }

    btc_msg_t msg;

    msg.sig = BTC_SIG_API_CALL;
    msg.pid = BTC_PID_A2DP;
    msg.act = BTC_AV_SINK_API_INIT_EVT;

    /* Switch to BTC context */
    bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
    return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}

esp_err_t esp_a2d_sink_deinit(void)
{
    if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
        return ESP_ERR_INVALID_STATE;
    }

    btc_msg_t msg;

    msg.sig = BTC_SIG_API_CALL;
    msg.pid = BTC_PID_A2DP;
    msg.act = BTC_AV_SINK_API_DEINIT_EVT;

    /* Switch to BTC context */
    bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
    return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}

esp_err_t esp_a2d_sink_register_data_callback(esp_a2d_sink_data_cb_t callback)
{
    if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
        return ESP_ERR_INVALID_STATE;
    }

    btc_msg_t msg;
    msg.sig = BTC_SIG_API_CALL;
    msg.pid = BTC_PID_A2DP;
    msg.act = BTC_AV_SINK_API_REG_DATA_CB_EVT;

    btc_av_args_t arg;
    memset(&arg, 0, sizeof(btc_av_args_t));
    arg.data_cb = callback;

    /* Switch to BTC context */
    bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL);
    return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}

esp_err_t esp_a2d_sink_connect(esp_bd_addr_t remote_bda)
{
    if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
        return ESP_ERR_INVALID_STATE;
    }

    bt_status_t stat;
    btc_av_args_t arg;
    btc_msg_t msg;

    msg.sig = BTC_SIG_API_CALL;
    msg.pid = BTC_PID_A2DP;
    msg.act = BTC_AV_SINK_API_CONNECT_EVT;

    memset(&arg, 0, sizeof(btc_av_args_t));

    /* Switch to BTC context */
    memcpy(&(arg.connect), remote_bda, sizeof(bt_bdaddr_t));
    stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL);
    return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}

esp_err_t esp_a2d_sink_disconnect(esp_bd_addr_t remote_bda)
{
    if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
        return ESP_ERR_INVALID_STATE;
    }

    bt_status_t stat;
    btc_msg_t msg;

    msg.sig = BTC_SIG_API_CALL;
    msg.pid = BTC_PID_A2DP;
    msg.act = BTC_AV_SINK_API_DISCONNECT_EVT;

    /* Switch to BTC context */
    stat = btc_transfer_context(&msg, NULL, 0, NULL);
    return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}

#endif /* BTC_AV_SINK_INCLUDED */

esp_err_t esp_a2d_register_callback(esp_a2d_cb_t callback)
{
    if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
        return ESP_ERR_INVALID_STATE;
    }

    if (callback == NULL) {
        return ESP_FAIL;
    }

    btc_profile_cb_set(BTC_PID_A2DP, callback);
    return ESP_OK;
}

esp_err_t esp_a2d_media_ctrl(esp_a2d_media_ctrl_t ctrl)
{
    if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
        return ESP_ERR_INVALID_STATE;
    }

    bt_status_t stat;
    btc_av_args_t arg;
    btc_msg_t msg;

    msg.sig = BTC_SIG_API_CALL;
    msg.pid = BTC_PID_A2DP;
    msg.act = BTC_AV_API_MEDIA_CTRL_EVT;

    memset(&arg, 0, sizeof(btc_av_args_t));

    /* Switch to BTC context */
    arg.ctrl = ctrl;
    stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL);
    return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}

#if BTC_AV_SRC_INCLUDED
esp_err_t esp_a2d_source_init(void)
{
    if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
        return ESP_ERR_INVALID_STATE;
    }

    btc_msg_t msg;

    msg.sig = BTC_SIG_API_CALL;
    msg.pid = BTC_PID_A2DP;
    msg.act = BTC_AV_SRC_API_INIT_EVT;

    /* Switch to BTC context */
    bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
    return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}

esp_err_t esp_a2d_source_deinit(void)
{
    if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
        return ESP_ERR_INVALID_STATE;
    }

    btc_msg_t msg;

    msg.sig = BTC_SIG_API_CALL;
    msg.pid = BTC_PID_A2DP;
    msg.act = BTC_AV_SRC_API_DEINIT_EVT;

    /* Switch to BTC context */
    bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
    return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}

esp_err_t esp_a2d_source_connect(esp_bd_addr_t remote_bda)
{
    if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
        return ESP_ERR_INVALID_STATE;
    }

    bt_status_t stat;
    btc_av_args_t arg;
    btc_msg_t msg;

    msg.sig = BTC_SIG_API_CALL;
    msg.pid = BTC_PID_A2DP;
    msg.act = BTC_AV_SRC_API_CONNECT_EVT;

    memset(&arg, 0, sizeof(btc_av_args_t));

    /* Switch to BTC context */
    memcpy(&(arg.src_connect), remote_bda, sizeof(bt_bdaddr_t));
    stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL);
    return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}

esp_err_t esp_a2d_source_disconnect(esp_bd_addr_t remote_bda)
{
    if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
        return ESP_ERR_INVALID_STATE;
    }

    bt_status_t stat;
    btc_msg_t msg;

    msg.sig = BTC_SIG_API_CALL;
    msg.pid = BTC_PID_A2DP;
    msg.act = BTC_AV_SRC_API_DISCONNECT_EVT;

    /* Switch to BTC context */
    stat = btc_transfer_context(&msg, NULL, 0, NULL);
    return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}

esp_err_t esp_a2d_source_register_data_callback(esp_a2d_source_data_cb_t callback)
{
    if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
        return ESP_ERR_INVALID_STATE;
    }

    btc_msg_t msg;
    msg.sig = BTC_SIG_API_CALL;
    msg.pid = BTC_PID_A2DP;
    msg.act = BTC_AV_SRC_API_REG_DATA_CB_EVT;

    btc_av_args_t arg;
    memset(&arg, 0, sizeof(btc_av_args_t));
    arg.src_data_cb = callback;

    /* Switch to BTC context */
    bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL);
    return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}

#endif /* BTC_AV_SRC_INCLUDED */

#endif /* #if BTC_AV_INCLUDED */

这个问题已经在 master 主分支实现了,但是并没有并入到任何稳定版本中。
估计是很少有用户有这种需求吧.





离线

#3 2018-05-03 19:44:26

晕哥
管理员
所在地: 微信 whycan_cn
注册时间: 2017-09-06
已发帖子: 9,223
积分: 9197

Re: ESP32 的 A2DP只有 SINK例程, 为什么没有Source例程,我们公司急需一个蓝牙喇叭发射端(Source)

打开 main.c
找到字符串 "ESP_SPEAKER"
改为小米蓝牙喇叭的 "NDZ-03-GA"

QQ20180503193848.png

连接小米蓝牙喇叭没有问题, 连上之后全是噪音。





离线

#4 2018-06-25 22:46:07

szxxbb
会员
注册时间: 2018-06-25
已发帖子: 3
积分: 3

Re: ESP32 的 A2DP只有 SINK例程, 为什么没有Source例程,我们公司急需一个蓝牙喇叭发射端(Source)

连上之后是噪音的原来是程序就是发随机数。
static int32_t bt_app_a2d_data_cb(uint8_t *data, int32_t len)
{
    if (len < 0 || data == NULL) {
        return 0;
    }

    // generate random sequence
    int val = rand() % (1 << 16);
    for (int i = 0; i < (len >> 1); i++) {
        data[(i << 1)] = val & 0xff;
        data[(i << 1) + 1] = (val >> 8) & 0xff;
    }

    return len;
}

离线

#5 2018-06-25 22:47:40

szxxbb
会员
注册时间: 2018-06-25
已发帖子: 3
积分: 3

Re: ESP32 的 A2DP只有 SINK例程, 为什么没有Source例程,我们公司急需一个蓝牙喇叭发射端(Source)

我遇到的问题是,如果旁边有几个设备都开通蓝牙,特别是手机开通蓝牙,这个demo查询蓝牙设备就会反复查到手机蓝牙,而不太容易查到蓝牙耳机。

离线

#6 2018-06-26 08:33:42

awfans
会员
注册时间: 2018-04-03
已发帖子: 264
积分: 264

Re: ESP32 的 A2DP只有 SINK例程, 为什么没有Source例程,我们公司急需一个蓝牙喇叭发射端(Source)

szxxbb 说:

我遇到的问题是,如果旁边有几个设备都开通蓝牙,特别是手机开通蓝牙,这个demo查询蓝牙设备就会反复查到手机蓝牙,而不太容易查到蓝牙耳机。

估计和信道满员(瞎猜的)有关,你会发现半夜的时候 WIFI信号会比白天好很多,因为你楼上楼下的邻居已经熟睡,不占用信道。

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn