Permalink
Browse files

PKAudioPlayer now broadcasts a distributed notification the first tim…

…e it plays something after being initialized. This allows multiple apps to use PlayerKit as their core without their outputs clashing.
  • Loading branch information...
1 parent a030804 commit 69427da94d333e7004a1f7784cc421ebab13f02b Peter MacWhinnie committed Feb 9, 2011
Showing with 110 additions and 32 deletions.
  1. +62 −0 PKAudioPlayer.cpp
  2. +4 −0 PKAudioPlayer.h
  3. +2 −1 PKAudioPlayerEngine.cpp
  4. +2 −0 PKAudioPlayerInternal.h
  5. +7 −6 PlayerKit.xcodeproj/pjm.mode2v3
  6. +33 −25 PlayerKit.xcodeproj/pjm.pbxuser
View
@@ -26,6 +26,17 @@ PK_VISIBILITY_HIDDEN volatile int32_t AudioPlayerStateInitCount = 0;
PK_EXTERN CFStringRef const PKAudioPlayerDidEncounterErrorNotification = CFSTR("PKAudioPlayerDidEncounterErrorNotification");
PK_EXTERN CFStringRef const PKAudioPlayerDidFinishPlayingNotification = CFSTR("PKAudioPlayerDidFinishPlayingNotification");
PK_EXTERN CFStringRef const PKAudioPlayerDidChangeOutputDeviceNotification = CFSTR("PKAudioPlayerDidChangeOutputDeviceNotification");
+PK_EXTERN CFStringRef const PKAudioPlayerDidEncounterOtherPlayerNotification = CFSTR("PKAudioPlayerDidEncounterOtherPlayerNotification");
+
+#pragma mark -
+
+static CFStringRef const PKAudioPlayerDidBroadcastPresenceNotification = CFSTR("com.roundabout.PKAudioPlayerDidBroadcastPresenceNotification");
+
+static void PKAudioPlayerDidBroadcastPresence(CFNotificationCenterRef center,
+ void *observer,
+ CFStringRef name,
+ const void *object,
+ CFDictionaryRef userInfo);
#pragma mark -
#pragma mark Lifecycle
@@ -107,6 +118,17 @@ PK_EXTERN Boolean PKAudioPlayerInit(CFErrorRef *outError)
});
});
+
+ CFNotificationCenterAddObserver(CFNotificationCenterGetDistributedCenter(),
+ NULL,
+ CFNotificationCallback(&PKAudioPlayerDidBroadcastPresence),
+ PKAudioPlayerDidBroadcastPresenceNotification,
+ NULL,
+ CFNotificationSuspensionBehaviorDeliverImmediately);
+
+ CFUUIDRef sessionUUID = CFUUIDCreate(kCFAllocatorDefault);
+ AudioPlayerState.sessionID = CFUUIDCreateString(kCFAllocatorDefault, sessionUUID);
+ CFRelease(sessionUUID);
}
catch (RBException e)
{
@@ -160,6 +182,12 @@ PK_EXTERN Boolean PKAudioPlayerTeardown(CFErrorRef *outError)
AudioPlayerState.decoder->Release();
AudioPlayerState.decoder = NULL;
}
+
+ if(AudioPlayerState.sessionID)
+ {
+ CFRelease(AudioPlayerState.sessionID);
+ AudioPlayerState.sessionID = NULL;
+ }
}
catch (RBException e)
{
@@ -168,10 +196,33 @@ PK_EXTERN Boolean PKAudioPlayerTeardown(CFErrorRef *outError)
return false;
}
+ memset(&AudioPlayerState, 0, sizeof(AudioPlayerState));
+
return true;
}
#pragma mark -
+#pragma mark Notifications
+
+static void PKAudioPlayerDidBroadcastPresence(CFNotificationCenterRef center,
+ void *observer,
+ CFStringRef name,
+ const void *object,
+ CFDictionaryRef userInfo)
+{
+ if(CFEqual(AudioPlayerState.sessionID, CFStringRef(object)))
+ return;
+
+ dispatch_async(dispatch_get_main_queue(), ^{
+ CFNotificationCenterPostNotification(CFNotificationCenterGetLocalCenter(),
+ PKAudioPlayerDidEncounterOtherPlayerNotification,
+ NULL,
+ NULL,
+ true);
+ });
+}
+
+#pragma mark -
#pragma mark Playback Callbacks
static UInt32 PKAudioPlayerScheduleSlice(PKAudioPlayerEngine *graph, AudioBufferList *ioBuffer, UInt32 numberOfFramesToRead, CFErrorRef *error, void *userData)
@@ -424,6 +475,17 @@ PK_EXTERN Boolean PKAudioPlayerPlay(CFErrorRef *outError)
RBLockableObject::Acquisitor lock(&AudioPlayerStateLock);
+ if(OSMemoryBarrier(), !AudioPlayerState.hasBroadcastedPresence)
+ {
+ CFNotificationCenterPostNotification(CFNotificationCenterGetDistributedCenter(),
+ PKAudioPlayerDidBroadcastPresenceNotification,
+ AudioPlayerState.sessionID,
+ NULL,
+ true);
+
+ OSAtomicCompareAndSwap32Barrier(AudioPlayerState.hasBroadcastedPresence, 1, &AudioPlayerState.hasBroadcastedPresence);
+ }
+
try
{
if(!AudioPlayerState.engine->IsRunning())
View
@@ -30,6 +30,10 @@ PK_EXTERN CFStringRef const PKAudioPlayerDidFinishPlayingNotification;
///The notification posted when an audio player has changed output devices.
PK_EXTERN CFStringRef const PKAudioPlayerDidChangeOutputDeviceNotification;
+///The notification posted when an audio player discovers that another
+///PlayerKit-powered application is playing music on the host computer.
+PK_EXTERN CFStringRef const PKAudioPlayerDidEncounterOtherPlayerNotification;
+
#pragma mark -
#pragma mark Lifecycle
View
@@ -574,7 +574,7 @@ void PKAudioPlayerEngine::StopProcessing() throw(RBException)
{
PKScheduledDataSlice *dataSlice = mDataSlices[index];
dataSlice->Acquire();
- dataSlice->mInvalidated = true;
+ dataSlice->Reset();
dataSlice->Relinquish();
}
@@ -591,6 +591,7 @@ void PKAudioPlayerEngine::StopProcessing() throw(RBException)
RBAssertNoErr(errorCode, CFSTR("Could not reset node %ld, error %ld."), node, errorCode);
}
+ //Reset any paused state.
mProcessingIsPaused = false;
if(mSortedDataSlicesForPausedProcessing)
View
@@ -27,6 +27,8 @@ typedef struct PKAudioPlayer {
//State
volatile int32_t isPaused;
+ volatile int32_t hasBroadcastedPresence;
+ CFStringRef sessionID;
} PKAudioPlayer;
///The singleton instance of the audio player state.
@@ -277,14 +277,14 @@
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
<array>
<array>
- <integer>17</integer>
+ <integer>16</integer>
<integer>15</integer>
<integer>14</integer>
<integer>0</integer>
</array>
</array>
<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
- <string>{{0, 0}, {429, 333}}</string>
+ <string>{{0, 196}, {429, 333}}</string>
</dict>
<key>PBXTopSmartGroupGIDs</key>
<array/>
@@ -445,8 +445,8 @@
</array>
<key>TableOfContents</key>
<array>
- <string>1EC3B95A12EFC63E0066884A</string>
- <string>1EC3B95B12EFC63E0066884A</string>
+ <string>1E9637CD130246ED00AA0968</string>
+ <string>1E9637CE130246ED00AA0968</string>
<string>1C9437FD063B20B00039CFAC</string>
<string>1C9437FE063B20B00039CFAC</string>
<string>1C9437FF063B20B00039CFAC</string>
@@ -483,8 +483,9 @@
<integer>0</integer>
<key>WindowOrderList</key>
<array>
+ <string>1E9637CF130246ED00AA0968</string>
<string>1C530D52069F1CE1000CFCEE</string>
- <string>/Users/pjm/Documents/Projects/PlayerKit/PlayerKit.xcodeproj</string>
+ <string>/Users/pjm/Documents/Projects/Shippable/PlayerKit/PlayerKit.xcodeproj</string>
</array>
<key>WindowString</key>
<string>994 459 446 419 0 0 1440 878 </string>
@@ -699,7 +700,7 @@
<key>TableOfContents</key>
<array>
<string>1C530D52069F1CE1000CFCEE</string>
- <string>1EC3B95C12EFC63E0066884A</string>
+ <string>1E9637D2130246ED00AA0968</string>
<string>1CD0528F0623707200166675</string>
<string>XCMainBuildResultsModuleGUID</string>
</array>
@@ -32,8 +32,8 @@
PBXFileDataSource_Target_ColumnID,
);
};
- PBXPerProjectTemplateStateSaveDate = 317703741;
- PBXWorkspaceStateSaveDate = 317703741;
+ PBXPerProjectTemplateStateSaveDate = 318916325;
+ PBXWorkspaceStateSaveDate = 318916325;
};
sourceControlManager = 1EE97A48124D80BC00AA4646 /* Source Control */;
userBuildSettings = {
@@ -65,9 +65,9 @@
};
1E4195EB12E12C3C007038D2 /* PKDelayEffect.cpp */ = {
uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {914, 2205}}";
- sepNavSelRange = "{4003, 0}";
- sepNavVisRange = "{3060, 1370}";
+ sepNavIntBoundsRect = "{{0, 0}, {914, 2028}}";
+ sepNavSelRange = "{1098, 0}";
+ sepNavVisRange = "{465, 1379}";
sepNavWindowFrame = "{{153, 38}, {973, 709}}";
};
};
@@ -118,17 +118,17 @@
};
1EE97A4F124D80EA00AA4646 /* PKAudioPlayerEngine.cpp */ = {
uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {830, 18120}}";
- sepNavSelRange = "{607, 0}";
- sepNavVisRange = "{0, 999}";
+ sepNavIntBoundsRect = "{{0, 0}, {830, 15808}}";
+ sepNavSelRange = "{16359, 0}";
+ sepNavVisRange = "{14917, 1760}";
sepNavWindowFrame = "{{130, 97}, {889, 671}}";
};
};
1EE97A50124D80EA00AA4646 /* PKAudioPlayerEngine.h */ = {
uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {830, 6990}}";
+ sepNavIntBoundsRect = "{{0, 0}, {830, 6032}}";
sepNavSelRange = "{2862, 0}";
- sepNavVisRange = "{1954, 1371}";
+ sepNavVisRange = "{14997, 1820}";
sepNavWindowFrame = "{{130, 97}, {889, 671}}";
};
};
@@ -156,6 +156,14 @@
sepNavWindowFrame = "{{84, 139}, {889, 671}}";
};
};
+ 1EE97A58124D80EA00AA4646 /* PKScheduledDataSlice.cpp */ = {
+ uiCtxt = {
+ sepNavIntBoundsRect = "{{0, 0}, {916, 1287}}";
+ sepNavSelRange = "{2737, 0}";
+ sepNavVisRange = "{1625, 1347}";
+ sepNavWindowFrame = "{{15, 160}, {975, 713}}";
+ };
+ };
1EE97A5A124D80EA00AA4646 /* PKTaskQueue.cpp */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {439, 3300}}";
@@ -246,41 +254,41 @@
};
1EEBF2F31269DFEF002CC6CA /* PKAudioPlayer.h */ = {
uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {830, 1875}}";
- sepNavSelRange = "{3435, 0}";
- sepNavVisRange = "{3208, 1563}";
+ sepNavIntBoundsRect = "{{0, 0}, {830, 1703}}";
+ sepNavSelRange = "{1425, 0}";
+ sepNavVisRange = "{40, 1915}";
sepNavWindowFrame = "{{38, 181}, {889, 671}}";
};
};
1EEBF2F51269E012002CC6CA /* PKAudioPlayerInternal.h */ = {
uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {830, 750}}";
- sepNavSelRange = "{568, 0}";
- sepNavVisRange = "{225, 1073}";
+ sepNavIntBoundsRect = "{{0, 0}, {830, 689}}";
+ sepNavSelRange = "{638, 0}";
+ sepNavVisRange = "{152, 1100}";
sepNavWindowFrame = "{{15, 202}, {889, 671}}";
};
};
1EEBF2F91269E033002CC6CA /* PKAudioPlayer.cpp */ = {
uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {830, 10110}}";
- sepNavSelRange = "{6067, 0}";
- sepNavVisRange = "{5290, 1496}";
- sepNavWindowFrame = "{{61, 160}, {889, 671}}";
+ sepNavIntBoundsRect = "{{0, 0}, {830, 9945}}";
+ sepNavSelRange = "{6045, 0}";
+ sepNavVisRange = "{5583, 1092}";
+ sepNavWindowFrame = "{{38, 181}, {889, 671}}";
};
};
1EEBF474126A16E8002CC6CA /* PKAudioEffect.h */ = {
uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {830, 1245}}";
+ sepNavIntBoundsRect = "{{0, 0}, {830, 1079}}";
sepNavSelRange = "{2974, 0}";
- sepNavVisRange = "{0, 1090}";
+ sepNavVisRange = "{0, 1302}";
sepNavWindowFrame = "{{61, 160}, {889, 671}}";
};
};
1EEBF475126A16E8002CC6CA /* PKAudioEffect.cpp */ = {
uiCtxt = {
- sepNavIntBoundsRect = "{{0, 0}, {830, 3915}}";
- sepNavSelRange = "{2464, 0}";
- sepNavVisRange = "{4074, 880}";
+ sepNavIntBoundsRect = "{{0, 0}, {830, 3393}}";
+ sepNavSelRange = "{419, 0}";
+ sepNavVisRange = "{0, 839}";
sepNavWindowFrame = "{{61, 160}, {889, 671}}";
};
};

0 comments on commit 69427da

Please sign in to comment.