NoSloppy

SoundFontNamingService.java

Jan 9th, 2024
29
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 38.05 KB | None | 0 0
  1. package com.example.soundfontconverter;
  2.  
  3. import org.springframework.stereotype.Service;
  4.  
  5. import java.io.IOException;
  6. import java.nio.file.*;
  7. import java.util.HashMap;
  8. import java.util.List;
  9. import java.util.Map;
  10. import java.io.BufferedReader;
  11. import java.io.File;
  12. import java.io.FileReader;
  13. import java.util.stream.Stream;
  14. import java.util.Comparator;
  15. import java.util.stream.Collectors;
  16. import java.text.SimpleDateFormat;
  17. import java.util.Date;
  18. import java.util.Set;
  19. import java.util.HashSet;
  20.  
  21. @Service
  22. public class SoundFontNamingService {
  23.  
  24. enum BoardType {
  25. CFX,
  26. GH3,
  27. PROFFIE,
  28. VERSO,
  29. XENO3;
  30.  
  31. public static String getKey(BoardType source, BoardType target) {
  32. return source.name() + "_TO_" + target.name();
  33. }
  34. }
  35. private StringBuilder logStringBuilder = new StringBuilder();
  36. private boolean chained = false;
  37. private String realTarget = "PROFFIE";
  38. private static final String DEFAULTS_PATH = "./inis";
  39. private static final Map<String, String> CFX_TO_PROFFIE = new HashMap<>();
  40. private static final Map<String, String> CFX_TO_VERSO = new HashMap<>();
  41. private static final Map<String, String> GH3_TO_PROFFIE = new HashMap<>();
  42. private static final Map<String, String> PROFFIE_TO_CFX = new HashMap<>();
  43. private static final Map<String, String> PROFFIE_TO_GH3 = new HashMap<>();
  44. private static final Map<String, String> PROFFIE_TO_VERSO = new HashMap<>();
  45. private static final Map<String, String> PROFFIE_TO_XENO3 = new HashMap<>();
  46. private static final Map<String, String> VERSO_TO_CFX = new HashMap<>();
  47. private static final Map<String, String> VERSO_TO_PROFFIE = new HashMap<>();
  48. private static final Map<String, String> XENO3_TO_PROFFIE = new HashMap<>();
  49. //... additional board mappings can be added here
  50.  
  51. // Central mapping repository
  52. private static final Map<String, Map<String, String>> soundMappings = new HashMap<>();
  53. private static final Map<String, Integer> soundCounter = new HashMap<>();
  54.  
  55. static {
  56. initializeMappings();
  57. }
  58.  
  59. private static void loadMappingsFromCSV(String csvFilePath, Map<String, String> mapping) {
  60. try (BufferedReader reader = new BufferedReader(new FileReader(csvFilePath))) {
  61. String line;
  62. while ((line = reader.readLine()) != null) {
  63. String[] parts = line.split(",");
  64. if (parts.length >= 2) {
  65. mapping.put(parts[0], parts[1]);
  66. }
  67. }
  68. } catch (IOException e) {
  69. e.printStackTrace();
  70. }
  71. }
  72.  
  73. private static void safeLoadMappingsFromCSV(String csvFilePath, Map<String, String> mapping) {
  74. File f = new File(csvFilePath);
  75. if(f.exists() && !f.isDirectory()) {
  76. loadMappingsFromCSV(csvFilePath, mapping);
  77. }
  78. }
  79.  
  80. private static void initializeMappings() {
  81. safeLoadMappingsFromCSV("./CSV/CFX_TO_PROFFIE.csv", CFX_TO_PROFFIE);
  82. // safeLoadMappingsFromCSV("./CSV/CFX_TO_VERSO.csv", CFX_TO_VERSO);
  83. // safeLoadMappingsFromCSV("./CSV/GH3_TO_PROFFIE.csv", GH3_TO_PROFFIE);
  84. safeLoadMappingsFromCSV("./CSV/PROFFIE_TO_CFX.csv", PROFFIE_TO_CFX);
  85. // safeLoadMappingsFromCSV("./CSV/PROFFIE_TO_GH3.csv", PROFFIE_TO_CFX);
  86. safeLoadMappingsFromCSV("./CSV/PROFFIE_TO_VERSO.csv", PROFFIE_TO_VERSO);
  87. safeLoadMappingsFromCSV("./CSV/PROFFIE_TO_XENO3.csv", PROFFIE_TO_XENO3);
  88. // safeLoadMappingsFromCSV("./CSV/VERSO_TO_PROFFIE.csv", VERSO_TO_PROFFIE);
  89. safeLoadMappingsFromCSV("./CSV/XENO3_TO_PROFFIE.csv", XENO3_TO_PROFFIE);
  90. // ... and so on for other mappings ...
  91.  
  92. soundMappings.put(BoardType.getKey(BoardType.CFX, BoardType.PROFFIE), CFX_TO_PROFFIE);
  93. // soundMappings.put(BoardType.getKey(BoardType.CFX, BoardType.VERSO), CFX_TO_VERSO);
  94. soundMappings.put(BoardType.getKey(BoardType.PROFFIE, BoardType.CFX), PROFFIE_TO_CFX);
  95. soundMappings.put(BoardType.getKey(BoardType.PROFFIE, BoardType.GH3), PROFFIE_TO_CFX);
  96. soundMappings.put(BoardType.getKey(BoardType.PROFFIE, BoardType.VERSO), PROFFIE_TO_VERSO);
  97. soundMappings.put(BoardType.getKey(BoardType.PROFFIE, BoardType.XENO3), PROFFIE_TO_XENO3);
  98. soundMappings.put(BoardType.getKey(BoardType.GH3, BoardType.PROFFIE), CFX_TO_PROFFIE);
  99. // soundMappings.put(BoardType.getKey(BoardType.VERSO, BoardType.CFX), VERSO_TO_CFX);
  100. soundMappings.put(BoardType.getKey(BoardType.VERSO, BoardType.PROFFIE), VERSO_TO_PROFFIE);
  101. soundMappings.put(BoardType.getKey(BoardType.XENO3, BoardType.PROFFIE), XENO3_TO_PROFFIE);
  102.  
  103. // Reverse Mapping fist so actual mappings will override
  104.  
  105. // CFX to Proffie mapping
  106. for (Map.Entry<String, String> entry : PROFFIE_TO_CFX.entrySet()) {
  107. CFX_TO_PROFFIE.putIfAbsent(entry.getValue(), entry.getKey());
  108. }
  109. // for (Map.Entry<String, String> entry : VERSO_TO_CFX.entrySet()) {
  110. // CFX_TO_VERSO.putIfAbsent(entry.getValue(), entry.getKey());
  111. // }
  112. // Verso to Proffie mapping
  113. for (Map.Entry<String, String> entry : PROFFIE_TO_VERSO.entrySet()) {
  114. VERSO_TO_PROFFIE.putIfAbsent(entry.getValue(), entry.getKey());
  115. }
  116. // Xeno3 to Proffie mapping
  117. for (Map.Entry<String, String> entry : PROFFIE_TO_XENO3.entrySet()) {
  118. XENO3_TO_PROFFIE.putIfAbsent(entry.getValue(), entry.getKey());
  119. }
  120. }
  121.  
  122. private static void ensureDirectoryExists(Path dirPath) {
  123. try {
  124. if (!Files.exists(dirPath)) {
  125. Files.createDirectories(dirPath);
  126. System.out.println("Creating directory: " + dirPath);
  127. }
  128. } catch (IOException ex) {
  129. ex.printStackTrace();
  130. }
  131. }
  132.  
  133. private static void copyFile(Path sourcePath, Path targetPath) {
  134. try {
  135. Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
  136. } catch (IOException ex) {
  137. System.err.println("Error copying file from " + sourcePath + " to " + targetPath);
  138. ex.printStackTrace();
  139. }
  140. }
  141.  
  142. // If no optimizeForProffie parameter is included, default optimizeForProffie to true
  143. private void convertSounds(BoardType sourceBoard, String sourceDir, BoardType targetBoard, String targetDir) throws IOException {
  144. convertSounds(sourceBoard, sourceDir, targetBoard, targetDir, true);
  145. }
  146.  
  147. // This version takes the optimizeForProffie parameter. It's the main logic
  148. private void convertSounds(BoardType sourceBoard, String sourceDir, BoardType targetBoard, String targetDir, boolean optimizeForProffie) throws IOException {
  149. soundCounter.clear();
  150. String key = BoardType.getKey(sourceBoard, targetBoard);
  151. System.out.println("----------------------------------------------------------------\n.");
  152. if (targetBoard == BoardType.PROFFIE && realTarget == "PROFFIE") {
  153. System.out.println("Converting from " + sourceBoard + " to " + targetBoard + "\n.");
  154. } else if (targetBoard != BoardType.PROFFIE) {
  155. realTarget = targetBoard.toString();
  156. } else {
  157. System.out.println("Converting from " + sourceBoard + " to " + realTarget + "\n.");
  158. }
  159.  
  160. // Directory structure code here:
  161. String sourceDirName = new File(sourceDir).getName();
  162. // Include a special case for GH3 output directory naming
  163. String finalTargetDir = targetDir + "/Converted_to_" + targetBoard + "/" +
  164. (targetBoard == BoardType.GH3 ? "sound1 - " : "") +
  165. sourceDirName;
  166.  
  167. // Prepare Log file
  168. if (chained == false) {
  169. ensureDirectoryExists(Paths.get(finalTargetDir));
  170. SimpleDateFormat sdf = new SimpleDateFormat("MMM dd, yyyy");
  171. String currentDate = sdf.format(new Date());
  172. logStringBuilder.append("Converted with SoundFont Naming Converter 3.0\n");
  173. logStringBuilder.append("Brian Conner a.k.a NoSloppy\n\n");
  174. logStringBuilder.append(currentDate).append("\n");
  175.  
  176. if (targetBoard == BoardType.PROFFIE && realTarget == "PROFFIE") {
  177. logStringBuilder.append("Converted: ").append(sourceBoard).append(" to ").append(targetBoard).append("\n");
  178. logStringBuilder.append("Optimized for Fat32 performance: ").append(optimizeForProffie ? "Yes" : "No").append("\n\n");
  179. } else if (targetBoard != BoardType.PROFFIE) {
  180. realTarget = targetBoard.toString();
  181. } else {
  182. logStringBuilder.append("Converted: ").append(sourceBoard).append(" to ").append(realTarget).append("\n");
  183. logStringBuilder.append("\n");
  184. }
  185. }
  186.  
  187. // If it's Proffie to Proffie, skip the mapping
  188. Map<String, String> mapping;
  189. if (sourceBoard == BoardType.PROFFIE && targetBoard == BoardType.PROFFIE) {
  190. mapping = null; // No mapping required for Proffie to Proffie
  191. } else {
  192. if (!soundMappings.containsKey(key)) {
  193. System.out.println("Conversion from " + sourceBoard + " to " + targetBoard + " is not supported.");
  194. return;
  195. }
  196. mapping = soundMappings.get(key);
  197. }
  198.  
  199. ensureDirectoryExists(Paths.get(finalTargetDir));
  200.  
  201. // Check if source has directories named something like "Bonus Files" or "extra"
  202. boolean hasExtrasDirectories = false;
  203. try {
  204. hasExtrasDirectories = Files.walk(Paths.get(sourceDir), 1) // Only check immediate children
  205. .filter(Files::isDirectory).anyMatch(path -> {
  206. String dirName = path.getFileName().toString().toLowerCase();
  207. return dirName.contains("bonus") || dirName.contains("extra");
  208. });
  209. } catch (IOException ex) {
  210. ex.printStackTrace();
  211. }
  212.  
  213. // If "extras" directory is needed, create it now
  214. if (hasExtrasDirectories) {
  215. ensureDirectoryExists(Paths.get(finalTargetDir + "/extras"));
  216. }
  217.  
  218. // Main sound conversion
  219. try (Stream<Path> paths = Files.walk(Paths.get(sourceDir))) {
  220. Map<String, Integer> fileNameCounter = new HashMap<>();
  221. boolean fontSoundProcessed = false;
  222.  
  223. paths.filter(Files::isRegularFile)
  224. .filter(path -> !path.getFileName().toString().startsWith("."))
  225. .filter(path -> {
  226.  
  227. String parentDirName = path.getParent().getFileName().toString().toLowerCase();
  228. if (parentDirName.contains("bonus") || parentDirName.contains("extra")) {
  229. copyFile(path, Paths.get(finalTargetDir, "extras", path.getFileName().toString()));
  230. String logEntryExtras = "Moved extra/bonus file to " + finalTargetDir + "/extras/" + path.getFileName();
  231. System.out.println(logEntryExtras);
  232. logStringBuilder.append(logEntryExtras).append("\n");
  233. return false;
  234. }
  235. return true;
  236. })
  237. .sorted(Comparator.comparing(Path::toString))
  238. .forEach(path -> {
  239. try {
  240. String fileName = path.getFileName().toString();
  241. // Convert to lowercase only if the file is a .wav file
  242. if (fileName.toLowerCase().endsWith(".wav")) {
  243. fileName = fileName.toLowerCase();
  244. }
  245. // Move non-wav files directly to the target folder
  246. if (!fileName.endsWith(".wav")) {
  247. copyFile(path, Paths.get(finalTargetDir, fileName));
  248. String logEntryNonWav = "Moved non-wav file: " + fileName;
  249. System.out.println(logEntryNonWav);
  250. logStringBuilder.append(logEntryNonWav).append("\n");
  251. return;
  252. }
  253.  
  254. // Move "track" wav files to "tracks" folder if not xeno
  255. if (fileName.contains("track") || fileName.contains("theme")) {
  256. if (targetBoard == BoardType.XENO3) {
  257. System.out.println("Targetboard = Xeno, renaming files named 'track' or 'theme'");
  258. } else {
  259. ensureDirectoryExists(Paths.get(finalTargetDir + "/tracks"));
  260. copyFile(path, Paths.get(finalTargetDir, "tracks", fileName));
  261. String logEntryTrack = "Moved track file: " + fileName;
  262. System.out.println(logEntryTrack);
  263. logStringBuilder.append(logEntryTrack).append("\n");
  264. return;
  265. }
  266. }
  267.  
  268. // For other wav files, use the mapping
  269. // String baseName = fileName.replaceAll(" (\\(\\d+\\))?\\.wav$|\\d+\\.wav$", ".wav");
  270. // String baseName = fileName.replaceAll("( \\(\\d+\\)| \\d+|\\d+)?\\.wav$", ".wav");
  271. String baseName = fileName.replaceAll("( \\(\\d+\\)| \\d+|\\(\\d+\\)|\\d+)+\\.wav$", ".wav");
  272.  
  273.  
  274. // If we're doing Proffie to Proffie, keep the baseName as is
  275. String convertedBaseName = (mapping == null) ? baseName : mapping.getOrDefault(baseName, baseName);
  276.  
  277. String outputPath = "";
  278. if (convertedBaseName != null) {
  279. int count = soundCounter.getOrDefault(convertedBaseName, 0) + 1;
  280. soundCounter.put(convertedBaseName, count);
  281.  
  282. String prefix = (convertedBaseName.contains(".")) ? convertedBaseName.substring(0, convertedBaseName.lastIndexOf('.')) : convertedBaseName;
  283. String formattedCount = String.valueOf(count);
  284.  
  285. Set<String> loggedFiles = new HashSet<>(); // flag to prevent multi logging of poweroff case
  286.  
  287. if (targetBoard == BoardType.CFX) {
  288. String newPrefix;
  289. int currentCounter;
  290.  
  291.  
  292. String switchKey = convertedBaseName.toLowerCase().replaceAll("\\.wav$", "");
  293. // process incoming "melt" files as "drag" as well - JUST MAP IT!!
  294. // if ("melt".equalsIgnoreCase(switchKey)) {
  295. // switchKey = "drag";
  296. // }
  297. String commonKey;
  298. switch (switchKey) {
  299. // Adding pwroff2 regardless of only 1 input file.
  300. case "poweroff":
  301. commonKey = "pwroff";
  302. currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  303. if (currentCounter == 1) {
  304. // Create poweroff.wav
  305. outputPath = finalTargetDir + "/poweroff.wav";
  306. copyFile(path, Paths.get(outputPath));
  307. // Log the file creation
  308. String logEntryPoweroff = "Converted: " + path.getFileName().toString() + " -> " + outputPath.replace("temporaryDirectory/", "");
  309. System.out.println(logEntryPoweroff);
  310. logStringBuilder.append(logEntryPoweroff).append("\n");
  311.  
  312. // Also create pwroff2.wav
  313. outputPath = finalTargetDir + "/pwroff2.wav";
  314. copyFile(path, Paths.get(outputPath));
  315. // Log the file creation
  316. String logEntryPwroff2 = "Converted: " + path.getFileName().toString() + " -> " + outputPath.replace("temporaryDirectory/", "");
  317. System.out.println(logEntryPwroff2);
  318. logStringBuilder.append(logEntryPwroff2).append("\n");
  319. } else if (currentCounter == 2) {
  320. // Overwrite pwroff2.wav
  321. outputPath = finalTargetDir + "/pwroff2.wav";
  322. copyFile(path, Paths.get(outputPath));
  323. // Log the file update
  324. String logEntryUpdate = "Updated: " + path.getFileName().toString() + " -> " + outputPath.replace("temporaryDirectory/", "");
  325. System.out.println(logEntryUpdate);
  326. logStringBuilder.append(logEntryUpdate).append("\n");
  327. } else {
  328. // Follow original pattern for subsequent files
  329. newPrefix = "poweroff" + (currentCounter - 1);
  330. outputPath = finalTargetDir + "/" + newPrefix + ".wav";
  331. copyFile(path, Paths.get(outputPath));
  332. // Log the file creation
  333. String logEntrySubsequent = "Converted: " + path.getFileName().toString() + " -> " + outputPath.replace("temporaryDirectory/", "");
  334. System.out.println(logEntrySubsequent);
  335. logStringBuilder.append(logEntrySubsequent).append("\n");
  336. }
  337. fileNameCounter.put(commonKey, currentCounter + 1);
  338. loggedFiles.add(path.getFileName().toString()); // Add the filename to the set
  339. break;
  340.  
  341. // case "clash":
  342. // commonKey = "clash";
  343. // currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  344. // if (currentCounter == 1) {
  345. // newPrefix = "clash" + currentCounter;
  346. // } else if (currentCounter == 2) {
  347. // newPrefix = "fclash" + (currentCounter -1);
  348. // } else {
  349. // newPrefix = "clash" + (currentCounter - 1);
  350. // }
  351. // outputPath = finalTargetDir + "/" + newPrefix + ".wav";
  352. // fileNameCounter.put(commonKey, currentCounter + 1);
  353. // break;
  354.  
  355. case "font":
  356. commonKey = "font";
  357. currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  358. if (currentCounter == 1) {
  359. outputPath = finalTargetDir + "/font" + ".wav";
  360. } else {
  361. int nextBootCounter = fileNameCounter.getOrDefault("boot", 1);
  362. outputPath = finalTargetDir + "/boot" + (nextBootCounter == 1 ? "" : nextBootCounter) + ".wav";
  363. fileNameCounter.put("boot", nextBootCounter + 1);
  364. }
  365. fileNameCounter.put(commonKey, currentCounter + 1);
  366. break;
  367.  
  368. // These get no number on the first file, then sequence the rest staring from 2
  369. case "boot":
  370. commonKey = "boot";
  371. currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  372. outputPath = finalTargetDir + "/boot" + (currentCounter == 1 ? "" : currentCounter) + ".wav";
  373. fileNameCounter.put(commonKey, currentCounter + 1);
  374. break;
  375.  
  376. case "color":
  377. commonKey = "color";
  378. currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  379. outputPath = finalTargetDir + "/" + convertedBaseName.substring(0, convertedBaseName.length() - 4) + (currentCounter == 1 ? "" : currentCounter) + ".wav";
  380. fileNameCounter.put(commonKey, currentCounter + 1);
  381. break;
  382. // case "blaster":
  383. // commonKey = "blaster";
  384. // currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  385. // outputPath = finalTargetDir + "/" + convertedBaseName.substring(0, convertedBaseName.length() - 4) + (currentCounter == 1 ? "" : currentCounter) + ".wav";
  386. // fileNameCounter.put(commonKey, currentCounter + 1);
  387. // break;
  388. case "poweron":
  389. commonKey = "poweron";
  390. currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  391. outputPath = finalTargetDir + "/" + convertedBaseName.substring(0, convertedBaseName.length() - 4) + (currentCounter == 1 ? "" : currentCounter) + ".wav";
  392. fileNameCounter.put(commonKey, currentCounter + 1);
  393. break;
  394. case "lockup":
  395. commonKey = "lockup";
  396. currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  397. outputPath = finalTargetDir + "/" + convertedBaseName.substring(0, convertedBaseName.length() - 4) + (currentCounter == 1 ? "" : currentCounter) + ".wav";
  398. fileNameCounter.put(commonKey, currentCounter + 1);
  399. break;
  400. case "drag":
  401. commonKey = "drag";
  402. currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  403. outputPath = finalTargetDir + "/" + convertedBaseName.substring(0, convertedBaseName.length() - 4) + (currentCounter == 1 ? "" : currentCounter) + ".wav";
  404. fileNameCounter.put(commonKey, currentCounter + 1);
  405. break;
  406. // case "drag":
  407. // commonKey = "drag";
  408. // currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  409. // // Use commonKey to generate outputPath
  410. // outputPath = finalTargetDir + "/" + commonKey + (currentCounter == 1 ? "" : currentCounter) + ".wav";
  411. // fileNameCounter.put(commonKey, currentCounter + 1);
  412. // break;
  413.  
  414. case "force":
  415. commonKey = "force";
  416. currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  417. outputPath = finalTargetDir + "/" + convertedBaseName.substring(0, convertedBaseName.length() - 4) + (currentCounter == 1 ? "" : currentCounter) + ".wav";
  418. fileNameCounter.put(commonKey, currentCounter + 1);
  419. break;
  420.  
  421. default:
  422. currentCounter = fileNameCounter.getOrDefault(switchKey, 1);
  423. outputPath = finalTargetDir + "/" + convertedBaseName.substring(0, convertedBaseName.length() - 4) + currentCounter + ".wav";
  424.  
  425. fileNameCounter.put(switchKey, currentCounter + 1);
  426. break;
  427. }
  428.  
  429. } else if (targetBoard == BoardType.PROFFIE) {
  430. if (prefix.length() > 6 && count == 1 && soundCounter.containsKey(baseName)) {
  431. formattedCount = String.valueOf(count);
  432. } else {
  433. formattedCount = (prefix.length() > 6) ? String.valueOf(count) : String.format("%02d", count);
  434. }
  435. if (optimizeForProffie) {
  436. outputPath = count == 1 ? finalTargetDir + "/" + prefix + ".wav" : finalTargetDir + "/" + prefix + "/" + prefix + formattedCount + ".wav";
  437.  
  438. if (count == 2) {
  439. Path originalPath = Paths.get(finalTargetDir, prefix + ".wav");
  440. Path newPath = Paths.get(finalTargetDir, prefix, prefix + (prefix.length() > 6 ? "1" : "01") + ".wav");
  441. ensureDirectoryExists(Paths.get(finalTargetDir + "/" + prefix));
  442. Files.move(originalPath, newPath, StandardCopyOption.REPLACE_EXISTING);
  443. String logEntryProffie = "Numbered and moved first file to subdirectory:\n"
  444. + " " + originalPath.subpath(2, originalPath.getNameCount())
  445. + " -> "
  446. + newPath.subpath(2, newPath.getNameCount());
  447. System.out.println(logEntryProffie);
  448. logStringBuilder.append(logEntryProffie).append("\n");
  449. }
  450. } else {
  451. outputPath = finalTargetDir + "/" + (count > 1 ? prefix + formattedCount : prefix) + ".wav";
  452.  
  453. if (count == 2) {
  454. Path originalPath = Paths.get(finalTargetDir, prefix + ".wav");
  455. Path newPath = Paths.get(finalTargetDir, prefix + (prefix.length() > 6 ? "1" : "01") + ".wav");
  456. Files.move(originalPath, newPath, StandardCopyOption.REPLACE_EXISTING);
  457. String logEntryProffie = "Numbered the first file:\n "
  458. + " " + originalPath.subpath(2, originalPath.getNameCount())
  459. + " -> "
  460. + newPath.subpath(2, newPath.getNameCount());
  461. System.out.println(logEntryProffie);
  462. logStringBuilder.append(logEntryProffie).append("\n");
  463. }
  464. }
  465. } else if (targetBoard == BoardType.VERSO && convertedBaseName.equals("font.wav")) {
  466. String commonKey = "font";
  467. int currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  468. fileNameCounter.put(commonKey, currentCounter + 1);
  469.  
  470. if (currentCounter == 1) {
  471. outputPath = finalTargetDir + "/font.wav";
  472. copyFile(path, Paths.get(outputPath));
  473. String logEntryVerso = "Converted: " + path.getFileName().toString() + " -> " + outputPath.replace("temporaryDirectory/", "");
  474. System.out.println(logEntryVerso);
  475. logStringBuilder.append(logEntryVerso).append("\n");
  476. } else {
  477. String logEntryVersoSkipped = "Skipped additional 'font' file: " + fileName;
  478. System.out.println(logEntryVersoSkipped);
  479. logStringBuilder.append(logEntryVersoSkipped).append("\n");
  480. }
  481. return;
  482.  
  483. } else if (targetBoard == BoardType.XENO3) {
  484. outputPath = Paths.get(finalTargetDir, prefix + " (" + count + ").wav").toString();
  485.  
  486. } else if (count > 1 || (targetBoard != BoardType.PROFFIE && count == 1)) {
  487. outputPath = Paths.get(finalTargetDir, prefix + formattedCount + ".wav").toString();
  488. } else {
  489. outputPath = Paths.get(finalTargetDir, prefix + ".wav").toString();
  490. }
  491.  
  492. // Now write the answer after all that checking and filtering.
  493. // one more check if poweroff happened.
  494. // Conditional general logging
  495. if (!loggedFiles.contains(path.getFileName().toString())) {
  496. copyFile(path, Paths.get(outputPath));
  497. String logEntry = "Converted: " + path.getFileName().toString() + " -> " + outputPath.replace("temporaryDirectory/", "");
  498. System.out.println(logEntry);
  499. logStringBuilder.append(logEntry).append("\n");
  500. }
  501.  
  502. } else { // convertedBaseName = null
  503. System.out.println("Skipped wav file without mapping: " + fileName);
  504. }
  505. } catch (IOException e) {
  506. System.err.println("An IOException occurred: " + e.getMessage());
  507. }
  508. });
  509. if (chained == true) {
  510. logStringBuilder.append("\n*********----- MTFBWY -----*********\n");
  511. } else {
  512. logStringBuilder.append("\n\n");
  513. }
  514. try {
  515. System.out.println("--- Writing _Conversion_Log.txt ---");
  516. Files.writeString(Paths.get(finalTargetDir, "_Conversion_Log.txt"), logStringBuilder.toString());
  517. } catch (IOException e) {
  518. System.err.println("Failed to write log: " + e.getMessage());
  519. }
  520. } catch (IOException ex) {
  521. System.err.println("An error occurred while reading the file: " + ex.getMessage());
  522. }
  523.  
  524. // After processing all files, check for default INIs for Proffie
  525. if (targetBoard == BoardType.PROFFIE) {
  526. String[] defaultFiles = {"config.ini", "smoothsw.ini"};
  527. for (String defaultFile : defaultFiles) {
  528. File targetDefaultFile = new File(finalTargetDir, defaultFile);
  529. if (!targetDefaultFile.exists()) {
  530. File inisFile = new File(DEFAULTS_PATH + "/" + defaultFile);
  531. if (inisFile.exists()) {
  532. try {
  533. Files.copy(inisFile.toPath(), targetDefaultFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
  534. System.out.println("Copied default file: " + defaultFile);
  535. } catch (IOException e) {
  536. // e.printStackTrace();
  537. System.err.println("Error while copying file: " + defaultFile);
  538.  
  539. }
  540. }
  541. }
  542. }
  543. }
  544. }
  545.  
  546. public class MutableInt {
  547. public int value;
  548. public MutableInt(int value) {
  549. this.value = value;
  550. }
  551. }
  552.  
  553. public void cleanupTemporaryDirectory() {
  554. System.out.println("Removing any existing temporaryDirectory and generated zip file");
  555. try {
  556. Path tempDir = Paths.get("temporaryDirectory");
  557. if (Files.exists(tempDir)) {
  558. Files.walk(tempDir)
  559. .sorted(Comparator.reverseOrder()) // Important to delete child before parent
  560. .forEach(path -> {
  561. try {
  562. Files.deleteIfExists(path);
  563. } catch (IOException e) {
  564. // Handle the exception, e.g., logging it.
  565. e.printStackTrace();
  566. }
  567. });
  568. }
  569.  
  570. // Deleting the generated zip file.
  571. Files.deleteIfExists(Paths.get("temporaryDirectory.zip"));
  572.  
  573. } catch (IOException e) {
  574. // Handle the exception, e.g., logging it.
  575. e.printStackTrace();
  576. }
  577. }
  578.  
  579. public void convertSoundFont(List<Path> savedFiles, String sourceBoard, String targetBoard, boolean optimize) throws IOException {
  580. BoardType srcBoard = BoardType.valueOf(sourceBoard.toUpperCase());
  581. BoardType tgtBoard = BoardType.valueOf(targetBoard.toUpperCase());
  582.  
  583. String sourceDir = savedFiles.get(0).getParent().toString();
  584. convertSounds(srcBoard, sourceDir, tgtBoard, "temporaryDirectory", optimize);
  585. }
  586.  
  587. public void chainConvertSoundFont(List<Path> savedFiles, String sourceBoard, String targetBoard, boolean optimize) throws IOException {
  588. // Clear the StringBuilder for subsequent log entries
  589. logStringBuilder.setLength(0);
  590. if ("PROFFIE".equals(sourceBoard) || "PROFFIE".equals(targetBoard)) {
  591. // Just convert normally.
  592. convertSoundFont(savedFiles, sourceBoard, targetBoard, optimize);
  593. } else {
  594. // Do the chained conversion;
  595. // cCnvert to PROFFIE first and save it in /temporaryDirectory/Converted_to_PROFFIE.
  596. // Using realTarget for logging only
  597. realTarget = targetBoard;
  598. convertSoundFont(savedFiles, sourceBoard, "PROFFIE", false);
  599. chained = !chained;
  600.  
  601. // Now use the converted PROFFIE files as source for the actual target.
  602. // Clear the StringBuilder for subsequent log entries
  603. //logStringBuilder.setLength(0);
  604. Path tempProffieDir = Paths.get("temporaryDirectory", "Converted_to_PROFFIE");
  605. List<Path> proffieFiles = Files.walk(tempProffieDir)
  606. .filter(Files::isRegularFile)
  607. .collect(Collectors.toList());
  608. convertSoundFont(proffieFiles, "PROFFIE", targetBoard, false);
  609. chained = !chained;
  610.  
  611. // Optional: Cleanup the temporary directory used for the PROFFIE conversion.
  612. }
  613. }
  614.  
  615. public void removeOriginalDirectory(String originalDirName) {
  616. Path originalDir = Paths.get("temporaryDirectory", originalDirName);
  617. try {
  618. System.out.println("Initiating removal of directory: " + originalDir.toString());
  619. Files.walk(originalDir)
  620. .sorted(Comparator.reverseOrder()) // Important to delete child before parent
  621. .forEach(path -> {
  622. try {
  623. Files.deleteIfExists(path);
  624. } catch (IOException e) {
  625. e.printStackTrace();
  626. }
  627. });
  628. } catch (IOException e) {
  629. e.printStackTrace();
  630. }
  631. System.out.println("Completed removal of directory: " + originalDir.toString());
  632. }
  633.  
  634. public Path zipConvertedFiles(String targetDir) throws IOException {
  635. Path zipPath = Paths.get(targetDir + ".zip");
  636.  
  637. // Logging the structure
  638. Path sourcePath = Paths.get(targetDir);
  639. System.out.println("Logging directory structure before zipping:");
  640. Files.walk(sourcePath).forEach(p -> {
  641. // System.out.println(p.toString());
  642. });
  643. System.out.println("Starting to create ZIP file...");
  644.  
  645. try (FileSystem zipFs = FileSystems.newFileSystem(zipPath, Map.of("create", "true"))) {
  646. // Exclude the top-level source directory itself when walking
  647. Files.walk(sourcePath).filter(p -> !p.equals(sourcePath)).forEach(path -> {
  648. try {
  649. if (Files.isRegularFile(path) && Files.size(path) > 0) { // Ensure it's a file and has content
  650. String sourceDirName = sourcePath.getFileName().toString();
  651. Path destPath = zipFs.getPath("/" + sourceDirName + "/" + sourcePath.relativize(path).toString());
  652.  
  653. // Ensure the parent directory structure exists in the ZIP
  654. if (destPath.getParent() != null) {
  655. Files.createDirectories(destPath.getParent());
  656. }
  657.  
  658. Files.copy(path, destPath, StandardCopyOption.REPLACE_EXISTING);
  659. }
  660. } catch (NoSuchFileException e) {
  661. System.err.println("Directory structure in ZIP does not match expected structure: " + e.getMessage());
  662. } catch (Exception e) {
  663. e.printStackTrace();
  664. System.err.println("Error processing file: " + path.toString() +
  665. ". Destination path in ZIP: " + zipFs.getPath("/" + sourcePath.relativize(path).toString()));
  666. }
  667. });
  668.  
  669. } catch (Exception e) {
  670. e.printStackTrace();
  671. throw new IOException("Error encountered during zip operation: " + e.getMessage());
  672. }
  673. System.out.println("Conversion complete. Zip file saved and ready for download from " + targetDir + ".zip");
  674. return zipPath;
  675. }
  676. }
  677.  
Add Comment
Please, Sign In to add comment