X-Git-Url: https://git.distorted.org.uk/~mdw/disorder/blobdiff_plain/81b1bf12365297c8bace12f28e45c0796c593915..572c28992641c1fc82a3d3218ece737a078390a0:/server/speaker-network.c diff --git a/server/speaker-network.c b/server/speaker-network.c index 6ffe929..59630ff 100644 --- a/server/speaker-network.c +++ b/server/speaker-network.c @@ -30,8 +30,9 @@ #include #include #include -#include #include +#include +#include #include "configuration.h" #include "syscalls.h" @@ -102,15 +103,10 @@ static void network_init(void) { 0 }; static const int one = 1; - int sndbuf, target_sndbuf = 131072, n; + int sndbuf, target_sndbuf = 131072; socklen_t len; char *sockname, *ssockname; - /* Override sample format */ - config->sample_format.rate = 44100; - config->sample_format.channels = 2; - config->sample_format.bits = 16; - config->sample_format.byte_format = AO_FMT_BIG; res = get_address(&config->broadcast, &pref, &sockname); if(!res) exit(-1); if(config->broadcast_from.n) { @@ -150,21 +146,24 @@ static void network_init(void) { } info("multicasting on %s", sockname); } else { - struct ifreq *ifs; - int nifs; + struct ifaddrs *ifs; - /* See if the address matches the broadcast address of some interface */ - ifreq_list(bfd, &ifs, &nifs); - for(n = 0; n < nifs; ++n) { - if(ioctl(bfd, SIOCGIFBRDADDR, &ifs[n]) < 0) - fatal(errno, "error calling ioctl SIOCGIFBRDADDR"); - if(sockaddr_equal(&ifs[n].ifr_broadaddr, res->ai_addr)) + if(getifaddrs(&ifs) < 0) + fatal(errno, "error calling getifaddrs"); + while(ifs) { + /* (At least on Darwin) IFF_BROADCAST might be set but ifa_broadaddr + * still a null pointer. It turns out that there's a subsequent entry + * for he same interface which _does_ have ifa_broadaddr though... */ + if((ifs->ifa_flags & IFF_BROADCAST) + && ifs->ifa_broadaddr + && sockaddr_equal(ifs->ifa_broadaddr, res->ai_addr)) break; + ifs = ifs->ifa_next; } - if(n < nifs) { + if(ifs) { if(setsockopt(bfd, SOL_SOCKET, SO_BROADCAST, &one, sizeof one) < 0) fatal(errno, "error setting SO_BROADCAST on broadcast socket"); - info("broadcasting on %s (%s)", sockname, ifs[n].ifr_name); + info("broadcasting on %s (%s)", sockname, ifs->ifa_name); } else info("unicasting on %s", sockname); } @@ -197,7 +196,7 @@ static void network_init(void) { static size_t network_play(size_t frames) { struct rtp_header header; struct iovec vec[2]; - size_t bytes = frames * device_bpf, written_frames; + size_t bytes = frames * bpf, written_frames; int written_bytes; /* We transmit using RTP (RFC3550) and attempt to conform to the internet * AVT profile (RFC3551). */ @@ -213,8 +212,8 @@ static size_t network_play(size_t frames) { /* Find the number of microseconds elapsed since rtp_time=0 */ delta = tvsub_us(now, rtp_time_0); assert(delta <= UINT64_MAX / 88200); - target_rtp_time = (delta * playing->format.rate - * playing->format.channels) / 1000000; + target_rtp_time = (delta * config->sample_format.rate + * config->sample_format.channels) / 1000000; /* Overflows at ~6 years uptime with 44100Hz stereo */ /* rtp_time is the number of samples we've played. NB that we play @@ -273,7 +272,7 @@ static size_t network_play(size_t frames) { if(bytes > NETWORK_BYTES - sizeof header) { bytes = NETWORK_BYTES - sizeof header; /* Always send a whole number of frames */ - bytes -= bytes % device_bpf; + bytes -= bytes % bpf; } /* "The RTP clock rate used for generating the RTP timestamp is independent * of the number of channels and the encoding; it equals the number of @@ -299,9 +298,9 @@ static size_t network_play(size_t frames) { } else audio_errors /= 2; written_bytes -= sizeof (struct rtp_header); - written_frames = written_bytes / device_bpf; + written_frames = written_bytes / bpf; /* Advance RTP's notion of the time */ - rtp_time += written_frames * playing->format.channels; + rtp_time += written_frames * config->sample_format.channels; return written_frames; } @@ -342,7 +341,7 @@ static int network_ready(void) { const struct speaker_backend network_backend = { BACKEND_NETWORK, - FIXED_FORMAT, + 0, network_init, 0, /* activate */ network_play,