andrzej-kaczmarek commented on code in PR #1659:
URL: https://github.com/apache/mynewt-nimble/pull/1659#discussion_r1423649726


##########
apps/auracast_usb/include/usb_audio.h:
##########
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+#ifndef H_USB_AUDIO_
+#define H_USB_AUDIO_
+
+#include <stdint.h>
+
+typedef void (* usb_audio_sample_rate_cb_t)(uint32_t);
+
+/* Set default sample rate, should only be used before USB is initialized */
+void usb_desc_sample_rate_set(uint32_t sample_rate);
+
+/* Set callback to receive sample rate set by USB host */
+void usb_audio_sample_rate_cb_set(usb_audio_sample_rate_cb_t cb);
+
+/* Get current sample rate */
+uint32_t usb_audio_sample_rate_get(void);

Review Comment:
   we don't need those if we set USB to support 1 sample rate only



##########
apps/auracast_usb/syscfg.yml:
##########
@@ -0,0 +1,115 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+
+syscfg.defs:
+    AURACAST_CHAN_NUM: 2
+
+    BROADCAST_ID:
+        description: Broadcast ID value, will use random number if 0
+        value: 0x000000
+    BROADCAST_NAME:
+        description: Broadcast name
+        value: '"NimBLE Auracast"'
+    BROADCAST_CODE:
+        description: Broadcast code used for encrpytion
+        value: '"listen2nimble"'
+
+    LC3_FRAME_DURATION:
+        description: LC3 frame duration
+        value: 10000
+    LC3_SAMPLING_FREQ:
+        description: LC3 sampling frequency
+        value: 48000
+    LC3_BITRATE:
+        description: LC3 bitrate
+        value: 96000
+
+    BIG_PHY:
+        description:
+        value: 3
+    BIG_NUM_BIS:
+        description: Max number of BISes used
+        value: 2
+    BIG_RTN:
+        description: BIG RTN (number of retransmissions)
+        value: 0
+    BIG_PACKING:
+        description: Arrangement of BIS subevents (0 = sequential, 1 = 
interleaved)
+        value: 0
+    BIG_FRAMING:
+        description:
+        value: 0
+    BIG_ENCRYPTION:
+        description: BIS encryption
+        value: 1
+
+syscfg.vals:
+    CONSOLE_IMPLEMENTATION: full
+    LOG_IMPLEMENTATION: full
+    STATS_IMPLEMENTATION: full
+
+    # Disable not used GAP roles (we only do non-connectable
+    # advertising here)
+    BLE_ROLE_BROADCASTER: 1
+    BLE_ROLE_CENTRAL: 0
+    BLE_ROLE_OBSERVER: 0
+    BLE_ROLE_PERIPHERAL: 0
+
+    # Enable Extended Advertising
+    BLE_EXT_ADV: 1
+
+    # Enable Periodic Advertising
+    BLE_PERIODIC_ADV: 1
+
+    # Max advertising data size
+    BLE_EXT_ADV_MAX_SIZE: 261
+
+    # Number of multi-advertising instances. Note that due
+    # to historical reasonds total number of advertising
+    # instances is BLE_MULTI_ADV_INSTANCES + 1 as instance
+    # 0 is always available
+    BLE_MULTI_ADV_INSTANCES: 1
+
+    # Controller uses msys pool for storing advertising data and scan 
responses.
+    # Since we advertise a lot of data (~6k in total) at the same time we need
+    # to increase block count.
+    MSYS_1_BLOCK_COUNT: 32
+
+    BLE_PHY_2M: 1
+
+    BLE_VERSION: 54
+    BLE_ISO: 1
+    BLE_ISO_BROADCASTER: 1
+    BLE_MAX_BIG: 1
+    BLE_MAX_BIS: 2
+
+    BLE_PHY_NRF52_HEADERMASK_WORKAROUND: 1

Review Comment:
   this is only valid for nrf52



