fix(sim): simulator volume (#7302)

This commit is contained in:
Raphael Coeffic
2026-04-22 12:45:48 +10:00
committed by GitHub
parent 919c9bb704
commit 669b5fbced
4 changed files with 31 additions and 11 deletions
@@ -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;
+12
View File
@@ -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);
+1 -6
View File
@@ -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);
}