如何在delphi上访问midi打击乐器?

时间:2014-11-30 12:39:17

标签: delphi midi channel

我知道如何播放midi乐器的128种声音,我需要的是如何进入midi打击乐器。

2 个答案:

答案 0 :(得分:7)

使用WikipediaMSDNMIDI.org,我发现了如何使用打击乐器“乐器”。 (也就是说,我找到了如何设置频道。)尝试以下代码。这太棒了。

unit Unit5;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, MMSystem;

type
  TForm5 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form5: TForm5;

type
  TMIDIInstrument = (midiAcousticGrandPiano, midiBrightAcousticPiano,
                     midiElectricGrandPiano, midiHonkyTonkPiano,
                     midiRhodesPiano, midiChorusedPiano, midiHarpsichord,
                     midiClavinet, midiCelesta, midiGlockenspiel,
                     midiMusicBox, midiVibraphone, midiMarimba, midiXylophone,
                     midiTubularBells, midiDulcimer, midiHammondOrgan,
                     midiPercussiveOrgan, midiRockOrgan, midiChurchOrgan,
                     midiReedOrgan, midiAccordion, midiHarmonica,
                     midiTangoAccordion, midiAcousticGuitarNylon,
                     midiAcousticGuitarSteel, midiElectricGuitarJazz,
                     midiElectricGuitarClean, midiElectricGuitarMuted,
                     midiOverdrivenGuitar, midiDistortionGuitar,
                     midiGuitarHarmonics, midiAcousticBass, midiElectricBassFinger,
                     midiElectricBassPick, midiFretlessBass, midiSlapBass1,
                     midiSlapBass2, midiSynthBass1, midiSynthBass2, midiViolin,
                     midiViola, midiCello, midiContrabass, midiTremoloStrings,
                     midiPizzicatoStrings, midiOrchestralHarp, midiTimpani,
                     midiStringEnsemble1, midiStringEnsemble2, midiSynthStrings1,
                     midiSynthStrings2, midiChoirAahs, midiVoiceOohs,
                     midiSynthVoice, midiOrchestraHit, midiTrumpet, midiTrombone,
                     midiTuba, midiMutedTrumpet, midiFrenchHorn, midiBrassSection,
                     midiSynthBrass1, midiSynthBrass2, midiSopranoSax, midiAltoSax,
                     midiTenorSax, midiBaritoneSax, midiOboe, midiEnglishHorn,
                     midiBassoon, midiClarinet, midiPiccolo, midiFlute,
                     midiRecorder, midiPanFlute, midiBottleBlow, midiShakuhachi,
                     midiWhistle, midiOcarina, midiLead1Square,
                     midiLead2Sawtooth, midiLead3CalliopeLead, midiLead4ChiffLead,
                     midiLead5Charang, midiLead6Voice, midiLead7Fifths,
                     midiLead8BrassLead, midiPad1NewAge, midiPad2Warm,
                     midiPad3Polysynth, midiPad4Choir, midiPad5Bowed,
                     midiPad6Metallic, midiPad7Halo, midiPad8Sweep, midiFX1Rain,
                     midiFX2Soundtrack, midiFX3Crystal, midiFX4Atmosphere, midiFX5Brightness, midiFX6Goblins,
                     midiFX7Echoes, midiFX8SciFi, midiSitar, midiBanjo, midiShamisen,
                     midiKoto, midiKalimba, midiBagpipe, midiFiddle,
                     midiShanai, midiTinkleBelll, midiAgogo, midiSteelDrums,
                     midiWoodblock, midiTaikoDrum, midiMelodicTom, midiSynthDrum,
                     midiReverseCymbal, midiGuitarFretNoise, midiBreathNoise,
                     midiSeashore, midiBirdTweet, midiTelephoneRing,
                     midiHelicopter, midiApplause, midiGunshot);

const
  MIDI_NOTE_ON = $90;
  MIDI_NOTE_OFF = $80;
  MIDI_CHANGE_INSTRUMENT = $C0;
  MIDI_DEVICE = 0;
  MIDI_VEL = 108;
  MIDI_PERCUSSION_CHANNEL = 9;

implementation

{$R *.dfm}

var
  mo: HMIDIOUT;

function MIDIEncodeMessage(Channel, Msg, Param1, Param2: integer): integer;
begin
  result := Channel or Msg + (Param1 shl 8) + (Param2 shl 16);
end;

procedure SetCurrentInstrument(CurrentInstrument: TMIDIInstrument);
begin
  midiOutShortMsg(mo, MIDIEncodeMessage(0, MIDI_CHANGE_INSTRUMENT, ord(CurrentInstrument), 0));
end;

procedure NoteOn(Channel, NewNote, NewIntensity: byte);
begin
  midiOutShortMsg(mo, MIDIEncodeMessage(Channel, MIDI_NOTE_ON, NewNote, NewIntensity));
end;

procedure NoteOff(Channel, NewNote, NewIntensity: byte);
begin
  midiOutShortMsg(mo, MIDIEncodeMessage(Channel, MIDI_NOTE_OFF, NewNote, NewIntensity));
end;

procedure TForm5.FormCreate(Sender: TObject);
var
  i: Integer;
begin
  midiOutOpen(@mo, 0, 0, 0, CALLBACK_NULL);
  midiOutSetVolume(mo, $FFFFFFFF);

  // Normal MIDI
  SetCurrentInstrument(midiChurchOrgan);
  NoteOn(0, 20, 127);
  sleep(200);
  NoteOn(0, 50, 127);
  sleep(200);
  NoteOn(0, 80, 127);
  sleep(200);
  NoteOn(0, 110, 127);
  sleep(1000);
  NoteOff(0, 110, 127);
  sleep(200);
  NoteOff(0, 80, 127);
  sleep(200);
  NoteOff(0, 50, 127);
  sleep(200);
  NoteOff(0, 20, 127);

  SetCurrentInstrument(midiAcousticGuitarNylon);
  NoteOn(0, 100, 127);
  NoteOn(0, 50, 127);

  sleep(1000);

  // Percussion
  for i := 0 to 127 do
  begin
    NoteOn(MIDI_PERCUSSION_CHANNEL, i, 127);
    sleep(100);
  end;

end;

end.

如您所见,您只需要将频道包含在MIDI信息中。打击乐频道为9(第10频道)。 (所有其他频道都是“普通”频道;请参阅维基百科文章。)

答案 1 :(得分:1)

MIDI标准本身并未定义任何乐器或打击乐声音。

通用MIDI规范定义了128种乐器和47种打击乐声音。 所有通道除了通道9(从零开始计数)播放乐器,通道9播放打击乐声音,不同的音符编号会产生不同的声音。

其他规格(通用MIDI 2,GS,XG等)定义更多声音,并具有选择用于打击乐声音的通道的机制。