主にMSX関係のコンテンツが置いてあります。

ゲーム音声の模索(途中)

MSXでゲーム中にPCMボイスのようなものをSCCで実現できないかと模索していました。

とある方法を思いつき、再生することに一応は成功しました。wavファイルにしたので聞いてみてください。

wavファイル(実機録音)

そこそこクリアに聞こえたかと思います。

これはSCMDで鳴らしていてMMLは以下の通りです。

;初期設定-----------------------------------------
tempotype=["calculation"]
@title=["voice test"]
@author=["めが"]
@original=[""]
@comment=[""]

@s"100"=[0000000000ff0000000000000000ffff000000000000ffff00ff0000000000ff]
@s"101"=[0000000000000000000000000000000000000000000000ff000000ffffff0000]
@s"102"=[000000fdfffd0000fdff000000fffdfffdfdffff00fd0000fdfdfffdfdfdfdff]
@s"103"=[00fdfdfd00fdff00ffff00fffdfdfffffdfdfffffcff00fffdfdfdfffffffdfd]
@s"104"=[fffdfdff00fffffffffffdff00fffffffffffdfffdffff0000fffdfdff00ffff]
@s"105"=[0000ffff00ff0000fffdfdfffffdffff000000fffd000100fffffffffd00fdfd]
@s"106"=[0000ffff00ffff0000fdfc000100000000fcff00ffffffff000000fd0101fdfd]
@s"107"=[0300000000ff0000fd01fdfd00000000fffd0000fdfdff00ffff0003fffffffd]
@s"108"=[0000ff0000010000ff0000ffff01030404010000fffffffffffffffdfffffffd]
@s"109"=[0d0dfdfdfcf8fd0f1703fafcfd050a05fdfbfffbf8fdfcfbf8f6fa0f06f4faf6]
@s"110"=[05080c00f800fd080503fdfdfbf8fd01faf8fbf3fb0e0aecf2121403fffdfbf6]
@s"111"=[0405f8fff7ec0c0efafaf6fcf3fa0ef7e9f6120cee00f8fb03fdfbf60d12f6e5]
@s"112"=[0500ecf6fd000400f3e9e6f8fb2605daed030dfafcf4ec050afa0a04d7e1f1ec]
@s"113"=[2c14e6cacdf8331ceefa0f1ff805fbe6fbf8f1261ff1e8d6cf2c120ae91214e4]
@s"114"=[3bf1e13b0c031f13f1e1dbfb05eed21d0f0332e1f136f30a31f1e6eebb1b09c0]
@s"115"=[520ddc54d2fb29ec4325fb29dad8d2a35c09df43c4ff21e15723002edadfc38d]
@s"116"=[4d002140d117ece95c1a1817cde9c8d21c141a29ec08fdf833280c17dae6d4cc]
@s"117"=[0d0f061708011d1b141c0300e4ecece608080a1705001d1a1c1c0103e4e6ece6]
@s"118"=[0f08111c0503140a14170303dde4ede514110a2400fb1303171a0003d8dcffe1]
@s"119"=[3d340a3addee06f338160ce9b6a606ed3f400f34dcecfd00491613e8b7a0eee9]
@s"120"=[5a481229c5fddc1f521a21c5c383fbf861481d23ae05d23640241ac0ca800ddf]
@s"121"=[531a36fbc3fcb331215103dcb89200b851fd49e9d1eeb1291c57fce8ac98e4bb]
@s"122"=[4d085ffbfbd2da0c2c3c1cf3bba1d2ce2e263224eee9d8091a3111eee6b6f7d4]
@s"123"=[25f72e0612fdfb05fcfbec03e40eee18fb1c060a05f60ff812ff0afdfbf3f8f8]
@s"124"=[03040e0403fafafb050d0e0d0100f7fb0005080301fafd000a0a0f0600f8f8fa]
@s"125"=[0104050504040101030406080808050300fdfdfd000101030100fffdfdfcfdfd]
@s"126"=[00000000000000000000000300030303030001000001030303030101000000ff]
@s"127"=[0000000101000000000000000001010000000000000000000000000000ff00ff]
@s"128"=[00000000000000000000000000000000000000000000000000000000ffffffff]
@s"129"=[000000000000000000000000000000000000000000000000ffffffffffffffff]
@s"130"=[0301fa0001fcfc0000fafd0301fbfc0300f70104fffafd00fffcff00fffcf4fc]
@s"131"=[0500f8000a03fcfcfd00fdfbfb0001fdf8fd0303fffdfd030501fdff0401fbfd]
@s"132"=[050a09090d0c06040100010304040401fcfaf8f8f2f4f7f6f6f7f8f4f7f8f6fa]
@s"133"=[0004060908090808060504000000fffdfdfbfbfaf8f8f8f8fbfbfbfbfbfbfcfd]
@s"134"=[000303030303040403030000fdfcfbfbfbfbfdfdfdfffdfdfdfdfdfdfdfdffff]
@s"135"=[00000101030304040303010000fffdfdfdfdfdfdfdfdfcfcfbfbfbfbfcfcfdff]
@s"136"=[00010303030303030303010000fffdfdfcfcfcfcfcfcfcfbfbfbfbfbfbfdfdff]
@s"137"=[0001030303030304030301010000fffdfdfdfcfdfcfcfbfafaf8fafbfbfcfdff]
@s"138"=[00030303040405050504030300000000fffdfdfbfbfaf7f6f6f7f8f8fbfcfdff]
@s"139"=[00030304050406090a0a0a0906050400fcf8f4f1f3f2f1f8faf6fbfbf8fbfdfd]
@s"140"=[0404090c09080503010a0c0904f8eee3d8d6dfddddeffbf808170f0a01fff6fc]
@s"141"=[1744494a533f230f05ff0cfd031212f8f6eddbd6e5f30303f6dfc9b1b6c8d6e3]
@s"142"=[21464c414a46250f09130f1718181303e8d8cdc0c6d7eaf8ffeed4b1c0d1dae3]
@s"143"=[23525746565236140d14141a0e161a0cece6dbc8c3ced8e5eddac4acc3d4d7da]
@s"144"=[25434d4c56513a2518171a1c0d1a2309f6f1e0c9cfd4d8e5e5d1b3aac5c4c0ec]
@s"145"=[243b3a374f3d292420202524141d1c0af3ecddd2d7e1e4f1eecfb7adb6bdcae8]
@s"146"=[2a443f3d482e1f1b211c2a2d1d232406eae6dcd4dfeeeefceccead9ca6bcd2f1]
@s"147"=[1f3a3c3b37240a0c1711243b2e232909eaeedbd3e5f6e903f8dabaa6a4bfd8ea]
@s"148"=[2931312f26ff0c0e041a482c2d2e09ecefd3d1e9fafc1c0aeedbb79cb1cad8f4]
@s"149"=[232e363714120e00fb292823291ffdf2e3d6dbecf31a2312fdefb89fb2c6cdf4]
@s"150"=[1a37443c250ff8e5ee051821332e0ffbe4cdcfe4ff20333320ffc4a0a3b1c3ed]
@s"151"=[263d3b2d13f8e4e3f811252e3c2c0cf8e4d2e5f30e2d372e1df1b39b98a6c3e9]
@s"152"=[0f2929251705f8f4f60f1b252f291100e6dfe9f3051b241f14eec9afadbdd2e8]
@s"153"=[12181a14050105fc111d1c23200a01efe6f6fa03181a1a17fadfc9bbc0d4ddf1]
@s"154"=[0e1716110e06030a0e121a1a170f03fffcf700060a130f00ecd3c4c4cdd7e8fb]
@s"155"=[121a16120c03000811172026211406fcf2eef3fd0612160af8e1cdc1c5cfddf2]
@s"156"=[081f1a130a04fd030f1c242c291c05f2e6dfe8fa0a1b211a08efd2bdbac6d7ec]
@s"157"=[0f18120900fdfd091c262c2d1f08f1e4dfe5f80c1a252111fce1c9bbc3dae9fa]
@s"158"=[0508090a0c0a0f181a1b1a1309fff6eff3fc040d14160f01eedacdcad3dce8f8]
@s"159"=[0c0f0d0f0e080d14171b1f1b0e04f7edeef4fd0611141205f6e1cfc5ccdce8f6]
@s"160"=[0d130e120f0d121a1c1f201408fbece4e5edf808131a160dfceadacecfdbe6f2]
@s"161"=[0e131d231c1a160a030801fffff7f3ededf4000c1a1f1f1704efd7c5c3d1ddf3]
@s"162"=[0a121b1f1b170f04fffbf6fbfbfd000004090d11110f0c04faead4ccd1dbe4f7]
@s"163"=[080a131712110c0404fd000003040508080808040300fdf6ede5e4e6e4ecf2f7]
@s"164"=[04060d0e0a0d0a0a0c0c0a050605080906060103fffcf7ede4e1e9eeedf8f7f8]
@s"165"=[04060a08060a090e0e0e0a0909080a0601fffdfdfbfaf4eee6e8ecf2eff6f8fb]
@s"166"=[040508060508090d0d0f0a0a0a08080501fffdfbfbf8f6f3edeaecf2f3f3fcfb]
@s"167"=[04050908060a0a0d0e0f0c0c090603fffdfbfbfafafaf8f6f1edecf2f4f7fcfb]
@s"168"=[00ff050408060a0c0d0d0c06050300fdfdfdfdfdfdfdfbfaf6f3f3f2f6f6fbfb]
@s"169"=[0304060a0e12110f0c09060401fffffffffdfcfcfcfbfaf6f1edeef4f2f7f8fb]
@s"170"=[04080d0d0f12120f0d06060403fdfdfbfcfbf8f8fafcfbf8f3f1eef1f7f6fbfc]
@s"171"=[04080c0c0f0f0f0d09050401fffcfafaf8f8f8fbfcfdfcfbf8f6f4f6faf8fdfd]
@s"172"=[0001060a080a0a0a0803030000fcf8f7f8f8fbfdff00010300fdf8f8fafbfcfc]
@s"173"=[0003050609090806050503fffbf8f8fbfdfdff00030303fffbf6f3f6faf8fbfb]
@s"174"=[03080a0c0d0a0a08060400fbf8f8f8fbfbfbfcff030300fdfbf8f6f6fcfafcfb]
@s"175"=[030808090a0909060503fdfbf8f8f8fbfbfbff0104050100fdfbf6f6fbf7fafb]
@s"176"=[030808090a0c0a060503fffbfafaf8fafbfd000103040100fdfbf6f4faf8fafb]
@s"177"=[030808090a0a09050503fdfbfafbf8fafdfd000304040100fdf8f4f4faf7f8fb]
@s"178"=[050808080a0a0a060500fdfbfbfbf8f8fcff000303040300fdfaf6f4f8f8f8fb]
@s"179"=[03080808090a0a050300fffdfbf8f8fafdfffd0005050300fdfbf6f3f6f8f7fb]
@s"180"=[030808080a0a09050300fdfbf8f8f8fbfcfd000505040300fdf8f4f3f6f8f8fc]
@s"181"=[090f0d0905050001050905fcf7f4f6fa0005050300010401fdfcfaf4f1eeeef4]
@s"182"=[171f06fbfdfb01120ef7effd00fc0401f7fc110f01fcf8f3fc04fdfafaf2edf8]
@s"183"=[1317fdf8ff030a08f6f80303fdfbfd000505fdfcfdfc0000fdfbf8fbfdfcf8fb]
@s"184"=[030a00fd030805fdfb000000fdfb010000fd0501fbfdfffd00fbfb0301fffdfd]
@s"185"=[0405fdfdfd0401fdfd0004fdfaff0303fffd010400fdfd0301ff01010000fcfc]
@s"186"=[00fdfcfcff0001fffc010103ffff01000100fc0303fdfffc03fffffffc01fffd]
@se"sonic"=[
"100",1 "101",1 "102",1 "103",1 "104",1 "105",1 "106",1 "107",1 "108",1 "109",1
"110",1 "111",1 "112",1 "113",1 "114",1 "115",1 "116",1 "117",1 "118",1 "119",1
"120",1 "121",1 "122",1 "123",1 "124",1 "125",1 "126",1 "127",1 "128",1 "129",1
"130",1 "131",1 "132",1 "133",1 "134",1 "135",1 "136",1 "137",1 "138",1 "139",1
"140",1 "141",1 "142",1 "143",1 "144",1 "145",1 "146",1 "147",1 "148",1 "149",1
"150",1 "151",1 "152",1 "153",1 "154",1 "155",1 "156",1 "157",1 "158",1 "159",1
"160",1 "161",1 "162",1 "163",1 "164",1 "165",1 "166",1 "167",1 "168",1 "169",1
"170",1 "171",1 "172",1 "173",1 "174",1 "175",1 "176",1 "177",1 "178",1 "179",1
"180",1 "181",1 "182",1 "183",1 "184",1 "185",1 "186",1 "nos",1
]
@p"sonic"=[
353,1 0,1 10,1 106,1 -99,1 16,1 44,1 3,1 35,1 113,1
-33,1 65,1 4,1 -47,1 27,1 58,1 25,1 -39,1 -16,1 -4,1
5,1 6,1 15,1 28,1 -28,1 -209,1 -14,1 -191,1 19,1 -110,1
111,1 -11,1 128,1 173,1 102,1 -102,1 -29,1 -30,1 -52,1 -131,1
-177,1 6,1 -21,1 -6,1 3,1 0,1 6,1 6,1 9,1 4,1
10,1 4,1 12,1 10,1 7,1 1,1 14,1 11,1 18,1 15,1
26,1 19,1 28,1 30,1 21,1 13,1 19,1 12,1 62,1 -8,1
23,1 26,1 69,1 14,1 7,1 8,1 6,1 24,1 8,1 29,1
29,1 -17,1 83,1 112,1 20,1 4,1 -63,1
]

