aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAstatin <[email protected]>2025-07-15 13:12:11 +0200
committerAstatin <[email protected]>2025-07-15 13:12:11 +0200
commit81f8a04c38671a82c756450bbe13803e1701ada0 (patch)
tree490102918a07d63456f7a9eb9ccf62b3bee69985
parent9d24a19cd9a392d5a2067a3e233a5a26a1518c35 (diff)
Fix noise channel audio to make it more noise and less metallic
-rw-r--r--Cargo.lock10
-rw-r--r--src/audio.rs91
-rw-r--r--src/desktop/audio.rs4
3 files changed, 41 insertions, 64 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 608c9aa..55ff001 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -572,7 +572,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e3d747f100290a1ca24b752186f61f6637e1deffe3bf6320de6fcb29510a307"
dependencies = [
"bitflags 2.4.0",
- "libloading 0.7.4",
+ "libloading 0.8.6",
"winapi",
]
@@ -594,7 +594,7 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
dependencies = [
- "libloading 0.7.4",
+ "libloading 0.8.6",
]
[[package]]
@@ -827,7 +827,7 @@ dependencies = [
"bitflags 2.4.0",
"com",
"libc",
- "libloading 0.7.4",
+ "libloading 0.8.6",
"thiserror",
"widestring",
"winapi",
@@ -1020,7 +1020,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
dependencies = [
"cfg-if",
- "windows-targets 0.48.1",
+ "windows-targets 0.52.6",
]
[[package]]
@@ -2245,7 +2245,7 @@ dependencies = [
"js-sys",
"khronos-egl",
"libc",
- "libloading 0.7.4",
+ "libloading 0.8.6",
"log",
"metal",
"naga",
diff --git a/src/audio.rs b/src/audio.rs
index cd8eeb2..b8f6aa9 100644
--- a/src/audio.rs
+++ b/src/audio.rs
@@ -29,50 +29,6 @@ const SQUARE_WAVE_PATTERN_DUTY_3: [u8; 32] = [
0, 1, 0, 1, 0, 2,
];
-/*
- * Sometimes, you have to abandon the idea of doing things the right way and just do the thing.
- *
- * The Gameboy noise wave generation function is stateful and the sample averaging feature (a
- * low pass filter to filter out some weird noises created by the "too squared" nature of our
- * sound wave) needs a pure function (and fast). It's too hard so I just computed the result
- * of the noise function and put it here. It's O(1) :3
- */
-
-const NOISE_WAVE: [u16; 1023] = [
- 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1,
- 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0,
- 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0,
- 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0,
- 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1,
- 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0,
- 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1,
- 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0,
- 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0,
- 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0,
- 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1,
- 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0,
- 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1,
- 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0,
- 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1,
- 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1,
- 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1,
- 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1,
- 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0,
- 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1,
- 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
- 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0,
- 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0,
- 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1,
- 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1,
- 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1,
- 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1,
- 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0,
- 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0,
- 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1,
- 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1,
-];
-
const SQUARE_WAVE_PATTERNS: [[u8; 32]; 4] = [
SQUARE_WAVE_PATTERN_DUTY_0,
SQUARE_WAVE_PATTERN_DUTY_1,
@@ -233,6 +189,12 @@ pub struct NoiseWave {
clock_shift: u8,
lsfr_width: u8,
clock_divider: u8,
+
+ rng: u16,
+ last_i: usize,
+
+ left_volume: u8,
+ right_volume: u8,
}
impl NoiseWave {
@@ -246,6 +208,8 @@ impl NoiseWave {
clock_shift: u8,
lsfr_width: u8,
clock_divider: u8,
+ left_volume: u8,
+ right_volume: u8,
) -> NoiseWave {
NoiseWave {
num_sample,
@@ -257,6 +221,10 @@ impl NoiseWave {
clock_shift,
lsfr_width,
clock_divider,
+ rng: 0x42,
+ last_i: 0,
+ left_volume,
+ right_volume,
}
}
}
@@ -296,26 +264,31 @@ impl io::Wave for NoiseWave {
envelope
};
- let mut avg = 0.;
+ let ns = ((262144. / ((clock_divider) * (2 << self.clock_shift) as f32)) / 32768.)
+ * self.num_sample as f32;
- for n in 0..SAMPLE_AVERAGING {
- if self.num_sample as i32 + n as i32 - SAMPLE_AVERAGING as i32 >= 0 {
- let ns = ((262144. / ((clock_divider) * (2 << self.clock_shift) as f32)) / 32768.)
- * (self.num_sample + n - (SAMPLE_AVERAGING / 2)) as f32;
-
- let i = (ns as f32 * (32768 as f32 / SAMPLE_RATE as f32)) as usize;
+ let i = (ns as f32 * (32768 as f32 / SAMPLE_RATE as f32)) as usize;
- let up = if self.lsfr_width == 1 {
- NOISE_WAVE[i % 63]
- } else {
- NOISE_WAVE[i % 1023]
- };
+ let up = self.rng & 1;
+ if i != self.last_i {
+ self.last_i = i;
- avg += up as f32 * 2. - 1.;
+ self.rng >>= 1;
+ if self.lsfr_width == 1 {
+ self.rng |= ((self.rng & 1) ^ ((self.rng >> 1) & 1)) << 7;
+ } else {
+ self.rng |= ((self.rng & 1) ^ ((self.rng >> 1) & 1)) << 15;
}
}
- Some((avg / SAMPLE_AVERAGING as f32) * envelope_boundaries / 32.)
+ let mut res = up as f32 * 2. - 1.;
+ if left {
+ res = (self.left_volume as f32 / 8.) * res;
+ } else {
+ res = (self.right_volume as f32 / 8.) * res;
+ }
+
+ Some(res * envelope_boundaries / 64.)
}
}
@@ -595,6 +568,8 @@ impl AudioNoiseChannel {
self.clock_shift,
self.lsfr_width,
self.clock_divider,
+ if self.left { self.left_volume + 1 } else { 0 },
+ if self.right { self.right_volume + 1 } else { 0 },
));
} else {
*wave = None;
diff --git a/src/desktop/audio.rs b/src/desktop/audio.rs
index db15a4f..2438d01 100644
--- a/src/desktop/audio.rs
+++ b/src/desktop/audio.rs
@@ -18,7 +18,9 @@ impl<W: Wave + Send + 'static> Iterator for RodioWave<W>
fn next(&mut self) -> Option<Self::Item> {
self.1 += 1;
let left = self.1 % 2 == 0;
- self.0.next(left)
+ let result = self.0.next(left);
+
+ result
}
}