old school music tracker audio backend
at main 94 lines 3.1 kB view raw
1use std::{ 2 num::{NonZero, NonZeroU16}, 3 time::Duration, 4}; 5 6use cpal::traits::{DeviceTrait, HostTrait}; 7use torque_tracker_engine::{ 8 file::impulse_format::{header::PatternOrder, sample::VibratoWave}, 9 manager::{AudioManager, OutputConfig, PlaybackSettings, ToWorkerMsg}, 10 project::{ 11 event_command::NoteCommand, 12 note_event::{Note, NoteEvent, VolumeEffect}, 13 pattern::{InPatternPosition, PatternOperation}, 14 song::{Song, SongOperation}, 15 }, 16 sample::{Sample, SampleMetaData}, 17}; 18 19fn main() { 20 let mut manager = AudioManager::new(Song::default()); 21 let mut reader = hound::WavReader::open("test-files/770_Hz_Tone.wav").unwrap(); 22 let spec = reader.spec(); 23 println!("sample specs: {spec:?}"); 24 assert!(spec.channels == 1); 25 let sample_data = reader 26 .samples::<i16>() 27 .map(|result| <f32 as dasp::Sample>::from_sample(result.unwrap())); 28 let sample = Sample::new_mono(sample_data); 29 let meta = SampleMetaData { 30 sample_rate: NonZero::new(spec.sample_rate).unwrap(), 31 base_note: Note::new(64).unwrap(), 32 default_volume: 20, 33 global_volume: 20, 34 default_pan: None, 35 vibrato_speed: 0, 36 vibrato_depth: 0, 37 vibrato_rate: 0, 38 vibrato_waveform: VibratoWave::default(), 39 }; 40 41 let mut song = manager.try_edit_song().unwrap(); 42 song.apply_operation(SongOperation::SetSample(0, meta, sample)) 43 .unwrap(); 44 for i in 0..12 { 45 let command = PatternOperation::SetEvent { 46 position: InPatternPosition { 47 row: i * 2, 48 channel: i as u8, 49 }, 50 event: NoteEvent { 51 note: Note::new(60 + (i as u8) * 2).unwrap(), 52 sample_instr: 0, 53 vol: VolumeEffect::None, 54 command: NoteCommand::None, 55 }, 56 }; 57 song.apply_operation(SongOperation::PatternOperation(0, command)) 58 .unwrap(); 59 } 60 song.apply_operation(SongOperation::SetOrder(0, PatternOrder::Number(0))) 61 .unwrap(); 62 63 song.finish(); 64 65 let host = cpal::default_host(); 66 let default_device = host.default_output_device().unwrap(); 67 let default_config = default_device.default_output_config().unwrap(); 68 println!("default config {:?}", default_config); 69 println!("device: {:?}", default_device.name()); 70 let config = OutputConfig { 71 buffer_size: 1024, 72 channel_count: NonZeroU16::new(2).unwrap(), 73 sample_rate: NonZero::new(default_config.sample_rate().0).unwrap(), 74 }; 75 76 let mut callback = manager.get_callback::<f32>(config); 77 let stream = default_device 78 .build_output_stream( 79 &default_config.config(), 80 move |data, _| callback(data), 81 |e| eprintln!("{e:?}"), 82 None, 83 ) 84 .unwrap(); 85 86 manager 87 .try_msg_worker(ToWorkerMsg::Playback(PlaybackSettings::default())) 88 .unwrap(); 89 90 std::thread::sleep(Duration::from_secs(5)); 91 println!("{:?}", manager.playback_status()); 92 drop(stream); 93 manager.stream_closed(); 94}