Question

AUParamInfo() doesn't seem to exist in the iOS7 frameworks (CoreAudio, AudioUnit, AudioToolbox). I'm wondering what would be the way to get all parameters for a unit. That is, without knowing what type or subtype of unit it is, since if not the answer would be to look up in the Audio Unit Parameters Reference.

Était-ce utile?

La solution

Greg's answer is right in the sense that kAudioUnitProperty_ParameterList is the right property ID to query to eventually get all parameters of a unit. However, the way to get all parameters is a bit more involved:

  1. Use AudioUnitGetPropertyInfo to see if the property is available and if it is, get back its data size (data size for the whole info which might be a collection, not for a single element of whatever type the property is, mind you).
  2. Use AudioUnitGetProperty proper to get the property back. Also, at this point, if the property you got back is a collection of elements as opposed to a single one, you'll have to call AudioUnitGetProperty once for each element. Specifically, you'll call it dataSize / sizeof(TypeToHoldSingleInstanceOfYourProperty) times.

    //  Get number of parameters in this unit (size in bytes really):
    UInt32 parameterListSize = 0;
    AudioUnitGetPropertyInfo(_audioUnit, kAudioUnitProperty_ParameterList, kAudioUnitScope_Global, 0, &parameterListSize, NULL);
    
    //  Get ids for the parameters:
    AudioUnitParameterID *parameterIDs = malloc(parameterListSize);
    AudioUnitGetProperty(_audioUnit, kAudioUnitProperty_ParameterList, kAudioUnitScope_Global, 0, parameterIDs, &parameterListSize);
    
    AudioUnitParameterInfo parameterInfo_t;
    UInt32 parameterInfoSize = sizeof(AudioUnitParameterInfo);
    UInt32 parametersCount = parameterListSize / sizeof(AudioUnitParameterID);
    for(UInt32 pIndex = 0; pIndex < parametersCount; pIndex++){
        AudioUnitGetProperty(_audioUnit, kAudioUnitProperty_ParameterInfo, kAudioUnitScope_Global, parameterIDs[pIndex], &parameterInfo_t, &parameterInfoSize);
        // do whatever you want with each parameter...
    }
    

Autres conseils

Not sure if this will be helpful, but the documentation states:

To get parameter information from an audio unit, a host application first gets the value of the audio unit’s kAudioUnitProperty_ParameterList property, a property provided for you by superclasses in the SDK. This property’s value is a list of the defined parameter IDs for the audio unit. The host can then query the kAudioUnitProperty_ParameterInfo property for each parameter ID.

(from the Audio Unit Programming Guide)

Here is a Swift 5 version proposal

1 - Define a convenient structure to store our info

/// Swifty AudioUnit parameters array

struct AudioUnitParameter: CustomStringConvertible {
    var id: Int
    var name: String = ""
    var minValue: Float
    var maxValue: Float
    var defaultValue: Float
    var unit: Int

    init(_ info: AudioUnitParameterInfo, id: UInt32) {
        self.id = Int(id)
        if let cfName = info.cfNameString?.takeUnretainedValue() {
            name = String(cfName)
        }
        minValue = Float(info.minValue)
        maxValue = Float(info.maxValue)
        defaultValue = Float(info.defaultValue)
        unit = Int(info.unit.rawValue)
    }
    
    var description: String {
        "Parameter [id: \(id)] :  \(name) [\(minValue)..\(maxValue)] \(unit)"
    }
}

2 - Add a convenient parameters getter on the AudioUnit class

extension AudioUnit {
    
    /// Returns an array with audioUnit parameters descriptions
    var parameters: [AudioUnitParameter] {
        
        var out = [AudioUnitParameter]()
        
        //  Get number of parameters in this unit (size in bytes really):
        var parameterListSize: UInt32 = 0
        let parameterSize = MemoryLayout<AudioUnitParameterID>.size
        AudioUnitGetPropertyInfo(self, kAudioUnitProperty_ParameterList,
                                 kAudioUnitScope_Global,
                                 0, &parameterListSize, nil);
        
        let numberOfParameters = Int(parameterListSize) / parameterSize

        //  Get ids for the parameters:
        let parameterIds = UnsafeMutablePointer<UInt32>.allocate(capacity: Int(parameterListSize))
        AudioUnitGetProperty(self, kAudioUnitProperty_ParameterList,
                             kAudioUnitScope_Global,
                             0, parameterIds, &parameterListSize);

        var info = AudioUnitParameterInfo()
        var infoSize = UInt32(MemoryLayout<AudioUnitParameterInfo>.size)
        
        for i in 0 ..< numberOfParameters {
            let id = parameterIds[i]
            AudioUnitGetProperty(self, kAudioUnitProperty_ParameterInfo,
                                 kAudioUnitScope_Global,
                                 id, &info, &infoSize);
            out += [AudioUnitParameter(info, id: id)]
        }
        return out
    }
}

Usage:

if let params = myDLSSynthAudioUnit.parameters {
    params.forEach { print($0) }
}
Property [0] :  Tuning [-1200.0..1200.0] 9
Property [1] :  Volume [-120.0..40.0] 13
Property [2] :  Reverb Volume [-120.0..40.0] 13

We can also implement a string getter for the Unit integer code. Just copy all the parameters from the Apple AudioUnitParameterUnit.

extension AudioUnitParameterUnit {
    var name: String { ["Generic", "Indexed", "Boolean", "Percent", ... ][rawValue] }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top