audio timescale support

This commit is contained in:
Alula 2020-09-04 14:00:09 +02:00
parent 460037ab31
commit d83a7ecb4d
No known key found for this signature in database
GPG Key ID: 3E00485503A1D8BA
2 changed files with 22 additions and 2 deletions

View File

@ -6,11 +6,12 @@ use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
use crate::engine_constants::EngineConstants;
use crate::ggez::{Context, filesystem, GameResult};
use crate::ggez::GameError::AudioError;
use crate::ggez::GameError::{AudioError, InvalidValue};
use crate::sound::organya::Song;
use crate::sound::playback::{PlaybackEngine, SavedPlaybackState};
use crate::sound::wave_bank::SoundBank;
use crate::str;
use cpal::Sample;
pub mod pixtone;
mod wave_bank;
@ -126,11 +127,21 @@ impl SoundManager {
Ok(())
}
pub fn set_speed(&mut self, speed: f32) -> GameResult {
if speed <= 0.0 {
return Err(InvalidValue(str!("Speed must be bigger than 0.0!")));
}
self.tx.send(PlaybackMessage::SetSpeed(speed))?;
Ok(())
}
}
enum PlaybackMessage {
Stop,
PlaySong(Box<Song>),
SetSpeed(f32),
SaveState,
RestoreState,
}
@ -177,6 +188,10 @@ fn run<T>(rx: Receiver<PlaybackMessage>, bank: SoundBank,
Ok(PlaybackMessage::Stop) => {
state = PlaybackState::Stopped;
}
Ok(PlaybackMessage::SetSpeed(speed)) => {
assert!(speed > 0.0);
engine.set_sample_rate((sample_rate / speed) as usize);
}
Ok(PlaybackMessage::SaveState) => {
saved_state = Some(engine.get_state());
}
@ -212,7 +227,7 @@ fn run<T>(rx: Receiver<PlaybackMessage>, bank: SoundBank,
}
};
let value: T = cpal::Sample::from::<u16>(&sample);
let value: T = Sample::from::<u16>(&sample);
for sample in frame.iter_mut() {
*sample = value;
}

View File

@ -103,8 +103,13 @@ impl PlaybackEngine {
}
pub fn set_sample_rate(&mut self, sample_rate: usize) {
self.frames_this_tick = (self.frames_this_tick as f32 * (self.output_format.sample_rate as f32 / sample_rate as f32)) as usize;
self.output_format.sample_rate = sample_rate as u32;
self.frames_per_tick = (sample_rate / 1000) * self.song.time.wait as usize;
if self.frames_this_tick >= self.frames_per_tick {
self.frames_this_tick = 0;
}
}
pub fn get_state(&self) -> SavedPlaybackState {