DarkPlaces
Game engine based on the Quake 1 engine by id Software, developed by LadyHavoc
 
snd_wav.c File Reference
#include "darkplaces.h"
#include "snd_main.h"
#include "snd_wav.h"
#include "sound.h"
+ Include dependency graph for snd_wav.c:

Go to the source code of this file.

Data Structures

struct  wavinfo_t
 

Functions

static void FindChunk (const char *name)
 
static void FindNextChunk (const char *name)
 
static int GetLittleLong (void)
 
static short GetLittleShort (void)
 
static wavinfo_t GetWavinfo (char *name, unsigned char *wav, int wavlength)
 
qbool S_LoadWavFile (const char *filename, sfx_t *sfx)
 
static void WAV_FreeSfx (sfx_t *sfx)
 
static void WAV_GetSamplesFloat (channel_t *ch, sfx_t *sfx, int firstsampleframe, int numsampleframes, float *outsamplesfloat)
 

Variables

static unsigned char * data_p
 
static int iff_chunk_len
 
static unsigned char * iff_data
 
static unsigned char * iff_end
 
static unsigned char * last_chunk
 
const snd_fetcher_t wav_fetcher = { WAV_GetSamplesFloat, NULL, WAV_FreeSfx }
 

Function Documentation

◆ FindChunk()

static void FindChunk ( const char * name)
static

Definition at line 100 of file snd_wav.c.

101{
104}
const GLchar * name
Definition glquake.h:601
static void FindNextChunk(const char *name)
Definition snd_wav.c:68
static unsigned char * last_chunk
Definition snd_wav.c:43
static unsigned char * iff_data
Definition snd_wav.c:44

References FindNextChunk(), iff_data, last_chunk, and name.

Referenced by GetWavinfo().

◆ FindNextChunk()

static void FindNextChunk ( const char * name)
static

Definition at line 68 of file snd_wav.c.

69{
70 while (1)
71 {
73
74 if (data_p >= iff_end)
75 { // didn't find the chunk
76 data_p = NULL;
77 return;
78 }
79
80 data_p += 4;
82 if (iff_chunk_len < 0)
83 {
84 data_p = NULL;
85 return;
86 }
88 {
89 // truncated chunk!
90 data_p = NULL;
91 return;
92 }
93 data_p -= 8;
94 last_chunk = data_p + 8 + ( (iff_chunk_len + 1) & ~1 );
95 if (!strncmp((const char *)data_p, name, 4))
96 return;
97 }
98}
#define NULL
Definition qtypes.h:12
static unsigned char * data_p
Definition snd_wav.c:41
static int GetLittleLong(void)
Definition snd_wav.c:58
static unsigned char * iff_end
Definition snd_wav.c:42
static int iff_chunk_len
Definition snd_wav.c:45

References data_p, GetLittleLong(), iff_chunk_len, iff_end, last_chunk, name, and NULL.

Referenced by FindChunk(), and GetWavinfo().

◆ GetLittleLong()

static int GetLittleLong ( void )
static

Definition at line 58 of file snd_wav.c.

59{
60 int val = 0;
61
62 val = BuffLittleLong (data_p);
63 data_p += 4;
64
65 return val;
66}
int BuffLittleLong(const unsigned char *buffer)
Extract a little endian 32bit int from the given buffer.
Definition com_msg.c:71

References BuffLittleLong(), and data_p.

Referenced by FindNextChunk(), and GetWavinfo().

◆ GetLittleShort()

static short GetLittleShort ( void )
static

Definition at line 48 of file snd_wav.c.

49{
50 short val;
51
52 val = BuffLittleShort (data_p);
53 data_p += 2;
54
55 return val;
56}
short BuffLittleShort(const unsigned char *buffer)
Extract a little endian 16bit short from the given buffer.
Definition com_msg.c:76

References BuffLittleShort(), and data_p.

Referenced by GetWavinfo().

◆ GetWavinfo()

static wavinfo_t GetWavinfo ( char * name,
unsigned char * wav,
int wavlength )
static

Definition at line 131 of file snd_wav.c.

