Email or username:

Password:

Forgot your password?
patchlore

I'm writing a vocal synthesizer in Rust!

Some initial scaffolding:

github.com/paulbatchelor/voxbo

All it has is a very simple WAV writer for mono 44.1khz 16-bit audio. Offline rendering to disk is very helpful for prototyping and debugging.

19 comments
patchlore

Next up: porting a glottal source model. The one I use is based on the LF model with pulsed glottal noise for breathiness.

Original C code here:

git.sr.ht/~pbatch/mnodes/tree/

patchlore

The glottal component of my singing synthesizer has now been ported to Rust [0], which was translated from C. Rust like to use x.exp() instead of exp(x) for math funcs, so that tripped me up a few times.

The sound is pretty unremarkable [1], and will need a filter (tract) component to give it vowels.

0: github.com//PaulBatchelor/voxb

1: github.com/PaulBatchelor/voxbo

patchlore

I have ported my tract filter to rust now [0]. I couldn't resist garnishing my "simple" example a little bit [1] to make it more musical and sing-y.

In addition to the bare minimum tract filter processing the glottal source, I've also added some controls over vibrato, amplitude, and tract shape (for vowel morphing). I tuned the tract shapes by ear using the distinct region model.

0: github.com/PaulBatchelor/voxbo

1: github.com/PaulBatchelor/voxbo

I have ported my tract filter to rust now [0]. I couldn't resist garnishing my "simple" example a little bit [1] to make it more musical and sing-y.

In addition to the bare minimum tract filter processing the glottal source, I've also added some controls over vibrato, amplitude, and tract shape (for vowel morphing). I tuned the tract shapes by ear using the distinct region model.

patchlore

dev logs I made while coding up the implementation: pbat.ch/recurse/tasks/implemen

patchlore

An initial interactive demo inside the browser! Hit begin, then use the sliders to control glottal and tract params:

pbat.ch/recurse/demos/singer_t

MarcatoMarc

@patchlore great start! How does this run in brower? Webasm?

patchlore

There has been a game jam this week, so it's distracted me from some of this vocal synth work.

Velum support comes next, which is what is needed to get nasal sounds.

Devlogs so far: pbat.ch/recurse/tasks/implemen

#rust #dsp #vocalsynth

th4

@patchlore it is absolutely fascinating seeing you implement this.
Do you have any pointers for someone who would like to learn more about the theory? (I reckon it's your domain of specialty, right?)

patchlore

Porting the nasal sounds has been a bit of a bumpy ride.

I have introduced a NaN somewhere. This kills the DSP. Now I need to track down where it has been introduced.

My approach has been to use panic and counters to iteratively bisect and find the earliest instance of a NaN. It's slow and tedious work.

The NaNhunt will resume tomorrow.

crop

@patchlore
Your problem made me search for "better" floats. ... maybe this crate would help in your case: lib.rs/crates/typed_floats

patchlore

@crop nice! this looks very helpful indeed. I will check it out!

patchlore

With some trial and error, I managed to get throat singing working!

#vocalsynthesis #dsp #rust

Adrian Cochrane

@patchlore Sounds beautiful! With lots of promise!

MarcatoMarc

@patchlore Awesome!

patchlore

I made an oopsie and now the particular shapes I sculpted for this demo don't work anymore. Had to sculpt some new ones. They are okay enough though not as loud and pronounced as this one.

patchlore

Anyways, nasal/velum control seems to work I think. It's now a slider on the demo page. I've also turned on 2x oversampling, which will hopefully smooth things out a bit:

pbat.ch/recurse/demos/singer_t

Reilly Spitzfaden (they/them) replied to patchlore

@patchlore this project is super cool! My only experience with DSP/synths is in C++/JUCE, but I've been wanting to learn how to do it in Rust. I'll have to give this project a look

patchlore replied to Reilly Spitzfaden (they/them)

@reillypascal still learning things. the actual DSP programming feels pretty similar to how I do it in C, at least with my current coding style. I'm sure I'll get rustier as I go. Rust is more strict about number types (float vs int), and has some funny notation for math functions (x.sin() instead of sin(x)). There is a huge performance difference between debug and release builds.

Go Up