Giter Club home page Giter Club logo

arduino_midi_library's Introduction

Arduino MIDI Library

GitHub release License Build Examples Coveralls

This library adds MIDI I/O communications to an Arduino board.

Features

  • New : MIDI over USB, Bluetooth, IP & AppleMIDI (see Transports).
  • New : Active Sensing support
  • Compatible with all Arduino boards (and clones with an AVR processor).
  • Simple and fast way to send and receive every kind of MIDI message (including all System messages, SysEx, Clock, etc..).
  • OMNI input reading (read all channels).
  • Software Thru, with message filtering.
  • Callbacks to handle input messages more easily.
  • Last received message is saved until a new one arrives.
  • Configurable: overridable template-based settings.
  • Create more than one MIDI interface for mergers/splitters applications.
  • Use any serial port, hardware or software.

Getting Started

  1. Use the Arduino Library Manager to install the library. Type "MIDI I/Os for Arduino" in the Arduino IDE Library Manager

  2. Start coding:

#include <MIDI.h>

// Create and bind the MIDI interface to the default hardware Serial port
MIDI_CREATE_DEFAULT_INSTANCE();

void setup()
{
    MIDI.begin(MIDI_CHANNEL_OMNI);  // Listen to all incoming messages
}

void loop()
{
    // Send note 42 with velocity 127 on channel 1
    MIDI.sendNoteOn(42, 127, 1);

    // Read incoming messages
    MIDI.read();
}
  1. Read the documentation or watch the awesome video tutorials from Notes & Volts.

Documentation

USB Migration (4.x to 5.x)

All USB related code has been moved into a separate repository Arduino-USB-MIDI, USB MIDI Device support with MIDIUSB, still using this library to do all the MIDI heavy-lifting.

Migration has been made as easy as possible: only the declaration of the MIDI object has been modified, the rest of your code remains identical.

4.3.1 code:

#include <MIDI.h>
#include <midi_UsbTransport.h>

static const unsigned sUsbTransportBufferSize = 16;
typedef midi::UsbTransport<sUsbTransportBufferSize> UsbTransport;

UsbTransport sUsbTransport;

MIDI_CREATE_INSTANCE(UsbTransport, sUsbTransport, MIDI);

// ...

now becomes in 5.x:

#include <USB-MIDI.h>
USBMIDI_CREATE_DEFAULT_INSTANCE();

// ...

Start with the NoteOnOffEverySec example that is based on the original MidiUSB sketch. Note the only difference is in the declaration.

The USB-MIDI Arduino library depends on this library and the MIDIUSB library.

USB-MIDI uses the latest Arduino IDE depends feature in the library.properties file installing all the dependencies automatically when installing from the IDE.

Other Transport mechanisms

Version 5 of this library, allows for other Transport layers than the original MIDI 1.0 Electrical Specification (hardware serial).

All these Transport layers use this library for all the underlying MIDI work, making it easy to switch transport protocols or making transport protocol bridges.

Differences between Serial & other transports

  • Software Thru is enabled by default on Serial, but not on other transports.

Contact & Contribution

To report a bug, contribute, discuss on usage, or request support, please discuss it here.

You can also contact me on Twitter: @fortysevenfx.

Contributors

Special thanks to all who have contributed to this open-source project !

You want to help ? Check out the contribution guidelines.

License

MIT © 2009 - present Francois Best

arduino_midi_library's People

Contributors

davidmenting avatar franky47 avatar ifreilicht avatar insolace avatar ivankravets avatar jarosz avatar kant avatar lathoub avatar lnnrts avatar muxa avatar paul-emile-element avatar per1234 avatar rolel avatar softegg avatar stfufane avatar

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  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  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  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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

arduino_midi_library's Issues

MIDI.sendControlChange(???);

Hello I am trying to achieve something like midi keypad with arduino and distance sensors.
I have four fixed notes and four distance sensors. I want to send a note with velocity( value coming from distance sensor ) to max/msp. I am using MIDI/MOCO for LUFA firmware.

The problem is that somehow it changes the positions of the components of the midi package.
In max I have displayed:

  1. MIDI channel
  2. Control number
  3. Control value
    Somehow and sometime I have control number on the place that should be control value???
    I have tried with newer and older arduino versions. Where could be the problem?

I am attaching my patch. Can anyone help me?
Thanks in advance.

#include <MIDI.h>
#include <FIRFilters.h>
MIDI_CREATE_DEFAULT_INSTANCE();

#define a (0.07)

filters<int> f0;
filters<int> f1;
filters<int> f2;
filters<int> f3;
filters<int> f4;
filters<int> f5;
filters<int> f6;

void setup()
{
    delay(500);
    MIDI.begin();
    delay(10);
    pinMode( 6, OUTPUT);
    pinMode( 9, OUTPUT);
    pinMode(10, OUTPUT);
    pinMode(11, OUTPUT);

    pinMode(13, OUTPUT);
    delay(10);
    digitalWrite( 13, HIGH );
}

void loop()
{ 
    uint16_t sen0 = f0.EMA( analogRead( A0 ), a );
    analogWrite( 11, (sen0/4) );
    playNote0( sen0 / 2 );
//----------------------------------------------------

    uint16_t sen1 = f1.EMA( analogRead( A1 ), a );
    analogWrite( 10, (sen1>>2) );
    playNote1( sen1 >> 1 );
//----------------------------------------------------

    uint16_t sen2 = f2.EMA( analogRead( A2 ), a );
    analogWrite( 9, (sen2>>2) );
    playNote2( sen2 >> 1 );  
//----------------------------------------------------  

    uint16_t sen3 = f3.EMA( analogRead( A3 ), a );
    analogWrite( 6, (sen3>>4) );
    playNote3( sen3 >> 1 );  
//----------------------------------------------------   

    uint16_t sen4 = f4.EMA( analogRead( A4 ), a );
    analogWrite( 6, (sen4/4) );
    playNote4( sen4 >> 1 );  
//----------------------------------------------------  

    uint16_t sen5 = f5.EMA( analogRead( A5 ), a );  
    analogWrite( 6, (sen5>>4) );
    playNote5( sen5 >> 1 );  
//----------------------------------------------------  

    uint16_t sen6 = f6.EMA( analogRead( A6 ), a );  
    analogWrite( 6, (sen6>>4) );
    playNote6( sen6 >> 1 );  
//----------------------------------------------------   

  delay( 10 ); //??  
}

//-----------PLAYNOTES----------------

#define midi_channel (1)                    

const byte notes[7] = { 45, 60, 80, 120, 32, 36, 43 };

void playNote0( uint16_t sen )
{ 
    static boolean flag = 0;
    if( sen > 0 )
    {
        MIDI.sendControlChange(notes[0], sen, midi_channel);   
        flag = 1;
    } else {
        if( sen == 0 && flag == 1 ){
            MIDI.sendControlChange(notes[0], 0, midi_channel);
            flag = 0;
        }
    }
}

void playNote1( uint16_t sen )
{ 
    static boolean flag = 0;
    if( sen > 0 )
    {
        MIDI.sendControlChange(notes[1], sen, midi_channel);   
        flag = 1;
    } else {
        if( sen == 0 && flag == 1 ){
            MIDI.sendControlChange(notes[1], 0, midi_channel);
            flag = 0;
        }
    }
}

