Merge osxmods into 2.1
This commit is contained in:
@@ -421,12 +421,12 @@ double vol2attn(double vol, long max_db, long min_db) {
|
||||
return vol_setting;
|
||||
}
|
||||
|
||||
uint64_t get_absolute_time_in_ns() {
|
||||
uint64_t time_now_ns;
|
||||
uint64_t get_absolute_time_in_fp() {
|
||||
uint64_t time_now_fp;
|
||||
#ifdef COMPILE_FOR_LINUX
|
||||
struct timespec tn;
|
||||
clock_gettime(CLOCK_MONOTONIC,&tn);
|
||||
time_now_ns=((uint64_t)tn.tv_sec<<32)+((uint64_t)tn.tv_nsec<<32)/1000000000;
|
||||
time_now_fp=((uint64_t)tn.tv_sec<<32)+((uint64_t)tn.tv_nsec<<32)/1000000000;
|
||||
#endif
|
||||
#ifdef COMPILE_FOR_OSX
|
||||
uint64_t time_now_mach;
|
||||
@@ -438,7 +438,7 @@ uint64_t get_absolute_time_in_ns() {
|
||||
// If this is the first time we've run, get the timebase.
|
||||
// We can use denom == 0 to indicate that sTimebaseInfo is
|
||||
// uninitialised because it makes no sense to have a zero
|
||||
// denominator is a fraction.
|
||||
// denominator in a fraction.
|
||||
|
||||
if ( sTimebaseInfo.denom == 0 ) {
|
||||
debug(1,"Mac initialise timebase info.");
|
||||
@@ -448,12 +448,13 @@ uint64_t get_absolute_time_in_ns() {
|
||||
// Do the maths. We hope that the multiplication doesn't
|
||||
// overflow; the price you pay for working in fixed point.
|
||||
|
||||
// need to turn this into NTP 64-bit fixed point format
|
||||
// and change the very misleading title of this function to
|
||||
// get_absolute_fp_time or something
|
||||
time_now_ns = time_now_mach * sTimebaseInfo.numer / sTimebaseInfo.denom;
|
||||
// this gives us nanoseconds
|
||||
uint64_t time_now_ns = time_now_mach * sTimebaseInfo.numer / sTimebaseInfo.denom;
|
||||
|
||||
// take the units and shift them to the upper half of the fp, and take the nanoseconds, shift them to the upper half and then divide the result to 1000000000
|
||||
time_now_fp = ((time_now_ns/1000000000)<<32) + (((time_now_ns%1000000000)<<32)/1000000000);
|
||||
|
||||
#endif
|
||||
return time_now_ns;
|
||||
return time_now_fp;
|
||||
}
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ double vol2attn(double vol, long max_db, long min_db);
|
||||
|
||||
// return a monolithic (always increasing) time in nanoseconds
|
||||
|
||||
uint64_t get_absolute_time_in_ns(void);
|
||||
uint64_t get_absolute_time_in_fp(void);
|
||||
|
||||
shairport_cfg config;
|
||||
|
||||
|
||||
+18
-3
@@ -7,24 +7,39 @@ AM_INIT_AUTOMAKE
|
||||
AC_CONFIG_SRCDIR([shairport.c])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
|
||||
# Derived from the Avahi configure.ac file
|
||||
#
|
||||
# Specifying the OS type, defaulting to linux.
|
||||
#
|
||||
AC_ARG_WITH(os_type, AS_HELP_STRING([--with-os-type=OSType],[Specify the distribution to target: One of linux darwin]))
|
||||
if test "z$with_os_type" = "z"; then
|
||||
with_os_type="linux"
|
||||
fi
|
||||
with_os_type=`echo ${with_os_type} | tr '[[:upper:]]' '[[:lower:]]' `
|
||||
|
||||
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
|
||||
# Checks for libraries.
|
||||
AC_CHECK_LIB([rt],[clock_gettime], , AC_MSG_ERROR(librt needed))
|
||||
if test "x${with_os_type}" = xlinux; then
|
||||
AC_CHECK_LIB([rt],[clock_gettime], , AC_MSG_ERROR(librt needed))
|
||||
fi
|
||||
|
||||
AC_CHECK_LIB([daemon],[daemon_log], , AC_MSG_ERROR(libdaemon needed))
|
||||
AC_CHECK_LIB([pthread],[pthread_create], , AC_MSG_ERROR(pthread library needed))
|
||||
AC_CHECK_LIB([m],[exp], , AC_MSG_ERROR(maths library needed))
|
||||
AC_CHECK_LIB([popt],[poptGetContext], , AC_MSG_ERROR(libpopt needed))
|
||||
|
||||
# Look for polarssl flag
|
||||
AC_ARG_WITH(polarssl, [ --with-polarssl = choose polarssl for encryption services (choose this or openssl)], [
|
||||
AC_ARG_WITH(polarssl, [ --with-polarssl = choose polarssl for encryption services (choose this or --with-openssl)], [
|
||||
AC_MSG_RESULT(>>Including polarssl)
|
||||
AC_CHECK_LIB([polarssl],[ssl_init], , AC_MSG_ERROR(PolarSSL selected but the library cannot be found!))], )
|
||||
|
||||
# Look for openssl flag
|
||||
AC_ARG_WITH(openssl, [ --with-openssl = choose openssl for encryption services (choose this or polarssl)], [
|
||||
AC_ARG_WITH(openssl, [ --with-openssl = choose openssl for encryption services (choose this or --with-polarssl)], [
|
||||
AC_MSG_RESULT(>>Including openssl and libcrypto)
|
||||
AC_CHECK_LIB([crypto], [MD5_Init], , AC_MSG_ERROR(libcrypto selected, but the library cannot be found!))
|
||||
AC_CHECK_LIB([ssl],[SSL_library_init], , AC_MSG_ERROR(openssl selected but the library cannot be found!))], )
|
||||
|
||||
@@ -35,25 +35,25 @@
|
||||
|
||||
#ifdef CONFIG_AVAHI
|
||||
extern mdns_backend mdns_avahi;
|
||||
#endif
|
||||
|
||||
extern mdns_backend mdns_external_avahi;
|
||||
extern mdns_backend mdns_external_dns_sd;
|
||||
extern mdns_backend mdns_tinysvcmdns;
|
||||
|
||||
#endif
|
||||
#ifdef CONFIG_HAVE_DNS_SD_H
|
||||
extern mdns_backend mdns_dns_sd;
|
||||
extern mdns_backend mdns_external_dns_sd;
|
||||
#endif
|
||||
#ifdef CONFIG_TINYSVCMDNS
|
||||
extern mdns_backend mdns_tinysvcmdns;
|
||||
#endif
|
||||
|
||||
static mdns_backend *mdns_backends[] = {
|
||||
#ifdef CONFIG_AVAHI
|
||||
&mdns_avahi,
|
||||
&mdns_external_avahi,
|
||||
#endif
|
||||
#ifdef CONFIG_HAVE_DNS_SD_H
|
||||
&mdns_dns_sd,
|
||||
#endif
|
||||
&mdns_external_avahi,
|
||||
&mdns_external_dns_sd,
|
||||
#endif
|
||||
#ifdef CONFIG_TINYSVCMDNS
|
||||
&mdns_tinysvcmdns,
|
||||
#endif
|
||||
|
||||
@@ -162,6 +162,13 @@ static inline seq_t SUCCESSOR(seq_t x) {
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline seq_t PREDECESSOR(seq_t x) {
|
||||
uint32_t p = (x & 0xffff)+0x10000;
|
||||
p-=1;
|
||||
p = p & 0xffff;
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline uint32_t ORDINATE(seq_t x) {
|
||||
uint32_t p = x & 0xffff;
|
||||
uint32_t q = ab_read & 0x0ffff;
|
||||
@@ -170,7 +177,7 @@ static inline uint32_t ORDINATE(seq_t x) {
|
||||
}
|
||||
|
||||
// wrapped number between two seq_t.
|
||||
inline int32_t seq_diff(seq_t a, seq_t b) {
|
||||
int32_t seq_diff(seq_t a, seq_t b) {
|
||||
int32_t diff = ORDINATE(b) - ORDINATE(a);
|
||||
return diff;
|
||||
}
|
||||
@@ -182,6 +189,13 @@ static inline int seq_order(seq_t a, seq_t b) {
|
||||
return d > 0;
|
||||
}
|
||||
|
||||
static inline seq_t seq_sum(seq_t a, seq_t b) {
|
||||
uint32_t p = a & 0xffff;
|
||||
uint32_t q = b & 0x0ffff;
|
||||
uint32_t r = (a+b) & 0xffff;
|
||||
return r;
|
||||
}
|
||||
|
||||
static void alac_decode(short *dest, uint8_t *buf, int len) {
|
||||
unsigned char packet[MAX_PACKET];
|
||||
unsigned char packetp[MAX_PACKET];
|
||||
@@ -276,7 +290,7 @@ void player_put_packet(seq_t seqno,uint32_t timestamp, uint8_t *data, int len) {
|
||||
abuf = audio_buffer + BUFIDX(seqno);
|
||||
ab_write = SUCCESSOR(seqno);
|
||||
} else if (seq_order(ab_write, seqno)) { // newer than expected
|
||||
rtp_request_resend(ab_write+1, seqno-1);
|
||||
rtp_request_resend(SUCCESSOR(ab_write), PREDECESSOR(seqno));
|
||||
resend_requests++;
|
||||
abuf = audio_buffer + BUFIDX(seqno);
|
||||
ab_write = SUCCESSOR(seqno);
|
||||
@@ -301,7 +315,7 @@ void player_put_packet(seq_t seqno,uint32_t timestamp, uint8_t *data, int len) {
|
||||
|
||||
pthread_mutex_lock(&ab_mutex);
|
||||
|
||||
time_of_last_audio_packet = get_absolute_time_in_ns();
|
||||
time_of_last_audio_packet = get_absolute_time_in_fp();
|
||||
|
||||
int rc = pthread_cond_signal(&flowcontrol);
|
||||
if (rc)
|
||||
@@ -335,7 +349,6 @@ static abuf_t *buffer_get_frame(void) {
|
||||
int16_t buf_fill;
|
||||
uint64_t local_time_now;
|
||||
// struct timespec tn;
|
||||
seq_t read, next;
|
||||
abuf_t *abuf = 0;
|
||||
int i;
|
||||
abuf_t *curframe;
|
||||
@@ -345,7 +358,7 @@ static abuf_t *buffer_get_frame(void) {
|
||||
int32_t dac_delay = 0;
|
||||
do {
|
||||
// get the time
|
||||
local_time_now = get_absolute_time_in_ns();
|
||||
local_time_now = get_absolute_time_in_fp();
|
||||
|
||||
// if config.timeout (default 120) seconds have elapsed since the last audio packet was received, then we should stop.
|
||||
// config.timeout of zero means don't check..., but iTunes may be confused by a long gap followed by a resumption...
|
||||
@@ -384,7 +397,7 @@ static abuf_t *buffer_get_frame(void) {
|
||||
if ((flush_rtp_timestamp) && (flush_rtp_timestamp>=curframe->timestamp)) {
|
||||
// debug(1,"Dropping flushed packet %d",curframe->sequence_number);
|
||||
curframe->ready=0;
|
||||
ab_read++;
|
||||
ab_read==SUCCESSOR(ab_read);
|
||||
} else if (ab_buffering) { // if we are getting packets but not yet forwarding them to the player
|
||||
if (first_packet_timestamp==0) { // if this is the very first packet
|
||||
// debug(1,"First frame seen, time %u, with %d frames...",curframe->timestamp,seq_diff(ab_read, ab_write));
|
||||
@@ -480,8 +493,8 @@ static abuf_t *buffer_get_frame(void) {
|
||||
// debug(1,"pthread_cond_timedwait returned error code %d.",rc);
|
||||
#endif
|
||||
#ifdef COMPILE_FOR_OSX
|
||||
uint64_t sec = time_to_wait_for_wakeup_ns>>32;;
|
||||
uint64_t nsec = ((time_to_wait_for_wakeup_ns&0xffffffff)*1000000000)>>32;
|
||||
uint64_t sec = time_to_wait_for_wakeup_fp>>32;;
|
||||
uint64_t nsec = ((time_to_wait_for_wakeup_fp&0xffffffff)*1000000000)>>32;
|
||||
struct timespec time_to_wait;
|
||||
time_to_wait.tv_sec = sec;
|
||||
time_to_wait.tv_nsec = nsec;
|
||||
@@ -495,15 +508,15 @@ static abuf_t *buffer_get_frame(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
read = ab_read;
|
||||
ab_read++;
|
||||
seq_t read = ab_read;
|
||||
ab_read=SUCCESSOR(ab_read);
|
||||
|
||||
// check if t+16, t+32, t+64, t+128, ... (buffer_start_fill / 2)
|
||||
// packets have arrived... last-chance resend
|
||||
|
||||
if (!ab_buffering) {
|
||||
for (i = 16; i < (seq_diff(ab_read,ab_write) / 2); i = (i * 2)) {
|
||||
next = ab_read + i;
|
||||
seq_t next = seq_sum(ab_read,i);
|
||||
abuf = audio_buffer + BUFIDX(next);
|
||||
if (!abuf->ready) {
|
||||
rtp_request_resend(next, next);
|
||||
@@ -691,6 +704,7 @@ static void *player_thread_func(void *arg) {
|
||||
if (inframe) {
|
||||
inbuf = inframe->data;
|
||||
if (inbuf) {
|
||||
play_number++;
|
||||
// if it's a supplied silent frame, let us know...
|
||||
if (inframe->timestamp==0) {
|
||||
// debug(1,"Player has a supplied silent frame.");
|
||||
@@ -710,7 +724,7 @@ static void *player_thread_func(void *arg) {
|
||||
rt = reference_timestamp;
|
||||
nt = inframe->timestamp;
|
||||
|
||||
uint64_t local_time_now = get_absolute_time_in_ns();
|
||||
uint64_t local_time_now = get_absolute_time_in_fp();
|
||||
//struct timespec tn;
|
||||
//clock_gettime(CLOCK_MONOTONIC,&tn);
|
||||
//uint64_t local_time_now=((uint64_t)tn.tv_sec<<32)+((uint64_t)tn.tv_nsec<<32)/1000000000;
|
||||
@@ -865,20 +879,18 @@ static void *player_thread_func(void *arg) {
|
||||
if (inframe->sequence_number!=last_seqno_read)
|
||||
debug(1,"Player: packets out of sequence: expected: %d, got %d.",last_seqno_read,inframe->sequence_number);
|
||||
last_seqno_read=inframe->sequence_number; // reset warning...
|
||||
}
|
||||
|
||||
if (play_number%print_interval==0) {
|
||||
// we can now calculate running averages for sync error (frames), corrections (ppm), insertions plus deletions (ppm), drift (ppm)
|
||||
double moving_average_sync_error = (1.0*tsum_of_sync_errors)/number_of_statistics;
|
||||
double moving_average_correction = (1.0*tsum_of_corrections)/number_of_statistics;
|
||||
double moving_average_insertions_plus_deletions = (1.0*tsum_of_insertions_and_deletions)/number_of_statistics;
|
||||
double moving_average_drift = (1.0*tsum_of_drifts)/number_of_statistics;
|
||||
uint64_t clock_jitter = ((local_to_remote_time_jitters/local_to_remote_time_jitters_count)*1000000)>>32;
|
||||
// if ((play_number/print_interval)%20==0)
|
||||
debug(1,"Sync error: %.1f (frames); net correction: %.1f (ppm); corrections: %.1f (ppm); missing packets %llu; late packets %llu; too late packets %llu; resend requests %llu; min DAC queue size %lli.", moving_average_sync_error, moving_average_correction*1000000/352, moving_average_insertions_plus_deletions*1000000/352,missing_packets,late_packets,too_late_packets,resend_requests,minimum_dac_queue_size);
|
||||
minimum_dac_queue_size=1000000; // hack reset
|
||||
}
|
||||
}
|
||||
if (play_number%print_interval==0) {
|
||||
// we can now calculate running averages for sync error (frames), corrections (ppm), insertions plus deletions (ppm), drift (ppm)
|
||||
double moving_average_sync_error = (1.0*tsum_of_sync_errors)/number_of_statistics;
|
||||
double moving_average_correction = (1.0*tsum_of_corrections)/number_of_statistics;
|
||||
double moving_average_insertions_plus_deletions = (1.0*tsum_of_insertions_and_deletions)/number_of_statistics;
|
||||
double moving_average_drift = (1.0*tsum_of_drifts)/number_of_statistics;
|
||||
// if ((play_number/print_interval)%20==0)
|
||||
debug(1,"Sync error: %.1f (frames); net correction: %.1f (ppm); corrections: %.1f (ppm); missing packets %llu; late packets %llu; too late packets %llu; resend requests %llu; min DAC queue size %lli.", moving_average_sync_error, moving_average_correction*1000000/352, moving_average_insertions_plus_deletions*1000000/352,missing_packets,late_packets,too_late_packets,resend_requests,minimum_dac_queue_size);
|
||||
minimum_dac_queue_size=1000000; // hack reset
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ typedef struct {
|
||||
typedef uint16_t seq_t;
|
||||
|
||||
// wrapped number between two seq_t.
|
||||
inline int32_t seq_diff(seq_t a, seq_t b);
|
||||
int32_t seq_diff(seq_t a, seq_t b);
|
||||
|
||||
int player_play(stream_cfg *cfg);
|
||||
void player_stop(void);
|
||||
|
||||
@@ -32,8 +32,10 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "player.h"
|
||||
@@ -153,7 +155,7 @@ static void *rtp_control_receiver(void *arg) {
|
||||
if (please_shutdown)
|
||||
break;
|
||||
nread = recv(control_socket, packet, sizeof(packet), 0);
|
||||
local_time_now=get_absolute_time_in_ns();
|
||||
local_time_now=get_absolute_time_in_fp();
|
||||
// clock_gettime(CLOCK_MONOTONIC,&tn);
|
||||
// local_time_now=((uint64_t)tn.tv_sec<<32)+((uint64_t)tn.tv_nsec<<32)/1000000000;
|
||||
|
||||
@@ -245,8 +247,16 @@ static void *rtp_timing_sender(void *arg) {
|
||||
req.origin = req.receive = req.transmit=0;
|
||||
|
||||
// clock_gettime(CLOCK_MONOTONIC,&dtt);
|
||||
departure_time=get_absolute_time_in_ns();
|
||||
sendto(timing_socket, &req, sizeof(req), 0, (struct sockaddr*)&rtp_client_timing_socket, sizeof(rtp_client_timing_socket));
|
||||
departure_time=get_absolute_time_in_fp();
|
||||
socklen_t msgsize = sizeof(struct sockaddr_in);
|
||||
#ifdef AF_INET6
|
||||
if (rtp_client_timing_socket.SAFAMILY==AF_INET6) {
|
||||
msgsize = sizeof(struct sockaddr_in6);
|
||||
}
|
||||
#endif
|
||||
if (sendto(timing_socket, &req, sizeof(req), 0, (struct sockaddr*)&rtp_client_timing_socket, msgsize)==-1) {
|
||||
perror("Error sendto-ing to timing socket");
|
||||
}
|
||||
request_number++;
|
||||
if (request_number<=4)
|
||||
usleep(500000);
|
||||
@@ -272,7 +282,7 @@ static void *rtp_timing_receiver(void *arg) {
|
||||
if (please_shutdown)
|
||||
break;
|
||||
nread = recv(timing_socket, packet, sizeof(packet), 0);
|
||||
arrival_time=get_absolute_time_in_ns();
|
||||
arrival_time=get_absolute_time_in_fp();
|
||||
// clock_gettime(CLOCK_MONOTONIC,&att);
|
||||
|
||||
if (nread < 0)
|
||||
@@ -319,7 +329,7 @@ static void *rtp_timing_receiver(void *arg) {
|
||||
unsigned int cc;
|
||||
for (cc=time_ping_history-1;cc>0;cc--) {
|
||||
time_pings[cc]=time_pings[cc-1];
|
||||
time_pings[cc].dispersion = (time_pings[cc].dispersion*133)/100; // make the dispersions 'age' by this rational factor
|
||||
time_pings[cc].dispersion = (time_pings[cc].dispersion*133)/100; // make the dispersions 'age' by this rational factor
|
||||
}
|
||||
time_pings[0].local_to_remote_difference = local_time_by_remote_clock-arrival_time;
|
||||
time_pings[0].dispersion = return_time;
|
||||
@@ -335,24 +345,22 @@ static void *rtp_timing_receiver(void *arg) {
|
||||
l2rtd=time_pings[cc].local_to_remote_difference;
|
||||
tld=time_pings[cc].dispersion;
|
||||
}
|
||||
int64_t ji;
|
||||
if (time_ping_count>1) {
|
||||
if (l2rtd>local_to_remote_time_difference) {
|
||||
local_to_remote_time_jitters=local_to_remote_time_jitters+l2rtd-local_to_remote_time_difference;
|
||||
ji = l2rtd-local_to_remote_time_difference;
|
||||
} else {
|
||||
local_to_remote_time_jitters=local_to_remote_time_jitters+local_to_remote_time_difference-l2rtd;
|
||||
ji = - (local_to_remote_time_difference-l2rtd);
|
||||
}
|
||||
local_to_remote_time_jitters_count+=1;
|
||||
}
|
||||
|
||||
// int64_t rtus = (tld*1000000)>>32; int64_t ji = ((local_to_remote_time_jitters/local_to_remote_time_jitters_count)*1000000)>>32; debug(1,"Choosing time difference with dispersion of %lld us with jitter of %lld",rtus,ji);
|
||||
// int64_t rtus = (tld*1000000)>>32; ji = (ji*1000000)>>32; debug(1,"Choosing time difference with dispersion of %lld us with jitter of %lld us",rtus,ji);
|
||||
int64_t ji;
|
||||
|
||||
local_to_remote_time_difference=l2rtd;
|
||||
|
||||
if (time_ping_count>1) {
|
||||
if (l2rtd>local_to_remote_time_difference) {
|
||||
local_to_remote_time_jitters=local_to_remote_time_jitters+l2rtd-local_to_remote_time_difference;
|
||||
ji = l2rtd-local_to_remote_time_difference;
|
||||
} else {
|
||||
local_to_remote_time_jitters=local_to_remote_time_jitters+local_to_remote_time_difference-l2rtd;
|
||||
ji = - (local_to_remote_time_difference-l2rtd);
|
||||
}
|
||||
local_to_remote_time_jitters_count+=1;
|
||||
}
|
||||
// uncomment below to print jitter between client's clock and oour clock
|
||||
// int64_t rtus = (tld*1000000)>>32; ji = (ji*1000000)>>32; debug(1,"Choosing time difference with dispersion of %lld us with delta of %lld us",rtus,ji);
|
||||
|
||||
local_to_remote_time_difference=l2rtd;
|
||||
} else {
|
||||
debug(1, "Timing port -- Unknown RTP packet of type 0x%02X length %d.", packet[1], nread);
|
||||
}
|
||||
@@ -418,37 +426,67 @@ void rtp_setup(SOCKADDR *remote, int cport, int tport, int *lsport, int *lcport,
|
||||
die("rtp_setup called with active stream!");
|
||||
|
||||
debug(2, "rtp_setup: cport=%d tport=%d.", cport, tport);
|
||||
|
||||
// we do our own timing and ignore the timing port.
|
||||
// an audio perfectionist may wish to learn the protocol.
|
||||
|
||||
// print out what we know about the client
|
||||
void *addr;
|
||||
char *ipver;
|
||||
int port;
|
||||
char ipstr[INET6_ADDRSTRLEN];
|
||||
char portstr[20];
|
||||
#ifdef AF_INET6
|
||||
if (remote->SAFAMILY == AF_INET6) {
|
||||
struct sockaddr_in6 *sa6 = (struct sockaddr_in6*)remote;
|
||||
addr = &(sa6->sin6_addr);
|
||||
port = ntohs(sa6->sin6_port);
|
||||
ipver = "IPv6";
|
||||
}
|
||||
#endif
|
||||
if (remote->SAFAMILY == AF_INET) {
|
||||
struct sockaddr_in *sa4 = (struct sockaddr_in*)remote;
|
||||
addr = &(sa4->sin_addr);
|
||||
port = ntohs(sa4->sin_port);
|
||||
ipver = "IPv4";
|
||||
}
|
||||
inet_ntop(remote->SAFAMILY,addr,ipstr,sizeof(ipstr));
|
||||
debug(1,"Connection from %s: %s:%d",ipver,ipstr,port);
|
||||
|
||||
|
||||
|
||||
// set up a the record of the remote's control socket
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *servinfo;
|
||||
|
||||
memset(&rtp_client_control_socket,0,sizeof(rtp_client_control_socket));
|
||||
memset(&hints,0, sizeof hints);
|
||||
hints.ai_family = remote->SAFAMILY;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
snprintf(portstr, 20, "%d", cport);
|
||||
if (getaddrinfo(ipstr,portstr,&hints,&servinfo)!=0)
|
||||
die("Can't get address of client's control port");
|
||||
|
||||
memcpy(&rtp_client_control_socket, remote, sizeof(rtp_client_control_socket));
|
||||
#ifdef AF_INET6
|
||||
if (rtp_client_control_socket.SAFAMILY == AF_INET6) {
|
||||
struct sockaddr_in6 *sa6 = (struct sockaddr_in6*)&rtp_client_control_socket;
|
||||
sa6->sin6_port = htons(cport);
|
||||
} else
|
||||
if (servinfo->ai_family == AF_INET6)
|
||||
memcpy(&rtp_client_control_socket,servinfo->ai_addr,sizeof(struct sockaddr_in6));
|
||||
else
|
||||
#endif
|
||||
{
|
||||
struct sockaddr_in *sa = (struct sockaddr_in*)&rtp_client_control_socket;
|
||||
sa->sin_port = htons(cport);
|
||||
}
|
||||
|
||||
memcpy(&rtp_client_control_socket,servinfo->ai_addr,sizeof(struct sockaddr_in));
|
||||
freeaddrinfo(servinfo);
|
||||
|
||||
// set up a the record of the remote's timing socket
|
||||
|
||||
memcpy(&rtp_client_timing_socket, remote, sizeof(rtp_client_timing_socket));
|
||||
memset(&rtp_client_timing_socket,0,sizeof(rtp_client_timing_socket));
|
||||
memset(&hints,0, sizeof hints);
|
||||
hints.ai_family = remote->SAFAMILY;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
snprintf(portstr, 20, "%d", tport);
|
||||
if (getaddrinfo(ipstr,portstr,&hints,&servinfo)!=0)
|
||||
die("Can't get address of client's timing port");
|
||||
#ifdef AF_INET6
|
||||
if (rtp_client_timing_socket.SAFAMILY == AF_INET6) {
|
||||
struct sockaddr_in6 *sa6 = (struct sockaddr_in6*)&rtp_client_timing_socket;
|
||||
sa6->sin6_port = htons(tport);
|
||||
} else
|
||||
if (servinfo->ai_family == AF_INET6)
|
||||
memcpy(&rtp_client_timing_socket,servinfo->ai_addr,sizeof(struct sockaddr_in6));
|
||||
else
|
||||
#endif
|
||||
{
|
||||
struct sockaddr_in *sa = (struct sockaddr_in*)&rtp_client_timing_socket;
|
||||
sa->sin_port = htons(tport);
|
||||
}
|
||||
memcpy(&rtp_client_timing_socket,servinfo->ai_addr,sizeof(struct sockaddr_in));
|
||||
freeaddrinfo(servinfo);
|
||||
|
||||
// now, we open three sockets -- one for the audio stream, one for the timing and one for the control
|
||||
|
||||
@@ -513,8 +551,15 @@ void rtp_request_resend(seq_t first, seq_t last) {
|
||||
*(unsigned short *)(req+2) = htons(1); // our seqnum
|
||||
*(unsigned short *)(req+4) = htons(first); // missed seqnum
|
||||
*(unsigned short *)(req+6) = htons(last-first+1); // count
|
||||
|
||||
sendto(audio_socket, req, sizeof(req), 0, (struct sockaddr*)&rtp_client_control_socket, sizeof(rtp_client_control_socket));
|
||||
socklen_t msgsize = sizeof(struct sockaddr_in);
|
||||
#ifdef AF_INET6
|
||||
if (rtp_client_timing_socket.SAFAMILY==AF_INET6) {
|
||||
msgsize = sizeof(struct sockaddr_in6);
|
||||
}
|
||||
#endif
|
||||
if (sendto(audio_socket, req, sizeof(req), 0, (struct sockaddr*)&rtp_client_control_socket,msgsize)==-1) {
|
||||
perror("Error sendto-ing to audio socket");
|
||||
}
|
||||
} else {
|
||||
if (!request_sent) {
|
||||
debug(2,"rtp_request_resend called without active stream!");
|
||||
|
||||
@@ -751,23 +751,23 @@ static int rtsp_auth(char **nonce, rtsp_message *req, rtsp_message *resp) {
|
||||
#ifdef HAVE_LIBPOLARSSL
|
||||
md5_context tctx;
|
||||
md5_starts(&tctx);
|
||||
md5_update(&tctx, username, strlen(username));
|
||||
md5_update(&tctx, (const unsigned char *)username, strlen(username));
|
||||
md5_update(&tctx, (unsigned char *) ":", 1);
|
||||
md5_update(&tctx, realm, strlen(realm));
|
||||
md5_update(&tctx, (const unsigned char *)realm, strlen(realm));
|
||||
md5_update(&tctx, (unsigned char *) ":", 1);
|
||||
md5_update(&tctx, config.password, strlen(config.password));
|
||||
md5_update(&tctx, (const unsigned char *)config.password, strlen(config.password));
|
||||
md5_finish(&tctx,digest_urp);
|
||||
md5_starts(&tctx);
|
||||
md5_update(&tctx, req->method, strlen(req->method));
|
||||
md5_update(&tctx, (const unsigned char *)req->method, strlen(req->method));
|
||||
md5_update(&tctx, (unsigned char *) ":", 1);
|
||||
md5_update(&tctx, uri, strlen(uri));
|
||||
md5_update(&tctx, (const unsigned char *)uri, strlen(uri));
|
||||
md5_finish(&tctx,digest_mu);
|
||||
#endif
|
||||
|
||||
int i;
|
||||
unsigned char buf[33];
|
||||
for (i=0; i<16; i++)
|
||||
sprintf(buf + 2*i, "%02X", digest_urp[i]);
|
||||
sprintf((char *)buf + 2*i, "%02X", digest_urp[i]);
|
||||
|
||||
#ifdef HAVE_LIBSSL
|
||||
MD5_Init(&ctx);
|
||||
@@ -786,18 +786,18 @@ static int rtsp_auth(char **nonce, rtsp_message *req, rtsp_message *resp) {
|
||||
md5_starts(&tctx);
|
||||
md5_update(&tctx, buf, 32);
|
||||
md5_update(&tctx, (unsigned char *) ":", 1);
|
||||
md5_update(&tctx, *nonce, strlen(*nonce));
|
||||
md5_update(&tctx, (const unsigned char *)*nonce, strlen(*nonce));
|
||||
md5_update(&tctx, (unsigned char *) ":", 1);
|
||||
for (i=0; i<16; i++)
|
||||
sprintf(buf + 2*i, "%02X", digest_mu[i]);
|
||||
sprintf((char *)buf + 2*i,"%02X", digest_mu[i]);
|
||||
md5_update(&tctx, buf, 32);
|
||||
md5_finish(&tctx,digest_total);
|
||||
#endif
|
||||
|
||||
for (i=0; i<16; i++)
|
||||
sprintf(buf + 2*i, "%02X", digest_total[i]);
|
||||
sprintf((char *)buf + 2*i,"%02X", digest_total[i]);
|
||||
|
||||
if (!strcmp(response, buf))
|
||||
if (!strcmp(response, (const char *)buf))
|
||||
return 0;
|
||||
warn("auth failed");
|
||||
|
||||
@@ -910,7 +910,8 @@ void rtsp_listen_loop(void) {
|
||||
int fd = socket(p->ai_family, p->ai_socktype, IPPROTO_TCP);
|
||||
int yes = 1;
|
||||
|
||||
ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1)
|
||||
perror("setsockopt");
|
||||
|
||||
#ifdef IPV6_V6ONLY
|
||||
// some systems don't support v4 access on v6 sockets, but some do.
|
||||
|
||||
@@ -0,0 +1,209 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
2785806419BB488D00C0B34D /* alac.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = alac.c; sourceTree = "<group>"; };
|
||||
2785806519BB488D00C0B34D /* alac.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = alac.h; sourceTree = "<group>"; };
|
||||
2785806619BB488D00C0B34D /* audio.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = audio.c; sourceTree = "<group>"; };
|
||||
2785806719BB488D00C0B34D /* audio.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = audio.h; sourceTree = "<group>"; };
|
||||
2785806819BB488D00C0B34D /* audio_alsa.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = audio_alsa.c; sourceTree = "<group>"; };
|
||||
2785806919BB488D00C0B34D /* audio_ao.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = audio_ao.c; sourceTree = "<group>"; };
|
||||
2785806A19BB488D00C0B34D /* audio_dummy.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = audio_dummy.c; sourceTree = "<group>"; };
|
||||
2785806B19BB488D00C0B34D /* audio_pipe.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = audio_pipe.c; sourceTree = "<group>"; };
|
||||
2785806C19BB488D00C0B34D /* audio_pulse.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = audio_pulse.c; sourceTree = "<group>"; };
|
||||
2785806D19BB488D00C0B34D /* audio_sndio.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = audio_sndio.c; sourceTree = "<group>"; };
|
||||
2785806E19BB488D00C0B34D /* AUTHORS */ = {isa = PBXFileReference; lastKnownFileType = text; path = AUTHORS; sourceTree = "<group>"; };
|
||||
2785807119BB488D00C0B34D /* common.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = common.c; sourceTree = "<group>"; };
|
||||
2785807219BB488D00C0B34D /* common.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = common.h; sourceTree = "<group>"; };
|
||||
2785807C19BB488D00C0B34D /* configure.ac */ = {isa = PBXFileReference; lastKnownFileType = text; path = configure.ac; sourceTree = "<group>"; };
|
||||
2785807D19BB488D00C0B34D /* COPYING */ = {isa = PBXFileReference; lastKnownFileType = text; path = COPYING; sourceTree = "<group>"; };
|
||||
2785807F19BB488D00C0B34D /* documents */ = {isa = PBXFileReference; lastKnownFileType = folder; path = documents; sourceTree = "<group>"; };
|
||||
2785808019BB488D00C0B34D /* INSTALL */ = {isa = PBXFileReference; lastKnownFileType = text; path = INSTALL; sourceTree = "<group>"; };
|
||||
2785808219BB488D00C0B34D /* LICENSES */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSES; sourceTree = "<group>"; };
|
||||
2785808419BB488D00C0B34D /* Makefile.am */ = {isa = PBXFileReference; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
|
||||
2785808619BB488D00C0B34D /* mdns.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mdns.c; sourceTree = "<group>"; };
|
||||
2785808719BB488D00C0B34D /* mdns.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mdns.h; sourceTree = "<group>"; };
|
||||
2785808819BB488D00C0B34D /* mdns_avahi.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mdns_avahi.c; sourceTree = "<group>"; };
|
||||
2785808919BB488D00C0B34D /* mdns_dns_sd.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mdns_dns_sd.c; sourceTree = "<group>"; };
|
||||
2785808A19BB488D00C0B34D /* mdns_external.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mdns_external.c; sourceTree = "<group>"; };
|
||||
2785808B19BB488D00C0B34D /* mdns_tinysvcmdns.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mdns_tinysvcmdns.c; sourceTree = "<group>"; };
|
||||
2785808D19BB488D00C0B34D /* NEWS */ = {isa = PBXFileReference; lastKnownFileType = text; path = NEWS; sourceTree = "<group>"; };
|
||||
2785808E19BB488D00C0B34D /* player.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = player.c; sourceTree = "<group>"; };
|
||||
2785808F19BB488D00C0B34D /* player.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = player.h; sourceTree = "<group>"; };
|
||||
2785809019BB488D00C0B34D /* README */ = {isa = PBXFileReference; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
|
||||
2785809119BB488D00C0B34D /* README.md */ = {isa = PBXFileReference; lastKnownFileType = text; path = README.md; sourceTree = "<group>"; };
|
||||
2785809219BB488D00C0B34D /* rtp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = rtp.c; sourceTree = "<group>"; };
|
||||
2785809319BB488D00C0B34D /* rtp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = rtp.h; sourceTree = "<group>"; };
|
||||
2785809419BB488D00C0B34D /* rtsp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = rtsp.c; sourceTree = "<group>"; };
|
||||
2785809519BB488D00C0B34D /* rtsp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = rtsp.h; sourceTree = "<group>"; };
|
||||
2785809619BB488D00C0B34D /* scripts */ = {isa = PBXFileReference; lastKnownFileType = folder; path = scripts; sourceTree = "<group>"; };
|
||||
2785809719BB488D00C0B34D /* shairport-sync.xcworkspace */ = {isa = PBXFileReference; lastKnownFileType = wrapper.workspace; path = "shairport-sync.xcworkspace"; sourceTree = "<group>"; };
|
||||
2785809819BB488D00C0B34D /* shairport.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = shairport.c; sourceTree = "<group>"; };
|
||||
2785809A19BB488D00C0B34D /* tinysvcmdns.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = tinysvcmdns.c; sourceTree = "<group>"; };
|
||||
2785809B19BB488D00C0B34D /* tinysvcmdns.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = tinysvcmdns.h; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
2785805919BB488D00C0B34D = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
2785806419BB488D00C0B34D /* alac.c */,
|
||||
2785806519BB488D00C0B34D /* alac.h */,
|
||||
2785806619BB488D00C0B34D /* audio.c */,
|
||||
2785806719BB488D00C0B34D /* audio.h */,
|
||||
2785806819BB488D00C0B34D /* audio_alsa.c */,
|
||||
2785806919BB488D00C0B34D /* audio_ao.c */,
|
||||
2785806A19BB488D00C0B34D /* audio_dummy.c */,
|
||||
2785806B19BB488D00C0B34D /* audio_pipe.c */,
|
||||
2785806C19BB488D00C0B34D /* audio_pulse.c */,
|
||||
2785806D19BB488D00C0B34D /* audio_sndio.c */,
|
||||
2785806E19BB488D00C0B34D /* AUTHORS */,
|
||||
2785807119BB488D00C0B34D /* common.c */,
|
||||
2785807219BB488D00C0B34D /* common.h */,
|
||||
2785807C19BB488D00C0B34D /* configure.ac */,
|
||||
2785807D19BB488D00C0B34D /* COPYING */,
|
||||
2785807F19BB488D00C0B34D /* documents */,
|
||||
2785808019BB488D00C0B34D /* INSTALL */,
|
||||
2785808219BB488D00C0B34D /* LICENSES */,
|
||||
2785808419BB488D00C0B34D /* Makefile.am */,
|
||||
2785808619BB488D00C0B34D /* mdns.c */,
|
||||
2785808719BB488D00C0B34D /* mdns.h */,
|
||||
2785808819BB488D00C0B34D /* mdns_avahi.c */,
|
||||
2785808919BB488D00C0B34D /* mdns_dns_sd.c */,
|
||||
2785808A19BB488D00C0B34D /* mdns_external.c */,
|
||||
2785808B19BB488D00C0B34D /* mdns_tinysvcmdns.c */,
|
||||
2785808D19BB488D00C0B34D /* NEWS */,
|
||||
2785808E19BB488D00C0B34D /* player.c */,
|
||||
2785808F19BB488D00C0B34D /* player.h */,
|
||||
2785809019BB488D00C0B34D /* README */,
|
||||
2785809119BB488D00C0B34D /* README.md */,
|
||||
2785809219BB488D00C0B34D /* rtp.c */,
|
||||
2785809319BB488D00C0B34D /* rtp.h */,
|
||||
2785809419BB488D00C0B34D /* rtsp.c */,
|
||||
2785809519BB488D00C0B34D /* rtsp.h */,
|
||||
2785809619BB488D00C0B34D /* scripts */,
|
||||
2785809719BB488D00C0B34D /* shairport-sync.xcworkspace */,
|
||||
2785809819BB488D00C0B34D /* shairport.c */,
|
||||
2785809A19BB488D00C0B34D /* tinysvcmdns.c */,
|
||||
2785809B19BB488D00C0B34D /* tinysvcmdns.h */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXLegacyTarget section */
|
||||
2785805E19BB488D00C0B34D /* shairport-sync */ = {
|
||||
isa = PBXLegacyTarget;
|
||||
buildArgumentsString = "$(ACTION)";
|
||||
buildConfigurationList = 2785809C19BB488D00C0B34D /* Build configuration list for PBXLegacyTarget "shairport-sync" */;
|
||||
buildPhases = (
|
||||
);
|
||||
buildToolPath = /usr/bin/make;
|
||||
buildWorkingDirectory = "/Users/mike/Documents/git/shairport-sync";
|
||||
dependencies = (
|
||||
);
|
||||
name = "shairport-sync";
|
||||
passBuildSettingsInEnvironment = 1;
|
||||
productName = "shairport-sync";
|
||||
};
|
||||
/* End PBXLegacyTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
2785805A19BB488D00C0B34D /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0510;
|
||||
};
|
||||
buildConfigurationList = 2785805D19BB488D00C0B34D /* Build configuration list for PBXProject "shairport-sync" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = 2785805919BB488D00C0B34D;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
2785805E19BB488D00C0B34D /* shairport-sync */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
2785805B19BB488D00C0B34D /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
2785805C19BB488D00C0B34D /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
2785809D19BB488D00C0B34D /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUGGING_SYMBOLS = YES;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
OTHER_CFLAGS = "";
|
||||
OTHER_LDFLAGS = "";
|
||||
PRODUCT_NAME = "shairport-sync";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
2785809E19BB488D00C0B34D /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
COPY_PHASE_STRIP = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
OTHER_CFLAGS = "";
|
||||
OTHER_LDFLAGS = "";
|
||||
PRODUCT_NAME = "shairport-sync";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
2785805D19BB488D00C0B34D /* Build configuration list for PBXProject "shairport-sync" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
2785805B19BB488D00C0B34D /* Debug */,
|
||||
2785805C19BB488D00C0B34D /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
2785809C19BB488D00C0B34D /* Build configuration list for PBXLegacyTarget "shairport-sync" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
2785809D19BB488D00C0B34D /* Debug */,
|
||||
2785809E19BB488D00C0B34D /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 2785805A19BB488D00C0B34D /* Project object */;
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0510"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "2785805E19BB488D00C0B34D"
|
||||
BuildableName = "shairport-sync"
|
||||
BlueprintName = "shairport-sync"
|
||||
ReferencedContainer = "container:shairport-sync.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
buildConfiguration = "Debug">
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Debug"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
allowLocationSimulation = "NO">
|
||||
<PathRunnable
|
||||
FilePath = "/Users/mike/Documents/git/shairport-sync/shairport-sync">
|
||||
</PathRunnable>
|
||||
<CommandLineArguments>
|
||||
<CommandLineArgument
|
||||
argument = "-v"
|
||||
isEnabled = "YES">
|
||||
</CommandLineArgument>
|
||||
</CommandLineArguments>
|
||||
<AdditionalOptions>
|
||||
<AdditionalOption
|
||||
key = "DYLD_INSERT_LIBRARIES"
|
||||
value = "/usr/lib/libgmalloc.dylib"
|
||||
isEnabled = "YES">
|
||||
</AdditionalOption>
|
||||
<AdditionalOption
|
||||
key = "OBJC_PRINT_EXCEPTIONS"
|
||||
value = "YES"
|
||||
isEnabled = "YES">
|
||||
</AdditionalOption>
|
||||
<AdditionalOption
|
||||
key = "USERBREAK"
|
||||
value = "1"
|
||||
isEnabled = "YES">
|
||||
</AdditionalOption>
|
||||
<AdditionalOption
|
||||
key = "MallocGuardEdges"
|
||||
value = ""
|
||||
isEnabled = "YES">
|
||||
</AdditionalOption>
|
||||
<AdditionalOption
|
||||
key = "MallocScribble"
|
||||
value = ""
|
||||
isEnabled = "YES">
|
||||
</AdditionalOption>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
buildConfiguration = "Release"
|
||||
debugDocumentVersioning = "YES">
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>SchemeUserState</key>
|
||||
<dict>
|
||||
<key>shairport-sync.xcscheme</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
<dict>
|
||||
<key>2785805E19BB488D00C0B34D</key>
|
||||
<dict>
|
||||
<key>primary</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:shairport-sync.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDESourceControlProjectFavoriteDictionaryKey</key>
|
||||
<false/>
|
||||
<key>IDESourceControlProjectIdentifier</key>
|
||||
<string>FE3806DD-2182-4590-A83E-FEB5D071A2C5</string>
|
||||
<key>IDESourceControlProjectName</key>
|
||||
<string>shairport-sync</string>
|
||||
<key>IDESourceControlProjectOriginsDictionary</key>
|
||||
<dict>
|
||||
<key>6DA2D7CF-469E-4320-AD70-9612E79D9450</key>
|
||||
<string>ssh://github.com/mikebrady/shairport-sync.git</string>
|
||||
</dict>
|
||||
<key>IDESourceControlProjectPath</key>
|
||||
<string>shairport-sync.xcworkspace</string>
|
||||
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
|
||||
<dict>
|
||||
<key>6DA2D7CF-469E-4320-AD70-9612E79D9450</key>
|
||||
<string>..</string>
|
||||
</dict>
|
||||
<key>IDESourceControlProjectURL</key>
|
||||
<string>ssh://github.com/mikebrady/shairport-sync.git</string>
|
||||
<key>IDESourceControlProjectVersion</key>
|
||||
<integer>110</integer>
|
||||
<key>IDESourceControlProjectWCCIdentifier</key>
|
||||
<string>6DA2D7CF-469E-4320-AD70-9612E79D9450</string>
|
||||
<key>IDESourceControlProjectWCConfigurations</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
|
||||
<string>public.vcs.git</string>
|
||||
<key>IDESourceControlWCCIdentifierKey</key>
|
||||
<string>6DA2D7CF-469E-4320-AD70-9612E79D9450</string>
|
||||
<key>IDESourceControlWCCName</key>
|
||||
<string>shairport-sync</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>BuildLocationStyle</key>
|
||||
<string>UseAppPreferences</string>
|
||||
<key>CustomBuildLocationType</key>
|
||||
<string>RelativeToDerivedData</string>
|
||||
<key>DerivedDataLocationStyle</key>
|
||||
<string>Default</string>
|
||||
<key>HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges</key>
|
||||
<true/>
|
||||
<key>IssueFilterStyle</key>
|
||||
<string>ShowActiveSchemeOnly</string>
|
||||
<key>LiveSourceIssuesEnabled</key>
|
||||
<true/>
|
||||
<key>SnapshotAutomaticallyBeforeSignificantChanges</key>
|
||||
<true/>
|
||||
<key>SnapshotLocationStyle</key>
|
||||
<string>Default</string>
|
||||
</dict>
|
||||
</plist>
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Bucket
|
||||
type = "0"
|
||||
version = "2.0">
|
||||
<Breakpoints>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.SymbolicBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "Yes"
|
||||
symbolName = "SIGUSR1"
|
||||
moduleName = "">
|
||||
<Actions>
|
||||
<BreakpointActionProxy
|
||||
ActionExtensionID = "Xcode.BreakpointAction.DebuggerCommand">
|
||||
<ActionContent
|
||||
consoleCommand = "process handle SIGUSR1 -n true -p true -s false">
|
||||
</ActionContent>
|
||||
</BreakpointActionProxy>
|
||||
</Actions>
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
</Breakpoints>
|
||||
</Bucket>
|
||||
Reference in New Issue
Block a user