Skip to content

Commit

Permalink
audio: pocoman opening works
Browse files Browse the repository at this point in the history
  • Loading branch information
evmar committed Oct 5, 2024
1 parent 307aea1 commit 8c1713a
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 7 deletions.
2 changes: 1 addition & 1 deletion cli/src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ impl win32::Host for EnvRef {
gui.create_surface(opts)
}

fn write_audio(&mut self, buf: &[i16]) {
fn write_audio(&mut self, buf: &[u8]) {
let mut env = self.0.borrow_mut();
let gui = env.ensure_gui().unwrap();
gui.write_audio(buf);
Expand Down
78 changes: 76 additions & 2 deletions cli/src/sdl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,13 @@ fn message_from_events(
}

pub struct GUI {
sdl: sdl2::Sdl,
video: sdl2::VideoSubsystem,
pump: sdl2::EventPump,
timer: sdl2::TimerSubsystem,
win: Option<WindowRef>,
msg_queue: Option<win32::Message>,
audio: Option<Audio>,
}

impl GUI {
Expand All @@ -94,11 +96,13 @@ impl GUI {
let timer = sdl.timer().map_err(|err| anyhow::anyhow!(err))?;

Ok(GUI {
sdl,
video,
pump,
timer,
win: None,
msg_queue: None,
audio: None,
})
}

Expand Down Expand Up @@ -158,8 +162,11 @@ impl GUI {
Box::new(Texture::new(self.win.as_ref().unwrap(), opts))
}

pub fn write_audio(&mut self, _buf: &[i16]) {
log::warn!("TODO: write_audio");
pub fn write_audio(&mut self, buf: &[u8]) {
if self.audio.is_none() {
self.audio = Some(Audio::init(&self.sdl));
}
self.audio.as_mut().unwrap().write_audio(buf);
}
}

Expand Down Expand Up @@ -278,3 +285,70 @@ impl win32::Surface for Texture {
.unwrap();
}
}

#[derive(Default)]
struct AudioBuffer {
buf: Vec<i16>,
ofs: usize,
}
impl AudioBuffer {
fn write(&mut self, buf: &[u8]) {
if self.ofs > 0 {
todo!();
}

if self.buf.len() < 44100 {
self.buf.resize(44100, 0);
}

assert!(buf.len() % 2 == 0);
let write_buf = unsafe {
let data = self.buf.as_mut_ptr().add(self.ofs) as *mut u8;
let len = (buf.len() - self.ofs) * 2;
std::slice::from_raw_parts_mut(data, len)
};
if write_buf.len() < buf.len() {
panic!("audio buffer overflow");
}
write_buf[..buf.len()].copy_from_slice(buf);
}
}

impl sdl2::audio::AudioCallback for AudioBuffer {
type Channel = i16;
fn callback(&mut self, buf: &mut [i16]) {
let available = &self.buf[self.ofs..];
if available.len() > buf.len() {
buf.copy_from_slice(&available[..buf.len()]);
} else {
log::warn!("audiobuf underflow");
buf[..available.len()].copy_from_slice(available);
buf[available.len()..].fill(0);
}
self.ofs += buf.len();
}
}

struct Audio {
dev: sdl2::audio::AudioDevice<AudioBuffer>,
}

impl Audio {
fn init(sdl: &sdl2::Sdl) -> Self {
let audio = sdl.audio().unwrap();
let spec = sdl2::audio::AudioSpecDesired {
freq: Some(11025), // TODO: accept from caller I guess?
channels: Some(1),
samples: None,
};
let dev = audio
.open_playback(None, &spec, |_spec| AudioBuffer::default())
.unwrap();
dev.resume();
Audio { dev }
}

fn write_audio(&mut self, buf: &[u8]) {
self.dev.lock().write(buf);
}
}
2 changes: 1 addition & 1 deletion web/glue/src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ impl win32::Host for JsHost {
todo!("remove_dir {path}")
}

fn write_audio(&mut self, _buf: &[i16]) {
fn write_audio(&mut self, _buf: &[u8]) {
log::warn!("TODO: write_audio");
}
}
2 changes: 1 addition & 1 deletion win32/src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,5 +159,5 @@ pub trait Host {
fn create_window(&mut self, hwnd: u32) -> Box<dyn Window>;
fn create_surface(&mut self, hwnd: u32, opts: &SurfaceOptions) -> Box<dyn Surface>;

fn write_audio(&mut self, buf: &[i16]);
fn write_audio(&mut self, buf: &[u8]);
}
11 changes: 9 additions & 2 deletions win32/src/winapi/winmm/wave.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::MMRESULT;
use crate::machine::Machine;
use bitflags::bitflags;
use memory::Extensions;

#[win32_derive::dllexport]
pub fn waveOutGetNumDevs(_machine: &mut Machine) -> u32 {
Expand Down Expand Up @@ -237,12 +238,18 @@ pub fn waveOutUnprepareHeader(

#[win32_derive::dllexport]
pub fn waveOutWrite(
_machine: &mut Machine,
machine: &mut Machine,
hwo: HWAVEOUT,
pwh: Option<&WAVEHDR>,
cbwh: u32,
) -> MMRESULT {
log::info!("TODO: write audio");
assert_eq!(cbwh, std::mem::size_of::<WAVEHDR>() as u32);
let hdr = pwh.unwrap();
let buf = machine
.emu
.memory
.mem()
.sub32(hdr.lpData, hdr.dwBufferLength);
machine.host.write_audio(buf);
MMRESULT::MMSYSERR_NOERROR
}

0 comments on commit 8c1713a

Please sign in to comment.