Building a game sound engine for a mobile app : flexible sampler
Hi, I'm building an audio sound engine for a mobile game using libpd and the rjlib library. I want it to be CPU efficient so as to run on lower end android phones too without glitches
My first assumption is that playing back audio is less costly than using synths : is this a fact or am I wrong from the start ?
The idea is to build a flexible sampler with distinct attack, sustain and release parts. I can then load any synth sound I exported from my DAW and play it almost as if it were the original synth (without all the modulations of course). Kind of like the ableton sampler: I could choose the start, the sustain loop portion, and the release part of the sound. That would allow me to add portamento, amplitude, pitch and filter enveloppes, hold notes forever, instantly change the pitch, with no glitches between parts ... It would have to sound like I was playing the original synth preset from my DAW, inside PD !
However this looks a bit trickier than I thought and seems to require a bit of patching. In the end I'm wondering if it's not going to end up costing more resource from the CPU than using a PD synth ?
So before I start building this thing I'm wondering : is it a good idea, or I am missing something here ? And also, does it not already exist ?
I hope I've managed to be somewhat clear, i'd love to hear your feedback !
Cheers
Simon
[writesf~] problem
@EMR66 "I have only got a real precision, using soundfiler (although this limits me since the table only accepts whole samples as we have already spoken ..)"
This, of course, is not a limitation of soundfiler... It's a limitation of all sampled audio files.
There is no way to create an audio file, in any software, containing a fractional number of samples. Period, end of discussion.
In theory, if the frequency is a rational number, you could find the least common multiple of the wavelength and 1.0 and then have all the required sample values precalculated. But this would disallow irrational wavelengths because the LCM would be infinite. So if the desire is to support every possible real number frequency, without interpolation, it's mathematically impossible because of irrational numbers.
To handle every possible real number frequency requires interpolation. There is no way out of that.
"So, until I get that [writesf ~] record correctly, it is useless for me to use [tabread4 ~] or [tabplay ~] ..."
A fractionally sized wavetable is impossible. Literally, impossible.
Meanwhile, it's very easy to play a wavetable at an arbitrary frequency, with interpolation.
The practical solution here is to create the wavetable with a whole number of samples and interpolate in the wavetable oscillator.
hjh
[writesf~] problem
@EMR66 "But if I want to record an 8Hz wave (5512.5 samples) (125ms), the table will only accept 5512 samples, (124.988..ms) This time difference may seem insignificant, but for my work it is becoming a horror."
It's also, as David said, a wrong conception.
There is no such thing as a fractionally-sized wavetable. Period, full stop. (That's the main reason why you haven't been able to write exactly the duration you want: because it's impossible.)
The only way to use a wavetable to generate a frequency that is not an integer number of samples is to play back the wavetable with interpolation. (EDIT: David's solution (make the wavetable twice as long, and read every other sample) is also valid -- a different way around to the same result. I overstated a bit to say "the only way.")
You'll simply have to make the wavetable with an integer size (plus an extra 3 samples, per tabread4~'s requirement) and play it back at the desired rate, and allow tabread4~ to do its job and interpolate the samples for you.
hjh
Phase modulation FM8 emulation troubles
@RandLaneFly "Dude... all i can say is thank you."
Glad to help. It just happens that I was working on this less than a month ago for a synthesis theory class.
"the fm8 sounds more filled out with high frequencies"
The FM8 plot (bottom left) looks like a lot of aliasing. I'm not sure if that's really "filled out." (And the "FM8 sine tone" plot is definitely not from a pure sine tone. It might be deliberate or it might be just a poor oscillator implementation. One of my former students did some research comparing analog oscillators against digital ones from commercial VSTs. The VSTs are often really awful -- unbelievable amounts of aliasing. Massive is one of the worst offenders. I think this is one of the reasons for the harshness of modern EDM -- adding a lot of noise into the pads is a way to cover the kind of gross sound of the oscillators.)
One thing you might try is to use a wavetable oscillator instead of [cos~]. The wavetable can include a bit extra harmonic content.
hjh
waveforms and filters in standard synths
Honestly never really used regular computer synths much, but started doing some daily eartraining with Syntorial and got to trying to remake some of the synth sounds in PD. Two questions:
How are low-pass filters constructed in a standard computer synth? They have a 0-1 value in Syntorial (and presumably other synths). To reproduce that in PD I'm multiplying 0-1 by 30 (arbitrary value so that the sound stays pretty bright when the lop value is at 1) by the frequency of the pitch being filtered and putting it into a chain of [lop~]...
Syntorial's sawtooth and pulse(square) sound pretty clean, but in PD they have a lot of frequencies below the ground tone that make the sound very noisy. Are these filtered out with [hip~]s?
Also, anyone know any nice PD patches that regulate a standard synth setup? Might be interesting to analyze them.
edit: just noticed the thread two lines below this one, so I'll check that out...
Which version for an absolute noob?
@CrouchingPython Pd has midi output...... and you could connect an external synth and select it from the Pd "Media" "Midi Settings".
But if it is a software synth on your computer then you need to loop-back the output of Pd to the input of the software synth.
In Windows you could use loopMIDI........... http://www.tobias-erichsen.de/software.html
Open it and set up a loop (there could well be one opened straight away by loopMIDI..... then open Pd and connect to it....... and open your software synth and connect to it.........
Widows10 might still have "Microsoft GS Wavetable Synth" still built in, but some say it doesn't work and Google will find you plenty of free and better ones.
The Arturia is a controller...... it outputs midi messages the same as Pd....... and still needs a synth (something to make the sounds when triggered by midi messages).....
David.
prophet 3003 wavetable synth prototype
hi folks, thanks for the kind comments!
sure ill share the patch eventually but right now its an uncommented messy laboratory affair. best thing you can do right now is look at the patch image above which is quite self explanatory.
here is the vs rom in one wav file, scan this in 128 chunks of 128 samples and you have the single wave data.
harmonic aliasing is best described by acreil in the above mentioned blog post because thats where i got the idea from. the rest is trial and error and a lot of listening to integer combinations.
harmonic aliasing is actually my own term for what im trying to do. here is how i would describe it:
-
if you repeat 128 samples with a phasor at 128 hz (or 64/32/16/8/4/2) or any multiple of 128 your phasor restarts exactly at the beginning of the wave data and the aliasing frequencies generated by the steppyness of the data will follow the harmonic overtone series 1,2,3 etc. depending on the multiple.
-
if you introduce another prime divider ie. 3 as in 128 / 3 the phasor will line up with the sample data every 3rd sample and the osc will alias at the 3rd subharmonic frequency which will be somewhat more disharmonic than any overtone.
-
another way to look at it would be the pattern repetitions. at subdivision 5 the phasor starts at 5 different points in the sample data and its easy to imagine that the readout patterns are all slightly different ... but the whole thing cycles after 5 phasor rounds = 5th subharmonic..
-
if you subdivide 128 further with a higher prime ie. 563 you will get 562 different sounding samples until nr. 563 lines up again. get the idea?
this is all very easy to hear once you experiment with prime subdivisions and multiplications. just remember its all based on synching the data flow from the sample with the frequency of the index phasor. this will work with ANY sample data, the vs rom is just cool to use for vintage synth fans.
whats important for proper aliasing is that you use a simple [tabread] into the data without any interpolation like tabread4 or oversampling!
all the other elements in the synth like delay, waveshaper, sequencer follow the same rule as they are just repetition devices like the wavetable oscillator.
if you finally synch everything to the sample rate of your soundcard the voltages that hit your speakers will repeat in exact patterns. thats the idea of this synth: precision number repetition controlled by harmonic/disharmonic integer combinations ... just like the great 80s synths waldorf microwave or prophet vs.
prophet 3003 wavetable synth prototype
hi all ... im developing a funky wavetable synth thats inspired by the sequential circuits prophet 2000 from 1985. it uses the original 12 bit ROM from this synth and and a synthesis menthod called harmonic aliasing.
- all frequencies and repeat rates are related by simple integer relationships
- adaptive just intonation = infinite tuning systems
- 3 oscillators per voice
- wavetables by multiplexing oscs with waveshaped sines
- variable sample rate simulation via resampling with audiorate wavetables (BLITs)
- integrated complex numeric sequencer
- integrated delay for hardware mixer feedback loop with analog eqs
basically it includes everything i think is cool about numeric sequencing and is still really low on dsp because its all based on integers mechanics like early wavetable synths.
this synth can sound really ambient or real raw depending on the complexity of the number relationships and the waveshaping settings. eventually this is going to be a hardware synth with FPGA technology, variable sample rate per oscillator and analog eqs/filter ... just like in the 80s 
project logo:
https://i.imgur.com/F1kqrMt.png
prototype patch:
wave multiplexing:
.
harmonic aliasing is inspired by a patch by acreil: https://forum.pdpatchrepo.info/topic/6759/new-anti-aliasing-and-phase-distortion-abstractions.
early discussion: https://forum.pdpatchrepo.info/topic/11176/adaptive-sample-rate-and-harmonic-aliasing-in-pd
.
mixer delay feedback loop feature:
lots of different sounds with audiorate waveshaping:
.
Implementations of "wavetable" synthesis
@nuromantix Thanks for the info. So we could say that a simple crossfade between two waveforms (like the TG33 and Prophet VS) would be equivalent to a mix between two oscillators. On the other hand, Stepping through a wavetable (aka a bank of pre-computed waveforms) like the PPG would be equivalent to re-doing the transition that was recorded in the wavetable. In your filter example, crossfading between a filter-open and a filter-closed waveforms is not the same as opening or closing the filter, but if a high number of snapshots of the filter sweep have been saved to a wavetable as consecutive, single-cycle waveforms, stepping through the wavetable achieves a much similar result. (In my last example the patch is also crossfading between adjacent waveforms in the wavetable, which might not be necessary).
My idea was to be able to morph between two arbitrary waveforms, but I think that creating a wavetable of the "morph" between wave A and wave B is pretty much the same as crossfading. Nevertheless, a wavetable is useful if the transition from A to B involves some other processing that the crossfade can't reproduce.
Implementations of "wavetable" synthesis
Turns out I didn't really understand what a "wavetable" in those kind of synths is. I can't find a lot of information on this but from what I understood, a "wavetable" is not a collection of unrelated waveforms one after the other (like in my previous patch), but rather the collection of "intermediate" steps from waveform A to waveform B, therefore scanning the wavetable (aka, crossfading between one step and the next) has the effect of morphing between the shape of waveform A and waveform B. The morphing is already in the wavetable.
Here is how I've implemented it in a polyphonic context. You load a wavetable and then scan the various intermediate positions with the crossfade slider.
wavetable.synth.zip
(Requires bsaylor external for the envelope)
In the utilities folder there is a patch where you load waveform A and waveform B (both must be single-cycle waveforms of the exact same length) and it generates a wavetable, which can be saved to a .wav file.

