Problème de rapidité avec javax.sound.midi.Synthesizer

qhhu Messages postés 66 Date d'inscription vendredi 16 décembre 2005 Statut Membre Dernière intervention 21 octobre 2009 - 14 févr. 2007 à 22:55
qhhu Messages postés 66 Date d'inscription vendredi 16 décembre 2005 Statut Membre Dernière intervention 21 octobre 2009 - 27 mars 2007 à 20:00
Bonjour a tous!
mon problème vient de la: J'ai crée un mini-"simulateur" de batterie qui joue un son (de batterie^^) quant j'appuie sur une certaine touche. Jusque la ca va. Mais le prob c'est que quant j'appuie sur une touche, le son se déclenche, mais avec un temps de retard... et du coup , ca casse tout le rythme! N'y aurait-il pas un moyen de rendre tout ca un peu plus rapide?? J'utilise javax.sound.midi.Synthetizer.

Merci d'avance

11 réponses

cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 131
15 févr. 2007 à 06:52
Bah si tu nous montre pas le code, ca va être dur de te dire ce qui peut être optimisé...

De même, utilise des outils de profiler afin de voir les parties de ton prog qui doivent être optimisée (celle où ton code passe le plus de temps).

Utilise-tu des threads ? Car sans threads, ton application doit attendre qu'une tâche soit finie avant d'en lancer une autre, ca peut venir de là si tu fait des traitements lourds avant de lancer ton son !
0
qhhu Messages postés 66 Date d'inscription vendredi 16 décembre 2005 Statut Membre Dernière intervention 21 octobre 2009
15 févr. 2007 à 17:02
lol! Oui pardon j'ai pas réfléchi...
Le voici:

import javax.sound.midi.*;
import java.awt.event.*;
import javax.swing.*;
publicclass test extends JFrame{
    ShortMessage message;
    Synthesizer synth;
    Receiver receiver;
    int charleston = 174;
    int grossecaisse = 171;
    int caisseclaire = 166;
    public test(){
        super("MyAudioDrumms");
        setBounds(10,10,200,150);
        setDefaultCloseOperation(3);
        setFocusable(true);
        requestFocus();
        addKeyListener(new KeyAdapter(){
            public void keyPressed(KeyEvent evt){
                char c = evt.getKeyChar();
                switch(c){
                    case 'y':frappe(grossecaisse);break;
                    case 'x':frappe(caisseclaire);break;
                    case 'm':frappe(charleston);break;
                }
            }
        });
        try{
        message = new ShortMessage();
        synth = MidiSystem.getSynthesizer();
        synth.open();
        receiver  = synth.getReceiver();
        } catch (Exception e){}
        setVisible(true);
    }
    public void frappe(int instrument){
        try{
        int volume = 50;
        if(instrument == grossecaisse)
            volume = 100;
        synth.getChannels()[0].programChange(instrument);
        message.setMessage(ShortMessage.NOTE_ON, 0, 60, volume);
        receiver.send(message, -1);
        } catch(Exception e){}
    }
    public static void main(String[] args)throws Exception{
       
            new test();
       
       
    }
}
0
cs_DARKSIDIOUS Messages postés 15814 Date d'inscription jeudi 8 août 2002 Statut Membre Dernière intervention 4 mars 2013 131
15 févr. 2007 à 17:40
Là je peux pas t'en dire plus, je ne connais pas la librairie, et je ne sais donc pas son niveau d'optimisation.
0
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
15 févr. 2007 à 18:00
Salut,

déjà pour commencer détache le traitement de frappe dans un thread par ce que le Synthesizer est assez bouffe ressources

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

WORA
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
qhhu Messages postés 66 Date d'inscription vendredi 16 décembre 2005 Statut Membre Dernière intervention 21 octobre 2009
15 févr. 2007 à 20:09
Excuse-moi mais je vois pas bien comment tu veu faire ca...
Pour un Thread, il faut un Runnable avec une boucle while dedans...
Or je vois pas ou la trouver cette boucle...
En plus, la méthode run de Runnable ne prend pas de paramètres, alors comment lui dire sur quelle touche on a tappé...
Merci de vos réponses!
0
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
15 févr. 2007 à 20:22
Salut,

je sais pas moi tu peux faire :

import javax.sound.midi.*;
import java.awt.event.*;
import javax.swing.*;

