MoMuというのを見つけたので、ソフトウェアシンセのキーボードを作ってみる。
(XcodeのiOS6 iPhone Simulatorで試しています。)
ポイント
ToolKitをXcodeで使えるようにする
-MoMu ToolKit 1.0.0
mo_audio.h
mo_audio.m
mo_def.h
momu.h をXcodeにコピーする
-MoMu-STK 1.0.0
フォルダごとXcodeにコピーする
参考
MoMu ToolKitは下記のアドレスから
http://momu.stanford.edu/toolkit/
サンプルコード
#import “ViewController.h”
#import <AudioToolbox/AudioToolbox.h>
#import <QuartzCore/QuartzCore.h>
#import “Stk.h”
#import “Mandolin.h”
#import “mo_audio.h”
using namespace stk;
struct AudioData {
Mandolin *myMandolin;
};
#define SRATE 441000
#define FRAMESIZE 128
#define NUMCHANNELS 2
// コールバック用 MoAudio::start()にはめ込む
void audioCallback(Float32 * buffer, UInt32 framesize, void* userData){
AudioData *data = (AudioData*)userData;
for (int i=0; i<framesize; i++) {
SAMPLE out = data->myMandolin->tick();
buffer[2*i] = buffer[2*i+1] = out;
}
}
@interface ViewController () {
struct AudioData audioData;
}
@end
@implementation ViewController
– (void)viewDidLoad
{
[super viewDidLoad];
// マンドリンを作る
[self createMandolin];
// 鍵盤を作る
[self createKeys];
}
– (void)createMandolin
{
audioData.myMandolin = new Mandolin(250);
audioData.myMandolin->setFrequency(400);
MoAudio::init(SRATE, FRAMESIZE, NUMCHANNELS);
MoAudio::start(audioCallback, &audioData);
}
– (void)createKeys
{
NSArray *keys = [@”1 2 3 4 5 6 7″ componentsSeparatedByString:@” “];
for (int i=0; i<[keys count]; i++) {
UILabel *keyboard = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 30, 80)];
keyboard.center = CGPointMake(i*60 + 60, 200);
keyboard.text = [keys objectAtIndex:i];
keyboard.backgroundColor = [UIColor brownColor];
keyboard.textAlignment = 1;
[self.view addSubview:keyboard];
// shadow
keyboard.layer.masksToBounds = NO;
keyboard.layer.shadowOffset = CGSizeMake(5, 5);
keyboard.layer.shadowRadius = 5;
keyboard.layer.shadowOpacity = 0.5;
// gesture
keyboard.userInteractionEnabled = YES;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap:)];
[keyboard addGestureRecognizer:tap];
}
}
– (void)tap:(UIGestureRecognizer*)gr
{
// タップでならす
UILabel *l = (UILabel*)gr.view;
int frequency = [self getNote:l.text];
audioData.myMandolin->setFrequency(frequency);
audioData.myMandolin->pluck(1);
CABasicAnimation *ba = [CABasicAnimation animationWithKeyPath:@”shadowOffset”];
ba.fromValue = [NSValue valueWithCGSize:l.layer.shadowOffset];
ba.toValue = [NSValue valueWithCGSize:CGSizeMake(0, 0)];
ba.duration = 0.2;
ba.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[l.layer addAnimation:ba forKey:@”shadowOffset”];
}
// 鍵盤のラベルでfrequencyを戻す
– (int)getNote:(NSString*)name
{
int result = 440;
if ([name isEqual:@”1″]) {
result = 262;
}
else if ([name isEqual:@”2″]) {
result = 294;
}
else if ([name isEqual:@”3″]) {
result = 330;
}
else if ([name isEqual:@”4″]) {
result = 349;
}
else if ([name isEqual:@”5″]) {
result = 392;
}
else if ([name isEqual:@”6″]) {
result = 440;
}
else if ([name isEqual:@”7″]) {
result = 494;
}
return result;
}
– (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
@end