atsushieno / managed-midi

[Past project] Cross-platform MIDI processing library for mono and .NET (ALSA, CoreMIDI, Android, WinMM and UWP).
MIT License
194 stars 26 forks source link

ALSA: Can't hear any output #66

Closed kimimaru4000 closed 4 years ago

kimimaru4000 commented 4 years ago

Environment:

* OS: Linux Mint 20 Ulyana
* .NET Core 3.1
* Package: managed-midi version 1.9.14

I've imported managed-midi into my .NET Core application, but I cannot hear output from the example code in any of my audio devices (speakers and headphones).

Code:

public sealed class MusicCommand : BaseCommand
{
    private IMidiOutput Output = null;

    public override void Initialize(CommandHandler commandHandler)
    {
        IMidiAccess access = MidiAccessManager.Default;

        Console.WriteLine($"Output count: {access.Outputs.Count()}");
        string lastOutput = access.Outputs.Last().Id;
        Console.WriteLine($"Last output: {lastOutput}");

        Task<IMidiOutput> t = access.OpenOutputAsync(access.Outputs.Last().Id);

        t.Wait();

        Output = t.Result;

        Console.WriteLine($"Finished waiting and opened output. Details: ({Output.Details.Id}, {Output.Details.Name}, {Output.Details.Manufacturer}, {Output.Details.Version}) | Connection: {Output.Connection}");
    }   

    public override void CleanUp()
    {
        Task task = Output.CloseAsync();
        task.Wait();

        Console.WriteLine("Closed output!");
    }

    public override void ExecuteCommand(EvtChatCommandArgs e)
    {
        Output.Send(new byte [] {0xC0, GeneralMidi.Instruments.AcousticBass}, 0, 2, 0); // There are constant fields for each GM instrument
        Output.Send(new byte [] {MidiEvent.NoteOn, 0x40, 0x70}, 0, 3, 0); // There are constant fields for each MIDI event
        Output.Send(new byte [] {MidiEvent.NoteOff, 0x40, 0x70}, 0, 3, 0);
        Output.Send(new byte [] {MidiEvent.Program, 0x30}, 0, 2, 0); // Strings Ensemble
        Output.Send(new byte [] {0x90, 0x40, 0x70}, 0, 3, 0);
        Output.Send(new byte [] {0x80, 0x40, 0x70}, 0, 3, 0);
    }
}

Whenever the user types !music, it calls ExecuteCommand and should play the MIDI sounds, but I don't hear anything.

Here's the output I get for my console lines:

Output count: 1
Last output: 14_0
Finished waiting and opened output. Details: (14_0, Midi Through Port-0, , ) | Connection: Open

Is there something I'm missing?

atsushieno commented 4 years ago

Midi Through Port-0

This does not generate any audible outputs. Maybe you would like to install timidity, fluidsynth or anything that works as an ALSA MIDI device.

kimimaru4000 commented 4 years ago

Thank you! I installed timidity and some soundfonts, and I'm hearing some sounds now!

This is off-topic, but is there a chance you can explain the example code? Specifically:

output.Send(new byte [] {MidiEvent.NoteOn, 0x40, 0x70}, 0, 3, 0);

Is byte[1] the note and byte[2] the pitch?

output.Send(new byte [] {MidiEvent.NoteOff, 0x40, 0x70}, 0, 3, 0);

How come this starts at timestamp 0 instead of 3, considering it's playing the note in the previous line for 3 "length" (what is this measured in exactly)?

atsushieno commented 4 years ago

I know I'm not great at offering docs. Please check this API signature:

https://www.fuget.org/packages/managed-midi/1.9.14/lib/netstandard2.0/Commons.Music.Midi.dll/Commons.Music.Midi/IMidiOutput

That 3 part is the length part of the array ({MidiEvent.NoteOn, 0x40, 0x70}). The timestamp part is the last 0 in this case.

kimimaru4000 commented 4 years ago

Thank you! My main issue was resolved, so I'm closing this before it strays too far off-topic. I'll do some reading up on MIDI on my own to learn more about what each of these fields mean.