2010-01-02 33 views
7

Tôi đã mua bàn phím MIDI cho sinh nhật của mình. Tôi tìm thấy một chương trình (MidiPiano) nhận tín hiệu từ đầu vào MIDI và dịch nó thành âm nhạc, nhưng tôi muốn viết một bản thân.Nhận tín hiệu từ cổng MIDI trong C#

Tôi có thể tìm tài liệu để thực hiện tác vụ như vậy ở đâu? Giao thức MIDI là tài liệu tốt, nhưng không phải là cổng MIDI.

Tôi đã kiểm tra hai dự án từ CodeProject (Project MIDI và C# MIDI Toolkit), nhưng đã dành nhiều giờ mà không cần đến gần mục tiêu của tôi.

Tham chiếu đến dự án sẽ ổn, nhưng vui lòng chỉ C#.

Trả lời

2

Tôi không thể tìm thấy nhiều, nhưng như Josh nói, Carl đã thực hiện khá nhiều công việc trên MIDI, vì vậy có thể cho anh ta một email ... thậm chí anh ta có thể trả lời, nhưng anh ta thường là một VB. Net guy vì vậy, trừ khi ai đó đã chuyển công cụ của mình để C#?

Đối với một số tài liệu tham khảo khác trông đầy hứa hẹn ...

Nếu bạn đang tìm kiếm một giải pháp C# tinh khiết ... có một cái nhìn tại Alvas.Audio. Nó trông hơi cao cấp cho những gì bạn đang yêu cầu, nhưng có thể có một số trợ giúp.

Cũng có lẽ project midi

+0

Cảm ơn Mark, và vui lòng xem nhận xét của tôi gửi cho Josh. Tôi sẽ hỏi Carl sau khi hội tụ dự án của mình cho WPF. Chắc chắn tôi sẽ có rất nhiều câu hỏi sau đó. – gideonrv

6

Bạn cần phải bọc tất cả các chức năng cần thiết được liệt kê ở http://msdn.microsoft.com/en-us/library/dd757277(VS.85).aspx

Nó không phải quá khó khăn nếu bạn chỉ sử dụng tin nhắn ngắn, mọi thứ trở nên một chút phức tạp hơn nếu bạn muốn làm SysEx hoặc phát trực tuyến.

Tất cả những gì bạn cần cho cổng nhập cơ bản là nhận ID nhập hợp lệ (InputCount -1), chuyển ID hợp lệ để Mở, Bắt đầu nhập, nhận tin nhắn qua đại biểu ... Ngừng nhập và sau đó cuối cùng đóng nó lại. Đây là một ví dụ rất thô sơ về việc làm thế nào điều này có thể đạt được - bạn sẽ cần phải kiểm tra và cẩn thận rằng Cổng không được thu thập trước khi nó đóng và cuộc gọi lại đã kết thúc hoặc bạn sẽ đóng băng hệ thống của mình!

Chúc may mắn!

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); 
    } 
}
+0

Davey nói: "Nhận tin nhắn qua đại biểu ..." và đó chính xác là vấn đề hiện tại của tôi. Liệu NativeMethods.MidiInProc có giải quyết được sự cố không? Đơn giản như vậy, một đại biểu đã sẵn sàng? Cảm ơn, Davey, tôi sẽ kiểm tra vào cuối tuần tới. – gideonrv

1

Sử dụng bộ công cụ C# Midi để nhận thông tin midi từ bàn phím (được kết nối với thẻ âm thanh midi trong cổng của bạn). Để tạo âm thanh (nhạc hoặc nhạc chuông), bạn cần tạo một luồng dữ liệu âm thanh kỹ thuật số tiếp tục. Bạn có thể bắt đầu với Bộ công cụ C# Synth (cùng tác giả như bộ công cụ midi) để viết synth của riêng bạn.

Nhưng bạn cũng có thể tải xuống chương trình sequencer (mã nguồn mở) miễn phí (ví dụ như audacity) và sử dụng các công cụ VST để thực hiện công việc cho bạn. Có rất nhiều plugin miễn phí có sẵn trên web.

2

Tôi chỉ đang trong quá trình phát triển hệ thống truyền thông midi C#. Bộ công cụ midi của Sanford rất tốt nhưng việc triển khai Leslie có nhiều cải tiến giúp mã ít đọc được hơn. Mã của tôi càng đơn giản càng tốt. Nếu bạn muốn bạn có thể tham gia cùng tôi. Trong một vài ngày tôi xuất bản màn hình midi làm việc hoàn toàn. Chỉ cần nhìn vào http://puremidi.codeplex.com/

+0

Cảm ơn câu trả lời của bạn. Tôi hiện đang tham gia vào các dự án WPF/ADO.Net/Interop khác, và, như bây giờ, nó sẽ là một lúc trước khi tôi có thể trở lại âm nhạc. Khi thời gian đến, tôi sẽ liên lạc. – gideonrv

0

Tôi đã giải quyết vấn đề này bằng cách viết một tập lệnh Python để truyền gói UDP mỗi lần ghi chú ON/OFF xuất hiện trên bàn phím MIDI.

MIDI over TCP/IP/UDP to be received inUnity3D with C#/.NET

Bằng cách đó cụ thể những thứ MIDI nền tảng được bọc, và tôi có thể viết dựa vào nền tảng C# code để nhận các gói tin UDP.

Các vấn đề liên quan