I have a program which plays two sounds. I want the user to know which sound is being played, so I have two large images of buttons. I have three different views that I would like to swap between – one where both buttons are red (nothing is playing), and two where one of the two buttons is green (to show which is playing).
The main problem I am getting is that my sound plays and finishes before the view has swapped! (I am using [window setContentView:firstSound] before the sounds are played)
The altered view eventually does show up, but only after the method playing the wavs has finished.
I am playing the sound files using NSSound (they are both short wav files, so I thought it appropriate)
Anyone know what I have done wrong? Or if there is another way I could do this? Thanks heaps!!
Edit: I have followed the advice to make it so that only the image is changed (rather than the view), but the same problem occurs. The update happens after the sounds have finished playing.
Here’s the code:
-(void)readWavs{
//[window setContentView:firstWav];
[redButton setHidden:YES];
NSString *resourcePath = [[NSBundle mainBundle] pathForResource:@"fish" ofType:@"wav"];
NSSound *sound = [[NSSound alloc] initWithContentsOfFile:resourcePath byReference:YES];
[sound play];
sleep(3); //needed so that the sound will actually play
[sound stop];
[sound release];
//[redButton setHidden:NO];
//[window setContentView:testView];
sleep(2);
//[window setContentView:secondWav];
NSString *resourcePath2 = [[NSBundle mainBundle] pathForResource:@"fish" ofType:@"wav"];
NSSound *sound2 = [[NSSound alloc] initWithContentsOfFile:resourcePath2 byReference:YES];
[sound2 play];
sleep(3);
[sound2 stop];
[sound2 release];
}
The green ‘on’ button should show up before the sound plays, but it only does so after the method is done.
You’re blocking the run loop with those
sleep()s. The display isn’t updated until all the processing for the current event is finished, and that doesn’t happen until thisreadWavsmethod is finished.If you want to do something after the sound is finished, assign it a delegate (probably the same object that started the sound) and implement the NSSoundDelegate
-sound:didFinishPlaying:method. Then, inreadWavs, just start the sound and return – your delegate method will be called when it finishes, and becausereadWavsreturns immediately, it won’t block the run loop.