Coder Social home page Coder Social logo

rtmidi.core's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rtmidi.core's Issues

Problems with port names ending with a number.

If a port name ends with a number that coincides with the port number, the number is stripped from the name.

Example:

If I have two ports named (their real names) "Port 1" and "Port 2", they will both be reported as "Port" in the port list and hence cannot be used.

Edit: The problem seems to be a macOS problem only. I can't see that port names have any numbers appended on macOS, causing the real port name to be truncated if it ends with the same number as the internal port number.

Assert if C# 7.2 ref struct (stack-only struct) is applicable

Should help performance by ensuring messages are kept on the stack at all times, removing any allocations.

Caveat: Harder to code with, as messages cannot be stored on heap (no class fields, no usage as generic type such as storing messages in a list, cannot be captured by a lambda etc.).

Virtual Ports

Until now I used Tobias Erichsen's library for the dynamic creation of virtual midi ports but since my switch to Windows 11 this component no longer works.
While doing research I noticed that RtMidi provides an API for opening virtual ports: Virtual Ports

Do you think it is possible to integrate these RtMidi.Core functions? That would be great.

THANKS

System Common Messages

Hello!
We have developed a midi show control / midi timecode about 10 years ago, and I'm trying to get it into the new .net era ๐Ÿ˜„

We have used the Sanford.Multimedia.Midi for a long time, as it gives us access to BOTH System Exclusive (SysEx) and System Common messages. Our problem is that it is not .net Standard friendly.

I was really hoping to use this library to accomplish this task of moving our midi library onto .net standard, however I have noticed no support for System Common messages? (Listed here https://www.midi.org/specifications-old/item/table-1-summary-of-midi-message)

Is this something that is implemented here and I'm missing it, or is it something that still needs to be implemented? Thanks!

Greg

Windows 32-bit dll

Currently we only include 64bit dll for windows, as it would require manually loading the appropriate platform-specific dll before calling RtMidiC the first time, to ensure the correct 32/64-bit dll is preloaded.

I assume most will be running 64bit, so this has low priority.

Midi Clock

Hello,

I can't get the midi clock reception to work, is this normal?
I have trouble identifying if this comes from my hardware configuration or if the function does not work.

Thank you

Listen for device connect/disconnect event

When a MIDI device is connected, its ports become available and can be checked for manually via RtMidiDeviceManager.

I was trying to come up with a way to turn this into an event, so that I can listen for when a device is connected or disconnected (or, when a MIDI port appears or disappears from the list). Tracing the code, I realized the manual checks directly query RtMidi's available ports via GetPortCount and GetPortName.

I don't know if there is a different call in the RtMidi API that can, similarly to the input listener callback, listen to changes in available ports? The event doesn't even necessarily need to carry information of what's changed - we can simply ask for the list manually once the event is fired and our method executes.

RtMidi not reporting SysEx input

Having a bit of trouble with the SysEx input (which, ironically, I wrote).

Tests I wrote do work and confirm that the library is able to receive and parse them properly. However, I'm trying to listen to a SysEx message event in my application, but it doesn't seem to trigger at all.

I've done debugging to confirm the issue isn't my implementation. SysExMessage.TryDecode is never being called. I've tried tracing the calls back to the best of my knowledge, and it looks like MidiInputDevice.Decode is never called either. I've set a breakpoint at the method's entry point, and it does pause execution if I send a note on/off, but not a SysEx message from my MIDI controller. MidiInputDevice.RtMidiInputDevice_Message exhibits the same behaviour.

Now entering very unfamiliar territory, it seems RtMidiInputDevice.HandleRtMidiCallback is not called either when a SysEx message is triggered. From what I can tell, this method transfers all of the data from RtMidi into the C# library. It is, again, called when I send a note on/off, and stepping into it the message variable does get updated with that information.

To me, this suggests this is an issue with RtMidi not reporting the SysEx received from the MIDI device. I don't know if it's simply not configured to receive this kind of message when it is initialized, or if it's an issue in itself (you mentioned in the README we're using a custom build of RtMidi).

SysEx output works perfectly fine, and I've also confirmed using MIDI Monitor that the SysEx messages are actually being transmitted both ways:
image

So far this has been reproduced on macOS, pending testing on Windows.

How to get more time resolution

Hi,

First of all, thanks for writing and sharing this software.

