old school music tracker audio backend

prepare different effect handlers

luca3s 320a9761 10b34922

+31 -24
+5 -4
tracker-engine/src/file/mod.rs
··· 22 22 /// 23 23 /// R should be buffered in some way and not do a syscall on every read. 24 24 /// If you ever find yourself using multiple different reader and/or handlers please open an issue on Github, i will change this to take &dyn. 25 - pub fn parse_song<R: std::io::Read + std::io::Seek, H: FnMut(LoadDefect)>( 25 + pub fn parse_song<R: std::io::Read + std::io::Seek>( 26 26 reader: &mut R, 27 - defect_handler: &mut H, 28 27 ) -> Result<Song<false>, LoadErr> { 29 - let header = header::ImpulseHeader::parse(reader, defect_handler)?; 28 + //ignore defects 29 + let mut defect_handler = |_| (); 30 + let header = header::ImpulseHeader::parse(reader, &mut defect_handler)?; 30 31 let mut song = Song::default(); 31 32 song.copy_values_from_header(&header); 32 33 ··· 38 39 .flat_map(|(idx, ptr)| ptr.map(|ptr| (idx, ptr))) 39 40 { 40 41 ptr.move_to_self(reader)?; 41 - let pattern = pattern::parse_pattern(reader, defect_handler)?; 42 + let pattern = pattern::parse_pattern(reader, &mut defect_handler)?; 42 43 song.patterns[idx] = pattern; 43 44 } 44 45
+2 -4
tracker-engine/src/live_audio.rs
··· 45 45 } 46 46 47 47 fn send_state(&mut self, info: Option<Info>) { 48 - self.state_sender.write(( 49 - self.playback_state.as_ref().map(|s| s.get_status()), 50 - info, 51 - )); 48 + self.state_sender 49 + .write((self.playback_state.as_ref().map(|s| s.get_status()), info)); 52 50 } 53 51 54 52 #[inline]
+24 -16
tracker-engine/src/manager.rs
··· 80 80 81 81 use super::{OutputConfig, OutputStream, StreamBuilder}; 82 82 83 - 84 83 impl<Stream: cpal::traits::StreamTrait> OutputStream for Stream { 85 84 type BufferInformation = cpal::OutputStreamTimestamp; 86 - 85 + 87 86 type PauseErr = cpal::PauseStreamError; 88 - 87 + 89 88 type PlayErr = cpal::PlayStreamError; 90 - 89 + 91 90 fn pause(&mut self) -> Result<(), Self::PauseErr> { 92 91 <Self as cpal::traits::StreamTrait>::pause(self) 93 92 } 94 - 93 + 95 94 fn play(&mut self) -> Result<(), Self::PlayErr> { 96 95 <Self as cpal::traits::StreamTrait>::play(self) 97 96 } ··· 103 102 type Stream = Device::Stream; 104 103 fn create( 105 104 self, 106 - mut data_callback: impl FnMut(&mut [f32], <<Self as StreamBuilder>::Stream as OutputStream>::BufferInformation) 107 - + Send 105 + mut data_callback: impl FnMut( 106 + &mut [f32], 107 + <<Self as StreamBuilder>::Stream as OutputStream>::BufferInformation, 108 + ) + Send 108 109 + 'static, 109 110 err_callback: impl FnMut(Self::StreamErr) + Send + 'static, 110 111 config: OutputConfig, ··· 134 135 135 136 impl TryFrom<cpal::StreamConfig> for OutputConfig { 136 137 type Error = (); 137 - 138 + 138 139 /// fails if BufferSize isn't explicit or zero output channels are specified. 139 140 fn try_from(value: cpal::StreamConfig) -> Result<Self, Self::Error> { 140 141 match value.buffer_size { ··· 156 157 status: triple_buffer::Output<(Option<PlaybackStatus>, Option<S::BufferInformation>)>, 157 158 } 158 159 159 - impl<S: OutputStream> Debug for ActiveStream<S> 160 - where 161 - S::BufferInformation: Debug 160 + impl<S: OutputStream> Debug for ActiveStream<S> 161 + where 162 + S::BufferInformation: Debug, 162 163 { 163 164 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 164 165 f.debug_struct("ActiveStream") ··· 264 265 } 265 266 266 267 /// last playback status sent by the audio worker 267 - pub fn playback_status(&mut self) -> Option<&(Option<PlaybackStatus>, Option<S::BufferInformation>)> { 268 + pub fn playback_status( 269 + &mut self, 270 + ) -> Option<&(Option<PlaybackStatus>, Option<S::BufferInformation>)> { 268 271 self.stream.as_mut().map(|s| s.status.read()) 269 272 } 270 273 ··· 296 299 &mut self, 297 300 create_stream: Builder, 298 301 config: OutputConfig, 299 - ) -> Result<(), Builder::CreateErr> 302 + ) -> Result<(), Builder::CreateErr> 300 303 where 301 - Builder: StreamBuilder<Stream = S> 304 + Builder: StreamBuilder<Stream = S>, 302 305 { 303 306 const TO_WORKER_CAPACITY: usize = 5; 304 307 ··· 306 309 let to_worker = rtrb::RingBuffer::new(TO_WORKER_CAPACITY); 307 310 let reader = self.song.build_reader().unwrap(); 308 311 309 - let audio_worker = LiveAudio::<S::BufferInformation>::new(reader, to_worker.1, from_worker.0, config); 312 + let audio_worker = 313 + LiveAudio::<S::BufferInformation>::new(reader, to_worker.1, from_worker.0, config); 310 314 311 315 // let stream = device.build_output_stream_raw( 312 316 // &config.into(), ··· 315 319 // |err| println!("{err}"), 316 320 // None, 317 321 // )?; 318 - let stream = create_stream.create(audio_worker.get_typed_callback(), |err| eprintln!("{err:?}"), config)?; 322 + let stream = create_stream.create( 323 + audio_worker.get_typed_callback(), 324 + |err| eprintln!("{err:?}"), 325 + config, 326 + )?; 319 327 let buffer_time = 320 328 Duration::from_millis((config.buffer_size * 1000 / config.buffer_size).into()); 321 329