first
Some checks failed
Linux / Build Linux (push) Has been cancelled
Linux / Build Linux-1 (push) Has been cancelled
macOS / Build macOS (push) Has been cancelled
macOS / Build macOS-1 (push) Has been cancelled
Windows (MinGW) / Build MinGW (push) Has been cancelled
Windows (MinGW) / Build MinGW-1 (push) Has been cancelled
Windows (MSVC) / Build Windows (push) Has been cancelled
Windows (MSVC) / Build Windows-1 (push) Has been cancelled
Some checks failed
Linux / Build Linux (push) Has been cancelled
Linux / Build Linux-1 (push) Has been cancelled
macOS / Build macOS (push) Has been cancelled
macOS / Build macOS-1 (push) Has been cancelled
Windows (MinGW) / Build MinGW (push) Has been cancelled
Windows (MinGW) / Build MinGW-1 (push) Has been cancelled
Windows (MSVC) / Build Windows (push) Has been cancelled
Windows (MSVC) / Build Windows-1 (push) Has been cancelled
This commit is contained in:
commit
8269b17aa7
652 changed files with 273930 additions and 0 deletions
275
Quake/snd_wave.c
Normal file
275
Quake/snd_wave.c
Normal file
|
|
@ -0,0 +1,275 @@
|
|||
/*
|
||||
* WAV streaming music support. Adapted from ioquake3 with changes.
|
||||
*
|
||||
* Copyright (C) 1999-2005 Id Software, Inc.
|
||||
* Copyright (C) 2005 Stuart Dalton <badcdev@gmail.com>
|
||||
* Copyright (C) 2010-2012 O.Sezer <sezero@users.sourceforge.net>
|
||||
*
|
||||
* 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.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include "quakedef.h"
|
||||
|
||||
#if defined(USE_CODEC_WAVE)
|
||||
#include "snd_codec.h"
|
||||
#include "snd_codeci.h"
|
||||
#include "snd_wave.h"
|
||||
|
||||
/*
|
||||
=================
|
||||
FGetLittleLong
|
||||
=================
|
||||
*/
|
||||
static int FGetLittleLong (FILE *f)
|
||||
{
|
||||
int v;
|
||||
if (!fread(&v, sizeof(v), 1, f))
|
||||
return -1;
|
||||
return LittleLong(v);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
FGetLittleShort
|
||||
=================
|
||||
*/
|
||||
static short FGetLittleShort(FILE *f)
|
||||
{
|
||||
short v;
|
||||
if (!fread(&v, sizeof(v), 1, f))
|
||||
return -1;
|
||||
return LittleShort(v);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
WAV_ReadChunkInfo
|
||||
=================
|
||||
*/
|
||||
static int WAV_ReadChunkInfo(FILE *f, char *name)
|
||||
{
|
||||
int len;
|
||||
|
||||
name[4] = 0;
|
||||
|
||||
if (!fread(name, 4, 1, f))
|
||||
return -1;
|
||||
|
||||
len = FGetLittleLong(f);
|
||||
if (len < 0)
|
||||
{
|
||||
Con_Printf("WAV: Negative chunk length\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
WAV_FindRIFFChunk
|
||||
|
||||
Returns the length of the data in the chunk, or -1 if not found
|
||||
=================
|
||||
*/
|
||||
static int WAV_FindRIFFChunk(FILE *f, const char *chunk)
|
||||
{
|
||||
char name[5];
|
||||
int len;
|
||||
|
||||
while ((len = WAV_ReadChunkInfo(f, name)) >= 0)
|
||||
{
|
||||
/* If this is the right chunk, return */
|
||||
if (!strncmp(name, chunk, 4))
|
||||
return len;
|
||||
len = ((len + 1) & ~1); /* pad by 2 . */
|
||||
|
||||
/* Not the right chunk - skip it */
|
||||
fseek(f, len, SEEK_CUR);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
WAV_ReadRIFFHeader
|
||||
=================
|
||||
*/
|
||||
static qboolean WAV_ReadRIFFHeader(const char *name, FILE *file, snd_info_t *info)
|
||||
{
|
||||
char dump[16];
|
||||
int wav_format;
|
||||
int fmtlen = 0;
|
||||
|
||||
if (fread(dump, 1, 12, file) < 12 ||
|
||||
strncmp(dump, "RIFF", 4) != 0 ||
|
||||
strncmp(&dump[8], "WAVE", 4) != 0)
|
||||
{
|
||||
Con_Printf("%s is missing RIFF/WAVE chunks\n", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Scan for the format chunk */
|
||||
if ((fmtlen = WAV_FindRIFFChunk(file, "fmt ")) < 0)
|
||||
{
|
||||
Con_Printf("%s is missing fmt chunk\n", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Save the parameters */
|
||||
wav_format = FGetLittleShort(file);
|
||||
if (wav_format != WAV_FORMAT_PCM)
|
||||
{
|
||||
Con_Printf("%s is not Microsoft PCM format\n", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
info->channels = FGetLittleShort(file);
|
||||
info->rate = FGetLittleLong(file);
|
||||
FGetLittleLong(file);
|
||||
FGetLittleShort(file);
|
||||
info->bits = FGetLittleShort(file);
|
||||
|
||||
if (info->bits != 8 && info->bits != 16)
|
||||
{
|
||||
Con_Printf("%s is not 8 or 16 bit\n", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
info->width = info->bits / 8;
|
||||
info->dataofs = 0;
|
||||
|
||||
/* Skip the rest of the format chunk if required */
|
||||
if (fmtlen > 16)
|
||||
{
|
||||
fmtlen -= 16;
|
||||
fseek(file, fmtlen, SEEK_CUR);
|
||||
}
|
||||
|
||||
/* Scan for the data chunk */
|
||||
if ((info->size = WAV_FindRIFFChunk(file, "data")) < 0)
|
||||
{
|
||||
Con_Printf("%s is missing data chunk\n", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (info->channels != 1 && info->channels != 2)
|
||||
{
|
||||
Con_Printf("Unsupported number of channels %d in %s\n",
|
||||
info->channels, name);
|
||||
return false;
|
||||
}
|
||||
info->samples = (info->size / info->width) / info->channels;
|
||||
if (info->samples == 0)
|
||||
{
|
||||
Con_Printf("%s has zero samples\n", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_WAV_CodecOpenStream
|
||||
=================
|
||||
*/
|
||||
static qboolean S_WAV_CodecOpenStream(snd_stream_t *stream)
|
||||
{
|
||||
long start = stream->fh.start;
|
||||
|
||||
/* Read the RIFF header */
|
||||
/* The file reads are sequential, therefore no need
|
||||
* for the FS_*() functions: We will manipulate the
|
||||
* file by ourselves from now on. */
|
||||
if (!WAV_ReadRIFFHeader(stream->name, stream->fh.file, &stream->info))
|
||||
return false;
|
||||
|
||||
stream->fh.start = ftell(stream->fh.file); /* reset to data position */
|
||||
if (stream->fh.start - start + stream->info.size > stream->fh.length)
|
||||
{
|
||||
Con_Printf("%s data size mismatch\n", stream->name);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_WAV_CodecReadStream
|
||||
=================
|
||||
*/
|
||||
int S_WAV_CodecReadStream(snd_stream_t *stream, int bytes, void *buffer)
|
||||
{
|
||||
int remaining = stream->info.size - stream->fh.pos;
|
||||
int i, samples;
|
||||
|
||||
if (remaining <= 0)
|
||||
return 0;
|
||||
if (bytes > remaining)
|
||||
bytes = remaining;
|
||||
stream->fh.pos += bytes;
|
||||
if (!fread(buffer, bytes, 1, stream->fh.file))
|
||||
return -1;
|
||||
if (stream->info.width == 2)
|
||||
{
|
||||
samples = bytes / 2;
|
||||
for (i = 0; i < samples; i++)
|
||||
((short *)buffer)[i] = LittleShort( ((short *)buffer)[i] );
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
static void S_WAV_CodecCloseStream (snd_stream_t *stream)
|
||||
{
|
||||
S_CodecUtilClose(&stream);
|
||||
}
|
||||
|
||||
static int S_WAV_CodecRewindStream (snd_stream_t *stream)
|
||||
{
|
||||
FS_rewind(&stream->fh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static qboolean S_WAV_CodecInitialize (void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static void S_WAV_CodecShutdown (void)
|
||||
{
|
||||
}
|
||||
|
||||
snd_codec_t wav_codec =
|
||||
{
|
||||
CODECTYPE_WAVE,
|
||||
true, /* always available. */
|
||||
"wav",
|
||||
S_WAV_CodecInitialize,
|
||||
S_WAV_CodecShutdown,
|
||||
S_WAV_CodecOpenStream,
|
||||
S_WAV_CodecReadStream,
|
||||
S_WAV_CodecRewindStream,
|
||||
NULL, /* jump */
|
||||
S_WAV_CodecCloseStream,
|
||||
NULL
|
||||
};
|
||||
|
||||
#endif /* USE_CODEC_WAVE */
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue