Moduł MIDI

Uniwersytet Gdański - Instytut Matematyki - Zakład Informatyki - Strona domowa

Co to jest ?

MIDI to moduł, a właściwie zestaw modułów, służących do tworzenia plików typu .mid, czyli plików sterujących syntezatorem wbudowanym w kartę dźwiękową. W tym dokumencie skupię się tylko na zarysach tych modułów, szczególnie na funkcjach wykorzystywanych w programie przykładowym, który zamieszczam pod koniec dokumentu.

MIDI::Opus

Jest to moduł służący do operowania na utworach MIDI. Oto parametry, które można przekazać konstruktorowi :

format
Określa format pliku midi, zazwyczaj po prostu 0.
ticks
Prędkość utworu.
tracks
Lista ścieżek dźwiękowych, które opiszę za chwilę.
from_file
Wczytuje podany plik.
from_handle
Wczytuje dane z podanego uchwytu do pliku (strumienia).
no_parse
Pozwala zapobiegać parsowaniu wczytywanego pliku (gdy jest to niepotrzebne).

A oto wybrane metody :

dump
Zrzuca zawartość utworu do pliku tekstowego.
write_to_file
Zapisuje utwór do pliku .mid.

MIDI::Track

Moduł służący do tworzenia i modyfikowania ścieżek utworów. Ścieżki są składowymi utworu - korzysta z nich moduł opisany powyżej. Najważniejszym parametrem konstruktora jest events, który jest listą zdarzeń MIDI. Każdy event jest komunikatem, który może między innymi oznaczać wydobycie konkretnego dźwięku, ale nie tylko. Opisany poniżej moduł odpowiada za eventy.

MIDI::Event

Każdy event jest listą podobną do tej :

( 'note_on', 141, 4, 50, 64 )

Pierwszym parametrem jest nazwa komunikatu, drugim czas liczony od poprzedniego komunikatu. Pozostałe parametry są różne, zależnie od typu komunikatu. Pełną listę komunikatów można znaleźć w dokumentacji modułu, ja przytoczę te najważniejsze.

('note_on', dtime, channel, note, velocity)
Rozpoczyna odtwarzanie dźwięku w czasie dtime od poprzedniego komunikatu, na kanale channel (0 - 15), o wysokości note (0 - 127) i o głośności velocity (0 - 127).
('note_off', dtime, channel, note, velocity)
Kończy odtwarzanie dźwięku, rozpoczętego poprzednim komunikatem.
('patch_change', dtime, channel, patch)
Zmienia barwę dźwięku na podaną parametrem patch (0 - 127).

Komunikatów jest o wiele więcej, m.in. 'key_after_touch', 'pitch_wheel_change' i inne.

Przykład

Posiadając podstawową wiedzę o opisanych modułach, można napisać prosty program, który zapisze plik midi ze znaną melodię :)

# Program generujacy melodie # Autor : S.P. use MIDI; use warnings; @NAZWY_NUT = ('C1', 'C#1', 'D1', 'D#1', 'E1', 'F1', 'F#1', 'G1', 'G#1', 'A1', 'B1', 'H1', 'C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'B', 'H', 'c', 'c#', 'd', 'd#', 'e', 'f', 'f#', 'g', 'g#', 'a', 'b', 'h', 'c1', 'c#1', 'd1', 'd#1', 'e1', 'f1', 'f#1', 'g1', 'g#1', 'a1', 'b1', 'h1', 'c2', 'c#2', 'd2', 'd#2', 'e2', 'f2', 'f#2', 'g2', 'g#2', 'a2', 'b2', 'h2', 'c3'); $numer_pierwszej_nuty = 24; %NUTY = (); for($i = 0 ; $i < $#NAZWY_NUT ; $i++) { $NUTY{$NAZWY_NUT[$i]} = $i + $numer_pierwszej_nuty; } my @events = ( ['set_tempo', 0, 500_000], ); @STAR_WARS = ('f1', 50, 'f1', 50, 'f1', 50, 'b1', 200, 'f2', 200, 'd#2', 30, 'd2', 30, 'c2', 30, 'b2', 200, 'f2', 60, 'd#2', 30, 'd2', 30, 'c2', 30, 'b2', 200, 'f2', 60, 'd#2', 30, 'd2', 30, 'd#2', 30, 'c2', 300, 'b1', 200, 'f2', 200, 'd#2', 30, 'd2', 30, 'c2', 30, 'b2', 200, 'f2', 60, 'd#2', 30, 'd2', 30, 'c2', 30, 'b2', 200, 'f2', 60, 'd#2', 30, 'd2', 30, 'd#2', 30, 'c2', 200, 'f1', 50, 'f1', 50, 'g1', 140, 'g1', 60, 'd#2', 50, 'd2', 50, 'c2', 50, 'b1', 50, 'b1', 30, 'c2', 30, 'd2', 30, 'c2', 70, 'g1', 30, 'a1', 100, 'f1', 40, 'f1', 40, 'g1', 130, 'g1', 60, 'd#2', 50, 'd2', 50, 'c2', 50, 'b1', 50, 'f2', 70, 'c2', 30, 'c2', 250, 'f1', 30, 'f1', 30, 'g1', 140, 'g1', 60, 'd#2', 50, 'd2', 50, 'c2', 50, 'b1', 50, 'b1', 30, 'c2', 30, 'd2', 30, 'c2', 70, 'g1', 30, 'a1', 100, 'f1', 50, 'f1', 60, 'b1', 60, 'g#1', 40, 'f#1', 60, 'f1', 40, 'd#1', 60, 'c#1', 40, 'c1', 60, 'b', 40, 'f1', 300); graj(@STAR_WARS); my $pianino_track = MIDI::Track->new({ 'events' => \@events }); my $opus = MIDI::Opus->new( { 'format' => 0, 'ticks' => 96, 'tracks' => [ $pianino_track ] } ); $opus->write_to_file( 'starwars.mid' ); sub graj { @MELODIA = @_; for($i = 0 ; $i < $#MELODIA ; $i = $i + 2) { pianino($MELODIA[$i], 0, $MELODIA[$i + 1]); } } sub pianino { ($wysokosc, $opoznienie, $dlugosc) = @_; push @events, ['note_on', $opoznienie, 1, $NUTY{$wysokosc}, 127]; push @events, ['note_off', $dlugosc, 1, $NUTY{$wysokosc}, 127]; }

Dodatkowe informacje

Dokumentacja modułu znajduje się na stronie http://search.cpan.org/~sburke/MIDI-Perl-0.81/lib/MIDI.pm

Jeżeli mamy kłopot z odtworzeniem pliku midi na standardowym odtwarzaczu multimedialnym, możemy poszukać w Internecie odtwarzacza przeznaczonego wyłącznie do odczytu plików midi. Uwaga: nie każda karta dźwiękowa posiada syntezator, musimy wtedy kombinować z rozwiązaniami software'owymi.

Autor opracowania

S.P.

Uniwersytet Gdański - Instytut Matematyki - Zakład Informatyki - Strona domowa - Perl - Wyklady
[c] Piotr Arłukowicz, materiały z tej strony udostępnione są na licencji GNU.