User Tools

Site Tools


notes:sysnet:spring2011

Orca

Orca is a project, that was started to make a program that would allow for a person to be a composer to a room full of computers (ie. a orchestra of computers).

Instead of people playing instruments the computers will be playing them in a set up like a orchestra. What we set out to do, is to have a composer station where the user can tell the computers what to play and then have the computers play there instruments. For this there are several thing that need to have happen. We would need all the computers to talk to the composer computer, this will requirer the use of networking (ie. Server/Client). Then we want the computers to play music in a formate that will let us play different instruments from the music on different stations. Midi was picked for it ability to do just that. Then we picked a language that would let use drop the program on all most any computer (ie. Java C++ Python). Java was picked for its ablates to network and use midi and have a user interface all in one. So after all that the program will play like you have your own privet orchestra.

ORCA is a telecommunication of intstruments that require input and output networking between servers and clients.

This is a diagram of Orca.

diagram.txt
                                              Orca
                                               |
                                               |
                                               V
Client<--------------------Networking<--------Java---------------------->Midi
(Connect-Input Stream)         |               |                          |
Socket Ports                   |               |                          |
                               V               |                          V
                            Server             |                       File Format
                   (Listen-Output Stream)      |                      (Structure of midi)
                       Working Example         |
                                               |
                                               V
                                           Programming JDK
                                               |
                                               |
                                               |
                                               V
                                             Sources
                                          (Documentation)

Networking

*Server -socket input stream

  1. listen for connection

*Client -socket output stream

  1. use port to connect to server

Midi -fileformat A 4-byte chunk type (ascii) A 4-byte length (32 bits, msb first) length bytes of data

-psudocode

MidiSynth

MidiSynth()

open()

close()

createShortEvent()

Key - extends Rectangle

Key()

isNoteOn()

on()

off()

setNoteState()

Piano - extends JPanel - implements MouseListener

Piano()

mousePressed()

mouseReleased()

mouseExited()

mouseClicked()

mouseEntered()

getKey()

paint()

ChannelData

ChannelData()

setComponentStates()

InstrumentsTable - extends JPanel

InstrumentsTable()

getColumnName()

getColumnClass()

isCellEditable()

setValueAt()

valueChanged()

getPreferredSize()

getMaximumSize()

programChange()

Controls - extends JPanel - implements ActionListener, ChangeListener, ItemListener

Controls()

createButton()

createCheckBox()

createSlider()

create14BitSlider()

stateChanged()

itemStateChanged()

actionPerformed()

RecordFrame - extends JFrame - implements Actionlistner, MetaEventListener

RecordFrame()

getColumnCount()

getRowCount()

getValueAt()

getColumnName()

getColumnClass()

isCellEditable()

setValueAt()

createButton()

actionPerformed()

acceptFile()

getDescription()

meta()

saveMidiFile()

TrackData TrackData()

end

-octave notes

-working examples

variable length conversion

81 00 (hex). ← example

10000001 00000000 ← in binary

1 0000001 0 0000000 ← septerate flag value

0000001 0000000 ← count 7 bits for both varaibles

00000010000000 ← merge so 14 bits

0000 0000 1000 0000 ← add two zero to make group of four values

80hex = 8 * 16 + 0 * 0 = 8 * 16 + 0 = 128 decimal

0x00000080 0x81 0x00 ← acual value

Java -programming

-doumentation

-tutorials

-sources

-examples


Server/Client

  • socket programming
    • IP/DNS, listen(), accept(), bind(), connect()
  • relationship, roles, connection
  • conductor/instruments

Java

  • other languages
  • JDK

Midi

  • standards
  • file structure

Pseudo Code

