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

          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,我安裝了就行了.  回復  更多評論
            
          主站蜘蛛池模板: 镇坪县| 湘阴县| 聂荣县| 尚志市| 通榆县| 中阳县| 临漳县| 马关县| 安乡县| 娱乐| 漯河市| 津南区| 榆林市| 铅山县| 托里县| 龙口市| 株洲市| 陆丰市| 长武县| 彭水| 大石桥市| 安丘市| 金乡县| 望城县| 桐庐县| 蓬莱市| 故城县| 宁陕县| 溆浦县| 永州市| 调兵山市| 凯里市| 婺源县| 宁陕县| 砀山县| 连山| 独山县| 五台县| 商洛市| 且末县| 涡阳县|