132{
133 wavinfo_t info;
134 int i;
135 int format;
136 int samples;
137
138 memset (&info, 0, sizeof(info));
139
140 if (!wav)
141 return info;
142
143 iff_data = wav;
144 iff_end = wav + wavlength;
145
146 // find "RIFF" chunk
147 FindChunk("RIFF");
148 if (!(data_p && !strncmp((const char *)data_p+8, "WAVE", 4)))
149 {
150 Con_Print("Missing RIFF/WAVE chunks\n");
151 return info;
152 }
153
154 // get "fmt " chunk
155 iff_data = data_p + 12;
156 //DumpChunks ();
157
158 FindChunk("fmt ");
159 if (!data_p)
160 {
161 Con_Print("Missing fmt chunk\n");
162 return info;
163 }
164 data_p += 8;
166 if (format != 1)
167 {
168 Con_Print("Microsoft PCM format only\n");
169 return info;
170 }
171
172 info.channels = GetLittleShort();
173 info.rate = GetLittleLong();
174 data_p += 4+2;
175 info.width = GetLittleShort() / 8;
176
177 // get cue chunk
178 FindChunk("cue ");
179 if (data_p)
180 {
181 data_p += 32;
182 info.loopstart = GetLittleLong();
183
184 // if the next chunk is a LIST chunk, look for a cue length marker
185 FindNextChunk ("LIST");
186 if (data_p)
187 {
188 if (!strncmp ((const char *)data_p + 28, "mark", 4))
189 { // this is not a proper parse, but it works with cooledit...
190 data_p += 24;
191 i = GetLittleLong (); // samples in loop
192 info.samples = info.loopstart + i;
193 }
194 }
195 }
196 else
197 info.loopstart = -1;
198
199 // find data chunk
200 FindChunk("data");
201 if (!data_p)
202 {
203 Con_Print("Missing data chunk\n");
204 return info;
205 }
206
207 data_p += 4;
208 samples = GetLittleLong () / info.width / info.channels;
209
210 if (info.samples)
211 {
212 if (samples < info.samples)
213 {
214 Con_Printf ("Sound %s has a bad loop length\n", name);
215 info.samples = samples;
216 }
217 }
218 else
219 info.samples = samples;
220
221 info.dataofs = data_p - wav;
222
223 return info;
224}
void Con_Print(const char *msg)
Prints to all appropriate console targets, and adds timestamps.
Definition console.c:1504
void Con_Printf(const char *fmt,...)
Prints to all appropriate console targets.
Definition console.c:1514
GLsizei samples
Definition glquake.h:623
GLint GLint GLint GLsizei GLsizei GLenum format
Definition glquake.h:649
int i
static short GetLittleShort(void)
Definition snd_wav.c:48
static void FindChunk(const char *name)
Definition snd_wav.c:100
int rate
Definition snd_wav.c:32
int samples
Definition snd_wav.c:36
int width
Definition snd_wav.c:33
int dataofs
Definition snd_wav.c:37
int channels
Definition snd_wav.c:34
int loopstart
Definition snd_wav.c:35

References wavinfo_t::channels, Con_Print(), Con_Printf(), data_p, wavinfo_t::dataofs, FindChunk(), FindNextChunk(), format, GetLittleLong(), GetLittleShort(), i, iff_data, iff_end, wavinfo_t::loopstart, name, wavinfo_t::rate, samples, wavinfo_t::samples, and wavinfo_t::width.

Referenced by S_LoadWavFile().

◆ S_LoadWavFile()

qbool S_LoadWavFile ( const char * filename,
sfx_t * sfx )

Definition at line 268 of file snd_wav.c.

269{
270 fs_offset_t filesize;
271 unsigned char *data;
272 wavinfo_t info;
273 int i, len;
274 const unsigned char *inb;
275 unsigned char *outb;
276
277 // Already loaded?
278 if (sfx->fetcher != NULL)
279 return true;
280
281 // Load the file
282 data = FS_LoadFile(filename, snd_mempool, false, &filesize);
283 if (!data)
284 return false;
285
286 // Don't try to load it if it's not a WAV file
287 if (memcmp (data, "RIFF", 4) || memcmp (data + 8, "WAVE", 4))
288 {
289 Mem_Free(data);
290 return false;
291 }
292
293 if (developer_loading.integer >= 2)
294 Con_Printf ("Loading WAV file \"%s\"\n", filename);
295
296 info = GetWavinfo (sfx->name, data, (int)filesize);
297 if (info.channels < 1 || info.channels > 2) // Stereo sounds are allowed (intended for music)
298 {
299 Con_Printf("%s has an unsupported number of channels (%i)\n",sfx->name, info.channels);
300 Mem_Free(data);
301 return false;
302 }
303 //if (info.channels == 2)
304 // Log_Printf("stereosounds.log", "%s\n", sfx->name);
305
306 sfx->format.speed = info.rate;
307 sfx->format.width = info.width;
308 sfx->format.channels = info.channels;
309 sfx->fetcher = &wav_fetcher;
310 sfx->fetcher_data = Mem_Alloc(snd_mempool, info.samples * sfx->format.width * sfx->format.channels);
311 sfx->total_length = info.samples;
312 sfx->memsize += filesize;
313 len = info.samples * sfx->format.channels * sfx->format.width;
314 inb = data + info.dataofs;
315 outb = (unsigned char *)sfx->fetcher_data;
316 if (info.width == 2)
317 {
318 if (mem_bigendian)
319 {
320 // we have to byteswap the data at load (better than doing it while mixing)
321 for (i = 0;i < len;i += 2)
322 {
323 outb[i] = inb[i+1];
324 outb[i+1] = inb[i];
325 }
326 }
327 else
328 {
329 // we can just copy it straight
330 memcpy(outb, inb, len);
331 }
332 }
333 else
334 {
335 // convert unsigned byte sound data to signed bytes for quicker mixing
336 for (i = 0;i < len;i++)
337 outb[i] = inb[i] - 0x80;
338 }
339
340 if (info.loopstart < 0)
341 sfx->loopstart = sfx->total_length;
342 else
343 sfx->loopstart = info.loopstart;
344 sfx->loopstart = min(sfx->loopstart, sfx->total_length);
345 sfx->flags &= ~SFXFLAG_STREAMED;
346
347 Mem_Free(data); // we already got a copy of this in fetcher_data
348 return true;
349}
unsigned char * FS_LoadFile(const char *path, mempool_t *pool, qbool quiet, fs_offset_t *filesizepointer)
Definition fs.c:3540
int64_t fs_offset_t
Definition fs.h:37
GLsizeiptr const GLvoid * data
Definition glquake.h:639
cvar_t developer_loading
Definition host.c:52
#define min(A, B)
Definition mathlib.h:37
mempool_t * snd_mempool
Definition snd_main.c:144
static wavinfo_t GetWavinfo(char *name, unsigned char *wav, int wavlength)
Definition snd_wav.c:131
const snd_fetcher_t wav_fetcher
Definition snd_wav.c:260
int integer
Definition cvar.h:73
qbool mem_bigendian
Definition zone.c:34
#define Mem_Free(mem)
Definition zone.h:96
#define Mem_Alloc(pool, size)
Definition zone.h:92

