How to fade out an NSSound object

I wrote a cheap and fun soundbar for my Mac, and I play various sounds using NSSound as follows:

-(void)play:(NSSound *)soundEffect:(BOOL)stopIfPlaying {
    BOOL wasPlaying = FALSE;

    if([nowPlaying isPlaying])  {
        [nowPlaying stop];
        wasPlaying = TRUE;
    }   

    if(soundEffect != nowPlaying)
    {
        [soundEffect play];
        nowPlaying = soundEffect;
    } else if(soundEffect == nowPlaying && ![nowPlaying isPlaying] && !wasPlaying) {
        [nowPlaying play];
    }
}

Instead of just stopping him dead, I would like him to disappear in a few seconds or so.

+5
source share
3 answers

This is the final version of the method:

-(void)play:(NSSound *)soundEffect:(BOOL)stopIfPlaying {
    BOOL wasPlaying = FALSE;

    if([nowPlaying isPlaying])  {
        struct timespec ts;
        ts.tv_sec = 0;
        ts.tv_nsec = 25000000;

        // If the sound effect is the same, fade it out.
        if(soundEffect == nowPlaying)
        {
            for(int i = 1; i < 30; ++i)
            {
                [nowPlaying setVolume: (1.0 / i )];
                nanosleep(&ts, &ts);
            }           
        }

        [nowPlaying stop];
        [nowPlaying setVolume:1];
        wasPlaying = TRUE;
    }   

    if(soundEffect != nowPlaying)
    {
        [soundEffect play];
        nowPlaying = soundEffect;
    } else if(soundEffect == nowPlaying && ![nowPlaying isPlaying] && !wasPlaying) {
        [nowPlaying play];
    }
}

Thus, it only disappears if I miss the same sound (that is, I press the same button), I also went to the sediment, and not to sleep, since it has a granularity of 1 second.

I tried my best to understand why my 200 millisecond delay didn’t show any effect, but then 200 NANOseconds really didn’t take so long :-)

+1

NSTimer, .

+1

Is something like this possible? You probably want a more linear fall, but the main idea is to create a loop and a sleeping period of time until the next update.

if([nowPlaying isPlaying])  {
    for(int i = 1; i < 100; ++i)
    {
        [nowPlaying setVolume: (1.0 / i)];
        Sleep(20);
    }
    [nowPlaying stop];
    wasPlaying = TRUE;
}
0
source

All Articles