Pump audio faster, up to XAUDIO2_MAX_QUEUED_BUFFERS (64) frames, then wait.
This commit is contained in:
parent
517dce01b1
commit
8a5d3526e5
|
@ -405,7 +405,7 @@ void AudioSystem::SubmitFrame(size_t index, uint32_t samples_ptr) {
|
||||||
assert_true(index < maximum_client_count_);
|
assert_true(index < maximum_client_count_);
|
||||||
assert_true(clients_[index].driver != NULL);
|
assert_true(clients_[index].driver != NULL);
|
||||||
(clients_[index].driver)->SubmitFrame(samples_ptr);
|
(clients_[index].driver)->SubmitFrame(samples_ptr);
|
||||||
ResetEvent(client_wait_handles_[index]);
|
//ResetEvent(client_wait_handles_[index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioSystem::UnregisterClient(size_t index) {
|
void AudioSystem::UnregisterClient(size_t index) {
|
||||||
|
|
|
@ -40,6 +40,7 @@ XAudio2AudioDriver::XAudio2AudioDriver(Emulator* emulator, HANDLE wait)
|
||||||
pcm_voice_(0),
|
pcm_voice_(0),
|
||||||
wait_handle_(wait),
|
wait_handle_(wait),
|
||||||
voice_callback_(0),
|
voice_callback_(0),
|
||||||
|
current_frame_(0),
|
||||||
AudioDriver(emulator) {}
|
AudioDriver(emulator) {}
|
||||||
|
|
||||||
XAudio2AudioDriver::~XAudio2AudioDriver() {}
|
XAudio2AudioDriver::~XAudio2AudioDriver() {}
|
||||||
|
@ -101,7 +102,8 @@ void XAudio2AudioDriver::Initialize() {
|
||||||
waveformat.Samples.wValidBitsPerSample = waveformat.Format.wBitsPerSample;
|
waveformat.Samples.wValidBitsPerSample = waveformat.Format.wBitsPerSample;
|
||||||
waveformat.dwChannelMask = ChannelMasks[waveformat.Format.nChannels];
|
waveformat.dwChannelMask = ChannelMasks[waveformat.Format.nChannels];
|
||||||
|
|
||||||
hr = audio_->CreateSourceVoice(&pcm_voice_, &waveformat.Format, 0,
|
hr = audio_->CreateSourceVoice(&pcm_voice_, &waveformat.Format,
|
||||||
|
0, // XAUDIO2_VOICE_NOSRC | XAUDIO2_VOICE_NOPITCH,
|
||||||
XAUDIO2_DEFAULT_FREQ_RATIO, voice_callback_);
|
XAUDIO2_DEFAULT_FREQ_RATIO, voice_callback_);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
XELOGE("CreateSourceVoice failed with %.8X", hr);
|
XELOGE("CreateSourceVoice failed with %.8X", hr);
|
||||||
|
@ -127,22 +129,28 @@ void XAudio2AudioDriver::SubmitFrame(uint32_t frame_ptr) {
|
||||||
// Process samples! They are big-endian floats.
|
// Process samples! They are big-endian floats.
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
|
XAUDIO2_VOICE_STATE state;
|
||||||
|
pcm_voice_->GetState(&state, XAUDIO2_VOICE_NOSAMPLESPLAYED);
|
||||||
|
assert_true(state.BuffersQueued < frame_count_);
|
||||||
|
|
||||||
auto input_frame = memory_->TranslateVirtual<float*>(frame_ptr);
|
auto input_frame = memory_->TranslateVirtual<float*>(frame_ptr);
|
||||||
auto output_frame = reinterpret_cast<float*>(frame_);
|
auto output_frame = reinterpret_cast<float*>(frames_[current_frame_]);
|
||||||
auto interleave_channels = frame_channels_;
|
auto interleave_channels = frame_channels_;
|
||||||
|
|
||||||
// interleave the data
|
// interleave the data
|
||||||
for (int index = 0, o = 0; index < channel_samples_; ++index) {
|
for (uint32_t index = 0, o = 0; index < channel_samples_; ++index) {
|
||||||
for (int channel = 0, table = 0; channel < interleave_channels;
|
for (uint32_t channel = 0, table = 0; channel < interleave_channels;
|
||||||
++channel, table += channel_samples_) {
|
++channel, table += channel_samples_) {
|
||||||
output_frame[o++] = xe::byte_swap(input_frame[table + index]);
|
output_frame[o++] = xe::byte_swap(input_frame[table + index]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XELOGE("Submitting audio frame %u", current_frame_);
|
||||||
|
|
||||||
XAUDIO2_BUFFER buffer;
|
XAUDIO2_BUFFER buffer;
|
||||||
buffer.Flags = 0;
|
buffer.Flags = 0;
|
||||||
buffer.pAudioData = (BYTE*)frame_;
|
buffer.pAudioData = (BYTE*)output_frame;
|
||||||
buffer.AudioBytes = sizeof(frame_);
|
buffer.AudioBytes = frame_size_;
|
||||||
buffer.PlayBegin = 0;
|
buffer.PlayBegin = 0;
|
||||||
buffer.PlayLength = channel_samples_;
|
buffer.PlayLength = channel_samples_;
|
||||||
buffer.LoopBegin = XAUDIO2_NO_LOOP_REGION;
|
buffer.LoopBegin = XAUDIO2_NO_LOOP_REGION;
|
||||||
|
@ -155,6 +163,15 @@ void XAudio2AudioDriver::SubmitFrame(uint32_t frame_ptr) {
|
||||||
assert_always();
|
assert_always();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
current_frame_ = (current_frame_ + 1) % frame_count_;
|
||||||
|
|
||||||
|
XAUDIO2_VOICE_STATE state2;
|
||||||
|
pcm_voice_->GetState(&state2, XAUDIO2_VOICE_NOSAMPLESPLAYED);
|
||||||
|
|
||||||
|
if (state2.BuffersQueued >= frame_count_) {
|
||||||
|
ResetEvent(wait_handle_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XAudio2AudioDriver::Shutdown() {
|
void XAudio2AudioDriver::Shutdown() {
|
||||||
|
@ -169,7 +186,6 @@ void XAudio2AudioDriver::Shutdown() {
|
||||||
audio_->Release();
|
audio_->Release();
|
||||||
|
|
||||||
delete voice_callback_;
|
delete voice_callback_;
|
||||||
CloseHandle(wait_handle_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace xaudio2
|
} // namespace xaudio2
|
||||||
|
|
|
@ -32,13 +32,18 @@ class XAudio2AudioDriver : public AudioDriver {
|
||||||
IXAudio2* audio_;
|
IXAudio2* audio_;
|
||||||
IXAudio2MasteringVoice* mastering_voice_;
|
IXAudio2MasteringVoice* mastering_voice_;
|
||||||
IXAudio2SourceVoice* pcm_voice_;
|
IXAudio2SourceVoice* pcm_voice_;
|
||||||
static const int frame_channels_ = 6;
|
|
||||||
static const int channel_samples_ = 256;
|
|
||||||
float frame_[frame_channels_ * channel_samples_];
|
|
||||||
HANDLE wait_handle_;
|
HANDLE wait_handle_;
|
||||||
|
|
||||||
class VoiceCallback;
|
class VoiceCallback;
|
||||||
VoiceCallback* voice_callback_;
|
VoiceCallback* voice_callback_;
|
||||||
|
|
||||||
|
static const uint32_t frame_count_ = XAUDIO2_MAX_QUEUED_BUFFERS;
|
||||||
|
static const uint32_t frame_channels_ = 6;
|
||||||
|
static const uint32_t channel_samples_ = 256;
|
||||||
|
static const uint32_t frame_samples_ = frame_channels_ * channel_samples_;
|
||||||
|
static const uint32_t frame_size_ = sizeof(float) * frame_samples_;
|
||||||
|
float frames_[frame_count_][frame_samples_];
|
||||||
|
uint32_t current_frame_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace xaudio2
|
} // namespace xaudio2
|
||||||
|
|
Loading…
Reference in New Issue