Midi-пианино на клавиатуре
или как издать миди-звук с помощью Delphi.
ЧАСТЬ 1. Миди-пианино.
Для начала напишем небольшую программку типа пианино на клавиатуре.
Первое, что необходимо сделать,- это заюзать MMSystem (т.е дописать после Uses: MMSystem)
Далее перед implementation пишем:
var
Form1: TForm1;
hMidi :integer;
midimsg :integer; //миди сообщение
no:integer; //нота
//Открываем MidiOut при создании формы
procedure TForm1.FormCreate(Sender: TObject);
begin
midiOutOpen(@hmidi, 0, 0, 0, 0);
Form1.KeyPreview:= true;
end;
//Обрабатываем нажатие клавиш
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
if key='1' then no:=60 ; //c
if key='2' then no:=62 ; //d
if key='3' then no:=64 ; //e
if key='4' then no:=65 ; //f
if key='5' then no:=67 ; //g
if key='6' then no:=69 ; //a
if key='7' then no:=71 ; //b
if key='8' then no:=72 ; //c
if key='9' then no:=74 ; //d
if key='0' then no:=76 ; //e
if key='-' then no:=77 ; //f
if key='=' then no:=79 ; //g
//формируем сообщение
midimsg := $90 + ((no) * $100) + (127 * $10000) + 0;
//отправляем его
midiOutShortMsg (hmidi, midimsg);
end;
//закрываем MidiOut:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
midiOutClose(hmidi);
end;
Ну вот и все! Запускаем и наслаждаемся своей игрой!
Полный исходный код можно взять ЗДЕСЬ
ЧАСТЬ 2.Инструменты.
Так, пианино написали, но в midi, как известно 128 инструментов, что же делать?
Все также просто:
Отправляем короткое сообщение :
midimsg := $C0+$100*t ; // где t - номер инструмента
midiOutShortMsg (hmidi, midimsg);
Можно, конечно поэкспериментировать, и узнать что за инструмент скрывается за
каждой цифрой, но, зачем? Все можно увидеть здесь:
Instruments:array [0..127] of String=(
'AcousticGrandPiano', 'BrightAcousticPiano', 'ElectricGrandPiano',
'HonkyTonkPiano', 'ElectricPiano1', 'ElectricPiano2', 'Harpsichord', 'Clavinet',
'Celesta', 'Glockenspiel', 'MusicBox', 'Vibraphone', 'Marimba', 'Xylophone',
'TubularBells', 'Dulcimer',
'DrawbarOrgan', 'PercussiveOrgan', 'RockOrgan', 'ChurchOrgan',
'ReedOrgan', 'Accordion', 'Harmonica', 'TangoAccordion',
'AcousticNylonGuitar', ' AcousticSteelGuitar', 'JazzElectricGuitar',
'CleanElectricGuitar', 'MutedElectricGuitar', 'OverdrivenGuitar',
'DistortionGuitar', 'GuitarHarmonics', 'AcousticBass',
'FingeredElectricBass', 'PickedElectricBass', 'FretlessBass',
'SlapBass1', 'SlapBass2', 'SynthBass1', 'SynthBass2',
'Violin', 'Viola', 'Cello', 'Contrabass',
'TremoloStrings', 'PizzicatoStrings', 'OrchestralHarp', 'Timpani',
'StringEnsemble1', 'StringEnsemble2', 'SynthStrings1',
'SynthStrings2', 'ChoirAahs', 'VoiceOohs', 'SynthVoice', 'OrchestraHit',
'Trumpet', 'Trombone', 'Tuba', 'MutedTrumpet', 'FrenchHorn',
'BrassSection', 'SynthBrass1', 'SynthBrass2',
'SopranoSax', 'AltoSax', 'TenorSax', 'BaritoneSax',
'Oboe', 'EnglishHorn', 'Bassoon', 'Clarinet',
'Piccolo', 'Flute', 'Recorder', 'PanFlute', 'BlownBottle',
'Shakuhachi', 'Whistle', 'Ocarina',
'SquareLead', 'SawtoothLead', 'CalliopeLead', 'ChiffLead',
'CharangLead', 'VoiceLead', 'FifthsLead', 'BassandLead',
'NewAgePad', 'WarmPad', 'PolySynthPad', 'ChoirPad',
'BowedPad', 'MetallicPad', 'HaloPad', 'SweepPad',
'SynthFXRain', 'SynthFXSoundtrack', 'SynthFXCrystal', 'SynthFXAtmosphere',
'SynthFXBrightness', 'SynthFXGoblins', 'SynthFXEchoes', 'SynthFXSciFi',
'Sitar', 'Banjo', 'Shamisen', 'Koto', 'Kalimba',
'Bagpipe', 'Fiddle', 'Shanai',
'TinkleBell', 'Agogo', 'SteelDrums', 'Woodblock',
'TaikoDrum', 'MelodicTom', 'SynthDrum', 'ReverseCymbal',
'GuitarFretNoise', 'BreathNoise', 'Seashore', 'BirdTweet',
'TelephoneRing', 'Helicopter', 'Applause', 'Gunshot');
В этом массиве описаны все стандартные инструменты General Midi и по номеру можно вызвать название.
Например:
Edit1.text:=instruments[2]; // в Edit1 будет выведено ElectricGrandPiano
Но лучше все вывести в ListBox :
procedure TForm1.Button1Click(Sender: TObject);
var
i :integer;
begin
for i:=0 to 127 do
begin
ListBox1.Items.Add(FloatToStr(i)+'.'+Instruments[i]);
end;
end;
ЧАСТЬ 3.Отпускание ноты.
После некоторых экспериментов с инструментами Вы, наверное, заметили, что после отпускания клавиши
нота все равно продолжает звучать. Дело вот в чем: в миди за каждый звук отвечает две разных функции-
взятие ноты и отпускание ноты. Первая кодируется так: $90+$100*nota+$10000*vol +chan , где nota- высота ноты
(0-127); vol- громкость взятой ноты(0-127); chan- канал(0-15);
Снятие ноты: $80+$100*nota+chan.
Если добавить обработку события отпускания клавиш, то играть станет намного интереснее:
procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if key=ord('1') then no:=60; //c
if key=ord('2') then no:=62 ; //d
if key=ord('3') then no:=64 ; //e
if key=ord('4') then no:=65; //f
if key=ord('5') then no:=67 ; //g
if key=ord('6') then no:=69; //a
if key=ord('7') then no:=71 ; //b
if key=ord('8') then no:=72 ; //c
if key=ord('9') then no:=74 ; //d
if key=ord('0') then no:=76; //e
if key=ord('-') then no:=77 ; //f
if key=ord('=') then no:=79 ; //g
//формируем сообщение
midimsg := $80 + ((no) * $100) +0 ;
//отправляем его
midiOutShortMsg (hmidi, midimsg);
Автор: Mo-skin(c) , URL: last.h16.ru - Технологии программирования миди.
Публикация данной статьи разрешается только при указании ссылки на сайт автора!
|