Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Audio #106

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open

Audio #106

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ jobs:
- name: Run rustfmt
run: cargo fmt --check
- name: Unit tests
run: cargo test -- --include-ignored --nocapture

run: |
sudo apt update -y;
sudo apt install -y libasound2-dev;
cargo test -- --include-ignored --nocapture
- name: Clippy
run: cargo clippy --all-features

Expand Down
2 changes: 2 additions & 0 deletions fpt-egui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ eframe = { version = "0.26.2", default-features = false, features = ["glow"] }
log = "0.4.14"
clap = { version = "4.5", features = ["derive"] }
rfd = "0.14.1"
cpal = "0.15"
blip_buf = "0.1"

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
env_logger = "0.11.2"
Expand Down
59 changes: 59 additions & 0 deletions fpt-egui/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ use std::collections::VecDeque;
use std::sync::mpsc::{channel, Receiver, Sender};
use std::time::Duration;

use blip_buf::BlipBuf;
use clap::{Parser, ValueEnum};
use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
use cpal::{Sample, SampleFormat, Stream};
use eframe::Frame;
#[allow(unused_imports)]
use egui::{
Expand Down Expand Up @@ -106,6 +109,8 @@ pub struct FPT {

#[allow(dead_code)]
rom_channel: (Sender<Vec<u8>>, Receiver<Vec<u8>>),

stream: Stream,
}

impl Default for FPT {
Expand All @@ -132,10 +137,62 @@ impl Default for FPT {
bg_map_texture: None,

rom_channel: channel(),
stream: play_audio(),
}
}
}

fn play_audio() -> Stream {
let host = cpal::default_host();
let device = host
.default_output_device()
.expect("no output device available");
let supported_config = device
.default_output_config()
.expect("error while querying configs");

let sample_format = supported_config.sample_format();

let err_fn = |err| eprintln!("an error occurred on the output audio stream: {}", err);
let config = supported_config.clone().into();

let sample_rate: u32 = supported_config.sample_rate().0;
//let mut blip_buf = BlipBuf::new(dbg!(sample_rate / 10));
//blip_buf.set_rates(512.0, dbg!(sample_rate as f64));

let stream = match sample_format {
SampleFormat::F32 => device.build_output_stream(
&config,
move |data: &mut [f32], _: &cpal::OutputCallbackInfo| {
for sample in data {
*sample = Sample::EQUILIBRIUM;
}
//let time = dbg!(data.len() as f32 / sample_rate as f32);

//for i in 0..dbg!((((512.0 * time) / 10.0) as usize)) {
// dbg!(i);
// blip_buf.add_delta(0, 10);
// blip_buf.add_delta(5, -10);
// blip_buf.end_frame(10);
//}

//let mut buf: Vec<i16> = vec![0; dbg!(data.len())];
//blip_buf.read_samples(&mut buf, false);

//for (i, sample) in buf.iter().enumerate() {
// data[i] = *sample as f32;
//}
},
err_fn,
None,
),
sample_format => panic!("Unsupported sample format '{sample_format}'"),
}
.unwrap();

stream
}

impl FPT {
/// Called once before the first frame.
#[allow(unused_variables)]
Expand All @@ -159,6 +216,8 @@ impl FPT {
} else {
fpt.gb.boot_real();
}

fpt.stream.play().unwrap();
fpt
}

Expand Down
1 change: 1 addition & 0 deletions fpt/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ edition = "2021"
regex = "1.10"
num-traits = "0.2"
rand = "0.8"
blip_buf = "0.1"

[dev-dependencies]
rstest = "0.18"
Expand Down
44 changes: 44 additions & 0 deletions fpt/src/apu/apu.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use crate::memory::{Bus,map};
use crate::bw;

use blip_buf::BlipBuf;

struct SquareChannel {
active: bool,
duty_cycle: u8,
period: u32,
blip_buf: BlipBuf,
}

impl SquareChannel {
pub fn new(sample_rate: u32) -> SquareChannel {
SquareChannel {
active: false,
duty_cycle: 1,
period: 2048,
blip_buf: BlipBuf::new(sample_rate),
}
}
}

pub struct Apu{
bus: Bus,
}

impl Apu {
pub fn new(bus: Bus) -> Apu {
Apu {
bus
}
}

pub fn step(&mut self, cycles: u32) {
let nr52 = self.bus.read(map::NR52);

//let audio_on = dbg!(bw::telst_bit8::<7>(nr52));
//let ch4_on = dbg!(bw::test_bit8::<3>(nr52));
//let ch3_on = dbg!(bw::test_bit8::<2>(nr52));
//let ch2_on = dbg!(bw::test_bit8::<1>(nr52));
//let ch1_on = dbg!(bw::test_bit8::<0>(nr52));
}
}
3 changes: 3 additions & 0 deletions fpt/src/apu/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod apu;

pub use apu::Apu;
7 changes: 7 additions & 0 deletions fpt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub use debug_interface::{DebugCmd, DebugEvent, DebugInterface};
use lr35902::LR35902;
use memory::{Bus, Buttons};
use ppu::{Frame, Ppu, DOTS_IN_ONE_FRAME};
use apu::Apu;
use timer::Timer;

pub mod bw;
Expand All @@ -16,12 +17,15 @@ pub mod debugger;
pub mod lr35902;
pub mod memory;
pub mod ppu;
pub mod apu;
pub mod timer;


pub struct Gameboy {
bus: Bus,
cpu: LR35902,
ppu: Ppu,
apu: Apu,
timer: Timer,
}

Expand All @@ -33,6 +37,7 @@ impl Gameboy {
bus: bus.clone(),
cpu: LR35902::new(bus.clone()),
ppu: Ppu::new(bus.clone()),
apu: Apu::new(bus.clone()),
timer: Timer::new(bus),
}
}
Expand Down Expand Up @@ -134,6 +139,7 @@ impl Gameboy {
let cycles = self.cpu.step();
// TODO: care for double speed mode (need to run half as much dots)
self.ppu.step(cycles as u32);
self.apu.step(cycles as u32);
self.timer.step(self.cpu.clock_cycles());
cycles
}
Expand All @@ -142,6 +148,7 @@ impl Gameboy {
let cycles = self.cpu.instruction() as u32;
// TODO: care for double speed mode (need to run half as much dots)
self.ppu.step(cycles);
self.apu.step(cycles);
self.timer.step(self.cpu.clock_cycles());
cycles
}
Expand Down
Loading