rolfdegen / Jeannie-Open-source-Synthesizer

Jeannie 8-voice polyphonic open source synthesizer
73 stars 12 forks source link

triggering multiple midi notes at the exact same time glitches out voices #22

Open UltraBlackLinux opened 2 years ago

UltraBlackLinux commented 2 years ago

Hey there, I found a very frustrating issue. When triggering multiple midi notes at the exact same time, the voices just start glitching out, and getting stuck in horrible noises.

The attached file shows it all: The first track is the midi track which I use to trigger the notes on the synthesizer. The second track contains two samples of what Jeannie produced. The third track is what I managed to get after way too many tries: reaper_project.zip (To check it out, you have to install Reaper)

Please fix this! Thanks!

rolfdegen commented 2 years ago

Hi I work with Ableton Live and have no problems sending midi notes. Midi notes can be received in the Jeannie every 256 usec. We still have a small improvement in the midi NoteOn routine to avoid stuck notes. Try these..

` // // Setup // FLASHMEM void setup() { .. myMidiTimer.begin(MidiClockTimer, 256); // Midi Timer interrupt myMidiTimer.priority(254);

}

// // Midi Timer Interrupt // FLASHMEM void MidiClockTimer (void) {
// read Midi datas MIDI.read(midiChannel); // MIDI 5 Pin DIN usbMIDI.read(midiChannel); // usbMidi

// play Sequencer notes
Sequencer();

}

// // Note On from Midi IN // FLASHMEM void myNoteOn(byte channel, byte note, byte velocity) {

// Prevent notes hanger
for (int i = 0; i < NO_OF_VOICES; i++) {
    if (voices[i].note == note && voices[i].voiceOn == 1) {
        endVoice(i + 1);
    }
}

// Transpose mode ? ---------------------------------------------------
if (SEQmode == 1 && SEQrunStatus == true) {

    for (uint8_t i = 0; i < SEQstepNumbers; i++) {
        if (SeqNoteBufStatus[i] == 1) {
            SeqTranspose = note - SeqNote1Buf[i];
            return;
        }
    }
    SeqTranspose = 0;
    return;
}
//---------------------------------------------------------------------
if (PageNr == 11 && SEQrunStatus == false && SEQmode == 2) {
    if (SeqRecNoteCount < 8) {
        SeqRecNoteCount++;
    }
}

// Unisono Mode 0 -----------------------------------------------------
if (unison == 0) {
    switch (getVoiceNo(-1))  {
        case 1:
        if (oscDetuneSync == true) {
            waveformMod1a.sync();
            waveformMod1b.sync();
        }
        voice1On(note, velocity, VOICEMIXERLEVEL);
        updateVoice1();
        break;
        case 2:
        if (oscDetuneSync == true) {
            waveformMod2a.sync();
            waveformMod2b.sync();
        }
        voice2On(note, velocity, VOICEMIXERLEVEL);
        updateVoice2();
        break;
        case 3:
        if (oscDetuneSync == true) {
            waveformMod3a.sync();
            waveformMod3b.sync();
        }
        voice3On(note, velocity, VOICEMIXERLEVEL);
        updateVoice3();
        break;
        case 4:
        if (oscDetuneSync == true) {
            waveformMod4a.sync();
            waveformMod4b.sync();
        }
        voice4On(note, velocity, VOICEMIXERLEVEL);
        updateVoice4();
        break;
        case 5:
        if (oscDetuneSync == true) {
            waveformMod5a.sync();
            waveformMod5b.sync();
        }
        voice5On(note, velocity, VOICEMIXERLEVEL);
        updateVoice5();
        break;
        case 6:
        if (oscDetuneSync == true) {
            waveformMod6a.sync();
            waveformMod6b.sync();
        }
        voice6On(note, velocity, VOICEMIXERLEVEL);
        updateVoice6();
        break;
        case 7:
        if (oscDetuneSync == true) {
            waveformMod7a.sync();
            waveformMod7b.sync();
        }
        voice7On(note, velocity, VOICEMIXERLEVEL);
        updateVoice7();
        break;
        case 8:
        if (oscDetuneSync == true) {
            waveformMod8a.sync();
            waveformMod8b.sync();
        }
        voice8On(note, velocity, VOICEMIXERLEVEL);
        updateVoice8();
        break;
    }
    } else {
    // Unisono Mode 1  ------------------------------------------------
    if (unison == 1) incNotesOn();  //For Unison mode

    if (unison != 0 && oscDetuneSync == true) {
        waveformMod1a.sync();
        waveformMod1b.sync();
        waveformMod2a.sync();
        waveformMod2b.sync();
        waveformMod3a.sync();
        waveformMod3b.sync();
        waveformMod4a.sync();
        waveformMod4b.sync();
        waveformMod5a.sync();
        waveformMod5b.sync();
        waveformMod6a.sync();
        waveformMod6b.sync();
        waveformMod7a.sync();
        waveformMod7b.sync();
        waveformMod8a.sync();
        waveformMod8b.sync();
    }

    voice1On(note, velocity, UNISONVOICEMIXERLEVEL);
    voice2On(note, velocity, UNISONVOICEMIXERLEVEL);
    voice3On(note, velocity, UNISONVOICEMIXERLEVEL);
    voice4On(note, velocity, UNISONVOICEMIXERLEVEL);
    voice5On(note, velocity, UNISONVOICEMIXERLEVEL);
    voice6On(note, velocity, UNISONVOICEMIXERLEVEL);
    voice7On(note, velocity, UNISONVOICEMIXERLEVEL);
    voice8On(note, velocity, UNISONVOICEMIXERLEVEL);
    updatesAllVoices();//Set detune values
    prevNote = note;
}

// LFO1 (Pitch) sync --------------------------------------------------
if (oscLfoRetrig == 1 || oscLfoRetrig == 2) {
    pitchLfo.sync();
    //float pha = LFO1phase;
    //pitchLfo.phase(pha);
}

// LFO2 (Filter) sync -------------------------------------------------
if (filterLfoRetrig == 1 || filterLfoRetrig == 2) {
    filterLfo.sync();
    //float pha = LFO2phase;
    //filterLfo.phase(pha);
}

// LFO3 (AMP) sync ----------------------------------------------------
if (Lfo3Retrig == 1 || Lfo3Retrig == 2) {
    ModLfo3.sync();
    //float pha = LFO3phase;
    //ModLfo3.phase(pha);
}   

MidiStatusSymbol = 1;
EnvIdelFlag = true; // oscilloscope enabled
//drawVoiceLED ();
voiceLEDflag = true;

// Sequencer Recording notes
SequencerRecNotes(note, velocity);

// update LFO randomFlag
LFO1randomFlag = false;
LFO2randomFlag = false;
LFO3randomFlag = false;

} `

My last firmware 1.57 https://www.tubeohm.com/jeannie-firmware.html

UltraBlackLinux commented 2 years ago

work with Ableton Live and have no problems sending midi notes.

Does it work in Reaper too? I doubt that it makes much of a difference. I am running linux so no Ableton for me.

My last firmware 1.57 https://www.tubeohm.com/jeannie-firmware.html

I'm running that already, so is that broken by any chance?

rolfdegen commented 2 years ago

OK. I will try next time with reaper.

rolfdegen commented 2 years ago

Ok. I could also see the problem in Reaper with Jeannie. I'm working on a solution :)