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