加载声音字体失败,显示“无法找到补丁0 bank 0x0 / 0”
当查看完整的最终路径时,soundfont的URL看起来正确。
AVAudioUnitSampler继承自AVAudioUnitMidiInstrumentAVAudioUnitSampler没有自己的初始化程序。AVAudioUnitMidiInstrument有一个需要AudioComponentDescription的代码

使用任何一个都会导致相同的错误。

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)

结果是:
Unable to find patch 0 bank 0x0/0

使用较低级别的API可以在音频单元上设置属性。
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));

最佳答案

A)Xcode 6 beta的更高版本,即版本3,添加了其他方法,消除了桥接的需要。

//
//  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)
    }
}

与没有AVAudioEngine相比,它要简单得多。

08-19 11:41