Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Delphi中更改MIDI音符的音高和音量?_Delphi_Midi - Fatal编程技术网

如何在Delphi中更改MIDI音符的音高和音量?

如何在Delphi中更改MIDI音符的音高和音量?,delphi,midi,Delphi,Midi,我在项目中使用以下代码在按键时播放midi音符(这是源代码中与midi相关的部分): 我知道有midi信息可以改变音高和音量。但是我在delphi中找不到任何使用它们的例子。 请帮助我修改playNote程序,使声音类似于吉他的弯曲效果(半音阶或全音阶上弹奏的音符的平滑音高移动),并同样改变音符的音量(淡入淡出效果) 提前谢谢你 您正在寻找新的 前四位为1110,后四位标识信道。接下来的两个字节是14位变桨弯曲值的MSB和LSB。(第一位总是0) 俯仰弯杆的“中心”值为8192 例如,通道1上的

我在项目中使用以下代码在按键时播放midi音符(这是源代码中与midi相关的部分):

我知道有midi信息可以改变音高和音量。但是我在delphi中找不到任何使用它们的例子。 请帮助我修改playNote程序,使声音类似于吉他的弯曲效果(半音阶或全音阶上弹奏的音符的平滑音高移动),并同样改变音符的音量(淡入淡出效果)

提前谢谢你

您正在寻找新的

前四位为
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;