Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AU Preset (.aupreset) resource path issue in iOS LoadPresetDemo sample code

I've been working with the iOS LoadPresetDemo sample code - if loads AUPreset files to configure different types of samplers (pretty cool) - and have run into a question/issue.

The demo code runs fine but when I try to reuse the .aupreset files in test project built from scratch, the Trombone.aupreset doesn't work. Digging into it, I noticed what seems like oddness with the audio sample paths in the .aupreset file.

The paths in the plist (images below) point to:

file://localhost//Library/Audio/Sounds/Tbone/1a%23.caf

but that is not the correct path - according to the project directory structure. There are no "Library/Audio" directories - virtual or real. So I'm confused. The Apple demo works fine but my from scratch project does not (get error -43 when trying to load the samples). The code that loads the samples (at bottom) is not doing anything to relativize the paths at runtime.

Does anyone see what I am misunderstanding here? - Thanks!

directory structure

.aupreset plist

// Load a synthesizer preset file and apply it to the Sampler unit
- (OSStatus) loadSynthFromPresetURL: (NSURL *) presetURL {

CFDataRef propertyResourceData = 0;
Boolean status;
SInt32 errorCode = 0;
OSStatus result = noErr;

// Read from the URL and convert into a CFData chunk
status = CFURLCreateDataAndPropertiesFromResource (
            kCFAllocatorDefault,
            (__bridge CFURLRef) presetURL,
            &propertyResourceData,
            NULL,
            NULL,
            &errorCode
         );

NSAssert (status == YES && propertyResourceData != 0, @"Unable to create data and properties from a preset. Error code: %d '%.4s'", (int) errorCode, (const char *)&errorCode);

// Convert the data object into a property list
CFPropertyListRef presetPropertyList = 0;
CFPropertyListFormat dataFormat = 0;
CFErrorRef errorRef = 0;
presetPropertyList = CFPropertyListCreateWithData (
                        kCFAllocatorDefault,
                        propertyResourceData,
                        kCFPropertyListImmutable,
                        &dataFormat,
                        &errorRef
                    );

// Set the class info property for the Sampler unit using the property list as the value.
if (presetPropertyList != 0) {

    result = AudioUnitSetProperty(
                self.samplerUnit,
                kAudioUnitProperty_ClassInfo,
                kAudioUnitScope_Global,
                0,
                &presetPropertyList,
                sizeof(CFPropertyListRef)
            );

    CFRelease(presetPropertyList);
}

if (errorRef) CFRelease(errorRef);
CFRelease (propertyResourceData);

return result;
}
like image 279
spring Avatar asked Feb 21 '23 14:02

spring


2 Answers

I had the same Problem and after 2 hours of comparing the "load preset"-Demo with my code I found the solution:

When adding the sound-folder check the options:

  • Copy items
  • Create folder references for any added folders -- and the added folders will be blue like in the "load preset"-demo-project!
like image 153
roxxx303 Avatar answered Feb 24 '23 05:02

roxxx303


The following is from Apple Technical Note TN2283 and discusses the paths issue that was initially asked about. You will obviously need to have the Sounds Folder, your assets and preset file part of your bundle.

Technical Note TN2283 AUSampler - Loading Instruments Excerpt

When the AUSampler attempts to load audio files via the paths provided in the external file refs portion of an .aupreset file or a set of individual file URLs, it will use the following rules to resolve each path:

If the audio file is found at the original path, it is loaded. If the audio file is NOT found, the AUSampler looks to see if a path includes a portion matching "/Sounds/", "/Sampler Files/" or "/Apple Loops/" in that order.

If the path DOES NOT include one of the listed sub-paths, an error is returned. If the path DOES include one of the listed sub-paths, the portion of the path preceding the sub-path is removed and the following directory location constants are substituted in the following order:

Bundle Directory NSLibraryDirectory NSDocumentDirectory NSDownloadsDirectory

For example, in an iOS application if the original path was "/Users/geddy/Library/Audio/Sounds/MyFavoriteHeadacheSound.caf" and this path was not found, the AUSampler would then search for the audio file in the following four places:

<Bundle_Directory>/Sounds/MyFavoriteHeadacheSound.caf
<NSLibraryDirectory>/Sounds/MyFavoriteHeadacheSound.caf
<NSDocumentDirectory>/Sounds/MyFavoriteHeadacheSound.caf
<NSDownloadsDirectory>/Sounds/MyFavoriteHeadacheSound.caf

Therefore using the above example, if you were moving a preset created on the Desktop to an iOS application you could simply place the MyFavoriteHeadacheSound.caf file in a folder called "Sounds" within your application bundle and the AUSampler will find the audio file referenced by the preset.

like image 35
Miles Monroe Avatar answered Feb 24 '23 04:02

Miles Monroe