void Update() { // Update the note state array. foreach (var cs in _channelArray) { for (var i = 0; i < 128; i++) { var x = cs._noteArray[i]; if (x > 1) cs._noteArray[i] = x - 1; // Key down -> Hold. else if (x < 0) cs._noteArray[i] = 0; // Key up -> Off. } } // Process the message queue. while (true) { // Pop from the queue. var data = DequeueIncomingData(); if (data == 0) break; // Parse the message. var message = new MidiMessage(data); // Split the first byte. var statusCode = message.status >> 4; var channelNumber = message.status & 0xf; // Note on message? if (statusCode == 9) { var velocity = 1.0f / 127 * message.data2 + 1; _channelArray[channelNumber]._noteArray[message.data1] = velocity; _channelArray[(int)MidiChannel.All]._noteArray[message.data1] = velocity; if (noteOnDelegate != null) noteOnDelegate((MidiChannel)channelNumber, message.data1, velocity - 1); } // Note off message? if (statusCode == 8 || (statusCode == 9 && message.data2 == 0)) { _channelArray[channelNumber]._noteArray[message.data1] = -1; _channelArray[(int)MidiChannel.All]._noteArray[message.data1] = -1; if (noteOffDelegate != null) noteOffDelegate((MidiChannel)channelNumber, message.data1); } // CC message? if (statusCode == 0xb) { // Normalize the value. var level = 1.0f / 127 * message.data2; // Update the channel if it already exists, or add a new channel. _channelArray[channelNumber]._knobMap[message.data1] = level; // Do again for All-ch. _channelArray[(int)MidiChannel.All]._knobMap[message.data1] = level; if (knobDelegate != null) knobDelegate((MidiChannel)channelNumber, message.data1, level); } #if UNITY_EDITOR // Record the message. _totalMessageCount++; _messageHistory.Enqueue(message); #endif } #if UNITY_EDITOR // Truncate the history. while (_messageHistory.Count > 8) _messageHistory.Dequeue(); #endif }
void Update() { Refresh(); // Update the note state array. foreach (var cs in _channelArray) { for (var i = 0; i < 128; i++) { var x = cs._noteArray[i]; if (x > 1) { cs._noteArray[i] = x - 1; // Key down -> Hold. } else if (x < 0) { cs._noteArray[i] = 0; // Key up -> Off. } } } MidiDriver.Refresh(); // Process the message queue. while (true) { if (msgQueue.Count == 0) { break; } // Pop from the queue. MidiMessage message = msgQueue.Dequeue(); // Split the first byte. var statusCode = message.status >> 4; var channelNumber = message.status & 0xf; // Note on message? if (statusCode == 9) { var velocity = 1.0f / 127 * message.data2 + 1; _channelArray[channelNumber]._noteArray[message.data1] = velocity; _channelArray[(int)MidiChannel.All]._noteArray[message.data1] = velocity; if (noteOnDelegate != null) { noteOnDelegate((MidiChannel)channelNumber, message.data1, velocity - 1); } } // Note off message? if (statusCode == 8 || (statusCode == 9 && message.data2 == 0)) { _channelArray[channelNumber]._noteArray[message.data1] = -1; _channelArray[(int)MidiChannel.All]._noteArray[message.data1] = -1; if (noteOffDelegate != null) { noteOffDelegate((MidiChannel)channelNumber, message.data1); } } // CC message? if (statusCode == 0xb) { // Normalize the value. var level = 1.0f / 127 * message.data2; // Update the channel if it already exists, or add a new channel. int knobNumber = message.data1; if (_midiMap) { knobNumber = _midiMap.JackValue(knobNumber); } _channelArray[channelNumber]._knobMap[knobNumber] = level; // Do again for All-ch. _channelArray[(int)MidiChannel.All]._knobMap[knobNumber] = level; if (knobDelegate != null) { knobDelegate((MidiChannel)channelNumber, knobNumber, level); } } // System message? if (statusCode == 0xf) { if (channelNumber == 0) { if (message.data1 >= _sysexMem.Length) { return; } _sysexMem[message.data1] = message.data2; if (sysexDelegate != null) { sysexDelegate((MidiSysex)message.data1, message.data2); } } else { if (message.status == (byte)MidiRealtime.Clock) { if (realtimeDelegate != null) { realtimeDelegate(MidiRealtime.Clock); } } if (message.status == (byte)MidiRealtime.Start) { _isPlaying = true; if (realtimeDelegate != null) { realtimeDelegate(MidiRealtime.Start); } } if (message.status == (byte)MidiRealtime.Continue) { _isPlaying = true; if (realtimeDelegate != null) { realtimeDelegate(MidiRealtime.Continue); } } if (message.status == (byte)MidiRealtime.Stop) { _isPlaying = false; if (realtimeDelegate != null) { realtimeDelegate(MidiRealtime.Stop); } } } } } }
void Update() { // Update the note state array. foreach (var cs in _channelArray) { for (var i = 0; i < 128; i++) { var x = cs._noteArray[i]; if (x > 1) { cs._noteArray[i] = x - 1; // Key down -> Hold. } else if (x < 0) { cs._noteArray[i] = 0; // Key up -> Off. } } } // Process the message queue. while (true) { // Pop from the queue. var data = DequeueIncomingData(); if (data == 0) { break; } // Parse the message. var message = new MidiMessage(data); // Split the first byte. var statusCode = message.status >> 4; var channelNumber = message.status & 0xf; // Note on message? if (statusCode == 9) { var velocity = 1.0f / 127 * message.data2 + 1; _channelArray[channelNumber]._noteArray[message.data1] = velocity; _channelArray[(int)MidiChannel.All]._noteArray[message.data1] = velocity; if (noteOnDelegate != null) { noteOnDelegate((MidiChannel)channelNumber, message.data1, velocity - 1); } if (noteOnEvent != null) { noteOnEvent.Invoke((MidiChannel)channelNumber, message.data1, velocity - 1); } } // Note off message? if (statusCode == 8 || (statusCode == 9 && message.data2 == 0)) { _channelArray[channelNumber]._noteArray[message.data1] = -1; _channelArray[(int)MidiChannel.All]._noteArray[message.data1] = -1; if (noteOffDelegate != null) { noteOffDelegate((MidiChannel)channelNumber, message.data1); } if (noteOffEvent != null) { noteOffEvent((MidiChannel)channelNumber, message.data1); } } // CC message? if (statusCode == 0xb) { // Normalize the value. var level = 1.0f / 127 * message.data2; // Update the channel if it already exists, or add a new channel. _channelArray[channelNumber]._knobMap[message.data1] = level; // Do again for All-ch. _channelArray[(int)MidiChannel.All]._knobMap[message.data1] = level; if (knobDelegate != null) { knobDelegate((MidiChannel)channelNumber, message.data1, level); } if (knobEvent != null) { knobEvent((MidiChannel)channelNumber, message.data1, level); } } // Clock message ? if (message.status == 0xF8) { var timestamp = GetTimestamp(); if (timestamp > 0) { _clockEventTimestamps.Enqueue(timestamp); } _clockEventCount++; if (_clockEventCount >= 24) { if (_clockEventTimestamps.Count > 1) { float mean = 0; int count = _clockEventTimestamps.Count - 1; ulong time = _clockEventTimestamps.Dequeue(); while (_clockEventTimestamps.Count > 0) { ulong temp = _clockEventTimestamps.Dequeue(); ulong diff = temp - time; mean += ((diff) / (float)count); time = temp; } _lastBeatLength = (24.0f * mean / 1000.0f); if (clockEvent != null) { clockEvent(24.0f * mean); } } else { _clockEventTimestamps.Clear(); } _clockEventCount = 0; } } #if UNITY_EDITOR // Record the message. _totalMessageCount++; _messageHistory.Enqueue(message); #endif } #if UNITY_EDITOR // Truncate the history. while (_messageHistory.Count > 8) { _messageHistory.Dequeue(); } #endif }
void Update() { // Update the note state array. foreach (var cs in _channelArray) { for (var i = 0; i < 128; i++) { var x = cs._noteArray[i]; if (x > 1) { cs._noteArray[i] = x - 1; // Key down -> Hold. } else if (x < 0) { cs._noteArray[i] = 0; // Key up -> Off. } } } // Process the message queue. while (true) { // MIDI IN message pop from the queue. var data = DequeueIncomingData(); if (data == 0) { break; } // Parse the message. var message = new MidiMessage(data); // Split the first byte. var statusCode = message.status >> 4; var channelNumber = message.status & 0xf; // Note on message? if (statusCode == 9) { var velocity = 1.0f / 127 * message.data2 + 1; _channelArray[channelNumber]._noteArray[message.data1] = velocity; _channelArray[(int)MidiChannel.All]._noteArray[message.data1] = velocity; if (noteOnDelegate != null) { noteOnDelegate((MidiChannel)channelNumber, message.data1, velocity - 1); } } // Note off message? if (statusCode == 8 || (statusCode == 9 && message.data2 == 0)) { _channelArray[channelNumber]._noteArray[message.data1] = -1; _channelArray[(int)MidiChannel.All]._noteArray[message.data1] = -1; if (noteOffDelegate != null) { noteOffDelegate((MidiChannel)channelNumber, message.data1); } } // CC message? if (statusCode == 0xb) { // Normalize the value. var level = 1.0f / 127 * message.data2; // Update the channel if it already exists, or add a new channel. _channelArray[channelNumber]._knobMap[message.data1] = level; // Do again for All-ch. _channelArray[(int)MidiChannel.All]._knobMap[message.data1] = level; if (knobDelegate != null) { knobDelegate((MidiChannel)channelNumber, message.data1, level); } } #if UNITY_EDITOR // Record the message. _totalMessageCount++; _messageHistory.Enqueue(message); #endif } while (true) { // dequeue MIDI OUT message var data = DequeueSendData(); if (data == 0) { break; } } #if UNITY_EDITOR // Truncate the history. while (_messageHistory.Count > 8) { _messageHistory.Dequeue(); } #endif }
public void Update() { // Update the note state array. foreach (var cs in _channelArray) { for (var i = 0; i < 128; i++) { var x = cs._noteArray[i]; if (x > 1) { cs._noteArray[i] = x - 1; // Key down -> Hold. } else if (x < 0) { cs._noteArray[i] = 0; // Key up -> Off. } } } // Process the message queue. while (true) { // Pop from the queue. var data = DequeueIncomingData(); if (data == 0) { break; } // Parse the message. var message = new MidiMessage(data); // Split the first byte. var statusCode = (StatusCode)(message.status >> 4); var channelNumber = message.status & 0xf; if (statusCode == StatusCode.NoteOn) { var velocity = 1.0f / 127 * message.data2 + 1; _channelArray[channelNumber]._noteArray[message.data1] = velocity; _channelArray[(int)MidiChannel.All]._noteArray[message.data1] = velocity; if (noteOnDelegate != null) { noteOnDelegate((MidiChannel)channelNumber, message.data1, velocity - 1); } } else if (statusCode == StatusCode.NoteOff || (statusCode == StatusCode.NoteOn && message.data2 == 0)) { _channelArray[channelNumber]._noteArray[message.data1] = -1; _channelArray[(int)MidiChannel.All]._noteArray[message.data1] = -1; if (noteOffDelegate != null) { noteOffDelegate((MidiChannel)channelNumber, message.data1); } } else if (statusCode == StatusCode.ControlChange) { // Normalize the value. var level = 1.0f / 127 * message.data2; // Update the channel if it already exists, or add a new channel. _channelArray[channelNumber]._knobMap[message.data1] = level; // Do again for All-ch. _channelArray[(int)MidiChannel.All]._knobMap[message.data1] = level; if (knobDelegate != null) { knobDelegate((MidiChannel)channelNumber, message.data1, level); } } else if (statusCode == StatusCode.Clock) { // Add the current time to the clock history queue _midiClockHistory.Enqueue(Time.time); // Keep 96 messages in the queue (a bar worth) while (_midiClockHistory.Count > 96) { _midiClockHistory.Dequeue(); // Calculate the tempo by averaging the difference between each time recorded var times = _midiClockHistory.ToArray(); var sum = 0f; for (int i = 1; i < times.Length; i++) { sum += times[i] - times[i - 1]; } SecondsPerBeat = sum / 96; BeatsPerMinute = 60 / (SecondsPerBeat * 24); } } #if UNITY_EDITOR // If it's not a clock, record the message. if (statusCode != StatusCode.Clock) { _totalMessageCount++; _messageHistory.Enqueue(message); } #endif } #if UNITY_EDITOR // Truncate the history. while (_messageHistory.Count > 8) { _messageHistory.Dequeue(); } #endif }