Java 오디오 재생은 로컬 환경에 의존해야하므로 Java는 오디오 프로세싱에 거의 장점이 없거나, 즉 Java 시스템을 개발할 때 오디오 재생 요소를 고려하지 않습니다. 가장 빠른 Java 1.1 버전에는 나중에 javax.sound 패키지가 없으며 오디오는 애플릿 패키지를 통해서만 검색 할 수 있음을 알아야합니다.
불행하게도, 그래픽 프로그램의 개발에서 우리의 프로그램은 필연적으로 이미지 작업과 협력하기 위해 배경 음악, 효과 사운드 등을 사용해야합니다. 아아, 이것은 마스터 선이 우리에게 연기 한 농담입니다. 다행스럽게도 Mas
그러나 후속 문제는 Java Multimedia Tool Class의 일반적인 문제와 마찬가지로 Javax.sound 패키지를 사용하는 데있어 완전한 릴리스 메커니즘이 없다는 것입니다. Windows 개발을 수행하면 MediaPlayer에게 전화를 걸면 큰 문제가되지 않을 수도 있지만 Java에서는 오디오 프로그램이 반복적으로 실행되면 메모리 누적 손실을 경험하기가 매우 쉽습니다.
이것은 이미 "허용 가능한"문제입니까? 이를 고려하여 Loonframework Framework Development에서 Sound에서 관련 메소드를 2 차 통합하여 가장 간단한 코드로 가장 완전한 오디오 제어 클래스를 만들기 위해 노력했습니다. Loonframework 게임이 아직 큰 성공을 거두지 못했기 때문에 먼저 당신이 그들을 살펴볼 수있는 몇 가지 방법을 추출 할 것입니다!
네트워크 리소스 호출에 해당하는 자체 URI 클래스는 LoonFramework에서 설정됩니다. 기본 내용은 다음과 같습니다.
(Streamhelper가 loonframework의 자체 스트리밍 제어 클래스 인 경우 GethttPStream 메소드를 직접 교체하십시오.)
package org.loon.framework.game.net; import org.loon.framework.game.game.helper.streamHelper;/** * // ** ** * // ** ** * // ** ** ** ** ** ** ** * <p> * 제목 : loonframework * </p> * <p> * 설명 : loonframwork 전담 uri (Unified Resource Identifier) * </p> * <p> * * Copyright : Copyyright : Copyyright. <p> * Company : loonframework * </p> * * * @author chenpeng * @email : [email protected] * @version 0.1 */public class uri ... {// 전송 프로토콜 유형 public static final int _l_uri_http = 1; 공개 정적 최종 INT _L_URI_UDP = 2; 개인 문자열 _URI; 개인 int _type; /** * // ** * Destructor, URI를 주입하고 유형을 유형하는 데 사용됩니다 * * @param uri * @param type */public uri (String uri, int type) ... {_uri = new String (uri); _type = 유형; }/** * // ** * Destructor, uri * * @param type uri */public uri (String uri)를 주입하는 데 사용됩니다 ... {_uri = new String (uri); _type = uri._l_uri_http; }/*** // *** URI가있는 자원의 바이트 배열을 반환합니다. * * @return */ public byte [] getData () ... {if (_uri == null) ... {return null; } return Stremhelper.gethttpStream (_URI); } public String getUri () ... {return _URI; } public int gettype () ... {return _type; }} loonframework 프레임 워크에서 기본 사운드 데이터 클래스는 오디오 데이터 소스를 균일하게 관리하도록 사용자 정의됩니다. 패키지 org.loon.framework.game.sound; import org.loon.framework.game.helper.streamhelper; import org.loon.framework.game.net.uri;/** ** ** * <p> * 제목 : loonframwork * </p> * <p> * 설명 : LoonFramewnework.loon.framework.game.net.uri;/** * <p> * 설명 : Loonframewnework * <p> * 설명 : Loonfram Sount 및 Cache Soin (See-Good and Cache). 프레임 워크) * </p> * <p> * 저작권 : 저작권 (c) 2007 * </p> * <p> * 회사 : loonframework * </p> * * * @author chenpeng * @email : [email protected] * @version 0.1 */public class sounddata ... {private byte [] _data; 개인 부울 _loop; 개인 int _type; 공개 정적 최종 int _l_soundtype_midi = 1; 공개 정적 최종 int _l_soundtype_wav = 2; /** * // ** * Destructor, uri, type, loop * * @param uri * @param loop */public sounddata (uri uri, int type, boolean loop) ... {if (uri! = null) ... {_data = uri.getData (); } _type = 유형; _loop = 루프; }/** * // ** * Destructor, 데이터를 주입, 유형, 루프 * * @param data * @param loop */public sounddata (byte [] data, int type, boolean loop) ... {if (data! = null && data.length> 0) ... // 직접 복사 바이트 배열 System.ArrayCopy (data, 0, _data, 0, _data.length); } _type = 유형; _loop = 루프; }/** * // ** * Destructor, Resname을 주입, 유형, loop * @param resname * @param loop */public sounddata (String resname, int type, boolean loop) ... } public byte [] getData () ... {return _data; } public boolean getLoop () ... {return _loop; } public void setloop (부울 루프) ... {_loop = 루프; } public int gettype () ... {return _type; }}
LoonFramework는 오디오 재생 관련 방법 및 사운드 플레이를 캡슐화합니다. 프로그래머는 javax.sound의 내부 세부 사항을 무시하고 관련 작업을 완료하기 위해 직접 사운드 플레이를 호출 할 수 있습니다.
패키지 org.loon.framework.game.sound; import java.io.bytearrayinputStream; import javax.sound.midi.metaeventListener; import javax.sound.midi.meTamessage; import javax.sound.midi.midisystem; import javax.sound.sound.Educte; javax.sound.midi.Sequencer;import javax.sound.sampled.AudioFileFormat;import javax.sound.sampled.AudioSystem;import javax.sound.sampled.Clip;import javax.sound.sampled.DataLine;import org.loon.framework.game.net.URI;/** *//** * <p> * 제목 : loonframework * </p> * <p> * 설명 : 사운드 파일 작업을 수행하는 데 사용됩니다 (Loonframework에서 일부 방법 만 참조하십시오. 자세한 내용은 Loonframework-Game 프레임 워크 참조) * </p> * <p> * Copyright : Copyright (C) 2007 * </p> * <p> * Company : Loonframework * * * * @Author Chenpenge * @Author Chenpeng * * * * * * * * @Author Chenpeng * * * * * * * * * @Author chenpeng * * * @email : [email protected] * @version 0.1 */public class soundplay는 metaeventlistener, runnable을 구현합니다 ... {private int _sleeptime; 개인 클립 _audio; 개인 시퀀서 _midi; 개인 부울 _loop; 개인 int _soundtype; 개인 부울 _playing; 개인 스레드 _thread = null; 개인 부울 _isrun = false; /** * // ** * Destructor, 초기화 사운드 플레이 * */public soundplay () ... {_loop = false; _soundtype = 0; _sleeptime = 1000; _playing = false; } // 사운드 파일로드 public boolean load (SoundData Data) ... {reset (); if (data == null || data.getData () == null) ... {return false; } return init (data.getData (), data.getType (), data.getLoop ()); }/** * // ** * URL 파일의 직접 재생 * * @param uri * @param ftype * @param loop * @return */public boolean load (uri uri, int ftype, boolean loop) ... {// data reset (); if (uri == null) ... {return false; } // SoundData SoundData 데이터 = New SoundData (uri, ftype, loop); if (data == null || data.getData () == null) ... {return false; } return init (data.getData (), data.getType (), data.getLoop ()); }/** * // ** * 사운드 관련 데이터 초기화 * * @param data * @param ftype * @param loop * @return */private boolean init (byte [] data, int ftype, boolean loop) ... {boolean result = false; bytearrayinputStream bis = null; try ... {bis = 새로운 BytearrayinputStream (data); } catch (예외 e) ... {bis = null; } if (bis == null) ... {return false; } // 유형 스위치 판단 (ftype) ... {// midi case sounddata._l_soundtype_midi : // midi가 존재하지 않는 경우 (_midi == null) ... {try ... {// 시퀀서를 얻습니다 _midi.open (); } catch (예외) ... {_midi = null; } if (_midi! = null) ... {_midi.addmetaeventListener (this); }} // 미디가 아직 얻지 못한 경우 (_midi! = null) ... {// 시퀀스 시퀀스 SC = NULL; try ... {sc = midisystem.getSequence (bis); } catch (예외 e) ... {sc = null; } if (sc! = null) ... {try ... {_midi.set equence (sc); // loop_loop = 루프 여부를 가져옵니다. // 결과를로드할지 여부 = true; } catch (예외 ee) ... {} // 사운드 유형 가져옵니다. }} try ... {bis.close (); } catch (예외 ee) ... {} break; // wav case sounddata._l_soundtype_wav : audiofileformat type = null; // 오디오를 시도하십시오 ... {type = audiosystem.getaudiofileformat (bis); } catch (예외 e) ... {type = null; } // 닫기 스트림 시도 ... {bis.close (); } catch (예외) ... {} if (type == null) ... {return false; } // 지정된 정보 dataline.info di = new dataline.info (clip.class, type.getformat ())에 따라 데이터 행의 정보 개체를 구성합니다. // 클립으로 변환 시도 ... {_audio = (clip) audiosystem.getline (di); } catch (예외 e) ... {} // 파일 재생 시도 ... {_audio.open (type.getFormat (), data, 0, data.length); _loop = 루프; 결과 = true; } catch (예외 e) ... {} // 파일 유형 가져 오기 _soundtype = soundData._l_SoundType_wav; 부서지다; } 반환 결과; } public boolean play (sounddata data) ... {if (! load (data)) ... {return false; } return play (); } public boolean play () ... {switch (_soundtype) ... {case sounddata._soundtype_midi : try ... {_midi.start (); _playing = true; _soundtype = sounddata._l_soundtype_midi; } catch (예외 ee) ... {} break; case sounddata._l_soundtype_wav : if (_audio! = null) ... {if (_loop) ... {// loop _audio.setlooppoints (0, -1); _audio.setframeposition (0); _audio.loop (clip.loop_continuously); } else ... {// 재생 위치를 0 _audio.setframeposition (0)으로 강제합니다. _audio.start (); } _playing = true; } 부서지다; } return _playing; }/*** // *** 자동 재생, 루프는 정지 후 끝납니다. * * @param data * @return */ public boolean autoplay (sounddata data) ... {if (! load (data)) ... {return false; } return autoplay (); }/*** // *** 자동 재생은 루프가 중지 된 후에 끝납니다. * * @return */ public boolean autoplay () ... {_isrun = true; _thread = 새 스레드 (this); _thread.start (); 반환 _playing; }/***// ***재생 중지*/public void stop () ... {if (_audio! = null && _audio.isActive ()) ... {try ... {_audio.stop (); } catch (예외 e) ... {}} if (_midi! = null) ... {_midi.stop (); } _playing = false; _isrun = false; }/*** // *** 릴리스 데이터**/public void reset () ... {stop (); _loop = false; _soundtype = 0; if (_midi! = null) ... {_midi.close (); _midi = null; } if (_audio! = null && _audio.isopen ()) ... {_audio.close (); _audio = null; } _isrun = false; _thread = null; }/***// ***SET MetamesSage*/public void meta (metamessage meta) ... {// if (_loop && _soundtype == soundData._= SoundData._l_SoundType_Midi && meta.getType () == 47)를 결정하는지 결정합니다. _midi.isopen ()) ... {_midi.setmicrosecondPosition (0); _midi.start (); }}} public void run () ... {while (_isrun) ... {play (); // 재생 유형이 고유하기 때문에이를 결정하기 위해 하나의 _playing 결과 만 반환됩니다. if (_midi! = null) ... {_playing = _midi.isrunning (); } if (_audio! = null) ... {_playing = _audio.isrunning (); } // 재생이 중지 될 때 (! _playing) ... {// release reset (); } try ... {thread.sleep (_sleeptime); } catch (InterruptedException e) ... {e.printstacktrace (); }}} public int getseptime () ... {return _sleeptime; }/*** // *** AutoPlay 스레드 루프 시간을 설정합니다. * * @param time */ public void setsleeptime (int time) ... {_sleeptime = time; }}
현재 우리가 직면해야 할 것은 복잡한 javax.sound를 다시 다룰 필요없이 사운드 다타 데이터 및 실체로 캡슐화 된 사운드 플레이 작업 만 있습니다.
통화 방법은 다음과 같습니다.
패키지 org.test; import org.loon.framework.game.helper.streamhelper; import org.loon.framework.game.net.uri; import org.loon.framework.game.sound.sounddata; import org.loon.loon.framework.game.sound.soundplay;//** ** *** // thit <p> 설명 : 사운드 플레이 재생 테스트 </p> * <p> 저작권 : 저작권 (c) 2007 </p> * <p> 회사 : loonframework </p> * @author chenpeng * @email : [email protected] * @version 0.1 */public class soundplaytest ... {int ftype) 데이터 = null; Switch (ftype) .. {// loonframework의 URI를 통해 Net 부서지다; // 로컬 리소스 케이스 1 : BYTE [] BYTE [] BYTES = StreamHelper.getResourcedata ( "/Midi/Who Big Hero.mid")를 통해 음악을 재생합니다. data = new SoundData (bytes, sounddata._l_soundtype_midi, false); 부서지다; // 음악 파일 경로를 통해 음악 재생 케이스 2 : data = new SoundData ( "c :/who the big hero.mid", sounddata._l_soundtype_midi, false); 부서지다; } soundplay play = 새로운 사운드 플레이 (); // 자동 재생과 재생 메소드의 차이점은 자동 재생이 재생 후 자동으로 자원을 중지하고 해제하고 재생을 수동으로 중단해야한다는 것입니다. //play.play(Data); play.atoplay (데이터); } public static void main (String [] args) .. {selectPlay (2); }}
Loonframework 게임이 완전히 발표 된 후에 더 자세한 방법이 설명됩니다.
또한 : StreamHelper는 다른 loonframework 방법과 관련이 있으므로 아직 제공되지 않습니다. inputStream to byte []는 다음과 같이 쓸 수 있습니다.
// IS는 입력 된 입력 BYTEARRAYOUTPUTSTREAM BYTEARRAYOUTPUTSTREAM = NEW BYTEARRAYOUTPUTSTREAM (); // BYTE [] BYTE [] ARRAYBYTE = NULL을 수행하는 데 사용됩니다. 시도 ... {// 각 전송의 크기는 4096 바이트 [] bytes = new Byte [4096]입니다. 바이트 = 새로운 바이트 [is.available ()]; int 읽기; while ((read = is.read (bytes))> = 0) ... {bytearRayoutputStream.write (bytes, 0, read); } arrayByte = bytearRayoutputStream.tobytearRay (); } catch (ioexception e) ... {return null; } 마침내 ... {try ... {if (bytearRayoutputStream! = null) ... {bytearRayoutputStream.close (); bytearrayoutputStream = null; } if (is! = null) ... {is.close (); is = null; }} catch (ioexception e) ... {}}