X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fopenal%2Fsound.c;h=bcea104d3e4167b94fae261ad3c5e822473681af;hb=f3b05d5b038cb8fe4d720d8d43bf89bf94759251;hp=f4f07b9b6e91112d15b1b154dad7e8b4bcfa4df3;hpb=14813cefff1cc036bf217346188c168429b52e81;p=flatwaifu.git
diff --git a/src/openal/sound.c b/src/openal/sound.c
index f4f07b9..bcea104 100644
--- a/src/openal/sound.c
+++ b/src/openal/sound.c
@@ -1,11 +1,27 @@
+/* Copyright (C) 2020 SovietPony
+ *
+ * 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, version 3 of the License ONLY.
+ *
+ * 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 .
+ */
+
#include "sound.h"
#include "music.h"
#include "files.h" // F_findres F_getreslen
#include "memory.h" // M_lock M_unlock
-#include "misc.h" // int2host
#include "error.h" // logo
+#include "common/endianness.h"
+
#ifdef __APPLE__
# include
# include
@@ -14,7 +30,6 @@
# include
#endif
-#include "SDL.h" // SDL_BuildAudioCVT SDL_ConvertAudio
#include
#include // malloc
#include // memcpy
@@ -22,12 +37,14 @@
#define TAG_OAL1 0x4F414C31
#define MAX_CHANNELS 8
+#define OAL_FORMAT AL_FORMAT_MONO8
+
#pragma pack(1)
typedef struct dmi {
- dword len;
- dword rate;
- dword lstart;
- dword llen;
+ word len;
+ word rate;
+ word lstart;
+ word llen;
byte data[];
} dmi;
#pragma pack()
@@ -95,7 +112,7 @@ void MUS_update (void) {
/* Sound */
-static int sound_menu_handler (menu_msg_t *msg, const menu_t *m, void *data, int i) {
+static int sound_menu_handler (menu_msg_t *msg, const menu_t *m, int i) {
static int cur;
enum { VOLUME, __NUM__ };
static const simple_menu_t sm = {
@@ -115,7 +132,7 @@ static int sound_menu_handler (menu_msg_t *msg, const menu_t *m, void *data, int
}
const menu_t *S_menu (void) {
- static const menu_t m = { sound_menu_handler };
+ static const menu_t m = { &sound_menu_handler };
return &m;
}
@@ -135,25 +152,74 @@ const cfg_t *S_conf (void) {
return conf;
}
-static void convert_this_ext (Uint32 src_format, int src_chan, int src_rate, Uint32 dst_format, int dst_chan, int dst_rate, const void *buf, int len, void **maxbuf, int *maxlen) {
- SDL_AudioCVT cvt;
- *maxlen = 0;
- *maxbuf = NULL;
- if (SDL_BuildAudioCVT(&cvt, src_format, src_chan, src_rate, dst_format, dst_chan, dst_rate) != -1) {
- *maxlen = len * cvt.len_mult;
- *maxbuf = malloc(*maxlen);
- if (*maxbuf != NULL) {
- memcpy(*maxbuf, buf, len);
- cvt.buf = *maxbuf;
- cvt.len = len;
- if (SDL_ConvertAudio(&cvt) == 0) {
- *maxlen = len * cvt.len_ratio;
- } else {
- free(*maxbuf);
- *maxbuf = NULL;
- *maxlen = 0;
+// Convert mono signed/unsigned 8bit sound to openal format
+// AL_FORMAT_MONO8 -> mono unsigned 8bit
+// AL_FORMAT_STEREO8 -> stereo unsigned 8bit
+// AL_FORMAT_MONO16 -> mono signed 16bit
+// AL_FORMAT_STEREO16 -> stereo signed 16bit
+static void cvt_this (int sign, ALint format, const void *data, size_t len, void **outdata, size_t *outlen) {
+ *outdata = NULL;
+ *outlen = 0;
+ switch (format) {
+ case AL_FORMAT_MONO8:
+ {
+ int8_t *y = malloc(len);
+ if (y != NULL) {
+ memcpy(y, data, len);
+ if (sign) {
+ for (size_t i = 0; i < len; i++) {
+ y[i] ^= 0x80;
+ }
+ }
+ *outdata = y;
+ *outlen = len;
+ }
}
- }
+ break;
+ case AL_FORMAT_MONO16:
+ {
+ int16_t *y = malloc(2 * len);
+ if (y != NULL) {
+ for (size_t i = 0; i < len; ++i) {
+ int32_t c = ((int8_t*)data)[i] ^ (sign ? 0x00 : 0x80);
+ y[i] = c >= 0 ? c * 32767 / 127 : c * -32767 / -128;
+ }
+ }
+ *outdata = y;
+ *outlen = 2 * len;
+ }
+ break;
+ case AL_FORMAT_STEREO8:
+ {
+ int8_t *y = malloc(2 * len);
+ if (y != NULL) {
+ int8_t *yy = y;
+ for (size_t i = 0; i < len; i++) {
+ int8_t xx = ((int8_t*)data)[i] ^ (sign ? 0x80 : 0x00);
+ *yy = xx; yy++;
+ *yy = xx; yy++;
+ }
+ *outdata = y;
+ *outlen = 2 * len;
+ }
+ }
+ break;
+ case AL_FORMAT_STEREO16:
+ {
+ int16_t *y = malloc(2 * 2 * len);
+ if (y != NULL) {
+ int16_t *yy = y;
+ for (size_t i = 0; i < len; ++i) {
+ int32_t x = ((int8_t*)data)[i] ^ (sign ? 0x00 : 0x80);
+ int16_t xx = x >= 0 ? x * 32767 / 127 : x * -32767 / -128;
+ *yy = xx; yy++;
+ *yy = xx; yy++;
+ }
+ }
+ *outdata = y;
+ *outlen = 2 * 2* len;
+ }
+ break;
}
}
@@ -162,14 +228,12 @@ static openal_snd *new_openal_snd (const void *data, dword len, dword rate, dwor
ALuint buffer = 0;
openal_snd *snd = NULL;
void *newdata = NULL;
- int newlen = 0;
- // for some reason 8bit formats makes psshshshsh
- // TODO do this without SDL
- convert_this_ext(sign ? AUDIO_S8 : AUDIO_U8, 1, rate, AUDIO_S16SYS, 1, rate, data, len, &newdata, &newlen);
+ size_t newlen = 0;
+ cvt_this(sign, OAL_FORMAT, data, len, &newdata, &newlen);
if (newdata != NULL) {
alGenBuffers(1, &buffer);
if (alGetError() == AL_NO_ERROR) {
- alBufferData(buffer, AL_FORMAT_MONO16, newdata, newlen, rate);
+ alBufferData(buffer, OAL_FORMAT, newdata, newlen, rate);
if (alGetError() == AL_NO_ERROR) {
snd = malloc(sizeof(openal_snd));
if (snd != NULL) {
@@ -195,18 +259,18 @@ snd_t *S_get (int id) {
handle = M_lock(id);
if (handle != NULL) {
void *data = handle;
- dword len = F_getreslen(id);
- dword rate = 11025;
- dword lstart = 0;
- dword llen = 0;
+ word len = F_getreslen(id);
+ word rate = 11025;
+ word lstart = 0;
+ word llen = 0;
int sign = 0;
- if (len > 16) {
+ if (len > 8) {
dmi *hdr = handle;
- dword hdr_len = int2host(hdr->len);
- dword hdr_rate = int2host(hdr->rate);
- dword hdr_lstart = int2host(hdr->lstart);
- dword hdr_llen = int2host(hdr->llen);
- if (hdr_len <= len - 8 && hdr_lstart + hdr_llen <= len - 16) {
+ word hdr_len = short2host(hdr->len);
+ word hdr_rate = short2host(hdr->rate);
+ word hdr_lstart = short2host(hdr->lstart);
+ word hdr_llen = short2host(hdr->llen);
+ if (hdr_len <= len - 4 && hdr_lstart + hdr_llen <= len - 8) {
data = hdr->data;
len = hdr_len;
rate = hdr_rate;