2016-03-19 48 views
2

私はゲームで自分のサウンドを再生するためにJLayerを使用しています。私は自分の音楽(常に演奏)と効果音(散発的)のための独立した音量レベルを設定しようとしています。今すぐ私のコードは、マスターボリュームレベルを変更して、期待どおりに両方のボリュームを変更します。ここでは、私がやりたいことを実証するためのサンプルコードをいくつか紹介します(私はSSCCEのようなものをたくさんカットし、いくつかの "バグ"があることを認識しています)。異なる音量で同時にJava mp3を再生

ご協力いただければ幸いです。

public static void playSoundOrMusic(String filename, String type) { 
    String soundFilename = ""; 

    if (type.equals("SFX")){ 
     soundFilename = "res/sounds/sfx/" + filename; 
    } else if (type.equals("MUSIC")){ 
     soundFilename = "res/sounds/music/" + filename; 
    } 

    FileInputStream fis = null; 
    try { 
     fis = new FileInputStream(soundFilename); 
    } catch (FileNotFoundException e) { 
     LOGGER.error("Sound file missing", e); 
    } 
    BufferedInputStream bis = new BufferedInputStream(fis); 

    try { 
     if (type.equals("SFX")){ 
      sfxPlayer = new Player(bis); 
     } else if (type.equals("MUSIC")){ 
      musicPlayer = new Player(bis); 
     } 
    } catch (JavaLayerException e) { 
     LOGGER.error("Sound file issue", e); 
    } catch (ArrayIndexOutOfBoundsException e) { 
     LOGGER.error("Sound file issue", e); 
    } 

    if (type.equals("SFX")){ 
     Info source = Port.Info.SPEAKER; 
     if (AudioSystem.isLineSupported(source)){ 
      try { 
       Port outline = (Port) AudioSystem.getLine(source); 
       outline.open();     
       FloatControl volumeControl = (FloatControl) outline.getControl(FloatControl.Type.VOLUME);     
       volumeControl.setValue(OptionsJPanel.sfxVolume); 
      } catch (LineUnavailableException ex) { 
       LOGGER.error("Sound line issue", ex); 
      } 

      new Thread(new Runnable() { 
       @Override 
       public void run() { 
        try { 
         sfxPlayer.play(); 
        } catch (Exception ex) { 
         LOGGER.error("Sound(sfx) playing issue", ex); 
        } 
       } 
      }).start(); 
     } 
    } 

    if (type.equals("MUSIC")){ 
     Info source = Port.Info.SPEAKER; 
     if (AudioSystem.isLineSupported(source)){ 
      try { 
       Port outline = (Port) AudioSystem.getLine(source); 
       outline.open();     
       FloatControl volumeControl = (FloatControl) outline.getControl(FloatControl.Type.VOLUME);     
       volumeControl.setValue(OptionsJPanel.musicVolume); 
      } catch (LineUnavailableException ex) { 
       LOGGER.error("Sound line issue", ex); 
      } 

      new Thread(new Runnable() { 
       String threadFilename = filename; 
       @Override 
       public void run() { 
        try { 
         musicPlayer.play(); 
         while(!musicPlayer.isComplete()){ 
          Thread.currentThread(); 
          Thread.sleep(1000); 
         } 
         playSoundOrMusic(threadFilename, type); 
        } catch (Exception ex) { 
         LOGGER.error("Sound(music) playing issue", ex); 
        } 
       } 
      }).start(); 
     } 
    } 
} 
+0

