From 8d87d9ef9f726a0123bb458c4aa07d1a47eb3a15 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Magalh=C3=A3es?= <joamag@gmail.com>
Date: Sun, 26 Mar 2023 22:36:33 +0100
Subject: [PATCH] feat: support for waveform plotting Also fixed small channel
 3 issue

---
 CHANGELOG.md           |  2 ++
 frontends/web/ts/gb.ts | 12 ++++++++++++
 src/apu.rs             | 14 +++++++++++++-
 src/gb.rs              | 25 +++++++++++++++++++++++++
 4 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index c3b9efac..3db9bd18 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 ### Added
 
 * Support for CGB flag parsing
+* Waveform plotting support
 
 ### Changed
 
@@ -18,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 ### Fixed
 
 * Major JoyPad issue with Action/Select read in register
+* Small issue with channel 3 audio and DAC disable
 
 ## [0.7.2] - 2023-03-04
 
diff --git a/frontends/web/ts/gb.ts b/frontends/web/ts/gb.ts
index dcde0e67..ce5fab78 100644
--- a/frontends/web/ts/gb.ts
+++ b/frontends/web/ts/gb.ts
@@ -606,6 +606,18 @@ export class GameboyEmulator extends EmulatorBase implements Emulator {
         };
     }
 
+    get audioOutput(): Record<string, number> {
+        const output = this.gameBoy?.audio_all_output();
+        if (!output) return {};
+        return {
+            master: output[0],
+            ch1: output[1],
+            ch2: output[2],
+            ch3: output[3],
+            ch4: 0
+        };
+    }
+
     get palette(): string | undefined {
         const paletteObj = PALETTES[this.paletteIndex];
         return paletteObj.name;
diff --git a/src/apu.rs b/src/apu.rs
index 03893a90..b44762b9 100644
--- a/src/apu.rs
+++ b/src/apu.rs
@@ -348,6 +348,18 @@ impl Apu {
         self.ch1_output + self.ch2_output + self.ch3_output
     }
 
+    pub fn ch1_output(&self) -> u8 {
+        self.ch1_output
+    }
+
+    pub fn ch2_output(&self) -> u8 {
+        self.ch2_output
+    }
+
+    pub fn ch3_output(&self) -> u8 {
+        self.ch3_output
+    }
+
     pub fn audio_buffer(&self) -> &VecDeque<u8> {
         &self.audio_buffer
     }
@@ -526,7 +538,7 @@ impl Apu {
             return;
         }
 
-        if self.ch3_enabled {
+        if self.ch3_enabled && self.ch3_dac {
             let wave_index = self.ch3_position >> 1;
             let mut output = self.wave_ram[wave_index as usize];
             output = if (self.ch3_position & 0x01) == 0x01 {
diff --git a/src/gb.rs b/src/gb.rs
index 07acdf7c..a45b8921 100644
--- a/src/gb.rs
+++ b/src/gb.rs
@@ -189,6 +189,31 @@ impl GameBoy {
         buffer
     }
 
+    pub fn audio_output(&self) -> u8 {
+        self.apu_i().output()
+    }
+
+    pub fn audio_all_output(&self) -> Vec<u8> {
+        vec![
+            self.audio_output(),
+            self.audio_ch1_output(),
+            self.audio_ch2_output(),
+            self.audio_ch3_output(),
+        ]
+    }
+
+    pub fn audio_ch1_output(&self) -> u8 {
+        self.apu_i().ch1_output()
+    }
+
+    pub fn audio_ch2_output(&self) -> u8 {
+        self.apu_i().ch2_output()
+    }
+
+    pub fn audio_ch3_output(&self) -> u8 {
+        self.apu_i().ch3_output()
+    }
+
     pub fn cartridge_eager(&mut self) -> Cartridge {
         self.mmu().rom().clone()
     }
-- 
GitLab