2015-09-22 1 views
1

J'essaie d'obtenir Java jouer un son à un certain taux à cet égard, j'essaie d'obtenir un Controll taux d'échantillonnage pour SourceDataLine:type de contrôle non pris en charge: Sample Rate

`package com.pap.sound; 

import javax.sound.sampled.*; 
import java.io.IOException; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.util.BitSet; 

public class Player implements Playable { 
private AudioFormat format; 
private SourceDataLine sourceDataLine; 
private DataLine.Info info; 
private final URL soundUrl; 
private final boolean[] stopped; 
private float playRate; 
private boolean playRateChanged; 


public Player(URL soundUrl) throws LineUnavailableException,  MalformedURLException { 
    this.format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,44100, 16, 2 , 4, 44100,false); 
    this.info = new DataLine.Info(SourceDataLine.class, format); 
    this.sourceDataLine = (SourceDataLine) AudioSystem.getLine(info); 
    this.soundUrl = soundUrl; 
    this.stopped = new boolean[1]; 
    this.stopped[0] = false; 
    this.playRate = 1; 
    this.playRateChanged = false; 
} 
@Override 
public boolean play() throws LineUnavailableException { 
    sourceDataLine.open(); 
    Thread playerThread = new Thread(){ 

     @Override 
     public void run() { 
      int numberOfBitesRead = 0; 
      AudioInputStream auis = null; 
      try { 
       auis = AudioSystem.getAudioInputStream(soundUrl); 
      } catch (UnsupportedAudioFileException e) { 
       e.printStackTrace(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      byte[] bytes = new byte[4]; 
      sourceDataLine.start(); 
      try { 
       auis.mark(auis.available()); 

      while(!stopped[0]) { 

       numberOfBitesRead = auis.read(bytes); 
       if(numberOfBitesRead == -1) { 
        auis.reset(); 
       } 

       sourceDataLine.write(bytes, 0, bytes.length); 
       FloatControl fc = (FloatControl)  sourceDataLine.getControl(FloatControl.Type.SAMPLE_RATE); 
       if(playRateChanged) { 
        fc.setValue((int)(44200*playRate)); 
        playRateChanged = false; 
       } 
      } 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 

    }; 

    playerThread.start(); 

    return false; 
} 

@Override 
public boolean stop() { 
    this.stopped[0] = true; 
    this.sourceDataLine.stop(); 
    this.sourceDataLine.close(); 
    return false; 
} 

@Override 
public boolean setPlayRate(float playRate) { 
    this.playRate = playRate; 
    this.playRateChanged = true; 
    return false; 
} 

} `

Mais à l'exécution je reçois:

Exception in thread "Thread-1" java.lang.IllegalArgumentException: Unsupported control type: Sample Rate 
    at com.sun.media.sound.AbstractLine.getControl(AbstractLine.java:150) 
    at com.pap.sound.Player$1.run(Player.java:67) 

Avez-vous déjà rencontré quelque chose comme ça? J'ai essayé de trouver une réponse pour cela mais je n'ai pas pu en trouver un. J'utilise Java 8. enter image description here Nous vous remercions de votre aide.

+1

