[aud] Add audio subsystem

This commit is contained in:
2024-02-20 12:38:53 +05:30
parent 6f3cfebaec
commit 3da4eb5ed6
5 changed files with 70 additions and 6 deletions

1
.gitignore vendored
View File

@@ -1,2 +1,3 @@
.idea
/target
/roms

View File

@@ -14,10 +14,10 @@ Screenshot program author: [Javamannen](https://esolangs.org/wiki/User:Javamanne
- [X] Outer loop - 60fps display loop
- [X] Display adapter
- [X] SDL2 adapter
- [ ] Keyboard
- [ ] Audio
- [X] Keyboard
- [X] Audio
- [ ] Load/Save memory
- [ ] Load a ROM
- [X] Load a ROM
## Usage instructions

View File

@@ -0,0 +1,48 @@
use sdl2::audio::AudioQueue;
use crate::emu::memory::RamMemory;
use crate::misc::endian::read_big_endian_u16;
use crate::misc::error::DeviceType::AUDIO;
use crate::misc::error::EmulatorError;
use crate::misc::result::EmulatorResult;
pub const AUDIO_BUFFER_SIZE: usize = 256;
pub struct AudioProcessor<'a> {
ram: &'a RamMemory,
frame_buffer: Box<[u8; AUDIO_BUFFER_SIZE]>,
audio_queue: &'a AudioQueue<u8>,
}
impl<'a> AudioProcessor<'a> {
pub fn try_new(ram: &'a RamMemory, audio_queue: &'a AudioQueue<u8>) -> EmulatorResult<AudioProcessor<'a>> {
let frame_buffer = vec![0u8; AUDIO_BUFFER_SIZE].into_boxed_slice()
.try_into()
.map_err(|_| {
EmulatorError::AllocationFailure(AUDIO, "Failed to allocate graphics")
})?;
Ok(AudioProcessor {
ram,
audio_queue,
frame_buffer,
})
}
}
impl<'a> AudioProcessor<'a> {
pub fn queue(&mut self) -> EmulatorResult<()> {
let audio_base_reg = (self.get_audio_base_reg() as u32) << 8;
let fb = self.frame_buffer.as_mut();
if self.audio_queue.size() == 0 {
log::warn!("Detected Queue empty!");
}
self.ram.try_copy_block(audio_base_reg, fb)?;
self.audio_queue.queue_audio(fb).map_err(|s| { EmulatorError::OtherError(Some(AUDIO), s) })
}
fn get_audio_base_reg(&self) -> u16 {
let data = self.ram.get_data_ref();
let audio_base_reg = data.get(6..8).unwrap();
read_big_endian_u16(audio_base_reg.try_into().unwrap())
}
}

View File

@@ -2,6 +2,7 @@ use std::fs::File;
use std::io::Read;
use std::time::Duration;
use clap::Parser;
use sdl2::audio::{AudioQueue, AudioSpecDesired};
use sdl2::event::Event;
use sdl2::EventPump;
use sdl2::keyboard::Keycode;
@@ -9,6 +10,7 @@ use sdl2::pixels::Color;
use sdl2::render::{BlendMode, WindowCanvas};
use simple_logger::SimpleLogger;
use crate::args::BytePusherArgs;
use crate::emu::audio::AudioProcessor;
use crate::emu::cpu::Cpu;
use crate::emu::graphics::GraphicsProcessor;
use crate::emu::keyboard::Keyboard;
@@ -30,11 +32,12 @@ fn main() -> EmulatorResult<()> {
let (file_bytes, x) = try_load_rom(&file_name)?;
assert!(x < MEM_LENGTH);
let (mut canvas, mut event_pump) = initiate_sdl();
let (mut canvas, mut event_pump, mut audio_queue) = initiate_sdl();
let ram = RamMemory::try_from(file_bytes.as_slice())?;
let graphics_processor = GraphicsProcessor::try_new(&ram)?;
let mut audio_processor = AudioProcessor::try_new(&ram,&audio_queue)?;
let mut keyboard = Keyboard::new(&ram);
let cpu = Cpu::new(&ram, &graphics_processor);
@@ -70,6 +73,7 @@ fn main() -> EmulatorResult<()> {
// draw graphics
sdl2_graphics_adapter.draw(&mut canvas)?;
// TODO render audio
audio_processor.queue()?;
canvas.present();
@@ -115,12 +119,22 @@ fn try_load_rom(file_name_option: &Option<String>) -> EmulatorResult<(Vec<u8>, u
Ok((file_bytes, bytes_read))
}
fn initiate_sdl() -> (WindowCanvas, EventPump) {
fn initiate_sdl() -> (WindowCanvas, EventPump, AudioQueue<u8>) {
const BASE_RESOLUTION: u32 = 256;
const DRAW_FACTOR: u32 = 4;
const WINDOW_RESOLUTION: u32 = BASE_RESOLUTION * DRAW_FACTOR;
let sdl_context = sdl2::init().unwrap();
let video_subsystem = sdl_context.video().unwrap();
// TODO audio subsystem
let audio_subsystem = sdl_context.audio().unwrap();
let wanted_spec = AudioSpecDesired{
channels: Some(1),
samples: Some(256),
freq: Some(15360),
};
let audio_queue = audio_subsystem.open_queue::<u8,_>(None, &wanted_spec).unwrap();
audio_queue.resume();
let window = video_subsystem.window("byte-pusher-emu", WINDOW_RESOLUTION, WINDOW_RESOLUTION)
.position_centered()
@@ -136,5 +150,5 @@ fn initiate_sdl() -> (WindowCanvas, EventPump) {
canvas.set_blend_mode(BlendMode::None);
canvas.present();
let event_pump = sdl_context.event_pump().unwrap();
(canvas, event_pump)
(canvas, event_pump, audio_queue)
}

View File

@@ -15,6 +15,7 @@ pub enum EmulatorError {
AllocationFailure(DeviceType, &'static str),
UnreachableMemory(DeviceType, u32),
EmulatorIOError(Error),
OtherError(Option<DeviceType>,String)
}
impl From<TryFromSliceError> for EmulatorError {