void playNote2( uint16_t sen )
{ 
    static boolean flag = 0;  
    if( sen > 0 )
    {
        MIDI.sendControlChange(notes[2], sen, midi_channel);   
        flag = 1;
    } else {
        if( sen == 0 && flag == 1 ){
            MIDI.sendControlChange(notes[2], 0, midi_channel);
            flag = 0;
        }
    }
}

void playNote3( uint16_t sen )
{ 
    static boolean flag = 0;
    if( sen > 0 )
    {
        MIDI.sendControlChange(notes[3], sen, midi_channel);   
        flag = 1;
    } else {
        if( sen == 0 && flag == 1 ){
            MIDI.sendControlChange(notes[3], 0, midi_channel);
            flag = 0;
        }
    }  
}

void playNote4( uint16_t sen )
{ 
    static boolean flag = 0;
    if( sen > 0 )
    {
        MIDI.sendControlChange(notes[4], sen, midi_channel);   
        flag = 1;
    } else {
        if( sen == 0 && flag == 1 ){
            MIDI.sendControlChange(notes[4], 0, midi_channel);
            flag = 0;
        }
    }  
}

void playNote5( uint16_t sen )
{ 
    static boolean flag = 0;
    if( sen > 0 )
    {
        MIDI.sendControlChange(notes[5], sen, midi_channel);   
        flag = 1;
    } else {
        if( sen == 0 && flag == 1 ){
            MIDI.sendControlChange(notes[5], 0, midi_channel);
            flag = 0;
        }
    }  
}

void playNote6( uint16_t sen )
{ 
    static boolean flag = 0;
    if( sen > 0 )
    {
        MIDI.sendControlChange(notes[6], sen, midi_channel);   
        flag = 1;
    } else {
        if( sen == 0 && flag == 1 ){
            MIDI.sendControlChange(notes[6], 0, midi_channel);
            flag = 0;
        }
    }  
}

Add TimeCodeFullFrame support

SourceForge reference: https://sourceforge.net/p/arduinomidilib/feature-requests/3/

There is "setHandleTimeCodeQuarterFrame" callback, but there is one more message, that is used in Midi Time Code. It's called Time Code Full Frame
Here is picture of how it should look like:
http://www.muzoborudovanie.ru/articles/midi/pict/407.gif
Here is some code, which I use now to catch this message (should be used with bug fix I have posted):

MIDI.setHandleSystemExclusive(HandleTCFF);
...
void HandleTCFF(byte* array, byte arsize)
{
  if((arsize > 2) && (array[1]==0x7F))
  {
    Hours = array[5] & 0x1F;
    Minutes = array[6] & 0x3F;
    Seconds = array[7] & 0x3F;
    Frames = array[8] & 0x1F;
  }
}

Forgot to mention why &'s are used. There can be some other data in byte:

Frames: xxxyyyyy
xxx - Reserved
yyyyy - Frame number (0-29)
Seconds: xxyyyyyy 
xx - Reserved
yyyyyy - Second number (0-59)
Minutes: 
xx - Reserved
yyyyyy - Minute number (0-59)
Hours: xyyzzzzz
x - Reserved
yy - Frame format:
00 - 24 fps
01 - 25 fps
10 - 30 fps Drop frame
11 - 30 fps Non-drop
zzzzz - Hour number (0-23)

midi lib 4.0

Hi!
Updated my program from Version 3.2 to Version 4.0.

On re-compiling my old program with the new Midi-Lib I get the message:
"`Clock´ was not declared in this scope". (code-line: MIDI.sendRealTime(Clock);)
With version 3.2 this code-line worked without problem.

I get the same compiler-error for:
MIDI.sendRealTime(Stop);
MIDI.sendRealTime(Start);

Thanks and best regards,

Chris

Arduino Leonardo support?

Hey guys,

I wanted to asked whether there will be Arduino Leonardo support? Basic example doesn't work. I tried 4.0 version and checked TX out on the scope - nothing going on (yes I removed the bit checking whether there is midi data coming, to simulate just simple midi out).

Regards,
Jonas

Why DUE does not work ?

Same sample code(MIDI_BASIC_IO.ino), UNO was works great. Why DUE does not?

void loop()
{
if (MIDI.read())
{ Something here}
}

"Something" line never run :( Anybody help plz~

SysEx messages longer than 127 bytes are ignored by MIDI.setHandleSystemExclusive()

Hello,

I have code that was working with version 3.2, receiving and Serial.print'ing long SysEx messages (tested up to 200 bytes). I see that version 4.2 includes a bug fix for messages longer than "byte" length but now my callback function is either ignoring or not receiving messages that are longer than 127 bytes. In MIDI.cpp there is a function called decodeSysEx, but no hints on where to use it. Do I need to copy that function code into my sketch? Can it be run within my callback function or does it need to follow MIDI.read? For reference, here is my call back function:

void handleSysEx(byte* array, unsigned array_size)
{
  for (int i = 0; i < array_size; i++)
  {
    Serial.print(array[i], HEX);
    Serial.print("\t");
  }
  Serial.println();
}

Brian

Receiving device does not receive data if powered up first

SourceForge reference: https://sourceforge.net/p/arduinomidilib/bugs/13/

If I power up first the Arduino Uno and afterwards the receiving device it is not possible for the receiving device to receive any midi-data. If I first power up the receiving device or if I push the Reset Button on the Arduino Uno everything works fine. Tested this with the Jomox MBase and the Elektron Octatrack, also crosschecked this with the standard serial library (there this does not occur)

Can't compile with default MIDI object

I have tried compiling code with the latest version of the MIDI Library with an Arduino UNO. I saw that I am supposed to add 'MIDI_CREATE_DEFAULT_INSTANCE();' below where I include the library.

When I include this line, I get the following error:

expected constructor, destructor, or type conversion before the ';' token

Yet it compiles fine when I leave out the new object.

Any idea why?

PitchBend problem

Hi,
I'm trying to use sendPitchBend to send a float number, but I got a error with that function. It says that "Toto" is not a member of "midi::DefaultSettings". I have searched the library and couldn't find that variable anywhere. Is it a problem with my code or a bug in the library ?

My code

#include <MIDI.h>
#include <Wire.h>
#include <SparkFun_MMA8452Q.h>


float ym;
float n;

MIDI_CREATE_DEFAULT_INSTANCE();

MMA8452Q accel;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(57600);
  accel.init(SCALE_8G, ODR_200);
  MIDI.begin();
}

void loop() {
  // put your main code here, to run repeatedly:
    for(n = 0; n<30;n++)
    {
    accel.read();
    ym = ym + accel.cy;
    }
    ym = ym/n;
    if(MIDI.read())
    {
    MIDI.sendPitchBend(ym,1);
    }
} 

Interrupt driven callbacks and sends

Sometimes I get into the situation, that I have to break from the main loop into an inner loop, which will only terminate under a certain condition.

Pseudo code example

