serialize on debug
This commit is contained in:
parent
0fcf937d51
commit
6a04f7da9a
8 changed files with 115 additions and 39 deletions
28
src/bng.rs
28
src/bng.rs
|
@ -1,16 +1,22 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use amplify::{From, Wrapper};
|
||||||
use derive_new::new;
|
use derive_new::new;
|
||||||
use derived_deref::Deref;
|
use derived_deref::Deref;
|
||||||
use fasteval::Instruction;
|
use fasteval::Instruction;
|
||||||
use instrument::Instrument;
|
pub(super) use instrument::Instrument;
|
||||||
|
pub(super) use score::Atom;
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
mod instrument;
|
mod instrument;
|
||||||
mod score;
|
mod score;
|
||||||
|
|
||||||
#[derive(new, Debug, PartialEq)]
|
#[derive(Debug, PartialEq, Wrapper, From)]
|
||||||
pub struct InstructionWrapper(Instruction);
|
pub struct Expression(Instruction);
|
||||||
|
|
||||||
impl Serialize for InstructionWrapper {
|
#[cfg(debug_assertions)]
|
||||||
|
impl Serialize for Expression {
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where
|
where
|
||||||
S: serde::Serializer,
|
S: serde::Serializer,
|
||||||
|
@ -20,7 +26,15 @@ impl Serialize for InstructionWrapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(new)]
|
||||||
struct BngFile {
|
#[cfg_attr(debug_assertions, derive(Serialize))]
|
||||||
instruments: Vec<Instrument>,
|
pub(super) struct Channel {
|
||||||
|
instr: String,
|
||||||
|
score: Vec<Atom>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(debug_assertions, derive(new, Serialize))]
|
||||||
|
pub(super) struct BngFile {
|
||||||
|
instruments: Vec<HashMap<String, Instrument>>,
|
||||||
|
channels: HashMap<String, Channel>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,16 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use derive_new::new;
|
||||||
use derived_deref::Deref;
|
use derived_deref::Deref;
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use super::InstructionWrapper as Instruction;
|
use super::Expression as Instruction;
|
||||||
|
|
||||||
#[derive(Serialize, Deref)]
|
#[derive(Deref, new)]
|
||||||
pub struct Instrument(Instruction);
|
#[cfg_attr(debug_assertions, derive(Serialize))]
|
||||||
|
pub struct Instrument {
|
||||||
|
#[target]
|
||||||
|
expr: Instruction,
|
||||||
|
vars: Option<HashMap<String, f32>>,
|
||||||
|
}
|
||||||
|
|
|
@ -2,15 +2,17 @@ use std::num::{NonZeroU16, NonZeroU8};
|
||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use bng_macros::{QuickModifierParser, SlopeModifierParser};
|
use bng_macros::{QuickModifierParser, SlopeModifierParser};
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
use serde::Serialize;
|
||||||
use strum::EnumDiscriminants;
|
use strum::EnumDiscriminants;
|
||||||
|
|
||||||
mod lex;
|
mod lex;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
use super::InstructionWrapper as Instruction;
|
use super::Expression as Instruction;
|
||||||
|
|
||||||
#[cfg_attr(debug_assertions, derive(Debug, PartialEq))]
|
#[cfg_attr(debug_assertions, derive(Debug, PartialEq))]
|
||||||
pub(super) enum Atom {
|
pub enum Atom {
|
||||||
Note(u8),
|
Note(u8),
|
||||||
Rest,
|
Rest,
|
||||||
StartHere,
|
StartHere,
|
||||||
|
@ -22,6 +24,16 @@ pub(super) enum Atom {
|
||||||
Comment,
|
Comment,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
impl Serialize for Atom {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: serde::Serializer,
|
||||||
|
{
|
||||||
|
serializer.serialize_str("atom")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg_attr(debug_assertions, derive(Debug, PartialEq))]
|
#[cfg_attr(debug_assertions, derive(Debug, PartialEq))]
|
||||||
pub(super) enum FlatAtom {
|
pub(super) enum FlatAtom {
|
||||||
Note(u8),
|
Note(u8),
|
||||||
|
@ -55,7 +67,7 @@ impl Clone for FlatAtom {
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
#[cfg_attr(debug_assertions, derive(Debug, PartialEq))]
|
#[cfg_attr(debug_assertions, derive(Debug, PartialEq))]
|
||||||
pub(super) enum Modifier {
|
pub enum Modifier {
|
||||||
Volume(u8),
|
Volume(u8),
|
||||||
Octave(u8),
|
Octave(u8),
|
||||||
Length(NonZeroU8),
|
Length(NonZeroU8),
|
||||||
|
@ -70,16 +82,16 @@ impl Default for Modifier {
|
||||||
|
|
||||||
#[derive(QuickModifierParser, Clone)]
|
#[derive(QuickModifierParser, Clone)]
|
||||||
#[cfg_attr(debug_assertions, derive(Debug, PartialEq))]
|
#[cfg_attr(debug_assertions, derive(Debug, PartialEq))]
|
||||||
pub(super) enum QuickModifier {
|
pub enum QuickModifier {
|
||||||
Volume(bool),
|
Volume(bool),
|
||||||
Octave(bool),
|
Octave(bool),
|
||||||
Length(bool),
|
Length(bool),
|
||||||
Pizz(bool),
|
Pizz(bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, SlopeModifierParser)]
|
#[derive(Clone, Copy, SlopeModifierParser, Debug)]
|
||||||
#[cfg_attr(debug_assertions, derive(Debug, PartialEq))]
|
#[cfg_attr(debug_assertions, derive(PartialEq))]
|
||||||
pub(super) enum SlopeModifier {
|
pub enum SlopeModifier {
|
||||||
Note,
|
Note,
|
||||||
Volume,
|
Volume,
|
||||||
Octave,
|
Octave,
|
||||||
|
|
|
@ -16,7 +16,7 @@ use nom::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
super::super::InstructionWrapper as Instruction,
|
super::super::Expression as Instruction,
|
||||||
{Atom, FlatAtom, Modifier, QuickModifier, SlopeModifier},
|
{Atom, FlatAtom, Modifier, QuickModifier, SlopeModifier},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -68,15 +68,16 @@ fn flat_atom_parser(notes: &str) -> impl Parser<&str, FlatAtom, nom::error::Erro
|
||||||
map_res(take_till1(|c| c == ','), |s| {
|
map_res(take_till1(|c| c == ','), |s| {
|
||||||
let parser = fasteval::Parser::new();
|
let parser = fasteval::Parser::new();
|
||||||
let mut slab = fasteval::Slab::new();
|
let mut slab = fasteval::Slab::new();
|
||||||
Result::<Instruction, nom::error::Error<&str>>::Ok(Instruction::new(
|
Result::<Instruction, nom::error::Error<&str>>::Ok(
|
||||||
parser
|
parser
|
||||||
.parse(s, &mut slab.ps)
|
.parse(s, &mut slab.ps)
|
||||||
.map_err(|_| {
|
.map_err(|_| {
|
||||||
nom::error::Error::new(s, nom::error::ErrorKind::Verify)
|
nom::error::Error::new(s, nom::error::ErrorKind::Verify)
|
||||||
})?
|
})?
|
||||||
.from(&slab.ps)
|
.from(&slab.ps)
|
||||||
.compile(&slab.ps, &mut slab.cs),
|
.compile(&slab.ps, &mut slab.cs)
|
||||||
))
|
.into(),
|
||||||
|
)
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -15,7 +15,7 @@ mod flat_atom {
|
||||||
use nom::Parser;
|
use nom::Parser;
|
||||||
|
|
||||||
use super::super::{
|
use super::super::{
|
||||||
super::super::super::InstructionWrapper as Instruction, super::UP, flat_atom_parser, Atom,
|
super::super::super::Expression as Instruction, super::UP, flat_atom_parser, Atom,
|
||||||
FlatAtom, Modifier, QuickModifier, SlopeModifier,
|
FlatAtom, Modifier, QuickModifier, SlopeModifier,
|
||||||
};
|
};
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -136,17 +136,19 @@ mod flat_atom {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Ok((
|
Ok((
|
||||||
SAMPLE_STR,
|
SAMPLE_STR,
|
||||||
FlatAtom::SlopeStarts(SlopeModifier::Note, {
|
FlatAtom::SlopeStarts(
|
||||||
|
SlopeModifier::Note,
|
||||||
|
{
|
||||||
let parser = fasteval::Parser::new();
|
let parser = fasteval::Parser::new();
|
||||||
let mut slab = fasteval::Slab::new();
|
let mut slab = fasteval::Slab::new();
|
||||||
Instruction::new(
|
|
||||||
parser
|
parser
|
||||||
.parse(FASTEVAL_INSTRUCTION, &mut slab.ps)
|
.parse(FASTEVAL_INSTRUCTION, &mut slab.ps)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.from(&slab.ps)
|
.from(&slab.ps)
|
||||||
.compile(&slab.ps, &mut slab.cs),
|
.compile(&slab.ps, &mut slab.cs)
|
||||||
|
}
|
||||||
|
.into()
|
||||||
)
|
)
|
||||||
})
|
|
||||||
)),
|
)),
|
||||||
flat_atom_parser("abcdefg").parse(concatcp!(
|
flat_atom_parser("abcdefg").parse(concatcp!(
|
||||||
Atom::SLOPE.0,
|
Atom::SLOPE.0,
|
||||||
|
|
|
@ -10,13 +10,12 @@ mod inflate {
|
||||||
fn instruction() -> Instruction {
|
fn instruction() -> Instruction {
|
||||||
let parser = fasteval::Parser::new();
|
let parser = fasteval::Parser::new();
|
||||||
let mut slab = fasteval::Slab::new();
|
let mut slab = fasteval::Slab::new();
|
||||||
Instruction::new(
|
|
||||||
parser
|
parser
|
||||||
.parse(FASTEVAL_INSTRUCTION, &mut slab.ps)
|
.parse(FASTEVAL_INSTRUCTION, &mut slab.ps)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.from(&slab.ps)
|
.from(&slab.ps)
|
||||||
.compile(&slab.ps, &mut slab.cs),
|
.compile(&slab.ps, &mut slab.cs)
|
||||||
)
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -21,7 +21,7 @@ pub enum BngCli {
|
||||||
#[cfg_attr(debug_assertions, derive(Debug))]
|
#[cfg_attr(debug_assertions, derive(Debug))]
|
||||||
pub struct PlayOpts {
|
pub struct PlayOpts {
|
||||||
#[arg(value_parser = FileContents::from_str)]
|
#[arg(value_parser = FileContents::from_str)]
|
||||||
input: FileContents,
|
pub(super) input: FileContents,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`BngCli`] "export" command options
|
/// [`BngCli`] "export" command options
|
||||||
|
|
43
src/main.rs
43
src/main.rs
|
@ -1,12 +1,51 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
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::{BngCli as Cli, PlayOpts};
|
||||||
|
use fasteval::Compiler;
|
||||||
|
|
||||||
mod bng;
|
mod bng;
|
||||||
mod cli;
|
mod cli;
|
||||||
|
|
||||||
fn main() {
|
fn main() -> Result<(), serde_yml::Error> {
|
||||||
// println!("{}", option_env!("TEST").unwrap_or("ok"));
|
// println!("{}", option_env!("TEST").unwrap_or("ok"));
|
||||||
let args = cli::BngCli::parse();
|
let args = Cli::parse();
|
||||||
|
println!(
|
||||||
|
"{}",
|
||||||
|
serde_yml::to_string(&BngFile::new(
|
||||||
|
vec![HashMap::from([
|
||||||
|
(
|
||||||
|
"sine".to_string(),
|
||||||
|
Instrument::new(instruction("sin(2*PI*f*t)"), None)
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"square".to_string(),
|
||||||
|
Instrument::new(
|
||||||
|
instruction("v*abs(sin(2*PI*f*t))"),
|
||||||
|
Some(HashMap::from([("v".to_string(), 1f32)]))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
])],
|
||||||
|
HashMap::<String, Channel>::from([(
|
||||||
|
"melody".to_string(),
|
||||||
|
Channel::new("sine".to_string(), vec![])
|
||||||
|
)])
|
||||||
|
))?
|
||||||
|
);
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
println!("{:?}", args);
|
println!("{:?}", args);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn instruction(expr_str: &str) -> Expression {
|
||||||
|
let parser = fasteval::Parser::new();
|
||||||
|
let mut slab = fasteval::Slab::new();
|
||||||
|
parser
|
||||||
|
.parse(expr_str, &mut slab.ps)
|
||||||
|
.unwrap()
|
||||||
|
.from(&slab.ps)
|
||||||
|
.compile(&slab.ps, &mut slab.cs)
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue