• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Bug in saving user presets [Solved]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Bug in saving user presets [Solved]


  • Subject: Re: Bug in saving user presets [Solved]
  • From: Doug Wyatt <email@hidden>
  • Date: Fri, 27 Jan 2006 14:45:33 -0800

So it sounds like the autovectorization option in the compiler is misbehaving. I'd suggest filing a bug against the compiler. They'll want a complete "compiler test case", which means giving them preprocessed source code. I usually do this by grabbing the compiler command line out of the Xcode build log and modifying it as follows:

remove "-x c++"
remove "-o <filename>"
add "-E"
add "> preprocessed.c"

Then execute the modified command line in Terminal.

Doug

On Jan 27, 2006, at 5:00, Robert Abernathy wrote:
The problem turns out to be in AUElement. If the Auto- vectorization flag is set in the compiler, SaveState and RestoreState shift the order of the preset values. This may not show in AU's with a small number of presets.

Since the audio portions of the AU are all done using the Accelerate framework, this flag isn't getting me anything anyway. So, my problem is solved. But, it is a bit weird and a major pain to track down.

Rob

On 25 Jan 2006, at 21:39, Robert Abernathy wrote:


I'm tracking down a bug in user presets in an AU I'm working on.

I've tracked it down to being in AUBase::SaveState or AUElement::SaveState.

The parameter data is being gathered correctly in AUElement::SaveState. If I print it here as it is being pulled from mParameters or mIndexedParameters, it is correct.

If I take the, the dictionary that is built in AUBase::SaveState and print it out immediately after the parameter data is added, I can see that the data is wrong at this point. (See code below, the function TestState is where the data is checked. It mimics the read data in AUElement::RestoreState to do the dictionary/data read.)

The parameter data is offset by two indices. As the parameters are read back in AUElement::PrintState, the zeroth and first elements are garbage (close to zero). The 2nd entry contains the value of the zeroth parameter. The 3rd entry contains the value of the first parameter and so forth, up to the 90th entry containing the value of the 88th parameter. The 89th and 90th parameters are missing.

If I print the data out as it is being read back in AUElement::RestoreState, the pattern above is the same. Shifted off by two with the first two entries garbage.

The code I used for testing is below.

Any help would be much appreciated as I'm kinda stuck here.

Thanks,
Rob



Code below---------------------------------------------------------------- --------------

