How do you go about sampling wavetables?

Sampler and Sampling discussion (techniques, tips and tricks, etc.)
RELATED
PRODUCTS

Post

It took me just a few minutes to reset the phases in the Legacy wavetable, which contains 60 waveforms. Just to give you an idea of how quick it is.
Wavetables for DUNE2/3, Blofeld, IL Harmor, Hive and Serum etc: http://charlesdickens.neocities.org/
£10 for lifetime updates including wavetable editor for Windows.

Music: https://soundcloud.com/markholt

Post

I tried to do what you said, but, it seems like it automatically normalizes the waveform in the process, which, of course, i don't want, as i already normalized the whole wavetable. Also, i'm kind of confused about the display or partials. What is actually happening, when i sweep all partials' phase to zero?

Post

You definitely don't want to set all partials to zero phase.

Every N sample waveform can be represented by N/2 (amplitude, phase) pairs.

The first "0" partial is DC.

If you have a cycle of 1024 samples the highest harmonic is then harmonic #511 at 511 times the frequency.

If you want to look at additive synthesis based upon formulae you should easily find additive synthesizers that let you both specify a formula for amplitude and phase as well as tweak the individual (amp, ph) pair for each partial.

The basic "geometric" waveforms are almost all "phase = 0". 0 is equal to 1 if we're using percentage rather than degrees or radians and you'll very often see a preference for "phase = 1" rather than "phase = 0", but that's all up to personal preference.

Some symbols used:
= is "equivalence"
/ is division
* is multiplication
^ is raising to a power

I'll use functional notation to express other concepts:

skip(N) means the output = 1 except for every N which is = 0.
In other words skip(2) for example would zero all even harmonics.

rotate(N) means for each N, rotate the phase by 1/N.
In other words rotate(4) would give phase = 0, 1/4, 2/4, 3/4, 0, 1/4, ...

Assuming all phases are equal, the basic waveforms are:
sine = 1, 0, first only
Image

impulse = 1, 0, all
Image

ramp = 1/N, 0, 1
Image

square = 1/N, 0, skip(2)
Image

So looking at square and considering the fact we skip even harmonics with skip(2), don't you wonder what might happen if you use skip(3) or skip(...) instead?

staircase3 = 1/N, 0, skip(3)
Image

It turns out "square" is just a staircase waveform with two steps!

staircase4 = 1/N, 0, skip(4)
Image

triangle = 1/N^2, rotate(4), skip(2)
Image

Again... we must wonder what rotate(N) does. skip(N) is boring since we know the relationship between staircase2 and triangle is simply that it's been integrated, so sharp edges are smoothed out. Therefore triangle with skip(3) is staircase3 with straight lines and so forth... almost.

It fact it doesn't work out that way because the phase relationship doesn't line up with rotate(N) anymore. As you work with more complex shapes you'll find things become less intuitive (there are multiplications and higher order between things) and it can help to draw the geometric shape directly then try to create the numbers you get from a fourier transform.

One interesting thing about this though is if you observe the difference in the peak amplitude of the triangle you'll see it's way beyond 1.0 or "0 dB". So by modifying the phase we can get something that sounds exactly like a triangle with a lower peak amplitude.

When we don't bother to rotate the phase for every odd-odd harmonic of the triangle we get this:
parabola = 1/N^2, 0, skip(2)
Image

So that's why mucking with phases is a bad idea. You'll change the peak and overall waveform significantly when you do that. You might have a geometric shape based on straight lines and you'll end up with something like this instead:

Image
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

TBH, i'm close to give up. Total pain in the butt to get the single waves phase aligned correctly. And, even the slightest difference in phase will end in a bad result, when sweeping through the wavetable. Unfortunately, Wavelab also doesn't detect the zero crossings reliably, when the phase of the waveform starts with a negative value, and, when you edit it manually, a few samples can already mess up the morphing.

Guess this "dirty" way of doing it (resampling) is really not very worthwhile.

Post

aciddose wrote: Wed Jan 02, 2019 10:32 pm You definitely don't want to set all partials to zero phase. {et al}
Very interesting, Thank you. 8)
I'm not a musician, but I've designed sounds that others use to make music. http://soundcloud.com/obsidiananvil

Post

aciddose wrote: Tue Jan 01, 2019 5:42 pm I just dump the process memory. You'll likely find the PCM format samples whether in raw format (like .wav?) or floating point or whatever else along with names, loop points, tuning, key maps and so on.

This is slightly advanced reversing but it is "still in diapers" level, so anyone with enough dedication can learn to do it. Try finding a "heap walker" tool that allows you to browse the heap allocations of a process and dump those blocks into files. Also it would help if you write your own "host" as an extremely bare-bones shell application so you have essentially a stand-alone plug-in instance allocated with a minimum number of system libraries mapped which greatly simplifies things.

I'm extremely picky about these things though.

For example years ago we talked about D50 and M1 ROMs... since then I've dumped these successfully and reverse engineered a majority of their code/structures. Recently I've been working on an alpha juno ROM to allow me to make modifications to disable the "all notes off" on last note-off and re-map the pedals. I'm 80% of the way there, the hard part has actually been finding a reliable source for re-writable EPROMs to use while debugging so I may need to create an adapter using a modern SMD eprom to fit in the firmware ROM socket.

https://soundcloud.com/aciddose-1/jim1
https://soundcloud.com/aciddose-1/stringitize

Unfortunately what I've personally found after achieving this? The samples are god awful garbage and it wasn't anywhere near worth the effort.

As far as "alpha juno as a controller"... an interesting pass-time but realistically way more efficient to just use a real controller. The alpha juno board sucks.
I just read this topic while researching information about wavetables. I was trying to do the same for the M1 ROMs by analyzing a memory dump file with Windows debugging tools, but haven't had the time to continue. The D50 wave ROM was really easy: it is a resource built into a DLL as 32bit float raw waves.
A heap walker is definitely something I would try, haven't thought about it :)

Post

The format of the plug-in is horrid, so I would recommend you reverse the M1 ROMs themselves instead. There are numerous software-specific optimizations used in the plug-in and the data does NOT match the original data structures in the M1 hardware ROMs.
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

aciddose wrote: Sat Sep 14, 2019 1:19 am The format of the plug-in is horrid, so I would recommend you reverse the M1 ROMs themselves instead. There are numerous software-specific optimizations used in the plug-in and the data does NOT match the original data structures in the M1 hardware ROMs.
Thank you for the info. Actually, that was my first choice, I just haven’t found the actual ROM files anywhere. I did found the Wavestation’s though. :tu:

Post

aciddose wrote: Sat Sep 14, 2019 1:19 am The format of the plug-in is horrid, so I would recommend you reverse the M1 ROMs themselves instead. There are numerous software-specific optimizations used in the plug-in and the data does NOT match the original data structures in the M1 hardware ROMs.
Hi there,

I actually found the M1 data. Nice!

I'm writing a little Python program to decode the data as they are stored in LSB & MSB format in different masked ICs.

Post

There are a lot of weird pointer tables used. At first I thought since the processor was "roughly intel 286 compatible" it should be possible to disassemble the binary directly and step through the code to figure how to handle the data.

Unfortunately these old NEC chips use a nasty feature of the older processors called segment wrapping. When you compute a pointer you have a segment+offset pair... but the two values aren't entirely distinct, they overlap quite a bit. So since there are multiple overlapping pages and a limited total number of bits (21 was it?) the full address computed might end up wrapping in a difficult to predict way.

https://en.wikipedia.org/wiki/X86_memory_segmentation

This isn't terribly complicated to be honest... but IDA (the disassembler) does NOT support it. So any pointers computed from "by hand" segment/offset won't be handled correctly, and the disassembler won't be able to fully disassemble or identify what type or address of memory is being accessed. So you're forced to manually disassemble or write your own disassembler which is a nightmarish amount of work, either way.

On top of that the M1 code not only uses segment wrapped addresses in the code itself, the data structures contain similarly wrapped pointer data to other sub-structures in a complicated hierarchy of structures.

I got as far as fully decoding all the samples correctly, but at that point I lost most of my interest and never fully identified all the data structures or members. I mostly reversed the binary but IDA actually fights against you if it's allowed to automatically process anything since it doesn't understand page wrapping is limited to N bits on that specific processor (the generic 386 or 286 is used, there is no direct NEC chip support.) Due to that there is no real point to getting the code disassembled, since the advantage is automatic identification of data blocks... and without that you're manually trying to work everything out anyway.

Apparently it is possible to get it to work partially with a full version of IDA but... well, decoding the M1 data isn't worth $10,000 to me. The authors of the official korg software might have access to the original source code instead, which would be way more easy to work with.
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post

Hi there, I haven't thought about it. I tried to use IDA but again didn't have any time to analyze the code better. Since I was able to decode the wave ROM, I'm fine with it.
Another fun thing, I found that the wavetables for the Kord Electribe Wave iOS app were done with not other than Serum. Lol!. If you check the header of the wav files you see it it's signature.
Cheers.

Post

Having the single block of 2 mb for the sample roms isn't very useful... to actually use the samples you need minimally:
  1. Sample start & end
  2. Loop points
  3. Tuning tables (key maps)
I've decoded #1 and #2, but although I'm mostly certain I know where #3 is (pointers to and data arrays) I haven't been able to understand the format of the keymaps or other (tuning?) data. So I can produce all the samples exported as individual .wav files with working loop points, but I can't write keymap files or lists or set the internal tuning in each .wav to exactly middle-c.
Free plug-ins for Windows, MacOS and Linux. Xhip Synthesizer v8.0 and Xhip Effects Bundle v6.7.
The coder's credo: We believe our work is neither clever nor difficult; it is done because we thought it would be easy.
Work less; get more done.

Post Reply

Return to “Samplers, Sampling & Sample Libraries”