千里冰封
          JAVA 濃香四溢
          posts - 151,comments - 2801,trackbacks - 0
          <2007年9月>
          2627282930311
          2345678
          9101112131415
          16171819202122
          23242526272829
          30123456

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

           

          留言簿(204)

          隨筆分類(197)

          隨筆檔案(189)

          文章檔案(2)

          友情鏈接

          搜索

          •  

          積分與排名

          • 積分 - 964340
          • 排名 - 35

          最新隨筆

          最新評論

          閱讀排行榜

          評論排行榜

          JAVA在多媒體處理方面的確優勢不大,但是我們在程序中有些時候又需要一些音樂做為點綴,如果播放的音樂是wav等波形音頻文件,又挺大,所以背景音樂最好就是MIDI了,可是網上很多播放MIDI的教程都是簡單的幾句話的例子,并且沒有考慮資源的釋放問題,如果程序長久運行的話,就會出現內存越耗越多的情況,以至于最后拋出一個java.lang.OutOfMemoryError,整個程序就掛了.


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

          下面我們來看一個例子吧

          /*
           * 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();
              }
          }


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


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

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

          FeedBack:
          # re: JAVA播放MIDI音樂
          2007-09-23 00:15 | 學習者

          copy到netbeans中 并自己加了.mid的文件
          運行正常 就是只出數字 不出聲音
            回復  更多評論
            
          # re: JAVA播放MIDI音樂
          2007-09-24 09:10 | 千里冰封
          呵呵,關于這個,我等會會寫一篇說明 一下  回復  更多評論
            
          # re: JAVA播放MIDI音樂[未登錄]
          2008-05-08 13:01 | test
          那是因為你沒有安裝JavaTM Media Framework 2.1.1e,我安裝了就行了.  回復  更多評論
            
          主站蜘蛛池模板: 探索| 灵武市| 常熟市| 武安市| 余干县| 丽水市| 灵台县| 石阡县| 宁化县| 油尖旺区| 马关县| 依安县| 麻栗坡县| 容城县| 松江区| 荆州市| 长治市| 崇礼县| 鞍山市| 南丰县| 武义县| 确山县| 遂溪县| 壤塘县| 周至县| 云龙县| 蚌埠市| 环江| 遂溪县| 新昌县| 莫力| 册亨县| 临江市| 绥德县| 鹤壁市| 天峻县| 松溪县| 娄底市| 襄垣县| 巴彦淖尔市| 广昌县|