AVAudioUnitSampler Error loadSoundBankAtURL -> Unable to find patch 0 bank 0x0/0

1.3k Views Asked by At

Loading a soundfont is failing with 'Unable to find patch 0 bank 0x0/0' The URL to the soundfont appears correct when looking at the full resulting path.

AVAudioUnitSampler inherits from AVAudioUnitMidiInstrument

AVAudioUnitSampler does not have an initializer of it's own. AVAudioUnitMidiInstrument has one that takes an AudioComponentDescription

Using either results in the same error.

var error:NSError?
let soundBankUrl:NSURL = NSURL(fileURLWithPath:
NSBundle.mainBundle().pathForResource("FluidR3 GM2-2", ofType: "SF2"))

var audioEngine:AVAudioEngine  = AVAudioEngine()        

// sampler
var audioCompDesc = AudioComponentDescription(
    componentType: OSType(kAudioUnitType_MusicDevice),
    componentSubType: OSType(kAudioUnitSubType_Sampler),
    componentManufacturer: OSType(kAudioUnitManufacturer_Apple),
    componentFlags: 0, componentFlagsMask: 0)     

var sampler:AVAudioUnitSampler = AVAudioUnitSampler(audioCompDesc)
//     var sampler:AVAudioUnitSampler = AVAudioUnitSampler()


let loaded = sampler.loadSoundBankAtURL(soundBankUrl, error: &error)

Results in:

Unable to find patch 0 bank 0x0/0

Using the lower level APIs one would set a property on the audio unit.

AUSamplerBankPresetData bpdata;
bpdata.bankURL = (__bridge CFURLRef) presetURL;

bpdata.bankMSB = kAUSampler_DefaultMelodicBankMSB;
bpdata.bankLSB = kAUSampler_DefaultBankLSB;

bpdata.presetID = (UInt8) patch;

return [self loadSynthFromPresetURL:(NSURL*)presetURL
                          withPatch:(int) patch
                          audioUnit: (AudioUnit) audioUnit
               samplerBankPesetData: (AUSamplerBankPresetData) bpdata];

result = AudioUnitSetProperty(audioUnit,
kAUSamplerProperty_LoadPresetFromBank, kAudioUnitScope_Global,
              0, &samplerBankPresetData, sizeof(samplerBankPresetData));
1

There are 1 best solutions below

1
On

A) A later version, version 3, of the Xcode 6 beta added additional methods eliminating the need to bridge.

//
//  ViewController.swift
//  SwiftAudio
//
//  Created by Robert Buskens on 2014-06-06.
//  Copyright (c) 2014 Buskens & Associates Inc. All rights reserved.
//

import UIKit
import AVFoundation
import AudioUnit

class ViewController: UIViewController {

    var engine: AVAudioEngine
    var sampler:AVAudioUnitSampler

    init(coder aDecoder: NSCoder!) {
        var retVal:Bool = false
        var error:NSErrorPointer = nil

        engine =  AVAudioEngine()
        sampler = AVAudioUnitSampler()

        engine.attachNode(sampler)
        engine.connect(sampler, to: engine.outputNode, format: nil)

        var url = NSBundle.mainBundle().URLForResource("Framus_western", withExtension: "sf2")

        retVal = engine.startAndReturnError(error)


        var r:Bool = sampler.loadSoundBankInstrumentAtURL(url, program: 0, bankMSB: 0x79, bankLSB: 0, error: error)

        engine.startAndReturnError(error)

        println("engine start returned: \(retVal)")

        super.init(coder: aDecoder)    
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    @IBAction func playNote(sender: UIButton) {
        sampler.startNote(45, withVelocity: 80, onChannel: 1)
    }
}

Much simpler than without the AVAudioEngine.