Whats the right way to get correct Midi?

If I open that link in any browser that I’m not logged into Google it just shows the video straight with no questions asked.

On my iPad, it wouldn’t open that link unless I gave google permission to access all my photos. On my Mac, clicking it in Firefox brought me to a Google login screen, clicking it in Safari got me the video without any login.

Anyway, the video showed me something that might be relevant. I don’t know what device you’re using to send the MIDI messages (maybe Synthstrom Deluge?), but Daisy might be having trouble handling incoming MIDI clock messages. There’s a lot more MIDI activity than just your relatively slow NOTE_ON/NOTE_OFF activity.

It comes from the Deluge which only transmits note on/off and timing/transport data at that time.
I’ve done midi programming on Arduino and then Teensy for years and never had any issues like this - well apart from self generated code mess ups.

I’m pretty sure that the daisy’s processor should be capable of reading in the provided data without issues.

Yes, no doubt, should be capable. Teensy software is much more mature.

Has this been corrected and verified?

Realized that I didn’t post the actual example but the midihandler code. Here is the correct modified example:

#include "daisy_patch.h"
#include "daisysp.h"
#include <string>

using namespace daisy;
using namespace daisysp;

DaisyPatch hw;
Oscillator osc;
Svf        filt;

void AudioCallback(AudioHandle::InputBuffer  in,
                   AudioHandle::OutputBuffer out,
                   size_t                    size)
{
    float sig;
    for(size_t i = 0; i < size; i++)
    {
        sig = osc.Process();
        filt.Process(sig);
        for(size_t chn = 0; chn < 4; chn++)
        {
            out[chn][i] = filt.Low();
        }
    }
}

// Typical Switch case for Message Type.
void HandleMidiMessage(MidiEvent m)
{
	bool hasBeenCleared = false;
    switch(m.type)
    {
        case NoteOn:
        {
			hw.display.Fill(false);
			hasBeenCleared = true;
			
            NoteOnEvent p = m.AsNoteOn();
            // This is to avoid Max/MSP Note outs for now..

            if(m.data[1] != 0)
            {
				std::string str  = std::to_string(p.note);
				char*       cstr = &str[0];
				hw.display.SetCursor(20, 10);
				hw.display.WriteString(cstr, Font_7x10, true);

                p = m.AsNoteOn();
                osc.SetFreq(mtof(p.note));
                osc.SetAmp((p.velocity / 127.0f));
            }
        }
        break;
        case NoteOff:
        {
			if(!hasBeenCleared)
				hw.display.Fill(false);

            NoteOffEvent p = m.AsNoteOff();
            // This is to avoid Max/MSP Note outs for now..

			std::string str  = std::to_string(p.note);
			char*       cstr = &str[0];
			hw.display.SetCursor(20, 20);
			hw.display.WriteString(cstr, Font_7x10, true);
        }
        break;
        case ControlChange:
        {
            ControlChangeEvent p = m.AsControlChange();
            switch(p.control_number)
            {
                case 1:
                    // CC 1 for cutoff.
                    filt.SetFreq(mtof((float)p.value));
                    break;
                case 2:
                    // CC 2 for res.
                    filt.SetRes(((float)p.value / 127.0f));
                    break;
                default: break;
            }
            break;
        }
        default: break;
    }
	 hw.display.Update();
}


// Main -- Init, and Midi Handling
int main(void)
{
    // Init
    float samplerate;
    hw.Init();
    samplerate = hw.AudioSampleRate();

    // Synthesis
    osc.Init(samplerate);
    osc.SetWaveform(Oscillator::WAVE_POLYBLEP_SAW);
    filt.Init(samplerate);

    //display
    std::string str  = "Midi";
    char*       cstr = &str[0];
    hw.display.WriteString(cstr, Font_7x10, true);
    hw.display.Update();

    // Start stuff.
    hw.midi.StartReceive();
    hw.StartAdc();
    hw.StartAudio(AudioCallback);
    for(;;)
    {
        hw.midi.Listen();
        // Handle MIDI Events
        while(hw.midi.HasEvents())
        {
            HandleMidiMessage(hw.midi.PopEvent());
        }
    }
}

Anyone? Maybe someone from the development team? This basically renders the Midi note in useless with the current library. — or is that a bug with my unit?

Saw @brbrr and @ben_serge respond here: MIDI issues in Daisy Seed since last libDaisy updates a while back. Maybe you guys have some advice?

Btw: USB midi works correctly but would rather avoid using that.

Something that does stand out from your code is that you’re doing a lot with the OLED display on a per-message basis.

For example, you have the hw.display.Update() function happen on every single message.
If you either remove that call, or move it out into the main function and set it up to run at a regular interval. Do you still experience the inconsistent behavior?

for example, pseudo code:

// in infinite loop:
hw.midi.Listen();
// Handle MIDI Events
while(hw.midi.HasEvents())
{
    HandleMidiMessage(hw.midi.PopEvent());
}

now = System::GetNow();
if (now - last_display_update > 33) // 33ms = ~30fps
{
  // Do display stuff
  hw.display.Update();
  last_display_update = now;
}
1 Like

Hi,
I’ve got the same issue here, with latest version of libDaisy (5.3.0). Midi Input is unstable.
I compared with the version 4.0.0 of libDaisy and there’s no problem.
Maybe something that can be fixed soon? Or maybe my daisy is too old?

EDIT : just tested with version 5.0.0 and the MIDI is also perfectly stable, so issue came from either 5.1 or 5.2

1 Like

i was having trouble with midi in at the newest version as of mid august and was hoping the newer versions would have fixed it. it would be nice if there was a central thread that people could let each other know if midi was stable or not and for which versions.

I’m consindering getting on board on the diasy field train. I mainly wanna do midi processing.
Is this issue resolved? Can I trust the midi implementation or should I rather find something else?

Hi monkvagabond!

We have been improving MIDI, and I believe the recent libDaisy update included it.
For example, this issue that was brought up in this thread was resolved 2 months ago.

1 Like

Hi all, I’m having the same problem with my Daisy Pod – MIDI messages appear to get lost from time to time. It happens often enought to make it unusable, specially when there are lots of messages being sent, e.g., when I connect my Linnstrument.

A buffer overrun sounds like a likely culprit. Any updates on this?

Thanks in advance!

Yesterday I noticed that I was still using libDaisy 5.3.0, which is the version that is referenced in DaisyExamples. I’m happy to report that updating libDaisy to the latest version (5.4.0) fixed my problem!

2 Likes

@Takumi_Ogata, I bet lots of people start out lie I did, by cloning the DaisyExamples and hacking on that code. Updating libDaisy ref to point to the latest version could avoid a lot of headaches.

Hello Alex!

I’m glad to hear that it’s working for you now!
Did you clone the DaisyExamples recently and it was still using libDaisy 5.3.0? If so, thank you for bringing that up. I’ll let the team know about this.

Hi @Takumi_Ogata, I cloned DaisyExamples just a few days ago and as of right now (I just checked) the version of libDaisy on there is still 5.3.0.

Thanks!

Sounds good, thank you for checking! I will bring this up to the team :slight_smile:

Happy new year, @Takumi_Ogata!

Unfortunately I spoke too soon… it’s still easy to get things to break even in version 5.4.0, all I have to do is use 5-6 fingers on my Linnstrument, which apparently produces more MIDI messages than the current UART implementation is able to handle.

I’ll try it over USB, too, to see if that makes the problem go away. But even if that is the case, it would be nice to fix this issue.

Best,
Alex

Happy new year, Alex!

Thank you for keeping us posted about the experience. Could you tell us more about the code that you flashed?