When does NSSpeechSynthesizer finish speaking? - macos

How can I know when NSSpeechSynthesizer finishes speaking?

You read the documentation for NSSpeechSynthesizer and discover the -speechSynthesizer:didFinishSpeaking: delegate method.
Then, if you're not sure how to use delegate methods, you read more documentation about Cocoa delegates.
Then, if you still can't get it to work, you post a separate question here including as many details as you can about what you've tried (hint: code, a description of your app and how things are connected, etc.) and what isn't working (ie, the delegate method is never called, it crashes, etc.).

Related

Editing waveform audio input before it reaches a application

I am working on a voice changer that is supposed to manipulate the input buffer of a waveform-audio input device before the buffer is returned to a application.
The waveInOpen()-function gives 4 options to be notified when the buffer provided by waveInAddBuffer() has been filled.
The options are CALLBACK_EVENT, CALLBACK_FUNCTION, CALLBACK_THREAD, CALLBACK_WINDOW.
I have tried several things to to get my waveform manipulation to work but haven't found a reliable and clean solution yet.
What worked so far was intercepting waveInAddBuffer()-calls with Detours. I am saving all WAVEHDR-pointer used by waveInAddBuffer() and each time the function is called I delay the program for a few miliseconds and search for waveform-buffers that have been filled during the delay.
This isn't reliable though because the buffer size differs for each application and therefore there isn't a delay-time that works for every application.
I would be really thankful for new ideas!
edit:
Heres the other stuff I have tried:
Most applications set multiple flags when calling waveInOpen() that actually exclude each other. So you can never be sure what callback method actually is used. (e.g.: the flags CALLBACK_EVENT | CALLBACK_FUNCTION | CALLBACK_WINDOW are all set.)
When the CALLBACK_WINDOW flag is set, I have used the SetWindowLongPtr() function to create a subclass window that received MM_WIM_DATA messages before the window of the application. Unfortunately this didn't work, my subclass window never gets called.
I have created a custom-callback function that I replace with the callback function of the application when the CALLBACK_FUNCTION flag is set.
This didn't work because my function never gets called. I guess this is because my function is defined in a DLL, outside of the address space of the application.
There were several other things I have tried that didn't work because I made attempts that never could have worked because I didn't know enough about injection and hooks. I have learned quite a lot and I cant really summarize everything I have tried, because it's not helping the cause.

When to create a custom NSNotificationCenter?

