Compare commits
No commits in common. "e40f6f48a18ebdbff30d9c7665ce1d907055c305" and "36b0fe394c468f96c4447a9d64a20b691e926cba" have entirely different histories.
e40f6f48a1
...
36b0fe394c
4 changed files with 22 additions and 155 deletions
18
Cargo.toml
18
Cargo.toml
|
@ -4,26 +4,26 @@ version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
amplify = "4"
|
amplify = "4.7.0"
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
cfg-if = "1.0.0"
|
cfg-if = "1.0.0"
|
||||||
clap = { version = "4.5", features = ["derive"] }
|
clap = { version = "4.5", features = ["derive"] }
|
||||||
derived-deref = "2.1.0"
|
derived-deref = "2.1.0"
|
||||||
fasteval = "0.2.4"
|
fasteval = "0.2.4"
|
||||||
nom = "7.1.3"
|
nom = "7.1.3"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0.209", features = ["derive"] }
|
||||||
serde_yml = "0.0.12"
|
serde_yml = "0.0.12"
|
||||||
splines = "4"
|
splines = "4.3.1"
|
||||||
strum = { version = "0.26", features = ["derive"] }
|
strum = { version = "0.26", features = ["derive"] }
|
||||||
strum_macros = "0.26"
|
strum_macros = "0.26"
|
||||||
tinyaudio = { version = "1", optional = true }
|
tinyaudio = { version = "0.1", optional = true }
|
||||||
bng_macros = { path = "bng_macros" }
|
bng_macros = { path = "bng_macros" }
|
||||||
const_format = "0.2.33"
|
const_format = "0.2.33"
|
||||||
thiserror = "2"
|
thiserror = "1.0.64"
|
||||||
derive-new = "0.7"
|
derive-new = "0.7.0"
|
||||||
naan = "0.1"
|
naan = "0.1.32"
|
||||||
lazy_static = "1.5"
|
lazy_static = "1.5.0"
|
||||||
tune = "0.35"
|
tune = "0.35.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["play", "save"]
|
default = ["play", "save"]
|
||||||
|
|
37
src/cli.rs
37
src/cli.rs
|
@ -1,10 +1,7 @@
|
||||||
use std::{convert::Infallible, fmt::Display, fs::read_to_string, io, str::FromStr};
|
use std::{fmt::Display, fs::read_to_string, io, str::FromStr};
|
||||||
|
|
||||||
use amplify::{From, Wrapper};
|
use amplify::{From, Wrapper};
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use strum::EnumString;
|
|
||||||
|
|
||||||
pub mod doc;
|
|
||||||
|
|
||||||
/// Cli entry point
|
/// Cli entry point
|
||||||
#[derive(Clone, Parser)]
|
#[derive(Clone, Parser)]
|
||||||
|
@ -12,9 +9,9 @@ pub mod doc;
|
||||||
pub enum BngCli {
|
pub enum BngCli {
|
||||||
/// Play the song through default sink
|
/// Play the song through default sink
|
||||||
Play(PlayOpts),
|
Play(PlayOpts),
|
||||||
/// Export the song to a sound file
|
/// Export the song to a sound FileContents
|
||||||
Export(ExportOpts),
|
Export(ExportOpts),
|
||||||
/// List supported sound file extensions and instrument / song available expressions
|
/// List supported sound FileContents extensions and instrument / song available expressions
|
||||||
#[command(subcommand)]
|
#[command(subcommand)]
|
||||||
List(ListOpts),
|
List(ListOpts),
|
||||||
}
|
}
|
||||||
|
@ -31,10 +28,10 @@ pub struct PlayOpts {
|
||||||
#[derive(Clone, Parser)]
|
#[derive(Clone, Parser)]
|
||||||
#[cfg_attr(debug_assertions, derive(Debug))]
|
#[cfg_attr(debug_assertions, derive(Debug))]
|
||||||
pub struct ExportOpts {
|
pub struct ExportOpts {
|
||||||
/// Input file (written song file)
|
/// Input FileContents (written song FileContents)
|
||||||
#[arg(value_parser = FileContents::from_str)]
|
#[arg(value_parser = FileContents::from_str)]
|
||||||
input: FileContents,
|
input: FileContents,
|
||||||
/// Output file (sound file)
|
/// Output FileContents (sound FileContents)
|
||||||
#[arg(value_parser = AudioFileName::from_str)]
|
#[arg(value_parser = AudioFileName::from_str)]
|
||||||
output: AudioFileName,
|
output: AudioFileName,
|
||||||
}
|
}
|
||||||
|
@ -43,29 +40,17 @@ pub struct ExportOpts {
|
||||||
#[derive(Clone, Parser)]
|
#[derive(Clone, Parser)]
|
||||||
#[cfg_attr(debug_assertions, derive(Debug))]
|
#[cfg_attr(debug_assertions, derive(Debug))]
|
||||||
pub enum ListOpts {
|
pub enum ListOpts {
|
||||||
/// List supported sound file extensions to export songs
|
/// List supported sound FileContents extensions to export songs
|
||||||
|
#[command(subcommand)]
|
||||||
Extensions,
|
Extensions,
|
||||||
/// Show the math syntax used for instrument definition and slopes
|
/// List available math expressions for instrument definition
|
||||||
Math {
|
#[command(subcommand)]
|
||||||
/// Kind of syntax you want to list (functions, operators or literals)
|
Math,
|
||||||
#[arg(value_parser = MathDocKind::from_str)]
|
|
||||||
kind: Option<MathDocKind>,
|
|
||||||
},
|
|
||||||
/// List available score glyphs and their meaning
|
/// List available score glyphs and their meaning
|
||||||
|
#[command(subcommand)]
|
||||||
Glyphs,
|
Glyphs,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, EnumString)]
|
|
||||||
#[cfg_attr(debug_assertions, derive(Debug))]
|
|
||||||
pub enum MathDocKind {
|
|
||||||
#[strum(ascii_case_insensitive)]
|
|
||||||
Functions,
|
|
||||||
#[strum(ascii_case_insensitive)]
|
|
||||||
Operators,
|
|
||||||
#[strum(ascii_case_insensitive)]
|
|
||||||
Literals,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Wrapper, From)]
|
#[derive(Clone, Wrapper, From)]
|
||||||
#[wrapper(Deref)]
|
#[wrapper(Deref)]
|
||||||
#[cfg_attr(debug_assertions, derive(Debug))]
|
#[cfg_attr(debug_assertions, derive(Debug))]
|
||||||
|
|
|
@ -1,98 +0,0 @@
|
||||||
pub mod math {
|
|
||||||
pub const FUNCTIONS: &str = r#"* print(...strings and values...) -- Prints to stderr. Very useful to 'probe' an expression.
|
|
||||||
Evaluates to the last value.
|
|
||||||
Example: `print("x is", x, "and y is", y)`
|
|
||||||
Example: `x + print("y:", y) + z == x+y+z`
|
|
||||||
|
|
||||||
* log(base=10, val) -- Logarithm with optional 'base' as first argument.
|
|
||||||
If not provided, 'base' defaults to '10'.
|
|
||||||
Example: `log(100) + log(e(), 100)`
|
|
||||||
|
|
||||||
* e() -- Euler's number (2.718281828459045)
|
|
||||||
* pi() -- π (3.141592653589793)
|
|
||||||
|
|
||||||
* int(val)
|
|
||||||
* ceil(val)
|
|
||||||
* floor(val)
|
|
||||||
* round(modulus=1, val) -- Round with optional 'modulus' as first argument.
|
|
||||||
Example: `round(1.23456) == 1 && round(0.001, 1.23456) == 1.235`
|
|
||||||
|
|
||||||
* abs(val)
|
|
||||||
* sign(val)
|
|
||||||
|
|
||||||
* min(val, ...) -- Example: `min(1, -2, 3, -4) == -4`
|
|
||||||
* max(val, ...) -- Example: `max(1, -2, 3, -4) == 3`
|
|
||||||
|
|
||||||
* sin(radians) * asin(val)
|
|
||||||
* cos(radians) * acos(val)
|
|
||||||
* tan(radians) * atan(val)
|
|
||||||
* sinh(val) * asinh(val)
|
|
||||||
* cosh(val) * acosh(val)
|
|
||||||
* tanh(val) * atanh(val)"#;
|
|
||||||
pub const OPERATORS: &str = r#"Listed in order of precedence:
|
|
||||||
|
|
||||||
(Highest Precedence) ^ Exponentiation
|
|
||||||
% Modulo
|
|
||||||
/ Division
|
|
||||||
* Multiplication
|
|
||||||
- Subtraction
|
|
||||||
+ Addition
|
|
||||||
== != < <= >= > Comparisons (all have equal precedence)
|
|
||||||
&& and Logical AND with short-circuit
|
|
||||||
(Lowest Precedence) || or Logical OR with short-circuit"#;
|
|
||||||
pub const LITERALS: &str = r#"Several numeric formats are supported:
|
|
||||||
|
|
||||||
Integers: 1, 2, 10, 100, 1001
|
|
||||||
|
|
||||||
Decimals: 1.0, 1.23456, 0.000001
|
|
||||||
|
|
||||||
Exponents: 1e3, 1E3, 1e-3, 1E-3, 1.2345e100
|
|
||||||
|
|
||||||
Suffix:
|
|
||||||
1.23p = 0.00000000000123
|
|
||||||
1.23n = 0.00000000123
|
|
||||||
1.23µ, 1.23u = 0.00000123
|
|
||||||
1.23m = 0.00123
|
|
||||||
1.23K, 1.23k = 1230
|
|
||||||
1.23M = 1230000
|
|
||||||
1.23G = 1230000000
|
|
||||||
1.23T = 1230000000000"#;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub mod glyphs {
|
|
||||||
pub const ALL: &str = r#"rest: .
|
|
||||||
pizz.: '°
|
|
||||||
volume: +-
|
|
||||||
length: /\
|
|
||||||
octave: ><
|
|
||||||
comment?: ;,
|
|
||||||
start here: ':'
|
|
||||||
slope: {{MODIFIER EXPR score}}
|
|
||||||
note modifier prefix: n
|
|
||||||
volume modifier prefix: v
|
|
||||||
octave modifier prefix: o
|
|
||||||
length modifier prefix: l
|
|
||||||
tempo modifier prefix: t
|
|
||||||
loop: ()
|
|
||||||
loop with count: (COUNT score)
|
|
||||||
tuple: []
|
|
||||||
modifier: !
|
|
||||||
volume modifier prefix: v
|
|
||||||
octave modifier prefix: o
|
|
||||||
length modifier prefix: l
|
|
||||||
tempo modifier prefix: t
|
|
||||||
|
|
||||||
EXAMPLE
|
|
||||||
aabc.
|
|
||||||
'ab°A
|
|
||||||
+d+d+d---
|
|
||||||
/ff/f\\
|
|
||||||
ab>c<ba
|
|
||||||
;this is a comment (or lyrics whatever),
|
|
||||||
C:CC
|
|
||||||
(3deff)
|
|
||||||
(deff)
|
|
||||||
[ffe]
|
|
||||||
{{l 1-cos((PI*x)/2),acced}}
|
|
||||||
abbc!o5cc!v15feed!l4fedd!t60Gdd"#;
|
|
||||||
}
|
|
24
src/main.rs
24
src/main.rs
|
@ -4,7 +4,7 @@ use anyhow::Error;
|
||||||
use bng::{BngFile, Channel, Expression, Instrument};
|
use bng::{BngFile, Channel, Expression, Instrument};
|
||||||
/// TODO: remove clap, use only a file or standard in
|
/// TODO: remove clap, use only a file or standard in
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use cli::{doc, BngCli as Cli, ListOpts, MathDocKind, PlayOpts};
|
use cli::{BngCli as Cli, PlayOpts};
|
||||||
use fasteval::Compiler;
|
use fasteval::Compiler;
|
||||||
|
|
||||||
mod bng;
|
mod bng;
|
||||||
|
@ -24,27 +24,7 @@ fn main() -> Result<(), Error> {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
println!("{:#?}", bng_file);
|
println!("{:#?}", bng_file);
|
||||||
}
|
}
|
||||||
Cli::List(l) => match l {
|
_ => unimplemented!("can't do that yet"),
|
||||||
ListOpts::Extensions => println!("you can't export songs yet"),
|
|
||||||
ListOpts::Math { kind } => match kind {
|
|
||||||
None => println!(
|
|
||||||
"Functions :\n{}\n\nOperators :\n{}\n\nLiterals :\n{}",
|
|
||||||
doc::math::FUNCTIONS,
|
|
||||||
doc::math::OPERATORS,
|
|
||||||
doc::math::LITERALS
|
|
||||||
),
|
|
||||||
Some(m) => println!(
|
|
||||||
"{}",
|
|
||||||
match m {
|
|
||||||
MathDocKind::Functions => doc::math::FUNCTIONS,
|
|
||||||
MathDocKind::Operators => doc::math::OPERATORS,
|
|
||||||
MathDocKind::Literals => doc::math::LITERALS,
|
|
||||||
}
|
|
||||||
),
|
|
||||||
},
|
|
||||||
ListOpts::Glyphs => println!("{}", doc::glyphs::ALL),
|
|
||||||
},
|
|
||||||
Cli::Export(_) => unimplemented!("can't do that yet"),
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue