如何在Delphi中更改MIDI音符的音高和音量?
我在项目中使用以下代码在按键时播放midi音符(这是源代码中与midi相关的部分): 我知道有midi信息可以改变音高和音量。但是我在delphi中找不到任何使用它们的例子。 请帮助我修改playNote程序,使声音类似于吉他的弯曲效果(半音阶或全音阶上弹奏的音符的平滑音高移动),并同样改变音符的音量(淡入淡出效果) 提前谢谢你 您正在寻找新的 前四位为如何在Delphi中更改MIDI音符的音高和音量?,delphi,midi,Delphi,Midi,我在项目中使用以下代码在按键时播放midi音符(这是源代码中与midi相关的部分): 我知道有midi信息可以改变音高和音量。但是我在delphi中找不到任何使用它们的例子。 请帮助我修改playNote程序,使声音类似于吉他的弯曲效果(半音阶或全音阶上弹奏的音符的平滑音高移动),并同样改变音符的音量(淡入淡出效果) 提前谢谢你 您正在寻找新的 前四位为1110,后四位标识信道。接下来的两个字节是14位变桨弯曲值的MSB和LSB。(第一位总是0) 俯仰弯杆的“中心”值为8192 例如,通道1上的
1110
,后四位标识信道。接下来的两个字节是14位变桨弯曲值的MSB和LSB。(第一位总是0
)
俯仰弯杆的“中心”值为8192
例如,通道1上的最低弯曲点:
11100000 00000000 00000000
音高上下变化的程度完全取决于合成器。许多Synth都支持,但不是全部。我找到了一个解决方案
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;
在表单上放置一个t压缩条
,并将其Min
和Max
分别设置为0
和16383
然后你可以通过滚动鼠标滚轮来“弯曲”音高。(请注意,我在处理鼠标滚轮时使用的因子4可能不适合您的鼠标和当前的鼠标设置。)
示例:[我从我的网站上删除了EXE文件,因为Google Chrome认为它是一个恶意软件。虽然这几乎肯定是一个误报,但我担心它会对我的Google排名产生负面影响。]我曾使用过一些MIDI和Delphi,但我不是音乐家,我只知道基本知识。例如,我知道如何用给定的“音量”(称为“速度”,IIRC)弹奏给定的音符。我有点惊讶,你的
PlayNote
只接受音调而不接受“速度”。[此外,我使用NoteOn
和NoteOff
,因为有些乐器需要手动关闭音符…]我的PlayNote
过程非常简单。速度设置为127。我使用StopNote
关闭note。您可以在表单的onKeyUp
事件中看到它。非常感谢!这正是我需要与沥青一起工作的地方。淡出(-in)效果如何?是否可以在播放时改变单独音符的速度?我没有找到任何关于midi消息的信息,这些信息类似于可以调节速度的俯仰弯曲。@VIK:velocity是在音符开始时发送的一次性值。但是,“控制变更”信息可以连续发送。“控制更改”#7保留用于卷更改。请参阅David的MIDI规范,以获得易于阅读的参考资料@香农:谢谢你的有用链接。酷。我不知道在Windows中使用Midi这么容易。@Andreas:它甚至可以与我的魔法鼠标(它没有轮子,但有一个触摸板般的表面)在W7中平行地在Mac上工作!虽然如果我向上移动手指,音调会变低,反之亦然。只是一点小小的不便。我喜欢。
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;