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

Langage Java Discussion :

valeur de BUFFER_DURATION


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2008
    Messages
    764
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2008
    Messages : 764
    Par défaut valeur de BUFFER_DURATION
    Bonjour à tous

    Voilà, je fait des essais de création sonore avec le programme ci-dessous.

    A la ligne 84, vous pouvez voir une constante nommée "BUFFER_DURATION". J'ai l'impression que cette dernière détermine la durée d'un morceau de son avant qu'il ne soit repris en boucle pour créer un son continu en sortie (j'explique avec mes mots et selon ce que je comprends du programme, merci de me reprendre si je ne suis pas correct).
    Mon problème est que si je met cette valeur en dessous de 0.426, le son s'arrête au bout d'un temps court (je dirais 426 millisecondes .... par rapport à la valeur de BUFFER_DURATION). Et au-dessus de 0.425, le son sera continu. Je remarque aussi que plus la valeur de BUFFER_DURATION est petite (en dessous de 0.426), plus le son sera court.

    J'aimerai avoir une réponse plus rapide (en fait un retard faible) avec le slider et donc je pense que le mieux serait d'avoir cette BUFFER_DURATION la plus petite possible.
    Par "réponse plus rapide avec le slider", je veux dire que, lorsque je bouge le slider, j'aimerai que le son soit modifié le plus rapidement possible. Or, même en mettant le BUFFER_DURATION à 0.426 (valeur la plus petite possible chez moi pour que le son soit lu en boucle) je ne suis pas satisfait de la réponse.

    Autre question : Y-a-t'il un lien entre les réglages de la JavaVirtualMachine et le BUFFER_DURATION ou la continuité du son en sortie ?

    Merci pour votre aide !

    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
    161
    162
    163
    164
    165
    166
    167
    168
    169
    import java.awt.BorderLayout;
    import java.awt.EventQueue;
    import java.awt.Font;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.nio.ByteBuffer;
     
    import javax.sound.sampled.AudioFormat;
    import javax.sound.sampled.AudioSystem;
    import javax.sound.sampled.DataLine;
    import javax.sound.sampled.LineUnavailableException;
    import javax.sound.sampled.SourceDataLine;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JSlider;
    import javax.swing.SwingConstants;
     
     
    public class JFrame_sliderSine extends JFrame {
     
    	/**
             * 
             */
    	private static final long serialVersionUID = 3481827887325136254L;
     
    	private SampleThread m_thread;
    	private JSlider m_sliderPitch;
     
    	//Launch the app
    	public static void main(String[] args) {
    		EventQueue.invokeLater(new Runnable() {
    			public void run() {
    				try {
    					JFrame_sliderSine frame = new JFrame_sliderSine();
    					frame.setVisible(true);
    				} catch (Exception e) {
    					e.printStackTrace();
    				}
    			}
    		});
    	}
     
    	public JFrame_sliderSine() {
    		//UI stuff, created with WindowsBuilder
    		addWindowListener(new WindowAdapter() {
    			@Override
    			public void windowClosing(WindowEvent e) {
    				m_thread.exit();
    				System.exit(0);
    			}
    		});
     
    		setTitle("Slider Frequency Sine Wave Demo");
    		setResizable(false);
    		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		setBounds(100, 100, 793, 166);
    		setLocationRelativeTo(null);
    		getContentPane().setLayout(new BorderLayout(0, 0));
     
    		m_sliderPitch = new JSlider();
    		m_sliderPitch.setName("");
    		m_sliderPitch.setMinimum(100);
    		m_sliderPitch.setPaintLabels(true);
    		m_sliderPitch.setPaintTicks(true);
    		m_sliderPitch.setMajorTickSpacing(500);
    		m_sliderPitch.setMinorTickSpacing(100);
    		m_sliderPitch.setMaximum(4100);
    		m_sliderPitch.setValue(880);
    		getContentPane().add(m_sliderPitch);
     
    		JLabel lblAdjustPitch = new JLabel("Adjust pitch");
    		lblAdjustPitch.setHorizontalAlignment(SwingConstants.CENTER);
    		lblAdjustPitch.setFont(new Font("Tahoma", Font.PLAIN, 18));
    		getContentPane().add(lblAdjustPitch, BorderLayout.NORTH);
     
    		//Non-UI stuff
    		m_thread = new SampleThread();
    		m_thread.start();
    	}
     
    	class SampleThread extends Thread{
    		final static public int SAMPLING_RATE = 44100;
    		final static public int SAMPLE_SIZE = 2;			//Sample size in bytes
    		final static public double BUFFER_DURATION = 0.426;	//About a 500ms buffer
     
    		//You can play with the size of this buffer if you want.  Making it smaller speeds up
    	    //the response to the slider movement, but if you make it too small you will get 
    	    //noise in your output from buffer underflows, etc...
     
    		// Size in bytes of sine wave samples we'll create on each loop pass 
    		final static public int SINE_PACKET_SIZE = (int)(BUFFER_DURATION * SAMPLING_RATE * SAMPLE_SIZE);
     
    		SourceDataLine line; //$
    		public double fFreq;
    		public boolean bExitThread = false;
     
    		//Get the number of queued samples in the SourceDataLine buffer
    		private int getLineSampleCount() {
    			return line.getBufferSize() - line.available();
    		}
     
    		//Continually fill the audio output buffer whenever it starts to get empty, SINE_PACKET_SIZE/2
    	    //samples at a time, until we tell the thread to exit
    		public void run() {
    			//Position through the sine wave as a percentage (i.e. 0-1 is 0-2*PI)
    			double fCyclePosition = 0;
     
    			//Open up the audio output, using a sampling rate of 44100hz, 16 bit samples, mono, and big 
    	        // endian byte ordering.   Ask for a buffer size of at least 2*SINE_PACKET_SIZE
    			try {
    				AudioFormat format = new AudioFormat(44100, 16, 1, true, true);
    				DataLine.Info info = new DataLine.Info(SourceDataLine.class, format, SINE_PACKET_SIZE * 2);
     
    				if(!AudioSystem.isLineSupported(info)) throw new LineUnavailableException();
     
    				line = (SourceDataLine)AudioSystem.getLine(info);
    				line.open(format);
    				line.start();
    			} catch (LineUnavailableException e){
    				System.out.println("Line of that type is not available");
    				e.printStackTrace();
    				System.exit(-1);
    			}
     
    			System.out.println("Requested line buffer size = " + SINE_PACKET_SIZE*2);
    			System.out.println("Actual line buffer size = " + line.getBufferSize());
     
    			ByteBuffer cBuff = ByteBuffer.allocate(SINE_PACKET_SIZE);
     
    			//On each pass main loop fills the available free space in the audio buffer
    	        //Main loop creates audio samples for sine wave, runs until we tell the thread to exit
    	        //Each sample is spaced 1/SAMPLING_RATE apart in time
    			while(bExitThread == false) {
    				fFreq = m_sliderPitch.getValue();
     
    				double fCycleInc = fFreq / SAMPLING_RATE;	//Fraction of cycle between samples
    				cBuff.clear();								//Toss out samples from previous pass
     
    				//Generate SINE_PACKET_SIZE samples based on the current fCycleInc from fFreq
    				for(int i = 0; i < SINE_PACKET_SIZE / SAMPLE_SIZE; i++){
    					cBuff.putShort((short)(Short.MAX_VALUE * Math.sin(2 * Math.PI * fCyclePosition)));
     
    					fCyclePosition += fCycleInc;
    					if(fCyclePosition > 1) fCyclePosition -= 1;
    				}
    				//Write sine samples to the line buffer
    	            // If the audio buffer is full, this would block until there is enough room,
    	            // but we are not writing unless we know there is enough space.
    				line.write(cBuff.array(), 0, cBuff.position());
     
    				//Wait here until there are less than SINE_PACKET_SIZE samples in the buffer
    	            //(Buffer size is 2*SINE_PACKET_SIZE at least, so there will be room for 
    	            // at least SINE_PACKET_SIZE samples when this is true)
    				try {
    					while(getLineSampleCount() > SINE_PACKET_SIZE) Thread.sleep(1);
    				} catch (InterruptedException e) {
     
    				}
    			}
     
    			line.drain();
    			line.close();
    		}
     
    		public void exit() {
    			bExitThread = true;
    		}
    	}
    }

  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
    Si moi je mets :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    final static public double BUFFER_DURATION = 0.01;
    Alors je ne "percois" plus la latence et la réaction au changement du slider est immédiate.

    Cependant et comme dans tout programme musicaux du genre, si tu as un valeur trop petite (et donc une grand reactivité) le son va commencer a gresiller (ce qui n'est pas bon). Il faut un juste millieu. Et dans certains cas, il faudra tenter de passer par ASIO ou autres système et pas celui de base de ton OS qui a une latence encore plus grande.
    (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 éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2008
    Messages
    764
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2008
    Messages : 764
    Par défaut
    Bonjour,

    Merci pour ces infos intéressantes !

    Je vais faire des recherches sur ASIO !

    si tu as un valeur trop petite (et donc une grand reactivité) le son va commencer a gresiller
    Chez moi le son s'arrête carrément en dessous d'une valeur de 0.426 pour le BUFFER_DURATION.
    D'où pensez-vous que cela vienne.

    Merci

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

Discussions similaires

  1. récupérer la valeur du 2ème champ dans un DBLookUpListBox
    Par jakouz dans le forum Bases de données
    Réponses: 3
    Dernier message: 20/07/2004, 16h45
  2. Recherche fonctions rendant la valeur
    Par Bertrand_Collet dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 26/11/2002, 12h05
  3. récupérer la valeur de sortie d'un thread
    Par jakouz dans le forum Langage
    Réponses: 3
    Dernier message: 31/07/2002, 11h28
  4. [XSLT]position d'un element de valeur specifique
    Par squat dans le forum XSL/XSLT/XPATH
    Réponses: 6
    Dernier message: 25/07/2002, 16h42
  5. Réponses: 2
    Dernier message: 22/07/2002, 18h02

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