all repos — mgba @ 73e4516257b952987b8904a05b087305ffcbdfcb

mGBA Game Boy Advance Emulator

GBA Audio: Ability to mute individual audio channels
Jeffrey Pfau jeffrey@endrift.com
Sun, 05 Apr 2015 01:39:10 -0700
commit

73e4516257b952987b8904a05b087305ffcbdfcb

parent

8533f01be57d725e9c8e779869761f8f5d859b2e

4 files changed, 79 insertions(+), 30 deletions(-)

jump to
M CHANGESCHANGES

@@ -1,6 +1,7 @@

0.3.0: (Future) Features: - Ability to hide individual background layers, or OBJs + - Ability to mute individual audio channels Bugfixes: - GBA: Fix timers not updating timing when writing to only the reload register - All: Fix sanitize-deb script not cleaning up after itself
M src/gba/audio.csrc/gba/audio.c

@@ -41,6 +41,13 @@ blip_set_rates(audio->right, GBA_ARM7TDMI_FREQUENCY, 96000);

#endif CircleBufferInit(&audio->chA.fifo, GBA_AUDIO_FIFO_SIZE); CircleBufferInit(&audio->chB.fifo, GBA_AUDIO_FIFO_SIZE); + + audio->forceDisableCh[0] = false; + audio->forceDisableCh[1] = false; + audio->forceDisableCh[2] = false; + audio->forceDisableCh[3] = false; + audio->forceDisableChA = false; + audio->forceDisableChB = false; } void GBAAudioReset(struct GBAAudio* audio) {

@@ -750,55 +757,67 @@ int16_t sampleLeft = 0;

int16_t sampleRight = 0; int psgShift = 5 - audio->volume; - if (audio->ch1Left) { - sampleLeft += audio->ch1.sample; - } + if (audio->playingCh1 && !audio->forceDisableCh[0]) { + if (audio->ch1Left) { + sampleLeft += audio->ch1.sample; + } - if (audio->ch1Right) { - sampleRight += audio->ch1.sample; + if (audio->ch1Right) { + sampleRight += audio->ch1.sample; + } } - if (audio->ch2Left) { - sampleLeft += audio->ch2.sample; - } + if (audio->playingCh2 && !audio->forceDisableCh[1]) { + if (audio->ch2Left) { + sampleLeft += audio->ch2.sample; + } - if (audio->ch2Right) { - sampleRight += audio->ch2.sample; + if (audio->ch2Right) { + sampleRight += audio->ch2.sample; + } } - if (audio->ch3Left) { - sampleLeft += audio->ch3.sample; - } + if (audio->playingCh3 && !audio->forceDisableCh[2]) { + if (audio->ch3Left) { + sampleLeft += audio->ch3.sample; + } - if (audio->ch3Right) { - sampleRight += audio->ch3.sample; + if (audio->ch3Right) { + sampleRight += audio->ch3.sample; + } } - if (audio->ch4Left) { - sampleLeft += audio->ch4.sample; - } + if (audio->playingCh4 && !audio->forceDisableCh[3]) { + if (audio->ch4Left) { + sampleLeft += audio->ch4.sample; + } - if (audio->ch4Right) { - sampleRight += audio->ch4.sample; + if (audio->ch4Right) { + sampleRight += audio->ch4.sample; + } } sampleLeft = (sampleLeft * (1 + audio->volumeLeft)) >> psgShift; sampleRight = (sampleRight * (1 + audio->volumeRight)) >> psgShift; - if (audio->chALeft) { - sampleLeft += (audio->chA.sample << 2) >> !audio->volumeChA; - } + if (!audio->forceDisableChA) { + if (audio->chALeft) { + sampleLeft += (audio->chA.sample << 2) >> !audio->volumeChA; + } - if (audio->chARight) { - sampleRight += (audio->chA.sample << 2) >> !audio->volumeChA; + if (audio->chARight) { + sampleRight += (audio->chA.sample << 2) >> !audio->volumeChA; + } } - if (audio->chBLeft) { - sampleLeft += (audio->chB.sample << 2) >> !audio->volumeChB; - } + if (!audio->forceDisableChB) { + if (audio->chBLeft) { + sampleLeft += (audio->chB.sample << 2) >> !audio->volumeChB; + } - if (audio->chBRight) { - sampleRight += (audio->chB.sample << 2) >> !audio->volumeChB; + if (audio->chBRight) { + sampleRight += (audio->chB.sample << 2) >> !audio->volumeChB; + } } sampleLeft = _applyBias(audio, sampleLeft);
M src/gba/audio.hsrc/gba/audio.h

@@ -236,6 +236,10 @@ int32_t nextCh4;

int32_t nextSample; int32_t sampleInterval; + + bool forceDisableCh[4]; + bool forceDisableChA; + bool forceDisableChB; }; struct GBAStereoSample {
M src/platform/qt/Window.cppsrc/platform/qt/Window.cpp

@@ -818,6 +818,31 @@ connect(enableObj, &QAction::triggered, [this](bool enable) { m_controller->thread()->gba->video.renderer->disableOBJ = !enable; });

m_gameActions.append(enableObj); addControlledAction(videoLayers, enableObj, "enableOBJ"); + QMenu* audioChannels = avMenu->addMenu(tr("Audio channels")); + + for (int i = 0; i < 4; ++i) { + QAction* enableCh = new QAction(tr("Channel %0").arg(i + 1), audioChannels); + enableCh->setCheckable(true); + enableCh->setChecked(true); + connect(enableCh, &QAction::triggered, [this, i](bool enable) { m_controller->thread()->gba->audio.forceDisableCh[i] = !enable; }); + m_gameActions.append(enableCh); + addControlledAction(audioChannels, enableCh, QString("enableCh%0").arg(i + 1)); + } + + QAction* enableChA = new QAction(tr("Channel A"), audioChannels); + enableChA->setCheckable(true); + enableChA->setChecked(true); + connect(enableChA, &QAction::triggered, [this, i](bool enable) { m_controller->thread()->gba->audio.forceDisableChA = !enable; }); + m_gameActions.append(enableChA); + addControlledAction(audioChannels, enableChA, QString("enableChA")); + + QAction* enableChB = new QAction(tr("Channel B"), audioChannels); + enableChB->setCheckable(true); + enableChB->setChecked(true); + connect(enableChB, &QAction::triggered, [this, i](bool enable) { m_controller->thread()->gba->audio.forceDisableChB = !enable; }); + m_gameActions.append(enableChB); + addControlledAction(audioChannels, enableChB, QString("enableChB")); + QMenu* toolsMenu = menubar->addMenu(tr("&Tools")); m_shortcutController->addMenu(toolsMenu); QAction* viewLogs = new QAction(tr("View &logs..."), toolsMenu);