@gpasch答えはどこに行きましたか?私はちょうどそれを実装し、それは素晴らしい作品です。奨励金を割り当てることができませんでした:( – KisnardOnline

答えて

2

あなたがバッファリングされた入力ストリームを持っている:あなたはそれを読んで、あなたは、データを操作する(0.5(50%値を下げる))、その後、あなたは新しいストリームに入れて、第二のプレーヤーで再生されます。

BufferedInputStream bis = new BufferedInputStream(fis); 
ByteArrayOutputStream outputStream=new ByteArrayOutputStream(); 
byte[] data=new byte[1024]; 
while((k=audioInputStream.read(data, 0, data.length))>-1) { 
    for(int i=0; i<k; i++) data[i]=(byte)(0.5*data[i]); 
    outputStream.write(data, 0, k); 
} 
byte[] audioData=outputStream.toByteArray(); 
InputStream bis2=new ByteArrayInputStream(outData);  
player2.play(bis2); 

-

ここでファイルを処理して再生されますクラスです。メソッドprocessPlay()は、上記のように一定の割合(0.5)を減らすように調整できます。この割合をパラメータとして独自のメソッドを作成できます。

import javax.sound.sampled.*; 
import java.io.*; 
import java.net.*; 
import javazoom.spi.mpeg.sampled.file.MpegAudioFileReader; 

public class QHPlayer { 

public void play(String f) { 
    int k=0; 
    AudioFormat targetFormat=null; 
    try { 
    AudioInputStream audioInputStream=openFile(f); 
    targetFormat=audioInputStream.getFormat(); 
    byte[] data=new byte[1024]; 
    DataLine.Info dinfo=new DataLine.Info(SourceDataLine.class, targetFormat); 
    SourceDataLine line=null; 
     line=(SourceDataLine)AudioSystem.getLine(dinfo); 
     if(line!=null) { 
     line.open(targetFormat); 
     line.start(); 
     while((k=audioInputStream.read(data, 0, data.length))>-1) { 
      line.write(data, 0, k); 
     } 
     line.stop(); 
     line.close(); 
    } 
    } 
    catch(Exception ex) { ex.printStackTrace(); } 
} 

public void processPlay(String f) { 
    int k=0; 
    AudioFormat targetFormat=null; 
    ByteArrayOutputStream outputStream=new ByteArrayOutputStream(); 
    try { 
    AudioInputStream audioInputStream=openFile(f); 
    targetFormat=audioInputStream.getFormat(); 
    byte[] data=new byte[1024]; 

    while((k=audioInputStream.read(data, 0, data.length))>-1) 
     outputStream.write(data, 0, k); 
    byte[] b=outputStream.toByteArray(); 
    for(k=0; k<b.length; k++) b[k]=(byte)(0.5*b[k]); 


    DataLine.Info dinfo=new DataLine.Info(SourceDataLine.class, targetFormat); 
    SourceDataLine line=null; 
     line=(SourceDataLine)AudioSystem.getLine(dinfo); 
     if(line!=null) { 
     line.open(targetFormat); 
     line.start(); 
     System.out.println(line.available()); 
     k=0; 
     while(k<b.length) { 
     System.out.println(line.available()); 
      int i=line.write(b, k, 8*1024); 
      k+=i; 
     } 
     } 
     line.stop(); 
     line.close(); 
    } 
    catch(Exception ex) { ex.printStackTrace(); } 
} 

public void play(byte[] b) { 
    int k=0; 
    AudioFormat targetFormat=getAudioFormat(); 
    try { 
    DataLine.Info dinfo=new DataLine.Info(SourceDataLine.class, targetFormat); 
    SourceDataLine line=null; 
     line=(SourceDataLine)AudioSystem.getLine(dinfo); 
     if(line!=null) { 
     line.open(targetFormat); 
     line.start(); 
     while(k<b.length) { 
      int i=line.write(b, k, 8*1024); 
      k+=i; 
     } 
     line.stop(); 
     line.close(); 
    } 
    } 
    catch(Exception ex) { ex.printStackTrace(); } 
} 



    public AudioInputStream openFile(String file) { 
    AudioInputStream audioInputStream=null; 
    try { 
     File fileIn = new File(file); 
     if(file.endsWith(".mp3")) 
     audioInputStream=createMp3(fileIn); 
     else 
     audioInputStream=AudioSystem.getAudioInputStream(fileIn); 
    } 
    catch(Exception ex) { ex.printStackTrace(); } 
    return audioInputStream; 
    } 


    AudioInputStream createMp3(File fileIn) throws IOException, Exception { 
    AudioInputStream audioInputStream=null; 
    AudioFormat targetFormat=null; 
    try { 
     AudioInputStream in=null; 
     MpegAudioFileReader mp=new MpegAudioFileReader(); 
     in=mp.getAudioInputStream(fileIn); 
     AudioFormat baseFormat=in.getFormat(); 
     targetFormat=new AudioFormat(
       AudioFormat.Encoding.PCM_SIGNED, 
       baseFormat.getSampleRate(), 
       16, 
       baseFormat.getChannels(), 
       baseFormat.getChannels() * 2, 
       baseFormat.getSampleRate(), 
       false); 
     audioInputStream=AudioSystem.getAudioInputStream(targetFormat, in); 
    } 
    catch(UnsupportedAudioFileException ue) { System.out.println("\nUnsupported Audio"); } 
    return audioInputStream; 
    } 


    AudioFormat getAudioFormat() { 
    float sampleRate = 44100F; 
    int sampleSizeInBits = 16; 
    int channels = 2; 
    boolean signed = true; 
    boolean bigEndian = true; 
    return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed, bigEndian); 
    } 


    public static void main(String args[]) { 
    QHPlayer q=new QHPlayer(); 
    q.processPlay("c:/.....mp3"); 
    } 

} 
+0

私はaudioInputStreamをbisに変更しましたか?int k = 0で追加しました;私はoutDataをaudioDataに変更しましたか?うまくいかなかった - 音楽はすべて文字化けしています。 – KisnardOnline

+0

これはおそらくPlayer – gpasch

+0

と厳密に従う必要があります。プレーヤーが「MPEGストリーム」を再生できると言っています - バイトストリームを再生しないでください - 多分あなたは他の解決策を待つことができます - それ以外の場合はLine – gpasch

関連する問題