音楽関数
音楽ドライバの特徴
X-BASIC'の音楽ドライバはPCM音源です。
1つの音色データから算術演算ですべての音階のデータを作り出します。
現在の音楽ドライバは非常に重いです。仕様上同時8トラック、1トラックあたり3重和音が使えますが、
実際にそこまでの同時演奏するとテンポを維持できません。
MML
MML(Music Macro Language)は以下の通りです。隠し命令を含め、X68000のOPMDRV.Xにほぼ互換です。
(OPMDRV3.XやZ-Music系とは若干異なります。)
FM音源・PCMに関する構文(Y,@Wなど)はありません(すべてエラーになる)。
大文字小文字は区別されません。
MMLは基本的にUTF8で記述すること(コメントに日本語を使った時のみ影響する)。
書式 |
意味 |
値範囲 |
補足 |
例 |
Cn~Bn |
音符と音長 |
|
|
C-8. |
音符 |
CDEFGAB |
ド,レ,ミ,ファ,ソ,ラ,シ |
後ろに+ または # |
シャープ |
後ろに- |
フラット |
音長 |
1,2,4,8,16,32,64 |
音長指定は、その音符1音だけに対して有効 |
. (付点) |
省略したときはLまたは@Lで指定した音長になる |
|
付点は、元の音長さを1/(2*個数)づつ伸ばす
1個の時は1/2,2個の時は1/2+1/(2*2)~となる。
(長さの変化については楽典.com参照) |
Rn |
休符と音長 |
R |
|
R1 |
1,2,4,8,16,32,64 |
音長指定は、その音符1音だけに対して有効 |
. (付点) |
省略したときはLまたは@Lで指定した音長になる |
< |
オクターブ上昇 |
|
以降1オクターブ上げる |
G<G |
> |
オクターブ下降 |
|
以降1オクターブ下げる |
D>C |
'音符群' |
和音 |
|
一度に最大4音まで指定できる。 |
'C8.<G#' |
最初の1音にのみ音長を指定できる(その音長ですべての音が鳴る)。 |
和音内で使えるのは、音符(+#-を含む)、音長(付点を含む)、オクターブのみ。 |
& |
タイ |
|
次の音を発声するときに前の音を消さない(リリースが終わるまで;図1参照) |
C-4.&D |
ただし直近2音までで、3音目が発声されるときには1音目は必ず消える。 ループ音の場合は常に無効。 |
本来の演奏方法としてのタイ(およびスラー)とは違うかもしれません。 |
{~}n |
連符 |
|
{}内の音符を合わせて音長で演奏する |
{CDE}4 |
- 音長を省略したときは現在のデフォルト音長
- 数多い連符では1音あたりの音長がとても短くなり、アタックの遅い音では、音が出ない可能性があります
|
On |
デフォルトオクターブ |
0~8 |
|
O4 |
Ln |
デフォルト音長 |
1,2,4,8,16,32,64 |
音符への音長指定省略時に設定される音長 |
L2 |
付点指定はできない |
@Ln |
拡張デフォルト音長 |
1~192 |
音長をn/192分単位で指定する |
@L48 |
Qn |
発声割合 |
1~8 |
1音中で実際に音を出す割合をn/8で設定する |
Q7 |
Vn |
音量 |
0~15 |
|
V8 |
@Vn |
拡張音量 |
0~127 |
|
@V64 |
Pn |
パンポット |
1~3 |
|
P3 |
1=左,2=右,3=中央 |
@Pn |
拡張パンポット |
0~127 |
|
@P64 |
0=右~127=左,64=中央 |
@n |
音色 |
1~100 |
標準の音色については音色表参照のこと。 指定した音色が未登録の場合、@1になる。 |
@2 |
音色の切り替えには少し時間がかかる |
切り替えると前の音は即座に止まる |
音色によって基本音量が異なる |
/68では200まで指定できたが、X-BASIC'は100まで。 (必要ワークのサイズが桁違いに大きいから) |
@'~' |
コメント |
|
任意の文字列をMMLに埋め込む。 最大255バイト |
@'comment' |
m_comment()で読み取ることで、音楽と処理の同期が可能 |
BASICの最大文字列長を超える場合、BASIC側で全体を読み込めない。
BASICプログラムと同じ文字コードにすること。 |
: |
小節線 |
|
単に無視される。 |
CDECDE : GEDCDE : DR |
Tn |
テンポ |
32~200 |
1分間に4分音符を何拍演奏するか。 |
T128 |
/68では1つのチャンネル(トラック)で実行すればすべてのチャンネルに影響したが、
X-BASIC’は各チャンネルが完全に独立しているので テンポも各CHに設定する必要がある。 |
m_tempo()は全チャンネル一斉に設定する |
|:n ~ :| |
反復記号 |
1~256 n省略時は2 |
n回反復演奏する(ループ回数n)。 |
|:3 ~ |1 ~ |2~ |3 ~ :| |
|n |
|
n回目のループ時に演奏する部分を示す ループがネストしている場合は、直近のループに対するものとなる。 |
同じnが複数あった場合は、すべてが演奏される。 |
ループ回数より大きな値の部分は演奏されない。 |
nの記述順は自由。 |
|nはネストできない。
ゆえに |: ~ |1 |: |1 |2 :| :| という記述はできない。
1トラック内での回数制限はないので、 |: ~ |1 |2 :| |: |1 |2 :| は可能。 |
[D.C.] |
|
|
先頭に戻る |
|
1回のみ |
音色・パンポット・音量は戻らないので、必要ならMMLコマンドを置くこと |
[D.S.] |
|
|
[SEGNO]に戻る |
|
1回のみ |
音色・パンポット・音量は戻らないので、必要ならMMLコマンドを置くこと |
[SEGNO] [$] |
|
|
[D.S.]からの戻り場所 [D.S.]の前に存在すること |
|
[TOCODA] [*] |
|
|
[CODA]に飛ぶ |
|
1回のみ |
音色・パンポット・音量は戻らないので、必要ならMMLコマンドを置くこと |
[CODA] |
|
|
[*]の飛び先 |
|
[FINE] [^] |
|
|
[D.C.][D.S.][*]実行後なら演奏を終了 |
|
[END] |
|
|
演奏終了 |
|
[!] |
|
|
次の[!]まで飛ぶ ただし最初の1対のみ有効 |
[!]~1[!]~2[!]~3[!] ~1は演奏されず、~2,~3が演奏されます(2つ目以降の[!]は無視されるから)。 |
[LOOP] |
|
|
[DO]に戻る(無限ループ) |
[DO]~1[LOOP]~2 ~1だけが演奏され続けます。 |
[DO] |
|
|
[LOOP]からの戻り位置 |
同一ジャンプのネスティングはできない。
[END] [!] [LOOP] [DO] は/68の隠しMML。
図1:音色の時間的変化
音楽関数
チャンネルとトラックの関係は以下の通りです。

トラックはMML文字列をあらかじめ格納しておく領域です。
BASICの文字列では長い音楽を表現できないので、トラック上では最大文字列長を超えてMMLが結合されていきます。
MMLの最大長に制約はありません。
そのトラックを、実際に発声可能なチャンネルに割り付けます。
演奏中にチャンネルとトラックの割り付けを変更することで、演奏順の変更などが出来ます。
1つのチャンネルに割り付けられるトラックは、同時には1つだけです。
基本的には1チャンネルで1音が鳴りますが、4音まで同時発声可能な和音指定が出来るので、
理屈上は最大4*8音が同時出力可能です(が、重いので推奨しません)。
音楽関数を使う場合の全体の流れは以下のようになります。
- m_init()
- m_trk(trk,"mml")またはm_ftrk(trk,MMLファイル名)
- m_assign(ch,trk)
- m_play(ch)
サンプルとしてはmmlPlayer.bas や sym.bas をご覧ください。
関数名 | m_init |
書式 | m_init() |
機能 |
音楽関数を初期化する。
- トラック内容を消去
- CH~トラック割り付けを解除
- 音量を初期化(V8)
- パンポットを初期化(P3)
|
引数 | なし |
戻り値 | 常に0 |
関数名 | m_trk |
書式 | int m_trk(trk;int,mml;str) |
機能 |
トラックへMML文字列を追加する。
1トラック容量に上限はない。
演奏中でもトラック内容を変更することは出来るが、
再度m_play()を発行しない限り、変更された内容による演奏にはならない。
|
引数 |
|
戻り値 |
|
備考 | /68と異なり、iOSによりワークが自動確保されるので、m_alloc()はありません。 |
関数名 | m_ftrk |
書式 | int m_ftrk(trk;int,mmlFname;str) |
機能 |
ファイル中のMMLをトラックへを追加する。
1トラック容量に上限はない。
演奏中でもトラック内容を変更することは出来るが、
再度m_play()を発行しない限り変更された内容による演奏にはならない。
|
引数 |
trk | 1~80 | トラック番号 |
mmlFname | | MMLの含むテキストファイル |
|
戻り値 |
0 | 正常終了 |
<0 | エラー(ファイルが見つからないなど) |
|
備考 | /68と異なり、iOSによりワークが自動確保されるので、m_alloc()はありません。 |
関数名 | m_free |
書式 | int m_free(trk;int) |
機能 |
トラックを解放する。
|
引数 |
|
戻り値 | 常に0 |
関数名 | m_assign |
書式 | int m_assign(ch;int,trk;int) |
機能 |
チャンネルにトラックを割り当てる。
|
引数 |
ch | 1~8 | 割り付けるチャンネル |
trk | 1~80 | トラック番号 |
|
戻り値 | 常に0 |
関数名 | m_tone |
書式 | int m_tone(tno;int,toneFile;str,rate;int,octave;int,scale;int,floop;int) |
機能 |
音色データを設定する。
|
引数 |
tno | 1~100 | 音色を登録する番号 |
toneFile | | 音色ファイル名。
以下の音声フォーマットをサポートしている:
拡張子 | フォーマット |
.wav | WAV (RIFF Waveform Audio Format) |
.pcm | X68000 ADPCM |
.M44 | 44.1 KHz モノラル 符号あり 16ビットPCM(ビッグエンディアン) |
.M30 | 30.0 KHz モノラル 符号あり 16ビット(有効12ビット)PCM(ビッグエンディアン) |
.P16 | 15.625KHz モノラル 符号あり 16ビット(有効12ビット)PCM(ビッグエンディアン) |
拡張子まで記述する必要がある。
|
rate | | サンプリングデータのサンプリングレート(Hz) .pcmでのみ指定が必要。 |
octave | 0~8 | サンプリングデータのオクターブ
この音源は1つの音色データから8オクターブのすべての音階のデータを計算で作り出す。
オクターブと音階は、その音色の音程である。
|
scale |
ド | SCALE_C |
ド# | SCALE_CS |
レ | SCALE_D |
レ# | SCALE_DS |
ミ | SCALE_E |
ファ | SCALE_F |
ファ# | SCALE_FS |
ソ | SCALE_G |
ソ# | SCALE_GS |
ラ | SCALE_A |
ラ# | SCALE_AS |
シ | SCALE_B |
| サンプリングデータの音階
|
floop | YES/NO | ループ音かどうか
NO | 弦楽器など勝手に消音するタイプの楽器 発声時、繰り返されない。 |
YES | 管楽器など、吹いている間音が出続けるタイプの楽器 指定音長分繰り返し発声される。 |
|
標準で用意しているデータは以下の通り。
音色表
音色番号 | 音色名 | オクターブ | 音階 | ループ |
1 | アコースティックピアノ | 4 | SCALE_C | NO |
3 | エレクトリックピアノ | 4 | SCALE_C | NO |
7 | アコースティックギター | 4 | SCALE_C | NO |
8 | エレクトリックギター | 4 | SCALE_C | NO |
10 | バス | 3 | SCALE_C | NO |
11 | バンジョー | 4 | SCALE_C | NO |
12 | シタール | 5 | SCALE_A | NO |
14 | 琴 | 4 | SCALE_C | NO |
15 | パイプオルガン | 1 | SCALE_A | YES |
19 | ヴァイオリン | 4 | SCALE_C | YES |
21 | ストリング1 | 4 | SCALE_C | YES |
22 | ストリング2 | 3 | SCALE_A | YES |
25 | コーラス | 4 | SCALE_C | YES |
33 | サックス | 3 | SCALE_C | YES |
34 | トランペット | 4 | SCALE_C | YES |
35 | ホルン | 5 | SCALE_C | YES |
36 | トロンボーン | 4 | SCALE_C | YES |
37 | チューバ | 4 | SCALE_C | YES |
43 | ホイッスル | 4 | SCALE_C | NO |
45 | スネアドラム | 2 | SCALE_C | NO |
46 | リムショット | 4 | SCALE_C | NO |
48 | タムタム | 3 | SCALE_C | NO |
49 | ティンパニ | 1 | SCALE_C | NO |
50 | ボンゴ | 4 | SCALE_C | NO |
52 | トライアングル | 5 | SCALE_C | NO |
53 | カウベル | 4 | SCALE_C | NO |
55 | スチールドラム | 2 | SCALE_C | NO |
58 | マリンバ | 4 | SCALE_C | NO |
59 | クローズハイハット | 5 | SCALE_C | NO |
60 | オープンハイハット | 3 | SCALE_C | NO |
66 | ブラスター | 4 | SCALE_C | NO |
別の音色を追加するときは、空き番号を使うか、既存音色に対して上書きすること。
m_init()すると元に戻る。
|
戻り値 |
NO | 正常終了 |
YES | エラー(ファイルが見つからない/サポートされたフォーマットでない/メモリー不足など) |
|
備考 |
- 既存音色を置き換えた時は、実際に音が変わるのは@nで音色を設定するタイミングです(演奏中に変わることはない)
- 一般に、1音階のサンプリングデータから算術演算で音階データを作り出した場合、
せいぜい1~2オクターブ範囲でしかきれいな音色になりません。
もし全音階できれいな音色にしたい場合は、オクターブ別に音色を用意してください。
(将来のバージョンでは音階別サンプリングデータをサポートする予定です。
ただし、そのようなサンプリングデータが用意できれば。
- ループ音はうまく作らないと、ループする部分でプチ音が鳴ってしまいます。標準データでも多くはそれは解消されていません。
- 標準の音色・オクターブ・音階は必ずしも正しくないかもしれません(それらがはっきりしない物は適当に設定してあるので)。
私には音色などを識別する能力はないので(T_T)。
- 音色データはオンメモリに確保するため、音色を登録すればするほど多くのワークを必要とします。
|
関数名 | m_compile |
書式 | int m_compile(trk;int) |
機能 |
トラック内容を中間コードにコンパイルする。
通常はm_play()呼び出し時に自動的にコンパイルするが、
長いMMLの場合、それに時間がかかり演奏が遅延することがあるので、
それを避けたい場合には予めこれで処理する。
|
引数 |
|
戻り値 | エラーコード |
関数名 | m_play |
書式 | int m_play([c1;int][,c2;int]...[,c8;int]) |
機能 |
指定したチャンネルを演奏する。
そのチャンネルが演奏中の時はいったん演奏を中止し、トラック内容をコンパイルしてから演奏を開始する。
m_compile()でコンパイル済みの時は即時演奏が開始される。
|
引数 |
c1~c8 | 各1~8 | 演奏を開始するチャンネル。最大で8CH分指定できる。
省略時は全チャンネル
|
|
戻り値 | エラーコード |
備考 |
m_play()開始時には以下の状態で初期化されます。
- デフォルト音長4(L4または@L48)
- オクターブ4(O4)
- 音色1(@1)
- 発声割合8(Q8)
テンポはコンパイル時にm_tempo()で設定した値(指定していないときはT120)です。
パンポットと音量は外部で設定できるので初期化はありません。
前の演奏の結果を引き継ぐことはありません。
|
関数名 | m_stop |
書式 | int m_stop([c1;int][,c2;int]...[,c8;int]) |
機能 |
指定チャンネルを演奏一時停止する。
|
引数 |
c1~c8 | 各1~8 | 演奏を一時停止するチャンネル。最大で8CH分指定できる。
省略時は全チャンネル |
|
戻り値 | 常に0 |
関数名 | m_cont |
書式 | int m_cont([c1;int][,c2;int]...[,c8;int]) |
機能 |
チャンネルの演奏を再開する。
|
引数 |
c1~c8 | 各1~8 | 演奏を再開するチャンネル。最大で8CH分指定できる。
省略時は全チャンネル |
|
戻り値 | 常に0 |
関数名 | m_mute |
書式 | int m_mute([c1;int][,c2;int]...[,c8;int]) |
機能 |
指定チャンネルをミュートする。
|
引数 |
c1~c8 | 各1~8 | ミュートするチャンネル。最大で8CH分指定できる。
省略時は全チャンネル |
|
戻り値 | 常に0 |
関数名 | m_muteoff |
書式 | int m_muteoff([c1;int][,c2;int]...[,c8;int]) |
機能 |
指定チャンネルのミュートを解除する。
|
引数 |
c1~c8 | 各1~8 | ミュートを解除するチャンネル。最大で8CH分指定できる。
省略時は全チャンネル |
|
戻り値 | 常に0 |
関数名 | m_solo |
書式 | int m_solo(ch;int) |
機能 |
指定チャンネル以外をミュートする。
|
引数 |
|
戻り値 | 常に0 |
関数名 | m_stat |
書式 | int m_stat(ch;int) |
機能 |
指定チャンネルの演奏状態を得る
|
引数 |
|
戻り値 |
ch | <=0時 | BIT?=チャンネルで 1=演奏中 , 0=停止中 |
=1~8時 | 1=演奏中 , 0=停止中 |
|
関数名 | m_tempo |
書式 | int m_tempo(te;int) |
機能 |
MML内にテンポ指定(T)がないときのデフォルトテンポ設定を設定する。
全ch共通で設定される。
m_compile()もしくはm_play()前に設定しなければならない =演奏中に変更することは出来ない。
|
引数 |
te | 32~200 | 1分間に4分音符を何拍演奏するかの値 |
|
戻り値 | 常に0 |
補足 | m_tempo()の指定がないときはm_tempo(120)相当です。 |
関数名 | m_pan |
書式 | int m_pan(ch;int,pan;int) |
機能 |
指定チャンネルのパンポットを設定する。
pan<0の時は現在の音量を得る(MMLで変更ているときはその値)。
|
引数 |
ch | 1~8 | チャンネル |
pan | 0=右~127=左,64=中央 | パンポット設定値 |
<0 | 現在のパンポットを得る |
|
戻り値 |
設定時は常に0、読み出し時は現在のパンポット。
|
関数名 | m_vol |
書式 | int m_vol(ch;int,vl;int) |
機能 |
指定チャンネルの音量を設定する。
vl<0の時は現在の音量を得る(MMLで変更ているときはその値)。
|
引数 |
ch | 1~8 | チャンネル |
vl | 0~127 | 音量設定 |
<0 | 現在の音量を得る |
|
戻り値 |
設定時は常に0、読み出し時は現在の音量。
|
関数名 | m_comment |
書式 | str m_comment(ch;int) |
機能 | 指定チャンネルでの直前のコメント(@'~')を読み出す
これを使えば、音楽との同期処理が可能になる。
|
引数 |
|
戻り値 | コメント文字列
文字コードはMML内のそれに従う。
最大文字列長を超えるときは、先頭から入りきるだけ分返してくる。
|
関数名 | m_count |
書式 | int m_count(ch;int) |
機能 |
MML先頭からの発声した音および休符の総数を返す。
|
引数 |
|
戻り値 |
その総数
MML上の数ではなく、繰り返しなども考慮した実際の発声数である。
和音は1音と数える。
|
エラーコード
エラーコードは以下のようになっています。エラーは<0です。
エラーコードは将来的に変更される可能性があります。
MMLのエラーを判別するだけにとどめ、コードに依存する処理は書かないでください。
0 | 正常終了 |
1 | 正常終了(MMLが終了した) |
-100 | 内容がおかしい |
-99 | 異常なコマンド |
-98 | fetch中なのに別のMMLオブジェクトを設定しようとした |
-96 | オクターブの指定値がおかしい |
-95 | 音長値がおかしい |
-94 | テンポ値がおかしい |
-93 | 音量値がおかしい |
-92 | 音色値がおかしい |
-91 | パンポット値がおかしい |
-90 | 発声割合値がおかしい |
-88 | 音階の記述がおかしい |
-87 | 異常なMMLが存在する |
-86 | トークン長が長すぎる |
-84 | @以降の文字列が長すぎる |
-83 | |:がないのに|nがあった、|:~:|の対が正しくない(閉じてない) |
-80 | |:スタックがいっぱい=ネストが深すぎる |
-79 | |:スタックが空なのに読み出そうとした=対でない:|がある |
-78 | |nスタックがいっぱい |
-77 | |nスタックが空なのに読み出そうとした |
-76 | SEGNOがない |
-75 | SEGNOが多重にある |
-74 | DOがない |
-73 | DOが多重にある |
-72 | CODAがない |
-71 | CODAが多重にある |
-70 | 連符により1音が短くなりすぎる、連符なのに個別の音長さ指定がある |
-69 | {}が対になってない、{がないのに}があった、{がネストしている |
-68 | |nのn記述がない |
-67 | 和音数が多すぎる |
-66 | 和音の中に許されない記述がある、和音が閉じていない |
-65 | コメントが長過ぎる |
-64 | &(タイ)記述がおかしい |
-10 | メモリが足りない |
-9 | MMLが大きすぎる(オブジェクト、コメント) |
-8 | MMLの実体がない(テキスト、オブジェクト) |
全関数名リスト(アルファベット順)