X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fopenal%2Fsound.c;h=bcea104d3e4167b94fae261ad3c5e822473681af;hb=5c603e0069a09b80bf58b5269cf2bbc6be152222;hp=9dfca1919e106311a6c894bc3a3a0d656b229492;hpb=a99489422a881d2ace0312e82aa4191cec877b5c;p=flatwaifu.git diff --git a/src/openal/sound.c b/src/openal/sound.c index 9dfca19..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_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() @@ -41,11 +58,7 @@ typedef struct openal_channel { ALuint source; } openal_channel; -short snd_vol; -short mus_vol; -char music_random; -int music_time; -int music_fade; +static short snd_vol; static ALCdevice *device; static ALCcontext *context; @@ -53,60 +66,161 @@ static ALuint sources[MAX_CHANNELS]; /* Music */ -void S_initmusic (void) { +const cfg_t *MUS_args (void) { + return NULL; +} + +const cfg_t *MUS_conf (void) { + return NULL; +} +const menu_t *MUS_menu (void) { + return NULL; } -void S_donemusic (void) { +void MUS_init (void) { } -void S_startmusic (int time) { +void MUS_done (void) { } -void S_stopmusic (void) { +void MUS_start (int time) { } -void S_volumemusic (int v) { +void MUS_stop (void) { } -void F_loadmus (char n[8]) { +void MUS_volume (int v) { } -void F_freemus (void) { +void MUS_load (char n[8]) { } -void S_updatemusic (void) { +void MUS_free (void) { + +} + +void MUS_update (void) { } /* Sound */ -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; - } +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 = { + GM_BIG, "Sound", NULL, + { + { "Volume", NULL }, + } + }; + if (i == VOLUME) { + switch (msg->type) { + case GM_GETENTRY: return GM_init_int0(msg, GM_SCROLLER, 0, 0, 0); + case GM_GETINT: return GM_init_int(msg, snd_vol, 0, 128, 8); + case GM_SETINT: S_volume(msg->integer.i); return 1; } } + return simple_menu_handler(msg, i, __NUM__, &sm, &cur); +} + +const menu_t *S_menu (void) { + static const menu_t m = { &sound_menu_handler }; + return &m; +} + +const cfg_t *S_args (void) { + static const cfg_t args[] = { + { "sndvol", &snd_vol, Y_WORD }, + { NULL, NULL, 0 } + }; + return args; +} + +const cfg_t *S_conf (void) { + static const cfg_t conf[] = { + { "sound_volume", &snd_vol, Y_WORD }, + { NULL, NULL, 0 } + }; + return conf; +} + +// 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; + } } static openal_snd *new_openal_snd (const void *data, dword len, dword rate, dword lstart, dword llen, int sign) { @@ -114,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) { @@ -147,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; @@ -183,7 +295,7 @@ void S_free (snd_t *s) { ALint h; openal_snd *snd = (openal_snd*)s; if (snd != NULL) { - assert(snd->base.tag = TAG_OAL1); + assert(snd->base.tag == TAG_OAL1); if (context != NULL) { for (i = 0; i < MAX_CHANNELS; i++) { alGetSourcei(sources[i], AL_BUFFER, &h);