MidiShare: codi llenguatge Java

De wikijoan
Salta a la navegació Salta a la cerca

Nota: aquest document s'ha d'actualitzar per tal de fer sonar els exemples amb la targeta de so Edirol UA-25EX

Nota: aquest és un document de treball, la qual cosa vol dir que segueix el fil d'una investigació, que a vegades porta a resultats incorrectes o innecessaris, fins que finalment surten els èxits (o no). Bàsicament aquest document representa els primers intents de programar amb Java la llibreria MidiShare, que per fi tinc instal.lada, i fer sonar en la targeta de so.

Compilació i execució de projectes Java amb midishare. Shared library JMusic

Ja tinc instal.lat el midishare al Ubuntu Studio (tant el kernel com la llibreria), i ara he de començar a fer coses en Java:

~/midishare/lang/java/samples/tutorial$

Dins de /usr/local/bin hi ha binaris i utilitats:

  • /usr/local/bin/mscontrol -> no se sent res
  • /usr/local/bin/msecho -> no se sent res

/home/joan/midishare/lang/java/samples/tutorial/README.txt

Anem a executar el TutorialPart1.java i TutorialPart2.java (que el tenim funcionant i sonant en Windows)

$ cd midishare/lang/java/samples/tutorial
$ javac TutorialPart1.java
TutorialPart1.java:28: package grame.midishare does not exist
import grame.midishare.*;

Faig un exemple bàsic, amb la idea d'aconseguir que no falli la línia import grame.midishare.*;

import java.awt.*;
import java.util.*;
import java.applet.Applet;
import java.awt.event.*;
import java.applet.*;
import grame.midishare.*;

public class TutorialPart1b extends Applet 
 {
	public static void main(String args[])
	{
		System.out.println("HOLA ");
	}
}
$ javac -classpath /home/joan/midishare/lang/java/native TutorialPart1.java

ara ja funciona. És a dir, he de ficar en el classpath la llibreria de Java: /home/joan/midishare/lang/java/native aquesta és la llibreria bàsica. La llibreria /home/joan/midishare/lang/java/jni és dependent de l'arquitectura.

si vull configurar el CLASSPATH faig:

export CLASSPATH="/home/joan/midishare/lang/java/native:$CLASSPATH"

i aleshores funciona:

$ javac TutorialPart1b.java

però això només val per a la sessió actual.

Si vull que els canvis siguin permanents he de ficar la mateixa línia a baix de tot del fitxer ~/.bashrc

$ javac TutorialPart1.java

-> compila bé amb 20 warnings degut que troba el caràcter '@' amb un codi ASCII incorrecte

$ java TutorialPart1

arrenca bé l'applet, però tanmateix informa que MidiShare no està instal.lat -> de fet dóna errors (java.lang.UnsatisfiedLinkError: no JMidi in java.library.path)

 <TEST 1> : Check if MidiShare is installed : calling the Midi.Share() function is REQUIRED to properly load the JMidi native library
MidiShare installed : 0
1 means that MidiShare is installed
0 means that MidiShare is not installed

faig reload del servei de MidiShare (estava engegat, però el mateix)

Ho provo amb els aplicatius de C (que funcionaven), a veure què passa:

$ /home/joan/midishare/src/linux/applications/samples/msTutorial

 <TEST 1 : Check if MidiShare is installed> 
--> use g or G to run the next test
g
MidiShare installed  : YES -> en realitat és NO


Hem de depurar l'error

java.lang.UnsatisfiedLinkError: no JMidi in java.library.path

MidiShare installed : 0

-> no és que dongui 0, el problema està en que dóna un error i és per això que surt el 0.

falla la línia

text.appendText(String.valueOf(Midi.Share()));

si utilitzés el Eclipse em donaria una pista, doncs al ficar Midi. veuria si puc accedir als mètodes de la classe

$ javac AppletFrame.java
$ javac TutorialPart1b.java
$ java  TutorialPart1b

