]> git.xonotic.org Git - xonotic/darkplaces.git/blob - snd_mem.c
quakedef: Add darkplaces.h and include it in as many files as I can. Split up and...
[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 "darkplaces.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 void SCR_PushLoadingScreen (const char *, float);
32 void SCR_PopLoadingScreen (qbool);
33
34 /*
35 ====================
36 Snd_CreateRingBuffer
37
38 If "buffer" is NULL, the function allocates one buffer of "sampleframes" sample frames itself
39 (if "sampleframes" is 0, the function chooses the size).
40 ====================
41 */
42 snd_ringbuffer_t *Snd_CreateRingBuffer (const snd_format_t* format, unsigned int sampleframes, void* buffer)
43 {
44         snd_ringbuffer_t *ringbuffer;
45
46         // If the caller provides a buffer, it must give us its size
47         if (sampleframes == 0 && buffer != NULL)
48                 return NULL;
49
50         ringbuffer = (snd_ringbuffer_t*)Mem_Alloc(snd_mempool, sizeof (*ringbuffer));
51         memset(ringbuffer, 0, sizeof(*ringbuffer));
52         memcpy(&ringbuffer->format, format, sizeof(ringbuffer->format));
53
54         // If we haven't been given a buffer
55         if (buffer == NULL)
56         {
57                 unsigned int maxframes;
58                 size_t memsize;
59
60                 if (sampleframes == 0)
61                         maxframes = (format->speed + 1) / 2;  // Make the sound buffer large enough for containing 0.5 sec of sound
62                 else
63                         maxframes = sampleframes;
64
65                 memsize = maxframes * format->width * format->channels;
66                 ringbuffer->ring = (unsigned char *) Mem_Alloc(snd_mempool, memsize);
67                 ringbuffer->maxframes = maxframes;
68         }
69         else
70         {
71                 ringbuffer->ring = (unsigned char *) buffer;
72                 ringbuffer->maxframes = sampleframes;
73         }
74
75         return ringbuffer;
76 }
77
78
79 //=============================================================================
80
81 /*
82 ==============
83 S_LoadSound
84 ==============
85 */
86 qbool S_LoadSound (sfx_t *sfx, qbool complain)
87 {
88         char namebuffer[MAX_QPATH + 16];
89         size_t len;
90
91         // See if already loaded
92         if (sfx->fetcher != NULL)
93                 return true;
94
95         // If we weren't able to load it previously, no need to retry
96         // Note: S_PrecacheSound clears this flag to cause a retry
97         if (sfx->flags & SFXFLAG_FILEMISSING)
98                 return false;
99
100         // No sound?
101         if (snd_renderbuffer == NULL)
102                 return false;
103
104         // Initialize volume peak to 0; if ReplayGain is supported, the loader will change this away
105         sfx->volume_peak = 0.0;
106
107         if (developer_loading.integer)
108                 Con_Printf("loading sound %s\n", sfx->name);
109
110         SCR_PushLoadingScreen(sfx->name, 1);
111
112         // LadyHavoc: if the sound filename does not begin with sound/, try adding it
113         if (strncasecmp(sfx->name, "sound/", 6))
114         {
115                 dpsnprintf (namebuffer, sizeof(namebuffer), "sound/%s", sfx->name);
116                 len = strlen(namebuffer);
117                 if (len >= 4 && !strcasecmp (namebuffer + len - 4, ".wav"))
118                 {
119                         if (S_LoadWavFile (namebuffer, sfx))
120                                 goto loaded;
121                         memcpy (namebuffer + len - 3, "ogg", 4);
122                 }
123                 if (len >= 4 && !strcasecmp (namebuffer + len - 4, ".ogg"))
124                 {
125                         if (OGG_LoadVorbisFile (namebuffer, sfx))
126                                 goto loaded;
127                 }
128 #ifdef USEXMP
129                 else if (len >= 1)
130                 {
131                         if (XMP_LoadModFile (namebuffer, sfx))
132                                 goto loaded;
133                 }
134 #endif
135         }
136
137         // LadyHavoc: then try without the added sound/ as wav and ogg
138         dpsnprintf (namebuffer, sizeof(namebuffer), "%s", sfx->name);
139         len = strlen(namebuffer);
140         // request foo.wav: tries foo.wav, then foo.ogg
141         // request foo.ogg: tries foo.ogg only
142         // request foo.mod: tries foo.mod only
143         if (len >= 4 && !strcasecmp (namebuffer + len - 4, ".wav"))
144         {
145                 if (S_LoadWavFile (namebuffer, sfx))
146                         goto loaded;
147                 memcpy (namebuffer + len - 3, "ogg", 4);
148         }
149         if (len >= 4 && !strcasecmp (namebuffer + len - 4, ".ogg"))
150         {
151                 if (OGG_LoadVorbisFile (namebuffer, sfx))
152                         goto loaded;
153         }
154 #ifdef USEXMP
155         else if (len >= 1)
156         {
157                 if (XMP_LoadModFile (namebuffer, sfx))
158                         goto loaded;
159         }
160 #endif
161
162         // Can't load the sound!
163         sfx->flags |= SFXFLAG_FILEMISSING;
164         if (complain)
165                 Con_Printf(CON_ERROR "Failed to load sound \"%s\"\n", sfx->name);
166
167         SCR_PopLoadingScreen(false);
168         return false;
169
170 loaded:
171         SCR_PopLoadingScreen(false);
172         return true;
173 }