Commit Description:
Add timers for Simulation and various engines...
Commit Description:
Add timers for Simulation and various engines Starting to add additional timers for different stages of the process of updating in order to get more insight into what is slowing it down. The update takes 9ms, which is much longer than it used to. Engine-specific timers are coming later.
File last commit:
Show/Diff file:
Action:
FNA/lib/FAudio/utils/testxwma/testxwma.cpp
246 lines | 6.5 KiB | text/x-c | CppLexer
#include <stdio.h>
#include <SDL.h>
#include <FAudio.h>
float argPlayBegin = 0.0f;
float argPlayLength = 0.0f;
float argLoopBegin = 0.0f;
float argLoopLength = 0.0f;
uint32_t argLoopCount = 0;
FAudio *faudio = NULL;
FAudioMasteringVoice *mastering_voice = NULL;
FAudioSourceVoice *source_voice = NULL;
FAudioWaveFormatExtensible *wfx = NULL;
FAudioBuffer buffer = {0};
FAudioBufferWMA buffer_wma = {0};
/* based on https://docs.microsoft.com/en-us/windows/desktop/xaudio2/how-to--load-audio-data-files-in-xaudio2 */
#define fourccRIFF *((uint32_t *) "RIFF")
#define fourccDATA *((uint32_t *) "data")
#define fourccFMT *((uint32_t *) "fmt ")
#define fourccWAVE *((uint32_t *) "WAVE")
#define fourccXWMA *((uint32_t *) "XWMA")
#define fourccDPDS *((uint32_t *) "dpds")
uint32_t FindChunk(FILE *hFile, uint32_t fourcc, uint32_t *dwChunkSize, uint32_t *dwChunkDataPosition)
{
uint32_t hr = 0;
if (fseek(hFile, 0, SEEK_SET) != 0)
{
return -1;
}
uint32_t dwChunkType;
uint32_t dwChunkDataSize;
uint32_t dwRIFFDataSize = 0;
uint32_t dwFileType;
uint32_t bytesRead = 0;
uint32_t dwOffset = 0;
while (hr == 0)
{
if (fread(&dwChunkType, sizeof(uint32_t), 1, hFile) < 1)
hr = 1;
if (fread(&dwChunkDataSize, sizeof(uint32_t), 1, hFile) < 1)
hr = 1;
if (dwChunkType == fourccRIFF)
{
dwRIFFDataSize = dwChunkDataSize;
dwChunkDataSize = 4;
if (fread(&dwFileType, sizeof(uint32_t), 1, hFile) < 1)
hr = 1;
}
else
{
if (fseek(hFile, dwChunkDataSize, SEEK_CUR) != 0)
return 1;
}
dwOffset += sizeof(uint32_t) * 2;
if (dwChunkType == fourcc)
{
*dwChunkSize = dwChunkDataSize;
*dwChunkDataPosition = dwOffset;
return 0;
}
dwOffset += dwChunkDataSize;
if (bytesRead >= dwRIFFDataSize)
return 1;
}
return 1;
}
uint32_t ReadChunkData(FILE *hFile, void * buffer, uint32_t buffersize, uint32_t bufferoffset)
{
uint32_t hr = 0;
if (fseek(hFile, bufferoffset, SEEK_SET) != 0)
return 1;
if (fread(buffer, buffersize, 1, hFile) < 1)
hr = 1;
return hr;
}
uint32_t load_data(const char *filename)
{
/* open the audio file */
FILE *hFile = fopen(filename, "rb");
if (!hFile)
return 1;
fseek(hFile, 0, SEEK_SET);
/* Locate the 'RIFF' chunk in the audio file, and check the file type. */
uint32_t dwChunkSize;
uint32_t dwChunkPosition;
uint32_t filetype;
FindChunk(hFile,fourccRIFF, &dwChunkSize, &dwChunkPosition);
ReadChunkData(hFile, &filetype, sizeof(uint32_t), dwChunkPosition);
if (filetype != fourccWAVE && filetype != fourccXWMA)
return 1;
/* Locate the 'fmt ' chunk, and copy its contents into a WAVEFORMATEXTENSIBLE structure. */
FindChunk(hFile,fourccFMT, &dwChunkSize, &dwChunkPosition );
if (dwChunkSize > sizeof(FAudioWaveFormatExtensible))
{
wfx = (FAudioWaveFormatExtensible *) malloc(dwChunkSize);
printf("chunk-size exceeds wfx size, allocating more: %u > %u\n", dwChunkSize, sizeof(FAudioWaveFormatExtensible));
}
else
{
wfx = (FAudioWaveFormatExtensible *) malloc(sizeof(FAudioWaveFormatExtensible));
printf("chunk-size equal or less than wfx size, capping: %u <= %u\n", dwChunkSize, sizeof(FAudioWaveFormatExtensible));
}
ReadChunkData(hFile, wfx, dwChunkSize, dwChunkPosition );
/* Locate the 'data' chunk, and read its contents into a buffer. */
FindChunk(hFile, fourccDATA, &dwChunkSize, &dwChunkPosition);
uint8_t *pDataBuffer = (uint8_t *) malloc(dwChunkSize);
ReadChunkData(hFile, pDataBuffer, dwChunkSize, dwChunkPosition);
printf("data chunk size: %u\n", dwChunkSize);
buffer.AudioBytes = dwChunkSize; //buffer containing audio data
buffer.pAudioData = pDataBuffer; //size of the audio buffer in bytes
buffer.Flags = FAUDIO_END_OF_STREAM; // tell the source voice not to expect any data after this buffer
/* Locate the 'dpds' chunk, and read its contents into a buffer. */
if (FindChunk(hFile, fourccDPDS, &dwChunkSize, &dwChunkPosition) == 0)
{
uint32_t *cumulBytes = (uint32_t *) malloc(dwChunkSize);
ReadChunkData(hFile, cumulBytes, dwChunkSize, dwChunkPosition);
buffer_wma.pDecodedPacketCumulativeBytes = cumulBytes;
buffer_wma.PacketCount = dwChunkSize / sizeof(uint32_t);
}
fclose(hFile);
return 0;
}
void faudio_setup() {
uint32_t hr = FAudioCreate(&faudio, 0, FAUDIO_DEFAULT_PROCESSOR);
if (hr != 0) {
return;
}
hr = FAudio_CreateMasteringVoice(faudio, &mastering_voice, 2, 44100, 0, 0, NULL);
if (hr != 0) {
return;
}
hr = FAudio_CreateSourceVoice(
faudio,
&source_voice,
(FAudioWaveFormatEx *) wfx,
FAUDIO_VOICE_USEFILTER,
FAUDIO_MAX_FREQ_RATIO,
NULL, NULL, NULL
);
}
void play(void) {
buffer.PlayBegin = argPlayBegin * wfx->Format.nSamplesPerSec;
buffer.PlayLength = argPlayLength * wfx->Format.nSamplesPerSec;
buffer.LoopBegin = argLoopBegin * wfx->Format.nSamplesPerSec;
buffer.LoopLength = argLoopLength * wfx->Format.nSamplesPerSec;
buffer.LoopCount = argLoopCount;
if (buffer_wma.pDecodedPacketCumulativeBytes != NULL)
FAudioSourceVoice_SubmitSourceBuffer(source_voice, &buffer, &buffer_wma);
else
FAudioSourceVoice_SubmitSourceBuffer(source_voice, &buffer, NULL);
uint32_t hr = FAudioSourceVoice_Start(source_voice, 0, FAUDIO_COMMIT_NOW);
int is_running = 1;
while (hr == 0 && is_running) {
FAudioVoiceState state;
FAudioSourceVoice_GetState(source_voice, &state, 0);
is_running = (state.BuffersQueued > 0) != 0;
SDL_Delay(10);
}
FAudioVoice_DestroyVoice(source_voice);
/* free allocated space for FAudioWafeFormatExtensible */
free(wfx);
}
int main(int argc, char *argv[]) {
/* process command line arguments. This is just a test program, didn't go too nuts with validation. */
if (argc < 2 || (argc > 4 && argc != 7)) {
printf("Usage: %s filename [PlayBegin] [PlayLength] [LoopBegin LoopLength LoopCount]\n", argv[0]);
printf(" - filename (required): can be either a WAV or xWMA audio file.\n");
printf(" - PlayBegin (optional): start playing at this offset. (in seconds)\n");
printf(" - PlayLength (optional): duration of the region to be played. (in seconds)\n");
printf(" - LoopBegin (optional): start looping at this offset. (in seconds)\n");
printf(" - LoopLength (optional): duration of the loop (in seconds)\n");
printf(" - LoopCount (optional): number of times to loop\n");
return -1;
}
switch (argc)
{
case 7:
sscanf(argv[6], "%d", &argLoopCount);
sscanf(argv[5], "%f", &argLoopLength);
sscanf(argv[4], "%f", &argLoopBegin);
case 4:
sscanf(argv[3], "%f", &argPlayLength);
case 3:
sscanf(argv[2], "%f", &argPlayBegin);
}
if (load_data(argv[1]) != 0)
{
printf("Error loading data\n");
return -1;
}
faudio_setup();
play();
return 0;
}