$ javac -classpath /home/joan/midishare/lang/java/native TutorialPart1b.java -> compila bé
$ java -classpath /home/joan/midishare/lang/java/samples/tutorial TutorialPart1b

-> s'executa i hi ha excepció, però ara l'error ja és diferent

Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: grame/midishare/Midi
        at TutorialPart1b.test1(TutorialPart1b.java:59)

aquest error dóna a la instrucció Midi.Share(). Sembla que això no funciona en la nova versió que he instal.lat de del CVS (dev)

Importació de la llibreria import grame.midishare.*; a Eclipse:

Project -> Properties -> pestanya libraries -> Java Build Path -> Add Class Folder 
create new Folder
	Folder Name: Native
	Advanced: Link to folder in the filesystem (/home/joan/midishare/lang/java/native)
OK

i el resultat és que sobre la línia import grame.midishare.* no dóna una advertència d'error

funciona bé la importació de la llibreria, doncs la línia:

System.out.println(String.valueOf(Midi.typeTempo));

funciona bé, però en canvi la línia que ens interessa per saber si MidiShare està instal.lat no funciona:

System.out.println(String.valueOf(Midi.Share()));

dóna l'error:

Exception in thread "main" java.lang.NoClassDefFoundError: native/grame/midishare/Midi

i a més el mètode Share() no apareix de color blau.

Concretament, fico Midi i apreto '.s'. les possibilitats contextuals que m'apareixen i que comencen per 'S' són vàries.

La diferència de les icones és que les primeres són constants, mentre que Share() i SetSyncMode. El color tampoc vol dir res: les constants són en blau i els mètodes en negre.

Les dues últimes (Share() i SetSyncMode) no funcionen, tenen una icona una mica diferent, i quan les escric no estan en blau i donen l'error

java.lang.NoClassDefFoundError

Les primeres (de SongPos a SysRealTime) funcionen (fixar-se amb la icona). són mètodes.

miro el fitxer Midi.java (la mare dels ous):

	public static final int typeTempo			= 144; -> funciona, és una constant


	public  static native final int SetSyncMode(int mode);
	
	/**
  	Test if MidiShare is available on the Machine. The function actually tries to load the JMidi native library
  	and return a result according to the loading process result. 
  	Applications *must* call this function first, otherwise next calls to the MidiShare API will fail.
             
    *@return The result is true (= 1) if MidiShare is available, false (= 0) otherwise.
    */
	
	public static final int Share()
	{
		if (interfaceLoaded){
			return 1;
		}else{
			try {
			  	System.loadLibrary("JMidi");
				interfaceLoaded = true;
				return 1;
	      	} catch (UnsatisfiedLinkError e) {
				e.printStackTrace();
				return 0;
		  	}
		}	
	 }	


 java.lang.NoClassDefFoundError: native/grame/midishare/Midi means that your classpath is not set correctly. Make sure your JAVA_HOME is set up right before you run the tomcat or startup scripts. If that doesn't do it, see these FAQs:


proves:

//export CLASSPATH=""
//export CLASSPATH="/home/joan/midishare/lang/java/native"
//export CLASSPATH="/home/joan/midishare/lang/java/native:$CLASSPATH"
export CLASSPATH="/home/joan/midishare/lang/java/native/"
//export CLASSPATH="/home/joan/midishare/lang/java/native:"

faig diferents proves modificant el CLASSPATH i res de res. El CLASSPATH ha d'estar bé

Una de les possibles solucions és que disposo del Midi.java i del Midi.class, però hauria de saber compilar el Midi.class i tota la llibreria per tal de fer proves. A lo millor no es correspon el Midi.java amb el Midi.class actuals.


Vull compilar les llibreries de MidiShare manualment:

export CLASSPATH="/home/joan/midishare/lang/java/native/"
cd /home/joan/midishare/lang/java/native/grame/midishare
javac Midi.java

