Ver código fonte

trimming and bpm

Johann Woelper 4 anos atrás
pai
commit
e46a6026cf
4 arquivos alterados com 321 adições e 44 exclusões
  1. 219 0
      patterns/berlin.pat
  2. 8 8
      sampler.ini
  3. 58 23
      src/base.rs
  4. 36 13
      src/main.rs

+ 219 - 0
patterns/berlin.pat

@@ -0,0 +1,219 @@
+{
+  "name": "berlin",
+  "repeat": 1,
+  "bpm": 120,
+  "xsize": 16,
+  "ysize": 6,
+  "sounds": {
+    "12,1": {
+      "name": "kick_low.wav",
+      "location": "media/cc0/kick_low.wav",
+      "volume": 1.0,
+      "roll": 0,
+      "rollrate": 0,
+      "trim": 0.0,
+      "speed": 1.0,
+      "reverse": false
+    },
+    "11,3": {
+      "name": "hihiat_closed.wav",
+      "location": "media/cc0/hihiat_closed.wav",
+      "volume": 1.0,
+      "roll": 0,
+      "rollrate": 0,
+      "trim": 0.0,
+      "speed": 1.0,
+      "reverse": false
+    },
+    "2,2": {
+      "name": "snare_sharp.wav",
+      "location": "media/cc0/snare_sharp.wav",
+      "volume": 1.0,
+      "roll": 0,
+      "rollrate": 0,
+      "trim": 0.0,
+      "speed": 1.0,
+      "reverse": false
+    },
+    "14,2": {
+      "name": "snare_sharp.wav",
+      "location": "media/cc0/snare_sharp.wav",
+      "volume": 1.0,
+      "roll": 0,
+      "rollrate": 0,
+      "trim": 0.0,
+      "speed": 1.0,
+      "reverse": false
+    },
+    "15,3": {
+      "name": "hihiat_closed.wav",
+      "location": "media/cc0/hihiat_closed.wav",
+      "volume": 1.0,
+      "roll": 0,
+      "rollrate": 0,
+      "trim": 0.0,
+      "speed": 1.0,
+      "reverse": false
+    },
+    "0,1": {
+      "name": "kick_low.wav",
+      "location": "media/cc0/kick_low.wav",
+      "volume": 1.0,
+      "roll": 0,
+      "rollrate": 0,
+      "trim": 0.0,
+      "speed": 1.0,
+      "reverse": false
+    },
+    "14,1": {
+      "name": "kick_low.wav",
+      "location": "media/cc0/kick_low.wav",
+      "volume": 1.0,
+      "roll": 0,
+      "rollrate": 0,
+      "trim": 0.0,
+      "speed": 1.0,
+      "reverse": false
+    },
+    "8,1": {
+      "name": "kick_low.wav",
+      "location": "media/cc0/kick_low.wav",
+      "volume": 1.0,
+      "roll": 0,
+      "rollrate": 0,
+      "trim": 0.0,
+      "speed": 1.0,
+      "reverse": false
+    },
+    "5,3": {
+      "name": "hihiat_closed.wav",
+      "location": "media/cc0/hihiat_closed.wav",
+      "volume": 1.0,
+      "roll": 0,
+      "rollrate": 0,
+      "trim": 0.0,
+      "speed": 1.0,
+      "reverse": false
+    },
+    "7,3": {
+      "name": "hihiat_closed.wav",
+      "location": "media/cc0/hihiat_closed.wav",
+      "volume": 1.0,
+      "roll": 0,
+      "rollrate": 0,
+      "trim": 0.0,
+      "speed": 1.0,
+      "reverse": false
+    },
+    "3,3": {
+      "name": "hihiat_closed.wav",
+      "location": "media/cc0/hihiat_closed.wav",
+      "volume": 1.0,
+      "roll": 0,
+      "rollrate": 0,
+      "trim": 0.0,
+      "speed": 1.0,
+      "reverse": false
+    },
+    "6,2": {
+      "name": "snare_sharp.wav",
+      "location": "media/cc0/snare_sharp.wav",
+      "volume": 1.0,
+      "roll": 0,
+      "rollrate": 0,
+      "trim": 0.0,
+      "speed": 1.0,
+      "reverse": false
+    },
+    "9,3": {
+      "name": "hihiat_closed.wav",
+      "location": "media/cc0/hihiat_closed.wav",
+      "volume": 1.0,
+      "roll": 0,
+      "rollrate": 0,
+      "trim": 0.0,
+      "speed": 1.0,
+      "reverse": false
+    },
+    "1,3": {
+      "name": "hihiat_closed.wav",
+      "location": "media/cc0/hihiat_closed.wav",
+      "volume": 1.0,
+      "roll": 0,
+      "rollrate": 0,
+      "trim": 0.0,
+      "speed": 1.0,
+      "reverse": false
+    },
+    "10,1": {
+      "name": "kick_low.wav",
+      "location": "media/cc0/kick_low.wav",
+      "volume": 1.0,
+      "roll": 0,
+      "rollrate": 0,
+      "trim": 0.0,
+      "speed": 1.0,
+      "reverse": false
+    },
+    "10,2": {
+      "name": "snare_sharp.wav",
+      "location": "media/cc0/snare_sharp.wav",
+      "volume": 1.0,
+      "roll": 0,
+      "rollrate": 0,
+      "trim": 0.0,
+      "speed": 1.0,
+      "reverse": false
+    },
+    "4,1": {
+      "name": "kick_low.wav",
+      "location": "media/cc0/kick_low.wav",
+      "volume": 1.0,
+      "roll": 0,
+      "rollrate": 0,
+      "trim": 0.0,
+      "speed": 1.0,
+      "reverse": false
+    },
+    "13,3": {
+      "name": "hihiat_closed.wav",
+      "location": "media/cc0/hihiat_closed.wav",
+      "volume": 1.0,
+      "roll": 0,
+      "rollrate": 0,
+      "trim": 0.0,
+      "speed": 1.0,
+      "reverse": false
+    },
+    "0,4": {
+      "name": "bass_303.wav",
+      "location": "media/cc0/bass/bass_303.wav",
+      "volume": 1.0,
+      "roll": 0,
+      "rollrate": 0,
+      "trim": 0.0,
+      "speed": 0.960125,
+      "reverse": false
+    },
+    "2,1": {
+      "name": "kick_low.wav",
+      "location": "media/cc0/kick_low.wav",
+      "volume": 1.0,
+      "roll": 0,
+      "rollrate": 0,
+      "trim": 0.0,
+      "speed": 1.0,
+      "reverse": false
+    },
+    "6,1": {
+      "name": "kick_low.wav",
+      "location": "media/cc0/kick_low.wav",
+      "volume": 1.0,
+      "roll": 0,
+      "rollrate": 0,
+      "trim": 0.0,
+      "speed": 1.0,
+      "reverse": false
+    }
+  }
+}

+ 8 - 8
sampler.ini

@@ -9,8 +9,8 @@ Size=300,100
 Collapsed=0
 
 [Window][sources]
-Pos=861,106
-Size=361,711
+Pos=766,-59
+Size=454,1018
 Collapsed=0
 
 [Window][ImGui Demo]
@@ -29,22 +29,22 @@ Size=328,168
 Collapsed=0
 
 [Window][sound]
-Pos=71,153
-Size=354,269
+Pos=164,22
+Size=423,386
 Collapsed=0
 
 [Window][tracks]
-Pos=983,-71
+Pos=175,1015
 Size=300,160
 Collapsed=0
 
 [Window][pattern]
-Pos=38,658
-Size=826,309
+Pos=39,383
+Size=999,547
 Collapsed=0
 
 [Window][patterns]
-Pos=400,140
+Pos=736,93
 Size=414,352
 Collapsed=0
 

+ 58 - 23
src/base.rs

@@ -27,7 +27,7 @@ pub struct Sound {
     pub volume: f32,
     pub roll: i32,
     pub rollrate: i32,
-    pub trim: f32,
+    pub trim: i32,
       pub speed: f32,
     #[serde(default)]
     pub reverse: bool
@@ -58,6 +58,7 @@ impl Sound {
             volume: 1.0,
             speed: 1.0,
             roll: 0,
+            rollrate: 16,
             ..Default::default()
         })
     }
@@ -104,16 +105,35 @@ impl Sound {
     //     Decoder::new(self.cursor()).unwrap()
     // }
 
-    pub fn play(&self, device: &rodio::Device) {
+    pub fn play(&self, device: &rodio::Device, bpm: i32) {
+        //let delay = ((60.0 / self.bpm as f32)*1000.0) as u64;
+        let delay = ((60.0 / bpm as f32)*1000.0) as u64;
+        let rollrate = match self.rollrate {
+            0 => 16,
+            _ => self.rollrate
+        };
 
         if self.roll == 0 {
             match Decoder::new(self.cursor()) {
                 Ok(ok_decoder) => {
     
-                    rodio::play_raw(&device, ok_decoder
-                        .speed(self.speed)
-                        .amplify(self.volume)
-                        .convert_samples());
+
+                    if self.trim > 0 {
+                        rodio::play_raw(&device, ok_decoder
+                            .speed(self.speed)
+                            .amplify(self.volume)
+                            .take_duration(Duration::from_millis(self.trim as u64))
+                            .convert_samples());
+
+                    } else {
+                        rodio::play_raw(&device, ok_decoder
+                            .speed(self.speed)
+                            .amplify(self.volume)
+                            .convert_samples());
+                    }
+
+
+
     
                 }
                 Err(e) => {
@@ -122,7 +142,6 @@ impl Sound {
             }
 
         } else {
-            let delay = 100;
             for _ in 0..self.roll+1 {
     
                 match Decoder::new(self.cursor()) {
@@ -131,7 +150,7 @@ impl Sound {
                         rodio::play_raw(&device, ok_decoder
                             .speed(self.speed)
                             .amplify(self.volume)
-                            .take_duration(Duration::from_millis(delay))
+                            .take_duration(Duration::from_millis(delay / rollrate as u64))
                             .convert_samples());
         
                     }
@@ -139,19 +158,15 @@ impl Sound {
                         dbg!(e);
                     }
                 }
-                thread::sleep(Duration::from_millis(delay));
+            thread::sleep(Duration::from_millis(delay / rollrate as u64 ));
+
 
             }
         }
-
-
-
-
     }
 }
 
 
-
 fn hm_key_to_string(snds: &HashMap<(usize, usize), Sound>)  ->  HashMap<String, Sound> {
     snds.into_iter()
         .map(|(k, v)| (format!("{},{}", k.0, k.1), v.clone()))
@@ -199,7 +214,6 @@ D: serde::de::Deserializer<'de>,
 pub struct Pattern {
     pub name: String,
     pub repeat: i32,
-    pub bpm: i32,
     pub xsize: usize,
     pub ysize: usize,
     #[serde(serialize_with="ser_snds", deserialize_with="de_snds")]
@@ -214,7 +228,6 @@ impl Default for Pattern {
         Pattern {
             name: "Unnamed".to_string(),
             repeat: 0,
-            bpm: 120,
             xsize: 8,
             ysize: 1,
             sounds: HashMap::new(),
@@ -224,21 +237,41 @@ impl Default for Pattern {
 }
 
 impl Pattern {
-    pub fn play(&self, device: &Arc<rodio::Device>) {
+    pub fn play(&self, device: &Arc<rodio::Device>, bpm: i32) {
 
         let pat_clone = self.clone();
 
         let device = device.clone();
-        let delay = ((60.0 / self.bpm as f32)*1000.0) as u64;
+        // let device = device.clone();
+        let delay = ((60.0 / bpm as f32)*1000.0) as u64;
         
         thread::spawn(move || {
             
             // loop for repeats
+
             for _ in 0..pat_clone.repeat + 1 {
                 for x in 0..pat_clone.xsize {
                     for y in 0..pat_clone.ysize {
+                        let device = device.clone();
                         if let Some(s) = pat_clone.sounds.get(&(x, y)) {
-                            s.play(&device);
+                            // s.play(&device);
+                            
+                            let s = s.clone();
+                            thread::spawn(move || {
+
+                                s.play(&device, bpm);
+
+                                // if s.roll == 0 {
+                                //     s.play(&device, bpm);
+                                // } else {
+                                //     // let bpm = self.bpm;
+                                //     s.play_rolled(&device, bpm);
+                                // }
+                            
+
+
+                            });
+
                         }
                     }
                     thread::sleep(Duration::from_millis(delay));
@@ -261,8 +294,8 @@ impl Pattern {
 
     }
 
-    pub fn duration(&self) -> u64 {
-        ((60.0 / self.bpm as f32)*1000.0) as u64 * self.xsize as u64
+    pub fn duration(&self, bpm: i32) -> u64 {
+        ((60.0 / bpm as f32)*1000.0) as u64 * self.xsize as u64
 
     }
 
@@ -379,13 +412,15 @@ impl Pattern {
 
 #[derive(Clone, Debug)]
 pub struct Timeline {
-    pub patterns: Vec<Pattern>
+    pub patterns: Vec<Pattern>,
+    pub bpm: i32
 }
 
 impl Default for Timeline {
     fn default() -> Timeline {
         Timeline {
-            patterns: vec![Pattern::default()]
+            patterns: vec![Pattern::default()],
+            bpm: 120
         }
     }
 }

+ 36 - 13
src/main.rs

@@ -45,7 +45,8 @@ fn main() {
     
     let mut sounds = collect_sounds("media");
     let mut patterns = collect_patterns("patterns");
-    
+    let mut bpm = 120;
+
     let mut timeline = Timeline::default();
     
     let mut pattern_col: usize = 0;
@@ -65,23 +66,26 @@ fn main() {
     style.anti_aliased_fill = false;
     
     const PURPLE: [f32; 4] = [0.07, 0.05, 0.27, 1.00];
+    const YELLOW: [f32; 4] = [0.60, 0.25, 0.0, 1.00];
     system.main_loop(move |_, ui| {
 
         let colors = ui.push_style_colors(&[
             (StyleColor::FrameBg, PURPLE),
+            (StyleColor::FrameBgHovered, YELLOW),
             (StyleColor::Button, PURPLE),
+            (StyleColor::ButtonHovered, YELLOW),
             (StyleColor::TitleBgActive, PURPLE),
             (StyleColor::ResizeGrip, PURPLE),
+            (StyleColor::ResizeGripHovered, YELLOW),
             (StyleColor::CheckMark, PURPLE),
             (StyleColor::Tab, PURPLE),
+            (StyleColor::TabHovered, YELLOW),
         ]);
 
 
         Window::new(im_str!("sources"))
-            // .resizable(false)
             .position([400.0, 140.0], Condition::Appearing)
             .collapsible(false)
-            // .always_auto_resize(true)
             .size([300.0, 300.0], Condition::FirstUseEver)
             .build(ui, || {
 
@@ -101,7 +105,7 @@ fn main() {
                             }
                             ui.same_line(0.0);
                             if ui.small_button(im_str!("play")) {
-                                s.play(&dev);
+                                s.play(&dev, bpm);
                             }
                         });
                     }
@@ -125,7 +129,7 @@ fn main() {
                             }
                             ui.same_line(0.0);
                             if ui.small_button(im_str!("play")) {
-                                p.play(&dev);
+                                p.play(&dev, bpm);
                             }
                         });
                     }
@@ -167,7 +171,6 @@ fn main() {
                     .speed(0.05)
                     .build();
                 
-                ui.drag_int(im_str!("bpm"), &mut active_pattern.bpm).build();
 
                 ui.text(im_str!("loc     "));
                 for x in 0..active_pattern.xsize {
@@ -214,11 +217,12 @@ fn main() {
                         active_pattern.clear_sounds(y);
                     }
 
+
                 }
 
                 ui.text(im_str!("pat {} {}", pattern_col, pattern_row));
                 if ui.small_button(&im_str!("play")) {
-                    active_pattern.play(&dev);
+                    active_pattern.play(&dev, bpm);
                 }
 
         
@@ -238,19 +242,32 @@ fn main() {
                         .build();
 
                     ui.drag_float(im_str!("speed"), &mut s.speed)
-                        .min(0.0)
-                        .max(2.0)
+                        .min(0.01)
+                        .max(10.0)
                         .speed(0.01)
                         .build();    
                         
+                    ui.drag_int(im_str!("trim ms"), &mut s.trim)
+                        .min(0)
+                        .max(4000)
+                        .speed(0.05)
+                        .build();
+
                     ui.drag_int(im_str!("roll"), &mut s.roll)
+                        .min(0)
                         .max(32)
-                        .speed(0.05)
+                        .speed(0.01)
+                        .build();
+
+                    ui.drag_int(im_str!("roll rate"), &mut s.rollrate)
+                        .min(0)
+                        .max(32)
+                        .speed(0.01)
                         .build();
                         
                     if ui.small_button(&im_str!("adjust speed to pattern")) {
                         if let Some(sd) = s.duration() {
-                            let ad = active_pattern.duration();
+                            let ad = active_pattern.duration(bpm);
                             dbg!(&sd.as_millis());
                             let scale = sd.as_millis() as f32 / ad as f32;
                             dbg!(&scale);
@@ -261,7 +278,7 @@ fn main() {
                     }
                     ui.checkbox(im_str!("reverse"), &mut s.reverse);
                 
-                    if ui.small_button(&im_str!("play")) {s.play(&dev)}
+                    if ui.small_button(&im_str!("play")) {s.play(&dev, bpm)}
                 
                 }
 
@@ -274,9 +291,15 @@ fn main() {
             Window::new(im_str!("tracks"))
             .size([300.0, 100.0], Condition::FirstUseEver)
             .build(ui, || {
+
+                ui.drag_int(im_str!("BPM"), &mut bpm)
+                .min(1)
+                .max(1000)
+                .speed(0.01)
+                .build();
                
                 if ui.small_button(&im_str!("add")) {
-                    active_pattern.play(&dev);
+                    active_pattern.play(&dev, bpm);
                 }
             });