From 344cf45feb7d512adb40fe129c514b8baf6d95f3 Mon Sep 17 00:00:00 2001 From: Mike Brady Date: Sun, 7 Sep 2014 12:29:06 +0100 Subject: [PATCH 01/17] Initial Commit --- shairport-sync.xcodeproj/project.pbxproj | 209 +++++++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 shairport-sync.xcodeproj/project.pbxproj diff --git a/shairport-sync.xcodeproj/project.pbxproj b/shairport-sync.xcodeproj/project.pbxproj new file mode 100644 index 00000000..dfb8d68d --- /dev/null +++ b/shairport-sync.xcodeproj/project.pbxproj @@ -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 = ""; }; + 2785806519BB488D00C0B34D /* alac.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = alac.h; sourceTree = ""; }; + 2785806619BB488D00C0B34D /* audio.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = audio.c; sourceTree = ""; }; + 2785806719BB488D00C0B34D /* audio.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = audio.h; sourceTree = ""; }; + 2785806819BB488D00C0B34D /* audio_alsa.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = audio_alsa.c; sourceTree = ""; }; + 2785806919BB488D00C0B34D /* audio_ao.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = audio_ao.c; sourceTree = ""; }; + 2785806A19BB488D00C0B34D /* audio_dummy.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = audio_dummy.c; sourceTree = ""; }; + 2785806B19BB488D00C0B34D /* audio_pipe.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = audio_pipe.c; sourceTree = ""; }; + 2785806C19BB488D00C0B34D /* audio_pulse.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = audio_pulse.c; sourceTree = ""; }; + 2785806D19BB488D00C0B34D /* audio_sndio.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = audio_sndio.c; sourceTree = ""; }; + 2785806E19BB488D00C0B34D /* AUTHORS */ = {isa = PBXFileReference; lastKnownFileType = text; path = AUTHORS; sourceTree = ""; }; + 2785807119BB488D00C0B34D /* common.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = common.c; sourceTree = ""; }; + 2785807219BB488D00C0B34D /* common.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = common.h; sourceTree = ""; }; + 2785807C19BB488D00C0B34D /* configure.ac */ = {isa = PBXFileReference; lastKnownFileType = text; path = configure.ac; sourceTree = ""; }; + 2785807D19BB488D00C0B34D /* COPYING */ = {isa = PBXFileReference; lastKnownFileType = text; path = COPYING; sourceTree = ""; }; + 2785807F19BB488D00C0B34D /* documents */ = {isa = PBXFileReference; lastKnownFileType = folder; path = documents; sourceTree = ""; }; + 2785808019BB488D00C0B34D /* INSTALL */ = {isa = PBXFileReference; lastKnownFileType = text; path = INSTALL; sourceTree = ""; }; + 2785808219BB488D00C0B34D /* LICENSES */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSES; sourceTree = ""; }; + 2785808419BB488D00C0B34D /* Makefile.am */ = {isa = PBXFileReference; lastKnownFileType = text; path = Makefile.am; sourceTree = ""; }; + 2785808619BB488D00C0B34D /* mdns.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mdns.c; sourceTree = ""; }; + 2785808719BB488D00C0B34D /* mdns.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mdns.h; sourceTree = ""; }; + 2785808819BB488D00C0B34D /* mdns_avahi.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mdns_avahi.c; sourceTree = ""; }; + 2785808919BB488D00C0B34D /* mdns_dns_sd.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mdns_dns_sd.c; sourceTree = ""; }; + 2785808A19BB488D00C0B34D /* mdns_external.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mdns_external.c; sourceTree = ""; }; + 2785808B19BB488D00C0B34D /* mdns_tinysvcmdns.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mdns_tinysvcmdns.c; sourceTree = ""; }; + 2785808D19BB488D00C0B34D /* NEWS */ = {isa = PBXFileReference; lastKnownFileType = text; path = NEWS; sourceTree = ""; }; + 2785808E19BB488D00C0B34D /* player.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = player.c; sourceTree = ""; }; + 2785808F19BB488D00C0B34D /* player.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = player.h; sourceTree = ""; }; + 2785809019BB488D00C0B34D /* README */ = {isa = PBXFileReference; lastKnownFileType = text; path = README; sourceTree = ""; }; + 2785809119BB488D00C0B34D /* README.md */ = {isa = PBXFileReference; lastKnownFileType = text; path = README.md; sourceTree = ""; }; + 2785809219BB488D00C0B34D /* rtp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = rtp.c; sourceTree = ""; }; + 2785809319BB488D00C0B34D /* rtp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = rtp.h; sourceTree = ""; }; + 2785809419BB488D00C0B34D /* rtsp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = rtsp.c; sourceTree = ""; }; + 2785809519BB488D00C0B34D /* rtsp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = rtsp.h; sourceTree = ""; }; + 2785809619BB488D00C0B34D /* scripts */ = {isa = PBXFileReference; lastKnownFileType = folder; path = scripts; sourceTree = ""; }; + 2785809719BB488D00C0B34D /* shairport-sync.xcworkspace */ = {isa = PBXFileReference; lastKnownFileType = wrapper.workspace; path = "shairport-sync.xcworkspace"; sourceTree = ""; }; + 2785809819BB488D00C0B34D /* shairport.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = shairport.c; sourceTree = ""; }; + 2785809A19BB488D00C0B34D /* tinysvcmdns.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = tinysvcmdns.c; sourceTree = ""; }; + 2785809B19BB488D00C0B34D /* tinysvcmdns.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = tinysvcmdns.h; sourceTree = ""; }; +/* 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 = ""; + }; +/* 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 */; +} From 0733e962bb6b84f9c3ed53b6f0fe77eeebbc1a71 Mon Sep 17 00:00:00 2001 From: Mike Brady Date: Sun, 7 Sep 2014 12:31:23 +0100 Subject: [PATCH 02/17] rename absolute_time_in_ns to absolute_time_in_fp (more accurate name). Fix osx timing calculation. --- common.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/common.c b/common.c index a070a249..74ce7436 100644 --- a/common.c +++ b/common.c @@ -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; } From b24edddedc9a0288d946c76634c2e58de7557ae0 Mon Sep 17 00:00:00 2001 From: Mike Brady Date: Sun, 7 Sep 2014 12:32:01 +0100 Subject: [PATCH 03/17] Rename absolute_time_in_ns to absolute_time_in_fp. --- common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.h b/common.h index 43a19d70..e6084698 100644 --- a/common.h +++ b/common.h @@ -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; From 563d4c8780163d972da5e19ff2a9eb059418292d Mon Sep 17 00:00:00 2001 From: Mike Brady Date: Sun, 7 Sep 2014 12:33:17 +0100 Subject: [PATCH 04/17] Add code to distinguish Linux from Mac OS X. Make librt inclusion linux only. --- configure.ac | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index d7ea2faa..5bafb0b4 100644 --- a/configure.ac +++ b/configure.ac @@ -3,28 +3,35 @@ AC_PREREQ([2.50]) AC_INIT([shairport-sync], [2.1], [mikebrady@eircom.net]) +AC_CANONICAL_TARGET([]) AM_INIT_AUTOMAKE AC_CONFIG_SRCDIR([shairport.c]) AC_CONFIG_HEADERS([config.h]) +#The following would print linux or darwin +#echo "Target OS: ${target_os%%[[[:digit:]]]*}" + # 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${target_os%-gnu}" = 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!))], ) From f64f5982750e6f98aaa5beb8ca03aa29a92110f9 Mon Sep 17 00:00:00 2001 From: Mike Brady Date: Sun, 7 Sep 2014 12:33:54 +0100 Subject: [PATCH 05/17] Completely remove entries for mDNS backends that are not included. --- mdns.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/mdns.c b/mdns.c index 35e34c16..ed7d77fa 100644 --- a/mdns.c +++ b/mdns.c @@ -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 From 8bff3213c9878e8443fbaf68b827d6468c7602b5 Mon Sep 17 00:00:00 2001 From: Mike Brady Date: Sun, 7 Sep 2014 12:34:32 +0100 Subject: [PATCH 06/17] Initial commit --- .../contents.xcworkspacedata | 7 ++++ .../xcshareddata/shairport-sync.xccheckout | 41 +++++++++++++++++++ .../WorkspaceSettings.xcsettings | 22 ++++++++++ .../xcdebugger/Breakpoints_v2.xcbkptlist | 41 +++++++++++++++++++ 4 files changed, 111 insertions(+) create mode 100644 shairport-sync.xcworkspace/contents.xcworkspacedata create mode 100644 shairport-sync.xcworkspace/xcshareddata/shairport-sync.xccheckout create mode 100644 shairport-sync.xcworkspace/xcuserdata/mike.xcuserdatad/WorkspaceSettings.xcsettings create mode 100644 shairport-sync.xcworkspace/xcuserdata/mike.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist diff --git a/shairport-sync.xcworkspace/contents.xcworkspacedata b/shairport-sync.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..b19b9c31 --- /dev/null +++ b/shairport-sync.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/shairport-sync.xcworkspace/xcshareddata/shairport-sync.xccheckout b/shairport-sync.xcworkspace/xcshareddata/shairport-sync.xccheckout new file mode 100644 index 00000000..73663af3 --- /dev/null +++ b/shairport-sync.xcworkspace/xcshareddata/shairport-sync.xccheckout @@ -0,0 +1,41 @@ + + + + + IDESourceControlProjectFavoriteDictionaryKey + + IDESourceControlProjectIdentifier + FE3806DD-2182-4590-A83E-FEB5D071A2C5 + IDESourceControlProjectName + shairport-sync + IDESourceControlProjectOriginsDictionary + + 6DA2D7CF-469E-4320-AD70-9612E79D9450 + ssh://github.com/mikebrady/shairport-sync.git + + IDESourceControlProjectPath + shairport-sync.xcworkspace + IDESourceControlProjectRelativeInstallPathDictionary + + 6DA2D7CF-469E-4320-AD70-9612E79D9450 + .. + + IDESourceControlProjectURL + ssh://github.com/mikebrady/shairport-sync.git + IDESourceControlProjectVersion + 110 + IDESourceControlProjectWCCIdentifier + 6DA2D7CF-469E-4320-AD70-9612E79D9450 + IDESourceControlProjectWCConfigurations + + + IDESourceControlRepositoryExtensionIdentifierKey + public.vcs.git + IDESourceControlWCCIdentifierKey + 6DA2D7CF-469E-4320-AD70-9612E79D9450 + IDESourceControlWCCName + shairport-sync + + + + diff --git a/shairport-sync.xcworkspace/xcuserdata/mike.xcuserdatad/WorkspaceSettings.xcsettings b/shairport-sync.xcworkspace/xcuserdata/mike.xcuserdatad/WorkspaceSettings.xcsettings new file mode 100644 index 00000000..28f6741d --- /dev/null +++ b/shairport-sync.xcworkspace/xcuserdata/mike.xcuserdatad/WorkspaceSettings.xcsettings @@ -0,0 +1,22 @@ + + + + + BuildLocationStyle + UseAppPreferences + CustomBuildLocationType + RelativeToDerivedData + DerivedDataLocationStyle + Default + HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges + + IssueFilterStyle + ShowActiveSchemeOnly + LiveSourceIssuesEnabled + + SnapshotAutomaticallyBeforeSignificantChanges + + SnapshotLocationStyle + Default + + diff --git a/shairport-sync.xcworkspace/xcuserdata/mike.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/shairport-sync.xcworkspace/xcuserdata/mike.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 00000000..c978f2ea --- /dev/null +++ b/shairport-sync.xcworkspace/xcuserdata/mike.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + From d3691bd46e84fc3471f7052999587f3690949249 Mon Sep 17 00:00:00 2001 From: Mike Brady Date: Sun, 7 Sep 2014 12:36:24 +0100 Subject: [PATCH 07/17] =?UTF-8?q?Don=E2=80=99t=20bother=20with=20SO=5FREUS?= =?UTF-8?q?EADDR=20stuff.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- rtsp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rtsp.c b/rtsp.c index 913df53c..d364dc0a 100644 --- a/rtsp.c +++ b/rtsp.c @@ -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. From 2cded85dd4fcfa40a731f240126643965d79de97 Mon Sep 17 00:00:00 2001 From: Mike Brady Date: Sun, 7 Sep 2014 12:39:45 +0100 Subject: [PATCH 08/17] 1. Fix sendto calls to use the exactly correct length for message destinations. OS X objects to incorrect lengths, though Linux is silent on it. 2. Use getaddrinfo to make up correctly-formed destination sockets. 3. bind_port is now a steaming mass of crap. --- rtp.c | 137 ++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 91 insertions(+), 46 deletions(-) diff --git a/rtp.c b/rtp.c index 86f48597..d41f9e69 100644 --- a/rtp.c +++ b/rtp.c @@ -32,8 +32,10 @@ #include #include #include +#include #include #include +#include #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; + } + 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!"); From 32fc4ff5fe5dfc2755c6ffbf03c7ad70ac32b5e5 Mon Sep 17 00:00:00 2001 From: Mike Brady Date: Sun, 7 Sep 2014 12:40:36 +0100 Subject: [PATCH 09/17] Stop Mac OS X compiler complaining about seq_diff. --- player.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/player.h b/player.h index 35383590..04109ecb 100644 --- a/player.h +++ b/player.h @@ -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); From caf359befb8f3952b21c02314e80dad68406d3ac Mon Sep 17 00:00:00 2001 From: Mike Brady Date: Sun, 7 Sep 2014 12:43:08 +0100 Subject: [PATCH 10/17] =?UTF-8?q?1.=20Stop=20Mac=20OS=20X=20compiler=20com?= =?UTF-8?q?plaining=20about=20seq=5Fdiff=20being=20=E2=80=9Cinline?= =?UTF-8?q?=E2=80=9D=202.=20Use=20get=5Fabsolute=5Ftime=5Fin=5Ffp=20rather?= =?UTF-8?q?=20than=20get=5Fabsolute=5Ftime=5Fin=5Fns=203.=20Remove=20usele?= =?UTF-8?q?ss=20and=20buggy=20jitter=20count=20stuff?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- player.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/player.c b/player.c index 857d50ef..e61ecfd1 100644 --- a/player.c +++ b/player.c @@ -170,7 +170,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; } @@ -301,7 +301,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) @@ -345,7 +345,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... @@ -480,8 +480,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; @@ -709,7 +709,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; @@ -872,7 +872,6 @@ static void *player_thread_func(void *arg) { 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 From b38dfd0601cc4399903a50713dfab3d669da20ab Mon Sep 17 00:00:00 2001 From: Mike Brady Date: Sun, 7 Sep 2014 12:50:41 +0100 Subject: [PATCH 11/17] Try to quieten some warnings for Mac OS X --- rtsp.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/rtsp.c b/rtsp.c index d364dc0a..5c587a56 100644 --- a/rtsp.c +++ b/rtsp.c @@ -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"); From cb68cf79f527c5fb3ae6ebf72ceb447acc566a0f Mon Sep 17 00:00:00 2001 From: Mike Brady Date: Sun, 7 Sep 2014 12:56:26 +0100 Subject: [PATCH 12/17] Initial commit -- experimental --- .../xcschemes/shairport-sync.xcscheme | 93 +++++++++++++++++++ .../xcschemes/xcschememanagement.plist | 22 +++++ .../xcdebugger/Breakpoints_v2.xcbkptlist | 16 ---- 3 files changed, 115 insertions(+), 16 deletions(-) create mode 100644 shairport-sync.xcodeproj/xcuserdata/mike.xcuserdatad/xcschemes/shairport-sync.xcscheme create mode 100644 shairport-sync.xcodeproj/xcuserdata/mike.xcuserdatad/xcschemes/xcschememanagement.plist diff --git a/shairport-sync.xcodeproj/xcuserdata/mike.xcuserdatad/xcschemes/shairport-sync.xcscheme b/shairport-sync.xcodeproj/xcuserdata/mike.xcuserdatad/xcschemes/shairport-sync.xcscheme new file mode 100644 index 00000000..71103994 --- /dev/null +++ b/shairport-sync.xcodeproj/xcuserdata/mike.xcuserdatad/xcschemes/shairport-sync.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/shairport-sync.xcodeproj/xcuserdata/mike.xcuserdatad/xcschemes/xcschememanagement.plist b/shairport-sync.xcodeproj/xcuserdata/mike.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 00000000..32f8c201 --- /dev/null +++ b/shairport-sync.xcodeproj/xcuserdata/mike.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,22 @@ + + + + + SchemeUserState + + shairport-sync.xcscheme + + orderHint + 0 + + + SuppressBuildableAutocreation + + 2785805E19BB488D00C0B34D + + primary + + + + + diff --git a/shairport-sync.xcworkspace/xcuserdata/mike.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/shairport-sync.xcworkspace/xcuserdata/mike.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index c978f2ea..017760c2 100644 --- a/shairport-sync.xcworkspace/xcuserdata/mike.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/shairport-sync.xcworkspace/xcuserdata/mike.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -21,21 +21,5 @@ - - - - From d3e1112b63bf24e3d6fad0af77c420016e1e0dca Mon Sep 17 00:00:00 2001 From: Mike Brady Date: Sun, 7 Sep 2014 15:56:09 +0100 Subject: [PATCH 13/17] Modify to correctly identify a linux installation --- configure.ac | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 5bafb0b4..3c9fe638 100644 --- a/configure.ac +++ b/configure.ac @@ -8,15 +8,15 @@ AM_INIT_AUTOMAKE AC_CONFIG_SRCDIR([shairport.c]) AC_CONFIG_HEADERS([config.h]) -#The following would print linux or darwin -#echo "Target OS: ${target_os%%[[[:digit:]]]*}" +#The following should print linux or darwin +#echo "Target OS: ${target_os%-*}" # Checks for programs. AC_PROG_CC AC_PROG_INSTALL # Checks for libraries. -if test "x${target_os%-gnu}" = xlinux; then +if test "x${target_os%-*}" = xlinux; then AC_CHECK_LIB([rt],[clock_gettime], , AC_MSG_ERROR(librt needed)) fi From 367470ef0086fc0a8a62445ca1e87e2acf01dadd Mon Sep 17 00:00:00 2001 From: Mike Brady Date: Sun, 7 Sep 2014 15:59:27 +0100 Subject: [PATCH 14/17] Turn off debug message about jitter. --- rtp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtp.c b/rtp.c index d41f9e69..836a648c 100644 --- a/rtp.c +++ b/rtp.c @@ -357,8 +357,8 @@ static void *rtp_timing_receiver(void *arg) { } local_to_remote_time_jitters_count+=1; } - - 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); + // 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 { From 60c3d6cf4343517d9252f3cc44815276867af5b1 Mon Sep 17 00:00:00 2001 From: Mike Brady Date: Mon, 8 Sep 2014 11:00:43 +0100 Subject: [PATCH 15/17] Another approach to checking if linux or osx -- tell it, like in Avahi. --- configure.ac | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 3c9fe638..fd44816c 100644 --- a/configure.ac +++ b/configure.ac @@ -3,20 +3,28 @@ AC_PREREQ([2.50]) AC_INIT([shairport-sync], [2.1], [mikebrady@eircom.net]) -AC_CANONICAL_TARGET([]) AM_INIT_AUTOMAKE AC_CONFIG_SRCDIR([shairport.c]) AC_CONFIG_HEADERS([config.h]) -#The following should print linux or darwin -#echo "Target OS: ${target_os%-*}" +# 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. -if test "x${target_os%-*}" = xlinux; then +if test "x${with_os_type}" = xlinux; then AC_CHECK_LIB([rt],[clock_gettime], , AC_MSG_ERROR(librt needed)) fi From 0b90bb646c164f33048b97555db5e214a89d4090 Mon Sep 17 00:00:00 2001 From: Mike Brady Date: Mon, 8 Sep 2014 13:26:30 +0100 Subject: [PATCH 16/17] Seems as if we do need SO_REUSEADDR stuff after all -- to allow shairport-sync to stop and restart cleanly. --- rtsp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtsp.c b/rtsp.c index 5c587a56..5220d6f2 100644 --- a/rtsp.c +++ b/rtsp.c @@ -910,8 +910,8 @@ void rtsp_listen_loop(void) { int fd = socket(p->ai_family, p->ai_socktype, IPPROTO_TCP); int yes = 1; -// if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1) -// perror("setsockopt"); + 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. From 0462ead319e8d5111b5169943c5d8da66909f4c7 Mon Sep 17 00:00:00 2001 From: Mike Brady Date: Mon, 8 Sep 2014 13:28:26 +0100 Subject: [PATCH 17/17] Add seq_t PREDECSSOR and seq_sum functions, use them in place of add and subtract. Make play loop record plays and stats even when given silent frames. --- player.c | 61 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/player.c b/player.c index e61ecfd1..50c40e09 100644 --- a/player.c +++ b/player.c @@ -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; @@ -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); @@ -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; @@ -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)); @@ -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."); @@ -815,8 +829,6 @@ static void *player_thread_func(void *arg) { sync_error_out_of_bounds = 0; } - play_number++; - // debug(1,"Sync error %lld frames. Amount to stuff %d." ,sync_error,amount_to_stuff); // new stats calculation. We want a running average of sync error, drift, adjustment, number of additions+subtractions @@ -858,25 +870,24 @@ static void *player_thread_func(void *arg) { // check sequencing if (last_seqno_read==-1) - last_seqno_read=inframe->sequence_number; - else { - last_seqno_read = (last_seqno_read+1)&0xffff; - 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; - // 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 + last_seqno_read=inframe->sequence_number; + else { + last_seqno_read = (last_seqno_read+1)&0xffff; + 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; + // 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 + } } } }