Звичайно, ви можете, просто не банально, щоб це звучало "приємно".
Я не знаю, як це зробити в Linux, але якщо ви можете грати в буфер PCM, все, що вам потрібно зробити, - це заповнити його всім, що ви хочете.
Отже, якщо припустити, що ваш буфер налаштований на відтворення в однотонних, 16-бітних зразках, зі швидкістю 44100 зразків в секунду, створювати чистий (синусоїдальний) формат A4 (440 Гц) так само просто, як
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);
}
Однак цей звук, мабуть, дуже тьмяний для ваших інтересів, тому вам доведеться робити кілька складніших речей. Взагалі існує два типи синтезу звуку: аддитивний і віднімаючий . Є багато інших, але ці двоє, мабуть, найпростіші. Сьогодні я просто поговорю про синтез добавок.
Для синтезу добавок ви робите те саме, що я робив саме там, але замість того, щоб просто використовувати одну частоту на одній амплітуді, ви додаєте кілька хвиль разом. Це так само, як одночасно натискати кілька клавіш на піаніно. Таким чином, ви модифікуєте свій код таким чином:
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);
}
}
а потім використовуйте його так:
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);
До речі, я отримую мої частоти з тут (я використовую рівний темперамент , але є багато з інших строїв доступних).
Зауважте, що до сих пір я використовував тільки синусоїди, але старі синтезатори також підтримують квадратні , трикутні та пилові хвилі, кожен з яких має свої цікаві звукові властивості. Реалізація цих методів досить проста.
Інші речі, які ви можете зробити для збільшення різноманітності звуків, які ви можете створювати:
- Модуляція амплітуди : Зміна амплітуди хвилі протягом усього буфера
- Частота модуляції : Зміна частоти хвилі у всьому буфері
- Реверберація : повторення зразка шляхом зміни його форми та положення в буфері. Сама дуже складна тема.
- Обволікання : Зміна амплітуди вибірки, щоб дати їй більше життя
Сенс у тому, що самі методи не дуже складні, тому вам не потрібна бібліотека, щоб їх абстрагувати. Це використовує їх для створення цікавих звуків, що важко.
Одне заключне зауваження. Експериментуючи із таким звуком, може бути дуже корисно зберегти свої дані у файлах WAV, а потім візуалізувати їх у такому програмному забезпеченні, як Audacity. Таким чином ви можете зрозуміти, що ви робите більш чітко.