-> i funciona!! si faig ls -la *.class veig com s'actualitza la classe. És més, quan he fet el projecte de l'Eclipse, es compilaven totes les classes. Ho torno a fer:

workspace: /home/joan/workspace6

com a source agafo tot el que penja de /native

faig 'Run' i falla (Exception in thread "main" java.lang.NoClassDefFoundError: ), perquè de fet no tinc cap mètode main, però si faig

ls -la *.class

veig com s'han compilat totes les classes. (no, no és veritat. abans no sé com he aconseguit compilar amb el Eclipse tot el projecte, però ara no)

no hi ha manera.

compilaré totes les classes manualment:

$ javac Midi.java
$ javac DriverInfos.java
$ javac MidiException.java
$ javac MidiNativeAppl.java
$ javac ReadEvInfo.java
$ javac SmpteLoc.java
$ javac WriteEvInfo.java
$ javac MidiAppl.java
$ javac MidiTask.java
$ javac SlotInfos.java
$ javac SyncInfo.java

-> compilen tots molt bé, i els únics warnings són deguts als caràcters no-estàndar

ls -la *.class

-> ara sí, totes les classes estan actualitzades.

Nota posterior (abril 2009): no cal tornar a fer la compilació. En el procés d'instal.lació de midishare ja s'han compilat les classes. Els .class porten la data del dia de la compilació.

Ara torno a compilar el TutorialPart1c, i torna a fallar en la línia

Midi.Share()

i ara l'error és:

Exception in thread "main" java.lang.NoClassDefFoundError: native/grame/midishare/Midi
	at TutorialPart1c.main(TutorialPart1c.java:19)

faig un canvi a la llibreria Midi.java (typeKeyOn), compilo per veure que s'ha enterat del canvi, i ho torno a deixar com està.

Ara l'error ja és diferent (!):

java.lang.UnsatisfiedLinkError: no JMidi in java.library.path
	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1682)
	at java.lang.Runtime.loadLibrary0(Runtime.java:823)
	at java.lang.System.loadLibrary(System.java:1030)
	at grame.midishare.Midi.Share(Midi.java:1218)0

-> ara el problema està en aquesta línia (era necessari compilar les fonts!). La línia 1218

 public static final int Share()
        {
                if (interfaceLoaded){
                        return 1;
                }else{
                        try {
                                System.loadLibrary("JMidi"); -> no JMidi in java.library.path (no troba aquesta llibreria)
                                interfaceLoaded = true;
                                return 1;
                } catch (UnsatisfiedLinkError e) {
                                e.printStackTrace();
                                return 0;
                        }
                }       
         } 


Our natives libraries were placed in the /usr/lib/java directory by the installer and this was working OK on all previous OSX versions

no troba la llibreria System.loadLibrary("JMidi"), potser se li ha de dir on està

export CLASSPATH="/usr/lib/java:$CLASSPATH"

-> no funciona

a dins del directori hi ha les llibreries swt3.2-gtk.jar, swt-gtk.jar, swt.jar, que no crec que tingui res a veure. Per tant, suposo que la llibreria JMusic s'ha d'instal.lar...

In Java it would be using either the Jmidi or Jmusic frameworks which are a group of classes that extend java enabling you to easily write code that manipulates midi or in the case of Jmusic midi and audio.

jmidi package: http://www.softsynth.com/javamidi/doc/Package-jmidi.html

al google no hi ha massa èxit sobre JMidi i sobre la llibreria jmidi.jar

envio un mail a la llista de midishare-devel:

Hello!
I'm trying to setup my midishare installation and compile a little bit of code with Java.
I already compiled grame.midishare library successfully (renewed class files from java sources, necessary, I think)
I started with a simpler version of the known TutorialPart1.java, and the first problem is in Midi.Share() method to test if midishare is installed.
error:
java.lang.UnsatisfiedLinkError: no JMidi in java.library.path
it seems that JMidi library is not installed.
Digging inside the source the line that crash in Midi.java is System.loadLibrary("JMidi") in the Share() method.
I want to install jmidi.jar... I search Google... but few information about that, no chance to download. I search in my whole system looking for jmidi and nothing...