Today I forked it and tried to add MIDI Clock support (which I need to calculate BPM).
But what I found was a lack of precision for the timestamp (in private void HandleRtMidiCallback(double timestamp, IntPtr messagePtr, UIntPtr messageSize, IntPtr userData).

image

With values like 0,021 and 0,02 I can't get the original 120 bpm value, what I get is 119 and 121.

Do you know if that is the max resolution rtmidi can provide?

Thank you for reading this!

how to use?

Hey man, I have been playing around with your RtMidi.Core, it looks great and have gotten it compile. My goal is to be able to listen for and print out the MIDI note on and off events as they arrive.

I am rather unfamiliar with C and have been racking my brain trying to figure out how to add code to your Program.cs sample so that I can register an event handler for MIDI notes and print Channel/Key/Velocity to console. Do you have any sort of example code that shows how you would do that?

NRPN issues on macOS

There is a problem with sending NRPN messages on macOS.

On Windows, every NRPN message is correctly sent. With the sequence:

  • CC99 NRPN MSB
  • CC98 NRPN LSB
  • CC6 value MSB
  • CC38 value LSB

On macOS, the following sequence is sent if the value > 0:

  • CC99 NRPN MSB
  • CC98 NRPN LSB
  • CC6 value MSB
  • CC6 value MSB
  • CC38 value LSB

...and the following sequence if the value = 0:

  • CC99 NRPN MSB
  • CC98 NRPN LSB
  • CC6 value MSB
  • CC6 value MSB

So, on macOS, CC6 is always sent twice; if the value is 0, CC38 is excluded.

Note On with velocity 0 is sent as Note Off on macOS

The Midi spec says a Note On message with velocity 0 should be treated as a Note Off message. The Mackie Control spec, on the other hand, says that the release of a button should be reported as a Note On message with velocity 0.

When I make a call to IMidiOutputDevice.Send() with a NoteOnMessage with velocity 0; this is sent as a Note On (90 xx 00) on Windows but is sent as a Note Off (80 xx 40) on macOS.

Some daws have implemented the Mackie Control protocol strictly after the Mackie spec, meaning that they require a Note On/vel 0 message and ignore Note Off messages. My app doesn't work with these daws since the wrong Midi message is sent.

How can I ensure the Note On message is sent as I have defined it on macOS and not translated to a Note Off message?

SysEx messages limited to an unknown buffer size

Hi there,
I tried to receive a SysEx data dump with a size of 18108 bytes. Waiting for the callback always results in a timeout which suggests that the message is swallowed in an undelaying layer. On the one hand I have not found an option to set a buffer size and on the one hand I would have expected for the callback to be invoked multiple times until all packages have been received.
Is that a known issue? And is there anything that you or I can do?
Thanks

.NET Core support?

The description of this repo implies the library is for .NET Core projects, while the README states it is for .NET Standard. In my netcoreapp2.1 project, I cannot seem to access any of my MIDI hardware.

TestApp.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.1</TargetFramework>
    <RuntimeIdentifiers>win10-x64;osx.10.11-x64</RuntimeIdentifiers>
    <LangVersion>7.2</LangVersion>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="RtMidi.Core" Version="1.0.46" />
  </ItemGroup>
  
</Project>

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;

using RtMidi.Core;
using RtMidi.Core.Devices;
using RtMidi.Core.Messages;

namespace TestApp {
    class Program {
        static IMidiOutputDevice oDevice;
        static IMidiInputDevice iDevice;

        static void Main(string[] args) {
            Console.WriteLine($"APIs Available: {MidiDeviceManager.Default.GetAvailableMidiApis().Count().ToString()}");
            foreach (var api in MidiDeviceManager.Default.GetAvailableMidiApis())
                Console.WriteLine($"API: {api}");

            Console.WriteLine($"Outputs Available: {MidiDeviceManager.Default.OutputDevices.Count().ToString()}");
            foreach (var oDeviceInfo in MidiDeviceManager.Default.OutputDevices) {
                Console.WriteLine($"Output Device: {oDeviceInfo.Name}");
                oDevice = oDeviceInfo.CreateDevice();

                oDevice.Open();
                oDevice.Send(new ControlChangeMessage(0, 104, 5));
                oDevice.Dispose();
            }

            Console.WriteLine($"Inputs Available: {MidiDeviceManager.Default.InputDevices.Count().ToString()}");
            foreach (var iDeviceInfo in MidiDeviceManager.Default.InputDevices) {
                try {
                    Console.WriteLine($"Output Device: {iDeviceInfo.Name}");
                    iDevice = iDeviceInfo.CreateDevice();

                    iDevice.ControlChange += MIDIIn;
                    iDevice.Open();

                    Console.WriteLine("Listening...");
                    Console.ReadKey();

                } finally {
                    iDevice.ControlChange -= MIDIIn;
                    iDevice.Dispose();
                }
            }
        }

        static void MIDIIn(IMidiInputDevice sender, in ControlChangeMessage msg) {
            Console.WriteLine(msg.Control.ToString());
        }
    }
}

Output:

APIs Available: 0
Outputs Available: 0
Inputs Available: 0

Port uniqueness

Stumbled upon this problem. I need to support a use case where two identical MIDI controllers are connected to my application. The port names are the exact same in RtMidi.Core, however I see other applications appending a number to the port name where necessary. This leaves me unable to differentiate between the two ports, and while they both show up because of that I can only talk to one of these at a time.

Trying to implement this number appending on my side, while debugging I noticed a port id hidden in the private vars of MidiDeviceInfo, I could well use it by adding it to the name and ensure the ports are unique. I was gonna submit a PR which adds a get property for the id, however I found this instead:

// RtMidi may add port number to end of name to ensure uniqueness
Name = name.EndsWith(port.ToString())
? name.Substring(0, name.LastIndexOf(port.ToString(), StringComparison.Ordinal))
: name;

It seems you're already stripping the number out when RtMidi provides it? You mention RtMidi may add it, I assume it does this only in cases when a port with the same name exists already? If so, I think this code could be simplified and you should simply use the name provided by RtMidi. If not, you could write some code that checks if a port with the same name already exists, and if it does keep the number or replace it with our own number.

Unsure how to proceed myself on implementing this, would love to hear what you think is the best course of action for resolving this issue. Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.