Как изменить высоту и громкость MIDI-ноты в Delphi? - PullRequest
1 голос
/ 30 июля 2011

Я использую следующий код в своем проекте для воспроизведения миди-ноты при нажатии клавиш (это часть, относящаяся к миди-части источника):

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;

Я знаю, что есть миди-сообщения для изменения высоты тона иобъем.Но я не смог найти никаких примеров их использования в delphi.Пожалуйста, помогите мне изменить процедуру playNote , чтобы звук был похож на эффект изгиба гитары (плавное смещение высоты тона проигрываемой ноты на полутоне или весь тон) и аналогичным образом изменил громкость ноты (постепенное иэффект затухания).

Заранее спасибо!

Ответы [ 2 ]

3 голосов
/ 31 июля 2011

Я нашел решение.

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 посчитал его вредоносным ПО. Хотя это почти наверняка был ложный позитив, я боялся, что это негативно скажется на моем рейтинге Google.]

0 голосов
/ 31 июля 2011

Вы ищете сообщение Pitch Bend .

Первые четыре бита 1110, а следующие четыре идентифицируют канал. Следующие два байта - это MSB и LSB для 14-битного значения основного тона. (Первый бит всегда 0.)

Значение "центра" палки изгиба высоты тона равно 8192.

Например, самая низкая точка изгиба на первом канале:

11100000 00000000 00000000

То, насколько высота звука увеличивается и уменьшается, полностью зависит от синтезатора. Многие синтезаторы поддерживают , изменяя этот диапазон с помощью RPN , но не все.

...