fix 16 bit sounds

png-branch
an 2019-02-17 22:25:20 -05:00
parent 58cbdd1a57
commit 1a802c47db
4 changed files with 59 additions and 54 deletions

View File

@ -41,6 +41,8 @@ pub trait Sound
fn rate(&self) -> u16;
fn len(&self) -> usize;
fn index(&self, p: usize) -> i16;
fn lp_beg(&self) -> usize;
fn lp_end(&self) -> usize;
fn is_empty(&self) -> bool
{
@ -57,27 +59,18 @@ pub trait Sound
}
}
impl Sound8
{
/// Creates a new Sound8.
pub fn new(rate: u16, len: usize) -> Self
{
Self{rate, data: Vec::with_capacity(len)}
}
}
impl Sound16
{
/// Creates a new Sound16.
pub fn new(rate: u16, len: usize) -> Self
pub fn new(rate: u16, lp_beg: usize, lp_end: usize, len: usize) -> Self
{
Self{rate, data: Vec::with_capacity(len)}
Self{rate, lp_beg, lp_end, data: Vec::with_capacity(len)}
}
/// Creates a new Sound16 from an unsigned 8-bit stream.
pub fn new_from_8(rate: u16, b: &[u8]) -> Self
pub fn new_from_8(rate: u16, lp_beg: usize, lp_end: usize, b: &[u8]) -> Self
{
let mut snd = Sound16::new(rate, b.len());
let mut snd = Sound16::new(rate, lp_beg, lp_end, b.len());
for &sample in b {
snd.data.push(Sound16::sample_from_8(sample));
@ -87,12 +80,12 @@ impl Sound16
}
/// Creates a new Sound16 from a signed 16-bit stream.
pub fn new_from_16(rate: u16, b: &[u8]) -> Self
pub fn new_from_16(rate: u16, lp_beg: usize, lp_end: usize, b: &[u8]) -> Self
{
let mut snd = Sound16::new(rate, b.len() / 2);
let mut snd = Sound16::new(rate, lp_beg, lp_end, b.len() / 2);
for (&x, &y) in b.iter().step_by(2).zip(b.iter().step_by(2).next()) {
snd.data.push(i16::from_be_bytes([x, y]));
for i in (0..b.len()).step_by(2) {
snd.data.push(i16::from_le_bytes([b[i], b[i + 1]]));
}
snd
@ -101,18 +94,7 @@ impl Sound16
/// Creates a signed 16-bit sample from an unsigned 8-bit sample.
pub fn sample_from_8(sample: u8) -> i16
{
i16::from(sample) - 0x80 << 8
}
}
impl Sound for Sound8
{
fn rate(&self) -> u16 {self.rate}
fn len(&self) -> usize {self.data.len()}
fn index(&self, p: usize) -> i16
{
Sound16::sample_from_8(self.data[p])
(i16::from(sample) - 0x80) << 8
}
}
@ -121,17 +103,15 @@ impl Sound for Sound16
fn rate(&self) -> u16 {self.rate}
fn len(&self) -> usize {self.data.len()}
fn index(&self, p: usize) -> i16 {self.data[p]}
}
pub struct Sound8
{
rate: u16,
pub data: Vec<u8>,
fn lp_beg(&self) -> usize {self.lp_beg}
fn lp_end(&self) -> usize {self.lp_end}
}
pub struct Sound16
{
rate: u16,
lp_beg: usize,
lp_end: usize,
pub data: Vec<i16>,
}

View File

@ -392,8 +392,8 @@ pub type CollectionDef = (Option<Collection>, Option<Collection>);
bitflags! {
struct BmpFlags: u16
{
const Transparent = 0x40_00;
const ColumnMajor = 0x80_00;
const Transparent = 1 << 14;
const ColumnMajor = 1 << 15;
}
}
@ -401,9 +401,9 @@ bitflags! {
#[derive(Serialize)]
pub struct FrameFlags: u16
{
const Obscure = 0x20_00;
const FlipY = 0x40_00;
const FlipX = 0x80_00;
const Obscure = 1 << 13;
const FlipY = 1 << 14;
const FlipX = 1 << 15;
}
}

View File

@ -1,25 +1,34 @@
//! Marathon Sounds format handling.
use crate::durandal::{bin::*, err::*, fixed::*, sound::*};
//use bitflags::bitflags;
use bitflags::bitflags;
use serde::Serialize;
use std::collections::HashMap;
fn sound(b: &[u8]) -> ResultS<Sound16>
{
let len = c_u32b(b, 4)? as usize;
let rate = c_u16b(b, 8)?;
let loop_beg = c_u32b(b, 12)?;
let loop_end = c_u32b(b, 16)?;
let magic = c_byte(b, 20)?;
let len = c_u32b(b, 4)? as usize;
let rate = c_u16b(b, 8)?;
let lp_beg = c_u32b(b, 12)? as usize;
let lp_end = c_u32b(b, 16)? as usize;
let magic = c_byte(b, 20)?;
match magic {
0 => Ok(Sound16::new_from_8(rate, c_data(b, 22..22 + len)?)),
0 => {
let stream = c_data(b, 22..22 + len)?;
Ok(Sound16::new_from_8(rate, lp_beg, lp_end, stream))
}
0xFF => {
let stream = c_data(b, 63..63 + len)?;
match c_u16b(b, 47)? {
16 => Ok(Sound16::new_from_16(rate, stream)),
_ => Ok(Sound16::new_from_8(rate, stream)),
let len = c_u32b(b, 22)? as usize;
match c_u16b(b, 48)? {
16 => {
let stream = c_data(b, 63..63 + len * 2)?;
Ok(Sound16::new_from_16(rate, lp_beg, lp_end, stream))
}
_ => {
let stream = c_data(b, 63..63 + len)?;
Ok(Sound16::new_from_8(rate, lp_beg, lp_end, stream))
}
}
}
_ => bail!("invalid magic number"),
@ -37,6 +46,7 @@ fn sound_def(b: &[u8]) -> ResultS<Option<(Vec<usize>, u16, SoundDef)>>
let n_sounds = c_u16b(b, 16)? as usize;
let grp_ofs = c_u32b(b, 20)? as usize;
let volume = Volume::from_repr(volume)?;
let flags = ok!(SoundFlags::from_bits(flags), "bad SoundFlags")?;
let pitch_lo = Fixed::from_bits(pitch_lo);
let pitch_hi = Fixed::from_bits(pitch_hi);
@ -56,7 +66,7 @@ fn sound_def(b: &[u8]) -> ResultS<Option<(Vec<usize>, u16, SoundDef)>>
p += 4;
}
Ok(Some((ofs, index, SoundDef{volume, chance, pitch_lo, pitch_hi,
Ok(Some((ofs, index, SoundDef{volume, flags, chance, pitch_lo, pitch_hi,
sounds: Vec::with_capacity(n_sounds)})))
}
@ -98,6 +108,7 @@ pub fn read_sounds(b: &[u8]) -> ResultS<Vec<SoundTable>>
pub struct SoundDef
{
pub volume: Volume,
pub flags: SoundFlags,
pub chance: u16,
pub pitch_lo: Fixed,
pub pitch_hi: Fixed,
@ -106,6 +117,20 @@ pub struct SoundDef
type SoundTable = HashMap<u16, SoundDef>;
bitflags! {
#[derive(Serialize)]
pub struct SoundFlags: u16
{
const NoRestart = 1;
const NoChannelSwitch = 1 << 1;
const LessPitchChange = 1 << 2;
const NoPitchChange = 1 << 3;
const NoObstruction = 1 << 4;
const NoMediaObstruct = 1 << 5;
const Ambient = 1 << 6;
}
}
c_enum! {
#[derive(Debug, Serialize)]
pub enum Volume: u16

View File

@ -109,8 +109,8 @@ bitflags! {
#[derive(Serialize)]
pub struct GroupFlags: u16
{
const DrawOnRight = 0x00_01;
const DrawCenter = 0x00_02;
const DrawOnRight = 1;
const DrawCenter = 1 << 1;
}
}