s1=v15@se"sonic"@p"sonic"o4a1

MMLはこれだけです。実際にこれをコンパイルすると上記の音声が再生されます。PCMではありません。

海外パッチでグラ2のボイスが付く動画を見たことがありますが、あれは恐らくSCC 5Chを使ったCSM音声合成だろうと思うのでそれとも違うはずです。

今回のアイデアは、MSX上の話ではなく音をSCCデータに変換するツールのアルゴリズムが主体となっています。

処理されるのはただのデータなので、ドライバから見れば単なる1/60秒ごとの波形切り替え(加えてピッチエンベロープ)です。

波形切り替えは普通に音色の表現として使われているので、負荷としては通常の演奏と同じです(毎クロックの書き換えなので少々高目の負荷ではありますが)。通常の演奏の負荷程度ということは、MSXのゲームでもBGMに重ねてボイスを再生できるはずです。

データ量を見てみますと、87個の音色定義=87x32=2784バイト。その他合わせて計3346バイトとなります。

これをPCMで再生するとどうなるか。上記計算は定義データ量のみの計算なので、少し余裕を見て4000バイトのPCMで再生することを考えてみます。

再生長は約1.5秒。1.5秒で4000バイトなら、1秒2666.7バイト、切り上げて2667バイト。8bitPCMで1秒2667バイトはサンプリング周波数2667Hzということなので、その周波数で録音したものがこちらです。

