Skip to content

Commit

Permalink
MIDI Bridge update and some refactorings.
Browse files Browse the repository at this point in the history
- Update MIDI Bridge (both bridge software and C# interface).
- Added MidiChannel enum (to avoid use int number to represent channel numbers).
- Removed MidiMessage.cs. Now MidiMessage is defined in MidiBridge.
  • Loading branch information
Keijiro Takahashi authored and Keijiro Takahashi committed Nov 6, 2013
1 parent abcacec commit 39f6372
Show file tree
Hide file tree
Showing 5 changed files with 242 additions and 134 deletions.
103 changes: 78 additions & 25 deletions MidiBridge.cs
@@ -1,39 +1,83 @@
using UnityEngine;
//
// MidiBridge.cs - C# interface for MIDI Bridge
//
// Copyright (C) 2013 Keijiro Takahashi
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Net;

public class MidiBridge : MonoBehaviour
{
#region Configurations
// Port number used to communicate with Bridge.
const int portNumber = 52364;
#endregion

#region Public interface
public Queue<MidiMessage> incomingMessageQueue;

public void Send (int status, int data1, int data2 = 0xff)
public struct Message
{
public byte status;
public byte data1;
public byte data2;

public Message (byte status, byte data1, byte data2)
{
this.status = status;
this.data1 = data1;
this.data2 = data2;
}

public override string ToString ()
{
return string.Format ("s({0:X2}) d({1:X2},{2:X2})", status, data1, data2);
}
}

public Queue<Message> incomingMessageQueue;

public void Send (int status, int data1 = 0xff, int data2 = 0xff)
{
if (tcpClient != null && tcpClient.Connected) {
smallBuffer [0] = (data2 == 0xff) ? (byte)2 : (byte)3;
smallBuffer [1] = (byte)status;
smallBuffer [2] = (byte)data1;
smallBuffer [3] = (byte)data2;
smallBuffer [0] = (byte)status;
smallBuffer [1] = (byte)data1;
smallBuffer [2] = (byte)data2;
smallBuffer [3] = 0xff;
try {
tcpClient.GetStream ().Write (smallBuffer, 0, 4);
} catch (System.IO.IOException exception) {
Debug.Log (exception);
}
}
}

public void Warmup()
{
// Do nothing!
}

#endregion

#region Monobehaviour functions

void Awake ()
{
incomingMessageQueue = new Queue<MidiMessage> ();
incomingMessageQueue = new Queue<Message> ();
smallBuffer = new byte[4];
}

Expand All @@ -42,9 +86,14 @@ void Start ()
StartCoroutine (ConnectionCoroutine ());
StartCoroutine (ReceiverCoroutine ());
}

#endregion

#region TCP connection

// Port number used to communicate with Bridge.
const int portNumber = 52364;

// TCP connection.
TcpClient tcpClient;
bool isConnecting;
Expand All @@ -56,7 +105,7 @@ void Start ()
IEnumerator ConnectionCoroutine ()
{
// "Active Sense" message for heartbeating.
var heartbeat = new byte[4] {2, 0xff, 0xfe, 0};
var heartbeat = new byte[4] {0xfe, 0xff, 0xff, 0xff};

while (true) {
// Try to open the connection.
Expand Down Expand Up @@ -126,32 +175,36 @@ IEnumerator ReceiverCoroutine ()
var bufferFilled = tcpClient.GetStream ().Read (buffer, 0, available);

for (var offset = 0; offset < bufferFilled; offset += 4) {
var length = buffer [offset];
if (length == 2) {
incomingMessageQueue.Enqueue (new MidiMessage (buffer [offset + 1], buffer [offset + 2]));
} else if (length == 3) {
incomingMessageQueue.Enqueue (new MidiMessage (buffer [offset + 1], buffer [offset + 2], buffer [offset + 3]));
}
incomingMessageQueue.Enqueue (new Message (buffer [offset], buffer [offset + 1], buffer [offset + 2]));
}

yield return null;
}
}

#endregion

#region Singleton class interface
#region Singleton class handling

static MidiBridge _instance;

public static MidiBridge instance {
get {
if (_instance == null) {
var go = new GameObject ();
_instance = go.AddComponent<MidiBridge> ();
DontDestroyOnLoad (go);
go.hideFlags = HideFlags.HideInHierarchy;
var previous = FindObjectOfType (typeof(MidiBridge));
if (previous) {
Debug.LogWarning ("Initialized twice. Don't use MidiBridge in the scene hierarchy.");
_instance = (MidiBridge)previous;
} else {
var go = new GameObject ("__MidiBridge");
_instance = go.AddComponent<MidiBridge> ();
DontDestroyOnLoad (go);
go.hideFlags = HideFlags.HideInHierarchy;
}
}
return _instance;
}
}

#endregion
}

0 comments on commit 39f6372

Please sign in to comment.