Как затухнуть объект NSSound

Я написал дешевую и веселую звуковую плату для своего 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];
    }
}

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


person Stuart Grimshaw    schedule 13.11.2008    source источник


Ответы (3)


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

-(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 наносекунд на самом деле не так уж и долго, не так ли :-)

person Stuart Grimshaw    schedule 16.11.2008

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

person Marc Charbonneau    schedule 19.11.2008
comment
Не могли бы вы уточнить, как именно вы будете использовать NSTimer? - person Matt; 21.07.2015

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

if([nowPlaying isPlaying])  {
    for(int i = 1; i < 100; ++i)
    {
        [nowPlaying setVolume: (1.0 / i)];
        Sleep(20);
    }
    [nowPlaying stop];
    wasPlaying = TRUE;
}
person Chris Blackwell    schedule 14.11.2008
comment
Я только что попробовал этот Крис, функция сна усыпила весь ноутбук, что заставило меня хихикнуть. sleep работает нормально, за исключением параметра, который он принимает в секундах, а не в миллисекундах. - person Stuart Grimshaw; 15.11.2008
comment
Будь проклята твоя заблудшая клавиша Shift! - person Chris Blackwell; 18.11.2008