Question about creating wavetables and file size

William Echard's icon

Hi Everyone -- I'm trying to create some wavetables for my Disting, and have a question. What I need is a way to make sure that a one-channel buffer~ contains a single cycle of a waveform, and is an exact number of samples long (right now the plan is 600 samples). I do know how make a buffer~ of the right size, but it seems daunting to try and record arbitrary audio directly into a set-size buffer in a way that would capture just one cycle and would also start and end with zero crossings. So I'm thinking I'll need to use a tool like Audacity to trim samples down to a single cycle, and then somehow resample them so that the total length is exactly 600 samples. The resampling tools in Audacity don't seem geared to that, but is there a way to achieve it in Max using buffer~ or something else? Thanks for any help...

William Echard's icon
William Echard's icon

Ah Ha -- less urgent now because I just learned that Audacity does let you change the display mode to number of samples, and that can be dialed in using the Change Speed algorithm. I'd still be interested to know if something similar is possible within Max though, thanks...

Roman Thilenius's icon

it is possible somehow but it shall be easier to do that in your favorite DAW (cubase?), editor or converter (adobe media converter? barbabatch?).

however, i believe that you might prefer to use much longer samples. for some kinds of waveforms it is essential that they do not contain anything over the freqeuncy of half the sample rate.

imagine a 8 octaves keyboard and that you still want to have 44,100 Hz quality at the lowest key.

so 600 samples is not very long... however, for only 600 samples i would prefer cycle~ over buffer~ ... oh and have a look into wave~ ...

Roman Thilenius's icon

...and of course one could generate waveforms right in max, with exactly the rate required for your synth... there is no losless resampling algo!

William Echard's icon

Hi Roman -- Thanks for the reply. Yes, 600 samples is pretty short but it seems to be a common choice for Eurorack wavetable oscillators. It's OK for what I'm doing right now (just simple waves made by adding two sines in a harmonic ratio ), but I'll try bigger buffers later as the spectrums get more complex. I think the Disting is happy with pretty much any sample count for the single cycle, as long as it's the same for all waves in the table.

Experimenting more today, I found that it worked well to set up a recording buffer of about 800 samples, and also a scope object showing the same number of samples (8 samples per display buffer, 100 buffers on the display), with a fine tune on the delay attribute to keep it steady. Then I plug whatever synthesis algorithm I'm using into both the scope and the record object, tune the frequency to get one cycle into about 2/3 of the buffer size, and hit record when the single cycle is centered in the scope. Then I've been using Audacity to trim the edges and adjust to exactly 600 samples.

But regarding your last point, that's the sort of thing I'm wondering about. It's easy to generate waves at the right sample rate and bit depth in Max, and to make a buffer of exactly the right size for recording into. But it doesn't seem that there's any easy way to write exactly one cycle of a wave directly into a fixed-size buffer, which is why I've ended up with the record-then-trim method described above. If there's a more elegant solution, though, I'd be grateful for tips...

Roman Thilenius's icon

you only have to convert 600 and 601 samples to milliseconds and then enter a lenght value to the buffer object which is closer to 600 ... i think. otoh in case you are driving that using a phasor or so, why not set it up a bit longer.

Corbin Ross's icon

It shall be easier to do that in your favorite DAW

William Echard's icon

Thanks again -- I guess the takeaway is that Max is very strong on generating the source material, and for recording snippets that contain close to a single cycle, but that the final trimming and sizing is better done in a different editor like Audacity. In terms of selecting a buffer size, the target device (Disting) can only load 29000 mono sample frames at a 16-bit depth. So there's a strong incentive to keep the waves as small as possible without losing too much quality. I'm just about done with the 600-sample versions for my first set of tables, and that seems to be going OK, but maybe as an experiment I'll also do a version with buffers of 1024 (since there are 24 waves in this particular table).

Roman Thilenius's icon

oh yeah, if your aim is a disting or a waldorf wave you have to trust their internal interpolation methods anyway. :)

and as long as you are using harmonics waveforms not longer than the sample size you dont have to care about upsampling.

for easy generation maybe look into the percolate externals. (gen9.maxhelp)

Roman Thilenius's icon

coming back to this (i was just searching for "wavetable") i´d like to add that the "recording" situation you describe is indeed very difficult in max.

my first attempt 15 years ago was to put the bang which controls the generation of the wave in overdrive using [del 0] and let that start the record object - only to find out that for some reason the record object always starts writing stuff at the wrong position (too late)

and when the generation of the wavetable happened by playing an original from an existing buffer, i ended up with a wave which always starts with silence of one vector length.

later with max 6 - the record object now takes signals for start and stop - it still doesnt work as expected.

to sum it up, your best bet for recording buffers from a running function - or to copy between two buffers - is (still) to use [count~]

count~ can read from a buffer using index ~ , write to a buffer using poke~, and when you want to create a sinewave of 1Hz at time domain, you´d just do

counter~
/~ 600.
cos~ (or cycle~ )

and everything is perfectly in sync.