1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
// utils.rs // // Copyright (c) 2020 All The Music, LLC // // This work is licensed under the Creative Commons Attribution 4.0 International License. // To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/ or send // a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. #![allow(unused_parens)] use itertools::Itertools; /// Calculate total melodies given number of distinct notes and desired length of melodies /// /// # Arguments /// /// * `num_notes`: number of distinct notes to generate melodies with /// * `melody_length`: length of melodies to generate /// /// # Examples /// /// ```rust /// // Create MIDI note set with 6 notes /// let note_set = "C:4,C:7,D:4,E:4,F:4,G:5".parse::<libatm::MIDINoteSet>().unwrap(); /// // Calculate total number of melodies of length 9 with these 6 notes /// let num_melodies = atm::utils::gen_num_melodies(note_set.len() as u32, 9); /// // 6 ^ 9 is 10,077,696 /// assert_eq!(10077696, num_melodies); /// ``` pub fn gen_num_melodies(num_notes: u32, melody_length: u32) -> u64 { (num_notes as u64).pow(melody_length) } /// Generate melodies of length `length` containing the /// notes in provided note set `notes`. In other words, /// generate the cartesion product of `notes` with itself /// `length` times. /// /// # Arguments: /// /// * `notes`: set of MIDI notes (see: [libatm::MIDINote](../../libatm/midi_note/struct.MIDINote.html)) /// * `length`: length of sequences to generate /// /// # Examples /// /// ```rust /// // Create MIDI note set /// let note_set = "C:4,C:4,D:4,E:4,F:4,G:5".parse::<libatm::MIDINoteVec>().unwrap(); /// // Create iterable over all possible melodies, which in this example would be /// // 6 ^ 8 = 1,679,616 instances of `Vec<&libatm::MIDINote>`. /// let melodies = atm::utils::gen_sequences(¬e_set, 8); /// assert_eq!(1679616usize, melodies.count()) /// ``` pub fn gen_sequences( notes: &libatm::MIDINoteVec, length: u32, ) -> itertools::MultiProduct<std::slice::Iter<libatm::MIDINote>> { (0..(length)) .map(|_| notes.iter()) .multi_cartesian_product() }