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

Java Discussion :

Un générateur de sons


Sujet :

Java

  1. #1
    Membre expérimenté
    Avatar de anadoncamille
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2007
    Messages
    395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 395
    Billets dans le blog
    1
    Par défaut Un générateur de sons
    Bonjour,

    je veux créer un générateur de sons pour mon jeu vidéo. Je veux que ce générateur produisent divers cris d'oiseaux et d'autres sons d'ambiance. Les générer me permettra d'économiser des ressources mémoire.

    J'ai créé une classe qui génère un ensemble de sons de façon aléatoire, la voici :
    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
     
    import java.nio.*;
    import java.util.*;
    import javax.sound.sampled.*;
     
    public class Sounder implements Runnable {
     
      private static final int SAMPLE_SIZE_IN_BITS = 16;
      private static final int CHANNELS = 2;
      private static final boolean SIGNED = true;
      private static final boolean BIG_ENDIAN = true;
     
      private float SAMPLE_RATE;
      private AudioFormat AUDIO_FORMAT;
      private DataLine.Info LINE_INFO;
     
      private byte[] bytes;
      private ByteBuffer buffer;
      private short valueLeft;
      private short dValueLeft;
      private short valueRight;
      private short dValueRight;
     
      private SourceDataLine line;
     
      private Random random;
     
      public Sounder() {
        random = new Random(System.currentTimeMillis());
     
        SAMPLE_RATE = 44444;
        AUDIO_FORMAT = new AudioFormat(SAMPLE_RATE, SAMPLE_SIZE_IN_BITS, CHANNELS, SIGNED, BIG_ENDIAN);
        LINE_INFO = new DataLine.Info(SourceDataLine.class, AUDIO_FORMAT);
     
        bytes = new byte[10000];
        buffer = ByteBuffer.wrap(bytes, 0, bytes.length);
     
        valueLeft = (short)random.nextInt(1000);
        dValueLeft = (short)random.nextInt(100);
        valueRight = (short)random.nextInt(1000);
        dValueRight = (short)random.nextInt(100);
        try {
          line = (SourceDataLine)AudioSystem.getLine(LINE_INFO);
          line.open();
          line.start();
        }
        catch(Exception e) {
          e.printStackTrace();
        }
        new Thread(this).start();
      }
     
      public void next() {
        int bs = bytes.length / 2;
        int min = random.nextInt(bs / 2);
        int max = random.nextInt(bs / 2) + bs / 2;
        next(min, max);
      }
     
      public void next(int min, int max) {
        for (int i = min ; i < max; i++) {
          dValueLeft += random.nextInt(7) - 3;
          valueLeft += dValueLeft;
          if (Math.abs(valueLeft) >= 16380)
            dValueLeft = (short)-dValueLeft;
          buffer.putShort(i, valueLeft);
     
          dValueRight += random.nextInt(7) - 3;
          valueRight += dValueRight;
          if (Math.abs(valueRight) >= 16380)
            dValueRight = (short)-dValueRight;
          buffer.putShort(i + bytes.length / 2, valueRight);
        }
        line.write(bytes, 0, bytes.length);
      }
     
      public void run() {
        while (true) {
          next();
          try {
            Thread.sleep(50);
          }
          catch (Exception e) {
            e.printStackTrace();
          }
        }
      }
     
      public static void main(String[] args) {
        System.out.println("Brouillon de fond sonore.");
        System.out.println("Appuyez sur Ctrl-C pour terminer le programme.");
        for (int i = 0 ; i < 7 ; i++)
          new Sounder();
      }
     
    }
    J'utilise un codage de son linéaire PCM avec les canaux stéréo. Cependant je ne maitrise pas du tout l'aspect stéréo.
    J'ai essayé deux méthodes :
    - En supposant que le canal gauche et le canal droit sont entrelacés, j'ai codé ainsi la séquence : [gauche][droite][gauche][droite] etc...
    - En supposant que le canal gauche est avant le canal droit ou inversement, j'ai codé la séquence ainsi : [gauche][gauche]...[gauche][droite][droite]...[droite]
    Mais aucune n'a semblé fonctionner.

    Je cherche à comprendre comment encoder les données pour contrôler l'aspect stéréo du son généré.

    Comment dois-je m'y prendre ?

  2. #2
    Modérateur
    Avatar de wax78
    Homme Profil pro
    R&D - Palefrenier programmeur
    Inscrit en
    Août 2006
    Messages
    4 095
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : R&D - Palefrenier programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 095
    Par défaut
    Je ne comprends pas trop ta question entres nous. (EDIT : Si c'est claire en fait c'est moi qui suis un peu mal reveillé)

    Mais une chose est certaine a mon avis (mais cela ne resoudra pas ton probleme pour la cause).

    SAMPLE_RATE = 44444; -> SAMPLE_RATE = 44100;

    Je pense qu'il faut faire [gauche] [droite] [gauche] [droite] [gauche] [droite]...

    Sinon apres une recherche sur google je suis tombé sur :

    http://www.developer.com/java/other/article.php/2226701

    Ou il te donne un exemple comme tu le chercher pour le stereo. (cherche 'Creating a stereo sweep')
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre expérimenté
    Avatar de anadoncamille
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2007
    Messages
    395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 395
    Billets dans le blog
    1
    Par défaut vive la séréo
    Salut,

    Citation Envoyé par wax78 Voir le message
    SAMPLE_RATE = 44444; -> SAMPLE_RATE = 44100;
    Non, le problème ne vient pas de là, il n'y a pas de restriction quant à la fréquence d'échantillonage, sinon la vitesse à laquelle on peut fournir des données. 44100Hz est la valeur standard des gravures CD, qui nous permet d'éviter d'obtenir un son de trop bonne qualité, son que nous avions par la qualité analogique des cassettes et vinyles. En plus, le son numérique peut être filtré par inversion de données (équivalent d'un négatif d'image) pour obtenir un silence artificiel. Cela suppose que les normes soient respectées.
    44100Hz est la norme en vigueur pour la qualité audio, mais on peut utiliser d'autres fréquences.

    Citation Envoyé par wax78 Voir le message
    Je pense qu'il faut faire [gauche] [droite] [gauche] [droite] [gauche] [droite]...
    C'est exactement ça, les données sont entrelacées. L'erreur que j'avais faite était de fournir un mauvais index d'écriture de données. En fait j'écrivais deux octets, puis les deux suivants sur un index qui écrasait un des octets précédents.

    Voici les méthodes corrigées :
    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
     
      public void next() {
        int bs = bytes.length / 4;
        int min = random.nextInt(bs / 2);
        int max = random.nextInt(bs / 2) + bs / 2;
        next(min, max);
      }
     
      public void next(int min, int max) {
        for (int i = min ; i < max; i++) {
          dValueLeft += random.nextInt(19) - 9;
          valueLeft += dValueLeft;
          if (Math.abs(valueLeft) >= 16000)
            dValueLeft = (short)-dValueLeft;
          buffer.putShort(i * 4, valueLeft);
     
          dValueRight += random.nextInt(19) - 9;
          valueRight += dValueRight;
          if (Math.abs(valueRight) >= 16000)
            dValueRight = (short)-dValueRight;
          buffer.putShort(i * 4 + 2, valueRight);
        }
        line.write(bytes, 0, bytes.length);
      }
    Merci

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 29/11/2011, 22h52
  2. API > Interface audio > générateur de son
    Par mastronic dans le forum Windows
    Réponses: 1
    Dernier message: 01/02/2010, 10h03
  3. Réponses: 0
    Dernier message: 27/05/2009, 00h45
  4. Google lance son générateur de sitemap
    Par Kerod dans le forum Webmarketing
    Réponses: 4
    Dernier message: 15/02/2009, 13h48
  5. ecrire son OS (assembleur ??)
    Par Anonymous dans le forum Programmation d'OS
    Réponses: 9
    Dernier message: 25/11/2002, 19h25

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