diff options
Diffstat (limited to 'intern/SoundSystem/intern/SND_Utils.cpp')
-rw-r--r-- | intern/SoundSystem/intern/SND_Utils.cpp | 395 |
1 files changed, 395 insertions, 0 deletions
diff --git a/intern/SoundSystem/intern/SND_Utils.cpp b/intern/SoundSystem/intern/SND_Utils.cpp new file mode 100644 index 00000000000..3965c534cd3 --- /dev/null +++ b/intern/SoundSystem/intern/SND_Utils.cpp @@ -0,0 +1,395 @@ +/* + * SND_Utils.cpp + * + * Util functions for soundthingies + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include "SND_Utils.h" +#include "SoundDefines.h" +#include "SND_DependKludge.h" +/* +extern "C" { +#include "license_key.h" +} +*/ +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <math.h> +#include <string.h> + +#if defined(WIN32) +#include <io.h> +#else +#include <unistd.h> +#endif + +//extern int LICENSE_KEY_VALID; +#define LICENSE_KEY_VALID true + +#define BUFFERSIZE 32 + +/* loads a file */ +void* SND_LoadSample(char *filename) +{ + int file, filelen, buffersize = BUFFERSIZE; + void* data = NULL; + +#if defined(WIN32) + file = open(filename, O_BINARY|O_RDONLY); +#else + file = open(filename, 0|O_RDONLY); +#endif + + if (file == -1) + { + //printf("can't open file.\n"); + //printf("press q for quit.\n"); + } + else + { + filelen = lseek(file, 0, SEEK_END); + lseek(file, 0, SEEK_SET); + + if (filelen != 0) + { + data = malloc(buffersize); + + if (read(file, data, buffersize) != buffersize) + { + free(data); + data = NULL; + } + } + close(file); + + } + return (data); +} + + + +bool SND_IsSampleValid(const STR_String& name, void* memlocation) +{ + bool result = false; + bool loadedsample = false; + char buffer[BUFFERSIZE]; + + if (!memlocation) + { + STR_String samplename = name; + memlocation = SND_LoadSample(samplename.Ptr()); + + if (memlocation) + loadedsample = true; + } + + if (memlocation) + { + memcpy(&buffer, memlocation, BUFFERSIZE); + + if(!(memcmp(buffer, "RIFF", 4) && memcmp(&(buffer[8]), "WAVEfmt ", 8))) + { + int shortbuf = * ((short *) &buffer[20]); + if (shortbuf == SND_WAVE_FORMAT_PCM) + result = true; + + /* only fmod supports compressed wav */ +#ifdef USE_FMOD + /* and only valid publishers may use compressed wav */ + if (LICENSE_KEY_VALID) + { + switch (shortbuf) + { + case SND_WAVE_FORMAT_ADPCM: + case SND_WAVE_FORMAT_ALAW: + case SND_WAVE_FORMAT_MULAW: + case SND_WAVE_FORMAT_DIALOGIC_OKI_ADPCM: + case SND_WAVE_FORMAT_CONTROL_RES_VQLPC: + case SND_WAVE_FORMAT_GSM_610: + case SND_WAVE_FORMAT_MPEG3: + result = true; + break; + default: + { + break; + } + } + } +#endif + } +#ifdef USE_FMOD + /* only valid publishers may use ogg vorbis */ + else if (!memcmp(buffer, "OggS", 4) && LICENSE_KEY_VALID) + { + result = true; + } + /* only valid publishers may use mp3 */ + else if (((!memcmp(buffer, "ID3", 3)) || (!memcmp(buffer, "ÿû", 2))) && LICENSE_KEY_VALID) + { + result = true; + } +#endif + } + if (loadedsample) + { + free(memlocation); + memlocation = NULL; + } + + return result; +} + + + +/* checks if the passed pointer is a valid sample */ +bool CheckSample(void* sample) +{ + bool valid = false; + char buffer[32]; + + memcpy(buffer, sample, 16); + + if(!(memcmp(buffer, "RIFF", 4) && memcmp(&(buffer[8]), "WAVEfmt ", 8))) + { + valid = true; + } + + return valid; +} + + + +/* gets the type of the sample (0 == unknown, 1 == PCM etc */ +unsigned int SND_GetSampleFormat(void* sample) +{ + short sampletype = 0; + + if (CheckSample(sample)) + { + memcpy(&sampletype, ((char*)sample) + 20, 2); + } + + return (unsigned int)sampletype; +} + + + +/* gets the number of channels in a sample */ +unsigned int SND_GetNumberOfChannels(void* sample) +{ + short numberofchannels = 0; + + if (CheckSample(sample)) + { + memcpy(&numberofchannels, ((char*)sample) + 22, 2); + } + + return (unsigned int)numberofchannels; +} + + + +/* gets the samplerate of a sample */ +unsigned int SND_GetSampleRate(void* sample) +{ + unsigned int samplerate = 0; + + if (CheckSample(sample)) + { + memcpy(&samplerate, ((char*)sample) + 24, 4); + } + + return samplerate; +} + + + +/* gets the bitrate of a sample */ +unsigned int SND_GetBitRate(void* sample) +{ + short bitrate = 0; + + if (CheckSample(sample)) + { + memcpy(&bitrate, ((char*)sample) + 34, 2); + } + + return (unsigned int)bitrate; +} + + + +/* gets the length of the actual sample data (without the header) */ +unsigned int SND_GetNumberOfSamples(void* sample) +{ + unsigned int chunklength, length = 0, offset = 16; + char data[4]; + + if (CheckSample(sample)) + { + memcpy(&chunklength, ((char*)sample) + offset, 4); + offset = offset + chunklength + 4; + memcpy(data, ((char*)sample) + offset, 4); + + // lets find "data" + while (memcmp(data, "data", 4)) + { + offset += 4; + memcpy(data, ((char*)sample) + offset, 4); + } + offset += 4; + memcpy(&length, ((char*)sample) + offset, 4); + } + + return length; +} + + + +/* gets the size of the entire header (file - sampledata) */ +unsigned int SND_GetHeaderSize(void* sample) +{ + unsigned int chunklength, headersize = 0, offset = 16; + char data[4]; + + if (CheckSample(sample)) + { + memcpy(&chunklength, ((char*)sample) + offset, 4); + offset = offset + chunklength + 4; + memcpy(data, ((char*)sample) + offset, 4); + + // lets find "data" + while (memcmp(data, "data", 4)) + { + offset += 4; + memcpy(data, ((char*)sample) + offset, 4); + } + headersize = offset + 8; + } + + + return headersize; +} + + + +unsigned int SND_GetExtraChunk(void* sample) +{ + unsigned int extrachunk = 0, chunklength, offset = 16; + char data[4]; + + if (CheckSample(sample)) + { + memcpy(&chunklength, ((char*)sample) + offset, 4); + offset = offset + chunklength + 4; + memcpy(data, ((char*)sample) + offset, 4); + + // lets find "cue" + while (memcmp(data, "cue", 3)) + { + offset += 4; + memcpy(data, ((char*)sample) + offset, 4); + } + } + + return extrachunk; +} + + + +void SND_GetSampleInfo(signed char* sample, SND_WaveSlot* waveslot) +{ + WavFileHeader fileheader; + WavFmtHeader fmtheader; + WavFmtExHeader fmtexheader; + WavSampleHeader sampleheader; + WavChunkHeader chunkheader; + + if (CheckSample(sample)) + { + memcpy(&fileheader, sample, sizeof(WavFileHeader)); + sample += sizeof(WavFileHeader); + fileheader.size = ((fileheader.size+1) & ~1) - 4; + + while ((fileheader.size != 0) && (memcpy(&chunkheader, sample, sizeof(WavChunkHeader)))) + { + sample += sizeof(WavChunkHeader); + if (!memcmp(chunkheader.id, "fmt ", 4)) + { + memcpy(&fmtheader, sample, sizeof(WavFmtHeader)); + waveslot->SetSampleFormat(fmtheader.format); + + if (fmtheader.format == 0x0001) + { + waveslot->SetNumberOfChannels(fmtheader.numberofchannels); + waveslot->SetBitRate(fmtheader.bitrate); + waveslot->SetSampleRate(fmtheader.samplerate); + sample += chunkheader.size; + } + else + { + memcpy(&fmtexheader, sample, sizeof(WavFmtExHeader)); + sample += chunkheader.size; + } + } + else if (!memcmp(chunkheader.id, "data", 4)) + { + if (fmtheader.format == 0x0001) + { + waveslot->SetNumberOfSamples(chunkheader.size); + sample += chunkheader.size; + } + else if (fmtheader.format == 0x0011) + { + //IMA ADPCM + } + else if (fmtheader.format == 0x0055) + { + //MP3 WAVE + } + } + else if (!memcmp(chunkheader.id, "smpl", 4)) + { + memcpy(&sampleheader, sample, sizeof(WavSampleHeader)); + //loop = sampleheader.loops; + sample += chunkheader.size; + } + else + sample += chunkheader.size; + + sample += chunkheader.size & 1; + fileheader.size -= (((chunkheader.size + 1) & ~1) + 8); + } + } +} |