1. Is there any step by step instructions on how to setup a system in midishare-java?
2. Do you think that is better to code in C++ for midishare projects?

In the other hand, in windows exist msdrivers.exe. Which one is the equivalent in Linux. How to define which ports are going to be used? (I want to listen something whit msecho or msconnect, binaries work fine but nothing sounds...)

thanks in advance,
Joan Q

Ja sé com fer-ho directament amb la línia de comanda: (de manera que el resultat amb l'Eclipse i amb la línia de comandes coincideixen)

$ javac TutorialPart1c.java
$ java -classpath /home/joan/midishare/lang/java/native:/home/joan/workspace5/prova_inicial_midishare/  TutorialPart1c


1. What are exactly natives libraries (I'm a almost a beginner in java) ?

Natives libraries contains external code to be use by the JVM. They are
usually developed in C/C++ and can be called from java through the JNI
system.

Intento solucionar el tema del JMidi, suposant que és una llibreria nativa que està dins de JNI. Vaig a jni/linux i hi ha un makefile, que suposo que executant-lo instal.la configura i instal.la les llibreries natives

dins de ~/midishare/lang/java/jni/linux:

$ cat makefile

Si ens fixem en la primera línia, ja tinc la pista de què s'ha de fer...

# SET THE PATHNAME  for ../JDKxx/include HERE

INC2=/home/letz/j2sdk1.3/include
INC3=/home/letz/j2sdk1.3/include/linux

$ make -n
if [ ! -f /home/letz/j2sdk1.3/include/jni.h ]; then echo "You must set up the JDK include pathname in the INC2 variable"; exit 1; fi
if [ ! -f /home/letz/j2sdk1.3/include/linux/jni_md.h ]; then echo "You must set up the JDK include pathname in the INC3 variable"; exit 1; fi
gcc ../src/Midi.c     -I/home/letz/j2sdk1.3/include -I/home/letz/j2sdk1.3/include/linux  -D__Linux__ -D_REENTRANT -fPIC -c  -g -O2 
if [ ! -f /home/letz/j2sdk1.3/include/jni.h ]; then echo "You must set up the JDK include pathname in the INC2 variable"; exit 1; fi
if [ ! -f /home/letz/j2sdk1.3/include/linux/jni_md.h ]; then echo "You must set up the JDK include pathname in the INC3 variable"; exit 1; fi
gcc ../src/MidiAppl.c    -I/home/letz/j2sdk1.3/include -I/home/letz/j2sdk1.3/include/linux  -D__Linux__ -D_REENTRANT -fPIC -c  -g -O2  
gcc Midi.o MidiAppl.o -lMidiShare -shared -fPIC -W1,soname,libJMidi.so.1 -o libJMidi.so.1.0

Vull instal.lar el J2SDK: (jo tenia instal.lat el paquet sun-java6-jdk, veure primers_passos.txt, però això no m'instal.la el J2SDK (!))

Nota posterior (abril 2009): la instal.lació del JAVA està explicada a Instal.lació_Java, que produeix com a resultat la instal.lació a /usr/lib/jvm/java-6-sun, que és el lloc més correcta. Si tinc ben feta la instal.lació, no cal fer tot això que ve a continuació. Entenem per JDK precisament aquest directori.

$ sudo apt-get install java-package

A la pàgina web de Java em descarrego JDK 6 Update 7 (jdk-6u7-linux-i586.bin, 74Mb)

$ fakeroot make-jpkg jdk-6u7-linux-i586.bin

-> el que fa això és construir un paquet debian a partir de les fonts: sun-j2sdk1.6_1.6.0+update7_i386.deb

$ sudo dpkg -i sun-j2sdk1.6_1.6.0+update7_i386.deb
$ sudo update-alternatives --config java -> puc triar entre dues alternatives per al codi de Java

Hay 2 alternativas que proveen java.

  Selección     Alternativa
-----------------------------------------------
          1    /usr/lib/jvm/java-6-sun/jre/bin/java -> aquesta és la màquina virutal
*+        2    /usr/lib/j2sdk1.6-sun/bin/java -> aquest és el SDK (amb el codi font. Escullo aquesta)

$ export JAVA_HOME=/usr

(tot això ho he tret de http://blog.case.edu/jeremy.smith/2006/09/13/ubuntu_first_things)

i ara ja puc modificar el fitxer makefile:

# SET THE PATHNAME  for ../JDKxx/include HERE

#INC2=/home/letz/j2sdk1.3/include
#INC3=/home/letz/j2sdk1.3/include/linux
INC2=/usr/lib/j2sdk1.6-sun/include
INC3=/usr/lib/j2sdk1.6-sun/include/linux

o millor, si faig una instal.lació ben feta de Java:

INC2=/usr/lib/jvm/java-6-sun/include
INC3=/usr/lib/jvm/java-6-sun/include/linux
$ make -n
if [ ! -f /usr/lib/j2sdk1.6-sun/include/jni.h ]; then echo "You must set up the JDK include pathname in the INC2 variable"; exit 1; fi
if [ ! -f /usr/lib/j2sdk1.6-sun/include/linux/jni_md.h ]; then echo "You must set up the JDK include pathname in the INC3 variable"; exit 1; fi
gcc ../src/Midi.c     -I/usr/lib/j2sdk1.6-sun/include -I/usr/lib/j2sdk1.6-sun/include/linux  -D__Linux__ -D_REENTRANT -fPIC -c  -g -O2 
if [ ! -f /usr/lib/j2sdk1.6-sun/include/jni.h ]; then echo "You must set up the JDK include pathname in the INC2 variable"; exit 1; fi
if [ ! -f /usr/lib/j2sdk1.6-sun/include/linux/jni_md.h ]; then echo "You must set up the JDK include pathname in the INC3 variable"; exit 1; fi
gcc ../src/MidiAppl.c    -I/usr/lib/j2sdk1.6-sun/include -I/usr/lib/j2sdk1.6-sun/include/linux  -D__Linux__ -D_REENTRANT -fPIC -c  -g -O2  
gcc Midi.o MidiAppl.o -lMidiShare -shared -fPIC -W1,soname,libJMidi.so.1 -o libJMidi.so.1.0

fixem-nos bé que en la última línia tenim libJMidi.so.1 -o libJMidi.so.1.0 -> és a dir, la llibreria JMidi!!
gcc -shared -fPIC -> l'opció -shared vol dir que estem creant una shared library. The -fPIC and -fpic options enable ``position independent code'' generation, a requirement for shared libraries

Per tant, compilem:

$ sudo make

compila bé!!

com a resultat obtinc:

libJMidi.so.1.0, MidiAppl.o i Midi.o

un fitxer so vol dir un Shared Object.

$ java -classpath /home/joan/midishare/lang/java/native:/home/joan/workspace5/prova_inicial_midishare/:/home/joan/midishare/lang/java/jni/linux/  TutorialPart1c

-> no funciona

$ sudo cp libJMidi.so.1.0 /usr/lib

-> torno a executar TutorialPart1c i tampoc funciona

i si vull fer com els altres shared objects que estan a la carpeta /usr/lib, he de fer un softlink:

libJMidi.so.1 -> libJMidi.so.1.0
$ sudo ln -s libJMidi.so.1.0 libJMidi.so

Nota posterior abril 2009: amb això ja n'hi ha prou, no cal fer el que ve a continuació (/usr/lib/jni)

Documentació de Java:

loadLibrary

public static void loadLibrary(String libname)

    Loads the system library specified by the libname argument. The manner in which a library name is mapped to the actual system library is system dependent.

    The call System.loadLibrary(name) is effectively equivalent to the call

         Runtime.getRuntime().loadLibrary(name)
         

    Parameters:
        libname - the name of the library. 
    Throws:
        SecurityException - if a security manager exists and its checkLink method doesn't allow loading of the specified dynamic library 
        UnsatisfiedLinkError - if the library does not exist.
    See Also:
        Runtime.loadLibrary(java.lang.String), SecurityManager.checkLink(java.lang.String)

Per tant el meu cas (UnsatisfiedLinkError - if the library does not exist.) és que no existeix la llibreria o no troba la llibreria. Jo parteixo d'un fitxer libJMidi.so.1 que en ppi està bé.

També existeix la carpeta /usr/lib/jni, que conté els fitxers .so:

$ sudo cp libJMidi.so.1.0  /usr/lib/jni
$ sudo ln -s libJMidi.so.1.0 libJMidi.so

-> i encara no

(http://opensolaris.org/jive/thread.jspa?messageID=198252)

You could try:

$ ldd -r /usr/lib/jni/libsvnjavahl-1.so
man ldd -> print shared library dependencies

To specify java.library.path, start OpenGrok:

$ java -Djava.library.path=/usr/lib/jni ....

finalment:

$ java -Djava.library.path=/usr/lib/jni -classpath /home/joan/midishare/lang/java/native:/home/joan/workspace5/prova_inicial_midishare/:/home/joan/midishare/lang/java/jni/linux/  TutorialPart1c

i funciona!!!

i a més a més el resultat em dóna 1:

1 means that MidiShare is installed

de fet, sense res en el CLASSPATH, funciona:

$ java -Djava.library.path=/usr/lib/jni -classpath /home/joan/midishare/lang/java/native:  TutorialPart1c

Ara el següent pas és saber com fico l'opció -Djava.library.path=/usr/lib/jni en el Eclipse

(elimino el fitxer .so i el seu soft link de /usr/lib, perquè el que val és el que està a /usr/lib/jni)

I ara ja funciona el Tutorialpart1.java (applet de Java), però encara no se sent res. No se sent res perquè he de solucionar tot el tema de la connexió dels ports (igual que em passava en Windows).

$ man java

-Dproperty=value
Set a system property value. -> per tant estic ficant un system property value que es diu java.library.path, i que és la ruta on es troben les shared libraries

Recordem el que vam fer en instal.lar MidiShare a Windows XP: vam copiar el fitxer JMidi.dll (i JPlayer.dll) a C:/Windows. Doncs bé, precisament JMidi.dll és la llibreria que jo ara estic instal.lant a Linux, que està escrita en C, i que té tota la funcionalitat Midi de baix nivell (com obrir un dispositiu, etc.). Per tant, el mètode que he seguit (LoadLibrary...) és l'equivalent a instal.lar una dll en el món Windows. I l'altra avantatge és que aquestes llibreries estan escrites en C: és la manera d'incorporar codi C a un projecte Java, i a més a més en les crides a la llibreria no patirem d'una possible lentitud deguda a Java.

llegeixo en la documentació:

Linux version of MidiShare consists of both a shared library (JMidi, el que acabo de fer) and a kernel module (el mòdul midishare, lsmod)

Informació sobre Shared libraries:

http://www.linux.org/docs/ldp/howto/Program-Library-HOWTO/shared-libraries.html

ldconfig examines the existing files and creates the so names as symbolic links to the real names, as well as setting up the cache file /etc/ld.so.cache (described in a moment). -> ldconfig crea els enllaços simbòlics de forma automàtica

Therefore, ldconfig makes no assumptions about what you want programs to link to, so installers must specifically modify symbolic links to update what the linker will use for a library.

According to the FHS, most libraries should be installed in /usr/lib, but libraries required for startup should be in /lib and libraries that are not part of the system should be in /usr/local/lib. Other standard library locations include /usr/X11R6/lib for X-windows.

On GNU glibc-based systems, including all Linux systems, starting up an ELF binary executable automatically causes the program loader to be loaded and run. On Linux systems, this loader is named /lib/ld-linux.so.X (where X is a version number). This loader, in turn, finds and loads all other shared libraries used by the program.

If you want to just override a few functions in a library, but keep the rest of the library, you can enter the names of overriding libraries (.o files) in /etc/ld.so.preload; these preloading libraries will take precedence over the standard set. This preloading file is typically used for emergency patches; a distribution usually won't include such a file when delivered.

The program ldconfig by default reads in the file /etc/ld.so.conf, sets up the appropriate symbolic links in the dynamic link directories (so they'll follow the standard conventions), and then writes a cache to /etc/ld.so.cache that's then used by other programs. This greatly speeds up access to libraries. The implication is that ldconfig must be run whenever a DLL is added, when a DLL is removed, or when the set of DLL directories changes; running ldconfig is often one of the steps performed by package managers when installing a library. On start-up, then, the dynamic loader actually uses the file /etc/ld.so.cache and then loads the libraries it needs.

In Linux, the environment variable LD_LIBRARY_PATH is a colon-separated set of directories where libraries should be searched for first, before the standard set of directories; this is useful when debugging a new library or using a nonstandard library for special purposes

punt 3.4. Creating a Shared Library (interessant...)

Once you've created a shared library, you'll want to install it. The simple approach is simply to copy the library into one of the standard directories (e.g., /usr/lib) and run ldconfig -> això és el que he fet jo, copiar la llibreria en el lloc correcte, però he fet l'enllaç manualment, en comptes de fer ldconfig.

Finally, when you compile your programs, you'll need to tell the linker about any static and shared libraries that you're using. Use the -l and -L options for this -> això és el que faríem en un projecte de C/C++, però amb Java es fa d'una altra manera.


Ara el que he d'aconseguir és fer funcionar el meu codi amb Eclipse. He de trobar la manera com en l'Eclipse fico l'opció

-Djava.library.path=/usr/lib/jni

For just normal java projects, you can set the native library location on the project properties > Java Build Path, on both the Source and Libraries Tab. Then when you run within eclipse, eclipse will take care of setting java.library.path for you.

ja ho he trobat:

properties > Java Build Path > pestanya source > Native Library Location > Edit > ho edito i poso /usr/lib/jni

Sobre el CLASSPATH i el Eclipse

Si tinc el midishare instal.lat a /home/joan potser no hi ha problema, però si el tind instal.lat a /usr/share, es necessitaven permisos de root. Ho dic perquè en compilar TutorialPart1.java que està a /usr/src/midishare/lang/java/samples/tutorial, el propietari és el root i només aquest té permisos d'escriptura (necessaris per escriure el .class). No és correcte que si vull fer javac ho hagi de fer sempre com a root. Per tant, s'ha de donar els permisos necessaris a l'escriptori.

sudo chmod a+w tutorial/

Una altra cosa a comentar el classpath. Per no arrossegar tota l'estona

-classpath /home/joan/midishare/lang/java/native:/home/joan/workspace5/tutorial1/

una possibilitat és editar la variable d'entorn CLASSPATH:

$ export CLASSPATH=/home/joan/midishare/lang/java/native:/home/joan/workspace5/tutorial1/

o bé

$ export CLASSPATH=$CLASSPATH:/home/joan/midishare/lang/java/native:/home/joan/workspace5/tutorial1/

$ echo $CLASSPATH

Si vull fer els canvis permanents, puc editar /etc/environment:

CLASSPATH=/home/joan/midishare/lang/java/native:/home/joan/workspace5/tutorial1/

Recordem que el CLASSPATH és per a un usuari concret (m'hi he barallat molta estona, feina export -com a joan-, i sudo javac -com a root-).

$ javac AppletFrame.java
$ javac -classpath /home/joan/midishare/lang/java/native AppletFrame.java TutorialPart1.java
$ java -Djava.library.path=/usr/lib/jni -classpath /home/joan/midishare/lang/java/native:/home/joan/workspace5/tutorial1/  TutorialPart1

Eclipse

He importat aquest projecte al Eclipse (versió 3.4.2, Ganymedes, abril 2009). He creat un projecte nou, buscant com a font del projecte /usr/src/midishare/lang/java/samples/tutorial.

Per ficar la classpath: Project > properties > Java Build Path > pestanya Library > Add External Class Folder, i fico la meva llibreria de midishare: /home/joan/midishare/lang/java/native.

Ara ja no protesta la línia

import grame.midishare.*;

Quant a l'equivalent a l'Eclipse 3.4.2 de l'opció -Djava.library.path=/usr/lib, jo tenia documentat que es feia

properties > Java Build Path > pestanya source > Native Library Location > Edit > ho edito i poso /usr/lib


TutorialPart1.png

però la veritat és que en aquesta versió de l'Eclipse això no ho veig, o sigui que no ho fico, però el cert és que s'executa bé. Potser una diferència amb el que vaig provar fa uns mesos és que ara la Shared Library està a /usr/lib i no a /usr/lib/jni.

Finalment, executo de forma correcta el TutorialPart1, i el millor és tenir obert l'aplicatiu msdisplay (/usr/src/midishare/src/linux/applications/msdisplay) per veure com els events s'envien. El msdisplay funciona com una aplicació client, i va molt bé per debugar doncs a l'hora de programar no cal produir so real ni tenir a mà el sintetitzador o el controlador MIDI.

Test14

Test14, enviar una nota, no funciona

	void test14()
	{	int ref;
		text.appendText("\n\n<TEST 14>Send a note with pitch, velocity and duration\n");
		if ((ref = Midi.GetNamedAppl("msdisplay")) > 0)
			Midi.Connect(ourRefNum,ref, 1);
		sendNote (72); 
	}
<TEST 18> Display MidiShare drivers informations

List of MidiShare drivers
-------------------------------------
Reference number 127
name : MidiShare
slots : 0
version : 192
-------------------------------------

<TEST 19>Display port to slot connection state -> aquí hi hauria d'haver connexions si vull que funcioni
<TEST 20>Connect port to slot and display new connection state -> aquí hauria de veure text
if ((ref = Midi.GetNamedAppl("msdisplay")) > 0)

-> això serà cert quan està corrent l'aplicació msdisplay. Engegar-la:

$ msdisplay

-> no cal, només t'estava dient que si exsteix l'aplicació, connectat-hi per mostrar els resultats.

aquesta aplicació client s'encarrega d'enregistrar i mostrar els events MIDI que li passen.

Per tant, quan s'envia una nota (Test14), encara que de moment no sentim res, efectivament queda notificat l'event.

Funciona, però encara no se sent res. Es registra una nota pel port 0 i el canal 0

Afago un fitxer *.mid, l'obro amb el Rosegarden, i se sent (compte amb el volum!!). Jugo amb els canals i se sent per tots els canals (la targeta de so interna, per defecte, pot emetre soroll per tots els canals) (encara que el jack no funcioni)

Informació midishare interessant: http://www.musikwissenschaft.uni-mainz.de/~ag/q/q-midi/README

Això és important!!

Make sure you configure fluidsynth with MidiShare support (./configure --enable-midishare) when compiling it from the sources. Run fluidsynth as a MidiShare driver as follows:

$ fluidsynth -m midishare soundfont.sf2

$ fluidsynth -s localhost -m midishare soundfont.sf2
$ fluidsynth -s localhost -m alsa soundfont.sf2
$ fluidsynth -s localhost -m freebob soundfont.sf2

en tots els casos diu:

fluidsynth: error: Couldn't find the requested midi driver
Failed to create the MIDI thread; no MIDI input

Fer sonar els projectes

Això està explicat a Ubuntu_Studio:_Resum_preparació_Ubuntu_Studio_amb_MidiShare


creat per Joan Quintana Compte, octubre 2008