References wavinfo_t::channels, Con_Printf(), data, wavinfo_t::dataofs, developer_loading, FS_LoadFile(), GetWavinfo(), i, cvar_t::integer, wavinfo_t::loopstart, Mem_Alloc, mem_bigendian, Mem_Free, min, NULL, wavinfo_t::rate, wavinfo_t::samples, snd_mempool, wav_fetcher, and wavinfo_t::width.

Referenced by S_LoadSound().

◆ WAV_FreeSfx()

static void WAV_FreeSfx ( sfx_t * sfx)
static

Definition at line 254 of file snd_wav.c.

255{
256 // free the loaded sound data
257 Mem_Free(sfx->fetcher_data);
258}

References Mem_Free.

◆ WAV_GetSamplesFloat()

static void WAV_GetSamplesFloat ( channel_t * ch,
sfx_t * sfx,
int firstsampleframe,
int numsampleframes,
float * outsamplesfloat )
static

Definition at line 232 of file snd_wav.c.

233{
234 int i, len = numsampleframes * sfx->format.channels;
235 if (sfx->format.width == 2)
236 {
237 const short *bufs = (const short *)sfx->fetcher_data + firstsampleframe * sfx->format.channels;
238 for (i = 0;i < len;i++)
239 outsamplesfloat[i] = bufs[i] * (1.0f / 32768.0f);
240 }
241 else
242 {
243 const signed char *bufb = (const signed char *)sfx->fetcher_data + firstsampleframe * sfx->format.channels;
244 for (i = 0;i < len;i++)
245 outsamplesfloat[i] = bufb[i] * (1.0f / 128.0f);
246 }
247}
const GLenum * bufs
Definition glquake.h:673

References bufs, and i.

Variable Documentation

◆ data_p

unsigned char* data_p
static

Definition at line 41 of file snd_wav.c.

Referenced by FindNextChunk(), GetLittleLong(), GetLittleShort(), and GetWavinfo().

◆ iff_chunk_len

int iff_chunk_len
static

Definition at line 45 of file snd_wav.c.

Referenced by FindNextChunk().

◆ iff_data

unsigned char* iff_data
static

Definition at line 44 of file snd_wav.c.

Referenced by FindChunk(), and GetWavinfo().

◆ iff_end

unsigned char* iff_end
static

Definition at line 42 of file snd_wav.c.

Referenced by FindNextChunk(), and GetWavinfo().

◆ last_chunk

unsigned char* last_chunk
static

Definition at line 43 of file snd_wav.c.

Referenced by FindChunk(), and FindNextChunk().

◆ wav_fetcher

const snd_fetcher_t wav_fetcher = { WAV_GetSamplesFloat, NULL, WAV_FreeSfx }

Definition at line 260 of file snd_wav.c.

static void WAV_FreeSfx(sfx_t *sfx)
Definition snd_wav.c:254
static void WAV_GetSamplesFloat(channel_t *ch, sfx_t *sfx, int firstsampleframe, int numsampleframes, float *outsamplesfloat)
Definition snd_wav.c:232

Referenced by OGG_LoadVorbisFile(), and S_LoadWavFile().