void loop()
{
  Midi.read();
  while (1)
  { 
     if (somethingHasHappened() break;
  }
}

While the inner loop is running, midi.read is never executed. Therefore the defined callbacks are never called. Midi thru is interrupted. Not good.

Currently I have a call to midi.read() as the first statement in the implementation of somethingHasHappened(), but I would not consider this as proper design.

An approach to solve this problem would be to run the callbacks interrupt driven. HardwareSerial has already installed an isr to fill the serial ring buffer. We could steal this interrupt, peek the bytes from the port, construct the midi message as in midi.read() , call the midi callbacks, and call the original isr, so that midi.read() will behave as before, except that the callbacks already have been called.

Please discuss ....

MIDI_CREATE_DEFAULT_INSTANCE

Is it possible that you can replace this:
https://github.com/FortySevenEffects/arduino_midi_library/blob/master/src/midi_Defs.h#L172

With this now:
https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/variants/leonardo/pins_arduino.h#L358

Even 1.0.6 compatible:
https://github.com/arduino/Arduino/blob/ide-1.0.x/hardware/arduino/variants/leonardo/pins_arduino.h

Not sure if the older 1.0.5 has this definition, but its outdated. This definition is more general and should work with more MCUs.

Running status broken by Channel Aftertouch

Received via email from Zach Vorhies:

I wanted to let you know that we found that your library did not perform as expected on all keyboard types. We found the issue and fixed it for us. This fix works for my purposes but probably breaks the general use of your library. For us, we are just using the callback portion of the code for NoteOn / Off and sustain pedal, so this works for us.

Basically what happens is that after a note is pressed, and held, ChannelAfterTouch commands are sent (0xD0). This uses the running status to keep feeding data. The data stream then interrupts this with a NoteOn/NoteOf status change. However, this command just falls through and the HandleNoteOn/Off callback is never invoked.

Our solution is to check if a status message has come in, and if so then cancel the pending message and start over.

// Private method: MIDI parser
template<class SerialPort>
bool MidiInterface<SerialPort>::parse()
{
    const byte bytes_available = mSerial.available();

    if (bytes_available == 0) {
        // No data available.
        return false;
    }

    // This may not be necessary. We used this is our final build though, we
    // don't care about clock / ActiveSensing
    if ((mSerial.peek() == ActiveSensing) || (mSerial.peek() == Clock)) {
      // Consume status and keep going.
      mSerial.read();
      return parse();  // Keep going.
    }

    // This is the fix
    // Are we in the middle of another message?
    if ((mSerial.peek() >= NoteOff) && (mPendingMessageIndex > 0)) {
      // Then abort it and start over.
      resetInput();
    }

Status of Teensy version?

Hey Franky,
I can't quite tell from what's posted, what's the current status of the Teensy version of the MIDI Library, with USB support? I'm trying to find an easy way to merge data between UART MIDI and USB MIDI, and it's a bit of a headache going between the standard MIDI lib and Paul's USB MIDI for the Teensy. Your version looks like it'd make life a lot easier, I just can't tell if it's in a usable state, or a raw beta, or abandoned, or...?

Thanks for any insight you can give!

-Andy

Unit plays all midi notes at once

When I hook up my arduino with the library installed to a midi controller it sends a signal of random blocks of notes. How can I fix this?

sendPitchBend problem/bug with DefaultSettings

Hi,

When using:

struct MySettings : public midi::DefaultSettings
{
   static const bool UseRunningStatus = false; // Messes with my old equipment!
};
MIDI_CREATE_CUSTOM_INSTANCE(HardwareSerial, Serial2, midi, MySettings);

I get an error when trying to sendPitchBend:

C:\Program Files (x86)\arduino\Arduino\libraries\MIDI/MIDI.hpp:282:57: error: 'Toto' is not a member of 'MySettings'
     const int value = inPitchValue * MIDI_PITCHBEND_MAX * Settings::Toto;

My guess is that MIDI_PITCHBEND_MAX is not yet added to the DefaultSettings section and
Toto is a typo for Todo.

List of API changes / breaking changes for v4.3

Breaking Changes

  • Negative range of float/double signature of sendPitchBend extended to fix #53.
  • Sending Tune Requests through sendRealTime is no longer supported, use sendTuneRequest instead.

RPN / NRPN API

  • Replaced midi::RPN with midi::RPNLSB
  • Replaced midi::NRPN with midi::NRPNLSB
  • Replaced midi::DataEntry with midi::DataEntryMSB
  • Added beginRpn, sendRpnValue, sendRpnIncrement, sendRpnDecrement, endRpn
  • Added beginNrpn, sendNrpnValue, sendNrpnIncrement, sendNrpnDecrement, endNrpn

Non-Breaking Changes

The following changes mark the following old parts of the API as deprecated.

They are kept for backwards compatibility, but should not be used for new sketches. The old definitions will be removed in version 5.0.

  • Added sendAfterTouch with note, value and channel arguments as an alias of sendPolyPressure (now deprecated).
  • Moved Thru definitions to own sub-scope.
    • Replaced midi::Off with midi::Thru::Off
    • Replaced midi::Full with midi::Thru::Full
    • Replaced midi::SameChannel with midi::Thru::SameChannel
    • Replaced midi::DifferentChannel with midi::Thru::DifferentChannel

Other Changes

  • Default value for UseRunningStatus setting is now false. To benefit from Running Status again, use custom settings.

Intermittent failure to send with SoftwareSerial

Using SoftwareSerial, sendNoteOn() fails about every 4th attempt. Hardware (UART) serial works fine.

Simple test script which plays one note every second whilst button is pressed:

#include <SoftwareSerial.h>
#include <MIDI.h>

USING_NAMESPACE_MIDI

SoftwareSerial softSerial(3,13);
MIDI_CREATE_INSTANCE(SoftwareSerial, softSerial, midiA);

static const unsigned int g_nSwitch = 7; //Press button to ground

void setup()
{
  pinMode(g_nSwitch, INPUT_PULLUP);
  midiA.begin(); //Initialise MIDI (serial) interface A
  midiA.sendProgramChange(0, 1);
  midiA.sendControlChange(AllNotesOff, 0, 1);
}

void loop()
{
  if(!digitalRead(g_nSwitch))
  {
    midiA.sendNoteOn(60, 127, 1);
    delay(500);
    midiA.sendNoteOff(60, 0, 1);
    delay(500);
  }
}

Arduino verify error

I just downloaded the new midi library and when i open the MIDI_LibValidator.ino file with arduino 1.5.4 and veryify I get these errors.

In file included from MIDI_LibValidator.ino:10:
midi_ValidatorInstances.h:7: error: 'midi' has not been declared
midi_ValidatorInstances.h:7: error: expected initializer before '<' token
midi_ValidatorInstances.h:8: error: 'midi' has not been declared
midi_ValidatorInstances.h:8: error: expected initializer before '<' token
midi_ValidatorInstances:9: error: 'Serial1' is not a type
midi_ValidatorInstances:9: error: 'midiHW' has not been declared
midi_ValidatorInstances:9: error: expected constructor, destructor, or type conversion before ';' token
midi_ValidatorInstances:10: error: 'softSerial' is not a type
midi_ValidatorInstances:10: error: 'midiSW' has not been declared
midi_ValidatorInstances:10: error: expected constructor, destructor, or type conversion before ';' token
In file included from midi_ValidatorTester.ino:4:
midi_ValidatorTests.h:44: error: template declaration of 'bool testNoteOn'
midi_ValidatorTests.h:44: error: expected primary-expression before ')' token
midi_ValidatorTests.h:44: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests.h:44: error: (if you use '-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated)
midi_ValidatorTests.h:44: error: 'inMidi' was not declared in this scope
midi_ValidatorTests.h:45: error: template declaration of 'bool testNoteOff'
midi_ValidatorTests.h:45: error: expected primary-expression before ')' token
midi_ValidatorTests.h:45: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests.h:45: error: 'inMidi' was not declared in this scope
midi_ValidatorTests.h:46: error: template declaration of 'bool testControlChange'
midi_ValidatorTests.h:46: error: expected primary-expression before ')' token
midi_ValidatorTests.h:46: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests.h:46: error: 'inMidi' was not declared in this scope
midi_ValidatorTests.h:47: error: template declaration of 'bool testProgramChange'
midi_ValidatorTests.h:47: error: expected primary-expression before ')' token
midi_ValidatorTests.h:47: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests.h:47: error: 'inMidi' was not declared in this scope
midi_ValidatorTests.h:48: error: template declaration of 'bool testAftertouchMono'
midi_ValidatorTests.h:48: error: expected primary-expression before ')' token
midi_ValidatorTests.h:48: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests.h:48: error: 'inMidi' was not declared in this scope
midi_ValidatorTests.h:49: error: template declaration of 'bool testAftertouchPoly'
midi_ValidatorTests.h:49: error: expected primary-expression before ')' token
midi_ValidatorTests.h:49: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests.h:49: error: 'inMidi' was not declared in this scope
midi_ValidatorTests.h:50: error: template declaration of 'bool testPitchBend'
midi_ValidatorTests.h:50: error: expected primary-expression before ')' token
midi_ValidatorTests.h:50: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests.h:50: error: 'inMidi' was not declared in this scope
midi_ValidatorTests.h:51: error: template declaration of 'bool testSysEx'
midi_ValidatorTests.h:51: error: expected primary-expression before ')' token
midi_ValidatorTests.h:51: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests.h:51: error: 'inMidi' was not declared in this scope
midi_ValidatorTests.h:52: error: template declaration of 'bool testClock'
midi_ValidatorTests.h:52: error: expected primary-expression before ')' token
midi_ValidatorTests.h:52: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests.h:52: error: 'inMidi' was not declared in this scope
midi_ValidatorTests.h:53: error: template declaration of 'bool testStart'
midi_ValidatorTests.h:53: error: expected primary-expression before ')' token
midi_ValidatorTests.h:53: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests.h:53: error: 'inMidi' was not declared in this scope
midi_ValidatorTests.h:54: error: template declaration of 'bool testStop'
midi_ValidatorTests.h:54: error: expected primary-expression before ')' token
midi_ValidatorTests.h:54: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests.h:54: error: 'inMidi' was not declared in this scope
midi_ValidatorTests.h:55: error: template declaration of 'bool testContinue'
midi_ValidatorTests.h:55: error: expected primary-expression before ')' token
midi_ValidatorTests.h:55: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests.h:55: error: 'inMidi' was not declared in this scope
midi_ValidatorTests.h:56: error: template declaration of 'bool testActiveSensing'
midi_ValidatorTests.h:56: error: expected primary-expression before ')' token
midi_ValidatorTests.h:56: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests.h:56: error: 'inMidi' was not declared in this scope
midi_ValidatorTests.h:57: error: template declaration of 'bool testTimeCode'
midi_ValidatorTests.h:57: error: expected primary-expression before ')' token
midi_ValidatorTests.h:57: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests.h:57: error: 'inMidi' was not declared in this scope
midi_ValidatorTests.h:58: error: template declaration of 'bool testSongSelect'
midi_ValidatorTests.h:58: error: expected primary-expression before ')' token
midi_ValidatorTests.h:58: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests.h:58: error: 'inMidi' was not declared in this scope
midi_ValidatorTests.h:59: error: template declaration of 'bool testSongPosition'
midi_ValidatorTests.h:59: error: expected primary-expression before ')' token
midi_ValidatorTests.h:59: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests.h:59: error: 'inMidi' was not declared in this scope
midi_ValidatorTests.h:60: error: template declaration of 'bool testTuneRequest'
midi_ValidatorTests.h:60: error: expected primary-expression before ')' token
midi_ValidatorTests.h:60: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests.h:60: error: 'inMidi' was not declared in this scope
midi_ValidatorTests.h:61: error: template declaration of 'bool testSystemReset'
midi_ValidatorTests.h:61: error: expected primary-expression before ')' token
midi_ValidatorTests.h:61: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests.h:61: error: 'inMidi' was not declared in this scope
midi_ValidatorTester:12: error: 'MIDI_CLASS' has not been declared
midi_ValidatorTester:12: error: expected ',' or '...' before '&' token
midi_ValidatorTester:15: error: expected `)' before '&' token
midi_ValidatorTester:82: error: ISO C++ forbids declaration of 'MIDI_CLASS' with no type
midi_ValidatorTester:82: error: expected ';' before '&' token
midi_ValidatorTester.ino: In member function 'void Tester::setup()':
midi_ValidatorTester:24: error: 'mMidiInstance' was not declared in this scope
midi_ValidatorTester:24: error: 'MIDI_CHANNEL_OMNI' was not declared in this scope
midi_ValidatorTester.ino: In member function 'bool Tester::performTest(bool ()(int ()(SerialClass)))':
midi_ValidatorTester:33: error: 'mMidiInstance' was not declared in this scope
midi_ValidatorTester.ino: In member function 'bool Tester::run()':
midi_ValidatorTester:60: error: 'testNoteOn' was not declared in this scope
midi_ValidatorTester:61: error: 'testNoteOff' was not declared in this scope
midi_ValidatorTester:62: error: 'testControlChange' was not declared in this scope
midi_ValidatorTester:63: error: 'testProgramChange' was not declared in this scope
midi_ValidatorTester:64: error: 'testAftertouchMono' was not declared in this scope
midi_ValidatorTester:65: error: 'testAftertouchPoly' was not declared in this scope
midi_ValidatorTester:66: error: 'testPitchBend' was not declared in this scope
midi_ValidatorTester:67: error: 'testSysEx' was not declared in this scope
midi_ValidatorTester:68: error: 'testClock' was not declared in this scope
midi_ValidatorTester:69: error: 'testStart' was not declared in this scope
midi_ValidatorTester:70: error: 'testStop' was not declared in this scope
midi_ValidatorTester:71: error: 'testContinue' was not declared in this scope
midi_ValidatorTester:72: error: 'testActiveSensing' was not declared in this scope
midi_ValidatorTester:73: error: 'testTimeCode' was not declared in this scope
midi_ValidatorTester:74: error: 'testSongSelect' was not declared in this scope
midi_ValidatorTester:75: error: 'testSongPosition' was not declared in this scope
midi_ValidatorTester:76: error: 'testTuneRequest' was not declared in this scope
midi_ValidatorTester:77: error: 'testSystemReset' was not declared in this scope
midi_ValidatorTester.ino: At global scope:
midi_ValidatorTester:88: error: 'midiHW' was not declared in this scope
midi_ValidatorTester:89: error: 'midiSW' was not declared in this scope
midi_ValidatorTests:6: error: template declaration of 'bool testNoteOn'
midi_ValidatorTests:6: error: expected primary-expression before ')' token
midi_ValidatorTests:6: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests:6: error: 'inMidi' was not declared in this scope
midi_ValidatorTests:18: error: template declaration of 'bool testNoteOff'
midi_ValidatorTests:18: error: expected primary-expression before ')' token
midi_ValidatorTests:18: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests:18: error: 'inMidi' was not declared in this scope
midi_ValidatorTests:30: error: template declaration of 'bool testControlChange'
midi_ValidatorTests:30: error: expected primary-expression before ')' token
midi_ValidatorTests:30: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests:30: error: 'inMidi' was not declared in this scope
midi_ValidatorTests:42: error: template declaration of 'bool testProgramChange'
midi_ValidatorTests:42: error: expected primary-expression before ')' token
midi_ValidatorTests:42: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests:42: error: 'inMidi' was not declared in this scope
midi_ValidatorTests:54: error: template declaration of 'bool testAftertouchMono'
midi_ValidatorTests:54: error: expected primary-expression before ')' token
midi_ValidatorTests:54: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests:54: error: 'inMidi' was not declared in this scope
midi_ValidatorTests:66: error: template declaration of 'bool testAftertouchPoly'
midi_ValidatorTests:66: error: expected primary-expression before ')' token
midi_ValidatorTests:66: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests:66: error: 'inMidi' was not declared in this scope
midi_ValidatorTests:87: error: template declaration of 'bool testPitchBend'
midi_ValidatorTests:87: error: expected primary-expression before ')' token
midi_ValidatorTests:87: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests:87: error: 'inMidi' was not declared in this scope
midi_ValidatorTests:102: error: template declaration of 'bool testSysEx'
midi_ValidatorTests:102: error: expected primary-expression before ')' token
midi_ValidatorTests:102: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests:102: error: 'inMidi' was not declared in this scope
midi_ValidatorTests:121: error: template declaration of 'bool testClock'
midi_ValidatorTests:121: error: expected primary-expression before ')' token
midi_ValidatorTests:121: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests:121: error: 'inMidi' was not declared in this scope
midi_ValidatorTests:128: error: template declaration of 'bool testStart'
midi_ValidatorTests:128: error: expected primary-expression before ')' token
midi_ValidatorTests:128: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests:128: error: 'inMidi' was not declared in this scope
midi_ValidatorTests:135: error: template declaration of 'bool testStop'
midi_ValidatorTests:135: error: expected primary-expression before ')' token
midi_ValidatorTests:135: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests:135: error: 'inMidi' was not declared in this scope
midi_ValidatorTests:142: error: template declaration of 'bool testContinue'
midi_ValidatorTests:142: error: expected primary-expression before ')' token
midi_ValidatorTests:142: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests:142: error: 'inMidi' was not declared in this scope
midi_ValidatorTests:149: error: template declaration of 'bool testActiveSensing'
midi_ValidatorTests:149: error: expected primary-expression before ')' token
midi_ValidatorTests:149: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests:149: error: 'inMidi' was not declared in this scope
midi_ValidatorTests:167: error: template declaration of 'bool testTimeCode'
midi_ValidatorTests:167: error: expected primary-expression before ')' token
midi_ValidatorTests:167: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests:167: error: 'inMidi' was not declared in this scope
midi_ValidatorTests:181: error: template declaration of 'bool testSongSelect'
midi_ValidatorTests:181: error: expected primary-expression before ')' token
midi_ValidatorTests:181: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests:181: error: 'inMidi' was not declared in this scope
midi_ValidatorTests:202: error: template declaration of 'bool testSongPosition'
midi_ValidatorTests:202: error: expected primary-expression before ')' token
midi_ValidatorTests:202: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests:202: error: 'inMidi' was not declared in this scope
midi_ValidatorTests:217: error: template declaration of 'bool testTuneRequest'
midi_ValidatorTests:217: error: expected primary-expression before ')' token
midi_ValidatorTests:217: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests:217: error: 'inMidi' was not declared in this scope
midi_ValidatorTests:224: error: template declaration of 'bool testSystemReset'
midi_ValidatorTests:224: error: expected primary-expression before ')' token
midi_ValidatorTests:224: error: there are no arguments to 'MIDI_CLASS' that depend on a template parameter, so a declaration of 'MIDI_CLASS' must be available
midi_ValidatorTests:224: error: 'inMidi' was not declared in this scope

Multiple Input Channels

Hi,
I like the library, but there is one Problem I am having with it. You can not listen to more than one Input Midi Channel at a time. This is a serious limitation. My suggestion would be, to use a Bitmask instead of the Channel number to set the Channels to listen to. (So if bit 1 and 2 are set, you listen to Channels 1 and 2) At a later time in the "User Code", the User of the lib can sort the messages.

There are also two bugs in the Code, one might want to Fix:

  1. in the inputFilter method in Midi.hpp:
    the Argument "inChannel" is not used, but there is "mInputChannel" used instead. (You can not specify the Channel to filter if you call the method)
  2. in the thruFilter method in Midi.hpp:
    the Argument "inChannel" is not used, but there is "mInputChannel" used instead. (You can not specify the Channel to filter if you call the method)

BTW: I can Upload my Code with the changes applied, if you want to see it.

Incoming Running Status error on two-byte Midi message

NOTE: This has been reported for V3.2 also.
When running status is used for 2 byte messages, there is an error and a MIDI message is sent only on every second incoming byte i.e. I press Program Change Up on my controller and only every second incoming byte (remember that Program Change is a 2-bytes message) is processed. This is the same for AterTouchChannel (2 bytes also). 3 byte messages look OK.

Problem with sendPitchBend

Hello! I'm trying to use arduino midi library to send signals from arduino to some musical software on my computer. I'm a beginner about this, so my first attempt is to send some noteOn/noteOff and PitchBend messages. I'm using a button for noteOn/noteOff and a potentiometer for pitchbend. Also, I read signals on the computer through the software MIDI-OX.
This is the code i've written:

#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();

int Button=LOW; int PrevButton=LOW;
int ButtonPin=10;

int note=60; int velocity=127; int channel=1;

int potVal=0;

void setup()
{
  MIDI.begin(MIDI_CHANNEL_OFF);
  pinMode(ButtonPin,INPUT);
}

void loop()
{
  Button=digitalRead(ButtonPin);
  potVal=analogRead(A0);
  int value=map(potVal,0,1023,-8192,8191);

  if (Button==HIGH && PrevButton==LOW){ // when i start pressing the button
    MIDI.sendNoteOn(note,velocity,channel);
  }
  if (Button==LOW && PrevButton==HIGH){ // when i release the button
    MIDI.sendNoteOff(note,0,channel);
  } PrevButton=Button;

  if (Button==HIGH && PrevButton==HIGH){ // only when i'm pressing the button
    MIDI.sendPitchBend(value,channel);
  }
   delay(200);
}

And here's what MIDI-OX receives:
midi-ox-screen

What i don't understand is that after each pitchbend message there are lots of unwanted noteOn messages that, i think, are wrong. In fact, the status is 90 (as a noteOn), but data1 and data2 are the same as in the pitchbend (or similar because i was moving the potentiometer).

Am i making any mistake in the code, or have i change or add other commands?

Thanks in advance.

Arduino 1.5 BETA feedback

The MIDI Library v3.2 does not compile under the new Arduino 1.5 BETA (supporting the new Due Board).

Fix:

  • remove line 65 typedef uint16_t word;
    (it not used in the library anyway)

Can I also suggeste the following:

if defined(AVR_ATmega32U4) || defined(SAM3X8E) // Leonardo or Due

define USE_SERIAL_PORT Serial1 // Change the number (to Serial1 for example) if you want

else

define USE_SERIAL_PORT Serial // Change the number (to Serial1 for example) if you want

endif

This sets the Serial port to Serial1 for Leonardo and Due
(no need to remove these board (or flip switch) when compiling)

v4.3 Release ToDo List

Code changes

  • Update keywords.txt with API changes.
  • Fix warnings
  • Write unit tests for Callbacks.
  • Write complete unit tests for Thru

Release Workflow

  • Build all examples on all boards
  • Write release notes
  • Update readme
  • Generate documentation
  • Package release
  • Tag revision
  • Upload to GitHub releases
  • Upload documentation
  • Update Arduino page (does it even still exist ?)
  • Contact Arduino team for official addition to the library manager
  • Check update on PlatformIO
  • Close milestone

[Feature Request] Add SysEx construction helpers

Tracking here the list of SysEx messages construction helpers to be implemented:

Non Real Time Universal SysEx

  • Sample Dump Standard
    • Sample Dump Header
    • Sample Dump Data Packet
    • Sample Dump Request
  • Handshaking
    • EOF
    • Wait
    • Cancel
    • NAK
    • ACK
  • MTC Cueing
    • Setup
  • Sample Dump Extensions
    • Loop Point Transmission
    • Loop Point Request
    • Sample Name Transmission
    • Sample Name Request
    • Extended Dump Header
    • Extended Loop Point Transmission
    • Extended Loop Point Request
  • General System Information
    • Device Identity Request
    • Device Identity Reply
  • File Dump
    • File Dump Header
    • File Dump Data Packet
    • File Dump Request
  • MIDI Tuning Standard
    • Bulk Tuning Dump Request
    • Bulk Tuning Dump Reply
  • General MIDI
    • Enable
    • Disable
  • Downloadable Sounds
    • Enable
    • Disable

Real Time Universal SysEx

  • MTC
    • Full Message
    • User Bits
  • Notation Information
    • Bar Marker
    • Time Signature (immediate)
    • Time Signature (delayed)
  • Device Control
    • Master Volume
    • Master Balance
    • Master Fine Tuning
    • Master Coarse Tuning
  • MTC Cueing (immediate), see real-time equivalents without time field.
  • MIDI Machine Control
    • Single Bytes
    • Locate / GoTo
    • Shuttle
  • MIDI Tuning Standard
    • Single Note Tuning Change

Midi for USB - Need testers

Hi there!
I guess you all use Midi for the Serial ports. I've implemented a USB-Core for Arduino Leonardo/Micro (witht he help of rkistner) to use Midi with your PC as well. If someone is interested in testing this or even combining it with this library, feel free to message me about any results.

There is not much documentation yet, since I just want to check if the basic recognition is working and people actually want to use this. Then I could develop it further and also improve the API and integration. It is just a quick startup to ask you if it work, since I cannot test the Host side at the moment.

Information/discussion can be found here (scroll down a bit)
NicoHood/HID#2

Thx
Nico

Missing ControlChange in burst of messages

A burst of ControlChange message was sent using the Boarduino, but the Sanguino did not receive the first ones.

MCU Ready
0 active notes (total 8)        Head @ 0x0
Channel 1        Note On: pitch 60, velocity 127
Channel 1        Note Off: pitch 60, velocity 127
Channel 1        Note On: pitch 60, velocity 127
Channel 1        Note On: pitch 60, velocity 0
Channel 2        Note On: pitch 60, velocity 127
Channel 2        Note On: pitch 60, velocity 0
Channel 1        Control Change: number 42, value 0
Channel 1        Control Change: number 42, value 36
Channel 1        Control Change: number 42, value 40
Channel 1        Control Change: number 42, value 44
Channel 1        Control Change: number 42, value 48
Channel 1        Control Change: number 42, value 52
Channel 1        Control Change: number 42, value 56
Channel 1        Control Change: number 42, value 60
Channel 1        Control Change: number 42, value 64
Channel 1        Control Change: number 42, value 68
Channel 1        Control Change: number 42, value 72
Channel 1        Control Change: number 42, value 76
Channel 1        Control Change: number 42, value 80
Channel 1        Control Change: number 42, value 84
Channel 1        Control Change: number 42, value 88
Channel 1        Control Change: number 42, value 92
Channel 1        Control Change: number 42, value 96
Channel 1        Control Change: number 42, value 100
Channel 1        Control Change: number 42, value 104
Channel 1        Control Change: number 42, value 108
Channel 1        Control Change: number 42, value 112
Channel 1        Control Change: number 42, value 116
Channel 1        Control Change: number 42, value 120
Channel 1        Control Change: number 42, value 124
Channel 1        Program Change: number 12
Channel 11       Program Change: number 42
Channel 4        AfterTouch Poly: pitch 42, value 42
Channel 4        Aftertouch Channe: value 42
Channel 3        Pitch Bend: value 11632 or 0.42
Channel 3        Pitch Bend: value 2567 or -0.69
Start
Stop
Continue
Clock
Active Sensing
System Reset
System Reset
System Reset
MTC Quarter Frame: value 76
MTC Quarter Frame: value 76
Song Select: song number 42
Song Position: 1234 beats from song start
Tune Request
Tune Request

Handle RPN / NRPN CC messages

I need to implement Sending/receiving Midi NRPN /RPN
https://en.wikipedia.org/wiki/NRPN
http://www.philrees.co.uk/nrpnq.htm
http://www.2writers.com/eddie/TutNrpn.htm

What is the best way to include them in library???

How I can write a callback for NRPN handling??

void sendNRPN(uint8_t channel, uint16_t parameter, uint8_t value) {
MIDI.sendControlChange( 99, (parameter >> 7) & 0x7F, channel);
MIDI.sendControlChange( 98, (parameter & 0x7F), channel);
MIDI.sendControlChange( 6 , value, channel);
}
void sendNRPN(uint8_t channel, uint16_t parameter, uint16_t value) {
MIDI.sendControlChange( 99, (parameter >> 7) & 0x7F, channel);
MIDI.sendControlChange( 98, (parameter & 0x7F), channel);
MIDI.sendControlChange( 6, (value >> 7) & 0x7F, channel);
MIDI.sendControlChange( 38, (value & 0x7F), channel);
}

void sendRPN(uint8_t channel, uint16_t parameter, uint8_t value) {
MIDI.sendControlChange(101, (parameter >> 7) & 0x7F, channel);
MIDI.sendControlChange(100, (parameter & 0x7F), channel);
MIDI.sendControlChange(6, value, channel);
}
void sendRPN(uint8_t channel, uint16_t parameter, uint16_t value) {
MIDI.sendControlChange(101, (parameter >> 7) & 0x7F, channel);
MIDI.sendControlChange(100, (parameter & 0x7F), channel);
MIDI.sendControlChange(6, (value >> 7) & 0x7F, channel);
MIDI.sendControlChange(38, (value & 0x7F), channel);
}

Using with IDE 1.6.9

Importing the .zip file in IDE 1.6.9 give a message of:

Specified folder/zip file does not contain a valid library

How to use pass MIDI pointer reference into a class?

Sorry for this question but I couldn't find anywhere any info about it.
If we want to use MIDI.sendNote in a class/lib we need to pass the instance and/or pointer to the class but I couldn't find any example about it. If it's wrong place please delete my message.

sendControlChange(); generating NoteOn messages

Hey, I'm trying to use an Arduino Uno to create a device to do all sorts of MIDI manipulation, including turning PitchBend messages into CC messages (I have a sequencer that doesn't accept pitch bend, but uses a CC value for pitch shifting).

For some reason, in this particular project, when I use MIDI.sendControlChange, I get a load of NoteOn messages:
Link to screenshot on imgur

Here's a simplified version of part of a sketch I've written. I've not mentioned NoteOn at all here - any ideas of what could be happening? Thanks in advance!

#include <MIDI.h>

//constants
#define PITCHBENDMAX 8191
#define PITCHBENDMIN -8192

//variables
int CCPitch = 64;

MIDI_CREATE_DEFAULT_INSTANCE();

void setup()
{  
  MIDI.begin(MIDI_CHANNEL_OMNI);
  MIDI.setHandlePitchBend(TranslatePitchBend);
  MIDI.turnThruOff();
}

void loop()
{
  MIDI.read();
}

void TranslatePitchBend(byte channel, int bend)
{
  CCPitch = 1+ 127* float(
            (bend - PITCHBENDMIN)/
                float(PITCHBENDMAX-PITCHBENDMIN));

  MIDI.sendControlChange(80, CCPitch, channel);
}

Issue receiving more than one SysEx message

Hello!

I am having trouble to receive multiple sysex messages on an Arduino UNO.

I am using a self-made multiplatform SysEx configurator that sends 207 messages packets. This had to be done because of an OSx limitation that prevents me from sending SysEx messages greater than 256 bytes (you can find several forum posts with this issue on google).

I am receiving this data and writing it on the EEPROM.

After this, I am reading it to check what was written, and I am having several issues, always with the second and further packets. Sometimes it writes ok, sometimes there are bytes displacements... I can't find any patterns to this.

I tried sending the same message using Bome's SendSX (https://www.bome.com/products/sendsx) to send 3 packets, but separate in time, instead of one after another, and it worked perfectly.

I tried compressing the 3 packets into one large message, and it also worked.

I tried with this same software sending the 3 packets one after another with SendSX and I get similar results as with my software.

This is to tell you that I think the writing and reading into the EEPROM seems to work fine, but when I try packets that arrive very close in time, something is not working.

I don't know if it's a library issue, or a HIDUINO issue... I will post this in both githubs.

If I could get help with this it'd be awesome.

I attach the sketch I am using to write and read the EEPROM (switch between both commenting the WRITE_EEPROM define), the library that formats the data into the eeprom, and the sysex data I am testing with.

If you need further info on the issue or something is not clear, let me know.

Thanks in advance!

data sysex.txt
Sysex1.zip
KilomuxSysEx.zip

Large SysEx bug

The SysEx callback has a byte argument for the size, hence cannot report sizes larger than 255 (even if the rest of the library supports larger SysEx sizes).

disconnect callbacks

if i understand everything right, it should be possible to disconnect callbacks with:

include <MIDI.h>

MIDI.disconnectCallbackFromType(NoteOn);
and
MIDI.disconnectCallbackFromType(ControlChange);

but i got the compiler error:
Arduino: 1.5.6-r2 (Mac OS X), Board: "Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)"

Build options changed, rebuilding all

miro_Hal.ino: In function 'void setup()':
miro_Hal:126: error: 'ControlChange' was not declared in this scope

i also tried to include

#include <midi_Defs.h>
#include <midi_Namespace.h>
#include <midi_Settings.h>

but got the same results....

Thanks,
Joa

MIDI thru 'full' applies to active channel only

MIDI Thru seems to apply to the active channel only, rather than all MIDI channels. For example:

#include <MIDI.h>
void setup() {
  MIDI.begin();
  MIDI.setThruFilterMode(Full);
}
void loop() {
  MIDI.read();
}

will correctly send all MIDI messages received on channel 1 to the output, but no messages received on other channels. Calling setThruFilterMode(DifferentChannel) seems to disable MIDI thru entirely.

Ableton Live Overflows when sending MIDI through hairless MIDI

Hello,

I'm creating my own MIDI Controller using the Arduino MIDI library.
I succeed sending notes into Ableton Live, but I have some problems sending MIDI controls.
I want to trigger a loop with a button but Ableton Live overflows and I have to close it. Maybe should I use another CC number? or another Arduino input?
I selected cc 16 because it's for general purpose (i read it here: http://nickfever.com/402/production-tips-and-resources/midi-cc-list/)

Here is my code:

/*
* Roger Vilà - Midi  Controler Project
*/

#include <MIDI.h>

//Starting MIDI
MIDI_CREATE_DEFAULT_INSTANCE();

//VARIABLES

//the Led will shine while the button is pressed
int led = 13;

//button1 sends note, button2 sends Control Change
int button1 = 2;
int button2 = 4;

//last button state counter
int lastB1State = 0;
int lastB2State = 0; 

//curent button state counter
int currentB1State = 0;
int currentB2State = 0;

//Note 60 = C
int note = 60;

//Control 16 = general purpose 
int cc = 16;

//last control sent with B2
int lastControlSent = 0;

//Setup:
void setup(){

  //Start midi connection
  MIDI.begin();

  //Serial connection 115200 for Hairless MIDI
  Serial.begin(115200);

  //input button, output led
  pinMode(led, OUTPUT);
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
}

//Loop:
void loop(){

  //FIRST BUTTON WORKING PERFECT

  //BUTTON1 = B1 = piano key
  currentB1State = digitalRead(button1);

  if( currentB1State == 1 && lastB1State == 0){
    MIDI.sendNoteOn(note,127,1); 
    digitalWrite(led, HIGH);
  }  
  if (currentB1State == 0 && lastB1State == 1) {
    MIDI.sendNoteOff(note,0,1);
    digitalWrite(led, LOW);
  }

  lastB1State = currentB1State;

  /*
  currentB1State = digitalRead(button1);

  if( currentB1State == 1){

    if (lastB1State == 0) {
      MIDI.sendNoteOn(note,127,1);
      digitalWrite(led, HIGH);
    }

    lastB1State = 1;

  }else{

    if(currentB1State == 0){

      if (lastB1State == 1) {
        MIDI.sendNoteOff(note,0,1);
        digitalWrite(led, LOW);
      }

      lastB1State = 0;
    }
  }
  */
  //HERE I HAVE PROBLEMS

  //BUTTON2 = B2 = CC

  currentB2State = digitalRead(button2);

  if( currentB2State == 1 && lastB2State == 0){
    MIDI.sendControlChange(cc,127,1); 
    digitalWrite(led, HIGH);
  } 

  lastB2State = currentB2State;

  if( currentB2State == 0){
    digitalWrite(led, LOW);
  }
  /*
  currentB2State = digitalRead(button2);

  if( currentB2State == 1 && lastControlSent == 0){
    MIDI.sendControlChange(cc,127,1); 
    digitalWrite(led, HIGH);
    lastControlSent = 1;
    //100ms space
    delay(100);
  }

  if (currentB2State == 1 && lastControlSent == 1) {
    MIDI.sendControlChange(cc,0,1);
    digitalWrite(led, HIGH);
    lastControlSent = 0;
    //100ms space
    delay(100);
  }

  if( currentB2State == 0){
    digitalWrite(led, LOW);
  }
  */

  //50ms space
  delay(50);
}

Thank you very much.

default instance doesn't compile

after spending an entire day trying to get midi out to work on 32u4 based boards, it appears i needed to update to use it, but now nothing compiles and i get this:

Arduino: 1.0.5 (Mac OS X), Board: "Arduino Micro"
MIDI_Basic_IO:7: error: expected constructor, destructor, or type conversion before ';' token

i've updated all the library files, and am using the file in the examples. is there anything ELSE that needs to be changed to make this work?

error: 'Serial3' is not a type

I have followed your instructions, and was previously using v3.2. I found the midithru bug, so wanted to upgrade. Im using a MEGA but need to use serial port 3... am I doing something wrong with this

include <midi.h>

MIDI_CREATE_INSTANCE(HardwareSerial, Serial3, MIDI);

the compiler does not like it saying...
error: 'Serial3' is not a type

Trouble getting Song Position information

SourceForge reference: https://sourceforge.net/p/arduinomidilib/bugs/15/

I've been having trouble trying to get the Song Position handler to work for me. I need to perform an action at the beginning of a sequence (beat 0). However it doesn't respond. Am I missing something? Or am I completely misunderstanding how a Song Position Pointer works?

MIDI.setHandleSongPosition (SgPs);
.....
void SgPs(unsigned int beats)
{
    if (beats == 0)
    {
        doThing;
    }
    else
    {
        doOtherThing;
    }
}

Hi,
What are you using to send these messages? Song Position are usually sent by a DAW or a powerful song sequencer (with rewind, looping abilities etc).
If you want to repeat an action at the beginning of a looped sequence, you should count Clock messages (24 per quarter note).
Hope this helps.


I'm using Renoise v2.8. It does send out Song Position Pointer information.
If I just count Clock messages how will the program know when a sequencer loops back to the beginning? I have been successful counting Clock messages in order to give a tempo read-out, but I don't see how it would help in a looped sequence.

SysEx parse error

SourceForge reference: https://sourceforge.net/p/arduinomidilib/bugs/11/

SystemExclusive messages should end with 0x7F byte and You included this in your code, but in wrong place. Now You have code like this:

00641 // First, test if this is a status byte
00642 if (extracted >= 0x80) {
...
00674 case 0xF7:
00675 if (getTypeFromStatusByte(mPendingMessage[0]) == 
SystemExclusive) {
...

You have tested extracted to be more or equal to 0x80 and than expect, that it will be less (0x7F < 0x80). So that is an error.
So code should look like this:

00638 }
00639 else { 
if((extracted == 0xF7) && (getTypeFromStatusByte(mPendingMessage[0])
== SystemExclusive) && (mPendingMessageIndex>=3))
{
// Store System Exclusive array in midimsg structure
for (byte i=0;i<mPendingMessageIndex;i++) {
mMessage.sysex_array[i] = mPendingMessage[i];
}
mMessage.type = SystemExclusive;
// Get length
mMessage.data1 = (mPendingMessageIndex) & 0xFF; 
mMessage.data2 = (mPendingMessageIndex) >> 8;
mMessage.channel = 0;
mMessage.valid = true;
reset_input_attributes();
return true;
}
00641 // First, test if this is a status byte
00642 if (extracted >= 0x80) {

Last byte is not stored, because it's not a data byte, but EOX (EndOfExclusive).

MIDI file playback ?

I would love the ability to read midi file from SD that would trigger the same callbacks as the midi input, is this something planned ?

[RFC] Advanced Thru

Hi,

I am currently testing enhanced features in the midi-thru parts. The concept is, that you can add a callback to the midi auto-thru logic.

It has the signature bool fn(message.type, &message.data &message.data2, &channel) maybe will change ..

The behaviour is : if the function returns false, the message will not be sent , otherwise it will be sent with potentially modified parameters data1, data2 and channel (if available).

This is the first stage of the required features of a hardware midi patchbay, but is also useful on other occasions.

Currently I am using it for a box, that provides complex-preset based program changes to external modules. It will be connected by its midi-in from the masterkeyboard, on its midi out to a multitimbral instrument. First I am suppressing all active sensing from the keyboard, then I trap all program changes from the keyboard, remap them to the internal presets and send those new program changes from the box. This is just one example, there could be more.

I am convinced that it is not only me who could use this feature, so I am raising this issue as a starting point for a discussion.

Thank you

Kris

Running Status error

SourceForge reference: https://sourceforge.net/p/arduinomidilib/bugs/14/

When running status is used for 2 byte messages, there is an error and a MIDI message is sent only on every second incoming byte i.e. I press Program Change Up on my controller and only every second incoming byte (remember that Program Change is a 2-bytes message) is processed. This is the same for AterTouchChannel (2 bytes also). I haven't checked 3 bytes messages as my controller doesn't use rs for them, but you might want to check that logic too.

Can we have a callback example that reads SysEx?

Hello,

I'm using a older version of the library and would like to try out the newer version to see if an issue I'm having is fixed (SysEx terminator F7 bytes read out of of memory as 0). I can't get code to compile in Arduino IDE 1.6.7 with the teenseyduino add-in. The release page for the new version says:

"SysEx Callback
The SysEx callback has a new signature:
void handleSysEx(byte* data, unsigned size);"

But I don't understand what this means, nothing seems to have changed in the wiki regarding sysex call backs. This would compile and run using version 3.2:

`#include <MIDI.h>

void setup() {
Serial.begin(115200);
MIDI.begin(MIDI_CHANNEL_OMNI);
MIDI.setHandleSystemExclusive(handleSysEx);
Serial.println("MIDI SysEx Test");
}

void loop() {
MIDI.read();
}

void handleSysEx(byte* array, byte array_size)
{
for (int i = 0; i < array_size; i++)
{
Serial.print(array[i], HEX);
Serial.print("\t");
}
Serial.println();
}
`

But not with 4.2. I've tried adding the MIDI_CREATE_DEFAULT_INSTANCE(); but the MIDI.setHandleSystemExclusive(handleSysEx); line causes and invalid conversion error. I can't figure out what the correct syntax is to call my HandleSysEx function.

Enhancement Request: Serial Selection/Multiple Serials

Would it be possible to 1) allow the selection of a specific serial port without having to modify the header file, and/or 2) allow the selection of other pins/uarts for use simultaneously (e.g. MIDI in and MIDI out on separate serials)

Not entirely sure how feasible 2 in particular would be, but it would be helpful to be able to do MIDI IN and MIDI OUT both, assuming the Arduino has the bandwidth.

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.