How to perform sound synthesis?

I am generating a simple musical instrument using a ST board. basically I have a sensor which detects motion or spatial angle and generates sounds of differnt pitch and volume depending on the angle. I already have the driver for the audio codec so all I need to do is to generate sound samples and feed the samples to it. Now I am able to get the angle readings from the sensor but the challenging part is how to generate sound. From google search so far, I think I need to generate a sin function with frequency and amplitude(volume) set according to the reading from the sensor. But my codec assumes a sampling rate 0f 48KHz so how would I go about generating sinusoids with different frequencies for a fixed sampling rate?

So far I have done this:

samplingRate = 48000;
n = 0;//reset once there is a change in frequency

//this function is called 48000 times a second
int generateSineWave(float frequency,float volume)
{
int temp = volume*(sin(2*pi*frequency*n) ;
n = n + 1;
if(n == samplingRate )
n = 0;
if(abs(temp) > MAXVAL)
return ERROR_CODE;
return temp;
}


This seems to be working (I am hearing something),but I am not sure if it's generating the right frequency sinusoid. also the sound I am hearing is not very pleasant, how would I go about generating complex tones(like the ones in piano for example)? I guess also my control variables(spatial angles) needs to be low pass filtered. But apart from that any idea on how I could generate more audibly pleasant waves?

I am a newbie in sound synthesis so any suggestion/help would be greatly appreciated.

First of all, there is something wrong in your computation of the sine wave. It should be something like:

volume * sin(2 * pi * frequency * n / SAMPLE_RATE);

At the moment, your code is generating very high frequencies and what you are hearing are their mirror images.

This is the very first thing to fix. Other problems in your code include:

• Resetting the variable n every time the frequency is changed - this creates discontinuities ("clicks") in the waveform.
• Resetting the variable n every time it reaches the sample rate. You are not sure the waveform has completed a series of full cycles because the frequency might not be an integer.
• Directly computing the phase by multiplication rather than by integration of the frequency. This causes problems when frequency is modulated.
• Computing the sin function directly, which is an expensive operation on embedded hardware, that will have to be replaced by a table lookup + interpolation.

Also, make sure that your samples are scaled appropriately with respect to the scale of your DAC (for example, if this is sent to a 12-bit DAC with unsigned codes, volume must be lesser than 2047, and you should add a 2048 offset).

If you get it working, you will have a pure tone - I wouldn't call this tone "unpleasant", but it is static and not reminiscent of any music instrument.

There are many sound synthesis techniques to try, an overview of which wouldn't fit in this post. In short:

• Subtractive synthesis works by generating harmonically rich tones with simple waveforms (sawtooth, square), and then shaping them through filters. It is not really good at producing "realistic" sounds, but it is relatively easy to implement (the trickiest step is bandlimited waveform generation, read about minBLEP), the sounds it produce are expressive, and it is easy to understand how each synthesis parameter relates to each aspect of sound. Used by synthesizers in the 65-85, with a revival since 95 due to the popularity of the sounds they produce in electronic/dance music. A way of "cheating" to get subtractive synthesis sounds more realistic is to use single cycle waveforms of real instruments in place of oscillators, a technique known as wavetable synthesis.
• Additive synthesis directly builds up a complex tone by summing sinusoidal partials at various frequencies/amplitudes. Given the number of partials involved and the complexity of their variations over time, it is a rather unpractical method.
• FM synthesis works by interconnecting simple sine wave oscillators which modulate each other's frequency. It is surprisingly good at imitating natural sounds (esp. brass, metallophones), but it is very difficult to understand how its parameters (frequency ratios and modulation indices) relate to meaningful musical parameters (sound "brightness" for example). Had a golden era in the eighties and faded away.
• Sampling uses recordings of real instruments, and adjusts the playback speed of the recording (aka sample) to emulate the different notes. With this method it is trivial to get something that is immediately recognizable as a piano or guitar or coughing Ferris Bueller - though if you wish to capture all the playing nuances of an instrument you will need an increasingly large number of recordings. Currently the dominant form of sound synthesis in many applications, driven by the lowest cost of data storage.
• Physical modeling attempts to simulate the physical processes happening in musical instruments - using techniques such as finite element models or digital waveguides. This process can be computationally expensive and/or require a complex modeling and data analysis effort. The results can be very expressive in reproducing all playing nuances of an instrument. Currently quite rare, except for some very narrow application (Piano synthesis).

It is really a case of "realism/expressivity/simplicity, pick any two".

I am not sure about your goals - how many instrument sounds should your system provide? do you also want to modulate other parameters of sound besides pitch and volume with the accelerometer data? I am not sure either about your target platform (the ST MCUs go from 24 MHz/32kb flash/no FPU to 168 MHz with FPU and DSP instructions and 1M of onboard flash). Another factor to take into account is polyphony - do you want your system to be able to play several notes at the same time?

I would recommend:

• Sampling if you have at least 128kb of flash and need only one sound/instrument, or if you have very limited CPU.
• Subtractive synthesis if you have less flash and/or need more sounds/instruments ; or if you need to use external sensor data to easily modulate sound parameters besides pitch/volume.
• Thank you so much for the really informative post. I am correcting stuff bit by bit as I am moving along with my project...I guess I have a lot more to learn. I am really looking for some intermediate etween realism/simplicity. Would you provide any link or suggestion on sampling technique? I did some research but did not turn up successful so far. I have a 32 bitMCU with FPU and DSP with 1M flash so I guess that is what I would go with. Thank you once again! – as3rdaccount Nov 20 '12 at 3:01