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.