Subversion Repositories spk

Rev

Rev 289 | Rev 325 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 Voice file Creation V1.00 Created by Cycrow (Matthew Gravestock)
*/

// Main Spk File Library Include
#ifdef _WIN32
#include <spk.h>
#include <StringList.h>
#else
#include "../spk/spk.h"
#endif
#include <time.h>

#ifdef _WIN32
#include <windows.h>
#include <direct.h>
#include <shlobj.h>
#endif

#include "sndfile.hh"


void PrintSyntax (const Utils::WString &cmd)
{       
        wprintf ( L"Syntax: %s </command> [options]\n", cmd.c_str());
        wprintf ( L"\nCommands:\n" );
        /*
        printf ( "   /list\n\t- Lists installed packages\n" );
        printf ( "   /install <file>\n\t- Installs a package file\n" );
        printf ( "   /uninstall <package#>\n\t- Uninstalls a package, use id number from list\n" );
        printf ( "   /enable <package#>\n\t- Enables an installed package\n" );
        printf ( "   /disable <package#>\n\t- Disables an installed package\n" );
        printf ( "   /removeuninstall\n\t- Removes uninstall scripts\n" );
        printf ( "   /removeshared\n\t- Removes unused sharded files\n" );
        printf ( "\nSwitchs:\n" );
        printf ( "   -d (--directory) [directory]\n\tChange destination directory, otherwise uses current\n\n" );
        printf ( "   -v (--verbose)\n\tTurns on verbose mode\n\n" );
        printf ( "   -o (--override)\n\tOverride install warnings\n\tIE. allows you to install older scripts\n\n" );
        printf ( "   -t (--textrename)\n\tForces text file renaming for installed packages\n\n" );
        printf ( "   -l (--language) <language>\n\tSets the language id for text file renaming\n\totheriwse reads game lang.dat\n\n" );
        printf ( "   -c (--enablechild)\n\tAuto Enabled all children when parent is enabled\n\n" );
        printf ( "   -m (--forcemod\n\tForces a mod enabled even if theres one already enabled\n\n" );  
        */
}

void Pause()
{
#ifdef _DEBUG
        char pause;
        scanf ( "%s", &pause );
#endif
}

#define BUFFER_LEN 4096


void DoOffset(const Utils::WString &cmd, const Utils::WStringList &options, const std::vector<Utils::WString> &args)
{
        if (args.size() < 2)
        {
                wprintf(L"Syntax: %s offset [options] <offset> <file> [--out:<file>]\n", cmd.c_str());
                wprintf(L"      <offset>\t\tOffset time to adjust by\n");
                wprintf(L"      <file>\t\tThe file to adjust\n");
                wprintf(L"\nOptions:\n");
                wprintf(L"  --out:<file>\t\tThe output filename, otherwise, will write to the input\n");
                wprintf(L"  --page:<id>\t\tThe page id to read (otherwise will do all of them)\n");
        }
        else
        {
                Utils::WString offsetStr = args[0];
                Utils::WString fileStr = args[1];
                Utils::WString outFileStr = options.contains(L"out") ? options[L"out"]->data : fileStr;
                unsigned int pageID = options.contains(L"page") ? options[L"page"]->data.toInt() : 0;
                long offset = offsetStr.toLong();
                bool doIgnore = options.contains(L"ignore");

                CFileIO f;
                if (f.open(fileStr))
                {
                        bool inPage = false;
                        bool ignore = false;
                        Utils::WStringList list;
                        Utils::WStringList outList;
                        if (f.readLines(list))
                        {
                                for (auto itr = list.begin(); itr != list.end(); itr++)
                                {
                                        Utils::WString line = (*itr)->str;
                                        if (line.contains(L"<page id=\""))
                                        {
                                                long id = line.between(L"<page id=\"", L"\"").toLong();
                                                if (pageID == 0 || pageID == id)
                                                        inPage = true;
                                                else
                                                        ignore = true;
                                        }
                                        else if (line.contains(L"</page>"))
                                                inPage = false;
                                        else if (inPage)
                                        {
                                                long pos = line.findPos(L"s=\"");
                                                if (pos != -1)
                                                {
                                                        Utils::WString s = line.substr(pos + 3);
                                                        s = s.token(L"\"", 1);
                                                        long long time = s.toLong64();
                                                        long long toTime = time + offset;
                                                        line = line.findReplace(time, toTime);
                                                }
                                        }

                                        if(!ignore || !doIgnore)
                                                outList.pushBack(line);

                                        if (line.contains(L"</page>"))
                                                ignore = false;
                                }
                                CFileIO outFile(outFileStr);
                                outFile.writeFile(&outList);
                                outFile.close();
                        }
                }
                else
                        wprintf(L"Error: Unable to open file, %s\n", fileStr.c_str());
        }

}

