mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-01-25 18:35:17 +00:00
send sine
This commit is contained in:
parent
ba155c2213
commit
b548dda644
@ -1349,9 +1349,11 @@ typedef uint8_t sm_key_t[16];
|
||||
#define AVDTP_SUBEVENT_SIGNALING_MEDIA_CODEC_OTHER_CONFIGURATION 0x0A
|
||||
|
||||
/**
|
||||
* @format 1H1
|
||||
* @format 1H111
|
||||
* @param subevent_code
|
||||
* @param avdtp_cid
|
||||
* @param int_seid
|
||||
* @param acp_seid
|
||||
* @param status 0 == OK
|
||||
*/
|
||||
#define AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED 0x0B
|
||||
|
@ -4412,6 +4412,24 @@ static inline const uint8_t * avdtp_subevent_signaling_media_codec_other_configu
|
||||
static inline hci_con_handle_t avdtp_subevent_streaming_connection_established_get_avdtp_cid(const uint8_t * event){
|
||||
return little_endian_read_16(event, 3);
|
||||
}
|
||||
/**
|
||||
* @brief Get field int_seid from event AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED
|
||||
* @param event packet
|
||||
* @return int_seid
|
||||
* @note: btstack_type 1
|
||||
*/
|
||||
static inline uint8_t avdtp_subevent_streaming_connection_established_get_int_seid(const uint8_t * event){
|
||||
return event[5];
|
||||
}
|
||||
/**
|
||||
* @brief Get field acp_seid from event AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED
|
||||
* @param event packet
|
||||
* @return acp_seid
|
||||
* @note: btstack_type 1
|
||||
*/
|
||||
static inline uint8_t avdtp_subevent_streaming_connection_established_get_acp_seid(const uint8_t * event){
|
||||
return event[6];
|
||||
}
|
||||
/**
|
||||
* @brief Get field status from event AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED
|
||||
* @param event packet
|
||||
@ -4419,7 +4437,7 @@ static inline hci_con_handle_t avdtp_subevent_streaming_connection_established_g
|
||||
* @note: btstack_type 1
|
||||
*/
|
||||
static inline uint8_t avdtp_subevent_streaming_connection_established_get_status(const uint8_t * event){
|
||||
return event[5];
|
||||
return event[7];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -172,7 +172,8 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
uint8_t signal_identifier;
|
||||
uint8_t status;
|
||||
avdtp_sep_t sep;
|
||||
//
|
||||
uint8_t int_seid;
|
||||
uint8_t acp_seid;
|
||||
|
||||
switch (packet_type) {
|
||||
|
||||
@ -206,12 +207,17 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
|
||||
case AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED:
|
||||
status = avdtp_subevent_streaming_connection_established_get_status(packet);
|
||||
avdtp_cid = avdtp_subevent_streaming_connection_established_get_avdtp_cid(packet);
|
||||
int_seid = avdtp_subevent_streaming_connection_established_get_int_seid(packet);
|
||||
acp_seid = avdtp_subevent_streaming_connection_established_get_acp_seid(packet);
|
||||
|
||||
if (status != 0){
|
||||
printf(" --- a2dp source --- AVDTP_SUBEVENT_STREAMING_CONNECTION could not be established, status %d ---\n", status);
|
||||
break;
|
||||
}
|
||||
app_state = A2DP_STREAMING_OPENED;
|
||||
printf(" --- a2dp source --- AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED ---\n");
|
||||
avdtp_streaming_emit_connection_established(a2dp_source_context.a2dp_callback, avdtp_cid, int_seid, acp_seid, 0);
|
||||
printf(" --- a2dp source --- AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED --- avdtp_cid 0x%02x, local seid %d, remote seid %d\n", avdtp_cid, int_seid, acp_seid);
|
||||
break;
|
||||
|
||||
case AVDTP_SUBEVENT_SIGNALING_SEP_FOUND:
|
||||
@ -268,6 +274,9 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
// TODO: deal with reconfigure: avdtp_subevent_signaling_media_codec_sbc_configuration_get_reconfigure(packet);
|
||||
break;
|
||||
}
|
||||
case AVDTP_SUBEVENT_STREAMING_CAN_SEND_MEDIA_PACKET_NOW:
|
||||
avdtp_streaming_emit_can_send_media_packet_now(a2dp_source_context.a2dp_callback, avdtp_cid, 0, 0);
|
||||
break;
|
||||
|
||||
case AVDTP_SUBEVENT_SIGNALING_ACCEPT:
|
||||
signal_identifier = avdtp_subevent_signaling_accept_get_signal_identifier(packet);
|
||||
@ -314,6 +323,8 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
case A2DP_STREAMING_OPENED:
|
||||
switch (signal_identifier){
|
||||
case AVDTP_SI_START:
|
||||
printf(" AVDTP_SI_START successful\n");
|
||||
avdtp_signaling_emit_accept(a2dp_source_context.a2dp_callback, avdtp_cid, 0, signal_identifier, 0);
|
||||
break;
|
||||
case AVDTP_SI_CLOSE:
|
||||
break;
|
||||
@ -396,3 +407,11 @@ void a2dp_source_disconnect(uint16_t con_handle){
|
||||
avdtp_disconnect(con_handle, &a2dp_source_context);
|
||||
}
|
||||
|
||||
void a2dp_source_start_stream(uint16_t cid, uint8_t int_seid, uint8_t acp_seid){
|
||||
avdtp_start_stream(cid, int_seid, acp_seid, &a2dp_source_context);
|
||||
}
|
||||
|
||||
void a2dp_source_stop_stream(uint16_t cid, uint8_t int_seid, uint8_t acp_seid){
|
||||
avdtp_stop_stream(cid, int_seid, acp_seid, &a2dp_source_context);
|
||||
}
|
||||
|
||||
|
@ -236,7 +236,7 @@ static void stream_endpoint_state_machine(avdtp_connection_t * connection, avdtp
|
||||
stream_endpoint->l2cap_media_cid = l2cap_event_channel_opened_get_local_cid(packet);
|
||||
stream_endpoint->media_con_handle = l2cap_event_channel_opened_get_handle(packet);
|
||||
printf(" -> AVDTP_STREAM_ENDPOINT_OPENED, media con handle 0x%02x, l2cap_media_cid 0x%02x\n", stream_endpoint->media_con_handle, stream_endpoint->l2cap_media_cid);
|
||||
avdtp_streaming_emit_connection_established(context->avdtp_callback, stream_endpoint->l2cap_media_cid, 0);
|
||||
avdtp_streaming_emit_connection_established(context->avdtp_callback, connection->l2cap_signaling_cid, stream_endpoint->sep.seid, connection->remote_seps[stream_endpoint->remote_sep_index].seid, 0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -183,7 +183,8 @@ void avdtp_source_init(avdtp_context_t * avdtp_context){
|
||||
l2cap_register_service(&packet_handler, BLUETOOTH_PROTOCOL_AVDTP, 0xffff, LEVEL_0);
|
||||
}
|
||||
|
||||
int avdtp_source_stream_endpoint_ready(avdtp_stream_endpoint_t * stream_endpoint){
|
||||
int avdtp_source_stream_endpoint_ready(uint8_t local_seid){
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(local_seid, avdtp_source_context);
|
||||
if (!stream_endpoint) {
|
||||
printf("no stream_endpoint");
|
||||
return 0;
|
||||
@ -191,7 +192,8 @@ int avdtp_source_stream_endpoint_ready(avdtp_stream_endpoint_t * stream_endpoint
|
||||
return (stream_endpoint->state == AVDTP_STREAM_ENDPOINT_STREAMING || stream_endpoint->state == AVDTP_STREAM_ENDPOINT_STREAMING_W2_SEND);
|
||||
}
|
||||
|
||||
void avdtp_source_stream_endpoint_request_can_send_now(avdtp_stream_endpoint_t * stream_endpoint){
|
||||
void avdtp_source_stream_endpoint_request_can_send_now(uint8_t local_seid){
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(local_seid, avdtp_source_context);
|
||||
if (!stream_endpoint) {
|
||||
printf("no stream_endpoint");
|
||||
return;
|
||||
@ -264,23 +266,28 @@ static void avdtp_source_copy_media_payload(uint8_t * media_packet, int size, in
|
||||
*offset = pos;
|
||||
}
|
||||
|
||||
void avdtp_source_stream_send_media_payload(uint16_t l2cap_media_cid, btstack_ring_buffer_t * sbc_ring_buffer, uint8_t marker){
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_l2cap_cid(l2cap_media_cid, avdtp_source_context);
|
||||
void avdtp_source_stream_send_media_payload(uint8_t int_seid, btstack_ring_buffer_t * sbc_ring_buffer, uint8_t marker){
|
||||
avdtp_stream_endpoint_t * stream_endpoint = avdtp_stream_endpoint_for_seid(int_seid, avdtp_source_context);
|
||||
if (!stream_endpoint) {
|
||||
printf("no stream_endpoint found for 0x%02x", l2cap_media_cid);
|
||||
printf("no stream_endpoint found for seid %d", int_seid);
|
||||
return;
|
||||
}
|
||||
|
||||
int size = l2cap_get_remote_mtu_for_local_cid(l2cap_media_cid);
|
||||
if (stream_endpoint->l2cap_media_cid == 0){
|
||||
printf("no media cid found for seid %d", int_seid);
|
||||
return;
|
||||
}
|
||||
|
||||
int size = l2cap_get_remote_mtu_for_local_cid(stream_endpoint->l2cap_media_cid);
|
||||
int offset = 0;
|
||||
|
||||
l2cap_reserve_packet_buffer();
|
||||
uint8_t * media_packet = l2cap_get_outgoing_buffer();
|
||||
//int size = l2cap_get_remote_mtu_for_local_cid(l2cap_media_cid);
|
||||
//int size = l2cap_get_remote_mtu_for_local_cid(stream_endpoint->l2cap_media_cid);
|
||||
avdtp_source_setup_media_header(media_packet, size, &offset, marker, stream_endpoint->sequence_number);
|
||||
avdtp_source_copy_media_payload(media_packet, size, &offset, sbc_ring_buffer);
|
||||
stream_endpoint->sequence_number++;
|
||||
l2cap_send_prepared(l2cap_media_cid, offset);
|
||||
l2cap_send_prepared(stream_endpoint->l2cap_media_cid, offset);
|
||||
}
|
||||
|
||||
uint8_t avdtp_source_remote_seps_num(uint16_t avdtp_cid){
|
||||
|
@ -154,9 +154,9 @@ void avdtp_source_stop_stream(uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_
|
||||
|
||||
avdtp_stream_endpoint_t * avdtp_source_create_stream_endpoint(avdtp_sep_type_t sep_type, avdtp_media_type_t media_type);
|
||||
|
||||
void avdtp_source_stream_endpoint_request_can_send_now(avdtp_stream_endpoint_t * stream_endpoint);
|
||||
int avdtp_source_stream_endpoint_ready(avdtp_stream_endpoint_t * stream_endpoint);
|
||||
void avdtp_source_stream_send_media_payload(uint16_t l2cap_media_cid, btstack_ring_buffer_t * sbc_ring_buffer, uint8_t marker);
|
||||
void avdtp_source_stream_endpoint_request_can_send_now(uint8_t local_seid);
|
||||
int avdtp_source_stream_endpoint_ready(uint8_t local_seid);
|
||||
void avdtp_source_stream_send_media_payload(uint8_t local_seid, btstack_ring_buffer_t * sbc_ring_buffer, uint8_t marker);
|
||||
|
||||
uint8_t avdtp_source_remote_seps_num(uint16_t avdtp_cid);
|
||||
avdtp_sep_t * avdtp_source_remote_sep(uint16_t avdtp_cid, uint8_t index);
|
||||
|
@ -528,15 +528,17 @@ void avdtp_streaming_emit_can_send_media_packet_now(btstack_packet_handler_t cal
|
||||
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
}
|
||||
|
||||
void avdtp_streaming_emit_connection_established(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t status){
|
||||
void avdtp_streaming_emit_connection_established(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, uint8_t status){
|
||||
if (!callback) return;
|
||||
uint8_t event[6];
|
||||
uint8_t event[8];
|
||||
int pos = 0;
|
||||
event[pos++] = HCI_EVENT_AVDTP_META;
|
||||
event[pos++] = sizeof(event) - 2;
|
||||
event[pos++] = AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED;
|
||||
little_endian_store_16(event, pos, avdtp_cid);
|
||||
pos += 2;
|
||||
event[pos++] = int_seid;
|
||||
event[pos++] = acp_seid;
|
||||
event[pos++] = status;
|
||||
(*callback)(HCI_EVENT_PACKET, 0, event, sizeof(event));
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ void avdtp_prepare_capabilities(avdtp_signaling_packet_t * signaling_packet, uin
|
||||
int avdtp_signaling_create_fragment(uint16_t cid, avdtp_signaling_packet_t * signaling_packet, uint8_t * out_buffer);
|
||||
|
||||
void avdtp_signaling_emit_connection_established(btstack_packet_handler_t callback, uint16_t avdtp_cid, bd_addr_t addr, uint8_t status);
|
||||
void avdtp_streaming_emit_connection_established(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t status);
|
||||
void avdtp_streaming_emit_connection_established(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, uint8_t acp_seid, uint8_t status);
|
||||
void avdtp_signaling_emit_sep(btstack_packet_handler_t callback, uint16_t avdtp_cid, avdtp_sep_t sep);
|
||||
void avdtp_signaling_emit_accept(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t seid, avdtp_signal_identifier_t identifier, uint8_t status);
|
||||
void avdtp_signaling_emit_general_reject(btstack_packet_handler_t callback, uint16_t avdtp_cid, uint8_t int_seid, avdtp_signal_identifier_t identifier);
|
||||
|
@ -73,37 +73,23 @@
|
||||
#endif
|
||||
#define TABLE_SIZE_441HZ 100
|
||||
|
||||
typedef struct {
|
||||
// to app
|
||||
uint32_t fill_audio_ring_buffer_timeout_ms;
|
||||
uint32_t time_audio_data_sent; // ms
|
||||
uint32_t acc_num_missed_samples;
|
||||
uint32_t samples_ready;
|
||||
btstack_timer_source_t fill_audio_ring_buffer_timer;
|
||||
btstack_ring_buffer_t sbc_ring_buffer;
|
||||
btstack_sbc_encoder_state_t sbc_encoder_state;
|
||||
|
||||
int reconfigure;
|
||||
int num_channels;
|
||||
int sampling_frequency;
|
||||
int channel_mode;
|
||||
int block_length;
|
||||
int subbands;
|
||||
int allocation_method;
|
||||
int min_bitpool_value;
|
||||
int max_bitpool_value;
|
||||
} avdtp_stream_endpoint_context_t;
|
||||
static avdtp_stream_endpoint_context_t sc;
|
||||
|
||||
static uint8_t int_seid;
|
||||
// static uint8_t acp_seid;
|
||||
|
||||
typedef struct {
|
||||
int16_t source[TABLE_SIZE_441HZ];
|
||||
int left_phase;
|
||||
int right_phase;
|
||||
} paTestData;
|
||||
|
||||
typedef enum {
|
||||
STREAM_SINE,
|
||||
STREAM_MOD
|
||||
} stream_data_source_t;
|
||||
|
||||
static uint8_t media_sbc_codec_capabilities[] = {
|
||||
0xFF,//(AVDTP_SBC_44100 << 4) | AVDTP_SBC_STEREO,
|
||||
0xFF,//(AVDTP_SBC_BLOCK_LENGTH_16 << 4) | (AVDTP_SBC_SUBBANDS_8 << 2) | AVDTP_SBC_ALLOCATION_METHOD_LOUDNESS,
|
||||
2, 53
|
||||
};
|
||||
|
||||
static char * device_name = "A2DP Source BTstack";
|
||||
|
||||
// mac 2011: static bd_addr_t remote = {0x04, 0x0C, 0xCE, 0xE4, 0x85, 0xD3};
|
||||
@ -116,16 +102,17 @@ static bd_addr_t remote = {0x00, 0x21, 0x3c, 0xac, 0xf7, 0x38};
|
||||
// bt dongle: -u 02-04-01
|
||||
// static bd_addr_t remote = {0x00, 0x15, 0x83, 0x5F, 0x9D, 0x46};
|
||||
|
||||
static uint16_t avdtp_cid = 0;
|
||||
|
||||
static uint8_t sdp_avdtp_source_service_buffer[150];
|
||||
static avdtp_stream_endpoint_t * local_stream_endpoint;
|
||||
|
||||
static avdtp_sep_t * active_remote_sep = NULL;
|
||||
|
||||
static uint8_t media_sbc_codec_configuration[4];
|
||||
static uint8_t sbc_samples_storage[44100*4];
|
||||
|
||||
static uint8_t sbc_samples_storage[44100*4];
|
||||
static uint32_t fill_audio_ring_buffer_timeout_ms;
|
||||
static uint32_t time_audio_data_sent; // ms
|
||||
static uint32_t acc_num_missed_samples;
|
||||
static uint32_t samples_ready;
|
||||
static btstack_timer_source_t fill_audio_ring_buffer_timer;
|
||||
static btstack_ring_buffer_t sbc_ring_buffer;
|
||||
|
||||
static paTestData sin_data;
|
||||
|
||||
@ -133,23 +120,24 @@ static int hxcmod_initialized = 0;
|
||||
static modcontext mod_context;
|
||||
static tracker_buffer_state trkbuf;
|
||||
|
||||
|
||||
typedef enum {
|
||||
STREAM_SINE,
|
||||
STREAM_MOD
|
||||
} stream_data_source_t;
|
||||
|
||||
static uint8_t int_seid = 0;
|
||||
static uint8_t acp_seid = 0;
|
||||
static uint16_t a2dp_cid = 0;
|
||||
static int start_streaming_timer = 0;
|
||||
|
||||
a2dp_state_t app_state = A2DP_IDLE;
|
||||
stream_data_source_t data_source = STREAM_SINE;
|
||||
|
||||
static btstack_packet_callback_registration_t hci_event_callback_registration;
|
||||
static void avdtp_fill_audio_ring_buffer_timer_start(void);
|
||||
|
||||
static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
||||
UNUSED(channel);
|
||||
UNUSED(size);
|
||||
|
||||
bd_addr_t event_addr;
|
||||
uint8_t signal_identifier;
|
||||
uint8_t status;
|
||||
|
||||
switch (packet_type) {
|
||||
|
||||
@ -167,13 +155,36 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
break;
|
||||
case HCI_EVENT_AVDTP_META:
|
||||
switch (packet[2]){
|
||||
case AVDTP_SUBEVENT_STREAMING_CAN_SEND_MEDIA_PACKET_NOW: {
|
||||
avdtp_source_stream_send_media_payload(local_stream_endpoint->l2cap_media_cid, &sc.sbc_ring_buffer, 0);
|
||||
if (btstack_ring_buffer_bytes_available(&sc.sbc_ring_buffer)){
|
||||
avdtp_source_stream_endpoint_request_can_send_now(local_stream_endpoint);
|
||||
case AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED:
|
||||
int_seid = avdtp_subevent_streaming_connection_established_get_int_seid(packet);
|
||||
acp_seid = avdtp_subevent_streaming_connection_established_get_acp_seid(packet);
|
||||
a2dp_cid = avdtp_subevent_streaming_connection_established_get_avdtp_cid(packet);
|
||||
printf(" --- application --- AVDTP_SUBEVENT_STREAMING_CONNECTION_ESTABLISHED --- a2dp_cid 0x%02x, local seid %d, remote seid %d\n", a2dp_cid, int_seid, acp_seid);
|
||||
break;
|
||||
case AVDTP_SUBEVENT_SIGNALING_ACCEPT:
|
||||
signal_identifier = avdtp_subevent_signaling_accept_get_signal_identifier(packet);
|
||||
status = avdtp_subevent_signaling_accept_get_status(packet);
|
||||
printf(" --- application --- Accepted %d\n", signal_identifier);
|
||||
switch (signal_identifier){
|
||||
case AVDTP_SI_START:
|
||||
if (start_streaming_timer){
|
||||
if (avdtp_source_stream_endpoint_ready(int_seid)){
|
||||
avdtp_fill_audio_ring_buffer_timer_start();
|
||||
start_streaming_timer = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AVDTP_SUBEVENT_STREAMING_CAN_SEND_MEDIA_PACKET_NOW:
|
||||
avdtp_source_stream_send_media_payload(int_seid, &sbc_ring_buffer, 0);
|
||||
if (btstack_ring_buffer_bytes_available(&sbc_ring_buffer)){
|
||||
avdtp_source_stream_endpoint_request_can_send_now(int_seid);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
app_state = A2DP_IDLE;
|
||||
printf(" --- application --- not implemented\n");
|
||||
@ -187,7 +198,7 @@ static void packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packe
|
||||
default:
|
||||
// other packet type
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void show_usage(void){
|
||||
@ -196,33 +207,15 @@ static void show_usage(void){
|
||||
printf("\n--- Bluetooth AVDTP SOURCE Test Console %s ---\n", bd_addr_to_str(iut_address));
|
||||
printf("c - create connection to addr %s\n", bd_addr_to_str(remote));
|
||||
printf("C - disconnect\n");
|
||||
printf("d - discover stream endpoints\n");
|
||||
|
||||
if (!active_remote_sep){
|
||||
printf("Ctrl-c - exit\n");
|
||||
printf("---\n");
|
||||
return;
|
||||
}
|
||||
printf("m - start stream with %d\n", active_remote_sep->seid);
|
||||
printf("x - start streaming sine\n");
|
||||
if (hxcmod_initialized){
|
||||
printf("z - start streaming '%s'\n", mod_name);
|
||||
}
|
||||
printf("X - stop streaming\n");
|
||||
printf("A - abort stream with %d\n", active_remote_sep->seid);
|
||||
printf("S - stop stream with %d\n", active_remote_sep->seid);
|
||||
printf("P - suspend stream with %d\n", active_remote_sep->seid);
|
||||
printf("Ctrl-c - exit\n");
|
||||
printf("---\n");
|
||||
}
|
||||
|
||||
static uint8_t media_sbc_codec_capabilities[] = {
|
||||
0xFF,//(AVDTP_SBC_44100 << 4) | AVDTP_SBC_STEREO,
|
||||
0xFF,//(AVDTP_SBC_BLOCK_LENGTH_16 << 4) | (AVDTP_SBC_SUBBANDS_8 << 2) | AVDTP_SBC_ALLOCATION_METHOD_LOUDNESS,
|
||||
2, 53
|
||||
};
|
||||
|
||||
|
||||
static void produce_sine_audio(int16_t * pcm_buffer, void *user_data, int num_samples_to_write){
|
||||
paTestData *data = (paTestData*)user_data;
|
||||
int count;
|
||||
@ -262,8 +255,8 @@ static int fill_sbc_ring_buffer(void){
|
||||
int num_audio_samples_per_sbc_buffer = btstack_sbc_encoder_num_audio_frames();
|
||||
// int audio_bytes_to_read = num_audio_samples_per_sbc_buffer * BYTES_PER_AUDIO_SAMPLE;
|
||||
|
||||
while (sc.samples_ready >= num_audio_samples_per_sbc_buffer
|
||||
&& btstack_ring_buffer_bytes_free(&sc.sbc_ring_buffer) >= btstack_sbc_encoder_sbc_buffer_length()){
|
||||
while (samples_ready >= num_audio_samples_per_sbc_buffer
|
||||
&& btstack_ring_buffer_bytes_free(&sbc_ring_buffer) >= btstack_sbc_encoder_sbc_buffer_length()){
|
||||
|
||||
uint8_t pcm_frame[256*BYTES_PER_AUDIO_SAMPLE];
|
||||
|
||||
@ -275,10 +268,10 @@ static int fill_sbc_ring_buffer(void){
|
||||
|
||||
total_num_bytes_read += num_audio_samples_per_sbc_buffer;
|
||||
|
||||
if (btstack_ring_buffer_bytes_free(&sc.sbc_ring_buffer) >= sbc_frame_size ){
|
||||
if (btstack_ring_buffer_bytes_free(&sbc_ring_buffer) >= sbc_frame_size ){
|
||||
uint8_t size_buffer = sbc_frame_size;
|
||||
btstack_ring_buffer_write(&sc.sbc_ring_buffer, &size_buffer, 1);
|
||||
btstack_ring_buffer_write(&sc.sbc_ring_buffer, sbc_frame, sbc_frame_size);
|
||||
btstack_ring_buffer_write(&sbc_ring_buffer, &size_buffer, 1);
|
||||
btstack_ring_buffer_write(&sbc_ring_buffer, sbc_frame, sbc_frame_size);
|
||||
} else {
|
||||
printf("No space in sbc buffer\n");
|
||||
}
|
||||
@ -288,51 +281,53 @@ static int fill_sbc_ring_buffer(void){
|
||||
|
||||
static void avdtp_fill_audio_ring_buffer_timeout_handler(btstack_timer_source_t * timer){
|
||||
UNUSED(timer);
|
||||
btstack_run_loop_set_timer(&sc.fill_audio_ring_buffer_timer, sc.fill_audio_ring_buffer_timeout_ms); // 2 seconds timeout
|
||||
btstack_run_loop_add_timer(&sc.fill_audio_ring_buffer_timer);
|
||||
btstack_run_loop_set_timer(&fill_audio_ring_buffer_timer, fill_audio_ring_buffer_timeout_ms); // 2 seconds timeout
|
||||
btstack_run_loop_add_timer(&fill_audio_ring_buffer_timer);
|
||||
uint32_t now = btstack_run_loop_get_time_ms();
|
||||
|
||||
uint32_t update_period_ms = sc.fill_audio_ring_buffer_timeout_ms;
|
||||
if (sc.time_audio_data_sent > 0){
|
||||
update_period_ms = now - sc.time_audio_data_sent;
|
||||
uint32_t update_period_ms = fill_audio_ring_buffer_timeout_ms;
|
||||
if (time_audio_data_sent > 0){
|
||||
update_period_ms = now - time_audio_data_sent;
|
||||
}
|
||||
uint32_t num_samples = (update_period_ms * 44100) / 1000;
|
||||
sc.acc_num_missed_samples += (update_period_ms * 44100) % 1000;
|
||||
acc_num_missed_samples += (update_period_ms * 44100) % 1000;
|
||||
|
||||
if (sc.acc_num_missed_samples >= 1000){
|
||||
if (acc_num_missed_samples >= 1000){
|
||||
num_samples++;
|
||||
sc.acc_num_missed_samples -= 1000;
|
||||
acc_num_missed_samples -= 1000;
|
||||
}
|
||||
|
||||
sc.time_audio_data_sent = now;
|
||||
sc.samples_ready += num_samples;
|
||||
time_audio_data_sent = now;
|
||||
samples_ready += num_samples;
|
||||
|
||||
int total_num_bytes_read = fill_sbc_ring_buffer();
|
||||
// schedule sending
|
||||
if (total_num_bytes_read != 0){
|
||||
avdtp_source_stream_endpoint_request_can_send_now(local_stream_endpoint);
|
||||
avdtp_source_stream_endpoint_request_can_send_now(int_seid);
|
||||
}
|
||||
}
|
||||
|
||||
static void avdtp_fill_audio_ring_buffer_timer_start(void){
|
||||
btstack_run_loop_remove_timer(&sc.fill_audio_ring_buffer_timer);
|
||||
btstack_run_loop_set_timer_handler(&sc.fill_audio_ring_buffer_timer, avdtp_fill_audio_ring_buffer_timeout_handler);
|
||||
// btstack_run_loop_set_timer_context(&sc.fill_audio_ring_buffer_timer, stream_endpoint);
|
||||
btstack_run_loop_set_timer(&sc.fill_audio_ring_buffer_timer, sc.fill_audio_ring_buffer_timeout_ms); // 50 ms timeout
|
||||
btstack_run_loop_add_timer(&sc.fill_audio_ring_buffer_timer);
|
||||
btstack_run_loop_remove_timer(&fill_audio_ring_buffer_timer);
|
||||
btstack_run_loop_set_timer_handler(&fill_audio_ring_buffer_timer, avdtp_fill_audio_ring_buffer_timeout_handler);
|
||||
// btstack_run_loop_set_timer_context(&fill_audio_ring_buffer_timer, stream_endpoint);
|
||||
btstack_run_loop_set_timer(&fill_audio_ring_buffer_timer, fill_audio_ring_buffer_timeout_ms); // 50 ms timeout
|
||||
btstack_run_loop_add_timer(&fill_audio_ring_buffer_timer);
|
||||
}
|
||||
|
||||
static void avdtp_fill_audio_ring_buffer_timer_stop(void){
|
||||
btstack_run_loop_remove_timer(&sc.fill_audio_ring_buffer_timer);
|
||||
btstack_run_loop_remove_timer(&fill_audio_ring_buffer_timer);
|
||||
}
|
||||
|
||||
static void avdtp_source_stream_data_start(void){
|
||||
if (!avdtp_source_stream_endpoint_ready(local_stream_endpoint)) return;
|
||||
avdtp_fill_audio_ring_buffer_timer_start();
|
||||
printf(" --- application --- avdtp_source_stream_data_start --- local seid %d, remote seid %d\n", int_seid, acp_seid);
|
||||
a2dp_source_start_stream(a2dp_cid, int_seid, acp_seid);
|
||||
start_streaming_timer = 1;
|
||||
}
|
||||
|
||||
static void avdtp_source_stream_data_stop(){
|
||||
if (!avdtp_source_stream_endpoint_ready(local_stream_endpoint)) return;
|
||||
a2dp_source_stop_stream(a2dp_cid, int_seid, acp_seid);
|
||||
if (!avdtp_source_stream_endpoint_ready(int_seid)) return;
|
||||
avdtp_fill_audio_ring_buffer_timer_stop();
|
||||
}
|
||||
|
||||
@ -350,14 +345,15 @@ static void stdin_process(btstack_data_source_t *ds, btstack_data_source_callbac
|
||||
break;
|
||||
case 'C':
|
||||
printf("Disconnect not implemented\n");
|
||||
a2dp_source_disconnect(avdtp_cid);
|
||||
a2dp_source_disconnect(a2dp_cid);
|
||||
break;
|
||||
case 'x':
|
||||
// a2dp_source_start_stream(avdtp_cid, int_seid, acp_seid);
|
||||
avdtp_source_stream_data_start();
|
||||
break;
|
||||
case 'z':
|
||||
avdtp_source_stream_data_start();
|
||||
break;
|
||||
case 'X':
|
||||
// a2dp_source_stop_stream(avdtp_cid, int_seid, acp_seid);
|
||||
avdtp_source_stream_data_stop();
|
||||
break;
|
||||
default:
|
||||
@ -394,8 +390,8 @@ int btstack_main(int argc, const char * argv[]){
|
||||
gap_set_class_of_device(0x200408);
|
||||
|
||||
memset(sbc_samples_storage, 0, sizeof(sbc_samples_storage));
|
||||
btstack_ring_buffer_init(&sc.sbc_ring_buffer, sbc_samples_storage, sizeof(sbc_samples_storage));
|
||||
sc.fill_audio_ring_buffer_timeout_ms = 50;
|
||||
btstack_ring_buffer_init(&sbc_ring_buffer, sbc_samples_storage, sizeof(sbc_samples_storage));
|
||||
fill_audio_ring_buffer_timeout_ms = 50;
|
||||
|
||||
/* initialise sinusoidal wavetable */
|
||||
int i;
|
||||
|
Loading…
x
Reference in New Issue
Block a user