mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-01-26 12:35:25 +00:00
a2dp taret demo: add volume control
This commit is contained in:
parent
14e3e2c227
commit
502593062d
@ -308,7 +308,7 @@ hid_keyboard_demo: ${CORE_OBJ} ${COMMON_OBJ} ${CLASSIC_OBJ} ${SDP_CLIENT} btstac
|
||||
hid_mouse_demo: ${CORE_OBJ} ${COMMON_OBJ} ${CLASSIC_OBJ} ${SDP_CLIENT} btstack_ring_buffer.o hid_device.o btstack_hid_parser.o hid_mouse_demo.o
|
||||
${CC} $^ ${CFLAGS} ${LDFLAGS} -o $@
|
||||
|
||||
a2dp_source_demo: ${CORE_OBJ} ${COMMON_OBJ} ${CLASSIC_OBJ} ${SDP_CLIENT} ${SBC_ENCODER_OBJ} ${AVDTP_OBJ} ${HXCMOD_PLAYER_OBJ} avrcp.o avrcp_target.o a2dp_source_demo.c
|
||||
a2dp_source_demo: ${CORE_OBJ} ${COMMON_OBJ} ${CLASSIC_OBJ} ${SDP_CLIENT} ${SBC_ENCODER_OBJ} ${AVDTP_OBJ} ${HXCMOD_PLAYER_OBJ} avrcp.o avrcp_controller.o avrcp_target.o a2dp_source_demo.c
|
||||
${CC} $^ ${CFLAGS} ${LDFLAGS} -o $@
|
||||
|
||||
a2dp_sink_demo: ${CORE_OBJ} ${COMMON_OBJ} ${CLASSIC_OBJ} ${SDP_CLIENT} ${SBC_DECODER_OBJ} ${AVDTP_OBJ} avrcp.o avrcp_controller.o avrcp_target.o btstack_resample.o a2dp_sink_demo.c
|
||||
|
@ -966,8 +966,8 @@ static void show_usage(void){
|
||||
printf("N - stop rewind\n");
|
||||
printf("i - forward\n");
|
||||
printf("I - backward\n");
|
||||
printf("t - volume up\n");
|
||||
printf("T - volume down\n");
|
||||
printf("t - volume up to 70 percent\n");
|
||||
printf("T - volume down to 10 percent\n");
|
||||
printf("p - absolute volume of 50 percent\n");
|
||||
printf("M - mute\n");
|
||||
printf("r - skip\n");
|
||||
@ -1063,12 +1063,12 @@ static void stdin_process(char cmd){
|
||||
status = avrcp_controller_backward(avrcp_controller_cid);
|
||||
break;
|
||||
case 't':
|
||||
printf(" - volume up to 70, avrcp controller cid 0x%02x\n", avrcp_controller_cid);
|
||||
printf(" - volume up to 70 percent, avrcp target cid 0x%02x\n", avrcp_controller_cid);
|
||||
// status = avrcp_controller_volume_up(avrcp_controller_cid);
|
||||
status = avrcp_target_volume_changed(avrcp_target_cid, 70);
|
||||
break;
|
||||
case 'T':
|
||||
printf(" - volume down to 10, avrcp controller cid 0x%02x\n", avrcp_controller_cid);
|
||||
printf(" - volume down to 10 percent, avrcp target cid 0x%02x\n", avrcp_controller_cid);
|
||||
// status = avrcp_controller_volume_down(avrcp_controller_cid);
|
||||
status = avrcp_target_volume_changed(avrcp_target_cid, 10);
|
||||
break;
|
||||
|
@ -152,6 +152,8 @@ static const char * device_addr_string = "00:21:3C:AC:F7:38";
|
||||
static bd_addr_t device_addr;
|
||||
static uint8_t sdp_a2dp_source_service_buffer[150];
|
||||
static uint8_t sdp_avrcp_target_service_buffer[200];
|
||||
static uint8_t sdp_avrcp_controller_service_buffer[200];
|
||||
|
||||
static avdtp_media_codec_configuration_sbc_t sbc_configuration;
|
||||
static btstack_sbc_encoder_state_t sbc_encoder_state;
|
||||
|
||||
@ -166,6 +168,7 @@ static int hxcmod_initialized;
|
||||
static modcontext mod_context;
|
||||
static tracker_buffer_state trkbuf;
|
||||
|
||||
static uint16_t avrcp_controller_cid = 0;
|
||||
|
||||
/* AVRCP Target context START */
|
||||
static const uint8_t subunit_info[] = {
|
||||
@ -230,6 +233,7 @@ avrcp_play_status_info_t play_info;
|
||||
/* LISTING_START(MainConfiguration): Setup Audio Source and AVRCP Target services */
|
||||
static void a2dp_source_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t * event, uint16_t event_size);
|
||||
static void avrcp_target_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
|
||||
static void avrcp_controller_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
|
||||
#ifdef HAVE_BTSTACK_STDIN
|
||||
static void stdin_process(char cmd);
|
||||
#endif
|
||||
@ -252,7 +256,10 @@ static int a2dp_source_and_avrcp_services_init(void){
|
||||
// Initialize AVRCP Target.
|
||||
avrcp_target_init();
|
||||
avrcp_target_register_packet_handler(&avrcp_target_packet_handler);
|
||||
|
||||
// Initialize AVRCP Controller
|
||||
avrcp_controller_init();
|
||||
avrcp_controller_register_packet_handler(&avrcp_controller_packet_handler);
|
||||
|
||||
// Initialize SDP,
|
||||
sdp_init();
|
||||
|
||||
@ -267,10 +274,15 @@ static int a2dp_source_and_avrcp_services_init(void){
|
||||
#ifdef AVRCP_BROWSING_ENABLED
|
||||
supported_features |= (1 << AVRCP_TARGET_SUPPORTED_FEATURE_BROWSING);
|
||||
#endif
|
||||
|
||||
avrcp_target_create_sdp_record(sdp_avrcp_target_service_buffer, 0x10001, supported_features, NULL, NULL);
|
||||
sdp_register_service(sdp_avrcp_target_service_buffer);
|
||||
|
||||
// setup AVRCP Controller
|
||||
memset(sdp_avrcp_controller_service_buffer, 0, sizeof(sdp_avrcp_controller_service_buffer));
|
||||
uint16_t controller_supported_features = (1 << AVRCP_TARGET_SUPPORTED_FEATURE_CATEGORY_MONITOR_OR_AMPLIFIER);
|
||||
avrcp_controller_create_sdp_record(sdp_avrcp_controller_service_buffer, 0x10002, controller_supported_features, NULL, NULL);
|
||||
sdp_register_service(sdp_avrcp_controller_service_buffer);
|
||||
|
||||
// Set local name with a template Bluetooth address, that will be automatically
|
||||
// replaced with a actual address once it is available, i.e. when BTstack boots
|
||||
// up and starts talking to a Bluetooth module.
|
||||
@ -454,8 +466,6 @@ static void a2dp_source_packet_handler(uint8_t packet_type, uint16_t channel, ui
|
||||
|
||||
if (hci_event_packet_get_type(packet) != HCI_EVENT_A2DP_META) return;
|
||||
|
||||
printf("A2DP Meta %x\n", hci_event_a2dp_meta_get_subevent_code(packet));
|
||||
|
||||
switch (hci_event_a2dp_meta_get_subevent_code(packet)){
|
||||
case A2DP_SUBEVENT_SIGNALING_CONNECTION_ESTABLISHED:
|
||||
a2dp_subevent_signaling_connection_established_get_bd_addr(packet, address);
|
||||
@ -598,7 +608,9 @@ static void avrcp_target_packet_handler(uint8_t packet_type, uint16_t channel, u
|
||||
avrcp_target_set_subunit_info(media_tracker.avrcp_cid, AVRCP_SUBUNIT_TYPE_AUDIO, (uint8_t *)subunit_info, sizeof(subunit_info));
|
||||
return;
|
||||
}
|
||||
|
||||
case AVRCP_SUBEVENT_NOTIFICATION_VOLUME_CHANGED:
|
||||
printf("AVRCP Target: new volume %d\n", avrcp_subevent_notification_volume_changed_get_absolute_volume(packet));
|
||||
break;
|
||||
case AVRCP_SUBEVENT_EVENT_IDS_QUERY:
|
||||
status = avrcp_target_supported_events(media_tracker.avrcp_cid, events_num, events, sizeof(events));
|
||||
break;
|
||||
@ -645,6 +657,63 @@ static void avrcp_target_packet_handler(uint8_t packet_type, uint16_t channel, u
|
||||
}
|
||||
}
|
||||
|
||||
static void avrcp_controller_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
|
||||
UNUSED(channel);
|
||||
UNUSED(size);
|
||||
uint16_t local_cid;
|
||||
uint8_t status = 0xFF;
|
||||
bd_addr_t adress;
|
||||
|
||||
if (packet_type != HCI_EVENT_PACKET) return;
|
||||
if (hci_event_packet_get_type(packet) != HCI_EVENT_AVRCP_META) return;
|
||||
switch (packet[2]){
|
||||
case AVRCP_SUBEVENT_CONNECTION_ESTABLISHED: {
|
||||
local_cid = avrcp_subevent_connection_established_get_avrcp_cid(packet);
|
||||
if (avrcp_controller_cid != 0 && avrcp_controller_cid != local_cid) {
|
||||
printf("AVRCP Controller: Connection failed, expected 0x%02X l2cap cid, received 0x%02X\n", avrcp_controller_cid, local_cid);
|
||||
return;
|
||||
}
|
||||
|
||||
status = avrcp_subevent_connection_established_get_status(packet);
|
||||
if (status != ERROR_CODE_SUCCESS){
|
||||
printf("AVRCP Controller: Connection failed: status 0x%02x\n", status);
|
||||
avrcp_controller_cid = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
avrcp_controller_cid = local_cid;
|
||||
avrcp_subevent_connection_established_get_bd_addr(packet, adress);
|
||||
printf("AVRCP Controller: Channel successfully opened: %s, avrcp_controller_cid 0x%02x\n", bd_addr_to_str(adress), avrcp_controller_cid);
|
||||
|
||||
// automatically enable notifications
|
||||
avrcp_controller_enable_notification(avrcp_controller_cid, AVRCP_NOTIFICATION_EVENT_VOLUME_CHANGED);
|
||||
return;
|
||||
}
|
||||
case AVRCP_SUBEVENT_CONNECTION_RELEASED:
|
||||
printf("AVRCP Controller: Channel released: avrcp_controller_cid 0x%02x\n", avrcp_subevent_connection_released_get_avrcp_cid(packet));
|
||||
avrcp_controller_cid = 0;
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
status = packet[5];
|
||||
if (!avrcp_controller_cid) return;
|
||||
|
||||
// ignore INTERIM status
|
||||
if (status == AVRCP_CTYPE_RESPONSE_INTERIM) return;
|
||||
|
||||
switch (packet[2]){
|
||||
case AVRCP_SUBEVENT_NOTIFICATION_VOLUME_CHANGED:{
|
||||
int volume_percentage = avrcp_subevent_notification_volume_changed_get_absolute_volume(packet) * 100 / 127;
|
||||
printf("AVRCP Controller: notification absolute volume changed %d %%\n", volume_percentage);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_BTSTACK_STDIN
|
||||
static void show_usage(void){
|
||||
bd_addr_t iut_address;
|
||||
@ -662,6 +731,8 @@ static void show_usage(void){
|
||||
printf("p - pause streaming\n");
|
||||
printf("w - reconfigure stream for 44100 Hz\n");
|
||||
printf("e - reconfigure stream for 48000 Hz\n");
|
||||
printf("t - volume up\n");
|
||||
printf("T - volume down\n");
|
||||
|
||||
printf("\n--- Bluetooth AVRCP Target Commands %s ---\n", bd_addr_to_str(iut_address));
|
||||
printf("---\n");
|
||||
@ -691,6 +762,15 @@ static void stdin_process(char cmd){
|
||||
case '\r':
|
||||
break;
|
||||
|
||||
case 't':
|
||||
printf(" - volume up\n");
|
||||
status = avrcp_controller_volume_up(avrcp_controller_cid);
|
||||
break;
|
||||
case 'T':
|
||||
printf(" - volume down\n");
|
||||
status = avrcp_controller_volume_down(avrcp_controller_cid);
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
if (media_tracker.avrcp_cid){
|
||||
avrcp_target_set_now_playing_info(media_tracker.avrcp_cid, &tracks[data_source], sizeof(tracks)/sizeof(avrcp_track_t));
|
||||
|
Loading…
x
Reference in New Issue
Block a user