Skip to content

Commit

Permalink
ロジックの修正。
Browse files Browse the repository at this point in the history
C140対応。
  • Loading branch information
kuma committed Oct 7, 2018
1 parent 9f4a0e3 commit bafb809
Show file tree
Hide file tree
Showing 37 changed files with 12,918 additions and 8,589 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
[機能、特徴]
[VGM]
・メガドライブ2台分の音源構成(YM2612 + SN76489 + RF5C164)*2にそったVGMを生成します。
(他にYM2151,YM2203,YM2608,YM2610B,SegaPCM,HuC6280に対応しています。)
(他にYM2151,YM2203,YM2608,YM2610B,SegaPCM,HuC6280,C140に対応しています。)
・FM音源(YM2612)は最大6ch(この内1chを効果音モードに指定すると更に3ch)使用可能です。
・PCM(YM2612)を1ch使用可能です。(FM音源1chと排他的に使用します。)
・PSG(DCSG)音源(SN76489)は4ch(この内1chはノイズチャンネル)使用可能です。
・MEGA-CDのPCM音源(RF5C164)は8ch使用可能です。
・以上、メガドライブ音源系だけで最大42ch(その他合計で184ch)使用可能です。
・以上、メガドライブ音源系だけで最大42ch(その他合計で256ch)使用可能です。
(但し、RF5C164の2台目についてはVGMPlayでは今のところ正式には対応しておらず、鳴らすにはMDPlayerが必要です。)
・MMLの仕様はFMP7(開発:Guu氏)に似せています。

Expand Down
279 changes: 279 additions & 0 deletions mml2vgm/Core/Common.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
Expand All @@ -23,5 +24,283 @@ public static int CheckRange(int n, int min, int max)

return r;
}

public static byte[] GetPCMDataFromFile(string path, clsPcm instPCM, out bool is16bit)
{
string fnPcm = Path.Combine(path, instPCM.fileName);
is16bit = false;

if (!File.Exists(fnPcm))
{
msgBox.setErrMsg(string.Format("PCMファイルの読み込みに失敗しました。(filename:{0})", instPCM.fileName));
return null;
}

// ファイルの読み込み
byte[] buf = File.ReadAllBytes(fnPcm);

if (buf.Length < 4)
{
msgBox.setErrMsg("PCMファイル:不正なRIFFヘッダです。");
return null;
}
if (buf[0] != 'R' || buf[1] != 'I' || buf[2] != 'F' || buf[3] != 'F')
{
msgBox.setErrMsg("PCMファイル:不正なRIFFヘッダです。");
return null;
}

// サイズ取得
int fSize = buf[0x4] + buf[0x5] * 0x100 + buf[0x6] * 0x10000 + buf[0x7] * 0x1000000;

if (buf[0x8] != 'W' || buf[0x9] != 'A' || buf[0xa] != 'V' || buf[0xb] != 'E')
{
msgBox.setErrMsg("PCMファイル:不正なRIFFヘッダです。");
return null;
}

try
{
int p = 12;
byte[] des = null;

while (p < fSize + 8)
{
if (buf[p + 0] == 'f' && buf[p + 1] == 'm' && buf[p + 2] == 't' && buf[p + 3] == ' ')
{
p += 4;
int size = buf[p + 0] + buf[p + 1] * 0x100 + buf[p + 2] * 0x10000 + buf[p + 3] * 0x1000000;
p += 4;
int format = buf[p + 0] + buf[p + 1] * 0x100;
if (format != 1)
{
msgBox.setErrMsg(string.Format("PCMファイル:無効なフォーマットです。({0})", format));
return null;
}

int channels = buf[p + 2] + buf[p + 3] * 0x100;
if (channels != 1)
{
msgBox.setErrMsg(string.Format("PCMファイル:仕様(mono)とは異なるチャネル数です。({0})", channels));
return null;
}

int samplerate = buf[p + 4] + buf[p + 5] * 0x100 + buf[p + 6] * 0x10000 + buf[p + 7] * 0x1000000;
if (samplerate != 8000 && samplerate != 16000 && samplerate != 18500 && samplerate != 14000)
{
msgBox.setWrnMsg(string.Format("PCMファイル:仕様(8KHz/14KHz/16KHz/18.5KHz)とは異なるサンプリングレートです。({0})", samplerate));
//return null;
}

int bytepersec = buf[p + 8] + buf[p + 9] * 0x100 + buf[p + 10] * 0x10000 + buf[p + 11] * 0x1000000;
if (bytepersec != 8000)
{
// msgBox.setWrnMsg(string.Format("PCMファイル:仕様とは異なる平均データ割合です。({0})", bytepersec));
// return null;
}

int bitswidth = buf[p + 14] + buf[p + 15] * 0x100;
if (bitswidth != 8 && bitswidth != 16)
{
msgBox.setErrMsg(string.Format("PCMファイル:仕様(8bit/16bit)とは異なる1サンプルあたりのビット数です。({0})", bitswidth));
return null;
}

is16bit = bitswidth == 16;

int blockalign = buf[p + 12] + buf[p + 13] * 0x100;
if (blockalign != (is16bit ? 2 : 1))
{
msgBox.setErrMsg(string.Format("PCMファイル:無効なデータのブロックサイズです。({0})", blockalign));
return null;
}


p += size;
}
else if (buf[p + 0] == 'd' && buf[p + 1] == 'a' && buf[p + 2] == 't' && buf[p + 3] == 'a')
{
p += 4;
int size = buf[p + 0] + buf[p + 1] * 0x100 + buf[p + 2] * 0x10000 + buf[p + 3] * 0x1000000;
p += 4;

des = new byte[size];
Array.Copy(buf, p, des, 0x00, size);
p += size;
}
else
{
p += 4;
int size = buf[p + 0] + buf[p + 1] * 0x100 + buf[p + 2] * 0x10000 + buf[p + 3] * 0x1000000;
p += 4;

p += size;
}
}

// volumeの加工
if (is16bit)
{
for (int i = 0; i < des.Length; i += 2)
{
//16bitのwavファイルはsignedのデータのためそのままボリューム変更可能
int b = (int)((short)(des[i] | (des[i + 1] << 8)) * instPCM.vol * 0.01);
b = (b > 0xffff) ? 0xffff : b;
des[i] = (byte)(b & 0xff);
des[i + 1] = (byte)((b & 0xff00) >> 8);
}
}
else
{
for (int i = 0; i < des.Length; i++)
{
//8bitのwavファイルはunsignedのデータのためsignedのデータに変更してからボリューム変更する
int d = des[i];
//signed化
d -= 0x80;
d = (int)(d * instPCM.vol * 0.01);
//clip
d = (d > 127) ? 127 : d;
d = (d < -128) ? -128 : d;
//unsigned化
d += 0x80;

des[i] = (byte)d;
}
}

return des;
}
catch
{
msgBox.setErrMsg("PCMファイル:不正或いは未知のチャンクを持つファイルです。");
return null;
}
}

