Objective c 声音不正常
我在Mac 10.6上使用Cocoa。我试图让节拍器按出时间,但当我运行代码时,只有前两个声音被播放,然后它是安静的,直到最后一个声音再次播放。如果我用NSBeep()替换[player play]语句,效果会很好。有什么建议吗Objective c 声音不正常,objective-c,cocoa,nssound,Objective C,Cocoa,Nssound,我在Mac 10.6上使用Cocoa。我试图让节拍器按出时间,但当我运行代码时,只有前两个声音被播放,然后它是安静的,直到最后一个声音再次播放。如果我用NSBeep()替换[player play]语句,效果会很好。有什么建议吗 #import <Cocoa/Cocoa.h> @interface Metronome : NSObject { NSInteger timeSig; NSInteger noteValue; NSInteger bpm; NSUInteger be
#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
#导入
@接口节拍器:NSObject{
NSInteger-timeSig;
NSInteger值;
NSInteger-bpm;
整数位数;
CGFloat持续时间;
NSSound*滴答声播放器;
NSSound*tockPlayer;
}
@属性(读写)NSInteger timeSig;
@属性(读写)NSInteger noteValue;
@属性(读写)NSInteger bpm;
@属性(读写)浮动持续时间;
@属性(读写)编号;
-(id)init;
-(id)initWithTimeSig:(NSInteger)ts和noteValue:(NSInteger)nv和BPM:(NSInteger)bp;
-(无效)开始节拍器;
-(空)播放声音;
@结束
#导入“Metronome.h”
#定义defaultBpm 80
#定义defaultTimeSig 4
#定义defaultNoteValue 4
@实施节拍器
@综合timeSig、noteValue、duration、bpm、beatNumber;
-(id)init{
返回[self-initWithTimeSig:defaultTimeSig和NoteValue:defaultNoteValue和BPM:defaultBpm];
}
-(id)initWithTimeSig:(NSInteger)ts和noteValue:(NSInteger)nv和BPM:(NSInteger)bp{
[超级初始化];
如果(自我){
self.timeSig=ts;
self.noteValue=nv;
self.bpm=bp;
self.duration=60.0/bpm;
tickPlayer=[NSSound SoundName:@“Hat1”];
tockPlayer=[nssoundsoundnamed:@“Hat2”];
self.beatNumber=1;
}
回归自我;
}
-(无效)开始节拍器{
BOOL continueplay=是;
NSInteger-iter=0;
同时(继续播放){
如果(iter>12){
继续播放=错误;
}
iter++;
[自我播放声音];
NSDate*curtainTime=[[NSDate alloc]initWithTimeIntervalSinceNow:self.duration];
NSDate*currentTime=[[NSDate alloc]init];
while(continuePlaying&([currentTime比较:curtainTime]!=sensorderedescending)){
//如果([soundPlayerThread isCancelled]==是){
//继续播放=否;
//}
//[NSThread sleepForTimeInterval:0.01];
睡眠(.01);
//[滴答声];
//[TOCKPAYER stop];
[当前时间释放];
currentTime=[[NSDate alloc]init];
}
[缩短释放时间];
[当前时间释放];
}
}
-(void)播放声音{//**********此循环中存在问题
如果([tickPlayer显示])
[滴答声];
如果([TockPayer显示])
[TOCKPAYER stop];
如果(beatNumber==1){
[tockPlayer play];
}
else if(beatNumber==2){
[玩家游戏];
}
else if(beatNumber==self.timeSig){
beatNumber=0;
[玩家游戏];
}
否则{
//[滴答声];
[玩家游戏];
NSBeep();
}
beatNumber++;
//NSLog(@“%d”,编号);
//NSBeep();
}
@结束
我相信您使用sleep()会阻碍声音的播放。这是一种非常草率的方法,而是使用如下计时器:
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的值更改为其他值