MIDI-Perl-0.8 > MIDI::Simple

名前

MIDI::Simple - procedural/OOP interface for MIDI composition

MIDI::Simple - MIDI作曲のための手続き的/オブジェクト指向的なインターフェース

概要

 use MIDI::Simple;
 new_score;
 text_event 'http://www.ely.anglican.org/parishes/camgsm/chimes.html';
 text_event 'Lord through this hour/ be Thou our guide';
 text_event 'so, by Thy power/ no foot shall slide';
 set_tempo 500000;  # 1 qn => .5 seconds (500,000 microseconds)
 patch_change 1, 8;  # Patch 8 = Celesta

 noop c1, f, o2;  # Setup
 # Now play
 n qn, Cs2;   n F;   n Ds;  n hn, Gs_d1;
 n qn, Cs;    n Ds;  n F;   n hn, Cs;
 n qn, F;     n Cs;  n Ds;  n hn, Gs_d1;
 n qn, Gs_d1; n Ds;  n F;   n hn, Cs;

 write_score 'westmister_chimes.mid';

バージョン変更に関する注意

I consider this module a late-stage beta. Let me know if you run into any problems, and feel free to suggest features.

このモジュールは後半段階のベータ版である。何か問題が発生したら 私に知らせて欲しい。そしてお気軽に機能の提案をしていただきたい。

This module is somewhat incompatible with the MIDI::Simple versions before .700.

このモジュールはバージョン0.7以前のMIDI::Simpleとは少々互換性がない。

I think I've settled on (i.e., basically frozen) the basic interface for this module, and will now hopefully only add functionality.

このモジュールの基本的なインターフェースは決定済み(すなわち基本的に固定) と考えている。そして今や機能の追加だけですむことを願っている。

説明

This module sits on top of all the MIDI modules -- notably MIDI::Score (so you should skim MIDI::Score) -- and is meant to serve as a basic interface to them, for composition. By composition, I mean composing anew; you can use this module to add to or modify existing MIDI files, but that functionality is to be considered expermental.

このモジュールは全てのMIDIモジュール -- 特にMIDI::Score(MIDI::Scoreを 参照のこと) -- の上位に位置し、作曲のためのベーシックインターフェースの 役割を担っている。ここで作曲とは、新規作成のことだ。このモジュールを使って 既存のMIDIファイルに追加や修正が出来る。ただし、この機能は実験的なものだ。

This module provides two related but distinct bits of functionality: 1) a mini-language (implemented as procedures that can double as methods) for composing by adding notes to a score structure; and 2) simple functions for reading and writing scores, specifically the scores you make with the composition language.

このモジュールは二つの相互に関係した、しかし区別された機能を提供する: (1)スコア構造体にノートを追加することによって作曲を行えるミニ言語 (プロシージャとしてもメソッドとしても実装されている)。 (2)楽譜の読み書きのためのシンプルな機能。厳密に言うと この作曲用言語で作ったスコアのことだが。

The fact that this module's interface is both procedural and object-oriented makes it a definite two-headed beast. The parts of the guts of the source code are not for the faint of heart.

このモジュールのインターフェースがプロシージャかつオブジェクト指向である という事実は、モジュールを双頭の獣にさせてしまっている。ソースコードの中身は 心臓の弱い方にはお勧めできない。

オブジェクトの構造

A MIDI::Simple object is a data structure with the following attributes:

MIDI::Simpleのオブジェクトは、次のような属性を持ったデータ構造である:

Score(スコア)

This is a list of all the notes (each a listref) that constitute this one-track musical piece. Scores are explained in MIDI::Score. You probably don't need to access the Score attribute directly, but be aware that this is where all the notes you make with n events go.

これは1トラックの作品データを構成している全ノート(各々はリスト リファレンス)のリストである。スコアについてはMIDI::Scoreで説明して ある。あなたが直接スコアの属性にアクセスする必要はないだろう。 だが、あなたがnイベントで作った全ノートはこのスコアを進むことに 気をつけて欲しい。

Time(タイム)

This is a non-negative integer expressing the start-time, in ticks from the start-time of the MIDI piece, that the next note pushed to the Score will have.

これはMIDIデータの開始からの時間を負でない整数で表したもので、 単位はティックだ。Scoreに追加される次のノートはこの値を持つ。

Channel(チャンネル)

This is a number in the range [0-15] that specifies the current default channel for note events.

これは0-15の範囲の値をとり、ノートイベントのために現在の既定のチャンネルを 指定する。

Duration(デュレーション:持続時間)

This is a non-negative (presumably nonzero) number expressing, in ticks, the current default length of note events, or rests.

これは負でない(たぶん0でない)数で、ノートや休止の現在のデフォルトの 長さを表す。単位はティック。

Octave(オクターブ)

This is a number in the range [0-10], expressing what the current default octave number is. This is used for figuring out exactly what note-pitch is meant by a relative note-pitch specification like "A".

これは0-10の範囲の数で現在のデフォルトのオクターブ番号が何であるかを表す。 これを使って、"A"のような音階の相対的指定が何を意味するのかを正確に 把握することができる。

Notes(ノート:音符)

This is a list (presumably non-empty) of note-pitch specifications, as note numbers in the range [0-127].

これは音階指定のリスト(たぶん空ではない)で、0から127の ノートナンバーとして表される。

Volume(ボリューム)

This is an integer in the range [0-127] expressing the current default volume for note events.

これは0から127までの整数で、ノートに適用される現在のデフォルトの ボリュームを表す。

Tempo(テンポ)

This is an integer expressing the number of ticks a quarter note occupies. It's currently 96, and you shouldn't alter it unless you really know what you're doing. If you want to control the tempo of a piece, use the set_tempo routine, instead.

四分音符に占めるティックの数を表す整数。デフォルトは96だが、自分が何を やっているのか本当に理解できていない限り、この値を変更すべきではない。 作品のテンポをコントロールしたいなら代わりにset_tempoを使うこと。

Cookies

This is a hash that can be used by user-defined object-methods for storing whatever they want.

ユーザー定義のオブジェクトメソッドが必要なデータを保持するために 利用するハッシュ。

Each package that you call the procedure new_score from, has a default MIDI::Simple object associated with it, and all the above attributes are accessible as:

new_soreプロシージャから呼び出す全てのパッケージは、そのパッケージと 結びついたデフォルトのMIDI::Simpleオブジェクトを持っている。先に見た属性は 全て、次のようにしてアクセスできる。

  @Score $Time $Channel $Duration $Octave
  @Notes $Volume $Tempo %Cookies