public static void SetUInt32bit31(byte[] buf, int ptr, UInt32 value,bool sw=false)
{
buf[ptr + 0] = (byte)(value & 0xff);
buf[ptr + 1] = (byte)((value & 0xff00) >> 8);
buf[ptr + 2] = (byte)((value & 0xff0000) >> 16);
buf[ptr + 3] = (byte)((value & 0x7f000000) >> 24);
if (sw) buf[ptr + 3] |= 0x80;
}

public static byte[] PcmPadding(ref byte[] buf, ref long size, byte paddingData, int paddingSize)
{
byte[] newBuf = new byte[size + (paddingSize - (size % paddingSize))];
for (int i = (int)size; i < newBuf.Length; i++) newBuf[i] = paddingData;
Array.Copy(buf, newBuf, size);
buf = newBuf;
size = buf.Length;
return newBuf;
}

public static List<string> DivParts(string parts,Dictionary<enmChipType,ClsChip[]> chips)
{
List<string> ret = new List<string>();
string a = "";
int k = 1;
int m = 0;
string n0 = "";

try
{
for (int i = 0; i < parts.Length; i++)
{
if (m == 0 && parts[i] >= 'A' && parts[i] <= 'Z')
{
a = parts[i].ToString();
if (i + 1 < parts.Length && parts[i + 1] >= 'a' && parts[i + 1] <= 'z')
{
a += parts[i + 1].ToString();
i++;
}
else
{
a += " ";
}

k = GetChMax(a, chips) > 9 ? 2 : 1;
n0 = "";

}
else if (m == 0 && parts[i] == ',')
{
n0 = "";
}
else if (m == 0 && parts[i] == '-')
{
m = 1;
}
else if (parts[i] >= '0' && parts[i] <= '9')
{
string n = parts.Substring(i, k);
if (k == 2 && i + 1 < parts.Length)
{
i++;
}

if (m == 0)
{
n0 = n;

if (!int.TryParse(n0, out int s)) return null;
string p = string.Format("{0}{1:00}", a, s);
ret.Add(p);
}
else
{
string n1 = n;

if (!int.TryParse(n0, out int s)) return null;
if (!int.TryParse(n1, out int e)) return null;
if (s >= e) return null;

do
{
s++;
string p = string.Format("{0}{1:00}", a, s);
if (ret.Contains(p)) return null;
ret.Add(p);
} while (s < e);

i++;
m = 0;
n0 = "";
}
}
else
{
return null;
}
}
}
catch
{
//パート解析に失敗
msgBox.setErrMsg(string.Format("不正なパート定義です。({0})", parts), "", 0);
}

return ret;
}

