fix(sim): simulator volume (#7302)
This commit is contained in:
@@ -532,7 +532,8 @@ void WasmSimulatorInterface::setSdPath(const QString & sdPath,
|
||||
|
||||
void WasmSimulatorInterface::setVolumeGain(const int value)
|
||||
{
|
||||
m_volumeGain = qBound(0, value * SDL_MIX_MAXVOLUME / 100, SDL_MIX_MAXVOLUME);
|
||||
// Stored as user-facing gain (0.5x..3.0x) multiplied by 10.
|
||||
m_volumeGain = value;
|
||||
}
|
||||
|
||||
void WasmSimulatorInterface::setAnalogValue(uint8_t index, int16_t value)
|
||||
@@ -834,10 +835,22 @@ void WasmSimulatorInterface::queueAudio(const uint8_t * buf, uint32_t len)
|
||||
if (m_audioDevice == 0 || len == 0)
|
||||
return;
|
||||
|
||||
// Apply companion volume gain (m_volumeGain is 0..SDL_MIX_MAXVOLUME)
|
||||
// Apply companion volume gain (m_volumeGain = user gain * 10).
|
||||
// SDL_MixAudioFormat cannot amplify above unity, so scale manually
|
||||
// with saturation to support the UI's 0.5..3.0x range.
|
||||
if (m_volumeGain == 10) {
|
||||
SDL_QueueAudio(m_audioDevice, buf, len);
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray scaled(len, 0);
|
||||
SDL_MixAudioFormat((uint8_t *)scaled.data(), buf, AUDIO_S16SYS, len,
|
||||
m_volumeGain);
|
||||
auto * src = reinterpret_cast<const int16_t *>(buf);
|
||||
auto * dst = reinterpret_cast<int16_t *>(scaled.data());
|
||||
uint32_t n = len / sizeof(int16_t);
|
||||
for (uint32_t i = 0; i < n; ++i) {
|
||||
int32_t s = ((int32_t)src[i] * m_volumeGain) / 10;
|
||||
dst[i] = (int16_t)qBound<int32_t>(INT16_MIN, s, INT16_MAX);
|
||||
}
|
||||
SDL_QueueAudio(m_audioDevice, scaled.constData(), len);
|
||||
}
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ class WasmSimulatorInterface : public SimulatorInterface
|
||||
|
||||
// Audio
|
||||
SDL_AudioDeviceID m_audioDevice = 0;
|
||||
int m_volumeGain = SDL_MIX_MAXVOLUME;
|
||||
int m_volumeGain = 10; // unity gain (user gain * 10)
|
||||
|
||||
// Host-side analog values (polled by WASM via simuGetAnalog)
|
||||
static constexpr int MAX_ANALOGS = 32;
|
||||
|
||||
@@ -58,6 +58,18 @@ void audioConsumeCurrentBuffer()
|
||||
auto nextBuffer = fifo.getNextFilledBuffer();
|
||||
if (!nextBuffer) return;
|
||||
|
||||
#if !defined(SOFTWARE_VOLUME)
|
||||
// Simulate the hardware volume chip: scale samples in place.
|
||||
int volume = simuAudioGetVolume();
|
||||
if (volume < VOLUME_LEVEL_MAX) {
|
||||
auto* buf = const_cast<AudioBuffer*>(nextBuffer);
|
||||
for (uint16_t i = 0; i < buf->size; ++i) {
|
||||
buf->data[i] = (audio_data_t)(
|
||||
((int32_t)buf->data[i] * volume) / VOLUME_LEVEL_MAX);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
auto data = (const uint8_t*)nextBuffer->data;
|
||||
uint32_t len = nextBuffer->size * sizeof(audio_data_t);
|
||||
simuQueueAudio(data, len);
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "audio.h"
|
||||
#include "hal/audio_driver.h"
|
||||
#include "simuaudio.h"
|
||||
#include "simulib.h"
|
||||
|
||||
@@ -32,11 +32,6 @@ static SDL_AudioDeviceID _sdl_audio_device = 0;
|
||||
|
||||
void simuQueueAudio(const uint8_t* data, uint32_t len)
|
||||
{
|
||||
#if !defined(SOFTWARE_VOLUME)
|
||||
int volume = (simuAudioGetVolume() * SDL_MIX_MAXVOLUME ) / VOLUME_LEVEL_MAX;
|
||||
SDL_MixAudioFormat((uint8_t*)data, data, AUDIO_FMT, len, volume);
|
||||
#endif
|
||||
|
||||
SDL_QueueAudio(_sdl_audio_device, data, len);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user