¿Existe una biblioteca de sonido para que C genere muestras de sonido a partir del código? [cerrado]

10

Estoy trabajando en un motor para un juego de estilo retro en C. Estoy buscando una biblioteca de sonidos que produzca sonidos de chip a partir del código ... Quiero hacer mi propio rastreador de chiptune para que el motor cree música. ¿Existe tal cosa?

También estaría interesado en una biblioteca para usar archivos .nsf en mi proyecto.

Estoy usando Linux para el desarrollo.

rzrscm
fuente
Creo que esta pregunta pertenece a la categoría "Qué tecnología usar". Aunque, por lo general, estas solicitudes de nicho no generan una gran lista de respuestas, creo que no es constructivo.
MichaelHouse
Bueno, el problema es que parece que no puedo encontrar nada. Ni siquiera sé por dónde empezar ... Todas las bibliotecas que he encontrado se centran en cargar desde archivos como .wav. Puedo usar libmikmod si solo quiero cargar un módulo .mod o .xm, pero eso no es lo que quiero hacer.
rzrscm
No creo que esto realmente caiga en el desarrollo del juego. Es un medio más general que los juegos.
PixelArtDragon
Intente buscar "mod tracker" o quizás "demoscene tracker" para obtener información y recursos más generales.
Patrick Hughes
1
Personalmente encuentro esta pregunta una buena pregunta. Como me gusta programar juegos de estilo retro, es difícil encontrar recursos para cosas como esta sin ser parte de una comunidad oscura.
Zack The Human

Respuestas:

3

Probablemente no sea una respuesta correcta, pero aquí hay una biblioteca de varios motores de audio.

(Desplácese hacia abajo hasta el segundo segmento para bibliotecas de audio)

Al menos 9 de los 12 motores van con C. La mayoría de ellos también admiten archivos de seguimiento. Que no es tan diferente de los archivos nsf (supongo que estos son archivos de música NES).

Sidar
fuente
16

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:

  1. Modulación de amplitud : cambio de la amplitud de la onda en todo el búfer
  2. Modulación de frecuencia : cambio de la frecuencia de la onda en todo el búfer
  3. Reverberación : repetir una muestra cambiando su forma y posición en el búfer. En sí un tema muy complejo.
  4. 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.

Pijama Panda
fuente
+1 por rodar el tuyo. No veo muchas bibliotecas de Linux que admitan NSF. Pero, aquí está la especificación: webcache.googleusercontent.com/…
michael.bartnett
Gracias por la información. Podría seguir creando archivos .nsf para mi proyecto ahora que me doy cuenta de cuánto necesito poner para que los sonidos suenen correctamente.
rzrscm
+1 Supuse que cualquier respuesta a esta pregunta sería tediosa. No sé mucho sobre AM / FM, pero generalmente las ondas se enrutarán primero a un filtro, como en la síntesis sustractiva. Además, su ejemplo de múltiples notas de piano es correcto, ¡un mejor ejemplo sería solo una nota! Una sola nota de piano creará múltiples armónicos, lo que le dará su timbre. Un piano creará> 5 ondas sumadas, mientras que en la mayoría de los sintetizadores 2 o 3 estarán bien.
Tony
¿Cuál es la forma correcta de verificar los desbordamientos en la función "add_sine_wave"?
Eadmaster
@eadmaster: quise decir recorte. Asegúrese de que el valor encaje en unshort antes de convertirlo en a short.
Panda Pyjama
4

Para los efectos de sonido de chiptune, hay una respuesta definitiva: sfxr .

Es una aplicación independiente que puede usar para generar muestras, pero el código fuente también está disponible si desea integrarlo en su código.

Jari Komppa
fuente
3

Puedo recomendar personalmente las bibliotecas de audio de Blargg . Algo que puede ser de particular interés para usted es su Blip_Buffer .

El sitio de Blargg tiene varios sintetizadores de audio "retro", y estoy usando activamente su Game_Music_Emu para reproducir archivos NSF en un clon de Mega Man que estoy escribiendo.

Muchas de las bibliotecas están escritas en C ++, pero algunas también proporcionan una interfaz C.

Zack The Human
fuente
Definitivamente voy a probar algunos de estos ... Pueden ser justo lo que estoy buscando ya que estoy trabajando en un motor de juego que pretende emular la apariencia de un juego de NES.
rzrscm