I understand that I can use Projucer to make binary data of files to embed in code, however say that for whatever reason I do not want to do that and instead want to include said files in a finished App, in the install package, where do I store files (audio, images, videos, documents, and so on) in my project so I do not have to enter a path?
I tried to files via “Add Existing Files…” in Projucer, and then restarted VS and the files show there, however file is not found (nullptr).
Here is my simple test code;
formatManager.registerBasicFormats();
transportSource.addChangeListener(this);
File* file = new File("BrickHit.wav");
auto reader = formatManager.createReaderFor(*file);
if (reader != nullptr)
{
std::unique_ptr<AudioFormatReaderSource> newSource(new AudioFormatReaderSource(reader, true));
transportSource.setSource(newSource.get(), 0, nullptr, reader->sampleRate);
transportSource.start();
}
Windows doesn’t have the concept of bundles, so you are on your own to put files in a known location. You will have to create an installer for that purpose, and you can use File::getSpecialLocation() to choose a suitable location, without hardcoding paths.
To be clear, unless I put my files say in a special location, say “Desktop” and use getSpecialLocation(), even though my resource files are in my Projucer’s project root folder, I have to use absolute path to access these files in my code?
You have to distinguish between two perspectives: Compile time and run time.
Files you add to the project in the Projucer are meant to be resources for compile time, e.g. files that are needed to compile the application but not to run the application. To make it clear, if you distribute your plugin or application, you won’t ship the cpp source files, you will ship a compiled binary, built from these source files. The same goes for other resources that come with the project. Therefore it is a nice technique to embed files you need into your compiled binary as binary resource, this way they become part of your compiled executable.
The runtime perspective on the other hand does not even know that there was something like a Projucer project it was generated from. So if you want to load files at runtime you need to put them to a known location on the computer and load it from there at runtime. Therefore you need to create an installer tool, that makes sure that theses files will be copied to that exact location to be loadable at runtime. So you’re better off designing it in such a way that this file is not part of the project folder structure, except for the sake of building the installer from there.
So in my above example code, which was after I had added the wav file as a binary resource in Projucer, and then opened Visual Studio, and then compiled, I should be good right and only need to distribute the generated exe file right? Because when I go to the build folder after compilation, and copy the exe file to my desktop and run it, my sound still plays, leading me to believe the wav file is embedded in the exe file or am I wrong?
void MainComponent::releaseResources()
{
// This will be called when the audio device stops, or when it is being
// restarted due to a setting change.
// For more details, see the help for AudioProcessor::releaseResources()
transportSource.releaseResources();
}
Again, refer the the AudioTransportSource docs. It says that it does not own the object you pass in, and you need to manage it yourself. It’s good practice to read the docs when passing pointers around.
Now although above worked fine for playing a single wav file, I now have a problem playing several different, that may or may not be running at the same time, or at least overlapping.