/* * Tuxánci 2 - A first person shooter * Copyright (C) 2007-2011 Tuxánci Development Team * Copyright (C) 2025-2026 Connor Thomson * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifdef ENABLE_AUDIO #include #include "ta_sdl.h" #include "ta_alc.h" #include "ta_al.h" #include "files.h" #include "main.h" #include "ta_openmpt.h" #define TA_AUDIO_FREQUENCY_HZ 44100 #define TA_AUDIO_BUFFER_AMOUNT 4 #define TA_AUDIO_MIXBUFFER_SAMPLES 2048 ALCdevice *ta_audio_device; ALCcontext *ta_audio_context; ALuint ta_audio_source; ALuint ta_audio_buffers[TA_AUDIO_BUFFER_AMOUNT]; int16_t ta_audio_mixbuffer[TA_AUDIO_MIXBUFFER_SAMPLES]; static openmpt_module *ta_audio_module; static void ta_audio_decode(void) { size_t frame_count = TA_AUDIO_MIXBUFFER_SAMPLES / 2; size_t rendered = openmpt_module_read_interleaved_stereo( ta_audio_module, TA_AUDIO_FREQUENCY_HZ, frame_count, ta_audio_mixbuffer ); if (rendered < frame_count) { SDL_memset( ta_audio_mixbuffer + rendered * 2, 0, (frame_count - rendered) * 2 * sizeof(*ta_audio_mixbuffer) ); } } void ta_audio_init(void) { ta_audio_device = ta_alc_open_device(); ALCint attributes[] = { ALC_FREQUENCY, TA_AUDIO_FREQUENCY_HZ, 0 }; ta_audio_context = ta_alc_create_context(ta_audio_device, attributes); ta_alc_make_context_current(ta_audio_context); ta_audio_module = ta_openmpt_load_module(file_data_music_theme_it_start, file_data_music_theme_it_size); ta_openmpt_set_module_repeat_count(ta_audio_module, -1); alGenSources(1, &ta_audio_source); alGenBuffers(TA_AUDIO_BUFFER_AMOUNT, ta_audio_buffers); for (int index = 0; index < TA_AUDIO_BUFFER_AMOUNT; index++) { ta_audio_decode(); alBufferData( ta_audio_buffers[index], AL_FORMAT_STEREO16, ta_audio_mixbuffer, sizeof(ta_audio_mixbuffer), TA_AUDIO_FREQUENCY_HZ ); } alSourceQueueBuffers( ta_audio_source, TA_AUDIO_BUFFER_AMOUNT, ta_audio_buffers ); alSourcePlay(ta_audio_source); } void ta_audio_update(void) { ALint processed = 0; alGetSourcei(ta_audio_source, AL_BUFFERS_PROCESSED, &processed); while (processed--) { ALuint buffer; alSourceUnqueueBuffers(ta_audio_source, 1, &buffer); ta_audio_decode(); alBufferData(buffer, AL_FORMAT_STEREO16, ta_audio_mixbuffer, sizeof(ta_audio_mixbuffer), TA_AUDIO_FREQUENCY_HZ); alSourceQueueBuffers(ta_audio_source, 1, &buffer); } } void ta_audio_destroy(void) { alSourceStop(ta_audio_source); alDeleteSources(1, &ta_audio_source); alDeleteBuffers(TA_AUDIO_BUFFER_AMOUNT, ta_audio_buffers); if (!ta_audio_module) { openmpt_module_destroy(ta_audio_module); ta_audio_module = NULL; } ta_alc_make_context_current(NULL); alcDestroyContext(ta_audio_context); ta_alc_close_device(ta_audio_device); } #endif // ENABLE_AUDIO