fix audio, no longer hardcode snes9x size
This commit is contained in:
Generated
+8
-8
@@ -60,7 +60,7 @@ dependencies = [
|
|||||||
"regex",
|
"regex",
|
||||||
"rustc-hash 2.1.1",
|
"rustc-hash 2.1.1",
|
||||||
"shlex",
|
"shlex",
|
||||||
"syn 2.0.108",
|
"syn 2.0.109",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -89,9 +89,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.2.44"
|
version = "1.2.45"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "37521ac7aabe3d13122dc382493e20c9416f299d2ccd5b3a5340a2570cdeb0f3"
|
checksum = "35900b6c8d709fb1d854671ae27aeaa9eec2f8b01b364e1619a40da3e6fe2afe"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"find-msvc-tools",
|
"find-msvc-tools",
|
||||||
"jobserver",
|
"jobserver",
|
||||||
@@ -423,9 +423,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.41"
|
version = "1.0.42"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1"
|
checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
@@ -607,9 +607,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.108"
|
version = "2.0.109"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917"
|
checksum = "2f17c7e013e88258aa9543dcbe81aca68a667a9ac37cd69c9fbc07858bfe0e2f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -633,7 +633,7 @@ checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.108",
|
"syn 2.0.109",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
+43
-57
@@ -183,7 +183,7 @@ struct AudioState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AudioState {
|
impl AudioState {
|
||||||
fn new(in_audio_sample_rate: i32, emu_video_frame_rate: i32, output: &mut FFOut) -> Self {
|
fn new(in_audio_sample_rate: i32, output: &mut FFOut) -> Self {
|
||||||
let out_audio_codec = ffmpeg_next::encoder::find(ffmpeg_next::codec::Id::AAC).unwrap();
|
let out_audio_codec = ffmpeg_next::encoder::find(ffmpeg_next::codec::Id::AAC).unwrap();
|
||||||
let mut out_audio_ctx =
|
let mut out_audio_ctx =
|
||||||
ffmpeg_next::codec::context::Context::new_with_codec(out_audio_codec);
|
ffmpeg_next::codec::context::Context::new_with_codec(out_audio_codec);
|
||||||
@@ -208,12 +208,12 @@ impl AudioState {
|
|||||||
));
|
));
|
||||||
out_audio_enc.set_channel_layout(ffmpeg_next::ChannelLayout::STEREO);
|
out_audio_enc.set_channel_layout(ffmpeg_next::ChannelLayout::STEREO);
|
||||||
out_audio_enc.set_time_base(audio_time_base);
|
out_audio_enc.set_time_base(audio_time_base);
|
||||||
out_audio_enc.set_rate(48000);
|
out_audio_enc.set_rate(audio_time_base.1);
|
||||||
let out_audio_enc = out_audio_enc.open().unwrap();
|
let out_audio_enc = out_audio_enc.open().unwrap();
|
||||||
let mut in_aframe = FFAFrame::new(
|
let mut in_aframe = FFAFrame::new(
|
||||||
ffmpeg_next::format::Sample::I16(ffmpeg_next::format::sample::Type::Packed),
|
ffmpeg_next::format::Sample::I16(ffmpeg_next::format::sample::Type::Packed),
|
||||||
704,
|
1024,
|
||||||
// dbg!(in_audio_sample_rate / emu_video_frame_rate) as usize,
|
//dbg!(in_audio_sample_rate / emu_video_frame_rate) as usize,
|
||||||
ffmpeg_next::ChannelLayout::STEREO,
|
ffmpeg_next::ChannelLayout::STEREO,
|
||||||
);
|
);
|
||||||
in_aframe.set_rate(u32::try_from(in_audio_sample_rate).unwrap());
|
in_aframe.set_rate(u32::try_from(in_audio_sample_rate).unwrap());
|
||||||
@@ -223,24 +223,13 @@ impl AudioState {
|
|||||||
out_audio_enc.channel_layout(),
|
out_audio_enc.channel_layout(),
|
||||||
);
|
);
|
||||||
out_aframe.set_rate(out_audio_enc.rate());
|
out_aframe.set_rate(out_audio_enc.rate());
|
||||||
let resampler = ffmpeg_next::software::resampler(
|
let resampler = in_aframe
|
||||||
(
|
.resampler(
|
||||||
in_aframe.format(),
|
|
||||||
in_aframe.channel_layout(),
|
|
||||||
in_aframe.rate(),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
out_aframe.format(),
|
out_aframe.format(),
|
||||||
out_aframe.channel_layout(),
|
out_aframe.channel_layout(),
|
||||||
out_aframe.rate(),
|
out_aframe.rate(),
|
||||||
),
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
println!(
|
|
||||||
"Resample from {} to {}",
|
|
||||||
in_aframe.rate(),
|
|
||||||
out_aframe.rate()
|
|
||||||
);
|
|
||||||
let audio_buf = ringbuf::LocalRb::new(in_aframe.samples() * 2 * 20);
|
let audio_buf = ringbuf::LocalRb::new(in_aframe.samples() * 2 * 20);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
@@ -267,25 +256,34 @@ impl AudioState {
|
|||||||
self.encoded_audio.write_interleaved(output).unwrap();
|
self.encoded_audio.write_interleaved(output).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn resample(&mut self, drain: bool) {
|
fn resample_and_send(&mut self, output: &mut FFOut, drain: bool) {
|
||||||
println!(
|
match self.resampler.run(&self.in_aframe, &mut self.out_aframe) {
|
||||||
"RESAMPLE {:?} {:?}",
|
Ok(_) => {
|
||||||
self.in_aframe.pts(),
|
self.in_aframe.set_pts(Some(self.audio_frame_in));
|
||||||
self.out_aframe.pts()
|
self.out_aframe.set_pts(Some(self.audio_frame_out));
|
||||||
);
|
self.audio_frame_in += i64::try_from(self.in_aframe.samples()).unwrap();
|
||||||
match dbg!(self.resampler.run(&self.in_aframe, &mut self.out_aframe)) {
|
self.audio_frame_out += i64::try_from(self.out_aframe.samples()).unwrap();
|
||||||
Ok(Some(delay)) if drain => {
|
self.out_audio_enc.send_frame(&self.out_aframe).unwrap();
|
||||||
dbg!(delay);
|
self.writeout(output);
|
||||||
let null_frame = unsafe { FFAFrame::wrap(std::ptr::null_mut()) };
|
}
|
||||||
while let Ok(Some(delay)) = self.resampler.run(&null_frame, &mut self.out_aframe) {
|
Err(e) => {
|
||||||
dbg!("2", delay);
|
println!("Resampler error {e}");
|
||||||
if !drain {
|
}
|
||||||
|
}
|
||||||
|
loop {
|
||||||
|
let Some(delay) = self.resampler.delay() else {
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
if delay.output < 524 && !drain {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
self.in_aframe.set_pts(Some(self.audio_frame_in));
|
||||||
}
|
self.out_aframe.set_pts(Some(self.audio_frame_out));
|
||||||
Err(e) => println!("Resampler error {e}"),
|
self.resampler.flush(&mut self.out_aframe).unwrap();
|
||||||
_ => {}
|
self.audio_frame_in += i64::try_from(self.in_aframe.samples()).unwrap();
|
||||||
|
self.audio_frame_out += i64::try_from(self.out_aframe.samples()).unwrap();
|
||||||
|
self.out_audio_enc.send_frame(&self.out_aframe).unwrap();
|
||||||
|
self.writeout(output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn send_frames(&mut self, emu: &Emulator, output: &mut FFOut) {
|
fn send_frames(&mut self, emu: &Emulator, output: &mut FFOut) {
|
||||||
@@ -295,28 +293,18 @@ impl AudioState {
|
|||||||
while self.audio_buf.occupied_len() >= self.in_aframe.samples() * 2 {
|
while self.audio_buf.occupied_len() >= self.in_aframe.samples() * 2 {
|
||||||
let (_, toconvert, _) = unsafe { self.in_aframe.data_mut(0).align_to_mut::<i16>() };
|
let (_, toconvert, _) = unsafe { self.in_aframe.data_mut(0).align_to_mut::<i16>() };
|
||||||
assert_eq!(self.audio_buf.pop_slice(toconvert), toconvert.len());
|
assert_eq!(self.audio_buf.pop_slice(toconvert), toconvert.len());
|
||||||
dbg!(toconvert.len());
|
self.resample_and_send(output, false);
|
||||||
self.in_aframe.set_pts(Some(self.audio_frame_in));
|
|
||||||
self.out_aframe.set_pts(Some(self.audio_frame_out));
|
|
||||||
self.audio_frame_in += i64::try_from(self.in_aframe.samples()).unwrap();
|
|
||||||
self.audio_frame_out += i64::try_from(self.out_aframe.samples()).unwrap();
|
|
||||||
self.resample(false);
|
|
||||||
dbg!(self.out_aframe.samples());
|
|
||||||
self.out_audio_enc.send_frame(&self.out_aframe).unwrap();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
self.writeout(output);
|
|
||||||
}
|
}
|
||||||
fn drain(&mut self, output: &mut FFOut) {
|
fn drain(&mut self, output: &mut FFOut) {
|
||||||
while self.audio_buf.occupied_len() > 0 {
|
while self.audio_buf.occupied_len() > 0 {
|
||||||
let (_, toconvert, _) = unsafe { self.in_aframe.data_mut(0).align_to_mut::<i16>() };
|
let (_, toconvert, _) = unsafe { self.in_aframe.data_mut(0).align_to_mut::<i16>() };
|
||||||
let len = self.audio_buf.pop_slice(toconvert);
|
let len = self.audio_buf.pop_slice(toconvert);
|
||||||
toconvert[len..].fill(0);
|
toconvert[len..].fill(0);
|
||||||
self.resample(true);
|
self.resample_and_send(output, true);
|
||||||
self.out_aframe.set_pts(Some(self.audio_frame_out));
|
|
||||||
self.audio_frame_out += i64::try_from(len / 2).unwrap();
|
|
||||||
self.out_audio_enc.send_frame(&self.out_aframe).unwrap();
|
|
||||||
}
|
}
|
||||||
|
self.resample_and_send(output, true);
|
||||||
self.out_audio_enc.send_eof().unwrap();
|
self.out_audio_enc.send_eof().unwrap();
|
||||||
self.writeout(output);
|
self.writeout(output);
|
||||||
}
|
}
|
||||||
@@ -356,19 +344,17 @@ fn main() {
|
|||||||
let emu_video_framerate = emu.get_video_fps().to_i32().unwrap();
|
let emu_video_framerate = emu.get_video_fps().to_i32().unwrap();
|
||||||
let emu_time_base = Rational::new(1, emu_video_framerate);
|
let emu_time_base = Rational::new(1, emu_video_framerate);
|
||||||
let audio_sample_rate = emu.get_audio_sample_rate().to_i32().unwrap();
|
let audio_sample_rate = emu.get_audio_sample_rate().to_i32().unwrap();
|
||||||
let aspect_ratio = Rational::from(emu.get_aspect_ratio() as f64);
|
let aspect_ratio = Rational::from(f64::from(emu.get_aspect_ratio()));
|
||||||
let mut video_state =
|
let mut video_state =
|
||||||
VideoState::new(emu_time_base, aspect_ratio, w, h, pixel_format, &mut output);
|
VideoState::new(emu_time_base, aspect_ratio, w, h, pixel_format, &mut output);
|
||||||
let mut audio_state = AudioState::new(audio_sample_rate, emu_video_framerate, &mut output);
|
let mut audio_state = AudioState::new(audio_sample_rate, &mut output);
|
||||||
output.write_header().unwrap();
|
output.write_header().unwrap();
|
||||||
let video_stream_time_base = output.stream(0).unwrap().time_base();
|
// video_state
|
||||||
let audio_stream_time_base = output.stream(1).unwrap().time_base();
|
// .encoded_video
|
||||||
video_state
|
// .set_time_base(video_stream_time_base);
|
||||||
.encoded_video
|
// audio_state
|
||||||
.set_time_base(video_stream_time_base);
|
// .encoded_audio
|
||||||
audio_state
|
// .set_time_base(audio_stream_time_base);
|
||||||
.encoded_audio
|
|
||||||
.set_time_base(audio_stream_time_base);
|
|
||||||
|
|
||||||
let mut frame = Frame::default();
|
let mut frame = Frame::default();
|
||||||
while let Ok(()) = rply
|
while let Ok(()) = rply
|
||||||
|
|||||||
Reference in New Issue
Block a user