Skip to content

Commit

Permalink
refactor: more old code removed
Browse files Browse the repository at this point in the history
  • Loading branch information
nenikitov committed Oct 8, 2024
1 parent f5d3164 commit 869c6ef
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 110 deletions.
43 changes: 5 additions & 38 deletions engine/src/asset/sound/dat/mixer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,39 +10,7 @@ use itertools::Itertools;
use super::{
finetune::FineTune, pattern_effect::*, pattern_event::*, t_instrument::*, t_song::TSong,
};
use crate::asset::sound::sample::AudioBuffer;

trait AudioSamplePoint {
type Bytes: IntoIterator<Item = u8>;

fn into_normalized_f32(&self) -> f32;
fn from_normalized_f32(value: f32) -> Self;
fn into_bytes(&self) -> Self::Bytes;
}

impl AudioSamplePoint for i16 {
type Bytes = [u8; 2];

fn into_normalized_f32(&self) -> f32 {
if *self < 0 {
-(*self as f32 / Self::MIN as f32)
} else {
(*self as f32 / Self::MAX as f32)
}
}

fn from_normalized_f32(value: f32) -> Self {
if value < 0. {
-(value * i16::MIN as f32) as i16
} else {
(value * i16::MAX as f32) as i16
}
}

fn into_bytes(&self) -> Self::Bytes {
self.to_le_bytes()
}
}
use crate::asset::sound::sample::{AudioBuffer, AudioSamplePoint};

