NSSound无法正常工作 [英] NSSound not working properly
问题描述
我在Mac 10.6上使用Cocoa。我试图让节拍器点击出去的时间,但是当我运行代码只有前两个声音播放,那么它是安静的,直到结束时,一个声音再次播放。如果我用NSBeep()替换[播放器播放]语句,它工作正常。有任何建议吗?
I am using Cocoa on Mac 10.6. I am trying to have a metronome click out the time but when I run the code only the first two sounds are played then it is quiet till the end when a sound plays again. If I replace the [player play] statements with NSBeep() it works fine. Any suggestions?
#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
推荐答案
我相信你使用sleep()阻止了NSSound的播放。这是一个非常疯狂的方式来做到这一点,而是使用一个定时器,如:
I believe your use of sleep() is blocking the playing of NSSound. That's a very sloppy way to do this, instead use a timer like so:
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];
}
}
此外,您必须保留您计划的声音
Also, you must retain the sounds that you plan to use in your init method.
tickPlayer = [[NSSound soundNamed:@"Hat1"] retain];
tockPlayer = [[NSSound soundNamed:@"Hat2"] retain];
Cocoa方法应该以小写字母开头,就像我写的。我不太确定metronomes应该如何工作,所以你可能不得不改变12的值到别的东西。
And Cocoa methods should start with a lowercase letter like I've written them. I'm not too sure how metronomes are supposed to work, so you may have to change the value of 12 to something else.
这篇关于NSSound无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!