Advertisement
NoSloppy

original working all

Oct 12th, 2023
46
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 55.19 KB | None | 0 0
  1. original, working well version of index.html:
  2. ```
  3. <!DOCTYPE html>
  4. <html xmlns:th="http://www.thymeleaf.org">
  5. <head>
  6. <meta charset="UTF-8">
  7. <title>Sound Font Naming Converter</title>
  8.  
  9. <link rel="icon" type="image/png" href="/favicon.png">
  10. </head>
  11. <style>
  12.  
  13. body, html {
  14. background-color: #202020;
  15. color: #FFFFFF;
  16. font-family: Arial, sans-serif;
  17. }
  18. input, select, button {
  19. background-color: #555;
  20. color: #fff;
  21. border: 1px solid #777;
  22. border-radius: 2px;
  23. }
  24. progress {
  25. background: linear-gradient(to bottom, #FFFFFF, #00FF00);
  26. border: 1px solid #00AA00;
  27. }
  28. progress::-webkit-progress-bar {
  29. background: #222;
  30. }
  31. progress::-webkit-progress-value {
  32. background: linear-gradient(to bottom, #FFFFFF, #00FF00);
  33. }
  34. progress::-moz-progress-bar {
  35. background: linear-gradient(to bottom, #FFFFFF, #00FF00);
  36. }
  37. .uploadProgressBar {
  38. width: 50%;
  39. }
  40. button:active,
  41. input[type="button"]:active,
  42. input[type="submit"]:active,
  43. input[type="file"]:active + label {
  44. background-color: dodgerblue;
  45. }
  46.  
  47. button:hover,
  48. input[type="button"]:hover,
  49. input[type="submit"]:hover,
  50. input[type="file"]:hover + label {
  51. box-shadow: 0 0 2px 1px dodgerblue;
  52. }
  53.  
  54. h1 {
  55. text-align: center;
  56. }
  57.  
  58.  
  59. .downloadButton {
  60. display: none;
  61. }
  62.  
  63. /* Footer */
  64. .footer-title {
  65. min-width: 180px;
  66. font-size: 16px;
  67. padding-left: 10px;
  68. }
  69. .footer-container {
  70. position: absolute;
  71. bottom: 0;
  72. left: 0;
  73. width: 100%;
  74. display: flex;
  75. justify-content: space-between;
  76. align-items: center;
  77. background-color: #333;
  78. padding: 6px 0px;
  79. }
  80. .other-sites {
  81. float: right;
  82. padding-right: 10px;
  83. margin-left: 35px;
  84. }
  85. .footer-links {
  86. display: flex;
  87. align-items: center;
  88. white-space: nowrap;
  89. overflow: hidden;
  90. text-overflow: ellipsis;
  91. min-width: 100px;
  92. }
  93. .footer-links a img {
  94. height: 16px;
  95. width: 16px;
  96. /* margin-right: 5px;*/
  97. padding-right: 10px;
  98.  
  99. }
  100. .footer-links a:hover {
  101. color: #000;
  102. }
  103. .donate-button {
  104. width: 170px;
  105. height: auto;
  106. }
  107. </style>
  108. <body>
  109. <h1>Welcome to the Sound Font Naming Converter 3.0</h1>
  110. <p>1. Choose a source and target format from the drop down menus below.</p>
  111.  
  112. <!-- Message display for feedback -->
  113. <div th:if="${message}" th:text="${message}"></div>
  114.  
  115.  
  116. <!-- Form to get user input -->
  117. <form id="uploadForm" action="/convert" method="post" enctype="multipart/form-data">
  118. <!-- Dropdown for source board selection -->
  119. <select id="sourceBoard" name="sourceBoard" title="Source board">
  120. <option value="CFX">CFX</option>
  121. <option value="GH3">GH3</option>
  122. <option value="PROFFIE">PROFFIE</option>
  123. <option value="VERSO">VERSO</option>
  124. <option value="XENO3">XENO3</option>
  125. </select>
  126.  
  127. <!-- Dropdown for target board selection -->
  128. <select id="targetBoard" name="targetBoard" title="Target board">
  129. <option value="CFX">CFX</option>
  130. <option value="GH3">GH3</option>
  131. <option value="PROFFIE">PROFFIE</option>
  132. <option value="VERSO">VERSO</option>
  133. <option value="XENO3">XENO3</option>
  134. </select>
  135.  
  136. <input type="checkbox" id="optimizeForProffie" name="optimizeForProffie" value="true" checked>
  137. <label for="optimizeForProffie">Optimize for FAT32 performance? You should ;)</label>
  138. <br>
  139. <br>
  140. <br>
  141. <div>
  142. <button id="proffieOptimizerButton" type="button" class="proffieOptimizerButton"
  143. title="Reorganizes an existing Proffie font for best performance. Just choose a source folder and the process is automated. Save downloaded file."> Proffie Easy Optimizer </button>
  144. </div>
  145.  
  146.  
  147. <br>
  148.  
  149. <p>2. Add the font folder you wish to convert.</p>
  150.  
  151. <!-- Directory input -->
  152. <div>
  153. <input type="file" id="files" name="files" webkitdirectory directory multiple>
  154. </div>
  155. <br>
  156.  
  157. <p>3. Click "Convert" and then Download the resulting zip file to your computer.</p>
  158.  
  159. <!-- Convert button -->
  160. <input type="submit" value="Convert" id="convertInput" title="Convert selected font folder." >
  161.  
  162. <!-- Progress bar and its status message -->
  163. <div>
  164. <br>
  165. <p>Progress....</p>
  166. <progress id="uploadProgressBar" class="uploadProgressBar" max="100" value="0" ></progress>
  167. <p id="progressStatus">Waiting for files to be uploaded. Choose Files and click 'Convert'.</p>
  168. </div>
  169.  
  170. <!-- Download button (Hidden initially) -->
  171. <button id="downloadButton" type="button" class="downloadButton" title="Download converted font." >Download Converted Files</button>
  172.  
  173. <div class="footer-container">
  174. <span class="footer-title">NoSloppy - 2023</span>
  175.  
  176. <a href="https://www.buymeacoffee.com/BrianConner" title="Brian Conner supports the saber community. Support him back.">
  177. <img class="donate-button" src="/donateButton.jpg"></a>
  178.  
  179. <span class="footer-links">
  180. <span class="other-sites">Other sites: </span>
  181. <a href="https://crucible.hubbe.net/" target="_blank" title="The Crucible"><img src="https://crucible.hubbe.net/uploads/default/optimized/1X/2237f551ca8f4f69ac478df5c64aee1c951c33f5_2_180x180.png" alt="Crucible logo"></a>
  182. <a href="https://pod.hubbe.net/" target="_blank" title="ProffieOS Documentation site" ><img src="https://pod.hubbe.net/images/favicon.png" alt="Pod logo"></a>
  183. <a href="https://fredrik.hubbe.net/lightsaber/" target="_blank" title="Profezzorn's Proffieboard site"><img src="https://fredrik.hubbe.net/favicon.ico" alt="Lightsaber logo"></a>
  184. <a href="https://www.fett263.com/" target="_blank" title="Fett263's Style Library"><img src="https://www.fett263.com//favicon.ico" alt="Fett263 logo"></a>
  185. <a href="https://www.facebook.com/groups/opensourcesabers/" target="_blank" title="Open Source Group"><img src="https://www.facebook.com/favicon.ico" alt="Facebook logo"></a>
  186. </span>
  187. </div>
  188. </form>
  189. <script>
  190. let isEasyOptimizeActive = false;
  191. const sourceBoard = document.getElementById('sourceBoard');
  192. const targetBoard = document.getElementById('targetBoard');
  193. const proffieOptimizerButton = document.getElementById('proffieOptimizerButton');
  194. const optimizeCheckbox = document.getElementById('optimizeForProffie');
  195. const fileInput = document.getElementById('files');
  196. const downloadButton = document.getElementById('downloadButton');
  197. const progressBar = document.getElementById('uploadProgressBar');
  198. const progressStatus = document.getElementById('progressStatus');
  199. const form = document.getElementById('uploadForm');
  200.  
  201. document.addEventListener('DOMContentLoaded', function() {
  202. console.log('DOM fully loaded and parsed');
  203. toggleOptimizeCheckbox();
  204. });
  205.  
  206. targetBoard.addEventListener('change', function() {
  207. toggleOptimizeCheckbox();
  208. resetMessage();
  209. });
  210.  
  211. sourceBoard.addEventListener('change', function() {
  212. fileInput.value = '';
  213. resetMessage();
  214. });
  215.  
  216. proffieOptimizerButton.addEventListener('click', function() {
  217. proffieOptimizerButton.style.backgroundColor = 'dodgerblue';
  218. hideDownloadButton();
  219. isEasyOptimizeActive = true;
  220. fileInput.click();
  221. });
  222.  
  223. fileInput.addEventListener('mousedown', function(event) {
  224. const selectedFiles = fileInput.files;
  225. const convertButton = document.getElementById('convertInput');
  226. checkIfBoardsAreSame(event);
  227. });
  228.  
  229. fileInput.addEventListener('change', function() {
  230. if (this.files.length === 0) {
  231. isEasyOptimizeActive = false; // Reset the flag
  232. alert("No files selected. Please choose files before starting the conversion.");
  233. } else if (isEasyOptimizeActive && this.files.length > 0) {
  234. proffieOptimizerButton.style.backgroundColor = '#555';
  235. sourceBoard.value = "PROFFIE";
  236. targetBoard.value = "PROFFIE";
  237. optimizeCheckbox.checked = true;
  238.  
  239. setTimeout(() => {
  240. const event = new Event('submit', {
  241. 'bubbles': true,
  242. 'cancelable': true
  243. });
  244. form.dispatchEvent(event);
  245. }, 100);
  246. }
  247. });
  248.  
  249. function triggerDownload(targetBoard) {
  250. const wasEasyOptimizeActive = isEasyOptimizeActive; // Capture value here
  251. const xhr = new XMLHttpRequest();
  252. xhr.open('GET', `/downloadConvertedFiles?targetBoard=${targetBoard}`, true);
  253. xhr.responseType = 'blob';
  254.  
  255. xhr.onload = function() {
  256. if (this.status === 200) {
  257. const blob = this.response;
  258. const a = document.createElement('a');
  259. const url = window.URL.createObjectURL(blob);
  260.  
  261. a.href = url;
  262. if (wasEasyOptimizeActive) {
  263. a.download = `Optimized_for_PROFFIE.zip`;
  264. } else {
  265. a.download = `Converted_to_${targetBoard.toUpperCase()}.zip`;
  266. }
  267. document.body.appendChild(a);
  268. a.click();
  269. document.body.removeChild(a);
  270. window.URL.revokeObjectURL(url);
  271. // Delay the reset of the UI elements by 2 seconds
  272. setTimeout(() => {
  273. progressStatus.innerText = "Conversion complete.";
  274. if (isEasyOptimizeActive) {
  275. proffieOptimizerButton.style.backgroundColor = '#555';
  276. } else {
  277. downloadButton.style.backgroundColor = '#555';
  278. }
  279. }, 2000); // 2000 milliseconds = 2 seconds
  280. } else {
  281. console.error('Failed to download file:', this.status, this.statusText);
  282. }
  283. };
  284.  
  285. xhr.send();
  286. }
  287.  
  288. form.addEventListener('submit', function(event) {
  289. console.log("Form is being submitted. isEasyOptimizeActive:", isEasyOptimizeActive);
  290. const selectedFiles = fileInput.files;
  291.  
  292. if (selectedFiles.length === 0) {
  293. isEasyOptimizeActive = false; // Reset the flag
  294. alert("No files selected. Please choose files before starting the conversion.");
  295. event.preventDefault();
  296. return;
  297. }
  298.  
  299. event.preventDefault();
  300. const formData = new FormData(form);
  301.  
  302. const xhr = new XMLHttpRequest();
  303. xhr.open('POST', '/convert', true);
  304. xhr.setRequestHeader("Accept", "application/json");
  305.  
  306. xhr.upload.onprogress = function(event) {
  307. if (event.lengthComputable) {
  308. const percentComplete = (event.loaded / event.total) * 100;
  309. progressBar.value = percentComplete;
  310.  
  311. if (percentComplete < 100) {
  312. progressStatus.innerText = "Uploading files...";
  313. } else {
  314. progressStatus.innerText = "Files uploaded. Processing...";
  315. // Reset the progress bar and simulate conversion progress
  316. setTimeout(function() {
  317. progressBar.value = 0;
  318. simulateConversionProgress();
  319. }, 500);
  320. }
  321. }
  322. };
  323.  
  324. function simulateConversionProgress() {
  325. let value = 0;
  326. progressBar.interval = setInterval(function() { // Store the interval ID on the progressBar object
  327. if (value >= 100) {
  328. clearInterval(progressBar.interval);
  329. return;
  330. }
  331. value++;
  332. progressBar.value = value;
  333. if (value === 100) {
  334. progressStatus.innerText = "Conversion complete.";
  335. }
  336. }, 50); // this will complete the progress bar in 5 seconds. Adjust as needed.
  337. }
  338.  
  339. xhr.onload = function() {
  340. const response = JSON.parse(this.responseText);
  341. clearInterval(progressBar.interval);
  342.  
  343. if (response.status === "success") {
  344. progressBar.value = 100;
  345. progressStatus.innerText = "Conversion complete.";
  346. if (!isEasyOptimizeActive) {
  347. downloadButton.style.display = 'block';
  348. }
  349. else {
  350. const targetBoardValue = targetBoard.value;
  351. progressStatus.innerText = `Conversion complete. Standby for auto download of Optimized_for_PROFFIE.zip`;
  352. triggerDownload(targetBoardValue);
  353. }
  354. } else if (response.status === "info") {
  355. console.log('Response was info');
  356. progressStatus.innerText = response.message;
  357. downloadButton.style.display = 'none';
  358. } else {
  359. console.log('Response was something else');
  360. progressStatus.innerText = response.message;
  361. downloadButton.style.display = 'none';
  362. }
  363.  
  364. isEasyOptimizeActive = false;
  365. };
  366.  
  367. xhr.send(formData);
  368. });
  369.  
  370.  
  371. downloadButton.addEventListener('click', function() {
  372. // Change button text upon clicking
  373. progressStatus.innerText = "Fetching converted files. Standby for .zip download ...";
  374. downloadButton.style.backgroundColor = 'dodgerblue';
  375.  
  376. const targetBoardValue = targetBoard.value; // store this for later
  377. triggerDownload(targetBoardValue);
  378.  
  379. });
  380.  
  381.  
  382. function checkIfBoardsAreSame() {
  383. if (sourceBoard.value === "CFX" && (targetBoard.value === "PROFFIE" || targetBoard.value === "GH3")) {
  384. let confirmAction;
  385. if (targetBoard.value === "PROFFIE") {
  386. confirmAction = window.confirm("Conversion from CFX to PROFFIE is not required.\nProffieboards already natively support Plecter fonts.\nDo you want to continue anyway?");
  387. if (confirmAction) {
  388. // Manually open the file dialog since we previously blocked it
  389. fileInput.click();
  390. } else {
  391. toggleOptimizeCheckbox();
  392. }
  393. } else if (targetBoard.value === "GH3") {
  394. window.alert("Conversion from CFX to GH3 is unsupported.\nGH3 already natively supports Plecter fonts.");
  395. }
  396. } else if (sourceBoard.value === targetBoard.value) {
  397. if (sourceBoard.value === "PROFFIE") {
  398. window.alert("You've chosen Proffie to Proffie, which is for the purpose of optimizing the folder structure for best performance when using a FAT32 file system (which is what the SD card uses.)");
  399. optimizeCheckbox.checked = true;
  400. optimizeCheckbox.disabled = true;
  401. } else {
  402. window.alert("Conversion from " + sourceBoard.value + " to " + targetBoard.value + " is unnecessary.\nPlease choose a different conversion.");
  403. }
  404. } else {
  405. // Re-enable the checkbox if both boards are not Proffie
  406. optimizeCheckbox.disabled = false;
  407. }
  408. }
  409.  
  410. function resetMessage() {
  411. hideDownloadButton();
  412. progressBar.value = 0;
  413. progressStatus.innerText = "Waiting for files to be uploaded. Choose Files and click 'Convert'.";
  414. }
  415.  
  416. function hideDownloadButton() {
  417. downloadButton.style.display = 'none';
  418. }
  419.  
  420. function toggleOptimizeCheckbox() {
  421. var optimizeLabel = document.querySelector('label[for="optimizeForProffie"]');
  422.  
  423. if (targetBoard.value === "PROFFIE") {
  424. optimizeCheckbox.style.display = 'inline-block';
  425. optimizeLabel.style.display = 'inline-block';
  426. } else {
  427. optimizeCheckbox.style.display = 'none';
  428. optimizeLabel.style.display = 'none';
  429. }
  430. }
  431. </script>
  432.  
  433. </body>
  434. </html>
  435. ```
  436.  
  437. Original, working well version of SoundFontConverterController.java:
  438. ```
  439. package com.example.soundfontconverter;
  440.  
  441. import org.springframework.stereotype.Controller;
  442. import org.springframework.web.bind.annotation.GetMapping;
  443. import org.springframework.web.bind.annotation.PostMapping;
  444. import org.springframework.web.bind.annotation.RequestParam;
  445. import org.springframework.web.multipart.MultipartFile;
  446. import org.springframework.beans.factory.annotation.Autowired;
  447. import org.springframework.http.HttpStatus;
  448. import org.springframework.http.ResponseEntity;
  449. import org.springframework.http.HttpHeaders;
  450. import org.springframework.http.MediaType;
  451.  
  452. import java.io.IOException;
  453. import java.nio.file.Files;
  454. import java.nio.file.Path;
  455. import java.nio.file.Paths;
  456. import java.util.ArrayList;
  457. import java.util.List;
  458. import java.util.Map;
  459.  
  460. import java.io.StringWriter;
  461. import java.io.PrintWriter;
  462. // import javax.servlet.http.HttpServletResponse;
  463. import jakarta.servlet.http.HttpServletResponse;
  464. import jakarta.servlet.http.HttpServletRequest;
  465. import java.util.Enumeration;
  466. // import org.springframework.http.server.ServletServerHttpResponse;
  467. // import org.springframework.http.server.ServerHttpRequest;
  468.  
  469. @Controller
  470. public class SoundFontConverterController {
  471.  
  472. @Autowired
  473. private SoundFontNamingService soundFontNamingService;
  474. @Autowired
  475. private HttpServletRequest request;
  476.  
  477. @GetMapping("/")
  478. public String index() {
  479. return "index";
  480. }
  481.  
  482. @GetMapping("/downloadConvertedFiles")
  483. public ResponseEntity<?> downloadConvertedFiles(@RequestParam String targetBoard) {
  484. try {
  485. Path fileLocation = Paths.get("temporaryDirectory", "Converted_to_" + targetBoard + ".zip");
  486. byte[] data = Files.readAllBytes(fileLocation);
  487.  
  488. HttpHeaders headers = new HttpHeaders();
  489. headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileLocation.getFileName().toString());
  490. headers.setContentType(MediaType.parseMediaType("application/zip"));
  491.  
  492. return new ResponseEntity<>(data, headers, HttpStatus.OK);
  493. } catch (Exception e) {
  494. return new ResponseEntity<>("Error occurred while downloading file.", HttpStatus.INTERNAL_SERVER_ERROR);
  495. }
  496. }
  497.  
  498. @PostMapping("/convert")
  499. public ResponseEntity<?> convertSoundFont(
  500. @RequestParam String sourceBoard,
  501. @RequestParam String targetBoard,
  502. @RequestParam("files") MultipartFile[] files,
  503. @RequestParam(required = false) String optimizeForProffie) {
  504.  
  505. boolean optimize = "true".equals(optimizeForProffie); // Interpret the value
  506.  
  507. // Log all request parameters
  508. Enumeration<String> parameterNames = request.getParameterNames();
  509. while (parameterNames.hasMoreElements()) {
  510. String paramName = parameterNames.nextElement();
  511. String[] paramValues = request.getParameterValues(paramName);
  512. for (String paramValue : paramValues) {
  513. System.out.println("Param: " + paramName + " Value: " + paramValue);
  514. }
  515. }
  516.  
  517. // 1. Cleanup any existing temporaryDirectory before processing new files.
  518. soundFontNamingService.cleanupTemporaryDirectory();
  519.  
  520. Path tempDirPath = Paths.get("temporaryDirectory");
  521. if (!Files.exists(tempDirPath)) {
  522. try {
  523. Files.createDirectories(tempDirPath);
  524. } catch (IOException e) {
  525. return generateErrorResponse("Directory creation failed for path: " + tempDirPath, e);
  526. }
  527. }
  528.  
  529. List<Path> savedFiles = new ArrayList<>();
  530. for (MultipartFile file : files) {
  531. if (file.getOriginalFilename().endsWith(".DS_Store")) continue;
  532. Path savePath = Paths.get("temporaryDirectory", file.getOriginalFilename());
  533. try {
  534. Files.createDirectories(savePath.getParent());
  535. Files.copy(file.getInputStream(), savePath);
  536. savedFiles.add(savePath);
  537. } catch (IOException e) {
  538. return generateErrorResponse("File handling failed for path: " + savePath, e);
  539. }
  540. }
  541.  
  542. try {
  543. // 3. Convert files.
  544. soundFontNamingService.chainConvertSoundFont(savedFiles, sourceBoard, targetBoard, optimize);
  545.  
  546. // 4. Remove the original directory.
  547. String originalDirectoryName = savedFiles.get(0).getParent().getFileName().toString();
  548. soundFontNamingService.removeOriginalDirectory(originalDirectoryName);
  549.  
  550. // 5. Zip the converted files.
  551. Path resultZip = soundFontNamingService.zipConvertedFiles("temporaryDirectory/Converted_to_" + targetBoard);
  552.  
  553. // 6.Return a JSON indicating success instead of the zipped file
  554. return new ResponseEntity<>(Map.of("status", "success", "message", "Conversion complete!"), HttpStatus.OK);
  555. } catch (Exception e) {
  556. return new ResponseEntity<>(Map.of("status", "error", "message", "Conversion failed due to " + e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
  557. }
  558. }
  559.  
  560. private ResponseEntity<String> generateErrorResponse(String message, Exception e) {
  561. StringWriter sw = new StringWriter();
  562. e.printStackTrace(new PrintWriter(sw));
  563. String exceptionAsString = sw.toString();
  564. return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(message + exceptionAsString);
  565. }
  566.  
  567. }
  568. ```
  569.  
  570. Original, well working version of SoundFontNamingService.java:
  571. ```
  572. package com.example.soundfontconverter;
  573.  
  574. import org.springframework.stereotype.Service;
  575.  
  576. import java.io.IOException;
  577. import java.nio.file.*;
  578. import java.util.HashMap;
  579. import java.util.List;
  580. import java.util.Map;
  581. import java.io.BufferedReader;
  582. import java.io.File;
  583. import java.io.FileReader;
  584. import java.util.stream.Stream;
  585. import java.util.Comparator;
  586. import java.util.stream.Collectors;
  587. import java.text.SimpleDateFormat;
  588. import java.util.Date;
  589.  
  590. @Service
  591. public class SoundFontNamingService {
  592.  
  593. enum BoardType {
  594. CFX,
  595. GH3,
  596. PROFFIE,
  597. VERSO,
  598. XENO3;
  599.  
  600. public static String getKey(BoardType source, BoardType target) {
  601. return source.name() + "_TO_" + target.name();
  602. }
  603. }
  604. private StringBuilder logStringBuilder = new StringBuilder();
  605. private boolean chained = false;
  606. private String realTarget = "PROFFIE";
  607. private static final String DEFAULTS_PATH = "./inis";
  608. private static final Map<String, String> CFX_TO_PROFFIE = new HashMap<>();
  609. private static final Map<String, String> CFX_TO_VERSO = new HashMap<>();
  610. private static final Map<String, String> GH3_TO_PROFFIE = new HashMap<>();
  611. private static final Map<String, String> PROFFIE_TO_CFX = new HashMap<>();
  612. private static final Map<String, String> PROFFIE_TO_GH3 = new HashMap<>();
  613. private static final Map<String, String> PROFFIE_TO_VERSO = new HashMap<>();
  614. private static final Map<String, String> PROFFIE_TO_XENO3 = new HashMap<>();
  615. private static final Map<String, String> VERSO_TO_CFX = new HashMap<>();
  616. private static final Map<String, String> VERSO_TO_PROFFIE = new HashMap<>();
  617. private static final Map<String, String> XENO3_TO_PROFFIE = new HashMap<>();
  618. //... additional board mappings can be added here
  619.  
  620. // Central mapping repository
  621. private static final Map<String, Map<String, String>> soundMappings = new HashMap<>();
  622. private static final Map<String, Integer> soundCounter = new HashMap<>();
  623.  
  624. static {
  625. initializeMappings();
  626. }
  627.  
  628. private static void loadMappingsFromCSV(String csvFilePath, Map<String, String> mapping) {
  629. try (BufferedReader reader = new BufferedReader(new FileReader(csvFilePath))) {
  630. String line;
  631. while ((line = reader.readLine()) != null) {
  632. String[] parts = line.split(",");
  633. if (parts.length >= 2) {
  634. mapping.put(parts[0], parts[1]);
  635. }
  636. }
  637. } catch (IOException e) {
  638. e.printStackTrace();
  639. }
  640. }
  641.  
  642. private static void safeLoadMappingsFromCSV(String csvFilePath, Map<String, String> mapping) {
  643. File f = new File(csvFilePath);
  644. if(f.exists() && !f.isDirectory()) {
  645. loadMappingsFromCSV(csvFilePath, mapping);
  646. }
  647. }
  648.  
  649. private static void initializeMappings() {
  650. safeLoadMappingsFromCSV("./CSV/CFX_TO_PROFFIE.csv", CFX_TO_PROFFIE);
  651. // safeLoadMappingsFromCSV("./CSV/CFX_TO_VERSO.csv", CFX_TO_VERSO);
  652. // safeLoadMappingsFromCSV("./CSV/GH3_TO_PROFFIE.csv", GH3_TO_PROFFIE);
  653. safeLoadMappingsFromCSV("./CSV/PROFFIE_TO_CFX.csv", PROFFIE_TO_CFX);
  654. // safeLoadMappingsFromCSV("./CSV/PROFFIE_TO_GH3.csv", PROFFIE_TO_CFX);
  655. safeLoadMappingsFromCSV("./CSV/PROFFIE_TO_VERSO.csv", PROFFIE_TO_VERSO);
  656. safeLoadMappingsFromCSV("./CSV/PROFFIE_TO_XENO3.csv", PROFFIE_TO_XENO3);
  657. // safeLoadMappingsFromCSV("./CSV/VERSO_TO_PROFFIE.csv", VERSO_TO_PROFFIE);
  658. safeLoadMappingsFromCSV("./CSV/XENO3_TO_PROFFIE.csv", XENO3_TO_PROFFIE);
  659. // ... and so on for other mappings ...
  660.  
  661. soundMappings.put(BoardType.getKey(BoardType.CFX, BoardType.PROFFIE), CFX_TO_PROFFIE);
  662. // soundMappings.put(BoardType.getKey(BoardType.CFX, BoardType.VERSO), CFX_TO_VERSO);
  663. soundMappings.put(BoardType.getKey(BoardType.PROFFIE, BoardType.CFX), PROFFIE_TO_CFX);
  664. soundMappings.put(BoardType.getKey(BoardType.PROFFIE, BoardType.GH3), PROFFIE_TO_CFX);
  665. soundMappings.put(BoardType.getKey(BoardType.PROFFIE, BoardType.VERSO), PROFFIE_TO_VERSO);
  666. soundMappings.put(BoardType.getKey(BoardType.PROFFIE, BoardType.XENO3), PROFFIE_TO_XENO3);
  667. soundMappings.put(BoardType.getKey(BoardType.GH3, BoardType.PROFFIE), CFX_TO_PROFFIE);
  668. // soundMappings.put(BoardType.getKey(BoardType.VERSO, BoardType.CFX), VERSO_TO_CFX);
  669. soundMappings.put(BoardType.getKey(BoardType.VERSO, BoardType.PROFFIE), VERSO_TO_PROFFIE);
  670. soundMappings.put(BoardType.getKey(BoardType.XENO3, BoardType.PROFFIE), XENO3_TO_PROFFIE);
  671.  
  672. // Reverse Mapping fist so actual mappings will override
  673.  
  674. // CFX to Proffie mapping
  675. for (Map.Entry<String, String> entry : PROFFIE_TO_CFX.entrySet()) {
  676. CFX_TO_PROFFIE.putIfAbsent(entry.getValue(), entry.getKey());
  677. }
  678. // for (Map.Entry<String, String> entry : VERSO_TO_CFX.entrySet()) {
  679. // CFX_TO_VERSO.putIfAbsent(entry.getValue(), entry.getKey());
  680. // }
  681. // Verso to Proffie mapping
  682. for (Map.Entry<String, String> entry : PROFFIE_TO_VERSO.entrySet()) {
  683. VERSO_TO_PROFFIE.putIfAbsent(entry.getValue(), entry.getKey());
  684. }
  685. // Xeno3 to Proffie mapping
  686. for (Map.Entry<String, String> entry : PROFFIE_TO_XENO3.entrySet()) {
  687. XENO3_TO_PROFFIE.putIfAbsent(entry.getValue(), entry.getKey());
  688. }
  689. }
  690.  
  691. private static void ensureDirectoryExists(Path dirPath) {
  692. try {
  693. if (!Files.exists(dirPath)) {
  694. Files.createDirectories(dirPath);
  695. System.out.println("Creating directory: " + dirPath);
  696. }
  697. } catch (IOException ex) {
  698. ex.printStackTrace();
  699. }
  700. }
  701.  
  702. private static void copyFile(Path sourcePath, Path targetPath) {
  703. try {
  704. Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
  705. } catch (IOException ex) {
  706. System.err.println("Error copying file from " + sourcePath + " to " + targetPath);
  707. ex.printStackTrace();
  708. }
  709. }
  710.  
  711. // If no optimizeForProffie parameter is included, default optimizeForProffie to true
  712. private void convertSounds(BoardType sourceBoard, String sourceDir, BoardType targetBoard, String targetDir) throws IOException {
  713. convertSounds(sourceBoard, sourceDir, targetBoard, targetDir, true);
  714. }
  715.  
  716. // This version takes the optimizeForProffie parameter. It's the main logic
  717. private void convertSounds(BoardType sourceBoard, String sourceDir, BoardType targetBoard, String targetDir, boolean optimizeForProffie) throws IOException {
  718. soundCounter.clear();
  719. String key = BoardType.getKey(sourceBoard, targetBoard);
  720. System.out.println("----------------------------------------------------------------\n.");
  721. if (targetBoard == BoardType.PROFFIE && realTarget == "PROFFIE") {
  722. System.out.println("Converting from " + sourceBoard + " to " + targetBoard + "\n.");
  723. } else if (targetBoard != BoardType.PROFFIE) {
  724. realTarget = targetBoard.toString();
  725. } else {
  726. System.out.println("Converting from " + sourceBoard + " to " + realTarget + "\n.");
  727. }
  728.  
  729. // Directory structure code here:
  730. String sourceDirName = new File(sourceDir).getName();
  731. // Include a special case for GH3 output directory naming
  732. String finalTargetDir = targetDir + "/Converted_to_" + targetBoard + "/" +
  733. (targetBoard == BoardType.GH3 ? "sound1 - " : "") +
  734. sourceDirName;
  735.  
  736. // Prepare Log file
  737. if (chained == false) {
  738. ensureDirectoryExists(Paths.get(finalTargetDir));
  739. SimpleDateFormat sdf = new SimpleDateFormat("MMM dd, yyyy");
  740. String currentDate = sdf.format(new Date());
  741. logStringBuilder.append("Converted with SoundFont Naming Converter 3.0\n");
  742. logStringBuilder.append("Brian Conner a.k.a NoSloppy\n\n");
  743. logStringBuilder.append(currentDate).append("\n");
  744.  
  745. if (targetBoard == BoardType.PROFFIE && realTarget == "PROFFIE") {
  746. logStringBuilder.append("Converted: ").append(sourceBoard).append(" to ").append(targetBoard).append("\n");
  747. logStringBuilder.append("Optimized for Fat32 performance: ").append(optimizeForProffie ? "Yes" : "No").append("\n\n");
  748. } else if (targetBoard != BoardType.PROFFIE) {
  749. realTarget = targetBoard.toString();
  750. } else {
  751. logStringBuilder.append("Converted: ").append(sourceBoard).append(" to ").append(realTarget).append("\n");
  752. logStringBuilder.append("\n");
  753. }
  754. }
  755.  
  756. // If it's Proffie to Proffie, skip the mapping
  757. Map<String, String> mapping;
  758. if (sourceBoard == BoardType.PROFFIE && targetBoard == BoardType.PROFFIE) {
  759. mapping = null; // No mapping required for Proffie to Proffie
  760. } else {
  761. if (!soundMappings.containsKey(key)) {
  762. System.out.println("Conversion from " + sourceBoard + " to " + targetBoard + " is not supported.");
  763. return;
  764. }
  765. mapping = soundMappings.get(key);
  766. }
  767.  
  768. ensureDirectoryExists(Paths.get(finalTargetDir));
  769.  
  770. // Check if source has directories named something like "Bonus Files" or "extra"
  771. boolean hasExtrasDirectories = false;
  772. try {
  773. hasExtrasDirectories = Files.walk(Paths.get(sourceDir), 1) // Only check immediate children
  774. .filter(Files::isDirectory).anyMatch(path -> {
  775. String dirName = path.getFileName().toString().toLowerCase();
  776. return dirName.contains("bonus") || dirName.contains("extra");
  777. });
  778. } catch (IOException ex) {
  779. ex.printStackTrace();
  780. }
  781.  
  782. // If "extras" directory is needed, create it now
  783. if (hasExtrasDirectories) {
  784. ensureDirectoryExists(Paths.get(finalTargetDir + "/extras"));
  785. }
  786.  
  787. // Main sound conversion
  788. try (Stream<Path> paths = Files.walk(Paths.get(sourceDir))) {
  789. Map<String, Integer> fileNameCounter = new HashMap<>();
  790. boolean fontSoundProcessed = false;
  791.  
  792. paths.filter(Files::isRegularFile)
  793. .filter(path -> !path.getFileName().toString().startsWith("."))
  794. .filter(path -> {
  795.  
  796. String parentDirName = path.getParent().getFileName().toString().toLowerCase();
  797. if (parentDirName.contains("bonus") || parentDirName.contains("extra")) {
  798. copyFile(path, Paths.get(finalTargetDir, "extras", path.getFileName().toString()));
  799. String logEntryExtras = "Moved extra/bonus file to " + finalTargetDir + "/extras/" + path.getFileName();
  800. System.out.println(logEntryExtras);
  801. logStringBuilder.append(logEntryExtras).append("\n");
  802. return false;
  803. }
  804. return true;
  805. })
  806. .sorted(Comparator.comparing(Path::toString))
  807. .forEach(path -> {
  808. try {
  809. String fileName = path.getFileName().toString();
  810.  
  811. // Move non-wav files directly to the target folder
  812. if (!fileName.endsWith(".wav")) {
  813. copyFile(path, Paths.get(finalTargetDir, fileName));
  814. String logEntryNonWav = "Moved non-wav file: " + fileName;
  815. System.out.println(logEntryNonWav);
  816. logStringBuilder.append(logEntryNonWav).append("\n");
  817. return;
  818. }
  819.  
  820. // Move "track" wav files to "tracks" folder
  821. if (fileName.contains("track")) {
  822. ensureDirectoryExists(Paths.get(finalTargetDir + "/tracks"));
  823. copyFile(path, Paths.get(finalTargetDir, "tracks", fileName));
  824. String logEntryTrack = "Moved track file: " + fileName;
  825. System.out.println(logEntryTrack);
  826. logStringBuilder.append(logEntryTrack).append("\n");
  827. return;
  828. }
  829.  
  830. // For other wav files, use the mapping
  831. String baseName = fileName.replaceAll(" (\\(\\d+\\))?\\.wav$|\\d+\\.wav$", ".wav");
  832. // If we're doing Proffie to Proffie, keep the baseName as is
  833. String convertedBaseName = (mapping == null) ? baseName : mapping.getOrDefault(baseName, baseName);
  834.  
  835. String outputPath;
  836. if (convertedBaseName != null) {
  837. int count = soundCounter.getOrDefault(convertedBaseName, 0) + 1;
  838. soundCounter.put(convertedBaseName, count);
  839.  
  840. String prefix = (convertedBaseName.contains(".")) ? convertedBaseName.substring(0, convertedBaseName.lastIndexOf('.')) : convertedBaseName;
  841. String formattedCount = String.valueOf(count);
  842.  
  843. if (targetBoard == BoardType.CFX) {
  844. String newPrefix;
  845. int currentCounter;
  846.  
  847. String switchKey = convertedBaseName.toLowerCase().replaceAll("\\.wav$", "");
  848. String commonKey;
  849. switch (switchKey) {
  850. // First, handle the special numbering and weird naming cases
  851. case "poweroff":
  852. commonKey = "pwroff";
  853. currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  854. if (currentCounter == 1) {
  855. newPrefix = "poweroff";
  856. } else if (currentCounter == 2) {
  857. newPrefix = "pwroff2";
  858. } else {
  859. newPrefix = "poweroff" + (currentCounter - 1);
  860. }
  861. outputPath = finalTargetDir + "/" + newPrefix + ".wav";
  862. fileNameCounter.put(commonKey, currentCounter + 1);
  863. break;
  864.  
  865. // case "clash":
  866. // commonKey = "clash";
  867. // currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  868. // if (currentCounter == 1) {
  869. // newPrefix = "clash" + currentCounter;
  870. // } else if (currentCounter == 2) {
  871. // newPrefix = "fclash" + (currentCounter -1);
  872. // } else {
  873. // newPrefix = "clash" + (currentCounter - 1);
  874. // }
  875. // outputPath = finalTargetDir + "/" + newPrefix + ".wav";
  876. // fileNameCounter.put(commonKey, currentCounter + 1);
  877. // break;
  878.  
  879. case "font":
  880. commonKey = "font";
  881. currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  882. if (currentCounter == 1) {
  883. outputPath = finalTargetDir + "/font" + ".wav";
  884. } else {
  885. int nextBootCounter = fileNameCounter.getOrDefault("boot", 1);
  886. outputPath = finalTargetDir + "/boot" + (nextBootCounter == 1 ? "" : nextBootCounter) + ".wav";
  887. fileNameCounter.put("boot", nextBootCounter + 1);
  888. }
  889. fileNameCounter.put(commonKey, currentCounter + 1);
  890. break;
  891.  
  892. // These get no number on the first file, then sequence the rest staring from 2
  893. case "boot":
  894. commonKey = "boot";
  895. currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  896. outputPath = finalTargetDir + "/boot" + (currentCounter == 1 ? "" : currentCounter) + ".wav";
  897. fileNameCounter.put(commonKey, currentCounter + 1);
  898. break;
  899.  
  900. case "color":
  901. commonKey = "color";
  902. currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  903. outputPath = finalTargetDir + "/" + convertedBaseName.substring(0, convertedBaseName.length() - 4) + (currentCounter == 1 ? "" : currentCounter) + ".wav";
  904. fileNameCounter.put(commonKey, currentCounter + 1);
  905. break;
  906. case "blaster":
  907. commonKey = "blaster";
  908. currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  909. outputPath = finalTargetDir + "/" + convertedBaseName.substring(0, convertedBaseName.length() - 4) + (currentCounter == 1 ? "" : currentCounter) + ".wav";
  910. fileNameCounter.put(commonKey, currentCounter + 1);
  911. break;
  912. case "poweron":
  913. commonKey = "poweron";
  914. currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  915. outputPath = finalTargetDir + "/" + convertedBaseName.substring(0, convertedBaseName.length() - 4) + (currentCounter == 1 ? "" : currentCounter) + ".wav";
  916. fileNameCounter.put(commonKey, currentCounter + 1);
  917. break;
  918. case "lockup":
  919. commonKey = "lockup";
  920. currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  921. outputPath = finalTargetDir + "/" + convertedBaseName.substring(0, convertedBaseName.length() - 4) + (currentCounter == 1 ? "" : currentCounter) + ".wav";
  922. fileNameCounter.put(commonKey, currentCounter + 1);
  923. break;
  924. case "drag":
  925. commonKey = "drag";
  926. currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  927. outputPath = finalTargetDir + "/" + convertedBaseName.substring(0, convertedBaseName.length() - 4) + (currentCounter == 1 ? "" : currentCounter) + ".wav";
  928. fileNameCounter.put(commonKey, currentCounter + 1);
  929. break;
  930. case "force":
  931. commonKey = "force";
  932. currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  933. outputPath = finalTargetDir + "/" + convertedBaseName.substring(0, convertedBaseName.length() - 4) + (currentCounter == 1 ? "" : currentCounter) + ".wav";
  934. fileNameCounter.put(commonKey, currentCounter + 1);
  935. break;
  936.  
  937. default:
  938. currentCounter = fileNameCounter.getOrDefault(switchKey, 1);
  939. outputPath = finalTargetDir + "/" + convertedBaseName.substring(0, convertedBaseName.length() - 4) + currentCounter + ".wav";
  940.  
  941. fileNameCounter.put(switchKey, currentCounter + 1);
  942. break;
  943. }
  944.  
  945. } else if (targetBoard == BoardType.PROFFIE) {
  946. if (prefix.length() > 6 && count == 1 && soundCounter.containsKey(baseName)) {
  947. formattedCount = String.valueOf(count);
  948. } else {
  949. formattedCount = (prefix.length() > 6) ? String.valueOf(count) : String.format("%02d", count);
  950. }
  951. if (optimizeForProffie) {
  952. outputPath = count == 1 ? finalTargetDir + "/" + prefix + ".wav" : finalTargetDir + "/" + prefix + "/" + prefix + formattedCount + ".wav";
  953.  
  954. if (count == 2) {
  955. Path originalPath = Paths.get(finalTargetDir, prefix + ".wav");
  956. Path newPath = Paths.get(finalTargetDir, prefix, prefix + (prefix.length() > 6 ? "1" : "01") + ".wav");
  957. ensureDirectoryExists(Paths.get(finalTargetDir + "/" + prefix));
  958. Files.move(originalPath, newPath, StandardCopyOption.REPLACE_EXISTING);
  959. String logEntryProffie = "Numbered and moved first file to subdirectory:\n"
  960. + " " + originalPath.subpath(2, originalPath.getNameCount())
  961. + " -> "
  962. + newPath.subpath(2, newPath.getNameCount());
  963. System.out.println(logEntryProffie);
  964. logStringBuilder.append(logEntryProffie).append("\n");
  965. }
  966. } else {
  967. outputPath = finalTargetDir + "/" + (count > 1 ? prefix + formattedCount : prefix) + ".wav";
  968.  
  969. if (count == 2) {
  970. Path originalPath = Paths.get(finalTargetDir, prefix + ".wav");
  971. Path newPath = Paths.get(finalTargetDir, prefix + (prefix.length() > 6 ? "1" : "01") + ".wav");
  972. Files.move(originalPath, newPath, StandardCopyOption.REPLACE_EXISTING);
  973. String logEntryProffie = "Numbered the first file:\n "
  974. + " " + originalPath.subpath(2, originalPath.getNameCount())
  975. + " -> "
  976. + newPath.subpath(2, newPath.getNameCount());
  977. System.out.println(logEntryProffie);
  978. logStringBuilder.append(logEntryProffie).append("\n");
  979. }
  980. }
  981. } else if (targetBoard == BoardType.VERSO && convertedBaseName.equals("font.wav")) {
  982. String commonKey = "font";
  983. int currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  984. fileNameCounter.put(commonKey, currentCounter + 1);
  985.  
  986. if (currentCounter == 1) {
  987. outputPath = finalTargetDir + "/font.wav";
  988. copyFile(path, Paths.get(outputPath));
  989. String logEntryVerso = "Converted: " + path.getFileName().toString() + " -> " + outputPath.replace("temporaryDirectory/", "");
  990. System.out.println(logEntryVerso);
  991. logStringBuilder.append(logEntryVerso).append("\n");
  992. } else {
  993. String logEntryVersoSkipped = "Skipped additional 'font' file: " + fileName;
  994. System.out.println(logEntryVersoSkipped);
  995. logStringBuilder.append(logEntryVersoSkipped).append("\n");
  996. }
  997. return;
  998.  
  999. } else if (targetBoard == BoardType.XENO3) {
  1000. outputPath = Paths.get(finalTargetDir, prefix + " (" + count + ").wav").toString();
  1001.  
  1002. } else if (count > 1 || (targetBoard != BoardType.PROFFIE && count == 1)) {
  1003. outputPath = Paths.get(finalTargetDir, prefix + formattedCount + ".wav").toString();
  1004. } else {
  1005. outputPath = Paths.get(finalTargetDir, prefix + ".wav").toString();
  1006. }
  1007.  
  1008. copyFile(path, Paths.get(outputPath));
  1009. String logEntry = "Converted: " + path.getFileName().toString() + " -> " + outputPath.replace("temporaryDirectory/", "");
  1010. System.out.println(logEntry);
  1011. logStringBuilder.append(logEntry).append("\n");
  1012.  
  1013. } else { // convertedBaseName = null
  1014. System.out.println("Skipped wav file without mapping: " + fileName);
  1015. }
  1016. } catch (IOException e) {
  1017. System.err.println("An IOException occurred: " + e.getMessage());
  1018. }
  1019. });
  1020. if (chained == true) {
  1021. logStringBuilder.append("\n*********----- MTFBWY -----*********\n");
  1022. } else {
  1023. logStringBuilder.append("\n\n");
  1024. }
  1025. try {
  1026. System.out.println("--- Writing _Conversion_Log.txt ---");
  1027. Files.writeString(Paths.get(finalTargetDir, "_Conversion_Log.txt"), logStringBuilder.toString());
  1028. } catch (IOException e) {
  1029. System.err.println("Failed to write log: " + e.getMessage());
  1030. }
  1031. } catch (IOException ex) {
  1032. System.err.println("An error occurred while reading the file: " + ex.getMessage());
  1033. }
  1034.  
  1035. // After processing all files, check for default INIs for Proffie
  1036. if (targetBoard == BoardType.PROFFIE) {
  1037. String[] defaultFiles = {"config.ini", "smoothsw.ini"};
  1038. for (String defaultFile : defaultFiles) {
  1039. File targetDefaultFile = new File(finalTargetDir, defaultFile);
  1040. if (!targetDefaultFile.exists()) {
  1041. File inisFile = new File(DEFAULTS_PATH + "/" + defaultFile);
  1042. if (inisFile.exists()) {
  1043. try {
  1044. Files.copy(inisFile.toPath(), targetDefaultFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
  1045. System.out.println("Copied default file: " + defaultFile);
  1046. } catch (IOException e) {
  1047. // e.printStackTrace();
  1048. System.err.println("Error while copying file: " + defaultFile);
  1049.  
  1050. }
  1051. }
  1052. }
  1053. }
  1054. }
  1055. }
  1056.  
  1057. public class MutableInt {
  1058. public int value;
  1059. public MutableInt(int value) {
  1060. this.value = value;
  1061. }
  1062. }
  1063.  
  1064. public void cleanupTemporaryDirectory() {
  1065. System.out.println("Removing any existing temporaryDirectory and generated zip file");
  1066. try {
  1067. Path tempDir = Paths.get("temporaryDirectory");
  1068. if (Files.exists(tempDir)) {
  1069. Files.walk(tempDir)
  1070. .sorted(Comparator.reverseOrder()) // Important to delete child before parent
  1071. .forEach(path -> {
  1072. try {
  1073. Files.deleteIfExists(path);
  1074. } catch (IOException e) {
  1075. // Handle the exception, e.g., logging it.
  1076. e.printStackTrace();
  1077. }
  1078. });
  1079. }
  1080.  
  1081. // Deleting the generated zip file.
  1082. Files.deleteIfExists(Paths.get("temporaryDirectory.zip"));
  1083.  
  1084. } catch (IOException e) {
  1085. // Handle the exception, e.g., logging it.
  1086. e.printStackTrace();
  1087. }
  1088. }
  1089.  
  1090. public void convertSoundFont(List<Path> savedFiles, String sourceBoard, String targetBoard, boolean optimize) throws IOException {
  1091. BoardType srcBoard = BoardType.valueOf(sourceBoard.toUpperCase());
  1092. BoardType tgtBoard = BoardType.valueOf(targetBoard.toUpperCase());
  1093.  
  1094. String sourceDir = savedFiles.get(0).getParent().toString();
  1095. convertSounds(srcBoard, sourceDir, tgtBoard, "temporaryDirectory", optimize);
  1096. }
  1097.  
  1098. public void chainConvertSoundFont(List<Path> savedFiles, String sourceBoard, String targetBoard, boolean optimize) throws IOException {
  1099. // Clear the StringBuilder for subsequent log entries
  1100. logStringBuilder.setLength(0);
  1101. if ("PROFFIE".equals(sourceBoard) || "PROFFIE".equals(targetBoard)) {
  1102. // Just convert normally.
  1103. convertSoundFont(savedFiles, sourceBoard, targetBoard, optimize);
  1104. } else {
  1105. // Do the chained conversion;
  1106. // cCnvert to PROFFIE first and save it in /temporaryDirectory/Converted_to_PROFFIE.
  1107. // Using realTarget for logging only
  1108. realTarget = targetBoard;
  1109. convertSoundFont(savedFiles, sourceBoard, "PROFFIE", false);
  1110. chained = !chained;
  1111.  
  1112. // Now use the converted PROFFIE files as source for the actual target.
  1113. // Clear the StringBuilder for subsequent log entries
  1114. //logStringBuilder.setLength(0);
  1115. Path tempProffieDir = Paths.get("temporaryDirectory", "Converted_to_PROFFIE");
  1116. List<Path> proffieFiles = Files.walk(tempProffieDir)
  1117. .filter(Files::isRegularFile)
  1118. .collect(Collectors.toList());
  1119. convertSoundFont(proffieFiles, "PROFFIE", targetBoard, false);
  1120. chained = !chained;
  1121.  
  1122. // Optional: Cleanup the temporary directory used for the PROFFIE conversion.
  1123. }
  1124. }
  1125.  
  1126. public void removeOriginalDirectory(String originalDirName) {
  1127. Path originalDir = Paths.get("temporaryDirectory", originalDirName);
  1128. try {
  1129. System.out.println("Initiating removal of directory: " + originalDir.toString());
  1130. Files.walk(originalDir)
  1131. .sorted(Comparator.reverseOrder()) // Important to delete child before parent
  1132. .forEach(path -> {
  1133. try {
  1134. Files.deleteIfExists(path);
  1135. } catch (IOException e) {
  1136. e.printStackTrace();
  1137. }
  1138. });
  1139. } catch (IOException e) {
  1140. e.printStackTrace();
  1141. }
  1142. System.out.println("Completed removal of directory: " + originalDir.toString());
  1143. }
  1144.  
  1145. public Path zipConvertedFiles(String targetDir) throws IOException {
  1146. Path zipPath = Paths.get(targetDir + ".zip");
  1147.  
  1148. // Logging the structure
  1149. Path sourcePath = Paths.get(targetDir);
  1150. System.out.println("Logging directory structure before zipping:");
  1151. Files.walk(sourcePath).forEach(p -> {
  1152. // System.out.println(p.toString());
  1153. });
  1154. System.out.println("Starting to create ZIP file...");
  1155.  
  1156. try (FileSystem zipFs = FileSystems.newFileSystem(zipPath, Map.of("create", "true"))) {
  1157. // Exclude the top-level source directory itself when walking
  1158. Files.walk(sourcePath).filter(p -> !p.equals(sourcePath)).forEach(path -> {
  1159. try {
  1160. if (Files.isRegularFile(path) && Files.size(path) > 0) { // Ensure it's a file and has content
  1161. String sourceDirName = sourcePath.getFileName().toString();
  1162. Path destPath = zipFs.getPath("/" + sourceDirName + "/" + sourcePath.relativize(path).toString());
  1163.  
  1164. // Ensure the parent directory structure exists in the ZIP
  1165. if (destPath.getParent() != null) {
  1166. Files.createDirectories(destPath.getParent());
  1167. }
  1168.  
  1169. Files.copy(path, destPath, StandardCopyOption.REPLACE_EXISTING);
  1170. }
  1171. } catch (NoSuchFileException e) {
  1172. System.err.println("Directory structure in ZIP does not match expected structure: " + e.getMessage());
  1173. } catch (Exception e) {
  1174. e.printStackTrace();
  1175. System.err.println("Error processing file: " + path.toString() +
  1176. ". Destination path in ZIP: " + zipFs.getPath("/" + sourcePath.relativize(path).toString()));
  1177. }
  1178. });
  1179.  
  1180. } catch (Exception e) {
  1181. e.printStackTrace();
  1182. throw new IOException("Error encountered during zip operation: " + e.getMessage());
  1183. }
  1184. System.out.println("Conversion complete. Zip file saved and ready for download from " + targetDir + ".zip");
  1185. return zipPath;
  1186. }
  1187. }
  1188. ```
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement