简单的节拍器iPhone应用程序

时间:2012-01-16 00:53:43

标签: iphone ios audio

我正在尝试构建一个简单的节拍器应用程序,我想知道是否有任何示例代码或开源项目可供学习。我认为苹果曾经拥有它但不再拥有它。我认为它不应该那么难但我很想知道如何加载音频,如何设置定时器并相应地循环音频。任何帮助非常感谢。

4 个答案:

答案 0 :(得分:3)

Apple的Metronome应用程序仍可在iOS 4.2库中使用。

在Xcode中,只需转到Window - > Organizer
然后转到Documentation窗格并搜索Metronome 节拍器项目将显示在“示例代码”部分下。

您可以转到偏好设置 - >确保您拥有iOS 4.2库。下载 - >记录并确保iOS 4.2库在您的列表中。

所以......截至2015年夏季,Apple对其网站的重新设计似乎打破了这些链接。我找到了.xar格式http://devimages.apple.com/docsets/20101122/com.apple.adc.documentation.AppleiOS4_2.iOSLibrary.Xcode4.xar中的docket链接,你可以下载然后使用xar -xf <docsetfilename>命令行工具或者unarchiver应用程序提取。

答案 1 :(得分:2)

我尝试过NSTimer,但如果您正在寻找Pro Metronome,这不是一个好的解决方案。您需要一个核心引擎,将时间推到需要的位置。 NSTimer让你只需循环无法获得所需精度的时空。

现在看,iOS 5让您使用Music Sequencer,这是音乐应用程序的一个很好的解决方案。它有一个核心引擎来控制时间。

答案 2 :(得分:0)

这是我之前制作的一个节拍器项目,它相当简单但它应该有所帮助,如果你使用它只是引用我,Jordan Brown 15y Mango Apps。它花了一段时间才做,但从来没有用它做过应用程序。

        //.h
NSTimer *timer;
int count;
float bpm;
float speed;
UILabel *numberLabel;
IBOutlet UISwitch *vibrate;
IBOutlet UISegmentedControl *timing;
 }
 - (IBAction)up;
 - (IBAction)down;
 - (IBAction)stop:(id)sender;
 @property (nonatomic, retain)IBOutlet UILabel *numberLabel;
 @property (nonatomic, retain)IBOutlet UILabel *bpmLabel;

 @property (nonatomic, retain)IBOutlet UISegmentedControl *timing;



 //.m
  #define SECONDS 60
  #import <AudioToolbox/AudioToolbox.h>

 @implementation metronome
  @synthesize numberLabel; // labels
  @synthesize bpmLabel;
  @synthesize timing; 

-(IBAction)stop:(id)sender{
[timer invalidate];
[self performSelector:@selector(playTockSound)];
numberLabel.text = [NSString stringWithFormat:@"%i",count];
bpm = bpm;
if (bpm > 300) {
    bpm = 300;
}
int new = bpm;

bpmLabel.text = [NSString stringWithFormat:@"%i",new];
speed = INFINITY;

NSLog(@"%f",speed);
timer = [NSTimer scheduledTimerWithTimeInterval:speed target:self selector:@selector(updateNumber) userInfo:nil repeats:YES];

}
 -(IBAction)up{
 [timer invalidate];
count = 1;
[self performSelector:@selector(playTockSound)];
numberLabel.text = [NSString stringWithFormat:@"%i",count];
bpm = bpm+10;
if (bpm > 300) {
    bpm = 300;
}
int new = bpm;

bpmLabel.text = [NSString stringWithFormat:@"%i",new];
speed = SECONDS/bpm;

NSLog(@"%f",speed);
timer = [NSTimer scheduledTimerWithTimeInterval:speed target:self selector:@selector(updateNumber) userInfo:nil repeats:YES];
 }
-(IBAction)down{
 [timer invalidate];
count = 1;
[self performSelector:@selector(playTockSound)];
numberLabel.text = [NSString stringWithFormat:@"%i",count];
bpm = bpm-10;
if (bpm < 10) {
    bpm = 10;
}
int new = bpm;

bpmLabel.text = [NSString stringWithFormat:@"%i",new];
speed = SECONDS/bpm;
NSLog(@"%f",speed);
timer = [NSTimer scheduledTimerWithTimeInterval:SECONDS/bpm target:self               selector:@selector(updateNumber) userInfo:nil repeats:YES];

  }
  -(void)updateNumber{
count += 1;
//if 4/4 timing is selected then the count wont go past 4
if (timing.selectedSegmentIndex == 2) {
if (count >= 5) {
    count = 1;
}
}

//if 3/4 timing is selected then the count wont go past 3
if (timing.selectedSegmentIndex == 1) {
    if (count >= 4) {
        count = 1;
    }
}

//if 2/4 timing is selected then the count wont go past 2
if (timing.selectedSegmentIndex == 0) {
    if (count >= 3) {
        count = 1;
    }
}    
  //In each timing case it plays the sound on one and depending 
  //on the limitiations on the cont value the amount of each tick 
      if (count == 1) {
    [self performSelector:@selector(playTockSound)];
}else {
    [self performSelector:@selector(playTickSound)];
}

numberLabel.text = [NSString stringWithFormat:@"%i",count];
  }
  -(void)playTickSound
  {
NSString *path = [[NSBundle mainBundle] pathForResource:@"tick" 
                                                 ofType:@"caf"];
SystemSoundID soundID;
    AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:path]
                                 , &soundID);
  AudioServicesPlaySystemSound (soundID);




  }
  -(void)playTockSound
  {
NSString *path = [[NSBundle mainBundle] pathForResource:@"tock" 
                                                 ofType:@"caf"];

SystemSoundID soundID;
AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:path]
                                 , &soundID);
     AudioServicesPlaySystemSound (soundID);



  - (void)didReceiveMemoryWarning
  {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];

// Release any cached data, images, etc that aren't in use.
  }


  - (void)viewDidLoad
  {
bpm = 60.00;
speed = SECONDS/bpm;
timer = [NSTimer scheduledTimerWithTimeInterval:speed target:self selector:@selector(updateNumber) userInfo:nil repeats:YES];
int new = bpm;

bpmLabel.text = [NSString stringWithFormat:@"%i",new];
[super viewDidLoad];

  }

答案 3 :(得分:0)

就谷歌而言,这是我对此的调查结果。我已经尝试了Apple示例方法(使用后台线程)和NSTimer方法,到目前为止的赢家是使用线程。在主(UI)线程上运行时,没有办法让NSTimer足够准确地触发。我想你可以在后台运行一段时间,但Apple的例子确实非常有用。

相关问题