Cel mai bun mod de a juca sunete MIDI folosind C #

Încerc să reconstruiesc o aplicație metronomică veche care a fost inițial scrisă folosind codul MFC în C ++ pentru a fi scris în .NET folosind C# . Una dintre problemele pe care le întâlnesc este să joci fișierele midi care sunt folosite pentru a reprezenta "clicurile" metronomului.

Am găsit câteva articole online despre jocul MIDI în .NET, dar majoritatea se pare că se bazează pe bibliotecile personalizate pe care cineva le-a coborât împreună și le-a pus la dispoziție. Nu mă opresc să le folosesc, dar aș prefera să înțeleg pentru mine cum se face acest lucru, deoarece se pare că ar trebui să fie un exercițiu extrem de banal.

Deci, îmi lipsește ceva? Sau este doar dificil să folosiți MIDI în interiorul unei aplicații .NET?

0
fr hi bn

9 răspunsuri

Pentru extensie MIDI și Wave manipulare în. NET, cred că mâinile în jos NAudio este soluția (De asemenea, disponibil prin NuGet ).

0
adăugat

Nu pot pretinde că știu prea multe despre asta, dar nu cred că este așa de simplu - Carl Franklin de la DotNetRocks o> faime a făcut un pic echitabil cu ea - ați văzut lui DNRTV ?

0
adăugat

Cred că va trebui să p/invocați ferestrele api pentru a putea reda fișiere midi de pe .net.

This codeproject article does a good job on explaining how to do this: vb.net article to play midi files

Pentru a rescrie aceasta este C# ai avea nevoie de următoarea instrucțiune de import pentru mciSendString:

[DllImport("winmm.dll")] 
static extern Int32 mciSendString(String command, StringBuilder buffer, 
                                  Int32 bufferSize, IntPtr hwndCallback);

Sper că acest lucru vă ajută - noroc!

0
adăugat

System.Media. SoundPlayer este un mod bun și simplu de a reda fișiere WAV. Fișierele WAV au câteva avantaje față de MIDI, unul dintre ele fiind acela că puteți controla exact ceea ce sună fiecare instrument (mai degrabă decât să se bazeze pe sintetizatorul încorporat al calculatorului).

0
adăugat

Ne pare rău, această întrebare este puțin veche acum, dar următoarele au lucrat pentru mine (oarecum copiat de la Win32 - Midi buclă cu MCISendString ):

[DllImport("winmm.dll")]
static extern Int32 mciSendString(String command, StringBuilder buffer, Int32 bufferSize, IntPtr hwndCallback);

public static void playMidi(String fileName, String alias)
{
  mciSendString("open " + fileName + " type sequencer alias " + alias, new StringBuilder(), 0, new IntPtr());
  mciSendString("play " + alias, new StringBuilder(), 0, new IntPtr());
}

public static void stopMidi(String alias)
{
  mciSendString("stop " + alias, null, 0, new IntPtr());
  mciSendString("close " + alias, null, 0, new IntPtr());
}

O listă completă a șirurilor de comandă este dată aici. Partea răcoroasă în legătură cu acest lucru este că puteți folosi diferite lucruri în afară de secvențiatori pentru a juca lucruri diferite , spun waveaudio pentru redarea fișierelor .wav. Nu pot să-mi dau seama cum să-l joace .mp3.

De asemenea, rețineți că comanda de oprire și închidere trebuie trimisă pe același fir pe care au fost trimise comenzile deschise și de redare, altfel nu vor avea efect și fișierul va rămâne deschis. De exemplu:

[DllImport("winmm.dll")]
static extern Int32 mciSendString(String command, StringBuilder buffer,
                                    Int32 bufferSize, IntPtr hwndCallback);

public static Dictionary playingMidi = new Dictionary();

public static void PlayMidi(String fileName, String alias)
{
    if (playingMidi.ContainsKey(alias))
        throw new Exception("Midi with alias '" + alias + "' is already playing");

    playingMidi.Add(alias, false);

    Thread stoppingThread = new Thread(() => { StartAndStopMidiWithDelay(fileName, alias); });
    stoppingThread.Start();
}

public static void StopMidiFromOtherThread(String alias)
{
    if (!playingMidi.ContainsKey(alias))
        return;

    playingMidi[alias] = true;
}

public static bool isPlaying(String alias)
{
    return playingMidi.ContainsKey(alias);
}

private static void StartAndStopMidiWithDelay(String fileName, String alias)
{
    mciSendString("open " + fileName + " type sequencer alias " + alias, null, 0, new IntPtr());
    mciSendString("play " + alias, null, 0, new IntPtr());

    StringBuilder result = new StringBuilder(100);
    mciSendString("set " + alias + " time format milliseconds", null, 0, new IntPtr());
    mciSendString("status " + alias + " length", result, 100, new IntPtr());

    int midiLengthInMilliseconds;
    Int32.TryParse(result.ToString(), out midiLengthInMilliseconds);

    Stopwatch timer = new Stopwatch();
    timer.Start();

    while(timer.ElapsedMilliseconds < midiLengthInMilliseconds && !playingMidi[alias])
    {

    }

    timer.Stop();

    StopMidi(alias);
}

private static void StopMidi(String alias)
{
    if (!playingMidi.ContainsKey(alias))
        throw new Exception("Midi with alias '" + alias + "' is already stopped");

   //Execute calls to close and stop the player, on the same thread as the play and open calls
    mciSendString("stop " + alias, null, 0, new IntPtr());
    mciSendString("close " + alias, null, 0, new IntPtr());

    playingMidi.Remove(alias);
}
0
adăugat
utilizați mciSendString ("deschis" + nume_file + "alias" + alias, nou StringBuilder (), 0, noul IntPtr ()); în loc de mciSendString ("deschis" + nume de fișier + "alias de tip secvență" + alias, nou StringBuilder (), 0, noul IntPtr ()); pot reda fișierele .mp3 (și o grămadă mai mult ca .wav, .wma, etc.)
adăugat autor Silent Sojourner, sursa

O adăugare recentă este MIDI.NET care acceptă Porturi Midi, Fișiere Midi și SysEx.

0
adăugat

Puteți utiliza playerul media:

using WMPLib;
//...
WindowsMediaPlayer wmp = new WindowsMediaPlayer();
wmp.URL = Path.Combine(Application.StartupPath ,"Resources/mymidi1.mid");
wmp.controls.play();
0
adăugat

În prezent lucrez la o aplicație C# MIDI, iar ceilalți au dreptate - trebuie să utilizați p/invocați pentru aceasta. Sunt rularea propriei mele ca a părea mai potrivită pentru aplicație (am nevoie doar de un mic subset de funcționalitate MIDI), dar pentru scopurile dvs., C# MIDI Toolkit ar putea fi o potrivire mai bună. Este cel puțin cea mai bună bibliotecă .NET MIDI pe care am găsit-o și am căutat extensiv înainte de a începe proiectul.

0
adăugat
Instrumentul MIDI al lui Leslie este cu siguranță cea mai cuprinzătoare soluție C# la redarea, înregistrarea MIDI. Am folosit-o pentru un proiect foarte complex și a funcționat bine.
adăugat autor andynormancx, sursa

midi-dot-net got me up and running in minutes - lightweight and right-sized for my home project. It's also available on GitHub. (Not to be confused with the previously mentioned MIDI.NET, which also looks promising, I just never got around to it.)

Bineînțeles NAudio (de asemenea menționat mai sus) are multe capabilități, dar, la fel ca posterul original, am vrut doar să joc câteva note și citiți rapid și înțelegeți codul sursă.

0
adăugat