public class test extends JFrame{
    int charleston = 174;
    int grossecaisse = 171;
    int caisseclaire = 166;
    MyTimer timer = null;
    public test(){
        super("MyAudioDrumms");
        timer = new MyTimer();
        setBounds(10,10,200,150);
        setDefaultCloseOperation(3);
        setFocusable(true);
        requestFocus();
        addKeyListener(new KeyAdapter(){
            public void keyPressed(KeyEvent evt){
                char c = evt.getKeyChar();
                switch(c){
                    case 'y':timer.restart(grossecaisse);break;
                    case 'x':timer.restart(caisseclaire);break;
                    case 'm':timer.restart(charleston);break;
                }
            }
        });
        setVisible(true);
    }

    public static void main(String[] args)throws Exception{
            new test();
    }
}

class MyTimer implements ActionListener{
    private ShortMessage message = null;
    private Synthesizer synth = null;
    private Receiver receiver = null;
    private int instrument = 0;
    private javax.swing.Timer timer = null;

    public MyTimer(){
        timer = javax.swing.Timer(100, this);// je mets 100 pour le fun
        try{
                message = new ShortMessage();
                synth = MidiSystem.getSynthesizer();
                synth.open();
                receiver  = synth.getReceiver();
            } catch(Exception e){}
    }

    public void restart(int instrument){
        this.instrument = instrument;
        timer.restart();
    }

    public void actionPerformed(ActionListener e){
        if(e.getSource().equals(timer)){
            try{
                    synth.getChannels()[0].programChange(instrument);
                    message.setMessage(ShortMessage.NOTE_ON, 0, 60,
                     (instrument == grossecaisse) ? 100 : 50);
                    receiver.send(message, -1);
                } catch(Exception e){}
        }
    }
}

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

WORA
0
qhhu Messages postés 66 Date d'inscription vendredi 16 décembre 2005 Statut Membre Dernière intervention 21 octobre 2009
15 févr. 2007 à 20:49
Rebonjour
Avec ton code, la "note" se répète toute les 100 ms...
J'ai donc essayé de remplacer le Timer par un Thread... c'est un tt pti peu mieu, mais il reste encore un délai après l'appui...
Merci quant même.
Je pense que le problème vient plutôt du Synthesizer qui attend trop lontemps avant de jouer le son... Qu'en penses-tu?
0
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
15 févr. 2007 à 20:56
Salut,

nan j'ai oublié

public void actionPerformed(ActionListener e){
        if(e.getSource().equals(timer)){
            try{
                    synth.getChannels()[0].programChange(instrument);
                    message.setMessage(ShortMessage.NOTE_ON, 0, 60,
                     (instrument == grossecaisse) ? 100 : 50);
                    receiver.send(message, -1);
             } catch(Exception e){}
             timer.stop();
        }
    }

pour ce qui est du Synthesizer faut voir la taille du son, verifier également si le synté n'a ,pas un timeout pour closer les ressources, etc ...

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

WORA
0
qhhu Messages postés 66 Date d'inscription vendredi 16 décembre 2005 Statut Membre Dernière intervention 21 octobre 2009
15 févr. 2007 à 22:01
Re
J'ai trouvé un truc :
getLatency()
Obtains the processing latency incurred by this synthesizer, expressed in
microseconds. This latency measures the worst-case delay between the
time a MIDI message is delivered to the synthesizer and the time that the
synthesizer actually produces the corresponding result.

C'est ca mon problème... Il faudrait un moyen pour réduire cela...
Sinon pour ta méthode avec Timer, je ne peut jouer qu'un son à la fois... donc c'est pas encore ca... mais merci quant même!
0
Twinuts Messages postés 5375 Date d'inscription dimanche 4 mai 2003 Statut Modérateur Dernière intervention 14 juin 2023 111
15 févr. 2007 à 22:14
Salut,

bah recreer simplement l'instance à chaque fois.......... pour la latence il n'y a pas un set?

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

WORA
0
qhhu Messages postés 66 Date d'inscription vendredi 16 décembre 2005 Statut Membre Dernière intervention 21 octobre 2009
27 mars 2007 à 20:00
J'ai cherché et cherché mais je crois qu'il n'y a rien...
Je vais essayer avec d'autres méthodes (le wav par exemple!)
Merci bien en tout cas vous m'avez bien aidé!!
A bientot
0
Rejoignez-nous