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/src/XNA_Song.c
278 lines | 6.3 KiB | text/x-c | CLexer
/* 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>
*
*/
#ifndef DISABLE_XNASONG
#include "FAudio_internal.h"
/* stb_vorbis */
#define malloc FAudio_malloc
#define realloc FAudio_realloc
#define free FAudio_free
#ifdef memset /* Thanks, Apple! */
#undef memset
#endif
#define memset FAudio_memset
#ifdef memcpy /* Thanks, Apple! */
#undef memcpy
#endif
#define memcpy FAudio_memcpy
#define memcmp FAudio_memcmp
#define pow FAudio_pow
#define log(x) FAudio_log(x)
#define sin(x) FAudio_sin(x)
#define cos(x) FAudio_cos(x)
#define floor FAudio_floor
#define abs(x) FAudio_abs(x)
#define ldexp(v, e) FAudio_ldexp((v), (e))
#define exp(x) FAudio_exp(x)
#define qsort FAudio_qsort
#define assert FAudio_assert
#define FILE FAudioIOStream
#ifdef SEEK_SET
#undef SEEK_SET
#endif
#ifdef SEEK_END
#undef SEEK_END
#endif
#ifdef EOF
#undef EOF
#endif
#define SEEK_SET FAUDIO_SEEK_SET
#define SEEK_END FAUDIO_SEEK_END
#define EOF FAUDIO_EOF
#define fopen(path, mode) FAudio_fopen(path)
#define fclose(io) FAudio_close(io)
#define fread(dst, size, count, io) io->read(io->data, dst, size, count)
#define fseek(io, offset, whence) io->seek(io->data, offset, whence)
#define ftell(io) io->seek(io->data, 0, FAUDIO_SEEK_CUR)
#define STB_VORBIS_NO_PUSHDATA_API 1
#define STB_VORBIS_NO_INTEGER_CONVERSION 1
#include "stb_vorbis.h"
/* Globals */
static float songVolume = 1.0f;
static FAudio *songAudio = NULL;
static FAudioMasteringVoice *songMaster = NULL;
static FAudioSourceVoice *songVoice = NULL;
static FAudioVoiceCallback callbacks;
static stb_vorbis *activeSong = NULL;
static stb_vorbis_info activeSongInfo;
static uint8_t *songCache;
/* Internal Functions */
static void XNA_SongSubmitBuffer(FAudioVoiceCallback *callback, void *pBufferContext)
{
FAudioBuffer buffer;
uint32_t decoded = stb_vorbis_get_samples_float_interleaved(
activeSong,
activeSongInfo.channels,
(float*) songCache,
activeSongInfo.sample_rate * activeSongInfo.channels
);
if (decoded == 0)
{
return;
}
buffer.Flags = (decoded < activeSongInfo.sample_rate) ?
FAUDIO_END_OF_STREAM :
0;
buffer.AudioBytes = decoded * activeSongInfo.channels * sizeof(float);
buffer.pAudioData = songCache;
buffer.PlayBegin = 0;
buffer.PlayLength = decoded;
buffer.LoopBegin = 0;
buffer.LoopLength = 0;
buffer.LoopCount = 0;
buffer.pContext = NULL;
FAudioSourceVoice_SubmitSourceBuffer(
songVoice,
&buffer,
NULL
);
}
static void XNA_SongKill()
{
if (songVoice != NULL)
{
FAudioSourceVoice_Stop(songVoice, 0, 0);
FAudioVoice_DestroyVoice(songVoice);
songVoice = NULL;
}
if (songCache != NULL)
{
FAudio_free(songCache);
songCache = NULL;
}
if (activeSong != NULL)
{
stb_vorbis_close(activeSong);
activeSong = NULL;
}
}
/* "Public" API */
FAUDIOAPI void XNA_SongInit()
{
FAudioCreate(&songAudio, 0, FAUDIO_DEFAULT_PROCESSOR);
FAudio_CreateMasteringVoice(
songAudio,
&songMaster,
FAUDIO_DEFAULT_CHANNELS,
FAUDIO_DEFAULT_SAMPLERATE,
0,
0,
NULL
);
}
FAUDIOAPI void XNA_SongQuit()
{
XNA_SongKill();
FAudioVoice_DestroyVoice(songMaster);
FAudio_Release(songAudio);
}
FAUDIOAPI float XNA_PlaySong(const char *name)
{
FAudioWaveFormatEx format;
XNA_SongKill();
activeSong = stb_vorbis_open_filename(name, NULL, NULL);
/* Set format info */
activeSongInfo = stb_vorbis_get_info(activeSong);
format.wFormatTag = FAUDIO_FORMAT_IEEE_FLOAT;
format.nChannels = activeSongInfo.channels;
format.nSamplesPerSec = activeSongInfo.sample_rate;
format.wBitsPerSample = sizeof(float) * 8;
format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8;
format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign;
format.cbSize = 0;
/* Allocate decode cache */
songCache = (uint8_t*) FAudio_malloc(format.nAvgBytesPerSec);
/* Init voice */
FAudio_zero(&callbacks, sizeof(FAudioVoiceCallback));
callbacks.OnBufferEnd = XNA_SongSubmitBuffer;
FAudio_CreateSourceVoice(
songAudio,
&songVoice,
&format,
0,
1.0f, /* No pitch shifting here! */
&callbacks,
NULL,
NULL
);
FAudioVoice_SetVolume(songVoice, songVolume, 0);
/* Okay, this song is decoding now */
stb_vorbis_seek_start(activeSong);
XNA_SongSubmitBuffer(NULL, NULL);
/* Finally. */
FAudioSourceVoice_Start(songVoice, 0, 0);
return stb_vorbis_stream_length_in_seconds(activeSong);
}
FAUDIOAPI void XNA_PauseSong()
{
if (songVoice == NULL)
{
return;
}
FAudioSourceVoice_Stop(songVoice, 0, 0);
}
FAUDIOAPI void XNA_ResumeSong()
{
if (songVoice == NULL)
{
return;
}
FAudioSourceVoice_Start(songVoice, 0, 0);
}
FAUDIOAPI void XNA_StopSong()
{
XNA_SongKill();
}
FAUDIOAPI void XNA_SetSongVolume(float volume)
{
songVolume = volume;
if (songVoice != NULL)
{
FAudioVoice_SetVolume(songVoice, songVolume, 0);
}
}
FAUDIOAPI uint32_t XNA_GetSongEnded()
{
FAudioVoiceState state;
if (songVoice == NULL || activeSong == NULL)
{
return 1;
}
FAudioSourceVoice_GetState(songVoice, &state, 0);
return state.BuffersQueued == 0;
}
FAUDIOAPI void XNA_EnableVisualization(uint32_t enable)
{
/* TODO: Enable/Disable FAPO effect */
}
FAUDIOAPI uint32_t XNA_VisualizationEnabled()
{
/* TODO: Query FAPO effect enabled */
return 0;
}
FAUDIOAPI void XNA_GetSongVisualizationData(
float *frequencies,
float *samples,
uint32_t count
) {
/* TODO: Visualization FAPO that reads in Song samples, FFT analysis */
}
#endif /* DISABLE_XNASONG */
/* vim: set noexpandtab shiftwidth=8 tabstop=8: */