* 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 */
| 53 | * @sa http://www.ufopaedia.org/index.php?title=SOUND |
| 54 | */ |
| 55 | void SoundSet::loadCat(const std::string &filename, bool wav) |
| 56 | { |
| 57 | // Load CAT file |
| 58 | CatFile sndFile (filename.c_str()); |
| 59 | if (!sndFile) |
| 60 | { |
| 61 | throw Exception(filename + " not found"); |
| 62 | } |
| 63 | |
| 64 | // Load each sound file |
| 65 | for (int i = 0; i < sndFile.getAmount(); ++i) |
| 66 | { |
| 67 | // Read WAV chunk |
| 68 | unsigned char *sound = (unsigned char*) sndFile.load(i); |
| 69 | unsigned int size = sndFile.getObjectSize(i); |
| 70 | |
| 71 | // If there's no WAV header (44 bytes), add it |
| 72 | // Assuming sounds are 8-bit 8000Hz (DOS version) |
| 73 | unsigned char *newsound = 0; |
| 74 | if (!wav) |
| 75 | { |
| 76 | if (size != 0) |
| 77 | { |
| 78 | char header[] = {'R', 'I', 'F', 'F', 0x00, 0x00, 0x00, 0x00, 'W', 'A', 'V', 'E', 'f', 'm', 't', ' ', |
| 79 | 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x11, 0x2b, 0x00, 0x00, 0x11, 0x2b, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, |
| 80 | 'd', 'a', 't', 'a', 0x00, 0x00, 0x00, 0x00}; |
| 81 | |
| 82 | for (unsigned int n = 0; n < size; ++n) sound[n] *= 4; // scale to 8 bits |
| 83 | if (size > 5) size -= 5; // skip 5 garbage name bytes at beginning |
| 84 | if (size) size--; // omit trailing null byte |
| 85 | |
| 86 | int headersize = size + 36; |
| 87 | int soundsize = size; |
| 88 | memcpy(header + 4, &headersize, sizeof(headersize)); |
| 89 | memcpy(header + 40, &soundsize, sizeof(soundsize)); |
| 90 | |
| 91 | newsound = new unsigned char[44 + size*2]; |
| 92 | memcpy(newsound, header, 44); |
| 93 | if (size) memcpy(newsound + 44, sound+5, size); |
| 94 | Uint32 step16 = (8000<<16)/11025; |
| 95 | Uint8 *w = newsound+44; |
| 96 | int newsize = 0; |
| 97 | for (Uint32 offset16 = 0; (offset16>>16) < size; offset16 += step16, ++w, ++newsize) |
| 98 | { |
| 99 | *w = sound[5 + (offset16>>16)]; |
| 100 | } |
| 101 | size = newsize + 44; |
| 102 | } |
| 103 | } |
| 104 | else if (0x40 == sound[0x18] && 0x1F == sound[0x19] && 0x00 == sound[0x1A] && 0x00 == sound[0x1B]) |
| 105 | { |
| 106 | // so it's WAV, but in 8 khz, we have to convert it to 11 khz sound |
| 107 | |
| 108 | unsigned char *sound2 = new unsigned char[size*2]; |
| 109 | |
| 110 | // rewrite the samplerate in the header to 11 khz |
| 111 | sound[0x18]=0x11; sound[0x19]=0x2B; sound[0x1C]=0x11; sound[0x1D]=0x2B; |
| 112 |
no test coverage detected