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] [javax.sound]ou[MIDI]Jouer des sons "à la volée"


Sujet :

Multimédia Java

  1. #1
    Membre confirmé Avatar de Claythest
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    558
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 558
    Points : 554
    Points
    554
    Par défaut [Audio] [javax.sound]ou[MIDI]Jouer des sons "à la volée"
    Bonjour,

    J'essaie de réaliser un logiciel me permettant de jouer de la batterie provenant de Rock Band sur mon ordinateur.

    Pour ce faire, j'ai utilisé JInput pour récupérer les évènements généré par la batterie (qui réagit comme un vulgaire joystick), et je joue les sons avec la bibliothèque javax.sound.

    Au point où j'en suis actuellement, dès que je tape sur un des pads, le son associé est joué. Cependant, si j'en joue 2 en même temps, seul un seul s'exprime. Le comportement souhaité serait que les 2 soient joués indépendamment. Seulement, je ne maitrise pas cette API, et j'en appelle donc à votre aide. Que dois-je faire pour que les sons soient joués indépendamment ?

    Voici mon code :

    Fonction main : écoute les évènements générés par la batterie et ordonne l'exécution des sons associés (si vous n'avez pas de batterie, connectez un joystick de votre choix et modifiez les noms des "components" par ceux correspondant à vos boutons - les récupérer en rajoutant par exemple un else System.out.println(comp.getName()); et en appuyant alors sur les boutons de votre joystick )
    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
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package drums;
     
    import net.java.games.input.Component;
    import net.java.games.input.Controller;
    import net.java.games.input.Controller.Type;
    import net.java.games.input.ControllerEnvironment;
    import net.java.games.input.Event;
    import net.java.games.input.EventQueue;
     
    /**
     *
     * @author claythest
     */
    public class Main {
     
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            Controller[] controllers = ControllerEnvironment.getDefaultEnvironment().getControllers();
            Controller drums = null;
            int i = 0;
            while (i < controllers.length && drums == null) {
                if (controllers[i].getType() == Type.STICK) {
                    drums = controllers[i];
                }
                i++;
            }
            if (drums == null) {
                System.err.print("No Drums connected !");
                System.exit(0);
            }
     
            DrumsPlayer drumsPlayer = new DrumsPlayer();
     
            while (drums.poll()) {
                EventQueue queue = drums.getEventQueue();
                Event event = new Event();
                while (queue.getNextEvent(event)) {
                    Component comp = event.getComponent();
                    float value = event.getValue();
                    if (value == 1.0f) {
                        if (comp.getName().equals("C")) {
                            drumsPlayer.red();
                        } else if (comp.getName().equals("X")) {
                            drumsPlayer.yellow();
                        } else if (comp.getName().equals("A")) {
                            drumsPlayer.blue();
                        } else if (comp.getName().equals("B")) {
                            drumsPlayer.green();
                        } else if (comp.getName().equals("Y")) {
                            drumsPlayer.orange();
                        }
                    }
                }
            }
        }
    }
    Classe DrumPlayer : charge les fichiers sons (pour éviter de les ouvrir/fermer à chaque utilisation) et exécute les sons en utilisant les bons paramètres (le SourceDataLine et les bytes des fichiers à écrire dans le SourceDataLine) :
    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
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package drums;
     
    import java.io.File;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.sound.sampled.AudioFormat;
    import javax.sound.sampled.AudioInputStream;
    import javax.sound.sampled.AudioSystem;
    import javax.sound.sampled.DataLine;
    import javax.sound.sampled.LineUnavailableException;
    import javax.sound.sampled.SourceDataLine;
    import javax.sound.sampled.UnsupportedAudioFileException;
     
    /**
     *
     * @author claythest
     */
    public class DrumsPlayer {
     
        public static final int RED_PAD = 0;
        public static final int YELLOW_PAD = 1;
        public static final int BLUE_PAD = 2;
        public static final int GREEN_PAD = 3;
        public static final int ORANGE_PAD = 4;
        private static final String[] SOUND_FILES = new String[]{"snare.wav", "hihat.wav", "bass.wav", "crash.wav", "kick.wav"};
        private static final int BYTES_BUFFER_SIZE = 524288;  // 128Kb
        private SourceDataLine[] sourcesDataLine;
        private AudioFormat[] formats;
        private List<byte[]>[] soundsBytes;
     
        public DrumsPlayer() {
            loadSoundsFiles();
        }
     
        private void loadSoundsFiles() {
            soundsBytes = new ArrayList[5];
            sourcesDataLine = new SourceDataLine[5];
            formats = new AudioFormat[5];
            for (int i = 0; i < 5; i++) {
                AudioInputStream audioInputStream = null;
                try {
                    soundsBytes[i] = new ArrayList<byte[]>();
                    File soundFile = new File(SOUND_FILES[i]);
                    audioInputStream = AudioSystem.getAudioInputStream(soundFile);
                    AudioFormat format = audioInputStream.getFormat();
                    DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
                    SourceDataLine auline = (SourceDataLine) AudioSystem.getLine(info);
                    System.out.println(auline);
                    formats[i] = format;
                    sourcesDataLine[i] = auline;
                    int nBytesRead = 0;
                    byte[] abData = new byte[BYTES_BUFFER_SIZE];
                    while (nBytesRead != -1) {
                        nBytesRead = audioInputStream.read(abData, 0, abData.length);
                        if (nBytesRead >= 0) {
                            abData = Arrays.copyOf(abData, nBytesRead);
                            soundsBytes[i].add(abData);
                        }
                    }
                } catch (LineUnavailableException ex) {
                    Logger.getLogger(DrumsPlayer.class.getName()).log(Level.SEVERE, null, ex);
                } catch (UnsupportedAudioFileException ex) {
                    Logger.getLogger(DrumsPlayer.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IOException ex) {
                    Logger.getLogger(DrumsPlayer.class.getName()).log(Level.SEVERE, null, ex);
                } finally {
                    try {
                        audioInputStream.close();
                    } catch (IOException ex) {
                        Logger.getLogger(DrumsPlayer.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
        }
     
        public void red() {
            new DrumNote(soundsBytes[RED_PAD], sourcesDataLine[RED_PAD], formats[RED_PAD]);
        }
     
        public void yellow() {
            new DrumNote(soundsBytes[YELLOW_PAD], sourcesDataLine[YELLOW_PAD], formats[YELLOW_PAD]);
        }
     
        public void blue() {
            new DrumNote(soundsBytes[BLUE_PAD], sourcesDataLine[BLUE_PAD], formats[BLUE_PAD]);
        }
     
        public void green() {
            new DrumNote(soundsBytes[GREEN_PAD], sourcesDataLine[GREEN_PAD], formats[GREEN_PAD]);
        }
     
        public void orange() {
            new DrumNote(soundsBytes[ORANGE_PAD], sourcesDataLine[ORANGE_PAD], formats[ORANGE_PAD]);
        }
    }
    DrumNote : joue la note dans un nouveau thread en utilisant la méthode write du SourceDataLine :
    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
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package drums;
     
    import java.util.List;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.sound.sampled.AudioFormat;
    import javax.sound.sampled.LineUnavailableException;
    import javax.sound.sampled.SourceDataLine;
     
    /**
     *
     * @author claythest
     */
    public class DrumNote implements Runnable {
     
        private List<byte[]> toRead;
        private SourceDataLine auline;
        private AudioFormat format;
     
        public DrumNote(List<byte[]> toRead, SourceDataLine auline, AudioFormat format) {
            this.toRead = toRead;
            this.auline = auline;
            this.format = format;
            new Thread(this).start();
        }
     
        public void run() {
            try {
                auline.open(format);
                auline.start();
                for (int i = 0; i < toRead.size(); i++) {
                    byte[] abData = toRead.get(i);
                    auline.write(abData, 0, abData.length);
                }
                auline.drain();
                auline.close();
            } catch (LineUnavailableException ex) {
                Logger.getLogger(DrumNote.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
    Pour lancer ce programme, il vous faut télécharger l'API JInput (attention au classpath qui a besoin de localiser le .jar et les dll ou .so). Je mets aussi en pièce jointe les différents sons (au format wav) utilisés.

    Merci d'avance pour votre aide
    Fichiers attachés Fichiers attachés

  2. #2
    Membre confirmé Avatar de Claythest
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    558
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 558
    Points : 554
    Points
    554
    Par défaut
    Après réflexion, il se peut que la bibliothèque javax.sound ne permette pas de faire cela... Dois-je utiliser une autre API ? Laquelle ?

  3. #3
    Membre confirmé Avatar de Claythest
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    558
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 558
    Points : 554
    Points
    554
    Par défaut
    Bon j'ai changé de mécanisme, j'ai finalement opté pour le Midi.

    J'arrive à jouer des sons en même temps, seulement maintenant, ce sont les temps de réponses qui ne me satisfont pas...

    Voici le code :

    Classe principale, ayant le même rôle que précédemment, sauf que j'ai ajouté (pour faciliter le debugging) mon joystick afin de pouvoir jouer les notes directement en utilisant les boutons (pas besoin de brancher la batterie dessus pour tester).
    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
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package drums;
     
    import net.java.games.input.Component;
    import net.java.games.input.Controller;
    import net.java.games.input.Controller.Type;
    import net.java.games.input.ControllerEnvironment;
    import net.java.games.input.Event;
    import net.java.games.input.EventQueue;
     
    /**
     *
     * @author claythest
     */
    public class Main {
     
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            Controller[] controllers = ControllerEnvironment.getDefaultEnvironment().getControllers();
            Controller drums = null;
            int i = 0;
            while (i < controllers.length && drums == null) {
                if (controllers[i].getType() == Type.STICK) {
                    drums = controllers[i];
                }
                i++;
            }
            if (drums == null) {
                System.err.print("No Drums connected !");
                System.exit(0);
            } else {
                System.out.println(drums.getName());
            }
     
            DrumsPlayer drumsPlayer = new DrumsPlayer();
     
            while (drums.poll()) {
                EventQueue queue = drums.getEventQueue();
                Event event = new Event();
                while (queue.getNextEvent(event)) {
                    Component comp = event.getComponent();
                    float value = event.getValue();
                    if (value == 1.0f) {
                        if (comp.getName().equals("C")) {
                            drumsPlayer.red();
                        } else if (comp.getName().equals("X")) {
                            drumsPlayer.yellow();
                        } else if (comp.getName().equals("A")) {
                            drumsPlayer.blue();
                        } else if (comp.getName().equals("B")) {
                            drumsPlayer.green();
                        } else if (comp.getName().equals("Y")) {
                            drumsPlayer.orange();
                        } else if (comp.getName().equals("Trigger")) { // gestion de mon joystick
                            drumsPlayer.red();
                        } else if (comp.getName().equals("Thumb")) {
                            drumsPlayer.yellow();
                        } else if (comp.getName().equals("Thumb 2")) {
                            drumsPlayer.blue();
                        } else if (comp.getName().equals("Top")) {
                            drumsPlayer.green();
                        } else if (comp.getName().equals("Pinkie")) {
                            drumsPlayer.orange();
                        }
                    }
                }
            }
        }
    }

    Le Drum player : ouvre le channel correspondant à la batterie (le 9), et initialise les différents paramètres Midi (ouverture du synthétiseur, récupération du canal Midi 9).
    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
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package drums;
     
    import javax.sound.midi.MidiChannel;
    import javax.sound.midi.MidiSystem;
    import javax.sound.midi.MidiUnavailableException;
    import javax.sound.midi.Synthesizer;
     
    /**
     *
     * @author claythest
     */
    public class DrumsPlayer {
     
        public static final int RED_PAD = 0;
        public static final int YELLOW_PAD = 1;
        public static final int BLUE_PAD = 2;
        public static final int GREEN_PAD = 3;
        public static final int ORANGE_PAD = 4;
        private static final int DRUM_CHANNEL = 9;
        private MidiChannel midiChannel;
        private int[] notes;
        private int[] velocities;
     
        public DrumsPlayer() {
            notes = new int[5];
            notes[RED_PAD] = 37;
            notes[YELLOW_PAD] = 44;
            notes[BLUE_PAD] = 43;
            notes[GREEN_PAD] = 49;
            notes[ORANGE_PAD] = 35;
     
            velocities = new int[5];
            velocities[RED_PAD] = 100;
            velocities[YELLOW_PAD] = 100;
            velocities[BLUE_PAD] = 100;
            velocities[GREEN_PAD] = 100;
            velocities[ORANGE_PAD] = 100;
     
            Synthesizer synth = null;
            try {
                synth = MidiSystem.getSynthesizer();
            } catch (MidiUnavailableException e) {
                e.printStackTrace();
                System.exit(1);
            }
     
            try {
                synth.open();
            } catch (MidiUnavailableException e) {
                e.printStackTrace();
                System.exit(1);
            }
            MidiChannel[] channels = synth.getChannels();
            midiChannel = channels[DRUM_CHANNEL];
        }
     
        public void red() {
            playNote(RED_PAD);
        }
     
        public void yellow() {
            playNote(YELLOW_PAD);
        }
     
        public void blue() {
            playNote(BLUE_PAD);
        }
     
        public void green() {
            playNote(GREEN_PAD);
        }
     
        public void orange() {
            playNote(ORANGE_PAD);
        }
     
        private void playNote(int padColor) {
            new DrumNote(midiChannel, notes[padColor], velocities[padColor]);
        }
    }

    Mes notes : toujours des threads, qui se contentent d'exécuter la méthode noteOn sur le midi channel
    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
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package drums;
     
    import javax.sound.midi.MidiChannel;
     
    /**
     *
     * @author claythest
     */
    public class DrumNote implements Runnable {
     
        private MidiChannel midiChannel;
        private int note;
        private int velocity;
     
        public DrumNote(MidiChannel midiChannel, int note, int velocity) {
            this.midiChannel = midiChannel;
            this.note = note;
            this.velocity = velocity;
            new Thread(this).start();
        }
     
        public void run() {
            midiChannel.noteOn(note, velocity);
        }
    }
    Je perçois donc un certain temps de latence entre le moment ou j'appuie sur le bouton et le moment où j'entends le son... Temps de latence assez gênant lorsque je joue avec la batterie...


    Si quelqu'un a une idée sur comment améliorer mes temps de réponse, qu'il se montre !

    Merci d'avance

  4. #4
    Membre confirmé Avatar de Claythest
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    558
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 558
    Points : 554
    Points
    554
    Par défaut
    http://www.jsresources.org/faq_midi....reduce_latency

    J'ai trouvé une bonne piste... Je teste ça ce soir...

  5. #5
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    Tu nous diras si ça a marché et comment tu as fait.

    Ca pourra servir à d'autres personnes... (vu qu'ici, il n'y a pas trop de spécialiste du Java sound).

  6. #6
    Membre confirmé Avatar de Claythest
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    558
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 558
    Points : 554
    Points
    554
    Par défaut
    Ben pour le moment, je suis au point mort...

    J'ai recherché des synthesizers hardware (car si j'ai bien tout compris, toutes les cartes sons ont un synthesizer MIDI) en suivant les indications écrites sur le lien ci dessus.

    J'ai donc combiné MidiSystem.getMidiDeviceInfo() pour lister tous les Device MIDI sur ma machine et MidiSystem.getDevice(MidiDevice.Info info) pour récupérer le device, seulement aucun de mes "device" n'est un synthesizer... sauf un (le premier device récupéré) mais qui ne change rien au problème (j'ai pas fouillé non plus, mais si ça se trouve, c'est celui que me renvoie la méthode MidiSystem.getSynthsizer() ...).

    Donc je dois continuer à fouiller, car je vais devoir apprendre à utiliser autre chose qu'un synthesizer pour jouer des notes MIDI... ou alors, va falloir que j'apprenne en détail le fonctionnement de cette API, car j'avoue avancer dans le brouillard...

    Si quelqu'un de passage sur ce topic sait faire ou a une piste, qu'il n'hésite surtout pas


    P.S. : désolé pour ce franglais, mais comme la doc est anglaise et que je ne maitrise pas le sujet (je ne sais pas ce qu'est concrètement un synthesizer), ben je préfère utiliser le vocabulaire anglais

  7. #7
    Membre confirmé Avatar de Claythest
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    558
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 558
    Points : 554
    Points
    554
    Par défaut
    Bon ben après moultes recherches, il me faut un synthesizer hardware et rien d'autre... Or sur ma machine, je n'en ai pas... Et apparemment, le seul moyen d'en avoir un, c'est de changer sa carte son...

    http://www.dreamincode.net/forums/showtopic17508.htm

    Donc ben, je dois laisser tomber MIDI et java.sound.sample... Pour me tourner vers quoi ?

    J'aimerai rester dans le monde du Java pour cette petite application... Pourtant il existe bien des jeux Java avec musique de fond + bruitages sans aucun temps de latence... Si quelqu'un pouvait me guider, ce serait cool de sa part

  8. #8
    Membre confirmé Avatar de Claythest
    Profil pro
    Inscrit en
    Mai 2003
    Messages
    558
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2003
    Messages : 558
    Points : 554
    Points
    554
    Par défaut
    Bon, finalement, en remodifiant la première version (avec les fichiers sons) je suis arrivé à faire quelque chose (merci spécial à un ami pour son aide...).

    Voici les sources (La classe Main ne change pas).

    DrumPlayer :
    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
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package drums;
     
    import java.io.File;
     
    /**
     *
     * @author claythest
     */
    public class DrumsPlayer {
     
        public static final int RED_PAD = 0;
        public static final int YELLOW_PAD = 1;
        public static final int BLUE_PAD = 2;
        public static final int GREEN_PAD = 3;
        public static final int ORANGE_PAD = 4;
        private static final DrumNote[] NOTES = new DrumNote[]{new DrumNote(new File("snare.wav")), new DrumNote(new File("hihat.wav")), new DrumNote(new File("bass.wav")), new DrumNote(new File("crash.wav")), new DrumNote(new File("kick.wav"))};
     
        public DrumsPlayer() {
        }
     
        public void red() {
            play(RED_PAD);
        }
     
        public void yellow() {
            play(YELLOW_PAD);
        }
     
        public void blue() {
            play(BLUE_PAD);
        }
     
        public void green() {
            play(GREEN_PAD);
        }
     
        public void orange() {
            play(ORANGE_PAD);
        }
     
        private void play(int pad) {
            NOTES[pad].play();
        }
    }
    La clase DrumNote :
    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
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    package drums;
     
    import java.io.File;
    import java.io.IOException;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.sound.sampled.AudioFormat;
    import javax.sound.sampled.AudioInputStream;
    import javax.sound.sampled.AudioSystem;
    import javax.sound.sampled.DataLine;
    import javax.sound.sampled.LineUnavailableException;
    import javax.sound.sampled.SourceDataLine;
    import javax.sound.sampled.UnsupportedAudioFileException;
     
    /**
     *
     * @author claythest
     */
    public class DrumNote implements Runnable {
     
        private File soundFile;
     
        public DrumNote(File soundFile) {
            this.soundFile = soundFile;
        }
     
        public void play() {
            new Thread(this).start();
        }
     
        @Override
        public void run() {
            AudioInputStream audioInputStream = null;
            try {
                audioInputStream = AudioSystem.getAudioInputStream(soundFile);
                AudioFormat audioFormat = audioInputStream.getFormat();
                DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
                SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);
                line.open(audioFormat);
                line.start();
                byte[] bytes = new byte[1024];
                int bytesRead = 0;
                while ((bytesRead = audioInputStream.read(bytes, 0, bytes.length)) != -1) {
                    line.write(bytes, 0, bytesRead);
                }
                line.close();
            } catch (LineUnavailableException ex) {
                Logger.getLogger(DrumNote.class.getName()).log(Level.SEVERE, null, ex);
            } catch (UnsupportedAudioFileException ex) {
                Logger.getLogger(DrumNote.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException ex) {
                Logger.getLogger(DrumNote.class.getName()).log(Level.SEVERE, null, ex);
            } finally {
                try {
                    audioInputStream.close();
                } catch (IOException ex) {
                    Logger.getLogger(DrumNote.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }
    En fait le problème de ma première solution, c'est que je préchargeais les octets des fichiers sons... Pour une raison que j'ignore encore, il ne fallait pas... Il faut lire le fichier (méthode read sur le AudioInputStream) et l'envoyer sur la SourceLine... Lire les octets, les conserver, et les envoyer sur la SourceLine ne permettait pas de lire 2 sons en même temps... Je comprends pas pourquoi...

    Toujours est-il que cela fonctionne désormais, je peux jouer 2 sons en même temps (il y a juste un son qui ne fonctionne, le jaune, mais c'est encore très obscur ça, et vu l'heure, je verrais demain...).

    Manque plus qu'une petite interface pour configurer le tout, et j'aurai enfin mon logiciel me permettant de jouer de la batterie Rock Band sur mon PC

    Fin du monologue

  9. #9
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 084
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chef programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 084
    Points : 7 995
    Points
    7 995
    Par défaut
    Tu n'essayerais pas FMOD si tu veux du "rapide" et du plus puissant que javax.sound ?
    (en utilise NativeFMODex de jouvieje http://jerome.jouvie.free.fr/index.php).

    Je m'en suis servi à plusieurs reprises pour faire des synthetiseurs (C++ et java), acceptant le midi (j'ai utilisé la meme chose que toi pour recevoir les informations midi). J'ai une tres faible latence genre qlq ms je pense entre le moment ou j'appuyez sur la touche du clavier midi et le son que j'entends.

    J'ai aussi un programme qui ecoute sur le midi et qui joue des Samples exactement comme pour ton programme et franchement c'etait impeccable. Je pouvais jouer >16 pistes (sons) en meme temps avec bcp de succes.
    (http://renaud.warnotte.be/Projects/Wax%20Sequencer/ pour le sequenceur Midi et le lecteur de samples, mais le site est down pour le moment)

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 05/08/2009, 04h51
  2. Jouer des sons
    Par christophe63 dans le forum Signal
    Réponses: 9
    Dernier message: 05/01/2007, 16h59
  3. [VB.Net 2003] jouer des sons
    Par damned3 dans le forum Windows Forms
    Réponses: 2
    Dernier message: 02/12/2006, 05h30
  4. Comment jouer des sons dans un programme ???
    Par aldur_disciple dans le forum MFC
    Réponses: 8
    Dernier message: 17/08/2005, 12h10

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