Show More
Commit Description:
Tidy code.
Commit Description:
Tidy code.
References:
File last commit:
Show/Diff file:
Action:
FNA/lib/FAudio/utils/facttool/facttool.cpp
1095 lines | 26.0 KiB | text/x-c | CppLexer
1095 lines | 26.0 KiB | text/x-c | CppLexer
r0 | /* FAudio - XAudio Reimplementation for FNA | |||
* | ||||
* Copyright (c) 2011-2020 Ethan Lee, Luigi Auriemma, and the MonoGame Team | ||||
* | ||||
* This software is provided 'as-is', without any express or implied warranty. | ||||
* In no event will the authors be held liable for any damages arising from | ||||
* the use of this software. | ||||
* | ||||
* Permission is granted to anyone to use this software for any purpose, | ||||
* including commercial applications, and to alter it and redistribute it | ||||
* freely, subject to the following restrictions: | ||||
* | ||||
* 1. The origin of this software must not be misrepresented; you must not | ||||
* claim that you wrote the original software. If you use this software in a | ||||
* product, an acknowledgment in the product documentation would be | ||||
* appreciated but is not required. | ||||
* | ||||
* 2. Altered source versions must be plainly marked as such, and must not be | ||||
* misrepresented as being the original software. | ||||
* | ||||
* 3. This notice may not be removed or altered from any source distribution. | ||||
* | ||||
* Ethan "flibitijibibo" Lee <flibitijibibo@flibitijibibo.com> | ||||
* | ||||
*/ | ||||
/* This is where the actual tool lives! Try to do your work in here! */ | ||||
#include <FACT_internal.h> /* DO NOT INCLUDE THIS IN REAL CODE! */ | ||||
#include "../uicommon/imgui.h" | ||||
#include <SDL.h> | ||||
#include <vector> | ||||
#include <string> | ||||
const char* TOOL_NAME = "FACT Auditioning Tool"; | ||||
int TOOL_WIDTH = 1280; | ||||
int TOOL_HEIGHT = 720; | ||||
bool openEngineShow = true; | ||||
std::vector<FACTAudioEngine*> engines; | ||||
std::vector<std::string> engineNames; | ||||
std::vector<bool> engineShows; | ||||
std::vector<FACTSoundBank*> soundBanks; | ||||
std::vector<std::string> soundbankNames; | ||||
std::vector<bool> soundbankShows; | ||||
std::vector<FACTWaveBank*> waveBanks; | ||||
std::vector<uint8_t*> wavebankMems; | ||||
std::vector<std::string> wavebankNames; | ||||
std::vector<bool> wavebankShows; | ||||
std::vector<FACTWave*> waves; | ||||
void FAudioTool_Init() | ||||
{ | ||||
/* Nothing to do... */ | ||||
} | ||||
void FAudioTool_Quit() | ||||
{ | ||||
for (size_t i = 0; i < soundBanks.size(); i += 1) | ||||
{ | ||||
FACTSoundBank_Destroy(soundBanks[i]); | ||||
} | ||||
for (size_t i = 0; i < waves.size(); i += 1) | ||||
{ | ||||
FACTWave_Destroy(waves[i]); | ||||
} | ||||
for (size_t i = 0; i < waveBanks.size(); i += 1) | ||||
{ | ||||
FACTWaveBank_Destroy(waveBanks[i]); | ||||
SDL_free(wavebankMems[i]); | ||||
} | ||||
for (size_t i = 0; i < engines.size(); i += 1) | ||||
{ | ||||
FACTAudioEngine_ShutDown(engines[i]); | ||||
} | ||||
} | ||||
bool show_test_window = false; | ||||
void FAudioTool_Update() | ||||
{ | ||||
ImGui::ShowDemoWindow(&show_test_window); | ||||
uint8_t *buf; | ||||
size_t len; | ||||
/* Menu bar */ | ||||
if (ImGui::BeginMainMenuBar()) | ||||
{ | ||||
if (ImGui::BeginMenu("Window")) | ||||
{ | ||||
if (ImGui::MenuItem("Open AudioEngine", NULL, openEngineShow, true)) | ||||
{ | ||||
openEngineShow = !openEngineShow; | ||||
} | ||||
for (size_t i = 0; i < engines.size(); i += 1) | ||||
{ | ||||
if (ImGui::MenuItem( | ||||
engineNames[i].c_str(), | ||||
NULL, | ||||
engineShows[i], | ||||
true | ||||
)) { | ||||
engineShows[i] = !engineShows[i]; | ||||
} | ||||
} | ||||
for (size_t i = 0; i < soundBanks.size(); i += 1) | ||||
{ | ||||
if (ImGui::MenuItem( | ||||
soundbankNames[i].c_str(), | ||||
NULL, | ||||
soundbankShows[i], | ||||
true | ||||
)) { | ||||
soundbankShows[i] = !soundbankShows[i]; | ||||
} | ||||
} | ||||
for (size_t i = 0; i < waveBanks.size(); i += 1) | ||||
{ | ||||
if (ImGui::MenuItem( | ||||
wavebankNames[i].c_str(), | ||||
NULL, | ||||
wavebankShows[i], | ||||
true | ||||
)) { | ||||
wavebankShows[i] = !wavebankShows[i]; | ||||
} | ||||
} | ||||
ImGui::EndMenu(); | ||||
} | ||||
ImGui::EndMainMenuBar(); | ||||
} | ||||
/* Open AudioEngine */ | ||||
if (openEngineShow) | ||||
{ | ||||
if (ImGui::Begin("Open AudioEngine")) | ||||
{ | ||||
static char enginename[64] = "AudioEngine.xgs"; | ||||
if (ImGui::InputText( | ||||
"Open AudioEngine", | ||||
enginename, 64, | ||||
ImGuiInputTextFlags_EnterReturnsTrue | ||||
)) { | ||||
/* Load up file... */ | ||||
buf = (uint8_t*) SDL_LoadFile(enginename, &len); | ||||
FACTRuntimeParameters params; | ||||
SDL_memset( | ||||
¶ms, | ||||
'\0', | ||||
sizeof(FACTRuntimeParameters) | ||||
); | ||||
params.pGlobalSettingsBuffer = buf; | ||||
params.globalSettingsBufferSize = len; | ||||
/* Create engine... */ | ||||
FACTAudioEngine *engine; | ||||
FACTCreateEngine(0, &engine); | ||||
FACTAudioEngine_Initialize(engine, ¶ms); | ||||
SDL_free(buf); | ||||
/* Add to UI... */ | ||||
engines.push_back(engine); | ||||
engineNames.push_back(enginename); | ||||
engineShows.push_back(true); | ||||
} | ||||
} | ||||
ImGui::End(); | ||||
} | ||||
/* AudioEngine windows */ | ||||
for (size_t i = 0; i < engines.size(); i += 1) | ||||
{ | ||||
FACTAudioEngine_DoWork(engines[i]); | ||||
if (engineShows[i]) | ||||
{ | ||||
/* Early out */ | ||||
if (!ImGui::Begin(engineNames[i].c_str())) | ||||
{ | ||||
ImGui::End(); | ||||
continue; | ||||
} | ||||
/* Categories */ | ||||
if (ImGui::CollapsingHeader("Categories")) | ||||
for (uint16_t j = 0; j < engines[i]->categoryCount; j += 1) | ||||
if (ImGui::TreeNode(engines[i]->categoryNames[j])) | ||||
{ | ||||
ImGui::Text( | ||||
"Max Instances: %d", | ||||
engines[i]->categories[j].instanceLimit | ||||
); | ||||
ImGui::Text( | ||||
"Fade-in (ms): %d", | ||||
engines[i]->categories[j].fadeInMS | ||||
); | ||||
ImGui::Text( | ||||
"Fade-out (ms): %d", | ||||
engines[i]->categories[j].fadeOutMS | ||||
); | ||||
ImGui::Text( | ||||
"Instance Behavior: %X", | ||||
engines[i]->categories[j].maxInstanceBehavior | ||||
); | ||||
ImGui::Text( | ||||
"Parent Category Index: %d", | ||||
engines[i]->categories[j].parentCategory | ||||
); | ||||
ImGui::Text( | ||||
"Base Volume: %f", | ||||
engines[i]->categories[j].volume | ||||
); | ||||
ImGui::Text( | ||||
"Visibility: %X", | ||||
engines[i]->categories[j].visibility | ||||
); | ||||
ImGui::TreePop(); | ||||
} | ||||
/* Variables */ | ||||
if (ImGui::CollapsingHeader("Variables")) | ||||
for (uint16_t j = 0; j < engines[i]->variableCount; j += 1) | ||||
if (ImGui::TreeNode(engines[i]->variableNames[j])) | ||||
{ | ||||
ImGui::Text( | ||||
"Accessibility: %X", | ||||
engines[i]->variables[j].accessibility | ||||
); | ||||
ImGui::Text( | ||||
"Initial Value: %f", | ||||
engines[i]->variables[j].initialValue | ||||
); | ||||
ImGui::Text( | ||||
"Min Value: %f", | ||||
engines[i]->variables[j].minValue | ||||
); | ||||
ImGui::Text( | ||||
"Max Value: %f", | ||||
engines[i]->variables[j].maxValue | ||||
); | ||||
ImGui::TreePop(); | ||||
} | ||||
/* RPCs */ | ||||
if (ImGui::CollapsingHeader("RPCs")) | ||||
for (uint16_t j = 0; j < engines[i]->rpcCount; j += 1) | ||||
if (ImGui::TreeNode( | ||||
(void*) (intptr_t) j, | ||||
"Code %d", | ||||
engines[i]->rpcCodes[j] | ||||
)) { | ||||
ImGui::Text( | ||||
"Variable Index: %d", | ||||
engines[i]->rpcs[j].variable | ||||
); | ||||
ImGui::Text( | ||||
"Parameter: %d", | ||||
engines[i]->rpcs[j].parameter | ||||
); | ||||
ImGui::Text( | ||||
"Point Count: %d", | ||||
engines[i]->rpcs[j].pointCount | ||||
); | ||||
if (ImGui::TreeNode("Points")) | ||||
{ | ||||
for (uint8_t k = 0; k < engines[i]->rpcs[j].pointCount; k += 1) | ||||
if (ImGui::TreeNode( | ||||
(void*) (intptr_t) k, | ||||
"Point #%d", | ||||
k | ||||
)) { | ||||
ImGui::Text( | ||||
"Coordinate: (%f, %f)", | ||||
engines[i]->rpcs[j].points[k].x, | ||||
engines[i]->rpcs[j].points[k].y | ||||
); | ||||
ImGui::Text( | ||||
"Type: %d\n", | ||||
engines[i]->rpcs[j].points[k].type | ||||
); | ||||
ImGui::TreePop(); | ||||
} | ||||
ImGui::TreePop(); | ||||
} | ||||
ImGui::TreePop(); | ||||
} | ||||
/* DSP Presets */ | ||||
if (ImGui::CollapsingHeader("DSP Presets")) | ||||
for (uint16_t j = 0; j < engines[i]->dspPresetCount; j += 1) | ||||
if (ImGui::TreeNode( | ||||
(void*) (intptr_t) j, | ||||
"Code %d", | ||||
engines[i]->dspPresetCodes[j] | ||||
)) { | ||||
ImGui::Text( | ||||
"Accessibility: %X", | ||||
engines[i]->dspPresets[j].accessibility | ||||
); | ||||
ImGui::Text( | ||||
"Parameter Count: %d", | ||||
engines[i]->dspPresets[j].parameterCount | ||||
); | ||||
if (ImGui::TreeNode("Parameters")) | ||||
{ | ||||
for (uint32_t k = 0; k < engines[i]->dspPresets[j].parameterCount; k += 1) | ||||
if (ImGui::TreeNode( | ||||
(void*) (intptr_t) k, | ||||
"Parameter #%d", | ||||
k | ||||
)) { | ||||
ImGui::Text( | ||||
"Initial Value: %f", | ||||
engines[i]->dspPresets[j].parameters[k].value | ||||
); | ||||
ImGui::Text( | ||||
"Min Value: %f", | ||||
engines[i]->dspPresets[j].parameters[k].minVal | ||||
); | ||||
ImGui::Text( | ||||
"Max Value: %f", | ||||
engines[i]->dspPresets[j].parameters[k].maxVal | ||||
); | ||||
ImGui::Text( | ||||
"Unknown u16: %d", | ||||
engines[i]->dspPresets[j].parameters[k].unknown | ||||
); | ||||
ImGui::TreePop(); | ||||
} | ||||
ImGui::TreePop(); | ||||
} | ||||
ImGui::TreePop(); | ||||
} | ||||
ImGui::Separator(); | ||||
/* Open SoundBank */ | ||||
static char soundbankname[64] = "Sound Bank.xsb"; | ||||
if (ImGui::InputText( | ||||
"Open SoundBank", | ||||
soundbankname, 64, | ||||
ImGuiInputTextFlags_EnterReturnsTrue | ||||
)) { | ||||
/* Load up file... */ | ||||
buf = (uint8_t*) SDL_LoadFile(soundbankname, &len); | ||||
/* Create SoundBank... */ | ||||
FACTSoundBank *sb; | ||||
FACTAudioEngine_CreateSoundBank( | ||||
engines[i], | ||||
buf, | ||||
len, | ||||
0, | ||||
0, | ||||
&sb | ||||
); | ||||
SDL_free(buf); | ||||
/* Add to UI... */ | ||||
soundBanks.push_back(sb); | ||||
soundbankNames.push_back( | ||||
"SoundBank: " + std::string(sb->name) | ||||
); | ||||
soundbankShows.push_back(true); | ||||
} | ||||
/* Open WaveBank */ | ||||
static char wavebankname[64] = "Wave Bank.xwb"; | ||||
if (ImGui::InputText( | ||||
"Open WaveBank", | ||||
wavebankname, 64, | ||||
ImGuiInputTextFlags_EnterReturnsTrue | ||||
)) { | ||||
/* Load up file... */ | ||||
buf = (uint8_t*) SDL_LoadFile(wavebankname, &len); | ||||
/* Create WaveBank... */ | ||||
FACTWaveBank *wb; | ||||
FACTAudioEngine_CreateInMemoryWaveBank( | ||||
engines[i], | ||||
buf, | ||||
len, | ||||
0, | ||||
0, | ||||
&wb | ||||
); | ||||
/* Add to UI... */ | ||||
waveBanks.push_back(wb); | ||||
wavebankMems.push_back(buf); | ||||
wavebankNames.push_back( | ||||
"WaveBank: " + std::string(wb->name) | ||||
); | ||||
wavebankShows.push_back(true); | ||||
} | ||||
ImGui::Separator(); | ||||
/* Close file */ | ||||
if (ImGui::Button("Close AudioEngine")) | ||||
{ | ||||
/* Destroy SoundBank windows... */ | ||||
LinkedList *list = engines[i]->sbList; | ||||
while (list != NULL) | ||||
{ | ||||
for (size_t j = 0; j < soundBanks.size(); j += 1) | ||||
{ | ||||
if (list->entry == soundBanks[j]) | ||||
{ | ||||
list = list->next; | ||||
soundBanks.erase(soundBanks.begin() + j); | ||||
soundbankNames.erase(soundbankNames.begin() + j); | ||||
soundbankShows.erase(soundbankShows.begin() + j); | ||||
break; | ||||
} | ||||
} | ||||
} | ||||
/* Destroy WaveBank windows... */ | ||||
list = engines[i]->wbList; | ||||
while (list != NULL) | ||||
{ | ||||
for (size_t j = 0; j < waveBanks.size(); j += 1) | ||||
{ | ||||
if (list->entry == waveBanks[j]) | ||||
{ | ||||
list = list->next; | ||||
// FIXME: SDL_free(wavebankMems[j]); | ||||
waveBanks.erase(waveBanks.begin() + j); | ||||
wavebankMems.erase(wavebankMems.begin() + j); | ||||
wavebankNames.erase(wavebankNames.begin() + j); | ||||
wavebankShows.erase(wavebankShows.begin() + j); | ||||
break; | ||||
} | ||||
} | ||||
} | ||||
/* Close file, finally */ | ||||
FACTAudioEngine_ShutDown(engines[i]); | ||||
engines.erase(engines.begin() + i); | ||||
engineNames.erase(engineNames.begin() + i); | ||||
engineShows.erase(engineShows.begin() + i); | ||||
i -= 1; | ||||
} | ||||
/* We out. */ | ||||
ImGui::End(); | ||||
} | ||||
} | ||||
/* SoundBank windows */ | ||||
for (size_t i = 0; i < soundBanks.size(); i += 1) | ||||
if (soundbankShows[i]) | ||||
{ | ||||
/* Early out */ | ||||
if (!ImGui::Begin(soundbankNames[i].c_str())) | ||||
{ | ||||
ImGui::End(); | ||||
continue; | ||||
} | ||||
/* Close file */ | ||||
if (ImGui::Button("Close SoundBank")) | ||||
{ | ||||
FACTSoundBank_Destroy(soundBanks[i]); | ||||
soundBanks.erase(soundBanks.begin() + i); | ||||
soundbankNames.erase(soundbankNames.begin() + i); | ||||
soundbankShows.erase(soundbankShows.begin() + i); | ||||
i -= 1; | ||||
ImGui::End(); | ||||
continue; | ||||
} | ||||
ImGui::Separator(); | ||||
/* WaveBank Dependencies */ | ||||
if (ImGui::CollapsingHeader("WaveBank Dependencies")) | ||||
for (uint8_t j = 0; j < soundBanks[i]->wavebankCount; j += 1) | ||||
{ | ||||
ImGui::Text("%s", soundBanks[i]->wavebankNames[j]); | ||||
} | ||||
/* Cues */ | ||||
if (ImGui::CollapsingHeader("Cues")) | ||||
for (uint16_t j = 0; j < soundBanks[i]->cueCount; j += 1) | ||||
if (ImGui::TreeNode(soundBanks[i]->cueNames[j])) | ||||
{ | ||||
char playText[64]; | ||||
SDL_snprintf(playText, 64, "Play %s", soundBanks[i]->cueNames[j]); | ||||
if (ImGui::Button(playText)) | ||||
{ | ||||
FACTSoundBank_Play( | ||||
soundBanks[i], | ||||
j, | ||||
0, | ||||
0, | ||||
NULL | ||||
); | ||||
} | ||||
ImGui::Text( | ||||
"Flags: %X", | ||||
soundBanks[i]->cues[j].flags | ||||
); | ||||
ImGui::Text( | ||||
"Sound/Variation Code: %d", | ||||
soundBanks[i]->cues[j].sbCode | ||||
); | ||||
ImGui::Text( | ||||
"Transition Offset: %d", | ||||
soundBanks[i]->cues[j].transitionOffset | ||||
); | ||||
ImGui::Text( | ||||
"Instance Limit: %d", | ||||
soundBanks[i]->cues[j].instanceLimit | ||||
); | ||||
ImGui::Text( | ||||
"Fade-in (ms): %d", | ||||
soundBanks[i]->cues[j].fadeInMS | ||||
); | ||||
ImGui::Text( | ||||
"Fade-out (ms): %d", | ||||
soundBanks[i]->cues[j].fadeOutMS | ||||
); | ||||
ImGui::Text( | ||||
"Max Instance Behavior: %d", | ||||
soundBanks[i]->cues[j].maxInstanceBehavior | ||||
); | ||||
ImGui::TreePop(); | ||||
} | ||||
/* Sounds */ | ||||
if (ImGui::CollapsingHeader("Sounds")) | ||||
for (uint16_t j = 0; j < soundBanks[i]->soundCount; j += 1) | ||||
{ | ||||
if (ImGui::TreeNode( | ||||
(void*) (intptr_t) j, | ||||
"Code %d", | ||||
soundBanks[i]->soundCodes[j] | ||||
)) { | ||||
ImGui::Text( | ||||
"Flags: %X", | ||||
soundBanks[i]->sounds[j].flags | ||||
); | ||||
ImGui::Text( | ||||
"Category Index: %d", | ||||
soundBanks[i]->sounds[j].category | ||||
); | ||||
ImGui::Text( | ||||
"Volume: %f", | ||||
soundBanks[i]->sounds[j].volume | ||||
); | ||||
ImGui::Text( | ||||
"Pitch: %d", | ||||
soundBanks[i]->sounds[j].pitch | ||||
); | ||||
ImGui::Text( | ||||
"Priority: %d", | ||||
soundBanks[i]->sounds[j].priority | ||||
); | ||||
ImGui::Text( | ||||
"RPC Code Count: %d", | ||||
soundBanks[i]->sounds[j].rpcCodeCount | ||||
); | ||||
ImGui::Text( | ||||
"DSP Preset Code Count: %d", | ||||
soundBanks[i]->sounds[j].dspCodeCount | ||||
); | ||||
ImGui::Text( | ||||
"Track Count: %d", | ||||
soundBanks[i]->sounds[j].trackCount | ||||
); | ||||
if (ImGui::TreeNode("RPC Codes")) | ||||
{ | ||||
for (uint8_t k = 0; k < soundBanks[i]->sounds[j].rpcCodeCount; k += 1) | ||||
{ | ||||
ImGui::Text( | ||||
"%d", | ||||
soundBanks[i]->sounds[j].rpcCodes[k] | ||||
); | ||||
} | ||||
ImGui::TreePop(); | ||||
} | ||||
if (ImGui::TreeNode("DSP Preset Codes")) | ||||
{ | ||||
for (uint8_t k = 0; k < soundBanks[i]->sounds[j].dspCodeCount; k += 1) | ||||
{ | ||||
ImGui::Text( | ||||
"%d", | ||||
soundBanks[i]->sounds[j].dspCodes[k] | ||||
); | ||||
} | ||||
ImGui::TreePop(); | ||||
} | ||||
if (ImGui::TreeNode("Tracks")) | ||||
{ | ||||
for (uint8_t k = 0; k < soundBanks[i]->sounds[j].trackCount; k += 1) | ||||
if (ImGui::TreeNode( | ||||
(void*) (intptr_t) k, | ||||
"Track Code %d", | ||||
soundBanks[i]->sounds[j].tracks[k].code | ||||
)) { | ||||
ImGui::Text( | ||||
"Volume: %f", | ||||
soundBanks[i]->sounds[j].tracks[k].volume | ||||
); | ||||
ImGui::Text( | ||||
"Filter Type: %d", | ||||
soundBanks[i]->sounds[j].tracks[k].filter | ||||
); | ||||
ImGui::Text( | ||||
"Filter Q-Factor: %d", | ||||
soundBanks[i]->sounds[j].tracks[k].qfactor | ||||
); | ||||
ImGui::Text( | ||||
"Filter Frequency: %d", | ||||
soundBanks[i]->sounds[j].tracks[k].frequency | ||||
); | ||||
ImGui::Text( | ||||
"RPC Code Count: %d", | ||||
soundBanks[i]->sounds[j].tracks[k].rpcCodeCount | ||||
); | ||||
ImGui::Text( | ||||
"Event Count: %d", | ||||
soundBanks[i]->sounds[j].tracks[k].eventCount | ||||
); | ||||
if (ImGui::TreeNode("RPC Codes")) | ||||
{ | ||||
for (uint8_t l = 0; l < soundBanks[i]->sounds[j].tracks[k].rpcCodeCount; l += 1) | ||||
{ | ||||
ImGui::Text( | ||||
"%d", | ||||
soundBanks[i]->sounds[j].tracks[k].rpcCodes[l] | ||||
); | ||||
} | ||||
ImGui::TreePop(); | ||||
} | ||||
if (ImGui::TreeNode("Events")) | ||||
{ | ||||
for (uint8_t l = 0; l < soundBanks[i]->sounds[j].tracks[k].eventCount; l += 1) | ||||
if (ImGui::TreeNode( | ||||
(void*) (intptr_t) l, | ||||
"Event #%d", | ||||
l | ||||
)) { | ||||
const FACTEvent *evt = &soundBanks[i]->sounds[j].tracks[k].events[l]; | ||||
ImGui::Text( | ||||
"Type: %d", | ||||
evt->type | ||||
); | ||||
ImGui::Text( | ||||
"Timestamp: %d", | ||||
evt->timestamp | ||||
); | ||||
ImGui::Text( | ||||
"Random Offset: %d", | ||||
evt->randomOffset | ||||
); | ||||
if (evt->type == FACTEVENT_STOP) | ||||
{ | ||||
ImGui::Text( | ||||
"Flags: %X", | ||||
evt->stop.flags | ||||
); | ||||
} | ||||
else if ( evt->type == FACTEVENT_PLAYWAVE || | ||||
evt->type == FACTEVENT_PLAYWAVETRACKVARIATION || | ||||
evt->type == FACTEVENT_PLAYWAVEEFFECTVARIATION || | ||||
evt->type == FACTEVENT_PLAYWAVETRACKEFFECTVARIATION ) | ||||
{ | ||||
ImGui::Text( | ||||
"Play Flags: %X", | ||||
evt->wave.flags | ||||
); | ||||
ImGui::Text( | ||||
"Position: %d", | ||||
evt->wave.position | ||||
); | ||||
ImGui::Text( | ||||
"Angle: %d", | ||||
evt->wave.angle | ||||
); | ||||
ImGui::Text( | ||||
"Loop Count: %d", | ||||
evt->wave.loopCount | ||||
); | ||||
if (evt->wave.isComplex) | ||||
{ | ||||
ImGui::Text( | ||||
"Track Variation Type: %d", | ||||
evt->wave.complex.variation | ||||
); | ||||
ImGui::Text( | ||||
"Track Count: %d", | ||||
evt->wave.complex.trackCount | ||||
); | ||||
if (ImGui::TreeNode("Tracks")) | ||||
{ | ||||
for (uint16_t m = 0; m < evt->wave.complex.trackCount; m += 1) | ||||
if (ImGui::TreeNode( | ||||
(void*) (intptr_t) m, | ||||
"Track #%d", | ||||
m | ||||
)) { | ||||
ImGui::Text( | ||||
"Track Index: %d", | ||||
evt->wave.complex.tracks[m] | ||||
); | ||||
ImGui::Text( | ||||
"WaveBank Index: %d", | ||||
evt->wave.complex.wavebanks[m] | ||||
); | ||||
ImGui::Text( | ||||
"Weight: %d", | ||||
evt->wave.complex.weights[m] | ||||
); | ||||
ImGui::TreePop(); | ||||
} | ||||
ImGui::TreePop(); | ||||
} | ||||
} | ||||
else | ||||
{ | ||||
ImGui::Text( | ||||
"Track Index: %d", | ||||
evt->wave.simple.track | ||||
); | ||||
ImGui::Text( | ||||
"WaveBank Index: %d", | ||||
evt->wave.simple.wavebank | ||||
); | ||||
} | ||||
if ( evt->wave.variationFlags != 0 && | ||||
evt->wave.variationFlags != 0xFFFF ) | ||||
{ | ||||
ImGui::Text( | ||||
"Effect Variation Flags: %X", | ||||
evt->wave.variationFlags | ||||
); | ||||
if (evt->wave.variationFlags & 0x1000) | ||||
{ | ||||
ImGui::Text( | ||||
"Min Pitch: %d", | ||||
evt->wave.minPitch | ||||
); | ||||
ImGui::Text( | ||||
"Max Pitch: %d", | ||||
evt->wave.maxPitch | ||||
); | ||||
} | ||||
if (evt->wave.variationFlags & 0x2000) | ||||
{ | ||||
ImGui::Text( | ||||
"Min Volume: %f", | ||||
evt->wave.minVolume | ||||
); | ||||
ImGui::Text( | ||||
"Max Volume: %f", | ||||
evt->wave.maxVolume | ||||
); | ||||
} | ||||
if (evt->wave.variationFlags & 0xC000) | ||||
{ | ||||
ImGui::Text( | ||||
"Min Frequency: %f", | ||||
evt->wave.minFrequency | ||||
); | ||||
ImGui::Text( | ||||
"Max Frequency: %f", | ||||
evt->wave.maxFrequency | ||||
); | ||||
ImGui::Text( | ||||
"Min Q-Factor: %f", | ||||
evt->wave.minQFactor | ||||
); | ||||
ImGui::Text( | ||||
"Max Q-Factor: %f", | ||||
evt->wave.maxQFactor | ||||
); | ||||
} | ||||
} | ||||
} | ||||
else if ( evt->type == FACTEVENT_PITCH || | ||||
evt->type == FACTEVENT_VOLUME || | ||||
evt->type == FACTEVENT_PITCHREPEATING || | ||||
evt->type == FACTEVENT_VOLUMEREPEATING ) | ||||
{ | ||||
if (evt->value.settings == 0) | ||||
{ | ||||
ImGui::Text( | ||||
"Equation Flags: %X", | ||||
evt->value.equation.flags | ||||
); | ||||
ImGui::Text( | ||||
"Value 1: %f", | ||||
evt->value.equation.value1 | ||||
); | ||||
ImGui::Text( | ||||
"Value 2: %f", | ||||
evt->value.equation.value2 | ||||
); | ||||
} | ||||
else | ||||
{ | ||||
ImGui::Text( | ||||
"Initial Value: %f", | ||||
evt->value.ramp.initialValue | ||||
); | ||||
ImGui::Text( | ||||
"Initial Slope: %f", | ||||
evt->value.ramp.initialSlope | ||||
); | ||||
ImGui::Text( | ||||
"Slope Delta: %f", | ||||
evt->value.ramp.slopeDelta | ||||
); | ||||
ImGui::Text( | ||||
"Duration: %d", | ||||
evt->value.ramp.duration | ||||
); | ||||
} | ||||
ImGui::Text( | ||||
"Repeats: %d", | ||||
evt->value.repeats | ||||
); | ||||
ImGui::Text( | ||||
"Frequency: %d", | ||||
evt->value.frequency | ||||
); | ||||
} | ||||
else if ( evt->type == FACTEVENT_MARKER || | ||||
evt->type == FACTEVENT_MARKERREPEATING ) | ||||
{ | ||||
ImGui::Text( | ||||
"Marker: %d", | ||||
evt->marker.marker | ||||
); | ||||
ImGui::Text( | ||||
"Repeats: %d", | ||||
evt->marker.repeats | ||||
); | ||||
ImGui::Text( | ||||
"Frequency: %d", | ||||
evt->marker.frequency | ||||
); | ||||
} | ||||
else | ||||
{ | ||||
FAudio_assert(0 && "Unknown event type!"); | ||||
} | ||||
ImGui::TreePop(); | ||||
} | ||||
ImGui::TreePop(); | ||||
} | ||||
ImGui::TreePop(); | ||||
} | ||||
ImGui::TreePop(); | ||||
} | ||||
ImGui::TreePop(); | ||||
} | ||||
} | ||||
/* Variations */ | ||||
if (ImGui::CollapsingHeader("Variations")) | ||||
for (uint16_t j = 0; j < soundBanks[i]->variationCount; j += 1) | ||||
if (ImGui::TreeNode( | ||||
(void*) (intptr_t) j, | ||||
"Code #%d", | ||||
soundBanks[i]->variationCodes[j] | ||||
)) { | ||||
ImGui::Text( | ||||
"Flags: %X", | ||||
soundBanks[i]->variations[j].flags | ||||
); | ||||
ImGui::Text( | ||||
"Interactive Variable Index: %d", | ||||
soundBanks[i]->variations[j].variable | ||||
); | ||||
ImGui::Text( | ||||
"Entry Count: %X", | ||||
soundBanks[i]->variations[j].entryCount | ||||
); | ||||
if (ImGui::TreeNode("Entries")) | ||||
{ | ||||
for (uint16_t k = 0; k < soundBanks[i]->variations[j].entryCount; k += 1) | ||||
if (ImGui::TreeNode( | ||||
(void*) (intptr_t) k, | ||||
"Entry #%d", | ||||
k | ||||
)) { | ||||
if (soundBanks[i]->variations[j].isComplex) | ||||
{ | ||||
ImGui::Text("Complex Variation"); | ||||
ImGui::Text( | ||||
"Sound Code: %d", | ||||
soundBanks[i]->variations[j].entries[k].soundCode | ||||
); | ||||
} | ||||
else | ||||
{ | ||||
ImGui::Text("Simple Variation"); | ||||
ImGui::Text( | ||||
"Track Index: %d", | ||||
soundBanks[i]->variations[j].entries[k].simple.track | ||||
); | ||||
ImGui::Text( | ||||
"WaveBank Index: %d", | ||||
soundBanks[i]->variations[j].entries[k].simple.wavebank | ||||
); | ||||
} | ||||
ImGui::Text( | ||||
"Min Weight: %f", | ||||
soundBanks[i]->variations[j].entries[k].minWeight | ||||
); | ||||
ImGui::Text( | ||||
"Max Weight: %f", | ||||
soundBanks[i]->variations[j].entries[k].maxWeight | ||||
); | ||||
ImGui::TreePop(); | ||||
} | ||||
ImGui::TreePop(); | ||||
} | ||||
ImGui::TreePop(); | ||||
} | ||||
/* Transitions */ | ||||
if (ImGui::CollapsingHeader("Transitions")) | ||||
for (uint16_t j = 0; j < soundBanks[i]->transitionCount; j += 1) | ||||
if (ImGui::TreeNode( | ||||
(void*) (intptr_t) j, | ||||
"Code #%d", | ||||
soundBanks[i]->transitionCodes[j] | ||||
)) { | ||||
ImGui::Text( | ||||
"Entry Count: %X", | ||||
soundBanks[i]->transitions[j].entryCount | ||||
); | ||||
if (ImGui::TreeNode("Entries")) | ||||
{ | ||||
for (uint16_t k = 0; k < soundBanks[i]->transitions[j].entryCount; k += 1) | ||||
if (ImGui::TreeNode( | ||||
(void*) (intptr_t) k, | ||||
"Entry #%d", | ||||
k | ||||
)) { | ||||
ImGui::Text( | ||||
"Sound Code: %d", | ||||
soundBanks[i]->transitions[j].entries[k].soundCode | ||||
); | ||||
ImGui::Text( | ||||
"Src Min Marker: %d", | ||||
soundBanks[i]->transitions[j].entries[k].srcMarkerMin | ||||
); | ||||
ImGui::Text( | ||||
"Src Max Marker: %d", | ||||
soundBanks[i]->transitions[j].entries[k].srcMarkerMax | ||||
); | ||||
ImGui::Text( | ||||
"Dst Min Marker: %d", | ||||
soundBanks[i]->transitions[j].entries[k].dstMarkerMin | ||||
); | ||||
ImGui::Text( | ||||
"Dst Max Marker: %d", | ||||
soundBanks[i]->transitions[j].entries[k].dstMarkerMax | ||||
); | ||||
ImGui::Text( | ||||
"Fade In: %d", | ||||
soundBanks[i]->transitions[j].entries[k].fadeIn | ||||
); | ||||
ImGui::Text( | ||||
"Fade Out: %d", | ||||
soundBanks[i]->transitions[j].entries[k].fadeOut | ||||
); | ||||
ImGui::Text( | ||||
"Flags: %d", | ||||
soundBanks[i]->transitions[j].entries[k].flags | ||||
); | ||||
ImGui::TreePop(); | ||||
} | ||||
ImGui::TreePop(); | ||||
} | ||||
ImGui::TreePop(); | ||||
} | ||||
/* We out. */ | ||||
ImGui::End(); | ||||
} | ||||
/* WaveBank windows */ | ||||
for (size_t i = 0; i < waveBanks.size(); i += 1) | ||||
if (wavebankShows[i]) | ||||
{ | ||||
/* Early out */ | ||||
if (!ImGui::Begin(wavebankNames[i].c_str())) | ||||
{ | ||||
ImGui::End(); | ||||
continue; | ||||
} | ||||
/* Close file */ | ||||
if (ImGui::Button("Close WaveBank")) | ||||
{ | ||||
FACTWaveBank_Destroy(waveBanks[i]); | ||||
SDL_free(wavebankMems[i]); | ||||
waveBanks.erase(waveBanks.begin() + i); | ||||
wavebankMems.erase(wavebankMems.begin() + i); | ||||
wavebankNames.erase(wavebankNames.begin() + i); | ||||
wavebankShows.erase(wavebankShows.begin() + i); | ||||
i -= 1; | ||||
ImGui::End(); | ||||
continue; | ||||
} | ||||
/* Giant table of wavedata entries */ | ||||
ImGui::Columns(12, "wavebankentries"); | ||||
ImGui::Separator(); | ||||
ImGui::Text("Entry"); ImGui::NextColumn(); | ||||
ImGui::Text("Flags"); ImGui::NextColumn(); | ||||
ImGui::Text("Duration"); ImGui::NextColumn(); | ||||
ImGui::Text("Format Tag"); ImGui::NextColumn(); | ||||
ImGui::Text("Channels"); ImGui::NextColumn(); | ||||
ImGui::Text("Sample Rate"); ImGui::NextColumn(); | ||||
ImGui::Text("Block Align"); ImGui::NextColumn(); | ||||
ImGui::Text("Bit Depth"); ImGui::NextColumn(); | ||||
ImGui::Text("Play Offset"); ImGui::NextColumn(); | ||||
ImGui::Text("Play Length"); ImGui::NextColumn(); | ||||
ImGui::Text("Loop Offset"); ImGui::NextColumn(); | ||||
ImGui::Text("Loop Length"); ImGui::NextColumn(); | ||||
ImGui::Separator(); | ||||
for (uint32_t j = 0; j < waveBanks[i]->entryCount; j += 1) | ||||
{ | ||||
char playText[16]; | ||||
SDL_snprintf(playText, 16, "%d", j); | ||||
if (ImGui::Button(playText)) | ||||
{ | ||||
FACTWave *wave; | ||||
FACTWaveBank_Play( | ||||
waveBanks[i], | ||||
j, | ||||
0, | ||||
0, | ||||
0, | ||||
&wave | ||||
); | ||||
waves.push_back(wave); | ||||
} | ||||
ImGui::NextColumn(); | ||||
ImGui::Text("%d", waveBanks[i]->entries[j].dwFlags); | ||||
ImGui::NextColumn(); | ||||
ImGui::Text("%d", waveBanks[i]->entries[j].Duration); | ||||
ImGui::NextColumn(); | ||||
ImGui::Text("%d", waveBanks[i]->entries[j].Format.wFormatTag); | ||||
ImGui::NextColumn(); | ||||
ImGui::Text("%d", waveBanks[i]->entries[j].Format.nChannels); | ||||
ImGui::NextColumn(); | ||||
ImGui::Text("%d", waveBanks[i]->entries[j].Format.nSamplesPerSec); | ||||
ImGui::NextColumn(); | ||||
ImGui::Text("%d", waveBanks[i]->entries[j].Format.wBlockAlign); | ||||
ImGui::NextColumn(); | ||||
ImGui::Text("%d", waveBanks[i]->entries[j].Format.wBitsPerSample); | ||||
ImGui::NextColumn(); | ||||
ImGui::Text("%d", waveBanks[i]->entries[j].PlayRegion.dwOffset); | ||||
ImGui::NextColumn(); | ||||
ImGui::Text("%d", waveBanks[i]->entries[j].PlayRegion.dwLength); | ||||
ImGui::NextColumn(); | ||||
ImGui::Text("%d", waveBanks[i]->entries[j].LoopRegion.dwStartSample); | ||||
ImGui::NextColumn(); | ||||
ImGui::Text("%d", waveBanks[i]->entries[j].LoopRegion.dwTotalSamples); | ||||
ImGui::NextColumn(); | ||||
} | ||||
ImGui::Columns(1); | ||||
ImGui::Separator(); | ||||
/* We out. */ | ||||
ImGui::End(); | ||||
} | ||||
/* Playing Waves */ | ||||
for (size_t i = 0; i < waves.size(); i += 1) | ||||
{ | ||||
uint32_t state; | ||||
FACTWave_GetState(waves[i], &state); | ||||
if (state & FACT_STATE_STOPPED) | ||||
{ | ||||
FACTWave_Destroy(waves[i]); | ||||
waves.erase(waves.begin() + i); | ||||
i -= 1; | ||||
} | ||||
} | ||||
} | ||||