Javaで効果音を鳴らす時に便利なものを作った


JavaでWAVファイルなんかを流すときはそこまで手間はいらないけど、もう少し楽にやりたいので作ってみた。リソースってことにはしてあるけど、アプレットで使えるかどうかは知らん。デフォルトパッケージでやってる。

//SoundTools.java


import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.HashMap;

import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;

public class SoundTools {
 public Sequencer sequencer;
 MidiDevice msmmapper;
 boolean midimapper=true;
 HashMap semap;
 
 SoundTools(){
 semap=new HashMap();
 }
 
 public void loadSE(String[] filenames){
 for (int i=0;i<filenames.length;i++) {
 int idx=filenames[i].lastIndexOf(".");
 String name;
 if(idx>1)name=filenames[i].substring(0,idx);
 else name=filenames[i];
 byte[] data=fileToByte(filenames[i]);
 semap.put(name,new Sound(data));
 }
 }
 
 public void midiYomikomi(String fname){
 if (sequencer==null) {
 try {
 if(midimapper){
 sequencer=MidiSystem.getSequencer(false);
 midiChange(); 
 }else{
 sequencer=MidiSystem.getSequencer();
 }
 
 sequencer.open();
 } catch (MidiUnavailableException e) {
 e.printStackTrace();
 }
 }
 try {
 Sequence seq=MidiSystem.getSequence(getClass().getResource(fname));
 sequencer.setSequence(seq);
 
 } catch (InvalidMidiDataException e) {
 // TODO 自動生成された catch ブロック
 e.printStackTrace();
 } catch (IOException e) {
 // TODO 自動生成された catch ブロック
 e.printStackTrace();
 }
 }

public void midiChange(){
 MidiDevice.Info[] info=MidiSystem.getMidiDeviceInfo();
 for(int i=0;i<info.length;i++){
 if(info[i].getName().equals("Microsoft MIDI Mapper")){
 try{
 msmmapper=MidiSystem.getMidiDevice(info[i]);
 msmmapper.open();
 sequencer.getTransmitter().setReceiver(msmmapper.getReceiver());
 }catch(MidiUnavailableException e){
 e.printStackTrace();
 }
 }
 }
 }
 public byte[] fileToByte(String fname){
 InputStream fs;
 byte[] array=null;
 try {
 fs=getClass().getResourceAsStream(fname);
 array=new byte[fs.available()];
 fs.read(array);
 
 
 } catch (FileNotFoundException e) {
 e.printStackTrace();
 } catch (IOException e) {
 e.printStackTrace();
 }
 return array;
 }
 
 public Sound getSound(String name){
 return (Sound)semap.get(name);
 }
 public void speedChange(String name,double speed){
 getSound(name).speedChange(speed);
 }
 public void start(String name){
 getSound(name).clp.start();
 }
 public void start(String name,double speed){
 getSound(name).speedChange(speed);
 getSound(name).clp.start();
 }
 public void stop(String name){
 getSound(name).clp.stop();
 }
 public void setPos(String name,long time){
 getSound(name).clp.setMicrosecondPosition(time);
 }
 public long getPos(String name){
 return getSound(name).clp.getMicrosecondPosition();
 }
 public long getLength(String name){
 return getSound(name).clp.getMicrosecondLength();
 }
 public void setZero(String name){
 getSound(name).clp.setFramePosition(0);
 }
 public void loop(String name,int cnt){
 getSound(name).clp.loop(cnt);
 }
}
//Sound
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;


public class Sound {
 public Clip clp;
 byte[] data;
 public Sound(byte[] dt){
 data=dt;
 clp=byteToClip(dt,1.0);
 }
 
 public void speedChange(double speed){
 clp=byteToClip(data,speed);
 }
 
 
 public Clip byteToClip(byte[] array,double speed){
 Clip clip=null;
 try {
 
 int i;
 
 //"fmt "offset+2でch数(2byte)、+4でサンプリングレート(4byte)
 
 for(i=0;i<array.length;i++){
 if(array[i++]!='f')continue;
 if(array[i++]!='m')continue;
 if(array[i++]!='t')continue;
 if(array[i++]!=' ')continue;
 break;
 }
 i+=6;
 int ch=ByteBuffer.wrap(array,i,2).order(ByteOrder.LITTLE_ENDIAN).getShort();
 i+=2;
 int rate=ByteBuffer.wrap(array,i,4).order(ByteOrder.LITTLE_ENDIAN).getInt();
 i+=10;
 int bit=ByteBuffer.wrap(array,i,2).order(ByteOrder.LITTLE_ENDIAN).getShort();
 i+=2;
 
 for(i=0;i<array.length;i++){
 if(array[i++]!='d')continue;
 if(array[i++]!='a')continue;
 if(array[i++]!='t')continue;
 if(array[i++]!='a')continue;
 break;
 }
 int size=ByteBuffer.wrap(array,i,4).order(ByteOrder.LITTLE_ENDIAN).getInt();
 i+=4;
 
 AudioFormat.Encoding ae;
 if(bit!=8){
 ae =AudioFormat.Encoding.PCM_SIGNED;
 }else{
 ae =AudioFormat.Encoding.PCM_UNSIGNED;
 }
 
 rate=(int)(rate*speed);
 
 AudioFormat af = new AudioFormat(ae,rate,bit,ch,ch*(bit/8),rate,false);
 DataLine.Info info=new DataLine.Info(Clip.class,af);
 
 clip=(Clip)AudioSystem.getLine(info);
 
 clip.open(af,array,i,size);
 
 } catch (LineUnavailableException e) {
 e.printStackTrace();
 }
 return clip;
 }
}
//TestSound.java
import java.security.KeyStore.LoadStoreParameter;

import sun.awt.windows.ThemeReader;

public class TestSound {
 
 TestSound(){
 SoundTools st=new SoundTools();
 String[] filenames={"33-4.wav"};
 st.loadSE(filenames);
 st.start("33-4");
 try {
 Thread.sleep(5000);
 } catch (InterruptedException e) {
 // TODO 自動生成された catch ブロック
 e.printStackTrace();
 }
 }
 
 public static void main(String[] args) {
 // TODO 自動生成されたメソッド・スタブ
 TestSound ts =new TestSound(); 
 }

}

まあがんばれ

コメントを残す

メールアドレスが公開されることはありません。