Projecte Proj1

De Wikijoan
Dreceres ràpides: navegació, cerca
Proj1.png

Contingut

Introducció

Aquest és un projecte introductori de combinar midishare amb interfície gràfica. La idea és molt simple. Toco una nota amb un controlador midi i m'apareix, a pantalla completa, ben gros i sobre un fons de color, la nota que toco (amb el mscontrol, el vkeybd, o el WX5, per exemple). El següent projecte serà fer el mateix, però amb una nota dibuixada sobre un pentagrama.

Problemes que m'he trobat

Status Byte: primer bit: 1; 3 bits per al missatge; 4 bits per al canal. Per exemple: Note Off és 1000nnnn, Note On és 1001nnnn
En el cas de Note On, el DATA0 és l'altura (0-127, 7 bits restants) i DATA1 és la velocitat (0-127)
A l'aplicació Java, els valors de DATA0 i DATA1 els accedeixo amb Midi.GetData0(ev) i Midi.GetData1(ev). El valor del Status Byte l'accedeixo amb Midi.GetType(ev) i Midi.GetChan(ev).

Codi

La sortida de l'aplicació és:

installed = 1
version = 192
numberOfAppl = 6
MidiShare configureFilter() filter#-531275200
Connected for input? 1
Connected for output? 1
List of MidiShare client applications
-------------------------------------
1 : reference number 0 name : MidiShare
2 : reference number 1 name : msdisplay
3 : reference number 2 name : msconnect
4 : reference number 3 name : mscontrol
5 : reference number 4 name : vkeybd
6 : reference number 5 name : fluidsynth
7 : reference number 6 name : MidiShareInput
-------------------------------------typeKeyOn


Tipus event: 1 (0=typeNote; 1=typeKeyOn; 2=typeKeyOff)
Canal: 0
Data0: 60 (altura en el cas de Note On/Off)
Data1: 127 (velocitat en el cas de Note On/Off)
MidiShareInput, received typeKeyOn


Tipus event: 2 (0=typeNote; 1=typeKeyOn; 2=typeKeyOff)
Canal: 0
Data0: 60 (altura en el cas de Note On/Off)
Data1: 0 (velocitat en el cas de Note On/Off)


Tipus event: 0 (0=typeNote; 1=typeKeyOn; 2=typeKeyOff)
Canal: 0
Data0: 95 (altura en el cas de Note On/Off)
Data1: 127 (velocitat en el cas de Note On/Off)
MidiShareInput, received typeNote
Closing Midi, byebye

Anem a posar el codi. Són dues classes: Proj1 conté el main() i construeix la interfície gràfica. MidiShareInput conté tota la part de MidiShare i s'ha de comunicar amb Proj1 per tal de traduir els events MIDI en accions sobre la pantalla.

Proj1.java

package v4;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.TexturePaint;
import java.awt.Toolkit;
import java.awt.Transparency;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JPanel;


public class Proj1 extends Canvas implements Stage, KeyListener {
	
	private BufferStrategy strategy;
	private SpriteCache spriteCache;	
	private BufferedImage background;
	private MidiShareInput midiHandler;
	
