主な機能
- 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でも動作)