/** audio: this file implements the audio system. */ #ifndef _LCR_AUDIO #define _LCR_AUDIO #define LCR_SOUND_NONE 0 #define LCR_SOUND_CLICK 1 #define LCR_SOUND_CRASH_SMALL 2 #define LCR_SOUND_CRASH_BIG 3 #define LCR_SOUND_ACCELERATOR 4 #define LCR_AUDIO_CRASH_LEN 2048 struct { uint32_t frame; uint8_t soundPlayed; uint16_t soundPlayedSample; uint32_t noise; int engineIntensity; int engineOsc; int engineInc; } LCR_audio; void LCR_audioInit(void) { LCR_LOG0("initializing audio"); LCR_audio.frame = 0; LCR_audio.soundPlayed = LCR_SOUND_NONE; LCR_audio.soundPlayedSample = 0; LCR_audio.noise = 0; LCR_audio.engineOsc = 0; LCR_audio.engineInc = 1; LCR_audio.engineIntensity = 0; } void LCR_audioSetEngineIntensity(uint8_t value) { LCR_audio.engineIntensity = value; } void LCR_audioPlaySound(uint8_t sound) { LCR_LOG2("playing sound"); LCR_audio.soundPlayed = sound; LCR_audio.soundPlayedSample = 0; } uint8_t _LCR_audioNoise(void) { LCR_audio.noise = LCR_audio.noise * 32310901 + 37; return LCR_audio.noise >> 16; } uint8_t LCR_audioGetNextSample(void) { unsigned char result = 128; switch (LCR_audio.soundPlayed) { case LCR_SOUND_CRASH_SMALL: result += (LCR_AUDIO_CRASH_LEN - LCR_audio.soundPlayedSample) * (_LCR_audioNoise() / 16) / LCR_AUDIO_CRASH_LEN; if (LCR_audio.soundPlayedSample >= LCR_AUDIO_CRASH_LEN) LCR_audio.soundPlayed = LCR_SOUND_NONE; break; case LCR_SOUND_CRASH_BIG: result += ((LCR_AUDIO_CRASH_LEN * 2) - LCR_audio.soundPlayedSample) * (_LCR_audioNoise() / 8) / (2 * LCR_AUDIO_CRASH_LEN); if (LCR_audio.soundPlayedSample >= 2 * LCR_AUDIO_CRASH_LEN) LCR_audio.soundPlayed = LCR_SOUND_NONE; break; default: break; } if (LCR_audio.soundPlayed != LCR_SOUND_NONE) LCR_audio.soundPlayedSample++; else { LCR_audio.engineOsc += LCR_audio.engineInc ? (((_LCR_audioNoise() % 256) < (10 + LCR_audio.engineIntensity))) : -31; if (LCR_audio.engineInc && LCR_audio.engineOsc > (90 + (LCR_audio.engineIntensity / 8))) LCR_audio.engineInc = 0; else if ((!LCR_audio.engineInc) && LCR_audio.engineOsc < 10) LCR_audio.engineInc = 1; result += LCR_audio.engineIntensity < 20 ? LCR_audio.engineOsc / 2 : LCR_audio.engineOsc; } LCR_audio.frame++; return result; } #endif // guard