Finalize buttons for AirPlay and BT, worked on coexistence

This commit is contained in:
philippe44
2020-01-04 02:03:34 -08:00
parent d0d98c778b
commit 540466e746
18 changed files with 361 additions and 152 deletions

View File

@@ -69,7 +69,7 @@ static void lms_next(void) {
cli_send_cmd("button fwd");
}
static actrls_t controls = {
const static actrls_t controls = {
lms_volume_up, lms_volume_down, // volume up, volume down
lms_toggle, lms_play, // toggle, play
lms_pause, lms_stop, // pause, stop
@@ -102,7 +102,7 @@ static void cli_send_cmd(char *cmd) {
LOG_WARN("cannot send CLI %s", packet);
}
close(sock);
closesocket(sock);
}
/****************************************************************************************

View File

@@ -65,7 +65,7 @@ static void *decode_thread() {
toend = (stream.state <= DISCONNECT);
UNLOCK_S;
LOCK_O;
space = _buf_space(outputbuf);
space = !output.external ? _buf_space(outputbuf) : 0;
UNLOCK_O;
LOCK_D;
@@ -117,10 +117,6 @@ static void *decode_thread() {
}
}
#if EMBEDDED
deregister_external();
#endif
return 0;
}
@@ -246,6 +242,9 @@ void decode_close(void) {
pthread_join(thread, NULL);
#endif
mutex_destroy(decode.mutex);
#if EMBEDDED
deregister_external();
#endif
}
void decode_flush(void) {

View File

@@ -29,7 +29,7 @@
#define LOCK_D mutex_lock(decode.mutex);
#define UNLOCK_D mutex_unlock(decode.mutex);
enum { DECODE_BT = 1, DECODE_AIRPLAY };
enum { DECODE_BT = 1, DECODE_RAOP };
extern struct outputstate output;
extern struct decodestate decode;
@@ -60,8 +60,8 @@ static void sink_data_handler(const uint8_t *data, uint32_t len)
{
size_t bytes, space;
// would be better to lock decoder, but really, it does not matter
if (decode.state != DECODE_STOPPED) {
// would be better to lock output, but really, it does not matter
if (!output.external) {
LOG_SDEBUG("Cannot use external sink while LMS is controlling player");
return;
}
@@ -99,19 +99,18 @@ static void sink_data_handler(const uint8_t *data, uint32_t len)
* BT sink command handler
*/
static void bt_sink_cmd_handler(bt_sink_cmd_t cmd, ...)
static bool bt_sink_cmd_handler(bt_sink_cmd_t cmd, ...)
{
va_list args;
LOCK_D;
if (decode.state != DECODE_STOPPED) {
LOG_WARN("Cannot use BT sink while LMS is controlling player");
UNLOCK_D;
bt_sink_cmd(BT_SINK_DISCONNECTED);
return;
// don't LOCK_O as there is always a chance that LMS takes control later anyway
if (output.external != DECODE_BT && output.state > OUTPUT_STOPPED) {
LOG_WARN("Cannot use BT sink while LMS/AirPlay is controlling player");
return false;
}
LOCK_D;
va_start(args, cmd);
if (cmd != BT_SINK_VOLUME) LOCK_O;
@@ -120,12 +119,15 @@ static void bt_sink_cmd_handler(bt_sink_cmd_t cmd, ...)
case BT_SINK_CONNECTED:
output.external = DECODE_BT;
output.state = OUTPUT_STOPPED;
output.frames_played = 0;
_buf_flush(outputbuf);
bt_master(true);
LOG_INFO("BT sink started");
break;
case BT_SINK_DISCONNECTED:
if (output.external == DECODE_BT) {
output.external = 0;
output.state = OUTPUT_OFF;
bt_master(false);
LOG_INFO("BT sink stopped");
}
break;
@@ -155,6 +157,7 @@ static void bt_sink_cmd_handler(bt_sink_cmd_t cmd, ...)
UNLOCK_D;
va_end(args);
return true;
}
/****************************************************************************************
@@ -171,15 +174,15 @@ static void raop_sink_data_handler(const uint8_t *data, uint32_t len, u32_t play
/****************************************************************************************
* AirPlay sink command handler
*/
void raop_sink_cmd_handler(raop_event_t event, void *param)
static bool raop_sink_cmd_handler(raop_event_t event, void *param)
{
LOCK_D;
if (decode.state != DECODE_STOPPED) {
LOG_WARN("Cannot use Airplay sink while LMS is controlling player");
UNLOCK_D;
return;
// don't LOCK_O as there is always a chance that LMS takes control later anyway
if (output.external != DECODE_RAOP && output.state > OUTPUT_STOPPED) {
LOG_WARN("Cannot use Airplay sink while LMS/BT is controlling player");
return false;
}
LOCK_D;
if (event != RAOP_VOLUME) LOCK_O;
@@ -233,6 +236,10 @@ void raop_sink_cmd_handler(raop_event_t event, void *param)
case RAOP_SETUP:
// we need a fair bit of space for RTP process
_buf_resize(outputbuf, RAOP_OUTPUT_SIZE);
output.frames_played = 0;
output.external = DECODE_RAOP;
output.state = OUTPUT_STOPPED;
raop_master(true);
LOG_INFO("resizing buffer %u", outputbuf->size);
break;
case RAOP_STREAM:
@@ -242,16 +249,14 @@ void raop_sink_cmd_handler(raop_event_t event, void *param)
raop_sync.idx = 0;
raop_sync.start = true;
raop_sync.enabled = !strcasestr(output.device, "BT");
output.external = DECODE_AIRPLAY;
output.next_sample_rate = output.current_sample_rate = RAOP_SAMPLE_RATE;
output.state = OUTPUT_STOPPED;
break;
case RAOP_STOP:
LOG_INFO("Stop", NULL);
output.external = 0;
output.state = OUTPUT_OFF;
output.frames_played = 0;
raop_state = event;
raop_master(false);
break;
case RAOP_FLUSH:
LOG_INFO("Flush", NULL);
@@ -286,6 +291,7 @@ void raop_sink_cmd_handler(raop_event_t event, void *param)
if (event != RAOP_VOLUME) UNLOCK_O;
UNLOCK_D;
return true;
}
/****************************************************************************************
@@ -300,7 +306,7 @@ void register_external(void) {
} else {
LOG_WARN("Cannot be a BT sink and source");
}
if(enable_airplay){
if (enable_airplay){
raop_sink_init(raop_sink_cmd_handler, raop_sink_data_handler);
LOG_INFO("Initializing AirPlay sink");
}
@@ -311,8 +317,21 @@ void deregister_external(void) {
bt_sink_deinit();
LOG_INFO("Stopping BT sink");
}
if(enable_airplay){
if (enable_airplay){
raop_sink_deinit();
LOG_INFO("Stopping AirPlay sink");
}
}
void decode_resume(int external) {
switch (external) {
case DECODE_BT:
bt_disconnect();
break;
case DECODE_RAOP:
raop_disconnect();
raop_state = RAOP_STOP;
break;
}
_buf_resize(outputbuf, output.init_size);
}

View File

@@ -48,3 +48,9 @@ int pthread_create_name(pthread_t *thread, _CONST pthread_attr_t *attr,
uint32_t _gettime_ms_(void) {
return (uint32_t) (esp_timer_get_time() / 1000);
}
extern void cli_controls_init(void);
void embedded_init(void) {
cli_controls_init();
}

View File

@@ -43,8 +43,11 @@ uint32_t _gettime_ms_(void);
int pthread_create_name(pthread_t *thread, _CONST pthread_attr_t *attr,
void *(*start_routine)( void * ), void *arg, char *name);
void embedded_init(void);
void register_external(void);
void deregister_external(void);
void decode_resume(int external);
void (*server_notify)(in_addr_t ip, u16_t hport, u16_t cport);
#endif // EMBEDDED_H

View File

@@ -761,6 +761,7 @@ int main(int argc, char **argv) {
stream_init(log_stream, stream_buf_size);
#if EMBEDDED
embedded_init();
output_init_embedded(log_output, output_device, output_buf_size, output_params, rates, rate_delay, idle);
#else
if (!strcmp(output_device, "-")) {

View File

@@ -57,8 +57,6 @@ void output_init_embedded(log_level level, char *device, unsigned output_buf_siz
output.start_frames = FRAME_BLOCK;
output.rate_delay = rate_delay;
cli_controls_init();
if (strcasestr(device, "BT ")) {
LOG_INFO("init Bluetooth");
close_cb = &output_close_bt;

View File

@@ -330,6 +330,12 @@ static void process_strm(u8_t *pkt, int len) {
LOCK_O;
output.state = jiffies ? OUTPUT_START_AT : OUTPUT_RUNNING;
output.start_at = jiffies;
#if EMBEDDED
if (output.external) {
decode_resume(output.external);
output.external = 0;
}
#endif
UNLOCK_O;
LOG_DEBUG("unpause at: %u now: %u", jiffies, gettime_ms());
@@ -373,8 +379,10 @@ static void process_strm(u8_t *pkt, int len) {
sendSTAT("STMc", 0);
sentSTMu = sentSTMo = sentSTMl = false;
LOCK_O;
#if EMBEDDED
if (output.external) decode_resume(output.external);
output.external = 0;
_buf_resize(outputbuf, output.init_size);
#endif
output.threshold = strm->output_threshold;
output.next_replay_gain = unpackN(&strm->replay_gain);
output.fade_mode = strm->transition_type - '0';