瀏覽代碼

Merge remote-tracking branch 'origin/master' into master-cmake

Conflicts:
	components/driver_bt/bt_app_sink.c
Sebastien 5 年之前
父節點
當前提交
1f508039e8

+ 0 - 0
components/bluetooth/platform_bt_core.c → components/bluetooth/bt_app_core.c


+ 0 - 0
components/bluetooth/platform_bt_core.h → components/bluetooth/bt_app_core.h


+ 39 - 28
components/bluetooth/platform_bt_sink.c → components/bluetooth/bt_app_sink.c

@@ -7,13 +7,14 @@
    CONDITIONS OF ANY KIND, either express or implied.
 */
 
-#include <platform_bt_sink.h>
 #include <stdint.h>
 #include <stdbool.h>
 #include <stdlib.h>
 #include <string.h>
 #include "esp_log.h"
 
+#include "bt_app_core.h"
+#include "bt_app_sink.h"
 #include "esp_bt.h"
 #include "esp_bt_main.h"
 #include "esp_bt_device.h"
@@ -21,14 +22,13 @@
 #include "esp_a2dp_api.h"
 #include "esp_avrc_api.h"
 #include "nvs.h"
-#include "platform_config.h"
+#include "config.h"
 #include "freertos/FreeRTOS.h"
 #include "freertos/task.h"
 #include "trace.h"
 #include "audio_controls.h"
 #include "sys/lock.h"
 #include "display.h"
-#include "platform_bt_core.h"
 
 // AVRCP used transaction label
 #define APP_RC_CT_TL_GET_CAPS            (0)
@@ -71,8 +71,7 @@ static esp_avrc_rn_evt_cap_mask_t s_avrc_peer_rn_cap;
 static _lock_t s_volume_lock;
 static uint8_t s_volume = 0;
 static bool s_volume_notify;
-static bool s_playing = false; 
-static enum { AUDIO_IDLE, AUDIO_CONNECTED, AUDIO_ACTIVATED } s_audio = AUDIO_IDLE;
+static enum { AUDIO_IDLE, AUDIO_CONNECTED, AUDIO_PLAYING } s_audio = AUDIO_IDLE;
 
 static int s_sample_rate;
 static int tl;
@@ -102,7 +101,7 @@ static void bt_volume_down(void) {
 }
 
 static void bt_toggle(void) {
-	if (s_playing) esp_avrc_ct_send_passthrough_cmd(tl++ & 0x0f, ESP_AVRC_PT_CMD_STOP, ESP_AVRC_PT_CMD_STATE_PRESSED);
+	if (s_audio == AUDIO_PLAYING) esp_avrc_ct_send_passthrough_cmd(tl++ & 0x0f, ESP_AVRC_PT_CMD_STOP, ESP_AVRC_PT_CMD_STATE_PRESSED);
 	else esp_avrc_ct_send_passthrough_cmd(tl++, ESP_AVRC_PT_CMD_PLAY, ESP_AVRC_PT_CMD_STATE_PRESSED);
 }
 
