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 :

Audio génération et traitement de signal sonore synthé


Sujet :

Java

  1. #1
    Membre très actif

    Homme Profil pro
    Hobbyiste
    Inscrit en
    Juillet 2018
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Hobbyiste

    Informations forums :
    Inscription : Juillet 2018
    Messages : 129
    Billets dans le blog
    1
    Par défaut Audio génération et traitement de signal sonore synthé
    Je voudrais savoir si en java 8 au moins il y a moyen de développer une application audio de qualité. Par exemple faire un oscillateur à 440hz et faire un synthé digital et autres instruments. Sinon quel langage utiliser comme cpp et bibliothèques. J'ai entendu parler de faust mais je voudrais travailler à plus bas niveau
    Même payant éventuellement.
    Je peux donner des exemples de sources.

    Parce que quand je fais un oscillateur à 440Hz j'ai beaucoup de parasites qui cachent le bruit du son sinus.

    Sinon je voudrais trouver un collègue ou un ami qui fait du multimédia en java javafx libre audio 3d ou graphisme programmation disons intermédiaire ou expérimenté car moi je voudrais m'améliorer et arriver à mes objectifs.

  2. #2
    Membre très actif

    Homme Profil pro
    Hobbyiste
    Inscrit en
    Juillet 2018
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Hobbyiste

    Informations forums :
    Inscription : Juillet 2018
    Messages : 129
    Billets dans le blog
    1
    Par défaut Snippets
    Je vais essayer de trouver les meilleurs snippets.

  3. #3
    Modérateur
    Avatar de wax78
    Homme Profil pro
    R&D - Palefrenier programmeur
    Inscrit en
    Août 2006
    Messages
    4 105
    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 105
    Par défaut
    Citation Envoyé par DaTheWolf Voir le message
    Parce que quand je fais un oscillateur à 440Hz j'ai beaucoup de parasites qui cachent le bruit du son sinus.
    Utilises tu la librairie pour le son fournis avec java ?

    Utilises tu un buffer assez grand ? Plus le buffer est petit, plus la latence est petite, mais dans le même temps la machine ne suit pas et tu as des "cracks" et autres bruits bizarre qui arrivent.

    Ton générateur utilises-t-il des tables precalculée au lieu de "Math.sin()" ?
    (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

  4. #4
    Membre très actif

    Homme Profil pro
    Hobbyiste
    Inscrit en
    Juillet 2018
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Hobbyiste

    Informations forums :
    Inscription : Juillet 2018
    Messages : 129
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par wax78 Voir le message
    Utilises tu la librairie pour le son fournis avec java ?

    Utilises tu un buffer assez grand ? Plus le buffer est petit, plus la latence est petite, mais dans le même temps la machine ne suit pas et tu as des "cracks" et autres bruits bizarre qui arrivent.

    Ton générateur utilises-t-il des tables precalculée au lieu de "Math.sin()" ?
    Ça ne marche pas. Et si je comment résoudre ce problème de crachotement?

  5. #5
    Modérateur
    Avatar de wax78
    Homme Profil pro
    R&D - Palefrenier programmeur
    Inscrit en
    Août 2006
    Messages
    4 105
    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 105
    Par défaut
    "Ca ne marche pas ?"

    Si tu essayais déjà de répondre au 3 interrogations que j'ai émise ?
    (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

  6. #6
    Membre très actif

    Homme Profil pro
    Hobbyiste
    Inscrit en
    Juillet 2018
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Hobbyiste

    Informations forums :
    Inscription : Juillet 2018
    Messages : 129
    Billets dans le blog
    1
    Par défaut
    Excuse
    Jai augmenté la valeur de tailles buffer.
    Jai un canvas d'affichage de l'onde ordonné par un thread et un thread oscillateur.
    Mais jai toujours des cracks.
    Buffer ligne 44100*4

    Buffer intermédiaire car je lis les échantillons de oscillateur un par un 44100.

  7. #7
    Modérateur
    Avatar de wax78
    Homme Profil pro
    R&D - Palefrenier programmeur
    Inscrit en
    Août 2006
    Messages
    4 105
    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 105
    Par défaut
    Mmmm assez difficile à dire ainsi.

    Mais peut tu essayer de passer le programme avec un profiler afin de voir éventuellement ou se trouve le temps consommé par le cpu ?

    Si tu désactive l'affichage (et tout ce qui va avec), cela améliore-t-il les choses ?
    (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

  8. #8
    Membre très actif

    Homme Profil pro
    Hobbyiste
    Inscrit en
    Juillet 2018
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Hobbyiste

    Informations forums :
    Inscription : Juillet 2018
    Messages : 129
    Billets dans le blog
    1
    Par défaut
    En fait ce que j'avais bien compris c'est pour l oscillo temps réel. Il faudrait peut-être un timer pour bien mettre 44100 par secondes. En enregistrant dans un fichier ça ne pose pas le même problème. Mais pour le live je crois qu'il faut un "regleur" comme on regle sa montre. non? Ca me saute aux yeux maintenant.

  9. #9
    Modérateur
    Avatar de wax78
    Homme Profil pro
    R&D - Palefrenier programmeur
    Inscrit en
    Août 2006
    Messages
    4 105
    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 105
    Par défaut
    Peut être que tu peux poster un code minimaliste de ton oscillateur afin de voire comment tu as fait et que quelqu'un puisse te répondre ? Car cela dependra de l'api que tu utilises a mon avis.

    A l'époque moi j'utilisais un binding fmod pour java, avec un system de callback dans lequel tu remplissais le buffer sans t'occuper de rien niveau timer etc. Mais tu devais évidement t'arranger pour que le code dans le call back ne prenne pas plus de temps que ce qu'il n'était censé sinon tu avais quelque souci.
    (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

  10. #10
    Membre très actif

    Homme Profil pro
    Hobbyiste
    Inscrit en
    Juillet 2018
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Hobbyiste

    Informations forums :
    Inscription : Juillet 2018
    Messages : 129
    Billets dans le blog
    1
    Par défaut
    Ca c'est le thread "oscillo". La superclasse c'est Processor qui a comme membre 'values' liste de doubles. inputProcessor et outputProcessor liste de thread ascendants et descendants dans le traitement du son et l'enregistrement et la lecture en temps réel (déjà un peu ambitieux, mais "viser haut pour avoir plus"

    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
     
     
        public Oscillator(double frequency, double amplitude, WaveForm waveform) {
            super();
            this.frequency = frequency;
            timer = new NoteTimer();
            this.waveForm = waveform;
            this.amplitude = amplitude;
        }
     
     
        @Override
        public void run() {
     
            timer.init();
            int count = 0;
            while (isRunning()) {
                if (count > 44100 / 10.) {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    count = 0;
                }
                double noteTimeSec = timer.getTotalTimeElapsed() / 1E9;
     
                double positionRatioPerSecond = noteTimeSec;
     
                double f2pi = frequency * 2.0 * Math.PI;
     
                double f2piT = f2pi * positionRatioPerSecond;
     
     
                double ampl = amplitude;
     
                double total = 0;
     
     
                switch (waveForm) {
                    case SIN: // SIN
                        total = (Math.sin(f2piT) * ampl);  //32767 - max value for sample to take (-32767 to 32767)
                        break;
                    case RECT: // RECT
                        total = (Math.signum(Math.sin(f2piT)) * ampl);  //32767 - max value for sample to take (-32767 to 32767)
                        break;
                    case SAWTOOTH: // SAWTOOTH LINEAR
                        total = ((1 - f2piT / 2 * Math.PI) * ampl);  //32767 - max value for sample to take (-32767 to 32767)
                        break;
                    case TRI: // TRIANGLE LINEAR
                        total = ((1 - Math.abs(f2piT / 2 * Math.PI) * ampl));  //32767 - max value for sample to take (-32767 to 32767)
                        break;
                    default: // SIN
                        total = (Math.sin(f2piT) * ampl);  //32767 - max value for sample to take (-32767 to 32767)
                        break;
     
                }
                final double finalTotal = total;
     
                //System.out.println(total);
     
                outProcessors.forEach((s, processor) -> processor.queue(finalTotal));
     
                count++;
            }
     
        }
     
        public boolean isRunning() {
            return running;
        }
     
        public void setRunning(boolean running) {
            this.running = running;
        }
    La sortie sur ligne qui est plus complexe à gérer.
    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
     
    public class OutputProcessToLine extends Processor {
        private final ManagerBuffer managerBuffer;
     
        class ManagerBuffer {
            byte[] buffer = new byte[sampleRate/2];
            int bfIdx = 0;
     
            public byte[] addToBuffer(byte[] buffer4) {
                if (bfIdx < buffer.length - buffer4.length) {
                    for (int i = 0; i < buffer4.length; i++)
                        buffer[bfIdx++] = buffer4[i];
                    return null;
                } else {
                    byte[] copy =
                            Arrays.copyOf(buffer, bfIdx);
                    bfIdx = 0;
                    return copy;
                }
            }
        }
     
        private double amplitudeMax;
        private byte[] nextBuffer ;
     
        private AudioFormat af;
        private SourceDataLine sdl;
        boolean isBigEndian = false;
        boolean isSigned = true;
        int bits = 16;
        int channels = 1;
        int sampleRate = 44100;
     
     
        long offset = 0;
        public void run() {
            af = new AudioFormat(sampleRate, bits, channels, isSigned, isBigEndian);
     
            try {
                // 44,100 samples per second, 16-bit audio, mono, signed PCM, little
                // Endian
                DataLine.Info info = new DataLine.Info(SourceDataLine.class, af);
     
                sdl =  (SourceDataLine)AudioSystem.getLine(info);
                sdl.open(af, 44100 * 16);
            } catch (LineUnavailableException e) {
                System.out.println(e.getMessage());
            }
     
            // no sound gets made before this call
            sdl.start();
     
     
            while (isRunning()) {
                long samplesCount = 0;
                if (values.size() > 400) {
                    while(values.size()>0 && samplesCount<400)
                    {
                    double v = values.removeFirst();
                    byte[] nullOrBufferToPlay = addToBufferMono(v);
     
                    if (nullOrBufferToPlay != null) {
                        offset+=nullOrBufferToPlay.length;
                        try {
                            sdl.write(nullOrBufferToPlay, 0, nullOrBufferToPlay.length);
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        }
     
                        samplesCount++;
                        if (samplesCount % sampleRate == 0)
                            System.out.println("output runs");
                    }
                }
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                    samplesCount=0;
                }
            }
     
            end();
        }
     
        byte[] addToBufferMono(double v) {
            double aD = (amplitudeMax * v);
     
            short a = (short) aD;
            if(nextBuffer.length==2) {
                nextBuffer[0] = (byte) (a & 0x00FF);
                nextBuffer[1] = (byte) ((a & 0xFF00) >> 8);
            }
            if(nextBuffer.length==4) {
                nextBuffer[2] = (byte) (a & 0x00FF);
                nextBuffer[3] = (byte) ((a & 0xFF00) >> 8);
            }
            return managerBuffer.addToBuffer(nextBuffer);
     
        }
     
     
        public OutputProcessToLine(double amplitudeMax) {
            this.amplitudeMax = amplitudeMax;
            managerBuffer = new ManagerBuffer();
            nextBuffer = new byte[channels*2];
            System.out.println("output start");
        }
     
     
        public void end() {
            sdl.drain();
            sdl.stop();
     
        }
    }
    Les valeurs des tailles de buffers et autres sont assez arbitraires à mon point de vue.

    Le schéma d'action dans le main:

    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
    public void run() {
     
                Oscillator os1 = new Oscillator(440, 1, WaveForm.SIN);
                AudioViewer audioViewer = new AudioViewer(44100, 1, app);
                OutputProcessToLine outputProcessToLine = new OutputProcessToLine(50);
                os1.getOutProcessors().put("Drawing samples", audioViewer);
                os1.getOutProcessors().put("Playing 16bits Mono", outputProcessToLine);
                audioViewer.start();
     
                System.out.println("Oscillitor outs: " + os1.getOutProcessors().size());
     
     
                os1.start();
                outputProcessToLine.start();
     
            }

  11. #11
    Membre très actif

    Homme Profil pro
    Hobbyiste
    Inscrit en
    Juillet 2018
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Hobbyiste

    Informations forums :
    Inscription : Juillet 2018
    Messages : 129
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par wax78 Voir le message
    Mmmm assez difficile à dire ainsi.

    Mais peut tu essayer de passer le programme avec un profiler afin de voir éventuellement ou se trouve le temps consommé par le cpu ?

    Si tu désactive l'affichage (et tout ce qui va avec), cela améliore-t-il les choses ?

    Merci.

    Quel profiler choisir pour Java, JavaFX, Jogl et java.sound.sampled ?

    je n'en connais aucun.

  12. #12
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 914
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 914
    Billets dans le blog
    54
    Par défaut
    Pour les profiler, commence déjà par voir ce qui est dispo dans ton IDE.

    J'peux pas dire grand chose pour la partie sonore vue que c'est pas mon domaine et que le code ici n'est pas lançable, mais as-tu fais des recherches Google de ton coté ? En toute logique la partie UI doit pouvoir être totalement découplée de la partie sonore donc tu peux déjà tenter d'arriver a avoir une partie "serveur sonore" qui soit en état de fonctionnement avant de voir pour la partie UI/visue.

    Pour la partie UI, je penserai plutôt aller voir du coté de Canvas/WritableImage histoire de créer un composant bitmap plutôt que de tenter de faire des trucs avec des AreaChart (lenteur CSS + taille de stockage de données + observable + affichage vectoriel me semble un peu casse-gueule). Si ça passe pas en FX sinon voir en Java2D (que ce soit affiché dans du FX ou dans du Swing d'ailleurs, peut importe).

    Pour Jogl aucune idée j'ai jamais fait. Java3D et JavaFX3D me semblent pas mal basiques donc tu vas passer un certains temps a te construire une lib de manips 3D pour arriver a faire ce que tu veux en visues sonores. Après rien n'est impossible (j'trouve pu les vidéos récentes de la NASA sur leur outil de planification des trajectoires -celles que je trouve datent de 2014-2015- donc j'ai mis un truc de biologie marine a la place).
    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

  13. #13
    Membre très actif

    Homme Profil pro
    Hobbyiste
    Inscrit en
    Juillet 2018
    Messages
    129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Hobbyiste

    Informations forums :
    Inscription : Juillet 2018
    Messages : 129
    Billets dans le blog
    1
    Par défaut RUN_INSTRUCTIONS et Explications
    https://gitlab.com/Graphics3D/MyLittleSynth

    Bouye,

    Le code est public et fonctionne seulement bien en IDE depuis un moment.
    - Avec ce qu'il faut un JDK 100(?)% compliant v8 de préférence (mon IDE est sorti avant la v10 et ne fonctionne pas avec JDK10, question commerciale surement.
    - Maven 2
    - Le repository "privé" non publié sur des sources officielles auxquelles apparemment je ne complie pas: https://manudahmen/m2repository ou bientôt sur demoniakmachine.com
    à partir de là un mvn install devrait suffire et les classe à exècuter sont inscrites dans le fichier RUN_INSTRUCTION .... Je ne peux pas de mon côté faire mieux au point de l'exécutabilité du projet.
    En fait il y a deux Main:
    JavaFX et Une API que je voudrais développer plus avant dans la structure de classe et des fonctionnalités.

Discussions similaires

  1. Traitement de signal sonore
    Par taimed dans le forum MATLAB
    Réponses: 3
    Dernier message: 08/11/2017, 12h56
  2. Traitement signal sonore
    Par Jibons dans le forum Traitement du signal
    Réponses: 0
    Dernier message: 07/12/2011, 22h03
  3. [Débutant] Détection sonore(traitement du signal)
    Par zugeur dans le forum Signal
    Réponses: 9
    Dernier message: 24/03/2009, 20h25

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