Detecting AUv3 invalidations in a host app (iOS) - objective-c

I'm working on a AUv3 host app, and I want the users to be notified when a loaded audio unit crashes (gets invalidated) for some reason. I looked at Apple's documentations about AUAudioUnit, but couldn't find any information about how to detect an invalidation of an audio unit (AUv3) from the host app.
Does anyone know how to do this?
Thanks

when setting up your AudioEngine you can observe kAudioComponentInstanceInvalidationNotification to figure out if its audio component instance was invalidated later on.
[[NSNotificationCenter defaultCenter] addObserverForName:kAudioComponentInstanceInvalidationNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
AUAudioUnit *auUnit = (AUAudioUnit *)note.object;
NSValue *val = note.userInfo[#"audioUnit"];
AudioUnit auAddress = (AudioUnit)val.pointerValue;
NSLog(#"AudioComponent Invalidation of Unit:%# with Address:%p", auUnit, auAddress);
}];
keep in mind that you may have got the notification but the component ended up in a deadlock. So when trying to recover from that you may have to turn down the whole host app.

Related

Unable to receive NSWorkspaceActiveSpaceDidChangeNotification specifically, but other notifications work

-(void)monitor {
NSNotificationCenter *notcenter;
notcenter = [[NSWorkspace sharedWorkspace] notificationCenter];
[notcenter addObserver:self selector:#selector(activeSpaceDidChange:) name:NSWorkspaceActiveSpaceDidChangeNotification object:[NSWorkspace sharedWorkspace]];
- (void) activeSpaceDidChange:(NSNotification *)notification
{
NSLog(#"%#", notification.name);
}
Hey guys, does anyone have any info on this specific notification? For some reason, I seem to be able to get all other notifications, and if I put in nil for the name and receive all NSWorkspace messages, I can get all of them except NSWorkspaceActiveSpaceDidChangeNotification. All code snippets I have seen from people don't seem to be doing anything specific or different than what I have, so I have no idea why I wouldn't be able to get these notifications specifically.

How to observe notifications from a different application?

I'd like to get notified when a certain application triggers an event. I'm not an Objective-C developer nor do I know the OS X APIs—so I hope this question is not too basic.
My goal is to write the meta info of the currently playing song to a log file. For iTunes, I got this working with the following Objective-C line:
[[NSDistributedNotificationCenter defaultCenter]
addObserver: myObserver selector: #selector(observeNotification:)
name: #"com.apple.iTunes.playerInfo" object:nil];
However, I also need this for AirServer (which is an software AirPlay receiver). Unfortunately, the following doesn't work—the observer never gets called:
[[NSDistributedNotificationCenter defaultCenter]
addObserver: myObserver selector: #selector(observeNotification:)
name: #"com.pratikkumar.airserver-mac" object:nil];
So apparently, AirServer does not send these type of notifications. However, there's a notification in the Notification Center when a new song starts playing.
My next step would be to periodically check for new notifications in the OS X Notification Center (as described here: https://stackoverflow.com/a/25930769/1387396). This is not too clean though—so my questions is: is there another option in this particular case?
Catalina silently changed the addObserver behavior - you can no longer use a nil value for the name to observe all notifications - you have to pass in a name. This makes discovery of event names more difficult.
Firstly, you have to understand that while the NSDistributedNotificationCenter has the word Notification in it; it's not related. From the About Local Notifications and Remote Notifications, it does state:
Note: Remote notifications and local notifications are not related to broadcast notifications (NSNotificationCenter) or key-value observing notifications.
So, at that point, I'm going to answer from the perspective of NSDistributedNotificationCenter, and not about Remote/Local notifications - you already have a potential solution in the answer you linked for observing the DB file that contains a record of the notifications in that way.
This example code will not work on Catalina (10.15) because of API behavior changes
The first thing you need to do is listen for the correct notification. Creating a simple application that listens for all events; e.g. using:
NSDistributedNotificationCenter *center = [NSDistributedNotificationCenter defaultCenter];
[center addObserver:self
selector:#selector(notificationEvent:)
name:nil
object:nil];
-(void)notificationEvent:(NSNotification *)notif {
NSLog(#"%#", notif);
}
It indicates that the notifications are:
__CFNotification 0x6100000464b0 {name = com.airserverapp.AudioDidStart; object = com.pratikkumar.airserver-mac; userInfo = {
ip = "2002:d55e:dbb2:1:10e0:1bfb:4e81:b481";
remote = YES;
}}
__CFNotification 0x618000042790 {name = com.airserverapp.AudioDidStop; object = com.pratikkumar.airserver-mac; userInfo = {
ip = "2002:d55e:dbb2:1:10e0:1bfb:4e81:b481";
remote = YES;
}}
This indicates that the name parameter in the addObserver call should be com.airserverapp.AudioDidStart and com.airserverapp.AudioDidStop.
You can use code like that to determine all notifications, which will allow you to add the relevant observers when you want the particular observer. This is probably the easiest way to observe notifications of this type.

NSNotificationCenter has a maximum speed?

Using NSNotificationCenter , it worked well till i have started to send very fast messages to other class.
What is fast ? its about 30-40 notifications in second. and i dont get even 1 of them .
is there other way to do that ?
should i update a global instead ?
//post data out .
- (void)post:(NSString*)string
{
NSLog(#"done"); //the log is printing
NSDictionary *userInfo = nil;
[[NSNotificationCenter defaultCenter] postNotificationName:#"connector"
object:string
userInfo:userInfo];
}
I know the observer is good cause same code worked before .
Thanks a lot .
If you're sending 30-40 notifications a second you should really think about your implementation again.
Heres some alternatives:
Creating your own delegates for callbacks
Using a block
The problem with NSNotificationCentre is that it sends the message to every observer - this can get slow and is generally used for updating views on state change (Login/Logout).
It looks like you setting the wrong object, Which should be the object that posts the notification (or nil). What I think you should be doing adding the string to userInfo:
NSDictionary *userInfo = #{#"somekey" : string };
[[NSNotificationCenter defaultCenter] postNotificationName:#"connector"
object:self
userInfo:userInfo];

How to verify network connectivity in objective-c

I was looking over the Reachability sample project on developer.apple.com and found that it was a large project just to verify you had network connectivity.
First part of the question is "What is the minimum code required to find out if the device can reach a 3G or wifi network?"
And next should this be done inside the appDelegate (on start) or inside the first View Controller that is launched?
Thank you in advance
It's not large, it really does what you want. If it is too big for you, you can extract what you need only like reachabilityForLocalWiFi. But I'm afraid that it will not be much smaller.
Yes, you can use reachability in your application delegate or inside the first view controller.
Reachability notification registration ...
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(networkReachabilityDidChange:)
name:kReachabilityChangedNotification
object:nil];
__reachability = [[Reachability reachabilityWithHostName:#"www.google.com"] retain];
[__reachability startNotifier];
... callback method example ...
- (void)networkReachabilityDidChange:(NSNotification *)notification {
Reachability *reachability = ( Reachability * )[notification object];
if ( reachability.currentReachabilityStatus != NotReachable ) {
// Network is available, ie. www.google.com
} else {
// Network is not available, ie. www.google.com
}
}
... do not forget to stop notifications, remove observer and release rechability object.

iPhone MPMoviePlayerController lost sound while playing video on a real device

I am having issue with losing "video" sound while it was playing.
I followed all the standards but the Video/Audio sometimes gets muted or just disappears at the end of the video file. I have no idea why. Does any know what might be the issue?
This only happens when running the app on the real device, I can't reproduce the issue on the simulator.
Could a "didReceiveMemory" warning cause this? I sometimes receive this message when it happens.
The video file is being streamed via a URL address, format in MPEG-4 Movie, size less than 6.2 MB.
I have the following code:
- (IBAction) playMovie:(NSString*)theUrl
setMovieType:(NSString *)theType
setPlayOption:(int)theOption
setSenderUIButton:(UIButton *) thisSender
{
NSString *getvdoUrl = [[NSString alloc] initWithString:theUrl];
NSURL *thisVdoURL = [NSURL URLWithString:getvdoUrl];
[getvdoUrl release];
getvdoUrl = nil;
MPMoviePlayerController *movieplayer = [[MPMoviePlayerController alloc]
initWithContentURL:thisVdoURL];
thisVdoURL = nil;
if (movieplayer)
{
self.vdoPlayer = movieplayer;
[movieplayer release];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:self.vdoPlayer];
[self.vdoPlayer play];
}
}
-(void) moviePlayBackDidFinish:(NSNotification*)theNotification
{
MPMoviePlayerController *movieplayer= [theNotification object];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:movieplayer];
movieplayer.initialPlaybackTime = 0.0;
[movieplayer stop];
}
Below are the warning messages. I received them before the Video file started to play:
warning: Unable to read symbols for
"/Developer/Platforms/iPhoneOS.platform/DeviceSupport/3.1.3
(7E18)/Symbols/System/Library/VideoDecoders/VCH263.videodecoder"
(file not found).
warning: Unable to read symbols for
"/Developer/Platforms/iPhoneOS.platform/DeviceSupport/3.1.3
(7E18)/Symbols/System/Library/VideoDecoders/H264H1.videodecoder"
(file not found).
warning: Unable to read symbols for
"/Developer/Platforms/iPhoneOS.platform/DeviceSupport/3.1.3
(7E18)/Symbols/System/Library/VideoDecoders/MP4VH1.videodecoder"
(file not found).
2010-03-29 16:57:25.830 ....
v2[4663:207] setting
file:///private/var/mobile/Applications/7DCB1FCC-7268-4551-B737-8B418CA4A07E/tmp/MediaCache/[html]
You should try a different MP4 file, they are not all equal - they should be optimized for streaming if you are creating them from Quicktime - "hinted" if your create them with the help of mp4box for example. There could be issue with your file audio timestamps - try playing it via safari browser and/or quicktime if there would be any issues . I guess you follow the maximum bitrate/profile/level settings for H264 and AAC as well .
If you really are running out of memory in your phone, this can happen, the mediaplayer runs in separated process- not direcly in your application (I guess to allow it to use GPU decoder and sandbox it).
Are you playing this video just once in the app ? Are you removing the notification afterwards? - it is usually enough to register it just once even before playing video.
Something depends on which firmware are you compiling under and running under, bugs tend to be fixed in later versions, but from 4.0 whole API changed and code needs to be updated as well...
The warning messages are useless and common for simulator - they are just from simulator trying to reach debugging symbols for modules outside of SDK - as simulator's Quicktime runs through your desktop Quicktime - you may see your soundcard driver and more codecs there depending on your setup.