2016-01-29 2 views
2

J'ai un problème très spécifique avec JLayer dans mon projet Music-Player. Je veux inclure quelque chose pour ajuster le volume, mais il semble que ce ne soit pas si facile à mettre en œuvre.Modification du volume avec JLayer

Ceci est dû au fait que JLayer ne le prend pas en charge par lui-même. J'ai exclu la classe Player de mon projet et a changé certaines méthodes et cela fonctionne bien pour jouer mp3. Pour régler le volume I ajouté à la classe Player cette méthode:

public boolean setGain(float newGain) { 
     if (audio instanceof JavaSoundAudioDevice) { 
      System.out.println("InstanceOf"); 
      JavaSoundAudioDevice jsAudio = (JavaSoundAudioDevice) audio; 
      try { 
       jsAudio.write(null, 0, 0); 
      } catch (JavaLayerException ex) { 
       ex.printStackTrace(); 
      } 
      return jsAudio.setLineGain(newGain); 
     } 
     return false; 
    } 

Je puis extrait le JavaSoundAudioDevice, décompilé et changé:

public boolean setLineGain(float gain) 
{ 
    System.out.println("Vor Source"); 
    if (source != null) 
    { 
     System.out.println("Nach Source"); 
     FloatControl volControl = (FloatControl) source.getControl(FloatControl.Type.MASTER_GAIN); 
     float newGain = Math.min(Math.max(gain, volControl.getMinimum()), volControl.getMaximum()); 
     volControl.setValue(newGain); 
     return true; 
    } 
    return false; 
} 

Et:

public void createSource() throws JavaLayerException { 
     Throwable t = null; 
     try { 
      Line line = AudioSystem.getLine(getSourceLineInfo()); 
      if (line instanceof SourceDataLine) { 
       source = (SourceDataLine) line; 
       //source.open(fmt, millisecondsToBytes(fmt, 2000)); 
       source.open(fmt); 
       /* 
       if (source.isControlSupported(FloatControl.Type.MASTER_GAIN)) 
       { 
       FloatControl c = (FloatControl)source.getControl(FloatControl.Type.MASTER_GAIN); 
       c.setValue(c.getMaximum()); 
       }*/ 
       source.start(); 
      } 
     } catch (RuntimeException ex) { 
      t = ex; 
     } catch (LinkageError ex) { 
      t = ex; 
     } catch (LineUnavailableException ex) { 
      t = ex; 
     } 
     if (source == null) { 
      throw new JavaLayerException("cannot obtain source audio line", t); 
     } 
    } 

Mais la La méthode createSource, qui était déjà implémentée, ne fonctionne pas. Sur la ligne

Line line = AudioSystem.getLine(getSourceLineInfo()); 

Je reçois toujours un IllegalArgumentException:

java.lang.IllegalArgumentException: No line matching interface SourceDataLine supporting format PCM_SIGNED 0.0 Hz, 16 bit, 0 channels, 0 bytes/frame, little-endian is supported. 
at javax.sound.sampled.AudioSystem.getLine(AudioSystem.java:479) 
at javazoom.jl.player.JavaSoundAudioDevice.createSource(JavaSoundAudioDevice.java:80) 
at javazoom.jl.player.JavaSoundAudioDevice.writeImpl(JavaSoundAudioDevice.java:119) 
at javazoom.jl.player.AudioDeviceBase.write(Unknown Source) 
at MusikPlayer.Erweiterungen.Players.MyPlayer.setGain(MyPlayer.java:192) 
at MusikPlayer.PlayerTest.main(PlayerTest.java:21) 
Exception in thread "main" java.lang.IllegalArgumentException: No line matching interface SourceDataLine supporting format PCM_SIGNED 0.0 Hz, 16 bit, 0 channels, 0 bytes/frame, little-endian is supported. 
    at javax.sound.sampled.AudioSystem.getLine(AudioSystem.java:479) 
    at javazoom.jl.player.JavaSoundAudioDevice.createSource(JavaSoundAudioDevice.java:80) 
    at javazoom.jl.player.JavaSoundAudioDevice.writeImpl(JavaSoundAudioDevice.java:119) 
    at javazoom.jl.player.AudioDeviceBase.write(Unknown Source) 
    at MusikPlayer.Erweiterungen.Players.MyPlayer.decodeFrame(MyPlayer.java:161) 
    at MusikPlayer.Erweiterungen.Players.MyPlayer.play(MyPlayer.java:87) 
    at MusikPlayer.Erweiterungen.Players.MyPlayer.play(MyPlayer.java:66) 
    at MusikPlayer.PlayerTest.main(PlayerTest.java:22) 

Est-ce que quelqu'un sait pourquoi cela se passe? Est-ce que quelqu'un sait comment résoudre ce problème?

+1

Avez-vous commencé à partir de [ccm.libs.javazoom.jl.player.JavaSoundAudioDevice] (https://github.com/CCM-Modding/Pay2Spawn/blob/master/src/main/java/ccm/libs/javazoom /jl/player/JavaSoundAudioDevice.java) sur GitHub? Il semble être open source donc je ne vois pas le besoin de décompiler quelque chose. –

+0

Pour autant que je l'ai comparé, les deux classes sont les mêmes. Je viens de décompiler la classe de ma bibliothèque jlayer dont je dispose: http://www.javazoom.net/javalayer/sources.html – Schesam

+0

Téléchargez le projet depuis GitHub et déboguez-le. Ce problème nécessite une connaissance intime de cette bibliothèque. C'est l'avantage d'être open source: vous pouvez trouver le problème vous-même. –

Répondre

3

Eh bien, je l'ai résolu .. Cette classe de test est utilisé:

public class PlayerTest { 

public static void main(String[] args) { 
    try { 
     File f = new File("D:\\Musik\\Musik-Oberordner\\Favoriten\\06-ich_und_ich_-_so_soll_es_bleiben.mp3"); 
     MyPlayer player = new MyPlayer(new FileInputStream(f)); 
     player.setGain(-30f); 
     player.play(); 
    } catch (JavaLayerException | FileNotFoundException ex) { 
     ex.printStackTrace(); 
    } 

} 

le setten Gain ajuste le volume, de -80.0f à 6f.

Le changement JavaSoundAudioDevice:

package javazoom.jl.player; 

import javax.sound.sampled.AudioFormat; 
import javax.sound.sampled.AudioSystem; 
import javax.sound.sampled.DataLine; 
import javax.sound.sampled.FloatControl; 
import javax.sound.sampled.Line; 
import javax.sound.sampled.LineUnavailableException; 
import javax.sound.sampled.SourceDataLine; 

import javazoom.jl.decoder.Decoder; 
import javazoom.jl.decoder.JavaLayerException; 

/** 
* The <code>JavaSoundAudioDevice</code> implements an audio device by using the 
* JavaSound API. 
* 
* @since 0.0.8 
* @author Mat McGowan 
*/ 
public class JavaSoundAudioDevice extends AudioDeviceBase { 

private SourceDataLine source = null; 
private AudioFormat fmt = null; 
private byte[] byteBuf = new byte[4096]; 

protected void setAudioFormat(AudioFormat fmt0) { 
    fmt = fmt0; 
} 

protected AudioFormat getAudioFormat() { 
//  if (fmt == null) { 
    fmt = new AudioFormat(44100, 
      16, 
      2, 
      true, 
      false); 

    return fmt; 
} 

protected DataLine.Info getSourceLineInfo() { 
    AudioFormat fmt = getAudioFormat(); 
    //DataLine.Info info = new DataLine.Info(SourceDataLine.class, fmt, 4000); 
    DataLine.Info info = new DataLine.Info(SourceDataLine.class, fmt); 
    return info; 
} 

public void open(AudioFormat fmt) throws JavaLayerException { 
    if (!isOpen()) { 
     setAudioFormat(fmt); 
     openImpl(); 
     setOpen(true); 
    } 
} 

public boolean setLineGain(float gain) { 
    System.out.println("Vor Source"); 
    if (source != null) { 
     System.out.println("Nach Source"); 
     FloatControl volControl = (FloatControl) source.getControl(FloatControl.Type.MASTER_GAIN); 
     float newGain = Math.min(Math.max(gain, volControl.getMinimum()), volControl.getMaximum()); 
     volControl.setValue(newGain); 
     return true; 
    } 
    return false; 
} 

public void openImpl() 
     throws JavaLayerException { 
} 

// createSource fix. 
public void createSource() throws JavaLayerException { 
    Throwable t = null; 
    try { 
     Line line = AudioSystem.getLine(getSourceLineInfo()); 
     if (line instanceof SourceDataLine) { 
      source = (SourceDataLine) line; 
      //source.open(fmt, millisecondsToBytes(fmt, 2000)); 
      source.open(fmt); 

//    if (source.isControlSupported(FloatControl.Type.MASTER_GAIN)) 
//    { 
//     System.out.println("Control"); 
//    FloatControl c = (FloatControl)source.getControl(FloatControl.Type.MASTER_GAIN); 
//    c.setValue(c.getMinimum()); 
//    } 
       source.start(); 
     } 
    } catch (RuntimeException ex) { 
     t = ex; 
    } catch (LinkageError ex) { 
     t = ex; 
    } catch (LineUnavailableException ex) { 
     t = ex; 
    } 
    if (source == null) { 
     throw new JavaLayerException("cannot obtain source audio line", t); 
    } 
} 

public int millisecondsToBytes(AudioFormat fmt, int time) { 
    return (int) (time * (fmt.getSampleRate() * fmt.getChannels() * fmt.getSampleSizeInBits())/8000.0); 
} 

protected void closeImpl() { 
    if (source != null) { 
     source.close(); 
    } 
} 

protected void writeImpl(short[] samples, int offs, int len) 
     throws JavaLayerException { 
    if (source == null) { 
     createSource(); 
    } 

    byte[] b = toByteArray(samples, offs, len); 
    source.write(b, 0, len * 2); 
} 

protected byte[] getByteArray(int length) { 
    if (byteBuf.length < length) { 
     byteBuf = new byte[length + 1024]; 
    } 
    return byteBuf; 
} 

protected byte[] toByteArray(short[] samples, int offs, int len) { 
    byte[] b = getByteArray(len * 2); 
    int idx = 0; 
    short s; 
    while (len-- > 0) { 
     s = samples[offs++]; 
     b[idx++] = (byte) s; 
     b[idx++] = (byte) (s >>> 8); 
    } 
    return b; 
} 

protected void flushImpl() { 
    if (source != null) { 
     source.drain(); 
    } 
} 

public int getPosition() { 
    int pos = 0; 
    if (source != null) { 
     pos = (int) (source.getMicrosecondPosition()/1000); 
    } 
    return pos; 
} 

/** 
* Runs a short test by playing a short silent sound. 
*/ 
public void test() 
     throws JavaLayerException { 
//  try { 
     open(new AudioFormat(22000, 16, 1, true, false)); 
     short[] data = new short[22000/10]; 
     write(data, 0, data.length); 
     flush(); 
     close(); 
//  } catch (RuntimeException ex) { 
//   throw new JavaLayerException("Device test failed: " + ex); 
//  } 

    } 
} 

maintenant u doivent tout mettre en œuvre dans ur du projet, remplacer l'ancien JavaSoundDevice et profiter VolumeAdjusting!

+0

Pour résoudre votre propre problème =)> +1 ​​ –

+0

@TT Ce que j'ai eu pendant 19 mois: D Je vois que je me suis amélioré depuis lors – Schesam