Как исчезнуть объект NSSound - PullRequest
5 голосов
/ 14 ноября 2008

Я написал дешевую и веселую звуковую панель для моего Mac и играю различные звуки с помощью NSSound, например:

-(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];
    }
}

Вместо того, чтобы просто остановить его, я бы хотел, чтобы он исчез через пару секунд или около того.

Ответы [ 3 ]

1 голос
/ 17 ноября 2008

Это окончательная версия метода:

-(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];
    }
}

Таким образом, он исчезает только в том случае, если я передаю тот же звук (т. Е. Нажимаю одну и ту же кнопку), а также я предпочел наноспать, а не спать, поскольку он имеет зернистость 1 секунду.

Я некоторое время пытался понять, почему моя задержка в 200 миллисекунд, похоже, не имела никакого эффекта, но тогда 200 NANOseconds не так уж и длинны: -)

1 голос
/ 19 ноября 2008

Я бы использовал NSTimer, чтобы не блокировать основной поток.

0 голосов
/ 14 ноября 2008

Что-то вроде этого возможно? Возможно, вам нужен более линейный спад, но основная идея состоит в том, чтобы сделать цикл и перевести период ожидания до следующего обновления.

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