示例#1
0
/**
 * Loads the contents of an X-Com CAT file which usually contains
 * a set of sound files. The CAT starts with an index of the offset
 * and size of every file contained within. Each file consists of a
 * filename followed by its contents.
 * @param filename Filename of the CAT set.
 * @param wav Are the sounds in WAV format?
 * @sa http://www.ufopaedia.org/index.php?title=SOUND
 */
void SoundSet::loadCat(const std::string &filename, bool wav)
{
	// Load CAT file
	CatFile sndFile (filename.c_str());
	if (!sndFile)
	{
		throw Exception("Failed to load CAT");
	}

	// Load each sound file
	for (int i = 0; i < sndFile.getAmount(); ++i)
	{
		// Read WAV chunk
		char *sound = sndFile.load(i);
		unsigned int size = sndFile.getObjectSize(i);

		// If there's no WAV header (44 bytes), add it
		// Assuming sounds are 8-bit 8000Hz (DOS version)
		char *newsound = 0;
		if (!wav)
		{
			char header[] = {'R', 'I', 'F', 'F', 0x00, 0x00, 0x00, 0x00, 'W', 'A', 'V', 'E', 'f', 'm', 't', ' ',
							 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x40, 0x1f, 0x00, 0x00, 0x40, 0x1f, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00,
							 'd', 'a', 't', 'a', 0x00, 0x00, 0x00, 0x00};
			int headersize = size + 36;
			int soundsize = size;
			memcpy(header + 4, &headersize, sizeof(headersize));
			memcpy(header + 40, &soundsize, sizeof(soundsize));

			newsound = new char[44 + size];
			memcpy(newsound, header, 44);
			memcpy(newsound + 44, sound, size);
		}

		Sound *s = new Sound();
		try
		{
			if (wav)
				s->load(sound, size);
			else
				s->load(newsound, 44 + size);
		}
		catch (Exception &e)
		{
			// Ignore junk in the file
			e = e;
		}
		_sounds.push_back(s);

		delete[] sound;
		if (!wav)
		{
			delete[] newsound;
		}
	}
}
示例#2
0
/**
 * Loads the contents of an X-Com CAT file which usually contains
 * a set of sound files. The CAT starts with an index of the offset
 * and size of every file contained within. Each file consists of a
 * filename followed by its contents.
 * @param filename Filename of the CAT set.
 * @param wav Are the sounds in WAV format?
 * @sa http://www.ufopaedia.org/index.php?title=SOUND
 */
