Jasne, że tak, ale brzmi to „ładnie”.
Nie wiem, jak to zrobić w systemie Linux, ale jeśli możesz odtworzyć bufor PCM, wszystko, co musisz zrobić, to wypełnić go czymkolwiek chcesz.
Załóżmy więc, że twój bufor jest ustawiony na odtwarzanie monofonicznych, 16-bitowych próbek z prędkością 44100 próbek na sekundę, tworzenie czystego (sinusoidalnego) dźwięku A4 (440 Hz) jest tak proste, jak
int16_t buffer[44100];
float frequency = 440.0f;
float sampling_ratio = 44100.0f;
float amplitude = 0.5f;
float t;
for (int i = 0; i < 44100; i++)
{
float theta = ((float)i / sampling_ratio) * PI;
buffer[i] = (int16_t)(sin(theta * frequency) * 32767.0f * amplitude);
}
Jednak ten dźwięk jest prawdopodobnie bardzo nudny dla twoich zainteresowań, więc musisz robić bardziej skomplikowane rzeczy. Ogólnie istnieją dwa rodzaje syntezy dźwięku: addytywny i subtraktywny . Jest wiele innych, ale te dwa są prawdopodobnie najprostsze. Dzisiaj porozmawiam o syntezie addytywnej.
Aby uzyskać syntezę addytywną, robisz to samo, co przed chwilą, ale zamiast używać tylko jednej częstotliwości przy jednej amplitudzie, dodajesz kilka fal razem. To tak, jak naciśnięcie kilku klawiszy na pianinie jednocześnie. Więc modyfikujesz kod, aby wyglądał mniej więcej tak:
void add_sine_wave(int16_t* buffer, int buffer_length, float frequency, float sampling_ratio, float amplitude)
{
for (int i = 0; i < buffer_length; i++)
{
float theta = ((float)i / sampling_ratio) * M_PI;
// make sure to correct for overflows and underflows
buffer[i] += (int16_t)(sin(theta * frequency) * 32767.0f * amplitude);
}
}
a następnie użyj go w następujący sposób:
int16_t buffer[44100];
memset(buffer, 0, sizeof(buffer));
// Create an A Major chord
add_sine_wave(buffer, 44100, 440.0f, 44100.0f, 0.5f);
add_sine_wave(buffer, 44100, 554.37f, 44100.0f, 0.5f);
add_sine_wave(buffer, 44100, 659.26f, 44100.0f, 0.5f);
Nawiasem mówiąc, ja dostaję moje częstotliwości od tutaj (używam równe temperament , ale istnieje wiele od innych strojów dostępny).
Zauważ, że do tej pory używałem tylko fal sinusoidalnych, ale stare syntezatory obsługują również fale kwadratowe , trójkątne i piły , z których każda ma swoje własne interesujące właściwości dźwiękowe. Ich wdrożenie jest dość proste.
Inne rzeczy, które możesz zrobić, aby zwiększyć różnorodność dźwięków, które możesz stworzyć, to:
- Modulacja amplitudy : zmiana amplitudy fali w buforze
- Modulacja częstotliwości : zmiana częstotliwości fali w buforze
- Pogłos : Powtarzanie próbki poprzez zmianę jej kształtu i położenia w buforze. Sam w sobie bardzo złożony temat.
- Obwiednia : zmiana amplitudy próbki, aby dać jej więcej życia
Chodzi o to, że same techniki nie są bardzo trudne, więc tak naprawdę nie potrzebujesz biblioteki, aby je streścić. Wykorzystuje je do tworzenia interesujących dźwięków, co jest trudne.
Ostatnia uwaga. Podczas eksperymentowania z takim dźwiękiem przydatne może być zapisanie danych w plikach WAV, a następnie wizualizacja ich w oprogramowaniu takim jak Audacity. W ten sposób możesz wyraźniej zobaczyć, co robisz.