START
  string head = read(4)
  if head == MThd; then
    len = read(4)
    byte headData[] = read(len)
    if len == 6; then
      int format = headData[0-1]
      int ntrks = headData[2-3]
      int division = headData[4-5]
    else
      print "Error"
    endif
  else
    print "Error"
  endif	
  if format == 0; then
    if ntrks == 1; then
      string chunkType = read(4)
      if chunkType == MTrk; then
        len = read(4)
        byte mTrackEvents[] = read(len)
      else
        print "File is Corrupted."
      endif
      int i = 0
      byte byte[i] = read(1)
      while (byte && 0x80) == 0x80; do
        i++
        byte[i] = read(1)
      done
      for j = 0 to 3; do
        int[j] = byte[j]
        int[j] = shiftleft(int[j], jx7)
      done
      int dec = int[0] || int[1] || int[2] || int[3]
    else
      print "Too many tracks for type 0 file"
    endif
  else
    if format == 1; then
    else 
      if format == 2; then
      else
        print "File is Corrupted."
      endif
    endif
  endif
END


Working Examples

client/server

Python Client/Server

by John Rine

Early in the semester, the class was challanged to find some example code to perform socket communications. I volunteered to find Python examples. The client/server code listed below is from a tutorial. The tutorial is located at: http://heather.cs.ucdavis.edu/nmahoff/python/pynet.pdf .
Example Python TCP client code.

client.py
# simple illustration client/server pair; client program sends a string
# to server, which echoes it back to the client (in multiple copies),
# and the latter prints to the screen
 
# this is the client
 
import socket
import sys
 
# create a socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 
# connect to server
host = sys.argv[1] # server address
port = int(sys.argv[2]) # server port
s.connect((host, port))
 
s.send(sys.argv[3]) # send test string
 
# read echo
i = 0
while(1):
    data = s.recv(1000000) # read up to 1000000 bytes
    i += 1
    if (i < 5): # look only at the first part of the message
        print data
    if not data: # if end of data, leave loop
        break
    print 'received', len(data), 'bytes'
 
# close the connection
s.close()


Example Python TCP client code.

server.py
# simple illustration client/server pair; client program sends a string
# to server, which echoes it back to the client (in multiple copies),
# and the latter prints to the screen
# this is the server
import socket
import sys
# create a socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# associate the socket with a port
host = '' # can leave this blank on the server side
port = int(sys.argv[1])
s.bind((host, port))
# accept "call" from client
s.listen(1)
conn, addr = s.accept()
print 'client is at', addr
# read string from client (assumed here to be so short that one call to
# recv() is enough), and make multiple copies (to show the need for the
# "while" loop on the client side)
data = conn.recv(1000000)
data = 10000 * data # concatenate data with itself 999 times
# wait for the go-ahead signal from the keyboard (to demonstrate that
# recv() at the client will block until server sends)
z = raw_input()
# now send
conn.send(data)
# close the connection
conn.close()


Server execution

C:\Python27>python tms.py 2000
client is at ('127.0.0.1', 52539)

Client execution

C:\Python27>python tmc.py localhost 2000 abc


Java Client/Server Plays Notes Across a Network

Java TCP Client

TCPClient.java
//Author John T. Rine
 
import java.io.*;
import java.net.*;
class TCPClient
{
	public static void main(String argv[]) throws Exception
	{
		String sentence;
		String modifiedSentence;
		while(true)
		{
			BufferedReader inFromUser = new BufferedReader( new InputStreamReader(System.in));
			Socket clientSocket = new Socket("localhost", 4000); //new Socket("localhost", 4000);
			DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
			BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
			sentence = inFromUser.readLine();
			outToServer.writeBytes(sentence + '\n');
			modifiedSentence = inFromServer.readLine();
			System.out.println("FROM SERVER: " + modifiedSentence);
		}
  //clientSocket.close();
	}
} 


Java server code

TCPServerTwo.java
//Author John Rine
import java.io.*;
import java.net.*;
import javax.sound.midi.*;
 
