AudioKit / AudioKit

Audio synthesis, processing, & analysis platform for iOS, macOS and tvOS

Home Page:http://audiokit.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

EXS-24 load file failing

larryseyer opened this issue · comments

I have a properly working EXS-24 file with proper samples that loads and works correctly in both MainStage and Logic Pro X.

When trying to load this EXS-24 file into AudioKit's ESX-24 module, the app crashes.

I have tried moving the .exs file from its standard path to various other paths in an attempt to see if I could find out why the module was bombing out... but the best I can figure out is that the EXS-24 module does not look for samples in the current directory... or possibly, it is looking for them and can't find them for whatever reason.

I have created an Xcode project with example files (including a properly working EXS-24 file and it's samples)

The project crashes at the EXS-24 load point - every time.

https://www.dropbox.com/s/x7z8gew7lrwvwhv/Possible%20AudioKit%20ESX24%20Bug.zip?dl=0

Anyone else having this issue?

First of all, you rock for providing code demonstrating the problem. The file seems to be found, but then the app crashes, which is really strange. Could it be a corrupt or somehow incompatible EXS24 file?

Today I created a new version of an exs24 file with new samples. Same problem.

That same exs24 file loads fine into MainStage with no issues and plays just fine.

FYI.

L

Take a look at this issue, especially the last post from Jeff: #298

@larryseyer interesting, looks like one of the AudioKit contributors, Stephane Peter, is https://github.com/megastep

@larryseyer,

Kudos again, for posting a test Xcode project to allow others to help you out with troubleshooting. I looked at it and noticed that your audio files associated with your EXS24 file are in aif format, rather than wav. I'm wondering if you convert them to wav, then AKSampler will be able to load them correctly?

convert-aif-audio-to-wav

It would be great if AKSampler could load aif, caf, or m4a formats, in addition to wav. @aure, do you think that the audio format could be the culprit with Larry's issue? It doesn't explain the console output error referencing @megastep:

/Users/megastep/src/ak/AudioKit/AudioKit/Common/Nodes/Playback/Sampler/AKSampler.swift

Take care,
Mark

I'm still pretty convinced this is an EXS-24 path issue. I think you're creating the EXS file along side the audio files, then trying to move them into subdirectories with different names once they're in Xcode. If you read the last post by Jeff on the issue I referenced, I think he was stating the difficulty of setting up the EXS file while in Logic properly so that it can work as expected outside of Logic, ie. in Xcode.

Howdy
So yea loading an EXS instrument into iOS is pretty tricky to get going at first. The instrument has to be built with the intention of loading it into iOS - meaning, I couldn't take an EXS instrument I built just for a track in Logic, I would have to know, beforehand, that the instrument was going to end up on iOS.
That's because the samples MUST originate from one of those 'magic folders' I mention in the other thread, and then those must exist in the iOS project just like they did when the instrument was built.

Trust me, I fought with this for days before I started to finally figure it out - it seems convoluted at first, but the results are worth it.

It's also worth noting that the instruments don't transfer 100% the same from Logic to iOS - for example filter drive is ignored in iOS (or was last time I checked).

Point being, try not to think of it as moving a Logic instrument to iOS, think of it as using Logic to very methodically build and instrument to use in iOS. Also, the Apple software AULab is pretty good for building sampler files (.aupreset) that can be used in iOS pretty much exactly as they are when you build them.

Yeah, the binaries for each release are usually built on my Mac so that's why the absolute paths of the files show up with my username in the debug info for the library. Doesn't really mean much beyond that. ;)

One important thing to keep in mind between the simulator and the device though, generally speaking: the Mac filesystem is usually not case sensitive (HFS+) whereas the filesystem on the device is. So your file would manage to load on the simulator even if one of the letters is incorrectly capitalized in your path name, whereas it would fail on the device. Something I would look at in this kind of situation.

With no response on this issue and lots of responses/things to try, I'm going to close the issue for now. If you want to reopen it with new information, you may.

The reason I have not responded is because I am still experimenting with this.

I have not had any success so far. However, I have gained a great deal of information.

One thing that I am currently experimenting with is using something called 'Translator' to fix the paths of the EXS24 files.

