屋上へ行こうぜ…久しぶりに…キレちまったよ… (OpenJDK 12)
…と、サラリーマン金太郎のようなセリフが出てしまったので、日記に記録を。
このカテゴリで記事を書くの11年振りなんだな… 凄くあっという間というか…
OracleのJDKライセンスが4月から色々と面倒な事になっていることから(個人利用では影響ないみたいですけど)、「それだったらOpenJDKを入れようかな…」と、まずはWindows版のJDKを入れ替えをして、その後、「そーいや、自作ゲームは問題ないかな…」と動かしたところ…

アギギ… (#゜皿 ゚) う、動かん…
「マジカヨ! こんなの調査開発を始めた2003年以来初めてダヨ!」となり、「他のOSではどうかな…」と、続いてMac OSの方を確認。

アギギギ・ギー!オンナジカヨ!(#゜皿 ゚)
「OpenJDKが糞なの?糞なの?」と思いましたが、「以前からLinux Mintの方はOpenJDKだったよな。しかも自作ゲーは昔から動いていたし…」と思い、次はLinux上で実行をしたところ…

動くじゃねーかよ、コノヤロウ!!(# ゚皿 ゚)
しかもOpenJDK 8だよコノヤロウ!(# ゚Д ゚)
となりました。
Javaについて私は現在、完全に素人化しているので(といいつつ今年の2月に仕事で中華な方の代わりに仕方なく軽くEclipseでプログラムを書いたりはしてるんだけど。(^^ゞ)キチンとデバッグするのが面倒でなんとも言えないのですが(実はコンパイルするためのAntすら今は入ってないのがホンネ。(^^ゞ)、エラーメッセージとソースコード上から対応する箇所を確認すると、
(1) Class.getClassLoader
(2) Class.getResource
(3) ToolKit.getImage
※これはjarファイルからのケース。
のメソッドのどれかに被疑がかかりました。
自作フレームワーク内部ではエラーチェックをかなりしているのですが、あまりに初歩的なものに関してはエラーチェック&ログを出してない… まさかこんな初歩レベルで実行が行えないなんて…
C言語ならprintf、STLならcoutが乗ってないようなレベルかと思うレベルです。
軽くネット検索をすると、getResourceの使い方がjarだとお作法があるとかないとか…
(ネットのマニアック技術情報というのは8割がた嘘が書いてあると「経験則があるので信憑性がない」んだよなぁ…)
その後、Windowsの方のJREを8(Oracleのサポートする無償最新版)にしたところ、自作ゲームは問題なく動きました。
ということは、OpenJDK 8より上が厳しいんだな…
自作ゲームはたまに思い出したかのようにプレーするので(自画自賛だけど、プレーしてて楽しい♪)、将来プログラムが完全に動かせない時代がきたらメンテするか… (他の言語にポーティングするのもアリか)
とりあえずダウンロードサイトの方は今は誰が落として動かしているかも分からないようなものになっているので、サイトの方は放置でw
しっかし、アッパーコンパチを守らなかった時点で「OpenJDK 12は糞」だな。(これがバグだったら仕方ないけど)
Firefox Quantumの時と同じこと言うけど、「Oracle技術者のトップにド素人がいるのか?」と思うことにします。
このカテゴリで記事を書くの11年振りなんだな… 凄くあっという間というか…
OracleのJDKライセンスが4月から色々と面倒な事になっていることから(個人利用では影響ないみたいですけど)、「それだったらOpenJDKを入れようかな…」と、まずはWindows版のJDKを入れ替えをして、その後、「そーいや、自作ゲームは問題ないかな…」と動かしたところ…

アギギ… (#゜皿 ゚) う、動かん…
「マジカヨ! こんなの調査開発を始めた2003年以来初めてダヨ!」となり、「他のOSではどうかな…」と、続いてMac OSの方を確認。

アギギギ・ギー!オンナジカヨ!(#゜皿 ゚)
「OpenJDKが糞なの?糞なの?」と思いましたが、「以前からLinux Mintの方はOpenJDKだったよな。しかも自作ゲーは昔から動いていたし…」と思い、次はLinux上で実行をしたところ…

動くじゃねーかよ、コノヤロウ!!(# ゚皿 ゚)
しかもOpenJDK 8だよコノヤロウ!(# ゚Д ゚)
となりました。
Javaについて私は現在、完全に素人化しているので(といいつつ今年の2月に仕事で中華な方の代わりに仕方なく軽くEclipseでプログラムを書いたりはしてるんだけど。(^^ゞ)キチンとデバッグするのが面倒でなんとも言えないのですが(実はコンパイルするためのAntすら今は入ってないのがホンネ。(^^ゞ)、エラーメッセージとソースコード上から対応する箇所を確認すると、
(1) Class.getClassLoader
(2) Class.getResource
(3) ToolKit.getImage
※これはjarファイルからのケース。
のメソッドのどれかに被疑がかかりました。
自作フレームワーク内部ではエラーチェックをかなりしているのですが、あまりに初歩的なものに関してはエラーチェック&ログを出してない… まさかこんな初歩レベルで実行が行えないなんて…
C言語ならprintf、STLならcoutが乗ってないようなレベルかと思うレベルです。
軽くネット検索をすると、getResourceの使い方がjarだとお作法があるとかないとか…
(ネットのマニアック技術情報というのは8割がた嘘が書いてあると「経験則があるので信憑性がない」んだよなぁ…)
その後、Windowsの方のJREを8(Oracleのサポートする無償最新版)にしたところ、自作ゲームは問題なく動きました。
ということは、OpenJDK 8より上が厳しいんだな…
自作ゲームはたまに思い出したかのようにプレーするので(自画自賛だけど、プレーしてて楽しい♪)、将来プログラムが完全に動かせない時代がきたらメンテするか… (他の言語にポーティングするのもアリか)
とりあえずダウンロードサイトの方は今は誰が落として動かしているかも分からないようなものになっているので、サイトの方は放置でw
しっかし、アッパーコンパチを守らなかった時点で「OpenJDK 12は糞」だな。(これがバグだったら仕方ないけど)
Firefox Quantumの時と同じこと言うけど、「Oracle技術者のトップにド素人がいるのか?」と思うことにします。
Javaにおけるサウンドの設計 (SEとBGMの実装)
前回の設計にてJavaにおける音声発声の実現方式を検討しました。
今回は「ゲームプログラミング [共通]」カテゴリで設計したサウンドフレームワークに合せて組み込んで行きたいと思います。
まずはいつものようにサンプルソースを作成してみたので、これを元にJava上での実現方式について説明して行きたいと思います。
■サンプルソース (2008.05.17.zip)
jarファイルの実行はWindows上の場合は大抵ダブルクリックにて実行可能ですが、『この実行は自己責任』にてお願いいたします。
今回のサンプルソースでは、自機のショット音の発声と、BGMの発声を実現しています。
(Windows上での実行の場合はボリュームコントロールで、WAVEとシンセサイザがそれぞれSE,BGMとなっているので注意してください。また、OSのサービスをチューニングしている事により、MIDIが発声しないケースがあるので、これも注意してください。この場合はプログラムの初期化にてエラーになると思われます)
【データ構成図】

今回は設計図が大きくなりすぎたので、PDFでの掲載にしました。Adobe Readerがインストールされているコンピュータにて観覧できます。もしもAdobe Readerがインストールされていない場合は、多少縮小したイメージとして、こちらを用意しました。【縮小版設計図】
【共通音情報からJava特有の音情報を持つ】
共通のカテゴリのサウンドフレームワーク設計では、音情報は非常にプリミティブな物でしたが、今回具体的にJavaで実現するにあたり、SE用の情報とBGM用の情報を実装しました。これらは各々「SoundSEItem」「SoundBGMItem」クラスとして実装し、基底となる音情報(SoundItem)から派生した形で実現しています。
SoundSEItemにはAudioClipクラスを内包し、SounBGMItemにはSequenceクラスを内包しています。
【サウンドデバイスクラスの実装】
「Javaにおけるサウンドの設計 (音声発声の実現方法検討)」の設計にて、SEとBGMの発声実現方法を設計したので、これらを各々を「SoundDeviceSE」「SoundDeviceBGM」クラスとして実装しました。これらのクラスは再生に必要となる音情報(SoundSEItem, SoundBGMItemクラス)を引数として処理を行います。メソッドには各々play/pause/stopメソッドがあり再生/一時停止/停止を実現します。しかしながら、SEに関してはJavaのAudioClipクラスが一時停止を行う仕様を持たないため、処理の中身はNOP(No OPeration)としています。
(AudioClipを使用しない実現方法に変更した場合はこの中身の実装を行うだけで一時停止ができる設計になっています。これは共通フレームワーク処理設計としての概念です)
【音管理に音情報を追加する】
今回のサンプルソースでは、音情報は自機のショット音をSE(.wav)として1つ、BGM音をBGM(.midi)として音管理クラスに登録しています。
この実装はJavaにおけるフレームワークとして「SoundID」クラスを実装し、これにenum情報として「ShipMissile」と「BGM1」というIDを追加しました。また、音管理であるSoundManagerクラスの初期化メソッドであるinitialize内にて、これら音情報を登録しています。
もしも今後音情報を追加する場合には、
1.SoundIDクラスに音のIDを追加する。
2.SoundManager.initialize内にaddメソッドを用いて音情報を登録する。
といった事を行うと、ゲーム中に使用する音声を登録できます。
【発声させる】
登録された音情報は、タスク処理内等で発声させることができます。
サンプルソースでは、ゲームの初期化が行われた直後にBGMとしてSoundID.BGM1を、自機となるPlayerTaskクラスの実行処理であるexecuteメソッド内のショットを発射する際にSoundID.ShipMissileをSoundManager.playメソッドにてそれぞれ発声させています。
◇ ◇ ◇
非常に安易な設計にて、Javaのサウンドフレームワークを実現してみましたが、もしも高度な音声処理を行う場合には、音の情報としてSoundItemに情報を追加し、発声処理としてSoundDeviceSE並びにSoundDeviceBGMに高度な発声処理を実現すればゲーム全体の処理(フレームワーク)の流れは、変更がないままゲームを作成することができると思います。
とりあえずこれまでの設計にて、単純ではありますがJava上にてシューティング、アクション、RPG、パズル…等の2D型TVゲームにおけるリアルタイム演算、入力、描画、発声という設計を行うことができました。
◇ ◇ ◇
今後はゲームのジャンルを設定し、ゲームデザインを行い、絵を描き、音を作曲し、プログラミングをし…という流れとなるのですが、以前、本ブログで書いた
【2008/02/20】
>このカテゴリー「ゲームプログラミング [Java] 」では「何かゲームを作ってみる」
>という指針を決めて、ゲームを作って行く方向でその都度必要な設計を説明して
>いこうと思います。(現時点では何も決めていないのですが、XNAの設計の説明の
>最中に決めていこうかと思います…)
という内容が結局決まりませんでした。(^^ゞ
…というよりも、正確には「多少素案はあるのですが、独りで作っているSample Action Game 3Dに手がかかりすぎて、こちらに時間がかけられない…」という状況になっています。(このような自作自演をここまで独りよがりでやっているのも、ある意味凄いとは思っているのですが…(爆))
当初の希望としてはこのブログでJava(でなくてもいいのですが)のプログラマーの方と何人か知り合いでもできて、このブログを通じて(ソースも公開して)、「なんか作れたらいいかなぁ~」なんて思いましたが、「世の中そうも甘くない。」という事を切に実感しましたw
(これも良い経験と思うことにします)
ということで、とりあえずではありますが、現状での本カテゴリーは「何か思いついたらJavaってみる」程度に抑えておこうかと思います。
今回は「ゲームプログラミング [共通]」カテゴリで設計したサウンドフレームワークに合せて組み込んで行きたいと思います。
まずはいつものようにサンプルソースを作成してみたので、これを元にJava上での実現方式について説明して行きたいと思います。
■サンプルソース (2008.05.17.zip)
【実行画面】
jarファイルの実行はWindows上の場合は大抵ダブルクリックにて実行可能ですが、『この実行は自己責任』にてお願いいたします。
今回のサンプルソースでは、自機のショット音の発声と、BGMの発声を実現しています。
(Windows上での実行の場合はボリュームコントロールで、WAVEとシンセサイザがそれぞれSE,BGMとなっているので注意してください。また、OSのサービスをチューニングしている事により、MIDIが発声しないケースがあるので、これも注意してください。この場合はプログラムの初期化にてエラーになると思われます)
【データ構成図】

今回は設計図が大きくなりすぎたので、PDFでの掲載にしました。Adobe Readerがインストールされているコンピュータにて観覧できます。もしもAdobe Readerがインストールされていない場合は、多少縮小したイメージとして、こちらを用意しました。【縮小版設計図】
【共通音情報からJava特有の音情報を持つ】
共通のカテゴリのサウンドフレームワーク設計では、音情報は非常にプリミティブな物でしたが、今回具体的にJavaで実現するにあたり、SE用の情報とBGM用の情報を実装しました。これらは各々「SoundSEItem」「SoundBGMItem」クラスとして実装し、基底となる音情報(SoundItem)から派生した形で実現しています。
SoundSEItemにはAudioClipクラスを内包し、SounBGMItemにはSequenceクラスを内包しています。
【サウンドデバイスクラスの実装】
「Javaにおけるサウンドの設計 (音声発声の実現方法検討)」の設計にて、SEとBGMの発声実現方法を設計したので、これらを各々を「SoundDeviceSE」「SoundDeviceBGM」クラスとして実装しました。これらのクラスは再生に必要となる音情報(SoundSEItem, SoundBGMItemクラス)を引数として処理を行います。メソッドには各々play/pause/stopメソッドがあり再生/一時停止/停止を実現します。しかしながら、SEに関してはJavaのAudioClipクラスが一時停止を行う仕様を持たないため、処理の中身はNOP(No OPeration)としています。
(AudioClipを使用しない実現方法に変更した場合はこの中身の実装を行うだけで一時停止ができる設計になっています。これは共通フレームワーク処理設計としての概念です)
【音管理に音情報を追加する】
今回のサンプルソースでは、音情報は自機のショット音をSE(.wav)として1つ、BGM音をBGM(.midi)として音管理クラスに登録しています。
この実装はJavaにおけるフレームワークとして「SoundID」クラスを実装し、これにenum情報として「ShipMissile」と「BGM1」というIDを追加しました。また、音管理であるSoundManagerクラスの初期化メソッドであるinitialize内にて、これら音情報を登録しています。
もしも今後音情報を追加する場合には、
1.SoundIDクラスに音のIDを追加する。
2.SoundManager.initialize内にaddメソッドを用いて音情報を登録する。
といった事を行うと、ゲーム中に使用する音声を登録できます。
【発声させる】
登録された音情報は、タスク処理内等で発声させることができます。
サンプルソースでは、ゲームの初期化が行われた直後にBGMとしてSoundID.BGM1を、自機となるPlayerTaskクラスの実行処理であるexecuteメソッド内のショットを発射する際にSoundID.ShipMissileをSoundManager.playメソッドにてそれぞれ発声させています。
◇ ◇ ◇
非常に安易な設計にて、Javaのサウンドフレームワークを実現してみましたが、もしも高度な音声処理を行う場合には、音の情報としてSoundItemに情報を追加し、発声処理としてSoundDeviceSE並びにSoundDeviceBGMに高度な発声処理を実現すればゲーム全体の処理(フレームワーク)の流れは、変更がないままゲームを作成することができると思います。
とりあえずこれまでの設計にて、単純ではありますがJava上にてシューティング、アクション、RPG、パズル…等の2D型TVゲームにおけるリアルタイム演算、入力、描画、発声という設計を行うことができました。
◇ ◇ ◇
今後はゲームのジャンルを設定し、ゲームデザインを行い、絵を描き、音を作曲し、プログラミングをし…という流れとなるのですが、以前、本ブログで書いた
【2008/02/20】
>このカテゴリー「ゲームプログラミング [Java] 」では「何かゲームを作ってみる」
>という指針を決めて、ゲームを作って行く方向でその都度必要な設計を説明して
>いこうと思います。(現時点では何も決めていないのですが、XNAの設計の説明の
>最中に決めていこうかと思います…)
という内容が結局決まりませんでした。(^^ゞ
…というよりも、正確には「多少素案はあるのですが、独りで作っているSample Action Game 3Dに手がかかりすぎて、こちらに時間がかけられない…」という状況になっています。(このような自作自演をここまで独りよがりでやっているのも、ある意味凄いとは思っているのですが…(爆))
当初の希望としてはこのブログでJava(でなくてもいいのですが)のプログラマーの方と何人か知り合いでもできて、このブログを通じて(ソースも公開して)、「なんか作れたらいいかなぁ~」なんて思いましたが、「世の中そうも甘くない。」という事を切に実感しましたw
(これも良い経験と思うことにします)
ということで、とりあえずではありますが、現状での本カテゴリーは「何か思いついたらJavaってみる」程度に抑えておこうかと思います。
Javaにおけるサウンドの設計 (音声発声の実現方法検討)
前回の設計にてSE発声は波形データ(.wav、もしくは.au)で、BGM発声はコマンドデータ(.midi)で実現する方針を決めました。
今回はこれらの再生方法について検討して行きたいと思います。
【SE発声の検討】
まず、SE発声の実現方法ですが、数ある発声方法の中でシンプル(と私は思っている)な方法にAudioClipクラスを使用するという方法があるので、これを検討してみます。
このクラスはAppletクラスのstaticメソッドnewAudioClipを用いれば、.wav(.au)ファイルを指定してAudioClipクラスを取得することができます。
そしてファイルですが、本設計では「音声ファイルはビットマップの時同様にJARファイルの中にある」ものとします。
newAduioClipの呼び出しにはURLオブジェクトを渡す必要があるので、2/2の「ビットマップファイルの読み込み」の時に説明したようにJARファイル内の.wavファイルのパスを取得して、これを渡します。
このクラスが取得できれば再生/停止は至極簡単で、それぞれメソッドのplay/stopにて実現できます。
【BGM発声の検討】
次にBGM発声の実現方法ですが、MIDIの発声にはSequenceクラスとSequencerクラスを用いて再生できます。前者のSequenceクラスはMIDIの情報を持つクラス、後者のSequencerクラスはSequenceクラスの情報を用いてMIDIを発声させる機能という担当となります。
これらクラスはMidiSystemクラスを用いて取得することができ、それぞれ
・Sequence → MidiSystem.getSequence
・Sequencer → MidiSystem.getSequencer
にて取得します。そして、発声にはSequencerクラスのメソッドsetSequenceを用いて引数にSequenceクラスを設定します。
(どれも"Sequence"という似た文字を用いるので、少し分り辛いですね)
そしてMIDI情報となる、Sequenceクラスを取得するMidiSystem.getSequenceメソッドの引数にはMIDIファイルとなるURL(やFile)があるので、これもSEの音声ファイル同様、JARファイル内の.midiファイルのパスを取得して、これを渡します。
このクラスが取得できれば再生/停止はSequencerクラスのstart/stopメソッドにて実現します。
Sequencerクラスは再生開始位置をミリ秒レベルで細かく設定でき、setMicrosecondPositionメソッドにて設定できます。
4/25の説明で「MIDIファイルのようなトラック先頭には無音を入れる(べき)仕様(これはMIDIモジュールの初期化を行うためとされています)のファイルであるが、先頭の無音をスキップ(できる場合はしたい)したいケース」という説明を行いましたが、この仕様をこのメソッドにて実現できます。
また、BGMのようなループする曲を実現する場合にはSequencerクラスのsetLoopCountメソッドにて実現できます。(これはJ2SE5.0から提供されたメソッドなので、現時点では比較的新しいメソッドです)
【まとめ】
まずはこのような感じですが、SE(.wav)/BGM(.midi)の発声方法を検討しました。
この設計をイメージにして表すと、

のような感じとなります。
次回は「ゲームプログラミング [共通]」カテゴリで設計したサウンドのフレームワークに合せて組み込んでみたいと思います。
今回はこれらの再生方法について検討して行きたいと思います。
【SE発声の検討】
まず、SE発声の実現方法ですが、数ある発声方法の中でシンプル(と私は思っている)な方法にAudioClipクラスを使用するという方法があるので、これを検討してみます。
このクラスはAppletクラスのstaticメソッドnewAudioClipを用いれば、.wav(.au)ファイルを指定してAudioClipクラスを取得することができます。
そしてファイルですが、本設計では「音声ファイルはビットマップの時同様にJARファイルの中にある」ものとします。
newAduioClipの呼び出しにはURLオブジェクトを渡す必要があるので、2/2の「ビットマップファイルの読み込み」の時に説明したようにJARファイル内の.wavファイルのパスを取得して、これを渡します。
このクラスが取得できれば再生/停止は至極簡単で、それぞれメソッドのplay/stopにて実現できます。
【BGM発声の検討】
次にBGM発声の実現方法ですが、MIDIの発声にはSequenceクラスとSequencerクラスを用いて再生できます。前者のSequenceクラスはMIDIの情報を持つクラス、後者のSequencerクラスはSequenceクラスの情報を用いてMIDIを発声させる機能という担当となります。
これらクラスはMidiSystemクラスを用いて取得することができ、それぞれ
・Sequence → MidiSystem.getSequence
・Sequencer → MidiSystem.getSequencer
にて取得します。そして、発声にはSequencerクラスのメソッドsetSequenceを用いて引数にSequenceクラスを設定します。
(どれも"Sequence"という似た文字を用いるので、少し分り辛いですね)
そしてMIDI情報となる、Sequenceクラスを取得するMidiSystem.getSequenceメソッドの引数にはMIDIファイルとなるURL(やFile)があるので、これもSEの音声ファイル同様、JARファイル内の.midiファイルのパスを取得して、これを渡します。
このクラスが取得できれば再生/停止はSequencerクラスのstart/stopメソッドにて実現します。
Sequencerクラスは再生開始位置をミリ秒レベルで細かく設定でき、setMicrosecondPositionメソッドにて設定できます。
4/25の説明で「MIDIファイルのようなトラック先頭には無音を入れる(べき)仕様(これはMIDIモジュールの初期化を行うためとされています)のファイルであるが、先頭の無音をスキップ(できる場合はしたい)したいケース」という説明を行いましたが、この仕様をこのメソッドにて実現できます。
また、BGMのようなループする曲を実現する場合にはSequencerクラスのsetLoopCountメソッドにて実現できます。(これはJ2SE5.0から提供されたメソッドなので、現時点では比較的新しいメソッドです)
【まとめ】
まずはこのような感じですが、SE(.wav)/BGM(.midi)の発声方法を検討しました。
この設計をイメージにして表すと、

のような感じとなります。
次回は「ゲームプログラミング [共通]」カテゴリで設計したサウンドのフレームワークに合せて組み込んでみたいと思います。
Javaにおけるサウンドの設計 (Javaのサポートしているデータファイルについて)
前回挙げた共通のフレームワークのサンプルはJavaのソースではありましたが、実際の音声発声を行う部分の検討は行いませんでした。これは言語をニュートラルに考えた場合に発声の仕組みが異るためです。
今回は現時点のJavaがサポートしている音声発声サウンドライブラリを用いて実装を検討してみたいと思います。
まず、前回では音声にはSE並びにBGMがあることを説明しました。そして、これらの音声ファイルにはWAVE/MIDI/MP3等のデータフォーマットがあることも説明しました。
Javaがサポートしている音声ファイルのフォーマットは大きく分けて2つの系列があり、波形データ系とコマンドデータ系に分けられます。
以下に概要を説明たいと思います。ただし、これらのデータフォーマットについて詳細な説明を行うと、とても大変なので、ここでは少し大雑把な説明を行いたいと思います。
【波形データ系】
俗に言う「生音」「自然音」のデータを表し、例えば人の声やCDの音源がコレに当ります。音を波形(WAVE)データで示す事からこのように呼ばれたりします。
Windows系のOSでは「.wav」の音声ファイルがこの系列になり、Macintosh系のOSでは「AIFF」、Solaris系でX端末とかを使っている方ならば/dev/audioで「.au」と言ったところになります。
Javaではこれらを「.wav」「.au」「AIFF」のファイルフォーマットとしてサポートしています。
波形データ形式の特徴は、「自然界の音が記録できる」「データ量が多い(=ファイルサイズが大きい)」というようになっています。特に「データ量が多い」事から、場合によりプログラムが処理を行う際に(メモリの載せて)再生するデータを調整しなければならない、配布方法を検討する必要がでてきます。
【コマンドデータ系】
「楽器に対するコマンド」のデータを表します。これはデータファイルそのものには音の情報が入っているのではなく、例えば「ピアノの音を1秒間鳴らす」というような「コマンド」がファイル内に記述されています。このためファイル内に具体的な音のデータが格納されている訳ではないため、発声させるデバイス(これはゲームにおけるPC)の能力により音が変わります。つまりAさんのコンピュータとBさんのコンピュータで同じように再生しても、コンピュータのサウンド構成により聴こえる音が多少違うことになります。これは「自分のギターで弾いた音と他人のギターで弾いた音との比較」というような例えと一緒で、当然個体差があるので、同じ曲であっても若干違って聴こえてくる…というようなものです。
また、これらコマンドはピアノやギター等のおおよその楽器の使用を前提とされており、それら以外の楽器に対する発声をサポートしていません(例えば「オタマを使って窓を叩く音を1秒鳴らす」というようなコマンドは発行できません)。このため、音が限定されます。
Javaではこれらを「.midi(.mid)」「RMF(Rich Music Format)」のファイルフォーマットとしてサポートします。
前者のMIDIはデスクトップミュージックの世界ではデファクトスタンダードな地位を築いているので、どのOSからもMIDIとして再生することができます。
後者はインターネット上での再生に適しているそうなのですが、私はあまりこのフォーマットを知りません。(このフォーマットの存在がある…という程度)
コマンドデータ形式の特徴は「再生するコンピュータにより音質が変化する(例えば同じピアノでもコンピュータにより若干音が違って聴こえたりします)」「データ量が波形データに比べて圧倒的に小さい」というようになっています。またMIDIにおけるコマンドを理解していれば、コマンドを用いて再生速度(テンポ)、ボリューム等をプログラム上で「少ないオーバーヘッドで調節する事が可能」となります。
◇ ◇ ◇
このように2つの系列を持つフォーマットをJavaはサポートしているのですが、一般的にコマンドデータ系は生音を発するSEには向いていないとされており(一応MIDIにはレーザーの音やハンドクラップ等はありますが、バラエティには富んでいません)、SE発声には大抵波形データ系を用いる事になります。
BGM発声は波形データ系/コマンド系のどちらにも適していますが、曲の長いBGMになるとBGMのデータファイルのみで、CD 1枚相当のデータ量等になってしまいます。このため波形データを圧縮するフォーマットとして、MP3等のデータフォーマットがあるのですが、Javaの標準ライブラリではこのフォーマットをサポートしていません。MP3等の高圧縮音声データを再生する場合はフリーウェアのライブラリにて再生すると良いと思います(作者の方に許可を頂いて)。本設計ではJavaの標準ライブラリのみを使用した設計を検討したいと思うので、便利なフリーウェアのライブラリを用いた設計は行わない事にします。
【まとめ】
データフォーマットについて色々と述べましたが、JavaでサポートしているデータファイルやSE/BGMに適している分類を一覧すると以下のようになります。
◇ ◇ ◇
これらの事から、本ブログでの「Java上での設計」としては、「SEには波形データ系」を「BGMにはコマンドデータ系」を用いた設計を行って行こうと考えます。
次回よりこれらの発声の実装方法を検討して行こうと思います。
今回は現時点のJavaがサポートしている音声発声サウンドライブラリを用いて実装を検討してみたいと思います。
まず、前回では音声にはSE並びにBGMがあることを説明しました。そして、これらの音声ファイルにはWAVE/MIDI/MP3等のデータフォーマットがあることも説明しました。
Javaがサポートしている音声ファイルのフォーマットは大きく分けて2つの系列があり、波形データ系とコマンドデータ系に分けられます。
以下に概要を説明たいと思います。ただし、これらのデータフォーマットについて詳細な説明を行うと、とても大変なので、ここでは少し大雑把な説明を行いたいと思います。
【波形データ系】
俗に言う「生音」「自然音」のデータを表し、例えば人の声やCDの音源がコレに当ります。音を波形(WAVE)データで示す事からこのように呼ばれたりします。
Windows系のOSでは「.wav」の音声ファイルがこの系列になり、Macintosh系のOSでは「AIFF」、Solaris系でX端末とかを使っている方ならば/dev/audioで「.au」と言ったところになります。
Javaではこれらを「.wav」「.au」「AIFF」のファイルフォーマットとしてサポートしています。
波形データ形式の特徴は、「自然界の音が記録できる」「データ量が多い(=ファイルサイズが大きい)」というようになっています。特に「データ量が多い」事から、場合によりプログラムが処理を行う際に(メモリの載せて)再生するデータを調整しなければならない、配布方法を検討する必要がでてきます。
【コマンドデータ系】
「楽器に対するコマンド」のデータを表します。これはデータファイルそのものには音の情報が入っているのではなく、例えば「ピアノの音を1秒間鳴らす」というような「コマンド」がファイル内に記述されています。このためファイル内に具体的な音のデータが格納されている訳ではないため、発声させるデバイス(これはゲームにおけるPC)の能力により音が変わります。つまりAさんのコンピュータとBさんのコンピュータで同じように再生しても、コンピュータのサウンド構成により聴こえる音が多少違うことになります。これは「自分のギターで弾いた音と他人のギターで弾いた音との比較」というような例えと一緒で、当然個体差があるので、同じ曲であっても若干違って聴こえてくる…というようなものです。
また、これらコマンドはピアノやギター等のおおよその楽器の使用を前提とされており、それら以外の楽器に対する発声をサポートしていません(例えば「オタマを使って窓を叩く音を1秒鳴らす」というようなコマンドは発行できません)。このため、音が限定されます。
Javaではこれらを「.midi(.mid)」「RMF(Rich Music Format)」のファイルフォーマットとしてサポートします。
前者のMIDIはデスクトップミュージックの世界ではデファクトスタンダードな地位を築いているので、どのOSからもMIDIとして再生することができます。
後者はインターネット上での再生に適しているそうなのですが、私はあまりこのフォーマットを知りません。(このフォーマットの存在がある…という程度)
コマンドデータ形式の特徴は「再生するコンピュータにより音質が変化する(例えば同じピアノでもコンピュータにより若干音が違って聴こえたりします)」「データ量が波形データに比べて圧倒的に小さい」というようになっています。またMIDIにおけるコマンドを理解していれば、コマンドを用いて再生速度(テンポ)、ボリューム等をプログラム上で「少ないオーバーヘッドで調節する事が可能」となります。
◇ ◇ ◇
このように2つの系列を持つフォーマットをJavaはサポートしているのですが、一般的にコマンドデータ系は生音を発するSEには向いていないとされており(一応MIDIにはレーザーの音やハンドクラップ等はありますが、バラエティには富んでいません)、SE発声には大抵波形データ系を用いる事になります。
BGM発声は波形データ系/コマンド系のどちらにも適していますが、曲の長いBGMになるとBGMのデータファイルのみで、CD 1枚相当のデータ量等になってしまいます。このため波形データを圧縮するフォーマットとして、MP3等のデータフォーマットがあるのですが、Javaの標準ライブラリではこのフォーマットをサポートしていません。MP3等の高圧縮音声データを再生する場合はフリーウェアのライブラリにて再生すると良いと思います(作者の方に許可を頂いて)。本設計ではJavaの標準ライブラリのみを使用した設計を検討したいと思うので、便利なフリーウェアのライブラリを用いた設計は行わない事にします。
【まとめ】
データフォーマットについて色々と述べましたが、JavaでサポートしているデータファイルやSE/BGMに適している分類を一覧すると以下のようになります。
波形データ系 | コマンドデータ系 | |
ファイル拡張子 | .wav/.au | .midi(.mid) |
音の種別 | 自然音 | 楽器音 |
再生による音質の変化 | 基本的に変化無し | コンピュータにより変化する |
データサイズ | とてつもなく大きい | 小さい |
ボリューム等の プログラマブル 処理負荷 | とても大きい | 小さい |
SEとして | ○ 向いている | × 向いていない |
BGMとして | ○ 向いている (ただしデータサイズの 問題があるので△) | ○ 向いている |
◇ ◇ ◇
これらの事から、本ブログでの「Java上での設計」としては、「SEには波形データ系」を「BGMにはコマンドデータ系」を用いた設計を行って行こうと考えます。
次回よりこれらの発声の実装方法を検討して行こうと思います。
Javaにおけるフレームワークのサンプルを紹介 (いままでのお浚い)
今回は、カテゴリー「ゲームプログラミング [共通]」の設計の考えと、今迄説明してきたカテゴリー「ゲームプログラミング [Java] 」における実現方法のお浚いとして、フレームワークのサンプルプログラムを挙げてみたいと思います。
これには今迄説明してきたメインループ、キー入力、タスク、キャラクタータスク、タスク管理、描画管理、描画処理が盛りこまれています。(ただし現在は説明していないサウンド処理は実装していません)
将来はこれにステージ管理や敵キャラクター等をつけて、最も単純なゲーム位は完成(かもしれない)という程度まで説明します。
(しかしその前に、次回からはXNAのカテゴリーに話を移ります)
サンプルソースは、antにてコンパイルをして、jarファイルを生成しています。
jarファイルの実行はWindows上の場合は大抵ダブルクリックにて実行可能ですが、『この実行は自己責任』にてお願いいたします。
実行すると前回説明したビットマップ"sample.png"(以下、「自機」とします)が画面に表示されるので、これをキーボードの上下にて移動することができます。
また、Zキーを押下すると自機から弾が発射されます。Zキーを押しっぱなしにすると等間隔で連続して弾が発射されます。
■フレームワークサンプルソース
【データ構成概要】

このように今迄説明した設計を応用するとこのようなことが実現可能となります。
そしてこれを何倍も味付けしていくと、本格的なテレビゲームが実現できることになります。(この「何倍も」というのがとても大変な訳なのですが…)
次の設計はサウンド系を考えていますが、この設計の説明が終了したら、このカテゴリー「ゲームプログラミング [Java] 」では「何かゲームを作ってみる」という指針を決めて、ゲームを作って行く方向でその都度必要な設計を説明していこうと思います。(現時点では何も決めていないのですが、XNAの設計の説明の最中に決めていこうかと思います…)
そしてその頃はかなり不定期な日記になっていくと思います。
(私の場合、趣味でゲームを作り始めるとそうなりがちです)
これには今迄説明してきたメインループ、キー入力、タスク、キャラクタータスク、タスク管理、描画管理、描画処理が盛りこまれています。(ただし現在は説明していないサウンド処理は実装していません)
将来はこれにステージ管理や敵キャラクター等をつけて、最も単純なゲーム位は完成(かもしれない)という程度まで説明します。
(しかしその前に、次回からはXNAのカテゴリーに話を移ります)
サンプルソースは、antにてコンパイルをして、jarファイルを生成しています。
jarファイルの実行はWindows上の場合は大抵ダブルクリックにて実行可能ですが、『この実行は自己責任』にてお願いいたします。
実行すると前回説明したビットマップ"sample.png"(以下、「自機」とします)が画面に表示されるので、これをキーボードの上下にて移動することができます。
また、Zキーを押下すると自機から弾が発射されます。Zキーを押しっぱなしにすると等間隔で連続して弾が発射されます。
■フレームワークサンプルソース
【データ構成概要】

【実行画面】
このように今迄説明した設計を応用するとこのようなことが実現可能となります。
そしてこれを何倍も味付けしていくと、本格的なテレビゲームが実現できることになります。(この「何倍も」というのがとても大変な訳なのですが…)
次の設計はサウンド系を考えていますが、この設計の説明が終了したら、このカテゴリー「ゲームプログラミング [Java] 」では「何かゲームを作ってみる」という指針を決めて、ゲームを作って行く方向でその都度必要な設計を説明していこうと思います。(現時点では何も決めていないのですが、XNAの設計の説明の最中に決めていこうかと思います…)
そしてその頃はかなり不定期な日記になっていくと思います。
(私の場合、趣味でゲームを作り始めるとそうなりがちです)