レス数が1スレッドの最大レス数(1000件)を超えています。残念ながら投稿することができません。
おちゃめくらぶ掲示板
-
プチコン用棒歌ロイド「OSP」が2にバージョンアップ!
1週間前に公開したプチコンで歌わせることができるプログラム(棒歌ロイド)「OSP」
だけど早くも「OSP2」にバージョンアップしたにょ。
http://ww5.tiki.ne.jp/~ochame/petitcom/1page.htm#osp
http://youtu.be/amhVzkigxTM
というか、これがようやく完成品といった感じで前作は試作品といった感じにょ。
というのも、プチコンmkIIが配信された当初からプチコンで歌わせる動画を公開して
いる人が居たのだけどパラメータを手動セットしていくというのは非常に手間がかかる
ために、その手間を無くすという考えの人が必ずいると思ったからにょ。
ポケコンではBEEP 1,222,262でドの音を1秒間出すことができるけどそれを手動で並べて
曲を作るということはさすがにできないということで、自作MMLを作ったにょ。
それと同じく初代プチコンでもBEEPで曲を演奏する際に1つの音ごとにパラメータを
手動セットしていくのは非常に大変なのでMML演奏プログラムを作った人は多数現れた
からね。
私は、プチコンを入手したのは3DSを買ってからであり、その3DSを買ったのも私が欲しい
ピンクが発売されてからだったのでかなり出遅れたにょ。
しかし、mkIIでは比較的早い段階でプチコンを入手したので一番乗りに拘ったにょ。
その結果として、プチコンで自動的に歌わせるプログラムとしては何とか一番乗りはできた
もののOSPは開発速度を優先したためにやろうと思ったことが十分にできたとは言い難い
ものだったにょ。
プログラムを「ソースコードが見える形」で発表する以上は自分の中で想定する最低限の
クオリティに満たないものは発表は躊躇してしまうところだけど何とかそれにギリギリ
達したというレベルであり、「これ以上のものは作れない」というレベルには全く達して
無かったにょ。
特にテスト用に選んだ「春が来た」を何度も聞けば聞くほど不満点がどんどん見つかって
しまいそれを解消するものを作りたいと感じていたにょ。
ちなみになぜ「春が来た」なのかは「知名度が高い」「著作権切れである」「曲が短い」
「音符の種類が多い」「途中に休符を挟んでいる」などの理由があるにょ。
最初の2つは説明不要だと思うけどあとのものについて理由を書くと「曲が短い」という
のは何度も繰り返して聴けるためあら探しをしやすいということにょ。
「音符の種類」というのは八分音符、四分音符、付点四分音符、付点二分音符の4種類の
音符が短い曲の中に含まれているということにょ。
これによって各音符の長さがちゃんと出ているのかが分かるにょ。
「途中に休符を挟んでいる」というのも休符がちゃんと表現できているかの判断材料に
なるので有用にょ。
ということで、ここ1週間で少なくとも数100回は「春が来た」を聴いており、恐らくこの
期間内では「世界で最もたくさん『春が来た』を聴いた人」かもしれないにょ(笑)
ということで、このOSP2はどのようなものかというと改善点は下記の2つにょ。
(1)自由度が高くなった
(2)より正確に歌えるようになった
(1)具体的に言うと前作のOSPでは開発速度を優先したためにOMPでの使用が前提になって
いたけれど今回は好きなMML演奏プログラムと組み合わせて使用できるということにょ。
OMPは私にとっては使いやすいプログラムだけど多くの人にとっては使いやすいとは言い
難いものだろうからね。
OSPは「お手軽である」ということが最大のウリなんだけどOMP前提にしてしまうとその
ウリがどうしても弱くなってしまうにょ。
やはり、自分が使い慣れたものを使いたいということにょ。
確かにOSPもBASICの知識がそれなりにあれば他のプログラムでも活用できるけどそれだと
利用者のハードルを高めてしまう(OMPの仕組みを知っている人しか利用できない)ため
誰でも利用できるようなレベルではないにょ。
したがって、OSP2はサブルーチンとして機能を独立させてAPPEND命令で適当なMML演奏
プログラムと結合して、「GOSUB @OSP」とするだけで活用できるレベルにしてあるにょ。
といっても、現実的にはそれだけでは無理でOSP2で使用している変数に値を受け継ぐ
必要があるにょ。
そのため一般的なMML演奏プログラムで利用しているであろう値から変換せずにすむような
ものにしているにょ。
OMPはテンポ指定が特殊(OMPのテンポ8が一般的なMMLのテンポ120に相当する)なんだけど
これは曲のデータを少しでも減らしたいためよく使うであろうテンポ指定値を1桁にした
かったというのが理由にょ。(それだと微調整ができないためどうしても微調整をしたい
という人のために小数でもテンポ指定できるようにした)
そして、「テンポ指定1で音長1ならば1秒鳴る」というのは非常に明確で分かりやすいからね。
例えばテンポ72でで16分音符は何秒間鳴るのかというのは瞬時に答えられる人はまずいない
からね。(その点OMPは「音長/テンポ」であるため瞬時に答えられる)
それに音長指定もOMPは数字に比例した長さで鳴った方が分かりやすいというのと(データを
少なくするため1桁でしか指定できないということもあり)1桁だと指定値に比例する長さで
鳴らした方が分かりやすいというのとさらに単純に除算よりも乗算の方が演算が速いから
というのが理由にょ。
つまり、OMPはプログラム、データともに限界まで短くなっており、数字の計算が分かり
やすく、処理速度も限界まで速くなっているため音質の面で有利(処理速度の遅い
ポケコンだと時間がかかる処理を行えば音がブツ切れ状態になる)というわけで個人的に
非常に気に入っているもののやはりそのせいで一般的なMMLとは大きく異なっているにょ。
したがって、それを基準に作ったOSPでは一般的なMML演奏プログラムからは数値の変換が
必要不可欠となってしまうにょ。
しかし、OSP2ではプチコンのBEEP命令を使うMML演奏プログラムではほぼ数値の変換が
ほぼ不要になっているにょ。(多くの場合はMML演奏プログラムに使っている変数名に
変えてやるだけで他は何も変更しなくても動作する)
その代わりOMPで使用する場合には逆に変換が必要になるためOSP2ではプログラムのサイズや
処理速度面では不利になっているにょ。
それでも、OSP2はOMPと組み合わせた場合に1画面で収まっているにょ。
http://ww5.tiki.ne.jp/~ochame/petitcom/image/osp_omp.jpg
ちなみに上記のような自分が使っているMML変換プログラムへの組み込み方はこの「プチコン
MML with OSP2」を見れば誰でも簡単に分かると思うにょ。
http://ww5.tiki.ne.jp/~ochame/petitcom/osp_mml.htm
プチコンMMLはOMPと比べるとかなり一般的なMMLに近いものになっているためこちらならば
「OMPだと使いづらい」という一般MMLに慣れた人ならば有利になると思うにょ。(逆に
MMLなんて使ったことがなぃ「A→ラ」というのも瞬時に分からないレベルだとOMPの方が
分かりやすいと思う)
OSP2を組み込んだ「OMP with OSP」が使いづらいという人はこの「プチコンMML with OSP2」を
使えばいいし、普段使っているMML演奏プログラムが使いたいという人であればこの組み込み
方を参考にすれば簡単に自分が使っているMML演奏プログラムで使用できるようになるにょ。
ラベル@OSPの次の行にあるK=LEN(K$)というのは本来ならは最初に1回計算したら済むこと
なのでループ外に置くことが望ましいのだけど誰でも使えるようにするため1つでも手順を
減らすため涙をのんで@OSPのサブルーチン内に置くことにしたにょ。
これが無ければOSP2はOSPと同じ6行で済んだわけだしね。
上記のOMPやプチコンMMLもしくは自分が使っているMML演奏プログラムで曲を鳴らすのでは
なくBGMPLAYを使った曲に合わせて歌わせたいという人も当然出てくると思うにょ。
それもやり方は非常に簡単にょ。
それはこのMML演奏プログラム内にあるBEEPを消すかコメントアウトすればいいだけのこと
だからね。
要するに伴奏用ではなく単なるOSPの制御用としてMML演奏プログラムを用いるということにょ。
ただし、音ずれのないMML演奏プログラムを用いて音ずれのないMMLデータ(VSYNCによる
ウェイト指定が小数にならないようなデータ)ならば問題なく使用できるのだけどそうでない
場合はBGMPLAYとBEEPによるMML演奏プログラムは非同期であるため音ずれを起こしてしまう
可能性があるにょ。
音ずれのないMML演奏プログラムとデータを用いた場合でもTALK命令のタイムラグの関係上
完璧に合わせるというのは難しい(徐々にずれていくということが軽減されるというだけ)
ためにBGMPLAYによるMMLの最初に32分休符〜8分休符くらいの短い休符を入れてそのタイム
ラグを吸収しておく必要があるにょ。
そうすることで、BGMPLAYに合わせて問題なく歌わせることができるようになるにょ。
一見すると大変なようだけどMMLをちゃんと打ち込んでやれば後から全体の速度を変える
ということは簡単にできてしまうため1つ1つを手動セットしなければならないものと
比べると格段に楽になっているにょ。
(2)OSPでは誰でも簡単にそこそこ歌わせることができるのだけどキレイに歌わせるのは
逆に難しいにょ。
キレイに歌わせるならば1音1音ちゃんと微調整しながらパラメータセットするのが一番に
決まっているからね。
しかし、そんな原始的なことはとても私には耐えられないにょ。
そこで、お手軽にそこそこちゃんと歌ってくれるOSPを作ることにしたにょ。
なぜ1音ずつパラメータセットした方が良いのかというとそれは1音ずつ分けてTALK命令で
発声させるよりも1つのフレーズ単位でまとめて発声させる方がスムーズだからにょ。
それならば1音ずつ計算して発声は1つのフレーズ単位にすれば解決可能に思えるけどそう
いう単純なものではないにょ。
というのもTALK命令の速さとなるTの値が同じであっても発声する言葉で発声する時間が
異なるものになっているからにょ。
それならば各音がどれだけの時間発声するかを正確に測定して、それをデータとして用意
してそれを元にNの値を決定すれば良いだけに感じるかもしれないにょ。
発声する言葉によって発声する時間が異なるというのは「カ」と「バ」が異なるものに
なっているというだけではなく「バカ」と「カバ」さえも異なる時間になっているという
ことにょ。(厳密にいえば発声時間が異なるというよりも発声するまでのタイムラグが
異なるという感じだけどそのタイムラグを考慮してTALK命令を事前に実行しておくのは無理
であり、タイムラグを考慮した発声時間で計算しなくてはならない)
つまり、すべての言葉に対してあらかじめ発声する時間をデータとして持つ必要があるけど
そんなことは不可能にょ。
確かに「カバ」と「バカ」だとほんの数フレームの時間差であるためたいしたことはない
と思うかもしれないけど1フレーム単位の音ずれさえも気にっているという状況下において
たったの2音で数フレームのずれが出てしまうというのは非常に辛いにょ。(Tの値が
1000だと30フレームくらいの時間差になっている)
つまり、フレーズ単位で発声させることは可能だけど発声させる文字数が多くなれば多く
なるほど誤差が大きくなるにょ。(逆に誤差が相殺されるという可能性もあるけど)
そのため手動での調整は不可欠にょ。
したがって、自動的に歌わせるためにはフレーズ単位ではなく1音単位で発声させる
必要があるにょ。
1音単位であっても上記のように発声する言葉によって発生時間が異なるにょ。
1音が数フレームであってもテンポがゆっくりの場合にはそれが数倍〜10倍に拡大されて
しまう(←OSP1ではTの値のみで調整していたためこれが問題点となったけど1音ずつ
VSYNCで誤差を吸収していたから何とか聴けるレベルになっていた)わけだし、1音に複数の
言葉が入っている場合にも誤差が拡大していくにょ。
ただし、1音単位だと(ちゃんと正確なウエイトになっていれば)VSYNCによって1音ごとに
誤差を吸収できるため曲の後の方になればなるほどずれていくという心配はほとんど
無くなるにょ。(mkIIのVSYNCは仕様変更がなされたため従来ではMAINCTLを使わないと
できなかった正確なタイミングを取ることが可能になっているためTALK命令が追従できない
レベルの速いテンポで演奏しない限りは問題ない)
1音ずつ発声させれば(自動的に歌わせる場合に)フレーズ単位での発声と比べて音ずれが
無くなるというだけであってキレイになるというわけではないにょ。
それは原理上1音ずつ発声させた場合には音がどうしてもブツ切れ状態になってしまう
からにょ。
例えるならばポケコンのBASICでBEEP音による音階演奏をさせるようなものにょ。
そのブツ切れのような感じをいかに軽減させるかということがキレイに歌わせるか否かに
繋がってくるにょ。
ポケコンBASICの場合はやはりその処理速度がネックとなっていたにょ。
そのためBASICでは最も高速なMMLであるOMPはかなり有用だったにょ。
プチコンはその100倍以上速いため速度に関しては問題なさそうだけどそれでも可能な限り
処理そのものは軽い方がいいにょ。
それだけではなくいかに正確な長さの音符や休符が出せるかということがキレイに聞こえる
ためには必要不可欠になってくるにょ。
例えばテンポ120で2分音符を鳴らせば1秒になるのだけどこれが長かったり短かったり
すればキレイには聞こえなくなってしまうにょ。
これがどのようなものかはOSP2で実験してみれば一目瞭然にょ。
OSP2のリスト内にある185000という値を大きくすれば1音あたりの発声する時間が長くなり
小さくすれば短くなるのだけどはっきり分かるためには2倍、もしくは半分くらいにすると
いいにょ。
当然短くすればブツ切りが明確になってくる(テンポを遅くすればさらに分かりやすい)
のだけど長くした場合はそうならないため問題はないという人はいるかもしれないにょ。
「春が来た」の場合は最初の小節の中では「ル」や「ガ」は比較的発声までのタイムラグが
長目なので「ハールガキーター」が「ハー、ル、ガキーター」となってしまいスムーズさが
無くなっていることが分かると思うにょ。
それだけではなく音符より長目の時間だけ発声してしまうと休符が出せないという問題が
あるにょ。
「春が来た」では前半と後半の境目(「山にきた」の直前)に四分休符があるけどこれが
正確な長さ発声できないと休符が無くなってしまうにょ。
TALK命令はBEEPと異なり重ねて鳴らすことができないため休符を含まない場合は次の音が
鳴ると自動的に前の音が終了するにょ。
手作業でTALK命令を羅列して歌わせる場合にはすぐに次のTALK命令があるため実際に発声
されるのは最後のTALK命令だけになってしまうにょ。(したがって、WAITやVSYNCを用いて
適切なウエイトを入れておく必要がある)
1音ずつ自動的に発声するならば休符がない曲であれば多少のブツ切れ感を我慢すれば
問題ないけど休符がある場合にはそれが無くなるというだけではなく曲の最後の音が異様に
長い音になってしまうという問題もあるにょ。
TALK命令が重ねて発声できないというのを逆手にとってTALK " "をウエイトの後に入れれば
確かに発声しすぎは防ぐことができるにょ。
ただし、それはブツ切れ感をさらに増大させてしまうことになるにょ。
つまり、1音ずつ発声させるプログラムの場合は1音がどれだけ正確な長さ出せるかという
ことがキレイに歌えるかどうかの鍵になっていると思われるにょ。
この場合の「キレイ」というのは端的に言えば「いかにブツ切れ感を無くすか」という
ことにょ。
1音単位だとフレーズ単位と比べて誤差が小さくなる・・・と考えられるけどそれでも出す
音声によって2倍近く発声時間が異なるためこの誤差を軽減してやる必要があるにょ。
それに1つの音に1文字とは限らないためその文字数を考慮した補正が必要になってくるにょ。
その補正を行ったものがリスト中にある下記の式にょ。
N=185000/T/Y/(LEN(N$)-4/Y)
これは各音が発声される時間をストップウオッチで測定してそれを元に最も誤差が少なく
なるような値にしたものにょ。
これによってほとんどの音において理論値との誤差は数%に収まっているにょ。
例えばテンポ15の二分音符で「ア」と発声した時は理論値が8秒だけどこのOSP2では8.2秒
となっており、誤差は2.5%に収まっているにょ。
曲の中でよく使われるであろう八分音符〜二分音符において最も誤差が少なくなるように
補正されているため16分音符ではそこまで補正しきれてないものの短い音符だと完璧な
補正をしてもTALK命令の発声タイムラグによるブツ切れ感の方が遙かに大きいため相対的
には問題は小さくなると思われるにょ。(音符が途中で切れるブツ切れ感は長い音符の方が
目立ってしまうため)
短い音符のブツ切れ感を無くすにはフレーズ単位での発声をするしかないのだけどそれが
上記のように自動化できない以上は処理を簡略化して速度を上げるしかないにょ。
その点、OSPは「これ以上ない」というシンプルな構成であるため1音単位で発声させる
自動歌唱プログラムではこれが限界ではないかと思われるにょ。
とはいえ、OSP2では他のMMLで利用しやすいように汎用性を高めているのでOSP1のように
OMPに特化すればそれが最も高速になるにょ。
OSP1にOSP2の発声アルゴリズムを入れただけのものとはいえ、OMPで問題ない人にとっては
これがベストな選択肢にょ。(テンポ240くらいでも結構追従できてるし)
OSPをさらに超えるためにはあらかじめすべての数値を計算しておいてTALK命令で出力
するデータを配列変数に格納するという方法もあるし、短い音符の正確さを求めるならば
各音の発音時間を記したデータを用意する(フレーズ単位ではないためそれほど難しくは
ない)
という方法もあるにょ。
いずれも実現するのはそれほど難しくはないとはいえ、苦労やプログラムサイズの増大の
割にはたいした効果を得られないのではないかと思われるにょ。
じっくり聞き比べてみればようやく分かる程度の違いでプログラムサイズが10倍以上とかに
なってしまうのは個人的には許容ができないにょ。
ただでさえ、OSP2も数バイトをいかに削るかでかなり考えたくらいだからね。
これより正確さを落とさずに処理を簡略化(リストを短く)したり、リストを長くせずに
補正を正確にするアルゴリズムが見つかれば話は別だけどここまで短いプログラムだと
これ以上の大幅改善はほぼ無理ではないかと思われるにょ。
リストが短くそれなりに使えるものになっていると思うのでぜひ皆さんのプログラムに
組み込んで使ってもらいたいにょ。
|
|
|
掲示板管理者へ連絡
無料レンタル掲示板