(Although I doubt you'll use these from any package other than "main".) If you don't know what a package is, don't worry about it. Just consider these attributes synonymous with the above-listed variables. Just start your programs with

(あなたが"mian"パッケージ以外のパッケージからこれらを使うかどうか わからないが、)パッケージが何か理解できなくても、心配いらない。 とにかく属性は上記の変数と同じ名前を持つと考えればいいだけだ。 あなたのプログラムの最初で:

  use MIDI::Simple;
  new_score;

and you'll be fine.

とやれば問題ない。

ルーチン/メソッド/プロシージャ

MIDI::Simple provides some pure functions (i.e., things that take input, and give a return value, and that's all they do), but what you're mostly interested in its routines. By "routine" I mean a subroutine that you call, whether as a procedure or as a method, and that affects data structures other than the return value.

MIDI::Simpleはいくつかの純粋な関数(インプットをとり、戻り値を返すだけのもの)を提供する。しかし、そのルーチンは大変興味深いものだ。私は「ルーチン」をあなたが呼び出すサブルーチンの意味で使っている。これはプロシージャかメソッドかは関係ない。そして戻り値ではなくデータ構造に影響を与える。

Here I'm using "procedure" to mean a routine you call like this:

ここで私はプロシージャを次のような呼び出しをするルーチンの意味で使っている:

  name(parameters...);
  # or, just maybe:
  name;

(In technical terms, I mean a non-method subroutine that can have side effects, and which may not even provide a useful return value.) And I'm using "method" to mean a routine you call like this:

(技術的なことを言えば、副次効果をもたらす非メソッドなサブルーチンのことで、これは有益な戻り値をもたらさないだろう。)そしてメソッドとは次のような呼び出し方をするルーチンだ:

  $object->name(parameters);

So bear these terms in mind when you see routines below that act like one, or the other, or both.

これから先、一方か他方、あるいはその両方の振る舞いをするルーチンを見たら、 これらの言葉を思い出して欲しい。

MAIN ROUTINES

These are the most important routines:

最重要のルーチン:

new_score() または $obj = MIDI::Simple->new_score()

As a procedure, this initializes the package's default object (Score, etc.). As a method, this is a constructor, returning a new MIDI::Simple object. Neither form takes any parameters.

プロシージャとしてこのルーチンはパッケージのデフォルトオブジェクト (Score等)を初期化する。メソッドとしてはこのルーチンはコンストラクタ として機能し、新規のMIDI::Simpleオブジェクトを返す。どちらも引数をとらない。

n(...parameters...) または $obj->n(...parameters...)

This uses the parameters given (and/or the state variables like Volume, Channel, Notes, etc) to add a new note to the Score -- or several notes to the Score, if Notes has more than one element in it -- or no notes at all, if Notes is empty list.

このルーチンは与えられたパラメータ(Volume、Channel、Notes等々)を利用してScoreに新規のノートを追加する。あるいは、ノートが複数の要素をもっているならScoreにいくつかのノートを付け加える。もしNotesが空リストなら、ノートは付け加わらない。

Then it moves Time ahead as appropriate. See the section "Parameters For n/r/noop", below.

それからTimeを適切に進める。下の"n/r/nopのパラメータ"の所を見て欲しい。

r(...parameters...) or $obj->r(...parameters...)

This is exactly like n, except it never pushes anything to Score, but moves ahead Time. (In other words, there is no such thing as a rest-event; it's just a item during which there are no note-events playing.)

このルーチンはnとそっくりだ。例外はといえば、Timeを進める以外何もScoreに付け加えないということだけだ。(つまり、休止イベントのようなものは存在せず、ただノートイベントのない項目ということ。)

noop(...parameters...) or $obj->noop(...parameters...)

This is exactly like n and r, except it never alters Score, and never changes Time. It is meant to be used for setting the other state variables, i.e.: Channel, Duration, Octave, Volume, Notes.

このルーチンはnとそっくりだ。例外はScoreTimeに変更を加えないということだ。他のステータス変数、つまりChannel、Duration、Octave、Volume、Notesをセットするために使われる。

n/r/noopのパラメータ

A parameter in an n, r, or noop call is meant to change an attribute (AKA state variable), namely Channel, Duration, Octave, Volume, or Notes.

nr、やnoopを呼び出す際のパラメータは、属性(ステータス変数)、すなわちChannel、Duration、Octave、Volume、Notesを変更する。

Here are the kinds of parameters you can use in calls to n/r/noop:

n/r/noopの呼び出しに利用できるパラメータは:

* A numeric volume parameter. This has the form "V" followed by a positive integer in the range 0 (completely inaudible?) to 127 (AS LOUD AS POSSIBLE). Example: "V90" sets Volume to 90.

※数値によるvolumeパラメータ。これは"V"の後に0(完全に聞こえない?)から127(可能な限り 大 き く)までの正の整数が続く形式を持つ。例:"V90"はボリュームを90にセットする。

* An alphanumeric volume parameter. This is a key from the hash %MIDI::Simple::Volume. Current legal values are "ppp", "pp", "p", "mp", "mezzo" (or "m"), "mf", "f", "ff", and "fff". Example: "ff" sets Volume to 112. (Note that "m" isn't a good bareword, so use "mezzo" instead, or just always remember to use quotes around "m".)

※アルファベットによるvolumeパラメータ。これは%MIDI::Simple::Volumeのキーである。現在適正な値は、"ppp"、"pp"、"p"、"mp"、"mezzo"("m")、"mf"、"f"、"ff"、"fff"。例:"ff"はボリュームに112をセットする("m"は裸のワードとしては具合がよろしくないので、代わりに"mezzo"を使うこと。あるいは常に"m"をクォートで囲んでおくことを忘れないようにする)。

* A numeric channel parameter. This has the form "c" followed by a positive integer 0 to 15. Example: "c2", to set Channel to 2.

※数値による channelパラメータ。これは"c"の後に0から15までの正の整数が続く形式を持つ。例:"c2"はチャンネルに2をセットする。

* A numeric duration parameter. This has the form "d" followed by a positive (presumably nonzero) integer. Example: "d48", to set Duration to 48.

※数値によるdurationパラメータ。これは"d"の後に正の(たぶん0は入らない)整数が続く形式を持つ。例:"d48"はデュレーションに48をセットする。

* An alphabetic (or in theory, possibly alphanumeric) duration parameter. This is a key from the hash %MIDI::Simple::Length. Current legal values start with "wn", "hn", "qn", "en", "sn" for whole, half, quarter, eighth, or sixteenth notes. Add "d" to the beginning of any of these to get "dotted..." (e.g., "dqn" for a dotted quarter note). Add "dd" to the beginning of any of that first list to get "double-dotted..." (e.g., "ddqn" for a double-dotted quarter note). Add "t" to the beginning of any of that first list to get "triplet..." (e.g., "tsn" for a triplet sixteenth note -- i.e. a note such that 3 of them add up to something as long as one eighth note). You may add to the contents of %MIDI::Simple::Length to support whatever abbreviations you want, as long as the parser can't mistake them for any other kind of n/r/noop parameter.

※アルファベット(論理的にはアルファベットと数)によるduration。これは%MIDI::Simple::Lengthのキーだ。現在適正な値としては、全音符、二分音符、四分音符、八分音符、十六分音符に対応して、"wn"、 "hn"、 "qn"、"en"、"sn"がある。これらの最初に"d"を付け加えることで「付点〜」を得ることができる(例:"dqn"は付点四分音符)。先頭に"dd"を付けると「複付点〜」を得ることができる(例:"ddqn"は複付点四分音符)。先頭に"t"を付けることで「三連〜」を得ることができる("tsn"は三連十六分音符、つまり八分音符の長さの所に三つ音符が入る)。パーサーが他のn/r/noopのパラメータのものと取り違えない限り、あなたの望む略譜を%MIDI::Simple::Lengthに付け加えることができる。

* A numeric, absolute octave specification. This has the form: an "o" (lowercase oh), and then an integer in the range 0 to 10, representing an octave 0 to 10. The Octave attribute is used only in resolving relative note specifications, as explained further below in this section. (All absolute note specifications also set Octave to whatever octave they occur in.)

※数値によるoctaveの絶対指定。これは次の形式:"o"(小文字のオー)と、その後ろに0から10の整数(オクターブ0〜10)。このセクションのもう少し後で説明するように、オクターブ属性はノートの相対指定を解決する際にのみ用いられる(ノートの絶対指定は全て、それがどのオクターブにあるのかを設定する)。

* A numeric, relative octave specification. This has the form: "o_d" ("d" for down) or "o_u" ("u" for down), and then an integer. This increments, or decrements, Octave. E.g., if Octave is 6, "o_d2" will decrement Octave by 2, making it 4. If this moves Octave below 0, it is forced to 0. Or if it moves Octave above 10, it is forced to 10. (For more information, see the section "Invalid or Out-of-Range Parameters to n/r/noop", below.)

※数値によるoctaveの絶対指定。これは次の形式:"o_d"("d"は下がるの意味)か"o_u"(uは上がるの意味[訳補足:原文は下がるになっている])とその後ろに整数。これはオクターブ上げたり、下げたりする。例えば、オクターブが6の時、"o_d2"は二つ下げてオクターブ4にする。もしこれによってオクターブが0より小さい値になっても、強制的に0になる。また、オクターブが10より大きくなったら、強制的に10になる(詳細は後で出てくる"/n/r/noopのパラメータが不正、あるいは範囲を超えた場合"を参照のこと)。

* A numeric, absolute note specification. This has the form: an optional "n", and then an integer in the range 0 to 127, representing a note ranging from C0 to G10. The source to MIDI has a useful reference table showing the meanings of given note numbers. Examples: "n60", or "60", which each add a 60 to the list Notes.

※数値によるnoteの絶対指定。これは次の形式:省略可能な"n"とその後にC0からG10を表す0から127までの整数値。MIDIのソースには、ノートナンバーの意味を示す便利なリファレンス表が入っている。例:"n60"もしくは"60"とやると、Notesリストに60が追加される。

Since this is a kind of absolute note specification, it sets Octave to whatever octave the given numeric note occurs in. E.g., "n60" is "C5", and therefore sets Octave to 5.

これは一種の絶対指定なので、数値で指定されたノートにはオクターブがセットされる。例えば、"n60"は"C5"なので、オクターブには5がセットされる。

The setting of the Notes list is a bit special, compared to how setting the other attributes works. If there are any note specifications in a given parameter list for n, r, or noop, then all those specifications together are assigned to Notes.

ノートリストへのセットは、他の属性へのセットの仕方に比べて少し特殊だ。n/r/noopのパラメーターリストに何らかのノート指定をすると、それらの指定は全て一緒にノートに足される。

If there are no note specifications in the parameter list for n, r, or noop, then Notes isn't changed. (But see the destription of "rest", at the end of this section.)

n/r/noopのパラメーターリストにノート指定をしない場合、ノートは変化しない(ただしこのセクションの最後、"休符"の説明を見ること)。

So this:

だから:

  n mf, n40, n47, n50;

sets Volume to 80, and Notes to (40, 47, 50). And it sets Octave, first to 3 (since n40 is in octave 3), then to 3 again (since n47 = B3), and then finally to 4 (since n50 = D4).

これはボリュームに80、それからノートに40,47,50がセットされる。そしてオクターブは最初のノートに3(n40はオクターブ3だから)、次にもう一度3(n47=B3)、最後に4(n50=D4)がセットされる。

Note that this is the same as:

これは次のものと同じことに注意:

  n n40, n47, n50, mf;

The relative orders of parameters is usually irrelevant; but see the section "Order of Parameters in a Call to n/r/noop", below.

パラメータの相対的な順番は通常どうでもよい。だが後に出てくるn/r/noopの呼び出しにおけるパラメータの順番"を参照のこと。

* An alphanumeric, absolute note specification.

※アルファベットと数値によるnoteの絶対指定。

These have the form: a string denoting a note within the octave (as determined by %MIDI::Simple::Note -- see below, in the description of alphanumeric, relative note specifications), and then a number denoting the octave number (in the range 0-10). Examples: "C3", "As4" or "Asharp4", "Bf9" or "Bflat9".

次の形式を持つ:オクターブの取りうる範囲内(%MIDI::Simple::Noteに定められている--下のアルファベットと数値、ノートの相対指定の説明を参照)の音符を意味する文字列と、その後ろにオクターブ番号を表す数(0〜10)。例:"Cd"、"As4"あるいは"Asharp4"、"Bf9"あるいは"Bflat9"。

Since this is a kind of absolute note specification, it sets Octave to whatever octave the given numeric note occurs in. E.g., "C3" sets Octave to 3, "As4" sets Octave to 4, and "Bflat9" sets Octave to 9.

これは一種の絶対指定なので、数値で指定されたノートにはオクターブがセットされる。例えば、"C3"はオクターブに3を、"As4"はオクターブに4を、"Bflat9"はオクターブに9をセットする。

This:

つまり:

  n E3, B3, D4, mf;

does the same as this example of ours from before:

これは次の例と同じことだ。

  n n40, n47, n50, mf;

* An alphanumeric, relative note specification.

※アルファベットによるnoteの相対指定。

These have the form: a string denoting a note within the octave (as determined by %MIDI::Simple::Note), and then an optional parameter "_u[number]" meaning "so many octaves up from the current octave" or "_d[parameter]" meaning "so many octaves down from the current octave".

次の形式を持つ:オクターブの範囲内(%MIDI::Simple::Noteによって定められている)で音符を意味する文字列と、その後ろに省略可能なパラメータ"_u[数値]"(数値分だけ現在のオクターブよりあげる)か"_d[数値]"(数値分だけ現在のオクターブより下げる)。

Examples: "C", "As" or "Asharp", "Bflat" or "Bf", "C_d3", "As_d1" or "Asharp_d1", "Bflat_u3" or "Bf_u3".

例:"C"、"As"か"Asharp"、"Bflat"か"Bf"、"C_d3"、"As_d1"か"Asharp_d1"、"Bflat_u3"か"Bf_u3"。

In resolving what actual notes these kinds of specifications denote, the current value of Octave is used.

このような指定をされた実際のノートが何を表しているのかを解決するために、現在のオクターブの値が使用される。

What's a legal for the first bit (before any optional octave up/down specification) comes from the keys to the hash %MIDI::Simple::Note. The current acceptable values are:

何が先頭文字(オクターブの上げ下げを指定するオプションの前の部分)として適正かは、%MIDI::Simple::Noteのキーで決まる。現在取りうる値は:

 C                                 (maps to the value 0)
 Cs or Df or Csharp or Dflat       (maps to the value 1)
 D                                 (maps to the value 2)
 Ds or Ef or Dsharp or Eflat       (maps to the value 3)
 E                                 (maps to the value 4)
 F                                 (maps to the value 5)
 Fs or Gf or Fsharp or Gflat       (maps to the value 6)
 G                                 (maps to the value 7)
 Gs or Af or Gsharp or Aflat       (maps to the value 8)
 A                                 (maps to the value 9)
 As or Bf or Asharp or Bflat       (maps to the value 10)
 B                                 (maps to the value 11)

(Note that these are based on the English names for these notes. If you prefer to add values to accomodate other strings denoting notes in the octave, you may do so by adding to the hash %MIDI::Simple::Note like so:

これらはその音符に対応する音符英語名に基づいている。そのオクターブ内で音符を意味する他の文字列を利用するために値を付け加えたほうがよいなら、%MIDI::Simple::Noteに次のように付け加えることができる:

  use MIDI::Simple;
  %MIDI::Simple::Note =
    (%MIDI::Simple::Note,  # 古い値は全て保持
     'H' => 10,
     'Do' => 0,
     # ...等々...
    );

But the values you add must not contain any characters outside the range [A-Za-z\x80-\xFF]; and your new values must not look like anything that could be any other kind of specification. E.g., don't add "mf" or "o3" to %MIDI::Simple::Note.)

付け加える値には、[A-Za-z\x80-\xFF]の範囲外のいかなるキャラクタも含んではならない。そしてまた、他の指定に使用されうるものと同じであってはならない。例えば、"mf"や"o3"を%MIDI::Simple::Noteに加えてはならない。

Consider that these bits of code all do the same thing:

同じことをするコードを考えてみると:

  n E3, B3, D4, mf;       # way 1

  n E3, B,  D_u1, mf;     # way 2

  n o3, E, B,  D_u1, mf;  # way 3

  noop o3, mf;            # way 4
  n     E, B,  D_u1;

or even

さらに同じ:

  n o3, E, B, o4, D, mf;       # way 5!

  n o6, E_d3, B_d3, D_d2, mf;  # way 6!

If a "_d[number]" would refer to a note in an octave below 0, it is forced into octave 0. If a "_u[number]" would refer to a note in an octave above 10, it is forced into octave 10. E.g., if Octave is 8, "G_u4" would resolve to the same as "G10" (not "G12" -- as that's out of range); if Octave is 2, "G_d4" would resolve to the same as "G0". (For more information, see the section "Invalid or Out-of-Range Parameters to n/r/noop", below.)

もし"_d[number]"によってオクターブの値が0より小さいノートを示すことになったら、強制的にオクターブは0にセットされる。"_u[number]"によってオクターブの値が10より大きいノートを示すことになったら、強制的にオクターブは10にセットされる。例えば:オクターブが8のとき、"G_u4"は"G10"と同じことになる(範囲を超えるのでG12にはならない)。オクターブが2なら、"G_d4"は"G0"になる(詳細は後で出てくる"/n/r/noopのパラメータが不正、あるいは範囲を超えた場合"を参照のこと)。

* The string "rest" acts as a sort of note specification -- it sets Notes to empty-list. That way you can make a call to n actually make a rest:

※文字列restはノート指定の一種として振る舞う。--ノートに空リストをセットする。nを呼び出すやり方で実際上休符を作り出す。

  n qn, G;    # 四分音符のGを生成
  n hn, rest; # 二分休符 -- 空リストをつくってNotesを変更している
  n C,G;      # 二分音符の和音:同時にCとG
  r;          # 二分休符 -- Notesを変更して い な い
  n qn;       # 四分音符の和音:同時にCとG
  n rest;     # 四分休符
  n;          # もう一回四分休符

(If you can follow the above code, then you understand.)

(上のコードを追えるなら、あなたは理解している)

A "rest" that occurs in a parameter list with other note specs (e.g., "n qn, A, rest, G") has no effect, so don't do that.

他のノート指定を伴うパラメータリストに現れる"rest"(例:"n qn, A, rest, G")は無効なので、何もしない。

n/r/noopの呼び出しにおけるパラメータの順番

The order of parameters in calls to n/r/noop is not important except insofar as the parameters change the Octave parameter, which may change how some relative note specifications are resolved. For example:

n/r/noopの呼び出しにおけるパラメータの順番は、オクターブを変化させるパラメータを除いて、重要ではない。なぜならオクターブを変化させるパラメータは、ノートの相対指定の解決方法を変化させるかもしれないからだ。例えば:

  noop o4, mf;
  n G, B, A3, C;

is the same as "n mf, G4, B4, A3, C3". But just move that "C" to the start of the list:

これは"n mf, G4, B4, A3, C3"と同じだ。だが"C"をリストの最初に持ってくると:

  noop o4, mf;
  n C, G, B, A3;

and you something different, equivalent to "n mf, C4, G4, B4, A3".

そしてこれは先ほどとは違って、"n mf, C4, G4, B4, A3"になる。

But note that you can put the "mf" anywhere without changing anything.

"mf"は他に影響を与えないので、どこに置いてもよいことに注意。

But stylistically, I strongly advise putting note parameters at the end of the parameter list:

しかし体裁を考えて、音符パラメータはリストの最後に置くことを強くお勧めする。

  n mf, c10, C, B;  # 1. 良い
  n C, B, mf, c10;  # 2. 悪い
  n C, mf, c10, B;  # 3. 大変悪い!

3 is particularly bad because an uninformed/inattentive reader may get the impression that the C may be at a different volume and on a different channel than the B.

3番目は特にまずくて、生真面目/不注意な読み手は、Cが違うボリュームであるとか、Bとは違うチャンネルにあるなどの印象を持ってしまうかもしれない。

(Incidentally, "n C5,G5" and "n G5,C5" are the same for most purposes, since the C and the G are played at the same time, and with the same parameters (channel and volume); but actually they differ in which note gets put in the Score first, and therefore which gets encoded first in the MIDI file -- but this makes no difference at all, unless you're manipulating the note-items in Score or the MIDI events in a track.)

(ちなみに、"n C5,G5"と"n G5,C5"はほとんどの場合同じである。というのも、CとGは同時に演奏され、同じパラメータ(チャンネルとボリューム)を持つからだ。だが音符がスコアの最初に置かれ、MIDIファイルの最初にエンコードされる場合には、実際上の違いが生じる。もっとも、スコア内のノート項目か、トラック内のMIDIイベントを操作しない限り、違いは生じない。)

/n/r/noopのパラメータが不正、あるいは範囲を超えた場合

If a parameter in a call to n/r/noop is uninterpretable, Perl dies with an error message to that effect.

n/r/noopを呼び出す際のパラメータが解釈不能な場合、Perlはその効果に関するエラーメッセージを伴ってdieする。

If a parameter in a call to n/r/noop has an out-of-range value (like "o12" or "c19"), Perl dies with an error message to that effect.

n/r/noopを呼び出す際のパラメータが範囲を超えている場合("o12"とか"c19"のように)、Perlはその効果に関するエラーメッセージを伴ってdieする。

As somewhat of a merciful exception to this rule, if a parameter in a call to n/r/noop is a relative specification (whether like "o_d3" or "o_u3", or like "G_d3" or "G_u3") which happens to resolve to an out-of-range value (like "G_d3" given an Octave value of 2), then Perl will not die, but instead will silently try to bring that note back into range, by forcing it up to octave 0 (if it would have been lower), or down into 9 or 10 (if it would have been an octave higher than 10, or a note higher than G10), as appropriate.

このルールには幸運な例外があって、n/r/noopを呼び出す際のパラメータが相対指定("o_d3"や"o_u3"とか、"G_d3"や"G_u3"など) の時、それが範囲外の値を解決しなければならなくなった場合(オクターブの値が2の時に"G_d3"が与えるなどのような場合)、Perlはdieしない。その代わりに黙ってそのノートを強制的に0にまで上げる(0未満の場合)か、9なしは10にまで下げる(10より高いオクターブになってしまったり、G10よりも高いノートになった場合)ことによって、範囲内に収めようと試みる。

(This becomes strange in that, given an Octave of 8, "G_u4" is forced down to G10, but "A_u4" is forced down to an A9. But that boundary has to pop up someplace -- it's just unfortunate that it's in the middle of octave 10.)

(次のような場合、奇妙なことが起こる。すなわち、オクターブ8が与えられ時"G_u4"は強制的にG10になるが"A_u4"はA9になる。これは不幸なことにAがオクターブ10の真ん中にあるためだ。)

属性メソッド

The object attributes discussed above are readable and writeable with object methods. For each attribute there is a read/write method, and a read-only method that returns a reference to the attribute's value:

以上見てきたオブジェクトの属性はオブジェクトメソッドで読み書きができる。全ての属性について、読み書き用のメソッドと、属性値へのリファレンスを返す読み込み専用メソッドが存在する:

  Attribute ||  R/W-Method ||   RO-R-Method
  ----------++-------------++--------------------------------------
  Score     ||  Score      ||   Score_r      (returns a listref)
  Notes     ||  Notes      ||   Notes_r      (returns a listref)
  Time      ||  Time       ||   Time_r       (returns a scalar ref)
  Duration  ||  Duration   ||   Duration_r   (returns a scalar ref)
  Channel   ||  Channel    ||   Channel_r    (returns a scalar ref)
  Octave    ||  Octave     ||   Octave_r     (returns a scalar ref)
  Volume    ||  Volume     ||   Volume_r     (returns a scalar ref)
  Tempo     ||  Tempo      ||   Tempo_r      (returns a scalar ref)
  Cookies   ||  Cookies    ||   Cookies_r    (returns a hashref)

To read any of the above via a R/W-method, call with no parameters, e.g.:

読み書きメソッドを通じて上の属性を読み込むには、パラメータ無しでメソッドを呼べばよい。例えば:

  $notes = $obj->Notes;  # $obj->Notes() と同じ

The above is the read-attribute ("get") form.

上のは読み取り属性("get")形式。

To set the value, call with parameters:

値をセットするには、パラメータなしでメソッドを呼び出す:

  $obj->Notes(13,17,22);

The above is the write-attribute ("put") form. Incidentally, when used in write-attribute form, the return value is the same as the parameters, except for Score or Cookies. (In those two cases, I've suppressed it for efficiency's sake.)

上のは書き込む属性("put")形式。

Alternately (and much more efficiently), you can use the read-only reference methods to read or alter the above values;

上記の値を読みとったり変更したりするための別の方法として(そしてより効率的な方法として)、読み込み専用のリファレンス用メソッドを利用できる。

  $notes_r = $obj->Notes_r;
  # 読みとり:
  @old_notes = @$notes_r;
  # 書き込み:
  @$notes_r = (13,17,22);

And this is the only way to set Cookies, Notes, or Score to a (), like so:

そしてこれはCookies、NotesやScoreに空リスト()をセットする唯一の方法である。

  $notes_r = $obj->Notes_r;
  @$notes_r = ();

Since this:

このため:

  $obj->Notes;

is just the read-format call, remember?

これは単なる読み取り形式の呼び出しだ、覚えた?

Like all methods in this class, all the above-named attribute methods double as procedures that act on the default object -- in other words, you can say:

このクラスの全てのメソッド同様、上で名前の挙がった属性メソッドはデフォルトオブジェクトに対し作用するプロシージャとしての機能も持つ。つまり、このように書ける:

  Volume 10;              # 右と同じこと:  $Volume = 10;
  @score_copy = Score;    # 右と同じこと:  @score_copy = @Score
  Score @new_score;       # 右と同じこと:  @Score = @new_score;
  $score_ref = Score_r;   # 右と同じこと:  $score_ref = \@Score
  Volume(Volume + 10)     # 右と同じこと:  $Volume += 10

But, stylistically, I suggest not using these procedures -- just directly access the variables instead.

だが体裁を考えると、こういったプロシージャは使わない方がいい。代わりに直接変数にアクセスするべきだ。

MIDIイベントルーチン

These routines, below, add a MIDI event to the Score, with a start-time of Time. Example:

下に挙げるこれらのルーチンは、Timeの開始時間を伴ってScoreにMIDIイベントを追加する。例として:

  text_event "And now the bongos!";  # プロシージャとして使う

  $obj->text_event "And now the bongos!";  # メソッドとして使う

These are named after the MIDI events they add to the score, so see MIDI::Event for an explanation of what the data types (like "velocity" or "pitch_wheel") mean. I've reordered this list so that what I guess are the most important ones are toward the top:

これらのルーチンには、そのルーチンがスコアに付け加えるMIDIイベントの名前がつけられいる。よって、そのデータタイプ("velocity"や"pitch_wheel"など)が何を意味しているのかについての説明は、MIDI::Eventを参照のこと。

patch_change channel, patch;
key_after_touch channel, note, velocity;
channel_after_touch channel, velocity;
control_change channel, controller(0-127), value(0-127);
pitch_wheel_change channel, pitch_wheel;
set_tempo tempo; (See the section on tempo, below.)
smpte_offset hr, mn, se, fr, ff;
time_signature nn, dd, cc, bb;
key_signature sf, mi;
text_event text;
copyright_text_event text;
track_name text;
instrument_name text;
lyric text;
set_sequence_number sequence;
marker text;
cue_point text;
sequencer_specific raw;
sysex_f0 raw;
sysex_f7 raw;

And here's the ones I'll be surprised if anyone ever uses:

そして、もしも誰かが使ったなら、私が驚いてしまうであろうルーチンもある。

text_event_08 text;
text_event_09 text;
text_event_0a text;
text_event_0b text;
text_event_0c text;
text_event_0d text;
text_event_0e text;
text_event_0f text;
raw_meta_event command(0-255), raw;
song_position starttime;
song_select song_number;
tune_request starttime;
raw_data raw;
end_track starttime;
note duration, channel, note, velocity;

テンポ(Tempo)について

The chart above shows that tempo is set with a method/procedure that takes the form set_tempo(tempo), and MIDI::Event says that tempo is "microseconds, a value 0 to 16,777,215 (0x00FFFFFF)". But at the same time, you see that there's an attribute of the MIDI::Simple object called "Tempo", which I've warned you to leave at the default value of 96. So you may wonder what the deal is.

上のチャートが示しているように、テンポはset_tempo(tempo)という形式の メソッド/プロシージャによってセットされる。そしてMIDI::Eventで述べて いるように、tempoは"マイクロ秒、0〜16,777,215 (0x00FFFFFF)の値"である。 しかし同時に、MIDI::Simpleオブジェクトが"Tempo"と呼ぶ属性値が存在する。 これについて私は、デフォルト値の96のままにするよう警告してある。 Tempとは何なのか詳細が知りたい人がいるだろう:

The "Tempo" attribute (AKA "Divisions") is an integer that specifies the number of "ticks" per MIDI quarter note. Ticks is just the notional timing unit all MIDI events are expressed in terms of. Calling it "Tempo" is misleading, really; what you want to change to make your music go faster or slower isn't that parameter, but instead the mapping of ticks to actual time -- and that is what set_tempo does. Its one parameter is the number of microseconds each quarter note should get.

"Tempo"属性(分解能)とは、MIDIにおける四分音符あたりのティックの数を特定する整数のことである。ティックは論理的な時間間隔の単位であり、全てのMIDIイベントはこの値を使って表現されている。ティックを"Tempo"と呼ぶのは本当は間違いなのだ。あなたの曲のスピードを早くしたり遅くしたりする時に変更するのは、Tempoではなくて、ティックと実時間の対応の方である。これはset_tempoによってなされる。set_tempoによって設定されるパラメータは、一つひとつの四分音符が持つべきマイクロ秒の数である。

Suppose you wanted a tempo of 120 quarter notes per minute. In terms of microseconds per quarter note:

1分あたり四分音符120のテンポにしたいとしてみよう。一個の四分音符あたりの マイクロ秒だから:

  set_tempo 500_000; # 桁区切りのカンマに _ を使える

In other words, this says to make each quarter note take up 500,000 microseconds, namely .5 seconds. And there's 120 of those half-seconds to the minute; so, 120 quarter notes to the minute.

つまり上の例では、一つひとつの四分音符が500,000マイクロ秒(0.5秒)で 構成される。0.5秒が120個集まると1分になる。だから、120個の四分音符で 1分になるわけだ。

If you see a "[quarter note symbol] = 160" in a piece of sheet music, and you want to figure out what number you need for the set_tempo, do:

楽譜に"[四分音符のマーク] = 160"と書かかれてあって、 set_tempoでそれに必要な数を表したいなら:

  60_000_000 / 160  ... その結果得るのは:  375_000

Therefore, you should call:

よってこのように呼び出す:

  set_tempo 375_000;

So in other words, this general formula:

結局、次のような一般式:

  set_tempo int(60_000_000 / $quarter_notes_per_minute);

should do you fine.

を使えばよい。

As to the Tempo/Duration parameter, leave it alone and just assume that 96 ticks-per-quarter-note is a universal constant, and you'll be happy.

Tempo/Durationについては、そのままにしておいて、四分音符一個につき 96ティックで常に一定と考えておけば吉。

(You may wonder: Why 96? As far as I've worked out, all purmutations of the normal note lengths (whole, half, quarter, eighth, sixteenth, and even thirty-second notes) and tripletting, dotting, or double-dotting, times 96, all produce integers. For example, if a quarter note is 96 ticks, then a double-dotted thirty-second note is 21 ticks (i.e., 1.75 * 1/8 * 96). But that'd be a messy 10.5 if there were only 48 ticks to a quarter note. Now, if you wanted a quintuplet anywhere, you'd be out of luck, since 96 isn't a factor of five. It's actually 3 * (2 ** 5), i.e., three times two to the fifth. If you really need quintuplets, then you have my very special permission to mess with the Tempo attribute -- I suggest multiples of 96, e.g., 5 * 96.)

(あなたは疑問に思うだろう:「なぜ96なの?」。通常の音符の長さ(全音符・二分音符・四分音符・八分音符・十六分音符、さらには三十二分音符さえ)と三連符、付点音符、複付点音符を表現するにあたって、96なら全て生成できる。例えば四分音符がティック96なら複付点三十二分音符21ティックとなる(1.75 * 1/8 * 96)。もし四分音符が48ティックだったらこれは10.5になってしまう。今度は、五連符をつくりたいとする。不運なことに96には因数に5が含まれない。96は因数分解すると3 * (2 ** 5)。つまり3かける2の5乗。本当に五連符が欲しいならTemp属性の変更を許可しなければならない。この場合96の倍数が良いと思う。例えば5 * 96など。)

(You may also have read in MIDI::Filespec that time_signature allows you to define an arbitrary mapping of your concept of quarter note, to MIDI's concept of quarter note. For your sanity and mine, leave them the same, at a 1:1 mapping -- i.e., with an '8' for time_signature's last parameter, for "eight notated 32nd-notes per MIDI quarter note". And this is relevant only if you're calling time_signature anyway, which is not necessarily a given.)

[訳注:MIDI::Filespecは事実上存在しないので、上記の段落は訳していない]

さらなるルーチン

$opus = write_score filespec
$opus = $obj->write_score(filespec)

Writes the score to the filespec (e.g, "../../samples/funk2.midi", or a variable containing that value), with the score's Ticks as its tick parameters (AKA "divisions"). Among other things, this function calls the function make_opus, below, and if you capture the output of write_score, you'll get the opus created, if you want it for anything. (Also: you can also use a filehandle-reference instead of the filespec: write_score *STDOUT{IO}.)

指定したファイル("../../samples/funk2.midi"や、そういった値の入っている 変数)にスコアを書き出す。この時ティックパラメータ(分解能)としてその スコアのティックも一緒に書き出される。さらにいうと、この関数は下に挙げた make_opusを呼び出す。write_scoreの出力を捕まえれば、作成されたオプスを 手に入れることになる。また、ファイル指定の代わりにファイルハンドルへの リファレンスを使うことも出来る。:write_score *STDOUT{IO}。)

read_score filespec
$obj = MIDI::Simple->read_score('foo.mid'))

In the first case (a procedure call), does new_score to erase and initialize the object attributes (Score, Octave, etc), then reads from the file named. The file named has to be a MIDI file with exactly one eventful track, or Perl dies. And in the second case, read_score acts as a constructor method, returning a new object read from the file.

一番目のやり方の場合(プロシージャ呼び出し)、オブジェクトの属性(Score、Octave等)を消去・初期化するために、score_newし、それから指定されたファイルから読み込む。指定されたファイルは、確実にイベントで満たされた一つのトラックを持ったMIDIファイルでなければならない。さもなければPerlはdieする。二番目のやり方の場合、read_scoreはコンストラクタメソッドとして機能し、ファイルから読み込んだ新しいオブジェクトを返す。

Score, Ticks, and Time are all affected:

Score、TicksとTimeは影響を受ける。

Score is the event form of all the MIDI events in the MIDI file. (Note: Seriously deformed MIDI files may confuse the routine that turns MIDI events into a Score.)

ScoreはMIDIファイル中にある全MIDIイベントの形をとる(注意:著しく形式の 崩れたMIDIファイルはMIDIイベントをScoreに変換するルーチンを混乱させる)。

Ticks is set from the ticks setting (AKA "divisions") of the file.

Ticksはファイルのティック(分解能)に基づいてセットされる。

Time is set to the end time of the latest event in the file.

Timeはファイルの一番最後のイベントの終了時間がセットされる。

(Also: you can also use a filehandle-reference instead of the filespec: read_score *STDIN{IO}.)

(また、ファイル指定の代わりにファイルハンドルへの リファレンスを使うことも出来る。:read_score *STDOUT{IO}。)

If ever you have to make a Score out of a single track from a multitrack file, read the file into an $opus, and then consider something like:

マルチトラックファイルの複数のトラックからScoreをつくらなければならない場合、ファイルを$opusに読み込んでから次のようにする:

        new_score;
        $opus = MIDI::Opus->new({ 'from_file' => "foo2.mid" });
        $track = ($opus->tracks)[2]; # 三番目のトラックを得る

        ($score_r, $end_time) =
          MIDI::Score::events_r_to_score_r($track->events_r);

        $Ticks = $opus->ticks;
        @Score =  @$score_r;
        $Time = $end_time;
synch( LIST of coderefs )
$obj->synch( LIST of coderefs )

LIST is a list of coderefs (whether as a series of anonymous subs, or as a list of items like (\&foo, \&bar, \&baz), or a mixture of both) that synch calls in order to add to the given object -- which in the first form is the package's default object, and which in the second case is $obj. What synch does is:

LISTはサブルーチンへのリファレンスのリストだ(無名サブルーチンか(\&foo, \&bar, \&baz)のようなリストか、それらの混合かは問わない)。synchは与えられたオブジェクトに付け加えるためにそれらを呼び出す。与えられるオブジェクトは、一番目のプロシージャ形式の場合はそのパッケージのデフォルトオブジェクトが、そしてメソッドの場合は$objとなる。synchが何をするかというと:

* remember the initial value of Time, before calling any of the routines;

※ルーチンを呼び出す前に、Timeの最初の値を覚えておく。

* for each routine given, reset Time to what it was initially, call the routine, and then note what the value of Time is, after each call;

※与えられた全てのルーチン毎に、Timeの値を最初の値へとリセットしておく。 ルーチンを呼び出す。全てのルーチンを呼び出した後に、Tiemの値が何であるかを記録する。

* then, after having called all of the routines, set Time to whatever was the greatest (equals latest) value of Time that resulted from any of the calls to the routines.

※そして全てのルーチンを呼び出し終えた後、ルーチンの呼び出して解決されたTimeの最大値(すなわち最後の値)をTimeにセットする。

The coderefs are all called with one argument in @_ -- the object they are supposed to affect. All these routines should/must therefore use method calls instead of procedure calls. Here's an example usage of synch:

サブルーチンへのリファレンスは全て、@_の一つの引数(影響を受けるオブジェクト)を伴って呼び出される。それゆえ、これらのルーチンはプロシージャ呼び出しではなく、メソッド呼び出しでなければならない。synchの使用例:

        my $measure = 0;
        my @phrases =(
          [ Cs, F,  Ds, Gs_d1 ], [Cs,    Ds, F, Cs],
          [ F,  Cs, Ds, Gs_d1 ], [Gs_d1, Ds, F, Cs]
        );

        for(1 .. 20) { synch(\&count, \&lalala); }

        sub count {
          my $it = $_[0];
          $it->r(wn); # 全休符
          # "r(wn)"ではない。 -- プロシージャではなくメソッドとして使用!
          ++$measure;
        }

        sub lalala {
          my $it = $_[0];
          $it->noop(c1,mf,o3,qn); # セットアップ
          my $phrase_number = ($measure + -1) % 4;
          my @phrase = @{$phrases[$phrase_number]};
          foreach my $note (@phrase) { $it->n($note); }
        }
$opus = make_opus または $opus = $obj->make_opus

Makes an opus (a MIDI::Opus object) out of Score, setting the opus's tick parameter (AKA "divisions") to $ticks. The opus is, incidentally, format 0, with one track.

Scoreからオプス(MIDI::Opusオブジェクト)をつくる。このときオプスの ティック(分解能)に$ticksをセットする。ちなみにこのオプスは一つの トラックを持つフォーマット0だ。

dump_score または $obj->dump_score

Dumps Score's contents, via print (so you can select() an output handle for it). Currently this is in this somewhat uninspiring format:

printを通じてScoreの内容をダンプする(sekectを使って出力先の ハンドルを変更できる)。現在の所、これは次のような退屈な形式になる:

  ['note', 0, 96, 1, 25, 96],
  ['note', 96, 96, 1, 29, 96],

as it is (currently) just a call to &MIDI::Score::dump_score; but in the future I may (should?) make it output in n/r notation. In the meantime I assume you'll use this, if at all, only for debugging purposes.

現在のところ、&MIDI::Score::dump_scoreの呼び出しと変わらない。だが将来は n/rを表すように出力したい(するべきか?)。とりあえずは、 デバッグの目的でのみこれを使うことを想定している。

関数

These are subroutines that aren't methods and don't affect anything (i.e., don't have "side effects") -- they just take input and/or give output.

これらはメソッドでなく、他に影響を与えない(副作用をもたらさない) サブルーチンだ。つまりインプットを受け取りアウトプットを出すだけだ。

interval LISTREF, LIST

This takes a reference to a list of integers, and a list of note-pitch specifications (whether relative or absolute), and returns a list consisting of the given note specifications transposed by that many half-steps. E.g.,

整数のリストへのリファレンスと、音階指定のリストを引数にとる。 そして与えられたノート指定を半音単位でずらしたリストを返す。例えば:

  @majors = interval [0,4,7], C, Bflat3;

which returns the list (C,E,G,Bf3,D4,F4).

これは(C,E,G,Bf3,D4,F4)のリストを返す。

Items in LIST which aren't note specifications are passed thru unaltered.

ノート指定を含まないLISTの要素は、変更されない。

note_map { BLOCK } LIST

This is pretty much based on (or at least inspired by) the normal Perl map function, altho the syntax is a bit more restrictive (i.e., map can take the form map {BLOCK} LIST or map(EXPR,LIST) -- the latter won't work with note_map).

これはPerlのmap関数に基づいている(少なくともインスピレーションを 得た)。ただし文法は少しばかり規制が厳しいが(mapmap {BLOCK} LISTmap(EXPR,LIST)の形式をとれるが、note_mapは後者のようにはできない)。

note_map {BLOCK} (LIST) evaluates the BLOCK for each element of LIST (locally setting $_ to each element's note-number value) and returns the list value composed of the results of each such evaluation. Evaluates BLOCK in a list context, so each element of LIST may produce zero, one, or more elements in the returned value. Moreover, besides setting $_, note_map feeds BLOCK (which it sees as an anonymous subroutine) three parameters, which BLOCK can access in @_ :

note_map {BLOCK} (LIST)は、LISTの要素に対して(各要素はローカル化された $_にセットされる)ブロック内を評価して、その結果をまとめたリスト値を返す。 リストコンテキストでブロックを評価すること。LISTの各要素は戻り値において0,1,それ以上の要素を生成するかもしれない。さらに、$_にセットされる以外に、note_mapはブロック(無名サブルーチンとしてみる)に三つのパラメータを渡す。これは@_を使ってブロック内からアクセスできる。

  $_[0]  :  Same as $_.  I.e., The current note-specification,
            as a note number.
            This is the result of having fed the original note spec
            (which you can see in $_[2]) to is_note_spec.
  $_[0]  :  $_と同じ。つまり現在のノート指定。ノートナンバーとして表される。
            元のノート指定($_[2]参照)をis_note_specに与えた結果である。
  $_[1]  :  The absoluteness flag for this note, from the
            above-mentioned call to is_note_spec.
            0 = it was relative (like 'C')
            1 = it was absolute (whether as 'C4' or 'n41' or '41')
  $_[1]  :  このノートが絶対指定かどうかのフラグ。is_note_specから渡される。
            0 = 相対指定(例えば'C')
            1 = 絶対指定('C4'とか'n41'とか'41')
  $_[2] : the actual note specification from LIST, if you want
            to access it for any reason.
  $_[2]  :  何らかの理由でアクセスする場合の、LISTから得る実際のノート指定。

Incidentally, any items in LIST that aren't a note specification are passed thru unchanged -- BLOCK isn't called on it.

ちなみにLISTの中のノート指定でないどの要素も変更されずに素通りする。 BLOCKは呼ばれない。

So, in other words, what note_map does, for each item in LIST, is:

つまり、note_mapがすることは、LISTの各要素に対して:

* It calls is_note_spec on it to test whether it's a note specification at all. If it isn't, just passes it thru. If it is, then note_map stores the note number and the absoluteness flag that is_note_spec returned, and...

※それがノート指定かどうかをテストするためにis_note_specを呼び出す。 違っていたら、無視する。ノート指定であったら次にnote_mapは、その ノートナンバーと、is_note_specが返す絶対指定フラグを保持する。それから…

* It calls BLOCK, providing the note number in $_ and $_[0], the absoluteness flag in $_[1], and the original note specification in $_[2]. Stores the return value of calling BLOCK (in a list context of course) -- this should be a list of note numbers.

ブロックを呼び出す。このとき$_と$_[0]にはノートナンバーを、$_[1]には絶対指定フラグを、$_[2]には元のノート指定を与える。ブロック呼び出しの戻りを保持する(もちろんリストコンテキストで)。この戻り値はノートナンバーのリストであるべきだ。

* For each element of the return value (which is actually free to be an empty list), converts it from a note number to whatever kind of specification the original note value was. So, for each element, if the original was relative, note_map interprets the return value as a relative note number, and calls number_to_relative on it; if it was absolute, note_map will try to restore it to the correspondingly formatted absolute specification type.

※戻り値の各要素に対して(空リストでもよい)、ノートナンバーから元のノートの値による何らかの指定へと変換する。だから各要素に対して、元の指定が相対指定の場合、note_mapは戻り値を相対ノートナンバーとして解釈し、戻り値に対してnumber_to_relativeを呼び出す。絶対指定ならnote_mapは対応するようにフフォーマットされた絶対指定型としてそれを保持しようとする。

An example is, I hope, helpful:

この例が役に立つとよいのだが:

This:

これは:

        note_map { $_ - 3, $_ + 2 }  qw(Cs3 n42 50 Bf)

returns this:

次の値を返す:

        ('Bf2', 'Ef3', 'n39', 'n44', '47', '52', 'G', 'C_u1')

Or, to line things up:

つまりこういうふうに:

          Cs3       n42       50      Bf
           |         |        |       |
        /-----\   /-----\   /---\   /----\
        Bf2 Ef3   n39 n44   47 52   G C_u1

Now, of course, this is the same as what this:

もちろん、これは次の戻り値と同じだ:

        interval [-3, 2], qw(Cs3 n42 50 Bf)

returns. This is fitting, as interval, internally, is basically a simplified version of note_map. But interval only lets you do unconditional transposition, whereas note_map lets you do anything at all. For example:

これが一致するのは、基本的にintervalは内部的にはnote_mapを簡略したものだからだ。だが、intervalは無条件に音階を変更する。これに対してnote_mapは任意のことができる。例えば:

       @note_specs = note_map { $funky_lookup_table{$_} }
                              C, Gf;

or

や、

       @note_specs = note_map { $_ + int(rand(2)) }
                              @stuff;

note_map, like map, can seem confusing to beginning programmers (and many intermediate ones, too), but it is quite powerful.

map同様、note_mapは初心者プログラマを混乱させるかもしれない (そして中級プログラマもまた)。しかしこの関数は大変強力だ。

number_to_absolute NUMBER

This returns the absolute note specification (in the form "C5") that the MIDI note number in NUMBER represents.

この関数はMIDIノートナンバー(NUMBER)が表す絶対ノート指定を返す ("C5"のような形式)。

This is like looking up the note number in %MIDI::number2note -- not exactly the same, but effectively the same. See the source for more details.

これは%MIDI::number2noteからノートナンバーを探すのに似ている。 全く同じとはいわないが、効果は同じだ。詳細についてはソースを見て欲しい。

the function number_to_relative NUMBER

This returns the relative note specification that NUMBER represents. The idea of a numerical representation for relative note specifications was necessitated by interval and note_map -- since without this, you couldn't meaningfully say, for example, interval [0,2] 'F'. This should illustrate the concept:

この関数はNUMBERが表す相対ノート指定を返す。c<相対的な>ノート指定を数値で表現するという考えは、intervalnote_mapによって必要とされる。もしも相対指定が無かったら例えば、interval [0,2] 'F' という表現は無意味になるだろう。これは次のような概念で表される。

          number_to_relative(-10)   =>   "D_d1"
          number_to_relative( -3)   =>   "A_d1"
          number_to_relative(  0)   =>   "C"
          number_to_relative(  5)   =>   "F"
          number_to_relative( 10)   =>   "Bf"
          number_to_relative( 19)   =>   "G_u1"
          number_to_relative( 40)   =>   "E_u3"
is_note_spec STRING

If STRING is a note specification, is_note_spec(STRING) returns a list of two elements: first, a flag of whether the note specification is absolute (flag value 1) or relative (flag value 0); and second, a note number corresponding to that note specification. If STRING is not a note specification, is_note_spec(STRING) returns an empty list (which in a boolean context is FALSE).

STRINGがノート指定なら、is_note_spec(STRING)は二つの要素からなる リストを返す。一番目の要素はそのノート指定が絶対指定(値は1)か相対指定 (値は0)かを表すフラグだ。二番目の要素はそのノート指定に対応する ノートナンバーだ。もしSTRINGがノート指定でないなら、 is_note_spec(STRING)は空リスト(ブールコンテキストでは偽になる)を返す。

Implementationally, is_note_spec just uses is_absolute_note_spec and is_relative_note_spec.

実装上は、is_note_specis_absolute_note_specis_relative_note_specを利用しているだけだ。

Example usage:

使用例:

        @note_details = is_note_spec($thing);
        if(@note_details) {
          ($absoluteness_flag, $note_num) = @note_details;
          ...stuff...
        } else {
          push @other_stuff, $thing;  # or whatever
        }
is_relative_note_spec STRING

If STRING is an relative note specification, returns the note number for that specification as a one-element list (which in a boolean context is TRUE). Returns empty-list (which in a boolean context is FALSE) if STRING is NOT a relative note specification.

STRINGが相対ノート指定なら、一つの要素からなるリスト(ブールコンテキスト では真になる)としてその指定に対応するノートナンバーを返す。もしSTRINGが 相対ノート指定でないなら、空リストを返す(ブールコンテキストでは 偽になる)。

To just get the boolean value:

ブール値を得るだけなら:

      print "Snorf!\n" unless is_relative_note_spec($note);

But to actually get the note value:

だが、ノートの値を実際に得るためには:

      ($note_number) = is_relative_note_spec($note);

Or consider this:

あるいは次のように:

      @is_rel = is_relative_note_spec($note);
      if(@is_rel) {
        $note_number = $is_rel[0];
      } else {
        print "Snorf!\n";
      }

(Author's note, two years later: all this business of returning lists of various sizes, with this and other functions in here, is basically a workaround for the fact that there's not really any such thing as a boolean context in Perl -- at least, not as far as user-defined functions can see. I now think I should have done this with just returning a single scalar value: a number (which could be 0!) if the input is a number, and undef/emptylist (return;) if not -- then, the user could test:

(二年後の作者からの注意:ここにある関数がもたらす、様々なサイズの戻り値リストは基本的に次の事実を避けるためのものである。すなわち、Perlには本当の意味でブールコンテキストのようなものは存在しないということだ。少なくとも、ユーザー定義の関数が知ることは出来ない。私は今、単一のスカラー値を返すだけでブール判定が出来るようにするべきだとは思っている。もし数値がインプットされたら数字を(0も含む!)、そうでなかったらundefか空リストをreturnする。それからユーザーがテストすることができる)

      # 仮定 --
      # 実際にはこんな風には動作しない
      if(defined(my $note_val = is_relative_note_spec($string))) {
         ...$note_valを使って何かする...
      } else {
         print "Hey, that's no note!\n";
      }

However, I don't anticipate users actually using these messy functions often at all -- I basically wrote these for internal use by MIDI::Simple, then I documented them on the off chance they might be of use to anyone else.)

しかし、私はユーザーがこのような混乱した関数を実際に使うとは思わない。 私はこれらの関数を基本的にMIDI::Simpleが内部的に使うために書いた。 とはいえ、ひょっとしたら誰か他の人にこれらの関数が使われる かもしれないということでドキュメントに記した。

is_absolute_note_spec STRING

Just like is_relative_note_spec, but for absolute note specifications instead of relative ones.

相対指定の代わりに絶対ノート指定に対応している以外、 is_relative_note_specと同じだ。

Self() または $obj->Self();

Presumably the second syntax is useless -- it just returns $obj. But the first syntax returns the current package's default object.

恐らく二番目の方法は無意味だ。なぜなら$objを返すだけだから。だが最初の 方法は現在のパッケージでデフォルト使用されるオブジェクトを返す。

Suppose you write a routine, funkify, that does something-or-other to a given MIDI::Simple object. You could write it so that acts on the current package's default object, which is fine -- but, among other things, that means you can't call funkify from a sub you have synch call, since such routines should/must use only method calls. So let's say that, instead, you write funkify so that the first argument to it is the object to act on. If the MIDI::Simple object you want it to act on is it $sonata, you just say

あなたがfunkifyというルーチンを書いたとしよう。この関数は与えられたMIDI::Simpleのオブジェクトに対し何かを行う。現在のパッケージのデフォルトオブジェクトに対し作用するようだろう。だが注意すべきことに、これはsynchからfunkifyを呼び出すことができないことを意味する。なぜならこのようなルーチンはメソッド呼び出しでのみ使うべきだからだ。だから代わりに、最初の引数が作用されるオブジェクトになるように書くことだ。作用させたいMIDI::Simpleオブジェクトが$sonataなら、このようにする:

  funkify($sonata)

However, if you want it to act on the current package's default MIDI::Simple object, what to say? Simply,

だが、現在のパッケージのデフォルトのMIDI::Simpleオブジェクトに対し作用させたいのなら、どうするか?単純にこうする。

  $package_opus = Self;
  funkify($package_opus);

著作権

Copyright (c) 1998-2002 Sean M. Burke. All rights reserved.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

作者

Sean M. Burke sburke@cpan.org