Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define SOUND_DIR "/home/matthew/.steam/steam/steamapps/common/Transistor/Content/Audio/AudenFMOD/Build/Desktop/"
- #include "fmod_studio.hpp"
- #include "fmod.hpp"
- #include <stdio.h>
- #include <vector>
- #include <string>
- #include <string.h>
- #include <stdarg.h>
- #include <unistd.h>
- #include <algorithm>
- #include <iostream>
- #include <sstream>
- class ParameterDetails {
- public:
- std::string name;
- };
- class SoundDetails {
- public:
- int length_ms;
- std::string name;
- std::vector<ParameterDetails> parameters;
- int user_property_count;
- int bank_id;
- int event_id;
- FMOD::Studio::EventDescription * event;
- FMOD::Sound * sound;
- };
- class BankDetails {
- public:
- std::string name;
- std::string filename;
- FMOD::Studio::Bank * bank;
- };
- void ERRCHECK_fn(FMOD_RESULT result, const char *file, int line) {
- if (result != 0) {
- printf("[ERROR] Error at line %i in \"%s\". FMOD_RESULT: %i\n", line, file, result);
- }
- }
- #define ERRCHECK(_result) ERRCHECK_fn(_result, __FILE__, __LINE__)
- void RecurseSounds(FMOD::System * system, std::vector<SoundDetails> * soundDetails, std::vector<BankDetails> * bankDetails, int bank_id, FMOD::Sound * sound) {
- SoundDetails soundDetail;
- soundDetail.event = NULL;
- sound->getLength((unsigned int *)&(soundDetail.length_ms), FMOD_TIMEUNIT_MS);
- char name[8192];
- memset(name, 0, sizeof(name));
- ERRCHECK(sound->getName(name, sizeof(name)));
- soundDetail.name = std::string(name);
- soundDetail.user_property_count = 0;
- soundDetail.bank_id = bank_id;
- soundDetail.event_id = 0;
- soundDetail.sound = sound;
- soundDetails->push_back(soundDetail);
- int numSubSounds = 0;
- ERRCHECK(sound->getNumSubSounds(&numSubSounds));
- for (int i=0; i<numSubSounds; i++) {
- FMOD::Sound * subSound;
- ERRCHECK(sound->getSubSound(i, &subSound));
- RecurseSounds(system, soundDetails, bankDetails, bank_id, subSound);
- }
- }
- void LoadBank(FMOD::Studio::System * system, std::vector<SoundDetails> * soundDetails, std::vector<BankDetails> * bankDetails, const char * filename) {
- printf("[LoadBank] Loading \"%s\".\n", filename);
- BankDetails bank;
- bank.name = std::string(filename);
- bank.filename = std::string(SOUND_DIR) + std::string(filename);
- ERRCHECK(system->loadBankFile(bank.filename.c_str(), 0, &bank.bank));
- int event_count = -1;
- ERRCHECK(bank.bank->getEventCount(&event_count));
- printf("[LoadBank] Bank has %i events.\n", event_count);
- int bus_count = -1;
- ERRCHECK(bank.bank->getBusCount(&bus_count));
- printf("[LoadBank] Bank has %i busses.\n", bus_count);
- int string_count = -1;
- ERRCHECK(bank.bank->getStringCount(&string_count));
- printf("[LoadBank] Bank has %i strings.\n", string_count);
- int vca_count = -1;
- ERRCHECK(bank.bank->getVCACount(&vca_count));
- printf("[LoadBank] Bank has %i \"VCA\"s.\n", vca_count);
- bankDetails->push_back(bank);
- FMOD::Studio::EventDescription ** events = new FMOD::Studio::EventDescription*[event_count];
- int event_list_count = -1;
- ERRCHECK(bank.bank->getEventList(events, event_count, &event_list_count));
- printf("[LoadBank] Reading %i event descriptors.\n", event_list_count);
- //std::vector<std::string> names;
- for (int i=0; i<event_count; i++) {
- SoundDetails sound;
- sound.sound = NULL;
- sound.event = events[i];
- char path[8192];
- memset(path, 0, sizeof(path));
- int out_len;
- ERRCHECK(events[i]->getPath(path, sizeof(path), &out_len));
- sound.name = std::string(path);
- ERRCHECK(events[i]->getLength(&sound.length_ms));
- ERRCHECK(events[i]->getUserPropertyCount(&sound.user_property_count));
- int param_count;
- ERRCHECK(events[i]->getParameterCount(¶m_count));
- for (int j=0; j<param_count; j++) {
- FMOD_STUDIO_PARAMETER_DESCRIPTION param;
- ERRCHECK(events[i]->getParameterByIndex(j, ¶m));
- ParameterDetails param_details;
- param_details.name = std::string(param.name);
- sound.parameters.push_back(param_details);
- }
- sound.bank_id = bankDetails->size() - 1;
- sound.event_id = i;
- soundDetails->push_back(sound);
- }
- }
- void LoadVO(FMOD::System * system, std::vector<SoundDetails> * soundDetails, std::vector<BankDetails> * bankDetails, const char * filename) {
- printf("[LoadVO] Loading \"%s\".\n", filename);
- BankDetails bank;
- bank.name = std::string(filename);
- bank.filename = std::string(SOUND_DIR) + std::string(filename);
- bankDetails->push_back(bank);
- FMOD::Sound * sound;
- ERRCHECK(system->createSound(bank.filename.c_str(), 584, NULL, &sound));
- RecurseSounds(system, soundDetails, bankDetails, bankDetails->size() - 1, sound);
- }
- bool SoundDetailsComparator(const SoundDetails & x, const SoundDetails & y) {
- return x.name.compare(y.name) < 0;
- }
- bool channelFinished = false;
- FMOD_RESULT F_CALLBACK channelEndCallback(FMOD_CHANNELCONTROL *chanControl, FMOD_CHANNELCONTROL_TYPE controlType, FMOD_CHANNELCONTROL_CALLBACK_TYPE callbackType, void *commandData1, void *commandData2)
- {
- if (callbackType == FMOD_CHANNELCONTROL_CALLBACK_END) {
- channelFinished = true;
- }
- return FMOD_OK;
- }
- // Split from https://stackoverflow.com/questions/236129, thanks to Evan Teran.
- std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
- std::stringstream ss(s);
- std::string item;
- while (std::getline(ss, item, delim)) {
- elems.push_back(item);
- }
- return elems;
- }
- std::vector<std::string> split(const std::string &s, char delim) {
- std::vector<std::string> elems;
- split(s, delim, elems);
- return elems;
- }
- /* // This is gonna take way too long...
- // output.getnumdrivers = GetNumDriversCB;
- FMOD_RESULT F_CALLBACK FMOD_OUTPUT_GETNUMDRIVERS_CALLBACK(FMOD_OUTPUT_STATE *output_state, int *numdrivers) {
- *numdrivers = 1;
- }
- // output.getdriverinfo = GetDriverInfoCB;
- FMOD_RESULT F_CALLBACK FMOD_OUTPUT_GETDRIVERINFO_CALLBACK(
- FMOD_OUTPUT_STATE *output_state,
- int id,
- char *name,
- int namelen,
- FMOD_GUID *guid,
- int *systemrate,
- FMOD_SPEAKERMODE *speakermode,
- int *speakermodechannels
- ) {
- if (name != NULL)
- name[0] = 0;
- if (systemrate != NULL)
- *systemrate = 0;
- if (speakermode != NULL)
- *speakermode = FMOD_SPEAKERMODE_STEREO;
- if (speakermodechannels != NULL)
- *speakermodechannels = 2;
- }
- // output.init = InitCB;
- FMOD_RESULT F_CALLBACK FMOD_OUTPUT_INIT_CALLBACK(
- FMOD_OUTPUT_STATE *output_state,
- int selecteddriver,
- FMOD_INITFLAGS flags,
- int *outputrate,
- FMOD_SPEAKERMODE *speakermode,
- int *speakermodechannels,
- FMOD_SOUND_FORMAT *outputformat,
- int dspbufferlength,
- int dspnumbuffers,
- void *extradriverdata
- ) {
- }
- // output.start = StartCB;
- // output.stop = StopCB;
- // output.close = CloseCB;
- // output.update = UpdateCB;
- // output.gethandle = GetHandleCB;
- // output.getposition = GetPositionCB;
- // output.lock = LockCB;
- // output.unlock = UnlockCB;
- */
- int main(int argc, char ** argv)
- {
- FMOD::Studio::System* system;
- ERRCHECK(FMOD::Studio::System::create(&system));
- FMOD::System* lowLevelSystem;
- ERRCHECK(system->getLowLevelSystem(&lowLevelSystem));
- unsigned int handle;
- ERRCHECK(lowLevelSystem->setPluginPath("/home/matthew/Documents/FMOD/test"));
- ERRCHECK(lowLevelSystem->loadPlugin("libFModPlugins.so", &handle, 0));
- /*
- FMOD_OUTPUT_DESCRIPTION output;
- output.name = "Raw Output";
- output.version = 1;
- output.polling = 0;
- output.getnumdrivers = GetNumDriversCB;
- output.getdriverinfo = GetDriverInfoCB;
- output.init = InitCB;
- output.start = StartCB;
- output.stop = StopCB;
- output.close = CloseCB;
- output.update = UpdateCB;
- output.gethandle = GetHandleCB;
- output.getposition = GetPositionCB;
- output.lock = LockCB;
- output.unlock = UnlockCB;
- unsigned int output_handle;
- ERRCHECK(lowLevelSystem->registerOutput(&output, &output_handle));
- ERRCHECK(lowLevelSystem->setOutputByPlugin(output_handle));
- */
- // UNCOMMENT THIS IF WANT TO SAVE TO WAV FILE. FMOD_OUTPUTTYPE_WAVWRITER_NRT is supposed to work but
- // doesn't. (NRT means not-real-time, so you wouldn't have to wait for the sound to play for it to save)
- // ERRCHECK(lowLevelSystem->setOutput(FMOD_OUTPUTTYPE_WAVWRITER));
- ERRCHECK(system->initialize(32, FMOD_STUDIO_INIT_NORMAL, FMOD_INIT_NORMAL, 0));
- std::vector<SoundDetails> soundDetails;
- std::vector<BankDetails> bankDetails;
- LoadBank(system, &soundDetails, &bankDetails, "MasterBank.strings.bank");
- LoadBank(system, &soundDetails, &bankDetails, "MasterBank.bank");
- LoadBank(system, &soundDetails, &bankDetails, "AudenFMOD_Sounds.bank");
- LoadBank(system, &soundDetails, &bankDetails, "AudenFMOD_OldSounds.bank");
- LoadBank(system, &soundDetails, &bankDetails, "AudenFMOD_Music.bank");
- LoadBank(system, &soundDetails, &bankDetails, "AudenFMOD_Ambience.bank");
- LoadVO(lowLevelSystem, &soundDetails, &bankDetails, "VO.fsb");
- std::sort(soundDetails.begin(), soundDetails.end(), SoundDetailsComparator);
- for (int i=0; i<soundDetails.size(); i++) {
- printf("[Event] %i: %-80s (from %-24s, length: %5i)\n", i, soundDetails[i].name.c_str(), bankDetails[soundDetails[i].bank_id].name.c_str(), soundDetails[i].length_ms);
- }
- while (true) {
- std::string sound_string;
- std::cout << "[Main] Enter sound to play (nothing to quit, 0-5 to play 0-5 inclusive): ";
- std::cin >> sound_string;
- std::vector<std::string> numbers = split(sound_string, '-');
- int start = 0;
- int end = 0;
- if (numbers.size() == 1) {
- start = end = atoi(numbers[0].c_str());
- } else if (numbers.size() == 2) {
- start = atoi(numbers[0].c_str());
- end = atoi(numbers[1].c_str());
- } else {
- break;
- }
- if (start < 0 || start >= soundDetails.size() || end < 0 || end >= soundDetails.size()) {
- break;
- }
- for (int sound_id = start; sound_id <= end; sound_id++) {
- const SoundDetails & sound = soundDetails[sound_id];
- std::cout << "[Main] Playing " << sound_id << " (" << sound.name << ")..." << std::endl;
- if (sound.sound == NULL) {
- FMOD::Studio::EventInstance * instance;
- ERRCHECK(sound.event->createInstance(&instance));
- ERRCHECK(instance->start());
- FMOD_STUDIO_PLAYBACK_STATE state;
- do {
- ERRCHECK(instance->getPlaybackState(&state));
- ERRCHECK(system->update());
- usleep(1000);
- } while (state != FMOD_STUDIO_PLAYBACK_STOPPED);
- } else {
- FMOD::Channel * channel;
- ERRCHECK(lowLevelSystem->playSound(sound.sound, NULL, false, &channel));
- channel->setCallback(channelEndCallback);
- channelFinished = false;
- while (!channelFinished) {
- ERRCHECK(system->update());
- usleep(1000);
- }
- }
- }
- }
- ERRCHECK(system->release());
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement