我正在尝试使用AVAudioUnitSampler
创建钢琴乐器。我不想为每个钢琴琴键提供一个wav文件,而是希望AVAudioUnitSampler
插入两者之间的缺失值。例如,如果我为C3和D3提供一个wav文件,它应该能够使用其中一个生成C#3(C3和D3之间的注释)。在文档中,它提到您可以在文件名中提供范围,但是我不确定这是如何工作的,因为文档没有涉及太多细节。这是加载音频文件的方法的说明:
将音频文件加载到新乐器中,并将每个音频文件放置在其自己的采样器区域中。会使用音频文件中包含的有关它们在乐器中放置的任何信息,例如,根键,键范围。
这是我的工作代码:
Sampler.h
#import <Foundation/Foundation.h>
@interface Sampler : NSObject
@property double volume;
@end
Sampler.m
#import "Sampler.h"
@interface Sampler()
@property AVAudioEngine *engine;
@property AVAudioMixerNode *mixer;
@property AVAudioUnitSampler *sampler;
@end
@implementation Sampler
-(instancetype) init {
if (self = [super init]) {
[self initVolume];
[self loadSampler];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(midiPlayed:) name:@"MidiPlayedNotificationKey" object:nil];
}
return self;
}
-(void) initVolume {
_volume = 1.0; //CHANGE LATER
}
//loads the drum kit
-(void) loadSampler {
// Instatiate audio engine
_engine = [[AVAudioEngine alloc] init];
_mixer = [_engine mainMixerNode];
_sampler = [[AVAudioUnitSampler alloc] init];
[self loadSamples];
[self makeEngineConnections];
[self startEngine];
}
-(void) loadSamples {
NSString *instrument = @"PianoSamples";
NSArray *urls = [[NSBundle mainBundle] URLsForResourcesWithExtension:@"wav" subdirectory:instrument];
[_sampler loadAudioFilesAtURLs:urls error:nil];
}
-(void)makeEngineConnections {
[_engine attachNode:_sampler];
[_engine connect:_sampler to:_mixer format:[_sampler outputFormatForBus:0]];
}
-(void)startEngine {
[_engine startAndReturnError:nil];
}
//plays the sound when a MIDI note is played
-(void) midiPlayed:(NSNotification*)notification {
bool isKeyPlayed = [notification.userInfo[@"isKeyPlayed"] boolValue];
if (isKeyPlayed) {
int noteValue = [notification.userInfo[@"note"] intValue];
[_sampler startNote:noteValue withVelocity:_volume*127 onChannel:0];
NSLog(@"note value = %d", noteValue);
}
}
@end