##########
apps/auracast_usb/src/audio_usb.c:
##########
@@ -0,0 +1,236 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 <assert.h>
+#include <string.h>
+#include <stdint.h>
+#include <syscfg/syscfg.h>
+#include <hal/hal_gpio.h>
+#include <bsp/bsp.h>
+
+#include <os/os.h>
+#include <common/tusb_fifo.h>
+#include <class/audio/audio_device.h>
+#include <usb_audio.h>
+
+#include <lc3.h>
+#include <nrf_clock.h>
+
+#include <nimble/hci_common.h>
+#include <nimble/transport.h>
+#include "host/ble_gap.h"
+
+#include "app_priv.h"
+
+#if 1
+#define TP_PIN_ENCODE       LED_1
+#define TP_PIN_DATA_CB      LED_2
+#define TP_PIN_DATA_IN      LED_3
+#define TP_PIN_DATA_ISR     0
+#else
+#define TP_PIN_ENCODE       0
+#define TP_PIN_DATA_CB      0
+#define TP_PIN_DATA_IN      0
+#define TP_PIN_DATA_ISR     0
+#endif
+
+#define TP_INIT(_pin)       (TP_PIN_ ## _pin ? \
+                             hal_gpio_init_out(TP_PIN_ ## _pin, 0) : (void)0)
+#define TP_1(_pin)          (TP_PIN_ ## _pin ? \
+                             hal_gpio_write(TP_PIN_ ## _pin, 1) : (void)0)
+#define TP_0(_pin)          (TP_PIN_ ## _pin ? \
+                             hal_gpio_write(TP_PIN_ ## _pin, 0) : (void)0)

Review Comment:
   remove, this was only added for testing



##########
apps/auracast_usb/src/main.c:
##########
@@ -0,0 +1,349 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 "console/console.h"
+#include "config/config.h"
+
+#include "nimble/ble.h"
+#include "host/ble_hs.h"
+#include "host/util/util.h"
+
+#include "services/auracast/ble_svc_auracast.h"
+
+#include "hal/hal_gpio.h"
+#include "bsp/bsp.h"
+#include "app_priv.h"
+
+#define BROADCAST_SID                       1
+#define BROADCAST_SDU_INTVL                 MYNEWT_VAL(LC3_FRAME_DURATION)
+#define BROADCAST_SAMPLE_RATE               BLE_AUDIO_SAMPLING_RATE_48000_HZ
+#define BROADCAST_MAX_SDU                   (BROADCAST_SDU_INTVL * \
+                                             MYNEWT_VAL(LC3_BITRATE) / \
+                                             (1000 * 1000 * 8))
+
+#define BROADCASTER_INTERRUPT_TASK_PRIO  4
+#define BROADCASTER_INTERRUPT_TASK_STACK_SZ    512
+
+static uint8_t id_addr_type;
+
+static struct ble_audio_base auracast_base;
+static struct ble_audio_big_subgroup big_subgroup;
+
+static os_membuf_t bis_mem[
+    OS_MEMPOOL_SIZE(MYNEWT_VAL(BIG_NUM_BIS),
+                    sizeof(struct ble_audio_bis))
+];
+static struct os_mempool bis_pool;
+
+static os_membuf_t codec_spec_mem[
+    OS_MEMPOOL_SIZE(MYNEWT_VAL(BIG_NUM_BIS) * 2, 19)
+];
+static struct os_mempool codec_spec_pool;
+
+static struct os_task auracast_interrupt_task_str;
+static struct os_eventq auracast_interrupt_eventq;
+static os_stack_t 
auracast_interrupt_task_stack[BROADCASTER_INTERRUPT_TASK_STACK_SZ];
+
+static uint8_t auracast_adv_instance;
+
+static void
+auracast_interrupt_task(void *arg)
+{
+    while (1) {
+        os_eventq_run(&auracast_interrupt_eventq);
+    }
+}
+
+static void
+broadcast_stop_ev_cb(struct os_event *ev)
+{
+    ble_svc_auracast_stop(auracast_adv_instance);
+    ble_svc_auracast_terminate(auracast_adv_instance);
+}
+
+static struct os_event broadcast_stop_ev = {
+    .ev_cb = broadcast_stop_ev_cb,
+};
+
+static void
+auracast_gpio_irq(void *arg)
+{
+    os_eventq_put(&auracast_interrupt_eventq, &broadcast_stop_ev);
+}
+
+static void
+auracast_init()
+{
+    int rc;
+
+    assert(MYNEWT_VAL(AURACAST_CHAN_NUM) > 0);
+
+    rc = os_mempool_init(&bis_pool, MYNEWT_VAL(BIG_NUM_BIS),
+                         sizeof(struct ble_audio_bis), bis_mem,
+                         "bis_pool");
+    assert(rc == 0);
+
+    rc = os_mempool_init(&codec_spec_pool,
+                         MYNEWT_VAL(BIG_NUM_BIS) * 2, 19,
+                         codec_spec_mem, "codec_spec_pool");
+    assert(rc == 0);
+}
+
+static int
+base_create()
+{
+#if MYNEWT_VAL(BIG_NUM_BIS) > 1
+    struct ble_audio_bis *bis_left;
+    struct ble_audio_bis *bis_right;
+    uint8_t codec_spec_config_left_chan[] =
+        BLE_AUDIO_BUILD_CODEC_CONFIG(BROADCAST_SAMPLE_RATE,
+                                     BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS,
+                                     BLE_AUDIO_LOCATION_FRONT_LEFT,
+                                     BROADCAST_MAX_SDU, );
+    uint8_t codec_spec_config_right_chan[] =
+        BLE_AUDIO_BUILD_CODEC_CONFIG(BROADCAST_SAMPLE_RATE,
+                                     BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS,
+                                     BLE_AUDIO_LOCATION_FRONT_RIGHT,
+                                     BROADCAST_MAX_SDU, );
+#else
+    uint16_t chan_loc = BLE_AUDIO_LOCATION_FRONT_LEFT |
+                        BLE_AUDIO_LOCATION_FRONT_RIGHT;
+    uint8_t codec_spec_config[] =
+        BLE_AUDIO_BUILD_CODEC_CONFIG(BROADCAST_SAMPLE_RATE,
+                                     BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS,
+                                     chan_loc,
+                                     BROADCAST_MAX_SDU * 2, );
+
+    struct ble_audio_bis *bis;
+#endif
+    if (MYNEWT_VAL(BROADCAST_ID) != 0) {
+        auracast_base.broadcast_id = MYNEWT_VAL(BROADCAST_ID);
+    } else {
+        ble_hs_hci_rand(&auracast_base.broadcast_id, 3);
+    }
+    auracast_base.presentation_delay = 20000;
+
+    big_subgroup.bis_cnt = MYNEWT_VAL(BIG_NUM_BIS);
+
+    /** LC3 */
+    big_subgroup.codec_id.format = 0x06;
+
+    big_subgroup.codec_spec_config_len = 0;
+#if MYNEWT_VAL(BIG_NUM_BIS) > 1
+    bis_left = os_memblock_get(&bis_pool);
+    if (!bis_left) {
+        return BLE_HS_ENOMEM;
+    }
+
+    bis_left->codec_spec_config = os_memblock_get(&codec_spec_pool);
+    memcpy(bis_left->codec_spec_config,
+           codec_spec_config_left_chan,
+           sizeof(codec_spec_config_left_chan));
+    bis_left->codec_spec_config_len = sizeof(codec_spec_config_left_chan);
+    bis_left->idx = 1;
+
+    bis_right = os_memblock_get(&bis_pool);
+    if (!bis_right) {
+        return BLE_HS_ENOMEM;
+    }
+
+    bis_right->codec_spec_config = os_memblock_get(&codec_spec_pool);
+    memcpy(bis_right->codec_spec_config,
+           codec_spec_config_right_chan,
+           sizeof(codec_spec_config_right_chan));
+    bis_right->codec_spec_config_len = sizeof(codec_spec_config_right_chan);
+    bis_right->idx = 2;
+
+    STAILQ_INSERT_HEAD(&big_subgroup.bises, bis_left, next);
+    STAILQ_INSERT_TAIL(&big_subgroup.bises, bis_right, next);
+#else
+    bis = os_memblock_get(&bis_pool);
+    if (!bis) {
+        return BLE_HS_ENOMEM;
+    }
+
+    bis->codec_spec_config = os_memblock_get(&codec_spec_pool);
+    memcpy(bis->codec_spec_config,
+           codec_spec_config,
+           sizeof(codec_spec_config));
+    bis->codec_spec_config_len = sizeof(codec_spec_config);
+    STAILQ_INSERT_HEAD(&big_subgroup.bises, bis, next);
+#endif
+
+    STAILQ_INSERT_HEAD(&auracast_base.subs, &big_subgroup, next);
+    auracast_base.num_subgroups++;
+    return 0;
+}
+
+static int
+auracast_destroy_fn(struct ble_audio_base *base, void *args)
+{
+    struct ble_audio_bis *bis;
+    int i;
+
+    STAILQ_FOREACH(bis, &big_subgroup.bises, next) {
+        os_memblock_put(&codec_spec_pool, bis->codec_spec_config);
+        os_memblock_put(&bis_pool, bis);
+    }
+
+    memset(&big_subgroup, 0, sizeof(big_subgroup));
+
+    for (i = 0; i < MYNEWT_VAL(AURACAST_CHAN_NUM); i++) {
+        chans[i].handle = 0;
+    }
+
+    return 0;
+}
+
+static int
+iso_event(struct ble_iso_event *event, void *arg)
+{
+    int i;
+
+    switch (event->type) {
+    case BLE_ISO_EVENT_BIG_CREATE_COMPLETE:
+        console_printf("BIG created\n");
+        if (event->big_created.desc.num_bis >
+            MYNEWT_VAL(AURACAST_CHAN_NUM)) {
+            return BLE_HS_EINVAL;
+        }
+        if (MYNEWT_VAL(BIG_NUM_BIS) == event->big_created.desc.num_bis) {
+            for (i = 0; i < MYNEWT_VAL(AURACAST_CHAN_NUM); i++) {
+                chans[i].handle = event->big_created.desc.conn_handle[i];
+            }
+        } else {
+            for (i = 0; i < MYNEWT_VAL(AURACAST_CHAN_NUM); i++) {
+                chans[i].handle = event->big_created.desc.conn_handle[0];
+            }
+        }
+        return 0;
+    case BLE_ISO_EVENT_BIG_TERMINATE_COMPLETE:
+        console_printf("BIG terminated\n");
+        return 0;
+    default:
+        return BLE_HS_ENOTSUP;
+    }
+}
+
+static int
+auracast_create()
+{
+    const char *program_info = "NimBLE Auracast Test";
+    static struct ble_iso_big_params big_params = {
+        .sdu_interval = MYNEWT_VAL(LC3_FRAME_DURATION),
+        .max_sdu = BROADCAST_MAX_SDU,
+        .max_transport_latency = MYNEWT_VAL(LC3_FRAME_DURATION) / 1000,
+        .rtn = MYNEWT_VAL(BIG_RTN),
+        .phy = MYNEWT_VAL(BIG_PHY),
+        .packing = MYNEWT_VAL(BIG_PACKING),
+        .framing = MYNEWT_VAL(BIG_FRAMING),
+        .encryption = MYNEWT_VAL(BIG_ENCRYPTION),
+        .broadcast_code = MYNEWT_VAL(BROADCAST_CODE),
+    };
+
+    struct ble_svc_auracast_create_params create_params = {
+        .base = &auracast_base,
+        .big_params = &big_params,
+        .name = MYNEWT_VAL(BROADCAST_NAME),
+        .program_info = program_info,
+        .own_addr_type = id_addr_type,
+        .secondary_phy = BLE_HCI_LE_PHY_2M,
+        .sid = BROADCAST_SID,
+        .frame_duration = MYNEWT_VAL(LC3_FRAME_DURATION),
+        .sampling_frequency = MYNEWT_VAL(LC3_SAMPLING_FREQ),
+        .bitrate = MYNEWT_VAL(LC3_BITRATE),
+    };
+
+    return ble_svc_auracast_create(&create_params,
+                                   &auracast_adv_instance,
+                                   auracast_destroy_fn,
+                                   NULL,
+                                   NULL);
+}
+
+static int
+auracast_start()

Review Comment:
   (void)



##########
apps/auracast_usb/src/audio_usb.c:
##########
@@ -0,0 +1,187 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 <assert.h>
+#include <string.h>
+#include <syscfg/syscfg.h>
+#include <os/os.h>
+#include <common/tusb_fifo.h>
+#include <class/audio/audio_device.h>
+#include <usb_audio.h>
+
+#include <lc3.h>
+#include <nrf_clock.h>
+
+#include "host/ble_gap.h"
+
+#include "app_priv.h"
+
+static uint8_t g_usb_enabled;
+
+static void usb_data_func(struct os_event *ev);
+
+struct chan chans[AUDIO_CHANNELS];
+
+static struct os_event usb_data_ev = {
+    .ev_cb = usb_data_func,
+};
+
+static uint32_t frame_bytes_lc3;
+static uint16_t big_sdu;
+
+static int16_t samples[96000 / 100 * 2 * 2];
+static uint8_t samples_out[96000 / 100 * 2];
+static int samples_idx = 0;
+
+static uint32_t pkt_counter = 0;
+
+static void
+usb_data_func(struct os_event *ev)
+{
+    int ch_idx;
+    unsigned int num_bytes;
+    unsigned int num_samples;
+    unsigned int num_frames;
+    unsigned int frames_count;
+    int read;
+    int skip;
+
+    if (!g_usb_enabled) {
+        tud_audio_clear_ep_out_ff();
+        return;
+    }
+
+    while ((num_bytes = tud_audio_available()) > 0) {
+        num_samples = num_bytes / AUDIO_SAMPLE_SIZE;
+        num_frames = num_samples / MYNEWT_VAL(AURACAST_CHAN_NUM);
+        num_bytes = num_frames * AUDIO_SAMPLE_SIZE * 
MYNEWT_VAL(AURACAST_CHAN_NUM);
+
+        assert(samples_idx + num_samples < ARRAY_SIZE(samples));
+
+        read = tud_audio_read(&samples[samples_idx], num_bytes);
+
+        assert(read == num_bytes);
+        assert(samples[ARRAY_SIZE(samples) - 1] = 0xaaaa);
+
+        samples_idx += num_samples;
+        assert((samples_idx & 0x80000000) == 0);
+        frames_count = samples_idx / MYNEWT_VAL(AURACAST_CHAN_NUM);
+
+        if (frames_count >= LC3_FPDT) {
+            pkt_counter++;
+            skip = 0;
+
+            for (ch_idx = 0; ch_idx < MYNEWT_VAL(AURACAST_CHAN_NUM); ch_idx++) 
{
+                if (chans[ch_idx].handle == 0) {
+                    skip = 1;
+                    continue;
+                }
+            }
+
+            if (!skip) {
+                memset(samples_out, 0, sizeof(samples_out));
+                lc3_encode(chans[0].encoder, LC3_PCM_FORMAT_S16,
+                           samples + 0, AUDIO_CHANNELS,
+                           (int)frame_bytes_lc3, samples_out);
+
+                if (AUDIO_CHANNELS == 2) {
+                    ble_iso_tx(chans[0].handle, samples_out, big_sdu);
+
+                    memset(samples_out, 0, sizeof(samples_out));
+                    lc3_encode(chans[1].encoder, LC3_PCM_FORMAT_S16,
+                               samples + 1, AUDIO_CHANNELS,
+                               (int)frame_bytes_lc3, samples_out);
+                    ble_iso_tx(chans[1].handle, samples_out, big_sdu);
+                } else {
+                    ble_iso_tx(chans[0].handle, samples_out, big_sdu);
+                    if (BIG_NUM_BIS == 1) {
+                        memset(samples_out, 0, sizeof(samples_out));
+                        lc3_encode(chans[1].encoder, LC3_PCM_FORMAT_S16,
+                                   samples + 1, AUDIO_CHANNELS,
+                                   (int)frame_bytes_lc3, samples_out);
+                    }
+                    ble_iso_tx(chans[0].handle, samples_out, big_sdu);
+                }
+
+            }
+
+            if (frames_count > LC3_FPDT) {
+                int old_samples_idx = samples_idx;
+                samples_idx -= LC3_FPDT * AUDIO_CHANNELS;
+                memmove(samples, &samples[old_samples_idx],
+                        (old_samples_idx - samples_idx) * AUDIO_SAMPLE_SIZE);

Review Comment:
   samples, &samples[lc3_fpdt * chans], samples_idx * sample_size



##########
apps/auracast_usb/src/main.c:
##########
@@ -0,0 +1,349 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 "console/console.h"
+#include "config/config.h"
+
+#include "nimble/ble.h"
+#include "host/ble_hs.h"
+#include "host/util/util.h"
+
+#include "services/auracast/ble_svc_auracast.h"
+
+#include "hal/hal_gpio.h"
+#include "bsp/bsp.h"
+#include "app_priv.h"
+
+#define BROADCAST_SID                       1
+#define BROADCAST_SDU_INTVL                 MYNEWT_VAL(LC3_FRAME_DURATION)
+#define BROADCAST_SAMPLE_RATE               BLE_AUDIO_SAMPLING_RATE_48000_HZ
+#define BROADCAST_MAX_SDU                   (BROADCAST_SDU_INTVL * \
+                                             MYNEWT_VAL(LC3_BITRATE) / \
+                                             (1000 * 1000 * 8))
+
+#define BROADCASTER_INTERRUPT_TASK_PRIO  4
+#define BROADCASTER_INTERRUPT_TASK_STACK_SZ    512
+
+static uint8_t id_addr_type;
+
+static struct ble_audio_base auracast_base;
+static struct ble_audio_big_subgroup big_subgroup;
+
+static os_membuf_t bis_mem[
+    OS_MEMPOOL_SIZE(MYNEWT_VAL(BIG_NUM_BIS),
+                    sizeof(struct ble_audio_bis))
+];
+static struct os_mempool bis_pool;
+
+static os_membuf_t codec_spec_mem[
+    OS_MEMPOOL_SIZE(MYNEWT_VAL(BIG_NUM_BIS) * 2, 19)
+];
+static struct os_mempool codec_spec_pool;
+
+static struct os_task auracast_interrupt_task_str;
+static struct os_eventq auracast_interrupt_eventq;
+static os_stack_t 
auracast_interrupt_task_stack[BROADCASTER_INTERRUPT_TASK_STACK_SZ];
+
+static uint8_t auracast_adv_instance;
+
+static void
+auracast_interrupt_task(void *arg)
+{
+    while (1) {
+        os_eventq_run(&auracast_interrupt_eventq);
+    }
+}
+
+static void
+broadcast_stop_ev_cb(struct os_event *ev)
+{
+    ble_svc_auracast_stop(auracast_adv_instance);
+    ble_svc_auracast_terminate(auracast_adv_instance);

Review Comment:
   what's the point of having a button to stop the stream if we cannot restart 
it?



##########
apps/auracast_usb/src/main.c:
##########
@@ -0,0 +1,349 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 "console/console.h"
+#include "config/config.h"
+
+#include "nimble/ble.h"
+#include "host/ble_hs.h"
+#include "host/util/util.h"
+
+#include "services/auracast/ble_svc_auracast.h"
+
+#include "hal/hal_gpio.h"
+#include "bsp/bsp.h"
+#include "app_priv.h"
+
+#define BROADCAST_SID                       1
+#define BROADCAST_SDU_INTVL                 MYNEWT_VAL(LC3_FRAME_DURATION)
+#define BROADCAST_SAMPLE_RATE               BLE_AUDIO_SAMPLING_RATE_48000_HZ
+#define BROADCAST_MAX_SDU                   (BROADCAST_SDU_INTVL * \
+                                             MYNEWT_VAL(LC3_BITRATE) / \
+                                             (1000 * 1000 * 8))
+
+#define BROADCASTER_INTERRUPT_TASK_PRIO  4
+#define BROADCASTER_INTERRUPT_TASK_STACK_SZ    512
+
+static uint8_t id_addr_type;
+
+static struct ble_audio_base auracast_base;
+static struct ble_audio_big_subgroup big_subgroup;
+
+static os_membuf_t bis_mem[
+    OS_MEMPOOL_SIZE(MYNEWT_VAL(BIG_NUM_BIS),
+                    sizeof(struct ble_audio_bis))
+];
+static struct os_mempool bis_pool;
+
+static os_membuf_t codec_spec_mem[
+    OS_MEMPOOL_SIZE(MYNEWT_VAL(BIG_NUM_BIS) * 2, 19)
+];
+static struct os_mempool codec_spec_pool;
+
+static struct os_task auracast_interrupt_task_str;
+static struct os_eventq auracast_interrupt_eventq;
+static os_stack_t 
auracast_interrupt_task_stack[BROADCASTER_INTERRUPT_TASK_STACK_SZ];
+
+static uint8_t auracast_adv_instance;
+
+static void
+auracast_interrupt_task(void *arg)
+{
+    while (1) {
+        os_eventq_run(&auracast_interrupt_eventq);
+    }
+}
+
+static void
+broadcast_stop_ev_cb(struct os_event *ev)
+{
+    ble_svc_auracast_stop(auracast_adv_instance);
+    ble_svc_auracast_terminate(auracast_adv_instance);
+}
+
+static struct os_event broadcast_stop_ev = {
+    .ev_cb = broadcast_stop_ev_cb,
+};
+
+static void
+auracast_gpio_irq(void *arg)
+{
+    os_eventq_put(&auracast_interrupt_eventq, &broadcast_stop_ev);
+}
+
+static void
+auracast_init()
+{
+    int rc;
+
+    assert(MYNEWT_VAL(AURACAST_CHAN_NUM) > 0);
+
+    rc = os_mempool_init(&bis_pool, MYNEWT_VAL(BIG_NUM_BIS),
+                         sizeof(struct ble_audio_bis), bis_mem,
+                         "bis_pool");
+    assert(rc == 0);
+
+    rc = os_mempool_init(&codec_spec_pool,
+                         MYNEWT_VAL(BIG_NUM_BIS) * 2, 19,
+                         codec_spec_mem, "codec_spec_pool");
+    assert(rc == 0);
+}
+
+static int
+base_create()
+{
+#if MYNEWT_VAL(BIG_NUM_BIS) > 1
+    struct ble_audio_bis *bis_left;
+    struct ble_audio_bis *bis_right;
+    uint8_t codec_spec_config_left_chan[] =
+        BLE_AUDIO_BUILD_CODEC_CONFIG(BROADCAST_SAMPLE_RATE,
+                                     BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS,
+                                     BLE_AUDIO_LOCATION_FRONT_LEFT,
+                                     BROADCAST_MAX_SDU, );
+    uint8_t codec_spec_config_right_chan[] =
+        BLE_AUDIO_BUILD_CODEC_CONFIG(BROADCAST_SAMPLE_RATE,
+                                     BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS,
+                                     BLE_AUDIO_LOCATION_FRONT_RIGHT,
+                                     BROADCAST_MAX_SDU, );
+#else
+    uint16_t chan_loc = BLE_AUDIO_LOCATION_FRONT_LEFT |
+                        BLE_AUDIO_LOCATION_FRONT_RIGHT;
+    uint8_t codec_spec_config[] =
+        BLE_AUDIO_BUILD_CODEC_CONFIG(BROADCAST_SAMPLE_RATE,
+                                     BLE_AUDIO_SELECTED_FRAME_DURATION_10_MS,
+                                     chan_loc,
+                                     BROADCAST_MAX_SDU * 2, );
+
+    struct ble_audio_bis *bis;
+#endif
+    if (MYNEWT_VAL(BROADCAST_ID) != 0) {
+        auracast_base.broadcast_id = MYNEWT_VAL(BROADCAST_ID);
+    } else {
+        ble_hs_hci_rand(&auracast_base.broadcast_id, 3);
+    }
+    auracast_base.presentation_delay = 20000;
+
+    big_subgroup.bis_cnt = MYNEWT_VAL(BIG_NUM_BIS);
+
+    /** LC3 */
+    big_subgroup.codec_id.format = 0x06;
+
+    big_subgroup.codec_spec_config_len = 0;
+#if MYNEWT_VAL(BIG_NUM_BIS) > 1
+    bis_left = os_memblock_get(&bis_pool);
+    if (!bis_left) {
+        return BLE_HS_ENOMEM;
+    }
+
+    bis_left->codec_spec_config = os_memblock_get(&codec_spec_pool);
+    memcpy(bis_left->codec_spec_config,
+           codec_spec_config_left_chan,
+           sizeof(codec_spec_config_left_chan));
+    bis_left->codec_spec_config_len = sizeof(codec_spec_config_left_chan);
+    bis_left->idx = 1;
+
+    bis_right = os_memblock_get(&bis_pool);
+    if (!bis_right) {
+        return BLE_HS_ENOMEM;
+    }
+
+    bis_right->codec_spec_config = os_memblock_get(&codec_spec_pool);
+    memcpy(bis_right->codec_spec_config,
+           codec_spec_config_right_chan,
+           sizeof(codec_spec_config_right_chan));
+    bis_right->codec_spec_config_len = sizeof(codec_spec_config_right_chan);
+    bis_right->idx = 2;
+
+    STAILQ_INSERT_HEAD(&big_subgroup.bises, bis_left, next);
+    STAILQ_INSERT_TAIL(&big_subgroup.bises, bis_right, next);
+#else
+    bis = os_memblock_get(&bis_pool);
+    if (!bis) {
+        return BLE_HS_ENOMEM;
+    }
+
+    bis->codec_spec_config = os_memblock_get(&codec_spec_pool);
+    memcpy(bis->codec_spec_config,
+           codec_spec_config,
+           sizeof(codec_spec_config));
+    bis->codec_spec_config_len = sizeof(codec_spec_config);
+    STAILQ_INSERT_HEAD(&big_subgroup.bises, bis, next);
+#endif
+
+    STAILQ_INSERT_HEAD(&auracast_base.subs, &big_subgroup, next);
+    auracast_base.num_subgroups++;
+    return 0;
+}
+
+static int
+auracast_destroy_fn(struct ble_audio_base *base, void *args)
+{
+    struct ble_audio_bis *bis;
+    int i;
+
+    STAILQ_FOREACH(bis, &big_subgroup.bises, next) {
+        os_memblock_put(&codec_spec_pool, bis->codec_spec_config);
+        os_memblock_put(&bis_pool, bis);
+    }
+
+    memset(&big_subgroup, 0, sizeof(big_subgroup));
+
+    for (i = 0; i < MYNEWT_VAL(AURACAST_CHAN_NUM); i++) {
+        chans[i].handle = 0;
+    }
+
+    return 0;
+}
+
+static int
+iso_event(struct ble_iso_event *event, void *arg)
+{
+    int i;
+
+    switch (event->type) {
+    case BLE_ISO_EVENT_BIG_CREATE_COMPLETE:
+        console_printf("BIG created\n");
+        if (event->big_created.desc.num_bis >
+            MYNEWT_VAL(AURACAST_CHAN_NUM)) {
+            return BLE_HS_EINVAL;
+        }
+        if (MYNEWT_VAL(BIG_NUM_BIS) == event->big_created.desc.num_bis) {
+            for (i = 0; i < MYNEWT_VAL(AURACAST_CHAN_NUM); i++) {
+                chans[i].handle = event->big_created.desc.conn_handle[i];
+            }
+        } else {
+            for (i = 0; i < MYNEWT_VAL(AURACAST_CHAN_NUM); i++) {
+                chans[i].handle = event->big_created.desc.conn_handle[0];
+            }
+        }
+        return 0;
+    case BLE_ISO_EVENT_BIG_TERMINATE_COMPLETE:
+        console_printf("BIG terminated\n");
+        return 0;
+    default:
+        return BLE_HS_ENOTSUP;
+    }
+}
+
+static int
+auracast_create()
+{
+    const char *program_info = "NimBLE Auracast Test";
+    static struct ble_iso_big_params big_params = {
+        .sdu_interval = MYNEWT_VAL(LC3_FRAME_DURATION),
+        .max_sdu = BROADCAST_MAX_SDU,
+        .max_transport_latency = MYNEWT_VAL(LC3_FRAME_DURATION) / 1000,
+        .rtn = MYNEWT_VAL(BIG_RTN),
+        .phy = MYNEWT_VAL(BIG_PHY),
+        .packing = MYNEWT_VAL(BIG_PACKING),
+        .framing = MYNEWT_VAL(BIG_FRAMING),
+        .encryption = MYNEWT_VAL(BIG_ENCRYPTION),
+        .broadcast_code = MYNEWT_VAL(BROADCAST_CODE),
+    };
+
+    struct ble_svc_auracast_create_params create_params = {
+        .base = &auracast_base,
+        .big_params = &big_params,
+        .name = MYNEWT_VAL(BROADCAST_NAME),
+        .program_info = program_info,
+        .own_addr_type = id_addr_type,
+        .secondary_phy = BLE_HCI_LE_PHY_2M,
+        .sid = BROADCAST_SID,
+        .frame_duration = MYNEWT_VAL(LC3_FRAME_DURATION),
+        .sampling_frequency = MYNEWT_VAL(LC3_SAMPLING_FREQ),
+        .bitrate = MYNEWT_VAL(LC3_BITRATE),
+    };
+
+    return ble_svc_auracast_create(&create_params,
+                                   &auracast_adv_instance,
+                                   auracast_destroy_fn,
+                                   NULL,
+                                   NULL);
+}
+
+static int
+auracast_start()
+{
+    return ble_svc_auracast_start(auracast_adv_instance, iso_event, NULL);
+}
+
+static void
+on_sync(void)
+{
+    int rc;
+
+    console_printf("Bluetooth initialized\n");
+
+    /* Make sure we have proper identity address set (public preferred) */
+    rc = ble_hs_util_ensure_addr(0);
+    assert(rc == 0);
+
+    /* configure global address */
+    rc = ble_hs_id_infer_auto(0, &id_addr_type);
+    assert(rc == 0);
+
+    auracast_init();
+
+    rc = base_create();
+    assert(rc == 0);
+
+    rc = auracast_create();
+    assert(rc == 0);
+
+    rc = auracast_start();
+    assert(rc == 0);
+}
+
+/*
+ * main
+ *
+ * The main task for the project. This function initializes the packages,
+ * then starts serving events from default event queue.
+ *
+ * @return int NOTE: this function should never return!
+ */
+int
+mynewt_main(int argc, char **argv)
+{
+    /* Initialize OS */
+    sysinit();
+
+    console_printf("LE Audio Broadcast sample application\n");
+
+    /* Set sync callback */
+    ble_hs_cfg.sync_cb = on_sync;
+
+    os_eventq_init(&auracast_interrupt_eventq);
+    os_task_init(&auracast_interrupt_task_str, "auracast_interrupt_task",
+                 auracast_interrupt_task, NULL,
+                 BROADCASTER_INTERRUPT_TASK_PRIO, OS_WAIT_FOREVER,
+                 auracast_interrupt_task_stack,
+                 BROADCASTER_INTERRUPT_TASK_STACK_SZ);

Review Comment:
   why do we need a separate task for handling a button?



##########
apps/auracast_usb/src/main.c:
##########
@@ -0,0 +1,349 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 "console/console.h"
+#include "config/config.h"
+
+#include "nimble/ble.h"
+#include "host/ble_hs.h"
+#include "host/util/util.h"
+
+#include "services/auracast/ble_svc_auracast.h"
+
+#include "hal/hal_gpio.h"
+#include "bsp/bsp.h"
+#include "app_priv.h"
+
+#define BROADCAST_SID                       1
+#define BROADCAST_SDU_INTVL                 MYNEWT_VAL(LC3_FRAME_DURATION)
+#define BROADCAST_SAMPLE_RATE               BLE_AUDIO_SAMPLING_RATE_48000_HZ

Review Comment:
   this should depend on lc3 configuration



##########
apps/auracast_usb/src/audio_usb.c:
##########
@@ -0,0 +1,187 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 <assert.h>
+#include <string.h>
+#include <syscfg/syscfg.h>
+#include <os/os.h>
+#include <common/tusb_fifo.h>
+#include <class/audio/audio_device.h>
+#include <usb_audio.h>
+
+#include <lc3.h>
+#include <nrf_clock.h>
+
+#include "host/ble_gap.h"
+
+#include "app_priv.h"
+
+static uint8_t g_usb_enabled;
+
+static void usb_data_func(struct os_event *ev);
+
+struct chan chans[AUDIO_CHANNELS];
+
+static struct os_event usb_data_ev = {
+    .ev_cb = usb_data_func,
+};
+
+static uint32_t frame_bytes_lc3;
+static uint16_t big_sdu;
+
+static int16_t samples[96000 / 100 * 2 * 2];
+static uint8_t samples_out[96000 / 100 * 2];
+static int samples_idx = 0;
+
+static uint32_t pkt_counter = 0;
+
+static void
+usb_data_func(struct os_event *ev)
+{
+    int ch_idx;
+    unsigned int num_bytes;
+    unsigned int num_samples;
+    unsigned int num_frames;
+    unsigned int frames_count;
+    int read;
+    int skip;
+
+    if (!g_usb_enabled) {
+        tud_audio_clear_ep_out_ff();
+        return;
+    }
+
+    while ((num_bytes = tud_audio_available()) > 0) {
+        num_samples = num_bytes / AUDIO_SAMPLE_SIZE;
+        num_frames = num_samples / MYNEWT_VAL(AURACAST_CHAN_NUM);
+        num_bytes = num_frames * AUDIO_SAMPLE_SIZE * 
MYNEWT_VAL(AURACAST_CHAN_NUM);
+
+        assert(samples_idx + num_samples < ARRAY_SIZE(samples));
+
+        read = tud_audio_read(&samples[samples_idx], num_bytes);
+
+        assert(read == num_bytes);
+        assert(samples[ARRAY_SIZE(samples) - 1] = 0xaaaa);
+
+        samples_idx += num_samples;
+        assert((samples_idx & 0x80000000) == 0);
+        frames_count = samples_idx / MYNEWT_VAL(AURACAST_CHAN_NUM);
+
+        if (frames_count >= LC3_FPDT) {
+            pkt_counter++;
+            skip = 0;
+
+            for (ch_idx = 0; ch_idx < MYNEWT_VAL(AURACAST_CHAN_NUM); ch_idx++) 
{
+                if (chans[ch_idx].handle == 0) {
+                    skip = 1;
+                    continue;
+                }
+            }
+
+            if (!skip) {
+                memset(samples_out, 0, sizeof(samples_out));
+                lc3_encode(chans[0].encoder, LC3_PCM_FORMAT_S16,
+                           samples + 0, AUDIO_CHANNELS,
+                           (int)frame_bytes_lc3, samples_out);
+
+                if (AUDIO_CHANNELS == 2) {
+                    ble_iso_tx(chans[0].handle, samples_out, big_sdu);
+
+                    memset(samples_out, 0, sizeof(samples_out));
+                    lc3_encode(chans[1].encoder, LC3_PCM_FORMAT_S16,
+                               samples + 1, AUDIO_CHANNELS,
+                               (int)frame_bytes_lc3, samples_out);
+                    ble_iso_tx(chans[1].handle, samples_out, big_sdu);
+                } else {
+                    ble_iso_tx(chans[0].handle, samples_out, big_sdu);
+                    if (BIG_NUM_BIS == 1) {
+                        memset(samples_out, 0, sizeof(samples_out));
+                        lc3_encode(chans[1].encoder, LC3_PCM_FORMAT_S16,
+                                   samples + 1, AUDIO_CHANNELS,
+                                   (int)frame_bytes_lc3, samples_out);
+                    }
+                    ble_iso_tx(chans[0].handle, samples_out, big_sdu);
+                }
+
+            }
+
+            if (frames_count > LC3_FPDT) {
+                int old_samples_idx = samples_idx;
+                samples_idx -= LC3_FPDT * AUDIO_CHANNELS;
+                memmove(samples, &samples[old_samples_idx],
+                        (old_samples_idx - samples_idx) * AUDIO_SAMPLE_SIZE);
+            } else {
+                samples_idx = 0;
+            }
+        }
+    }
+
+}
+
+bool
+tud_audio_rx_done_post_read_cb(uint8_t rhport, uint16_t n_bytes_received,
+                               uint8_t func_id, uint8_t ep_out,
+                               uint8_t cur_alt_setting)
+{
+    (void)rhport;
+    (void)n_bytes_received;
+    (void)func_id;
+    (void)ep_out;
+    (void)cur_alt_setting;
+
+    if (!usb_data_ev.ev_queued) {
+        os_eventq_put(os_eventq_dflt_get(), &usb_data_ev);
+    }
+
+    return true;
+}
+
+void
+audio_usb_init(void)
+{
+    /* Need to reference those explicitly, so they are always pulled by linker
+     * instead of weak symbols in tinyusb.
+     */
+    (void)tud_audio_rx_done_post_read_cb;
+
+    usb_desc_sample_rate_set(LC3_SAMPLING_FREQ);
+
+    assert(LC3_FPDT == lc3_frame_samples(LC3_FRAME_DURATION,
+                                         LC3_SAMPLING_FREQ));
+
+    memset(samples, 0xaa, sizeof(samples));

Review Comment:
   remove



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to