4

I'm trying to play instrument of several .wav samples using AudioKit.

I've tried so far:

  1. Using AKSampler (with underlying AVAudioUnitSampler) – it worked fine, but I can't figure out how to control ADSR envelope here – calling stop will stop note immediately.
  2. Another way is to use AKSamplePlayer for each sample and play it, manually setting rate so it play the right note. I can (possibly?) then connect AKAmplitudeEnvelope to each sample player. But if I want to play 5 notes of the same sample simultaneously, I would need 5 instances of AKSamplePlayer, which seems like wasting resources.

I also tried to find a way to just push raw audio samples to the AudioKit output buffer, making mixing and sample interpolation by myself (in C, probably?). But didn't find how to do it :(

What is the right way to make a multi-sampled instrument using AudioKit? I feel like it must be a fairly simple task.

Pavel Alexeev
  • 6,026
  • 4
  • 43
  • 51

2 Answers2

3

Thanks to mahal tertin, it's pretty easy to use AKAUPresetBuilder!
You can create .aupreset file somewhere in tmp directory and then load this instrument with AKSampler.

The only thing worth noting is that by default AKAUPresetBuilder will generate samples with trigger mode set to trigger, which will ignore note-off events. So you should set it explicitly.

For example:

let sampleC4 = AKAUPresetBuilder.generateDictionary(
                    rootNote: 60,
                    filename: pathToC4WavSample,
                    startNote: 48,
                    endNote: 65)
sampleC4["triggerMode"] = "hold"

let sampleC5 = AKAUPresetBuilder.generateDictionary(
                    rootNote: 72,
                    filename: pathToC5WavSample,
                    startNote: 66,
                    endNote: 83)
sampleC5["triggerMode"] = "hold"

AKAUPresetBuilder.createAUPreset(
                    dict: [sampleC4, sampleC5],
                    path: pathToAUPresetFilename,
                    instrumentName: "My Instrument",
                    attack: 0,
                    release: 0.2)

and then create a sampler and start AudioKit:

sampler = AKSampler()

try sampler.loadInstrument(atPath: pathToAUPresetFilename)

AudioKit.output = sampler
AudioKit.start()

and then use this to start playing note:

sampler.play(noteNumber: MIDINoteNumber(63), velocity: MIDIVelocity(120), channel: 0)

and this to stop, respecting release parameter:

sampler.stop(noteNumber: MIDINoteNumber(63), channel: 0)
Pavel Alexeev
  • 6,026
  • 4
  • 43
  • 51
2

Probably the best way would be to embed your wav files into an EXS or Soundfont format, making use of tools in that realm to accomplish the ADSR for instance. Otherwise you'll kind of have to have an instrument for each sample.

Aurelius Prochazka
  • 4,510
  • 2
  • 11
  • 34
  • Instruments are user-generated, so I can't make exs24 or soundfont :( Maybe it's OK to have an instrument for each sample. But how can I setup the ADSR for the instrument? (I've read I can configure .caf files – but that looks way too complicated, and I have .wav, not .caf). – Pavel Alexeev Nov 17 '17 at 22:30
  • Can you send the sampler through an AKADSREnvelope and start and stop it timed appropriately? – Aurelius Prochazka Nov 17 '17 at 22:37
  • or use aupreset instruments, they can be modified with the parser. – mahal tertin Nov 18 '17 at 11:15
  • @AureliusProchazka, yes, I can, but again, it would require 5 samplers for 5 simultaneously played notes – they may end and start at different time :( – Pavel Alexeev Nov 18 '17 at 11:54
  • @mahaltertin, could you tell more about the “parser”? Is there any way to dynamically generate aupreset from bunch of .wav samples and then load in into AKSampler/AVAudioUnitSampler? – Pavel Alexeev Nov 18 '17 at 11:55
  • 1
    it's not trivial and i'm away from Xcode this weekend; this would be a starting point: http://audiokit.io/docs/Classes/AKAUPresetBuilder.html#/s:8AudioKit17AKAUPresetBuilderC14createAUPresetySaySo19NSMutableDictionaryCG4dict_SS4pathSS14instrumentNameSdSg6attackAK7releasetFZ – mahal tertin Nov 18 '17 at 12:48