wavファイル(PC録音)

2667Hzというかなり低いサンプリング周波数なので、高域がごっそり落ちてしまいました。

またPC上で聞いているときは、恐らく線形補間が自動で掛かる(と思います)のである程度は聞きやすいですが、これをSCCで再生するとなるともっとノイジーに聞こえます。

負荷に関してはこのサンプリング周波数なら中途半端すぎるので、実際にMSXで2667HzのPCMをBGMと同時に鳴らすのは無理そうな気がします。

1クロック32バイト=1920Hzなら可能性はありますが、それでもタイミングよくSCCを繋げるのは難しいです(SCMDでもかなり苦労した部分です)。PCMでやろうとすると、色々問題が立ちはだかり難しいはずです。

低データ容量で、低負荷で、PCMのように高域が落ちるわけでも無いのがこの再生方法の特徴と言えるでしょうか。

この方式の負荷が軽くて済む理由の一つとして、切り替えるタイミングが若干前後しても問題ないという点があるので、試したことはありませんがデータが(変換などして)移植でき、1クロック単位で波形書き換えと周波数書き換えができるドライバなら、同様に喋らせることはできると思われます。

そしてPCMのように、音質を犠牲にある程度データ量を減らすことも可能です。

;初期設定-----------------------------------------
tempotype=["calculation"]
@title=["voice test"]
@author=["めが"]
@original=[""]
@comment=[""]

