Claro que puedes, simplemente no es trivial hacer que suene "agradable".
No sé cómo hacerlo en Linux, pero si puedes jugar un búfer PCM, todo lo que tienes que hacer es llenarlo con lo que quieras.
Supongamos que su búfer está configurado para reproducirse en muestras monoaurales con signo de 16 bits, a 44100 muestras por segundo, crear un sonido A4 puro (sinusoidal) (440 Hz) es tan simple como
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);
}
Sin embargo, este sonido es probablemente muy aburrido para sus intereses, por lo que debe hacer algunas cosas más complicadas. En general, hay dos tipos de síntesis de sonido: aditiva y sustractiva . Hay muchos otros, pero estos dos son probablemente los más simples. Hoy solo hablaré sobre síntesis aditiva.
Para la síntesis aditiva, haces lo mismo que yo hice allá arriba, pero en lugar de usar una sola frecuencia en una amplitud, agregas varias ondas juntas. Esto es como presionar varias teclas en un piano al mismo tiempo. Entonces modifica su código para que se vea así:
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);
}
}
y luego úsalo así:
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);
Por cierto, yo estoy haciendo mi frecuencias desde aquí (estoy usando el temperamento igual , pero hay un montón de otras afinaciones disponibles).
Tenga en cuenta que hasta ahora solo he estado usando ondas sinusoidales, pero los sintetizadores antiguos también admiten ondas cuadradas , triangulares y de sierra , cada una con sus propias propiedades de sonido interesantes. Implementar esto es bastante sencillo.
Otras cosas que puede hacer para aumentar la variedad de sonidos que puede crear son:
- Modulación de amplitud : cambio de la amplitud de la onda en todo el búfer
- Modulación de frecuencia : cambio de la frecuencia de la onda en todo el búfer
- Reverberación : repetir una muestra cambiando su forma y posición en el búfer. En sí un tema muy complejo.
- Envolvente : cambiar la amplitud de una muestra para darle más vida
El punto aquí es que las técnicas en sí no son muy difíciles, por lo que realmente no necesita una biblioteca para resumirlas. Los está usando para crear sonidos interesantes, lo que es difícil.
Una nota final. Al experimentar con un sonido como este, puede ser realmente útil guardar sus datos en archivos WAV y luego visualizarlos en algún software como Audacity. De esa manera puedes ver lo que estás haciendo más claramente.