MIDI 声音仅在一个通道中(左或右)

MIDI sound only in one channel (left or right)

我有一个 WPF 应用程序需要播放 MIDI 声音,但只能在一个通道中播放 - 在左耳机或右耳机通道上。

我有一段代码可以播放 MIDI 音符(在两个通道中),但是我不知道如何修改它以仅在右通道或仅在左通道上播放 MIDI 声音。

这是我的代码:

public static class MidiNote
{
    public static MidiOut MidiOut = new MidiOut(0);
    public static void PlayNote(int key, int duration)
    {
        MidiOut.Volume = 65535;
        MidiOut.Send(MidiMessage.StartNote(key, 127, 1).RawData);
        Thread.Sleep(duration);
        MidiOut.Send(MidiMessage.StopNote(key, 0, 1).RawData);
    }
}

我找到了一些部分答案,但我不知道如何使用它们。我读了这两篇文章:

Play sound on specific channel with NAudio

How to play sound only on the left channel of the headphone and only on the right channel of the headphone in c#?

当您使用 MIDI 时,您必须向 MIDI OUT 设备发送适当的 MIDI 消息(Control-Change 或 CC 消息)以告诉它您要使用的 PAN 设置。

PAN 设置值应在 0-127 范围内,其中:

  • 0 = 向左平移
  • 127 = 向右平移
  • 64 = 平移中心

我以您的代码为起点,并添加了一些方法来允许调整 MIDI OUT 设备的 PAN 设置。

我用来演示 PANNING 的示例调用就像是一个 CONSOLE 应用程序一样编写,但新方法应该可以在您现有的 class / WPF 应用程序中正常工作。

public static class MidiNote
{
    public static MidiOut MidiOut = new MidiOut(0);

    public static void PlayNote(int key, int duration)
    {
        MidiOut.Volume = 65535;
        MidiOut.Send(MidiMessage.StartNote(key, 127, 1).RawData);
        Thread.Sleep(duration);
        MidiOut.Send(MidiMessage.StopNote(key, 0, 1).RawData);
    }

    public static void SetPanHardLeft()
    {
        var panSettingHardLeft = 0;
        var cce = new ControlChangeEvent(0L, 1, MidiController.Pan, panSettingHardLeft);
        MidiOut.Send( cce.GetAsShortMessage() );
    }

    public static void SetPanHardRight()
    {
        var panSettingHardRight = 127;
        var cce = new ControlChangeEvent(0L, 1, MidiController.Pan, panSettingHardRight);
        MidiOut.Send(cce.GetAsShortMessage());
    }

    public static void SetPanCenter()
    {
        var panSettingCenter = 64;
        var cce = new ControlChangeEvent(0L, 1, MidiController.Pan, panSettingCenter);
        MidiOut.Send(cce.GetAsShortMessage());
    }

    public static void PlayNoteRightChannel(int key, int duration)
    {
        var panSettingHardRight = 127;
        var cce = new ControlChangeEvent(0L, 1, MidiController.Pan, panSettingHardRight);
        MidiOut.Send(cce.GetAsShortMessage());

        PlayNote(key, duration);
    }

    static void Main(string[] args)
    {
        // Plays using current setting (probably CENTER)
        Console.WriteLine( "Pan setting unchanged (should be CENTER)");
        PlayNote( 50, 2000 );

        // Set the PAN for the MIDI device to HARD LEFT...
        Console.WriteLine("Pan setting HARD LEFT");
        SetPanHardLeft();
        // ...and play the note again
        PlayNote( 50, 2000);

        // Set the PAN for the MIDI device to HARD RIGHT...
        Console.WriteLine("Pan setting HARD RIGHT");
        SetPanHardRight();
        // ...and play the note again
        PlayNote(50, 2000);

        // Set the PAN for the MIDI device back to CENTER...
        Console.WriteLine("Pan setting CENTER");
        SetPanCenter();
        // ...and play the note one last time
        PlayNote(50, 2000);
    }

}