summaryrefslogtreecommitdiff
path: root/src/audio.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio.c')
-rw-r--r--src/audio.c125
1 files changed, 125 insertions, 0 deletions
diff --git a/src/audio.c b/src/audio.c
new file mode 100644
index 0000000..0f8a337
--- /dev/null
+++ b/src/audio.c
@@ -0,0 +1,125 @@
+/*
+ * 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 <https://www.gnu.org/licenses/>.
+ */
+
+#ifdef ENABLE_AUDIO
+
+#include <libopenmpt/libopenmpt.h>
+#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 \ No newline at end of file