#[derive(Default, Clone, Debug)]
struct PlayerChannelNote {
Expand Down Expand Up @@ -97,7 +65,7 @@ impl PlayerChannel {
self.direction = PlaybackDirection::Forwards;
}

fn generate_sample<T: AudioSamplePoint>(&mut self, step: f64) -> T {
fn generate_sample(&mut self, step: f64) -> f32 {
let current_sample = if let Some(instrument) = &self.instrument
&& let Some(sample) = &self.sample
&& let Some(note) = self.note.finetune
Expand Down Expand Up @@ -146,7 +114,7 @@ impl PlayerChannel {

let current_sample = if let Some((previous, position)) = &mut self.previous {
let factor = (*position / Self::SAMPLE_BLEND) as f32;
let previous_sample = previous.generate_sample::<T>(step).into_normalized_f32();
let previous_sample = previous.generate_sample(step);

*position += step;
if *position >= Self::SAMPLE_BLEND {
Expand All @@ -158,7 +126,7 @@ impl PlayerChannel {
current_sample
};

T::from_normalized_f32(current_sample)
current_sample

Check warning on line 129 in engine/src/asset/sound/dat/mixer.rs

View workflow job for this annotation

GitHub Actions / clippy

returning the result of a `let` binding from a block

warning: returning the result of a `let` binding from a block --> engine/src/asset/sound/dat/mixer.rs:129:9 | 115 | / let current_sample = if let Some((previous, position)) = &mut self.previous { 116 | | let factor = (*position / Self::SAMPLE_BLEND) as f32; 117 | | let previous_sample = previous.generate_sample(step); ... | 126 | | current_sample 127 | | }; | |__________- unnecessary `let` binding 128 | 129 | current_sample | ^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_and_return = note: `#[warn(clippy::let_and_return)]` on by default help: return the expression directly | 115 ~ 116 | 117 ~ if let Some((previous, position)) = &mut self.previous { 118 + let factor = (*position / Self::SAMPLE_BLEND) as f32; 119 + let previous_sample = previous.generate_sample(step); 120 + 121 + *position += step; 122 + if *position >= Self::SAMPLE_BLEND { 123 + self.previous = None 124 + } 125 + 126 + previous_sample + factor * (current_sample - previous_sample) 127 + } else { 128 + current_sample 129 + } |
}

fn trigger_note(&mut self) {
Expand Down Expand Up @@ -341,8 +309,7 @@ impl<'a> Player<'a> {
let sample = self
.channels
.iter_mut()
.map(|c| c.generate_sample::<S>(step))
.map(|c| c.into_normalized_f32())
.map(|c| c.generate_sample(step))
//.enumerate()
//.filter_map(|(i, s)| (i == 0).then_some(s))
.sum::<f32>();
Expand Down
79 changes: 52 additions & 27 deletions engine/src/asset/sound/sample.rs
Original file line number Diff line number Diff line change
@@ -1,42 +1,63 @@
// TODO(nenikitov): Remove this test code
use std::{fmt::Debug, ops::Index};
use std::{fmt::Debug, mem::size_of, ops::Index};

pub enum AudioSamplePointFormat {
Int,
Float,
}

impl AudioSamplePointFormat {
pub const fn signature(&self) -> u16 {
match self {
AudioSamplePointFormat::Int => 1,
AudioSamplePointFormat::Float => 3,
}
}
}

pub trait AudioSamplePoint: Default + Clone + Copy {
const SIZE_BITS: usize = size_of::<Self>();

pub trait SamplePoint: Default + Clone + Copy {
fn into_normalized_f32(&self) -> f32;

Check warning on line 21 in engine/src/asset/sound/sample.rs

View workflow job for this annotation

GitHub Actions / clippy

methods called `into_*` usually take `self` by value

warning: methods called `into_*` usually take `self` by value --> engine/src/asset/sound/sample.rs:21:28 | 21 | fn into_normalized_f32(&self) -> f32; | ^^^^^ | = help: consider choosing a less ambiguous name = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#wrong_self_convention = note: `#[warn(clippy::wrong_self_convention)]` on by default
fn from_normalized_f32(value: f32) -> Self;

fn wave_format() -> AudioSamplePointFormat;
fn wave_le_bytes(&self) -> [u8; Self::SIZE_BITS];
}

macro_rules! impl_sample_point_for {
($($ty:ty),*) => {
$(impl SamplePoint for $ty {
fn into_normalized_f32(&self) -> f32 {
if *self < 0 {
-(*self as f32 / Self::MIN as f32)
} else {
(*self as f32 / Self::MAX as f32)
}
}

fn from_normalized_f32(value: f32) -> Self {
if value < 0. {
-(value * Self::MIN as f32) as Self
} else {
(value * Self::MAX as f32) as Self
}
}
})*
impl AudioSamplePoint for i16 {
fn into_normalized_f32(&self) -> f32 {
if *self < 0 {
-(*self as f32 / Self::MIN as f32)
} else {
(*self as f32 / Self::MAX as f32)
}
}
}

impl_sample_point_for!(i16);
fn from_normalized_f32(value: f32) -> Self {
if value < 0. {
-(value * Self::MIN as f32) as Self
} else {
(value * Self::MAX as f32) as Self
}
}

fn wave_format() -> AudioSamplePointFormat {
AudioSamplePointFormat::Int
}

fn wave_le_bytes(&self) -> [u8; Self::SIZE_BITS] {
self.to_le_bytes()
}
}

#[derive(Debug, Clone)]
pub struct AudioBuffer<S: SamplePoint> {
pub struct AudioBuffer<S: AudioSamplePoint> {
pub data: Vec<S>,
pub sample_rate: usize,
}

impl<S: SamplePoint> AudioBuffer<S> {
impl<S: AudioSamplePoint> AudioBuffer<S> {
pub fn index_to_seconds(&self, index: usize) -> f64 {
index as f64 / self.sample_rate as f64
}
Expand All @@ -45,12 +66,16 @@ impl<S: SamplePoint> AudioBuffer<S> {
(seconds * self.sample_rate as f64) as usize

Check warning on line 66 in engine/src/asset/sound/sample.rs

View workflow job for this annotation

GitHub Actions / clippy

casting `f64` to `usize` may lose the sign of the value

warning: casting `f64` to `usize` may lose the sign of the value --> engine/src/asset/sound/sample.rs:66:9 | 66 | (seconds * self.sample_rate as f64) as usize | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#cast_sign_loss
}

pub fn len_samples(&self) -> usize {
self.data.len()
}

pub fn len_seconds(&self) -> f64 {
self.index_to_seconds(self.data.len())
self.index_to_seconds(self.len_samples())
}
}

impl<S: SamplePoint> Index<usize> for AudioBuffer<S> {
impl<S: AudioSamplePoint> Index<usize> for AudioBuffer<S> {
type Output = S;

fn index(&self, index: usize) -> &Self::Output {
Expand Down
3 changes: 3 additions & 0 deletions engine/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@
clippy::cast_possible_truncation,
clippy::cast_precision_loss,
clippy::unreadable_literal,
incomplete_features,
)]
#![warn(unused_imports)]
#![feature(
// Discussion about possible future alternatives:
// https://github.com/rust-lang/rust/pull/101179
debug_closure_helpers,
duration_consts_float,
generic_const_exprs,
io_error_more,
let_chains,
maybe_uninit_uninit_array_transpose,
Expand Down
61 changes: 16 additions & 45 deletions engine/src/utils/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use image::{

use crate::asset::{
color_map::Color,
sound::sample::{AudioBuffer, SamplePoint},
sound::sample::{AudioBuffer, AudioSamplePoint},
};

pub trait PngFile {
Expand Down Expand Up @@ -98,14 +98,21 @@ where
}
}

pub trait WaveFile {
fn to_wave(&self) -> Vec<u8>;
pub trait WaveFile<S: AudioSamplePoint> {
fn to_wave(&self) -> Vec<u8>
where
[(); S::SIZE_BITS]:;
}

impl<S: SamplePoint> WaveFile for AudioBuffer<S> {
fn to_wave(&self) -> Vec<u8> {
let bits_per_sample: usize = S::SIZE_BITS;
let bytes_per_sample: usize = bits_per_sample / 8;
impl<S: AudioSamplePoint> WaveFile<S> for AudioBuffer<S> {
fn to_wave(&self) -> Vec<u8>
where
[(); S::SIZE_BITS]:,
{
const CHANNELS: usize = 1;

let bytes_per_sample: usize = S::SIZE_BITS;
let bits_per_sample: usize = bytes_per_sample / 8;

let size = self.len_samples() * CHANNELS * bytes_per_sample;

Expand All @@ -115,7 +122,7 @@ impl<S: SamplePoint> WaveFile for AudioBuffer<S> {
.chain("WAVE".bytes())
.chain("fmt ".bytes())
.chain(u32::to_le_bytes(16))
.chain(u16::to_le_bytes(1))
.chain(u16::to_le_bytes(S::wave_format().signature()))
.chain(u16::to_le_bytes(CHANNELS as u16))
.chain(u32::to_le_bytes(self.sample_rate as u32))
.chain(u32::to_le_bytes(
Expand All @@ -125,43 +132,7 @@ impl<S: SamplePoint> WaveFile for AudioBuffer<S> {
.chain(u16::to_le_bytes(bits_per_sample as u16))
.chain("data".bytes())
.chain(u32::to_le_bytes(size as u32))
.chain(
self.data
.iter()
.flat_map(|s| s.into_iter().flat_map(|s| s.to_integer_le_bytes())),
)
.collect()
}
}

pub trait WaveFileOld {
fn to_wave(&self, sample_rate: usize, channel_count: usize) -> Vec<u8>;
}

impl WaveFileOld for Vec<i16> {
fn to_wave(&self, sample_rate: usize, channel_count: usize) -> Vec<u8> {
const BITS_PER_SAMPLE: usize = 16;
const BYTES_PER_SAMPLE: usize = BITS_PER_SAMPLE / 8;

let size = self.len() * BYTES_PER_SAMPLE;

"RIFF"
.bytes()
.chain(u32::to_be_bytes((36 + size) as u32))
.chain("WAVE".bytes())
.chain("fmt ".bytes())
.chain(u32::to_le_bytes(16))
.chain(u16::to_le_bytes(1))
.chain(u16::to_le_bytes(channel_count as u16))
.chain(u32::to_le_bytes(sample_rate as u32))
.chain(u32::to_le_bytes(
(sample_rate * channel_count * BYTES_PER_SAMPLE) as u32,
))
.chain(u16::to_le_bytes((channel_count * BYTES_PER_SAMPLE) as u16))
.chain(u16::to_le_bytes(BITS_PER_SAMPLE as u16))
.chain("data".bytes())
.chain(u32::to_le_bytes(size as u32))
.chain(self.iter().flat_map(|s| s.to_le_bytes()))
.chain(self.data.iter().flat_map(|s| s.wave_le_bytes()))
.collect()
}
}

0 comments on commit 869c6ef

Please sign in to comment.