I've been playing about with the NSNotificationCenter and I've been wondering when you would use your own custom notification center rather than the defaultCenter? And what would the advantages of this be?
Forgive my ignorance, but it seems like I could get along quite happily just using the defaultCenter and nothing else, but I want to make sure I am not missing something vital.
Apple documentation is vague, and it just states that usually a programmer wouldn't need to create a new one:
Each running Cocoa program has a default notification center. You typically don’t create your own. An NSNotificationCenter object can deliver notifications only within a single program.
Full source: NSNotificationCenter documentation.
However every notification center can handle a network of notifications, distinguished by name and object. When you add an observer you typically call the method in some way like this:
[center addObserver: self selector: #selector(observe:) name: #"observe" object: someObject];
And when you post a notification you can specify the object:
[center postNotificationName: #"observe" object: someObject];
This way say that you use N names and M objects, you can handle N*M distinguished notifications. I think there is no need to use two notification centers. Theoretically if you have finished all names you can create another one using alloc+init, but I hardly see how it can actually turn out handy.
Also consider that notification center is often used when there are two objects that do not own a direct pointer to each other (otherwise why not simply calling a method on it?), due to avoid complicated bindings (specially when you use a lot of xib files), so having an unique notification center object is very handy.
If instead you use a notification center got with allot+init, then you must ensure that all the communicating objects have a pointer to that notification center, and this would add some complexity. All notification center's power would be wasted.
Although it's used heavily in AppKit via the defaultCenter singleton accessor, at it's heart, NSNotificationCenter is really just a "generic decoupling mechanism." Allowing you to alloc/init your own instances of it is just an expression of that generic-ness. If you wanted to use it for something else, you could.
To illustrate with a somewhat absurd example, think of it this way: NSDocument has a windowControllers accessor that returns a specific, blessed, important instance of NSArray that contains references to all the window controllers specific to that document. That said, NSArray is just a "generic list data structure". Just because there exists this special instance of it with a specified purpose doesn't mean it might not be useful to reuse NSArray for your own purposes. Both NSArray and NSNotificationCenter provide generic data structures/building blocks, specific instances of which are used in blessed "occupations" around AppKit, but both of which could be useful on their own.
The primary use case I've seen for creating standalone instances of NSNotificationCenter is when you want to run multiple instances of some complex subsystem on multiple threads in parallel and not have them potentially get confused by cross-thread notifications. In this case, the general pattern is to allocate one NSNotificationCenter per thread. This compartmentalizes the notifications for each network of objects to a single thread. This will generally be required if observers pass nil for the object parameter intending to listen to all notifications with a given name, regardless of source.
All that said, I concede that, in my experience, making private instances of NSNotificationCenter is pretty rare.
Apple's Doc
If your app uses notifications extensively, you may want to create and post to your own notification centers rather than posting only to the default notification center. When a notification is posted to a notification center, the notification center scans through the list of registered observers, which may slow down your app. By organizing notifications functionally around one or more notification centers, less work is done each time a notification is posted, which can improve performance throughout your app.

Is KillTimer really necessary?

This may seem to be a duplicate question for Is KillTimer necessary?, but i would like to confirm this with credible source.
Does destroying window really free the resource allocated by the OS for the timer? (does DestroyWindowsTimers really get called let alone if such function actually exists? if so, where?)
No, it is not necessary. From the documentation of DestroyWindow (with emphasis added):
The function sends WM_DESTROY and WM_NCDESTROY messages to the window to deactivate it and remove the keyboard focus from it. The function also destroys the window's menu, flushes the thread message queue, destroys timers, removes clipboard ownership, and breaks the clipboard viewer chain (if the window is at the top of the viewer chain).
Doing a google search the only actual real looking reference to it looked to be some Win2k source code. The url ended with /Censorship/win2k_sources/private/.../timers.c, I'm assuming from the source code leak a while back. I did not look at the code, nor will I post a link here.
That function most likely exist - something like that almost has to exist for timers linked to window handles - since the timer message is delivered to a specific window handle.
I can't see anywhere in the documentation that states that you don't have to call KillTimer to get rid of a timer. So based on the documented contract, you need to call KillTimer. In practice Windows will probably clean it up for you, but since that is undocumented behavior you should write your code to follow the documented behavior and call KillTimer on all your timers.

How to stop the termination of the application

I know that my question perhaps sound's a bit confusing, but I wan't to stop the terminating of a Cocoa Mac Os X application. I don't know if there is an API to that. And I also don't know how to do that.
My idea was to call an NSAlert inside the applicationWillTerminate: method. But that doesn't stop the termination of the App.
Another possibility would be to use a while loop, which doesn't stop, but this isn't any good practice, because it uses a lot of CPU and doesn't add any possibility of keeping the rest of the app running.
Please give me an idea, how I could solve this problem.
Much times thanks. =D
Implement the application delegate method applicationShouldTerminate:. Return either NSTerminateCancel or NSTerminateLater. If you return NSTerminateLater then you should eventually call replyToApplicationShouldTerminate: with your final answer.

Where does a cocoa app main() function go?

I'm trying to build a super-simple Cocoa app, basically one that has one function (for example, main()) with a while loop. It does some stuff, does a curl request, then waits a few seconds before starting over.
I've got my project all setup in XCode with all the necessary variables and functions, but I don't know where to put my main() function that does all the work.
Where do I define the main function?
Cocoa is very much oriented towards event-driven programming. That end, the main() function generally just starts up the main runloop and then the application delegate can kick off anything it wants to do. That said, it's certainly possible to write a non-event-based cocoa program that uses main() To do more complicated stuff. In that case, it works basically the same as in C.
Cocoa With Love just had a post about Minimalist Cocoa programming that may be of interest. It uses main() to do some work. It's not really something I would recommend emulating in your own app, but it's certainly possible.
If you design your app according to the usual Cocoa architecture, you don't really put any of your own code in main. The whole app should be event driven (where events are things like UI interactions from the user, network events, etc).
That said, there is a main function. If you've created a default Cocoa project in XCode, the main function will be in a file called "main.m". It will get run just like a main function in C. You'll see that there's a call in there to NSApplicationMain(). That's what starts a Cocoa application running (creates the application, loads the main nib file, starts running the main run loop, etc) . NSApplicationMain() doesn't return until the application quits, so if you really want to put stuff in main(), you need to put it above the call to NSApplicationMain().
Again, that's not the normal "Cocoa way" to do things, but without more info about what you want to do, it's hard to give you more advice.
As others have answered, it's possible to implement what you want to do in a way you suggested, i.e., by running a while loop inside main.
However, that is not the best way to write a Cocoa app which reloads a URL once in a few seconds. In a different environment, there's a different standard way to do things. So, you sometimes need to un-learn what you got used to. You might have thought: I want to do X. In language/environment A, I would have coded like P to do X. Now I'd like to use language/environment B. How should I implement P? That's not the way to get used to a new environment. Just ask, How should I do X in the environment B?
The most Cocoa-esque way would be this:
Open XCode, create a new project, choose a Cocoa GUI app from the template.
In the application delegate, implement applicationDidFinishLaunching:. We are going to set up an NSTimer.
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
NSTimer*timer=[NSTimer scheduledTimerWithTimeInterval:5
target:self
selector:#selector(timerFired:)
userInfo:nil
repeats:YES];
}
This creates a timer which fires once in five seconds, and at each time it fires it calls the method timerFired: of the app delegate itself, specified by self. For more on NSTimer, read this apple document.
Implement timerFired:.
- (void)timerFired:(NSTimer*)theTimer{
// do whatever you want. you can use plain C to invoke curl,
// or if you want you can use Cocoa methods to access a URL.
}
There's no fourth step!
The main function is provided by the template. It calls NSApplicationMain, which set up the Cocoa system. Eventually, it calls applicationDidFinishLaunching: of your delegate for you. You respond to that message. Then you set up a timer. The timer calls the method you specified for you. Then you respond to that message, again. That's basically how Cocoa works. The Cocoa system asks you to do something, so you do something. Your control over the flow of the program becomes rather passive, compared to what you would have programmed in Applescript.
To add to Andrew Madsen's answer, the best thing to do is start with an Xcode project template. It'll get a skeletal main(), a XIB, a plist, and other standard Cocoa stuff set up for you.

Resources