Получение сигналов от порта MIDI в C#

Я купил клавиатуру MIDI на свой день рождения. Я нашел программу (MidiPiano), который получает сигналы от входа MIDI и переводит его на музыку, но я хотел бы написать тот сам.

Где я могу найти документацию для того, чтобы сделать такую задачу? Протокол MIDI хорошо зарегистрирован, но не порты MIDI.

Я проверил два проекта от CodeProject (MIDI проекта и Набор инструментов MIDI C#), но провел много часов, не будучи рядом с моей целью.

Ссылка на проект будет прекрасна, но пожалуйста, только C#.

7
задан gideonrv 2 January 2010 в 10:12
поделиться

3 ответа

Я тоже ничего не смог найти, но, как говорит Джош, Карл определенно проделал большую работу по MIDI, так что, возможно, дайте ему электронное письмо. ...он может даже ответить, но он обычно парень из VB.Net, так что если только кто-то не портировал его вещи на C#?

Для некоторых других ссылок, которые выглядели многообещающими...

Если вы ищете чистое решение на C#... посмотрите на Alvas.Audio. Это действительно выглядит немного преуспевающим для того, что вы просите, но может быть полезно.

Также возможно проект midi

2
ответ дан 6 December 2019 в 23:06
поделиться

Вам нужно обернуть все необходимые функции, перечисленные по адресу http://msdn.microsoft.com/en-us/library/dd757277(VS.85).aspx

Это не слишком сложно, если вы используете только короткие сообщения, все немного усложняется, если вы хотите делать SysEx или выводить потоковое вещание.

Все, что вам нужно для основного порта ввода, это получить правильные идентификаторы ввода (InputCount -1), передать правильный идентификатор на Open, Start the input, получить сообщения через делегата.... Остановить вход и затем окончательно закрыть его. Это очень грубый пример того, как это может быть достигнуто - вам нужно будет сделать некоторую проверку и быть осторожным, чтобы порт не был собран до того, как он будет закрыт, и закрытый обратный вызов произошел, или вы заморозите свою систему!

Удачи!

namespace MIDI
{
    public class InputPort
    {
        private NativeMethods.MidiInProc midiInProc;
        private IntPtr handle;

        public InputPort()
        {
            midiInProc = new NativeMethods.MidiInProc(MidiProc);
            handle = IntPtr.Zero;
        }

        public static int InputCount
        {
            get { return NativeMethods.midiInGetNumDevs(); }
        }

        public bool Close()
        {
            bool result = NativeMethods.midiInClose(handle) 
                == NativeMethods.MMSYSERR_NOERROR;
            handle = IntPtr.Zero;
            return result;
        }

        public bool Open(int id)
        {
            return NativeMethods.midiInOpen(
                out handle,
                id,
                midiInProc,
                IntPtr.Zero,
                NativeMethods.CALLBACK_FUNCTION)
                    == NativeMethods.MMSYSERR_NOERROR;
        }

        public bool Start()
        {
            return NativeMethods.midiInStart(handle)
                == NativeMethods.MMSYSERR_NOERROR;
        }

        public bool Stop()
        {
            return NativeMethods.midiInStop(handle)
                == NativeMethods.MMSYSERR_NOERROR;
        }

        private void MidiProc(IntPtr hMidiIn,
            int wMsg,
            IntPtr dwInstance,
            int dwParam1,
            int dwParam2)
        {
            // Receive messages here
        }
    }

    internal static class NativeMethods
    {
        internal const int MMSYSERR_NOERROR = 0;
        internal const int CALLBACK_FUNCTION = 0x00030000;

        internal delegate void MidiInProc(
            IntPtr hMidiIn,
            int wMsg,
            IntPtr dwInstance,
            int dwParam1,
            int dwParam2);

        [DllImport("winmm.dll")]
        internal static extern int midiInGetNumDevs();

        [DllImport("winmm.dll")]
        internal static extern int midiInClose(
            IntPtr hMidiIn);

        [DllImport("winmm.dll")]
        internal static extern int midiInOpen(
            out IntPtr lphMidiIn,
            int uDeviceID,
            MidiInProc dwCallback,
            IntPtr dwCallbackInstance,
            int dwFlags);

        [DllImport("winmm.dll")]
        internal static extern int midiInStart(
            IntPtr hMidiIn);

        [DllImport("winmm.dll")]
        internal static extern int midiInStop(
            IntPtr hMidiIn);
    }
}
6
ответ дан 6 December 2019 в 23:06
поделиться

Используйте C # Midi Toolkit для получения MIDI-информации с клавиатуры (подключенной к входному MIDI-порту звуковой карты). Для создания звука (музыки или тонов) вам необходимо сгенерировать непрерывный поток цифровых аудиоданных. Вы можете начать с C # Synth Toolkit (того же автора, что и midi toolkit), чтобы написать свой собственный синтезатор.

Но вы также можете загрузить бесплатную программу секвенсора (с открытым исходным кодом) (например, Audacity) и использовать плагины для инструментов VST, которые сделают эту работу за вас. В сети доступно множество бесплатных плагинов.

1
ответ дан 6 December 2019 в 23:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: