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 :

Diminuer le volume d'un flux audio avant de l'enregistrer dans un fichier


Sujet :

Multimédia Java

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Ingénieur de construction de réseaux
    Inscrit en
    Novembre 2014
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur de construction de réseaux
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Novembre 2014
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Diminuer le volume d'un flux audio avant de l'enregistrer dans un fichier
    Bonjour à tous,

    Après pas mal de recherches sur le net sur le sujet, j'ai pu valider un script permettant de "mixer" 2 flux audio. L'objectif est relativement simple : à partir de 2 fichiers audios encodés de manière identique (fichiers wav, 8KHz, 8 bits, mono) et correspondant pour l'un à des paroles et pour l'autre à une musique de fond, être capable d'écrire dans un 3ème fichier le son résultant du "mixage" des 2. Sachant que l'un des postulats de départ est que le second fichier contenant la musique est toujours plus long que le 1er contenant les paroles, on ne conserve qu'une partie de ce second fichier pour le "mixage" des flux (dont la longueur est identique au 1er).

    Je fais pour cela appel à la bibliothèque java MixingAudioInputStream accessible ici.

    Voila le code en question qui fonctionne parfaitement (même si ce n'est pas le plus propre qui existe... je suis loin d'être un vrai développeur ) :

    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
     
    /**
     * Write a description of class main here.
     * 
     * @author (your name) 
     * @version (a version number or a date)
     */
     
    import java.io.*;
    import java.io.FileInputStream;
    import java.util.List;
    import javax.sound.sampled.*;
     
    public class main
    {
    public static void main(String arg[ ]) { 
     
        try {
         // Déclaration des variables utilisées pour le mixage des flux audio
         File file1 = new File(arg[0]);
         File file2 = new File(arg[1]);
         InputStream part1 = new FileInputStream(file1);
         InputStream part2 = new FileInputStream(file2);
         AudioFormat formatAudio = null;
         List audioInputStreamList = new java.util.ArrayList();
         AudioInputStream ais1 = null;
         AudioInputStream ais2 = null;
         AudioInputStream aisTemp = null;
     
         // Déclaration des fichiers
         File fichierTemp = File.createTempFile("wav", "tmp");
         File f = new File("C:/Users/julien.laffitte/final.wav");
         f.setWritable(true);
     
         // Récupération du format audio dans lequel sont enregistrés les prompts
         AudioFileFormat formatFichierAudio = AudioSystem.getAudioFileFormat(new BufferedInputStream(part1));
         AudioFileFormat.Type targetType = formatFichierAudio.getType();
     
         // Création du 1er flux de type "AudioInputStream" utilisé dans la reconstruction
         ais1 = AudioSystem.getAudioInputStream(file1);
     
         // Récupération du format audio dans lequel sont enregistrés les prompts
         formatAudio = ais1.getFormat();
     
         // Création d'un flux temporaire de type "AudioInputStream" utilisé dans la reconstruction à partir de la bande son
         aisTemp = AudioSystem.getAudioInputStream(file2);
     
         // Récupération de la longueur du fichier audio énonçant les horaires
         byte[] bufferTemp = new byte[(int)ais1.getFrameLength()];
         int nbOctetsLus = aisTemp.read(bufferTemp, 0, bufferTemp.length);
     
          // Création du 2nd flux de type "AudioInputStream" utilisé dans la reconstruction : il est coupé à la même durée que le 1er fichier
          ByteArrayInputStream baisTemp = new ByteArrayInputStream(bufferTemp);
          ais2 = new AudioInputStream(baisTemp, formatAudio, bufferTemp.length/formatAudio.getFrameSize());
     
          // Ajout des flux dans une liste
          audioInputStreamList.add(ais1);
          audioInputStreamList.add(ais2);
     
          // Appel de la classe permettant le mixage des flux contenu dans la liste, et dont le format est spécifié en paramètre
          MixingAudioInputStream mixer = new MixingAudioInputStream(formatAudio, audioInputStreamList);
     
          System.out.println("Mixage OK.\n");
     
          System.out.println("Format fichier audio Part1 : " + formatFichierAudio.toString());
          System.out.println("Format fichier Part2 : " + ais1.getFormat().toString());
          System.out.println("Format fichier Part2 : " + ais2.getFormat().toString());
          System.out.println("Format fichier Final : " + mixer.getFormat().toString());
     
          try {
               // Ecriture du flux résultant dans un fichier
              javax.sound.sampled.AudioSystem.write(mixer, formatFichierAudio.getType(), f);
            }
            catch (Exception e) {
                System.err.println("Caught Exception: " + e.getMessage());
            }
        }
        catch (Exception e) {
            System.err.println("Caught Exception: " + e.getMessage());
            System.err.println("Cause: " + e.getCause());
            System.err.println("toString: " + e.toString());
        }
    }
    }
    Le seul souci qui peut arriver ici est que le volume du fond sonore soit un peu fort par rapport aux paroles et vienne les masquer ou en gêne l'écoute.
    J'ai donc cherché à améliorer le code pour réduire le volume automatiquement selon une certaine valeur : j'ai trouvé pour cela la bibliothèque AmplitudeAudioInputStream qui est accessible ici.

    Voila le code que j'ai ajouté pour réaliser cette opération :

    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
     
          [...]
          // Création du 2nd flux de type "AudioInputStream" utilisé dans la reconstruction : il est coupé à la même durée que le 1er fichier
          ByteArrayInputStream baisTemp = new ByteArrayInputStream(bufferTemp);
          ais2 = new AudioInputStream(baisTemp, formatAudio, bufferTemp.length/formatAudio.getFrameSize());
     
          // Création d'un 3ème flux de type "AudioInputStream" dont le volume a été réduit en utilisant le float passé en paramètre de setAmplitudeLinear
          org.tritonus.dsp.ais.AmplitudeAudioInputStream amplifiedAudioInputStream = new org.tritonus.dsp.ais.AmplitudeAudioInputStream(ais2, ais2.getFormat());
          amplifiedAudioInputStream.setAmplitudeLinear(0.4f);
          ais3 = AudioSystem.getAudioInputStream(ais2.getFormat(), amplifiedAudioInputStream);
     
          System.out.println("Réduction volume OK.\n");
     
          // Ajout des flux dans une liste
          audioInputStreamList.add(ais1);
          audioInputStreamList.add(ais3);
     
          // Appel de la classe permettant le mixage des flux contenu dans la liste, et dont le format est spécifié en paramètre
          MixingAudioInputStream mixer = new MixingAudioInputStream(formatAudio, audioInputStreamList);
     
          System.out.println("Mixage OK.\n");
     
          System.out.println("Format fichier audio Part1 : " + formatFichierAudio.toString());
          System.out.println("Format fichier Part2 : " + ais1.getFormat().toString());
          System.out.println("Format fichier Part2 : " + ais2.getFormat().toString());
          System.out.println("Format fichier Final : " + mixer.getFormat().toString());
     
          try {
               // Ecriture du flux résultant dans un fichier
              javax.sound.sampled.AudioSystem.write(mixer, formatFichierAudio.getType(), f);
            }
            catch (Exception e) {
                System.err.println("Caught Exception: " + e.getMessage());
            }
        }
        catch (Exception e) {
            System.err.println("Caught Exception: " + e.getMessage());
            System.err.println("Cause: " + e.getCause());
            System.err.println("toString: " + e.toString());
        }
    }
    }
    Or ce code ne fonctionne pas, l'erreur suivante remonte systématiquement à l'exécution :
    could not write audio file: file type not supported: WAVE; nested exception is: java.lang.IllegalArgumentException: could not write audio file: file type not supported: WAVE

    L'erreur semble indiquer qu'il y a un problème de format, or je valide bien que les formats des différents flux audio sont identiques en les affichant.

    En cherchant j'ai pu mettre le doigt sur la ligne qui pose souci : il s'agit du write à la toute fin du code, qui pourtant fonctionne parfaitement lorsque je n'essaie pas de réduire le volume.

    Est ce que vous auriez une piste pour résoudre ce problème ?

    Merci de votre aide !

  2. #2
    Nouveau Candidat au Club
    Homme Profil pro
    Ingénieur de construction de réseaux
    Inscrit en
    Novembre 2014
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur de construction de réseaux
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Novembre 2014
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Pour compléter les investigations, j'ai ajouté les contrôles suivants :

    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
     
          [...]
          System.out.println("Format fichier audio Part1 : " + formatFichierAudio.toString());
          System.out.println("Format fichier Part1 : " + ais1.getFormat().toString());
          System.out.println("Format fichier Part2 : " + ais2.getFormat().toString());
          System.out.println("Format fichier volume modifié : " + ais3.getFormat().toString());
          System.out.println("Format fichier Final (mixé) : " + mixer.getFormat().toString());
     
          AudioFileFormat.Type[] typesDeFichiers = AudioSystem.getAudioFileTypes(mixer);
          for (int i = 0; i < typesDeFichiers.length ; i++) {
              System.out.println("Format de fichier " + i + " supporté par le flux Final (mixé) : " + typesDeFichiers[i].toString());
          }
     
          System.out.println("Format WAVE est supporté par le flux Final (mixé) : " + AudioSystem.isFileTypeSupported(AudioFileFormat.Type.WAVE, mixer));
     
          System.out.println("Format du fichier de destination : " + (AudioSystem.getAudioFileFormat((java.io.File)f)).toString());      
          AudioInputStream aisFinal = AudioSystem.getAudioInputStream(f);
          System.out.println("Format WAVE est supporté par le fichier de destination : " + AudioSystem.isFileTypeSupported(AudioFileFormat.Type.WAVE, aisFinal));
     
          try {
               // Ecriture du flux résultant dans un fichier
              javax.sound.sampled.AudioSystem.write(mixer, formatFichierAudio.getType(), f);
            }
            catch (Exception e) {
                System.err.println("Caught Exception: " + e.getMessage());
            }
        }
        catch (Exception e) {
            System.err.println("Caught Exception: " + e.getMessage());
            System.err.println("Cause: " + e.getCause());
            System.err.println("toString: " + e.toString());
        }
    }
    }
    Ce qui me donne la sortie suivante :

    Format fichier audio Part1 : WAVE (.wav) file, byte length: 146964, data format: ULAW 8000.0 Hz, 8 bit, mono, 1 bytes/frame, , frame length: 146906
    Format fichier Part1 : ULAW 8000.0 Hz, 8 bit, mono, 1 bytes/frame,
    Format fichier Part2 : ULAW 8000.0 Hz, 8 bit, mono, 1 bytes/frame,
    Format fichier volume modifié : ULAW 8000.0 Hz, 8 bit, mono, 1 bytes/frame,
    Format fichier Final (mixé) : ULAW 8000.0 Hz, 8 bit, mono, 1 bytes/frame,
    Format de fichier 0 supporté par le flux Final (mixé) : WAVE
    Format de fichier 1 supporté par le flux Final (mixé) : AU
    Format de fichier 2 supporté par le flux Final (mixé) : AIFF
    Format WAVE est supporté par le flux Final (mixé) : true
    Format du fichier de destination : WAVE (.wav) file, byte length: 146952, data format: ULAW 8000.0 Hz, 8 bit, mono, 1 bytes/frame, , frame length: 146906
    Format WAVE est supporté par le fichier de destination : true


    D'après les tests j'en conclue que l'écriture devrait pouvoir se faire puisque tout indique que le type WAVE est supporté... et pourtant j'obtiens toujours l'erreur à l'écriture :

    Caught Exception: could not write audio file: file type not supported: WAVE

    Je ne comprends vraiment pas...

Discussions similaires

  1. Réponses: 0
    Dernier message: 13/05/2014, 17h15
  2. Réponses: 3
    Dernier message: 20/10/2013, 15h55
  3. Réponses: 0
    Dernier message: 29/10/2009, 09h57
  4. Réponses: 0
    Dernier message: 29/10/2009, 09h56
  5. Réponses: 2
    Dernier message: 17/04/2007, 11h44

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