/* 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 * */ /* This is where the actual tool lives! Try to do your work in here! */ #include /* DO NOT INCLUDE THIS IN REAL CODE! */ #include "../uicommon/imgui.h" #include #include #include const char* TOOL_NAME = "FACT Auditioning Tool"; int TOOL_WIDTH = 1280; int TOOL_HEIGHT = 720; bool openEngineShow = true; std::vector engines; std::vector engineNames; std::vector engineShows; std::vector soundBanks; std::vector soundbankNames; std::vector soundbankShows; std::vector waveBanks; std::vector wavebankMems; std::vector wavebankNames; std::vector wavebankShows; std::vector 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; } } }