https://samplerzone.com/collections/translator

When I get something to actually work, I will post my results here.

It does appear to be a problem with paths since the EXS24 format stores FULL paths in it's file.

I've been talking with Garth (the creator of Translator) about this issue and he has given me several suggestions on how to fix this issue... along with the Apple suggestion (which did not work for me).

As I know more, I will post it here.

Thanks for everyone for all of the help.

Together, we will figure this out.

L

Cool, thanks for the update!

I think I may have found the problem.

In the AKSampler.swift file I find this:

/// Load an EXS24 sample data file
///
/// - parameter file: Name of the EXS24 file without the .exs extension
///
open func loadEXS24(_ file: String) throws {
try loadInstrument(file, type: "exs")
}

But according to the docs from Apple about loadInstrument, it takes an array of URL types like this:

private var drumKit = AVAudioUnitSampler()
let kits = [URL(string: "/Users/larryseyer/Dropbox/Soloist XCode/Test Sampler/TestSampler/TestSampler/Brushes.sf2"),
            URL(string: "/Users/larryseyer/Music/Audio Music Apps/Sampler Instruments/Brushes/Brushes.exs")]

init()
{
    do
    {
        try drumKit.loadInstrument(at: kits[1]!)
    }
    catch
    {
        print("file was not found.")
    }       
}

When I send it an array of URLs (see above) it does NOT bomb out.

I will post a link to an Xcode project later today demonstrating what I've found...

But I was so excited to find something that actually LOADED, that I had to post what I found so far...

More to come.

@larryseyer Cool, also consider submitting a pull request. Thanks so much for your diligence. This is the way AudioKit gets better.

OK, here is what I've found out:

As far as I can tell, there is nothing wrong with AudioKit with regards to this issue.

Inititally, I had thought there was an issue with AudioKit's array's vs. strings in the LoadEXS24 method, but after further investigating, that turned out not to be the issue at all.

The EXS format has some peculiarities that have to be dealt with specially in IOS.

First of all, the EXS format stores ABSOLUTE paths in it's file structure. This is a huge problem unless you follow the following guidelines to remedy it's flaws.

Most of the developers that I know (myself included) will use MainStage ($30) or Logic Pro X ($200) to make their EXS formated files.

This is because both of those program have most of the tools necessary to build the file format fairly quickly and easily. You can audition the layout, sounds, and groupings in real time using a keyboard to trigger the sounds.

The problem with using those two tools is that the EXS format will store YOUR absolute path to the samples inside of the EXS file format. (including your personal "users/username" path)

MainStage stores it's sample files in the following folder:

/users/username/music/audio music apps/sampler instruments

However, Logic Pro X store it's sample files in the following folder:

/library/application support/logic/sampler instruments

Apple suggests using the following file locations for all EXS files when developing IOS apps:

yourappbundle/sounds/sampler instruments

You can see the inherent problem here.

Neither one of the two tools will store the files in the proper location for IOS.

The other problem is that BOTH of these programs store their samples in .WAV format.

IOS devices want to see .AIFF format files.

So what is the solution?

After many many hours of experimenting with this and after consulting with another respected developer, I found a tool that will 'fix' the paths of an EXS file to work properly inside of an IOS application.