void SoundSet::loadCat(const std::string &filename, bool wav)
{
	// Load CAT file
	CatFile sndFile (filename.c_str());
	if (!sndFile)
	{
		throw Exception(filename + " not found");
	}

	// Load each sound file
	for (int i = 0; i < sndFile.getAmount(); ++i)
	{
		// Read WAV chunk
		unsigned char *sound = (unsigned char*) sndFile.load(i);
		unsigned int size = sndFile.getObjectSize(i);

		// If there's no WAV header (44 bytes), add it
		// Assuming sounds are 8-bit 8000Hz (DOS version)
		unsigned char *newsound = 0;
		if (!wav)
		{
			if (size != 0)
			{
				char header[] = {'R', 'I', 'F', 'F', 0x00, 0x00, 0x00, 0x00, 'W', 'A', 'V', 'E', 'f', 'm', 't', ' ',
								 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x11, 0x2b, 0x00, 0x00, 0x11, 0x2b, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00,
								 'd', 'a', 't', 'a', 0x00, 0x00, 0x00, 0x00};

				for (unsigned int n = 0; n < size; ++n) sound[n] *= 4; // scale to 8 bits
				if (size > 5) size -= 5; // skip 5 garbage name bytes at beginning
				if (size) size--; // omit trailing null byte

				int headersize = size + 36;
				int soundsize = size;
				memcpy(header + 4, &headersize, sizeof(headersize));
				memcpy(header + 40, &soundsize, sizeof(soundsize));

				newsound = new unsigned char[44 + size*2];
				memcpy(newsound, header, 44);
				if (size) memcpy(newsound + 44, sound+5, size);
				Uint32 step16 = (8000<<16)/11025;
				Uint8 *w = newsound+44;
				int newsize = 0;
				for (Uint32 offset16 = 0; (offset16>>16) < size; offset16 += step16, ++w, ++newsize)
				{
					*w = sound[5 + (offset16>>16)];
				}
				size = newsize + 44;
			}
		}
		else if (0x40 == sound[0x18] && 0x1F == sound[0x19] && 0x00 == sound[0x1A] && 0x00 == sound[0x1B])
示例#3
0
/**
 * Loads the contents of an X-Com CAT file which usually contains
 * a set of sound files. The CAT starts with an index of the offset
 * and size of every file contained within. Each file consists of a
 * filename followed by its contents.
 * @param filename Filename of the CAT set.
 * @param wav Are the sounds in WAV format?
 * @sa http://www.ufopaedia.org/index.php?title=SOUND
 */
void SoundSet::loadCat(const std::string &filename, bool wav)
{
	// Load CAT file
	CatFile sndFile (filename.c_str());
	if (!sndFile)
	{
		throw Exception(filename + " not found");
	}

	// Load each sound file
	for (int i = 0; i < sndFile.getAmount(); ++i)
	{
		// Read WAV chunk
		unsigned char *sound = (unsigned char*) sndFile.load(i);
		unsigned int size = sndFile.getObjectSize(i);

		// If there's no WAV header (44 bytes), add it
		// Assuming sounds are 6-bit 8000Hz (DOS version)
		unsigned char *newsound = 0;
		const int headerSize = 44;
		if (!wav)
		{
			if (size > 5) size -= 5; // skip 5 garbage name bytes at beginning
			if (size) size--; // omit trailing null byte
			if (size != 0)
			{
				char header[] = {'R', 'I', 'F', 'F', 0x00, 0x00, 0x00, 0x00, 'W', 'A', 'V', 'E', 'f', 'm', 't', ' ',
								 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x11, 0x2b, 0x00, 0x00, 0x11, 0x2b, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00,
								 'd', 'a', 't', 'a', 0x00, 0x00, 0x00, 0x00};

				// scale to 8 bits
				for (unsigned int n = 0; n < size; ++n) sound[5 + n] *= 4;

				// copy and do the conversion...
				newsound = new unsigned char[headerSize + size*2];
				memcpy(newsound, header, headerSize);
				memcpy(newsound + headerSize, sound + 5, size);
				int newsize = convertSampleRate(sound + 5, size, newsound + headerSize);
				size = newsize + headerSize;

				// Rewrite the number of samples in the WAV file
				int headersize = newsize + 36;
				int soundsize = newsize;
				memcpy(newsound + 4, &headersize, sizeof(headersize));
				memcpy(newsound + 40, &soundsize, sizeof(soundsize));
			}
		}
		// so it's WAV, but in 8 khz, we have to convert it to 11 khz sound
		else if (0x40 == sound[0x18] && 0x1F == sound[0x19] && 0x00 == sound[0x1A] && 0x00 == sound[0x1B])
		{
			unsigned char *sound2 = new unsigned char[size*2];

			// rewrite the samplerate in the header to 11 khz
			sound[0x18]=0x11; sound[0x19]=0x2B; sound[0x1C]=0x11; sound[0x1D]=0x2B;

			// copy and do the conversion...
			memcpy(sound2, sound, size);
			int newsize = convertSampleRate(sound + headerSize, size - headerSize, sound2 + headerSize);
			size = newsize + headerSize;

			// Rewrite the number of samples in the WAV file
			memcpy(sound2 + 0x28, &newsize, sizeof(newsize));

			// Ok, now replace the original with the converted:
			delete[] sound;
			sound = sound2;
		}

		Sound *s = new Sound();
		try
		{
			if (size == 0)
			{
				throw Exception("Invalid sound file");
			}
			if (wav)
				s->load(sound, size);
			else
				s->load(newsound, size);
		}
		catch (const Exception &)
		{
			// Ignore junk in the file
		}
		_sounds[i] = s;

		delete[] sound;
		if (!wav)
		{
			delete[] newsound;
		}
	}
}
示例#4
0
/**
 * Loads individual contents of a TFTD CAT file by index.
 * a set of sound files. The CAT starts with an index of the offset
 * and size of every file contained within. Each file consists of a
 * filename followed by its contents.
 * @param filename Filename of the CAT set.
 * @param index which index in the cat file do we load?
 * @sa http://www.ufopaedia.org/index.php?title=SOUND
 */
void SoundSet::loadCatbyIndex(const std::string &filename, int index)
{
	// Load CAT file
	CatFile sndFile (filename.c_str());
	if (!sndFile)
	{
		throw Exception(filename + " not found");
	}
	if (index >= sndFile.getAmount())
	{
		std::ostringstream err;
		err << filename << " does not contain " << index << " sound files.";
		throw Exception(err.str());
	}

	// Read WAV chunk
	unsigned char *sound = (unsigned char*) sndFile.load(index);
	unsigned int size = sndFile.getObjectSize(index);

	// there's no WAV header (44 bytes), add it
	// sounds are 8-bit 11025Hz, signed
	unsigned char *newsound = 0;

	if (size != 0)
	{
		char header[] = {'R', 'I', 'F', 'F', 0x00, 0x00, 0x00, 0x00, 'W', 'A', 'V', 'E', 'f', 'm', 't', ' ',
							0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x11, 0x2b, 0x00, 0x00, 0x11, 0x2b, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00,
							'd', 'a', 't', 'a', 0x00, 0x00, 0x00, 0x00};


		if (size > 5) size -= 5; // skip 5 garbage name bytes at beginning
		if (size) size--; // omit trailing null byte

		int headersize = size + 36;
		int soundsize = size;
		memcpy(header + 4, &headersize, sizeof(headersize));
		memcpy(header + 40, &soundsize, sizeof(soundsize));

		newsound = new unsigned char[44 + size];
		memcpy(newsound, header, 44);

		// TFTD sounds are signed, so we need to convert them.
		for (unsigned int n = 5; n < size + 5; ++n)
		{
			int value = (int)sound[n] + 128;
			sound[n] = (uint8_t)value;
		}

		if (size) memcpy(newsound + 44, sound+5, size);
		size = size + 44;
	}

	Sound *s = new Sound();
	try
	{
		if (size == 0)
		{
			throw Exception("Invalid sound file");
		}
		s->load(newsound, size);
	}
	catch (const Exception &)
	{
		// Ignore junk in the file
	}
	_sounds[getTotalSounds()] = s;

	delete[] sound;
	delete[] newsound;
}