我在我的项目中使用以下代码在按键上播放midi音符(这是与midi相关的部分来源):
uses
MMSystem;
var
hMidi, midimsg, notenum, instrumNum :integer;
procedure TForm1.FormCreate(Sender: TObject);
begin
midiOutOpen(@hmidi, 0, 0, 0, 0);
midimsg := $C0+$100*29; // set midi instrument to overdriven guitar (29th in GM midi instrument list)
midiOutShortMsg (hmidi, midimsg);
end;
procedure playNote(var note:integer);
begin
midimsg := $90 + (note * $100) + (127 * $10000) + 0;
midiOutShortMsg (hmidi, midimsg);
end;
procedure stopNote(var note:integer);
begin
midimsg := $80 + (note * $100) + 0 ;
midiOutShortMsg (hmidi, midimsg);
end;
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
playNote(60);
end;
procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
stopNote(60);
end;
procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
midiOutClose(hmidi);
end;
我知道有midi消息可以改变音高和音量。但我在delphi中找不到它们的用法示例。 请帮助我修改 playNote 程序,使声音类似于吉他弯曲效果(半音或全音调播放音符的平滑音高)和类似改变音符的音量(淡入)和淡出效果)。
提前谢谢!
答案 0 :(得分:3)
我找到了解决方案。
const
MIDI_NOTE_ON = $90;
MIDI_NOTE_OFF = $80;
MIDI_CHANGE_INSTRUMENT = $C0;
MIDI_PITCH_BEND = $E0;
function MIDIEncodeMessage(Msg, Param1, Param2: byte): integer;
begin
result := Msg + (Param1 shl 8) + (Param2 shl 16);
end;
procedure TForm4.FormClose(Sender: TObject; var Action: TCloseAction);
begin
midiOutClose(hMidi);
end;
procedure TForm4.FormCreate(Sender: TObject);
begin
playing := false;
midiOutOpen(@hMidi, 0, 0, 0, CALLBACK_NULL);
midiOutShortMsg(hMidi, MIDIEncodeMessage(MIDI_CHANGE_INSTRUMENT, 19, 0));
end;
procedure TForm4.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if playing then Exit;
ProgressBar1.Position := $2000;
midiOutShortMsg(hMidi, MIDIEncodeMessage(MIDI_PITCH_BEND,
lo(ProgressBar1.Position), hi(ProgressBar1.Position)));
midiOutShortMsg(hMidi, MIDIEncodeMessage(MIDI_NOTE_ON, 50, 127));
playing := true;
end;
procedure TForm4.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
midiOutShortMsg(hMidi, MIDIEncodeMessage(MIDI_NOTE_OFF, 50, 127));
playing := false;
end;
procedure TForm4.FormMouseWheel(Sender: TObject; Shift: TShiftState;
WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
begin
ProgressBar1.StepBy(4*WheelDelta);
midiOutShortMsg(hMidi, MIDIEncodeMessage(MIDI_PITCH_BEND,
lo(ProgressBar1.Position), hi(ProgressBar1.Position)));
end;
在表单上放置TProgressBar
,并将其Min
和Max
分别设置为0
和16383
。
然后你可以通过滚动鼠标滚轮来“弯曲”音高。 (请注意,处理鼠标滚轮时使用的因子4可能不适合您的鼠标和当前的鼠标设置。)
示例:pitchbend.exe [我从我的网站上删除了EXE文件,因为Google Chrome认为它是恶意软件。虽然这几乎肯定是误报,但我担心它会对我的谷歌排名产生负面影响。]
答案 1 :(得分:0)
您正在寻找pitch bend message。
前四位为1110
,后四位识别通道。对于14位弯音值,接下来的两个字节是MSB和LSB。 (第一位总是0
。)
弯音杆的“中心”值是8192.
例如,通道1上的最低弯曲点:
11100000 00000000 00000000
音高上升和下降完全取决于合成器。许多合成器支持changing this range with an RPN,但不是全部。