NSSound 无法正常工作

Posted

技术标签:

【中文标题】NSSound 无法正常工作【英文标题】:NSSound not working properly 【发布时间】:2011-06-08 14:32:04 【问题描述】:

我在 Mac 10.6 上使用 Cocoa。我试图让节拍器点击时间,但是当我运行代码时,只播放前两个声音,然后它是安静的,直到再次播放声音时结束。如果我用 NSBeep() 替换 [player play] 语句,它工作正常。有什么建议吗?

#import <Cocoa/Cocoa.h>


@interface Metronome : NSObject 

NSInteger timeSig;
NSInteger noteValue;
NSInteger bpm;
NSUInteger beatNumber;
CGFloat duration;
NSSound *tickPlayer;
NSSound *tockPlayer;


@property(readwrite) NSInteger timeSig;
@property(readwrite) NSInteger noteValue;
@property(readwrite) NSInteger bpm;
@property(readwrite) float duration;
@property(readwrite) NSUInteger beatNumber;

-(id)init;
-(id)initWithTimeSig:(NSInteger)ts  andNoteValue:(NSInteger)nv andBpm:(NSInteger)bp;
-(void)BeginMetronome;
 -(void)PlaySound;

@end

#import "Metronome.h"

 #define defaultBpm 80
 #define defaultTimeSig 4
 #define defaultNoteValue 4

 @implementation Metronome

 @synthesize timeSig, noteValue, duration, bpm, beatNumber;
 -(id)init
return [self initWithTimeSig:defaultTimeSig andNoteValue:defaultNoteValue       andBpm:defaultBpm];
 
 -(id)initWithTimeSig:(NSInteger)ts andNoteValue:(NSInteger)nv andBpm:(NSInteger)bp 
[super init];
if(self)
    self.timeSig = ts;
    self.noteValue = nv;
    self.bpm = bp;
    self.duration = 60.0/bpm;
    tickPlayer = [NSSound soundNamed:@"Hat1"];
    tockPlayer = [NSSound soundNamed:@"Hat2"];
    self.beatNumber = 1;



return self;
 
 -(void)BeginMetronome
BOOL continuePlaying = YES;
NSInteger iter=0;

while (continuePlaying)
    if(iter > 12)
        continuePlaying = FALSE;
    
    iter++;
    [self PlaySound];
    NSDate *curtainTime = [[NSDate alloc] initWithTimeIntervalSinceNow:self.duration];
    NSDate *currentTime = [[NSDate alloc] init];

    while (continuePlaying && ([currentTime compare:curtainTime] != NSOrderedDescending))  
        // if ([soundPlayerThread isCancelled] == YES) 
        //   continuePlaying = NO;
        //
        //[NSThread sleepForTimeInterval:0.01];
        sleep(.01);
        //[tickPlayer stop];
        //[tockPlayer stop];
        [currentTime release];
        currentTime = [[NSDate alloc] init];
    
    [curtainTime release];      
    [currentTime release];      



  - (void)PlaySound           //***********Problem in this loop
if ([tickPlayer isPlaying])
    [tickPlayer stop];
if ([tockPlayer isPlaying])
    [tockPlayer stop];

if (beatNumber == 1) 
    [tockPlayer play];

else if (beatNumber == 2)
    [tickPlayer play];

else if (beatNumber == self.timeSig) 
    beatNumber = 0;
    [tickPlayer play];

else
    //[tickPlayer stop];
    [tickPlayer play];
    NSBeep();



beatNumber++;
//NSLog(@" %d ", beatNumber);
 // NSBeep();
 



 @end

【问题讨论】:

【参考方案1】:

我相信您对 sleep() 的使用阻止了 NSSound 的播放。这是一种非常草率的方法,而是使用这样的计时器:

static NSInteger iter;

- (void) beginMetronome 

    iter = 0;

    NSTimer *timer = [NSTimer timerWithTimeInterval:self.duration target:self selector:@selector(continueMetronome:) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
    [timer fire];    


- (void) continueMetronome:(NSTimer *)theTimer 

    [self PlaySound];

    if (++iter > 12) 

        [theTimer invalidate];
    

此外,您必须保留计划在 init 方法中使用的声音。

tickPlayer = [[NSSound soundNamed:@"Hat1"] retain];
tockPlayer = [[NSSound soundNamed:@"Hat2"] retain];

而且 Cocoa 方法应该像我写的那样以小写字母开头。我不太确定节拍器应该如何工作,因此您可能需要将 12 的值更改为其他值。

【讨论】:

以上是关于NSSound 无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

mongoose 中的 UpdateMany 无法正常工作,但直接在 mongodb 中可以正常工作

简单的 C# 应用程序无法正常工作,在 Visual Studio 中运行时工作正常

AVPlayer 无法正常工作 - Swift

Bootstrap - 按钮切换无法正常工作

xmppframework 的 didReceive 存在无法正常工作

iOS 13 UITextView 将 UITextView 转换为图像无法正常工作。在 iOS 12 以下正常工作