@s"100"=[020200fffeffff0102ffffffffff0000fffefefefe00fffdfe00000100fefdfc]
@s"101"=[0405f8fff7ec0c0efafaf6fcf3fa0ef7e9f6120cee00f8fb03fdfbf60d12f6e5]
@s"102"=[0500ecf6fd000400f3e9e6f8fb2605daed030dfafcf4ec050afa0a04d7e1f1ec]
@s"103"=[2c14e6cacdf8331ceefa0f1ff805fbe6fbf8f1261ff1e8d6cf2c120ae91214e4]
@s"104"=[3bf1e13b0c031f13f1e1dbfb05eed21d0f0332e1f136f30a31f1e6eebb1b09c0]
@s"105"=[520ddc54d2fb29ec4325fb29dad8d2a35c09df43c4ff21e15723002edadfc38d]
@s"106"=[4d002140d117ece95c1a1817cde9c8d21c141a29ec08fdf833280c17dae6d4cc]
@s"107"=[0e0c0c1a06021812141a0302e0e8ece60e0c0a1e02fe180e1a1b0003dee1f6e4]
@s"108"=[3d340a3addee06f338160ce9b6a606ed3f400f34dcecfd00491613e8b7a0eee9]
@s"109"=[5a481229c5fddc1f521a21c5c383fbf861481d23ae05d23640241ac0ca800ddf]
@s"110"=[531a36fbc3fcb331215103dcb89200b851fd49e9d1eeb1291c57fce8ac98e4bb]
@s"111"=[4d085ffbfbd2da0c2c3c1cf3bba1d2ce2e263224eee9d8091a3111eee6b6f7d4]
@s"112"=[25f72e0612fdfb05fcfbec03e40eee18fb1c060a05f60ff812ff0afdfbf3f8f8]
@s"113"=[020101010200feff0101020301010000ffff010100feff010201010000fefcfe]
@s"114"=[0103040405050505040403020100fffefdfbfbfaf9faf9f9faf9fafafafcfcfe]
@s"115"=[0404090c09080503010a0c0904f8eee3d8d6dfddddeffbf808170f0a01fff6fc]
@s"116"=[1744494a533f230f05ff0cfd031212f8f6eddbd6e5f30303f6dfc9b1b6c8d6e3]
@s"117"=[21464c414a46250f09130f1718181303e8d8cdc0c6d7eaf8ffeed4b1c0d1dae3]
@s"118"=[244a52495652381c1216171b0e181e0af1ecdec8c9d1d8e5e9d6bcabc4cccce3]
@s"119"=[27403c3a4c362420201e282818202008eee9dcd3dbe8e9f6edceb2a4aebcceec]
@s"120"=[1f3a3c3b37240a0c1711243b2e232909eaeedbd3e5f6e903f8dabaa6a4bfd8ea]
@s"121"=[2931312f26ff0c0e041a482c2d2e09ecefd3d1e9fafc1c0aeedbb79cb1cad8f4]
@s"122"=[232e363714120e00fb292823291ffdf2e3d6dbecf31a2312fdefb89fb2c6cdf4]
@s"123"=[1a37443c250ff8e5ee051821332e0ffbe4cdcfe4ff20333320ffc4a0a3b1c3ed]
@s"124"=[263d3b2d13f8e4e3f811252e3c2c0cf8e4d2e5f30e2d372e1df1b39b98a6c3e9]
@s"125"=[0f2929251705f8f4f60f1b252f291100e6dfe9f3051b241f14eec9afadbdd2e8]
@s"126"=[12181a14050105fc111d1c23200a01efe6f6fa03181a1a17fadfc9bbc0d4ddf1]
@s"127"=[101816120d04020910141d201c1204fef7f2fa0208121205f2dac8c2c9d3e2f6]
@s"128"=[081f1a130a04fd030f1c242c291c05f2e6dfe8fa0a1b211a08efd2bdbac6d7ec]
@s"129"=[0f18120900fdfd091c262c2d1f08f1e4dfe5f80c1a252111fce1c9bbc3dae9fa]
@s"130"=[0a0e0c0e0e0a0f171a1c1e160afff3ebedf4fe0913171206f5e2d2cacfdce7f5]
@s"131"=[0e131d231c1a160a030801fffff7f3ededf4000c1a1f1f1704efd7c5c3d1ddf3]
@s"132"=[0a121b1f1b170f04fffbf6fbfbfd000004090d11110f0c04faead4ccd1dbe4f7]
@s"133"=[060810120e0f0b0708040502040406080707040401fefaf2e8e3e6eae8f2f4f8]
@s"134"=[030509090a0c0d0e0d0b0907050202fffefcfbfbfbfbf9f6f1efeff3f4f6fbfb]
@s"135"=[03080809090a0806050300fcfaf9f8fafcfdff0103030200fdfaf6f5f8f7f8fa]
@s"136"=[151b02fafeff060d02f8f900fefc0000fe000706fffcfcfafc00fafafcf7f2fa]
@s"137"=[0204fefd000402fefc000200fdfe020100fe0103fffdfeff01fefe01ff00fdfd]
@se"sonic"=[
"100",11 "101",1 "102",1 "103",1 "104",1 "105",1 "106",1 "107",2 "108",1 "109",1
"110",1 "111",1 "112",1 "113",8 "114",8 "115",1 "116",1 "117",1 "118",2 "119",2
"120",1 "121",1 "122",1 "123",1 "124",1 "125",1 "126",1 "127",2 "128",1 "129",1
"130",3 "131",1 "132",1 "133",2 "134",7 "135",10 "136",2 "137",3 "nos",1
]
@p"sonic"=[
367,2 69,4 -45,3 196,6 57,10 -213,2 -188,2 -101,1 105,2 123,1
173,1 102,1 -117,2 -44,1 -52,1 -131,1 -174,2 -18,6 20,2 14,2
18,2 18,3 30,2 24,1 35,2 38,1 40,2 41,3 87,4 125,6
72,4 93,1 113,4
]

