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