4

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;
}
spring
  • 18,009
  • 15
  • 80
  • 160

3 Answers3

5

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!
Mark Ursino
  • 31,209
  • 11
  • 51
  • 83
roxxx303
  • 66
  • 1
3

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.

  • A great way to check if the sampler is playing on the simulator but NOT on the device, is to clean and run the simulator, then find the app bundle it created ( generally in ~/UserAccount/Library/Application Support/iPhone Simulator/6.0/Applications/RandomAppNumber/AppNamePkg ) right click on the Application Package, and select "Show Package Contents", if there's no officially named folder in there like "Sounds" with the correct samples inside it, even IF the correct samples are in the package but NOT inside a "Sounds" or "Sample Files" dir, then it won't play on the device but will in the sim – OverToasty Nov 21 '12 at 13:12
  • Hi guys - im having a related issue and wondering if you could help please - http://stackoverflow.com/questions/21468108/ios-ausampler-audiounit-file-path-issue-with-exs-audio-files – fxfuture Jan 30 '14 at 22:59
0

You need to add both presets to your target so that they are part of the bundle:

Show Package Contents of the Device Built executable

That's what the line:

NSURL *presetURL = [[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource:@"Trombone" ofType:@"aupreset"]];

says.

Also you may want to have a look at Referencing External Audio Files at the bottom of the page.

verec
  • 5,224
  • 5
  • 33
  • 40
  • Aren't they included by virtue of being added to the project? I just just double-checked that they are included in "Copy Bundle Resources" and they are. Thanks for the 'Ref Ext; Audio' - according to that the odd path for the .caf files should still work. Alas, still getting the -43 error. – spring Feb 19 '12 at 15:32