	public Proj1() {
		spriteCache = new SpriteCache();
		
		JFrame ventana = new JFrame("Proj1");
		JPanel panel = (JPanel)ventana.getContentPane();
		setBounds(0,0,Stage.WIDTH,Stage.HEIGHT);
		panel.setPreferredSize(new Dimension(Stage.WIDTH,Stage.HEIGHT));
		panel.setLayout(null);
		panel.add(this);
		ventana.setBounds(0,0,Stage.WIDTH,Stage.HEIGHT);
		ventana.setUndecorated(true); //no volem els botons de les finestres
		ventana.setVisible(true);
		ventana.addWindowListener( new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		ventana.setResizable(false);
		createBufferStrategy(2);
		strategy = getBufferStrategy();
		requestFocus();
		addKeyListener(this);
		setIgnoreRepaint(true);
		
		BufferedImage cursor = spriteCache.createCompatible(10,10,Transparency.BITMASK);
		Toolkit t = Toolkit.getDefaultToolkit();
		//Cursor c = t.createCustomCursor(cursor,new Point(5,5),"null"); //amaguem el cursor
		//setCursor(c);
		
		background = spriteCache.createCompatible(
			Stage.WIDTH,  
			Stage.HEIGHT,
			Transparency.OPAQUE);
	
	}


	public void paintWorld(String vnota) {
		Graphics2D g = (Graphics2D)strategy.getDrawGraphics();

		g.setColor(Color.blue);
		g.fillRect(0,0,background.getWidth(),background.getHeight());

		g.setFont(new Font("Arial",Font.BOLD,400));
		g.setPaint(Color.LIGHT_GRAY);
		g.drawString(vnota,Stage.WIDTH/2-250,Stage.HEIGHT/2+100);
		strategy.show();
	}

	
	public SpriteCache getSpriteCache() {
		return spriteCache;
	}
	
	public void keyPressed(KeyEvent e) {
		switch (e.getKeyCode()) {
			case KeyEvent.VK_Q : midiHandler.finalitzar(); System.exit(0); break; //lletra Q: quit
			case KeyEvent.VK_S :System.out.println(midiHandler.inport);
			
			case KeyEvent.VK_C : paintWorld("C"); midiHandler.playNote(60); break;
			case KeyEvent.VK_D : paintWorld("D"); midiHandler.playNote(62); break;
			case KeyEvent.VK_E : paintWorld("E"); midiHandler.playNote(64); break;
			case KeyEvent.VK_F : paintWorld("F"); midiHandler.playNote(65); break;
			case KeyEvent.VK_G : paintWorld("G"); midiHandler.playNote(67); break;	
			case KeyEvent.VK_A : paintWorld("A"); midiHandler.playNote(69); break;
			case KeyEvent.VK_B : paintWorld("B"); midiHandler.playNote(71); break;
		}
	}
	
	public void keyReleased(KeyEvent e) {}
	public void keyTyped(KeyEvent e) {}
	
	public void game() {

		paintWorld("");
		midiHandler = new MidiShareInput(this);
	}
	

	public static void main(String[] args) {
		Proj1 inv = new Proj1();
		inv.game();
	}
}

MidiShareInput.java

package v4;

import java.awt.*;
import java.awt.event.*;


import grame.midishare.*;

public class MidiShareInput extends MidiAppl {

    int inport;
    int outport;
    protected Proj1 proj1;
    

	
    public MidiShareInput(Proj1 proj1) {
    	this.proj1 = proj1;
    	// set these how you want them
        inport=0;
        outport=1;
        int installed = 0;
        try {
            installed = Midi.Share();
        }
        catch (UnsatisfiedLinkError e) {
            e.printStackTrace();
            System.out.println(
                "\nMidiShare Java API probably not installed properly, grame.midishare.Midi.Share() barfed.\n" + e);
            System.exit(0);
        }

        System.out.println("installed = " + installed);
        int version = Midi.GetVersion();
        System.out.println("version = " + version);
        int numberOfAppl = Midi.CountAppls();
        System.out.println("numberOfAppl = " + numberOfAppl);

        
        try {
        	this.Open("MidiShareInput");
            Midi.Connect(this.refnum, 0, 1);
            Midi.Connect(0, this.refnum, 1);
            // Check output connection
            int connected = Midi.IsConnected(this.refnum, 0);
            System.out.println("Connected for input? " + connected);

            // Check input connection
            connected = Midi.IsConnected(0, this.refnum);
            System.out.println("Connected for output? " + connected);

            //em connecto a fluidsynth
            int ref_fluidsynth;
            if ((ref_fluidsynth = Midi.GetNamedAppl("fluidsynth")) > 0) Midi.Connect (this.refnum,ref_fluidsynth, 1);
            //em connecto al mscontrol
            int ref_mscontrol;
            if ((ref_mscontrol = Midi.GetNamedAppl("mscontrol")) > 0) Midi.Connect (ref_mscontrol,this.refnum, 1);
            //em connecto al vkeybd
            int ref_vkeybd;
            if ((ref_vkeybd = Midi.GetNamedAppl("vkeybd")) > 0) Midi.Connect (ref_vkeybd,this.refnum, 1);
            
            StringBuffer text = new StringBuffer();

            short i;
            int ref, n = Midi.CountAppls();
            text.append("List of MidiShare client applications\n");
            text.append("-------------------------------------\n");
            for (i = 1; i <= n; i++) {
                ref = Midi.GetIndAppl(i); // get the refnum from the order number
                text.append(String.valueOf(i));
                text.append(" : reference number ");
                text.append(String.valueOf(ref));
                text.append(" name : ");
                text.append(Midi.GetName(ref));
                text.append("\n");
            }
            text.append("-------------------------------------");
            System.out.println(text.toString());
        }
        catch (MidiException e1) {
            System.out.println("Error opening MidiShareInput: " + e1);
            e1.printStackTrace();
        }
   	
    }

