rogged/src/audio.c

153 lines
3.4 KiB
C

#include "audio.h"
#include "raylib.h"
#include "common.h"
#include <math.h>
#include <stddef.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846 // xd
#endif
#define SAMPLE_RATE 44100
#define DURATION 0.1
// Generate a simple sine wave tone
static void play_tone(float frequency, float duration, float volume) {
int sample_count = (int)(SAMPLE_RATE * duration);
if (sample_count > SAMPLE_RATE)
sample_count = SAMPLE_RATE;
if (sample_count <= 0)
return;
// Allocate samples dynamically to avoid shared static buffer corruption
float *samples = (float *)MemAlloc(sample_count * sizeof(float));
if (samples == NULL)
return;
// Generate sine wave
for (int i = 0; i < sample_count; i++) {
float t = (float)i / SAMPLE_RATE;
samples[i] = sinf(2.0f * M_PI * frequency * t) * volume;
// Apply simple envelope (fade in/out)
float envelope = 1.0f;
int fade_samples = SAMPLE_RATE / 20; // 50ms fade
if (i < fade_samples) {
envelope = (float)i / fade_samples;
} else if (i > sample_count - fade_samples) {
envelope = (float)(sample_count - i) / fade_samples;
}
samples[i] *= envelope;
}
// Create wave from samples
Wave wave = {.frameCount = (unsigned int)sample_count,
.sampleRate = SAMPLE_RATE,
.sampleSize = 32,
.channels = 1,
.data = samples};
Sound sound = LoadSoundFromWave(wave);
PlaySound(sound);
UnloadSound(sound);
// Free the dynamically allocated buffer
MemFree(samples);
}
void audio_init(void) {
// Initialize audio device
InitAudioDevice();
}
void audio_close(void) {
// Close audio device
CloseAudioDevice();
}
void audio_play_move(void) {
// Low blip for movement
play_tone(200.0f, 0.05f, 0.3f);
}
void audio_play_attack(GameState *gs) {
// Mid-range hit sound
// play_tone(400.0f, 0.1f, 0.5f);
int choice = GetRandomValue(1, 3);
switch (choice) {
case 1:
PlaySound(gs->sounds.attack1);
break;
case 2:
PlaySound(gs->sounds.attack2);
break;
case 3:
PlaySound(gs->sounds.attack3);
break;
default:
PlaySound(gs->sounds.attack1);
break;
}
}
void audio_play_item_pickup(GameState *gs) {
// High-pitched pickup sound
PlaySound(gs->sounds.pickup);
}
void audio_play_enemy_death(GameState *gs) {
// Descending death sound
play_tone(300.0f, 0.1f, 0.5f);
play_tone(150.0f, 0.15f, 0.4f);
}
void audio_play_player_damage(GameState *gs) {
// Harsh damage sound
play_tone(150.0f, 0.1f, 0.6f);
play_tone(100.0f, 0.1f, 0.4f);
}
void audio_play_stairs(GameState *gs) {
// Ascending stairs sound
PlaySound(gs->sounds.staircase);
}
void audio_play_dodge(GameState *gs) {
// High-pitched whoosh
// play_tone(900.0f, 0.08f, 0.3f);
int choice = GetRandomValue(1, 3);
switch (choice) {
case 1:
PlaySound(gs->sounds.dodge1);
break;
case 2:
PlaySound(gs->sounds.dodge2);
break;
case 3:
PlaySound(gs->sounds.dodge3);
break;
default:
PlaySound(gs->sounds.dodge1);
break;
}
return;
}
void audio_play_block(GameState *gs) {
// Low-then-mid metallic clang
play_tone(250.0f, 0.06f, 0.5f);
play_tone(350.0f, 0.04f, 0.3f);
}
void audio_play_crit(GameState *gs) {
// Sharp crack with high-pitched follow
audio_play_attack(gs);
PlaySound(gs->sounds.crit);
}
void audio_play_proc(void) {
// Ascending two-tone proc chime
play_tone(500.0f, 0.08f, 0.4f);
play_tone(700.0f, 0.1f, 0.35f);
}