Advertisement
NoSloppy

all

Oct 12th, 2023
42
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 56.31 KB | None | 0 0
  1. 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. // Assuming conversionData is the data received from the backend
  250. function processFiles(conversionData, files) {
  251. const zip = new JSZip();
  252.  
  253. files.forEach(file => {
  254. const newFilePath = getNewFilePath(file.name, conversionData); // Assume this function determines the new path
  255. const folderPath = newFilePath.substring(0, newFilePath.lastIndexOf('/'));
  256. const fileName = newFilePath.substring(newFilePath.lastIndexOf('/') + 1);
  257.  
  258. if (folderPath) {
  259. zip.folder(folderPath);
  260. }
  261.  
  262. zip.file(newFilePath, file);
  263. });
  264.  
  265. zip.generateAsync({type:"blob"})
  266. .then(function(blob) {
  267. saveZip(blob); // Assume this function triggers the download of the blob
  268. });
  269. }
  270.  
  271. function getNewFilePath(oldFilePath, conversionData) {
  272. // ... logic to determine the new file path based on conversionData
  273. }
  274.  
  275. function saveZip(blob) {
  276. // ... logic to trigger download
  277. }
  278.  
  279.  
  280. async function processAndDownload(targetBoard) {
  281. const wasEasyOptimizeActive = isEasyOptimizeActive; // Capture value here
  282. const response = await fetch(`/getConversionData?targetBoard=${targetBoard}`);
  283. const conversionData = await response.json();
  284. const files = Array.from(document.getElementById('files').files);
  285. processFiles(conversionData, files);
  286.  
  287. // Delay the reset of the UI elements by 2 seconds
  288. setTimeout(() => {
  289. progressStatus.innerText = "Conversion complete.";
  290. if (isEasyOptimizeActive) {
  291. proffieOptimizerButton.style.backgroundColor = '#555';
  292. } else {
  293. downloadButton.style.backgroundColor = '#555';
  294. }
  295. }, 2000); // 2000 milliseconds = 2 seconds
  296. }
  297.  
  298.  
  299. function getNewFilePath(oldFilePath, conversionData) {
  300. // Example logic, replace with actual logic based on conversionData
  301. return conversionData[oldFilePath] || oldFilePath;
  302. }
  303.  
  304. function saveZip(blob) {
  305. const a = document.createElement('a');
  306. const url = window.URL.createObjectURL(blob);
  307.  
  308. a.href = url;
  309. a.download = 'ConvertedFiles.zip'; // replace with desired file name
  310. document.body.appendChild(a);
  311. a.click();
  312. document.body.removeChild(a);
  313. window.URL.revokeObjectURL(url);
  314. }
  315.  
  316.  
  317. form.addEventListener('submit', function(event) {
  318. console.log("Form is being submitted. isEasyOptimizeActive:", isEasyOptimizeActive);
  319. const selectedFiles = fileInput.files;
  320.  
  321. if (selectedFiles.length === 0) {
  322. isEasyOptimizeActive = false; // Reset the flag
  323. alert("No files selected. Please choose files before starting the conversion.");
  324. event.preventDefault();
  325. return;
  326. }
  327.  
  328. event.preventDefault();
  329. const fileNames = Array.from(selectedFiles).map(file => file.name);
  330. const fileNamesJson = JSON.stringify({fileNames: fileNames});
  331. const xhr = new XMLHttpRequest();
  332. xhr.open('POST', '/convert', true);
  333. xhr.setRequestHeader("Accept", "application/json");
  334.  
  335. xhr.upload.onprogress = function(event) {
  336. if (event.lengthComputable) {
  337. const percentComplete = (event.loaded / event.total) * 100;
  338. progressBar.value = percentComplete;
  339.  
  340. if (percentComplete < 100) {
  341. progressStatus.innerText = "Uploading files...";
  342. } else {
  343. progressStatus.innerText = "Files uploaded. Processing...";
  344. // Reset the progress bar and simulate conversion progress
  345. setTimeout(function() {
  346. progressBar.value = 0;
  347. simulateConversionProgress();
  348. }, 500);
  349. }
  350. }
  351. };
  352.  
  353. function simulateConversionProgress() {
  354. let value = 0;
  355. progressBar.interval = setInterval(function() { // Store the interval ID on the progressBar object
  356. if (value >= 100) {
  357. clearInterval(progressBar.interval);
  358. return;
  359. }
  360. value++;
  361. progressBar.value = value;
  362. if (value === 100) {
  363. progressStatus.innerText = "Conversion complete.";
  364. }
  365. }, 50); // this will complete the progress bar in 5 seconds. Adjust as needed.
  366. }
  367.  
  368. xhr.onload = function() {
  369. const response = JSON.parse(this.responseText);
  370. clearInterval(progressBar.interval);
  371.  
  372. if (response.status === "success") {
  373. progressBar.value = 100;
  374. progressStatus.innerText = "Conversion complete.";
  375. if (!isEasyOptimizeActive) {
  376. downloadButton.style.display = 'block';
  377. }
  378. else {
  379. const targetBoardValue = targetBoard.value;
  380. progressStatus.innerText = `Conversion complete. Standby for auto download of Optimized_for_PROFFIE.zip`;
  381. triggerDownload(targetBoardValue);
  382. }
  383. } else if (response.status === "info") {
  384. console.log('Response was info');
  385. progressStatus.innerText = response.message;
  386. downloadButton.style.display = 'none';
  387. } else {
  388. console.log('Response was something else');
  389. progressStatus.innerText = response.message;
  390. downloadButton.style.display = 'none';
  391. }
  392.  
  393. isEasyOptimizeActive = false;
  394. };
  395.  
  396. xhr.setRequestHeader("Content-Type", "application/json");
  397. xhr.send(fileNamesJson);
  398. });
  399.  
  400.  
  401. downloadButton.addEventListener('click', function() {
  402. // Change button text upon clicking
  403. progressStatus.innerText = "Fetching converted files. Standby for .zip download ...";
  404. downloadButton.style.backgroundColor = 'dodgerblue';
  405.  
  406. const targetBoardValue = targetBoard.value; // store this for later
  407. triggerDownload(targetBoardValue);
  408.  
  409. });
  410.  
  411.  
  412. function checkIfBoardsAreSame() {
  413. if (sourceBoard.value === "CFX" && (targetBoard.value === "PROFFIE" || targetBoard.value === "GH3")) {
  414. let confirmAction;
  415. if (targetBoard.value === "PROFFIE") {
  416. confirmAction = window.confirm("Conversion from CFX to PROFFIE is not required.\nProffieboards already natively support Plecter fonts.\nDo you want to continue anyway?");
  417. if (confirmAction) {
  418. // Manually open the file dialog since we previously blocked it
  419. fileInput.click();
  420. } else {
  421. toggleOptimizeCheckbox();
  422. }
  423. } else if (targetBoard.value === "GH3") {
  424. window.alert("Conversion from CFX to GH3 is unsupported.\nGH3 already natively supports Plecter fonts.");
  425. }
  426. } else if (sourceBoard.value === targetBoard.value) {
  427. if (sourceBoard.value === "PROFFIE") {
  428. 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.)");
  429. optimizeCheckbox.checked = true;
  430. optimizeCheckbox.disabled = true;
  431. } else {
  432. window.alert("Conversion from " + sourceBoard.value + " to " + targetBoard.value + " is unnecessary.\nPlease choose a different conversion.");
  433. }
  434. } else {
  435. // Re-enable the checkbox if both boards are not Proffie
  436. optimizeCheckbox.disabled = false;
  437. }
  438. }
  439.  
  440. function resetMessage() {
  441. hideDownloadButton();
  442. progressBar.value = 0;
  443. progressStatus.innerText = "Waiting for files to be uploaded. Choose Files and click 'Convert'.";
  444. }
  445.  
  446. function hideDownloadButton() {
  447. downloadButton.style.display = 'none';
  448. }
  449.  
  450. function toggleOptimizeCheckbox() {
  451. var optimizeLabel = document.querySelector('label[for="optimizeForProffie"]');
  452.  
  453. if (targetBoard.value === "PROFFIE") {
  454. optimizeCheckbox.style.display = 'inline-block';
  455. optimizeLabel.style.display = 'inline-block';
  456. } else {
  457. optimizeCheckbox.style.display = 'none';
  458. optimizeLabel.style.display = 'none';
  459. }
  460. }
  461. </script>
  462.  
  463. </body>
  464. </html>
  465. ```
  466.  
  467. SoundFontConverterController.java:
  468. ```
  469. package com.example.soundfontconverter;
  470.  
  471. import org.springframework.stereotype.Controller;
  472. import org.springframework.web.bind.annotation.GetMapping;
  473. import org.springframework.web.bind.annotation.PostMapping;
  474. import org.springframework.web.bind.annotation.RequestParam;
  475. import org.springframework.web.multipart.MultipartFile;
  476. import org.springframework.beans.factory.annotation.Autowired;
  477. import org.springframework.http.HttpStatus;
  478. import org.springframework.http.ResponseEntity;
  479. import org.springframework.http.HttpHeaders;
  480. import org.springframework.http.MediaType;
  481.  
  482. import java.io.IOException;
  483. import java.nio.file.Files;
  484. import java.nio.file.Path;
  485. import java.nio.file.Paths;
  486. import java.util.ArrayList;
  487. import java.util.List;
  488. import java.util.Map;
  489.  
  490. import java.io.StringWriter;
  491. import java.io.PrintWriter;
  492. // import javax.servlet.http.HttpServletResponse;
  493. import jakarta.servlet.http.HttpServletResponse;
  494. import jakarta.servlet.http.HttpServletRequest;
  495. import java.util.Enumeration;
  496. // import org.springframework.http.server.ServletServerHttpResponse;
  497. // import org.springframework.http.server.ServerHttpRequest;
  498.  
  499. @Controller
  500. public class SoundFontConverterController {
  501.  
  502. @Autowired
  503. private SoundFontNamingService soundFontNamingService;
  504. @Autowired
  505. private HttpServletRequest request;
  506.  
  507. @GetMapping("/")
  508. public String index() {
  509. return "index";
  510. }
  511.  
  512. @GetMapping("/getConversionData")
  513. public ResponseEntity<Map<String, Object>> getConversionData(@RequestParam String targetBoard) {
  514. try {
  515. Map<String, Object> conversionData = getConversionDataForTargetBoard(targetBoard);
  516. return new ResponseEntity<>(conversionData, HttpStatus.OK);
  517. } catch (Exception e) {
  518. return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
  519. }
  520. }
  521.  
  522. @GetMapping("/downloadConvertedFiles")
  523. public ResponseEntity<?> downloadConvertedFiles(@RequestParam String targetBoard) {
  524. try {
  525. Path fileLocation = Paths.get("temporaryDirectory", "Converted_to_" + targetBoard + ".zip");
  526. byte[] data = Files.readAllBytes(fileLocation);
  527.  
  528. HttpHeaders headers = new HttpHeaders();
  529. headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileLocation.getFileName().toString());
  530. headers.setContentType(MediaType.parseMediaType("application/zip"));
  531.  
  532. return new ResponseEntity<>(data, headers, HttpStatus.OK);
  533. } catch (Exception e) {
  534. return new ResponseEntity<>("Error occurred while downloading file.", HttpStatus.INTERNAL_SERVER_ERROR);
  535. }
  536. }
  537.  
  538. @PostMapping("/convert")
  539. public ResponseEntity<?> convertSoundFont(
  540. @RequestParam String sourceBoard,
  541. @RequestParam String targetBoard,
  542. @RequestParam("fileNames") List<String> files,
  543. @RequestParam(required = false) String optimizeForProffie) {
  544.  
  545. boolean optimize = "true".equals(optimizeForProffie); // Interpret the value
  546.  
  547. // Log all request parameters
  548. Enumeration<String> parameterNames = request.getParameterNames();
  549. while (parameterNames.hasMoreElements()) {
  550. String paramName = parameterNames.nextElement();
  551. String[] paramValues = request.getParameterValues(paramName);
  552. for (String paramValue : paramValues) {
  553. System.out.println("Param: " + paramName + " Value: " + paramValue);
  554. }
  555. }
  556.  
  557. // 1. Cleanup any existing temporaryDirectory before processing new files.
  558. //soundFontNamingService.cleanupTemporaryDirectory();
  559.  
  560. List<String> savedFiles = new ArrayList<>();
  561. for (String fileName : files) {
  562. virtualFileSystem.put(fileName, fileName);
  563. if (fileName.endsWith(".DS_Store")) continue;
  564. String virtualPath = "temporaryDirectory/" + fileName;
  565. virtualFileSystem.put(virtualPath, fileName);
  566. }
  567.  
  568. try {
  569. // 3. Convert files.
  570. soundFontNamingService.chainConvertSoundFont(virtualFileSystem, sourceBoard, targetBoard, optimize, "temporaryDirectory");
  571. // 4. Remove the original directory.
  572. String originalDirectoryName = savedFiles.get(0).getParent().getFileName().toString();
  573. soundFontNamingService.removeOriginalDirectory(originalDirectoryName);
  574.  
  575. // 5. Zip the converted files.
  576. Path resultZip = soundFontNamingService.zipConvertedFiles("Converted_to_" + targetBoard);
  577.  
  578. // 6.Return a JSON indicating success instead of the zipped file
  579. return new ResponseEntity<>(Map.of("status", "success", "message", "Conversion complete!"), HttpStatus.OK);
  580. } catch (Exception e) {
  581. return new ResponseEntity<>(Map.of("status", "error", "message", "Conversion failed due to " + e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
  582. }
  583. }
  584.  
  585. private ResponseEntity<String> generateErrorResponse(String message, Exception e) {
  586. StringWriter sw = new StringWriter();
  587. e.printStackTrace(new PrintWriter(sw));
  588. String exceptionAsString = sw.toString();
  589. return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(message + exceptionAsString);
  590. }
  591.  
  592. }
  593. ```
  594.  
  595. SoundFontNamingService.java:
  596. ```
  597. package com.example.soundfontconverter;
  598.  
  599. import org.springframework.stereotype.Service;
  600.  
  601. import java.io.IOException;
  602. import java.nio.file.*;
  603. import java.util.HashMap;
  604. import java.util.List;
  605. import java.util.Map;
  606. import java.io.BufferedReader;
  607. import java.io.File;
  608. import java.io.FileReader;
  609. import java.util.stream.Stream;
  610. import java.util.Comparator;
  611. import java.util.stream.Collectors;
  612. import java.text.SimpleDateFormat;
  613. import java.util.*;
  614. import java.util.ArrayList;
  615.  
  616.  
  617. @Service
  618. public class SoundFontNamingService {
  619.  
  620. enum BoardType {
  621. CFX,
  622. GH3,
  623. PROFFIE,
  624. VERSO,
  625. XENO3;
  626.  
  627.  
  628. public static String getKey(BoardType source, BoardType target) {
  629. return source.name() + "_TO_" + target.name();
  630. }
  631. }
  632.  
  633. private Map<String, String> fileContentMap = new HashMap<>();
  634.  
  635. private StringBuilder logStringBuilder = new StringBuilder();
  636. private boolean chained = false;
  637. private String realTarget = "PROFFIE";
  638. private static final String DEFAULTS_PATH = "./inis";
  639. private static final Map<String, String> CFX_TO_PROFFIE = new HashMap<>();
  640. private static final Map<String, String> CFX_TO_VERSO = new HashMap<>();
  641. private static final Map<String, String> GH3_TO_PROFFIE = new HashMap<>();
  642. private static final Map<String, String> PROFFIE_TO_CFX = new HashMap<>();
  643. private static final Map<String, String> PROFFIE_TO_GH3 = new HashMap<>();
  644. private static final Map<String, String> PROFFIE_TO_VERSO = new HashMap<>();
  645. private static final Map<String, String> PROFFIE_TO_XENO3 = new HashMap<>();
  646. private static final Map<String, String> VERSO_TO_CFX = new HashMap<>();
  647. private static final Map<String, String> VERSO_TO_PROFFIE = new HashMap<>();
  648. private static final Map<String, String> XENO3_TO_PROFFIE = new HashMap<>();
  649. //... additional board mappings can be added here
  650.  
  651. // Central mapping repository
  652. private static final Map<String, Map<String, String>> soundMappings = new HashMap<>();
  653. private static final Map<String, Integer> soundCounter = new HashMap<>();
  654.  
  655. static {
  656. initializeMappings();
  657. }
  658.  
  659. private static void loadMappingsFromCSV(String csvFilePath, Map<String, String> mapping) {
  660. try (BufferedReader reader = new BufferedReader(new FileReader(csvFilePath))) {
  661. String line;
  662. while ((line = reader.readLine()) != null) {
  663. String[] parts = line.split(",");
  664. if (parts.length >= 2) {
  665. mapping.put(parts[0], parts[1]);
  666. }
  667. }
  668. } catch (IOException e) {
  669. e.printStackTrace();
  670. }
  671. }
  672.  
  673. private static void safeLoadMappingsFromCSV(String csvFilePath, Map<String, String> mapping) {
  674. File f = new File(csvFilePath);
  675. if(f.exists() && !f.isDirectory()) {
  676. loadMappingsFromCSV(csvFilePath, mapping);
  677. }
  678. }
  679.  
  680. private static void initializeMappings() {
  681. safeLoadMappingsFromCSV("./CSV/CFX_TO_PROFFIE.csv", CFX_TO_PROFFIE);
  682. // safeLoadMappingsFromCSV("./CSV/CFX_TO_VERSO.csv", CFX_TO_VERSO);
  683. // safeLoadMappingsFromCSV("./CSV/GH3_TO_PROFFIE.csv", GH3_TO_PROFFIE);
  684. safeLoadMappingsFromCSV("./CSV/PROFFIE_TO_CFX.csv", PROFFIE_TO_CFX);
  685. // safeLoadMappingsFromCSV("./CSV/PROFFIE_TO_GH3.csv", PROFFIE_TO_CFX);
  686. safeLoadMappingsFromCSV("./CSV/PROFFIE_TO_VERSO.csv", PROFFIE_TO_VERSO);
  687. safeLoadMappingsFromCSV("./CSV/PROFFIE_TO_XENO3.csv", PROFFIE_TO_XENO3);
  688. // safeLoadMappingsFromCSV("./CSV/VERSO_TO_PROFFIE.csv", VERSO_TO_PROFFIE);
  689. safeLoadMappingsFromCSV("./CSV/XENO3_TO_PROFFIE.csv", XENO3_TO_PROFFIE);
  690. // ... and so on for other mappings ...
  691.  
  692. soundMappings.put(BoardType.getKey(BoardType.CFX, BoardType.PROFFIE), CFX_TO_PROFFIE);
  693. // soundMappings.put(BoardType.getKey(BoardType.CFX, BoardType.VERSO), CFX_TO_VERSO);
  694. soundMappings.put(BoardType.getKey(BoardType.PROFFIE, BoardType.CFX), PROFFIE_TO_CFX);
  695. soundMappings.put(BoardType.getKey(BoardType.PROFFIE, BoardType.GH3), PROFFIE_TO_CFX);
  696. soundMappings.put(BoardType.getKey(BoardType.PROFFIE, BoardType.VERSO), PROFFIE_TO_VERSO);
  697. soundMappings.put(BoardType.getKey(BoardType.PROFFIE, BoardType.XENO3), PROFFIE_TO_XENO3);
  698. soundMappings.put(BoardType.getKey(BoardType.GH3, BoardType.PROFFIE), CFX_TO_PROFFIE);
  699. // soundMappings.put(BoardType.getKey(BoardType.VERSO, BoardType.CFX), VERSO_TO_CFX);
  700. soundMappings.put(BoardType.getKey(BoardType.VERSO, BoardType.PROFFIE), VERSO_TO_PROFFIE);
  701. soundMappings.put(BoardType.getKey(BoardType.XENO3, BoardType.PROFFIE), XENO3_TO_PROFFIE);
  702.  
  703. // Reverse Mapping fist so actual mappings will override
  704.  
  705. // CFX to Proffie mapping
  706. for (Map.Entry<String, String> entry : PROFFIE_TO_CFX.entrySet()) {
  707. CFX_TO_PROFFIE.putIfAbsent(entry.getValue(), entry.getKey());
  708. }
  709. // for (Map.Entry<String, String> entry : VERSO_TO_CFX.entrySet()) {
  710. // CFX_TO_VERSO.putIfAbsent(entry.getValue(), entry.getKey());
  711. // }
  712. // Verso to Proffie mapping
  713. for (Map.Entry<String, String> entry : PROFFIE_TO_VERSO.entrySet()) {
  714. VERSO_TO_PROFFIE.putIfAbsent(entry.getValue(), entry.getKey());
  715. }
  716. // Xeno3 to Proffie mapping
  717. for (Map.Entry<String, String> entry : PROFFIE_TO_XENO3.entrySet()) {
  718. XENO3_TO_PROFFIE.putIfAbsent(entry.getValue(), entry.getKey());
  719. }
  720. }
  721.  
  722. public void virtualFileSystemCopyFile(String sourcePath, String targetPath, Map<String, List<String>> virtualFileSystem) {
  723. List<String> sourceFiles = virtualFileSystem.get(sourcePath);
  724. if (sourceFiles != null) {
  725. virtualFileSystem.put(targetPath, new ArrayList<>(sourceFiles));
  726. }
  727. }
  728.  
  729. public void virtualFileSystemMoveFile(String sourcePath, String targetPath, Map<String, List<String>> virtualFileSystem) {
  730. List<String> sourceFiles = virtualFileSystem.remove(sourcePath);
  731. if (sourceFiles != null) {
  732. virtualFileSystem.put(targetPath, sourceFiles);
  733. }
  734. }
  735.  
  736. private static void copyFile(Path sourcePath, Path targetPath) {
  737. try {
  738. Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
  739. } catch (IOException ex) {
  740. System.err.println("Error copying file from " + sourcePath + " to " + targetPath);
  741. ex.printStackTrace();
  742. }
  743. }
  744.  
  745. // This version takes the optimizeForProffie parameter. It's the main logic
  746. private void convertSounds(BoardType sourceBoard, Map<String, String> fileNamesAndPaths, BoardType targetBoard, String targetDir, boolean optimizeForProffie, Map<String, List<String>> virtualFileSystem) throws IOException {
  747. if (virtualFileSystem == null) {
  748. virtualFileSystem = new HashMap<>();
  749. }
  750. soundCounter.clear();
  751. String key = BoardType.getKey(sourceBoard, targetBoard);
  752. System.out.println("----------------------------------------------------------------\n.");
  753. if (targetBoard == BoardType.PROFFIE && realTarget == "PROFFIE") {
  754. System.out.println("Converting from " + sourceBoard + " to " + targetBoard + "\n.");
  755. } else if (targetBoard != BoardType.PROFFIE) {
  756. realTarget = targetBoard.toString();
  757. } else {
  758. System.out.println("Converting from " + sourceBoard + " to " + realTarget + "\n.");
  759. }
  760.  
  761. // Since soundFileNames are now just strings without path information, we'll use a placeholder for sourceDirName
  762. String sourceDirName = "SourceDirectory";
  763. String finalTargetDir = targetDir + "/Converted_to_" + targetBoard + "/" +
  764. (targetBoard == BoardType.GH3 ? "sound1 - " : "") +
  765. sourceDirName;
  766.  
  767.  
  768. // Prepare Log file
  769. if (chained == false) {
  770. ensureDirectoryExists(finalTargetDir, virtualFileSystem);
  771. SimpleDateFormat sdf = new SimpleDateFormat("MMM dd, yyyy");
  772. String currentDate = sdf.format(new Date());
  773. logStringBuilder.append("Converted with SoundFont Naming Converter 3.0\n");
  774. logStringBuilder.append("Brian Conner a.k.a NoSloppy\n\n");
  775. logStringBuilder.append(currentDate).append("\n");
  776.  
  777. if (targetBoard == BoardType.PROFFIE && realTarget == "PROFFIE") {
  778. logStringBuilder.append("Converted: ").append(sourceBoard).append(" to ").append(targetBoard).append("\n");
  779. logStringBuilder.append("Optimized for Fat32 performance: ").append(optimizeForProffie ? "Yes" : "No").append("\n\n");
  780. } else if (targetBoard != BoardType.PROFFIE) {
  781. realTarget = targetBoard.toString();
  782. } else {
  783. logStringBuilder.append("Converted: ").append(sourceBoard).append(" to ").append(realTarget).append("\n");
  784. logStringBuilder.append("\n");
  785. }
  786. }
  787.  
  788. // If it's Proffie to Proffie, skip the mapping
  789. Map<String, String> mapping;
  790. if (sourceBoard == BoardType.PROFFIE && targetBoard == BoardType.PROFFIE) {
  791. mapping = null; // No mapping required for Proffie to Proffie
  792. } else {
  793. if (!soundMappings.containsKey(key)) {
  794. System.out.println("Conversion from " + sourceBoard + " to " + targetBoard + " is not supported.");
  795. return;
  796. }
  797. mapping = soundMappings.get(key);
  798. }
  799.  
  800. ensureDirectoryExists(finalTargetDir, virtualFileSystem);
  801.  
  802.  
  803. // Check if source has directories named something like "Bonus Files" or "extra"
  804. boolean hasExtrasDirectories = false;
  805. try {
  806. hasExtrasDirectories = Files.walk(Paths.get(new File(soundFileNames.get(0)).getParent()), 1) // Only check immediate children
  807. .filter(Files::isDirectory).anyMatch(path -> {
  808. String dirName = path.getFileName().toString().toLowerCase();
  809. return dirName.contains("bonus") || dirName.contains("extra");
  810. });
  811. } catch (IOException ex) {
  812. ex.printStackTrace();
  813. }
  814.  
  815. // If "extras" directory is needed, create it now
  816. if (hasExtrasDirectories) {
  817. ensureDirectoryExists(finalTargetDir + "/extras", virtualFileSystem);
  818. }
  819.  
  820. // Main sound conversion
  821. List<String> paths = soundFileNames;
  822. Map<String, Integer> fileNameCounter = new HashMap<>();
  823. boolean fontSoundProcessed = false;
  824.  
  825. paths.stream()
  826. .filter(path -> !new File(path).getName().startsWith(".")) // Filtering out hidden files
  827. .filter(path -> {
  828.  
  829. String parentDirName = new File(path).getParentFile().getName().toLowerCase();
  830. if (parentDirName.contains("bonus") || parentDirName.contains("extra")) {
  831. virtualFileSystemCopyFile(path, finalTargetDir + "/extras/" + new File(path).getName(), virtualFileSystem);
  832.  
  833. String logEntryExtras = "Moved extra/bonus file to " + finalTargetDir + "/extras/" + new File(path).getName();
  834. System.out.println(logEntryExtras);
  835. logStringBuilder.append(logEntryExtras).append("\n");
  836. return false;
  837. }
  838. return true;
  839. })
  840. .sorted() // As the list contains string file names, the default sorting should suffice
  841. .forEach(fileName -> {
  842. try {
  843. // This line is no longer needed as fileName is now directly obtained from the forEach loop.
  844.  
  845. // Move non-wav files directly to the target folder
  846. if (!fileName.endsWith(".wav")) {
  847. virtualFileSystemCopyFile(fileName, finalTargetDir + "/" + fileName, virtualFileSystem);
  848. String logEntryNonWav = "Moved non-wav file: " + fileName;
  849. System.out.println(logEntryNonWav);
  850. logStringBuilder.append(logEntryNonWav).append("\n");
  851. return;
  852. }
  853.  
  854. // Move "track" wav files to "tracks" folder
  855. if (fileName.contains("track")) {
  856. ensureDirectoryExists(finalTargetDir + "/tracks", virtualFileSystem);
  857. virtualFileSystemCopyFile(fileName, finalTargetDir + "/tracks/" + fileName, virtualFileSystem);
  858. String logEntryTrack = "Moved track file: " + fileName;
  859. System.out.println(logEntryTrack);
  860. logStringBuilder.append(logEntryTrack).append("\n");
  861. return;
  862. }
  863.  
  864. // For other wav files, use the mapping
  865. String baseName = fileName.replaceAll(" (\\(\\d+\\))?\\.wav$|\\d+\\.wav$", ".wav");
  866. // If we're doing Proffie to Proffie, keep the baseName as is
  867. String convertedBaseName = (mapping == null) ? baseName : mapping.getOrDefault(baseName, baseName);
  868.  
  869. String outputPath;
  870. if (convertedBaseName != null) {
  871. int count = soundCounter.getOrDefault(convertedBaseName, 0) + 1;
  872. soundCounter.put(convertedBaseName, count);
  873.  
  874. String prefix = (convertedBaseName.contains(".")) ? convertedBaseName.substring(0, convertedBaseName.lastIndexOf('.')) : convertedBaseName;
  875. String formattedCount = String.valueOf(count);
  876.  
  877. if (targetBoard == BoardType.CFX) {
  878. String newPrefix;
  879. int currentCounter;
  880.  
  881. String switchKey = convertedBaseName.toLowerCase().replaceAll("\\.wav$", "");
  882. String commonKey;
  883. switch (switchKey) {
  884. // First, handle the special numbering and weird naming cases
  885. case "poweroff":
  886. commonKey = "pwroff";
  887. currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  888. if (currentCounter == 1) {
  889. newPrefix = "poweroff";
  890. } else if (currentCounter == 2) {
  891. newPrefix = "pwroff2";
  892. } else {
  893. newPrefix = "poweroff" + (currentCounter - 1);
  894. }
  895. outputPath = finalTargetDir + "/" + newPrefix + ".wav";
  896. fileNameCounter.put(commonKey, currentCounter + 1);
  897. break;
  898.  
  899. // case "clash":
  900. // commonKey = "clash";
  901. // currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  902. // if (currentCounter == 1) {
  903. // newPrefix = "clash" + currentCounter;
  904. // } else if (currentCounter == 2) {
  905. // newPrefix = "fclash" + (currentCounter -1);
  906. // } else {
  907. // newPrefix = "clash" + (currentCounter - 1);
  908. // }
  909. // outputPath = finalTargetDir + "/" + newPrefix + ".wav";
  910. // fileNameCounter.put(commonKey, currentCounter + 1);
  911. // break;
  912.  
  913. case "font":
  914. commonKey = "font";
  915. currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  916. if (currentCounter == 1) {
  917. outputPath = finalTargetDir + "/font" + ".wav";
  918. } else {
  919. int nextBootCounter = fileNameCounter.getOrDefault("boot", 1);
  920. outputPath = finalTargetDir + "/boot" + (nextBootCounter == 1 ? "" : nextBootCounter) + ".wav";
  921. fileNameCounter.put("boot", nextBootCounter + 1);
  922. }
  923. fileNameCounter.put(commonKey, currentCounter + 1);
  924. break;
  925.  
  926. // These get no number on the first file, then sequence the rest staring from 2
  927. case "boot":
  928. commonKey = "boot";
  929. currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  930. outputPath = finalTargetDir + "/boot" + (currentCounter == 1 ? "" : currentCounter) + ".wav";
  931. fileNameCounter.put(commonKey, currentCounter + 1);
  932. break;
  933.  
  934. case "color":
  935. commonKey = "color";
  936. currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  937. outputPath = finalTargetDir + "/" + convertedBaseName.substring(0, convertedBaseName.length() - 4) + (currentCounter == 1 ? "" : currentCounter) + ".wav";
  938. fileNameCounter.put(commonKey, currentCounter + 1);
  939. break;
  940. case "blaster":
  941. commonKey = "blaster";
  942. currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  943. outputPath = finalTargetDir + "/" + convertedBaseName.substring(0, convertedBaseName.length() - 4) + (currentCounter == 1 ? "" : currentCounter) + ".wav";
  944. fileNameCounter.put(commonKey, currentCounter + 1);
  945. break;
  946. case "poweron":
  947. commonKey = "poweron";
  948. currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  949. outputPath = finalTargetDir + "/" + convertedBaseName.substring(0, convertedBaseName.length() - 4) + (currentCounter == 1 ? "" : currentCounter) + ".wav";
  950. fileNameCounter.put(commonKey, currentCounter + 1);
  951. break;
  952. case "lockup":
  953. commonKey = "lockup";
  954. currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  955. outputPath = finalTargetDir + "/" + convertedBaseName.substring(0, convertedBaseName.length() - 4) + (currentCounter == 1 ? "" : currentCounter) + ".wav";
  956. fileNameCounter.put(commonKey, currentCounter + 1);
  957. break;
  958. case "drag":
  959. commonKey = "drag";
  960. currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  961. outputPath = finalTargetDir + "/" + convertedBaseName.substring(0, convertedBaseName.length() - 4) + (currentCounter == 1 ? "" : currentCounter) + ".wav";
  962. fileNameCounter.put(commonKey, currentCounter + 1);
  963. break;
  964. case "force":
  965. commonKey = "force";
  966. currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  967. outputPath = finalTargetDir + "/" + convertedBaseName.substring(0, convertedBaseName.length() - 4) + (currentCounter == 1 ? "" : currentCounter) + ".wav";
  968. fileNameCounter.put(commonKey, currentCounter + 1);
  969. break;
  970.  
  971. default:
  972. currentCounter = fileNameCounter.getOrDefault(switchKey, 1);
  973. outputPath = finalTargetDir + "/" + convertedBaseName.substring(0, convertedBaseName.length() - 4) + currentCounter + ".wav";
  974.  
  975. fileNameCounter.put(switchKey, currentCounter + 1);
  976. break;
  977. }
  978.  
  979. } else if (targetBoard == BoardType.PROFFIE) {
  980. if (prefix.length() > 6 && count == 1 && soundCounter.containsKey(baseName)) {
  981. formattedCount = String.valueOf(count);
  982. } else {
  983. formattedCount = (prefix.length() > 6) ? String.valueOf(count) : String.format("%02d", count);
  984. }
  985. if (optimizeForProffie) {
  986. outputPath = count == 1 ? finalTargetDir + "/" + prefix + ".wav" : finalTargetDir + "/" + prefix + "/" + prefix + formattedCount + ".wav";
  987.  
  988. if (count == 2) {
  989. String originalPath = finalTargetDir + "/" + prefix + ".wav";
  990. String newPath = finalTargetDir + "/" + prefix + "/" + prefix + (prefix.length() > 6 ? "1" : "01") + ".wav";
  991. ensureDirectoryExists(finalTargetDir + "/" + prefix, virtualFileSystem);
  992. virtualFileSystemMoveFile(originalPath, newPath, virtualFileSystem);
  993. Path originalPathObj = Paths.get(originalPath);
  994. Path newPathObj = Paths.get(newPath);
  995. String logEntryProffie = "Numbered and moved first file to subdirectory:\n"
  996. + " " + originalPathObj.subpath(2, originalPathObj.getNameCount())
  997. + " -> "
  998. + newPathObj.subpath(2, newPathObj.getNameCount());
  999. System.out.println(logEntryProffie);
  1000. logStringBuilder.append(logEntryProffie).append("\n");
  1001. }
  1002. } else {
  1003. outputPath = finalTargetDir + "/" + (count > 1 ? prefix + formattedCount : prefix) + ".wav";
  1004.  
  1005. if (count == 2) {
  1006. String originalPath = finalTargetDir + "/" + prefix + ".wav";
  1007. String newPath = finalTargetDir + "/" + prefix + (prefix.length() > 6 ? "1" : "01") + ".wav";
  1008. virtualFileSystemMoveFile(originalPath, newPath, virtualFileSystem);
  1009. Path originalPathObj = Paths.get(originalPath);
  1010. Path newPathObj = Paths.get(newPath);
  1011. String logEntryProffie = "Numbered the first file:\n "
  1012. + " " + originalPathObj.subpath(2, originalPathObj.getNameCount())
  1013. + " -> "
  1014. + newPathObj.subpath(2, newPathObj.getNameCount());
  1015. System.out.println(logEntryProffie);
  1016. logStringBuilder.append(logEntryProffie).append("\n");
  1017. }
  1018. }
  1019. } else if (targetBoard == BoardType.VERSO && convertedBaseName.equals("font.wav")) {
  1020. String commonKey = "font";
  1021. int currentCounter = fileNameCounter.getOrDefault(commonKey, 1);
  1022. fileNameCounter.put(commonKey, currentCounter + 1);
  1023.  
  1024. if (currentCounter == 1) {
  1025. outputPath = finalTargetDir + "/font.wav";
  1026. virtualFileSystemMoveFile(fileName, outputPath, virtualFileSystem); // Changed path.toString() to fileName
  1027. String logEntryVerso = "Converted: " + new File(fileName).getName() + " -> " + outputPath.replace("temporaryDirectory/", ""); // Changed path.getFileName().toString() to new File(fileName).getName()
  1028. System.out.println(logEntryVerso);
  1029. logStringBuilder.append(logEntryVerso).append("\n");
  1030. } else {
  1031. String logEntryVersoSkipped = "Skipped additional 'font' file: " + fileName;
  1032. System.out.println(logEntryVersoSkipped);
  1033. logStringBuilder.append(logEntryVersoSkipped).append("\n");
  1034. }
  1035. return;
  1036. } else if (targetBoard == BoardType.XENO3) {
  1037. outputPath = Paths.get(finalTargetDir, prefix + " (" + count + ").wav").toString();
  1038.  
  1039. } else if (count > 1 || (targetBoard != BoardType.PROFFIE && count == 1)) {
  1040. outputPath = Paths.get(finalTargetDir, prefix + formattedCount + ".wav").toString();
  1041. } else {
  1042. outputPath = Paths.get(finalTargetDir, prefix + ".wav").toString();
  1043. }
  1044.  
  1045. virtualFileSystemMoveFile(fileName, outputPath, virtualFileSystem);
  1046. String logEntry = "Converted: " + new File(fileName).getName() + " -> " + outputPath.replace("temporaryDirectory/", ""); // Replaced path.getFileName().toString() with new File(fileName).getName()
  1047. System.out.println(logEntry);
  1048. logStringBuilder.append(logEntry).append("\n");
  1049.  
  1050. } else { // convertedBaseName = null
  1051. System.out.println("Skipped wav file without mapping: " + fileName);
  1052. }
  1053. } catch (IOException e) {
  1054. System.err.println("An IOException occurred: " + e.getMessage());
  1055. }
  1056. });
  1057. if (chained == true) {
  1058. logStringBuilder.append("\n*********----- MTFBWY -----*********\n");
  1059. } else {
  1060. logStringBuilder.append("\n\n");
  1061. }
  1062. try {
  1063. System.out.println("--- Writing _Conversion_Log.txt ---");
  1064. Files.writeString(Paths.get(finalTargetDir + "/_Conversion_Log.txt"), logStringBuilder.toString());
  1065. } catch (IOException e) {
  1066. System.err.println("Failed to write log: " + e.getMessage());
  1067. }
  1068. // } catch (IOException ex) {
  1069. // System.err.println("An error occurred while reading the file: " + ex.getMessage());
  1070. // }
  1071.  
  1072.  
  1073. // After processing all files, check for default INIs for Proffie
  1074. if (targetBoard == BoardType.PROFFIE) {
  1075. String[] defaultFiles = {"config.ini", "smoothsw.ini"};
  1076. for (String defaultFile : defaultFiles) {
  1077. File targetDefaultFile = new File(finalTargetDir, defaultFile);
  1078. if (!targetDefaultFile.exists()) {
  1079. File inisFile = new File(DEFAULTS_PATH + "/" + defaultFile);
  1080. if (inisFile.exists()) {
  1081. try {
  1082. Files.copy(inisFile.toPath(), targetDefaultFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
  1083. System.out.println("Copied default file: " + defaultFile);
  1084. String content = Files.readString(inisFile.toPath()); // Read the content of inisFile
  1085. addFileToVFS(finalTargetDir, defaultFile, content, virtualFileSystem, fileContentMap); // Use the content variable here
  1086. } catch (IOException e) {
  1087. // e.printStackTrace();
  1088. System.err.println("Error while copying file: " + defaultFile);
  1089. }
  1090. }
  1091. }
  1092. }
  1093. }
  1094. }
  1095.  
  1096. private static void ensureDirectoryExists(String dirPath, Map<String, List<String>> virtualFileSystem) {
  1097. if (!virtualFileSystem.containsKey(dirPath)) {
  1098. virtualFileSystem.put(dirPath, new ArrayList<>());
  1099. System.out.println("Creating directory: " + dirPath);
  1100. }
  1101. }
  1102.  
  1103. // Updated method signature
  1104. private void addFileToVFS(String dirPath, String fileName, String content, Map<String, List<String>> virtualFileSystem, Map<String, String> fileContentMap) {
  1105. ensureDirectoryExists(dirPath, virtualFileSystem); // Ensure the directory exists
  1106. String filePath = dirPath + "/" + fileName;
  1107. virtualFileSystem.get(dirPath).add(filePath); // Add file path to directory
  1108. fileContentMap.put(filePath, content); // Store the file content
  1109. }
  1110.  
  1111. public class MutableInt {
  1112. public int value;
  1113. public MutableInt(int value) {
  1114. this.value = value;
  1115. }
  1116. }
  1117.  
  1118.  
  1119. private List<String> savedFiles = new ArrayList<>();
  1120.  
  1121.  
  1122. private void convertSoundFont(Map<String, String> fileNamesAndPaths, String sourceBoard, String targetBoard, boolean optimize) throws IOException {
  1123. BoardType srcBoard = BoardType.valueOf(sourceBoard.toUpperCase());
  1124. BoardType tgtBoard = BoardType.valueOf(targetBoard.toUpperCase());
  1125.  
  1126. String sourceDirName = new File(savedFiles.get(0).toString()).getParentFile().getName();
  1127. List<String> soundFileNames = //... obtain or create the list of sound file names here;
  1128. convertSounds(srcBoard, fileNamesAndPaths, tgtBoard, "temporaryDirectory", optimize, virtualFileSystem);
  1129. }
  1130.  
  1131. private void chainConvertSoundFont(Map<String, String> fileNamesAndPaths, String sourceBoard, String targetBoard, boolean optimize) throws IOException {
  1132. // Clear the StringBuilder for subsequent log entries
  1133. logStringBuilder.setLength(0);
  1134. if ("PROFFIE".equals(sourceBoard) || "PROFFIE".equals(targetBoard)) {
  1135. // Just convert normally.
  1136. convertSoundFont(virtualFileSystem, sourceBoard, targetBoard, optimize);
  1137. } else {
  1138. // Do the chained conversion;
  1139. // cCnvert to PROFFIE first and save it in /temporaryDirectory/Converted_to_PROFFIE.
  1140. // Using realTarget for logging only
  1141. realTarget = targetBoard;
  1142. convertSoundFont(savedFiles, sourceBoard, "PROFFIE", false);
  1143. chained = !chained;
  1144.  
  1145. // Now use the converted PROFFIE files as source for the actual target.
  1146. // Clear the StringBuilder for subsequent log entries
  1147. //logStringBuilder.setLength(0);
  1148. Path tempProffieDir = Paths.get("temporaryDirectory", "Converted_to_PROFFIE");
  1149. Map<String, String> proffieFiles = Files.walk(tempProffieDir)
  1150. .filter(Files::isRegularFile)
  1151. .collect(Collectors.toList());
  1152. convertSoundFont(virtualFileSystem, "PROFFIE", targetBoard, false);
  1153. chained = !chained;
  1154.  
  1155. // Optional: Cleanup the temporary directory used for the PROFFIE conversion.
  1156. }
  1157. }
  1158.  
  1159.  
  1160. public Path zipConvertedFiles(String targetDir) throws IOException {
  1161. Path zipPath = Paths.get(targetDir + ".zip");
  1162.  
  1163. // Logging the structure
  1164. Path sourcePath = Paths.get(targetDir);
  1165. System.out.println("Logging directory structure before zipping:");
  1166. Files.walk(sourcePath).forEach(p -> {
  1167. // System.out.println(p.toString());
  1168. });
  1169. System.out.println("Starting to create ZIP file...");
  1170.  
  1171. try (FileSystem zipFs = FileSystems.newFileSystem(zipPath, Map.of("create", "true"))) {
  1172. // Exclude the top-level source directory itself when walking
  1173. Files.walk(sourcePath).filter(p -> !p.equals(sourcePath)).forEach(path -> {
  1174. try {
  1175. if (Files.isRegularFile(path) && Files.size(path) > 0) { // Ensure it's a file and has content
  1176. String sourceDirName = sourcePath.getFileName().toString();
  1177. Path destPath = zipFs.getPath("/" + sourceDirName + "/" + sourcePath.relativize(path).toString());
  1178.  
  1179. // Ensure the parent directory structure exists in the ZIP
  1180. if (destPath.getParent() != null) {
  1181. Files.createDirectories(destPath.getParent());
  1182. }
  1183.  
  1184. Files.copy(path, destPath, StandardCopyOption.REPLACE_EXISTING);
  1185. }
  1186. } catch (NoSuchFileException e) {
  1187. System.err.println("Directory structure in ZIP does not match expected structure: " + e.getMessage());
  1188. } catch (Exception e) {
  1189. e.printStackTrace();
  1190. System.err.println("Error processing file: " + path.toString() +
  1191. ". Destination path in ZIP: " + zipFs.getPath("/" + sourcePath.relativize(path).toString()));
  1192. }
  1193. });
  1194.  
  1195. } catch (Exception e) {
  1196. e.printStackTrace();
  1197. throw new IOException("Error encountered during zip operation: " + e.getMessage());
  1198. }
  1199. System.out.println("Conversion complete. Zip file saved and ready for download from " + targetDir + ".zip");
  1200. return zipPath;
  1201. }
  1202. }
  1203. ```
  1204.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement