summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 7e3cef6)
raw | patch | inline | side by side (parent: 7e3cef6)
author | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Tue, 24 Mar 2020 12:44:53 +0000 (15:44 +0300) | ||
committer | DeaDDooMER <deaddoomer@deadsoftware.ru> | |
Tue, 24 Mar 2020 12:44:53 +0000 (15:44 +0300) |
src/CMakeLists.txt | patch | blob | history | |
src/menu.c | patch | blob | history | |
src/menu.h | patch | blob | history | |
src/openal/sound.c | patch | blob | history | |
src/sdlmixer/sound.c | patch | blob | history | |
src/sound.h | patch | blob | history |
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e33b8325772008742ac6eb957f73c781366ff332..fcbd51ad9a14ecab8613a20008e412e35d9ffd67 100644 (file)
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
option(WITH_SOFTWARE "Build with Software render" ON)
option(SOUND_DRIVER "Build with selected sound driver" "OpenAL")
-set(WITH_OPENAL (SOUND_DRIVER EQUALS "OpenAL"))
-set(WITH_SDLMIXER (SOUND_DRIVER EQUALS "SDL_mixer"))
+string(TOUPPER "${SOUND_DRIVER}" SOUND_DRIVER)
+string(COMPARE EQUAL "${SOUND_DRIVER}" "OPENAL" WITH_OPENAL)
+string(COMPARE EQUAL "${SOUND_DRIVER}" "SDLMIXER" WITH_SDLMIXER)
set(D2D_GAME_ROOT .)
set(D2D_OPENGL_ROOT ${D2D_GAME_ROOT}/gl)
set(D2D_SOUND_INCLUDE_DIR "${SDLMIXER_INCLUDE_DIR}")
set(D2D_SOUND_LIBRARY "${SDLMIXER_LIBRARY}")
else(WITH_OPENAL)
- message(FATAL_ERROR "Select SOUND_DRIVER as OpenAL or SDL_mixer")
+ message(FATAL_ERROR "Select SOUND_DRIVER as 'OPENAL' or 'SDLMIXER'")
endif(WITH_OPENAL)
if (WITH_OPENGL)
if (WITH_SOFTWARE)
add_executable(doom2d-soft ${D2D_GAME_SRC} ${D2D_SOUND_SRC} ${D2D_SDL_SRC} ${D2D_SOFTWARE_SRC})
- target_include_directories(doom2d-soft PRIVATE "${D2D_GAME_ROOT}" "${D2D_SOUND_LIBRARY}" "${SDL_INCLUDE_DIR}")
+ target_include_directories(doom2d-soft PRIVATE "${D2D_GAME_ROOT}" "${D2D_SOUND_INCLUDE_DIR}" "${SDL_INCLUDE_DIR}")
target_link_libraries(doom2d-soft "${D2D_SOUND_LIBRARY}" "${SDL_LIBRARY}")
endif (WITH_SOFTWARE)
diff --git a/src/menu.c b/src/menu.c
index 95fbbf660dc7fbfc2ad2b8019314c5171d332d58..7f44950493624f25d6ab8ccd6b67e21009d718e6 100644 (file)
--- a/src/menu.c
+++ b/src/menu.c
static int movsndt=0;
static byte cbuf[32];
-static snd_t *voc=NULL;
-static int voc_ch=0;
+static snd_t *voc;
+static int voc_ch;
static void GMV_stop (void) {
- if(voc) {
- if(voc_ch) {S_stop(voc_ch);voc_ch=0;}
- free(voc);voc=NULL;
+ if (voc != NULL) {
+ if (voc_ch) {
+ S_stop(voc_ch);
+ voc_ch = 0;
+ }
+ S_free(voc);
+ voc = NULL;
}
}
-void GMV_say (char *nm) {
- // TODO fix this
- /*
- int r,len;
- snd_t *p;
- byte *d;
-
- if((r=F_findres(nm))==-1) return;
- if(!(p=malloc((len=F_getreslen(r))+16))) return;
- p->len=len;p->rate=11000;
- p->lstart=p->llen=0;
- GMV_stop();
- F_loadres(r,p+1,0,len);
- for(d=(byte*)(p+1);len;--len,++d) *d^=128;
- voc=p;
- voc_ch=S_play(voc,-1,1024,255);
- */
+void GMV_say (const char nm[8]) {
+ snd_t *snd = S_load(nm);
+ if (snd) {
+ GMV_stop();
+ voc = S_load(nm);
+ voc_ch = S_play(voc, 0, 255);
+ }
}
static void GM_set (menu_t *m) {
diff --git a/src/menu.h b/src/menu.h
index fedd702301d2eacffe63c981c441caa40becc189..bb6d829777bcde7f8f7886cb3c1cd13fd2d19a84 100644 (file)
--- a/src/menu.h
+++ b/src/menu.h
extern byte gm_redraw;
extern short lastkey;
-void GMV_say (char *nm);
+void GMV_say (const char nm[8]);
void G_keyf (int key, int down);
void G_code (void);
int GM_act (void);
diff --git a/src/openal/sound.c b/src/openal/sound.c
index af75aa381eeef080d04619e3f3a3cd4d2ce0888a..d046803dc4d0f0018d6039b5e73e3b91726160bb 100644 (file)
--- a/src/openal/sound.c
+++ b/src/openal/sound.c
@@ -103,7 +103,7 @@ static void convert_this_ext (Uint32 src_format, int src_chan, int src_rate, Uin
}
}
-static openal_snd *new_openal_snd (const void *data, dword len, dword rate, dword lstart, dword llen) {
+static openal_snd *new_openal_snd (const void *data, dword len, dword rate, dword lstart, dword llen, int sign) {
assert(data);
ALuint buffer = 0;
openal_snd *snd = NULL;
@@ -111,7 +111,7 @@ static openal_snd *new_openal_snd (const void *data, dword len, dword rate, dwor
int newlen = 0;
// for some reason 8bit formats makes psshshshsh
// TODO do this without SDL
- convert_this_ext(AUDIO_S8, 1, rate, AUDIO_S16SYS, 1, rate, data, len, &newdata, &newlen);
+ convert_this_ext(sign ? AUDIO_S8 : AUDIO_U8, 1, rate, AUDIO_S16SYS, 1, rate, data, len, &newdata, &newlen);
if (newdata != NULL) {
alGenBuffers(1, &buffer);
if (alGetError() == AL_NO_ERROR) {
@@ -135,30 +135,35 @@ static openal_snd *new_openal_snd (const void *data, dword len, dword rate, dwor
}
snd_t *S_get (int id) {
+ void *handle;
openal_snd *snd = NULL;
- void *handle = M_lock(id);
- if (context != NULL && handle != NULL) {
- byte *data = handle;
- dword len = F_getreslen(id);
- dword rate = 8000;
- dword lstart = 0;
- dword llen = 0;
- if (len > 16) {
- 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) {
- data = hdr->data;
- len = hdr_len;
- rate = hdr_rate;
- lstart = hdr_lstart;
- llen = hdr_llen;
+ if (context != NULL) {
+ handle = M_lock(id);
+ if (handle != NULL) {
+ void *data = handle;
+ dword len = F_getreslen(id);
+ dword rate = 11025;
+ dword lstart = 0;
+ dword llen = 0;
+ int sign = 0;
+ if (len > 16) {
+ 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) {
+ data = hdr->data;
+ len = hdr_len;
+ rate = hdr_rate;
+ lstart = hdr_lstart;
+ llen = hdr_llen;
+ sign = 1;
+ }
}
+ snd = new_openal_snd(data, len, rate, lstart, llen, sign);
+ M_unlock(handle);
}
- snd = new_openal_snd(data, len, rate, lstart, llen);
- M_unlock(handle);
}
return (snd_t*)snd;
}
return S_get(F_findres(name));
}
+void S_free (snd_t *s) {
+ int i;
+ ALint h;
+ openal_snd *snd = (openal_snd*)s;
+ if (snd != NULL) {
+ assert(snd->base.tag = TAG_OAL1);
+ if (context != NULL) {
+ for (i = 0; i < MAX_CHANNELS; i++) {
+ alGetSourcei(sources[i], AL_BUFFER, &h);
+ if (h == snd->buffer) {
+ alSourceStop(sources[i]);
+ alSourcei(sources[i], AL_BUFFER, 0);
+ }
+ }
+ alDeleteBuffers(1, &snd->buffer);
+ assert(alGetError() == AL_NO_ERROR);
+ }
+ snd->base.tag = 0;
+ free(s);
+ }
+}
+
void S_init (void) {
assert(device == NULL && context == NULL);
const ALCint attrs[] = {ALC_MONO_SOURCES, MAX_CHANNELS, 0};
diff --git a/src/sdlmixer/sound.c b/src/sdlmixer/sound.c
index 026e01fec9486d79a499196d596c412ccc2e618a..93c1b6350f3cd9ae3935a1c4dde5071fcf2391e8 100644 (file)
--- a/src/sdlmixer/sound.c
+++ b/src/sdlmixer/sound.c
#define TAG_MIX1 0x4d495831
#pragma pack(1)
-struct dmi {
+typedef struct dmi {
Uint32 len; // length [bytes]
Uint32 rate; // freq [Hz]
Uint32 lstart; // loop start offset [bytes]
Uint32 llen; // loop length [bytes]
Uint8 data[]; // sound data
-};
+} dmi;
#pragma pack()
-struct sound {
+typedef struct sdlmixer_snd {
snd_t base;
Mix_Chunk *c;
-};
+} sdlmixer_snd;
short snd_vol; // public 0..128
}
-/* sound */
+/* Sound */
void S_init (void) {
assert(devinit == 0);
devinit = 1;
} else {
logo("S_init: Mix_OpenAudio: %s\n", Mix_GetError());
+ SDL_QuitSubSystem(SDL_INIT_AUDIO);
}
} else {
logo("S_init: SDL_InitSubSytem: %s\n", SDL_GetError());
}
}
-static Mix_Chunk *convert_this (int rate, const Uint8 *buf, int len) {
+static Mix_Chunk *convert_this (int rate, int sign, const Uint8 *buf, int len) {
SDL_AudioCVT cvt;
Mix_Chunk *c = NULL;
- if (SDL_BuildAudioCVT(&cvt, AUDIO_S8, 1, rate, devformat, devchannels, devfreq) != -1) {
+ if (SDL_BuildAudioCVT(&cvt, sign ? AUDIO_S8 : AUDIO_U8, 1, rate, devformat, devchannels, devfreq) != -1) {
int maxlen = len * cvt.len_mult;
Uint8 *maxbuf = malloc(maxlen);
if (maxbuf != NULL) {
return c;
}
-// TODO load raw sounds with voices
+static sdlmixer_snd *new_sdlmixer_snd (const void *data, dword len, dword rate, dword lstart, dword llen, int sign) {
+ Mix_Chunk *c = NULL;
+ sdlmixer_snd *snd = NULL;
+ c = convert_this(rate, sign, data, len);
+ if (c != NULL) {
+ snd = malloc(sizeof(sdlmixer_snd));
+ if (snd != NULL) {
+ snd->base.tag = TAG_MIX1;
+ snd->c = c;
+ } else {
+ free(c->abuf);
+ free(c);
+ }
+ }
+ return snd;
+}
snd_t *S_get (int id) {
- if (!devinit) {
- return NULL;
- }
- struct dmi *snd = M_lock(id);
- struct sound *res = NULL;
- if (snd != NULL) {
- int rlen = F_getreslen(id);
- if (rlen > 16) {
- Uint32 len = int2host(snd->len);
- Uint32 rate = int2host(snd->rate);
- Uint32 lstart = int2host(snd->lstart);
- Uint32 llen = int2host(snd->llen);
- if (len <= rlen - 8 && lstart + llen <= rlen - 16) {
- Mix_Chunk *c = convert_this(rate, snd->data, len);
- if (c != NULL) {
- res = malloc(sizeof(struct sound));
- if (res != NULL) {
- res->base.tag = TAG_MIX1;
- res->c = c;
- // TODO loops
- } else {
- free(c);
- }
+ void *handle;
+ sdlmixer_snd *snd = NULL;
+ if (devinit != NULL) {
+ handle = M_lock(id);
+ if (handle != NULL) {
+ void *data = handle;
+ dword len = F_getreslen(id);
+ dword rate = 11025;
+ dword lstart = 0;
+ dword llen = 0;
+ int sign = 0;
+ if (len > 16) {
+ 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) {
+ data = hdr->data;
+ len = hdr_len;
+ rate = hdr_rate;
+ lstart = hdr_lstart;
+ llen = hdr_llen;
+ sign = 1;
}
- } else {
- logo("S_get(%i): invalid header {len=%u:rate=%u:lstart=%u:llen=%u:rlen=%i}\n", id, len, rate, lstart, llen, rlen);
}
- } else {
- logo("S_load(%i): too short\n", id);
+ snd = new_sdlmixer_snd(data, len, rate, lstart, llen, sign);
+ M_unlock(handle);
}
- M_unlock(snd);
- } else {
- logo("S_load(%i): not found\n", id);
}
- return (snd_t*)res;
+ return (snd_t*)snd;
}
snd_t *S_load (const char name[8]) {
return S_get(id);
}
+void S_free (snd_t *s) {
+ int i;
+ sdlmixer_snd *snd = (sdlmixer_snd*)s;
+ if (snd != NULL) {
+ assert(snd->base.tag == TAG_MIX1);
+ if (devinit) {
+ for (i = 0; i < devchunkchannels; i++) {
+ if (Mix_GetChunk(i) == snd->c) {
+ Mix_HaltChannel(i);
+ }
+ }
+ }
+ free(snd->c->abuf);
+ free(snd->c);
+ free(snd);
+ }
+}
+
short S_play (snd_t *s, short c, short v) {
+ short channel = 0;
+ sdlmixer_snd *snd = (sdlmixer_snd*)s;
assert(c >= 0 && c <= 8);
assert(v >= 0 && v <= 255);
- short channel = 0;
- if (devinit) {
- if (s) {
- struct sound *snd = (struct sound *)s;
- assert(snd->base.tag == TAG_MIX1);
- // TODO care about global volume level
- snd->c->volume = v * MIX_MAX_VOLUME / 255;
- channel = Mix_PlayChannel(c <= 0 ? -1 : c - 1, snd->c, 0);
- channel = channel == -1 ? 0 : channel + 1;
- }
+ if (devinit && snd != NULL) {
+ assert(snd->base.tag == TAG_MIX1);
+ // TODO care about global volume level
+ snd->c->volume = v * MIX_MAX_VOLUME / 255;
+ channel = Mix_PlayChannel(c <= 0 ? -1 : c - 1, snd->c, 0);
+ channel = channel == -1 ? 0 : channel + 1;
}
return channel;
}
void S_stop (short c) {
assert(c >= 0 && c <= 8);
- if (devinit) {
- if (c > 0) {
- Mix_HaltChannel(c - 1);
- }
+ if (devinit && c > 0) {
+ Mix_HaltChannel(c - 1);
}
}
diff --git a/src/sound.h b/src/sound.h
index ca2e044a8b4e49617bc850d4b79bf9918cf4be5d..8851b8513320a4d6870faeebee0b6b24473edda1 100644 (file)
--- a/src/sound.h
+++ b/src/sound.h
// Get sound handle for resource with name
snd_t *S_load (const char name[8]);
+// Stop sound and free handle
+void S_free (snd_t *s);
+
// Initialize sound subsystem
void S_init (void);