├── .gitattributes ├── .gitignore ├── FM-SoundConvertor.sln ├── FM-SoundConvertor ├── App.config ├── Console.cs ├── DX7.cs ├── Dat.cs ├── Directory.cs ├── FM-SoundConvertor.csproj ├── FMtrial.cs ├── File.cs ├── Fmp.cs ├── Main.cs ├── Muc.cs ├── Option.cs ├── Path.cs ├── Pmd.cs ├── Properties │ └── AssemblyInfo.cs ├── RetroMusicEditor.cs ├── Tone.cs ├── VGMMusicMaker.cs ├── VOPM.cs └── bin │ └── Release │ └── FM-SoundConvertor.exe ├── LICENSE └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .vs/FM-SoundConvertor/v16/.suo 3 | FM-SoundConvertor/bin/Debug/FM-SoundConvertor.exe 4 | FM-SoundConvertor/bin/Debug/FM-SoundConvertor.exe.config 5 | FM-SoundConvertor/bin/Debug/FM-SoundConvertor.pdb 6 | FM-SoundConvertor/bin/Release/FM-SoundConvertor.exe.config 7 | FM-SoundConvertor/bin/Release/FM-SoundConvertor.pdb 8 | FM-SoundConvertor/obj/Debug/FM-SoundConvertor.csproj.CoreCompileInputs.cache 9 | FM-SoundConvertor/obj/Debug/FM-SoundConvertor.csproj.FileListAbsolute.txt 10 | FM-SoundConvertor/obj/Debug/FM-SoundConvertor.csprojAssemblyReference.cache 11 | FM-SoundConvertor/obj/Debug/FM-SoundConvertor.exe 12 | FM-SoundConvertor/obj/Debug/FM-SoundConvertor.pdb 13 | FM-SoundConvertor/obj/Release/FM-SoundConvertor.csproj.CoreCompileInputs.cache 14 | FM-SoundConvertor/obj/Release/FM-SoundConvertor.csproj.FileListAbsolute.txt 15 | FM-SoundConvertor/obj/Release/FM-SoundConvertor.exe 16 | FM-SoundConvertor/obj/Release/FM-SoundConvertor.pdb 17 | FM-SoundConvertor/obj/Release/FM-SoundConvertor.csprojAssemblyReference.cache 18 | FM-SoundConvertor/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache 19 | -------------------------------------------------------------------------------- /FM-SoundConvertor.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29905.134 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FM-SoundConvertor", "FM-SoundConvertor\FM-SoundConvertor.csproj", "{A3DA1746-8229-471A-8029-3322CCFB15AB}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {A3DA1746-8229-471A-8029-3322CCFB15AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {A3DA1746-8229-471A-8029-3322CCFB15AB}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {A3DA1746-8229-471A-8029-3322CCFB15AB}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {A3DA1746-8229-471A-8029-3322CCFB15AB}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {8AE8F879-C449-4863-9888-D78245A3EED5} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /FM-SoundConvertor/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /FM-SoundConvertor/Console.cs: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | using System.Linq; 5 | using System.Collections.Generic; 6 | 7 | using static System.Console; 8 | 9 | 10 | 11 | namespace FM_SoundConvertor 12 | { 13 | public class Console 14 | { 15 | public static void Log(int Val) 16 | { 17 | WriteLine("{0}", Val.ToString()); 18 | } 19 | 20 | 21 | 22 | public static void Log(string Str) 23 | { 24 | WriteLine("{0}", Str); 25 | } 26 | 27 | 28 | 29 | public static void Log(string Pref, string Str) 30 | { 31 | WriteLine("{0} : {1}", Pref, Str); 32 | } 33 | 34 | 35 | 36 | public static void Log(IEnumerable aStr) 37 | { 38 | aStr.ToList().ForEach(Str => Log(Str)); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /FM-SoundConvertor/DX7.cs: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | using System; 5 | 6 | using static FM_SoundConvertor.Path; 7 | using static FM_SoundConvertor.File; 8 | using static FM_SoundConvertor.Console; 9 | 10 | 11 | 12 | namespace FM_SoundConvertor 13 | { 14 | class DX7 15 | { 16 | enum eName 17 | { 18 | Name0, Name1, Name2, Name3, Name4, Name5, Name6, Name7, Name8, Name9 19 | } 20 | 21 | enum ePut 22 | { 23 | AR6, DR6, SR6, RR6, L16, SL6, L36, L46, _06, _16, _26, _36, DK6, KV6, TL6, ML6, _56, 24 | AR5, DR5, SR5, RR5, L15, SL5, L35, L45, _05, _15, _25, _35, DK5, KV5, TL5, ML5, _55, 25 | AR4, DR4, SR4, RR4, L14, SL4, L34, L44, _04, _14, _24, _34, DK4, KV4, TL4, ML4, _54, 26 | AR3, DR3, SR3, RR3, L13, SL3, L33, L43, _03, _13, _23, _33, DK3, KV3, TL3, ML3, _53, 27 | AR2, DR2, SR2, RR2, L12, SL2, L32, L42, _02, _12, _22, _32, DK2, KV2, TL2, ML2, _52, 28 | AR1, DR1, SR1, RR1, L11, SL1, L31, L41, _01, _11, _21, _31, DK1, KV1, TL1, ML1, _51, 29 | _70, _71, _72, _73, _74, _75, _76, _77, 30 | AL, FB, 31 | _80, _81, _82, _83, _84, _85, 32 | } 33 | 34 | enum eOfs 35 | { 36 | //0 1 2 3 4 5 6 7 8 37 | AR0, DR0, SR0, RR0, SL0, DK0, TL0, ML0, KV0, 38 | AR1, DR1, SR1, RR1, SL1, DK1, TL1, ML1, KV1, 39 | AR2, DR2, SR2, RR2, SL2, DK2, TL2, ML2, KV2, 40 | AR3, DR3, SR3, RR3, SL3, DK3, TL3, ML3, KV3, 41 | } 42 | 43 | static ePut[,] aaoPut = new ePut[/*AL*/8, /*eOfs*/9*/*OP*/4]{ 44 | { // 0 45 | ePut.AR6, ePut.DR6, ePut.SR6, ePut.RR6, ePut.SL6, ePut.DK6, ePut.TL6, ePut.ML6, ePut.KV6, 46 | ePut.AR5, ePut.DR5, ePut.SR5, ePut.RR5, ePut.SL5, ePut.DK5, ePut.TL5, ePut.ML5, ePut.KV5, 47 | ePut.AR4, ePut.DR4, ePut.SR4, ePut.RR4, ePut.SL4, ePut.DK4, ePut.TL4, ePut.ML4, ePut.KV4, 48 | ePut.AR3, ePut.DR3, ePut.SR3, ePut.RR3, ePut.SL3, ePut.DK3, ePut.TL3, ePut.ML3, ePut.KV3, 49 | }, 50 | { // 1 51 | ePut.AR6, ePut.DR6, ePut.SR6, ePut.RR6, ePut.SL6, ePut.DK6, ePut.TL6, ePut.ML6, ePut.KV6, 52 | ePut.AR5, ePut.DR5, ePut.SR5, ePut.RR5, ePut.SL5, ePut.DK5, ePut.TL5, ePut.ML5, ePut.KV5, 53 | ePut.AR4, ePut.DR4, ePut.SR4, ePut.RR4, ePut.SL4, ePut.DK4, ePut.TL4, ePut.ML4, ePut.KV4, 54 | ePut.AR3, ePut.DR3, ePut.SR3, ePut.RR3, ePut.SL3, ePut.DK3, ePut.TL3, ePut.ML3, ePut.KV3, 55 | }, 56 | { // 2 57 | ePut.AR4, ePut.DR4, ePut.SR4, ePut.RR4, ePut.SL4, ePut.DK4, ePut.TL4, ePut.ML4, ePut.KV4, 58 | ePut.AR6, ePut.DR6, ePut.SR6, ePut.RR6, ePut.SL6, ePut.DK6, ePut.TL6, ePut.ML6, ePut.KV6, 59 | ePut.AR5, ePut.DR5, ePut.SR5, ePut.RR5, ePut.SL5, ePut.DK5, ePut.TL5, ePut.ML5, ePut.KV5, 60 | ePut.AR3, ePut.DR3, ePut.SR3, ePut.RR3, ePut.SL3, ePut.DK3, ePut.TL3, ePut.ML3, ePut.KV3, 61 | }, 62 | { // 3 63 | ePut.AR6, ePut.DR6, ePut.SR6, ePut.RR6, ePut.SL6, ePut.DK6, ePut.TL6, ePut.ML6, ePut.KV6, 64 | ePut.AR5, ePut.DR5, ePut.SR5, ePut.RR5, ePut.SL5, ePut.DK5, ePut.TL5, ePut.ML5, ePut.KV5, 65 | ePut.AR4, ePut.DR4, ePut.SR4, ePut.RR4, ePut.SL4, ePut.DK4, ePut.TL4, ePut.ML4, ePut.KV4, 66 | ePut.AR3, ePut.DR3, ePut.SR3, ePut.RR3, ePut.SL3, ePut.DK3, ePut.TL3, ePut.ML3, ePut.KV3, 67 | }, 68 | { // 4 69 | ePut.AR6, ePut.DR6, ePut.SR6, ePut.RR6, ePut.SL6, ePut.DK6, ePut.TL6, ePut.ML6, ePut.KV6, 70 | ePut.AR5, ePut.DR5, ePut.SR5, ePut.RR5, ePut.SL5, ePut.DK5, ePut.TL5, ePut.ML5, ePut.KV5, 71 | ePut.AR4, ePut.DR4, ePut.SR4, ePut.RR4, ePut.SL4, ePut.DK4, ePut.TL4, ePut.ML4, ePut.KV4, 72 | ePut.AR3, ePut.DR3, ePut.SR3, ePut.RR3, ePut.SL3, ePut.DK3, ePut.TL3, ePut.ML3, ePut.KV3, 73 | }, 74 | { // 5 75 | ePut.AR6, ePut.DR6, ePut.SR6, ePut.RR6, ePut.SL6, ePut.DK6, ePut.TL6, ePut.ML6, ePut.KV6, 76 | ePut.AR5, ePut.DR5, ePut.SR5, ePut.RR5, ePut.SL5, ePut.DK5, ePut.TL5, ePut.ML5, ePut.KV5, 77 | ePut.AR4, ePut.DR4, ePut.SR4, ePut.RR4, ePut.SL4, ePut.DK4, ePut.TL4, ePut.ML4, ePut.KV4, 78 | ePut.AR3, ePut.DR3, ePut.SR3, ePut.RR3, ePut.SL3, ePut.DK3, ePut.TL3, ePut.ML3, ePut.KV3, 79 | }, 80 | { // 6 81 | ePut.AR6, ePut.DR6, ePut.SR6, ePut.RR6, ePut.SL6, ePut.DK6, ePut.TL6, ePut.ML6, ePut.KV6, 82 | ePut.AR5, ePut.DR5, ePut.SR5, ePut.RR5, ePut.SL5, ePut.DK5, ePut.TL5, ePut.ML5, ePut.KV5, 83 | ePut.AR4, ePut.DR4, ePut.SR4, ePut.RR4, ePut.SL4, ePut.DK4, ePut.TL4, ePut.ML4, ePut.KV4, 84 | ePut.AR3, ePut.DR3, ePut.SR3, ePut.RR3, ePut.SL3, ePut.DK3, ePut.TL3, ePut.ML3, ePut.KV3, 85 | }, 86 | { // 7 87 | ePut.AR6, ePut.DR6, ePut.SR6, ePut.RR6, ePut.SL6, ePut.DK6, ePut.TL6, ePut.ML6, ePut.KV6, 88 | ePut.AR5, ePut.DR5, ePut.SR5, ePut.RR5, ePut.SL5, ePut.DK5, ePut.TL5, ePut.ML5, ePut.KV5, 89 | ePut.AR4, ePut.DR4, ePut.SR4, ePut.RR4, ePut.SL4, ePut.DK4, ePut.TL4, ePut.ML4, ePut.KV4, 90 | ePut.AR3, ePut.DR3, ePut.SR3, ePut.RR3, ePut.SL3, ePut.DK3, ePut.TL3, ePut.ML3, ePut.KV3, 91 | }, 92 | }; 93 | 94 | 95 | 96 | static int ToneLength() 97 | { 98 | return 32; 99 | } 100 | 101 | static int HeadLength() 102 | { 103 | return 0x06; 104 | } 105 | 106 | static int TailLength() 107 | { 108 | return 0x02; 109 | } 110 | 111 | static int NameLength() 112 | { 113 | return System.Enum.GetNames(typeof(eName)).Length; 114 | } 115 | 116 | static int PutLength() 117 | { 118 | return (System.Enum.GetNames(typeof(ePut)).Length * sizeof(byte)) + NameLength(); 119 | } 120 | 121 | static int SyxLength() 122 | { 123 | return HeadLength() + (ToneLength() * PutLength()) + TailLength(); 124 | } 125 | 126 | 127 | 128 | public static byte[] New() 129 | { 130 | var Buffer = new byte[SyxLength()]; 131 | Tone vTone = new Tone(); 132 | vTone.aOp[3].AR = 31; 133 | for (vTone.Number = 0; vTone.Number < ToneLength(); ++vTone.Number){ 134 | Put(vTone, ref Buffer); 135 | } 136 | return Buffer; 137 | } 138 | 139 | 140 | 141 | static int Get(byte[] Buffer, int O, int e, int Max) 142 | { 143 | return (int)Math.Round(BitConverter.ToSingle(Buffer, O + (e * sizeof(float))) * Max); 144 | } 145 | 146 | 147 | 148 | static void Get(ref Tone @Tone, byte[] Buffer, int i) 149 | { 150 | #if false//[ 151 | int o = HeadLength() + (i * PutLength()); 152 | int O = o + NameLength(); 153 | Tone.aOp[0].AR = Get(Buffer, O, (int)ePut.AR0, 31); 154 | Tone.aOp[1].AR = Get(Buffer, O, (int)ePut.AR1, 31); 155 | Tone.aOp[2].AR = Get(Buffer, O, (int)ePut.AR2, 31); 156 | Tone.aOp[3].AR = Get(Buffer, O, (int)ePut.AR3, 31); 157 | Tone.aOp[0].DR = Get(Buffer, O, (int)ePut.DR0, 31); 158 | Tone.aOp[1].DR = Get(Buffer, O, (int)ePut.DR1, 31); 159 | Tone.aOp[2].DR = Get(Buffer, O, (int)ePut.DR2, 31); 160 | Tone.aOp[3].DR = Get(Buffer, O, (int)ePut.DR3, 31); 161 | Tone.aOp[0].SR = Get(Buffer, O, (int)ePut.SR0, 31); 162 | Tone.aOp[1].SR = Get(Buffer, O, (int)ePut.SR1, 31); 163 | Tone.aOp[2].SR = Get(Buffer, O, (int)ePut.SR2, 31); 164 | Tone.aOp[3].SR = Get(Buffer, O, (int)ePut.SR3, 31); 165 | Tone.aOp[0].RR = Get(Buffer, O, (int)ePut.RR0, 15); 166 | Tone.aOp[1].RR = Get(Buffer, O, (int)ePut.RR1, 15); 167 | Tone.aOp[2].RR = Get(Buffer, O, (int)ePut.RR2, 15); 168 | Tone.aOp[3].RR = Get(Buffer, O, (int)ePut.RR3, 15); 169 | Tone.aOp[0].SL = Get(Buffer, O, (int)ePut.SL0, 15); 170 | Tone.aOp[1].SL = Get(Buffer, O, (int)ePut.SL1, 15); 171 | Tone.aOp[2].SL = Get(Buffer, O, (int)ePut.SL2, 15); 172 | Tone.aOp[3].SL = Get(Buffer, O, (int)ePut.SL3, 15); 173 | Tone.aOp[0].TL = Get(Buffer, O, (int)ePut.TL0, 127); 174 | Tone.aOp[1].TL = Get(Buffer, O, (int)ePut.TL1, 127); 175 | Tone.aOp[2].TL = Get(Buffer, O, (int)ePut.TL2, 127); 176 | Tone.aOp[3].TL = Get(Buffer, O, (int)ePut.TL3, 127); 177 | Tone.aOp[0].KS = Get(Buffer, O, (int)ePut.KS0, 3); 178 | Tone.aOp[1].KS = Get(Buffer, O, (int)ePut.KS1, 3); 179 | Tone.aOp[2].KS = Get(Buffer, O, (int)ePut.KS2, 3); 180 | Tone.aOp[3].KS = Get(Buffer, O, (int)ePut.KS3, 3); 181 | Tone.aOp[0].ML = Get(Buffer, O, (int)ePut.ML0, 15); 182 | Tone.aOp[1].ML = Get(Buffer, O, (int)ePut.ML1, 15); 183 | Tone.aOp[2].ML = Get(Buffer, O, (int)ePut.ML2, 15); 184 | Tone.aOp[3].ML = Get(Buffer, O, (int)ePut.ML3, 15); 185 | Tone.aOp[0].DT = Get(Buffer, O, (int)ePut.DT1_0, 99); 186 | Tone.aOp[1].DT = Get(Buffer, O, (int)ePut.DT1_1, 99); 187 | Tone.aOp[2].DT = Get(Buffer, O, (int)ePut.DT1_2, 99); 188 | Tone.aOp[3].DT = Get(Buffer, O, (int)ePut.DT1_3, 99); 189 | Tone.aOp[0].DT2 = Get(Buffer, O, (int)ePut.DT2_0, 3); 190 | Tone.aOp[1].DT2 = Get(Buffer, O, (int)ePut.DT2_1, 3); 191 | Tone.aOp[2].DT2 = Get(Buffer, O, (int)ePut.DT2_2, 3); 192 | Tone.aOp[3].DT2 = Get(Buffer, O, (int)ePut.DT2_3, 3); 193 | Tone.AL = Get(Buffer, O, (int)ePut.AL, 7); 194 | Tone.FB = Get(Buffer, O, (int)ePut.FB, 7); 195 | 196 | var aChar = new char[] 197 | { 198 | (char)Buffer[o + (int)eName.Name0], 199 | (char)Buffer[o + (int)eName.Name1], 200 | (char)Buffer[o + (int)eName.Name2], 201 | (char)Buffer[o + (int)eName.Name3], 202 | (char)Buffer[o + (int)eName.Name4], 203 | (char)Buffer[o + (int)eName.Name5], 204 | (char)Buffer[o + (int)eName.Name6], 205 | (char)Buffer[o + (int)eName.Name7], 206 | (char)Buffer[o + (int)eName.Name8], 207 | (char)Buffer[o + (int)eName.Name9], 208 | }; 209 | Tone.Name = ""; 210 | foreach (var Char in aChar) if (Char != 0) Tone.Name += Char.ToString(); 211 | 212 | Tone.Number = i; 213 | #endif//] 214 | } 215 | 216 | 217 | 218 | static void Put(byte[] Buffer, int O, int e, int v) 219 | { 220 | var aPut = BitConverter.GetBytes((byte)v);//aPut.Length==2 221 | Array.Copy(aPut, 0, Buffer, O + (e * sizeof(byte)), sizeof(byte)); 222 | } 223 | 224 | 225 | 226 | static int AR(int v) 227 | { 228 | switch (v){ 229 | default: 230 | case 0: return 0; 231 | case 1: return 16; 232 | case 2: return 22; 233 | case 3: return 21; 234 | case 4: return 22; 235 | case 5: return 27; 236 | case 6: return 29; 237 | case 7: return 32; 238 | case 8: return 35; 239 | case 9: return 38; 240 | case 10:return 41; 241 | case 11:return 44; 242 | case 12:return 47; 243 | case 13:return 50; 244 | case 14:return 54; 245 | case 15:return 57; 246 | case 16:return 58; 247 | case 17:return 63; 248 | case 18:return 64; 249 | case 19:return 69; 250 | case 20:return 71; 251 | case 21:return 75; 252 | case 22:return 75; 253 | case 23:return 79; 254 | case 24:return 82; 255 | case 25:return 83; 256 | case 26:return 85; 257 | case 27:return 86; 258 | case 28:return 99; 259 | case 29:return 99; 260 | case 30:return 99; 261 | case 31:return 99; 262 | } 263 | } 264 | 265 | 266 | 267 | static int DR(int v) 268 | { 269 | switch (v){ 270 | default: 271 | case 0: return 0; 272 | case 1: return 11; 273 | case 2: return 18; 274 | case 3: return 15; 275 | case 4: return 18; 276 | case 5: return 21; 277 | case 6: return 24; 278 | case 7: return 27; 279 | case 8: return 30; 280 | case 9: return 33; 281 | case 10:return 36; 282 | case 11:return 40; 283 | case 12:return 43; 284 | case 13:return 46; 285 | case 14:return 49; 286 | case 15:return 52; 287 | case 16:return 55; 288 | case 17:return 58; 289 | case 18:return 61; 290 | case 19:return 64; 291 | case 20:return 68; 292 | case 21:return 71; 293 | case 22:return 75; 294 | case 23:return 79; 295 | case 24:return 82; 296 | case 25:return 99; 297 | case 26:return 99; 298 | case 27:return 99; 299 | case 28:return 99; 300 | case 29:return 99; 301 | case 30:return 99; 302 | case 31:return 99; 303 | } 304 | } 305 | 306 | 307 | 308 | static int SR(int v) 309 | { 310 | switch (v){ 311 | default: 312 | case 0: return 0; 313 | case 1: return 13; 314 | case 2: return 19; 315 | case 3: return 16; 316 | case 4: return 19; 317 | case 5: return 22; 318 | case 6: return 25; 319 | case 7: return 29; 320 | case 8: return 32; 321 | case 9: return 35; 322 | case 10:return 38; 323 | case 11:return 41; 324 | case 12:return 44; 325 | case 13:return 47; 326 | case 14:return 50; 327 | case 15:return 54; 328 | case 16:return 55; 329 | case 17:return 60; 330 | case 18:return 61; 331 | case 19:return 66; 332 | case 20:return 69; 333 | case 21:return 72; 334 | case 22:return 74; 335 | case 23:return 77; 336 | case 24:return 79; 337 | case 25:return 83; 338 | case 26:return 85; 339 | case 27:return 89; 340 | case 28:return 91; 341 | case 29:return 93; 342 | case 30:return 96; 343 | case 31:return 96; 344 | } 345 | } 346 | 347 | 348 | 349 | static int RR(int v) 350 | { 351 | switch (v){ 352 | default: 353 | case 0: return 13; 354 | case 1: return 16; 355 | case 2: return 22; 356 | case 3: return 29; 357 | case 4: return 35; 358 | case 5: return 41; 359 | case 6: return 47; 360 | case 7: return 54; 361 | case 8: return 60; 362 | case 9: return 66; 363 | case 10:return 72; 364 | case 11:return 77; 365 | case 12:return 83; 366 | case 13:return 89; 367 | case 14:return 93; 368 | case 15:return 96; 369 | } 370 | } 371 | 372 | 373 | 374 | static int SL(int v) 375 | { 376 | return 99 - (v*4); 377 | } 378 | 379 | 380 | 381 | static int TL(int v) 382 | { 383 | v -= 8; 384 | v = (v > 0)? v: 0; 385 | v = 99 - v; 386 | v = (v > 0)? v: 0; 387 | return v; 388 | } 389 | 390 | 391 | 392 | static int ML(int v) 393 | { 394 | return v<<1; 395 | } 396 | 397 | 398 | 399 | static int KS(int v) 400 | { 401 | switch (v){ 402 | default: 403 | case 0: return 0; 404 | case 1: return 2; 405 | case 2: return 4; 406 | case 3: return 7; 407 | } 408 | } 409 | 410 | 411 | 412 | static int DT(int v) 413 | { 414 | switch (v){ 415 | default: 416 | case 0: return (7+0)<<3; 417 | case 1: return (7+1)<<3; 418 | case 2: return (7+2)<<3; 419 | case 3: return (7+3)<<3; 420 | case 4: return (7-0)<<3; 421 | case 5: return (7-1)<<3; 422 | case 6: return (7-2)<<3; 423 | case 7: return (7-3)<<3; 424 | } 425 | } 426 | 427 | 428 | 429 | static int KV(int op, int alg) 430 | { 431 | switch (op){ 432 | default: 433 | case 0: return (alg == 7)? 7<<2: 0; 434 | case 1: return (alg >= 4)? 7<<2: 0; 435 | case 2: return (alg >= 5)? 7<<2: 0; 436 | case 3: return 7<<2; 437 | } 438 | } 439 | 440 | 441 | 442 | static int AL(int v) 443 | { 444 | switch (v){ 445 | default: 446 | case 0: return 0; 447 | case 1: return 13; 448 | case 2: return 7; 449 | case 3: return 6; 450 | case 4: return 4; 451 | case 5: return 23; 452 | case 6: return 30; 453 | case 7: return 31; 454 | } 455 | } 456 | 457 | 458 | 459 | static int FB(int v) 460 | { 461 | return v | 0x08; 462 | } 463 | 464 | 465 | 466 | public static void Put(Tone @Tone, ref byte[] Buffer) 467 | { 468 | if (Tone.IsValid() && Tone.Number < ToneLength()) 469 | { 470 | int O = HeadLength() + (Tone.Number * PutLength()); 471 | int o = O + PutLength() - NameLength(); 472 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.AR0], AR(Tone.aOp[0].AR)); 473 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.AR1], AR(Tone.aOp[1].AR)); 474 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.AR2], AR(Tone.aOp[2].AR)); 475 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.AR3], AR(Tone.aOp[3].AR)); 476 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.DR0], DR(Tone.aOp[0].DR)); 477 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.DR1], DR(Tone.aOp[1].DR)); 478 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.DR2], DR(Tone.aOp[2].DR)); 479 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.DR3], DR(Tone.aOp[3].DR)); 480 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.SR0], SR(Tone.aOp[0].SR)); 481 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.SR1], SR(Tone.aOp[1].SR)); 482 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.SR2], SR(Tone.aOp[2].SR)); 483 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.SR3], SR(Tone.aOp[3].SR)); 484 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.RR0], RR(Tone.aOp[0].RR)); 485 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.RR1], RR(Tone.aOp[1].RR)); 486 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.RR2], RR(Tone.aOp[2].RR)); 487 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.RR3], RR(Tone.aOp[3].RR)); 488 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.SL0], SL((Tone.aOp[0].DR > 0)? Tone.aOp[0].SL: 0)); 489 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.SL1], SL((Tone.aOp[1].DR > 0)? Tone.aOp[1].SL: 0)); 490 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.SL2], SL((Tone.aOp[2].DR > 0)? Tone.aOp[2].SL: 0)); 491 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.SL3], SL((Tone.aOp[3].DR > 0)? Tone.aOp[3].SL: 0)); 492 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.TL0], TL(Tone.aOp[0].TL)); 493 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.TL1], TL(Tone.aOp[1].TL)); 494 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.TL2], TL(Tone.aOp[2].TL)); 495 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.TL3], TL(Tone.aOp[3].TL)); 496 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.ML0], ML(Tone.aOp[0].ML)); 497 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.ML1], ML(Tone.aOp[1].ML)); 498 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.ML2], ML(Tone.aOp[2].ML)); 499 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.ML3], ML(Tone.aOp[3].ML)); 500 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.DK0], DT(Tone.aOp[0].DT) | KS(Tone.aOp[0].KS)); 501 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.DK1], DT(Tone.aOp[1].DT) | KS(Tone.aOp[1].KS)); 502 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.DK2], DT(Tone.aOp[2].DT) | KS(Tone.aOp[2].KS)); 503 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.DK3], DT(Tone.aOp[3].DT) | KS(Tone.aOp[3].KS)); 504 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.KV0], KV(0, Tone.AL)); 505 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.KV1], KV(1, Tone.AL)); 506 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.KV2], KV(2, Tone.AL)); 507 | Put(Buffer, O, (int)aaoPut[Tone.AL,(int)eOfs.KV3], KV(3, Tone.AL)); 508 | Put(Buffer, O, (int)ePut.AL, AL(Tone.AL)); 509 | Put(Buffer, O, (int)ePut.FB, FB(Tone.FB)); 510 | Put(Buffer, O, (int)ePut.L16, 0x63); 511 | Put(Buffer, O, (int)ePut.L15, 0x63); 512 | Put(Buffer, O, (int)ePut.L14, 0x63); 513 | Put(Buffer, O, (int)ePut.L13, 0x63); 514 | Put(Buffer, O, (int)ePut.L36, (Tone.aOp[0].SR == 0)? SL((Tone.aOp[0].DR > 0)? Tone.aOp[0].SL: 0): 0); 515 | Put(Buffer, O, (int)ePut.L35, (Tone.aOp[1].SR == 0)? SL((Tone.aOp[1].DR > 0)? Tone.aOp[1].SL: 0): 0); 516 | Put(Buffer, O, (int)ePut.L34, (Tone.aOp[2].SR == 0)? SL((Tone.aOp[2].DR > 0)? Tone.aOp[2].SL: 0): 0); 517 | Put(Buffer, O, (int)ePut.L33, (Tone.aOp[3].SR == 0)? SL((Tone.aOp[3].DR > 0)? Tone.aOp[3].SL: 0): 0); 518 | Put(Buffer, O, (int)ePut._70, 0x63); 519 | Put(Buffer, O, (int)ePut._71, 0x63); 520 | Put(Buffer, O, (int)ePut._72, 0x63); 521 | Put(Buffer, O, (int)ePut._73, 0x63); 522 | Put(Buffer, O, (int)ePut._74, 0x32); 523 | Put(Buffer, O, (int)ePut._75, 0x32); 524 | Put(Buffer, O, (int)ePut._76, 0x32); 525 | Put(Buffer, O, (int)ePut._77, 0x32); 526 | Put(Buffer, O, (int)ePut._84, 0x01); 527 | Put(Buffer, O, (int)ePut._85, 0x18); 528 | 529 | if (String.IsNullOrWhiteSpace(Tone.Name)) 530 | { 531 | Tone.Name = Tone.Number.ToString(); 532 | } 533 | Buffer[o + (int)eName.Name0] = (byte)((Tone.Name.Length > 0) ? Tone.Name[0] : ' '); 534 | Buffer[o + (int)eName.Name1] = (byte)((Tone.Name.Length > 1) ? Tone.Name[1] : ' '); 535 | Buffer[o + (int)eName.Name2] = (byte)((Tone.Name.Length > 2) ? Tone.Name[2] : ' '); 536 | Buffer[o + (int)eName.Name3] = (byte)((Tone.Name.Length > 3) ? Tone.Name[3] : ' '); 537 | Buffer[o + (int)eName.Name4] = (byte)((Tone.Name.Length > 4) ? Tone.Name[4] : ' '); 538 | Buffer[o + (int)eName.Name5] = (byte)((Tone.Name.Length > 5) ? Tone.Name[5] : ' '); 539 | Buffer[o + (int)eName.Name6] = (byte)((Tone.Name.Length > 6) ? Tone.Name[6] : ' '); 540 | Buffer[o + (int)eName.Name7] = (byte)((Tone.Name.Length > 7) ? Tone.Name[7] : ' '); 541 | Buffer[o + (int)eName.Name8] = (byte)((Tone.Name.Length > 8) ? Tone.Name[8] : ' '); 542 | Buffer[o + (int)eName.Name9] = (byte)((Tone.Name.Length > 9) ? Tone.Name[9] : ' '); 543 | } 544 | } 545 | 546 | 547 | 548 | public static bool IsValid(byte[] Buffer) 549 | { 550 | return ( 551 | Buffer[0x00] == 0xf0 552 | && Buffer[0x01] == 0x43 553 | && Buffer[0x02] == 0x00 554 | && Buffer[0x03] == 0x09 555 | && Buffer[0x04] == 0x20 556 | && Buffer[0x05] == 0x00 557 | && Buffer[0x1007] == 0xf7 558 | ); 559 | } 560 | 561 | 562 | 563 | public static void Reader(string Path, Option @Option) 564 | { 565 | var Buffer = ReadByte(Path); 566 | if (Buffer.Length == SyxLength() && IsValid(Buffer)) 567 | { 568 | Tone vTone = new Tone(); 569 | 570 | var BufferMuc = ""; 571 | var BufferDat = Dat.New(); 572 | var BufferFmp = ""; 573 | var BufferPmd = ""; 574 | var BufferVopm = Vopm.New(); 575 | var BufferFMtrial = FMtrial.New(); 576 | var BufferRme = Rme.New(); 577 | var BufferVmm = Vmm.New(); 578 | 579 | for (int i = 0; i < ToneLength(); ++i) 580 | { 581 | Get(ref vTone, Buffer, i); 582 | 583 | if (Option.bMuc) Muc.Put(vTone, ref BufferMuc); 584 | if (Option.bDat) Dat.Put(vTone, ref BufferDat); 585 | if (Option.bFmp) Fmp.Put(vTone, ref BufferFmp); 586 | if (Option.bPmd) Pmd.Put(vTone, ref BufferPmd); 587 | if (Option.bVopm) Vopm.Put(vTone, ref BufferVopm); 588 | if (Option.bFMtrial) FMtrial.Put(vTone, ref BufferFMtrial); 589 | if (Option.bRme) Rme.Put(vTone, ref BufferRme); 590 | if (Option.bVmm) Vmm.Put(vTone, ref BufferVmm); 591 | } 592 | 593 | if (Option.bMuc) Muc.Writer(Path, BufferMuc); 594 | if (Option.bDat) Dat.Writer(Path, BufferDat); 595 | if (Option.bFmp) Fmp.Writer(Path, BufferFmp); 596 | if (Option.bPmd) Pmd.Writer(Path, BufferPmd); 597 | if (Option.bVopm) Vopm.Writer(Path, BufferVopm); 598 | if (Option.bFMtrial) FMtrial.Writer(Path, BufferFMtrial); 599 | if (Option.bRme) Rme.Writer(Path, BufferRme); 600 | if (Option.bVmm) Vmm.Writer(Path, BufferVmm); 601 | } 602 | } 603 | 604 | 605 | 606 | public static void Reader(string[] aPath, Option @Option) 607 | { 608 | #if false//[ 609 | foreach (var Path in aPath) 610 | { 611 | if (!String.IsNullOrWhiteSpace(Path) && Extension(Path).ToLower() == ".syx") Reader(Path, Option); 612 | } 613 | #endif//] 614 | } 615 | 616 | 617 | 618 | public static void Writer(string Path, byte[] Buffer) 619 | { 620 | byte Sum = 0; 621 | int o = HeadLength(); 622 | int n = ToneLength() * PutLength(); 623 | for (; n > 0; --n, ++o) Sum += Buffer[o]; 624 | 625 | Buffer[0x00] = 0xf0; 626 | Buffer[0x01] = 0x43; 627 | Buffer[0x02] = 0x00; 628 | Buffer[0x03] = 0x09; 629 | Buffer[0x04] = 0x20; 630 | Buffer[0x05] = 0x00; 631 | Buffer[0x1006] = (byte)(-Sum & 0x7f); 632 | Buffer[0x1007] = 0xf7; 633 | 634 | WriteByte(ChangeExtension(Path, ".syx"), Buffer); 635 | } 636 | } 637 | } 638 | -------------------------------------------------------------------------------- /FM-SoundConvertor/Dat.cs: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | using System; 5 | 6 | using static FM_SoundConvertor.Path; 7 | using static FM_SoundConvertor.File; 8 | using static FM_SoundConvertor.Console; 9 | 10 | 11 | 12 | namespace FM_SoundConvertor 13 | { 14 | class Dat 15 | { 16 | enum ePut 17 | { 18 | Void, 19 | DTML0, DTML2, DTML1, DTML3, 20 | TL0, TL2, TL1, TL3, 21 | KSAR0, KSAR2, KSAR1, KSAR3, 22 | DR0, DR2, DR1, DR3, 23 | SR0, SR2, SR1, SR3, 24 | SLRR0, SLRR2, SLRR1, SLRR3, 25 | FBAL, 26 | Name0, Name1, Name2, Name3, Name4, Name5, 27 | } 28 | 29 | 30 | 31 | static int ToneLength() 32 | { 33 | return 0x100; 34 | } 35 | 36 | static int PutLength() 37 | { 38 | return System.Enum.GetNames(typeof(ePut)).Length; 39 | } 40 | 41 | static int DatLength() 42 | { 43 | return ToneLength() * PutLength(); 44 | } 45 | 46 | 47 | 48 | public static byte[] New() 49 | { 50 | return new byte[DatLength()]; 51 | } 52 | 53 | 54 | 55 | static void Get(ref Tone @Tone, byte[] Buffer, int i) 56 | { 57 | var o = i * PutLength(); 58 | Tone.aOp[0].AR = Buffer[o + (int)ePut.KSAR0] & 0x1f; 59 | Tone.aOp[1].AR = Buffer[o + (int)ePut.KSAR1] & 0x1f; 60 | Tone.aOp[2].AR = Buffer[o + (int)ePut.KSAR2] & 0x1f; 61 | Tone.aOp[3].AR = Buffer[o + (int)ePut.KSAR3] & 0x1f; 62 | Tone.aOp[0].DR = Buffer[o + (int)ePut.DR0]; 63 | Tone.aOp[1].DR = Buffer[o + (int)ePut.DR1]; 64 | Tone.aOp[2].DR = Buffer[o + (int)ePut.DR2]; 65 | Tone.aOp[3].DR = Buffer[o + (int)ePut.DR3]; 66 | Tone.aOp[0].SR = Buffer[o + (int)ePut.SR0]; 67 | Tone.aOp[1].SR = Buffer[o + (int)ePut.SR1]; 68 | Tone.aOp[2].SR = Buffer[o + (int)ePut.SR2]; 69 | Tone.aOp[3].SR = Buffer[o + (int)ePut.SR3]; 70 | Tone.aOp[0].RR = Buffer[o + (int)ePut.SLRR0] & 0xf; 71 | Tone.aOp[1].RR = Buffer[o + (int)ePut.SLRR1] & 0xf; 72 | Tone.aOp[2].RR = Buffer[o + (int)ePut.SLRR2] & 0xf; 73 | Tone.aOp[3].RR = Buffer[o + (int)ePut.SLRR3] & 0xf; 74 | Tone.aOp[0].SL = Buffer[o + (int)ePut.SLRR0] >> 4; 75 | Tone.aOp[1].SL = Buffer[o + (int)ePut.SLRR1] >> 4; 76 | Tone.aOp[2].SL = Buffer[o + (int)ePut.SLRR2] >> 4; 77 | Tone.aOp[3].SL = Buffer[o + (int)ePut.SLRR3] >> 4; 78 | Tone.aOp[0].TL = Buffer[o + (int)ePut.TL0]; 79 | Tone.aOp[1].TL = Buffer[o + (int)ePut.TL1]; 80 | Tone.aOp[2].TL = Buffer[o + (int)ePut.TL2]; 81 | Tone.aOp[3].TL = Buffer[o + (int)ePut.TL3]; 82 | Tone.aOp[0].KS = Buffer[o + (int)ePut.KSAR0] >> 6; 83 | Tone.aOp[1].KS = Buffer[o + (int)ePut.KSAR1] >> 6; 84 | Tone.aOp[2].KS = Buffer[o + (int)ePut.KSAR2] >> 6; 85 | Tone.aOp[3].KS = Buffer[o + (int)ePut.KSAR3] >> 6; 86 | Tone.aOp[0].ML = Buffer[o + (int)ePut.DTML0] & 0xf; 87 | Tone.aOp[1].ML = Buffer[o + (int)ePut.DTML1] & 0xf; 88 | Tone.aOp[2].ML = Buffer[o + (int)ePut.DTML2] & 0xf; 89 | Tone.aOp[3].ML = Buffer[o + (int)ePut.DTML3] & 0xf; 90 | Tone.aOp[0].DT = Buffer[o + (int)ePut.DTML0] >> 4; 91 | Tone.aOp[1].DT = Buffer[o + (int)ePut.DTML1] >> 4; 92 | Tone.aOp[2].DT = Buffer[o + (int)ePut.DTML2] >> 4; 93 | Tone.aOp[3].DT = Buffer[o + (int)ePut.DTML3] >> 4; 94 | Tone.aOp[0].DT2 = 0; 95 | Tone.aOp[1].DT2 = 0; 96 | Tone.aOp[2].DT2 = 0; 97 | Tone.aOp[3].DT2 = 0; 98 | Tone.aOp[0].AM = 0; 99 | Tone.aOp[1].AM = 0; 100 | Tone.aOp[2].AM = 0; 101 | Tone.aOp[3].AM = 0; 102 | Tone.AL = Buffer[o + (int)ePut.FBAL] & 0x7; 103 | Tone.FB = Buffer[o + (int)ePut.FBAL] >> 3; 104 | 105 | var aChar = new char[] 106 | { 107 | (char)Buffer[o + (int)ePut.Name0], 108 | (char)Buffer[o + (int)ePut.Name1], 109 | (char)Buffer[o + (int)ePut.Name2], 110 | (char)Buffer[o + (int)ePut.Name3], 111 | (char)Buffer[o + (int)ePut.Name4], 112 | (char)Buffer[o + (int)ePut.Name5], 113 | }; 114 | Tone.Name = ""; 115 | foreach (var Char in aChar) if (Char != 0) Tone.Name += Char.ToString(); 116 | 117 | Tone.Number = i; 118 | } 119 | 120 | 121 | 122 | public static void Put(Tone @Tone, ref byte[] Buffer) 123 | { 124 | if (Tone.IsValid()) 125 | { 126 | int o = Tone.Number * PutLength(); 127 | Buffer[o + (int)ePut.Void] = 0; 128 | Buffer[o + (int)ePut.DTML0] = (byte)((Tone.aOp[0].DT << 4) | Tone.aOp[0].ML); 129 | Buffer[o + (int)ePut.DTML1] = (byte)((Tone.aOp[1].DT << 4) | Tone.aOp[1].ML); 130 | Buffer[o + (int)ePut.DTML2] = (byte)((Tone.aOp[2].DT << 4) | Tone.aOp[2].ML); 131 | Buffer[o + (int)ePut.DTML3] = (byte)((Tone.aOp[3].DT << 4) | Tone.aOp[3].ML); 132 | Buffer[o + (int)ePut.TL0] = (byte)Tone.aOp[0].TL; 133 | Buffer[o + (int)ePut.TL1] = (byte)Tone.aOp[1].TL; 134 | Buffer[o + (int)ePut.TL2] = (byte)Tone.aOp[2].TL; 135 | Buffer[o + (int)ePut.TL3] = (byte)Tone.aOp[3].TL; 136 | Buffer[o + (int)ePut.KSAR0] = (byte)((Tone.aOp[0].KS << 6) | Tone.aOp[0].AR); 137 | Buffer[o + (int)ePut.KSAR1] = (byte)((Tone.aOp[1].KS << 6) | Tone.aOp[1].AR); 138 | Buffer[o + (int)ePut.KSAR2] = (byte)((Tone.aOp[2].KS << 6) | Tone.aOp[2].AR); 139 | Buffer[o + (int)ePut.KSAR3] = (byte)((Tone.aOp[3].KS << 6) | Tone.aOp[3].AR); 140 | Buffer[o + (int)ePut.DR0] = (byte)Tone.aOp[0].DR; 141 | Buffer[o + (int)ePut.DR1] = (byte)Tone.aOp[1].DR; 142 | Buffer[o + (int)ePut.DR2] = (byte)Tone.aOp[2].DR; 143 | Buffer[o + (int)ePut.DR3] = (byte)Tone.aOp[3].DR; 144 | Buffer[o + (int)ePut.SR0] = (byte)Tone.aOp[0].SR; 145 | Buffer[o + (int)ePut.SR1] = (byte)Tone.aOp[1].SR; 146 | Buffer[o + (int)ePut.SR2] = (byte)Tone.aOp[2].SR; 147 | Buffer[o + (int)ePut.SR3] = (byte)Tone.aOp[3].SR; 148 | Buffer[o + (int)ePut.SLRR0] = (byte)((Tone.aOp[0].SL << 4) | Tone.aOp[0].RR); 149 | Buffer[o + (int)ePut.SLRR1] = (byte)((Tone.aOp[1].SL << 4) | Tone.aOp[1].RR); 150 | Buffer[o + (int)ePut.SLRR2] = (byte)((Tone.aOp[2].SL << 4) | Tone.aOp[2].RR); 151 | Buffer[o + (int)ePut.SLRR3] = (byte)((Tone.aOp[3].SL << 4) | Tone.aOp[3].RR); 152 | Buffer[o + (int)ePut.FBAL] = (byte)((Tone.FB << 3) | Tone.AL); 153 | Buffer[o + (int)ePut.Name0] = (byte)((Tone.Name.Length > 0) ? Tone.Name[0] : 0); 154 | Buffer[o + (int)ePut.Name1] = (byte)((Tone.Name.Length > 1) ? Tone.Name[1] : 0); 155 | Buffer[o + (int)ePut.Name2] = (byte)((Tone.Name.Length > 2) ? Tone.Name[2] : 0); 156 | Buffer[o + (int)ePut.Name3] = (byte)((Tone.Name.Length > 3) ? Tone.Name[3] : 0); 157 | Buffer[o + (int)ePut.Name4] = (byte)((Tone.Name.Length > 4) ? Tone.Name[4] : 0); 158 | Buffer[o + (int)ePut.Name5] = (byte)((Tone.Name.Length > 5) ? Tone.Name[5] : 0); 159 | } 160 | } 161 | 162 | 163 | 164 | public static void Reader(string Path, Option @Option) 165 | { 166 | var Buffer = ReadByte(Path); 167 | if (Buffer.Length == DatLength()) 168 | { 169 | Tone vTone = new Tone(); 170 | 171 | var BufferMuc = ""; 172 | var BufferFmp = ""; 173 | var BufferPmd = ""; 174 | var BufferVopm = Vopm.New(); 175 | var BufferFMtrial = FMtrial.New(); 176 | var BufferRme = Rme.New(); 177 | var BufferDx7 = DX7.New(); 178 | var BufferVmm = Vmm.New(); 179 | 180 | for (int i = 0; i < ToneLength(); ++i) 181 | { 182 | Get(ref vTone, Buffer, i); 183 | 184 | if (Option.bMuc) Muc.Put(vTone, ref BufferMuc); 185 | if (Option.bFmp) Fmp.Put(vTone, ref BufferFmp); 186 | if (Option.bPmd) Pmd.Put(vTone, ref BufferPmd); 187 | if (Option.bVopm) Vopm.Put(vTone, ref BufferVopm); 188 | if (Option.bFMtrial) FMtrial.Put(vTone, ref BufferFMtrial); 189 | if (Option.bRme) Rme.Put(vTone, ref BufferRme); 190 | if (Option.bDx7) DX7.Put(vTone, ref BufferDx7); 191 | if (Option.bVmm) Vmm.Put(vTone, ref BufferVmm); 192 | } 193 | 194 | if (Option.bMuc) Muc.Writer(Path, BufferMuc); 195 | if (Option.bFmp) Fmp.Writer(Path, BufferFmp); 196 | if (Option.bPmd) Pmd.Writer(Path, BufferPmd); 197 | if (Option.bVopm) Vopm.Writer(Path, BufferVopm); 198 | if (Option.bFMtrial) FMtrial.Writer(Path, BufferFMtrial); 199 | if (Option.bRme) Rme.Writer(Path, BufferRme); 200 | if (Option.bDx7) DX7.Writer(Path, BufferDx7); 201 | if (Option.bVmm) Vmm.Writer(Path, BufferVmm); 202 | } 203 | } 204 | 205 | 206 | 207 | public static void Reader(string[] aPath, Option @Option) 208 | { 209 | foreach (var Path in aPath) 210 | { 211 | if (!String.IsNullOrWhiteSpace(Path) && Extension(Path).ToLower() == ".dat") Reader(Path, Option); 212 | } 213 | } 214 | 215 | 216 | 217 | public static void Writer(string Path, byte[] Buffer) 218 | { 219 | WriteByte(ChangeExtension(Path, ".dat"), Buffer); 220 | } 221 | } 222 | } 223 | -------------------------------------------------------------------------------- /FM-SoundConvertor/Directory.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | using System; 5 | using System.Linq; 6 | using System.Collections.Generic; 7 | 8 | using static FM_SoundConvertor.Path; 9 | 10 | 11 | 12 | namespace FM_SoundConvertor { 13 | public class Directory { 14 | public static string[] Enum(string Path){ 15 | Path = UnCloak(Path); 16 | if (System.IO.Directory.Exists(Path)){ 17 | return System.IO.Directory.EnumerateDirectories(Path, "*", System.IO.SearchOption.AllDirectories) 18 | .Select(Entry => Entry.Replace('\\','/')) 19 | .Where(Entry => (Entry.IndexOf("/.") == -1)) 20 | .OrderBy(Entry => Entry) 21 | .ToArray(); 22 | } 23 | return System.Array.Empty(); 24 | } 25 | 26 | 27 | 28 | public static string[] Enum(string[] aPath){ 29 | var aEnum = new List(); 30 | Array.ForEach(aPath, Path => aEnum.AddRange(Enum(Path))); 31 | return aEnum.ToArray(); 32 | } 33 | 34 | 35 | 36 | public static bool Exist(string Path){ 37 | Path = UnCloak(Path); 38 | return System.IO.Directory.Exists(Path); 39 | } 40 | 41 | 42 | 43 | public static void Delete(string Path){ 44 | try { 45 | Path = UnCloak(Path); 46 | System.IO.Directory.Delete(Path, true); 47 | } 48 | catch (System.IO.DirectoryNotFoundException){} 49 | } 50 | 51 | 52 | 53 | public static System.DateTime Date(string Path){ 54 | Path = UnCloak(Path); 55 | if (Exist(Path)) return System.IO.Directory.GetLastWriteTime(Path); 56 | return new System.DateTime(0); 57 | } 58 | 59 | 60 | 61 | public static System.DateTime Newer(IEnumerable aPath){ 62 | var aDate = aPath.Select(Path => Date(Path)); 63 | return new System.DateTime(aDate.Max().Ticks); 64 | } 65 | 66 | 67 | 68 | public static string Parent(string Path){ 69 | Path = UnCloak(Path); 70 | return System.IO.Directory.GetParent(Path).FullName; 71 | } 72 | 73 | 74 | 75 | public static void Create(string Path){ 76 | Path = UnCloak(Path); 77 | System.IO.Directory.CreateDirectory(Path); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /FM-SoundConvertor/FM-SoundConvertor.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {A3DA1746-8229-471A-8029-3322CCFB15AB} 8 | Exe 9 | FM_SoundConvertor 10 | FM-SoundConvertor 11 | v4.7.2 12 | 512 13 | true 14 | true 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /FM-SoundConvertor/FMtrial.cs: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | using System; 5 | 6 | using static FM_SoundConvertor.Path; 7 | using static FM_SoundConvertor.File; 8 | using static FM_SoundConvertor.Console; 9 | 10 | 11 | 12 | namespace FM_SoundConvertor 13 | { 14 | class FMtrial 15 | { 16 | enum eName 17 | { 18 | Name0, Name1, Name2, Name3, Name4, Name5, Name6, Name7, Name8, Name9, Name10, Name11, Name12, Name13, Name14, Name15, 19 | Name16, Name17, Name18, Name19, Name20, _0, _1, _2, 20 | } 21 | 22 | enum ePut 23 | { 24 | _0, 25 | AL, FB, 26 | _1, _2, _3, _4, _5, _6, _7, _8, _9, 27 | AR0, DR0, SR0, RR0, SL0, TL0, KS0, ML0, DT1_0, DT2_0, WF0, 28 | AR1, DR1, SR1, RR1, SL1, TL1, KS1, ML1, DT1_1, DT2_1, WF1, 29 | AR2, DR2, SR2, RR2, SL2, TL2, KS2, ML2, DT1_2, DT2_2, WF2, 30 | AR3, DR3, SR3, RR3, SL3, TL3, KS3, ML3, DT1_3, DT2_3, WF3, 31 | _10, _11, MX, _13, _14, _15, _16, _17, _18, _19, 32 | _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, 33 | _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, 34 | _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, 35 | OS, PB, 36 | } 37 | 38 | 39 | 40 | 41 | static int ToneLength() 42 | { 43 | return 0x124; 44 | } 45 | 46 | static int HeadLength() 47 | { 48 | return 0xa0; 49 | } 50 | 51 | static int NameLength() 52 | { 53 | return System.Enum.GetNames(typeof(eName)).Length; 54 | } 55 | 56 | static int PutLength() 57 | { 58 | return NameLength() + (System.Enum.GetNames(typeof(ePut)).Length * sizeof(float)); 59 | } 60 | 61 | static int FxbLength() 62 | { 63 | return HeadLength() + (ToneLength() * PutLength()); 64 | } 65 | 66 | 67 | 68 | public static byte[] New() 69 | { 70 | return new byte[FxbLength()]; 71 | } 72 | 73 | 74 | 75 | static int Get(byte[] Buffer, int O, int e, int Max) 76 | { 77 | return (int)Math.Round(BitConverter.ToSingle(Buffer, O + (e * sizeof(float))) * Max); 78 | } 79 | 80 | 81 | 82 | static void Get(ref Tone @Tone, byte[] Buffer, int i) 83 | { 84 | int o = HeadLength() + (i * PutLength()); 85 | int O = o + NameLength(); 86 | Tone.aOp[0].AR = Get(Buffer, O, (int)ePut.AR0, 31); 87 | Tone.aOp[1].AR = Get(Buffer, O, (int)ePut.AR1, 31); 88 | Tone.aOp[2].AR = Get(Buffer, O, (int)ePut.AR2, 31); 89 | Tone.aOp[3].AR = Get(Buffer, O, (int)ePut.AR3, 31); 90 | Tone.aOp[0].DR = Get(Buffer, O, (int)ePut.DR0, 31); 91 | Tone.aOp[1].DR = Get(Buffer, O, (int)ePut.DR1, 31); 92 | Tone.aOp[2].DR = Get(Buffer, O, (int)ePut.DR2, 31); 93 | Tone.aOp[3].DR = Get(Buffer, O, (int)ePut.DR3, 31); 94 | Tone.aOp[0].SR = Get(Buffer, O, (int)ePut.SR0, 31); 95 | Tone.aOp[1].SR = Get(Buffer, O, (int)ePut.SR1, 31); 96 | Tone.aOp[2].SR = Get(Buffer, O, (int)ePut.SR2, 31); 97 | Tone.aOp[3].SR = Get(Buffer, O, (int)ePut.SR3, 31); 98 | Tone.aOp[0].RR = Get(Buffer, O, (int)ePut.RR0, 15); 99 | Tone.aOp[1].RR = Get(Buffer, O, (int)ePut.RR1, 15); 100 | Tone.aOp[2].RR = Get(Buffer, O, (int)ePut.RR2, 15); 101 | Tone.aOp[3].RR = Get(Buffer, O, (int)ePut.RR3, 15); 102 | Tone.aOp[0].SL = Get(Buffer, O, (int)ePut.SL0, 15); 103 | Tone.aOp[1].SL = Get(Buffer, O, (int)ePut.SL1, 15); 104 | Tone.aOp[2].SL = Get(Buffer, O, (int)ePut.SL2, 15); 105 | Tone.aOp[3].SL = Get(Buffer, O, (int)ePut.SL3, 15); 106 | Tone.aOp[0].TL = Get(Buffer, O, (int)ePut.TL0, 127); 107 | Tone.aOp[1].TL = Get(Buffer, O, (int)ePut.TL1, 127); 108 | Tone.aOp[2].TL = Get(Buffer, O, (int)ePut.TL2, 127); 109 | Tone.aOp[3].TL = Get(Buffer, O, (int)ePut.TL3, 127); 110 | Tone.aOp[0].KS = Get(Buffer, O, (int)ePut.KS0, 3); 111 | Tone.aOp[1].KS = Get(Buffer, O, (int)ePut.KS1, 3); 112 | Tone.aOp[2].KS = Get(Buffer, O, (int)ePut.KS2, 3); 113 | Tone.aOp[3].KS = Get(Buffer, O, (int)ePut.KS3, 3); 114 | Tone.aOp[0].ML = Get(Buffer, O, (int)ePut.ML0, 15); 115 | Tone.aOp[1].ML = Get(Buffer, O, (int)ePut.ML1, 15); 116 | Tone.aOp[2].ML = Get(Buffer, O, (int)ePut.ML2, 15); 117 | Tone.aOp[3].ML = Get(Buffer, O, (int)ePut.ML3, 15); 118 | Tone.aOp[0].DT = Get(Buffer, O, (int)ePut.DT1_0, 99); 119 | Tone.aOp[1].DT = Get(Buffer, O, (int)ePut.DT1_1, 99); 120 | Tone.aOp[2].DT = Get(Buffer, O, (int)ePut.DT1_2, 99); 121 | Tone.aOp[3].DT = Get(Buffer, O, (int)ePut.DT1_3, 99); 122 | Tone.aOp[0].DT2 = Get(Buffer, O, (int)ePut.DT2_0, 3); 123 | Tone.aOp[1].DT2 = Get(Buffer, O, (int)ePut.DT2_1, 3); 124 | Tone.aOp[2].DT2 = Get(Buffer, O, (int)ePut.DT2_2, 3); 125 | Tone.aOp[3].DT2 = Get(Buffer, O, (int)ePut.DT2_3, 3); 126 | Tone.AL = Get(Buffer, O, (int)ePut.AL, 7); 127 | Tone.FB = Get(Buffer, O, (int)ePut.FB, 7); 128 | 129 | var aChar = new char[] 130 | { 131 | (char)Buffer[o + (int)eName.Name0], 132 | (char)Buffer[o + (int)eName.Name1], 133 | (char)Buffer[o + (int)eName.Name2], 134 | (char)Buffer[o + (int)eName.Name3], 135 | (char)Buffer[o + (int)eName.Name4], 136 | (char)Buffer[o + (int)eName.Name5], 137 | (char)Buffer[o + (int)eName.Name6], 138 | (char)Buffer[o + (int)eName.Name7], 139 | (char)Buffer[o + (int)eName.Name8], 140 | (char)Buffer[o + (int)eName.Name9], 141 | (char)Buffer[o + (int)eName.Name10], 142 | (char)Buffer[o + (int)eName.Name11], 143 | (char)Buffer[o + (int)eName.Name12], 144 | (char)Buffer[o + (int)eName.Name13], 145 | (char)Buffer[o + (int)eName.Name14], 146 | (char)Buffer[o + (int)eName.Name15], 147 | (char)Buffer[o + (int)eName.Name16], 148 | (char)Buffer[o + (int)eName.Name17], 149 | (char)Buffer[o + (int)eName.Name18], 150 | (char)Buffer[o + (int)eName.Name19], 151 | (char)Buffer[o + (int)eName.Name20], 152 | }; 153 | Tone.Name = ""; 154 | foreach (var Char in aChar) if (Char != 0) Tone.Name += Char.ToString(); 155 | 156 | Tone.Number = i; 157 | } 158 | 159 | 160 | 161 | static void Put(byte[] Buffer, int O, int e, int Max, int v) 162 | { 163 | var aPut = BitConverter.GetBytes((float)v / (float)Max); 164 | Array.Copy(aPut, 0, Buffer, O + (e * sizeof(float)), aPut.Length); 165 | } 166 | 167 | 168 | 169 | public static void Put(Tone @Tone, ref byte[] Buffer) 170 | { 171 | if (Tone.IsValid() && Tone.Number < ToneLength()) 172 | { 173 | int o = HeadLength() + (Tone.Number * PutLength()); 174 | int O = o + NameLength(); 175 | Put(Buffer, O, (int)ePut.AR0, 31, Tone.aOp[0].AR); 176 | Put(Buffer, O, (int)ePut.AR1, 31, Tone.aOp[1].AR); 177 | Put(Buffer, O, (int)ePut.AR2, 31, Tone.aOp[2].AR); 178 | Put(Buffer, O, (int)ePut.AR3, 31, Tone.aOp[3].AR); 179 | Put(Buffer, O, (int)ePut.DR0, 31, Tone.aOp[0].DR); 180 | Put(Buffer, O, (int)ePut.DR1, 31, Tone.aOp[1].DR); 181 | Put(Buffer, O, (int)ePut.DR2, 31, Tone.aOp[2].DR); 182 | Put(Buffer, O, (int)ePut.DR3, 31, Tone.aOp[3].DR); 183 | Put(Buffer, O, (int)ePut.SR0, 31, Tone.aOp[0].SR); 184 | Put(Buffer, O, (int)ePut.SR1, 31, Tone.aOp[1].SR); 185 | Put(Buffer, O, (int)ePut.SR2, 31, Tone.aOp[2].SR); 186 | Put(Buffer, O, (int)ePut.SR3, 31, Tone.aOp[3].SR); 187 | Put(Buffer, O, (int)ePut.RR0, 15, Tone.aOp[0].RR); 188 | Put(Buffer, O, (int)ePut.RR1, 15, Tone.aOp[1].RR); 189 | Put(Buffer, O, (int)ePut.RR2, 15, Tone.aOp[2].RR); 190 | Put(Buffer, O, (int)ePut.RR3, 15, Tone.aOp[3].RR); 191 | Put(Buffer, O, (int)ePut.SL0, 15, Tone.aOp[0].SL); 192 | Put(Buffer, O, (int)ePut.SL1, 15, Tone.aOp[1].SL); 193 | Put(Buffer, O, (int)ePut.SL2, 15, Tone.aOp[2].SL); 194 | Put(Buffer, O, (int)ePut.SL3, 15, Tone.aOp[3].SL); 195 | Put(Buffer, O, (int)ePut.TL0, 127, Tone.aOp[0].TL); 196 | Put(Buffer, O, (int)ePut.TL1, 127, Tone.aOp[1].TL); 197 | Put(Buffer, O, (int)ePut.TL2, 127, Tone.aOp[2].TL); 198 | Put(Buffer, O, (int)ePut.TL3, 127, Tone.aOp[3].TL); 199 | Put(Buffer, O, (int)ePut.KS0, 3, Tone.aOp[0].KS); 200 | Put(Buffer, O, (int)ePut.KS1, 3, Tone.aOp[1].KS); 201 | Put(Buffer, O, (int)ePut.KS2, 3, Tone.aOp[2].KS); 202 | Put(Buffer, O, (int)ePut.KS3, 3, Tone.aOp[3].KS); 203 | Put(Buffer, O, (int)ePut.ML0, 15, Tone.aOp[0].ML); 204 | Put(Buffer, O, (int)ePut.ML1, 15, Tone.aOp[1].ML); 205 | Put(Buffer, O, (int)ePut.ML2, 15, Tone.aOp[2].ML); 206 | Put(Buffer, O, (int)ePut.ML3, 15, Tone.aOp[3].ML); 207 | Put(Buffer, O, (int)ePut.DT1_0, 99, Tone.aOp[0].DT); 208 | Put(Buffer, O, (int)ePut.DT1_1, 99, Tone.aOp[1].DT); 209 | Put(Buffer, O, (int)ePut.DT1_2, 99, Tone.aOp[2].DT); 210 | Put(Buffer, O, (int)ePut.DT1_3, 99, Tone.aOp[3].DT); 211 | Put(Buffer, O, (int)ePut.DT2_0, 3, Tone.aOp[0].DT2); 212 | Put(Buffer, O, (int)ePut.DT2_1, 3, Tone.aOp[1].DT2); 213 | Put(Buffer, O, (int)ePut.DT2_2, 3, Tone.aOp[2].DT2); 214 | Put(Buffer, O, (int)ePut.DT2_3, 3, Tone.aOp[3].DT2); 215 | Put(Buffer, O, (int)ePut.AL, 7, Tone.AL); 216 | Put(Buffer, O, (int)ePut.FB, 7, Tone.FB); 217 | Put(Buffer, O, (int)ePut.MX, 7, 7); 218 | Put(Buffer, O, (int)ePut.OS, 1, 1); 219 | Put(Buffer, O, (int)ePut.PB, 127, 2); 220 | 221 | if (String.IsNullOrWhiteSpace(Tone.Name)) 222 | { 223 | Tone.Name = Tone.Number.ToString(); 224 | } 225 | Buffer[o + (int)eName.Name0] = (byte)((Tone.Name.Length > 0) ? Tone.Name[0] : 0); 226 | Buffer[o + (int)eName.Name1] = (byte)((Tone.Name.Length > 1) ? Tone.Name[1] : 0); 227 | Buffer[o + (int)eName.Name2] = (byte)((Tone.Name.Length > 2) ? Tone.Name[2] : 0); 228 | Buffer[o + (int)eName.Name3] = (byte)((Tone.Name.Length > 3) ? Tone.Name[3] : 0); 229 | Buffer[o + (int)eName.Name4] = (byte)((Tone.Name.Length > 4) ? Tone.Name[4] : 0); 230 | Buffer[o + (int)eName.Name5] = (byte)((Tone.Name.Length > 5) ? Tone.Name[5] : 0); 231 | Buffer[o + (int)eName.Name6] = (byte)((Tone.Name.Length > 6) ? Tone.Name[6] : 0); 232 | Buffer[o + (int)eName.Name7] = (byte)((Tone.Name.Length > 7) ? Tone.Name[7] : 0); 233 | Buffer[o + (int)eName.Name8] = (byte)((Tone.Name.Length > 8) ? Tone.Name[8] : 0); 234 | Buffer[o + (int)eName.Name9] = (byte)((Tone.Name.Length > 9) ? Tone.Name[9] : 0); 235 | Buffer[o + (int)eName.Name10] = (byte)((Tone.Name.Length > 10) ? Tone.Name[10] : 0); 236 | Buffer[o + (int)eName.Name11] = (byte)((Tone.Name.Length > 11) ? Tone.Name[11] : 0); 237 | Buffer[o + (int)eName.Name12] = (byte)((Tone.Name.Length > 12) ? Tone.Name[12] : 0); 238 | Buffer[o + (int)eName.Name13] = (byte)((Tone.Name.Length > 13) ? Tone.Name[13] : 0); 239 | Buffer[o + (int)eName.Name14] = (byte)((Tone.Name.Length > 14) ? Tone.Name[14] : 0); 240 | Buffer[o + (int)eName.Name15] = (byte)((Tone.Name.Length > 15) ? Tone.Name[15] : 0); 241 | Buffer[o + (int)eName.Name16] = (byte)((Tone.Name.Length > 16) ? Tone.Name[16] : 0); 242 | Buffer[o + (int)eName.Name17] = (byte)((Tone.Name.Length > 17) ? Tone.Name[17] : 0); 243 | Buffer[o + (int)eName.Name18] = (byte)((Tone.Name.Length > 18) ? Tone.Name[18] : 0); 244 | Buffer[o + (int)eName.Name19] = (byte)((Tone.Name.Length > 19) ? Tone.Name[19] : 0); 245 | Buffer[o + (int)eName.Name20] = (byte)((Tone.Name.Length > 20) ? Tone.Name[20] : 0); 246 | } 247 | } 248 | 249 | 250 | 251 | public static bool IsValid(byte[] Buffer) 252 | { 253 | return (Buffer[0x00] == (byte)'C' 254 | && Buffer[0x01] == (byte)'c' 255 | && Buffer[0x02] == (byte)'n' 256 | && Buffer[0x03] == (byte)'K' 257 | && Buffer[0x05] == 0x01 258 | && Buffer[0x06] == 0xdb 259 | && Buffer[0x07] == 0x18 260 | && Buffer[0x08] == (byte)'F' 261 | && Buffer[0x09] == (byte)'B' 262 | && Buffer[0x0a] == (byte)'C' 263 | && Buffer[0x0b] == (byte)'h' 264 | && Buffer[0x0f] == 0x01 265 | && Buffer[0x10] == (byte)'J' 266 | && Buffer[0x11] == (byte)'K' 267 | && Buffer[0x12] == (byte)'J' 268 | && Buffer[0x13] == (byte)'M' 269 | && Buffer[0x17] == 0x01 270 | && Buffer[0x1a] == 0x01 271 | && Buffer[0x1b] == 0x24 272 | && Buffer[0x9d] == 0x01 273 | && Buffer[0x9e] == 0xda 274 | && Buffer[0x9f] == 0x80 275 | ); 276 | } 277 | 278 | 279 | 280 | public static void Reader(string Path, Option @Option) 281 | { 282 | var Buffer = ReadByte(Path); 283 | if (Buffer.Length == FxbLength() && IsValid(Buffer)) 284 | { 285 | Tone vTone = new Tone(); 286 | 287 | var BufferMuc = ""; 288 | var BufferDat = Dat.New(); 289 | var BufferFmp = ""; 290 | var BufferPmd = ""; 291 | var BufferVopm = Vopm.New(); 292 | var BufferRme = Rme.New(); 293 | var BufferDx7 = DX7.New(); 294 | var BufferVmm = Vmm.New(); 295 | 296 | for (int i = 0; i < ToneLength(); ++i) 297 | { 298 | Get(ref vTone, Buffer, i); 299 | 300 | if (Option.bMuc) Muc.Put(vTone, ref BufferMuc); 301 | if (Option.bDat) Dat.Put(vTone, ref BufferDat); 302 | if (Option.bFmp) Fmp.Put(vTone, ref BufferFmp); 303 | if (Option.bPmd) Pmd.Put(vTone, ref BufferPmd); 304 | if (Option.bVopm) Vopm.Put(vTone, ref BufferVopm); 305 | if (Option.bRme) Rme.Put(vTone, ref BufferRme); 306 | if (Option.bDx7) DX7.Put(vTone, ref BufferDx7); 307 | if (Option.bVmm) Vmm.Put(vTone, ref BufferVmm); 308 | } 309 | 310 | if (Option.bMuc) Muc.Writer(Path, BufferMuc); 311 | if (Option.bDat) Dat.Writer(Path, BufferDat); 312 | if (Option.bFmp) Fmp.Writer(Path, BufferFmp); 313 | if (Option.bPmd) Pmd.Writer(Path, BufferPmd); 314 | if (Option.bVopm) Vopm.Writer(Path, BufferVopm); 315 | if (Option.bRme) Rme.Writer(Path, BufferRme); 316 | if (Option.bDx7) DX7.Writer(Path, BufferDx7); 317 | if (Option.bVmm) Vmm.Writer(Path, BufferVmm); 318 | } 319 | } 320 | 321 | 322 | 323 | public static void Reader(string[] aPath, Option @Option) 324 | { 325 | foreach (var Path in aPath) 326 | { 327 | if (!String.IsNullOrWhiteSpace(Path) && Extension(Path).ToLower() == ".fxb") Reader(Path, Option); 328 | } 329 | } 330 | 331 | 332 | 333 | public static void Writer(string Path, byte[] Buffer) 334 | { 335 | Buffer[0x00] = (byte)'C'; 336 | Buffer[0x01] = (byte)'c'; 337 | Buffer[0x02] = (byte)'n'; 338 | Buffer[0x03] = (byte)'K'; 339 | Buffer[0x05] = 0x01; 340 | Buffer[0x06] = 0xdb; 341 | Buffer[0x07] = 0x18; 342 | Buffer[0x08] = (byte)'F'; 343 | Buffer[0x09] = (byte)'B'; 344 | Buffer[0x0a] = (byte)'C'; 345 | Buffer[0x0b] = (byte)'h'; 346 | Buffer[0x0f] = 0x01; 347 | Buffer[0x10] = (byte)'J'; 348 | Buffer[0x11] = (byte)'K'; 349 | Buffer[0x12] = (byte)'J'; 350 | Buffer[0x13] = (byte)'M'; 351 | Buffer[0x17] = 0x01; 352 | Buffer[0x1a] = 0x01; 353 | Buffer[0x1b] = 0x24; 354 | Buffer[0x9d] = 0x01; 355 | Buffer[0x9e] = 0xda; 356 | Buffer[0x9f] = 0x80; 357 | 358 | WriteByte(ChangeExtension(Path, ".fxb"), Buffer); 359 | } 360 | } 361 | } 362 | -------------------------------------------------------------------------------- /FM-SoundConvertor/File.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | using System; 5 | using System.Linq; 6 | using System.Collections.Generic; 7 | 8 | using static FM_SoundConvertor.Path; 9 | 10 | 11 | 12 | namespace FM_SoundConvertor { 13 | public class File { 14 | public static string[] Enum(string Path){ 15 | Path = UnCloak(Path); 16 | if (System.IO.Directory.Exists(Path)){ 17 | return System.IO.Directory.EnumerateFiles(Path) 18 | .Select(Entry => Entry.Replace('\\','/')) 19 | .Where(Entry => (Entry.IndexOf("/.") == -1)) 20 | .OrderBy(Entry => Entry) 21 | .ToArray(); 22 | } 23 | return System.Array.Empty(); 24 | } 25 | 26 | 27 | 28 | public static string[] Enum(string[] aPath){ 29 | var aEnum = new List(); 30 | Array.ForEach(aPath, Path => aEnum.AddRange(Enum(Path))); 31 | return aEnum.ToArray(); 32 | } 33 | 34 | 35 | 36 | public static bool Exist(string Path){ 37 | Path = UnCloak(Path); 38 | return System.IO.File.Exists(Path); 39 | } 40 | 41 | 42 | 43 | public static void Delete(string Path){ 44 | try { 45 | Path = UnCloak(Path); 46 | System.IO.File.Delete(Path); 47 | } 48 | catch (System.IO.DirectoryNotFoundException){} 49 | } 50 | 51 | 52 | 53 | public static System.DateTime Date(string Path){ 54 | Path = UnCloak(Path); 55 | if (Exist(Path)) return System.IO.File.GetLastWriteTime(Path); 56 | return new System.DateTime(0); 57 | } 58 | 59 | 60 | 61 | public static System.DateTime Newer(IEnumerable aPath){ 62 | var aDate = aPath.Select(Path => Date(Path)); 63 | return new System.DateTime(aDate.Max().Ticks); 64 | } 65 | 66 | 67 | 68 | public static string[] ReadLine(string Path){ 69 | Path = UnCloak(Path); 70 | if (Exist(Path)) return System.IO.File.ReadAllLines(Path, System.Text.Encoding.ASCII); 71 | return System.Array.Empty(); 72 | } 73 | 74 | 75 | 76 | public static string ReadText(string Path){ 77 | Path = UnCloak(Path); 78 | if (Exist(Path)) return System.IO.File.ReadAllText(Path, System.Text.Encoding.ASCII); 79 | return System.String.Empty; 80 | } 81 | 82 | 83 | 84 | public static byte[] ReadByte(string Path){ 85 | Path = UnCloak(Path); 86 | if (Exist(Path)) return System.IO.File.ReadAllBytes(Path); 87 | return System.Array.Empty(); 88 | } 89 | 90 | 91 | 92 | public static void WriteLine(string Path, string[] aLine){ 93 | Path = UnCloak(Path); 94 | System.IO.File.WriteAllLines(Path, aLine, System.Text.Encoding.ASCII); 95 | } 96 | 97 | 98 | 99 | public static void WriteText(string Path, string Text){ 100 | Path = UnCloak(Path); 101 | System.IO.File.WriteAllText(Path, Text, System.Text.Encoding.ASCII); 102 | } 103 | 104 | 105 | 106 | public static void WriteByte(string Path, byte[] aByte){ 107 | Path = UnCloak(Path); 108 | System.IO.File.WriteAllBytes(Path, aByte); 109 | } 110 | 111 | 112 | 113 | public static long Size(string Path){ 114 | Path = UnCloak(Path); 115 | if (Exist(Path)) return (new System.IO.FileInfo(Path)).Length; 116 | return 0; 117 | } 118 | 119 | 120 | 121 | public static void Touch(string Path){ 122 | Path = UnCloak(Path); 123 | System.IO.File.OpenWrite(Path).Close(); 124 | System.IO.File.SetLastWriteTime(Path, System.DateTime.Now); 125 | } 126 | 127 | 128 | 129 | public static void Copy(string Src, string Dst){ 130 | Src = UnCloak(Src); 131 | Dst = UnCloak(Dst); 132 | if (Exist(Src)) System.IO.File.Copy(Src, Dst, true); 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /FM-SoundConvertor/Fmp.cs: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | using System; 5 | 6 | using static FM_SoundConvertor.Path; 7 | using static FM_SoundConvertor.File; 8 | using static FM_SoundConvertor.Console; 9 | 10 | 11 | 12 | namespace FM_SoundConvertor 13 | { 14 | class Fmp 15 | { 16 | enum eState 17 | { 18 | Entry, 19 | Op0, 20 | Op1, 21 | Op2, 22 | Op3, 23 | Header, 24 | } 25 | 26 | 27 | 28 | static void GetOp(string[] aTok, ref Op @Op, int nTok) 29 | { 30 | int.TryParse(aTok[0], out Op.AR); 31 | int.TryParse(aTok[1], out Op.DR); 32 | int.TryParse(aTok[2], out Op.SR); 33 | int.TryParse(aTok[3], out Op.RR); 34 | int.TryParse(aTok[4], out Op.SL); 35 | int.TryParse(aTok[5], out Op.TL); 36 | int.TryParse(aTok[6], out Op.KS); 37 | int.TryParse(aTok[7], out Op.ML); 38 | int.TryParse(aTok[8], out Op.DT); 39 | 40 | switch (nTok) 41 | { 42 | case 9: 43 | { 44 | Op.DT2 = 0; 45 | Op.AM = 0; 46 | break; 47 | } 48 | case 10: 49 | { 50 | Op.DT2 = 0; 51 | int.TryParse(aTok[9], out Op.AM); 52 | break; 53 | } 54 | case 11: 55 | { 56 | int.TryParse(aTok[9], out Op.DT2); 57 | int.TryParse(aTok[10], out Op.AM); 58 | break; 59 | } 60 | } 61 | } 62 | 63 | 64 | 65 | static string Put(int Value) 66 | { 67 | return String.Format("{0,3},", Value); 68 | } 69 | 70 | static string Put(Op @Op) 71 | { 72 | return Put(Op.AR) + Put(Op.DR) + Put(Op.SR) + Put(Op.RR) + Put(Op.SL) + Put(Op.TL) + Put(Op.KS) + Put(Op.ML) + Put(Op.DT) + Put(Op.AM).TrimEnd(','); 73 | } 74 | 75 | public static void Put(Tone @Tone, ref string Buffer) 76 | { 77 | if (Tone.IsValid()) 78 | { 79 | var Name = String.Format("({0})", Tone.Name) + "\n"; 80 | var Header = "'@ " + String.Format("FA {0}", Tone.Number) + "\n"; 81 | var Op0 = "'@ " + Put(Tone.aOp[0]) + "\n"; 82 | var Op1 = "'@ " + Put(Tone.aOp[1]) + "\n"; 83 | var Op2 = "'@ " + Put(Tone.aOp[2]) + "\n"; 84 | var Op3 = "'@ " + Put(Tone.aOp[3]) + "\n"; 85 | var Footer = "'@ " + Put(Tone.AL) + Put(Tone.FB).TrimEnd(',') + "\n"; 86 | Buffer += Name + Header + Op0 + Op1 + Op2 + Op3 + Footer + "\n"; 87 | } 88 | } 89 | 90 | 91 | 92 | public static void Reader(string Path, Option @Option) 93 | { 94 | var vTone = new Tone(); 95 | int nTok = 0; 96 | 97 | var BufferMuc = ""; 98 | var BufferDat = Dat.New(); 99 | var BufferPmd = ""; 100 | var BufferVopm = Vopm.New(); 101 | var BufferFMtrial = FMtrial.New(); 102 | var BufferRme = Rme.New(); 103 | var BufferDx7 = DX7.New(); 104 | var BufferVmm = Vmm.New(); 105 | 106 | var State = eState.Entry; 107 | var aLine = ReadLine(Path); 108 | foreach (var Line in aLine) 109 | { 110 | if (String.IsNullOrWhiteSpace(Line)) continue; 111 | if (Line[0] != '\'') continue; 112 | 113 | var bPartCommnet = false; 114 | var aChar = Line.ToCharArray(); 115 | var oChar = 0; 116 | foreach (var Char in aChar) 117 | { 118 | var bPart = (Char == ';'); 119 | if (bPartCommnet) aChar[oChar] = ' '; 120 | if (bPart) bPartCommnet = !bPartCommnet; 121 | if (bPartCommnet) aChar[oChar] = ' '; 122 | ++oChar; 123 | } 124 | var Text = new string(aChar); 125 | if (String.IsNullOrEmpty(Text.Trim(' '))) continue; 126 | 127 | switch (State) 128 | { 129 | case eState.Entry: 130 | { 131 | var bHead = Text.StartsWith("'@"); 132 | if (bHead) 133 | { 134 | nTok = 9; 135 | var oSub = 0; 136 | Text = Text.Substring(2).Trim(); 137 | if (Text.StartsWith("F")) { nTok = 9; oSub = 1; } 138 | if (Text.StartsWith("FA")) { nTok = 10; oSub = 2; } 139 | if (Text.StartsWith("FC")) { nTok = 11; oSub = 2; } 140 | Text = Text.Substring(oSub); 141 | 142 | var aTok = Text.Split(new char[] { ' ', '\t', }, StringSplitOptions.RemoveEmptyEntries); 143 | if (aTok.Length >= 1) 144 | { 145 | int.TryParse(aTok[0], out vTone.Number); 146 | State = eState.Op0; 147 | break; 148 | } 149 | } 150 | break; 151 | } 152 | case eState.Op0: 153 | { 154 | var bHead = Text.StartsWith("'@"); 155 | if (bHead) 156 | { 157 | Text = Text.Substring(2); 158 | var aTok = Text.Split(new char[] { ' ', '\t', ',' }, StringSplitOptions.RemoveEmptyEntries); 159 | if (aTok.Length >= nTok) 160 | { 161 | GetOp(aTok, ref vTone.aOp[0], nTok); 162 | State = eState.Op1; 163 | break; 164 | } 165 | } 166 | State = eState.Entry; 167 | break; 168 | } 169 | case eState.Op1: 170 | { 171 | var bHead = Text.StartsWith("'@"); 172 | if (bHead) 173 | { 174 | Text = Text.Substring(2); 175 | var aTok = Text.Split(new char[] { ' ', '\t', ',' }, StringSplitOptions.RemoveEmptyEntries); 176 | if (aTok.Length >= nTok) 177 | { 178 | GetOp(aTok, ref vTone.aOp[1], nTok); 179 | State = eState.Op2; 180 | break; 181 | } 182 | } 183 | State = eState.Entry; 184 | break; 185 | } 186 | case eState.Op2: 187 | { 188 | var bHead = Text.StartsWith("'@"); 189 | if (bHead) 190 | { 191 | Text = Text.Substring(2); 192 | var aTok = Text.Split(new char[] { ' ', '\t', ',' }, StringSplitOptions.RemoveEmptyEntries); 193 | if (aTok.Length >= nTok) 194 | { 195 | GetOp(aTok, ref vTone.aOp[2], nTok); 196 | State = eState.Op3; 197 | break; 198 | } 199 | } 200 | State = eState.Entry; 201 | break; 202 | } 203 | case eState.Op3: 204 | { 205 | var bHead = Text.StartsWith("'@"); 206 | if (bHead) 207 | { 208 | Text = Text.Substring(2); 209 | var aTok = Text.Split(new char[] { ' ', '\t', ',' }, StringSplitOptions.RemoveEmptyEntries); 210 | if (aTok.Length >= nTok) 211 | { 212 | GetOp(aTok, ref vTone.aOp[3], nTok); 213 | State = eState.Header; 214 | break; 215 | } 216 | } 217 | State = eState.Entry; 218 | break; 219 | } 220 | case eState.Header: 221 | { 222 | var bHead = Text.StartsWith("'@"); 223 | if (bHead) 224 | { 225 | Text = Text.Substring(2); 226 | var aTok = Text.Split(new char[] { ' ', '\t', ',' }, StringSplitOptions.RemoveEmptyEntries); 227 | if (aTok.Length >= 2) 228 | { 229 | int.TryParse(aTok[0], out vTone.AL); 230 | int.TryParse(aTok[1], out vTone.FB); 231 | vTone.Name = ""; 232 | 233 | if (Option.bMuc) Muc.Put(vTone, ref BufferMuc); 234 | if (Option.bDat) Dat.Put(vTone, ref BufferDat); 235 | if (Option.bPmd) Pmd.Put(vTone, ref BufferPmd); 236 | if (Option.bVopm) Vopm.Put(vTone, ref BufferVopm); 237 | if (Option.bFMtrial) FMtrial.Put(vTone, ref BufferFMtrial); 238 | if (Option.bRme) Rme.Put(vTone, ref BufferRme); 239 | if (Option.bDx7) DX7.Put(vTone, ref BufferDx7); 240 | if (Option.bVmm) Vmm.Put(vTone, ref BufferVmm); 241 | } 242 | } 243 | State = eState.Entry; 244 | break; 245 | } 246 | } 247 | } 248 | 249 | if (Option.bMuc) Muc.Writer(Path, BufferMuc); 250 | if (Option.bDat) Dat.Writer(Path, BufferDat); 251 | if (Option.bPmd) Pmd.Writer(Path, BufferPmd); 252 | if (Option.bVopm) Vopm.Writer(Path, BufferVopm); 253 | if (Option.bFMtrial) FMtrial.Writer(Path, BufferFMtrial); 254 | if (Option.bRme) Rme.Writer(Path, BufferRme); 255 | if (Option.bDx7) DX7.Writer(Path, BufferDx7); 256 | if (Option.bVmm) Vmm.Writer(Path, BufferVmm); 257 | } 258 | 259 | 260 | 261 | public static void Reader(string[] aPath, Option @Option) 262 | { 263 | foreach (var Path in aPath) 264 | { 265 | if (!String.IsNullOrWhiteSpace(Path) && Extension(Path).ToLower() == ".mwi") Reader(Path, Option); 266 | } 267 | } 268 | 269 | 270 | 271 | public static void Writer(string Path, string Buffer) 272 | { 273 | WriteText(ChangeExtension(Path, ".mwi"), Buffer); 274 | } 275 | } 276 | } 277 | 278 | -------------------------------------------------------------------------------- /FM-SoundConvertor/Main.cs: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | using System; 5 | 6 | 7 | 8 | namespace FM_SoundConvertor 9 | { 10 | class Program 11 | { 12 | static int Main(string[] aArg) 13 | { 14 | var Option = new Option(); 15 | 16 | int oArg = 0; 17 | foreach (var Arg in aArg) 18 | { 19 | if (Arg[0] == '-') 20 | { 21 | switch (Arg) 22 | { 23 | case "-muc": 24 | { 25 | Option.bMuc = true; 26 | break; 27 | } 28 | case "-dat": 29 | { 30 | Option.bDat = true; 31 | break; 32 | } 33 | case "-fmp": 34 | { 35 | Option.bFmp = true; 36 | break; 37 | } 38 | case "-pmd": 39 | { 40 | Option.bPmd = true; 41 | break; 42 | } 43 | case "-vopm": 44 | { 45 | Option.bVopm = true; 46 | break; 47 | } 48 | case "-fmtrial": 49 | { 50 | Option.bFMtrial = true; 51 | break; 52 | } 53 | case "-rme": 54 | { 55 | Option.bRme = true; 56 | break; 57 | } 58 | case "-dx7": 59 | { 60 | Option.bDx7 = true; 61 | break; 62 | } 63 | case "-vmm": 64 | { 65 | Option.bVmm = true; 66 | break; 67 | } 68 | } 69 | aArg[oArg] = String.Empty; 70 | } 71 | ++oArg; 72 | } 73 | 74 | Muc.Reader(aArg, Option); 75 | Dat.Reader(aArg, Option); 76 | Fmp.Reader(aArg, Option); 77 | Pmd.Reader(aArg, Option); 78 | Vopm.Reader(aArg, Option); 79 | FMtrial.Reader(aArg, Option); 80 | Rme.Reader(aArg, Option); 81 | DX7.Reader(aArg, Option); 82 | Vmm.Reader(aArg, Option); 83 | return 0; 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /FM-SoundConvertor/Muc.cs: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | using System; 5 | 6 | using static FM_SoundConvertor.Path; 7 | using static FM_SoundConvertor.File; 8 | using static FM_SoundConvertor.Console; 9 | 10 | 11 | 12 | namespace FM_SoundConvertor 13 | { 14 | class Muc 15 | { 16 | enum eState 17 | { 18 | Entry, 19 | Header, 20 | Op0, 21 | Op1, 22 | Op2, 23 | Op3, 24 | } 25 | 26 | enum eType 27 | { 28 | Mucom, 29 | Mmldrv, 30 | } 31 | 32 | 33 | 34 | static void GetOp(string[] aTok, ref Op @Op, eType Type) 35 | { 36 | switch (Type) 37 | { 38 | case eType.Mucom: 39 | { 40 | int.TryParse(aTok[0], out Op.AR); 41 | int.TryParse(aTok[1], out Op.DR); 42 | int.TryParse(aTok[2], out Op.SR); 43 | int.TryParse(aTok[3], out Op.RR); 44 | int.TryParse(aTok[4], out Op.SL); 45 | int.TryParse(aTok[5], out Op.TL); 46 | int.TryParse(aTok[6], out Op.KS); 47 | int.TryParse(aTok[7], out Op.ML); 48 | int.TryParse(aTok[8], out Op.DT); 49 | Op.DT2 = 0; 50 | Op.AM = 0; 51 | break; 52 | } 53 | case eType.Mmldrv: 54 | { 55 | int.TryParse(aTok[0], out Op.AR); 56 | int.TryParse(aTok[1], out Op.DR); 57 | int.TryParse(aTok[2], out Op.SR); 58 | int.TryParse(aTok[3], out Op.RR); 59 | int.TryParse(aTok[4], out Op.SL); 60 | int.TryParse(aTok[5], out Op.TL); 61 | int.TryParse(aTok[6], out Op.KS); 62 | int.TryParse(aTok[7], out Op.ML); 63 | int.TryParse(aTok[8], out Op.DT); 64 | int.TryParse(aTok[9], out Op.DT2); 65 | int.TryParse(aTok[10], out Op.AM); 66 | break; 67 | } 68 | } 69 | } 70 | 71 | 72 | 73 | static string Put(int Value) 74 | { 75 | return String.Format("{0,3},", Value); 76 | } 77 | 78 | static string Put(Op @Op) 79 | { 80 | return Put(Op.AR) + Put(Op.DR) + Put(Op.SR) + Put(Op.RR) + Put(Op.SL) + Put(Op.TL) + Put(Op.KS) + Put(Op.ML) + Put(Op.DT).TrimEnd(','); 81 | } 82 | 83 | public static void Put(Tone @Tone, ref string Buffer) 84 | { 85 | if (Tone.IsValid()) 86 | { 87 | var Entry = " " + String.Format("@{0}:{{", Tone.Number) + "\n"; 88 | var Header = " " + Put(Tone.FB) + Put(Tone.AL).TrimEnd(',') + "\n"; 89 | var Op0 = " " + Put(Tone.aOp[0]) + "\n"; 90 | var Op1 = " " + Put(Tone.aOp[1]) + "\n"; 91 | var Op2 = " " + Put(Tone.aOp[2]) + "\n"; 92 | var Op3 = " " + Put(Tone.aOp[3]) + String.Format(",\"{0}\"}}", Tone.Name) + "\n"; 93 | Buffer += Entry + Header + Op0 + Op1 + Op2 + Op3 + "\n"; 94 | } 95 | } 96 | 97 | 98 | 99 | static void Reader(string Path, Option @Option) 100 | { 101 | var vTone = new Tone(); 102 | var Type = eType.Mucom; 103 | var nTok = 0; 104 | 105 | var BufferDat = Dat.New(); 106 | var BufferFmp = ""; 107 | var BufferPmd = ""; 108 | var BufferVopm = Vopm.New(); 109 | var BufferFMtrial = FMtrial.New(); 110 | var BufferRme = Rme.New(); 111 | var BufferDx7 = DX7.New(); 112 | var BufferVmm = Vmm.New(); 113 | 114 | var State = eState.Entry; 115 | var aLine = ReadLine(Path); 116 | foreach (var Line in aLine) 117 | { 118 | if (String.IsNullOrWhiteSpace(Line)) continue; 119 | if (Line[0] == '\'') continue; 120 | 121 | var oMark = Line.IndexOf(';'); 122 | var Text = (oMark >= 0)? Line.Remove(oMark): Line; 123 | if (String.IsNullOrEmpty(Text.Trim(' '))) continue; 124 | 125 | switch (State) 126 | { 127 | case eState.Entry: 128 | { 129 | var bMucom = Text.StartsWith(" @"); 130 | var bMmldrv = Text.StartsWith("@"); 131 | 132 | Text = Text.Trim(); 133 | if (bMucom || bMmldrv) 134 | { 135 | vTone.Number++; 136 | 137 | Type = (bMucom) ? eType.Mucom : eType.Mmldrv; 138 | nTok = (bMucom) ? 9 : 11; 139 | 140 | var aTok = Text.Split(new char[] { ' ', '\t', '@', ':', '{', }, StringSplitOptions.RemoveEmptyEntries); 141 | if (aTok.Length >= 1) 142 | { 143 | int Number; 144 | if (int.TryParse(aTok[0], out Number)) vTone.Number = Number; 145 | } 146 | State = eState.Header; 147 | break; 148 | } 149 | break; 150 | } 151 | case eState.Header: 152 | { 153 | var aTok = Text.Split(new char[] { ' ', '\t', ',', }, StringSplitOptions.RemoveEmptyEntries); 154 | if (aTok.Length >= 2) 155 | { 156 | switch (Type) 157 | { 158 | case eType.Mucom: 159 | { 160 | int.TryParse(aTok[0], out vTone.FB); 161 | int.TryParse(aTok[1], out vTone.AL); 162 | break; 163 | } 164 | case eType.Mmldrv: 165 | { 166 | int.TryParse(aTok[0], out vTone.AL); 167 | int.TryParse(aTok[1], out vTone.FB); 168 | break; 169 | } 170 | } 171 | State = eState.Op0; 172 | break; 173 | } 174 | State = eState.Entry; 175 | break; 176 | } 177 | case eState.Op0: 178 | { 179 | var aTok = Text.Split(new char[] { ' ', '\t', ',', }, StringSplitOptions.RemoveEmptyEntries); 180 | if (aTok.Length >= nTok) 181 | { 182 | GetOp(aTok, ref vTone.aOp[0], Type); 183 | State = eState.Op1; 184 | break; 185 | } 186 | State = eState.Entry; 187 | break; 188 | } 189 | case eState.Op1: 190 | { 191 | var aTok = Text.Split(new char[] { ' ', '\t', ',', }, StringSplitOptions.RemoveEmptyEntries); 192 | if (aTok.Length >= nTok) 193 | { 194 | GetOp(aTok, ref vTone.aOp[1], Type); 195 | State = eState.Op2; 196 | break; 197 | } 198 | State = eState.Entry; 199 | break; 200 | } 201 | case eState.Op2: 202 | { 203 | var aTok = Text.Split(new char[] { ' ', '\t', ',', }, StringSplitOptions.RemoveEmptyEntries); 204 | if (aTok.Length >= nTok) 205 | { 206 | GetOp(aTok, ref vTone.aOp[2], Type); 207 | State = eState.Op3; 208 | break; 209 | } 210 | State = eState.Entry; 211 | break; 212 | } 213 | case eState.Op3: 214 | { 215 | var aTok = Text.Split(new char[] { ' ', '\t', ',', }, StringSplitOptions.RemoveEmptyEntries); 216 | switch (Type) 217 | { 218 | case eType.Mucom: 219 | { 220 | if (aTok.Length >= nTok) 221 | { 222 | GetOp(aTok, ref vTone.aOp[3], Type); 223 | 224 | if (aTok.Length >= (nTok+1)) 225 | { 226 | var Tok = ""; 227 | for (int o = nTok; o < aTok.Length; ++o) Tok += aTok[o]; 228 | 229 | var oHead = Tok.IndexOf('\"'); 230 | var oTail = Tok.IndexOf('\"', oHead+1); 231 | var bTerm = Tok.EndsWith("}"); 232 | if (oHead >= 0 && oTail >= 0 && bTerm) 233 | { 234 | vTone.Name = Tok.Substring(oHead+1, oTail-oHead-1); 235 | } 236 | } 237 | 238 | if (Option.bDat) Dat.Put(vTone, ref BufferDat); 239 | if (Option.bFmp) Fmp.Put(vTone, ref BufferFmp); 240 | if (Option.bPmd) Pmd.Put(vTone, ref BufferPmd); 241 | if (Option.bVopm) Vopm.Put(vTone, ref BufferVopm); 242 | if (Option.bFMtrial) FMtrial.Put(vTone, ref BufferFMtrial); 243 | if (Option.bRme) Rme.Put(vTone, ref BufferRme); 244 | if (Option.bDx7) DX7.Put(vTone, ref BufferDx7); 245 | if (Option.bVmm) Vmm.Put(vTone, ref BufferVmm); 246 | } 247 | break; 248 | } 249 | case eType.Mmldrv: 250 | { 251 | if (aTok.Length >= nTok) 252 | { 253 | GetOp(aTok, ref vTone.aOp[3], Type); 254 | 255 | vTone.Name = ""; 256 | 257 | if (Option.bDat) Dat.Put(vTone, ref BufferDat); 258 | if (Option.bFmp) Fmp.Put(vTone, ref BufferFmp); 259 | if (Option.bPmd) Pmd.Put(vTone, ref BufferPmd); 260 | if (Option.bVopm) Vopm.Put(vTone, ref BufferVopm); 261 | if (Option.bFMtrial) FMtrial.Put(vTone, ref BufferFMtrial); 262 | if (Option.bRme) Rme.Put(vTone, ref BufferRme); 263 | if (Option.bDx7) DX7.Put(vTone, ref BufferDx7); 264 | if (Option.bVmm) Vmm.Put(vTone, ref BufferVmm); 265 | } 266 | break; 267 | } 268 | } 269 | State = eState.Entry; 270 | break; 271 | } 272 | } 273 | } 274 | 275 | if (Option.bDat) Dat.Writer(Path, BufferDat); 276 | if (Option.bFmp) Fmp.Writer(Path, BufferFmp); 277 | if (Option.bPmd) Pmd.Writer(Path, BufferPmd); 278 | if (Option.bVopm) Vopm.Writer(Path, BufferVopm); 279 | if (Option.bFMtrial) FMtrial.Writer(Path, BufferFMtrial); 280 | if (Option.bRme) Rme.Writer(Path, BufferRme); 281 | if (Option.bDx7) DX7.Writer(Path, BufferDx7); 282 | if (Option.bVmm) Vmm.Writer(Path, BufferVmm); 283 | } 284 | 285 | 286 | 287 | public static void Reader(string[] aPath, Option @Option) 288 | { 289 | foreach (var Path in aPath) 290 | { 291 | if (!String.IsNullOrWhiteSpace(Path) && Extension(Path).ToLower() == ".muc") Reader(Path, Option); 292 | } 293 | } 294 | 295 | 296 | 297 | public static void Writer(string Path, string Buffer) 298 | { 299 | WriteText(ChangeExtension(Path, ".muc"), Buffer); 300 | } 301 | } 302 | } 303 | -------------------------------------------------------------------------------- /FM-SoundConvertor/Option.cs: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | namespace FM_SoundConvertor 5 | { 6 | class Option 7 | { 8 | public bool bMuc; 9 | public bool bDat; 10 | public bool bPmd; 11 | public bool bFmp; 12 | public bool bVopm; 13 | public bool bFMtrial; 14 | public bool bRme; 15 | public bool bDx7; 16 | public bool bVmm; 17 | 18 | 19 | 20 | public Option() 21 | { 22 | bMuc = false; 23 | bDat = false; 24 | bPmd = false; 25 | bFmp = false; 26 | bVopm = false; 27 | bFMtrial = false; 28 | bRme = false; 29 | bDx7 = false; 30 | bVmm = false; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /FM-SoundConvertor/Path.cs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | using System; 5 | using System.Linq; 6 | using System.Collections.Generic; 7 | 8 | 9 | 10 | namespace FM_SoundConvertor { 11 | public class Path { 12 | public static string[] Full(string[] aPath){ 13 | return aPath.Select(Path => Full(Path)).ToArray(); 14 | } 15 | 16 | 17 | 18 | public static string Full(string Path){ 19 | return System.IO.Path.GetFullPath(Path).Replace('\\','/'); 20 | } 21 | 22 | 23 | 24 | public static string Directory(string Path){ 25 | return System.IO.Path.GetDirectoryName(Path).Replace('\\','/'); 26 | } 27 | 28 | 29 | 30 | public static string Base(string Path){ 31 | return System.IO.Path.GetFileNameWithoutExtension(Path); 32 | } 33 | 34 | 35 | 36 | public static string Name(string Path){ 37 | return System.IO.Path.GetFileName(Path); 38 | } 39 | 40 | 41 | 42 | public static string Extension(string Path){ 43 | return System.IO.Path.GetExtension(Path); 44 | } 45 | 46 | 47 | 48 | public static string TrimStart(string Path){ 49 | return Path.TrimStart(':','\\','/'); 50 | } 51 | 52 | 53 | 54 | public static string TrimEnd(string Path){ 55 | return Path.TrimEnd(':','\\','/'); 56 | } 57 | 58 | 59 | 60 | public static string Trim(string Path){ 61 | return TrimStart(TrimEnd(Path)); 62 | } 63 | 64 | 65 | 66 | public static string Combine(string Base, string Path){ 67 | return Full(System.IO.Path.Combine(Base, TrimStart(Path))); 68 | } 69 | 70 | 71 | 72 | public static string Combine(string Base, string Path, string Extension){ 73 | return string.Concat(Combine(Base, Path), Extension); 74 | } 75 | 76 | 77 | 78 | public static string ChangeDirectory(string From, string To, string Path){ 79 | return Combine(To, Path.Substring(From.Length)); 80 | } 81 | 82 | 83 | 84 | public static string ChangeExtension(string Path, string Extension){ 85 | return Combine(Directory(Path), Base(Path), Extension); 86 | } 87 | 88 | 89 | 90 | public static string Cloak(string Path){ 91 | return "\"" + Trim(Path) + "\""; 92 | } 93 | 94 | 95 | 96 | public static string UnCloak(string Path){ 97 | return Path.Trim('\"'); 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /FM-SoundConvertor/Pmd.cs: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | using System; 5 | 6 | using static FM_SoundConvertor.Path; 7 | using static FM_SoundConvertor.File; 8 | using static FM_SoundConvertor.Console; 9 | 10 | 11 | 12 | namespace FM_SoundConvertor 13 | { 14 | class Pmd 15 | { 16 | enum eState 17 | { 18 | Entry, 19 | Op0, 20 | Op1, 21 | Op2, 22 | Op3, 23 | } 24 | 25 | 26 | 27 | static void GetOp(string[] aTok, ref Op @Op) 28 | { 29 | int.TryParse(aTok[0], out Op.AR); 30 | int.TryParse(aTok[1], out Op.DR); 31 | int.TryParse(aTok[2], out Op.SR); 32 | int.TryParse(aTok[3], out Op.RR); 33 | int.TryParse(aTok[4], out Op.SL); 34 | int.TryParse(aTok[5], out Op.TL); 35 | int.TryParse(aTok[6], out Op.KS); 36 | int.TryParse(aTok[7], out Op.ML); 37 | int.TryParse(aTok[8], out Op.DT); 38 | Op.DT2 = 0; 39 | int.TryParse(aTok[9], out Op.AM); 40 | } 41 | 42 | 43 | 44 | static string Put(int Value) 45 | { 46 | return String.Format("{0,4}", Value); 47 | } 48 | 49 | static string Put(Op @Op) 50 | { 51 | return Put(Op.AR) + Put(Op.DR) + Put(Op.SR) + Put(Op.RR) + Put(Op.SL) + Put(Op.TL) + Put(Op.KS) + Put(Op.ML) + Put(Op.DT) + Put(Op.AM); 52 | } 53 | 54 | public static void Put(Tone @Tone, ref string Buffer) 55 | { 56 | if (Tone.IsValid()) 57 | { 58 | var Header = String.Format("@{0}", Tone.Number) + Put(Tone.AL) + Put(Tone.FB) + String.Format(" = {0}", Tone.Name) + "\n"; 59 | var Op0 = Put(Tone.aOp[0]) + "\n"; 60 | var Op1 = Put(Tone.aOp[1]) + "\n"; 61 | var Op2 = Put(Tone.aOp[2]) + "\n"; 62 | var Op3 = Put(Tone.aOp[3]) + "\n"; 63 | Buffer += Header + Op0 + Op1 + Op2 + Op3 + "\n"; 64 | } 65 | } 66 | 67 | 68 | 69 | public static void Reader(string Path, Option @Option) 70 | { 71 | var vTone = new Tone(); 72 | bool bLineComment = false; 73 | 74 | var BufferMuc = ""; 75 | var BufferDat = Dat.New(); 76 | var BufferFmp = ""; 77 | var BufferVopm = Vopm.New(); 78 | var BufferFMtrial = FMtrial.New(); 79 | var BufferRme = Rme.New(); 80 | var BufferDx7 = DX7.New(); 81 | var BufferVmm = Vmm.New(); 82 | 83 | var State = eState.Entry; 84 | var aLine = ReadLine(Path); 85 | foreach (var Line in aLine) 86 | { 87 | if (String.IsNullOrWhiteSpace(Line)) continue; 88 | 89 | var bLine = (Line[0] == '`'); 90 | if (bLine) 91 | { 92 | bLineComment = !bLineComment; 93 | continue; 94 | } 95 | if (bLineComment) continue; 96 | 97 | var bPartCommnet = false; 98 | var bTailCommnet = false; 99 | var aChar = Line.ToCharArray(); 100 | var oChar = 0; 101 | foreach (var Char in aChar) 102 | { 103 | if (bTailCommnet) aChar[oChar] = ' '; 104 | 105 | var bPart = (Char == '`'); 106 | if (bPartCommnet) aChar[oChar] = ' '; 107 | if (bPart) bPartCommnet = !bPartCommnet; 108 | if (bPartCommnet) aChar[oChar] = ' '; 109 | 110 | if (Char == ';') bTailCommnet = true; 111 | if (bTailCommnet) aChar[oChar] = ' '; 112 | ++oChar; 113 | } 114 | var Text = new string(aChar); 115 | if (String.IsNullOrEmpty(Text.Trim(' '))) continue; 116 | 117 | switch (State) 118 | { 119 | case eState.Entry: 120 | { 121 | if (Text[0] == ' ' || Text[0] == '\t') continue; 122 | 123 | var bHead = Text.StartsWith("@"); 124 | var oName = Text.IndexOf('='); 125 | if (bHead) 126 | { 127 | var aTok = Text.Split(new char[] { ' ', '\t', '=', }, StringSplitOptions.RemoveEmptyEntries); 128 | if (aTok.Length >= 3) 129 | { 130 | aTok[0] = aTok[0].Substring(1); 131 | 132 | int.TryParse(aTok[0], out vTone.Number); 133 | int.TryParse(aTok[1], out vTone.AL); 134 | int.TryParse(aTok[2], out vTone.FB); 135 | vTone.Name = (aTok.Length >= 4 && oName > 0) ? aTok[3] : ""; 136 | State = eState.Op0; 137 | break; 138 | } 139 | } 140 | break; 141 | } 142 | case eState.Op0: 143 | { 144 | var aTok = Text.Split(new char[] { ' ', '\t', }, StringSplitOptions.RemoveEmptyEntries); 145 | if (aTok.Length >= 10) 146 | { 147 | GetOp(aTok, ref vTone.aOp[0]); 148 | State = eState.Op1; 149 | break; 150 | } 151 | State = eState.Entry; 152 | break; 153 | } 154 | case eState.Op1: 155 | { 156 | var aTok = Text.Split(new char[] { ' ', '\t', }, StringSplitOptions.RemoveEmptyEntries); 157 | if (aTok.Length >= 10) 158 | { 159 | GetOp(aTok, ref vTone.aOp[1]); 160 | State = eState.Op2; 161 | break; 162 | } 163 | State = eState.Entry; 164 | break; 165 | } 166 | case eState.Op2: 167 | { 168 | var aTok = Text.Split(new char[] { ' ', '\t', }, StringSplitOptions.RemoveEmptyEntries); 169 | if (aTok.Length >= 10) 170 | { 171 | GetOp(aTok, ref vTone.aOp[2]); 172 | State = eState.Op3; 173 | break; 174 | } 175 | State = eState.Entry; 176 | break; 177 | } 178 | case eState.Op3: 179 | { 180 | var aTok = Text.Split(new char[] { ' ', '\t', }, StringSplitOptions.RemoveEmptyEntries); 181 | if (aTok.Length >= 10) 182 | { 183 | GetOp(aTok, ref vTone.aOp[3]); 184 | 185 | if (Option.bMuc) Muc.Put(vTone, ref BufferMuc); 186 | if (Option.bDat) Dat.Put(vTone, ref BufferDat); 187 | if (Option.bFmp) Fmp.Put(vTone, ref BufferFmp); 188 | if (Option.bVopm) Vopm.Put(vTone, ref BufferVopm); 189 | if (Option.bFMtrial) FMtrial.Put(vTone, ref BufferFMtrial); 190 | if (Option.bRme) Rme.Put(vTone, ref BufferRme); 191 | if (Option.bDx7) DX7.Put(vTone, ref BufferDx7); 192 | if (Option.bVmm) Vmm.Put(vTone, ref BufferVmm); 193 | } 194 | State = eState.Entry; 195 | break; 196 | } 197 | } 198 | } 199 | 200 | if (Option.bMuc) Muc.Writer(Path, BufferMuc); 201 | if (Option.bDat) Dat.Writer(Path, BufferDat); 202 | if (Option.bFmp) Fmp.Writer(Path, BufferFmp); 203 | if (Option.bVopm) Vopm.Writer(Path, BufferVopm); 204 | if (Option.bFMtrial) FMtrial.Writer(Path, BufferFMtrial); 205 | if (Option.bRme) Rme.Writer(Path, BufferRme); 206 | if (Option.bDx7) DX7.Writer(Path, BufferDx7); 207 | if (Option.bVmm) Vmm.Writer(Path, BufferVmm); 208 | } 209 | 210 | 211 | 212 | public static void Reader(string[] aPath, Option @Option) 213 | { 214 | foreach (var Path in aPath) 215 | { 216 | if (!String.IsNullOrWhiteSpace(Path) && Extension(Path).ToLower() == ".mml") Reader(Path, Option); 217 | } 218 | } 219 | 220 | 221 | 222 | public static void Writer(string Path, string Buffer) 223 | { 224 | WriteText(ChangeExtension(Path, ".mml"), Buffer); 225 | } 226 | } 227 | } 228 | -------------------------------------------------------------------------------- /FM-SoundConvertor/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 6 | // 制御されます。アセンブリに関連付けられている情報を変更するには、 7 | // これらの属性値を変更します。 8 | [assembly: AssemblyTitle("FM-SoundConvertor")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("FM-SoundConvertor")] 13 | [assembly: AssemblyCopyright("Copyright ©D.M.88 2020")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // ComVisible を false に設定すると、このアセンブリ内の型は COM コンポーネントから 18 | // 参照できなくなります。COM からこのアセンブリ内の型にアクセスする必要がある場合は、 19 | // その型の ComVisible 属性を true に設定します。 20 | [assembly: ComVisible(false)] 21 | 22 | // このプロジェクトが COM に公開される場合、次の GUID が typelib の ID になります 23 | [assembly: Guid("a3da1746-8229-471a-8029-3322ccfb15ab")] 24 | 25 | // アセンブリのバージョン情報は次の 4 つの値で構成されています: 26 | // 27 | // メジャー バージョン 28 | // マイナー バージョン 29 | // ビルド番号 30 | // リビジョン 31 | // 32 | // すべての値を指定するか、次を使用してビルド番号とリビジョン番号を既定に設定できます 33 | // 既定値にすることができます: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /FM-SoundConvertor/RetroMusicEditor.cs: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | using System; 5 | 6 | using static FM_SoundConvertor.Path; 7 | using static FM_SoundConvertor.File; 8 | using static FM_SoundConvertor.Console; 9 | 10 | 11 | 12 | namespace FM_SoundConvertor 13 | { 14 | class Rme 15 | { 16 | enum eName 17 | { 18 | Name0,Name0s, Name1,Name1s, Name2,Name2s, Name3,Name3s, Name4,Name4s, Name5,Name5s, Name6,Name6s, Name7,Name7s, Name8,Name8s, 19 | _LF_L, _LF_H, _Null, 20 | } 21 | 22 | enum ePut 23 | { 24 | _w0, Wave, _w1, _w2, AL, 25 | CV0, _00, AR0, DR0, SR0, RR0, _01, SL0, TL0, KS0, _03, _04, _05, _06, _07, _08, _09, _0a, _0b, FB, ML0_L, ML0_H, DT0, 26 | CV1, _10, AR1, DR1, SR1, RR1, _11, SL1, TL1, KS1, _13, _14, _15, _16, _17, _18, _19, _1a, _1b, _1c, ML1_L, ML1_H, DT1, 27 | CV2, _20, AR2, DR2, SR2, RR2, _21, SL2, TL2, KS2, _23, _24, _25, _26, _27, _28, _29, _2a, _2b, _2c, ML2_L, ML2_H, DT2, 28 | CV3, _30, AR3, DR3, SR3, RR3, _31, SL3, TL3, KS3, _33, _34, _35, _36, _37, _38, _39, _3a, _3b, _3c, ML3_L, ML3_H, DT3, 29 | _x0, _x1, _x2, _x3, _x4, _x5, _x6, _x7, _x8, _x9, 30 | _y0, _y1, _y2, _y3, _y4, _y5, _y6, _y7, _y8, Off, 31 | _z0, 32 | } 33 | 34 | 35 | 36 | 37 | static int ToneLength() 38 | { 39 | return 0x100; 40 | } 41 | 42 | static int HeadLength() 43 | { 44 | return 0x6b; 45 | } 46 | 47 | static int NameLength() 48 | { 49 | return System.Enum.GetNames(typeof(eName)).Length; 50 | } 51 | 52 | static int PutLength() 53 | { 54 | return NameLength() + (System.Enum.GetNames(typeof(ePut)).Length * sizeof(int)); 55 | } 56 | 57 | static int RmeLength() 58 | { 59 | return HeadLength() + (ToneLength() * PutLength()); 60 | } 61 | 62 | 63 | 64 | public static byte[] New() 65 | { 66 | var Buffer = new byte[RmeLength()]; 67 | Tone vTone = new Tone(); 68 | vTone.aOp[3].AR = 31; 69 | for (vTone.Number = 0; vTone.Number < ToneLength(); ++vTone.Number){ 70 | Put(vTone, ref Buffer); 71 | } 72 | return Buffer; 73 | } 74 | 75 | 76 | 77 | static int GetInt(byte[] Buffer, int O, int e) 78 | { 79 | return (int)BitConverter.ToInt32(Buffer, O + (e * sizeof(int))); 80 | } 81 | 82 | 83 | 84 | static int GetDbl(byte[] Buffer, int O, int e) 85 | { 86 | return (int)Math.Round(BitConverter.ToDouble(Buffer, O + (e * sizeof(int)))); 87 | } 88 | 89 | 90 | 91 | static void Get(ref Tone @Tone, byte[] Buffer, int i) 92 | { 93 | int o = HeadLength() + (i * PutLength()); 94 | int O = o + NameLength(); 95 | Tone.aOp[0].AR = GetInt(Buffer, O, (int)ePut.AR0); 96 | Tone.aOp[1].AR = GetInt(Buffer, O, (int)ePut.AR1); 97 | Tone.aOp[2].AR = GetInt(Buffer, O, (int)ePut.AR2); 98 | Tone.aOp[3].AR = GetInt(Buffer, O, (int)ePut.AR3); 99 | Tone.aOp[0].DR = GetInt(Buffer, O, (int)ePut.DR0); 100 | Tone.aOp[1].DR = GetInt(Buffer, O, (int)ePut.DR1); 101 | Tone.aOp[2].DR = GetInt(Buffer, O, (int)ePut.DR2); 102 | Tone.aOp[3].DR = GetInt(Buffer, O, (int)ePut.DR3); 103 | Tone.aOp[0].SR = GetInt(Buffer, O, (int)ePut.SR0); 104 | Tone.aOp[1].SR = GetInt(Buffer, O, (int)ePut.SR1); 105 | Tone.aOp[2].SR = GetInt(Buffer, O, (int)ePut.SR2); 106 | Tone.aOp[3].SR = GetInt(Buffer, O, (int)ePut.SR3); 107 | Tone.aOp[0].RR = GetInt(Buffer, O, (int)ePut.RR0); 108 | Tone.aOp[1].RR = GetInt(Buffer, O, (int)ePut.RR1); 109 | Tone.aOp[2].RR = GetInt(Buffer, O, (int)ePut.RR2); 110 | Tone.aOp[3].RR = GetInt(Buffer, O, (int)ePut.RR3); 111 | Tone.aOp[0].SL = GetInt(Buffer, O, (int)ePut.SL0); 112 | Tone.aOp[1].SL = GetInt(Buffer, O, (int)ePut.SL1); 113 | Tone.aOp[2].SL = GetInt(Buffer, O, (int)ePut.SL2); 114 | Tone.aOp[3].SL = GetInt(Buffer, O, (int)ePut.SL3); 115 | Tone.aOp[0].TL = GetInt(Buffer, O, (int)ePut.TL0); 116 | Tone.aOp[1].TL = GetInt(Buffer, O, (int)ePut.TL1); 117 | Tone.aOp[2].TL = GetInt(Buffer, O, (int)ePut.TL2); 118 | Tone.aOp[3].TL = GetInt(Buffer, O, (int)ePut.TL3); 119 | Tone.aOp[0].KS = GetInt(Buffer, O, (int)ePut.KS0); 120 | Tone.aOp[1].KS = GetInt(Buffer, O, (int)ePut.KS1); 121 | Tone.aOp[2].KS = GetInt(Buffer, O, (int)ePut.KS2); 122 | Tone.aOp[3].KS = GetInt(Buffer, O, (int)ePut.KS3); 123 | Tone.aOp[0].ML = GetDbl(Buffer, O, (int)ePut.ML0_L); 124 | Tone.aOp[1].ML = GetDbl(Buffer, O, (int)ePut.ML1_L); 125 | Tone.aOp[2].ML = GetDbl(Buffer, O, (int)ePut.ML2_L); 126 | Tone.aOp[3].ML = GetDbl(Buffer, O, (int)ePut.ML3_L); 127 | Tone.aOp[0].DT = GetInt(Buffer, O, (int)ePut.DT0); 128 | Tone.aOp[1].DT = GetInt(Buffer, O, (int)ePut.DT1); 129 | Tone.aOp[2].DT = GetInt(Buffer, O, (int)ePut.DT2); 130 | Tone.aOp[3].DT = GetInt(Buffer, O, (int)ePut.DT3); 131 | Tone.AL = GetInt(Buffer, O, (int)ePut.AL); 132 | Tone.FB = GetInt(Buffer, O, (int)ePut.FB); 133 | 134 | var aChar = new char[] 135 | { 136 | (char)Buffer[o + (int)eName.Name0], 137 | (char)Buffer[o + (int)eName.Name1], 138 | (char)Buffer[o + (int)eName.Name2], 139 | (char)Buffer[o + (int)eName.Name3], 140 | (char)Buffer[o + (int)eName.Name4], 141 | (char)Buffer[o + (int)eName.Name5], 142 | (char)Buffer[o + (int)eName.Name6], 143 | (char)Buffer[o + (int)eName.Name7], 144 | (char)Buffer[o + (int)eName.Name8], 145 | }; 146 | Tone.Name = ""; 147 | foreach (var Char in aChar) if (Char != 0) Tone.Name += Char.ToString(); 148 | 149 | Tone.Number = i; 150 | } 151 | 152 | 153 | 154 | static void PutInt(byte[] Buffer, int O, int e, int v) 155 | { 156 | var aPut = BitConverter.GetBytes(v); 157 | Array.Copy(aPut, 0, Buffer, O + (e * sizeof(int)), aPut.Length); 158 | } 159 | 160 | 161 | 162 | static void PutDbl(byte[] Buffer, int O, int e, double v) 163 | { 164 | var aPut = BitConverter.GetBytes(v); 165 | Array.Copy(aPut, 0, Buffer, O + (e * sizeof(int)), aPut.Length); 166 | } 167 | 168 | 169 | 170 | static int Limit(double v) 171 | { 172 | return (int)Math.Round((v < 10000)? v: 10000, MidpointRounding.AwayFromZero); 173 | } 174 | 175 | 176 | 177 | static int AR(int v) 178 | { 179 | switch (v){ 180 | case 0: return 10000; 181 | case 1: return 7640; 182 | case 2: return 3820; 183 | case 3: return 5094; 184 | case 4: return 3820; 185 | case 5: return 2547; 186 | case 6: return 1912; 187 | case 7: return 1274; 188 | case 8: return 957; 189 | case 9: return 638; 190 | case 10:return 479; 191 | case 11:return 319; 192 | case 12:return 241; 193 | case 13:return 161; 194 | case 14:return 122; 195 | case 15:return 81; 196 | case 16:return 63; 197 | case 17:return 42; 198 | case 18:return 34; 199 | case 19:return 21; 200 | case 20:return 16; 201 | case 21:return 10; 202 | case 22:return 9; 203 | case 23:return 6; 204 | case 24:return 5; 205 | case 25:return 3; 206 | case 26:return 3; 207 | case 27:return 2; 208 | case 28:return 1; 209 | case 29:return 1; 210 | case 30:return 0; 211 | default: 212 | case 31:return 0; 213 | } 214 | } 215 | 216 | 217 | 218 | static int DR(int v, int sl) 219 | { 220 | switch (v){ 221 | case 0: return (sl == 0)? 0: -1; 222 | case 1: return Limit(3543 * sl); 223 | case 2: return Limit(1772 * sl); 224 | case 3: return Limit(2380 * sl); 225 | case 4: return Limit(1772 * sl); 226 | case 5: return Limit(1162.7 * sl); 227 | case 6: return Limit(872.8 * sl); 228 | case 7: return Limit(595.7 * sl); 229 | case 8: return Limit(443.8 * sl); 230 | case 9: return Limit(298.3 * sl); 231 | case 10:return Limit(218.4 * sl); 232 | case 11:return Limit(149 * sl); 233 | case 12:return Limit(108.1 * sl); 234 | case 13:return Limit(73.2 * sl); 235 | case 14:return Limit(56.4 * sl); 236 | case 15:return Limit(37 * sl); 237 | case 16:return Limit(28 * sl); 238 | case 17:return Limit(19 * sl); 239 | case 18:return Limit(14.3 * sl); 240 | case 19:return Limit(9.3 * sl); 241 | case 20:return Limit(7 * sl); 242 | case 21:return Limit(4.7 * sl); 243 | case 22:return Limit(4.2 * sl); 244 | case 23:return Limit(2.8 * sl); 245 | case 24:return Limit(2.1 * sl); 246 | case 25:return Limit(1.3 * sl); 247 | case 26:return Limit(1 * sl); 248 | case 27:return Limit(0.65 * sl); 249 | case 28:return Limit(0.5 * sl); 250 | case 29:return Limit(0.4 * sl); 251 | case 30:return Limit(0 * sl); 252 | default: 253 | case 31:return Limit(0 * sl); 254 | } 255 | } 256 | 257 | 258 | 259 | static int SR(int v) 260 | { 261 | switch (v){ 262 | case 0: return -1; 263 | case 1: return Limit(92123); 264 | case 2: return Limit(46068); 265 | case 3: return Limit(61406); 266 | case 4: return Limit(46068); 267 | case 5: return Limit(30704); 268 | case 6: return Limit(23039); 269 | case 7: return Limit(15375); 270 | case 8: return Limit(11538); 271 | case 9: return Limit(7701); 272 | case 10:return Limit(5770); 273 | case 11:return Limit(3847); 274 | case 12:return Limit(2833); 275 | case 13:return Limit(1933); 276 | case 14:return Limit(1470); 277 | case 15:return Limit(980); 278 | case 16:return Limit(754); 279 | case 17:return Limit(500); 280 | case 18:return Limit(377); 281 | case 19:return Limit(247); 282 | case 20:return Limit(186); 283 | case 21:return Limit(124); 284 | case 22:return Limit(113); 285 | case 23:return Limit(72); 286 | case 24:return Limit(55); 287 | case 25:return Limit(37); 288 | case 26:return Limit(28); 289 | case 27:return Limit(19); 290 | case 28:return Limit(13); 291 | case 29:return Limit(10); 292 | case 30:return Limit(3); 293 | default: 294 | case 31:return Limit(3); 295 | } 296 | } 297 | 298 | 299 | 300 | static int RR(int v) 301 | { 302 | switch (v){ 303 | case 0: return -1; 304 | case 1: return Limit(61406); 305 | case 2: return Limit(30704); 306 | case 3: return Limit(15375); 307 | case 4: return Limit(7701); 308 | case 5: return Limit(3847); 309 | case 6: return Limit(1933); 310 | case 7: return Limit(980); 311 | case 8: return Limit(500); 312 | case 9: return Limit(247); 313 | case 10:return Limit(124); 314 | case 11:return Limit(72); 315 | case 12:return Limit(37); 316 | case 13:return Limit(19); 317 | case 14:return Limit(10); 318 | default: 319 | case 15:return Limit(3); 320 | } 321 | } 322 | 323 | 324 | 325 | static int SL(int v) 326 | { 327 | switch (v){ 328 | default: 329 | case 0: return 255; 330 | case 1: return 215; 331 | case 2: return 180; 332 | case 3: return 152; 333 | case 4: return 127; 334 | case 5: return 107; 335 | case 6: return 91; 336 | case 7: return 76; 337 | case 8: return 64; 338 | case 9: return 54; 339 | case 10:return 46; 340 | case 11:return 38; 341 | case 12:return 30; 342 | case 13:return 27; 343 | case 14:return 22; 344 | case 15:return 0; 345 | } 346 | } 347 | 348 | 349 | 350 | static int TL(int v) 351 | { 352 | return 255 - v; 353 | } 354 | 355 | 356 | 357 | static int KS(int v) 358 | { 359 | switch (v){ 360 | default: 361 | case 0: return 0; 362 | case 1: return 6; 363 | case 2: return 12; 364 | case 3: return 16; 365 | } 366 | } 367 | 368 | 369 | 370 | static double ML(int v) 371 | { 372 | switch (v){ 373 | case 0: return 0.5; 374 | default: 375 | case 1: return 1; 376 | case 2: return 2; 377 | case 3: return 3; 378 | case 4: return 4; 379 | case 5: return 5; 380 | case 6: return 6; 381 | case 7: return 7; 382 | case 8: return 8; 383 | case 9: return 9; 384 | case 10:return 10; 385 | case 11:return 11; 386 | case 12:return 12; 387 | case 13:return 13; 388 | case 14:return 14; 389 | case 15:return 15; 390 | } 391 | } 392 | 393 | 394 | 395 | static int DT(int v) 396 | { 397 | switch (v){ 398 | default: 399 | case 0: return 0; 400 | case 1: return 1; 401 | case 2: return 2; 402 | case 3: return 3; 403 | case 4: return 0; 404 | case 5: return -1; 405 | case 6: return -2; 406 | case 7: return -3; 407 | } 408 | } 409 | 410 | 411 | 412 | public static void Put(Tone @Tone, ref byte[] Buffer) 413 | { 414 | if (Tone.IsValid() && Tone.Number < ToneLength()) 415 | { 416 | int o = HeadLength() + (Tone.Number * PutLength()); 417 | int O = o + NameLength(); 418 | PutInt(Buffer, O, (int)ePut._w0, 0xff); 419 | PutInt(Buffer, O, (int)ePut.Wave, 7);//FM 420 | PutInt(Buffer, O, (int)ePut._w1, 0x800000); 421 | PutInt(Buffer, O, (int)ePut.CV0, 2); 422 | PutInt(Buffer, O, (int)ePut.CV1, 2); 423 | PutInt(Buffer, O, (int)ePut.CV2, 2); 424 | PutInt(Buffer, O, (int)ePut.CV3, 2); 425 | PutInt(Buffer, O, (int)ePut.AR0, AR(Tone.aOp[0].AR)); 426 | PutInt(Buffer, O, (int)ePut.AR1, AR(Tone.aOp[1].AR)); 427 | PutInt(Buffer, O, (int)ePut.AR2, AR(Tone.aOp[2].AR)); 428 | PutInt(Buffer, O, (int)ePut.AR3, AR(Tone.aOp[3].AR)); 429 | PutInt(Buffer, O, (int)ePut.DR0, DR(Tone.aOp[0].DR, Tone.aOp[0].SL)); 430 | PutInt(Buffer, O, (int)ePut.DR1, DR(Tone.aOp[1].DR, Tone.aOp[1].SL)); 431 | PutInt(Buffer, O, (int)ePut.DR2, DR(Tone.aOp[2].DR, Tone.aOp[2].SL)); 432 | PutInt(Buffer, O, (int)ePut.DR3, DR(Tone.aOp[3].DR, Tone.aOp[3].SL)); 433 | PutInt(Buffer, O, (int)ePut.SR0, SR(Tone.aOp[0].SR)); 434 | PutInt(Buffer, O, (int)ePut.SR1, SR(Tone.aOp[1].SR)); 435 | PutInt(Buffer, O, (int)ePut.SR2, SR(Tone.aOp[2].SR)); 436 | PutInt(Buffer, O, (int)ePut.SR3, SR(Tone.aOp[3].SR)); 437 | PutInt(Buffer, O, (int)ePut.RR0, RR(Tone.aOp[0].RR)); 438 | PutInt(Buffer, O, (int)ePut.RR1, RR(Tone.aOp[1].RR)); 439 | PutInt(Buffer, O, (int)ePut.RR2, RR(Tone.aOp[2].RR)); 440 | PutInt(Buffer, O, (int)ePut.RR3, RR(Tone.aOp[3].RR)); 441 | PutInt(Buffer, O, (int)ePut.SL0, SL(Tone.aOp[0].SL)); 442 | PutInt(Buffer, O, (int)ePut.SL1, SL(Tone.aOp[1].SL)); 443 | PutInt(Buffer, O, (int)ePut.SL2, SL(Tone.aOp[2].SL)); 444 | PutInt(Buffer, O, (int)ePut.SL3, SL(Tone.aOp[3].SL)); 445 | PutInt(Buffer, O, (int)ePut.TL0, TL(Tone.aOp[0].TL)); 446 | PutInt(Buffer, O, (int)ePut.TL1, TL(Tone.aOp[1].TL)); 447 | PutInt(Buffer, O, (int)ePut.TL2, TL(Tone.aOp[2].TL)); 448 | PutInt(Buffer, O, (int)ePut.TL3, TL(Tone.aOp[3].TL)); 449 | PutInt(Buffer, O, (int)ePut.KS0, KS(Tone.aOp[0].KS)); 450 | PutInt(Buffer, O, (int)ePut.KS1, KS(Tone.aOp[1].KS)); 451 | PutInt(Buffer, O, (int)ePut.KS2, KS(Tone.aOp[2].KS)); 452 | PutInt(Buffer, O, (int)ePut.KS3, KS(Tone.aOp[3].KS)); 453 | PutDbl(Buffer, O, (int)ePut.ML0_L, ML(Tone.aOp[0].ML)); 454 | PutDbl(Buffer, O, (int)ePut.ML1_L, ML(Tone.aOp[1].ML)); 455 | PutDbl(Buffer, O, (int)ePut.ML2_L, ML(Tone.aOp[2].ML)); 456 | PutDbl(Buffer, O, (int)ePut.ML3_L, ML(Tone.aOp[3].ML)); 457 | PutInt(Buffer, O, (int)ePut.DT0, DT(Tone.aOp[0].DT)); 458 | PutInt(Buffer, O, (int)ePut.DT1, DT(Tone.aOp[1].DT)); 459 | PutInt(Buffer, O, (int)ePut.DT2, DT(Tone.aOp[2].DT)); 460 | PutInt(Buffer, O, (int)ePut.DT3, DT(Tone.aOp[3].DT)); 461 | PutInt(Buffer, O, (int)ePut.AL, Tone.AL); 462 | PutInt(Buffer, O, (int)ePut.FB, Tone.FB); 463 | PutInt(Buffer, O, (int)ePut._x4, -1); 464 | PutInt(Buffer, O, (int)ePut._x7, 0xff); 465 | PutInt(Buffer, O, (int)ePut._x8, 0xff); 466 | PutInt(Buffer, O, (int)ePut._y0, 1); 467 | PutInt(Buffer, O, (int)ePut._y4, 0x10000); 468 | PutInt(Buffer, O, (int)ePut._z0, -2); 469 | PutInt(Buffer, O, (int)ePut.Off, 1); 470 | 471 | if (String.IsNullOrWhiteSpace(Tone.Name)) 472 | { 473 | Tone.Name = Tone.Number.ToString(); 474 | } 475 | Buffer[o + (int)eName.Name0] = (byte)((Tone.Name.Length > 0) ? Tone.Name[0] : 0); 476 | Buffer[o + (int)eName.Name1] = (byte)((Tone.Name.Length > 1) ? Tone.Name[1] : 0); 477 | Buffer[o + (int)eName.Name2] = (byte)((Tone.Name.Length > 2) ? Tone.Name[2] : 0); 478 | Buffer[o + (int)eName.Name3] = (byte)((Tone.Name.Length > 3) ? Tone.Name[3] : 0); 479 | Buffer[o + (int)eName.Name4] = (byte)((Tone.Name.Length > 4) ? Tone.Name[4] : 0); 480 | Buffer[o + (int)eName.Name5] = (byte)((Tone.Name.Length > 5) ? Tone.Name[5] : 0); 481 | Buffer[o + (int)eName.Name6] = (byte)((Tone.Name.Length > 6) ? Tone.Name[6] : 0); 482 | Buffer[o + (int)eName.Name7] = (byte)((Tone.Name.Length > 7) ? Tone.Name[7] : 0); 483 | Buffer[o + (int)eName.Name8] = (byte)((Tone.Name.Length > 8) ? Tone.Name[8] : 0); 484 | Buffer[o + (int)eName._LF_L] = 0x0a; 485 | } 486 | } 487 | 488 | 489 | 490 | public static bool IsValid(byte[] Buffer) 491 | { 492 | return ( 493 | Buffer[0x00] == (byte)'R' 494 | && Buffer[0x01] == (byte)'e' 495 | && Buffer[0x02] == (byte)'t' 496 | && Buffer[0x03] == (byte)'r' 497 | && Buffer[0x04] == (byte)'o' 498 | && Buffer[0x05] == (byte)' ' 499 | && Buffer[0x06] == (byte)'M' 500 | && Buffer[0x07] == (byte)'u' 501 | && Buffer[0x08] == (byte)'s' 502 | && Buffer[0x09] == (byte)'i' 503 | && Buffer[0x0a] == (byte)'c' 504 | && Buffer[0x0b] == (byte)' ' 505 | && Buffer[0x0c] == (byte)'P' 506 | && Buffer[0x0d] == (byte)'r' 507 | && Buffer[0x0e] == (byte)'o' 508 | && Buffer[0x0f] == (byte)'j' 509 | 510 | && Buffer[0x10] == (byte)'e' 511 | && Buffer[0x11] == (byte)'c' 512 | && Buffer[0x12] == (byte)'t' 513 | && Buffer[0x13] == 0x00 514 | && Buffer[0x14] == 0x01 515 | && Buffer[0x15] == 0x09 516 | && Buffer[0x16] == 0x00 517 | && Buffer[0x17] == 0x00 518 | && Buffer[0x18] == 0x0a 519 | && Buffer[0x19] == 0x00 520 | && Buffer[0x1a] == 0x01 521 | && Buffer[0x1b] == 0x00 522 | && Buffer[0x1c] == 0x00 523 | && Buffer[0x1d] == 0x00 524 | && Buffer[0x1e] == 0x00 525 | && Buffer[0x1f] == 0x00 526 | 527 | && Buffer[0x20] == 0x00 528 | && Buffer[0x21] == 0x00 529 | && Buffer[0x22] == 0x80 530 | && Buffer[0x23] == 0x00 531 | && Buffer[0x24] == 0x00 532 | && Buffer[0x25] == 0x00 533 | && Buffer[0x26] == 0x01 534 | && Buffer[0x27] == 0x00 535 | && Buffer[0x28] == 0x00 536 | && Buffer[0x29] == 0x00 537 | && Buffer[0x2a] == 0x00 538 | && Buffer[0x2b] == 0x00 539 | && Buffer[0x2c] == 0x00 540 | && Buffer[0x2d] == 0x00 541 | && Buffer[0x2e] == 0x00 542 | && Buffer[0x2f] == 0x00 543 | 544 | && Buffer[0x30] == 0x00 545 | && Buffer[0x31] == 0x00 546 | && Buffer[0x32] == 0x00 547 | && Buffer[0x33] == 0x00 548 | && Buffer[0x34] == 0x5e 549 | && Buffer[0x35] == 0x40 550 | && Buffer[0x36] == 0x00 551 | && Buffer[0x37] == 0x00 552 | && Buffer[0x38] == 0x01 553 | && Buffer[0x39] == 0x00 554 | && Buffer[0x3a] == 0x00 555 | && Buffer[0x3b] == 0x00 556 | && Buffer[0x3c] == 0x00 557 | && Buffer[0x3d] == 0x00 558 | && Buffer[0x3e] == 0x00 559 | && Buffer[0x3f] == 0x00 560 | 561 | && Buffer[0x40] == 0x04 562 | && Buffer[0x41] == 0x00 563 | && Buffer[0x42] == 0x00 564 | && Buffer[0x43] == 0x00 565 | && Buffer[0x44] == 0x04 566 | && Buffer[0x45] == 0x00 567 | && Buffer[0x46] == 0x00 568 | && Buffer[0x47] == 0x00 569 | && Buffer[0x48] == 0x00 570 | && Buffer[0x49] == 0x00 571 | && Buffer[0x4a] == 0x00 572 | && Buffer[0x4b] == 0x00 573 | && Buffer[0x4c] == 0x00 574 | && Buffer[0x4d] == 0x00 575 | && Buffer[0x4e] == 0x00 576 | && Buffer[0x4f] == 0x00 577 | 578 | && Buffer[0x50] == 0x00 579 | && Buffer[0x51] == 0x02 580 | && Buffer[0x52] == 0x44 581 | && Buffer[0x53] == 0xac 582 | && Buffer[0x54] == 0x00 583 | && Buffer[0x55] == 0x00 584 | && Buffer[0x56] == 0x10 585 | && Buffer[0x57] == 0xe8 586 | && Buffer[0x58] == 0x03 587 | && Buffer[0x59] == 0xd0 588 | && Buffer[0x5a] == 0x07 589 | && Buffer[0x5b] == 0x00 590 | && Buffer[0x5c] == 0x00 591 | && Buffer[0x5d] == 0x00 592 | && Buffer[0x5e] == 0x00 593 | && Buffer[0x5f] == 0x00 594 | 595 | && Buffer[0x60] == 0x00 596 | && Buffer[0x61] == 0x00 597 | && Buffer[0x62] == 0x00 598 | && Buffer[0x63] == 0x01 599 | && Buffer[0x64] == 0x00 600 | && Buffer[0x65] == 0x00 601 | && Buffer[0x66] == 0x00 602 | && Buffer[0x67] == 0x00 603 | && Buffer[0x68] == 0x01 604 | && Buffer[0x69] == 0x00 605 | && Buffer[0x6a] == 0x00 606 | ); 607 | } 608 | 609 | 610 | 611 | public static void Reader(string Path, Option @Option) 612 | { 613 | var Buffer = ReadByte(Path); 614 | if (Buffer.Length == RmeLength() && IsValid(Buffer)) 615 | { 616 | Tone vTone = new Tone(); 617 | 618 | var BufferMuc = ""; 619 | var BufferDat = Dat.New(); 620 | var BufferFmp = ""; 621 | var BufferPmd = ""; 622 | var BufferVopm = Vopm.New(); 623 | var BufferFMtrial = FMtrial.New(); 624 | var BufferDx7 = DX7.New(); 625 | 626 | for (int i = 0; i < ToneLength(); ++i) 627 | { 628 | Get(ref vTone, Buffer, i); 629 | 630 | if (Option.bMuc) Muc.Put(vTone, ref BufferMuc); 631 | if (Option.bDat) Dat.Put(vTone, ref BufferDat); 632 | if (Option.bFmp) Fmp.Put(vTone, ref BufferFmp); 633 | if (Option.bPmd) Pmd.Put(vTone, ref BufferPmd); 634 | if (Option.bVopm) Vopm.Put(vTone, ref BufferVopm); 635 | if (Option.bFMtrial) FMtrial.Put(vTone, ref BufferFMtrial); 636 | if (Option.bDx7) DX7.Put(vTone, ref BufferDx7); 637 | } 638 | 639 | if (Option.bMuc) Muc.Writer(Path, BufferMuc); 640 | if (Option.bDat) Dat.Writer(Path, BufferDat); 641 | if (Option.bFmp) Fmp.Writer(Path, BufferFmp); 642 | if (Option.bPmd) Pmd.Writer(Path, BufferPmd); 643 | if (Option.bVopm) Vopm.Writer(Path, BufferVopm); 644 | if (Option.bFMtrial) FMtrial.Writer(Path, BufferFMtrial); 645 | if (Option.bDx7) DX7.Writer(Path, BufferDx7); 646 | } 647 | } 648 | 649 | 650 | 651 | public static void Reader(string[] aPath, Option @Option) 652 | { 653 | #if false//[ 654 | foreach (var Path in aPath) 655 | { 656 | if (!String.IsNullOrWhiteSpace(Path) && Extension(Path).ToLower() == ".rtp") Reader(Path, Option); 657 | } 658 | #endif//] 659 | } 660 | 661 | 662 | 663 | public static void Writer(string Path, byte[] Buffer) 664 | { 665 | Buffer[0x00] = (byte)'R'; 666 | Buffer[0x01] = (byte)'e'; 667 | Buffer[0x02] = (byte)'t'; 668 | Buffer[0x03] = (byte)'r'; 669 | Buffer[0x04] = (byte)'o'; 670 | Buffer[0x05] = (byte)' '; 671 | Buffer[0x06] = (byte)'M'; 672 | Buffer[0x07] = (byte)'u'; 673 | Buffer[0x08] = (byte)'s'; 674 | Buffer[0x09] = (byte)'i'; 675 | Buffer[0x0a] = (byte)'c'; 676 | Buffer[0x0b] = (byte)' '; 677 | Buffer[0x0c] = (byte)'P'; 678 | Buffer[0x0d] = (byte)'r'; 679 | Buffer[0x0e] = (byte)'o'; 680 | Buffer[0x0f] = (byte)'j'; 681 | 682 | Buffer[0x10] = (byte)'e'; 683 | Buffer[0x11] = (byte)'c'; 684 | Buffer[0x12] = (byte)'t'; 685 | Buffer[0x13] = 0x00; 686 | Buffer[0x14] = 0x01; 687 | Buffer[0x15] = 0x09; 688 | Buffer[0x16] = 0x00; 689 | Buffer[0x17] = 0x00; 690 | Buffer[0x18] = 0x0a; 691 | Buffer[0x19] = 0x00; 692 | Buffer[0x1a] = 0x01; 693 | Buffer[0x1b] = 0x00; 694 | Buffer[0x1c] = 0x00; 695 | Buffer[0x1d] = 0x00; 696 | Buffer[0x1e] = 0x00; 697 | Buffer[0x1f] = 0x00; 698 | 699 | Buffer[0x20] = 0x00; 700 | Buffer[0x21] = 0x00; 701 | Buffer[0x22] = 0x80; 702 | Buffer[0x23] = 0x00; 703 | Buffer[0x24] = 0x00; 704 | Buffer[0x25] = 0x00; 705 | Buffer[0x26] = 0x01; 706 | Buffer[0x27] = 0x00; 707 | Buffer[0x28] = 0x00; 708 | Buffer[0x29] = 0x00; 709 | Buffer[0x2a] = 0x00; 710 | Buffer[0x2b] = 0x00; 711 | Buffer[0x2c] = 0x00; 712 | Buffer[0x2d] = 0x00; 713 | Buffer[0x2e] = 0x00; 714 | Buffer[0x2f] = 0x00; 715 | 716 | Buffer[0x30] = 0x00; 717 | Buffer[0x31] = 0x00; 718 | Buffer[0x32] = 0x00; 719 | Buffer[0x33] = 0x00; 720 | Buffer[0x34] = 0x5e; 721 | Buffer[0x35] = 0x40; 722 | Buffer[0x36] = 0x00; 723 | Buffer[0x37] = 0x00; 724 | Buffer[0x38] = 0x01; 725 | Buffer[0x39] = 0x00; 726 | Buffer[0x3a] = 0x00; 727 | Buffer[0x3b] = 0x00; 728 | Buffer[0x3c] = 0x00; 729 | Buffer[0x3d] = 0x00; 730 | Buffer[0x3e] = 0x00; 731 | Buffer[0x3f] = 0x00; 732 | 733 | Buffer[0x40] = 0x04; 734 | Buffer[0x41] = 0x00; 735 | Buffer[0x42] = 0x00; 736 | Buffer[0x43] = 0x00; 737 | Buffer[0x44] = 0x04; 738 | Buffer[0x45] = 0x00; 739 | Buffer[0x46] = 0x00; 740 | Buffer[0x47] = 0x00; 741 | Buffer[0x48] = 0x00; 742 | Buffer[0x49] = 0x00; 743 | Buffer[0x4a] = 0x00; 744 | Buffer[0x4b] = 0x00; 745 | Buffer[0x4c] = 0x00; 746 | Buffer[0x4d] = 0x00; 747 | Buffer[0x4e] = 0x00; 748 | Buffer[0x4f] = 0x00; 749 | 750 | Buffer[0x50] = 0x00; 751 | Buffer[0x51] = 0x02; 752 | Buffer[0x52] = 0x44; 753 | Buffer[0x53] = 0xac; 754 | Buffer[0x54] = 0x00; 755 | Buffer[0x55] = 0x00; 756 | Buffer[0x56] = 0x10; 757 | Buffer[0x57] = 0xe8; 758 | Buffer[0x58] = 0x03; 759 | Buffer[0x59] = 0xd0; 760 | Buffer[0x5a] = 0x07; 761 | Buffer[0x5b] = 0x00; 762 | Buffer[0x5c] = 0x00; 763 | Buffer[0x5d] = 0x00; 764 | Buffer[0x5e] = 0x00; 765 | Buffer[0x5f] = 0x00; 766 | 767 | Buffer[0x60] = 0x00; 768 | Buffer[0x61] = 0x00; 769 | Buffer[0x62] = 0x00; 770 | Buffer[0x63] = 0x01; 771 | Buffer[0x64] = 0x00; 772 | Buffer[0x65] = 0x00; 773 | Buffer[0x66] = 0x00; 774 | Buffer[0x67] = 0x00;//ToneLength 775 | Buffer[0x68] = 0x01; 776 | Buffer[0x69] = 0x00; 777 | Buffer[0x6a] = 0x00; 778 | 779 | WriteByte(ChangeExtension(Path, ".rtp"), Buffer); 780 | } 781 | } 782 | } 783 | -------------------------------------------------------------------------------- /FM-SoundConvertor/Tone.cs: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | namespace FM_SoundConvertor 5 | { 6 | class Op 7 | { 8 | public int AR; 9 | public int DR; 10 | public int SR; 11 | public int RR; 12 | public int SL; 13 | public int TL; 14 | public int KS; 15 | public int ML; 16 | public int DT; 17 | public int DT2; 18 | public int AM; 19 | 20 | 21 | 22 | public Op() 23 | { 24 | AR = 0; 25 | DR = 0; 26 | SR = 0; 27 | RR = 0; 28 | SL = 0; 29 | TL = 0; 30 | KS = 0; 31 | ML = 0; 32 | DT = 0; 33 | DT2 = 0; 34 | AM = 0; 35 | } 36 | } 37 | 38 | 39 | 40 | class Tone 41 | { 42 | public string Name; 43 | public int Number; 44 | public int FB; 45 | public int AL; 46 | public Op[] aOp; 47 | 48 | 49 | 50 | public Tone() 51 | { 52 | Name = ""; 53 | Number = -1; 54 | FB = 0; 55 | AL = 0; 56 | aOp = new Op[4]; 57 | aOp[0] = new Op(); 58 | aOp[1] = new Op(); 59 | aOp[2] = new Op(); 60 | aOp[3] = new Op(); 61 | } 62 | 63 | 64 | 65 | public bool IsValid() 66 | { 67 | return (Number >= 0x00 && Number <= 0xff && (aOp[0].AR > 0 || aOp[1].AR > 0 || aOp[2].AR > 0 || aOp[3].AR > 0)); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /FM-SoundConvertor/VGMMusicMaker.cs: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | using System; 5 | 6 | using static FM_SoundConvertor.Path; 7 | using static FM_SoundConvertor.File; 8 | using static FM_SoundConvertor.Console; 9 | 10 | 11 | 12 | namespace FM_SoundConvertor 13 | { 14 | class Vmm 15 | { 16 | enum ePut 17 | { 18 | AL, FB, AMDFMD, 19 | ML0, DT0, TL0, RS0, AR0, AMDR0, SR0, RR0, SL0, SSGEG0, 20 | ML2, DT2, TL2, RS2, AR2, AMDR2, SR2, RR2, SL2, SSGEG2, 21 | ML1, DT1, TL1, RS1, AR1, AMDR1, SR1, RR1, SL1, SSGEG1, 22 | ML3, DT3, TL3, RS3, AR3, AMDR3, SR3, RR3, SL3, SSGEG3, 23 | } 24 | 25 | 26 | 27 | static int ToneLength() 28 | { 29 | return 0x100; 30 | } 31 | 32 | static int PutLength() 33 | { 34 | return System.Enum.GetNames(typeof(ePut)).Length; 35 | } 36 | 37 | static int VmmLength() 38 | { 39 | return ToneLength() * PutLength(); 40 | } 41 | 42 | 43 | 44 | public static byte[] New() 45 | { 46 | return new byte[VmmLength()]; 47 | } 48 | 49 | 50 | 51 | static byte DT(int v) 52 | { 53 | switch (v){ 54 | case 7: return 0; 55 | case 6: return 1; 56 | case 5: return 2; 57 | case 0: return 3; 58 | case 1: return 4; 59 | case 2: return 5; 60 | case 3: return 6; 61 | } 62 | return 3; 63 | } 64 | 65 | 66 | 67 | public static void Put(Tone @Tone, ref byte[] Buffer) 68 | { 69 | if (Tone.IsValid()) 70 | { 71 | int o = Tone.Number * PutLength(); 72 | Buffer[o + (int)ePut.AL] = (byte)Tone.AL; 73 | Buffer[o + (int)ePut.FB] = (byte)Tone.FB; 74 | Buffer[o + (int)ePut.AMDFMD] = 0; 75 | 76 | Buffer[o + (int)ePut.ML0] = (byte)Tone.aOp[0].ML; 77 | Buffer[o + (int)ePut.DT0] = DT(Tone.aOp[0].DT); 78 | Buffer[o + (int)ePut.TL0] = (byte)Tone.aOp[0].TL; 79 | Buffer[o + (int)ePut.RS0] = (byte)Tone.aOp[0].KS; 80 | Buffer[o + (int)ePut.AR0] = (byte)Tone.aOp[0].AR; 81 | Buffer[o + (int)ePut.AMDR0] = (byte)Tone.aOp[0].DR; 82 | Buffer[o + (int)ePut.SR0] = (byte)Tone.aOp[0].SR; 83 | Buffer[o + (int)ePut.RR0] = (byte)Tone.aOp[0].RR; 84 | Buffer[o + (int)ePut.SL0] = (byte)Tone.aOp[0].SL; 85 | Buffer[o + (int)ePut.SSGEG0] = 0; 86 | 87 | Buffer[o + (int)ePut.ML1] = (byte)Tone.aOp[1].ML; 88 | Buffer[o + (int)ePut.DT1] = DT(Tone.aOp[1].DT); 89 | Buffer[o + (int)ePut.TL1] = (byte)Tone.aOp[1].TL; 90 | Buffer[o + (int)ePut.RS1] = (byte)Tone.aOp[1].KS; 91 | Buffer[o + (int)ePut.AR1] = (byte)Tone.aOp[1].AR; 92 | Buffer[o + (int)ePut.AMDR1] = (byte)Tone.aOp[1].DR; 93 | Buffer[o + (int)ePut.SR1] = (byte)Tone.aOp[1].SR; 94 | Buffer[o + (int)ePut.RR1] = (byte)Tone.aOp[1].RR; 95 | Buffer[o + (int)ePut.SL1] = (byte)Tone.aOp[1].SL; 96 | Buffer[o + (int)ePut.SSGEG1] = 0; 97 | 98 | Buffer[o + (int)ePut.ML2] = (byte)Tone.aOp[2].ML; 99 | Buffer[o + (int)ePut.DT2] = DT(Tone.aOp[2].DT); 100 | Buffer[o + (int)ePut.TL2] = (byte)Tone.aOp[2].TL; 101 | Buffer[o + (int)ePut.RS2] = (byte)Tone.aOp[2].KS; 102 | Buffer[o + (int)ePut.AR2] = (byte)Tone.aOp[2].AR; 103 | Buffer[o + (int)ePut.AMDR2] = (byte)Tone.aOp[2].DR; 104 | Buffer[o + (int)ePut.SR2] = (byte)Tone.aOp[2].SR; 105 | Buffer[o + (int)ePut.RR2] = (byte)Tone.aOp[2].RR; 106 | Buffer[o + (int)ePut.SL2] = (byte)Tone.aOp[2].SL; 107 | Buffer[o + (int)ePut.SSGEG2] = 0; 108 | 109 | Buffer[o + (int)ePut.ML3] = (byte)Tone.aOp[3].ML; 110 | Buffer[o + (int)ePut.DT3] = DT(Tone.aOp[3].DT); 111 | Buffer[o + (int)ePut.TL3] = (byte)Tone.aOp[3].TL; 112 | Buffer[o + (int)ePut.RS3] = (byte)Tone.aOp[3].KS; 113 | Buffer[o + (int)ePut.AR3] = (byte)Tone.aOp[3].AR; 114 | Buffer[o + (int)ePut.AMDR3] = (byte)Tone.aOp[3].DR; 115 | Buffer[o + (int)ePut.SR3] = (byte)Tone.aOp[3].SR; 116 | Buffer[o + (int)ePut.RR3] = (byte)Tone.aOp[3].RR; 117 | Buffer[o + (int)ePut.SL3] = (byte)Tone.aOp[3].SL; 118 | Buffer[o + (int)ePut.SSGEG3] = 0; 119 | } 120 | } 121 | 122 | 123 | 124 | static bool IsValid(byte[] Tone) 125 | { 126 | return (Tone[(int)ePut.AR0] > 0) || (Tone[(int)ePut.AR1] > 0) || (Tone[(int)ePut.AR2] > 0) || (Tone[(int)ePut.AR3] > 0); 127 | } 128 | 129 | 130 | 131 | public static void Reader(string[] aPath, Option @Option) 132 | { 133 | #if false//[ 134 | foreach (var Path in aPath) 135 | { 136 | if (!String.IsNullOrWhiteSpace(Path) && Extension(Path).ToLower() == ".vgi") Reader(Path, Option); 137 | } 138 | #endif//] 139 | } 140 | 141 | 142 | 143 | public static void Writer(string Path, byte[] Buffer) 144 | { 145 | var s = PutLength(); 146 | for (int i = 0; i < ToneLength(); ++i){ 147 | var Tone = new byte[s]; 148 | Array.Copy(Buffer, (i * s), Tone, 0, s); 149 | if (IsValid(Tone)){ 150 | WriteByte(ChangeExtension(Path, $"[{i}].vgi"), Tone); 151 | } 152 | } 153 | } 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /FM-SoundConvertor/VOPM.cs: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | using System; 5 | 6 | using static FM_SoundConvertor.Path; 7 | using static FM_SoundConvertor.File; 8 | using static FM_SoundConvertor.Console; 9 | 10 | 11 | 12 | namespace FM_SoundConvertor 13 | { 14 | class Vopm 15 | { 16 | enum ePut 17 | { 18 | AL, FB, 19 | _0, _1, _2, _3, _4, _5, _6, _7, 20 | Mask, 21 | TL0, AR0, DR0, SL0, SR0, RR0, KS0, ML0, DT1_0, DT2_0, AM0, 22 | TL1, AR1, DR1, SL1, SR1, RR1, KS1, ML1, DT1_1, DT2_1, AM1, 23 | TL2, AR2, DR2, SL2, SR2, RR2, KS2, ML2, DT1_2, DT2_2, AM2, 24 | TL3, AR3, DR3, SL3, SR3, RR3, KS3, ML3, DT1_3, DT2_3, AM3, 25 | Name0, Name1, Name2, Name3, Name4, Name5, Name6, Name7, Name8, Name9, Name10, Name11, Name12, Name13, Name14, Name15, 26 | } 27 | 28 | 29 | 30 | static int ToneLength() 31 | { 32 | return 0x80; 33 | } 34 | 35 | static int HeadLength() 36 | { 37 | return 0xa0; 38 | } 39 | 40 | static int PutLength() 41 | { 42 | return System.Enum.GetNames(typeof(ePut)).Length; 43 | } 44 | 45 | static int FxbLength() 46 | { 47 | return HeadLength() + (ToneLength() * PutLength()); 48 | } 49 | 50 | 51 | 52 | public static byte[] New() 53 | { 54 | return new byte[FxbLength()]; 55 | } 56 | 57 | 58 | 59 | static void Get(ref Tone @Tone, byte[] Buffer, int i) 60 | { 61 | int o = HeadLength() + (i * PutLength()); 62 | Tone.aOp[0].AR = Buffer[o + (int)ePut.AR0]; 63 | Tone.aOp[1].AR = Buffer[o + (int)ePut.AR1]; 64 | Tone.aOp[2].AR = Buffer[o + (int)ePut.AR2]; 65 | Tone.aOp[3].AR = Buffer[o + (int)ePut.AR3]; 66 | Tone.aOp[0].DR = Buffer[o + (int)ePut.DR0]; 67 | Tone.aOp[1].DR = Buffer[o + (int)ePut.DR1]; 68 | Tone.aOp[2].DR = Buffer[o + (int)ePut.DR2]; 69 | Tone.aOp[3].DR = Buffer[o + (int)ePut.DR3]; 70 | Tone.aOp[0].SR = Buffer[o + (int)ePut.SR0]; 71 | Tone.aOp[1].SR = Buffer[o + (int)ePut.SR1]; 72 | Tone.aOp[2].SR = Buffer[o + (int)ePut.SR2]; 73 | Tone.aOp[3].SR = Buffer[o + (int)ePut.SR3]; 74 | Tone.aOp[0].RR = Buffer[o + (int)ePut.RR0]; 75 | Tone.aOp[1].RR = Buffer[o + (int)ePut.RR1]; 76 | Tone.aOp[2].RR = Buffer[o + (int)ePut.RR2]; 77 | Tone.aOp[3].RR = Buffer[o + (int)ePut.RR3]; 78 | Tone.aOp[0].SL = Buffer[o + (int)ePut.SL0]; 79 | Tone.aOp[1].SL = Buffer[o + (int)ePut.SL1]; 80 | Tone.aOp[2].SL = Buffer[o + (int)ePut.SL2]; 81 | Tone.aOp[3].SL = Buffer[o + (int)ePut.SL3]; 82 | Tone.aOp[0].TL = Buffer[o + (int)ePut.TL0]; 83 | Tone.aOp[1].TL = Buffer[o + (int)ePut.TL1]; 84 | Tone.aOp[2].TL = Buffer[o + (int)ePut.TL2]; 85 | Tone.aOp[3].TL = Buffer[o + (int)ePut.TL3]; 86 | Tone.aOp[0].KS = Buffer[o + (int)ePut.KS0]; 87 | Tone.aOp[1].KS = Buffer[o + (int)ePut.KS1]; 88 | Tone.aOp[2].KS = Buffer[o + (int)ePut.KS2]; 89 | Tone.aOp[3].KS = Buffer[o + (int)ePut.KS3]; 90 | Tone.aOp[0].ML = Buffer[o + (int)ePut.ML0]; 91 | Tone.aOp[1].ML = Buffer[o + (int)ePut.ML1]; 92 | Tone.aOp[2].ML = Buffer[o + (int)ePut.ML2]; 93 | Tone.aOp[3].ML = Buffer[o + (int)ePut.ML3]; 94 | Tone.aOp[0].DT = Buffer[o + (int)ePut.DT1_0]; 95 | Tone.aOp[1].DT = Buffer[o + (int)ePut.DT1_1]; 96 | Tone.aOp[2].DT = Buffer[o + (int)ePut.DT1_2]; 97 | Tone.aOp[3].DT = Buffer[o + (int)ePut.DT1_3]; 98 | Tone.aOp[0].DT2 = Buffer[o + (int)ePut.DT2_0]; 99 | Tone.aOp[1].DT2 = Buffer[o + (int)ePut.DT2_1]; 100 | Tone.aOp[2].DT2 = Buffer[o + (int)ePut.DT2_2]; 101 | Tone.aOp[3].DT2 = Buffer[o + (int)ePut.DT2_3]; 102 | Tone.aOp[0].AM = Buffer[o + (int)ePut.AM0]; 103 | Tone.aOp[1].AM = Buffer[o + (int)ePut.AM1]; 104 | Tone.aOp[2].AM = Buffer[o + (int)ePut.AM2]; 105 | Tone.aOp[3].AM = Buffer[o + (int)ePut.AM3]; 106 | Tone.AL = Buffer[o + (int)ePut.AL]; 107 | Tone.FB = Buffer[o + (int)ePut.FB]; 108 | 109 | var aChar = new char[] 110 | { 111 | (char)Buffer[o + (int)ePut.Name0], 112 | (char)Buffer[o + (int)ePut.Name1], 113 | (char)Buffer[o + (int)ePut.Name2], 114 | (char)Buffer[o + (int)ePut.Name3], 115 | (char)Buffer[o + (int)ePut.Name4], 116 | (char)Buffer[o + (int)ePut.Name5], 117 | (char)Buffer[o + (int)ePut.Name6], 118 | (char)Buffer[o + (int)ePut.Name7], 119 | (char)Buffer[o + (int)ePut.Name8], 120 | (char)Buffer[o + (int)ePut.Name9], 121 | (char)Buffer[o + (int)ePut.Name10], 122 | (char)Buffer[o + (int)ePut.Name11], 123 | (char)Buffer[o + (int)ePut.Name12], 124 | (char)Buffer[o + (int)ePut.Name13], 125 | (char)Buffer[o + (int)ePut.Name14], 126 | (char)Buffer[o + (int)ePut.Name15], 127 | }; 128 | Tone.Name = ""; 129 | foreach (var Char in aChar) if (Char != 0) Tone.Name += Char.ToString(); 130 | 131 | Tone.Number = i; 132 | } 133 | 134 | 135 | 136 | public static void Put(Tone @Tone, ref byte[] Buffer) 137 | { 138 | if (Tone.IsValid() && Tone.Number < ToneLength()) 139 | { 140 | int o = HeadLength() + (Tone.Number * PutLength()); 141 | Buffer[o + (int)ePut.AR0] = (byte)Tone.aOp[0].AR; 142 | Buffer[o + (int)ePut.AR1] = (byte)Tone.aOp[1].AR; 143 | Buffer[o + (int)ePut.AR2] = (byte)Tone.aOp[2].AR; 144 | Buffer[o + (int)ePut.AR3] = (byte)Tone.aOp[3].AR; 145 | Buffer[o + (int)ePut.DR0] = (byte)Tone.aOp[0].DR; 146 | Buffer[o + (int)ePut.DR1] = (byte)Tone.aOp[1].DR; 147 | Buffer[o + (int)ePut.DR2] = (byte)Tone.aOp[2].DR; 148 | Buffer[o + (int)ePut.DR3] = (byte)Tone.aOp[3].DR; 149 | Buffer[o + (int)ePut.SR0] = (byte)Tone.aOp[0].SR; 150 | Buffer[o + (int)ePut.SR1] = (byte)Tone.aOp[1].SR; 151 | Buffer[o + (int)ePut.SR2] = (byte)Tone.aOp[2].SR; 152 | Buffer[o + (int)ePut.SR3] = (byte)Tone.aOp[3].SR; 153 | Buffer[o + (int)ePut.RR0] = (byte)Tone.aOp[0].RR; 154 | Buffer[o + (int)ePut.RR1] = (byte)Tone.aOp[1].RR; 155 | Buffer[o + (int)ePut.RR2] = (byte)Tone.aOp[2].RR; 156 | Buffer[o + (int)ePut.RR3] = (byte)Tone.aOp[3].RR; 157 | Buffer[o + (int)ePut.SL0] = (byte)Tone.aOp[0].SL; 158 | Buffer[o + (int)ePut.SL1] = (byte)Tone.aOp[1].SL; 159 | Buffer[o + (int)ePut.SL2] = (byte)Tone.aOp[2].SL; 160 | Buffer[o + (int)ePut.SL3] = (byte)Tone.aOp[3].SL; 161 | Buffer[o + (int)ePut.TL0] = (byte)Tone.aOp[0].TL; 162 | Buffer[o + (int)ePut.TL1] = (byte)Tone.aOp[1].TL; 163 | Buffer[o + (int)ePut.TL2] = (byte)Tone.aOp[2].TL; 164 | Buffer[o + (int)ePut.TL3] = (byte)Tone.aOp[3].TL; 165 | Buffer[o + (int)ePut.KS0] = (byte)Tone.aOp[0].KS; 166 | Buffer[o + (int)ePut.KS1] = (byte)Tone.aOp[1].KS; 167 | Buffer[o + (int)ePut.KS2] = (byte)Tone.aOp[2].KS; 168 | Buffer[o + (int)ePut.KS3] = (byte)Tone.aOp[3].KS; 169 | Buffer[o + (int)ePut.ML0] = (byte)Tone.aOp[0].ML; 170 | Buffer[o + (int)ePut.ML1] = (byte)Tone.aOp[1].ML; 171 | Buffer[o + (int)ePut.ML2] = (byte)Tone.aOp[2].ML; 172 | Buffer[o + (int)ePut.ML3] = (byte)Tone.aOp[3].ML; 173 | Buffer[o + (int)ePut.DT1_0] = (byte)Tone.aOp[0].DT; 174 | Buffer[o + (int)ePut.DT1_1] = (byte)Tone.aOp[1].DT; 175 | Buffer[o + (int)ePut.DT1_2] = (byte)Tone.aOp[2].DT; 176 | Buffer[o + (int)ePut.DT1_3] = (byte)Tone.aOp[3].DT; 177 | Buffer[o + (int)ePut.DT2_0] = (byte)Tone.aOp[0].DT2; 178 | Buffer[o + (int)ePut.DT2_1] = (byte)Tone.aOp[1].DT2; 179 | Buffer[o + (int)ePut.DT2_2] = (byte)Tone.aOp[2].DT2; 180 | Buffer[o + (int)ePut.DT2_3] = (byte)Tone.aOp[3].DT2; 181 | Buffer[o + (int)ePut.AM0] = (byte)Tone.aOp[0].AM; 182 | Buffer[o + (int)ePut.AM1] = (byte)Tone.aOp[1].AM; 183 | Buffer[o + (int)ePut.AM2] = (byte)Tone.aOp[2].AM; 184 | Buffer[o + (int)ePut.AM3] = (byte)Tone.aOp[3].AM; 185 | Buffer[o + (int)ePut.AL] = (byte)Tone.AL; 186 | Buffer[o + (int)ePut.FB] = (byte)Tone.FB; 187 | Buffer[o + (int)ePut.Mask] = 0xf << 3; 188 | 189 | if (String.IsNullOrWhiteSpace(Tone.Name)) 190 | { 191 | Tone.Name = Tone.Number.ToString(); 192 | } 193 | Buffer[o + (int)ePut.Name0] = (byte)((Tone.Name.Length > 0) ? Tone.Name[0] : 0); 194 | Buffer[o + (int)ePut.Name1] = (byte)((Tone.Name.Length > 1) ? Tone.Name[1] : 0); 195 | Buffer[o + (int)ePut.Name2] = (byte)((Tone.Name.Length > 2) ? Tone.Name[2] : 0); 196 | Buffer[o + (int)ePut.Name3] = (byte)((Tone.Name.Length > 3) ? Tone.Name[3] : 0); 197 | Buffer[o + (int)ePut.Name4] = (byte)((Tone.Name.Length > 4) ? Tone.Name[4] : 0); 198 | Buffer[o + (int)ePut.Name5] = (byte)((Tone.Name.Length > 5) ? Tone.Name[5] : 0); 199 | Buffer[o + (int)ePut.Name6] = (byte)((Tone.Name.Length > 6) ? Tone.Name[6] : 0); 200 | Buffer[o + (int)ePut.Name7] = (byte)((Tone.Name.Length > 7) ? Tone.Name[7] : 0); 201 | Buffer[o + (int)ePut.Name8] = (byte)((Tone.Name.Length > 8) ? Tone.Name[8] : 0); 202 | Buffer[o + (int)ePut.Name9] = (byte)((Tone.Name.Length > 9) ? Tone.Name[9] : 0); 203 | Buffer[o + (int)ePut.Name10] = (byte)((Tone.Name.Length > 10) ? Tone.Name[10] : 0); 204 | Buffer[o + (int)ePut.Name11] = (byte)((Tone.Name.Length > 11) ? Tone.Name[11] : 0); 205 | Buffer[o + (int)ePut.Name12] = (byte)((Tone.Name.Length > 12) ? Tone.Name[12] : 0); 206 | Buffer[o + (int)ePut.Name13] = (byte)((Tone.Name.Length > 13) ? Tone.Name[13] : 0); 207 | Buffer[o + (int)ePut.Name14] = (byte)((Tone.Name.Length > 14) ? Tone.Name[14] : 0); 208 | Buffer[o + (int)ePut.Name15] = (byte)((Tone.Name.Length > 15) ? Tone.Name[15] : 0); 209 | } 210 | } 211 | 212 | 213 | 214 | public static bool IsValid(byte[] Buffer) 215 | { 216 | return (Buffer[0x00] == (byte)'C' 217 | && Buffer[0x01] == (byte)'c' 218 | && Buffer[0x02] == (byte)'n' 219 | && Buffer[0x03] == (byte)'K' 220 | && Buffer[0x08] == (byte)'F' 221 | && Buffer[0x09] == (byte)'B' 222 | && Buffer[0x0a] == (byte)'C' 223 | && Buffer[0x0b] == (byte)'h' 224 | && Buffer[0x0f] == 1 225 | && Buffer[0x10] == (byte)'V' 226 | && Buffer[0x11] == (byte)'O' 227 | && Buffer[0x12] == (byte)'P' 228 | && Buffer[0x13] == (byte)'M' 229 | && Buffer[0x17] == 1 230 | && Buffer[0x1b] == 0x80 231 | && Buffer[0x9e] == 0x23 232 | && Buffer[0x9f] == 0x80 233 | ); 234 | } 235 | 236 | 237 | 238 | public static void Reader(string Path, Option @Option) 239 | { 240 | var Buffer = ReadByte(Path); 241 | if (Buffer.Length == FxbLength() && IsValid(Buffer)) 242 | { 243 | Tone vTone = new Tone(); 244 | 245 | var BufferMuc = ""; 246 | var BufferDat = Dat.New(); 247 | var BufferFmp = ""; 248 | var BufferPmd = ""; 249 | var BufferFMtrial = FMtrial.New(); 250 | var BufferRme = Rme.New(); 251 | var BufferDx7 = DX7.New(); 252 | var BufferVmm = Vmm.New(); 253 | 254 | for (int i = 0; i < ToneLength(); ++i) 255 | { 256 | Get(ref vTone, Buffer, i); 257 | 258 | if (Option.bMuc) Muc.Put(vTone, ref BufferMuc); 259 | if (Option.bDat) Dat.Put(vTone, ref BufferDat); 260 | if (Option.bFmp) Fmp.Put(vTone, ref BufferFmp); 261 | if (Option.bPmd) Pmd.Put(vTone, ref BufferPmd); 262 | if (Option.bFMtrial) FMtrial.Put(vTone, ref BufferFMtrial); 263 | if (Option.bRme) Rme.Put(vTone, ref BufferRme); 264 | if (Option.bDx7) DX7.Put(vTone, ref BufferDx7); 265 | if (Option.bVmm) Vmm.Put(vTone, ref BufferVmm); 266 | } 267 | 268 | if (Option.bMuc) Muc.Writer(Path, BufferMuc); 269 | if (Option.bDat) Dat.Writer(Path, BufferDat); 270 | if (Option.bFmp) Fmp.Writer(Path, BufferFmp); 271 | if (Option.bPmd) Pmd.Writer(Path, BufferPmd); 272 | if (Option.bFMtrial) FMtrial.Writer(Path, BufferFMtrial); 273 | if (Option.bRme) Rme.Writer(Path, BufferRme); 274 | if (Option.bDx7) DX7.Writer(Path, BufferDx7); 275 | if (Option.bVmm) Vmm.Writer(Path, BufferVmm); 276 | } 277 | } 278 | 279 | 280 | 281 | public static void Reader(string[] aPath, Option @Option) 282 | { 283 | foreach (var Path in aPath) 284 | { 285 | if (!String.IsNullOrWhiteSpace(Path) && Extension(Path).ToLower() == ".fxb") Reader(Path, Option); 286 | } 287 | } 288 | 289 | 290 | 291 | public static void Writer(string Path, byte[] Buffer) 292 | { 293 | Buffer[0x00] = (byte)'C'; 294 | Buffer[0x01] = (byte)'c'; 295 | Buffer[0x02] = (byte)'n'; 296 | Buffer[0x03] = (byte)'K'; 297 | Buffer[0x08] = (byte)'F'; 298 | Buffer[0x09] = (byte)'B'; 299 | Buffer[0x0a] = (byte)'C'; 300 | Buffer[0x0b] = (byte)'h'; 301 | Buffer[0x0f] = 1; 302 | Buffer[0x10] = (byte)'V'; 303 | Buffer[0x11] = (byte)'O'; 304 | Buffer[0x12] = (byte)'P'; 305 | Buffer[0x13] = (byte)'M'; 306 | Buffer[0x17] = 1; 307 | Buffer[0x1b] = 0x80; 308 | Buffer[0x9e] = 0x23; 309 | Buffer[0x9f] = 0x80; 310 | 311 | WriteByte(ChangeExtension(Path, ".fxb"), Buffer); 312 | } 313 | } 314 | } 315 | -------------------------------------------------------------------------------- /FM-SoundConvertor/bin/Release/FM-SoundConvertor.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DM-88mkII/FM-SoundConvertor/4a8c0253bc8ca2ff44a67a49cc1b8fba3eb218e2/FM-SoundConvertor/bin/Release/FM-SoundConvertor.exe -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 D.M.88 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FM-SoundConvertor 2 | [MUCOM88](https://onitama.tv/mucom88/) に付属している、FmToneEditor で作成した音色を活用する為の、Windows用コマンドラインツールです。 3 | 4 | 以下の音色定義を相互変換します。 5 | ||入出力拡張子|入力定義|出力定義|注釈| 6 | |:-:|:-:|:-:|:-:|:-:| 7 | |MUCOM88|.muc|MUCOM形式
mmldrv形式|MUCOM形式|| 8 | |MUCOM88音色ファイル|.dat|dat形式|dat形式|| 9 | |FMP|.mwi|旧式
F形式
FA形式
FC形式|FA形式|| 10 | |PMD|.mml|PMD形式|PMD形式|| 11 | |VOPM|.fxb|fxb形式|fxb形式|| 12 | |FM trial v4.3|.fxb|fxb形式|fxb形式|| 13 | |Retro Music Editor v1.9.1|.rtp||rtp形式|出力のみ対応| 14 | |VGM Music Maker|.vgi||vgi形式|出力のみ対応| 15 | |DX7|.syx||SysEx形式|出力のみ対応| 16 | 17 | 実行ファイルのダウンロードは[こちら](https://github.com/DM-88mkII/FM-SoundConvertor/blob/master/FM-SoundConvertor/bin/Release/FM-SoundConvertor.exe) 18 | 19 |
20 | 21 | # 使い方 22 | ~~~ 23 | FM-SoundConvertor.exe 変換オプション 入力ファイル 24 | 25 | 変換オプション 26 | -muc 拡張子が .muc ではない入力ファイルの音色定義を、MUCOM形式に変換し .muc ファイルを出力します。 27 | -dat 拡張子が .dat ではない入力ファイルの音色定義を、dat形式に変換し .dat ファイルを出力します。 28 | -fmp 拡張子が .mwi ではない入力ファイルの音色定義を、FA形式に変換し .mwi ファイルを出力します。 29 | -pmd 拡張子が .mml ではない入力ファイルの音色定義を、PMD形式に変換し .mml ファイルを出力します。 30 | -vopm 拡張子が .fxb ではない入力ファイルの音色定義を、fxb形式に変換し .fxb ファイルを出力します。 31 | -fmtrial 拡張子が .fxb ではない入力ファイルの音色定義を、fxb形式に変換し .fxb ファイルを出力します。 32 | -rme 拡張子が .rtp ではない入力ファイルの音色定義を、rtp形式に変換し .rtp ファイルを出力します。 33 | -vmm 拡張子が .vgi ではない入力ファイルの音色定義を、vgi形式に変換し .vgi ファイルを出力します。 34 | -dx7 拡張子が .syx ではない入力ファイルの音色定義を、SysEx形式に変換し .syx ファイルを出力します。 35 | 36 | 変換オプションと入力ファイルは、複数個の指定が可能です。 37 | 注意:-vopm と -fmtrial は、同じ拡張子のファイルを出力してしまうので、併用できません。 38 | ~~~ 39 | 40 |
41 | 42 | # 共通仕様 43 | 以下の条件の音色定義は無効と解釈し、出力しません。 44 | * 音色番号が 0 ~ 255 の範囲外 45 | * VOPM の場合は、0 ~ 127 の範囲外 46 | * 全オペレーターの AR が 0 47 | 48 |
49 | 50 | # MUCOM88 音色番号解釈の独自仕様 51 | 音色番号を無記入にすると、直前の音色番号+1 として解釈します。 52 | ~~~ 53 | ;初回は音色番号0 と解釈する 54 | @:{ 55 | 6, 2 56 | 22, 22, 0, 14, 7, 16, 1, 1, 0 57 | 17, 11, 0, 14, 3, 57, 1, 15, 7 58 | 21, 10, 4, 14, 2, 20, 1, 0, 2 59 | 31, 0, 4, 15, 0, 0, 1, 1, 5,"Bass"} 60 | 61 | ;指定された音色番号10 と解釈する 62 | @10:{ 63 | 7, 3 64 | 26, 25, 0, 14, 2, 15, 3, 0, 1 65 | 25, 16, 10, 14, 6, 15, 3, 0, 7 66 | 23, 23, 10, 14, 10, 0, 3, 1, 4 67 | 31, 12, 20, 15, 1, 0, 0, 2, 5,"Kick"};o2c 68 | 69 | ;連続した音色番号11 と解釈する 70 | @:{ 71 | 7, 5 72 | 24, 21, 0, 14, 3, 3, 0, 15, 0 73 | 31, 14, 16, 15, 1, 0, 0, 5, 3 74 | 31, 11, 15, 15, 1, 0, 0, 7, 7 75 | 31, 16, 20, 15, 1, 0, 0, 9, 4,"Snare"};o1g 76 | ~~~ 77 | 独自の音色ライブラリの編集や、楽曲用の音色セットが作りやすくなるかなと。 78 | 79 |
80 | 81 | # .muc 内の MUCOM形式 と mmldrv形式 の自動判別について 82 | MUCOM形式 83 | - 行頭が、半角スペース2つの後に@ 84 | ~~~ 85 | ;最初の2つのパラメータは、FB、AL の順 86 | @:{ 87 | 6, 2 88 | 22, 22, 0, 14, 7, 16, 1, 1, 0 89 | 17, 11, 0, 14, 3, 57, 1, 15, 7 90 | 21, 10, 4, 14, 2, 20, 1, 0, 2 91 | 31, 0, 4, 15, 0, 0, 1, 1, 5,"Bass"} 92 | 93 | @ 94 | 6 2 95 | 22 22 0 14 7 16 1 1 0 96 | 17 11 0 14 3 57 1 15 7 97 | 21 10 4 14 2 20 1 0 2 98 | 31 0 4 15 0 0 1 1 5 99 | ~~~ 100 | 101 | mmldrv形式 102 | - 行頭が、@ 103 | ~~~ 104 | ;最初の2つのパラメータは、AL、FB の順 105 | @ 106 | 2 6 107 | 22 22 0 14 7 16 1 1 0 0 0 108 | 17 11 0 14 3 57 1 15 7 0 0 109 | 21 10 4 14 2 20 1 0 2 0 0 110 | 31 0 4 15 0 0 1 1 5 0 0 111 | ~~~ 112 | 113 | 形式の違いによる、FB と AL の順序にご注意ください。 114 | 115 |
116 | 117 | # その他 118 | Windows環境での不要なファイルを嫌い、.NET Framework で作成しましたが、.NET Core への転用は容易かと思います。 119 | 120 | 音色定義に特化した簡易パーサーの為、ユースケースによっては正常に変換できない場合があるかもしれません。 121 | 122 | 自分用に作ったので、気の利いたものではありませんが、何かのお役に立てば幸いです。 123 | --------------------------------------------------------------------------------