千里冰封
          JAVA 濃香四溢
          posts - 151,comments - 2801,trackbacks - 0

          JAVA在多媒體處理方面的確優(yōu)勢(shì)不大,但是我們?cè)诔绦蛑杏行r(shí)候又需要一些音樂(lè)做為點(diǎn)綴,如果播放的音樂(lè)是wav等波形音頻文件,又挺大,所以背景音樂(lè)最好就是MIDI了,可是網(wǎng)上很多播放MIDI的教程都是簡(jiǎn)單的幾句話的例子,并且沒(méi)有考慮資源的釋放問(wèn)題,如果程序長(zhǎng)久運(yùn)行的話,就會(huì)出現(xiàn)內(nèi)存越耗越多的情況,以至于最后拋出一個(gè)java.lang.OutOfMemoryError,整個(gè)程序就掛了.


          在MIDI的播放中,一個(gè)類是比較重要的,那就是MidiSystem類,它負(fù)責(zé)整個(gè)MIDI播放設(shè)備等的管理,其實(shí)就是Seqencer,它就是一個(gè)MIDI播放設(shè)置,用于播放MIDI序列的,還有一個(gè)類叫Seqence,它就是MIDI的序列,MIDI的序列可以自己由程序生成,也可以從文件中或者URL中讀取.

          下面我們來(lái)看一個(gè)例子吧

          /*
           * Test5.java
           *
           * Created on 2007-9-22, 11:16:22
           *
           * To change this template, choose Tools | Templates
           * and open the template in the editor.
           
          */

          package test1;

          import java.io.File;
          import java.io.IOException;
          import java.io.InputStream;
          import java.util.Hashtable;
          import java.util.Map;
          import java.util.logging.Level;
          import java.util.logging.Logger;
          import javax.sound.midi.InvalidMidiDataException;
          import javax.sound.midi.MidiSystem;
          import javax.sound.midi.MidiUnavailableException;
          import javax.sound.midi.Sequence;
          import javax.sound.midi.Sequencer;

          /**
           *
           * 
          @author hadeslee
           
          */
          public class Test5 implements Runnable{

              
          private Sequencer midi;
              
          private String[] names={"1.mid","2.mid","3.mid","4.mid","5.mid"};
              
          private int i;
              
          private Map<String,Sequence> map;
              
          public Test5(){
                  initMap();
                  
          new Thread(this).start();
              }
              
          private void initMap(){
                  
          try {
                      map 
          = new Hashtable<String, Sequence>();
                      midi 
          = MidiSystem.getSequencer();
                      midi.open();
                      
          for (String s : names) {
                          
          try {
                              Sequence s1 
          = MidiSystem.getSequence(new File(s));
                              map.put(s, s1);
                          } 
          catch (InvalidMidiDataException ex) {
                              Logger.getLogger(Test5.
          class.getName()).log(Level.SEVERE, null, ex);
                          } 
          catch (IOException ex) {
                              Logger.getLogger(Test5.
          class.getName()).log(Level.SEVERE, null, ex);
                          }
                      }
                  } 
          catch (MidiUnavailableException ex) {
                      Logger.getLogger(Test5.
          class.getName()).log(Level.SEVERE, null, ex);
                  }
                  
              }
              
          private void createPlayer(String name){
                  
          try {

                      Sequence se
          =map.get(name);

                      midi.setSequence(se);
                      midi.start();

                      
                  }
          catch (InvalidMidiDataException ex) {
                      Logger.getLogger(Test5.
          class.getName()).log(Level.SEVERE, null, ex);
                  }
                  
              }
              
          public void run(){
                  
          while(true){
                      
          try {
                          System.out.println(
          "換文件了."+(++i));
                          String name
          =names[(int)(Math.random()*names.length)];
                          createPlayer(name);
                          Thread.sleep(
          10000);
                          
                      } 
          catch (InterruptedException ex) {
                          Logger.getLogger(Test5.
          class.getName()).log(Level.SEVERE, null, ex);
                      }
                  }
              }
              
          public static void main(String[] args) {
                  
          new Test5();
              }
          }


          在這里有很重要的一點(diǎn),那就是在程序運(yùn)行的時(shí)候,只要一個(gè)Seqencer就可以了,我以前在程序里面每次播放的時(shí)候都生成了一個(gè)Seqencer,因?yàn)槟莻€(gè)時(shí)候我想,我都調(diào)用它的close()方法了,它還能被打開(kāi)嗎?其實(shí)它還可以再度被打開(kāi)的,就是這樣一種慣性思維使得程序最終因內(nèi)存溢出而崩潰.
          現(xiàn)在按我這種方式播,哪怕10毫秒換一次MIDI都可以,換個(gè)幾萬(wàn)次內(nèi)存一點(diǎn)都沒(méi)有加.呵呵,真是防不勝防啊.


          盡管千里冰封
          依然擁有晴空

          你我共同品味JAVA的濃香.
          posted on 2007-09-22 13:52 千里冰封 閱讀(2300) 評(píng)論(3)  編輯  收藏 所屬分類: JAVASE

          FeedBack:
          # re: JAVA播放MIDI音樂(lè)
          2007-09-23 00:15 | 學(xué)習(xí)者

          copy到netbeans中 并自己加了.mid的文件
          運(yùn)行正常 就是只出數(shù)字 不出聲音
            回復(fù)  更多評(píng)論
            
          # re: JAVA播放MIDI音樂(lè)
          2007-09-24 09:10 | 千里冰封
          呵呵,關(guān)于這個(gè),我等會(huì)會(huì)寫一篇說(shuō)明 一下  回復(fù)  更多評(píng)論
            
          # re: JAVA播放MIDI音樂(lè)[未登錄](méi)
          2008-05-08 13:01 | test
          那是因?yàn)槟銢](méi)有安裝JavaTM Media Framework 2.1.1e,我安裝了就行了.  回復(fù)  更多評(píng)論
            
          主站蜘蛛池模板: 仁化县| 万安县| 通河县| 宝鸡市| 迭部县| 凉城县| 古蔺县| 留坝县| 唐山市| 德庆县| 剑阁县| 枣强县| 翼城县| 宁化县| 光山县| 定陶县| 宜州市| 安阳市| 乳山市| 鄂伦春自治旗| 宽城| 房产| 剑阁县| 义马市| 西城区| 大关县| 通城县| 长葛市| 合水县| 泉州市| 曲松县| 鄂伦春自治旗| 丹凤县| 平顶山市| 碌曲县| 崇明县| 汝城县| 鹤山市| 武鸣县| 望城县| 班戈县|