Linux + Java Clipの限界?

これまでになんとかClipを使って音を出すことができるようになったので、いよいよ汎用性を高めようと、音の操作を別のクラスにまとめてみた。

ClipPlayer.java
import java.io.*;
import javax.sound.sampled.*;

class ClipPlayer {

   private Clip clip;

  public ClipPlayer(String filename) {
    try {
      AudioInputStream stream = AudioSystem.getAudioInputStream(getClass().getResource(filename));
      AudioFormat format = stream.getFormat();
      DataLine.Info info = new DataLine.Info(Clip.class, format);
      clip = (Clip)AudioSystem.getLine(info);
      clip.open(stream);
      stream.close();
    } catch(Exception e) {
      e.printStackTrace();
    }
  }

  public void play() {
    if(clip != null) {
      if(getPosition() % (getLength() - 1) == 0) {
        clip.stop();
        clip.setFramePosition(0);
      }
      new Thread() {
        public void run() {
          clip.start();
        }
      }.start();
    } else {
      System.out.println("再生できるデータがありません。");
    }
  }

  public void pause() {
    if(clip != null) {
      clip.stop();
    }
  }

  public int getLength() {
    if(clip != null) {
      return clip.getFrameLength();
    } else {
      return 0;
    }
  }

  public long getPosition() {
    if(clip != null) {
      return clip.getLongFramePosition();
    } else {
      return 0;
    }
  }

}


ClipPlayerTest.java
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

class ClipPlayerTest {

  static JFrame frame;
  static JButton playButton, stopButton;
  static JLabel counterLabel;
  static JProgressBar pBar;
  static ClipPlayer cp;

  public static void main(String[] args) {
    cp = new ClipPlayer("sa00101.wav");
    ClipPlayerTest cpt = new ClipPlayerTest();
    frame.setVisible(true);
    int positionInt = 0;
    int maxLength = cp.getLength() - 1;
    while(true) {
      positionInt = (int)cp.getPosition();
      counterLabel.setText(positionInt + "/" + maxLength);
      pBar.setValue((int)positionInt % (maxLength));
      if(positionInt % (cp.getLength() - 1) == 0) {
        playButton.setEnabled(true);
        stopButton.setEnabled(false);
      }
      try {
        Thread.sleep(500);
      } catch(Exception e) {
        e.printStackTrace();
      }
    }
  }

  ClipPlayerTest() {
    frame = new JFrame(getClass().getSimpleName());
    playButton = new JButton("再生");
    stopButton = new JButton("停止");
    stopButton.setEnabled(false);
    ActionListener al = new ActionListener() {
      public void actionPerformed(ActionEvent ae) {
        playButton.setEnabled(!playButton.isEnabled());
        stopButton.setEnabled(!stopButton.isEnabled());
        if(ae.getSource() == playButton) {
          cp.play();
        } else {
          cp.pause();
        }
      }
    };
    playButton.addActionListener(al);
    stopButton.addActionListener(al);
    counterLabel = new JLabel("0", JLabel.RIGHT);
    pBar = new JProgressBar(0, cp.getLength());
    frame.getContentPane().setLayout(new FlowLayout());
    frame.add(playButton);
    frame.add(stopButton);
    frame.add(counterLabel);
    frame.add(pBar);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(350,100);
    frame.setLocationRelativeTo(null);
  }
}

そして、前回の音源ファイル「sa00101.wav」も同じ場所に用意して、次のように実行。

javac *.java
java ClipPlayerTest

無事成功!

実は、これらの実行ファイルと音源ファイルをJARで一つにまとめて扱うことが目標。そこで、これらのファイルのある場所に「mf.txt」というテキストファイルを用意。

mf.txt
Main-Class: ClipPlayerTest

そして、さらに次のように実行。

jar cvfm ClipPlayerTest.jar mf.txt *.class
jar uvf ClipPlayerTest.jar sa00101.wav
java -jar ClipPlayerTest.jar

…あれ?最初の少しだけ再生され、あとは動いているのに音が止まってしまう。

前回の一つのclass内で再生させたものを同じようにJARでまとめると、なんの問題もなく再生できるのに、汎用性を高めようとClipの操作を別ファイルで行うと、JARでまとめた時には音がならなくなる。

色々調べたがさっぱりわからない。もしかしてうまく読み込めていなくて、「clip.open(stream)」の部分を書き換えたら動くのか?と思い、「clip.open(stream)」を消して次のように書いてみた。

byte[] buf = new byte[stream.available()];
stream.read(buf);
clip.open(format, buf, 0, buf.length);

JARにまとめなければ変更前と同様に音はなるが、JARにまとめるとまたすぐに音が止まってしまった。

Clipは一時停止や繰り返しの機能があって便利そうだったが、よくよく考えれば大きなファイルでは困るようなことが書かれているところもあったし、仕方がないのでもう一方で試してみることにする。

探してはみたものの、Clipで扱えるファイルの大きさの限界がどのくらいなのかはよくわからないまま。わかっているのは、外部のclassでClipを操作する方法ではJARにまとめたときに音がならなくなる、という現状。これもLinux + Javaのせい?

コメント
コメントする








   
この記事のトラックバックURL
トラックバック

calendar

S M T W T F S
      1
2345678
9101112131415
16171819202122
23242526272829
3031     
<< July 2017 >>

selected entries

categories

archives

links

profile

書いた記事数:84 最後に更新した日:2016/09/11

search this site.

others

mobile

qrcode

powered

無料ブログ作成サービス JUGEM