首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSSound不能正常工作

NSSound不能正常工作
EN

Stack Overflow用户
提问于 2011-06-08 22:32:04
回答 1查看 731关注 0票数 0

我在Mac10.6上使用Cocoa。我正在尝试让节拍器按下时间,但当我运行代码时,只播放前两个声音,然后它是安静的,直到最后再次播放声音。如果我将player play语句替换为NSBeep(),它可以很好地工作。有什么建议吗?

代码语言:javascript
复制
#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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-06-09 21:14:55

我相信您使用sleep()会阻碍NSSound的播放。这是一种非常草率的方式,而不是像这样使用计时器:

代码语言:javascript
复制
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方法中使用的声音。

代码语言:javascript
复制
tickPlayer = [[NSSound soundNamed:@"Hat1"] retain];
tockPlayer = [[NSSound soundNamed:@"Hat2"] retain];

Cocoa方法应该以小写字母开头,就像我写的那样。我不太确定节拍器是如何工作的,所以您可能必须将12的值更改为其他值。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6280453

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档