class TCPServerTwo
{
	public static void main(String argv[]) throws Exception
 	{
		String clientSentence = "go";
		String capitalizedSentence;
		ServerSocket welcomeSocket = new ServerSocket(4000); //new ServerSocket(6789);
 
		while(!clientSentence.equals("stop"))
		{
			Socket connectionSocket = welcomeSocket.accept();
			BufferedReader inFromClient =
			new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
			DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
			clientSentence = inFromClient.readLine();
			System.out.println("Received: " + clientSentence);
			capitalizedSentence = clientSentence.toUpperCase() + '\n';
			outToClient.writeBytes(capitalizedSentence);
			if (clientSentence.equals("play"))
			{
				try
				{
					Receiver rec = MidiSystem.getReceiver();
					ShortMessage mmess = new ShortMessage();
					mmess.setMessage(144, 0, 60, 93);
					rec.send(mmess, -1);
					Thread.sleep(1000);
				}
				catch(Exception e)
				{
					e.printStackTrace();		
				}
 
			}
        	}
//	synth.close();
	welcomeSocket.close();	
 	}
} 


Java client execution.

C:\Users\John\Desktop\Spring 2011 School\CSIT 2320\Play a note across the networ
k>REM java MyFirstApp

C:\Users\John\Desktop\Spring 2011 School\CSIT 2320\Play a note across the networ
k>SET /P M=What program to run?
What program to run?TCPClient

C:\Users\John\Desktop\Spring 2011 School\CSIT 2320\Play a note across the networ
k>java TCPClient
play
FROM SERVER: PLAY
play
FROM SERVER: PLAY


  • midi messages (notes)
  • sound, playing notes

This is an example of playing a single note by sending a MIDI message to a MIDI receiver.

simpleMidiNote.java
//Author: John T. Rine
//04-10-2011
 
import javax.sound.midi.*;
public class simpleMidiNote
{
 
	public static void main (String args[]) throws Exception
	{
		//http://download.oracle.com/javase/tutorial/sound/MIDI-messages.html
		ShortMessage myMsg = new ShortMessage();
  		// Start playing the note Middle C (60), 
  		// moderately loud (velocity = 93).
 		myMsg.setMessage(ShortMessage.NOTE_ON, 0, 60, 93);
		long timeStamp = -1;
		Receiver rcvr = MidiSystem.getReceiver();
  		rcvr.send(myMsg, timeStamp);
 
		//http://download.oracle.com/javase/tutorial/essential/concurrency/sleep.html
		//Pause for 4 seconds
            	Thread.sleep(4000);
 
	}
}
File Parsing


Reading the MIDI file header

by John Rine

Listed below is the code to read and display the header of a midi format file. The code is written in “long hand” (no methods) as it is in development. The data conversion sections could be placed into methods to make tthe code more compact. Remember, it is still under development, but it works.

orca_Protocol.java
//Author: John T. Rine
//05-02-2011
import java.io.*;
 