/*
        Main entry point to program
*/
int main ( int argc, char **argv )
{
        // display program header to command prompt
        printf ( "\nX3 Voice Create V1.00 (SPK Library Version %.2f) 15/12/2023 Created by Cycrow\n\n", GetLibraryVersion() );

        // parse the cmd name
        Utils::WString cmd (argv[0]);
        Utils::WString command(argc > 1 ? argv[1] : "");
        cmd = cmd.findReplace(L"\\", L"/");
        Utils::WString cmdDir = cmd.tokens(L"/", 1, cmd.countToken(L"/") - 1);
        cmd = cmd.token(L"/", cmd.countToken(L"/"));

        Utils::WStringList options;
        std::vector<Utils::WString> args;
        for (int i = 2; i < argc; i++)
        {
                Utils::WString arg(argv[i]);
                if (arg.startsWith(L"--"))
                {
                        arg = arg.substr(2);

                        if (arg.contains(L":"))
                        {
                                Utils::WString a = arg.token(L":", 1);
                                Utils::WString b = arg.tokens(L":", 2);
                                options.pushBack(a, b);
                        }
                        else
                                options.pushBack(arg);
                }
                else
                        args.push_back(arg);
        }

        if (command == L"offset")
                DoOffset(cmd, options, args);
        else if (command == L"help")
        {
                PrintSyntax(cmd);
        }
        else
        {

                Utils::String mainFileStr = "d:/x/X3 Terran Conflict - Guilds/addon2/mov/00344.wav";
                Utils::WString dir = L"d:/x/X3 Terran Conflict - Guilds/addon2/mov/working";
                Utils::String output = "d:/x/X3 Terran Conflict - Guilds/addon2/mov/working/00344.wav";
                Utils::WString outputXML = L"d:/x/X3 Terran Conflict - Guilds/addon2/mov/working/00044.xml";

                SF_INFO info;
                SNDFILE* mainFile = sf_open(mainFileStr.c_str(), SFM_READ, &info);
                if (mainFile)
                {
                        double duration = static_cast<double>(info.frames) / static_cast<double>(info.samplerate);
                        size_t currentPos = static_cast<size_t>((duration * 1000.0) + 0.5);

                        CFileIO(mainFileStr).copy(output);


                        SF_INFO outInfo;
                        SNDFILE* outputFile = sf_open(output.c_str(), SFM_RDWR, &outInfo);
                        if (outputFile)
                        {
                                double buffer[BUFFER_LEN];

                                int check = sf_format_check(&outInfo);
                                sf_count_t seek = sf_seek(outputFile, 0, SEEK_END);

                                Utils::WStringList xmlOut;
                                xmlOut.pushBack(L"<?xml version=\"1.0\" ?>");
                                xmlOut.pushBack(L"<language id=\"44\">");

                                CDirIO D(dir);
                                Utils::WStringList list;
                                if (D.dirList(list))
                                {
                                        for (auto itr = list.begin(); itr != list.end(); itr++)
                                        {
                                                if (D.isDir((*itr)->str))
                                                {
                                                        CDirIO curDir(D.dir((*itr)->str));
                                                        long pageID = (*itr)->str.toInt();

                                                        xmlOut.pushBack(Utils::WString(L"<page id=\"") + pageID + L"\" stream=\"3\">");

                                                        Utils::WStringList idList;
                                                        if (curDir.dirList(idList))
                                                        {
                                                                for (auto itr2 = idList.begin(); itr2 != idList.end(); itr2++)
                                                                {
                                                                        if (curDir.isFile((*itr2)->str))
                                                                        {
                                                                                CFileIO F(curDir.file((*itr2)->str));
                                                                                long id = F.baseName().toInt();
                                                                                size_t len = 0;

                                                                                SF_INFO inInfo;
                                                                                SNDFILE* inputFile = sf_open(F.fullFilename().toString().c_str(), SFM_READ, &inInfo);
                                                                                if (inputFile)
                                                                                {
                                                                                        double duration = static_cast<double>(inInfo.frames) / static_cast<double>(inInfo.samplerate);
                                                                                        size_t len = static_cast<size_t>((duration * 1000.0) + 0.5);


                                                                                        sf_count_t readcount;
                                                                                        while ((readcount = sf_read_double(inputFile, buffer, BUFFER_LEN)) > 0)
                                                                                                sf_write_double(outputFile, buffer, readcount);
                                                                                        //int* data = new int[inInfo.frames * inInfo.channels];
                                                                                        //sf_count_t readCount = sf_readf_int(inputFile, data, inInfo.frames);
                                                                                        //sf_count_t writeCount = sf_writef_int(outputFile, data, inInfo.frames);

                                                                                        xmlOut.pushBack(Utils::WString(L"\t<t id=\"") + id + L"\" s=\"" + (long)currentPos + L"\" l=\"" + (long)len + "\"/>");
                                                                                        currentPos += len;
                                                                                        sf_close(inputFile);
                                                                                }
                                                                        }
                                                                }
                                                        }

                                                        xmlOut.pushBack(L"</page>");
                                                }
                                        }
                                }

                                xmlOut.pushBack("</language>");

                                sf_close(outputFile);

                                CFileIO xml(outputXML);
                                xml.writeFile(&xmlOut);
                        }

                        sf_close(mainFile);
                }
        }
        //Pause();

        return 0;
}