代码之家  ›  专栏  ›  技术社区  ›  Stuart Grimshaw

如何使声音对象淡入淡出

  •  5
  • Stuart Grimshaw  · 技术社区  · 17 年前

    -(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 回复  |  直到 17 年前
        1
  •  1
  •   Stuart Grimshaw    17 年前

    -(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纳秒实际上并没有那么长,是吗:-)

        2
  •  1
  •   Marc Charbonneau    17 年前

    我会使用NSTimer来避免阻塞主线程。

        3
  •  0
  •   Chris Blackwell    17 年前

    也许是这样的?你可能想要一个更线性的衰减,但基本的想法是做一个循环,并在一段时间内休眠,直到下一次更新。

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