MIDIとTkxをグラフィックツールキットとして使用して、真珠にシンプルなドラムマシンを作成してみましょう。
主な機能
- 47個のツール、4個を同時に使用できます。
- キーボード制御。
- 音量調節
- 60〜600ビート/分のBPMレギュレーター。
一般に、このプログラムのアイデアは偶然に生まれました。私がGeneral MIDIに関する記事に出会った瞬間です。 そのため、この仕様では、打楽器用に10番の特別なチャンネルを提供しています。
必要なノート番号はこの
ページにあります 。
モジュールが必要になります:Win32API :: MIDIおよびTkx。 ActivePerlを使用する場合、後者はすでにインストールされています。
プログラミングに移りましょう
#!/ usr / bin / perl
厳格な使用;
Tkxを使用します。
Win32APIを使用:: MIDI;
ハッシュを決定、ペア:楽器名=>ノート番号
my%drums =(
'Bass Drum 2' => 35、
「ベースドラム1」=> 36、
'サイドスティック' => 37、
「スネアドラム1」=> 38、
'Hand Clap' => 39、
「スネアドラム2」=> 40、
「ロートム2」=> 41、
「閉じたハイハット」=> 42、
「低トム1」=> 43、
「ペダルハイハット」=> 44、
「ミッドトム2」=> 45、
「ハイハットを開く」=> 46、
「ミッドトム1」=> 47、
「ハイトム2」=> 48、
「クラッシュシンバル1」=> 49、
「ハイトム1」=> 50、
「ライドシンバル1」=> 51、
「チャイニーズシンバル」=> 52、
'Ride Bell' => 53、
'タンバリン' => 54、
「スプラッシュシンバル」=> 55、
'カウベル' => 56、
「クラッシュシンバル2」=> 57、
'Vibra Slap' => 58、
「ライドシンバル2」=> 59、
'High Bongo' => 60、
「低ボンゴ」=> 61、
「ミュートコンガ」=> 62、
「ハイコンガを開く」=> 63、
「低コンガ」=> 64、
「高ティンバレ」=> 65、
「低ティンバレ」=> 66、
'High Agogo' => 67、
「低いアゴゴ」=> 68、
「カバサ」=> 69、
'マラカス' => 70、
「短いホイッスル」=> 71、
「ロングホイッスル」=> 72、
'ショートギロ' => 73、
'ロングギロ' => 74、
'Claves' => 75、
「ハイウッドブロック」=> 76、
「低木ブロック」=> 77、
'Mute Cuica' => 78、
'Open Cuica' => 79、
「ミュートトライアングル」=> 80、
「三角形を開く」=> 81、
);
スクリーンショットのように、デフォルト値とリズムパターンを設定します
私の$ bpm = 300;
私の$ビット= 0;
my $ bits = [[0、1、1、0]、[0、0、1、0]、[1、0、0、0]、[1、0、1、0]];
私の@volume =(127、127、127、127);
my @drumset =( 'Bass Drum 2'、 'Bass Drum 1'、 'Snare Drum 1'、 'Snare Drum 2');
my @kb_keys =(qw(QWERASDFUIOPHJKL));
Win32APIを作成する:: MIDIオブジェクト
my $ mo = new Win32API :: MIDI :: Out()or die "Cannot create MIDI output";
プログラムウィンドウのウィジェットを作成し、タイトルを設定し、サイズ変更機能を無効にします
my $ mw = Tkx :: widget-> new( '。');
$ mw-> g_wm_title( 'Drum Machine in Perl');
$ mw-> g_wm_resizable(0、0);
my @pad =(-padx => 4、-pady => 4、-sticky => 'nsew');
インターフェイス、bindimホットキーを描画します
私の$ i(0..3){
私の$ combo = $ mw-> new_ttk__combobox(
-textvariable => \ $ drumset [$ i]、
-state => 'readonly'、
-values => [sort {$ drums {$ a} <=> $ drums {$ b}} keys%drums]、
);
私の$ scale = $ mw-> new_ttk__scale(
-variable => \ $ volume [$ i]、
-from => 0、
-to => 127、
-length => 50、
);
$ combo-> g_grid(-row => $ i、-column => 0、@pad);
$ scale-> g_grid(-row => $ i、-column => 1、@pad);
私の$ j(0..3){
my $ k = $ kb_keys [4 * $ i + $ j];
私の$ c = $ mw-> new_ttk__checkbutton(
-変数=> \ $ビット-> [$ i]-> [$ j]
-style => 'Toolbutton'、
-text => "$ k"、
);
Tkx :: bind(all => $ _ => sub {$ c-> invoke()})for(lc($ k)、uc($ k));
Tkx :: grid($ c、-row => $ i、-column => $ j + 2、@pad);
}
}
my $ bpm_label = $ mw-> new_ttk__label(-text => "$ bpm BPM");
私の$ bpm_scale = $ mw-> new_ttk__scale(
-variable => \ $ bpm、
-from => 60、
-to => 600、
-command => sub {$ bpm_label-> m_configure(-text => int($ bpm)。 'BPM')}、
);
$ bpm_label-> g_grid(-row => 4、-column => 0);
$ bpm_scale-> g_grid(-row => 5、-column => 0);
メインループでは、短い
メッセージをシーケンサーに送信し、BPMに応じてdruploop()を呼び出す間隔を計算します。
サブドラムループ{
私の$ b = $ビット++%4;
for(0..3){
if($ビット-> [$ _]-> [$ b]){
$ mo-> ShortMsg((0x00000090 | 9)|($ドラム{$ドラムセット[$ _]} << 8)|($ボリューム[$ _] << 16));
}
}
Tkx :: after(int(60000 / $ bpm)=> \&drumloop);
}
Tkx :: after(1000 => \&drumloop);
Tkx :: MainLoop;
以上です。 Windows用のビルドを作成しました。
参照資料
ソースコードWindowsでビルド(Wineでも動作)