iOS AUSampler audiounit - file path issue with EXS audio files? - ios

Following the Apple docs here I have been able to successfully load a GarageBand EXS sampler instrument into AUSampler in my iOS app by recreating, for example the following path within my app directory:
/Sampler Files/Funk Horn Section/nameofaudio.aif
iOS looks for the audio file in the following directory:
file:///Library/Application%20Support/GarageBand/Instrument%20Library/Sampler/Sampler%20Files/Funk%20Horn%20Section/'
However this doesn't work when I create my own EXS file. How does it know to remove the first part of the filepath if GarageBand?? I've even tried creating my EXS instrument and even created in the same GarageBand directory but it makes no difference:
Failed to locate sample '001%20VirusTI%20-%20SeaThr%2314A1B3.aif -- file:///macSSD/Library/Application%20Support/GarageBand/Instrument%20Library/Sampler/Sampler%20Files/VirusTI%20-%20SeaThreeHS%20v2/'
I've also tried manually editing the file path in the exs file with a text editor but nothing works.
The EXS instrument plays fine in logic. But my app can't find it.
Any help greatly appreciated.

The key here is that your source sampler file has to reference samples that come from any of these 'trigger' directory structures to work properly:
"/Sounds/"
"/Sampler Files/"
"/Apple Loops/"
"/EXS Factory Samples/"
"/SoundFont Samples/"
Your sample has to exist in a directory path with one of those triggers in it, and then the path has to match the exact same in your bundle. iOS looks for one of those triggers, then deletes everything before that, and uses that as the new search path in the bundle to find your sample.
It is tricky, but it will work this way if you make sure everything is in order.
I fought with this because my samples were stored in places without any of those keywords, and so it would never find them.

Related

Editing MP3/Wav Files in a Flutter App (Dart)

Is it possible in a Flutter App to "concatenate" sound files without calling Swift/Java code to handle it for me? (Partially because I don't know Swift, and partially because I haven't figured out ffmpeg yet) The microphone provides either mp3 or wav files, and either works fine for me.
I'm attempting to make a Recording app that has more functionality than the ones I've previously found. Specifically, I want it to be able to pause the recording for an indefinite amount of time, and start again WITHOUT creating two files for the user to save -- it should combine them and save it later as a single file.
You can take a look about this
medcorder_audio
and for splitting
audiocutter

How to loading outside .love save file? (love2d+ LUA)

I write editor and game and it requires a save game option.
I Just want use a Save folder in game folder. not inside.love
How to get a bug.
Start game
Enter menu by Escape key
Press save game - this create savegame
Press Load game - you get an error "File not exist" but you write this file seconds ago.
I successful save a game in savesm2k folder but it folder outside .love file and i don't know how correct load saved game.
Used engine: Love2d 0.10.2
OS: Linux Mint 18.1 x64bit
I read many manuals and I'm stuck.
For loading save game i use this commands
lsg=love.filesystem.getSaveDirectory().."/M2k-Saves/m2ksave"
lsg=love.filesystem.getSourceBaseDirectory().."/M2k-Saves/m2ksave";
data, size = love.filesystem.read (lsg);
leveldatacopy=freadbin (data);
Why does the program not try read existing file? and report no exist? I try using another command but using GetSaveDirectory broke function WriteMAP (requires for binary map and data writing) etc. but it write files which cannot be loaded in load section.
Maybe I should use LUA for reading files direct from folder but I don't know how to correct DO it.
example with bug.
https://github.com/dj--alex/m2ktest
file m2ktest-load-savegame-test.love
At this moment on every saving i manually replace saved game inside love archive (!) . This is not normal.
Anybody can tell me how i get and correct open saved file? Not from inside .love file . from outside of course. If levels and configs can be readed from love file inside save files must be outside. I can only can create files outside love file . i know love file is a zip archive.
If required i can post a .love file but is game completely done and have 150kb of clean code.
You should not prefix paths with love.filesystem.getSaveDirectory() or love.filesystem.getSourceBaseDirectory(). This is done automatically, internally to the love.filesystem functions. Saying
lsg = "/M2k-Saves/m2ksave"
data, size = love.filesystem.read (lsg)
leveldatacopy = freadbin (data)
should work, and will place the file in the save directory / outside of the .love file or game directory. (Love forbids writing anywhere except in the save directory.)
Love's filesystem model is like a "stack" of filesystems. For file reading, it first looks in love.filesystem.getSaveDirectory() with whatever path you pass in. If it finds a file, it uses that; otherwise it looks inside the love.filesystem.getSourceBaseDirectory() (or – if packed – inside the .zip / .love file). Writing files always goes to love.filesystem.getSaveDirectory(), you cannot write to love.filesystem.getSourceBaseDirectory() (because it may not be an actual directory but a zip file).

AUSampler: referencing external (downloaded) audio files

I have an app that uses .aupreset files along with .wav samples to define instruments that are loaded into an AUSampler audio unit.
The .aupreset files reference the .wav files with absolute paths. As described in Technical Note 2283, if the audio files cannot be found at the original path, then the system searches in the Bundle Directory, NSLibraryDirectory, NSDocumentsDirectory, and NSDownloadsDirectory, in that order.
I can get the instruments working in the app bundle, but now I'm trying to support downloaded instruments. If I put the content in <NSLibraryDirectory>/Sounds/, the AUSampler can't find the .wav samples, but if I put it in <NSDocumentsDirectory>/Sounds/, it works. I don't want to clutter the Documents directory with the instruments though, as that folder shows up in iTunes.
This is the error printed by the AUSampler:
09:27:25.251 ERROR: [0x19989c310] 372: Failed to locate sample 'file:///Sounds/trance/square-lead/Square-12000Hz.wav'
Also, I can't even create a directory at the NSDownloadsDirectory location - I just get an Operation not permitted error.
Has anyone successfully loaded samples from the Library before?
(This is on iOS 8.)
I received this explanation from an Apple Engineer:
It turns out the documentation for this is incorrect for iOS: AUSampler will only look in NSDocumentDirectory and the NSDownloadsDirectory in addition to the bundle. These are the recommended locations for storing application-specific data, if you aren't going to store it in the bundle, or you wish to enable users to add additional content to the app.
For OSX, the NSLibraryDirectory is also available.
From my own testing, however, you can't use the NSDownloadsDirectory either, as trying to create the directory returns an error ("The operation couldn’t be completed. Operation not permitted"). So it would appear that the only options on iOS are loading from the bundle or from the Documents directory.
This isn't ideal when you also want to enable iTunes File Sharing for other content, so I did think of another workaround: put the content in an arbitrary location, and when loading the .aupreset file, rewrite all the file references to refer to that location before setting it on the Audio Unit.
Yes, you can definitely load samples from the Library directory.
I thought you had to create the library directory, but I was mistaken. It is the Application Support directory I was thinking of.

NULL when using fopen with xcode

I am trying to initialize a multidimensional array from a file using C for a iPhone 4inch app but I can't open up the file using fopen.
Whenever I try this I get a NULL:
FILE *f;
f=fopen("/level1.rez", "r");
if (f == NULL)
{
printf("Error Reading File\n");
//exit (0);
}
I am not sure how to open files using C.
I tried this already:
I printed out the current working directory using getcwd but all I got was "/" and when I attached that to the file name I still got NULL.
I read that if you go to product > scheme > edit scheme then options you can change the current working directory but I don't see that option.
Also I read that you can use absolute paths like: /users/name/desktop/program
but I am new to iOS development so I don't know if that is a good idea.
So how do I get fopen to work?
You CAN specify absolute paths in iOS, but the path in your example is probably used in Mac OS, which is laid out a little differently. You can specify paths to fopen() as you say, but there is more work to finding out what the first part of that path really is.
The iOS puts all AppStore apps into folders with randomly generated sandbox directory names. It is basically the the hexadecimal string of a GUID. So you need to use methods from iOS frameworks to get the first part of the path (or URL) to your file.
If the file is part of the app bundle so it can ship with the app, then you will need to use NSBundle methods to find the path to the file.
If the file is generated or downloaded after the app starts up on the device, then you need to use NSFileManager methods to determine the path to the directory of the file. (Typically the Documents directory. You can build a directory structure of your choice within the sandbox.)

Saving xml file on iOS (pugiXml and Cocos2d-x)

Recently I've ran into a big problem with pugiXml (used within cocos2d-x engine).
Shortly, I've made a quiz game (in mentioned Cocos2d-x). I keep my questions (and some other data) in an Xml file. On new game they get parsed and inserted into dictionaries. If a question is answered, a short string indicating the answer (whether it was good or not - Y/N) is inserted into that Xml file (below that particular question). Later, I use this data to show statistics (I count the percentage of questions with good answers - which is counting the amount of Y's divided by the amount of questions, multiplied by 100).
I use:
CCFileUtils::sharedFileUtils()->fullPathForFilename(o_QA);
to get the file and later
pBuffer = CCFileUtils::sharedFileUtils()->getFileData(fullPath.c_str(), "rb", &bufferSize);
to put file into buffer and
pugi::xml_parse_result result = doc.load_buffer(pBuffer,bufferSize);
to parse data and start working on it.
Finally, I save the file with:
doc.save_file(fullPath.c_str());
Android:
It's working very well, although I had to copy the file with questions to /data/data/app/Files/ . Still, It's keeping the changes on many devices.
iOS:
Unfortunately, on iOS it's not working. Data get loaded and parsed (which means, that I can actually play the game), but they are not saved. I've tried moving the files to other folders (started from Resources/Documents, then main Resources folder, Resources/Library/Application Support). It's still not saving the data and I don't know what to do. The result is my statistics not being counted well (it doesn't matter how you answer the questions - all of them are false, because the Xml file is not being updated).
Did anyone run into similar problem?
Can you, please, help me?
I am doing something similar in my own app, using both pugixml and cocos2d-x. So I can confirm this combination works well.
Rather, because on iOS you cannot both read and write the data from and to the app bundle (which is read only), you will need to implement a simple check in the writable document directory - If you a saved file there, load it, if not, load from the app bundle.
So in essence for loading, if your saved filename is "my_save.xml", here is an example flow:
1) Construct a path for your save file in the writable folder by concatenating the writable folder path + your filename. CCFileUtils should have something like getWritablePath() for that.
2) if the file exists in the folder, load it. Otherwise, go to 3).
3) Construct a path to your original data file from the app bundle, using CCFileUtils::sharedFileUtils()->fullPathForFilename(). Load the file from there.
For saving, simply do step 1 and save the file there.

Resources