@@ -139,14 +138,14 @@ const static actrls_t controls = {
 /* disconnection */
 void bt_disconnect(void) {
 	displayer_control(DISPLAYER_SHUTDOWN);
-	if (s_playing) esp_avrc_ct_send_passthrough_cmd(tl++ & 0x0f, ESP_AVRC_PT_CMD_STOP, ESP_AVRC_PT_CMD_STATE_PRESSED);
+	if (s_audio == AUDIO_PLAYING) esp_avrc_ct_send_passthrough_cmd(tl++ & 0x0f, ESP_AVRC_PT_CMD_STOP, ESP_AVRC_PT_CMD_STATE_PRESSED);
 	actrls_unset();
-	ESP_LOGI(BT_AV_TAG, "forced disconnection");
+	ESP_LOGI(BT_AV_TAG, "forced disconnection %d", s_audio);
 }
 
 /* update metadata if any */
 void update_metadata(bool force) {
-	if ((s_metadata.updated || force) && s_audio == AUDIO_ACTIVATED) {
+	if ((s_metadata.updated || force) && s_audio == AUDIO_PLAYING) {
 		(*bt_app_a2d_cmd_cb)(BT_SINK_PROGRESS, -1, s_metadata.duration);
 		(*bt_app_a2d_cmd_cb)(BT_SINK_METADATA, s_metadata.artist, s_metadata.album, s_metadata.title);
 		s_metadata.updated = false;
@@ -231,7 +230,6 @@ void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param
     switch (event) {
     case ESP_AVRC_CT_METADATA_RSP_EVT:
         bt_app_alloc_meta_buffer(param);
-        /* no break */
         /* fall through */
     case ESP_AVRC_CT_CONNECTION_STATE_EVT:
     case ESP_AVRC_CT_PASSTHROUGH_RSP_EVT:
@@ -291,18 +289,17 @@ static void bt_av_hdl_a2d_evt(uint16_t event, void *p_param)
 			
 			// verify that we can take control
 			if ((*bt_app_a2d_cmd_cb)(BT_SINK_AUDIO_STARTED, s_sample_rate)) {
-				// resynchronize events as¨PLAY might be sent before STARTED ...
-				s_audio = AUDIO_ACTIVATED;
 				
-				// send PLAY there, in case it was sent before AUDIO_STATE
-				if (s_playing) (*bt_app_a2d_cmd_cb)(BT_SINK_PLAY);
+				// if PLAY is sent before AUDIO_STARTED, generate the event here
+				s_audio = AUDIO_PLAYING;
+				(*bt_app_a2d_cmd_cb)(BT_SINK_PLAY);
 				
 				// force metadata update
 				update_metadata(true);
 				
 				actrls_set(controls, NULL);
-			} else if (s_playing) {
-				// if decoder is busy but BT is playing, stop it (would be better to not ACK this command, but don't know how)
+			} else {
+				// if decoder is busy, stop it (would be better to not ACK this command, but don't know how)
 				esp_avrc_ct_send_passthrough_cmd(tl++ & 0x0f, ESP_AVRC_PT_CMD_STOP, ESP_AVRC_PT_CMD_STATE_PRESSED);	
 			}	
 		} else if (ESP_A2D_AUDIO_STATE_STOPPED == a2d->audio_stat.state ||
@@ -383,19 +380,33 @@ void bt_av_notify_evt_handler(uint8_t event_id, esp_avrc_rn_param_t *event_param
         break;
     case ESP_AVRC_RN_PLAY_STATUS_CHANGE:
         ESP_LOGI(BT_AV_TAG, "Playback status changed: 0x%x", event_parameter->playback);
-		// re-synchronize events
-		s_playing = (event_parameter->playback == ESP_AVRC_PLAYBACK_PLAYING);
-		if (event_parameter->playback == ESP_AVRC_PLAYBACK_PLAYING && s_audio != AUDIO_IDLE) {
-			// if decoder is busy then stop (would be better to not ACK this command, but don't know how)
-			if (s_audio == AUDIO_CONNECTED || !(*bt_app_a2d_cmd_cb)(BT_SINK_PLAY)) {
-				esp_avrc_ct_send_passthrough_cmd(tl++ & 0x0f, ESP_AVRC_PT_CMD_STOP, ESP_AVRC_PT_CMD_STATE_PRESSED);
-			} else {
-				update_metadata(false);
+		if (s_audio != AUDIO_IDLE) {
+			switch (event_parameter->playback) {
+			case ESP_AVRC_PLAYBACK_PLAYING:
+				// if decoder is busy then stop (would be better to not ACK this command, but don't know how)
+				if (s_audio != AUDIO_PLAYING && !(*bt_app_a2d_cmd_cb)(BT_SINK_PLAY)) {
+					ESP_LOGW(BT_AV_TAG, "Player busy with another controller");					
+					esp_avrc_ct_send_passthrough_cmd(tl++ & 0x0f, ESP_AVRC_PT_CMD_STOP, ESP_AVRC_PT_CMD_STATE_PRESSED);
+				} else {
+					s_audio = AUDIO_PLAYING;
+					update_metadata(false);
+				}
+				break;		
+			case ESP_AVRC_PLAYBACK_PAUSED:
+				s_audio = AUDIO_CONNECTED;
+				(*bt_app_a2d_cmd_cb)(BT_SINK_PAUSE);
+				break;
+			case ESP_AVRC_PLAYBACK_STOPPED:
+				s_audio = AUDIO_CONNECTED;
+				(*bt_app_a2d_cmd_cb)(BT_SINK_PROGRESS, 0, -1);			
+				(*bt_app_a2d_cmd_cb)(BT_SINK_STOP);
+				break;
+			default:
+				ESP_LOGI(BT_AV_TAG, "Un-handled event");
+				break;
 			}	
-		} else if (event_parameter->playback == ESP_AVRC_PLAYBACK_PAUSED) (*bt_app_a2d_cmd_cb)(BT_SINK_PAUSE);
-		else if (event_parameter->playback == ESP_AVRC_PLAYBACK_STOPPED) {
-			(*bt_app_a2d_cmd_cb)(BT_SINK_PROGRESS, 0, -1);			
-			(*bt_app_a2d_cmd_cb)(BT_SINK_STOP);
+		} else {
+			ESP_LOGW(BT_AV_TAG, "Not yet in BT connected mode: 0x%x", event_parameter->playback);
 		}	
         bt_av_playback_changed();
         break;

+ 2 - 1
components/bluetooth/platform_bt_sink.h → components/bluetooth/bt_app_sink.h

@@ -10,7 +10,8 @@
 #define __BT_APP_SINK_H__
 
 #include <stdint.h>
-#include <platform_bt_core.h>
+
+#include "platform_bt_core.h"
 typedef enum { 	BT_SINK_CONNECTED, BT_SINK_DISCONNECTED, BT_SINK_AUDIO_STARTED, BT_SINK_AUDIO_STOPPED, BT_SINK_PLAY, BT_SINK_STOP, BT_SINK_PAUSE, 
 				BT_SINK_RATE, BT_SINK_VOLUME, BT_SINK_METADATA, BT_SINK_PROGRESS } bt_sink_cmd_t;
 				

+ 1 - 1
components/bluetooth/platform_bt_source.c → components/bluetooth/bt_app_source.c

@@ -3,6 +3,7 @@
 #include <ctype.h>
 #include <stdlib.h>
 
+#include "platform_bt_core.h"
 #include "esp_log.h"
 #include "esp_bt.h"
 #include "esp_bt_device.h"
@@ -15,7 +16,6 @@
 #include "esp_wifi.h"
 #include "freertos/timers.h"
 #include "argtable3/argtable3.h"
-#include "platform_bt_core.h"
 #include "platform_config.h"
 #include "trace.h"
 

+ 1 - 0
components/display/display.c

@@ -362,6 +362,7 @@ void displayer_control(enum displayer_cmd_e cmd, ...) {
 		break;
 	case DISPLAYER_TIMER_RUN:
 		if (!displayer.timer) {
+			display_bus(&displayer, DISPLAY_BUS_TAKE);
 			displayer.timer = true;		
 			displayer.tick = xTaskGetTickCount();		
 		}	

+ 7 - 4
components/squeezelite/decode_external.c

@@ -23,7 +23,8 @@
 #include "squeezelite.h"
 #include "raop_sink.h"
 #include <math.h>
-#include <platform_bt_sink.h>
+
+#include "bt_app_sink.h"
 
 #define LOCK_O   mutex_lock(outputbuf->mutex)
 #define UNLOCK_O mutex_unlock(outputbuf->mutex)
@@ -132,21 +133,23 @@ static bool bt_sink_cmd_handler(bt_sink_cmd_t cmd, va_list args)
 	case BT_SINK_AUDIO_STOPPED:	
 		if (output.external == DECODE_BT) {
 			if (output.state > OUTPUT_STOPPED) output.state = OUTPUT_STOPPED;
+			output.stop_time = gettime_ms();
 			LOG_INFO("BT sink stopped");
 		}	
 		break;
 	case BT_SINK_PLAY:
 		output.state = OUTPUT_RUNNING;
-		LOG_INFO("BT sink playing");
+		LOG_INFO("BT playing");
 		break;
 	case BT_SINK_STOP:		
 		_buf_flush(outputbuf);
 		output.state = OUTPUT_STOPPED;
 		output.stop_time = gettime_ms();
-		LOG_INFO("BT sink stopped");
+		LOG_INFO("BT stopped");
 		break;
 	case BT_SINK_PAUSE:		
-		LOG_INFO("BT sink paused, just silence");
+		output.stop_time = gettime_ms();
+		LOG_INFO("BT paused, just silence");
 		break;
 	case BT_SINK_RATE:
 		output.next_sample_rate = output.current_sample_rate = va_arg(args, u32_t);