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