IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Multimédia Java Discussion :

[Audio] Peripherique Midi Virtuel


Sujet :

Multimédia Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3
    Par défaut [Audio] Peripherique Midi Virtuel
    Bonjour a tous,

    Je développe actuellement dans le cadre d'un projet un programme permettant d'utiliser la batterie de Guitar Hero (connectée en USB) sur Linux pour l'utiliser comme une périphérique MIDI.

    Pour ce qui est de la partie connexion de la batterie au PC, je récupère les infos de la batterie via l'API JInput. La batterie est reconnue comme un gamepad.

    Jusque la pas de problème rencontré.

    Actuellement j'utilise la librairie JFugue pour générer des sons MIDI correspondant au données reçues de la batterie. J'ai des problèmes de latence (environ 1sec entre le moment ou je tape sur la batterie et le moment ou j'entends le son). La n'est pas vraiment le problème pour le moment, mais si vous avez des solutions je suis preneur.

    Mon but est de pouvoir utiliser la batterie comme périphérique externe MIDI sur des logiciels de musique. Il faut donc que celle-ci soit reconnue en tant que tel.

    Comment puis-je avec Java créer un périphérique midi virtuel reconnu par le système et par les application de musique (type Ardour GTK), à partir duquel j'envoie mes données MIDI ?

    J'ai déjà regardé en utilisant JACK => L'application est un client Jack possédant 2 entrées et 2 sorties mais je ne pense pas arriver faire ce que je veux.

    Le projet final ne doit pas produire de musique directement mais doit agir comme un instrument externe (ou un clavier virtuel).

    Merci.

  2. #2
    Membre à l'essai
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3
    Par défaut Résolu
    Bon après plusieurs recherche j'ai trouvé une solution qui fonctionne plutôt bien !! J'explique pour ceux que ça intéresse.

    Donc étant donné qu'il n'existe pas de lib Java permettant de créer directement un port de sortie MIDI virtuel sur ALSA Sequencer, il faut obligatoirement passer par une lib C/C++ et donc utiliser la JNI (Java Native Interface).

    Je me suis donc lancé dans le dev d'une petite lib C/C++ qui me permet d'ouvrir des ports MIDI virtuels en utilisant ALSA Sequencer (Interfacé par qjackctl).

    Pour cela j'ai regardé les source d'un virtual keyboard qui ouvre des ports virtuels : Virtual MIDI Piano Keyboard. J'ai remarqué que le soft utilise une lib opensources (RtMidi : http://www.music.mcgill.ca/~gary/rtmidi/index.html) qui facilite l'accès à ces ports et la gestion du midi en C/C++. Le tuto est bien fait sur le site.

    Classe JAVA :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
     
    /**
     * @author waxayaz
     *
     */
    public class MidiAlsaSeq {
     
    	static {
    		//Chargement de la liabrairie C++
    		System.loadLibrary("MidiAlsaSeq");
    	}
     
     
    	...
     
     
    	/**
             * Constructeur
             */
    	public MidiAlsaSeq(SupportedController sc) {
    			controller = sc;
    			openAlsaVirtualPort();
    	}
     
     
     
    	/**
             * Methode native qui permet l'ouverture d'un port virtuel Alsa
             **/
    	public native void openAlsaVirtualPort();
     
     
    	/**
             * Methode native qui permet l'envoi d'un message midi
             * @param message int[Canal MIDI, Note, Velocite]
             */
    	public native void sendMessage(int message[]);
     
     
    	private void sendMidiNoteForComponent(Component c, Float data) {
     
    		if(data > 0.0 && controller.isPlayableComponents(c)) {
     
    			//Construction du message MIDI
    			int message[] = new int[3];
    			message[0] = 9;
    			message[1] = controller.getNoteForComponent(c);
    			message[2] = 100;
     
    			//Envoi de la note MIDI
    			sendMessage(message);
     
    			try {
    				Thread.sleep(50);
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
    	}
     
     
    	...
     
    }
    Pour coder la partie C/C++ de la lib il nous faut un fichier header qui contient les prototypes de fonction natives déclarées dans la classe java.
    On utilise l'utilitaire "javah" pour générer le .h à partie du .class :

    bash@bash:/../ProjetJava/bin$ javah -jni -o MidiAlsaSeq.h com.waxayaz.MIDIGamePad.midi.MidiAlsaSeq

    MidiAlsaSeq.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class com_waxayaz_MIDIGamePad_midi_MidiAlsaSeq */
     
    #ifndef _Included_com_waxayaz_MIDIGamePad_midi_MidiAlsaSeq
    #define _Included_com_waxayaz_MIDIGamePad_midi_MidiAlsaSeq
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     com_waxayaz_MIDIGamePad_midi_MidiAlsaSeq
     * Method:    openAlsaVirtualPort
     * Signature: ()V
     */
    JNIEXPORT void JNICALL Java_com_waxayaz_MIDIGamePad_midi_MidiAlsaSeq_openAlsaVirtualPort
      (JNIEnv *, jobject);
     
    /*
     * Class:     com_waxayaz_MIDIGamePad_midi_MidiAlsaSeq
     * Method:    sendMessage
     * Signature: ([I)V
     */
    JNIEXPORT void JNICALL Java_com_waxayaz_MIDIGamePad_midi_MidiAlsaSeq_sendMessage
      (JNIEnv *, jobject, jintArray);
     
    #ifdef __cplusplus
    }
    #endif
    #endif
    On code le fichier MidiAlsaSeq.cpp :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    #include "MidiAlsaSeq.h"
    #include <cstdlib>
    #include <iostream>
    #include <stdlib.h>
    #include "RtMidi.h"
     
    RtMidiOut *midiout;
     
     
    JNIEXPORT void JNICALL Java_com_waxayaz_MIDIGamePad_midi_MidiAlsaSeq_openAlsaVirtualPort (JNIEnv *env, jobject obj)
    {
    	midiout = new RtMidiOut();
    	midiout->openVirtualPort( "USBDrums" );
    	std::cout << "Virtal Port Opened" << std::endl;
    }
     
     
     
     
    JNIEXPORT void JNICALL Java_com_waxayaz_MIDIGamePad_midi_MidiAlsaSeq_sendMessage (JNIEnv *env, jobject obj, jintArray array)
    {
    	jint buf[3];
         	env->GetIntArrayRegion(array, 0, 3, buf);
     
    	int canal = buf[0];
    	int note = buf[1];
    	int velocite = buf[2];
     
    	unsigned char canal_c = static_cast<unsigned char>(canal);
    	unsigned char note_c = static_cast<unsigned char>(note);
    	unsigned char velocite_c = static_cast<unsigned char>(velocite);
     
    	std::vector<unsigned char> message;  //message midi
     
    	//Construction du message
    	message.push_back(STATUS_NOTEON + (canal_c & MASK_CHANNEL));
     
            message.push_back(note & MASK_SAFETY);
     
            message.push_back(velocite_c & MASK_SAFETY);
     
    	//Envoi du message
    	midiout->sendMessage( &message );
    }
    On met dans le même repertoire :
    +MonRep
    |----- MidiAlsaSeq.cpp
    |----- MidiAlsaSeq.h
    |----- RtError.h
    |----- RtMidi.cpp
    |----- RtMidi.h

    On compile ensuite la lib : on obtient un fichier .so

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    g++ -D__LINUX_ALSASEQ__ -o libMidiAlsaSeq.so -shared -Wl,-soname,libMidiAlsaSeq.so -I/usr/lib/jvm/java-6-sun-1.6.0.16/include -I/usr/lib/jvm/java-6-sun-1.6.0.16/include/linux MidiAlsaSeq.cpp RtMidi.cpp -lasound -lpthread -static -lstdc++
    Et voila c'est gagné il suffit de mettre le chemin du .so dans le LD_LIBRARY_PATH !!!

    export LD_LIBRARY_PATH=/chemin/libMidiAlsaSeq.so

    Pour ce qui veulent plus de détail n'hésitez pas!

  3. #3
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Avril 2008
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2008
    Messages : 71
    Par défaut
    Citation Envoyé par Waxayaz Voir le message
    Bonjour a tous,

    Je développe actuellement dans le cadre d'un projet un programme permettant d'utiliser la batterie de Guitar Hero (connectée en USB) sur Linux pour l'utiliser comme une périphérique MIDI.

    Pour ce qui est de la partie connexion de la batterie au PC, je récupère les infos de la batterie via l'API JInput. La batterie est reconnue comme un gamepad.

    Jusque la pas de problème rencontré.

    Actuellement j'utilise la librairie JFugue pour générer des sons MIDI correspondant au données reçues de la batterie. J'ai des problèmes de latence (environ 1sec entre le moment ou je tape sur la batterie et le moment ou j'entends le son). La n'est pas vraiment le problème pour le moment, mais si vous avez des solutions je suis preneur.

    Mon but est de pouvoir utiliser la batterie comme périphérique externe MIDI sur des logiciels de musique. Il faut donc que celle-ci soit reconnue en tant que tel.

    Comment puis-je avec Java créer un périphérique midi virtuel reconnu par le système et par les application de musique (type Ardour GTK), à partir duquel j'envoie mes données MIDI ?

    J'ai déjà regardé en utilisant JACK => L'application est un client Jack possédant 2 entrées et 2 sorties mais je ne pense pas arriver faire ce que je veux.

    Le projet final ne doit pas produire de musique directement mais doit agir comme un instrument externe (ou un clavier virtuel).

    Merci.
    Bonjour,

    je suis entrain de commencer un projet similaire au tiens. Ma problématique de départ est que j'ai besoin de pouvoir faire transiter des messages midi par un port virtuel (la même chose que toi si j'ai bien compris). Ensuite il faut que je puisse m'en servir dans un logiciel de mao.

    Ou en es-tu dans ton projet?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Open-Source]Compositeur virtuel pour instrument MIDI
    Par Invité dans le forum Mon programme
    Réponses: 2
    Dernier message: 19/09/2009, 14h09
  2. [Driver] Probleme de peripherique audio acer aspire 5610
    Par Petsman dans le forum Périphériques
    Réponses: 3
    Dernier message: 16/04/2009, 19h15
  3. [Audio] Régler le volume son MIDI
    Par anadoncamille dans le forum Multimédia
    Réponses: 2
    Dernier message: 12/12/2008, 20h44
  4. [Audio] [javax.sound]ou[MIDI]Jouer des sons "à la volée"
    Par Claythest dans le forum Multimédia
    Réponses: 8
    Dernier message: 12/12/2008, 16h12
  5. aucun peripherique audio
    Par intissar_g dans le forum Composants
    Réponses: 10
    Dernier message: 25/07/2007, 23h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo