├── .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 |
--------------------------------------------------------------------------------