Data structure for synthesizing audio assemblies

I am writing a simple synthesizer in the assembly as a training project, and I would like to implement some more additional features found on modern synthesizers, namely: an ADSR envelope and pulse-width modulation using a sine wave. At the moment, I mainly create samples manually and click on the audio output, which has a fetch buffer and an interrupt that it creates when the buffer becomes almost empty.

I am stuck on how to generate a β€œcontinuous” waveform. I am currently generating patterns for one wave instance (be it a saw or an impulse) and just loop so that one wave generates a continuous output. As you can imagine, this does not scale well for PWM and ADSR envelope. Therefore, I need to generate a wave on demand, with possible corrections on the fly, for example, modulation of the pulse width or pitch (for example, for legato), but I'm at a dead end on how to effectively represent this in memory, as well as how " pause "waveform formation when the buffer is full, and" resume "when an interrupt occurs.

I'm not looking for a solution as much as pushing in the right direction of thinking :-)

Thanks!

+4
source share
2 answers

It seems that your way of generating a wave is a suitable approach for subtractive synthesis. If you want to adjust the PWM of your waveform, you will have to regenerate the samples (or get a pre-calculated waveform stored in memory).

In most cases, you will also need to rebuild the wavetable if the pitch changes. You can read the wave at a higher speed by calculating the increments of the read pointer relative to the fundamental wave, but for this you will need to interpolate between the values ​​in the wavetable and may introduce smoothing with more complex waves.

In most cases, of course, it is unlikely that the generated wave will be exactly 2 ^ n samples. Therefore, at the beginning of the processing procedure, copy the samples from the previous wave first before copying the current wave to the output buffer.

You do not want the regeneration process to violate your DSP process procedure, so I would build an updated waveform in a separate memory location and copy it when ready.

The ADSR envelope (subtractive path) should be used as the gain after generating the wave, and not affect the wave.

Hope that helps :)

+1
source

On-demand wave generation will work for simple waves, although if you later want to add additional / dsps functions, you still need some kind of buffer.

ADSR for amplitude is quite simple, since you just scale the waveform, for frequency modulation it is a little more complicated, here is an article explaining about this link

You can also check out farbraush github, there must be some nice inspiration for you.

+1
source

Source: https://habr.com/ru/post/1443851/


All Articles