The tool is called 'Translator' ( see http://www.chickensys.com/products2/translator/ ) and without it, I can honestly say I don't think I would have ever gotten this to work.

I used Translator to fix all of the file paths of the EXS24 file WHILE it was inside of my IOS project folder named "Sounds/Sampler Instruments". This folder was located INSIDE of my IOS project.

The Translator function that I used to fix the paths is a red labeled tool marked 'Fix References'. This will RE-WRITE the paths to the samples correctly for IOS to be able to 'see' them.

The other function you will need to use is the one that converts the .WAV files into .AIFF files. Both of these functions can be done using Translator.

Then, using AudioKit's AKSampler you tell the LoadEXS24 method to load as follows:

try drumKit.loadEXS24("Sounds/Sampler Instruments/YourEXSFile.exs")

This works reliably and every time.

Thanks to all who helps figure out this issue.

We can mark this issue as 'closed'

All the best to you!

L

Thanks @larryseyer for explaining your journey in such detail. These are all things I was alluding to in my previous post, and I'm glad you were able to push through it.

I want to reiterate that it CAN be done from Logic (without any external tools), it just involves quite a bit of file location madness. First, the sounds used to build the sampler must originate from somewhere within a folder that has one of those 'magic folder names' that Apple lists. This structure then has to be rebuilt on the iOS project. There was another quirk I experienced that I can't remember the details of exactly, but if I tried to save or move the logic instrument after that, it would re-write the file paths and screw it all up. It might have been that I chose to save the instruments with the Logic project (as folder) and that worked.

In my experience though, wav files do work - I have never used aiff and I use Logic-built instruments on ios all the time.

What I have moved on to though is using AuLab and building an aupreset file. It doesn't mess with the file paths too much (they still have to match, from one of the 'magic folders' down), and all the parameters in AuLab are readable by the sampler in ios. AuLab has it's own set of issues, but since the last osx update, alot of these have been addressed.
Fill out those bug reports to apple! It really helps them catch these problems.

Finally, there is a class in AudioKit called AKAUPresetBuilder that allows you to build aupreset sampler filers programatically. It can work fairly simply, or you can get extremely complex, defining zones, layers, envelopes, etc - that is not for the faint of heart, but it is there.

Thanks again for helping with this.

Thanks @eljeff for the help!

Now on to other things!

L

I think this is basically a closed issue. Might be nice to include what was learned here in a documentation or tutorial. We're going to be writing more tutorials soon, so I'll be sure to come back here for reference.

@eljeff can you elaborate on how to load an AUPreset file using AudioKit?

@derekfairholm what part do you need me to elaborate on? What have you you tried and what has not worked so far? Where is the AUPreset coming from? How are your samples organised?

Thanks for replying @eljeff. I'm just looking for an alternative to loading the EXS24 file for use with the AKSampler. I've really exhausted my patience trying to load the EXS24 file with all of the info on this thread and can't manage to do it. It sounds like you're saying that an AUPreset file is a less problematic alternative to EXS24, but AudioKit doesn't seem to have a method to load that filetype from the AKSampler. I've been using a .SF2 sound font to build my project so far, but sound quality wise it falls short. I've built an AUPreset in AULab and I'm wondering how to load that file into the AKSampler. My samples are in my project bundle with the path "/Sounds/Samples"

AKSampler.loadPath(_ filePath: String)

That will load your aupreset file.

Thank you! Now for some reason it can't find the audio files, logging:

loadPath Error loading audio file at /Sounds/AURhodes_1

I've used the samples in my project to create the preset file so I can't imagine what's going on. I wonder if using the AUPresetBuilder is the best option?

Thanks again

That is another, fairly undocumented can of worms. I use it pretty extensively myself but it was through lots of trial and error that I got it working. I'm not sure which will be better / easier to get working - trying to tackle AUPresetBuilder, or figuring out why it can't find your files.

My suggestion would be to make a dead simple aupreset with ONE audio file, get that working, and then see how that translates to whatever else you are doing.

Remember, the sounds have to be in the same directory structure when you BUILD the instrument as well...so I suggest creating the Sounds folder in your code folder, then building the aupreset from those files.

It's really bizarre--I think I've tried just about everything I can think of here and xCode can't even find the .aupreset file in my project when I run it. When I include file path with the extension it logs:

Preset file 'Sounds/Rhodes.aupreset -- file:///' not found
EXCEPTION (-43): "Preset file not found"

I've triple checked the location all files involved. The aupreset has been built with samples that are in the project bundle. I think I might need to move on to AUPresetBuilder. What a strange and frustrating issue...

Do what you can to browse the files that are actually added to the app package...I can't remember exactly but a lot of times, you can add the files into xCode in groups, and it will just throw them all in the root directory. So try loading it without the directory.

To get the stuff to stay in directories, I drag the files in and choose 'folder reference'.

You are gonna need to get the file system sorted out before anything will work, so again, stay at it as simple as possible and figure that out. Let us know what works for you!