0

I have a very specific issue and I have not yet found a solution. I have an IBAction for a button press. What I want to happen when this button is pressed is:

  1. play a sound file (this is about 5 seconds long sound)

  2. flash words on the screen (this is also about 5 seconds long)

I want this to happen concurrently so total time is about 5 seconds (words flashing while sound is playing).

What I end up with is that the words flash first, then the sound plays. I can never get them to go concurrently. Interestingly also I can never get the sound to play first even when placed at the very start of the action.

I've tried NSThread the sound, exec, CATransaction flush, but nothing can get them concurrent.

any ideas, btw I am total beginner programmer so sorry if not described the proper way.

-(IBAction) playButtonClick:(id)sender {
   int i;

    [_audioPlayer play];

    for (i=0; i<10; i++){
      [self.model getNextWord];   
      [self displayWord];
      [CATransaction flush];
      usleep(550000);   // word on screen for 0.55 seconds
    }

}

[CATransaction flush] is required else all I would see would be the very last word.

Baxxter
  • 3
  • 3
  • sound takes some time to load, make sure your sound is in memory before the button becomes active. Using a lightweight sound effects player like [JSQSystemSoundPlayer](https://github.com/jessesquires/JSQSystemSoundPlayer) can come in handy. – ishaq Jan 28 '16 at 20:24
  • can you provide the IBAction function? – pkatsourakis Jan 28 '16 at 20:30
  • Will you supply the code where you are calling both functions? – CaptainBli Jan 28 '16 at 21:26
  • `usleep`? Thou shalt not hold the UI hostage. The `main` thread must be free wheeling. Consider this post: http://stackoverflow.com/questions/6835472/uilabel-text-not-being-updated – SwiftArchitect Jan 28 '16 at 21:49

1 Answers1

1

You have 2 tools at your disposal:

  • prepareToPlay()
  • playAtTime(_:)

Prepare so that the sound is in memory.

Calling this method preloads buffers and acquires the audio hardware needed for playback, which minimizes the lag between calling the play method and the start of sound output.

Wait until the rest of your UI is ready prior playing.

Use this method to precisely synchronize the playback of two or more AVAudioPlayer objects.

SwiftArchitect
  • 47,376
  • 28
  • 140
  • 179
  • Thanks for the info. It is working now as I envisioned. Also thanks to the pointer about usleep. I was able to remove the usleep and CATransaction flush and do things properly !! – Baxxter Jan 29 '16 at 00:31
  • I used both prepareToPlay and playAtTime. – Baxxter Jan 29 '16 at 18:38