audio: Add Nellymoser support

This commit is contained in:
relrelb 2020-12-05 22:42:57 +02:00 committed by Mike Welsh
parent 2c2a9367ae
commit 074731e1a4
6 changed files with 163 additions and 30 deletions

122
Cargo.lock generated
View File

@ -260,9 +260,9 @@ checksum = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
[[package]]
name = "bumpalo"
version = "3.4.0"
version = "3.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820"
checksum = "099e596ef14349721d9016f6b80dd3419ea1bf289ab9b44df8e4dfd3a005d5d9"
[[package]]
name = "bytemuck"
@ -534,7 +534,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "784ad0fbab4f3e9cef09f20e0aea6000ae08d2cb98ac4c0abc53df18803d702f"
dependencies = [
"percent-encoding",
"time 0.2.24",
"time 0.2.25",
"version_check",
]
@ -550,7 +550,7 @@ dependencies = [
"publicsuffix",
"serde",
"serde_json",
"time 0.2.24",
"time 0.2.25",
"url",
]
@ -985,9 +985,9 @@ dependencies = [
[[package]]
name = "derivative"
version = "2.1.3"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eaed5874effa6cde088c644ddcdcb4ffd1511391c5be4fdd7a5ccd02c7e4a183"
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
dependencies = [
"proc-macro2",
"quote",
@ -1426,7 +1426,7 @@ dependencies = [
"cfg-if 1.0.0",
"js-sys",
"libc",
"wasi 0.10.1+wasi-snapshot-preview1",
"wasi 0.10.2+wasi-snapshot-preview1",
"wasm-bindgen",
]
@ -1745,9 +1745,9 @@ dependencies = [
[[package]]
name = "inplace_it"
version = "0.3.2"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd01a2a73f2f399df96b22dc88ea687ef4d76226284e7531ae3c7ee1dc5cb534"
checksum = "90953f308a79fe6d62a4643e51f848fbfddcd05975a38e69fdf4ab86a7baf7ca"
[[package]]
name = "instant"
@ -1900,9 +1900,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
version = "0.2.82"
version = "0.2.84"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89203f3fba0a3795506acaad8ebce3c80c0af93f994d5a1d7a0b1eeb23271929"
checksum = "1cca32fa0182e8c0989459524dc356b8f2b5c10f1b9eb521b7d182c03cf8c5ff"
[[package]]
name = "libflate"
@ -2249,6 +2249,15 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c44922cb3dbb1c70b5e5f443d63b64363a898564d739ba5198e3a9138442868d"
[[package]]
name = "nellymoser-rs"
version = "0.1.0"
source = "git+https://github.com/ruffle-rs/nellymoser?branch=main#6cc9051aee2de649dcaeee4d66d14d0b14c8c0f6"
dependencies = [
"bitstream-io 1.0.0",
"rustdct",
]
[[package]]
name = "net2"
version = "0.2.37"
@ -2297,14 +2306,23 @@ dependencies = [
[[package]]
name = "nom"
version = "6.0.1"
version = "6.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88034cfd6b4a0d54dd14f4a507eceee36c0b70e5a02236c4e4df571102be17f0"
checksum = "ab6f70b46d6325aa300f1c7bb3d470127dfc27806d8ea6bf294ee0ce643ce2b1"
dependencies = [
"memchr",
"version_check",
]
[[package]]
name = "num-complex"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "747d632c0c558b87dbabbe6a82f3b4ae03720d0646ac5b7b4dae89394be5f2c5"
dependencies = [
"num-traits",
]
[[package]]
name = "num-derive"
version = "0.3.3"
@ -2681,6 +2699,15 @@ dependencies = [
"output_vt100",
]
[[package]]
name = "primal-check"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01419cee72c1a1ca944554e23d83e483e1bccf378753344e881de28b5487511d"
dependencies = [
"num-integer",
]
[[package]]
name = "proc-macro-crate"
version = "0.1.5"
@ -2961,6 +2988,7 @@ dependencies = [
"json",
"log",
"minimp3",
"nellymoser-rs",
"num-traits",
"num_enum 0.5.1",
"percent-encoding",
@ -3156,6 +3184,29 @@ dependencies = [
"semver",
]
[[package]]
name = "rustdct"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fadcb505b98aa64da1dadb1498b912e3642aae4606623cb3ae952cd8da33f80d"
dependencies = [
"rustfft",
]
[[package]]
name = "rustfft"
version = "5.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2af893d9cfb30d3d2f2ac4bd2a071232143558e06e791dc768179f0089f68f8"
dependencies = [
"num-complex",
"num-integer",
"num-traits",
"primal-check",
"strength_reduce",
"transpose",
]
[[package]]
name = "rustls"
version = "0.19.0"
@ -3478,6 +3529,12 @@ dependencies = [
"lock_api",
]
[[package]]
name = "strength_reduce"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3ff2f71c82567c565ba4b3009a9350a96a7269eaa4001ebedae926230bc2254"
[[package]]
name = "strsim"
version = "0.9.3"
@ -3539,13 +3596,12 @@ dependencies = [
[[package]]
name = "tar"
version = "0.4.30"
version = "0.4.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "489997b7557e9a43e192c527face4feacc78bfbe6eed67fd55c4c9e381cba290"
checksum = "0313546c01d59e29be4f09687bcb4fb6690cec931cc3607b6aec7a0e417f4cc6"
dependencies = [
"filetime",
"libc",
"redox_syscall 0.1.57",
"xattr",
]
@ -3599,11 +3655,11 @@ dependencies = [
[[package]]
name = "thread_local"
version = "1.1.0"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb9bc092d0d51e76b2b19d9d85534ffc9ec2db959a2523cdae0697e2972cd447"
checksum = "d8208a331e1cb318dd5bd76951d2b8fc48ca38a69f5f4e4af1b6a9f8c6236915"
dependencies = [
"lazy_static",
"once_cell",
]
[[package]]
@ -3635,9 +3691,9 @@ dependencies = [
[[package]]
name = "time"
version = "0.2.24"
version = "0.2.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "273d3ed44dca264b0d6b3665e8d48fb515042d42466fad93d2a45b90ec4058f7"
checksum = "1195b046942c221454c2539395f85413b33383a067449d78aab2b7b052a142f7"
dependencies = [
"const_fn",
"libc",
@ -3682,9 +3738,9 @@ dependencies = [
[[package]]
name = "tinyvec"
version = "1.1.0"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccf8dbc19eb42fba10e8feaaec282fb50e2c14b2726d6301dbfeed0f73306a6f"
checksum = "317cca572a0e89c3ce0ca1f1bdc9369547fe318a683418e42ac8f59d14701023"
dependencies = [
"tinyvec_macros",
]
@ -3747,6 +3803,16 @@ dependencies = [
"tracing",
]
[[package]]
name = "transpose"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3311ef71dea6a1fd6bf5bfc10ec5b4bef6174048f6b481dbc6ce915ff48c0a0"
dependencies = [
"num-integer",
"strength_reduce",
]
[[package]]
name = "ttf-parser"
version = "0.6.2"
@ -3910,9 +3976,9 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "wasi"
version = "0.10.1+wasi-snapshot-preview1"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93c6c3420963c5c64bca373b25e77acb562081b9bb4dd5bb864187742186cea9"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[package]]
name = "wasm-bindgen"
@ -4127,9 +4193,9 @@ dependencies = [
[[package]]
name = "weezl"
version = "0.1.3"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e2bb9fc8309084dd7cd651336673844c1d47f8ef6d2091ec160b27f5c4aa277"
checksum = "4a32b378380f4e9869b22f0b5177c68a5519f03b3454fde0b291455ddbae266c"
[[package]]
name = "wgpu"
@ -4344,7 +4410,7 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a9a231574ae78801646617cefd13bfe94be907c0e4fa979cfd8b770aa3c5d08"
dependencies = [
"nom 6.0.1",
"nom 6.1.0",
]
[[package]]

View File

@ -36,6 +36,7 @@ instant = "0.1"
encoding_rs = "0.8.26"
rand = { version = "0.8.3", features = ["std", "small_rng"], default-features = false }
serde = { version = "1.0.123", features = ["derive"], optional = true }
nellymoser-rs = { git = "https://github.com/ruffle-rs/nellymoser", branch = "main" }
[dependencies.jpeg-decoder]
version = "0.1.22"

View File

@ -2,10 +2,12 @@
mod adpcm;
mod mp3;
mod nellymoser;
mod pcm;
pub use adpcm::AdpcmDecoder;
pub use mp3::Mp3Decoder;
pub use nellymoser::NellymoserDecoder;
pub use pcm::PcmDecoder;
use crate::tag_utils::SwfSlice;
@ -56,6 +58,9 @@ pub fn make_decoder<'a, R: 'a + Send + Read>(
format.sample_rate.into(),
data,
)),
AudioCompression::Nellymoser => {
Box::new(NellymoserDecoder::new(data, format.sample_rate.into()))
}
_ => {
let msg = format!(
"make_decoder: Unhandled audio compression {:?}",

View File

@ -0,0 +1,42 @@
use super::{Decoder, SeekableDecoder};
use std::io::{Cursor, Read};
pub struct NellymoserDecoder<R: Read> {
decoder: nellymoser_rs::Decoder<R>,
}
impl<R: Read> NellymoserDecoder<R> {
pub fn new(reader: R, sample_rate: u32) -> Self {
Self {
decoder: nellymoser_rs::Decoder::new(reader, sample_rate),
}
}
}
impl<R: Read> Iterator for NellymoserDecoder<R> {
type Item = [i16; 2];
fn next(&mut self) -> Option<Self::Item> {
let sample = self.decoder.next()? as i16;
Some([sample, sample])
}
}
impl<R: Read> Decoder for NellymoserDecoder<R> {
#[inline]
fn num_channels(&self) -> u8 {
1
}
#[inline]
fn sample_rate(&self) -> u16 {
self.decoder.sample_rate() as u16
}
}
impl<R: AsRef<[u8]>> SeekableDecoder for NellymoserDecoder<Cursor<R>> {
#[inline]
fn reset(&mut self) {
self.decoder.reset();
}
}

View File

@ -1,7 +1,7 @@
use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
use generational_arena::Arena;
use ruffle_core::backend::audio::decoders::{
self, AdpcmDecoder, Mp3Decoder, PcmDecoder, SeekableDecoder,
self, AdpcmDecoder, Mp3Decoder, NellymoserDecoder, PcmDecoder, SeekableDecoder,
};
use ruffle_core::backend::audio::{
swf, AudioBackend, SoundHandle, SoundInstanceHandle, SoundTransform,
@ -167,6 +167,9 @@ impl CpalAudioBackend {
format.sample_rate.into(),
data,
)),
AudioCompression::Nellymoser => {
Box::new(NellymoserDecoder::new(data, format.sample_rate.into()))
}
_ => {
let msg = format!(
"start_stream: Unhandled audio compression {:?}",

View File

@ -1,7 +1,7 @@
use fnv::FnvHashMap;
use generational_arena::Arena;
use ruffle_core::backend::audio::{
decoders::{AdpcmDecoder, Mp3Decoder},
decoders::{AdpcmDecoder, Mp3Decoder, NellymoserDecoder},
swf::{self, AudioCompression},
AudioBackend, PreloadStreamHandle, SoundHandle, SoundInstanceHandle, SoundTransform,
};
@ -452,6 +452,10 @@ impl WebAudioBackend {
sound.format.sample_rate.into(),
std::io::Cursor::new(audio_data.to_vec()), //&sound.data[..]
)),
AudioCompression::Nellymoser => Box::new(NellymoserDecoder::new(
std::io::Cursor::new(audio_data.to_vec()),
sound.format.sample_rate.into(),
)),
compression => {
return Err(format!("Unimplemented codec: {:?}", compression).into())
}
@ -633,6 +637,14 @@ impl WebAudioBackend {
}
}
}
AudioCompression::Nellymoser => {
let decoder = NellymoserDecoder::new(audio_data, format.sample_rate.into());
for frame in decoder {
let (l, r) = (frame[0], frame[1]);
self.left_samples.push(f32::from(l) / 32767.0);
self.right_samples.push(f32::from(r) / 32767.0);
}
}
compression => return Err(format!("Unimplemented codec: {:?}", compression).into()),
}
@ -873,6 +885,10 @@ impl AudioBackend for WebAudioBackend {
stream.adpcm_block_offsets.push(stream.audio_data.len());
stream.audio_data.extend_from_slice(audio_data);
}
AudioCompression::Nellymoser => {
stream.num_sample_frames += stream.samples_per_block;
stream.audio_data.extend_from_slice(audio_data);
}
_ => {
// TODO: This is a guess and will vary slightly from block to block!
stream.num_sample_frames += stream.samples_per_block;