From e92fb3db7ff3e26df16f8db6dd2d080cdbeb3f98 Mon Sep 17 00:00:00 2001 From: Ilya Shurumov Date: Thu, 3 Dec 2020 17:33:49 +0600 Subject: [PATCH] - remove dump_music as it moved to OpenDriver2Tools --- tools/dump_music/dump_music.cpp | 740 -------------------- tools/dump_music/dump_music.vcxproj | 157 ----- tools/dump_music/dump_music.vcxproj.filters | 22 - 3 files changed, 919 deletions(-) delete mode 100644 tools/dump_music/dump_music.cpp delete mode 100644 tools/dump_music/dump_music.vcxproj delete mode 100644 tools/dump_music/dump_music.vcxproj.filters diff --git a/tools/dump_music/dump_music.cpp b/tools/dump_music/dump_music.cpp deleted file mode 100644 index ce4234e8..00000000 --- a/tools/dump_music/dump_music.cpp +++ /dev/null @@ -1,740 +0,0 @@ -#include -#include - -// WAV file header and smpl-chunk template - Quick and dirty solution because I'm lazy -int wavHeader[11] = { - 0x46464952, 0, 0x45564157, 0x20746D66, - 0x10, 0x10001, 0, 0, - 0x100002, 0x61746164, 0 -}; - -int smplChunk[17] = { - 0x6C706D73, 0x3C, 0, 0, - 0x1D316, 0x3C, 0, 0, - 0, 1, 0, 0, - 0, 0, 0, 0, - 0 -}; - -// PSX ADPCM coefficients -const double K0[5] = { 0, 0.9375, 1.796875, 1.53125, 1.90625 }; -const double K1[5] = { 0, 0, -0.8125, -0.859375, -0.9375 }; - -// PSX ADPCM decoding routine - decodes a single sample -short vagToPcm(unsigned char soundParameter, int soundData, double* vagPrev1, double* vagPrev2) -{ - int resultInt = 0; - - double dTmp1 = 0.0; - double dTmp2 = 0.0; - double dTmp3 = 0.0; - - if (soundData > 7) - soundData -= 16; - - dTmp1 = (double)soundData * pow(2, (double)(12 - (soundParameter & 0x0F))); - - dTmp2 = (*vagPrev1) * K0[(soundParameter >> 4) & 0x0F]; - dTmp3 = (*vagPrev2) * K1[(soundParameter >> 4) & 0x0F]; - - (*vagPrev2) = (*vagPrev1); - (*vagPrev1) = dTmp1 + dTmp2 + dTmp3; - - resultInt = (int)round((*vagPrev1)); - - if (resultInt > 32767) - resultInt = 32767; - - if (resultInt < -32768) - resultInt = -32768; - - return (short)resultInt; -} - -// Main decoding routine - Takes PSX ADPCM formatted audio data and converts it to PCM. It also extracts the looping information if used. -void decodeSound(unsigned char* iData, short* oData, int soundSize, int* loopStart, int* loopLength) -{ - unsigned char sp = 0; - int sd = 0; - double vagPrev1 = 0.0; - double vagPrev2 = 0.0; - int k = 0; - - for (int i = 0; i < soundSize; i++) - { - if (i % 16 == 0) - { - sp = iData[i]; - - if ((iData[i + 1] & 0x0E) == 6) - (*loopStart) = k; - - if ((iData[i + 1] & 0x0F) == 3 || (iData[i + 1] & 0x0F) == 7) - (*loopLength) = (k + 28) - (*loopStart); - - i += 2; - } - - sd = (int)iData[i] & 0x0F; - oData[k++] = vagToPcm(sp, sd, &vagPrev1, &vagPrev2); - sd = ((int)iData[i] >> 4) & 0x0F; - oData[k++] = vagToPcm(sp, sd, &vagPrev1, &vagPrev2); - } -} - -void XM_Sample2Delta(short *p, int len) -{ - short news, olds; - - news = 0; - for (int i = 0; i < len; ++i) - { - olds = p[i]; - p[i] -= news; - news = olds; - } -} - -//------------------------------------------------------------------------------------ - -#define XM_SONGS 8 - -#define XM_INSTR_HEADER_SIZE 263 -#define XM_MAX_CHANNELS 32 - -struct song_t -{ - int xm_offset; - int bank_offset; -}; - -struct SAMPLE_DATA -{ - unsigned long address; - unsigned long length; - unsigned long loop; - unsigned long samplerate; -}; - -struct PCMSample -{ - short* data; - int length; - int loopStart; - int loopLength; -}; - -struct XM_Note -{ - unsigned char note; - unsigned char inst; - unsigned char volc; - unsigned char efft; - unsigned char effp; -}; - -#pragma pack(push,1) - -struct XM_SampleHeader -{ - int32_t len, repS, repL; - uint8_t vol; - int8_t fine; - uint8_t typ, pan; - int8_t relTon; - uint8_t reserved; - char name[22]; -}; - -struct XM_InstHeaeder -{ - uint32_t instrSize; - char name[22]; - uint8_t typ; - int16_t antSamp; - int32_t sampleSize; - uint8_t ta[96]; - int16_t envVP[12][2], envPP[12][2]; - uint8_t envVPAnt, envPPAnt; - uint8_t envVSust, envVRepS, envVRepE; - uint8_t envPSust, envPRepS, envPRepE; - uint8_t envVTyp, envPTyp; - uint8_t vibTyp, vibSweep, vibDepth, vibRate; - uint16_t fadeOut; - uint8_t midiOn, midiChannel; - int16_t midiProgram, midiBend; - int8_t mute; - uint8_t reserved[15]; - XM_SampleHeader samp[16]; -}; - -#pragma pack(pop) - -int DecompressAndRestoreXM(char* destXM, char* xmData, int srcSize, PCMSample* samples) -{ - char* destOrig = destXM; - char* srcOrig = xmData; - - memcpy(destXM, xmData, 336); - - unsigned short* version = (unsigned short*)(&destXM[58]); - - // check if it's an XMPlay version (superpacked) - if (*version != 0xDDBA) - { - memcpy(destXM, xmData, srcSize); - return srcSize; - } - - printf("Decompressing XM...\n"); - - // convert XM to standard version - *version = 0x104; - - destXM += 336; // go to patterns - xmData += 68; - - short numChannels = *(short*)xmData; xmData += 2; - short numPatterns = *(short*)xmData; xmData += 2; - short numInstruments = *(short*)xmData; xmData += 264; // skip other header data since it's not changed - - printf("channel count: %d\n", numChannels); - - printf("Unpacking %d patterns\n", numPatterns); - - XM_Note rowNotes[XM_MAX_CHANNELS]; // more for safety - - for (int i = 0; i < numPatterns; i++) - { - xmData += 5; - int pattLen = *(short*)xmData; - xmData -= 5; - - memcpy(destXM, xmData, 7); // copy pattern header properties - destXM += 7; - xmData += 7; - - short patternSize = *(short*)xmData; - xmData += sizeof(short); // now pattern data itself - - short* unpackedPatternSize = (short*)destXM; - destXM += sizeof(short); - - // no empty reads - if (patternSize == 0) - continue; - - char* pattStartSrc = xmData; - char* pattStart = destXM; - - for (int r = 0; r < pattLen; r++) - { - // zero full channel size double from current position - memset(rowNotes, 0, sizeof(rowNotes)); - - while (1) - { - // don't overflow reading - if ((xmData - pattStartSrc) >= patternSize) - break; - - unsigned char patdat = *xmData++; - - if (patdat == 0xFF) // channel end - break; - - unsigned char data = 0; - - XM_Note& xmnote = rowNotes[patdat]; - - // unpack it fully - unsigned char note = *xmData++; - if (note & 0x80) - { - data = 0; if (note & 0x01) data = *xmData++; xmnote.note = data; - data = 0; if (note & 0x02) data = *xmData++; xmnote.inst = data; - data = 0; if (note & 0x04) data = *xmData++; xmnote.volc = data; - data = 0; if (note & 0x08) data = *xmData++; xmnote.efft = data; - data = 0; if (note & 0x10) data = *xmData++; xmnote.effp = data; - } - else - { - xmnote.note = note; - xmnote.inst = *xmData++; - xmnote.volc = *xmData++; - xmnote.efft = *xmData++; - xmnote.effp = *xmData++; - } - } - - // pack notes again - for (int c = 0; c < numChannels; c++) - { - XM_Note& xmnote = rowNotes[c]; - - if (xmnote.note > 0 && - xmnote.inst > 0 && - xmnote.volc > 0 && - xmnote.efft > 0 && - xmnote.effp > 0) - { - // write full note - memcpy(destXM, &xmnote, sizeof(XM_Note)); - destXM += sizeof(XM_Note); - } - else - { - char* packedFlag = destXM++; - - *packedFlag = 0x80; - - if (xmnote.note > 0) { *destXM++ = xmnote.note; *packedFlag |= 0x01; } - if (xmnote.inst > 0) { *destXM++ = xmnote.inst; *packedFlag |= 0x02; } - if (xmnote.volc > 0) { *destXM++ = xmnote.volc; *packedFlag |= 0x04; } - if (xmnote.efft > 0) { *destXM++ = xmnote.efft; *packedFlag |= 0x08; } - if (xmnote.effp > 0) { *destXM++ = xmnote.effp; *packedFlag |= 0x10; } - } - } - } - - *unpackedPatternSize = destXM - pattStart; - } - - printf("instrument count: %d\n", numInstruments); - - for (int i = 0; i < numInstruments; i++) - { - char* instStart = xmData; - - XM_InstHeaeder* instr = (XM_InstHeaeder*)xmData; - - { - int readSize = instr->instrSize; - if ((readSize < 4) || (readSize > XM_INSTR_HEADER_SIZE)) - readSize = XM_INSTR_HEADER_SIZE; - - if (instr->instrSize > XM_INSTR_HEADER_SIZE) - readSize += instr->instrSize - XM_INSTR_HEADER_SIZE; - - printf("instr %d size: %d readSize: %d\n", i, instr->instrSize, readSize); - - memcpy(destXM, xmData, readSize); - - xmData += readSize; - destXM += readSize; - } - - printf("instr name: %s\n", instr->name); - printf("sample count: %d\n", instr->antSamp); - - // since the XMPlay for PSX does not - // support more than one samples, we don't bother... - if (instr->antSamp > 0) - { - //if (i == 17) - // printf("flash!\n"); - - printf("sample: %s typ %d\n", instr->samp[0].name, instr->samp[0].typ); - - // samples are direct to the instrument number, - // so we don't bother here too... - PCMSample& sample = samples[i]; - - if ((instr->samp[0].typ & 0x16)) - { - instr->samp[0].len = sample.length * sizeof(short); - instr->samp[0].repS = sample.loopStart * sizeof(short); - instr->samp[0].repL = sample.loopLength * sizeof(short); - } - - // write headers - int readSize = instr->antSamp * sizeof(XM_SampleHeader); - - memcpy(destXM, xmData, readSize); - xmData += readSize; - destXM += readSize; - - if ((instr->samp[0].typ & 0x16)) - { - // right after the instrument data comes the sample data - // there is nothing to read, but there is something to write... - XM_Sample2Delta(sample.data, sample.length); - - memcpy(destXM, sample.data, sample.length * sizeof(short)); - destXM += sample.length * sizeof(short); - } - } - } - - int remainingStart = (xmData - srcOrig); - int remaining = srcSize - remainingStart; - - // copy remaining data - memcpy(destXM, xmData, remaining); - destXM += remaining; - - return destXM-destOrig; -} - -//----------------------------------------------------------------------------- - -int LoadSoundBank(SAMPLE_DATA* out_sample_info, PCMSample* out_samples, FILE* fp) -{ - int numBankSamples = 0; - fread(&numBankSamples, sizeof(int), 1, fp); - - printf("bank sounds: %d\n", numBankSamples); - - fread(out_sample_info, sizeof(SAMPLE_DATA), numBankSamples, fp); - - int bankSamplesOffset = ftell(fp); - - printf("bank sounds: %d\n", numBankSamples); - - for (int j = 0; j < numBankSamples; j++) - { - SAMPLE_DATA& sample = out_sample_info[j]; - PCMSample& pcmSample = out_samples[j]; - - if (sample.loop == 0) - sample.length -= 16; - - if (sample.length == 0) - continue; - - // read VAG and convert to ADPCM - { - unsigned char* iData = (unsigned char*)malloc(sample.length); - - pcmSample.length = (sample.length >> 4) * 28; - pcmSample.data = new short[pcmSample.length]; - - fseek(fp, bankSamplesOffset + sample.address, SEEK_SET); - fread(iData, sizeof(char), sample.length, fp); // Read the audio data - - decodeSound(iData, pcmSample.data, sample.length, &pcmSample.loopStart, &pcmSample.loopLength); - - free(iData); - - printf("sample %d rate=%d loop=%d size=%d\n", j, sample.samplerate, sample.loop, pcmSample.length); - } - } - - return numBankSamples; -} - -int DoConvertSBK(const char* sbkFileName) -{ - char tmpString[_MAX_PATH]; - snprintf(tmpString, _MAX_PATH, "%s_dec", sbkFileName); - - printf("Loading '%s'...\n", sbkFileName); - - FILE* sbkFp = fopen(sbkFileName, "rb"); - - if (!sbkFp) - { - printf("No such file '%s'!", sbkFileName); - return -1; - } - - CreateDirectoryA(tmpString, NULL); - - PCMSample pcmSamples[80]; - SAMPLE_DATA sampleDescs[80]; - memset(pcmSamples, 0, sizeof(PCMSample) * 80); - memset(sampleDescs, 0, sizeof(SAMPLE_DATA) * 80); - - int numBankSamples = LoadSoundBank(sampleDescs, pcmSamples, sbkFp); - - for (int i = 0; i < numBankSamples; i++) - { - PCMSample& sample = pcmSamples[i]; - SAMPLE_DATA& sampleDesc = sampleDescs[i]; - - snprintf(tmpString, _MAX_PATH, "%s_dec\\%d.wav", sbkFileName, i); - - FILE* wavfp = fopen(tmpString, "wb"); - - if (wavfp) - { - // Prepare the WAV file header - wavHeader[1] = sample.length * sizeof(short) + 36; // Size of the "RIFF" chunk - - if (sample.loopLength > 0) - wavHeader[1] += 68; - - wavHeader[6] = sampleDesc.samplerate; // Sampling rate - wavHeader[7] = wavHeader[6] * sizeof(short); // Average bytes per second - wavHeader[10] = sample.length * sizeof(short); // Size of the "data" chunk - - // Write WAV file header, the converted audio data, and the loop positions if used - fwrite(&wavHeader, sizeof(int), 11, wavfp); - fwrite(sample.data, sizeof(short), sample.length, wavfp); - if (sample.loopLength > 0) - { - smplChunk[13] = sample.loopStart * sizeof(short); - smplChunk[14] = sample.loopStart * sizeof(short) + sample.loopLength * sizeof(short); - fwrite(&smplChunk, sizeof(int), 17, wavfp); - } - - fclose(wavfp); - } - else - printf("Unable to create file %s\n", tmpString); - - } - - return 0; -} - -int DoConvertXMAndSBK(const char* xmFilename) -{ - char tmpString[_MAX_PATH]; - char sbkFileName[_MAX_PATH]; - strcpy_s(sbkFileName, xmFilename); - - char* extStr = strchr(sbkFileName, '.'); - if (extStr) - strcpy(extStr, ".sbk"); - - FILE* psxXmFp = fopen(xmFilename, "rb"); - - if (!psxXmFp) - { - printf("No such file '%s'!", xmFilename); - return -1; - } - - FILE* sbkFp = fopen(sbkFileName, "rb"); - - if (!sbkFp) - { - printf("No such file '%s'!", sbkFileName); - return -1; - } - - printf("Loading '%s' & '%s'...\n", xmFilename, sbkFileName); - - PCMSample pcmSamples[80]; - SAMPLE_DATA sampleDescs[80]; - memset(pcmSamples, 0, sizeof(PCMSample) * 80); - memset(sampleDescs, 0, sizeof(SAMPLE_DATA) * 80); - - int numBankSamples = LoadSoundBank(sampleDescs, pcmSamples, sbkFp); - - // restore XM and save to disk - { - *extStr = 0; - - printf("--- XM song '%s' ---\n", sbkFileName); - sprintf_s(tmpString, "%s_orig.xm", sbkFileName); - - FILE* xmFp = fopen(tmpString, "wb"); - - if (xmFp) - { - fseek(psxXmFp, 0, SEEK_END); - int songSize = ftell(psxXmFp); - fseek(psxXmFp, 0, SEEK_SET); - - // read the PSX XM - char* xmData = (char*)malloc(songSize); - fread(xmData, songSize, 1, psxXmFp); - - fclose(psxXmFp); - - // calculate new XM size according to samples - int addSize = 0; - - for (int j = 0; j < numBankSamples; j++) - { - //printf("sample %d rate=%d loop=%d size=%d\n", j, sample.samplerate, sample.loop, sample.length); - addSize += pcmSamples[j].length * sizeof(short); - } - - int calculatedXMSize = songSize * 4 + addSize; - - // decompress - char* newXMData = (char*)malloc(calculatedXMSize); // the new size is pretty hardcoded setting - - songSize = DecompressAndRestoreXM(newXMData, xmData, songSize, pcmSamples); - - free(xmData); - xmData = newXMData; - - fwrite(xmData, 1, songSize, xmFp); - fclose(xmFp); - - free(xmData); - } - else - printf("ERROR: can't open '%s' for write!", tmpString); - } - - // free samples - for (int j = 0; j < numBankSamples; j++) - { - delete[] pcmSamples[j].data; - pcmSamples[j].data = nullptr; - } - - // close handles - fclose(sbkFp); - - return 0; -} - -int DoExtractMusicFile(const char* fileName) -{ - FILE* fp = fopen(fileName, "rb"); - - if (!fp) - { - printf("No such file '%s'!", fileName); - return -1; - } - - printf("Loading '%s'...\n", fileName); - - //char songPath[_MAX_PATH]; - char tmpString[_MAX_PATH]; - - // max 80 samples per bank - PCMSample pcmSamples[80]; - SAMPLE_DATA sampleDescs[80]; - song_t songs[XM_SONGS]; - int numBankSamples = 0; - - // read song offsets - fread(songs, sizeof(song_t), XM_SONGS, fp); - - for (int i = 0; i < XM_SONGS; i++) - { - const song_t& offsets = songs[i]; - - int songSize = offsets.bank_offset - offsets.xm_offset; - - printf("--- XM song %d at %d (size %d) ---\n", i, offsets.xm_offset, songSize); - - // create folder for song - //sprintf_s(songPath, "%s_song_%d", fileName, i); - //CreateDirectoryA(songPath, NULL); // Create the sound bank directory - - // Read XM and store to separate file - fseek(fp, offsets.xm_offset, SEEK_SET); - - char* xmData = (char*)malloc(songSize); - fread(xmData, songSize, 1, fp); - - // Read sound bank and then convert it using vabdecode - fseek(fp, offsets.bank_offset, SEEK_SET); - - memset(pcmSamples, 0, sizeof(PCMSample) * 80); - memset(sampleDescs, 0, sizeof(SAMPLE_DATA) * 80); - - numBankSamples = LoadSoundBank(sampleDescs, pcmSamples, fp); - - // restore XM and save to disk - { - printf("--- XM song %d ---\n", i); - sprintf_s(tmpString, "%s_song%d.xm", fileName, i); - - FILE* xmFp = fopen(tmpString, "wb"); - - if (xmFp) - { - - // calculate new XM size according to samples - int addSize = 0; - - for (int j = 0; j < numBankSamples; j++) - { - //printf("sample %d rate=%d loop=%d size=%d\n", j, sample.samplerate, sample.loop, sample.length); - addSize += pcmSamples[j].length * sizeof(short); - } - - int calculatedXMSize = songSize * 4 + addSize; - - // decompress - char* newXMData = (char*)malloc(calculatedXMSize); // the new size is pretty hardcoded setting - - songSize = DecompressAndRestoreXM(newXMData, xmData, songSize, pcmSamples); - - free(xmData); - xmData = newXMData; - - fwrite(xmData, 1, songSize, xmFp); - fclose(xmFp); - } - else - printf("ERROR: can't open '%s' for write!", tmpString); - - free(xmData); - } - - // free samples - for (int j = 0; j < numBankSamples; j++) - { - delete[] pcmSamples[j].data; - pcmSamples[j].data = nullptr; - } - } - - fclose(fp); - - return 0; -} - -int DoAssembleMusicFile(const char* folder) -{ - - - return 0; -} - -//----------------------------------------------------- - -int main(int argc, char** argv) -{ - if (argc <= 1) - { - printf("usage:\n"); - printf("\tdump_music -bin2xm MUSIC.BIN\n"); - printf("\tdump_music -psx2xm FETUNE.XM\n"); - printf("\tdump_music -sbk2wav SOUNDS.SBK\n"); - - return -1; - } - - for (int i = 0; i < argc; i++) - { - if (!_stricmp(argv[i], "-bin2xm")) - { - if (i + 1 <= argc) - DoExtractMusicFile(argv[i + 1]); - else - printf("-extract must have an argument!"); - } - else if (!_stricmp(argv[i], "-psx2xm")) - { - if (i + 1 <= argc) - DoConvertXMAndSBK(argv[i + 1]); - else - printf("-psx2xm must have an argument!"); - } - else if (!_stricmp(argv[i], "-sbk2wav")) - { - if (i + 1 <= argc) - DoConvertSBK(argv[i + 1]); - else - printf("-sbk2wav must have an argument!"); - } - else if (!_stricmp(argv[i], "-a") || !_stricmp(argv[i], "-assemble")) - { - - } - } - - return 0; -} \ No newline at end of file diff --git a/tools/dump_music/dump_music.vcxproj b/tools/dump_music/dump_music.vcxproj deleted file mode 100644 index 20e4959f..00000000 --- a/tools/dump_music/dump_music.vcxproj +++ /dev/null @@ -1,157 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 15.0 - {E82851E6-2037-4D5A-9C8B-910DBCD09783} - Win32Proj - dumpmusic - 10.0.17763.0 - - - - Application - true - v141 - Unicode - - - Application - false - v141 - true - Unicode - - - Application - true - v141 - Unicode - - - Application - false - v141 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - - - true - - - false - - - false - - - - Level3 - Disabled - true - WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - - - Console - true - - - - - Use - Level3 - Disabled - true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - pch.h - - - Console - true - - - - - NotUsing - Level3 - MaxSpeed - true - true - true - WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - pch.h - - - Console - true - true - true - - - - - Use - Level3 - MaxSpeed - true - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - pch.h - - - Console - true - true - true - - - - - - - - - \ No newline at end of file diff --git a/tools/dump_music/dump_music.vcxproj.filters b/tools/dump_music/dump_music.vcxproj.filters deleted file mode 100644 index 43813b68..00000000 --- a/tools/dump_music/dump_music.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Исходные файлы - - - \ No newline at end of file