#include "pch.h"
#include "FSBExtract.h"
using namespace std;
void WriteWAVHeader
(
FILE* file,
unsigned int sampleRate,
short bitsPerChannel,
short numChannels,
unsigned int dataLen
);
int WaveCount(char* fsb);
extern "C" NATIVEDLL_API char* __cdecl ExtractWav(char* fsb, char* folder, int index)
{
FMOD::System *system;
FMOD::Sound *sound, *sound_to_play;
FMOD_RESULT result;
FMOD_SOUND_TYPE stype;
FMOD_SOUND_FORMAT sformat;
FILE* file = NULL;
unsigned int version, bs, dataLen, nameLength = 64;
void *extradriverdata = 0, *buffer = 0;
int schannels, numsubsounds, sbits;
char subsoundsName[64];
char* error;
float ssamplerate;
/*
Create a System object and initialize
*/
result = FMOD::System_Create(&system);
result = system->getVersion(&version);
if (result != FMOD_OK)
{
error = "fsb is the wrong version";
return error;
}
result = system->init(1, FMOD_INIT_NORMAL, extradriverdata);
result = system->createSound(fsb, FMOD_CREATESTREAM, 0, &sound);
if (result != FMOD_OK)
{
error = "There is a problem with the fsb file";
return error;
}
result = sound->getNumSubSounds(&numsubsounds);
if (numsubsounds)
{
sound->getSubSound(0, &sound_to_play);
}
else
{
sound_to_play = sound;
}
sound->getSubSound(index, &sound_to_play);
sound_to_play->seekData(0);
result = sound_to_play->getDefaults(&ssamplerate, &sbits);
result = sound->getFormat(&stype, &sformat, &schannels, &sbits);
result = sound_to_play->getLength(&bs, FMOD_TIMEUNIT_PCMBYTES);
result = sound_to_play->getName(subsoundsName, nameLength);
buffer = (char*)malloc(bs);
result = sound_to_play->readData(buffer, bs, &dataLen);
std::string dir(folder);
std::string name(subsoundsName);
std::string fsbname = dir + name;
std::vector<char> writable(fsbname.begin(), fsbname.end());
writable.push_back('\0');
errno_t error_t = fopen_s(&file, strcat(&*writable.begin(), ".wav"), "wb");
if (error_t)
{
error = "There is fopen_s error";
return error;
}
WriteWAVHeader(file, (unsigned int)ssamplerate, sbits, schannels, dataLen);
fwrite(buffer, dataLen, 1, file);
fclose(file);
free(extradriverdata);
free(buffer);
result = sound->release();
result = sound_to_play->release();
result = system->close();
result = system->release();
std::string ext("Extracting - ");
std::string filename(subsoundsName);
std::string retName = ext + filename;
std::vector<char> wn(retName.begin(), retName.end());
wn.push_back('\0');
return strcat(&*wn.begin(), ".wav");
}
void WriteWAVHeader
(
FILE* file,
unsigned int sampleRate,
short bitsPerChannel,
short numChannels,
unsigned int dataLen
)
{
const int fmtChunkLen = 16;
const unsigned short formatType = 1;
int bytesPerSecond = sampleRate * numChannels * sizeof(formatType);
short bytesPerSample = numChannels * sizeof(formatType);
unsigned int headerLen = dataLen + 36;
fwrite("RIFF", 4, 1, file);
fwrite(&headerLen, 4, 1, file);
fwrite("WAVE", 4, 1, file);
fwrite("fmt ", 4, 1, file);
fwrite(&fmtChunkLen, 4, 1, file);
fwrite(&formatType, 2, 1, file); // Format
fwrite(&numChannels, 2, 1, file); // Channels
fwrite(&sampleRate, 4, 1, file); // Sample Rate
fwrite(&bytesPerSecond, 4, 1, file); // Byterate
fwrite(&bytesPerSample, 2, 1, file); // Frame size
fwrite(&bitsPerChannel, 2, 1, file); // Bits per sample
fwrite("data", 4, 1, file);
fwrite(&dataLen, 4, 1, file); // Data Length
}
extern "C" NATIVEDLL_API int __cdecl WaveCount(char* fsb)
{
FMOD::System *system;
FMOD::Sound *sound;
FMOD_RESULT result;
unsigned int version;
void *extradriverdata = 0;
int numsubsounds;
/*
Create a System object and initialize
*/
result = FMOD::System_Create(&system);
result = system->getVersion(&version);
if (result != FMOD_OK)
{
return 0;
}
result = system->init(1, FMOD_INIT_NORMAL, extradriverdata);
result = system->createSound(fsb, FMOD_OPENONLY, 0, &sound);
if (result != FMOD_OK)
{
return 0;
}
free(extradriverdata);
result = sound->getNumSubSounds(&numsubsounds);
result = sound->release();
result = system->close();
result = system->release();
return numsubsounds;
}