📜 ⬆️ ⬇️

Software sound generation

Sound can be represented as an infinite number of waves of different frequencies
and amplitudes. Waves, in turn, can have almost any shape.
The most common and most commonly used ones are: sinusoidal (sine), square (square), sawy (saw), triangular (triangle), and noise (noise). First, let's try to understand the basic parameters of the wave: the period and amplitude.



Frequency (measured in hertz) - the number of periods per second. For example, at a frequency of 44100Hz, the number of periods is 44100. Now, when the basic terms have been studied, we proceed directly to the wave generation algorithm.
')
1) Sine wave

float samplerate; //
float wavefrequency; //
float wavevolume; //

float period=samplerate/wavefrequency/2; //
float pi=3.14; // pi
int n;

for(int a=0;a<samplelenght;a++) //
{
n=wavevolume*sin(a*pi/period); // sine-
buffer[a]=n; //
}


For example, we need to get a 16-kilobyte sinusoidal sound with a frequency of 1000Hz and the quality of the sample should be 44100Hz, then our parameters will have the following values: samplerate = 44100, wavefrequency = 1000, samplelenght = 16384.

The wavevolume parameter requires special explanation. It has long been known that sound quality is proportional to its bit-rate (8-bit, 16-bit, 24-bit, etc.). For 8-bit - a value from 0..255, for 16 - 0 ... 65536, for 24-x - 0 ... 16777216. Which to choose? It depends on what your task is, but less than 16, I would not advise (although there are exceptions - when it is necessary to reduce the volume of the sample instead of quality).

2) Sawtooth wave (saw)

float sr_2m=samplerate/wavefrequency; //
int c=0; //
//

for(int a=0;a<samplelenght;a++) //
{
if(c>=sr_2m) c=0; // ,
buffer[a]=wavevolume*(c/period)-wavevolume; //
c++;
}


3) Triangular

float period=samplerate/wavefrequency/2; //
int c=period*2;
int c2=-1;
float sr_2m=period;
float sr=samplerate/wavefrequency/4;

for(int a=0;a<samplelenght;a++)
{
if(c>sr_2m) c=sr_2m,c2=-1;
if(c<0) c=0,c2=1;
buffer[a]=wavevolume*(c/sr)-wavevolume;
c+=c2;
}



4) Noise (noise)

srand(wavevolume);
s1=mv.samplerate/wor,psc=s1+1,wov>>=7;

if(tabcnt==0)
{
for(ps=0;ps<mv.samplelenght;ps++)
{
if(psc>s1)
{
psc-=s1;
n=256*((rand()%(wov+1))-wov/2);
}
buffer[ps]=n;
psc++;
}
}


Now we will complicate the task - we will add two waves of different frequency and amplitude.

...
char buffer[16384];

float tone1=65,tone2=131;
float samplerate=44100/2; //
int a,b,amp1=128,amp2=64;

for(a=0;a<16384;a++)
{
b=amp1*sin(a*pi/samplerate/tone1)+amp2*sin(a*pi/samplerate/tone2);
if(b>128) b=128;
if(b<-128) b=-128;
buffer[a]=b;
}

...

With this sample you can already write melodies. Basically, this is the basis of wave
synthesis with which you can create any sound.

And finally, a couple of tips:

1) To get a richer sound, add waves with different
Forms: sine + square, triangle + saw, or such a monster: saw + square +
triangle + saw.
2) Percussion (hat) is best obtained by adding noise + sine.

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


All Articles