private static int GetChMax(string a, Dictionary<enmChipType,ClsChip[]> chips)
{
foreach (KeyValuePair<enmChipType, ClsChip[]> kvp in chips)
{
foreach (ClsChip chip in kvp.Value)
{
if (chip.Ch[0].Name.Substring(0, 2) == a)
{
return chip.ChMax;
}
}
}

return 0;
}

}
}
28 changes: 2 additions & 26 deletions mml2vgm/Core/Const.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,32 +15,8 @@ public static class Const
public const int INSTRUMENT_M_OPERATOR_SIZE = 11;
public const int WF_INSTRUMENT_SIZE = 33;

public const string TITLENAME = "TITLENAME";
public const string TITLENAMEJ = "TITLENAMEJ";
public const string GAMENAME = "GAMENAME";
public const string GAMENAMEJ = "GAMENAMEJ";
public const string SYSTEMNAME = "SYSTEMNAME";
public const string SYSTEMNAMEJ = "SYSTEMNAMEJ";
public const string COMPOSER = "COMPOSER";
public const string COMPOSERJ = "COMPOSERJ";
public const string RELEASEDATE = "RELEASEDATE";
public const string CONVERTED = "CONVERTED";
public const string NOTES = "NOTES";
public const string PARTNAME = "PART";
public const string CLOCKCOUNT = "CLOCKCOUNT";
public const string FMF_NUM = "FMF-NUM";
public const string PSGF_NUM = "PSGF-NUM";
public const string FORCEDMONOPARTYM2612 = "FORCEDMONOPARTYM2612";
public const string VERSION = "VERSION";
public const string PRIMARY = "PRIMARY";
public const string SECONDARY = "SECONDARY";
public const string FORMAT = "FORMAT";
public const string XGMBASEFRAME = "XGMBASEFRAME";
public const string OCTAVEREV = "OCTAVE-REV";

public const string NOTE = "c_d_ef_g_a_b";

readonly public static string[] IDName = new string[] { Const.PRIMARY, Const.SECONDARY };

/*
C ド 261.62
Expand Down Expand Up @@ -134,8 +110,8 @@ B シ 493.88 1.887776163901842
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
//0x90 0x94 0x98 0x9c
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
//0xa0 0xa4 HuC6280 0xa8 0xac
0x00,0x00,0x00,0x00, 0x99,0x9e,0x36,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00
//0xa0 0xa4 HuC6280 0xa8 C140 0xac
0x00,0x00,0x00,0x00, 0x99,0x9e,0x36,0x00, 0x00,0x12,0x7a,0x00, 0x00,0x00,0x00,0x00
};

readonly public static byte[] xhDat = new byte[] {
Expand Down
13 changes: 10 additions & 3 deletions mml2vgm/Core/Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<DefineConstants>
</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
Expand All @@ -40,7 +41,9 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="chips\C140.cs" />
<Compile Include="chips\clsChip.cs" />
<Compile Include="chips\clsOPN.cs" />
<Compile Include="chips\HuC6280.cs" />
<Compile Include="chips\RF5C164.cs" />
<Compile Include="chips\segaPcm.cs" />
Expand All @@ -57,12 +60,16 @@
<Compile Include="Const.cs" />
<Compile Include="Core.cs" />
<Compile Include="dv.cs" />
<Compile Include="EncAdpcmA.cs" />
<Compile Include="chips\EncAdpcmA.cs" />
<Compile Include="Enums.cs" />
<Compile Include="Information.cs" />
<Compile Include="Line.cs" />
<Compile Include="log.cs" />
<Compile Include="MML.cs" />
<Compile Include="mml2vgm.cs" />
<Compile Include="MMLAnalyze.cs" />
<Compile Include="msgBox.cs" />
<Compile Include="Note.cs" />
<Compile Include="partWork.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
Expand Down
Loading

1 comment on commit bafb809

@knight-ryu12
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UwU

Please sign in to comment.