ce qui est sourceDataLine et FloatControl? partager le code pour cela ... Créer [MCVE] (http://stackoverflow.com/help/mcve) – StackFlowed

+0

'this.format = new AudioFormat (AudioFormat.Encoding.PCM_SIGNED, 44100, 16, 2, 4, 44100, faux); this.info = new DataLine.Info (SourceDataLine.class, format); this.sourceDataLine = (SourceDataLine) AudioSystem.getLine (info); ' –

+0

@StackFlowed Je suis presque certain qu'ils sont [' SourceDataLine'] (https://docs.oracle.com/javase/8/docs/api/javax/sound/sampled/SourceDataLine.html) et ['FloatControl'] (https://docs.oracle.com/javase/8/docs/api/ javax/sound/sampled/FloatControl.html) de ['javax.sound.sampled'] (https://docs.oracle.com/javase/8/docs/api/javax/sound/sampled/package-summary.html). – TNT

Répondre

0

Finalement, j'ai trouvé une solution. Parce que l'ancien FloatControl.Type.SAMPLE_RATE n'est plus disponible en Java 8 J'ai choisi d'augmenter l'échantillon réer par ommiting simplement certains des octets quand je joue le son de la solution se présente comme suit:

C'est le inferface:

package com.pap.sound; 

import javax.sound.sampled.LineUnavailableException; 


public interface Playable { 
public boolean play() throws LineUnavailableException; 
public boolean stop(); 
public boolean setPlayRate(float playRate); 
} 
Ce

est la classe de joueur:

package com.pap.sound; 

import com.sun.media.sound.AudioFloatFormatConverter; 
import com.sun.media.sound.JavaSoundAudioClip; 
import com.sun.media.sound.SoftMixingDataLine; 

import javax.sound.sampled.*; 
import java.io.IOException; 
import java.net.MalformedURLException; 
import java.net.URL; 


public class Player implements Playable { 
private AudioFormat format; 
private SourceDataLine sourceDataLine; 
private DataLine.Info info; 
private final URL soundUrl; 
private final boolean[] stopped; 
private float playRate; 
private boolean playRateChanged; 
private int bytesWritten; 
private int bytesIgnorred; 


public Player(URL soundUrl) throws LineUnavailableException, MalformedURLException { 
    this.format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,44100, 16, 2 , 4, 44100,false); 
    this.info = new DataLine.Info(SourceDataLine.class, format); 
    this.sourceDataLine = (SourceDataLine) AudioSystem.getLine(info); 
    TargetDataLine tdl = AudioSystem.getTargetDataLine(format); 

    this.soundUrl = soundUrl; 
    this.stopped = new boolean[1]; 
    this.stopped[0] = false; 
    this.playRate = 1; 
    this.playRateChanged = false; 
    this.bytesWritten =0; 
    this.bytesIgnorred = 0; 
} 
@Override 
public boolean play() throws LineUnavailableException { 
    sourceDataLine.open(); 
    final Thread playerThread = new Thread(){ 

     @Override 
     public void run() { 
      int numberOfBitesRead = 0; 
      AudioInputStream auis = null; 
      try { 
       auis = AudioSystem.getAudioInputStream(soundUrl); 
      } catch (UnsupportedAudioFileException e) { 
       e.printStackTrace(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      byte[] bytes = new byte[4]; 
      sourceDataLine.start(); 
      try { 
       auis.mark(auis.available()); 

      while(!stopped[0]) { 

       numberOfBitesRead = auis.read(bytes); 
       if(numberOfBitesRead == -1) { 
        auis.reset(); 
       } 
       if(bytesWritten < (10)) { 
        sourceDataLine.write(bytes, 0, bytes.length); 
        bytesWritten+=4; 
       } else { 
        if(bytesIgnorred < ((int)(playRate*10-10))) { 
         bytesIgnorred+=4; 
        } else { 
         bytesWritten =0; 
         bytesIgnorred = 0; 
        } 
       } 
      } 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 

    }; 

    playerThread.start(); 

    return false; 
} 

@Override 
public boolean stop() { 
    this.stopped[0] = true; 
    this.sourceDataLine.stop(); 
    this.sourceDataLine.close(); 
    return false; 
} 

@Override 
public boolean setPlayRate(float playRate) { 
    this.playRate = playRate; 
    this.playRateChanged = true; 
    return false; 
} 

}

Pour le tester je le code suivant:

package com.pap.main; 

import com.pap.sound.Player; 
import javax.sound.sampled.LineUnavailableException; 
import java.net.MalformedURLException; 
import java.net.URL; 


public class Main { 
public static void main(String[] args) throws MalformedURLException, LineUnavailableException, InterruptedException { 
    URL url = ClassLoader.getSystemClassLoader().getSystemResource("steam.wav"); 
    Player player = new Player(url); 
    player.play(); 
    Thread.sleep(2000); 
    for(int i=0;i<60;i++) { 
     player.setPlayRate(1f+(float)(i)*0.1f); 
     System.out.println(1f+(float)(i)*0.1f + "x"); 
     Thread.sleep(1000); 
    } 
    player.stop(); 
} 

}