openkknd-pitchwell-archive/engine-c/src/audio.c
2026-09-17 21:48:48 +02:00

76 lines
2.7 KiB
C

#include "kknd.h"
/* =========================================================================
* audio.c - Procedural sound effects via SDL audio queue (no asset files).
* ========================================================================= */
static SDL_AudioDeviceID g_dev = 0;
static int g_audio_ok = 0;
int audio_init(void) {
SDL_AudioSpec want, have;
memset(&want, 0, sizeof want);
want.freq = 22050;
want.format = AUDIO_S16SYS;
want.channels = 1;
want.samples = 1024;
g_dev = SDL_OpenAudioDevice(NULL, 0, &want, &have, 0);
if (g_dev == 0) { return 0; }
g_audio_ok = 1;
SDL_PauseAudioDevice(g_dev, 0);
return 1;
}
void audio_shutdown(void) {
if (g_dev) SDL_CloseAudioDevice(g_dev);
g_dev = 0; g_audio_ok = 0;
}
static void queue_tone(float freq, float dur, float vol, int kind) {
if (!g_audio_ok) return;
int n = (int)(22050 * dur);
int16_t *buf = (int16_t *)calloc((size_t)n, sizeof(int16_t));
for (int i = 0; i < n; i++) {
float t = (float)i / 22050.0f;
float env = (kind == 0) ? (1.0f - t / dur) : 1.0f;
float s = sinf(2*3.14159f*freq*t);
if (kind == 1) s = (sinf(2*3.14159f*freq*t) + 0.3f*sinf(2*3.14159f*freq*2*t));
if (kind == 2) s = (sinf(2*3.14159f*freq*t) * (1.0f - t/dur)) ;
buf[i] = (int16_t)(s * vol * 32767 * env);
}
SDL_QueueAudio(g_dev, buf, (Uint32)(n * sizeof(int16_t)));
free(buf);
}
void audio_sfx(int id) {
switch (id) {
case 0: queue_tone(440, 0.08f, 0.25f, 0); break; /* move */
case 1: queue_tone(220, 0.06f, 0.30f, 1); break; /* shoot */
case 2: queue_tone(90, 0.35f, 0.45f, 2); break; /* boom */
case 3: queue_tone(660, 0.10f, 0.30f, 0); break; /* build */
case 4: queue_tone(880, 0.05f, 0.25f, 0); break; /* select */
case 5: queue_tone(140, 0.12f, 0.35f, 1); break; /* error */
default: break;
}
}
void audio_music_start(void) { /* procedural drone; intentionally silent by default */ }
void audio_music_stop(void) { /* no-op */ }
/* simple looping wasteland bassline (procedural, no asset files) */
static float g_music_t = 0;
static int g_music_step = 0;
static const float g_bass[8] = { 110.0f, 0, 146.8f, 0, 130.8f, 0, 98.0f, 0 };
static const float g_mel[8] = { 0, 329.6f, 0, 392.0f, 0, 293.7f, 0, 261.6f };
void audio_music_tick(float dt) {
if (!g_audio_ok) return;
g_music_t += dt;
const float step_dur = 0.40f;
if (g_music_t < step_dur) return;
g_music_t -= step_dur;
int s = g_music_step % 8;
if (g_bass[s] > 0) queue_tone(g_bass[s], step_dur * 0.95f, 0.10f, 2);
if (g_mel[s] > 0) queue_tone(g_mel[s], step_dur * 0.55f, 0.045f, 0);
g_music_step++;
}