If anyone is wondering about overriding fullState and setFullState so that you can work around the issue, this is what I've done
(NSDictionary<NSString *, id> *) fullState {
// Get the Component information
AudioComponentDescription acd = [self componentDescription];
NSMutableDictionary<NSString *,id> *result = [NSMutableDictionary dictionary];
[result setValue:[NSNumber numberWithInt:acd.componentManufacturer] forKey:@"manufacturer"];
[result setValue:[NSNumber numberWithInt:acd.componentSubType] forKey:@"subtype"];
[result setValue:[NSNumber numberWithInt:acd.componentType] forKey:@"type"];
[result setValue:[NSNumber numberWithInt:[self componentVersion]] forKey:@"version"];
[result setValue:[NSNumber numberWithFloat:2.0] forKey:@"preset_version"];
// The parameter space is flat and the ids are unique into the AUParameters.
// Doing this as a dictionary keyed by NSNumbers does not work with the
// PropertyListSerialization class used in NeSiUserPreset to store to disk.
// So, we go with two arrays.
NSMutableArray<NSNumber *> *parameter_ids = [NSMutableArray array];
NSMutableArray<NSNumber *> *parameter_values = [NSMutableArray array];
for (AUParameter *param in [[self parameterTree] allParameters]) {
[parameter_ids addObject: [NSNumber numberWithLongLong:param.address]];
[parameter_values addObject: [NSNumber numberWithFloat:param.value]];
}
[result setObject:parameter_ids forKey:@"parameters_ids"];
[result setObject:parameter_values forKey:@"parameters_values"];
return result;
//return [super fullState]; // Use this to get the old version of presets for testing.
}
(void) setFullState:(NSDictionary<NSString *,id> *)fullState {
// Check to see what version of the AU fullState is being used.
NSNumber *preset_version = [fullState valueForKey:@"preset_version"];
if (preset_version != nil) { // Implies a version 2.0 preset
// The parameterTree for LRC5 is flat and the ids are unique. This is the easy way to get
// the values into the parameter nodes.
NSArray<NSNumber *> *parameter_ids = [fullState valueForKey:@"parameters_ids"];
NSArray<NSNumber *> *parameters_values = [fullState valueForKey:@"parameters_values"];
AUParameterTree *pt = [self parameterTree];
for (int i = 0; i < parameter_ids.count; i++) {
AUParameter *param = [pt parameterWithAddress:parameter_ids[i].longLongValue];
param.value = parameters_values[i].floatValue;
}
} else {
#ifdef DEBUG
os_log(OS_LOG_DEFAULT, "Preset is old style...");
#endif
[super setFullState:fullState];
}
}
This will let you move to a new method of working with fullState and will still be able to read fullState sent to it from old documents and presets. But, in iOS 14, the problem with the base class implementation of setFullState is still there for old style presets and documents. It does work on iOS 13 and iOS 12. It should also work fine when the issue is fixed in iOS 14 and let users work with both old and new document and preset state.
Topic:
Media Technologies
SubTopic:
Audio
Tags: