Compare commits
6 Commits
0be0c3c0c9
...
36c047caf7
| Author | SHA1 | Date | |
|---|---|---|---|
| 36c047caf7 | |||
| f4f074b8e7 | |||
| a08246b30f | |||
| eb1a537ce2 | |||
| 31faeb3c1b | |||
| a3bb1cf11b |
64
src/play.rs
64
src/play.rs
@@ -12,29 +12,53 @@ fn from_string(s: String) -> String {
|
|||||||
.read_to_string(&mut content)
|
.read_to_string(&mut content)
|
||||||
.expect(format!("failed to read {}", s).as_ref());
|
.expect(format!("failed to read {}", s).as_ref());
|
||||||
content
|
content
|
||||||
.split("\n")
|
|
||||||
.map(|x| x.split_whitespace().collect::<Vec<_>>().join(" "))
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join("\n")
|
|
||||||
}
|
}
|
||||||
Err(_) => s,
|
Err(_) => s,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse(s: String) -> Vec<String> {
|
fn parse(s: String) -> Vec<String> {
|
||||||
|
let s = s
|
||||||
|
.split("\n")
|
||||||
|
.filter(|x: &&str| !x // doesnt start with #
|
||||||
|
.split_whitespace()
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join("")
|
||||||
|
.starts_with("#")
|
||||||
|
)
|
||||||
|
.map(|x| x
|
||||||
|
.split("#")
|
||||||
|
.take(1) // drop after #
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join("")
|
||||||
|
.split_whitespace()
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(" ")
|
||||||
|
)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join("\n");
|
||||||
let mut channels = vec![];
|
let mut channels = vec![];
|
||||||
let lines = s.split("\n").collect::<Vec<_>>();
|
let lines = s.split("\n").collect::<Vec<_>>();
|
||||||
let mut j = 0;
|
let mut j = 0;
|
||||||
for i in 0..lines.len() {
|
for i in 0..lines.len() {
|
||||||
while channels.len() <= j {
|
|
||||||
channels.push("".to_string());
|
|
||||||
}
|
|
||||||
match lines[i] {
|
match lines[i] {
|
||||||
"" => { j = 0; },
|
"" => {
|
||||||
_ => channels[{ let tmp = j; j += 1; tmp }] += &(" ".to_string() + lines[i]),
|
j = 0;
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
while channels.len() <= j {
|
||||||
|
channels.push("".to_string());
|
||||||
|
}
|
||||||
|
channels[{ let tmp = j; j += 1; tmp }] += &(" ".to_string() + lines[i]);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
channels.iter().map(|x| x.split_whitespace().collect::<Vec<_>>().join(" ")).collect()
|
channels
|
||||||
|
.iter()
|
||||||
|
.map(|x| x.split_whitespace().collect::<Vec<_>>()
|
||||||
|
.join(" ")
|
||||||
|
)
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -57,7 +81,7 @@ mod test {
|
|||||||
fn test_two_channels_one_bar() {
|
fn test_two_channels_one_bar() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
super::new("src/testdata/two_channels_one_bar.txt")[0],
|
super::new("src/testdata/two_channels_one_bar.txt")[0],
|
||||||
"2a 2b 2c".to_string()
|
"2*a 2*b 2*c".to_string()
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
super::new("src/testdata/two_channels_one_bar.txt")[1],
|
super::new("src/testdata/two_channels_one_bar.txt")[1],
|
||||||
@@ -73,7 +97,23 @@ mod test {
|
|||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
super::new("src/testdata/two_channels_two_bars.txt")[1],
|
super::new("src/testdata/two_channels_two_bars.txt")[1],
|
||||||
"2a 2b 2c 2d 2e 2f".to_string()
|
"2*a 2*b 2*c 2*d 2*e 2*f".to_string()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn drop_comment_lines() {
|
||||||
|
assert_eq!(
|
||||||
|
super::new("# hello\n # world\na b c")[0],
|
||||||
|
"a b c".to_string()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn drop_comment_trailer() {
|
||||||
|
assert_eq!(
|
||||||
|
super::new("a b c # hello world")[0],
|
||||||
|
"a b c".to_string()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
11
src/seq.rs
11
src/seq.rs
@@ -117,7 +117,7 @@ impl Seq {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn append_one(&mut self, s: String) {
|
fn append_one(&mut self, s: String) {
|
||||||
let re = regex::Regex::new(r"^(?<count>[0-9]*)(?<tone>.*)$").unwrap();
|
let re = regex::Regex::new(r"^((?<count>[0-9]+)\*)?(?<tone>.*)$").unwrap();
|
||||||
let captures = re.captures(&s).unwrap();
|
let captures = re.captures(&s).unwrap();
|
||||||
|
|
||||||
let n = match captures.name("count") {
|
let n = match captures.name("count") {
|
||||||
@@ -125,7 +125,8 @@ impl Seq {
|
|||||||
_ => 1,
|
_ => 1,
|
||||||
} as usize;
|
} as usize;
|
||||||
|
|
||||||
let tone = tone::new(captures.name("tone").unwrap().as_str());
|
let tone_s = captures.name("tone").unwrap().as_str();
|
||||||
|
let tone = tone::new(tone_s);
|
||||||
self.beats.push((n, tone));
|
self.beats.push((n, tone));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -139,9 +140,9 @@ mod test {
|
|||||||
let mut seq = new();
|
let mut seq = new();
|
||||||
|
|
||||||
seq.append("c c");
|
seq.append("c c");
|
||||||
seq.append("4d");
|
seq.append("4*d");
|
||||||
seq.append("2-");
|
seq.append("2*-");
|
||||||
seq.append("g 2e");
|
seq.append("g 2*e");
|
||||||
|
|
||||||
assert_eq!(seq.beats.len(), 6);
|
assert_eq!(seq.beats.len(), 6);
|
||||||
assert_eq!(seq.len(), 11);
|
assert_eq!(seq.len(), 11);
|
||||||
|
|||||||
9
src/testdata/chord_progressions.txt
vendored
Normal file
9
src/testdata/chord_progressions.txt
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
CM0 CM3 CM4 CM0
|
||||||
|
|
||||||
|
.
|
||||||
|
|
||||||
|
CM1 CM4 CM0
|
||||||
|
|
||||||
|
.
|
||||||
|
|
||||||
|
CM0 CM4 CM5 CM3
|
||||||
12
src/testdata/plus_three_sounds_nice.txt
vendored
Normal file
12
src/testdata/plus_three_sounds_nice.txt
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#CM0 CM3 CM4 CM0
|
||||||
|
#CM1 CM4 CM0
|
||||||
|
#CM0 CM4 CM5 CM3
|
||||||
|
|
||||||
|
# 1 4 6 4 # pop101
|
||||||
|
#GM0 GM3 GM5 GM3
|
||||||
|
|
||||||
|
60
|
||||||
|
63
|
||||||
|
66
|
||||||
|
69
|
||||||
|
72
|
||||||
12
src/testdata/sandbox.txt
vendored
Normal file
12
src/testdata/sandbox.txt
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#CM0 CM3 CM4 CM0
|
||||||
|
#CM1 CM4 CM0
|
||||||
|
#CM0 CM4 CM5 CM3
|
||||||
|
|
||||||
|
# 1 4 6 4 # pop101
|
||||||
|
#GM0 GM3 GM5 GM3
|
||||||
|
|
||||||
|
60
|
||||||
|
63
|
||||||
|
66
|
||||||
|
69
|
||||||
|
72
|
||||||
2
src/testdata/two_channels_one_bar.txt
vendored
2
src/testdata/two_channels_one_bar.txt
vendored
@@ -1,2 +1,2 @@
|
|||||||
2a 2b 2c
|
2*a 2*b 2*c
|
||||||
. a5 . b5 . c5
|
. a5 . b5 . c5
|
||||||
|
|||||||
4
src/testdata/two_channels_two_bars.txt
vendored
4
src/testdata/two_channels_two_bars.txt
vendored
@@ -1,5 +1,5 @@
|
|||||||
a b c
|
a b c
|
||||||
2a 2b 2c
|
2*a 2*b 2*c
|
||||||
|
|
||||||
d e f
|
d e f
|
||||||
2d 2e 2f
|
2*d 2*e 2*f
|
||||||
|
|||||||
31
src/tone.rs
31
src/tone.rs
@@ -84,21 +84,24 @@ impl Tone {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn string(&self) -> String {
|
pub fn string(&self) -> String {
|
||||||
match self.i32() {
|
let v = self.i32();
|
||||||
57|69 => "a",
|
let modifier = if v > 0 && v < 57 { "-" } else if v >= 69 { "+" } else { "" };
|
||||||
58|70 => "a+",
|
modifier.to_string() + match v {
|
||||||
59|71 => "b",
|
45|57|69 => "a",
|
||||||
60|72 => "c",
|
46|58|70 => "a+",
|
||||||
61|73 => "c+",
|
47|59|71 => "b",
|
||||||
62|74 => "d",
|
48|60|72 => "c",
|
||||||
63|75 => "d+",
|
49|61|73 => "c+",
|
||||||
64|76 => "e",
|
50|62|74 => "d",
|
||||||
65|77 => "f",
|
51|63|75 => "d+",
|
||||||
66|78 => "f+",
|
52|64|76 => "e",
|
||||||
67|79 => "g",
|
53|65|77 => "f",
|
||||||
68|80 => "g+",
|
54|66|78 => "f+",
|
||||||
|
55|67|79 => "g",
|
||||||
|
56|68|80 => "g+",
|
||||||
|
0 => " ",
|
||||||
_ => "?",
|
_ => "?",
|
||||||
}.to_string()
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user