    public void Open(String name) throws MidiException {
        super.Open(name);
        configureFilter();
    }

    /* kill active sensing */
    void configureFilter() {
        int i;
        for (i = 0; i < 256; i++) {
            //Midi.AcceptPort(filter, i, 1);
            Midi.AcceptPort(filter, i, 0);
            Midi.AcceptType(filter, i, 1);
        }

        for (i = 0; i < 16; i++) {
            Midi.AcceptChan(filter, i, 1);
        }
        Midi.AcceptPort(filter, inport, 1);
        Midi.AcceptType(filter, Midi.typeActiveSens, 0);
        //    Midi.AcceptType(filter, Midi.typeSysEx, 0);
        System.out.println("MidiShare configureFilter() filter#" + filter);
    }

    /** Simply notify that an input event occurred, print what kind */
    public void ReceiveAlarm(int ev) {

    	System.out.println("\n");
    	System.out.println("Tipus event: " + Midi.GetType(ev) + " (0=typeNote; 1=typeKeyOn; 2=typeKeyOff)");
    	System.out.println("Canal: " + Midi.GetChan(ev));
    	System.out.println("Data0: " + Midi.GetData0(ev) + " (altura en el cas de Note On/Off)");
    	System.out.println("Data1: " + Midi.GetData1(ev) + " (velocitat en el cas de Note On/Off)");
  
    
        switch (Midi.GetType(ev)) {
            case Midi.typeNote :
                System.out.println("MidiShareInput, received typeNote");
                proj1.paintWorld(String.valueOf(Midi.GetData0(ev)));
                break;
            case Midi.typeKeyOn :
                System.out.println("MidiShareInput, received typeKeyOn");
                proj1.paintWorld(String.valueOf(Midi.GetData0(ev)));
                break;
            case Midi.typeKeyOff :
                proj1.paintWorld(String.valueOf(Midi.GetData0(ev)));
                break;
            case Midi.typeKeyPress :
                System.out.println("MidiShareInput, received typeKeyPress");
                break;
            case Midi.typeCtrlChange :
                System.out.println("MidiShareInput, typeCtrlChange");
                break;
            case Midi.typeProgChange :
                System.out.println("MidiShareInput, received typeProgChange");
                break;
            case Midi.typeChanPress :
                System.out.println("MidiShareInput, received typeChanPress");
                break;
            case Midi.typePitchWheel :
                System.out.println("MidiShareInput, received typePitchWheel");
                break;
            case Midi.typeSysEx :
                System.out.println("MidiShareInput, received typeSysEx");
                break;
            default :
                break;
        }
        Midi.SendIm(this.refnum, ev);
    }

    void playNote(int pitch) {
        int channel = 1;
        int vel = 80;

        int event = Midi.NewEv(Midi.typeKeyOn); // ask for a new note event
        if (event != 0) { // if the allocation was succesfull
        	Midi.SetChan(event, channel); // set the Midi channel
            Midi.SetPort(event, outport); // set the destination port
            Midi.SetField(event, 0, pitch); // set the pitch field
            Midi.SetField(event, 1, vel); // set the velocity field
            Midi.SendIm(refnum, event);
        }
        System.out.println("Sent Midi note on " + (pitch));
        try {
            Thread.sleep(200);
        }
        	catch (InterruptedException e) {
        }

        event = Midi.NewEv(Midi.typeKeyOff);

        if (event != 0) {
            Midi.SetChan(event, channel);
            Midi.SetPort(event, outport);
            Midi.SetField(event, 0, pitch);
            Midi.SetField(event, 1, vel);
            Midi.SendIm(refnum, event);
        }
        System.out.println("Sent Midi note off " + (pitch));
        try {
            Thread.sleep(200);
        }
        catch (InterruptedException e) {
        }

    }
  

    public void finalitzar() {
        this.Close();
        System.out.println("Closing Midi, byebye"); 
    }

}
Eines de l'usuari
Espais de noms
Variants
Accions
Navegació
Institut Jaume Balmes
Màquines recreatives
CNC
Informàtica musical
joanillo.org Planet
Eines