{"id":538,"date":"2019-12-11T18:05:02","date_gmt":"2019-12-11T23:05:02","guid":{"rendered":"http:\/\/www.lazytrap.com\/trapped\/?p=538"},"modified":"2019-12-19T01:50:18","modified_gmt":"2019-12-19T06:50:18","slug":"novation-sysex-synth-bank-to-patch-dump-code","status":"publish","type":"post","link":"http:\/\/www.lazytrap.com\/trapped\/?p=538","title":{"rendered":"Novation SYSEX Synth bank patch dump C# source"},"content":{"rendered":"<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; auto-links: false; title: ; notranslate\" title=\"\">\nusing System;\nusing System.IO;\nusing System.Text;\nusing System.Text.RegularExpressions;\nusing System.Diagnostics;\n\nnamespace CircuitBank2Patch\n{\n    class Program\n    {\n        static void Main(string&#x5B;] args)\n        {\n\n            string startPath =&quot;&quot;;\n            string startfolderPath = &quot;&quot;;\n            string startfileName = &quot;&quot;;\n            string startfileExtension = &quot;&quot;;\n            Console.OutputEncoding = System.Text.Encoding.GetEncoding(28591);\n            Console.Title = &quot;Novation Circuit - Synth Bank Sysex Patch Dump&quot;;\n            string title = @&quot;\n                _________ .__                     .__  __   \n                \\_   ___ \\|__|______   ____  __ __|__|\/  |_ \n                \/    \\  \\\/|  \\_  __ \\_\/ ___\\|  |  \\  \\   __\\\n                \\     \\___|  ||  | \\\/\\  \\___|  |  \/  ||  |  \n                 \\______  \/__||__|    \\___  &gt;____\/|__||__|  \n                        \\\/                \\\/                \n                --------------------------------------------\n          Novation Circuit Synth Bank SYSEX Patch Dump Utility v1.0\n\n This program will dump all patches from a Cicruit Sysex (.syx) bank\n to a subdirectory named BankName_Extracted located wherever your bank \n file originates.\n\n  .----------------------------------------------------------------------.\n | Notes:                                                                |\n | This for Novation Circuit &gt;&gt;SYNTH bank .syx files ONLY&lt;&lt;.             |\n | The original bank file is NOT modified in any way.                    |\n | If your bank contains patches with duplicate names, the file names    |\n |  for those patches will have a number appended to the filename.       |\n | If the destination directory already contains patches, any new files  |\n | created will have a number appended to them. No files are deleted.    |\n `-----------------------------------------------------------------------&#039;\n\n Usage: Drag &amp; Drop your Circuit Patch Bank .syx file onto this EXE.\n\n ----------------------------------------------------------------------\n\n&quot;;\n\n            Console.WriteLine(title);\n            Console.WriteLine(&quot;Press any key to continue or press ESC to abort&quot;);\n            ConsoleKeyInfo info = Console.ReadKey();\n            if (info.Key == ConsoleKey.Escape)\n            {\n                Console.WriteLine(&quot;ESC pressed. Program Aborted, nothing will be processed.&quot;);\n                System.Threading.Thread.Sleep(5000);\n                System.Environment.Exit(0);\n\n            }\n            if (args.Length &gt; 0 &amp;&amp; File.Exists(args&#x5B;0]))\n            {\n                startPath = args&#x5B;0];\n                startfolderPath = Path.GetDirectoryName(startPath);\n                startfileName = Path.GetFileNameWithoutExtension(startPath);\n                startfileExtension = Path.GetExtension(startPath);\n                \/\/Console.WriteLine(&quot;{0}, {1}, {2}, {3}&quot;, startfileName, startPath, startfileExtension, startfolderPath);\n                Console.WriteLine(&quot;\\n&quot; +\n                    &quot;  Bank name: {0}\\n&quot; +\n                    &quot;  Bank Directory: {1}\\n&quot; +\n                    &quot;  Patches Destination Directory: {2}\\n\\n&quot;, startfileName, startfolderPath, startfolderPath + @&quot;\\&quot; + startfileName + @&quot;_Extracted\\&quot;,\n                    &quot;-------------------------------------&quot;);\n                System.Threading.Thread.Sleep(5000);\n\n            }\n\n\n            if (args.Length &lt;= 0)\n            {\n                Console.WriteLine(&quot;\\nNo file detected: To use this program, Drag and Drop your Bank directly onto the exe. \\n\\n Exiting...&quot;);\n                System.Threading.Thread.Sleep(5000);\n                System.Environment.Exit(0);\n            }\n\n            string filePath = startfolderPath;\n            string outputPath = filePath + @&quot;\\&quot; + startfileName + @&quot;_Extracted\\&quot;;\n            System.IO.Directory.CreateDirectory(outputPath);\n            FileStream filename;\n            filename = new FileStream(startPath, FileMode.Open);\n            var buffer = new byte&#x5B;350];\n            \/\/int bytesRead = 0; \/\/replaced by _ discard \n            int filecount = 0;\n            int initialpatch = 0;\n            int renamecount = 1;\n            while ((_ = filename.Read(buffer, 0, buffer.Length)) &gt; 0)\n            {\n\n                filecount++;\n                FileStream singlePatch;\n                singlePatch = new FileStream(outputPath + @&quot;patch&quot; + filecount + &quot;.syx&quot;, FileMode.Append);\n                singlePatch.Write(buffer, 0, buffer.Length);\n                singlePatch.Close();\n            }\n\n            while (filecount &gt; 0)  \/\/fix bytes for compatibility\n            {\n                FileStream renamePatch;\n                string fileforRename = outputPath + @&quot;patch&quot; + renamecount + &quot;.syx&quot;;\n                renamePatch = new FileStream(fileforRename, FileMode.Open, FileAccess.ReadWrite);\n                renamePatch.Seek(0x07, SeekOrigin.Begin);   \/\/replace by 0x07 with value 0x00 for librarian compatibility ..in bank it increase by patch #\n                renamePatch.WriteByte(0x00);\n                renamePatch.Seek(0x06, SeekOrigin.Begin);   \/\/replace by 0x06 with value 0x00 for librarian compatibility ..in bank it increase by patch #\n                renamePatch.WriteByte(0x00);\n                renamePatch.Seek(0x09, SeekOrigin.Begin);   \/\/start byte location of patch name\n                var data = new byte&#x5B;16];                    \/\/patch name can be up to 16 chars long\n                renamePatch.Read(data, 0, 16);              \/\/read all 16 bytes as new byte&#x5B;]\n                string convertbytes = Encoding.UTF8.GetString(data, 0, data.Length).Trim(); \/\/convert byte&#x5B;] (data) containing patch name to string\n                string converted = convertbytes.Replace(&quot; &quot;, &quot;_&quot;); \/\/replace whitespace with underscore for potential program, path, compatibility import issues\n                if (converted.Contains(&quot;Initial_Patch&quot;)) { converted += &quot;_&quot; + initialpatch; initialpatch++; } \/\/handle initial patches seperately\n                \/\/Console.WriteLine(&quot;{0}&quot;, converted.Trim());\n                renamePatch.Close();\n\n                \/\/HAVE PATCH NAME NOW CHECK FOR FILE AND RENAME\/MOVE TO PATCHNAME.SYX\n                \/\/HANDLE OUTPUT HERE\n\n                \/\/Console.WriteLine(&quot;{0}&quot;, GetUniqueFilePath(fullfilePath));\n                string fullfilePath = outputPath + converted.Trim() + &quot;.syx&quot;;\n                string uniquePath = GetUniqueFilePath(fullfilePath);\n                File.Move(fileforRename, uniquePath);  \/\/output file with dupecheck and rename \n                string outFile = Path.GetFileNameWithoutExtension(uniquePath);\n                if (outFile.Contains(@&quot;(&quot;)) { outFile = outFile + &quot; - Possible Dupilcate&quot;; }\n                Console.WriteLine(&quot;  Written: {0}&quot;, @&quot;.\\&quot; + startfileName + @&quot;_Extracted\\&quot; + outFile );\n                System.Threading.Thread.Sleep(50);\n                renamecount++;\n                filecount--;\n\n            }\n\n            filename.Close();\n            Console.WriteLine(&quot;Dump completed. Press SPACE to open folder or any other key to Exit.&quot;);\n            ConsoleKeyInfo info2 = Console.ReadKey();\n            if (info2.Key == ConsoleKey.Spacebar)\n            {\n                Process.Start(&quot;explorer.exe&quot;, outputPath);\n                System.Environment.Exit(0);\n\n            }\n\n\n        }\n\n        public static string GetUniqueFilePath(string filePath)\n        {\n            if (File.Exists(filePath))\n            {\n                string folderPath = Path.GetDirectoryName(filePath);\n                string fileName = Path.GetFileNameWithoutExtension(filePath);\n                string fileExtension = Path.GetExtension(filePath);\n                int number = 1;\n\n                Match regex = Regex.Match(fileName, @&quot;^(.+) \\((\\d+)\\)$&quot;);\n\n                if (regex.Success)\n                {\n                    fileName = regex.Groups&#x5B;1].Value;\n                    number = int.Parse(regex.Groups&#x5B;2].Value);\n                }\n\n                do\n                {\n                    number++;\n                    string newFileName = $&quot;{fileName} ({number}){fileExtension}&quot;;\n                    filePath = Path.Combine(folderPath, newFileName);\n                }\n                while (File.Exists(filePath));\n            }\n\n            return filePath;\n        }\n\n    }\n}\n\n<\/pre><\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":359,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[32,38],"tags":[110,95,166,163,165,164],"jetpack_featured_media_url":"http:\/\/www.lazytrap.com\/trapped\/wp-content\/uploads\/2018\/05\/code.png","_links":{"self":[{"href":"http:\/\/www.lazytrap.com\/trapped\/index.php?rest_route=\/wp\/v2\/posts\/538"}],"collection":[{"href":"http:\/\/www.lazytrap.com\/trapped\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.lazytrap.com\/trapped\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.lazytrap.com\/trapped\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.lazytrap.com\/trapped\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=538"}],"version-history":[{"count":5,"href":"http:\/\/www.lazytrap.com\/trapped\/index.php?rest_route=\/wp\/v2\/posts\/538\/revisions"}],"predecessor-version":[{"id":551,"href":"http:\/\/www.lazytrap.com\/trapped\/index.php?rest_route=\/wp\/v2\/posts\/538\/revisions\/551"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/www.lazytrap.com\/trapped\/index.php?rest_route=\/wp\/v2\/media\/359"}],"wp:attachment":[{"href":"http:\/\/www.lazytrap.com\/trapped\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=538"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.lazytrap.com\/trapped\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=538"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.lazytrap.com\/trapped\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=538"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}