Sound files loading inderpendantly of the source code folder

I am trying to make a standalone app. However the sounds are missing when use the app on another machine without my source code in my OF folder.

I see that the normal way of getting sounds is from the bin/data folder of the source file, and to this end the generation of each new code requires you to give position to the app to access the folder your OF folder is in.

All the examples I have seen seem to use this method. However there is a sound folder in the openFrameworks folder inside Xcode with things like ofFmodSoundPlayer in it.

I suspect this will give access to including sound files already stored inside the Xcode for the app. Are there any examples of using the so that the sound files can be independent of the source code.

Hi @Grumpy_Mike , ofUtils::ofSetDataPathRoot() might be helpful to set the path of the data folder to a predetermined location. Also, I often use an ofDirectory the access media files from a folder for various different oF apps (in psudeo-code):

// in ofApp.h
    const std::string path = "/path/to/media/files/";
    ofDirectory directory;
    ofImage image;

// in ofApp::setup()
    directory.allowExt("jpg");
    directory.listDir(path);
    directory.sort();
    image.load(directory.getFile(0));

Thanks for the reply.
I am a beginner with OF and I am not sure I followed what you were doing.
I set the path to /scr/sounds/ and I put my sound folder in the scr folder but I got an error of source directory does not exist.
Also I am not sure how to use ofUtils::ofSetDataPathRoot() When I call this in the ofApp.h I get an undeclared identifier error.

Hey Mike, for the ofDirectory code above, an absolute path can be specified, though there may be a way to specify a relative path. So, on my linux laptop it will be something like home/chilina/oFImages/source/. The path will be different for different users, and on mac and windows of course.

ofSetDataPathRoot() needs a path as an argument. An absolute path will work, as so will a path that is relative to the location of the data folder. So, these are the same folder location for me:

    // absolute path
    ofSetDataPathRoot("/home/chilina/oFData/data/");
    // relative path: "oF folder/apps/project folder/project/bin/"
    ofSetDataPathRoot("../../../../../ofData/");

I find the relative path notation confusing, so I tend to stick to using absolute paths. Also, ofToDataPath() will return a string with the location of the data folder (relative or absolute depending on the argument passed).

Thanks.
The thing is, that I want to run this app I have written on a machine that does not contain the source code, and so there will be no data folder to point to. All it can possibly point to is a location inside the app. Am I right in thinking that there is no way to do this because the path to get a sound is baked into OF to point somewhere outside the app?

If I move a compiled app from my oF folder to another location in the directory tree and run it, a call to ofDirectory::getAbsolutePath() on an empty directory will get the correct location of the /bin directory for the app. So, I suppose you could use something like that to establish where the application resides in the directory structure.

Edit: Also 1 more thought on this. Using ofxXmlSettings is kind of a fun way to have data (like strings) stored in a file outside of the app. So you could probably work out something with that too, where an app acquires its path to a folder of sound files from an .xml file.

Thanks Tim, but I think you are missing the point here.

I want to run this on a machine that does not contain the source code, therefore there will be no /bin directory on that machine.

That would mean having a app with another place for the files. It will not allow the app to be self contained.

I am getting the feeling that OF can not be used to create stand alone apps that I could distribute to run on machines without the source code being present. So I don’t think OF is of much use to me.

Hi, if you are compiling in for MacOS you can bundle everything inside your app, as in it an app is just a folder. Otherwise, on other platforms there is no way to do such that is implemented with openframeworks. It is still doable, but you will need to implement such. Besides that, regardless of the platform, you dont need to distribute the source code in order to be able to run the app on other computers.

check this How to set path to MacOS .app Resources folder

Then you can manually move the files into the app bundle or add a “Run Script” to the “Build phases” of the xcode project and add the following

rsync -avz --exclude='.DS_Store' "${SRCROOT}/bin/data/" " "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Resources/data/"

Thanks Roy,
That looks like the sort of thing I am after, great.

Unfortunately now my code won’t build (without those path changes) as there is a signing issue that has poped up so I am having to try and sort that out first. I did a search on the forum for this but from what I can see everything is set to --deep.

Hey @roymacdonald , so is the answer to this problem can be summarized as:

  1. Add the following to main.cpp:
	#ifdef TARGET_OSX
		string newRoot = "../Resources/data/";
		ofEnableDataPath();
		ofSetDataPathRoot(newRoot);
	#endif
  1. Move the supporting sound, image, video, shader files into a new subdirectory called “/Resources/data/”, which shares the same folder as the compiled app.

  2. Run the script in your post when the app is compiled?

Do you think that ofSetDataPathRoot() needs to be in main.cpp? Or could it be called in ofApp::setup()?

Do you think that ofSetDataPathRoot() needs to be in main.cpp? Or could it be called in ofApp::setup()?
Yes, otherwise it does not work. Actually it must be the first thing you call. Thus a regular main.cpp file should look like:


#include "ofMain.h"
#include "ofApp.h"

//========================================================================
int main( ){
#ifdef TARGET_OSX
		string newRoot = "../Resources/data/";
		ofEnableDataPath();
		ofSetDataPathRoot(newRoot);
#endif

	ofSetupOpenGL(1024,768,OF_WINDOW);			// <-------- setup the GL context

	// this kicks off the running of my app
	// can be OF_WINDOW or OF_FULLSCREEN
	// pass in width and height too:
	ofRunApp(new ofApp());

}

Move the supporting sound, image, video, shader files into a new subdirectory called “/Resources/data/”, which shares the same folder as the compiled app.

it is either this or add the script. The script runs by itself in xcode when you add it as a build phase when you compile.

rsync -avz --exclude='.DS_Store' "${SRCROOT}/bin/data/" "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Resources/data/"

2 Likes

xcode signing can be a real pain. On my own experience, it is better to let Xcode do it automatically.
There is a script phase in the build phases that does some stuff for the signing. You might want to check that if it is messing something. just an idea… good luck with it