1/* 2 * Copyright (C) 2010-2011 Julien BLACHE <jb@jblache.org> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 */ 18 19#ifdef HAVE_CONFIG_H 20# include <config.h> 21#endif 22 23#include <stdio.h> 24#include <stdlib.h> 25#include <unistd.h> 26#include <fcntl.h> 27#include <string.h> 28#include <inttypes.h> 29#include <stdint.h> 30#include <errno.h> 31#include <time.h> 32#include <pthread.h> 33 34#if defined(__linux__) 35# include <sys/timerfd.h> 36#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 37# include <sys/time.h> 38# include <sys/event.h> 39#endif 40 41#if defined(HAVE_SYS_EVENTFD_H) && defined(HAVE_EVENTFD) 42# define USE_EVENTFD 43# include <sys/eventfd.h> 44#endif 45 46#include <event.h> 47 48#include <gcrypt.h> 49 50#include "db.h" 51#include "daap_query.h" 52#include "logger.h" 53#include "mdns.h" 54#include "conffile.h" 55#include "misc.h" 56#include "rng.h" 57#include "transcode.h" 58#include "player.h" 59#include "raop.h" 60#include "laudio.h" 61 62 63#ifndef MIN 64# define MIN(a, b) ((a < b) ? a : b) 65#endif 66 67enum player_sync_source 68 { 69 PLAYER_SYNC_CLOCK, 70 PLAYER_SYNC_LAUDIO, 71 }; 72 73struct volume_param { 74 int volume; 75 uint64_t spk_id; 76}; 77 78struct player_command; 79typedef int (*cmd_func)(struct player_command *cmd); 80 81struct spk_enum 82{ 83 spk_enum_cb cb; 84 void *arg; 85}; 86 87struct player_command 88{ 89 pthread_mutex_t lck; 90 pthread_cond_t cond; 91 92 cmd_func func; 93 cmd_func func_bh; 94 95 int nonblock; 96 97 union { 98 struct volume_param vol_param; 99 void *noarg; 100 struct spk_enum *spk_enum; 101 struct raop_device *rd; 102 struct player_status *status; 103 struct player_source *ps; 104 player_status_handler status_handler; 105 uint32_t *id_ptr; 106 uint64_t *raop_ids; 107 enum repeat_mode mode; 108 uint32_t id; 109 int intval; 110 } arg; 111 112 int ret; 113 114 int raop_pending; 115}; 116 117struct player_source 118{ 119 uint32_t id; 120 121 uint64_t stream_start; 122 uint64_t output_start; 123 uint64_t end; 124 125 struct transcode_ctx *ctx; 126 127 struct player_source *pl_next; 128 struct player_source *pl_prev; 129 130 struct player_source *shuffle_next; 131 struct player_source *shuffle_prev; 132 133 struct player_source *play_next; 134}; 135 136 137/* Keep in sync with enum raop_devtype */ 138static const char *raop_devtype[] = 139 { 140 "AirPort Express 802.11g", 141 "AirPort Express 802.11n", 142 "AppleTV", 143 }; 144 145 146struct event_base *evbase_player; 147 148#ifdef USE_EVENTFD 149static int exit_efd; 150#else 151static int exit_pipe[2]; 152#endif 153static int cmd_pipe[2]; 154static int player_exit; 155static struct event exitev; 156static struct event cmdev; 157static pthread_t tid_player; 158 159/* Player status */ 160static enum play_status player_state; 161static enum repeat_mode repeat; 162static char shuffle; 163 164/* Status updates (for DACP) */ 165static player_status_handler update_handler; 166 167/* Playback timer */ 168static int pb_timer_fd; 169static struct event pb_timer_ev; 170#if defined(__linux__) 171static struct timespec pb_timer_last; 172#endif 173 174/* Sync source */ 175static enum player_sync_source pb_sync_source; 176 177/* Sync values */ 178static struct timespec pb_pos_stamp; 179static uint64_t pb_pos; 180 181/* Stream position (packets) */ 182static uint64_t last_rtptime; 183 184/* AirTunes devices */ 185static int dev_autoselect; 186static struct raop_device *dev_list; 187static uint8_t laudio_enabled; 188 189/* Device status */ 190static enum laudio_state laudio_status; 191static int laudio_selected; 192static int laudio_volume; 193static int laudio_relvol; 194static int raop_sessions; 195 196/* Commands */ 197static struct player_command *cur_cmd; 198 199/* Last commanded volume */ 200static int master_volume; 201 202/* Shuffle RNG state */ 203struct rng_ctx shuffle_rng; 204 205/* Audio source */ 206static struct player_source *source_head; 207static struct player_source *shuffle_head; 208static struct player_source *cur_playing; 209static struct player_source *cur_streaming; 210static uint32_t cur_plid; 211static struct evbuffer *audio_buf; 212 213 214/* Command helpers */ 215static void 216command_async_end(struct player_command *cmd) 217{ 218 cur_cmd = NULL; 219 220 pthread_cond_signal(&cmd->cond); 221 pthread_mutex_unlock(&cmd->lck); 222 223 /* Process commands again */ 224 event_add(&cmdev, NULL); 225} 226 227static void 228command_init(struct player_command *cmd) 229{ 230 memset(cmd, 0, sizeof(struct player_command)); 231 232 pthread_mutex_init(&cmd->lck, NULL); 233 pthread_cond_init(&cmd->cond, NULL); 234} 235 236static void 237command_deinit(struct player_command *cmd) 238{ 239 pthread_cond_destroy(&cmd->cond); 240 pthread_mutex_destroy(&cmd->lck); 241} 242 243 244static void 245status_update(enum play_status status) 246{ 247 player_state = status; 248 249 if (update_handler) 250 update_handler(); 251 252 if (status == PLAY_PLAYING) 253 dev_autoselect = 0; 254} 255 256 257/* Volume helpers */ 258static int 259rel_to_vol(int relvol) 260{ 261 float vol; 262 263 if (relvol == 100) 264 return master_volume; 265 266 vol = ((float)relvol * (float)master_volume) / 100.0; 267 268 return (int)vol; 269} 270 271static int 272vol_to_rel(int volume) 273{ 274 float rel; 275 276 if (volume == master_volume) 277 return 100; 278 279 rel = ((float)volume / (float)master_volume) * 100.0; 280 281 return (int)rel; 282} 283 284/* Master volume helpers */ 285static void 286volume_master_update(int newvol) 287{ 288 struct raop_device *rd; 289 290 master_volume = newvol; 291 292// if (laudio_selected) 293 if (laudio_enabled & laudio_selected) 294 laudio_relvol = vol_to_rel(laudio_volume); 295 296 for (rd = dev_list; rd; rd = rd->next) 297 { 298 if (rd->selected) 299 rd->relvol = vol_to_rel(rd->volume); 300 } 301} 302 303static void 304volume_master_find(void) 305{ 306 struct raop_device *rd; 307 int newmaster; 308 309 newmaster = -1; 310 311// if (laudio_selected) 312 if (laudio_enabled & laudio_selected) 313 newmaster = laudio_volume; 314 315 for (rd = dev_list; rd; rd = rd->next) 316 { 317 if (rd->selected && (rd->volume > newmaster)) 318 newmaster = rd->volume; 319 } 320 321 volume_master_update(newmaster); 322} 323 324 325/* Device select/deselect hooks */ 326static void 327speaker_select_laudio(void) 328{ 329 laudio_selected = 1; 330 331 if (laudio_volume > master_volume) 332 { 333 if (player_state == PLAY_STOPPED) 334 volume_master_update(laudio_volume); 335 else 336 laudio_volume = master_volume; 337 } 338 339 laudio_relvol = vol_to_rel(laudio_volume); 340} 341 342static void 343speaker_select_raop(struct raop_device *rd) 344{ 345 rd->selected = 1; 346 347 if (rd->volume > master_volume) 348 { 349 if (player_state == PLAY_STOPPED) 350 volume_master_update(rd->volume); 351 else 352 rd->volume = master_volume; 353 } 354 355 rd->relvol = vol_to_rel(rd->volume); 356} 357 358static void 359speaker_deselect_laudio(void) 360{ 361 laudio_selected = 0; 362 363 if (laudio_volume == master_volume) 364 volume_master_find(); 365} 366 367static void 368speaker_deselect_raop(struct raop_device *rd) 369{ 370 rd->selected = 0; 371 372 if (rd->volume == master_volume) 373 volume_master_find(); 374} 375 376int 377player_is_playing(void) 378{ 379 return player_state == PLAY_PLAYING ? 1 : 0; 380} 381 382static int 383player_get_current_pos_clock(uint64_t *pos, struct timespec *ts, int commit) 384{ 385 uint64_t delta; 386 int ret; 387 388 ret = clock_gettime(CLOCK_MONOTONIC, ts); 389 if (ret < 0) 390 { 391 DPRINTF(E_LOG, L_PLAYER, "Couldn't get clock: %s\n", strerror(errno)); 392 393 return -1; 394 } 395 396 delta = (ts->tv_sec - pb_pos_stamp.tv_sec) * 1000000 + (ts->tv_nsec - pb_pos_stamp.tv_nsec) / 1000; 397 398#ifdef DEBUG_SYNC 399 DPRINTF(E_DBG, L_PLAYER, "Delta is %" PRIu64 " usec\n", delta); 400#endif 401 402 delta = (delta * 44100) / 1000000; 403 404#ifdef DEBUG_SYNC 405 DPRINTF(E_DBG, L_PLAYER, "Delta is %" PRIu64 " samples\n", delta); 406#endif 407 408 *pos = pb_pos + delta; 409 410 if (commit) 411 { 412 pb_pos = *pos; 413 414 pb_pos_stamp.tv_sec = ts->tv_sec; 415 pb_pos_stamp.tv_nsec = ts->tv_nsec; 416 417#ifdef DEBUG_SYNC 418 DPRINTF(E_DBG, L_PLAYER, "Pos: %" PRIu64 " (clock)\n", *pos); 419#endif 420 } 421 422 return 0; 423} 424 425static int 426player_get_current_pos_laudio(uint64_t *pos, struct timespec *ts, int commit) 427{ 428 int ret; 429 430 *pos = laudio_get_pos(); 431 432 ret = clock_gettime(CLOCK_MONOTONIC, ts); 433 if (ret < 0) 434 { 435 DPRINTF(E_LOG, L_PLAYER, "Couldn't get clock: %s\n", strerror(errno)); 436 437 return -1; 438 } 439 440 if (commit) 441 { 442 pb_pos = *pos; 443 444 pb_pos_stamp.tv_sec = ts->tv_sec; 445 pb_pos_stamp.tv_nsec = ts->tv_nsec; 446 447#ifdef DEBUG_SYNC 448 DPRINTF(E_DBG, L_PLAYER, "Pos: %" PRIu64 " (laudio)\n", *pos); 449#endif 450 } 451 452 return 0; 453} 454 455int 456player_get_current_pos(uint64_t *pos, struct timespec *ts, int commit) 457{ 458 switch (pb_sync_source) 459 { 460 case PLAYER_SYNC_CLOCK: 461 return player_get_current_pos_clock(pos, ts, commit); 462 463 case PLAYER_SYNC_LAUDIO: 464 return player_get_current_pos_laudio(pos, ts, commit); 465 } 466 467 return -1; 468} 469 470/* Forward */ 471static void 472playback_abort(void); 473 474static void 475player_laudio_status_cb(enum laudio_state status) 476{ 477 struct timespec ts; 478 uint64_t pos; 479 480 switch (status) 481 { 482 /* Switch sync to clock sync */ 483 case LAUDIO_STOPPING: 484 DPRINTF(E_DBG, L_PLAYER, "Local audio stopping\n"); 485 486 laudio_status = status; 487 488 /* Synchronize pb_pos and pb_pos_stamp before laudio stops entirely */ 489 player_get_current_pos_laudio(&pos, &ts, 1); 490 491 pb_sync_source = PLAYER_SYNC_CLOCK; 492 break; 493 494 /* Switch sync to laudio sync */ 495 case LAUDIO_RUNNING: 496 DPRINTF(E_DBG, L_PLAYER, "Local audio running\n"); 497 498 laudio_status = status; 499 500 pb_sync_source = PLAYER_SYNC_LAUDIO; 501 break; 502 503 case LAUDIO_FAILED: 504 DPRINTF(E_DBG, L_PLAYER, "Local audio failed\n"); 505 506 pb_sync_source = PLAYER_SYNC_CLOCK; 507 508 laudio_close(); 509 510 if (raop_sessions == 0) 511 playback_abort(); 512 513 speaker_deselect_laudio(); 514 break; 515 516 default: 517 laudio_status = status; 518 break; 519 } 520} 521 522 523/* Metadata */ 524static void 525metadata_prune(uint64_t pos) 526{ 527 raop_metadata_prune(pos); 528} 529 530static void 531metadata_purge(void) 532{ 533 raop_metadata_purge(); 534} 535 536static void 537metadata_send(struct player_source *ps, int startup) 538{ 539 uint64_t offset; 540 uint64_t rtptime; 541 542 offset = 0; 543 544 /* Determine song boundaries, dependent on context */ 545 546 /* Restart after pause/seek */ 547 if (ps->stream_start) 548 { 549 offset = ps->output_start - ps->stream_start; 550 rtptime = ps->stream_start; 551 } 552 else if (startup) 553 { 554 rtptime = last_rtptime + AIRTUNES_V2_PACKET_SAMPLES; 555 } 556 /* Generic case */ 557 else if (cur_streaming && (cur_streaming->end)) 558 { 559 rtptime = cur_streaming->end + 1; 560 } 561 else 562 { 563 rtptime = 0; 564 DPRINTF(E_LOG, L_PLAYER, "PTOH! Unhandled song boundary case in metadata_send()\n"); 565 } 566 567 raop_metadata_send(ps->id, rtptime, offset, startup); 568} 569 570 571/* Audio sources */ 572/* Thread: httpd (DACP) */ 573static struct player_source * 574player_queue_make(struct query_params *qp, const char *sort) 575{ 576 struct db_media_file_info dbmfi; 577 struct player_source *q_head; 578 struct player_source *q_tail; 579 struct player_source *ps; 580 uint32_t id; 581 int ret; 582 583 qp->idx_type = I_NONE; 584 qp->sort = S_NONE; 585 586 if (sort) 587 { 588 if (strcmp(sort, "name") == 0) 589 qp->sort = S_NAME; 590 else if (strcmp(sort, "album") == 0) 591 qp->sort = S_ALBUM; 592 else if (strcmp(sort, "artist") == 0) 593 qp->sort = S_ARTIST; 594 } 595 596 ret = db_query_start(qp); 597 if (ret < 0) 598 { 599 DPRINTF(E_LOG, L_PLAYER, "Could not start query\n"); 600 601 return NULL; 602 } 603 604 DPRINTF(E_DBG, L_PLAYER, "Player queue query returned %d items\n", qp->results); 605 606 q_head = NULL; 607 q_tail = NULL; 608 while (((ret = db_query_fetch_file(qp, &dbmfi)) == 0) && (dbmfi.id)) 609 { 610 ret = safe_atou32(dbmfi.id, &id); 611 if (ret < 0) 612 { 613 DPRINTF(E_LOG, L_PLAYER, "Invalid song id in query result!\n"); 614 615 continue; 616 } 617 618 ps = (struct player_source *)malloc(sizeof(struct player_source)); 619 if (!ps) 620 { 621 DPRINTF(E_LOG, L_PLAYER, "Out of memory for struct player_source\n"); 622 623 ret = -1; 624 break; 625 } 626 627 memset(ps, 0, sizeof(struct player_source)); 628 629 ps->id = id; 630 631 if (!q_head) 632 q_head = ps; 633 634 if (q_tail) 635 { 636 q_tail->pl_next = ps; 637 ps->pl_prev = q_tail; 638 639 q_tail->shuffle_next = ps; 640 ps->shuffle_prev = q_tail; 641 } 642 643 q_tail = ps; 644 645 DPRINTF(E_DBG, L_PLAYER, "Added song id %d (%s)\n", id, dbmfi.title); 646 } 647 648 db_query_end(qp); 649 650 if (ret < 0) 651 { 652 DPRINTF(E_LOG, L_PLAYER, "Error fetching results\n"); 653 654 return NULL; 655 } 656 657 if (!q_head) 658 return NULL; 659 660 q_head->pl_prev = q_tail; 661 q_tail->pl_next = q_head; 662 663 return q_head; 664} 665 666/* Thread: httpd (DACP) */ 667struct player_source * 668player_queue_make_daap(const char *query, const char *sort) 669{ 670 struct query_params qp; 671 struct player_source *ps; 672 673 memset(&qp, 0, sizeof(struct query_params)); 674 675 qp.type = Q_ITEMS; 676 qp.offset = 0; 677 qp.limit = 0; 678 679 qp.filter = daap_query_parse_sql(query); 680 if (!qp.filter) 681 { 682 DPRINTF(E_LOG, L_PLAYER, "Improper DAAP query!\n"); 683 684 return NULL; 685 } 686 687 ps = player_queue_make(&qp, sort); 688 689 free(qp.filter); 690 691 return ps; 692} 693 694struct player_source * 695player_queue_make_pl(int plid, uint32_t *id) 696{ 697 struct query_params qp; 698 struct player_source *ps; 699 struct player_source *p; 700 uint32_t i; 701 702 memset(&qp, 0, sizeof(struct query_params)); 703 704 qp.id = plid; 705 qp.type = Q_PLITEMS; 706 qp.offset = 0; 707 qp.limit = 0; 708 709 ps = player_queue_make(&qp, NULL); 710 711 /* Shortcut for shuffled playlist */ 712 if (*id == 0) 713 return ps; 714 715 p = ps; 716 i = 0; 717 do 718 { 719 if (p->id == *id) 720 { 721 *id = i; 722 break; 723 } 724 725 p = p->pl_next; 726 i++; 727 } 728 while (p != ps); 729 730 return ps; 731} 732 733static void 734source_free(struct player_source *ps) 735{ 736 if (ps->ctx) 737 transcode_cleanup(ps->ctx); 738 739 free(ps); 740} 741 742static void 743source_stop(struct player_source *ps) 744{ 745 struct player_source *tmp; 746 747 while (ps) 748 { 749 if (ps->ctx) 750 { 751 transcode_cleanup(ps->ctx); 752 ps->ctx = NULL; 753 } 754 755 tmp = ps; 756 ps = ps->play_next; 757 758 tmp->play_next = NULL; 759 } 760} 761 762static struct player_source * 763source_shuffle(struct player_source *head) 764{ 765 struct player_source *ps; 766 struct player_source **ps_array; 767 int nitems; 768 int i; 769 770 if (!head) 771 return NULL; 772 773 ps = head; 774 nitems = 0; 775 do 776 { 777 nitems++; 778 ps = ps->pl_next; 779 } 780 while (ps != head); 781 782 ps_array = (struct player_source **)malloc(nitems * sizeof(struct player_source *)); 783 if (!ps_array) 784 { 785 DPRINTF(E_LOG, L_PLAYER, "Could not allocate memory for shuffle array\n"); 786 return NULL; 787 } 788 789 ps = head; 790 i = 0; 791 do 792 { 793 ps_array[i] = ps; 794 795 ps = ps->pl_next; 796 i++; 797 } 798 while (ps != head); 799 800 shuffle_ptr(&shuffle_rng, (void **)ps_array, nitems); 801 802 for (i = 0; i < nitems; i++) 803 { 804 ps = ps_array[i]; 805 806 if (i > 0) 807 ps->shuffle_prev = ps_array[i - 1]; 808 809 if (i < (nitems - 1)) 810 ps->shuffle_next = ps_array[i + 1]; 811 } 812 813 ps_array[0]->shuffle_prev = ps_array[nitems - 1]; 814 ps_array[nitems - 1]->shuffle_next = ps_array[0]; 815 816 ps = ps_array[0]; 817 818 free(ps_array); 819 820 return ps; 821} 822 823static void 824source_reshuffle(void) 825{ 826 struct player_source *ps; 827 828 ps = source_shuffle(source_head); 829 if (!ps) 830 return; 831 832 if (cur_streaming) 833 shuffle_head = cur_streaming; 834 else 835 shuffle_head = ps; 836} 837 838/* Helper */ 839static int 840source_open(struct player_source *ps, int no_md) 841{ 842 struct media_file_info *mfi; 843 844 ps->stream_start = 0; 845 ps->output_start = 0; 846 ps->end = 0; 847 ps->play_next = NULL; 848 849 mfi = db_file_fetch_byid(ps->id); 850 if (!mfi) 851 { 852 DPRINTF(E_LOG, L_PLAYER, "Couldn't fetch file id %d\n", ps->id); 853 854 return -1; 855 } 856 857 if (mfi->disabled) 858 { 859 DPRINTF(E_DBG, L_PLAYER, "File id %d is disabled, skipping\n", ps->id); 860 861 free_mfi(mfi, 0); 862 return -1; 863 } 864 865 DPRINTF(E_DBG, L_PLAYER, "Opening %s\n", mfi->path); 866 867 ps->ctx = transcode_setup(mfi, NULL, 0); 868 869 free_mfi(mfi, 0); 870 871 if (!ps->ctx) 872 { 873 DPRINTF(E_LOG, L_PLAYER, "Could not open file id %d\n", ps->id); 874 875 return -1; 876 } 877 878 if (!no_md) 879 metadata_send(ps, (player_state == PLAY_PLAYING) ? 0 : 1); 880 881 return 0; 882} 883 884static int 885source_next(int force) 886{ 887 struct player_source *ps; 888 struct player_source *head; 889 struct player_source *limit; 890 enum repeat_mode r_mode; 891 int ret; 892 893 head = (shuffle) ? shuffle_head : source_head; 894 limit = head; 895 r_mode = repeat; 896 897 /* Force repeat mode at user request */ 898 if (force && (r_mode == REPEAT_SONG)) 899 r_mode = REPEAT_ALL; 900 901 /* Playlist has only one file, treat REPEAT_ALL as REPEAT_SONG */ 902 if ((r_mode == REPEAT_ALL) && (source_head == source_head->pl_next)) 903 r_mode = REPEAT_SONG; 904 /* Playlist has only one file, not a user action, treat as REPEAT_ALL 905 * and source_check() will stop playback 906 */ 907 else if (!force && (r_mode == REPEAT_OFF) && (source_head == source_head->pl_next)) 908 r_mode = REPEAT_SONG; 909 910 if (!cur_streaming) 911 ps = head; 912 else 913 ps = (shuffle) ? cur_streaming->shuffle_next : cur_streaming->pl_next; 914 915 switch (r_mode) 916 { 917 case REPEAT_SONG: 918 if (cur_streaming->ctx) 919 { 920 ret = transcode_seek(cur_streaming->ctx, 0); 921 922 /* source_open() takes care of sending metadata, but we don't 923 * call it when repeating a song as we just seek back to 0 924 * so we have to handle metadata ourselves here 925 */ 926 if (ret >= 0) 927 metadata_send(cur_streaming, 0); 928 } 929 else 930 ret = source_open(cur_streaming, force); 931 932 if (ret < 0) 933 { 934 DPRINTF(E_LOG, L_PLAYER, "Failed to restart song for song repeat\n"); 935 936 return -1; 937 } 938 939 return 0; 940 941 case REPEAT_ALL: 942 if (!shuffle) 943 { 944 limit = ps; 945 break; 946 } 947 948 /* Reshuffle before repeating playlist */ 949 if (cur_streaming && (ps == shuffle_head)) 950 { 951 source_reshuffle(); 952 ps = shuffle_head; 953 } 954 955 limit = shuffle_head; 956 957 break; 958 959 case REPEAT_OFF: 960 limit = head; 961 962 if (force && (ps == limit)) 963 { 964 DPRINTF(E_DBG, L_PLAYER, "End of playlist reached and repeat is OFF\n"); 965 966 playback_abort(); 967 return 0; 968 } 969 break; 970 } 971 972 do 973 { 974 ret = source_open(ps, force); 975 if (ret < 0) 976 { 977 if (shuffle) 978 ps = ps->shuffle_next; 979 else 980 ps = ps->pl_next; 981 982 continue; 983 } 984 985 break; 986 } 987 while (ps != limit); 988 989 /* Couldn't open any of the files in our queue */ 990 if (ret < 0) 991 { 992 DPRINTF(E_WARN, L_PLAYER, "Could not open any file in the queue (next)\n"); 993 994 return -1; 995 } 996 997 if (!force && cur_streaming) 998 cur_streaming->play_next = ps; 999 1000 cur_streaming = ps; 1001 1002 return 0; 1003} 1004 1005static int 1006source_prev(void) 1007{ 1008 struct player_source *ps; 1009 struct player_source *head; 1010 struct player_source *limit; 1011 int ret; 1012 1013 if (!cur_streaming) 1014 return -1; 1015 1016 head = (shuffle) ? shuffle_head : source_head; 1017 ps = (shuffle) ? cur_streaming->shuffle_prev : cur_streaming->pl_prev; 1018 limit = ps; 1019 1020 if ((repeat == REPEAT_OFF) && (cur_streaming == head)) 1021 { 1022 DPRINTF(E_DBG, L_PLAYER, "Start of playlist reached and repeat is OFF\n"); 1023 1024 playback_abort(); 1025 return 0; 1026 } 1027 1028 /* We are not reshuffling on prev calls in the shuffle case - should we? */ 1029 1030 do 1031 { 1032 ret = source_open(ps, 1); 1033 if (ret < 0) 1034 { 1035 if (shuffle) 1036 ps = ps->shuffle_prev; 1037 else 1038 ps = ps->pl_prev; 1039 1040 continue; 1041 } 1042 1043 break; 1044 } 1045 while (ps != limit); 1046 1047 /* Couldn't open any of the files in our queue */ 1048 if (ret < 0) 1049 { 1050 DPRINTF(E_WARN, L_PLAYER, "Could not open any file in the queue (prev)\n"); 1051 1052 return -1; 1053 } 1054 1055 cur_streaming = ps; 1056 1057 return 0; 1058} 1059 1060static int 1061source_position(struct player_source *ps) 1062{ 1063 struct player_source *p; 1064 int ret; 1065 1066 ret = 0; 1067 for (p = source_head; p != ps; p = p->pl_next) 1068 ret++; 1069 1070 return ret; 1071} 1072 1073static uint64_t 1074source_check(void) 1075{ 1076 struct timespec ts; 1077 struct player_source *ps; 1078 struct player_source *head; 1079 uint64_t pos; 1080 enum repeat_mode r_mode; 1081 int i; 1082 int ret; 1083 1084 if (!cur_streaming) 1085 return 0; 1086 1087 ret = player_get_current_pos(&pos, &ts, 0); 1088 if (ret < 0) 1089 { 1090 DPRINTF(E_LOG, L_PLAYER, "Couldn't get current playback position\n"); 1091 1092 return 0; 1093 } 1094 1095 if (!cur_playing) 1096 { 1097 if (pos >= cur_streaming->output_start) 1098 { 1099 cur_playing = cur_streaming; 1100 status_update(PLAY_PLAYING); 1101 1102 /* Start of streaming, no metadata to prune yet */ 1103 } 1104 1105 return pos; 1106 } 1107 1108 if ((cur_playing->end == 0) || (pos < cur_playing->end)) 1109 return pos; 1110 1111 r_mode = repeat; 1112 /* Playlist has only one file, treat REPEAT_ALL as REPEAT_SONG */ 1113 if ((r_mode == REPEAT_ALL) && (source_head == source_head->pl_next)) 1114 r_mode = REPEAT_SONG; 1115 1116 if (r_mode == REPEAT_SONG) 1117 { 1118 ps = cur_playing; 1119 1120 /* Check that we haven't gone to the next file already 1121 * (repeat song toggled in the last 2 seconds of a song) 1122 */ 1123 if (cur_playing->play_next) 1124 { 1125 cur_playing = cur_playing->play_next; 1126 1127 if (ps->ctx) 1128 { 1129 transcode_cleanup(ps->ctx); 1130 ps->ctx = NULL; 1131 ps->play_next = NULL; 1132 } 1133 } 1134 1135 cur_playing->stream_start = ps->end + 1; 1136 cur_playing->output_start = cur_playing->stream_start; 1137 1138 /* Do not use cur_playing to reset the end position, it may have changed */ 1139 ps->end = 0; 1140 1141 status_update(PLAY_PLAYING); 1142 1143 metadata_prune(pos); 1144 1145 return pos; 1146 } 1147 1148 head = (shuffle) ? shuffle_head : source_head; 1149 1150 i = 0; 1151 while (cur_playing && (cur_playing->end != 0) && (pos > cur_playing->end)) 1152 { 1153 i++; 1154 1155 /* Stop playback if: 1156 * - at end of playlist (NULL) 1157 * - repeat OFF and at end of playlist (wraparound) 1158 */ 1159 if (!cur_playing->play_next 1160 || ((r_mode == REPEAT_OFF) && (cur_playing->play_next == head))) 1161 { 1162 playback_abort(); 1163 1164 return pos; 1165 } 1166 1167 ps = cur_playing; 1168 cur_playing = cur_playing->play_next; 1169 1170 cur_playing->stream_start = ps->end + 1; 1171 cur_playing->output_start = cur_playing->stream_start; 1172 1173 if (ps->ctx) 1174 { 1175 transcode_cleanup(ps->ctx); 1176 ps->ctx = NULL; 1177 ps->play_next = NULL; 1178 } 1179 } 1180 1181 if (i > 0) 1182 { 1183 DPRINTF(E_DBG, L_PLAYER, "Playback switched to next song\n"); 1184 1185 status_update(PLAY_PLAYING); 1186 1187 metadata_prune(pos); 1188 } 1189 1190 return pos; 1191} 1192 1193static int 1194source_read(uint8_t *buf, int len, uint64_t rtptime) 1195{ 1196 int new; 1197 int ret; 1198 int nbytes; 1199 1200 if (!cur_streaming) 1201 return 0; 1202 1203 nbytes = 0; 1204 new = 0; 1205 while (nbytes < len) 1206 { 1207 if (new) 1208 { 1209 DPRINTF(E_DBG, L_PLAYER, "New file\n"); 1210 1211 new = 0; 1212 1213 ret = source_next(0); 1214 if (ret < 0) 1215 return -1; 1216 } 1217 1218 if (EVBUFFER_LENGTH(audio_buf) == 0) 1219 { 1220 ret = transcode(cur_streaming->ctx, audio_buf, len - nbytes); 1221 if (ret <= 0) 1222 { 1223 /* EOF or error */ 1224 cur_streaming->end = rtptime + BTOS(nbytes) - 1; 1225 1226 new = 1; 1227 continue; 1228 } 1229 } 1230 1231 nbytes += evbuffer_remove(audio_buf, buf + nbytes, len - nbytes); 1232 } 1233 1234 return nbytes; 1235} 1236 1237 1238static void 1239playback_write(void) 1240{ 1241 uint8_t rawbuf[AIRTUNES_V2_PACKET_SAMPLES * 2 * 2]; 1242 int ret; 1243 1244 source_check(); 1245 /* Make sure playback is still running after source_check() */ 1246 if (player_state == PLAY_STOPPED) 1247 return; 1248 1249 last_rtptime += AIRTUNES_V2_PACKET_SAMPLES; 1250 1251 memset(rawbuf, 0, sizeof(rawbuf)); 1252 1253 ret = source_read(rawbuf, sizeof(rawbuf), last_rtptime); 1254 if (ret < 0) 1255 { 1256 DPRINTF(E_DBG, L_PLAYER, "Error reading from source, aborting playback\n"); 1257 1258 playback_abort(); 1259 return; 1260 } 1261 1262 if (laudio_enabled & laudio_status & LAUDIO_F_STARTED) 1263// if (laudio_status & LAUDIO_F_STARTED) 1264 laudio_write(rawbuf, last_rtptime); 1265 1266 if (raop_sessions > 0) 1267 raop_v2_write(rawbuf, last_rtptime); 1268} 1269 1270#if defined(__linux__) 1271static void 1272player_playback_cb(int fd, short what, void *arg) 1273{ 1274 struct itimerspec next; 1275 uint64_t ticks; 1276 int ret; 1277 1278 /* Acknowledge timer */ 1279 read(fd, &ticks, sizeof(ticks)); 1280 1281 playback_write(); 1282 1283 /* Make sure playback is still running */ 1284 if (player_state == PLAY_STOPPED) 1285 return; 1286 1287 pb_timer_last.tv_nsec += AIRTUNES_V2_STREAM_PERIOD; 1288 if (pb_timer_last.tv_nsec >= 1000000000) 1289 { 1290 pb_timer_last.tv_sec++; 1291 pb_timer_last.tv_nsec -= 1000000000; 1292 } 1293 1294 next.it_interval.tv_sec = 0; 1295 next.it_interval.tv_nsec = 0; 1296 next.it_value.tv_sec = pb_timer_last.tv_sec; 1297 next.it_value.tv_nsec = pb_timer_last.tv_nsec; 1298 1299 ret = timerfd_settime(pb_timer_fd, TFD_TIMER_ABSTIME, &next, NULL); 1300 if (ret < 0) 1301 { 1302 DPRINTF(E_LOG, L_PLAYER, "Could not set playback timer: %s\n", strerror(errno)); 1303 1304 playback_abort(); 1305 return; 1306 } 1307 1308 ret = event_add(&pb_timer_ev, NULL); 1309 if (ret < 0) 1310 { 1311 DPRINTF(E_LOG, L_PLAYER, "Could not re-add playback timer event\n"); 1312 1313 playback_abort(); 1314 return; 1315 } 1316} 1317#endif /* __linux__ */ 1318 1319 1320#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 1321static void 1322player_playback_cb(int fd, short what, void *arg) 1323{ 1324 struct timespec ts; 1325 struct kevent kev; 1326 int ret; 1327 1328 ts.tv_sec = 0; 1329 ts.tv_nsec = 0; 1330 1331 while (kevent(pb_timer_fd, NULL, 0, &kev, 1, &ts) > 0) 1332 { 1333 if (kev.filter != EVFILT_TIMER) 1334 continue; 1335 1336 playback_write(); 1337 1338 /* Make sure playback is still running */ 1339 if (player_state == PLAY_STOPPED) 1340 return; 1341 } 1342 1343 ret = event_add(&pb_timer_ev, NULL); 1344 if (ret < 0) 1345 { 1346 DPRINTF(E_LOG, L_PLAYER, "Could not re-add playback timer event\n"); 1347 1348 playback_abort(); 1349 return; 1350 } 1351} 1352#endif /* __FreeBSD__ || __FreeBSD_kernel__ */ 1353 1354 1355static void 1356device_free(struct raop_device *dev) 1357{ 1358 free(dev->name); 1359 1360 if (dev->v4_address) 1361 free(dev->v4_address); 1362 1363 if (dev->v6_address) 1364 free(dev->v6_address); 1365 1366 free(dev); 1367} 1368 1369/* Helpers */ 1370static void 1371device_remove(struct raop_device *dev) 1372{ 1373 struct raop_device *rd; 1374 struct raop_device *prev; 1375 int ret; 1376 1377 prev = NULL; 1378 for (rd = dev_list; rd; rd = rd->next) 1379 { 1380 if (rd == dev) 1381 break; 1382 1383 prev = rd; 1384 } 1385 1386 if (!rd) 1387 return; 1388 1389 DPRINTF(E_DBG, L_PLAYER, "Removing AirTunes device %s; stopped advertising\n", dev->name); 1390 1391 /* Make sure device isn't selected anymore */ 1392 if (dev->selected) 1393 speaker_deselect_raop(dev); 1394 1395 /* Save device volume */ 1396 ret = db_speaker_save(dev->id, 0, dev->volume); 1397 if (ret < 0) 1398 DPRINTF(E_LOG, L_PLAYER, "Could not save state for speaker %s\n", dev->name); 1399 1400 if (!prev) 1401 dev_list = dev->next; 1402 else 1403 prev->next = dev->next; 1404 1405 device_free(dev); 1406} 1407 1408static int 1409device_check(struct raop_device *dev) 1410{ 1411 struct raop_device *rd; 1412 1413 for (rd = dev_list; rd; rd = rd->next) 1414 { 1415 if (rd == dev) 1416 break; 1417 } 1418 1419 return (rd) ? 0 : -1; 1420} 1421 1422static int 1423device_add(struct player_command *cmd) 1424{ 1425 struct raop_device *dev; 1426 struct raop_device *rd; 1427 int selected; 1428 int ret; 1429 1430 dev = cmd->arg.rd; 1431 1432 for (rd = dev_list; rd; rd = rd->next) 1433 { 1434 if (rd->id == dev->id) 1435 break; 1436 } 1437 1438 /* New device */ 1439 if (!rd) 1440 { 1441 rd = dev; 1442 1443 ret = db_speaker_get(rd->id, &selected, &rd->volume); 1444 if (ret < 0) 1445 { 1446 selected = 0; 1447 rd->volume = (master_volume >= 0) ? master_volume : 75; 1448 } 1449 1450// if (dev_autoselect && selected) 1451 speaker_select_raop(rd); 1452 1453 rd->next = dev_list; 1454 dev_list = rd; 1455 } 1456 else 1457 { 1458 rd->advertised = 1; 1459 1460 if (dev->v4_address) 1461 { 1462 if (rd->v4_address) 1463 free(rd->v4_address); 1464 1465 rd->v4_address = dev->v4_address; 1466 rd->v4_port = dev->v4_port; 1467 1468 /* Address is ours now */ 1469 dev->v4_address = NULL; 1470 } 1471 1472 if (dev->v6_address) 1473 { 1474 if (rd->v6_address) 1475 free(rd->v6_address); 1476 1477 rd->v6_address = dev->v6_address; 1478 rd->v6_port = dev->v6_port; 1479 1480 /* Address is ours now */ 1481 dev->v6_address = NULL; 1482 } 1483 1484 if (rd->name) 1485 free(rd->name); 1486 rd->name = dev->name; 1487 dev->name = NULL; 1488 1489 rd->devtype = dev->devtype; 1490 1491 rd->has_password = dev->has_password; 1492 rd->password = dev->password; 1493 1494 device_free(dev); 1495 } 1496 1497 return 0; 1498} 1499 1500static int 1501device_remove_family(struct player_command *cmd) 1502{ 1503 struct raop_device *dev; 1504 struct raop_device *rd; 1505 1506 dev = cmd->arg.rd; 1507 1508 for (rd = dev_list; rd; rd = rd->next) 1509 { 1510 if (rd->id == dev->id) 1511 break; 1512 } 1513 1514 if (!rd) 1515 { 1516 DPRINTF(E_WARN, L_PLAYER, "AirTunes device %s stopped advertising, but not in our list\n", dev->name); 1517 1518 device_free(dev); 1519 return 0; 1520 } 1521 1522 /* v{4,6}_port non-zero indicates the address family stopped advertising */ 1523 if (dev->v4_port && rd->v4_address) 1524 { 1525 free(rd->v4_address); 1526 rd->v4_address = NULL; 1527 rd->v4_port = 0; 1528 } 1529 1530 if (dev->v6_port && rd->v6_address) 1531 { 1532 free(rd->v6_address); 1533 rd->v6_address = NULL; 1534 rd->v6_port = 0; 1535 } 1536 1537 if (!rd->v4_address && !rd->v6_address) 1538 { 1539 rd->advertised = 0; 1540 1541 if (!rd->session) 1542 device_remove(rd); 1543 } 1544 1545 device_free(dev); 1546 1547 return 0; 1548} 1549 1550/* RAOP callbacks executed in the player thread */ 1551static void 1552device_streaming_cb(struct raop_device *dev, struct raop_session *rs, enum raop_session_state status) 1553{ 1554 int ret; 1555 1556 if (status == RAOP_FAILED) 1557 { 1558 raop_sessions--; 1559 1560 ret = device_check(dev); 1561 if (ret < 0) 1562 { 1563 DPRINTF(E_WARN, L_PLAYER, "AirTunes device disappeared during streaming!\n"); 1564 1565 return; 1566 } 1567 1568 DPRINTF(E_LOG, L_PLAYER, "AirTunes device %s FAILED\n", dev->name); 1569 1570 if (player_state == PLAY_PLAYING) 1571 speaker_deselect_raop(dev); 1572 1573 dev->session = NULL; 1574 1575 if (!dev->advertised) 1576 device_remove(dev); 1577 } 1578 else if (status == RAOP_STOPPED) 1579 { 1580 raop_sessions--; 1581 1582 ret = device_check(dev); 1583 if (ret < 0) 1584 { 1585 DPRINTF(E_WARN, L_PLAYER, "AirTunes device disappeared during streaming!\n"); 1586 1587 return; 1588 } 1589 1590 DPRINTF(E_LOG, L_PLAYER, "AirTunes device %s stopped\n", dev->name); 1591 1592 dev->session = NULL; 1593 1594 if (!dev->advertised) 1595 device_remove(dev); 1596 } 1597} 1598 1599static void 1600device_command_cb(struct raop_device *dev, struct raop_session *rs, enum raop_session_state status) 1601{ 1602 cur_cmd->raop_pending--; 1603 1604 raop_set_status_cb(rs, device_streaming_cb); 1605 1606 if (status == RAOP_FAILED) 1607 device_streaming_cb(dev, rs, status); 1608 1609 if (cur_cmd->raop_pending == 0) 1610 { 1611 if (cur_cmd->func_bh) 1612 cur_cmd->ret = cur_cmd->func_bh(cur_cmd); 1613 else 1614 cur_cmd->ret = 0; 1615 1616 command_async_end(cur_cmd); 1617 } 1618} 1619 1620static void 1621device_shutdown_cb(struct raop_device *dev, struct raop_session *rs, enum raop_session_state status) 1622{ 1623 int ret; 1624 1625 cur_cmd->raop_pending--; 1626 1627 if (raop_sessions) 1628 raop_sessions--; 1629 1630 ret = device_check(dev); 1631 if (ret < 0) 1632 { 1633 DPRINTF(E_WARN, L_PLAYER, "AirTunes device disappeared before shutdown completion!\n"); 1634 1635 if (cur_cmd->ret != -2) 1636 cur_cmd->ret = -1; 1637 goto out; 1638 } 1639 1640 dev->session = NULL; 1641 1642 if (!dev->advertised) 1643 device_remove(dev); 1644 1645 out: 1646 if (cur_cmd->raop_pending == 0) 1647 { 1648 /* cur_cmd->ret already set 1649 * - to 0 (or -2 if password issue) in speaker_set() 1650 * - to -1 above on error 1651 */ 1652 command_async_end(cur_cmd); 1653 } 1654} 1655 1656static void 1657device_lost_cb(struct raop_device *dev, struct raop_session *rs, enum raop_session_state status) 1658{ 1659 /* We lost that device during startup for some reason, not much we can do here */ 1660 if (status == RAOP_FAILED) 1661 DPRINTF(E_WARN, L_PLAYER, "Failed to stop lost device\n"); 1662 else 1663 DPRINTF(E_INFO, L_PLAYER, "Lost device stopped properly\n"); 1664} 1665 1666static void 1667device_activate_cb(struct raop_device *dev, struct raop_session *rs, enum raop_session_state status) 1668{ 1669 struct timespec ts; 1670 int ret; 1671 1672 cur_cmd->raop_pending--; 1673 1674 ret = device_check(dev); 1675 if (ret < 0) 1676 { 1677 DPRINTF(E_WARN, L_PLAYER, "AirTunes device disappeared during startup!\n"); 1678 1679 raop_set_status_cb(rs, device_lost_cb); 1680 raop_device_stop(rs); 1681 1682 if (cur_cmd->ret != -2) 1683 cur_cmd->ret = -1; 1684 goto out; 1685 } 1686 1687 if (status == RAOP_PASSWORD) 1688 { 1689 status = RAOP_FAILED; 1690 cur_cmd->ret = -2; 1691 } 1692 1693 if (status == RAOP_FAILED) 1694 { 1695 speaker_deselect_raop(dev); 1696 1697 if (!dev->advertised) 1698 device_remove(dev); 1699 1700 if (cur_cmd->ret != -2) 1701 cur_cmd->ret = -1; 1702 goto out; 1703 } 1704 1705 dev->session = rs; 1706 1707 raop_sessions++; 1708 1709 if ((player_state == PLAY_PLAYING) && (raop_sessions == 1)) 1710 { 1711 ret = clock_gettime(CLOCK_MONOTONIC, &ts); 1712 if (ret < 0) 1713 { 1714 DPRINTF(E_LOG, L_PLAYER, "Could not get current time: %s\n", strerror(errno)); 1715 1716#if defined(__linux__) 1717 /* Fallback to nearest timer expiration time */ 1718 ts.tv_sec = pb_timer_last.tv_sec; 1719 ts.tv_nsec = pb_timer_last.tv_nsec; 1720#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 1721 if (cur_cmd->ret != -2) 1722 cur_cmd->ret = -1; 1723 goto out; 1724#endif 1725 } 1726 1727 raop_playback_start(last_rtptime + AIRTUNES_V2_PACKET_SAMPLES, &ts); 1728 } 1729 1730 raop_set_status_cb(rs, device_streaming_cb); 1731 1732 out: 1733 if (cur_cmd->raop_pending == 0) 1734 { 1735 /* cur_cmd->ret already set 1736 * - to 0 in speaker_set() (default) 1737 * - to -2 above if password issue 1738 * - to -1 above on error 1739 */ 1740 command_async_end(cur_cmd); 1741 } 1742} 1743 1744static void 1745device_probe_cb(struct raop_device *dev, struct raop_session *rs, enum raop_session_state status) 1746{ 1747 int ret; 1748 1749 cur_cmd->raop_pending--; 1750 1751 ret = device_check(dev); 1752 if (ret < 0) 1753 { 1754 DPRINTF(E_WARN, L_PLAYER, "AirTunes device disappeared during probe!\n"); 1755 1756 if (cur_cmd->ret != -2) 1757 cur_cmd->ret = -1; 1758 goto out; 1759 } 1760 1761 if (status == RAOP_PASSWORD) 1762 { 1763 status = RAOP_FAILED; 1764 cur_cmd->ret = -2; 1765 } 1766 1767 if (status == RAOP_FAILED) 1768 { 1769 speaker_deselect_raop(dev); 1770 1771 if (!dev->advertised) 1772 device_remove(dev); 1773 1774 if (cur_cmd->ret != -2) 1775 cur_cmd->ret = -1; 1776 goto out; 1777 } 1778 1779 out: 1780 if (cur_cmd->raop_pending == 0) 1781 { 1782 /* cur_cmd->ret already set 1783 * - to 0 in speaker_set() (default) 1784 * - to -2 above if password issue 1785 * - to -1 above on error 1786 */ 1787 command_async_end(cur_cmd); 1788 } 1789} 1790 1791static void 1792device_restart_cb(struct raop_device *dev, struct raop_session *rs, enum raop_session_state status) 1793{ 1794 int ret; 1795 1796 cur_cmd->raop_pending--; 1797 1798 ret = device_check(dev); 1799 if (ret < 0) 1800 { 1801 DPRINTF(E_WARN, L_PLAYER, "AirTunes device disappeared during restart!\n"); 1802 1803 raop_set_status_cb(rs, device_lost_cb); 1804 raop_device_stop(rs); 1805 1806 goto out; 1807 } 1808 1809 if (status == RAOP_FAILED) 1810 { 1811 speaker_deselect_raop(dev); 1812 1813 if (!dev->advertised) 1814 device_remove(dev); 1815 1816 goto out; 1817 } 1818 1819 dev->session = rs; 1820 1821 raop_sessions++; 1822 raop_set_status_cb(rs, device_streaming_cb); 1823 1824 out: 1825 if (cur_cmd->raop_pending == 0) 1826 { 1827 cur_cmd->ret = cur_cmd->func_bh(cur_cmd); 1828 1829 command_async_end(cur_cmd); 1830 } 1831} 1832 1833 1834/* Internal abort routine */ 1835static void 1836playback_abort(void) 1837{ 1838 if (laudio_enabled && laudio_status != LAUDIO_CLOSED) 1839// if (laudio_status != LAUDIO_CLOSED) 1840 laudio_close(); 1841 1842 if (raop_sessions > 0) 1843 raop_playback_stop(); 1844 1845 if (event_initialized(&pb_timer_ev)) 1846 event_del(&pb_timer_ev); 1847 1848 close(pb_timer_fd); 1849 pb_timer_fd = -1; 1850 1851 if (cur_playing) 1852 source_stop(cur_playing); 1853 else 1854 source_stop(cur_streaming); 1855 1856 cur_playing = NULL; 1857 cur_streaming = NULL; 1858 1859 evbuffer_drain(audio_buf, EVBUFFER_LENGTH(audio_buf)); 1860 1861 status_update(PLAY_STOPPED); 1862 1863 metadata_purge(); 1864} 1865 1866 1867/* Actual commands, executed in the player thread */ 1868static int 1869get_status(struct player_command *cmd) 1870{ 1871 struct timespec ts; 1872 struct player_source *ps; 1873 struct player_status *status; 1874 uint64_t pos; 1875 int ret; 1876 1877 status = cmd->arg.status; 1878 1879 status->shuffle = shuffle; 1880 status->repeat = repeat; 1881 1882 /* No devices selected, autoselect local audio */ 1883 if (laudio_enabled && master_volume < 0) 1884// if (master_volume < 0) 1885 speaker_select_laudio(); 1886 1887 status->volume = master_volume; 1888 1889 status->plid = cur_plid; 1890 1891 switch (player_state) 1892 { 1893 case PLAY_STOPPED: 1894 DPRINTF(E_DBG, L_PLAYER, "Player status: stopped\n"); 1895 1896 status->status = PLAY_STOPPED; 1897 break; 1898 1899 case PLAY_PAUSED: 1900 DPRINTF(E_DBG, L_PLAYER, "Player status: paused\n"); 1901 1902 status->status = PLAY_PAUSED; 1903 status->id = cur_streaming->id; 1904 1905 pos = last_rtptime + AIRTUNES_V2_PACKET_SAMPLES - cur_streaming->stream_start; 1906 status->pos_ms = (pos * 1000) / 44100; 1907 1908 status->pos_pl = source_position(cur_streaming); 1909 break; 1910 1911 case PLAY_PLAYING: 1912 if (!cur_playing) 1913 { 1914 DPRINTF(E_DBG, L_PLAYER, "Player status: playing (buffering)\n"); 1915 1916 status->status = PLAY_PAUSED; 1917 ps = cur_streaming; 1918 1919 /* Avoid a visible 2-second jump backward for the client */ 1920 pos = ps->output_start - ps->stream_start; 1921 } 1922 else 1923 { 1924 DPRINTF(E_DBG, L_PLAYER, "Player status: playing\n"); 1925 1926 status->status = PLAY_PLAYING; 1927 ps = cur_playing; 1928 1929 ret = player_get_current_pos(&pos, &ts, 0); 1930 if (ret < 0) 1931 { 1932 DPRINTF(E_LOG, L_PLAYER, "Could not get current stream position for playstatus\n"); 1933 1934 pos = 0; 1935 } 1936 1937 if (pos < ps->stream_start) 1938 pos = 0; 1939 else 1940 pos -= ps->stream_start; 1941 } 1942 1943 status->pos_ms = (pos * 1000) / 44100; 1944 1945 status->id = ps->id; 1946 status->pos_pl = source_position(ps); 1947 break; 1948 } 1949 1950 return 0; 1951} 1952 1953static int 1954now_playing(struct player_command *cmd) 1955{ 1956 uint32_t *id; 1957 1958 id = cmd->arg.id_ptr; 1959 1960 if (cur_playing) 1961 *id = cur_playing->id; 1962 else if (cur_streaming) 1963 *id = cur_streaming->id; 1964 else 1965 return -1; 1966 1967 return 0; 1968} 1969 1970static int 1971playback_stop(struct player_command *cmd) 1972{ 1973// if (laudio_status != LAUDIO_CLOSED) 1974 if (laudio_enabled && laudio_status != LAUDIO_CLOSED) 1975 laudio_close(); 1976 1977 /* We may be restarting very soon, so we don't bring the devices to a 1978 * full stop just yet; this saves time when restarting, which is nicer 1979 * for the user. 1980 */ 1981 cmd->raop_pending = raop_flush(device_command_cb, last_rtptime + AIRTUNES_V2_PACKET_SAMPLES); 1982 1983 if (event_initialized(&pb_timer_ev)) 1984 event_del(&pb_timer_ev); 1985 1986 close(pb_timer_fd); 1987 pb_timer_fd = -1; 1988 1989 if (cur_playing) 1990 source_stop(cur_playing); 1991 else 1992 source_stop(cur_streaming); 1993 1994 cur_playing = NULL; 1995 cur_streaming = NULL; 1996 1997 evbuffer_drain(audio_buf, EVBUFFER_LENGTH(audio_buf)); 1998 1999 status_update(PLAY_STOPPED); 2000 2001 metadata_purge(); 2002 2003 /* We're async if we need to flush RAOP devices */ 2004 if (cmd->raop_pending > 0) 2005 return 1; /* async */ 2006 2007 return 0; 2008} 2009 2010/* Playback startup bottom half */ 2011static int 2012playback_start_bh(struct player_command *cmd) 2013{ 2014#if defined(__linux__) 2015 struct itimerspec next; 2016#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 2017 struct kevent kev; 2018#endif 2019 int ret; 2020 2021 if ((laudio_status == LAUDIO_CLOSED) && (raop_sessions == 0)) 2022 { 2023 DPRINTF(E_LOG, L_PLAYER, "Cannot start playback: no output started\n"); 2024 2025 goto out_fail; 2026 } 2027 2028 /* Start laudio first as it can fail, but can be stopped easily if needed */ 2029 if (laudio_status == LAUDIO_OPEN) 2030 { 2031 laudio_set_volume(laudio_volume); 2032 2033 ret = laudio_start(pb_pos, last_rtptime + AIRTUNES_V2_PACKET_SAMPLES); 2034 if (ret < 0) 2035 { 2036 DPRINTF(E_LOG, L_PLAYER, "Local audio failed to start\n"); 2037 2038 goto out_fail; 2039 } 2040 } 2041 2042 ret = clock_gettime(CLOCK_MONOTONIC, &pb_pos_stamp); 2043 if (ret < 0) 2044 { 2045 DPRINTF(E_LOG, L_PLAYER, "Couldn't get current clock: %s\n", strerror(errno)); 2046 2047 goto out_fail; 2048 } 2049 2050 memset(&pb_timer_ev, 0, sizeof(struct event)); 2051 2052#if defined(__linux__) 2053 pb_timer_last.tv_sec = pb_pos_stamp.tv_sec; 2054 pb_timer_last.tv_nsec = pb_pos_stamp.tv_nsec; 2055 2056 pb_timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC); 2057 if (pb_timer_fd < 0) 2058 { 2059 DPRINTF(E_LOG, L_PLAYER, "Could not create playback timer: %s\n", strerror(errno)); 2060 2061 goto out_fail; 2062 } 2063 2064 next.it_interval.tv_sec = 0; 2065 next.it_interval.tv_nsec = 0; 2066 next.it_value.tv_sec = pb_timer_last.tv_sec; 2067 next.it_value.tv_nsec = pb_timer_last.tv_nsec; 2068 2069 ret = timerfd_settime(pb_timer_fd, TFD_TIMER_ABSTIME, &next, NULL); 2070 if (ret < 0) 2071 { 2072 DPRINTF(E_LOG, L_PLAYER, "Could not set playback timer: %s\n", strerror(errno)); 2073 2074 goto out_fail; 2075 } 2076#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 2077 pb_timer_fd = kqueue(); 2078 if (pb_timer_fd < 0) 2079 { 2080 DPRINTF(E_LOG, L_PLAYER, "Could not create kqueue: %s\n", strerror(errno)); 2081 2082 goto out_fail; 2083 } 2084 2085 memset(&kev, 0, sizeof(struct kevent)); 2086 2087 EV_SET(&kev, 1, EVFILT_TIMER, EV_ADD | EV_ENABLE, 0, AIRTUNES_V2_STREAM_PERIOD, 0); 2088 2089 ret = kevent(pb_timer_fd, &kev, 1, NULL, 0, NULL); 2090 if (ret < 0) 2091 { 2092 DPRINTF(E_LOG, L_PLAYER, "Could not add kevent timer: %s\n", strerror(errno)); 2093 2094 goto out_fail; 2095 } 2096#endif 2097 2098 event_set(&pb_timer_ev, pb_timer_fd, EV_READ, player_playback_cb, NULL); 2099 event_base_set(evbase_player, &pb_timer_ev); 2100 2101 ret = event_add(&pb_timer_ev, NULL); 2102 if (ret < 0) 2103 { 2104 DPRINTF(E_LOG, L_PLAYER, "Could not set up playback timer event\n"); 2105 2106 goto out_fail; 2107 } 2108 2109 /* Everything OK, start RAOP */ 2110 if (raop_sessions > 0) 2111 raop_playback_start(last_rtptime + AIRTUNES_V2_PACKET_SAMPLES, &pb_pos_stamp); 2112 2113 status_update(PLAY_PLAYING); 2114 2115 return 0; 2116 2117 out_fail: 2118 close(pb_timer_fd); 2119 pb_timer_fd = -1; 2120 playback_abort(); 2121 2122 return -1; 2123} 2124 2125static int 2126playback_start(struct player_command *cmd) 2127{ 2128 struct raop_device *rd; 2129 uint32_t *idx_id; 2130 int ret; 2131 2132 if (!source_head) 2133 { 2134 DPRINTF(E_LOG, L_PLAYER, "Nothing to play!\n"); 2135 2136 return -1; 2137 } 2138 2139 idx_id = cmd->arg.id_ptr; 2140 2141 if (player_state == PLAY_PLAYING) 2142 { 2143 if (idx_id) 2144 { 2145 if (cur_playing) 2146 *idx_id = cur_playing->id; 2147 else 2148 *idx_id = cur_streaming->id; 2149 } 2150 2151 status_update(player_state); 2152 2153 return 0; 2154 } 2155 2156 pb_pos = last_rtptime + AIRTUNES_V2_PACKET_SAMPLES - 88200; 2157 2158 if (idx_id) 2159 { 2160 if (cur_playing) 2161 source_stop(cur_playing); 2162 else if (cur_streaming) 2163 source_stop(cur_streaming); 2164 2165 cur_playing = NULL; 2166 cur_streaming = NULL; 2167 2168 if (shuffle) 2169 { 2170 source_reshuffle(); 2171 cur_streaming = shuffle_head; 2172 } 2173 else 2174 cur_streaming = source_head; 2175 2176 if (*idx_id > 0) 2177 { 2178 cur_streaming = source_head; 2179 for (; *idx_id > 0; (*idx_id)--) 2180 cur_streaming = cur_streaming->pl_next; 2181 2182 if (shuffle) 2183 shuffle_head = cur_streaming; 2184 } 2185 2186 ret = source_open(cur_streaming, 0); 2187 if (ret < 0) 2188 { 2189 DPRINTF(E_LOG, L_PLAYER, "Couldn't jump to queue position %d\n", *idx_id); 2190 2191 playback_abort(); 2192 return -1; 2193 } 2194 2195 *idx_id = cur_streaming->id; 2196 cur_streaming->stream_start = last_rtptime + AIRTUNES_V2_PACKET_SAMPLES; 2197 cur_streaming->output_start = cur_streaming->stream_start; 2198 } 2199 else if (!cur_streaming) 2200 { 2201 if (shuffle) 2202 source_reshuffle(); 2203 2204 ret = source_next(0); 2205 if (ret < 0) 2206 { 2207 DPRINTF(E_LOG, L_PLAYER, "Couldn't find anything to play!\n"); 2208 2209 playback_abort(); 2210 return -1; 2211 } 2212 2213 cur_streaming->stream_start = last_rtptime + AIRTUNES_V2_PACKET_SAMPLES; 2214 cur_streaming->output_start = cur_streaming->stream_start; 2215 } 2216 else 2217 { 2218 /* After a pause, the source is still open so source_open() doesn't get 2219 * called and we have to handle metadata ourselves. 2220 */ 2221 metadata_send(cur_streaming, 1); 2222 } 2223 2224 /* Start local audio if needed */ 2225 if (laudio_selected && (laudio_status == LAUDIO_CLOSED)) 2226 { 2227 ret = laudio_open(); 2228 if (ret < 0) 2229 { 2230 DPRINTF(E_LOG, L_PLAYER, "Could not open local audio\n"); 2231 2232 playback_abort(); 2233 return -1; 2234 } 2235 } 2236 2237 /* Start RAOP sessions on selected devices if needed */ 2238 cmd->raop_pending = 0; 2239 2240 for (rd = dev_list; rd; rd = rd->next) 2241 { 2242// if (rd->selected && !rd->session) 2243 if ( !rd->session) 2244 { 2245 ret = raop_device_start(rd, device_restart_cb, last_rtptime + AIRTUNES_V2_PACKET_SAMPLES); 2246 if (ret < 0) 2247 { 2248 DPRINTF(E_LOG, L_PLAYER, "Could not start selected AirTunes device %s\n", rd->name); 2249 continue; 2250 } 2251 2252 cmd->raop_pending++; 2253 } 2254 } 2255 2256 if ((laudio_status == LAUDIO_CLOSED) && (cmd->raop_pending == 0) && (raop_sessions == 0)) 2257 { 2258 DPRINTF(E_LOG, L_PLAYER, "Could not start playback: no output selected or couldn't start any output\n"); 2259 2260 playback_abort(); 2261 return -1; 2262 } 2263 2264 /* We're async if we need to start RAOP devices */ 2265 if (cmd->raop_pending > 0) 2266 return 1; /* async */ 2267 2268 /* Otherwise, just run the bottom half */ 2269 return playback_start_bh(cmd); 2270} 2271 2272static int 2273playback_prev_bh(struct player_command *cmd) 2274{ 2275 int ret; 2276 2277 if (cur_playing) 2278 source_stop(cur_playing); 2279 else 2280 source_stop(cur_streaming); 2281 2282 ret = source_prev(); 2283 if (ret < 0) 2284 { 2285 playback_abort(); 2286 2287 return -1; 2288 } 2289 2290 if (player_state == PLAY_STOPPED) 2291 return -1; 2292 2293 cur_streaming->stream_start = last_rtptime + AIRTUNES_V2_PACKET_SAMPLES; 2294 cur_streaming->output_start = cur_streaming->stream_start; 2295 2296 cur_playing = NULL; 2297 2298 /* Silent status change - playback_start() sends the real status update */ 2299 player_state = PLAY_PAUSED; 2300 2301 return 0; 2302} 2303 2304static int 2305playback_next_bh(struct player_command *cmd) 2306{ 2307 int ret; 2308 2309 if (cur_playing) 2310 source_stop(cur_playing); 2311 else 2312 source_stop(cur_streaming); 2313 2314 ret = source_next(1); 2315 if (ret < 0) 2316 { 2317 playback_abort(); 2318 2319 return -1; 2320 } 2321 2322 if (player_state == PLAY_STOPPED) 2323 return -1; 2324 2325 cur_streaming->stream_start = last_rtptime + AIRTUNES_V2_PACKET_SAMPLES; 2326 cur_streaming->output_start = cur_streaming->stream_start; 2327 2328 cur_playing = NULL; 2329 2330 /* Silent status change - playback_start() sends the real status update */ 2331 player_state = PLAY_PAUSED; 2332 2333 return 0; 2334} 2335 2336static int 2337playback_seek_bh(struct player_command *cmd) 2338{ 2339 struct player_source *ps; 2340 int ms; 2341 int ret; 2342 2343 ms = cmd->arg.intval; 2344 2345 if (cur_playing) 2346 ps = cur_playing; 2347 else 2348 ps = cur_streaming; 2349 2350 ps->end = 0; 2351 2352 /* Seek to commanded position */ 2353 ret = transcode_seek(ps->ctx, ms); 2354 if (ret < 0) 2355 { 2356 playback_abort(); 2357 2358 return -1; 2359 } 2360 2361 /* Adjust start_pos for the new position */ 2362 ps->stream_start = last_rtptime + AIRTUNES_V2_PACKET_SAMPLES - ((uint64_t)ret * 44100) / 1000; 2363 ps->output_start = last_rtptime + AIRTUNES_V2_PACKET_SAMPLES; 2364 2365 cur_streaming = ps; 2366 cur_playing = NULL; 2367 2368 /* Silent status change - playback_start() sends the real status update */ 2369 player_state = PLAY_PAUSED; 2370 2371 return 0; 2372} 2373 2374static int 2375playback_pause_bh(struct player_command *cmd) 2376{ 2377 struct player_source *ps; 2378 uint64_t pos; 2379 int ms; 2380 int ret; 2381 2382 if (cur_playing) 2383 ps = cur_playing; 2384 else 2385 ps = cur_streaming; 2386 2387 pos = ps->end; 2388 ps->end = 0; 2389 2390 /* Seek back to current playback position */ 2391 pos -= ps->stream_start; 2392 ms = (int)((pos * 1000) / 44100); 2393 2394 ret = transcode_seek(ps->ctx, ms); 2395 if (ret < 0) 2396 { 2397 playback_abort(); 2398 2399 return -1; 2400 } 2401 2402 /* Adjust start_pos to take into account the pause and seek back */ 2403 ps->stream_start = last_rtptime + AIRTUNES_V2_PACKET_SAMPLES - ((uint64_t)ret * 44100) / 1000; 2404 ps->output_start = last_rtptime + AIRTUNES_V2_PACKET_SAMPLES; 2405 2406 cur_streaming = ps; 2407 cur_playing = NULL; 2408 2409 status_update(PLAY_PAUSED); 2410 2411 return 0; 2412} 2413 2414static int 2415playback_pause(struct player_command *cmd) 2416{ 2417 struct player_source *ps; 2418 uint64_t pos; 2419 2420 pos = source_check(); 2421 if (pos == 0) 2422 { 2423 DPRINTF(E_LOG, L_PLAYER, "Could not retrieve current position for pause\n"); 2424 2425 playback_abort(); 2426 return -1; 2427 } 2428 2429 /* Make sure playback is still running after source_check() */ 2430 if (player_state == PLAY_STOPPED) 2431 return -1; 2432 2433 if (cur_playing) 2434 ps = cur_playing; 2435 else 2436 ps = cur_streaming; 2437 2438 /* Store pause position */ 2439 ps->end = pos; 2440 2441 cmd->raop_pending = raop_flush(device_command_cb, last_rtptime + AIRTUNES_V2_PACKET_SAMPLES); 2442 2443 if (laudio_status != LAUDIO_CLOSED) 2444 laudio_stop(); 2445 2446 if (event_initialized(&pb_timer_ev)) 2447 event_del(&pb_timer_ev); 2448 2449 close(pb_timer_fd); 2450 pb_timer_fd = -1; 2451 2452 if (ps->play_next) 2453 source_stop(ps->play_next); 2454 2455 cur_playing = NULL; 2456 cur_streaming = ps; 2457 cur_streaming->play_next = NULL; 2458 2459 evbuffer_drain(audio_buf, EVBUFFER_LENGTH(audio_buf)); 2460 2461 metadata_purge(); 2462 2463 /* We're async if we need to flush RAOP devices */ 2464 if (cmd->raop_pending > 0) 2465 return 1; /* async */ 2466 2467 /* Otherwise, just run the bottom half */ 2468 return cmd->func_bh(cmd); 2469} 2470 2471static int 2472speaker_enumerate(struct player_command *cmd) 2473{ 2474 struct raop_device *rd; 2475 struct spk_enum *spk_enum; 2476 struct spk_flags flags; 2477 char *laudio_name; 2478 2479 spk_enum = cmd->arg.spk_enum; 2480 2481 laudio_name = cfg_getstr(cfg_getsec(cfg, "audio"), "nickname"); 2482 2483 /* Auto-select local audio if there are no AirTunes devices */ 2484// if (!dev_list && !laudio_selected) 2485 if (laudio_enabled && !dev_list && !laudio_selected) 2486 speaker_select_laudio(); 2487 2488 flags.selected = laudio_selected; 2489 flags.has_password = 0; 2490 flags.has_video = 0; 2491 2492 if (laudio_enabled) 2493 spk_enum->cb(0, laudio_name, laudio_relvol, flags, spk_enum->arg); 2494// spk_enum->cb(0, laudio_name, laudio_relvol, flags, spk_enum->arg); 2495 2496#ifdef DEBUG_RELVOL 2497 DPRINTF(E_DBG, L_PLAYER, "*** master: %d\n", master_volume); 2498 if (laudio_enabled) 2499 DPRINTF(E_DBG, L_PLAYER, "*** laudio: abs %d rel %d\n", laudio_volume, laudio_relvol); 2500// DPRINTF(E_DBG, L_PLAYER, "*** laudio: abs %d rel %d\n", laudio_volume, laudio_relvol); 2501#endif 2502 2503 for (rd = dev_list; rd; rd = rd->next) 2504 { 2505 if (rd->advertised || rd->selected) 2506 { 2507 flags.selected = rd->selected; 2508 flags.has_password = rd->has_password; 2509 flags.has_video = (rd->devtype == RAOP_DEV_APPLETV); 2510 2511 spk_enum->cb(rd->id, rd->name, rd->relvol, flags, spk_enum->arg); 2512 2513#ifdef DEBUG_RELVOL 2514 DPRINTF(E_DBG, L_PLAYER, "*** %s: abs %d rel %d\n", rd->name, rd->volume, rd->relvol); 2515#endif 2516 } 2517 } 2518 2519 return 0; 2520} 2521 2522static int 2523speaker_activate(struct raop_device *rd) 2524{ 2525 struct timespec ts; 2526 uint64_t pos; 2527 int ret; 2528 2529// if (!rd) 2530 if (!rd && laudio_enabled) 2531 { 2532 /* Local */ 2533 DPRINTF(E_DBG, L_PLAYER, "Activating local audio\n"); 2534 2535 if (laudio_status == LAUDIO_CLOSED) 2536 { 2537 ret = laudio_open(); 2538 if (ret < 0) 2539 { 2540 DPRINTF(E_LOG, L_PLAYER, "Could not open local audio\n"); 2541 2542 return -1; 2543 } 2544 } 2545 2546 if (player_state == PLAY_PLAYING) 2547 { 2548 laudio_set_volume(laudio_volume); 2549 2550 ret = player_get_current_pos(&pos, &ts, 0); 2551 if (ret < 0) 2552 { 2553 DPRINTF(E_LOG, L_PLAYER, "Could not get current stream position for local audio start\n"); 2554 2555 laudio_close(); 2556 return -1; 2557 } 2558 2559 ret = laudio_start(pos, last_rtptime + AIRTUNES_V2_PACKET_SAMPLES); 2560 if (ret < 0) 2561 { 2562 DPRINTF(E_LOG, L_PLAYER, "Local playback failed to start\n"); 2563 2564 laudio_close(); 2565 return -1; 2566 } 2567 } 2568 2569 return 0; 2570 } 2571 else 2572 { 2573 /* RAOP */ 2574 if (player_state == PLAY_PLAYING) 2575 { 2576 DPRINTF(E_DBG, L_PLAYER, "Activating RAOP device %s\n", rd->name); 2577 2578 ret = raop_device_start(rd, device_activate_cb, last_rtptime + AIRTUNES_V2_PACKET_SAMPLES); 2579 if (ret < 0) 2580 { 2581 DPRINTF(E_LOG, L_PLAYER, "Could not start device %s\n", rd->name); 2582 2583 return -1; 2584 } 2585 } 2586 else 2587 { 2588 DPRINTF(E_DBG, L_PLAYER, "Probing RAOP device %s\n", rd->name); 2589 2590 ret = raop_device_probe(rd, device_probe_cb); 2591 if (ret < 0) 2592 { 2593 DPRINTF(E_LOG, L_PLAYER, "Could not probe device %s\n", rd->name); 2594 2595 return -1; 2596 } 2597 } 2598 2599 return 1; 2600 } 2601 2602 return -1; 2603} 2604 2605static int 2606speaker_deactivate(struct raop_device *rd) 2607{ 2608// if (!rd) 2609 if (!rd && laudio_enabled) 2610 { 2611 /* Local */ 2612 DPRINTF(E_DBG, L_PLAYER, "Deactivating local audio\n"); 2613 2614 if (laudio_status == LAUDIO_CLOSED) 2615 return 0; 2616 2617 if (laudio_status & LAUDIO_F_STARTED) 2618 laudio_stop(); 2619 2620 laudio_close(); 2621 2622 return 0; 2623 } 2624 else 2625 { 2626 /* RAOP */ 2627 DPRINTF(E_DBG, L_PLAYER, "Deactivating RAOP device %s\n", rd->name); 2628 2629 raop_set_status_cb(rd->session, device_shutdown_cb); 2630 raop_device_stop(rd->session); 2631 2632 return 1; 2633 } 2634 2635 return -1; 2636} 2637 2638static int 2639speaker_set(struct player_command *cmd) 2640{ 2641 struct raop_device *rd; 2642 uint64_t *ids; 2643 int nspk; 2644 int i; 2645 int ret; 2646 2647 ids = cmd->arg.raop_ids; 2648 2649 if (ids) 2650 nspk = ids[0]; 2651 else 2652 nspk = 0; 2653 2654 DPRINTF(E_DBG, L_PLAYER, "Speaker set: %d speakers\n", nspk); 2655 2656 cmd->raop_pending = 0; 2657 cmd->ret = 0; 2658 2659 /* RAOP devices */ 2660 for (rd = dev_list; rd; rd = rd->next) 2661 { 2662 for (i = 1; i <= nspk; i++) 2663 { 2664 DPRINTF(E_DBG, L_PLAYER, "Set %" PRIu64 " device %" PRIu64 "\n", ids[i], rd->id); 2665 2666 if (ids[i] == rd->id) 2667 break; 2668 } 2669 2670 if (i <= nspk) 2671 { 2672 if (rd->has_password && !rd->password) 2673 { 2674 DPRINTF(E_INFO, L_PLAYER, "RAOP device %s is password-protected, but we don't have it\n", rd->name); 2675 2676 cmd->ret = -2; 2677 continue; 2678 } 2679 2680 DPRINTF(E_DBG, L_PLAYER, "RAOP device %s selected\n", rd->name); 2681 2682 if (!rd->selected) 2683 speaker_select_raop(rd); 2684 2685 if (!rd->session) 2686 { 2687 ret = speaker_activate(rd); 2688 if (ret < 0) 2689 { 2690 DPRINTF(E_LOG, L_PLAYER, "Could not activate RAOP device %s\n", rd->name); 2691 2692 speaker_deselect_raop(rd); 2693 2694 if (cmd->ret != -2) 2695 cmd->ret = -1; 2696 } 2697 2698 /* ret = 1 if RAOP needs to take action */ 2699 cmd->raop_pending += ret; 2700 } 2701 } 2702 else 2703 { 2704 DPRINTF(E_DBG, L_PLAYER, "RAOP device %s NOT selected\n", rd->name); 2705 2706 if (rd->selected) 2707 speaker_deselect_raop(rd); 2708 2709 if (rd->session) 2710 { 2711 ret = speaker_deactivate(rd); 2712 if (ret < 0) 2713 { 2714 DPRINTF(E_LOG, L_PLAYER, "Could not deactivate RAOP device %s\n", rd->name); 2715 2716 if (cmd->ret != -2) 2717 cmd->ret = -1; 2718 } 2719 2720 /* ret = 1 if RAOP needs to take action */ 2721 cmd->raop_pending += ret; 2722 } 2723 } 2724 } 2725 2726 /* Local audio */ 2727 if(laudio_enabled) 2728 { 2729 for (i = 1; i <= nspk; i++) 2730 { 2731 if (ids[i] == 0) 2732 break; 2733 } 2734 2735 if (i <= nspk) 2736 { 2737 DPRINTF(E_DBG, L_PLAYER, "Local audio selected\n"); 2738 2739 if (!laudio_selected) 2740 speaker_select_laudio(); 2741 2742 if (!(laudio_status & LAUDIO_F_STARTED)) 2743 { 2744 ret = speaker_activate(NULL); 2745 if (ret < 0) 2746 { 2747 DPRINTF(E_LOG, L_PLAYER, "Could not activate local audio output\n"); 2748 2749 speaker_deselect_laudio(); 2750 2751 if (cmd->ret != -2) 2752 cmd->ret = -1; 2753 } 2754 } 2755 } 2756 else 2757 { 2758 DPRINTF(E_DBG, L_PLAYER, "Local audio NOT selected\n"); 2759 2760 if (laudio_selected) 2761 speaker_deselect_laudio(); 2762 2763 if (laudio_status != LAUDIO_CLOSED) 2764 { 2765 ret = speaker_deactivate(NULL); 2766 if (ret < 0) 2767 { 2768 DPRINTF(E_LOG, L_PLAYER, "Could not deactivate local audio output\n"); 2769 2770 if (cmd->ret != -2) 2771 cmd->ret = -1; 2772 } 2773 } 2774 } 2775 } 2776 2777 if (cmd->raop_pending > 0) 2778 return 1; /* async */ 2779 2780 return cmd->ret; 2781} 2782 2783static int 2784volume_set(struct player_command *cmd) 2785{ 2786 struct raop_device *rd; 2787 int volume; 2788 2789 volume = cmd->arg.intval; 2790 2791 if (master_volume == volume) 2792 return 0; 2793 2794 master_volume = volume; 2795 2796 if (laudio_selected) 2797 { 2798 laudio_volume = rel_to_vol(laudio_relvol); 2799 laudio_set_volume(laudio_volume); 2800 2801#ifdef DEBUG_RELVOL 2802 DPRINTF(E_DBG, L_PLAYER, "*** laudio: abs %d rel %d\n", laudio_volume, laudio_relvol); 2803#endif 2804 } 2805 2806 cmd->raop_pending = 0; 2807 2808 for (rd = dev_list; rd; rd = rd->next) 2809 { 2810/* 2811 if (!rd->selected) 2812 continue; 2813*/ 2814 rd->volume = rel_to_vol(rd->relvol); 2815 2816#ifdef DEBUG_RELVOL 2817 DPRINTF(E_DBG, L_PLAYER, "*** %s: abs %d rel %d\n", rd->name, rd->volume, rd->relvol); 2818#endif 2819 2820 if (rd->session) 2821 cmd->raop_pending += raop_set_volume_one(rd->session, rd->volume, device_command_cb); 2822 } 2823 2824 if (cmd->raop_pending > 0) 2825 return 1; /* async */ 2826 2827 return 0; 2828} 2829 2830static int 2831volume_setrel_speaker(struct player_command *cmd) 2832{ 2833 struct raop_device *rd; 2834 uint64_t id; 2835 int relvol; 2836 2837 id = cmd->arg.vol_param.spk_id; 2838 relvol = cmd->arg.vol_param.volume; 2839 2840 if (id == 0) 2841 { 2842 laudio_relvol = relvol; 2843 laudio_volume = rel_to_vol(relvol); 2844 laudio_set_volume(laudio_volume); 2845 2846#ifdef DEBUG_RELVOL 2847 DPRINTF(E_DBG, L_PLAYER, "*** laudio: abs %d rel %d\n", laudio_volume, laudio_relvol); 2848#endif 2849 } 2850 else 2851 { 2852 for (rd = dev_list; rd; rd = rd->next) 2853 { 2854 if (rd->id != id) 2855 continue; 2856 2857 if (!rd->selected) 2858 return 0; 2859 2860 rd->relvol = relvol; 2861 rd->volume = rel_to_vol(relvol); 2862 2863#ifdef DEBUG_RELVOL 2864 DPRINTF(E_DBG, L_PLAYER, "*** %s: abs %d rel %d\n", rd->name, rd->volume, rd->relvol); 2865#endif 2866 2867 if (rd->session) 2868 cmd->raop_pending = raop_set_volume_one(rd->session, rd->volume, device_command_cb); 2869 2870 break; 2871 } 2872 } 2873 2874 if (cmd->raop_pending > 0) 2875 return 1; /* async */ 2876 2877 return 0; 2878} 2879 2880static int 2881volume_setabs_speaker(struct player_command *cmd) 2882{ 2883 struct raop_device *rd; 2884 uint64_t id; 2885 int volume; 2886 2887 id = cmd->arg.vol_param.spk_id; 2888 volume = cmd->arg.vol_param.volume; 2889 2890 master_volume = volume; 2891 2892 if (id == 0) 2893 { 2894 laudio_relvol = 100; 2895 laudio_volume = volume; 2896 laudio_set_volume(laudio_volume); 2897 } 2898 else 2899 laudio_relvol = vol_to_rel(laudio_volume); 2900 2901#ifdef DEBUG_RELVOL 2902 DPRINTF(E_DBG, L_PLAYER, "*** laudio: abs %d rel %d\n", laudio_volume, laudio_relvol); 2903#endif 2904 2905 for (rd = dev_list; rd; rd = rd->next) 2906 { 2907 if (!rd->selected) 2908 continue; 2909 2910 if (rd->id != id) 2911 { 2912 rd->relvol = vol_to_rel(rd->volume); 2913 2914#ifdef DEBUG_RELVOL 2915 DPRINTF(E_DBG, L_PLAYER, "*** %s: abs %d rel %d\n", rd->name, rd->volume, rd->relvol); 2916#endif 2917 continue; 2918 } 2919 else 2920 { 2921 rd->relvol = 100; 2922 rd->volume = master_volume; 2923 2924#ifdef DEBUG_RELVOL 2925 DPRINTF(E_DBG, L_PLAYER, "*** %s: abs %d rel %d\n", rd->name, rd->volume, rd->relvol); 2926#endif 2927 2928 if (rd->session) 2929 cmd->raop_pending = raop_set_volume_one(rd->session, rd->volume, device_command_cb); 2930 } 2931 } 2932 2933 if (cmd->raop_pending > 0) 2934 return 1; /* async */ 2935 2936 return 0; 2937} 2938 2939static int 2940repeat_set(struct player_command *cmd) 2941{ 2942 switch (cmd->arg.mode) 2943 { 2944 case REPEAT_OFF: 2945 case REPEAT_SONG: 2946 case REPEAT_ALL: 2947 repeat = cmd->arg.mode; 2948 break; 2949 2950 default: 2951 DPRINTF(E_LOG, L_PLAYER, "Invalid repeat mode: %d\n", cmd->arg.mode); 2952 return -1; 2953 } 2954 2955 return 0; 2956} 2957 2958static int 2959shuffle_set(struct player_command *cmd) 2960{ 2961 switch (cmd->arg.intval) 2962 { 2963 case 1: 2964 if (!shuffle) 2965 source_reshuffle(); 2966 /* FALLTHROUGH*/ 2967 case 0: 2968 shuffle = cmd->arg.intval; 2969 break; 2970 2971 default: 2972 DPRINTF(E_LOG, L_PLAYER, "Invalid shuffle mode: %d\n", cmd->arg.intval); 2973 return -1; 2974 } 2975 2976 return 0; 2977} 2978 2979static int 2980queue_add(struct player_command *cmd) 2981{ 2982 struct player_source *ps; 2983 struct player_source *ps_shuffle; 2984 struct player_source *source_tail; 2985 struct player_source *ps_tail; 2986 2987 ps = cmd->arg.ps; 2988 2989 ps_shuffle = source_shuffle(ps); 2990 if (!ps_shuffle) 2991 ps_shuffle = ps; 2992 2993 if (source_head) 2994 { 2995 /* Playlist order */ 2996 source_tail = source_head->pl_prev; 2997 ps_tail = ps->pl_prev; 2998 2999 source_tail->pl_next = ps; 3000 ps_tail->pl_next = source_head; 3001 3002 source_head->pl_prev = ps_tail; 3003 ps->pl_prev = source_tail; 3004 3005 /* Shuffle */ 3006 source_tail = shuffle_head->shuffle_prev; 3007 ps_tail = ps_shuffle->shuffle_prev; 3008 3009 source_tail->shuffle_next = ps_shuffle; 3010 ps_tail->shuffle_next = shuffle_head; 3011 3012 shuffle_head->shuffle_prev = ps_tail; 3013 ps_shuffle->shuffle_prev = source_tail; 3014 } 3015 else 3016 { 3017 source_head = ps; 3018 shuffle_head = ps_shuffle; 3019 } 3020 3021 if (cur_plid != 0) 3022 cur_plid = 0; 3023 3024 return 0; 3025} 3026 3027static int 3028queue_clear(struct player_command *cmd) 3029{ 3030 struct player_source *ps; 3031 3032 if (!source_head) 3033 return 0; 3034 3035 shuffle_head = NULL; 3036 source_head->pl_prev->pl_next = NULL; 3037 3038 for (ps = source_head; ps; ps = source_head) 3039 { 3040 source_head = ps->pl_next; 3041 3042 source_free(ps); 3043 } 3044 3045 cur_plid = 0; 3046 3047 return 0; 3048} 3049 3050static int 3051queue_plid(struct player_command *cmd) 3052{ 3053 if (!source_head) 3054 return 0; 3055 3056 cur_plid = cmd->arg.id; 3057 3058 return 0; 3059} 3060 3061static int 3062set_update_handler(struct player_command *cmd) 3063{ 3064 update_handler = cmd->arg.status_handler; 3065 3066 return 0; 3067} 3068 3069/* Command processing */ 3070/* Thread: player */ 3071static void 3072command_cb(int fd, short what, void *arg) 3073{ 3074 struct player_command *cmd; 3075 int ret; 3076 3077 ret = read(cmd_pipe[0], &cmd, sizeof(cmd)); 3078 if (ret != sizeof(cmd)) 3079 { 3080 DPRINTF(E_LOG, L_PLAYER, "Could not read command! (read %d): %s\n", ret, (ret < 0) ? strerror(errno) : "-no error-"); 3081 3082 goto readd; 3083 } 3084 3085 if (cmd->nonblock) 3086 { 3087 cmd->func(cmd); 3088 3089 free(cmd); 3090 goto readd; 3091 } 3092 3093 pthread_mutex_lock(&cmd->lck); 3094 3095 cur_cmd = cmd; 3096 3097 ret = cmd->func(cmd); 3098 3099 if (ret <= 0) 3100 { 3101 cmd->ret = ret; 3102 3103 cur_cmd = NULL; 3104 3105 pthread_cond_signal(&cmd->cond); 3106 pthread_mutex_unlock(&cmd->lck); 3107 } 3108 else 3109 { 3110 /* Command is asynchronous, we don't want to process another command 3111 * before we're done with this one. See command_async_end(). 3112 */ 3113 3114 return; 3115 } 3116 3117 readd: 3118 event_add(&cmdev, NULL); 3119} 3120 3121 3122/* Thread: httpd (DACP) - mDNS */ 3123static int 3124send_command(struct player_command *cmd) 3125{ 3126 int ret; 3127 3128 if (!cmd->func) 3129 { 3130 DPRINTF(E_LOG, L_PLAYER, "BUG: cmd->func is NULL!\n"); 3131 3132 return -1; 3133 } 3134 3135 ret = write(cmd_pipe[1], &cmd, sizeof(cmd)); 3136 if (ret != sizeof(cmd)) 3137 { 3138 DPRINTF(E_LOG, L_PLAYER, "Could not send command: %s\n", strerror(errno)); 3139 3140 return -1; 3141 } 3142 3143 return 0; 3144} 3145 3146/* Thread: mDNS */ 3147static int 3148nonblock_command(struct player_command *cmd) 3149{ 3150 int ret; 3151 3152 ret = send_command(cmd); 3153 if (ret < 0) 3154 return -1; 3155 3156 return 0; 3157} 3158 3159/* Thread: httpd (DACP) */ 3160static int 3161sync_command(struct player_command *cmd) 3162{ 3163 int ret; 3164 3165 pthread_mutex_lock(&cmd->lck); 3166 3167 ret = send_command(cmd); 3168 if (ret < 0) 3169 { 3170 pthread_mutex_unlock(&cmd->lck); 3171 3172 return -1; 3173 } 3174 3175 pthread_cond_wait(&cmd->cond, &cmd->lck); 3176 3177 pthread_mutex_unlock(&cmd->lck); 3178 3179 ret = cmd->ret; 3180 3181 return ret; 3182} 3183 3184 3185/* Player API executed in the httpd (DACP) thread */ 3186int 3187player_get_status(struct player_status *status) 3188{ 3189 struct player_command cmd; 3190 int ret; 3191 3192 command_init(&cmd); 3193 3194 cmd.func = get_status; 3195 cmd.func_bh = NULL; 3196 cmd.arg.status = status; 3197 3198 ret = sync_command(&cmd); 3199 3200 command_deinit(&cmd); 3201 3202 return ret; 3203} 3204 3205int 3206player_now_playing(uint32_t *id) 3207{ 3208 struct player_command cmd; 3209 int ret; 3210 3211 command_init(&cmd); 3212 3213 cmd.func = now_playing; 3214 cmd.func_bh = NULL; 3215 cmd.arg.id_ptr = id; 3216 3217 ret = sync_command(&cmd); 3218 3219 command_deinit(&cmd); 3220 3221 return ret; 3222} 3223 3224int 3225player_playback_start(uint32_t *idx_id) 3226{ 3227 struct player_command cmd; 3228 int ret; 3229 3230 command_init(&cmd); 3231 3232 cmd.func = playback_start; 3233 cmd.func_bh = playback_start_bh; 3234 cmd.arg.id_ptr = idx_id; 3235 3236 ret = sync_command(&cmd); 3237 3238 command_deinit(&cmd); 3239 3240 return ret; 3241} 3242 3243int 3244player_playback_stop(void) 3245{ 3246 struct player_command cmd; 3247 int ret; 3248 3249 command_init(&cmd); 3250 3251 cmd.func = playback_stop; 3252 cmd.arg.noarg = NULL; 3253 3254 ret = sync_command(&cmd); 3255 3256 command_deinit(&cmd); 3257 3258 return ret; 3259} 3260 3261int 3262player_playback_pause(void) 3263{ 3264 struct player_command cmd; 3265 int ret; 3266 3267 command_init(&cmd); 3268 3269 cmd.func = playback_pause; 3270 cmd.func_bh = playback_pause_bh; 3271 cmd.arg.noarg = NULL; 3272 3273 ret = sync_command(&cmd); 3274 3275 command_deinit(&cmd); 3276 3277 return ret; 3278} 3279 3280int 3281player_playback_seek(int ms) 3282{ 3283 struct player_command cmd; 3284 int ret; 3285 3286 command_init(&cmd); 3287 3288 cmd.func = playback_pause; 3289 cmd.func_bh = playback_seek_bh; 3290 cmd.arg.intval = ms; 3291 3292 ret = sync_command(&cmd); 3293 3294 command_deinit(&cmd); 3295 3296 return ret; 3297} 3298 3299int 3300player_playback_next(void) 3301{ 3302 struct player_command cmd; 3303 int ret; 3304 3305 command_init(&cmd); 3306 3307 cmd.func = playback_pause; 3308 cmd.func_bh = playback_next_bh; 3309 cmd.arg.noarg = NULL; 3310 3311 ret = sync_command(&cmd); 3312 3313 command_deinit(&cmd); 3314 3315 return ret; 3316} 3317 3318int 3319player_playback_prev(void) 3320{ 3321 struct player_command cmd; 3322 int ret; 3323 3324 command_init(&cmd); 3325 3326 cmd.func = playback_pause; 3327 cmd.func_bh = playback_prev_bh; 3328 cmd.arg.noarg = NULL; 3329 3330 ret = sync_command(&cmd); 3331 3332 command_deinit(&cmd); 3333 3334 return ret; 3335} 3336 3337void 3338player_speaker_enumerate(spk_enum_cb cb, void *arg) 3339{ 3340 struct player_command cmd; 3341 struct spk_enum spk_enum; 3342 3343 command_init(&cmd); 3344 3345 spk_enum.cb = cb; 3346 spk_enum.arg = arg; 3347 3348 cmd.func = speaker_enumerate; 3349 cmd.func_bh = NULL; 3350 cmd.arg.spk_enum = &spk_enum; 3351 3352 sync_command(&cmd); 3353 3354 command_deinit(&cmd); 3355} 3356 3357int 3358player_speaker_set(uint64_t *ids) 3359{ 3360 struct player_command cmd; 3361 int ret; 3362 3363 command_init(&cmd); 3364 3365 cmd.func = speaker_set; 3366 cmd.func_bh = NULL; 3367 cmd.arg.raop_ids = ids; 3368 3369 ret = sync_command(&cmd); 3370 3371 command_deinit(&cmd); 3372 3373 return ret; 3374} 3375 3376int 3377player_volume_set(int vol) 3378{ 3379 struct player_command cmd; 3380 int ret; 3381 3382 command_init(&cmd); 3383 3384 cmd.func = volume_set; 3385 cmd.func_bh = NULL; 3386 cmd.arg.intval = vol; 3387 3388 ret = sync_command(&cmd); 3389 3390 command_deinit(&cmd); 3391 3392 return ret; 3393} 3394 3395int 3396player_volume_setrel_speaker(uint64_t id, int relvol) 3397{ 3398 struct player_command cmd; 3399 int ret; 3400 3401 command_init(&cmd); 3402 3403 cmd.func = volume_setrel_speaker; 3404 cmd.func_bh = NULL; 3405 cmd.arg.vol_param.spk_id = id; 3406 cmd.arg.vol_param.volume = relvol; 3407 3408 ret = sync_command(&cmd); 3409 3410 command_deinit(&cmd); 3411 3412 return ret; 3413} 3414 3415int 3416player_volume_setabs_speaker(uint64_t id, int vol) 3417{ 3418 struct player_command cmd; 3419 int ret; 3420 3421 command_init(&cmd); 3422 3423 cmd.func = volume_setabs_speaker; 3424 cmd.func_bh = NULL; 3425 cmd.arg.vol_param.spk_id = id; 3426 cmd.arg.vol_param.volume = vol; 3427 3428 ret = sync_command(&cmd); 3429 3430 command_deinit(&cmd); 3431 3432 return ret; 3433} 3434 3435int 3436player_repeat_set(enum repeat_mode mode) 3437{ 3438 struct player_command cmd; 3439 int ret; 3440 3441 command_init(&cmd); 3442 3443 cmd.func = repeat_set; 3444 cmd.func_bh = NULL; 3445 cmd.arg.mode = mode; 3446 3447 ret = sync_command(&cmd); 3448 3449 command_deinit(&cmd); 3450 3451 return ret; 3452} 3453 3454int 3455player_shuffle_set(int enable) 3456{ 3457 struct player_command cmd; 3458 int ret; 3459 3460 command_init(&cmd); 3461 3462 cmd.func = shuffle_set; 3463 cmd.func_bh = NULL; 3464 cmd.arg.intval = enable; 3465 3466 ret = sync_command(&cmd); 3467 3468 command_deinit(&cmd); 3469 3470 return ret; 3471} 3472 3473int 3474player_queue_add(struct player_source *ps) 3475{ 3476 struct player_command cmd; 3477 int ret; 3478 3479 command_init(&cmd); 3480 3481 cmd.func = queue_add; 3482 cmd.func_bh = NULL; 3483 cmd.arg.ps = ps; 3484 3485 ret = sync_command(&cmd); 3486 3487 command_deinit(&cmd); 3488 3489 return ret; 3490} 3491 3492void 3493player_queue_clear(void) 3494{ 3495 struct player_command cmd; 3496 3497 command_init(&cmd); 3498 3499 cmd.func = queue_clear; 3500 cmd.func_bh = NULL; 3501 cmd.arg.noarg = NULL; 3502 3503 sync_command(&cmd); 3504 3505 command_deinit(&cmd); 3506} 3507 3508void 3509player_queue_plid(uint32_t plid) 3510{ 3511 struct player_command cmd; 3512 3513 command_init(&cmd); 3514 3515 cmd.func = queue_plid; 3516 cmd.func_bh = NULL; 3517 cmd.arg.id = plid; 3518 3519 sync_command(&cmd); 3520 3521 command_deinit(&cmd); 3522} 3523 3524void 3525player_set_update_handler(player_status_handler handler) 3526{ 3527 struct player_command cmd; 3528 3529 command_init(&cmd); 3530 3531 cmd.func = set_update_handler; 3532 cmd.func_bh = NULL; 3533 cmd.arg.status_handler = handler; 3534 3535 sync_command(&cmd); 3536 3537 command_deinit(&cmd); 3538} 3539 3540/* Non-blocking commands used by mDNS */ 3541static void 3542player_device_add(struct raop_device *rd) 3543{ 3544 struct player_command *cmd; 3545 int ret; 3546 3547 cmd = (struct player_command *)malloc(sizeof(struct player_command)); 3548 if (!cmd) 3549 { 3550 DPRINTF(E_LOG, L_PLAYER, "Could not allocate player_command\n"); 3551 3552 device_free(rd); 3553 return; 3554 } 3555 3556 memset(cmd, 0, sizeof(struct player_command)); 3557 3558 cmd->nonblock = 1; 3559 3560 cmd->func = device_add; 3561 cmd->arg.rd = rd; 3562 3563 ret = nonblock_command(cmd); 3564 if (ret < 0) 3565 { 3566 free(cmd); 3567 device_free(rd); 3568 3569 return; 3570 } 3571} 3572 3573static void 3574player_device_remove(struct raop_device *rd) 3575{ 3576 struct player_command *cmd; 3577 int ret; 3578 3579 cmd = (struct player_command *)malloc(sizeof(struct player_command)); 3580 if (!cmd) 3581 { 3582 DPRINTF(E_LOG, L_PLAYER, "Could not allocate player_command\n"); 3583 3584 device_free(rd); 3585 return; 3586 } 3587 3588 memset(cmd, 0, sizeof(struct player_command)); 3589 3590 cmd->nonblock = 1; 3591 3592 cmd->func = device_remove_family; 3593 cmd->arg.rd = rd; 3594 3595 ret = nonblock_command(cmd); 3596 if (ret < 0) 3597 { 3598 free(cmd); 3599 device_free(rd); 3600 3601 return; 3602 } 3603} 3604 3605 3606/* RAOP devices discovery - mDNS callback */ 3607/* Thread: main (mdns) */ 3608static void 3609raop_device_cb(const char *name, const char *type, const char *domain, const char *hostname, int family, const char *address, int port, struct keyval *txt) 3610{ 3611 struct raop_device *rd; 3612 cfg_t *apex; 3613 const char *p; 3614 char *at_name; 3615 char *password; 3616 uint64_t id; 3617 char has_password; 3618 enum raop_devtype devtype; 3619 int ret; 3620 3621 ret = safe_hextou64(name, &id); 3622 if (ret < 0) 3623 { 3624 DPRINTF(E_LOG, L_PLAYER, "Could not extract AirTunes device ID (%s)\n", name); 3625 3626 return; 3627 } 3628 3629 at_name = strchr(name, '@'); 3630 if (!at_name) 3631 { 3632 DPRINTF(E_LOG, L_PLAYER, "Could not extract AirTunes device name (%s)\n", name); 3633 3634 return; 3635 } 3636 at_name++; 3637 3638 DPRINTF(E_DBG, L_PLAYER, "Event for AirTunes device %" PRIx64 "/%s (%d)\n", id, at_name, port); 3639 3640 rd = (struct raop_device *)malloc(sizeof(struct raop_device)); 3641 if (!rd) 3642 { 3643 DPRINTF(E_LOG, L_PLAYER, "Out of memory for new AirTunes device\n"); 3644 3645 return; 3646 } 3647 3648 memset(rd, 0, sizeof(struct raop_device)); 3649 3650 rd->id = id; 3651 rd->name = strdup(at_name); 3652 3653 if (port < 0) 3654 { 3655 /* Device stopped advertising */ 3656 switch (family) 3657 { 3658 case AF_INET: 3659 rd->v4_port = 1; 3660 break; 3661 3662 case AF_INET6: 3663 rd->v6_port = 1; 3664 break; 3665 } 3666 3667 player_device_remove(rd); 3668 3669 return; 3670 } 3671 3672 p = keyval_get(txt, "tp"); 3673 if (!p) 3674 { 3675 DPRINTF(E_LOG, L_PLAYER, "AirTunes %s: no tp field in TXT record!\n", name); 3676 3677 goto free_rd; 3678 } 3679 3680 if (*p == '\0') 3681 { 3682 DPRINTF(E_LOG, L_PLAYER, "AirTunes %s: tp has no value\n", name); 3683 3684 goto free_rd; 3685 } 3686 3687 if (!strstr(p, "UDP")) 3688 { 3689 DPRINTF(E_LOG, L_PLAYER, "AirTunes %s: device does not support AirTunes v2 (tp=%s), discarding\n", name, p); 3690 3691 goto free_rd; 3692 } 3693 3694 password = NULL; 3695 p = keyval_get(txt, "pw"); 3696 if (!p) 3697 { 3698 DPRINTF(E_INFO, L_PLAYER, "AirTunes %s: no pw field in TXT record, assuming no password protection\n", name); 3699 has_password = 0; 3700 } 3701 else if (*p == '\0') 3702 { 3703 DPRINTF(E_LOG, L_PLAYER, "AirTunes %s: pw has no value\n", name); 3704 3705 goto free_rd; 3706 } 3707 else 3708 { 3709 has_password = (strcmp(p, "false") != 0); 3710 } 3711 3712 if (has_password) 3713 { 3714 DPRINTF(E_LOG, L_PLAYER, "AirTunes device %s is password-protected\n", name); 3715 3716 apex = cfg_gettsec(cfg, "apex", at_name); 3717 if (apex) 3718 password = cfg_getstr(apex, "password"); 3719 3720 if (!password) 3721 DPRINTF(E_LOG, L_PLAYER, "No password given in config for AirTunes device %s\n", name); 3722 } 3723 3724 devtype = RAOP_DEV_APEX_80211N; 3725 3726 p = keyval_get(txt, "am"); 3727 if (!p) 3728 { 3729 DPRINTF(E_LOG, L_PLAYER, "AirTunes %s: no am field in TXT record!\n", name); 3730 3731 /* Old AirPort Express */ 3732 devtype = RAOP_DEV_APEX_80211G; 3733 3734 goto no_am; 3735 } 3736 3737 if (*p == '\0') 3738 { 3739 DPRINTF(E_LOG, L_PLAYER, "AirTunes %s: am has no value\n", name); 3740 3741 goto no_am; 3742 } 3743 3744 if (strncmp(p, "AppleTV", strlen("AppleTV")) == 0) 3745 devtype = RAOP_DEV_APPLETV; 3746 else if (strncmp(p, "AirPort4", strlen("AirPort4")) != 0) 3747 devtype = OTHER; 3748 3749 no_am: 3750 DPRINTF(E_DBG, L_PLAYER, "AirTunes device %s: password: %s, type %s\n", name, (password) ? "yes" : "no", raop_devtype[devtype]); 3751 3752 rd->advertised = 1; 3753 3754 switch (family) 3755 { 3756 case AF_INET: 3757 rd->v4_address = strdup(address); 3758 rd->v4_port = port; 3759 break; 3760 3761 case AF_INET6: 3762 rd->v6_address = strdup(address); 3763 rd->v6_port = port; 3764 break; 3765 } 3766 3767 rd->devtype = devtype; 3768 3769 rd->has_password = has_password; 3770 rd->password = password; 3771 3772 player_device_add(rd); 3773 3774 return; 3775 3776 free_rd: 3777 device_free(rd); 3778} 3779 3780/* Thread: player */ 3781static void * 3782player(void *arg) 3783{ 3784 struct raop_device *rd; 3785 int ret; 3786 3787 ret = db_perthread_init(); 3788 if (ret < 0) 3789 { 3790 DPRINTF(E_LOG, L_PLAYER, "Error: DB init failed\n"); 3791 3792 pthread_exit(NULL); 3793 } 3794 3795 event_base_dispatch(evbase_player); 3796 3797 if (!player_exit) 3798 DPRINTF(E_LOG, L_PLAYER, "Player event loop terminated ahead of time!\n"); 3799 3800 /* Save selected devices */ 3801 db_speaker_clear_all(); 3802 3803 ret = db_speaker_save(0, laudio_selected, laudio_volume); 3804 if (ret < 0) 3805 DPRINTF(E_LOG, L_PLAYER, "Could not save state for local audio\n"); 3806 3807 for (rd = dev_list; rd; rd = rd->next) 3808 { 3809 ret = db_speaker_save(rd->id, rd->selected, rd->volume); 3810 if (ret < 0) 3811 DPRINTF(E_LOG, L_PLAYER, "Could not save state for speaker %s\n", rd->name); 3812 } 3813 3814 db_perthread_deinit(); 3815 3816 pthread_exit(NULL); 3817} 3818 3819/* Thread: player */ 3820static void 3821exit_cb(int fd, short what, void *arg) 3822{ 3823 event_base_loopbreak(evbase_player); 3824 3825 player_exit = 1; 3826} 3827 3828/* Thread: main */ 3829int 3830player_init(void) 3831{ 3832 uint32_t rnd; 3833 int raop_v6enabled; 3834 int mdns_flags; 3835 int ret; 3836 3837 player_exit = 0; 3838 3839 dev_autoselect = 1; 3840 dev_list = NULL; 3841 3842 master_volume = -1; 3843 laudio_enabled = 0; 3844 3845// laudio_enabled = cfg_getbool(cfg_getsec(cfg, "general"), "laudio_enable"); 3846// laudio_enabled = 1; 3847 laudio_selected = 0; 3848 laudio_status = LAUDIO_CLOSED; 3849 raop_sessions = 0; 3850 3851 cur_cmd = NULL; 3852 3853 pb_timer_fd = -1; 3854 3855 source_head = NULL; 3856 shuffle_head = NULL; 3857 cur_playing = NULL; 3858 cur_streaming = NULL; 3859 cur_plid = 0; 3860 3861 player_state = PLAY_STOPPED; 3862 repeat = REPEAT_OFF; 3863 shuffle = 0; 3864 3865 update_handler = NULL; 3866 3867 /* Random RTP time start */ 3868 gcry_randomize(&rnd, sizeof(rnd), GCRY_STRONG_RANDOM); 3869 last_rtptime = ((uint64_t)1 << 32) | rnd; 3870 3871 rng_init(&shuffle_rng); 3872 3873 ret = db_speaker_get(0, &laudio_selected, &laudio_volume); 3874 if (ret < 0) 3875 laudio_volume = 75; 3876 else if (laudio_selected) 3877 speaker_select_laudio(); /* Run the select helper */ 3878 3879 audio_buf = evbuffer_new(); 3880 if (!audio_buf) 3881 { 3882 DPRINTF(E_LOG, L_PLAYER, "Could not allocate evbuffer for audio buffer\n"); 3883 3884 return -1; 3885 } 3886 3887 raop_v6enabled = cfg_getbool(cfg_getsec(cfg, "general"), "ipv6"); 3888 3889 3890#ifdef USE_EVENTFD 3891 exit_efd = eventfd(0, EFD_CLOEXEC); 3892 if (exit_efd < 0) 3893 { 3894 DPRINTF(E_LOG, L_PLAYER, "Could not create eventfd: %s\n", strerror(errno)); 3895 3896 goto exit_fail; 3897 } 3898#else 3899# if defined(__linux__) 3900 ret = pipe2(exit_pipe, O_CLOEXEC); 3901# else 3902 ret = pipe(exit_pipe); 3903# endif 3904 if (ret < 0) 3905 { 3906 DPRINTF(E_LOG, L_PLAYER, "Could not create pipe: %s\n", strerror(errno)); 3907 3908 goto exit_fail; 3909 } 3910#endif /* USE_EVENTFD */ 3911 3912# if defined(__linux__) 3913 ret = pipe2(cmd_pipe, O_CLOEXEC); 3914# else 3915 ret = pipe(cmd_pipe); 3916# endif 3917 if (ret < 0) 3918 { 3919 DPRINTF(E_LOG, L_PLAYER, "Could not create command pipe: %s\n", strerror(errno)); 3920 3921 goto cmd_fail; 3922 } 3923 3924 evbase_player = event_base_new(); 3925 if (!evbase_player) 3926 { 3927 DPRINTF(E_LOG, L_PLAYER, "Could not create an event base\n"); 3928 3929 goto evbase_fail; 3930 } 3931 3932#ifdef USE_EVENTFD 3933 event_set(&exitev, exit_efd, EV_READ, exit_cb, NULL); 3934#else 3935 event_set(&exitev, exit_pipe[0], EV_READ, exit_cb, NULL); 3936#endif 3937 event_base_set(evbase_player, &exitev); 3938 event_add(&exitev, NULL); 3939 3940 event_set(&cmdev, cmd_pipe[0], EV_READ, command_cb, NULL); 3941 event_base_set(evbase_player, &cmdev); 3942 event_add(&cmdev, NULL); 3943 3944 ret = laudio_init(player_laudio_status_cb); 3945 if (ret < 0) 3946 { 3947 DPRINTF(E_LOG, L_PLAYER, "Local audio init failed\n"); 3948 3949 goto laudio_fail; 3950 } 3951 3952 ret = raop_init(&raop_v6enabled); 3953 if (ret < 0) 3954 { 3955 DPRINTF(E_LOG, L_PLAYER, "RAOP init failed\n"); 3956 3957 goto raop_fail; 3958 } 3959 3960 if (raop_v6enabled) 3961 mdns_flags = MDNS_WANT_V4 | MDNS_WANT_V6 | MDNS_WANT_V6LL; 3962 else 3963 mdns_flags = MDNS_WANT_V4; 3964 3965 ret = mdns_browse("_raop._tcp", mdns_flags, raop_device_cb); 3966 if (ret < 0) 3967 { 3968 DPRINTF(E_FATAL, L_PLAYER, "Could not add mDNS browser for AirTunes devices\n"); 3969 3970 goto mdns_browse_fail; 3971 } 3972 3973 ret = pthread_create(&tid_player, NULL, player, NULL); 3974 if (ret < 0) 3975 { 3976 DPRINTF(E_LOG, L_PLAYER, "Could not spawn player thread: %s\n", strerror(errno)); 3977 3978 goto thread_fail; 3979 } 3980 3981 return 0; 3982 3983 thread_fail: 3984 mdns_browse_fail: 3985 raop_deinit(); 3986 raop_fail: 3987 laudio_deinit(); 3988 laudio_fail: 3989 event_base_free(evbase_player); 3990 evbase_fail: 3991 close(cmd_pipe[0]); 3992 close(cmd_pipe[1]); 3993 cmd_fail: 3994#ifdef USE_EVENTFD 3995 close(exit_efd); 3996#else 3997 close(exit_pipe[0]); 3998 close(exit_pipe[1]); 3999#endif 4000 exit_fail: 4001 evbuffer_free(audio_buf); 4002 4003 return -1; 4004} 4005 4006/* Thread: main */ 4007void 4008player_deinit(void) 4009{ 4010 int ret; 4011 4012#ifdef USE_EVENTFD 4013 ret = eventfd_write(exit_efd, 1); 4014 if (ret < 0) 4015 { 4016 DPRINTF(E_LOG, L_PLAYER, "Could not send exit event: %s\n", strerror(errno)); 4017 4018 return; 4019 } 4020#else 4021 int dummy = 42; 4022 4023 ret = write(exit_pipe[1], &dummy, sizeof(dummy)); 4024 if (ret != sizeof(dummy)) 4025 { 4026 DPRINTF(E_LOG, L_PLAYER, "Could not write to exit fd: %s\n", strerror(errno)); 4027 4028 return; 4029 } 4030#endif 4031 4032 ret = pthread_join(tid_player, NULL); 4033 if (ret != 0) 4034 { 4035 DPRINTF(E_LOG, L_PLAYER, "Could not join HTTPd thread: %s\n", strerror(errno)); 4036 4037 return; 4038 } 4039 4040 if (source_head) 4041 queue_clear(NULL); 4042 4043 evbuffer_free(audio_buf); 4044 4045 laudio_deinit(); 4046 raop_deinit(); 4047 4048 if (event_initialized(&pb_timer_ev)) 4049 event_del(&pb_timer_ev); 4050 4051 event_del(&cmdev); 4052 4053#ifdef USE_EVENTFD 4054 close(exit_efd); 4055#else 4056 close(exit_pipe[0]); 4057 close(exit_pipe[1]); 4058#endif 4059 close(cmd_pipe[0]); 4060 close(cmd_pipe[1]); 4061 cmd_pipe[0] = -1; 4062 cmd_pipe[1] = -1; 4063 event_base_free(evbase_player); 4064} 4065