ComponentResult AUBase::SaveState( CFPropertyListRef * outData)
{
ComponentDescription desc;
OSStatus result = GetComponentInfo((Component)GetComponentInstance (), &desc, NULL, NULL, NULL);
if (result) return result;


CFMutableDictionaryRef dict = CFDictionaryCreateMutable (NULL, 0,
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);


// first step -> save the version to the data ref
	SInt32 value = kCurrentSavedStateVersion;
	AddNumToDictionary (dict, kVersionString, value);

// second step -> save the component type, subtype, manu to the data ref
value = desc.componentType;
AddNumToDictionary (dict, kTypeString, value);


value = desc.componentSubType;
AddNumToDictionary (dict, kSubtypeString, value);

value = desc.componentManufacturer;
AddNumToDictionary (dict, kManufacturerString, value);

// fourth step -> save the state of all parameters on all scopes and elements
CFMutableDataRef data = CFDataCreateMutable(NULL, 0);
for (AudioUnitScope iscope = 0; iscope < 4; ++iscope) {
if (iscope == kAudioUnitScope_Group)
continue;
AUScope &scope = GetScope(iscope);
AudioUnitElement nElems = scope.GetNumberOfElements();
for (AudioUnitElement ielem = 0; ielem < nElems; ++ielem) {
AUElement *element = scope.GetElement(ielem);
UInt32 nparams = element->GetNumberOfParameters();
if (nparams > 0) {
struct {
UInt32 scope;
UInt32 element;
} hdr;

hdr.scope = EndianU32_NtoB(iscope);
hdr.element = EndianU32_NtoB(ielem);
CFDataAppendBytes(data, (UInt8 *)&hdr, sizeof(hdr));

element->SaveState(data);
}
}
}


// save all this in the data section of the dictionary
	CFDictionarySetValue(dict, kDataString, data);
	CFRelease (data);

	TestState(dict);  // my added function to print out the data

//OK - now we're going to do some properties
//save the preset name...
	CFDictionarySetValue (dict, kNameString, mCurrentPreset.presetName);

// Does the unit support the RenderQuality property - if so, save it...
value = 0;
result = DispatchGetProperty (kAudioUnitProperty_RenderQuality,
kAudioUnitScope_Global,
0,
&value);

if (result == noErr) {
AddNumToDictionary (dict, kRenderQualityString, value);
}

// Does the unit support the CPULoad Quality property - if so, save it...
Float32 cpuLoad;
result = DispatchGetProperty (kAudioUnitProperty_CPULoad,
kAudioUnitScope_Global,
0,
&cpuLoad);

if (result == noErr) {
CFNumberRef num = CFNumberCreate (NULL, kCFNumberFloatType, &cpuLoad);
CFDictionarySetValue (dict, kCPULoadString, num);
CFRelease (num);
}


// Do we have any element names for any of our scopes?
// first check to see if we have any names...
bool foundName = false;
for (AudioUnitScope i = 0; i < kNumScopes; ++i) {
foundName = GetScope (i).HasElementWithName();
if (foundName)
break;
}
// OK - we found a name away we go...
if (foundName) {
CFMutableDictionaryRef nameDict = CFDictionaryCreateMutable (NULL, 0,
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
for (AudioUnitScope i = 0; i < kNumScopes; ++i) {
GetScope (i).AddElementNamesToDict (nameDict);
}

CFDictionarySetValue (dict, kElementNameString, nameDict);
CFRelease (nameDict);
}

// we're done!!!
*outData = dict;

return noErr;
}
// -------------------------------------
// little function to test the data in the preset
void AUBase::TestState(CFMutableDictionaryRef dict) {
std::cout << "AUBase::TestState() . Count " << CFDictionaryGetCount(dict) << "\n";

CFDataRef data = reinterpret_cast<CFDataRef>(CFDictionaryGetValue (dict, kDataString));
if (data != NULL)
{
const UInt8 *p, *pend;

p = CFDataGetBytePtr(data);
pend = p + CFDataGetLength(data);

// we have a zero length data, which may just mean there were no parameters to save!
// if (p >= pend) return noErr;

while (p < pend) {
struct {
UInt32 scope;
UInt32 element;
} hdr;

hdr.scope = EndianU32_BtoN(*(UInt32 *)p); p += sizeof(UInt32);
hdr.element = EndianU32_BtoN(*(UInt32 *)p); p += sizeof(UInt32);

AUScope &scope = GetScope(hdr.scope);
AUElement *element = scope.GetElement(hdr.element);
// $$$ order of operations issue: what if the element does not yet exist?
// then we just break out of the loop
if (!element)
break;
p = element->PrintState(p);
}
}

}


// My added routine
// It mimicks AUElement::RestoreState
const UInt8 * AUElement::PrintState(const UInt8 *state)
{
const UInt8 *p = state;
UInt32 nparams = EndianU32_BtoN(*(UInt32 *)p);

std::cout << "Print state ... NParams = " << nparams << "\n";

p += sizeof(UInt32);

for (UInt32 i = 0; i < nparams; ++i) {
struct {
UInt32 paramID;
Float32 value;
} entry;

entry.paramID = EndianU32_BtoN(*(UInt32 *)p);
p += sizeof(UInt32);
UInt32 temp = EndianU32_BtoN(*(UInt32 *)p);
entry.value = *(Float32 *)&temp;
p += sizeof(Float32);

std::cout << "Print - Element: id = " << entry.paramID << " value = " << entry.value << "\n";

}
return p;
}
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
40musicunfolding.com


This email sent to email@hidden



_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
40apple.com


This email sent to email@hidden

-- Doug Wyatt Core Audio, Apple

_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


  • Follow-Ups:
    • Re: Bug in saving user presets [Solved]
      • From: Robert Abernathy <email@hidden>
References: 
 >Bug in saving user presets (From: Robert Abernathy <email@hidden>)
 >Re: Bug in saving user presets [Solved] (From: Robert Abernathy <email@hidden>)

  • Prev by Date: Out-of-range samples
  • Next by Date: Re: Accessing underlying AUGraph being used by quicktime
  • Previous by thread: Re: Bug in saving user presets [Solved]
  • Next by thread: Re: Bug in saving user presets [Solved]
  • Index(es):
    • Date
    • Thread