Show More
Commit Description:
Various UI improvements.
Commit Description:
Various UI improvements.
References:
File last commit:
Show/Diff file:
Action:
FNA/lib/FAudio/utils/testvolumemeter/audio_faudio.cpp
170 lines | 3.8 KiB | text/x-c | CppLexer
170 lines | 3.8 KiB | text/x-c | CppLexer
r0 | #include "audio.h" | |||
#include <FAudio.h> | ||||
#include <FAudioFX.h> | ||||
#include <FAPO.h> | ||||
struct AudioContext | ||||
{ | ||||
FAudio *faudio; | ||||
FAudioMasteringVoice *mastering_voice; | ||||
FAudioSourceVoice *source_voice; | ||||
unsigned int wav_channels; | ||||
unsigned int wav_samplerate; | ||||
drwav_uint64 wav_sample_count; | ||||
float *wav_samples; | ||||
FAudioBuffer buffer; | ||||
}; | ||||
void faudio_destroy_context(AudioContext *context) | ||||
{ | ||||
if (context != NULL) | ||||
{ | ||||
FAudioVoice_DestroyVoice(context->source_voice); | ||||
FAudioVoice_DestroyVoice(context->mastering_voice); | ||||
FAudio_Release(context->faudio); | ||||
delete context; | ||||
} | ||||
} | ||||
void faudio_wave_load(AudioContext *context, AudioSampleWave sample, bool stereo) | ||||
{ | ||||
if (context->source_voice) | ||||
{ | ||||
FAudioVoice_DestroyVoice(context->source_voice); | ||||
} | ||||
/* Buffer data... */ | ||||
context->wav_samples = WAVS_Open( | ||||
sample, | ||||
stereo, | ||||
&context->wav_channels, | ||||
&context->wav_samplerate, | ||||
&context->wav_sample_count | ||||
); | ||||
context->wav_sample_count /= context->wav_channels; | ||||
context->buffer.Flags = FAUDIO_END_OF_STREAM; | ||||
context->buffer.AudioBytes = 4 * context->wav_sample_count * context->wav_channels; | ||||
context->buffer.pAudioData = (uint8_t*) context->wav_samples; | ||||
context->buffer.PlayBegin = 0; | ||||
context->buffer.PlayLength = context->wav_sample_count; | ||||
context->buffer.LoopBegin = 0; | ||||
context->buffer.LoopLength = 0; | ||||
context->buffer.LoopCount = 0; | ||||
context->buffer.pContext = NULL; | ||||
/* Volume meter... */ | ||||
FAPO *fapo = NULL; | ||||
uint32_t hr = FAudioCreateVolumeMeter(&fapo, 0); | ||||
if (hr != 0) | ||||
{ | ||||
return; | ||||
} | ||||
/* Effect chain... */ | ||||
FAudioEffectDescriptor vmDesc; | ||||
vmDesc.InitialState = 1; | ||||
vmDesc.OutputChannels = context->wav_channels; | ||||
vmDesc.pEffect = fapo; | ||||
FAudioEffectChain vmChain; | ||||
vmChain.EffectCount = 1; | ||||
vmChain.pEffectDescriptors = &vmDesc; | ||||
/* Wave format... */ | ||||
FAudioWaveFormatEx waveFormat; | ||||
waveFormat.wFormatTag = 3; | ||||
waveFormat.nChannels = context->wav_channels; | ||||
waveFormat.nSamplesPerSec = context->wav_samplerate; | ||||
waveFormat.nAvgBytesPerSec = context->wav_samplerate * 4; | ||||
waveFormat.nBlockAlign = context->wav_channels * 4; | ||||
waveFormat.wBitsPerSample = 32; | ||||
waveFormat.cbSize = 0; | ||||
/*... Source voice, finally. */ | ||||
hr = FAudio_CreateSourceVoice( | ||||
context->faudio, | ||||
&context->source_voice, | ||||
&waveFormat, | ||||
0, | ||||
FAUDIO_DEFAULT_FREQ_RATIO, | ||||
NULL, | ||||
NULL, | ||||
&vmChain | ||||
); | ||||
if (hr != 0) | ||||
{ | ||||
return; | ||||
} | ||||
fapo->Release(fapo); | ||||
} | ||||
void faudio_wave_play(AudioContext *context) | ||||
{ | ||||
FAudioSourceVoice_Stop(context->source_voice, 0, FAUDIO_COMMIT_NOW); | ||||
FAudioSourceVoice_FlushSourceBuffers(context->source_voice); | ||||
FAudioSourceVoice_SubmitSourceBuffer(context->source_voice, &context->buffer, NULL); | ||||
FAudioSourceVoice_Start(context->source_voice, 0, FAUDIO_COMMIT_NOW); | ||||
} | ||||
void faudio_update_volumemeter(AudioContext *context, float *peak, float *rms) | ||||
{ | ||||
FAudioFXVolumeMeterLevels levels; | ||||
levels.pPeakLevels = peak; | ||||
levels.pRMSLevels = rms; | ||||
levels.ChannelCount = context->wav_channels; | ||||
if (context->source_voice != NULL) | ||||
{ | ||||
FAudioVoice_GetEffectParameters( | ||||
context->source_voice, | ||||
0, | ||||
&levels, | ||||
sizeof(levels) | ||||
); | ||||
} | ||||
} | ||||
AudioContext* faudio_create_context() | ||||
{ | ||||
// setup function pointers | ||||
audio_destroy_context = faudio_destroy_context; | ||||
audio_wave_load = faudio_wave_load; | ||||
audio_wave_play = faudio_wave_play; | ||||
audio_update_volumemeter = faudio_update_volumemeter; | ||||
// create FAudio objects | ||||
FAudio *faudio; | ||||
FAudioMasteringVoice *master; | ||||
uint32_t hr = FAudioCreate(&faudio, 0, FAUDIO_DEFAULT_PROCESSOR); | ||||
if (hr != 0) | ||||
{ | ||||
return NULL; | ||||
} | ||||
hr = FAudio_CreateMasteringVoice( | ||||
faudio, | ||||
&master, | ||||
FAUDIO_DEFAULT_CHANNELS, | ||||
FAUDIO_DEFAULT_SAMPLERATE, | ||||
0, | ||||
0, | ||||
NULL | ||||
); | ||||
if (hr != 0) | ||||
{ | ||||
return NULL; | ||||
} | ||||
// return a context object | ||||
AudioContext *context = new AudioContext(); | ||||
context->faudio = faudio; | ||||
context->mastering_voice = master; | ||||
context->source_voice = NULL; | ||||
context->wav_samples = NULL; | ||||
// load the first wave | ||||
audio_wave_load(context, (AudioSampleWave) 0, false); | ||||
return context; | ||||
} | ||||