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 :

Jouer une note isolée en MIDI


Sujet :

Multimédia Java

  1. #1
    Membre actif
    Jouer une note isolée en MIDI
    Salut,

    je cherche à intégrer du son MIDI dans AnAcondA, j'ai vu les classe de java.sound mais je n'arrive pas à créer une fonction qui aurait pour signature :

    void playNote(int instru, int note); // Pour jouer une note isolée d'un instrument de musique

    J'avais programmé une batukada aléatoire, visible dans la démo d'AnAcondA mais pour faire des mélodies, je ne sais pas comment faire. Comme je fais peu de commentaires dans mon projet, je suis bien emmbêté.

    Dans mes souvenirs, je n'ai pas pu jouer une note seule, mais ai été contraint de créer une plage rythmique, d'écrire les partitions des percussions et de jouer la plage. Je n'ai pas le souvenir d'avoir réussi à jouer un son de percussion seul.
    __________________________________
    | +
    | Sylvain Tournois - Création logicielle
    |
    | sylv.tournois.free.fr
    |

  2. #2
    Rédacteur

    Je n'ai pas de réponse directe mais va peut-être voir du côté de l'IRCAM: http://www.ircam.fr/ Ils ont des programmes Open Source écrits en Java de traitement de son au format midi.

    En espérant que ça puisse t'aider...
    Avant de poster, pensez à regarder la FAQ, les tutoriaux, la Javadoc (de la JRE que vous utilisez) et à faire une recherche
    Je ne réponds pas aux questions techniques par MP: les forums sont faits pour ça
    Mes articles et tutoriaux & Mon blog informatique

  3. #3
    Membre actif
    Citation Envoyé par CyberChouan
    Je n'ai pas de réponse directe mais va peut-être voir du côté de l'IRCAM: http://www.ircam.fr/ Ils ont des programmes Open Source écrits en Java de traitement de son au format midi.

    En espérant que ça puisse t'aider...
    Merci pour l'info, je suis allé voir, mais c'est beaucoup plus complexe que ce que je cherche à faire et ils utilisent des librairies supplémentaires.

    Je sais que la possibilité existe en Java sans librairie additionnelle.

    Dans Java, le package javax.sound.midi contient j'en suis sûr le service que je cherche, mais je ne trouve pas de tutoriel pour l'utiliser.

    Dans AnAcondA, j'avais été obligé de créer une plage sonore avant de pouvoir jouer dessus. Là je voudrais pouvoir jouer une note sans utilisation excessive de ressource.
    __________________________________
    | +
    | Sylvain Tournois - Création logicielle
    |
    | sylv.tournois.free.fr
    |

  4. #4
    Membre éprouvé
    je suis comme toi je cherche mais je n'ais toujours pas trouvé mon bonneur.
    Je te previent si je trouve quelque chose.

  5. #5
    Rédacteur/Modérateur

    Eventuellement, allez lire les topics et poser vos questions sur les forums (anglais) de javagaming.org, peut-etre y trouverez-vous des pistes ou des solutions.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  6. #6
    Membre actif
    Progressons (messages fusionnés ...)
    Salut,

    je fais quelques recherches mais je n'ai malheureusement pas beaucoup de temps en ce moment.

    Je poste dès que j'ai les lignes de code qu'il faut.

    A bientôt

    ================================================

    Salut,

    la gestion Java du standard MIDI oblige à mettre en place un structure assez lourde même pour jouer une seule note.

    Le MIDI étant destiné à la lecture d'un morceau de musique, il est moins adapté à la musique faite à la volée.

    En gros nous avons les éléments suivants :

    - Le séquenceur joue la musique qu'on lui donne sous forme d'une séquence
    - La séquence est l'ensemble des pistes de chaque instrument
    - Chaque piste contient la partition d'un instrument
    - Les notes et rythmes sont des messages sur la piste

    Nous avons besoin de tout ça pour jouer une note. C'est très lourd pour une note, l'intérêt c'est qu'on ne changera rien pour faire un morceau entier.

    ================================================

    Un lien bien utile :

    http://java.sun.com/j2se/1.4.2/docs/guide/sound/programmer_guide/chapter8.html

    Si vous avez des docs en français, je suis preneur. Je mets plus de temps pour l'anglais.

    D'après ce que j'ai compris, la classe javax.sound.midi.Synthesizer permet de jouer du son, peut-être une simple note.

    Suspense ...

    ================================================

    Il y a deux moyen de jouer du son MIDI en Java, soit par séquence (cf post précédent), soit par synthétiseur.

    La séquence est adaptée à la lecture de fichiers MIDI.
    Le synthétiseur va nous servir pour jouer une note.

    ================================================

    Ce code n'est pas encore fonctionnel, mais voici un bout du chemin :

    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
     
    import javax.sound.midi.*;
     
    public class MidiPlayer {
     
      public static void playNote(int note, int velocity) {
        Synthesizer synthesizer = null;
        try {
          synthesizer = MidiSystem.getSynthesizer();
        }
        catch (Exception e) {
          e.printStackTrace();
          synthesizer = null;
        }
        if (synthesizer != null) {
          MidiChannel[] channels = synthesizer.getChannels();
          channels[0].noteOn(note, velocity);
        }
      }
     
      public static void main(String[] args) {
        playNote(60, 93); // 60 = Do du milieu ; 93 : force de frappe de la note (0 = silence)
        while (true);
      }
     
    }


    Théoriquement, ça fonctionne. Cependant il manque la gestion des instruments, ce qui fait que la note ne se joue pas.

    A suivre...

    ================================================

    Un autre lien :

    http://java.sun.com/docs/books/tutorial/sound/index.html

    Bon je galère à la jouer cette note, mais j'y arriverai !

    ================================================

    En attendant, un site avec plein de musiques MIDI gratuites :

    http://www.mididb.com/

    ================================================

    Comme il est plus facile de jouer un fichier MIDI qu'une seule note, voici un lien vers un post que je viens de faire, c'est un player MIDI :

    http://www.developpez.net/forums/showthread.php?p=2470825#post2470825

    ================================================

    Aïe, ça se corse !

    Pour faire jouer un Synthesizer, il nous faut une SoundBank, il n'y en a pas par défaut.

    Ce qui est étrange, c'est qu'il y en a nécessairement au moins une par défaut dans Java, puisqu'on peut jouer du son en utilisant un séquenceur, cf mon générateur de batukada aléatoire :

    http://www.developpez.net/forums/showthread.php?p=2471127#post2471127

    Il reste à trouver comment obtenir une SoundBank, et ce n'est pas le Synthesizer qui va nous aider pour ça ...
    __________________________________
    | +
    | Sylvain Tournois - Création logicielle
    |
    | sylv.tournois.free.fr
    |

  7. #7
    Membre actif
    Help
    Y a-t-il quelqu'un qui ait fait ce trajet, jouer une simple note en MIDI ?
    J'en plie dans la ploucroute.

    J'en suis à potasser dans la classe MidiChannel les méthodes getProgram(), getController(int controller) et, attention, non pas setProgram (ca serait trop simple) mais programChange(int program)

    C'est d'un obscur , super mal documenté (en anglais, ça va sans dire).
    Mais si ils ne veulent pas qu'on joue du MIDI, ils n'ont qu'à le dire directement !!

    Grmf (expression de colère)

    Je ne me laisserai pas faire, j'y arriverai, même si je dois bosser chez Sun !
    __________________________________
    | +
    | Sylvain Tournois - Création logicielle
    |
    | sylv.tournois.free.fr
    |

  8. #8
    Membre actif
    En attendant mieux ...
    Un post que je viens de faire avec l'ancienne version de mon générateur de batukada aléatoire :

    http://www.developpez.net/forums/showthread.php?p=2471127#post2471127
    __________________________________
    | +
    | Sylvain Tournois - Création logicielle
    |
    | sylv.tournois.free.fr
    |

  9. #9
    Membre actif
    De qui se moque-t-on ?
    C'est incroyable !!

    J'ai posté le lien vers la batukada aléatoire car son fonctionnement prouve qu'il existe une SoundBank quelque part dans Java.

    Par contre, pas moyen d'y accéder. En lisant des docs, j'apprends maintenant qu'il faut télécharger une banque soi-même et l'intégrer au programme ou l'installer. Bref, c'est lourd.

    http://java.sun.com/products/java-media/sound/soundbanks.html

    Ce n'est pas très cohérent tout ça, ça m'étonne de la part de Sun.
    Sans compter que le domaine du MIDI est extrêmement obscur, qu'est-ce qui pose problème ?

    Je ne pense pas être le premier à vouloir faire de la musique MIDI en Java. C'est étrange ...
    __________________________________
    | +
    | Sylvain Tournois - Création logicielle
    |
    | sylv.tournois.free.fr
    |

  10. #10
    Membre actif
    Progressons ...
    Voici un code qui affiche quelques paramètres MIDI, les devices reconnus :

    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
     
      public static void printMidiDevices() {
        MidiDevice.Info[] devices = MidiSystem.getMidiDeviceInfo();
        MidiDevice device;
        Synthesizer synt;
        Sequencer sequ;
        try {
          for (int i = 0 ; i < devices.length ; i++) {
            System.out.println(devices[i].getDescription());
            device = MidiSystem.getMidiDevice(devices[i]);
            synt = null;
            sequ = null;
            if (device instanceof Synthesizer) {
              synt = (Synthesizer)device;
              System.out.println("  Synthesizer");
              System.out.println("  sound bank : " + synt.getDefaultSoundbank());
            }
            if (device instanceof Sequencer) {
              sequ = (Sequencer)device;
              System.out.println("  Sequencer");
            }
            if ((sequ == null) && (synt == null))
              System.out.println("  Neither Sequencer nor Synthesizer");
            System.out.println();
          }
        }
        catch (Exception e) {
          e.printStackTrace();
        }
      }


    Sur mon ordinateur, je n'obtiens aucune SoundBank par ce biais. Si vous en trouvez, ça m'intéresse.

    Voici le résultat que j'obtiens :



    Il y a quelque chose de troublant, à propos du "Internal Software Synthesizer", il n'est pas reconnu comme étant de la classe Shynthesizer. L'autre Synthesizer n'a pas de banque de son.

    Pourtant le son de la batukada aléatoire vient bien de quelque part ?
    __________________________________
    | +
    | Sylvain Tournois - Création logicielle
    |
    | sylv.tournois.free.fr
    |

  11. #11
    Membre actif
    Une petite victoire, coûteuse
    Youpiyaaa !!

    Voici un petit bout de code pour jouer une note en Midi, accessoirement ça joue aussi un fichier entier (ce n'est pas plus long). J'utilise le séquenceur qui n'est pas du tout adapté à jouer une seule note.

    Maintenant je m'en vais approfondir mes études sur le Synthesizer.

    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
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
     
    import java.io.File;
    import java.util.Random;
    import javax.sound.midi.MidiSystem;
    import javax.sound.midi.Sequencer;
    import javax.sound.midi.MetaEventListener;
    import javax.sound.midi.Sequence;
    import javax.sound.midi.Track;
    import javax.sound.midi.ShortMessage;
    import javax.sound.midi.MidiEvent;
     
    /* Un player MIDI simple
     *
     * 2007 - Sylvain Tournois
     *
     * www.anadoncamille.com
     */
    public class MidiPlayer implements MetaEventListener {
     
      public static void main(String[] args) {
        if (args.length < 1) {
          Random random = new Random();
          while (true)
    //        playMidiNote(random.nextInt(16), random.nextInt(128), random.nextInt(64) + 64);
            playMidiNote(9, random.nextInt(128), random.nextInt(64) + 64);
        }
        else
          playMidiFile(args[0]);
      }
     
      // Service : Joue une note MIDI
      public static void playMidiNote(int instrument, int note, int velocity) {
        System.out.println("Playing MIDI note (" + instrument + ", " + note + ", " + velocity + ") :");
        MidiPlayer mp = new MidiPlayer();
        mp.playNote(instrument, note, velocity);
        System.out.println("OK");
      }
     
      // Service : Joue un fichier au format MIDI (*.mid)
      public static void playMidiFile(String fileName) {
        System.out.println("Playing MIDI file : " + fileName);
        MidiPlayer mp = new MidiPlayer();
        mp.playFile(fileName);
        System.out.println("OK");
      }
     
      //========================================================
     
      // Constantes
      private static final int END = 47; // Fin de séquence 
      private static final int PROGRAM = 192; // Programmation de piste
      private static final int NOTEON = 144; // Début de note
      private static final int NOTEOFF = 128; // Fin de note
      private static final int TRACK_LENGTH = 2; // Longueur de la piste
      private static final int TRACK_START = 0; // Début de la piste
      private static final int TRACK_END = TRACK_LENGTH - 1; // Fin de la piste
      private static final int PERCUSSION = 9; // Instrument : percussions (chaque note est un des 47 instruments différents)
     
      // Le sequenceur permet de jouer une séquence midi
      private static Sequencer sequencer;
     
      // Constructeur du player
      public MidiPlayer() {
        if (sequencer == null) {
          try {
            sequencer = MidiSystem.getSequencer(); // Séquenceur MIDI par défaut
            sequencer.addMetaEventListener(this); // Réception des événements MIDI
          }
          catch (Exception e) {
            e.printStackTrace();
            sequencer = null;
          }
        }
      }
     
      // Joue une note de piano ou une des 47 percussions, si instrument == 9
      public void playNote(int instrument, int note, int velocity) {
        playSequence(getSequence(instrument, note, velocity));
      }
     
      // Crée une séquence MIDI pour une note/percussion
      public static Sequence getSequence(int instrument, int note, int velocity) {
        Sequence sequence;
        Track track;
        if (instrument == PERCUSSION)
          note = note % 47 + 35;
        try {
          sequence = new Sequence(Sequence.PPQ, 2); // 2 = longueur de la séquence (pour une note c'est suffisant)
          track = sequence.createTrack(); // Création d'une piste
          createEvent(track, PROGRAM, instrument, 1, 0, TRACK_START); // Programmation de la piste
          createEvent(track, NOTEON, instrument, note, velocity, TRACK_START); // Une note
          createEvent(track, NOTEOFF, instrument, note, velocity, TRACK_END); // Fin de la note
          createEvent(track, PROGRAM, instrument, 1, 0, TRACK_END); // Fin de la programmation
        }
        catch (Exception e) {
          e.printStackTrace(); 
          sequence = null;
        }
        return sequence;
      }
     
      // Envoie un message sur une piste
      private static void createEvent(Track track, int type, int chan, int num, int velocity, long tick) throws Exception {
        ShortMessage message = new ShortMessage();
        message.setMessage(type, chan, num, velocity); 
        MidiEvent event = new MidiEvent(message, tick);
        track.add(event);
      }
     
      // Joue un fichier au format MIDI (*.mid)
      public void playFile(String fileName) {
        playSequence(getSequence(fileName));
      }
     
      // Crée une séquence MIDI à partir du fichier fileName
      public static Sequence getSequence(String fileName) {
        File file = new File(fileName);
        if (!file.exists())
          return null;
        Sequence sequence;
        try {
          sequence = MidiSystem.getSequence(file);
        }
        catch (Exception e) {
          e.printStackTrace();
          sequence = null;
        }
        return sequence;
      }
     
      // Joue une séquence
      public void playSequence(Sequence sequence) {
        if ((sequence == null) || (sequencer == null))
          return;
        try {
          sequencer.setSequence(sequence); // Indique au séquenceur quelle séquence il va jouer
          if (!sequencer.isOpen()) // Si le séquenceur n'est pas ouvert
            sequencer.open(); // Ouverture du séquenceur
          sequencer.start(); // Lecture de la séquence
        }
        catch (Exception e) {
          e.printStackTrace();
        }
        while (isPlaying());
      }
     
      // Indique si le player est actif
      public boolean isPlaying() {
        if (sequencer == null)
          return false;
        return sequencer.isOpen();
      }
     
      // Réception des messages, traitement du message de fin de lecture
      public void meta(javax.sound.midi.MetaMessage metaMessage) {
        if (metaMessage.getType() == END) // Si fin de séquence
          sequencer.close(); // Fermeture du séquenceur
      }
     
    }


    Oui, c'est un peu long, mais si vous trouvez un moyen plus court pour jouer une seule note, je suis preneur.
    __________________________________
    | +
    | Sylvain Tournois - Création logicielle
    |
    | sylv.tournois.free.fr
    |

  12. #12
    Futur Membre du Club
    Il a quelque mois j'avais fait un clavier virtuel midi en Java. Ce bout de code peut t'aider :

    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
     
    import javax.sound.midi.*;
     
    public class midiSound {
     
    private Synthesizer synthesizer;
    private Soundbank soundBank;
    private Instrument [] instruments;
    private MidiChannel [] channels;
     
    public midiSound() throws MidiUnavailableException {
     
    // initialisation midi : on déclare et on ouvre un synthétiseur
    synthesizer = MidiSystem.getSynthesizer();
    synthesizer.open();
     
    // utilisation de la banque de sons par défault
    soundBank = synthesizer.getDefaultSoundbank();
     
    // obtention d'une liste des instruments contenus dans cette banque de sons
    instruments = soundBank.getInstruments();
     
    // obtention des canaux MIDI contrôlés par ce synthétiseur
    channels = synthesizer.getChannels();
     
    /* on choisit le premier instrument de la liste, c'est-à-dire le piano, et on l'affecte sur le premier canal. */
    synthesizer.loadInstrument(instruments[0]);
    channels[0].programChange(0);
     
    // la note est ensuite jouée
    /* paramètres : le canal, le numéro de la note jouée, la velocité (la vitesse à laquelle on a pressée la touche <img src="images/smilies/icon_wink.gif" border="0" alt="" title=";)" class="inlineimg" />, et enfin la durée (à remplacer par des threads) */
    playNote(channels[0], 48, 50, 3000);
    }
     
    // jouer une note
    public static void playNote(MidiChannel channel, int note, int velocite, int duree) {
    /* la durée doit être au moins 1 (même si c'est trop court pour être audible) */
    if (duree <= 0) duree = 1;
     
    // la note est jouée pendant la durée choisie
    for (int i = 0; i < duree; i++) {
    channel.noteOn(note, velocite);
    }
     
    // puis elle est arrêtée.
    channel.noteOff(note);
    }
    }

    Liste des notes Midi (image svg).

  13. #13
    Membre actif
    Pas de SoundBank
    Merci Cocoshaker pour ta réponse, j'ai testé le code, mais je me retrouve sans SoundBank, c'est à dire que le code plante quand je veux jouer une note.

    J'ai eu le même problème déjà mais je pensais avoir fait une mauvaise initialisation.

    Je ne comprends pas pourquoi je n'ai pas de soundbank, en as-tu importé ou en avais-tu une par défaut ?
    __________________________________
    | +
    | Sylvain Tournois - Création logicielle
    |
    | sylv.tournois.free.fr
    |

  14. #14
    Futur Membre du Club
    Au moment de l'installation du JRE il faut choisir l'option multimedia dans l'installation personnalisée, c'est pas automatique. Vu que tu as déjà le JRE d'installé, inutile de le réinstaller juste pour ça.
    - tu vas plutôt aller sur cette page : http://java.sun.com/products/java-media/sound/soundbanks.html et tu vas télécharger un des fichiers. Comme tu peux t'en douter, plus la banque de son est grosse en taille, meilleure est la qualité. Choisie celui que tu veux.
    - une fois le fichier téléchargé, va dans le dossier nommé "audio" dans le JRE (par défaut sous Windows : C:\Program files\Java\jre1.6.0_02\lib\audio). S'il n'existe pas, créé le.
    - décompresse la banque de sons. Au cas où, renomme la "soundbank.gm" si elle ne s'appelle pas déjà comme ça, puis mets la dans le dossier audio.
    - test!

    Après ça, dis moi si c'est bon.

  15. #15
    Rédacteur/Modérateur

    Ouaip depuis quelques temps, certaines "personnes" (hum... ) influentes de la communaute et des commites JSR ont juge bon de ne plus inclure JavaSound de base dans l'installation du JRE, car avoir quelques mega-octets en moins a l'install ca fait tres classe de nos jours sur nos disques durs qui font 500 Go ou plus... (sarcasmes inclus).
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  16. #16
    Membre actif
    Merci Cocoshaker, ça marche !
    Pour l'instant je n'ai entendu qu'une note de piano, mais je vais dormir avant de continuer les tests.

    Je me pose une question, penses-tu que je peux lier la soundbank autrement qu'en suggérant à l'utilisateur de faire une install multimédia de Java ? Je pense à inclure le fichier dans AnAcondA mais je me demande comment le lier au Synthesizer.

    ------

    Citation Envoyé par bouye Voir le message
    car avoir quelques mega-octets en moins a l'install ca fait tres classe de nos jours sur nos disques durs qui font 500 Go ou plus... (sarcasmes inclus).
    J'envisage une version disquette d'AnAcondA, juste le .jar avec les classes. Dépouillée au possible, sans graphisme ni son.
    __________________________________
    | +
    | Sylvain Tournois - Création logicielle
    |
    | sylv.tournois.free.fr
    |

  17. #17
    Membre actif
    Ca y est presque
    Ca marche en partie.

    On peut lier la soundbank à partir de n'importe où, y compris une url, avec les méthodes :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    MidiSystem.getSoundbank(...)


    Le piano marche bien, mais je n'arrive pas à obtenir d'autres instruments, ça ne joue que du piano.

    Il y a une autre question que je me pose, pourquoi doit-on faire 3000 noteOn pour 3s, n'y a t il pas moyen de faire noteOn puis noteOff à t+3000 ?

    Voici mon code :
    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
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    import javax.sound.midi.*;
    import java.io.*;
     
    public class MidiSynthe {
     
      public static void main(String[] args) {
        try {
          new MidiSynthe();
        }
        catch (Exception e) {
          e.printStackTrace();
        }
        while (true);
      }
     
      private Synthesizer synthesizer;
      private Soundbank soundBank;
      private Instrument [] instruments;
      private MidiChannel [] channels;
     
      public MidiSynthe() throws MidiUnavailableException {
     
        // initialisation midi : on déclare et on ouvre un synthétiseur
        synthesizer = MidiSystem.getSynthesizer();
        synthesizer.open();
     
        // utilisation de la banque de sons par défault
        soundBank = synthesizer.getDefaultSoundbank();
        if (soundBank == null) {
          try {
            soundBank = MidiSystem.getSoundbank(new File("../lib/soundbank.gm"));
          }
          catch (Exception e) {
            e.printStackTrace();
          }
        }
        // obtention d'une liste des instruments contenus dans cette banque de sons
        instruments = soundBank.getInstruments();
     
        // obtention des canaux MIDI contrôlés par ce synthétiseur
        channels = synthesizer.getChannels();
     
        synthesizer.loadAllInstruments(soundBank);
     
        // la note est ensuite jouée
        /* paramètres : le canal, le numéro de la note jouée, la velocité (la vitesse à laquelle on a pressée la touche <img src="images/smilies/icon_wink.gif" border="0" alt="" title=";)" class="inlineimg" />, et enfin la durée (à remplacer par des threads) */
        for (int i = 0 ; i < instruments.length ; i++) {
          System.out.println(i + ":" + instruments[i]);
          changeInstrument(i);
          playNote(channels[0], 48, 50, 1000);
          try {
            Thread.sleep(1000);
          }
          catch (Exception e) {
          }
        }
      }
     
      // changer d'instrument
      public void changeInstrument(int j) {
        Instrument i = instruments[j];
        Patch p = i.getPatch();
        channels[1].programChange(p.getBank(), p.getProgram());
      }
     
      // jouer une note
      public void playNote(MidiChannel channel, int note, int velocite, int duree) {
        /* la durée doit être au moins 1 (même si c'est trop court pour être audible) */
        if (duree <= 0) duree = 1;
     
        // la note est jouée pendant la durée choisie
        for (int i = 0; i < duree; i++) {
          channel.noteOn(note, velocite);
        }
     
        // puis elle est arrêtée.
        channel.noteOff(note);
      }
     
    }
    __________________________________
    | +
    | Sylvain Tournois - Création logicielle
    |
    | sylv.tournois.free.fr
    |

  18. #18
    Futur Membre du Club
    Dans ton code tu joue channels[0] mais tu changes l'instrument de channels[1]. Voilà pourquoi channels[0] reste sur du piano.

    Moi je faisais ça et ça fonctionnait sans problème :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    // changer d'instrument. En paramètre, un i comme instrument.
    public void changeInstrument(int i) {
    channels[0].programChange(i);
    }


    Et j'aurai pu faire ça, avec le canal en paramètre :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    // la même, avec en plus un c comme canal
    public void changeInstrument(int i, int c) {
    c.programChange(i);
    }


    Avec le MIDI, tu peux même changer le tempo de la séquence pendant qu'elle est jouée. Trop puissant le MIDI.

  19. #19
    Membre actif
    toujours po
    J'ai rectifié le channel mais en fait ça ne marche toujours pas, ça fait pareil.

    J'ai regardé si la banque de sons est compatible avec le Synthesizer, elle l'est.

    En fait on dirait que je n'arrive pas à reprogrammer le son par défaut, qui est un son de piano. Même si je commence par un autre instrument, c'est le même topo.

    Par contre quand je change de numéro de canal, j'obtiens des sons différents, mais toujours un seul son par canal.

    Voici où j'en suis :
    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
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
     
    import javax.sound.midi.*;
    import java.io.*;
     
    public class MidiSynthe {
     
      private Synthesizer synthesizer;
      private Soundbank soundBank;
      private Instrument [] instruments;
      private MidiChannel [] channels;
      private MidiChannel current;
     
      public MidiSynthe() throws MidiUnavailableException {
     
        // initialisation midi : on déclare et on ouvre un synthétiseur
        synthesizer = MidiSystem.getSynthesizer();
        synthesizer.open();
     
        // utilisation de la banque de sons par défaut
        soundBank = synthesizer.getDefaultSoundbank();
        if (soundBank == null) {
          try {
            // si pas de banque son par défaut, recherche d'une banque son dans un répertoire utilisateur
            soundBank = MidiSystem.getSoundbank(new File("../lib/soundbank.gm"));
          }
          catch (Exception e) {
            e.printStackTrace();
          }
        }
     
        // obtention d'une liste des instruments contenus dans cette banque de sons
        instruments = soundBank.getInstruments();
     
        // obtention des canaux MIDI contrôlés par ce synthétiseur
        channels = synthesizer.getChannels();
     
        // choix d'un canal
        current = channels[3];
     
        // mise en mémoire des instruments de la banque de sons
        if (synthesizer.isSoundbankSupported(soundBank))
          synthesizer.loadAllInstruments(soundBank);
        else
          System.out.println("ERREUR : Banque de sons incompatible.");
     
        // la note est ensuite jouée
        // paramètres de playNote : le canal, le numéro de la note jouée, la velocité (la vitesse à laquelle on a pressée la touche <img src="images/smilies/icon_wink.gif" border="0" alt="" title=";)" class="inlineimg" />, et enfin la durée (à remplacer par des threads) 
     
        // test des différents instruments de la banque de sons
        for (int i = 200 ; i < instruments.length ; i++) {
     
          // affichage de l'instrument joué
          System.out.println(i + ":" + instruments[i]);
     
          // sélection de l'instrument
          changeInstrument(current, i);
     
          // on joue une note
          playNote(current, 48, 50, 1000);
     
          // on atend le temps que la note soit jouée
          try {
            Thread.sleep(1000);
          }
          catch (Exception e) {
          }
        }
      }
     
      // changer d'instrument
      public void changeInstrument(MidiChannel channel, int j) {
        Instrument i = instruments[j];
        Patch p = i.getPatch();
        channel.programChange(p.getBank(), p.getProgram());
      }
     
      // jouer une note
      public void playNote(MidiChannel channel, int note, int velocite, int duree) {
        /* la durée doit être au moins 1 (même si c'est trop court pour être audible) */
        if (duree <= 0) duree = 1;
     
        // la note est jouée pendant la durée choisie
        for (int i = 0; i < duree; i++) {
          channel.noteOn(note, velocite);
        }
     
        // puis elle est arrêtée.
        channel.noteOff(note);
      }
     
      // test des différents sons MIDI
      public static void main(String[] args) {
        try {
          new MidiSynthe();
        }
        catch (Exception e) {
          e.printStackTrace();
        }
      }
     
    }
    __________________________________
    | +
    | Sylvain Tournois - Création logicielle
    |
    | sylv.tournois.free.fr
    |

  20. #20
    Futur Membre du Club
    Juste pour un test, essaye de remplacer ça :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
     if (synthesizer.isSoundbankSupported(soundBank))
          synthesizer.loadAllInstruments(soundBank);
        else
          System.out.println("ERREUR : Banque de sons incompatible.");


    Par ça :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    synthesizer.loadInstrument(instruments[0]);


    Et ça :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public void changeInstrument(MidiChannel channel, int j) {
        Instrument i = instruments[j];
        Patch p = i.getPatch();
        channel.programChange(p.getBank(), p.getProgram());
     }


    Par ça :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    public void changeInstrument(MidiChannel channel, int i) {
    	channel.programChange(i);
    }

###raw>template_hook.ano_emploi###