public class orca_Protocol
{
	public static void main(String[] args) throws IOException
	{
		FileInputStream in = null;
		try
		{
			System.out.print("Enter filename: ");
			BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
			String fileName = null;
			fileName = br.readLine();
			in = new FileInputStream(fileName);
			int c;
			StringBuffer strContent = new StringBuffer();
			int count = 0;
			while (count != 4)
			{
				c = in.read();
				strContent.append((char)c);
				count++;
			}
			System.out.println(strContent);
			String temp = strContent.toString();
			if(temp.equals("MThd")) System.out.println("Midi Header");
			long dummy = 0;
			c = 0;
			int shift = 0;
			long result = 0;
			for (int i = 0; i != 4; i++)
			{
				c = in.read();
				dummy = 0;
				dummy = (long) c;
				switch(i)
				{
					case 0:
						shift = 24;
						break;
					case 1:
						shift = 16;
						break;
					case 2:
						shift = 8;
						break;
					case 3:
						shift = 0;
						break;
				}
				dummy = dummy << shift;
				result = result | dummy;
			}
			System.out.println("Header Length = " + result);
			c = 0;
			shift = 0;
			int resultt = 0;
			for (int i = 0; i != 2; i++)
			{
				c = in.read();
				switch(i)
				{
					case 0:
						shift = 8;
						break;
					case 1:
						shift = 0;
						break;
				}
				c = c << shift;
				resultt = resultt | c;
			}
			String fileType;
			switch(c)
			{
				case 0:
					fileType = "single track file format";
					break;
				case 1:
					fileType = "multiple track file format";
					break;
				case 2:
					fileType = "multiple song file format (i.e., a series of type 0 files)"; 
					break;
				default:
					fileType = "Error";
 
			}
			System.out.println("Midi File Type = " + c + " " + "File Type: " + fileType);
			c = 0;
			shift = 0;
			resultt = 0;
			for (int i = 0; i != 2; i++)
			{
				c = in.read();
				switch(i)
				{
					case 0:
						shift = 8;
						break;
					case 1:
						shift = 0;
						break;
				}
				c = c << shift;
				resultt = resultt | c;
			}
			System.out.println("Number of track chunks that follow the header chunk  = " + c);
			c = 0;
			shift = 0;
			resultt = 0;
			for (int i = 0; i != 2; i++)
			{
				c = in.read();
				switch(i)
				{
					case 0:
						shift = 8;
						break;
					case 1:
						shift = 0;
						break;
				}
				c = c << shift;
				resultt = resultt | c;
			}
			System.out.println("Division  = " + c);
			System.out.println("Unit of time for delta timing.");
			System.out.println("If the value is positive, then it represents the units per beat.");
			System.out.println("For example, +96 would mean 96 ticks per beat.");
			System.out.println("If the value is negative, delta times are in SMPTE compatible units."); 
		}
		finally
		{
			if (in != null)
			{
				in.close();
			}
		}
	}
 
}


Execution of the MIDI file reading application. At present, it can only read and display MIDI header data.

C:\Users\John\Desktop\Spring 2011 School\CSIT 2320\Assignment_Due_05-02-2011>REM
 java MyFirstApp

C:\Users\John\Desktop\Spring 2011 School\CSIT 2320\Assignment_Due_05-02-2011>SET
 /P M=What program to run?
What program to run?orca_Protocol

C:\Users\John\Desktop\Spring 2011 School\CSIT 2320\Assignment_Due_05-02-2011>jav
a orca_Protocol
Enter filename: the_white_stripes-icky_thump.mid
MThd
Midi Header
Header Length = 6
Midi File Type = 1 File Type: multiple track file format
Number of track chunks that follow the header chunk  = 4
Division  = 224
Unit of time for delta timing.
If the value is positive, then it represents the units per beat.
For example, +96 would mean 96 ticks per beat.
If the value is negative, delta times are in SMPTE compatible units.

C:\Users\John\Desktop\Spring 2011 School\CSIT 2320\Assignment_Due_05-02-2011>pau
se
Press any key to continue . . .

User Interface


Score


Documentation

  • Java
    • java doc, API
    • tutorials
  • Midi

Pitchers


In Progress

Orca_Protocol.java
//Author: John T. Rine
//05-02-2011
//Edited by Matthew Taft
//05-20-2011
//Broke header and length reading routines into functions, added ability to read the first track into a byte array
//To Be Done: Create a class within Orca_Protocol to store tracks as arrays and make an array of them size of the number of tracks
//Ex:
//class trackArray {
//byte track[];
//}
//trackArray totTracks[len]
//for i=0;i<len;i++ {
//totTracks[i] = new trackArray();
 
import java.io.*;
 
public class Orca_Protocol {
	FileInputStream in = null;
	BufferedReader br;
	String fileName;
	StringBuffer strContent;
	long dummy, result;
	int c, count, shift;
	int format, ntrks, division, len;
	byte track[];
 
