| 270 | cycrow | 1 | /*
 | 
        
           |  |  | 2 |  Voice file Creation V1.00 Created by Cycrow (Matthew Gravestock)
 | 
        
           |  |  | 3 | */
 | 
        
           |  |  | 4 |   | 
        
           |  |  | 5 | // Main Spk File Library Include
 | 
        
           |  |  | 6 | #ifdef _WIN32
 | 
        
           |  |  | 7 | #include <spk.h>
 | 
        
           |  |  | 8 | #include <StringList.h>
 | 
        
           |  |  | 9 | #else
 | 
        
           |  |  | 10 | #include "../spk/spk.h"
 | 
        
           |  |  | 11 | #endif
 | 
        
           |  |  | 12 | #include <time.h>
 | 
        
           |  |  | 13 |   | 
        
           |  |  | 14 | #ifdef _WIN32
 | 
        
           |  |  | 15 | #include <windows.h>
 | 
        
           |  |  | 16 | #include <direct.h>
 | 
        
           |  |  | 17 | #include <shlobj.h>
 | 
        
           |  |  | 18 | #endif
 | 
        
           |  |  | 19 |   | 
        
           |  |  | 20 | #include "sndfile.hh"
 | 
        
           |  |  | 21 |   | 
        
           |  |  | 22 |   | 
        
           |  |  | 23 | void PrintSyntax (const Utils::WString &cmd)
 | 
        
           | 287 | cycrow | 24 | {	
 | 
        
           |  |  | 25 | 	wprintf ( L"Syntax: %s </command> [options]\n", cmd.c_str());
 | 
        
           |  |  | 26 | 	wprintf ( L"\nCommands:\n" );
 | 
        
           | 270 | cycrow | 27 | 	/*
 | 
        
           |  |  | 28 | 	printf ( "   /list\n\t- Lists installed packages\n" );
 | 
        
           |  |  | 29 | 	printf ( "   /install <file>\n\t- Installs a package file\n" );
 | 
        
           |  |  | 30 | 	printf ( "   /uninstall <package#>\n\t- Uninstalls a package, use id number from list\n" );
 | 
        
           |  |  | 31 | 	printf ( "   /enable <package#>\n\t- Enables an installed package\n" );
 | 
        
           |  |  | 32 | 	printf ( "   /disable <package#>\n\t- Disables an installed package\n" );
 | 
        
           |  |  | 33 | 	printf ( "   /removeuninstall\n\t- Removes uninstall scripts\n" );
 | 
        
           |  |  | 34 | 	printf ( "   /removeshared\n\t- Removes unused sharded files\n" );
 | 
        
           |  |  | 35 | 	printf ( "\nSwitchs:\n" );
 | 
        
           |  |  | 36 | 	printf ( "   -d (--directory) [directory]\n\tChange destination directory, otherwise uses current\n\n" );
 | 
        
           |  |  | 37 | 	printf ( "   -v (--verbose)\n\tTurns on verbose mode\n\n" );
 | 
        
           |  |  | 38 | 	printf ( "   -o (--override)\n\tOverride install warnings\n\tIE. allows you to install older scripts\n\n" );
 | 
        
           |  |  | 39 | 	printf ( "   -t (--textrename)\n\tForces text file renaming for installed packages\n\n" );
 | 
        
           |  |  | 40 | 	printf ( "   -l (--language) <language>\n\tSets the language id for text file renaming\n\totheriwse reads game lang.dat\n\n" );
 | 
        
           |  |  | 41 | 	printf ( "   -c (--enablechild)\n\tAuto Enabled all children when parent is enabled\n\n" );
 | 
        
           | 287 | cycrow | 42 | 	printf ( "   -m (--forcemod\n\tForces a mod enabled even if theres one already enabled\n\n" );	
 | 
        
           | 270 | cycrow | 43 | 	*/
 | 
        
           |  |  | 44 | }
 | 
        
           |  |  | 45 |   | 
        
           |  |  | 46 | void Pause()
 | 
        
           |  |  | 47 | {
 | 
        
           |  |  | 48 | #ifdef _DEBUG
 | 
        
           |  |  | 49 | 	char pause;
 | 
        
           |  |  | 50 | 	scanf ( "%s", &pause );
 | 
        
           |  |  | 51 | #endif
 | 
        
           |  |  | 52 | }
 | 
        
           |  |  | 53 |   | 
        
           |  |  | 54 | #define BUFFER_LEN 4096
 | 
        
           | 287 | cycrow | 55 |   | 
        
           |  |  | 56 |   | 
        
           |  |  | 57 | void DoOffset(const Utils::WString &cmd, const Utils::WStringList &options, const std::vector<Utils::WString> &args)
 | 
        
           |  |  | 58 | {
 | 
        
           |  |  | 59 | 	if (args.size() < 2)
 | 
        
           |  |  | 60 | 	{
 | 
        
           |  |  | 61 | 		wprintf(L"Syntax: %s offset [options] <offset> <file> [--out:<file>]\n", cmd.c_str());
 | 
        
           |  |  | 62 | 		wprintf(L"	<offset>\t\tOffset time to adjust by\n");
 | 
        
           |  |  | 63 | 		wprintf(L"	<file>\t\tThe file to adjust\n");
 | 
        
           |  |  | 64 | 		wprintf(L"\nOptions:\n");
 | 
        
           |  |  | 65 | 		wprintf(L"  --out:<file>\t\tThe output filename, otherwise, will write to the input\n");
 | 
        
           |  |  | 66 | 		wprintf(L"  --page:<id>\t\tThe page id to read (otherwise will do all of them)\n");
 | 
        
           |  |  | 67 | 	}
 | 
        
           |  |  | 68 | 	else
 | 
        
           |  |  | 69 | 	{
 | 
        
           |  |  | 70 | 		Utils::WString offsetStr = args[0];
 | 
        
           |  |  | 71 | 		Utils::WString fileStr = args[1];
 | 
        
           |  |  | 72 | 		Utils::WString outFileStr = options.contains(L"out") ? options[L"out"]->data : fileStr;
 | 
        
           |  |  | 73 | 		unsigned int pageID = options.contains(L"page") ? options[L"page"]->data.toInt() : 0;
 | 
        
           |  |  | 74 | 		long offset = offsetStr.toLong();
 | 
        
           | 289 | cycrow | 75 | 		bool doIgnore = options.contains(L"ignore");
 | 
        
           | 287 | cycrow | 76 |   | 
        
           |  |  | 77 | 		CFileIO f;
 | 
        
           |  |  | 78 | 		if (f.open(fileStr))
 | 
        
           |  |  | 79 | 		{
 | 
        
           |  |  | 80 | 			bool inPage = false;
 | 
        
           | 289 | cycrow | 81 | 			bool ignore = false;
 | 
        
           | 287 | cycrow | 82 | 			Utils::WStringList list;
 | 
        
           |  |  | 83 | 			Utils::WStringList outList;
 | 
        
           |  |  | 84 | 			if (f.readLines(list))
 | 
        
           |  |  | 85 | 			{
 | 
        
           |  |  | 86 | 				for (auto itr = list.begin(); itr != list.end(); itr++)
 | 
        
           |  |  | 87 | 				{
 | 
        
           |  |  | 88 | 					Utils::WString line = (*itr)->str;
 | 
        
           |  |  | 89 | 					if (line.contains(L"<page id=\""))
 | 
        
           |  |  | 90 | 					{
 | 
        
           |  |  | 91 | 						long id = line.between(L"<page id=\"", L"\"").toLong();
 | 
        
           |  |  | 92 | 						if (pageID == 0 || pageID == id)
 | 
        
           |  |  | 93 | 							inPage = true;
 | 
        
           | 289 | cycrow | 94 | 						else
 | 
        
           |  |  | 95 | 							ignore = true;
 | 
        
           | 287 | cycrow | 96 | 					}
 | 
        
           |  |  | 97 | 					else if (line.contains(L"</page>"))
 | 
        
           |  |  | 98 | 						inPage = false;
 | 
        
           |  |  | 99 | 					else if (inPage)
 | 
        
           |  |  | 100 | 					{
 | 
        
           |  |  | 101 | 						long pos = line.findPos(L"s=\"");
 | 
        
           |  |  | 102 | 						if (pos != -1)
 | 
        
           |  |  | 103 | 						{
 | 
        
           |  |  | 104 | 							Utils::WString s = line.substr(pos + 3);
 | 
        
           |  |  | 105 | 							s = s.token(L"\"", 1);
 | 
        
           | 289 | cycrow | 106 | 							long long time = s.toLong64();
 | 
        
           |  |  | 107 | 							long long toTime = time + offset;
 | 
        
           | 287 | cycrow | 108 | 							line = line.findReplace(time, toTime);
 | 
        
           |  |  | 109 | 						}
 | 
        
           |  |  | 110 | 					}
 | 
        
           | 289 | cycrow | 111 |   | 
        
           |  |  | 112 | 					if(!ignore || !doIgnore)
 | 
        
           |  |  | 113 | 						outList.pushBack(line);
 | 
        
           |  |  | 114 |   | 
        
           |  |  | 115 | 					if (line.contains(L"</page>"))
 | 
        
           |  |  | 116 | 						ignore = false;
 | 
        
           | 287 | cycrow | 117 | 				}
 | 
        
           |  |  | 118 | 				CFileIO outFile(outFileStr);
 | 
        
           |  |  | 119 | 				outFile.writeFile(&outList);
 | 
        
           |  |  | 120 | 				outFile.close();
 | 
        
           |  |  | 121 | 			}
 | 
        
           |  |  | 122 | 		}
 | 
        
           |  |  | 123 | 		else
 | 
        
           |  |  | 124 | 			wprintf(L"Error: Unable to open file, %s\n", fileStr.c_str());
 | 
        
           |  |  | 125 | 	}
 | 
        
           |  |  | 126 |   | 
        
           |  |  | 127 | }
 | 
        
           |  |  | 128 |   | 
        
           | 270 | cycrow | 129 | /*
 | 
        
           |  |  | 130 | 	Main entry point to program
 | 
        
           |  |  | 131 | */
 | 
        
           |  |  | 132 | int main ( int argc, char **argv )
 | 
        
           |  |  | 133 | {
 | 
        
           |  |  | 134 |  	// display program header to command prompt
 | 
        
           |  |  | 135 | 	printf ( "\nX3 Voice Create V1.00 (SPK Library Version %.2f) 15/12/2023 Created by Cycrow\n\n", GetLibraryVersion() );
 | 
        
           |  |  | 136 |   | 
        
           |  |  | 137 | 	// parse the cmd name
 | 
        
           |  |  | 138 | 	Utils::WString cmd (argv[0]);
 | 
        
           | 290 | cycrow | 139 | 	Utils::WString command(argc > 1 ? argv[1] : "");
 | 
        
           | 287 | cycrow | 140 | 	cmd = cmd.findReplace(L"\\", L"/");
 | 
        
           |  |  | 141 | 	Utils::WString cmdDir = cmd.tokens(L"/", 1, cmd.countToken(L"/") - 1);
 | 
        
           |  |  | 142 | 	cmd = cmd.token(L"/", cmd.countToken(L"/"));
 | 
        
           | 270 | cycrow | 143 |   | 
        
           | 287 | cycrow | 144 | 	Utils::WStringList options;
 | 
        
           |  |  | 145 | 	std::vector<Utils::WString> args;
 | 
        
           |  |  | 146 | 	for (int i = 2; i < argc; i++)
 | 
        
           |  |  | 147 | 	{
 | 
        
           |  |  | 148 | 		Utils::WString arg(argv[i]);
 | 
        
           |  |  | 149 | 		if (arg.startsWith(L"--"))
 | 
        
           |  |  | 150 | 		{
 | 
        
           |  |  | 151 | 			arg = arg.substr(2);
 | 
        
           | 270 | cycrow | 152 |   | 
        
           | 287 | cycrow | 153 | 			if (arg.contains(L":"))
 | 
        
           |  |  | 154 | 			{
 | 
        
           |  |  | 155 | 				Utils::WString a = arg.token(L":", 1);
 | 
        
           |  |  | 156 | 				Utils::WString b = arg.tokens(L":", 2);
 | 
        
           |  |  | 157 | 				options.pushBack(a, b);
 | 
        
           |  |  | 158 | 			}
 | 
        
           |  |  | 159 | 			else
 | 
        
           |  |  | 160 | 				options.pushBack(arg);
 | 
        
           |  |  | 161 | 		}
 | 
        
           |  |  | 162 | 		else
 | 
        
           |  |  | 163 | 			args.push_back(arg);
 | 
        
           |  |  | 164 | 	}
 | 
        
           |  |  | 165 |   | 
        
           |  |  | 166 | 	if (command == L"offset")
 | 
        
           |  |  | 167 | 		DoOffset(cmd, options, args);
 | 
        
           |  |  | 168 | 	else if (command == L"help")
 | 
        
           | 270 | cycrow | 169 | 	{
 | 
        
           | 287 | cycrow | 170 | 		PrintSyntax(cmd);
 | 
        
           |  |  | 171 | 	}
 | 
        
           |  |  | 172 | 	else
 | 
        
           |  |  | 173 | 	{
 | 
        
           | 270 | cycrow | 174 |   | 
        
           | 287 | cycrow | 175 | 		Utils::String mainFileStr = "d:/x/X3 Terran Conflict - Guilds/addon2/mov/00344.wav";
 | 
        
           |  |  | 176 | 		Utils::WString dir = L"d:/x/X3 Terran Conflict - Guilds/addon2/mov/working";
 | 
        
           |  |  | 177 | 		Utils::String output = "d:/x/X3 Terran Conflict - Guilds/addon2/mov/working/00344.wav";
 | 
        
           |  |  | 178 | 		Utils::WString outputXML = L"d:/x/X3 Terran Conflict - Guilds/addon2/mov/working/00044.xml";
 | 
        
           | 270 | cycrow | 179 |   | 
        
           | 287 | cycrow | 180 | 		SF_INFO info;
 | 
        
           |  |  | 181 | 		SNDFILE* mainFile = sf_open(mainFileStr.c_str(), SFM_READ, &info);
 | 
        
           |  |  | 182 | 		if (mainFile)
 | 
        
           | 270 | cycrow | 183 | 		{
 | 
        
           | 287 | cycrow | 184 | 			double duration = static_cast<double>(info.frames) / static_cast<double>(info.samplerate);
 | 
        
           |  |  | 185 | 			size_t currentPos = static_cast<size_t>((duration * 1000.0) + 0.5);
 | 
        
           | 270 | cycrow | 186 |   | 
        
           | 287 | cycrow | 187 | 			CFileIO(mainFileStr).copy(output);
 | 
        
           | 270 | cycrow | 188 |   | 
        
           |  |  | 189 |   | 
        
           | 287 | cycrow | 190 | 			SF_INFO outInfo;
 | 
        
           |  |  | 191 | 			SNDFILE* outputFile = sf_open(output.c_str(), SFM_RDWR, &outInfo);
 | 
        
           |  |  | 192 | 			if (outputFile)
 | 
        
           | 270 | cycrow | 193 | 			{
 | 
        
           | 287 | cycrow | 194 | 				double buffer[BUFFER_LEN];
 | 
        
           |  |  | 195 |   | 
        
           |  |  | 196 | 				int check = sf_format_check(&outInfo);
 | 
        
           |  |  | 197 | 				sf_count_t seek = sf_seek(outputFile, 0, SEEK_END);
 | 
        
           |  |  | 198 |   | 
        
           |  |  | 199 | 				Utils::WStringList xmlOut;
 | 
        
           |  |  | 200 | 				xmlOut.pushBack(L"<?xml version=\"1.0\" ?>");
 | 
        
           |  |  | 201 | 				xmlOut.pushBack(L"<language id=\"44\">");
 | 
        
           |  |  | 202 |   | 
        
           |  |  | 203 | 				CDirIO D(dir);
 | 
        
           |  |  | 204 | 				Utils::WStringList list;
 | 
        
           |  |  | 205 | 				if (D.dirList(list))
 | 
        
           | 270 | cycrow | 206 | 				{
 | 
        
           | 287 | cycrow | 207 | 					for (auto itr = list.begin(); itr != list.end(); itr++)
 | 
        
           | 270 | cycrow | 208 | 					{
 | 
        
           | 287 | cycrow | 209 | 						if (D.isDir((*itr)->str))
 | 
        
           |  |  | 210 | 						{
 | 
        
           |  |  | 211 | 							CDirIO curDir(D.dir((*itr)->str));
 | 
        
           |  |  | 212 | 							long pageID = (*itr)->str.toInt();
 | 
        
           | 270 | cycrow | 213 |   | 
        
           | 287 | cycrow | 214 | 							xmlOut.pushBack(Utils::WString(L"<page id=\"") + pageID + L"\" stream=\"3\">");
 | 
        
           | 270 | cycrow | 215 |   | 
        
           | 287 | cycrow | 216 | 							Utils::WStringList idList;
 | 
        
           |  |  | 217 | 							if (curDir.dirList(idList))
 | 
        
           | 270 | cycrow | 218 | 							{
 | 
        
           | 287 | cycrow | 219 | 								for (auto itr2 = idList.begin(); itr2 != idList.end(); itr2++)
 | 
        
           | 270 | cycrow | 220 | 								{
 | 
        
           | 287 | cycrow | 221 | 									if (curDir.isFile((*itr2)->str))
 | 
        
           | 270 | cycrow | 222 | 									{
 | 
        
           | 287 | cycrow | 223 | 										CFileIO F(curDir.file((*itr2)->str));
 | 
        
           |  |  | 224 | 										long id = F.baseName().toInt();
 | 
        
           |  |  | 225 | 										size_t len = 0;
 | 
        
           | 270 | cycrow | 226 |   | 
        
           | 287 | cycrow | 227 | 										SF_INFO inInfo;
 | 
        
           |  |  | 228 | 										SNDFILE* inputFile = sf_open(F.fullFilename().toString().c_str(), SFM_READ, &inInfo);
 | 
        
           |  |  | 229 | 										if (inputFile)
 | 
        
           |  |  | 230 | 										{
 | 
        
           |  |  | 231 | 											double duration = static_cast<double>(inInfo.frames) / static_cast<double>(inInfo.samplerate);
 | 
        
           |  |  | 232 | 											size_t len = static_cast<size_t>((duration * 1000.0) + 0.5);
 | 
        
           | 270 | cycrow | 233 |   | 
        
           |  |  | 234 |   | 
        
           | 287 | cycrow | 235 | 											sf_count_t readcount;
 | 
        
           |  |  | 236 | 											while ((readcount = sf_read_double(inputFile, buffer, BUFFER_LEN)) > 0)
 | 
        
           |  |  | 237 | 												sf_write_double(outputFile, buffer, readcount);
 | 
        
           |  |  | 238 | 											//int* data = new int[inInfo.frames * inInfo.channels];
 | 
        
           |  |  | 239 | 											//sf_count_t readCount = sf_readf_int(inputFile, data, inInfo.frames);
 | 
        
           |  |  | 240 | 											//sf_count_t writeCount = sf_writef_int(outputFile, data, inInfo.frames);
 | 
        
           |  |  | 241 |   | 
        
           |  |  | 242 | 											xmlOut.pushBack(Utils::WString(L"\t<t id=\"") + id + L"\" s=\"" + (long)currentPos + L"\" l=\"" + (long)len + "\"/>");
 | 
        
           |  |  | 243 | 											currentPos += len;
 | 
        
           |  |  | 244 | 											sf_close(inputFile);
 | 
        
           |  |  | 245 | 										}
 | 
        
           | 270 | cycrow | 246 | 									}
 | 
        
           |  |  | 247 | 								}
 | 
        
           |  |  | 248 | 							}
 | 
        
           | 287 | cycrow | 249 |   | 
        
           |  |  | 250 | 							xmlOut.pushBack(L"</page>");
 | 
        
           | 270 | cycrow | 251 | 						}
 | 
        
           |  |  | 252 | 					}
 | 
        
           |  |  | 253 | 				}
 | 
        
           |  |  | 254 |   | 
        
           | 287 | cycrow | 255 | 				xmlOut.pushBack("</language>");
 | 
        
           | 270 | cycrow | 256 |   | 
        
           | 287 | cycrow | 257 | 				sf_close(outputFile);
 | 
        
           | 270 | cycrow | 258 |   | 
        
           | 287 | cycrow | 259 | 				CFileIO xml(outputXML);
 | 
        
           |  |  | 260 | 				xml.writeFile(&xmlOut);
 | 
        
           |  |  | 261 | 			}
 | 
        
           |  |  | 262 |   | 
        
           |  |  | 263 | 			sf_close(mainFile);
 | 
        
           | 270 | cycrow | 264 | 		}
 | 
        
           |  |  | 265 | 	}
 | 
        
           |  |  | 266 | 	//Pause();
 | 
        
           |  |  | 267 |   | 
        
           |  |  | 268 | 	return 0;
 | 
        
           |  |  | 269 | }
 |