Craxic

Transistor Sound Ripper

Jan 6th, 2015
245
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #define SOUND_DIR "/home/matthew/.steam/steam/steamapps/common/Transistor/Content/Audio/AudenFMOD/Build/Desktop/"
  2.  
  3. #include "fmod_studio.hpp"
  4. #include "fmod.hpp"
  5. #include <stdio.h>
  6. #include <vector>
  7. #include <string>
  8. #include <string.h>
  9. #include <stdarg.h>
  10. #include <unistd.h>
  11. #include <algorithm>
  12. #include <iostream>
  13. #include <sstream>
  14.  
  15. class ParameterDetails {
  16. public:
  17.     std::string name;
  18. };
  19.  
  20. class SoundDetails {
  21. public:
  22.     int length_ms;
  23.     std::string name;
  24.     std::vector<ParameterDetails> parameters;
  25.     int user_property_count;
  26.     int bank_id;
  27.     int event_id;
  28.     FMOD::Studio::EventDescription * event;
  29.     FMOD::Sound * sound;
  30. };
  31.  
  32. class BankDetails {
  33. public:
  34.     std::string name;
  35.     std::string filename;
  36.     FMOD::Studio::Bank * bank;
  37. };
  38.  
  39. void ERRCHECK_fn(FMOD_RESULT result, const char *file, int line) {
  40.     if (result != 0) {
  41.         printf("[ERROR] Error at line %i in \"%s\". FMOD_RESULT: %i\n", line, file, result);
  42.     }
  43. }
  44. #define ERRCHECK(_result) ERRCHECK_fn(_result, __FILE__, __LINE__)
  45.  
  46. void RecurseSounds(FMOD::System * system, std::vector<SoundDetails> * soundDetails, std::vector<BankDetails> * bankDetails, int bank_id, FMOD::Sound * sound) {
  47.     SoundDetails soundDetail;
  48.     soundDetail.event = NULL;
  49.    
  50.     sound->getLength((unsigned int *)&(soundDetail.length_ms), FMOD_TIMEUNIT_MS);
  51.    
  52.     char name[8192];
  53.     memset(name, 0, sizeof(name));
  54.     ERRCHECK(sound->getName(name, sizeof(name)));
  55.     soundDetail.name = std::string(name);
  56.    
  57.     soundDetail.user_property_count = 0;
  58.     soundDetail.bank_id = bank_id;
  59.     soundDetail.event_id = 0;
  60.     soundDetail.sound = sound;
  61.     soundDetails->push_back(soundDetail);
  62.    
  63.     int numSubSounds = 0;
  64.     ERRCHECK(sound->getNumSubSounds(&numSubSounds));
  65.    
  66.     for (int i=0; i<numSubSounds; i++) {
  67.         FMOD::Sound * subSound;
  68.         ERRCHECK(sound->getSubSound(i, &subSound));
  69.         RecurseSounds(system, soundDetails, bankDetails, bank_id, subSound);
  70.     }
  71.    
  72. }
  73.  
  74. void LoadBank(FMOD::Studio::System * system, std::vector<SoundDetails> * soundDetails, std::vector<BankDetails> * bankDetails, const char * filename) {
  75.     printf("[LoadBank] Loading \"%s\".\n", filename);
  76.    
  77.     BankDetails bank;
  78.     bank.name = std::string(filename);
  79.     bank.filename = std::string(SOUND_DIR) + std::string(filename);
  80.     ERRCHECK(system->loadBankFile(bank.filename.c_str(), 0, &bank.bank));
  81.    
  82.     int event_count = -1;
  83.     ERRCHECK(bank.bank->getEventCount(&event_count));
  84.     printf("[LoadBank] Bank has %i events.\n", event_count);
  85.    
  86.     int bus_count = -1;
  87.     ERRCHECK(bank.bank->getBusCount(&bus_count));
  88.     printf("[LoadBank] Bank has %i busses.\n", bus_count);
  89.    
  90.     int string_count = -1;
  91.     ERRCHECK(bank.bank->getStringCount(&string_count));
  92.     printf("[LoadBank] Bank has %i strings.\n", string_count);
  93.    
  94.     int vca_count = -1;
  95.     ERRCHECK(bank.bank->getVCACount(&vca_count));
  96.     printf("[LoadBank] Bank has %i \"VCA\"s.\n", vca_count);
  97.    
  98.     bankDetails->push_back(bank);
  99.    
  100.     FMOD::Studio::EventDescription ** events = new FMOD::Studio::EventDescription*[event_count];
  101.     int event_list_count = -1;
  102.     ERRCHECK(bank.bank->getEventList(events, event_count, &event_list_count));
  103.     printf("[LoadBank] Reading %i event descriptors.\n", event_list_count);
  104.    
  105.     //std::vector<std::string> names;
  106.     for (int i=0; i<event_count; i++) {
  107.         SoundDetails sound;
  108.         sound.sound = NULL;
  109.         sound.event = events[i];
  110.        
  111.         char path[8192];
  112.         memset(path, 0, sizeof(path));
  113.         int out_len;
  114.         ERRCHECK(events[i]->getPath(path, sizeof(path), &out_len));
  115.         sound.name = std::string(path);
  116.         ERRCHECK(events[i]->getLength(&sound.length_ms));
  117.         ERRCHECK(events[i]->getUserPropertyCount(&sound.user_property_count));
  118.        
  119.         int param_count;
  120.         ERRCHECK(events[i]->getParameterCount(&param_count));
  121.        
  122.         for (int j=0; j<param_count; j++) {
  123.             FMOD_STUDIO_PARAMETER_DESCRIPTION param;
  124.             ERRCHECK(events[i]->getParameterByIndex(j, &param));
  125.            
  126.             ParameterDetails param_details;
  127.             param_details.name = std::string(param.name);
  128.             sound.parameters.push_back(param_details);
  129.         }
  130.        
  131.         sound.bank_id = bankDetails->size() - 1;
  132.         sound.event_id = i;
  133.         soundDetails->push_back(sound);
  134.     }
  135. }
  136.  
  137. void LoadVO(FMOD::System * system, std::vector<SoundDetails> * soundDetails, std::vector<BankDetails> * bankDetails, const char * filename) {
  138.     printf("[LoadVO] Loading \"%s\".\n", filename);
  139.  
  140.     BankDetails bank;
  141.     bank.name = std::string(filename);
  142.     bank.filename = std::string(SOUND_DIR) + std::string(filename);
  143.    
  144.     bankDetails->push_back(bank);
  145.    
  146.     FMOD::Sound * sound;
  147.     ERRCHECK(system->createSound(bank.filename.c_str(), 584, NULL, &sound));
  148.    
  149.     RecurseSounds(system, soundDetails, bankDetails, bankDetails->size() - 1, sound);
  150. }
  151.  
  152. bool SoundDetailsComparator(const SoundDetails & x, const SoundDetails & y) {
  153.     return x.name.compare(y.name) < 0;
  154. }
  155.  
  156. bool channelFinished = false;
  157.  
  158. FMOD_RESULT F_CALLBACK channelEndCallback(FMOD_CHANNELCONTROL *chanControl, FMOD_CHANNELCONTROL_TYPE controlType, FMOD_CHANNELCONTROL_CALLBACK_TYPE callbackType, void *commandData1, void *commandData2)
  159. {
  160.     if (callbackType == FMOD_CHANNELCONTROL_CALLBACK_END) {
  161.         channelFinished = true;
  162.     }
  163.  
  164.     return FMOD_OK;
  165. }
  166.  
  167. // Split from https://stackoverflow.com/questions/236129, thanks to Evan Teran.
  168. std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
  169.     std::stringstream ss(s);
  170.     std::string item;
  171.     while (std::getline(ss, item, delim)) {
  172.         elems.push_back(item);
  173.     }
  174.     return elems;
  175. }
  176.  
  177. std::vector<std::string> split(const std::string &s, char delim) {
  178.     std::vector<std::string> elems;
  179.     split(s, delim, elems);
  180.     return elems;
  181. }
  182.  
  183. /* // This is gonna take way too long...
  184. //    output.getnumdrivers = GetNumDriversCB;
  185. FMOD_RESULT F_CALLBACK FMOD_OUTPUT_GETNUMDRIVERS_CALLBACK(FMOD_OUTPUT_STATE *output_state, int *numdrivers) {
  186.     *numdrivers = 1;
  187. }
  188. //    output.getdriverinfo = GetDriverInfoCB;
  189. FMOD_RESULT F_CALLBACK FMOD_OUTPUT_GETDRIVERINFO_CALLBACK(
  190.     FMOD_OUTPUT_STATE *output_state,
  191.     int id,
  192.     char *name,
  193.     int namelen,
  194.     FMOD_GUID *guid,
  195.     int *systemrate,
  196.     FMOD_SPEAKERMODE *speakermode,
  197.     int *speakermodechannels
  198. ) {
  199.     if (name != NULL)
  200.         name[0] = 0;
  201.     if (systemrate != NULL)
  202.         *systemrate = 0;
  203.     if (speakermode != NULL)
  204.         *speakermode = FMOD_SPEAKERMODE_STEREO;
  205.     if (speakermodechannels != NULL)
  206.         *speakermodechannels = 2;
  207. }
  208. //    output.init = InitCB;
  209. FMOD_RESULT F_CALLBACK FMOD_OUTPUT_INIT_CALLBACK(
  210.   FMOD_OUTPUT_STATE *output_state,
  211.   int selecteddriver,
  212.   FMOD_INITFLAGS flags,
  213.   int *outputrate,
  214.   FMOD_SPEAKERMODE *speakermode,
  215.   int *speakermodechannels,
  216.   FMOD_SOUND_FORMAT *outputformat,
  217.   int dspbufferlength,
  218.   int dspnumbuffers,
  219.   void *extradriverdata
  220. ) {
  221.    
  222. }
  223. //    output.start = StartCB;
  224. //    output.stop = StopCB;
  225. //    output.close = CloseCB;
  226. //    output.update = UpdateCB;
  227. //    output.gethandle = GetHandleCB;
  228. //    output.getposition = GetPositionCB;
  229. //    output.lock = LockCB;
  230. //    output.unlock = UnlockCB;
  231. */
  232.  
  233. int main(int argc, char ** argv)
  234. {
  235.     FMOD::Studio::System* system;
  236.     ERRCHECK(FMOD::Studio::System::create(&system));
  237.     FMOD::System* lowLevelSystem;
  238.     ERRCHECK(system->getLowLevelSystem(&lowLevelSystem));
  239.    
  240.     unsigned int handle;
  241.    
  242.     ERRCHECK(lowLevelSystem->setPluginPath("/home/matthew/Documents/FMOD/test"));
  243.     ERRCHECK(lowLevelSystem->loadPlugin("libFModPlugins.so", &handle, 0));
  244.    
  245.     /*
  246.     FMOD_OUTPUT_DESCRIPTION output;
  247.     output.name = "Raw Output";
  248.     output.version = 1;
  249.     output.polling = 0;
  250.     output.getnumdrivers = GetNumDriversCB;
  251.     output.getdriverinfo = GetDriverInfoCB;
  252.     output.init = InitCB;
  253.     output.start = StartCB;
  254.     output.stop = StopCB;
  255.     output.close = CloseCB;
  256.     output.update = UpdateCB;
  257.     output.gethandle = GetHandleCB;
  258.     output.getposition = GetPositionCB;
  259.     output.lock = LockCB;
  260.     output.unlock = UnlockCB;
  261.    
  262.    
  263.     unsigned int output_handle;
  264.     ERRCHECK(lowLevelSystem->registerOutput(&output, &output_handle));
  265.     ERRCHECK(lowLevelSystem->setOutputByPlugin(output_handle));
  266.     */
  267.    
  268. // UNCOMMENT THIS IF WANT TO SAVE TO WAV FILE. FMOD_OUTPUTTYPE_WAVWRITER_NRT is supposed to work but
  269. // doesn't. (NRT means not-real-time, so you wouldn't have to wait for the sound to play for it to save)
  270. //    ERRCHECK(lowLevelSystem->setOutput(FMOD_OUTPUTTYPE_WAVWRITER));
  271.     ERRCHECK(system->initialize(32, FMOD_STUDIO_INIT_NORMAL, FMOD_INIT_NORMAL, 0));
  272.    
  273.     std::vector<SoundDetails> soundDetails;
  274.     std::vector<BankDetails> bankDetails;
  275.    
  276.     LoadBank(system, &soundDetails, &bankDetails, "MasterBank.strings.bank");
  277.     LoadBank(system, &soundDetails, &bankDetails, "MasterBank.bank");
  278.     LoadBank(system, &soundDetails, &bankDetails, "AudenFMOD_Sounds.bank");
  279.     LoadBank(system, &soundDetails, &bankDetails, "AudenFMOD_OldSounds.bank");
  280.     LoadBank(system, &soundDetails, &bankDetails, "AudenFMOD_Music.bank");
  281.     LoadBank(system, &soundDetails, &bankDetails, "AudenFMOD_Ambience.bank");
  282.     LoadVO(lowLevelSystem, &soundDetails, &bankDetails, "VO.fsb");
  283.    
  284.     std::sort(soundDetails.begin(), soundDetails.end(), SoundDetailsComparator);
  285.    
  286.     for (int i=0; i<soundDetails.size(); i++) {
  287.         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);
  288.     }
  289.    
  290.     while (true) {
  291.         std::string sound_string;
  292.         std::cout << "[Main] Enter sound to play (nothing to quit, 0-5 to play 0-5 inclusive): ";
  293.         std::cin >> sound_string;
  294.        
  295.         std::vector<std::string> numbers = split(sound_string, '-');
  296.        
  297.         int start = 0;
  298.         int end = 0;
  299.        
  300.         if (numbers.size() == 1) {
  301.             start = end = atoi(numbers[0].c_str());
  302.         } else if (numbers.size() == 2) {
  303.             start = atoi(numbers[0].c_str());
  304.             end = atoi(numbers[1].c_str());
  305.         } else {
  306.             break;
  307.         }
  308.        
  309.         if (start < 0 || start >= soundDetails.size() || end < 0 || end >= soundDetails.size()) {
  310.             break;
  311.         }
  312.        
  313.         for (int sound_id = start; sound_id <= end; sound_id++) {
  314.             const SoundDetails & sound = soundDetails[sound_id];
  315.            
  316.             std::cout << "[Main] Playing " << sound_id << " (" << sound.name << ")..." << std::endl;
  317.            
  318.             if (sound.sound == NULL) {
  319.                 FMOD::Studio::EventInstance * instance;
  320.                 ERRCHECK(sound.event->createInstance(&instance));
  321.                 ERRCHECK(instance->start());
  322.            
  323.                 FMOD_STUDIO_PLAYBACK_STATE state;
  324.                 do {
  325.                     ERRCHECK(instance->getPlaybackState(&state));
  326.                     ERRCHECK(system->update());
  327.                     usleep(1000);
  328.                 } while (state != FMOD_STUDIO_PLAYBACK_STOPPED);
  329.             } else {
  330.                 FMOD::Channel * channel;
  331.                 ERRCHECK(lowLevelSystem->playSound(sound.sound, NULL, false, &channel));
  332.                 channel->setCallback(channelEndCallback);
  333.                 channelFinished = false;
  334.            
  335.                 while (!channelFinished) {
  336.                     ERRCHECK(system->update());
  337.                     usleep(1000);
  338.                 }
  339.             }
  340.         }
  341.     }
  342.    
  343.     ERRCHECK(system->release());
  344.    
  345.     return 0;
  346. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×