Comments (7)
Thanks for bringing up the issue! That makes a lot of sense. It would be great if you could port it to Rust. Perhaps as an independent crate? I can then just rely on the crate.
from glicol.
I know exactly enough Rust to have made it this far: https://github.com/paulbatchelor/boing
My intention is to eventually populate it with a few more DSP goodies. Right now, it's just a bandlimited sawtooth oscillator as a proof-of-concept.
The example I have included with the library produces a bandlimited sawtooth oscillator and writes it to disk as raw PCM audio, which can be converted to WAV using SoX. I'm pretty sure it works:
https://github.com/PaulBatchelor/Boing/blob/main/examples/blsaw.rs
What steps do I take to make this working in Glicol?
I'm still very new to Rust, so if you have any suggestions, let me know!
from glicol.
I know exactly enough Rust to have made it this far: https://github.com/paulbatchelor/boing
My intention is to eventually populate it with a few more DSP goodies. Right now, it's just a bandlimited sawtooth oscillator as a proof-of-concept.
The example I have included with the library produces a bandlimited sawtooth oscillator and writes it to disk as raw PCM audio, which can be converted to WAV using SoX. I'm pretty sure it works:
https://github.com/PaulBatchelor/Boing/blob/main/examples/blsaw.rs
What steps do I take to make this working in Glicol?
I'm still very new to Rust, so if you have any suggestions, let me know!
I think describing "the process of how a saw osc" is made can best illustrate the point here.
glicol_parser
For my workflow, I always start with the parser.
Inside rs/parser/src/glicol.pest
, try to search for all the saw
and then add in parallel your fancy new node.
Can test here: https://pest.rs/#editor
Then in rs/parser/src/lib.rs
, you will see code like this:
Rule::saw => one_para_number_or_ref!("saw"),
Also, use the same macro
and add your own node.
Rule::saw => one_para_number_or_ref!("saw"),
Rule::yournode => one_para_number_or_ref!("yournode"),
So for this kind of node, it takes one number or a reference.
Done with the parser.
glicol_synth
In glicol_synth
, you can find the folder rs/synth/node/oscillator/
, and create a yournode.rs
.
You can write in a similar style to saw_osc.rs
. I would recommend some copy paste and then modifying the process
function for the main DSP and send_msg
to handle the update.
Remember to expose yournode.rs
to the mod.rs
there. Then you are good to go.
glicol main crate
Finally, in the main repo, there is this rs/main/src/util.rs
.
Try to find saw
and write yournode
in parallel. Remember to import your Struct at the top (I always forget).
move to wasm
Then you can use the script in wasm to compile the code. Nothing needs to be changed there for adding a new node.
Then cd
to the js
folder. In js/src/glicol.rs
comment out the window.version = "v0.12.12"
line to use local WASM.
Inside js
folder, run pnpm dev
(I use this) or just npm run dev
. You can now use your node in the browser.
Hope I didn't miss anything. Let me know if you encounter any issues.
from glicol.
@chaosprint awesome information. Let me digest this. This seems pretty comprehensive, but if I run into anything, I'll let you know.
from glicol.
@chaosprint awesome information. Let me digest this. This seems pretty comprehensive, but if I run into anything, I'll let you know.
If you'd like to keep it light and focus more on DSP, just look at glicol_synth
crate, playing with the examples
folder there.
And here's an example to combine glicol_synth
and cpal
to get sound on desktop platforms:
https://github.com/chaosprint/cpal/blob/glicol_techno_example/examples/glicol_synth.rs
from glicol.
@chaosprint It took some fiddling, but I got some initial sound working:
main...PaulBatchelor:glicol:main
For troubleshooting, it was helpful for me to write bytes to disk offline, so I whipped up this program that I run as an example in main
:
use glicol::Engine;
use std::fs::File;
use std::io::prelude::*;
fn main() {
let mut engine = Engine::<32>::new();
let mut bytes: [u8; 128] = [0; 128];
let nblks = (44100 * 5) / 32;
let file = File::create("test.bin");
engine.update_with_code(r#"o: blsaw 440 >> mul 0.1"#);
for _ in 0..nblks {
let blk = engine.next_block(vec![]).0;
for n in 0..32 {
let pos = n * 4;
let b = blk[0][n].to_le_bytes();
bytes[pos] = b[0];
bytes[pos + 1] = b[1];
bytes[pos + 2] = b[2];
bytes[pos + 3] = b[3];
}
_ = file.as_ref().unwrap().write_all(&bytes);
}
}
which I can convert to a WAV file with:
sox -t raw -r 44100 -c 1 -e floating-point -b 32 test.bin test.wav
from glicol.
@chaosprint It took some fiddling, but I got some initial sound working:
main...PaulBatchelor:glicol:main
For troubleshooting, it was helpful for me to write bytes to disk offline, so I whipped up this program that I run as an example in
main
:use glicol::Engine; use std::fs::File; use std::io::prelude::*; fn main() { let mut engine = Engine::<32>::new(); let mut bytes: [u8; 128] = [0; 128]; let nblks = (44100 * 5) / 32; let file = File::create("test.bin"); engine.update_with_code(r#"o: blsaw 440 >> mul 0.1"#); for _ in 0..nblks { let blk = engine.next_block(vec![]).0; for n in 0..32 { let pos = n * 4; let b = blk[0][n].to_le_bytes(); bytes[pos] = b[0]; bytes[pos + 1] = b[1]; bytes[pos + 2] = b[2]; bytes[pos + 3] = b[3]; } _ = file.as_ref().unwrap().write_all(&bytes); } }which I can convert to a WAV file with:
sox -t raw -r 44100 -c 1 -e floating-point -b 32 test.bin test.wav
Exciting! The offline workflow is very smart.
I am now rewriting the whole repo. This will be super helpful in the next version.
from glicol.
Related Issues (20)
- Clarification : DSL and grammar detail for web interface HOT 2
- what to expect in v0.13
- TODO: get rid of proc macros and use workspace
- Create `add node` and `add track` messages for synth context during rewriting
- Reverb got some noise...
- Support shared buffer to save memory space
- Use Enums for the AST HOT 4
- Help config Angular for Glicol HOT 1
- Add good real-time pitch shift and time stretch algorithm
- Use only one Rhai engine
- iOS or Android build? HOT 1
- Does glicol syntax resembles any other language? HOT 1
- tree-sitter parser HOT 2
- Feature idea HOT 4
- Panic when use specific code HOT 3
- Stop doesn't work in Glicol.js HOT 2
- API docs HOT 1
- Ideas List 2024
- Panic with this variation HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from glicol.