Writing a virtual synthesizer

Started by
10 comments, last by zeeli 15 years, 4 months ago
Hi, Recently I've become interested in writing a virtual synthesizer. Nothing fancy, just something basic to produce sound from. Unfortunatly i'm finding it difficult to find information, tutorials or the like online. I've used goggle several times, but since 'programming' is often used to describe setting a synthesizer's parameters I get few useful results. Ive tried other search strings to no avail. Can anyone suggest any good sites, tutorials, demos or information about starting out in coding a synthesizer. Thanks
Advertisement
What do you want -- a very "electronic" synth, or a wavetable (realistic) synth?

If #1, then this is what I'd suggest: As far as I know, synthesizer makers used to just "make stuff up" back in the day, and kept whatever sounded good. Whatever you do, you'll need assorted oscillators (sine, square, saw, white noise, pink noise, whatever else you can think of), filters (IIR, FIR), and effects (e.g. reverb, flanger, chorus, ring modulator) -- and ways to chain all these things together. So maybe I'd suggest that the best thing to do is to program a "virtual collection of effects boxes" in a very OO manner, with a way to have "cables" connecting instances of the various "boxes" in a signal-processing stream graph.

If #2, then I'm not sure what to tell you. But it all comes down to playing back prerecorded sounds at different speeds.

Of course, I suppose that you could include a wavetable synth as yet another "box" in a system as described in #1.

You'll also need to consider how to get control input to your synth. MIDI seems the obvious choice.

[Edited by - Emergent on November 26, 2008 2:38:46 PM]
thanks for the reply.

As to my intentions, the first point is probably my initial objective.
Whilst I'm not new to waveforms and how they can be used in sound synthesis, its how to create the waveform data and then 'play' that sound that i'm stuck on.

Edit: Deleted the nonesense I typed at 4am

Having had a chance to think about this there are two areas that I need to investigate.

Firstly the theory behind waveform synthesis, how to generate the waveform, combinations, apply filters and envelopes etc. Secondly how to interpret and write out this data into a sound format that can be played in a media player . Realtime buffered sound playback can wait and for reasons too boring to go into isn't needed at the moment.

Now I have a good idea how to generate a simple waveform like a sine wave, but was getting stuck on the fact that for say middle C you need a sample with 440 cycles per second (I think). Thats easy if the sound is 1 second long, but wasn't sure how well it would work with different lengths. I think I was getting confused as to how to fit multiples of 440 cycles into arbitrary buffer lengths. of course that should be a problem as long as a cycle takes up 1 sec/440 then its should play the same note?

As to the format of the data i'm at a total loss. I know the data type of sound formats (e.g 44.1hz 16 bit), but not what a 16bit value would represent. I Guess looking up the wav format should tell me, but i'm sure i've done that in the past and strangely not made any progress.



[Edited by - noisecrime on November 26, 2008 5:14:08 AM]
You don't need to fit an integer number of cycles into your buffer! You can do, e.g.,

t = 0;dt = 1/sampleFreq;for i = 1 to BUFFER_LEN{  buffer = sin(2*pi*noteFreq*t);  t += dt;}


(there are faster methods for generating sinusiods than calling 'sin' a billion times, but this certainly works).

For a very quick-and-dirty way to get audio out, dump to a raw binary file and import using Audacity. A step up from this would be to add the RIFF headers, etc needed for a WAV file. Or, alternately, buffered audio isn't actually all that hard; see this tutorial on the WAVOUT interface (you're on Windows, right?).

[Edited by - Emergent on November 26, 2008 2:18:03 PM]
Also consider looking at a library to do the dirty work for you (why reinvent a boring wheel? It's the effects you care about, not the WAV format, right?); for instance, a quick Google turned up a library called libsndfile. (I've never used it, so I can't vouch for it, but it seems to fit the bill).
Thanks for the additional information. Although actually it is the boring re-inventing of the wheel that i'm interested in ;) I want to learn about the subject and for reasons i'm unfortunately unable to get into, explore by writing out the sound file to a sound format such as wav.

Anyway you've given me some useful pointers, although i'm still not sure what the values of the raw data represent as such (or the range I presume its signed) I will use Audacity and see what I can discover.
You might find this interesting:
http://breakpoint.untergrund.net/2005/download.php?dir=2005/after_the_party/seminars/&file=bp05_seminars_-_Tammo_kb_Hinrichs_-_practical_softsynth_design_-_xvid.avi
Thanks, i'll check that out.
Creating your own synth isn't boring work at all. This wheel comes in many sizes and shapes, with most yet-to-be-invented.

Creating your own mixing system, however... that wheel certainly has been beat to death.
I read your thread 40 minutes ago and implemented something very basic in Matlab( great software to do these kind of things in because it is easy to convert algorithms to other languages and plot data).

It uses different infinite Fourier series to construct the waveforms (square,triangle,sawtooth). The sound of the wave is played and plotted.

samplerate = 8000;frequency = 1000;samplelength = 1;maxHarmonics = 25;ao = analogoutput('winsound');addchannel(ao,[1 2]);set(ao, 'SampleRate',samplerate);t = linspace(0,2*pi,samplerate*samplelength);y = 0;option = 0;switch option    case 0 % SINE WAVE        y = sin(samplelength*frequency*t);    case 1 % SQUARE WAVE    for k = 1:maxHarmonics        y = y + sin((2*k-1)*samplelength*frequency*t)/(2*k-1);    end    y = (pi/4)* y;    case 2 % TRIANGLE WAVE    for k = 1:maxHarmonics        y = y + sin((k*pi)/2)*(sin(k*samplelength*frequency*t)/(k*k));    end    y = 8/(pi*pi) * y;    case 3 % SAWTOOTH WAVE    for k = 1:maxHarmonics        y = y + (sin(k*samplelength*frequency*t)/k);    end    y = -(2/pi) * y;endputdata(ao,[y' y']);set(ao,'TriggerType','Immediate');startindex = 1;increment = 80;start(ao);while (ao.SamplesAvailable > 0)    while (ao.SamplesOutput < startindex + increment -1),end    try        x = ao.SamplesOutput;        plot(y(x:x+increment-1));        set(gca, 'YLim', [-1.0 1.0], 'XLim',[1 increment]);        drawnow;        startindex =  startindex+increment;    endenddelete(ao);


This topic is closed to new replies.

Advertisement