	public static void main(String[] args) throws IOException {
		Orca_Protocol test = new Orca_Protocol();
		try {
			System.out.print("Enter filename: ");
			BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
			test.fileName = br.readLine();
			test.in = new FileInputStream(test.fileName);
			test.readHeader(test.in);
			test.len = test.lenRead(test.in);
			test.c = 0;
			test.shift = 0;
			int resultt = 0;
			for (int i = 0; i != 2; i++)
			{
				test.c = test.in.read();
				switch(i)
				{
					case 0:
						test.shift = 8;
						break;
					case 1:
						test.shift = 0;
						break;
				}
				test.format = test.c << test.shift;
				resultt = resultt | test.c;
			}
			String fileType;
			switch(test.format)
			{
				case 0:
					fileType = "single track file format";
					break;
				case 1:
					fileType = "multiple track file format";
					break;
				case 2:
					fileType = "multiple song file format (i.e., a series of type 0 files)"; 
					break;
				default:
					fileType = "Error";
 
			}
			System.out.println("Midi File Type = " + test.format + " " + "File Type: " + fileType);
			test.c = 0;
			test.shift = 0;
			resultt = 0;
			for (int i = 0; i != 2; i++)
			{
				test.c = test.in.read();
				switch(i)
				{
					case 0:
						test.shift = 8;
						break;
					case 1:
						test.shift = 0;
						break;
				}
				test.ntrks = test.c << test.shift;
				resultt = resultt | test.c;
			}
			System.out.println("Number of track chunks that follow the header chunk  = " + test.ntrks);
			test.c = 0;
			test.shift = 0;
			resultt = 0;
			for (int i = 0; i != 2; i++)
			{
				test.c = test.in.read();
				switch(i)
				{
					case 0:
						test.shift = 8;
						break;
					case 1:
						test.shift = 0;
						break;
				}
				test.division = test.c << test.shift;
				resultt = resultt | test.c;
			}
			test.readHeader(test.in);
			test.len = test.lenRead(test.in);
			test.track = new byte[test.len];
			test.in.read(test.track, 0, test.len);
			System.out.println("Track 1: " + test.track);
			System.out.println("Division  = " + test.division);
			System.out.println("Unit of time for delta timing.");
			System.out.println("If the value is positive, then it represents the units per beat.");
			System.out.println("For example, +96 would mean 96 ticks per beat.");
			System.out.println("If the value is negative, delta times are in SMPTE compatible units."); 
		}
		finally
		{
			if (test.in != null)
			{
				test.in.close();
			}
		}
	}
 
	void readHeader(FileInputStream in) throws IOException {	
//readHeader() takes an argument of the score file opened and checks to see if the header portion read is a midi header
//or a midi track. This function could be changed to return a state on if the encountered string was MThd, MTrk or neither.
//It should be called immediately upon opening the file, and again after the chunk has been completely read in.
		int c;
		StringBuffer strContent = new StringBuffer();
		int count = 0;
		while (count != 4) {
			c = in.read();
			strContent.append((char)c);
			count++;
		}
		System.out.println(strContent);
		String temp = strContent.toString();
		if(temp.equals("MThd")) 
			System.out.println("Midi Header");
		if(temp.equals("MTrk"))
			System.out.println("Midi Track");
	}
 
	int lenRead(FileInputStream in) throws IOException {
//This function takes an argument of the score file opened and returns the length of the 
//header. This function should be called immediately after reading the first 4 bytes of the file 
//or any bytes containing the chunk headers.
			this.dummy = 0;
			this.c = 0;
			this.shift = 0;
			this.result = 0;
			for (int i = 0; i != 4; i++)
			{
				this.c = in.read();
				this.dummy = 0;
				this.dummy = (long) this.c;
				switch(i)
				{
					case 0:
						this.shift = 24;
						break;
					case 1:
						this.shift = 16;
						break;
					case 2:
						this.shift = 8;
						break;
					case 3:
						this.shift = 0;
						break;
				}
				this.dummy = this.dummy << this.shift;
				this.result = this.result | this.dummy;
			}
			System.out.println("Header Length = " + this.result);
			return((int)this.result);
	}
}
notes/sysnet/spring2011.txt · Last modified: 2011/05/20 14:04 by mtaft4