s1=v15@se"sonic" @p"sonic"o4a1

wavファイル(実機録音)

データとしてはかなり小さくなりましたが、音質はそこまで落ちてないように思います。3346バイトから1469バイトにまで減らせました。元のサイズの約44%です。音質が許容できるのならもっとデータを減らすことも可能です。

音質、と書きましたが高域がとか、低域がというような感じではなく、再生音そのものが少し変化している感じです。どんどん容量を小さくしていくと破綻が見え始め、最終的には喋っている内容が判別できなくなっていきます。

容量が小さいとか負荷が軽いとか利点ばかり書きましたが、弱点も当然ありまして、それは向く音と向かない音がある、という点です。

残念ながらPCMのように何でも記録できるというわけではありません。

向いているのは人の声のような、同じ波形を繰り返すことの多い音。向かないのはノイズ成分のような1波形の区切りが曖昧になってしまう音です。

なので楽器のドラム類なども向きませんし、オーケストラヒットなどは似ても似つかない音になります。人の声でも、エフェクトを掛けたような音声は不向きです。

で、肝心のアルゴリズムなのですが…。

こんな感じのツールを作って色々試行錯誤していたのですが、ちょっと時間が経ってしまうとほとんど忘れてしまい、そのまま放置という状況です…。

考えたアルゴリズムは2種類あって、もっと調整すれば音質も上がりそうな雰囲気だったのですが…。

これ以上放置すると、本当に全て忘れそうなのでひとまず記録として残しておくことにしました。

MSXでもSCCを使えば比較的簡単にボイスを使ったゲームができる可能性を忘れてしまうのはもったいないと思うので…。

またいつか時間ができればチャレンジしてみたいと思います。

音声サンプル

wavファイル(実機録音)
mmlファイル

これだけのボイスを喋らせて、データ量7KBチョイです。

SCMDはPCMデータや演奏データはマッパを活用して大容量のメモリを扱えるよう設計しましたが、定義エリアはそんなにデータを扱うこともないだろうと、12.5KBほどの固定になっています。なのでこの方法で大量にデータを作るわけにはいきませんが、このやり方を前提にドライバを作ればボイスに困らないゲームができるなぁと、現時点では夢想しています。

おまけ

高音質に変換できるとこんな感じです。ぜひコンパイルしてみて聞いてください。

mmlファイル