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