]> git.xonotic.org Git - xonotic/darkplaces.git/blob - snd_mem.c
Merge PR 'Use the text from modinfo.txt as the mod menu entry'
[xonotic/darkplaces.git] / snd_mem.c
1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
19 */
20
21
22 #include "quakedef.h"
23
24 #include "snd_main.h"
25 #include "snd_ogg.h"
26 #include "snd_wav.h"
27 #ifdef USEXMP
28 #include "snd_xmp.h"
29 #endif
30
31
32 /*
33 ====================
34 Snd_CreateRingBuffer
35
36 If "buffer" is NULL, the function allocates one buffer of "sampleframes" sample frames itself
37 (if "sampleframes" is 0, the function chooses the size).
38 ====================
39 */
40 snd_ringbuffer_t *Snd_CreateRingBuffer (const snd_format_t* format, unsigned int sampleframes, void* buffer)
41 {
42         snd_ringbuffer_t *ringbuffer;
43
44         // If the caller provides a buffer, it must give us its size
45         if (sampleframes == 0 && buffer != NULL)
46                 return NULL;
47
48         ringbuffer = (snd_ringbuffer_t*)Mem_Alloc(snd_mempool, sizeof (*ringbuffer));
49         memset(ringbuffer, 0, sizeof(*ringbuffer));
50         memcpy(&ringbuffer->format, format, sizeof(ringbuffer->format));
51
52         // If we haven't been given a buffer
53         if (buffer == NULL)
54         {
55                 unsigned int maxframes;
56                 size_t memsize;
57
58                 if (sampleframes == 0)
59                         maxframes = (format->speed + 1) / 2;  // Make the sound buffer large enough for containing 0.5 sec of sound
60                 else
61                         maxframes = sampleframes;
62
63                 memsize = maxframes * format->width * format->channels;
64                 ringbuffer->ring = (unsigned char *) Mem_Alloc(snd_mempool, memsize);
65                 ringbuffer->maxframes = maxframes;
66         }
67         else
68         {
69                 ringbuffer->ring = (unsigned char *) buffer;
70                 ringbuffer->maxframes = sampleframes;
71         }
72
73         return ringbuffer;
74 }
75
76
77 //=============================================================================
78
79 /*
80 ==============
81 S_LoadSound
82 ==============
83 */
84 qboolean S_LoadSound (sfx_t *sfx, qboolean complain)
85 {
86         char namebuffer[MAX_QPATH + 16];
87         size_t len;
88
89         // See if already loaded
90         if (sfx->fetcher != NULL)
91                 return true;
92
93         // If we weren't able to load it previously, no need to retry
94         // Note: S_PrecacheSound clears this flag to cause a retry
95         if (sfx->flags & SFXFLAG_FILEMISSING)
96                 return false;
97
98         // No sound?
99         if (snd_renderbuffer == NULL)
100                 return false;
101
102         // Initialize volume peak to 0; if ReplayGain is supported, the loader will change this away
103         sfx->volume_peak = 0.0;
104
105         if (developer_loading.integer)
106                 Con_Printf("loading sound %s\n", sfx->name);
107
108         SCR_PushLoadingScreen(sfx->name, 1);
109
110         // LadyHavoc: if the sound filename does not begin with sound/, try adding it
111         if (strncasecmp(sfx->name, "sound/", 6))
112         {
113                 dpsnprintf (namebuffer, sizeof(namebuffer), "sound/%s", sfx->name);
114                 len = strlen(namebuffer);
115                 if (len >= 4 && !strcasecmp (namebuffer + len - 4, ".wav"))
116                 {
117                         if (S_LoadWavFile (namebuffer, sfx))
118                                 goto loaded;
119                         memcpy (namebuffer + len - 3, "ogg", 4);
120                 }
121                 if (len >= 4 && !strcasecmp (namebuffer + len - 4, ".ogg"))
122                 {
123                         if (OGG_LoadVorbisFile (namebuffer, sfx))
124                                 goto loaded;
125                 }
126 #ifdef USEXMP
127                 else if (len >= 1)
128                 {
129                         if (XMP_LoadModFile (namebuffer, sfx))
130                                 goto loaded;
131                 }
132 #endif
133         }
134
135         // LadyHavoc: then try without the added sound/ as wav and ogg
136         dpsnprintf (namebuffer, sizeof(namebuffer), "%s", sfx->name);
137         len = strlen(namebuffer);
138         // request foo.wav: tries foo.wav, then foo.ogg
139         // request foo.ogg: tries foo.ogg only
140         // request foo.mod: tries foo.mod only
141         if (len >= 4 && !strcasecmp (namebuffer + len - 4, ".wav"))
142         {
143                 if (S_LoadWavFile (namebuffer, sfx))
144                         goto loaded;
145                 memcpy (namebuffer + len - 3, "ogg", 4);
146         }
147         if (len >= 4 && !strcasecmp (namebuffer + len - 4, ".ogg"))
148         {
149                 if (OGG_LoadVorbisFile (namebuffer, sfx))
150                         goto loaded;
151         }
152 #ifdef USEXMP
153         else if (len >= 1)
154         {
155                 if (XMP_LoadModFile (namebuffer, sfx))
156                         goto loaded;
157         }
158 #endif
159
160         // Can't load the sound!
161         sfx->flags |= SFXFLAG_FILEMISSING;
162         if (complain)
163                 Con_DPrintf("failed to load sound \"%s\"\n", sfx->name);
164
165         SCR_PopLoadingScreen(false);
166         return false;
167
168 loaded:
169         SCR_PopLoadingScreen(false);
170         return true;
171 }