コード例 #1
0
/**
 * Performs processing on incoming serial MIDI data from an attached
 * microcontroller. Incoming data is parsed for command and data bytes,
 * with a packet being transmitted to the host computer once the proper
 * combination of bytes have been received.
 */
void handle_MIDI_in(uint8_t b) {
  if (b & 0x80) { //Is this a command or data byte
    //New command byte.
    if (b == 0xF0) {
      //SysEx Begin command, handle as special case.
      current_cmd = 0xF0;
      data_ct = 1;
      packet_size = 3;
      MIDIpacket.Event = 0x04;
      MIDIpacket.Data1 = 0xF0;
    } else if (b == 0xF7) {
      //SysEx End message, also a special case
      if (data_ct == 0) {
        MIDIpacket.Event = 0x05;
        MIDIpacket.Data1 = 0xF7;
      } else if (data_ct == 1) {
        MIDIpacket.Event = 0x06;
        MIDIpacket.Data2 = 0xF7;
      } else {
        MIDIpacket.Event = 0x07;
        MIDIpacket.Data3 = 0xF7;
      }
      MIDI_Device_SendEventPacket(&Keyboard_MIDI_Interface,&MIDIpacket);
      MIDIpacket.Data1 = 0;
      MIDIpacket.Data2 = 0;
      MIDIpacket.Data3 = 0;
      current_cmd = 0x00;
    } else {
      current_cmd = b;
      data_ct = 0;
      //First, check for a System Common Message.
      if (b >= 0xF6) {
        //Single byte System Common Message, send it
        MIDIpacket.Event = 0x05;
        MIDIpacket.Data1 = b;
        MIDI_Device_SendEventPacket(&Keyboard_MIDI_Interface,&MIDIpacket);
        current_cmd = 0;
      } else if (b == 0xF3) {
        //Two byte System Common Message
        MIDIpacket.Event = 0x02;
        MIDIpacket.Data1 = b;
        packet_size = 1;
      } else if (b == 0xF2) {
        //The only three-byte System Common Message
        MIDIpacket.Event = 0x03;
        MIDIpacket.Data1 = b;
        packet_size = 2;
      } else {
        //Channel-specific Message
        current_cmd = b >> 4;
        data_ct = 0;
        packet_size = MIDI_PACKET_SIZE[current_cmd];
        MIDIpacket.Event = current_cmd;
        MIDIpacket.Data1 = b;
      }
    }
  } else {
    //New Data byte
    if (current_cmd == 0x00)
コード例 #2
0
void midi_stream_sysex (const uint8_t length, uint8_t* data)
{
    //  Assign this MIDI event to cable 0.
    const uint8_t midi_virtual_cable = 0;
	
    //     0x2 = 2-byte System Common
    //     0x3 = 3-byte System Common
    //     0x4 = 3-byte Sysex starts or continues
    //     0x5 = 1-byte System Common or Sysex ends
    //     0x6 = 2-byte Sysex ends
    //     0x7 = 3-byte Sysex ends

    midi_event.CableNumber = midi_virtual_cable << 4;

    uint8_t num = length;// + 1;
    bool first = true;
    while (num > 3) {
        midi_event.Command     = 0x4;
        if (first) {
            first = false;
            midi_event.Data1       = *data++;
        } else {
            midi_event.Data1       = *data++;
        }
        midi_event.Data2       = *data++;
        midi_event.Data3       = *data++;
        MIDI_Device_SendEventPacket(g_midi_interface_info, &midi_event);
        num -= 3;
    }
    if (num) {
        midi_event.Command      = 0x5;
        midi_event.Data1        = *data++;
        midi_event.Data2        = 0;
        midi_event.Data3        = 0;
        if (num == 2) {
            midi_event.Command  = 0x6;
            midi_event.Data2    = *data++;
        } else if (num == 3) {
            if (first) {
                midi_event.Command     = 0x3;
            } else {
                midi_event.Command  = 0x7;
            }
            midi_event.Data2    = *data++;
            midi_event.Data3    = *data++;
        }
        MIDI_Device_SendEventPacket(g_midi_interface_info, &midi_event);
    }
}
コード例 #3
0
ファイル: DUAL_MODE.c プロジェクト: AlanChatham/hiduino
void MIDI_OUT(void) {

	if (complete == 1) {

		complete = 0;
		
		LEDs_TurnOnLEDs(LEDMASK_TX);
		
		uint8_t Channel = 0;  

		MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t) {
			.CableNumber = 0,
			.Command     = MIDI_FROM_ARDUINO.Data1 >> 4,
			.Data1       = MIDI_FROM_ARDUINO.Data1 | Channel, 
			.Data2       = MIDI_FROM_ARDUINO.Data2, 
			.Data3       = MIDI_FROM_ARDUINO.Data3,		
		};
		
		
		MIDI_Device_SendEventPacket(&MIDI_Interface, &MIDIEvent);
		MIDI_Device_Flush(&MIDI_Interface);
		
	}	
	
	else {
コード例 #4
0
void sendMidiNote(int button, bool on) {
  int command = (on) ? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF;

  MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t) {
    .Event       = MIDI_EVENT(0, command),
    .Data1       = command | MIDI_CHANNEL(1),
    .Data2       = 60 + button,
    .Data3       = MIDI_STANDARD_VELOCITY,
  };

  MIDI_Device_SendEventPacket(&tbase8_MIDI_Interface, &MIDIEvent);
  MIDI_Device_Flush(&tbase8_MIDI_Interface);
}

/** Configures the board hardware and chip peripherals for the demo's functionality. */
void SetupHardware(void)
{
  /* Disable watchdog if enabled by bootloader/fuses */
  MCUSR &= ~(1 << WDRF);
  wdt_disable();


  /* Disable clock division */
  clock_prescale_set(clock_div_1);

  /* Set the port directions for port b and d */
  DDRD  = 0xFF;
  DDRB  = 0xFF;
  PORTD = 0b01010101;
  PORTB = 0b01010101;

  /* Hardware Initialization */
  USB_Init();
}
コード例 #5
0
ファイル: midi_usb.c プロジェクト: x37v/turntable_sequencer
void usb_send_func(MidiDevice * device, uint8_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) {
   MIDI_EventPacket_t event;
   event.CableNumber = 0;
   event.Data1 = byte0;
   event.Data2 = byte1;
   event.Data3 = byte2;

   //if the length is undefined we assume it is a SYSEX message
   if (midi_packet_length(byte0) == UNDEFINED) {
      switch(cnt) {
         case 3:
            if (byte2 == SYSEX_END)
               event.Command = SYSEX_ENDS_IN_3;
            else
               event.Command = SYSEX_START_OR_CONT;
            break;
         case 2:
            if (byte1 == SYSEX_END)
               event.Command = SYSEX_ENDS_IN_2;
            else
               event.Command = SYSEX_START_OR_CONT;
            break;
         case 1:
            if (byte0 == SYSEX_END)
               event.Command = SYSEX_ENDS_IN_1;
            else
               event.Command = SYSEX_START_OR_CONT;
            break;
         default:
            return; //invalid cnt
      }
   } else {
      //deal with 'system common' messages
      //TODO are there any more?
      switch(byte0 & 0xF0){
         case MIDI_SONGPOSITION:
            event.Command = SYS_COMMON_3;
            break;
         case MIDI_SONGSELECT:
         case MIDI_TC_QUATERFRAME:
            event.Command = SYS_COMMON_2;
            break;
         default:
            event.Command = byte0 >> 4;
            break;
      }
   }

   MIDI_Device_SendEventPacket(&USB_MIDI_Interface, &event);
   MIDI_Device_Flush(&USB_MIDI_Interface);
   MIDI_Device_USBTask(&USB_MIDI_Interface);
   USB_USBTask();
}
コード例 #6
0
void midi_stream_raw_cc(const uint8_t channel,
						const uint8_t cc,
						const uint8_t value)
{
	const uint8_t command = 0xb0;  // the Channel Change command.
	MIDI_EventPacket_t midi_event;
	midi_event.CableNumber = 0x0;  // USB-MIDI virtual cable (0..15)
	midi_event.Command     = command >> 4;
	midi_event.Data1       = command | (channel & 0x0f); // 0..15
	midi_event.Data2       = cc & 0x7f;   // 0..127
	midi_event.Data3       = value & 0x7f;  // 0..127
	MIDI_Device_SendEventPacket(g_midi_interface_info, &midi_event);
}
コード例 #7
0
// Append a Control Change Event to the currently selected USB Endpoint. If
// the endpoint is full it will be flushed.
//
//  controller   Number of the controller to alter.
//  value        Value to send to the CC.
//
void midi_stream_cc(const uint8_t controller, const uint8_t value)
{
    //  Assign this MIDI event to cable 0.
    const uint8_t midi_virtual_cable = 0;
    const uint8_t command = 0xb0;  // the Channel Change command.

    midi_event.CableNumber = midi_virtual_cable << 4;
    midi_event.Command     = command >> 4;
    midi_event.Data1       = command | (g_midi_channel & 0x0f); // 0..15
    midi_event.Data2       = controller & 0x7f;   // 0..127
    midi_event.Data3       = value & 0x7f;  // 0..127

    MIDI_Device_SendEventPacket(g_midi_interface_info, &midi_event);
}
コード例 #8
0
// Used to send a note on a specific channel
void midi_stream_note_ch(const uint8_t channel,
						 const uint8_t pitch,
						 const bool onoff)

{
	// Check if the message should be a NoteOn or NoteOff event.
	uint8_t command = ((onoff)? 0x90 : 0x80);

	// Assemble a USB-MIDI event packet, remembering to mask off the values
	// to the correct bit fields.
	MIDI_EventPacket_t midi_event;
	midi_event.CableNumber = 0x0;  // USB-MIDI virtual cable (0..15)
	midi_event.Command     = command >> 4;   // 0..15
	midi_event.Data1       = command | (channel & 0x0f);  // 0..15
	midi_event.Data2       = pitch & 0x7f;   // 0..127
	midi_event.Data3       = g_midi_velocity & 0x7f; // 0..127

	MIDI_Device_SendEventPacket(g_midi_interface_info, &midi_event);
}
コード例 #9
0
// Append a MIDI note change event (note on or off) to the currently
// selected USB endpoint. If the endpoint is full it will be flushed.
//
//  pitch    Pitch of the note to turn on or off.
//  onoff    True for a NoteOn, false for a NoteOff.
//
// NOTE: The endpoint can contain 64 bytes and each MIDI-USB message is 4
// bytes giving us just enough space to fit in, for example, 16 keydown
// messages.
//
void midi_stream_note(const uint8_t pitch, const bool onoff)
{
    // Each USB-MIDI endpoint can have up to 16 virtual cables each
    // with 16 MIDI channels. Assign everything to cable 0 for now.
    const uint8_t midi_virtual_cable = 0;

    // Check if the message should be a NoteOn or NoteOff event.
    uint8_t command = ((onoff)? 0x90 : 0x80);

    // Assemble a USB-MIDI event packet, remembering to mask off the values
    // to the correct bit fields.
    midi_event.CableNumber = midi_virtual_cable & 0x0f;  //0..15
    midi_event.Command     = command >> 4;   // 0..15
    midi_event.Data1       = command | (g_midi_channel & 0x0f);  // 0..15
    midi_event.Data2       = pitch & 0x7f;   // 0..127
    midi_event.Data3       = g_midi_velocity & 0x7f; // 0..127

    MIDI_Device_SendEventPacket(g_midi_interface_info, &midi_event);
}
コード例 #10
0
ファイル: DualMIDI.c プロジェクト: 40000ft/lufa
/** Checks for changes in the position of the board joystick, sending MIDI events to the host upon each change. */
void CheckJoystickMovement(void)
{
	static uint8_t PrevJoystickStatus;

	uint8_t MIDICommand = 0;
	uint8_t MIDIPitch;

	/* Get current joystick mask, XOR with previous to detect joystick changes */
	uint8_t JoystickStatus  = Joystick_GetStatus();
	uint8_t JoystickChanges = (JoystickStatus ^ PrevJoystickStatus);

	/* Get board button status - if pressed use second virtual cable, otherwise use the first */
	uint8_t VirtualCable = (Buttons_GetStatus() & BUTTONS_BUTTON1) ? 1 : 0;

	if (JoystickChanges & JOY_LEFT)
	{
		MIDICommand = ((JoystickStatus & JOY_LEFT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
		MIDIPitch   = 0x3C;
	}

	if (JoystickChanges & JOY_UP)
	{
		MIDICommand = ((JoystickStatus & JOY_UP)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
		MIDIPitch   = 0x3D;
	}

	if (JoystickChanges & JOY_RIGHT)
	{
		MIDICommand = ((JoystickStatus & JOY_RIGHT)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
		MIDIPitch   = 0x3E;
	}

	if (JoystickChanges & JOY_DOWN)
	{
		MIDICommand = ((JoystickStatus & JOY_DOWN)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
		MIDIPitch   = 0x3F;
	}

	if (JoystickChanges & JOY_PRESS)
	{
		MIDICommand = ((JoystickStatus & JOY_PRESS)? MIDI_COMMAND_NOTE_ON : MIDI_COMMAND_NOTE_OFF);
		MIDIPitch   = 0x3B;
	}

	if (MIDICommand)
	{
		MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t)
			{
				.Event       = MIDI_EVENT(VirtualCable, MIDICommand),

				.Data1       = MIDICommand | MIDI_CHANNEL(1),
				.Data2       = MIDIPitch,
				.Data3       = MIDI_STANDARD_VELOCITY,
			};

		MIDI_Device_SendEventPacket(&Keyboard_MIDI_Interface, &MIDIEvent);
		MIDI_Device_Flush(&Keyboard_MIDI_Interface);
	}

	PrevJoystickStatus = JoystickStatus;
}

/** Event handler for the library USB Connection event. */
void EVENT_USB_Device_Connect(void)
{
	LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
}
コード例 #11
0
ファイル: Arduino-usbmidi.c プロジェクト: Eloher/arduino-usb
/** Main program entry point. This routine contains the overall program flow, including initial
 *  setup of all components and the main program loop.
 */
int main(void)
{
    MIDI_EventPacket_t midiEvent;
    struct {
	uint8_t command;
	uint8_t channel;
	uint8_t data2;
	uint8_t data3;
    } midiMsg;
    int ind;

    int led1_ticks = 0;
    int led2_ticks = 0;

    SetupHardware();

    RingBuffer_InitBuffer(&USBtoUSART_Buffer);
    RingBuffer_InitBuffer(&USARTtoUSB_Buffer);

    LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
    sei();

    for (;;) {
	RingBuff_Count_t BufferCount = RingBuffer_GetCount(&USARTtoUSB_Buffer);

	/* See if we have a message yet */
	if (BufferCount >= 4) {
	    /* Read in the message from the serial buffer */
	    for (ind=0; ind<4; ind++) {
		((uint8_t *)&midiMsg)[ind] = RingBuffer_Remove(&USARTtoUSB_Buffer);
	    }

	    /* Build a midi event to send via USB */
	    midiEvent.CableNumber = 0;
	    midiEvent.Command = midiMsg.command >> 4;
	    midiEvent.Data1 = (midiMsg.command & 0xF0) | ((midiMsg.channel-1) & 0x0F);
	    midiEvent.Data2 = midiMsg.data2;
	    midiEvent.Data3 = midiMsg.data3;

	    MIDI_Device_SendEventPacket(&Keyboard_MIDI_Interface, &midiEvent);
	    MIDI_Device_Flush(&Keyboard_MIDI_Interface);

	    /* Turn on the TX led and starts its timer */
	    LEDs_TurnOnLEDs(LEDS_LED1);
	    led1_ticks = LED_ON_TICKS;
	}
	
	/* Turn off the Tx LED when the tick count reaches zero */
	if (led1_ticks) {
	    led1_ticks--;
	    if (led1_ticks == 0) {
		LEDs_TurnOffLEDs(LEDS_LED1);
	    }
	}

	if (MIDI_Device_ReceiveEventPacket(&Keyboard_MIDI_Interface, &midiEvent)) {
	    RingBuff_Count_t count = RingBuffer_GetCount(&USBtoUSART_Buffer);
	    /* Room to send a message? */
	    if ((BUFFER_SIZE - count) >= sizeof(midiMsg)) {
		midiMsg.command = midiEvent.Command << 4;
		midiMsg.channel = (midiEvent.Data1 & 0x0F) + 1;
		midiMsg.data2 = midiEvent.Data2;
		midiMsg.data3 = midiEvent.Data3;

		for (ind=0; ind<sizeof(midiMsg); ind++) {
		    RingBuffer_Insert(&USBtoUSART_Buffer, ((uint8_t *)&midiMsg)[ind]);
		}

		/* Turn on the RX led and start its timer */
		LEDs_TurnOnLEDs(LEDS_LED2);
		led2_ticks = LED_ON_TICKS;
	    } else {
		/* Turn on the RX led and leave it on to indicate the
		 * buffer is full and the sketch is not reading it 
		 * fast enough.
		 */
		LEDs_TurnOnLEDs(LEDS_LED2);
	    }

	    /* if there's no room in the serial buffer the message gets dropped */
	}

	/* Turn off the RX LED when the tick count reaches zero */
	if (led2_ticks) {
	    led2_ticks--;
	    if (led2_ticks == 0) {
		LEDs_TurnOffLEDs(LEDS_LED2);
	    }
	}

	/* any data to send to main processor? */
	if (!(RingBuffer_IsEmpty(&USBtoUSART_Buffer))) {
	    Serial_TxByte(RingBuffer_Remove(&USBtoUSART_Buffer));
	}

	MIDI_Device_USBTask(&Keyboard_MIDI_Interface);
	USB_USBTask();
    }
}