首  页 | 资讯中心 | 网络学院 | 天新汽车 | 天新手机 | 天新游戏 | 软件开发 | 考试认证
品 牌 机 | 笔 记 本 | 服 务 器 | 天新数码 - DC - DV - MP3 - MP4 - GPS - TV | 数字家庭
硬件 DIY - 主板 - CPU - 内 存 - 硬 盘 - 显示器 - 显卡 - 光驱 - 机箱 - 键鼠 - 网络设备
办公设备 | 打 印 机 | 扫 描 仪 | 投 影 仪 | 一 体 机 | 传 真 机 | 路 由 器 | 交 换 机
软件下载 | 驱动下载 | 游戏下载 | 源码下载 | 教程下载 | 站长在线 | 产品中心 | 报价中心
开发首页 | 开发语言 | .Net开发 | Java开发 | Web开发 | 数据库开发 | 移动开发 | 游戏开发 | 企业开发 | 操作系统 | 软件工程
VB VC Delphi PB BCB C++ - ASP.net C# VB.net - J2EE J2SE J2ME EJB - ASP PHP JSP CGI - MSSQL Oracle DB2 MySQL - CodingLife
  Java开发首页 | Java基础 | Java高级编程 | J2EE | J2SE | EJB | J2ME | Servlet/JSP | Applet/Swing | Struts/Hibernate
  您现在的位置:天新网 > 软件开发 > Java开发 > J2EE
为Java程序中添加播放MIDI音乐功能
http://dev.21tx.com 2007年09月23日 千里冰封

每日文章精萃
.Net:ASP.NET入门随想之开卷有益 Java:EJB3.0开发指南之无状态会话Bean
ASP:SQL语句简介-给初学者(1) PHP:Php利用java解析xml
JSP:JSP语法(3) CGI:Cgi入门教程之:13 设置口令
VB:VB实现动态调用含DateTime类型存储过 VC:VC++ 6.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(false);
            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都可以,换个几万次内存一点都没有加,呵呵,真是防不胜防啊。

上一篇: Spring破冰之旅 始于足下
下一篇: 彻底明白 Java 语言中的IO系统

编辑推荐
相关内容
·专家释疑:轻松提高Java代码的性能
·在厨房,车顶,草地上使用Spring
·剑客vs刀客 Java vs .NET之飘逸的Java
·JSF“裸体”降临Java Web世界
·基于JDBC的数据库连接池技术研究与应用
·使用JFreeChart生成热点图表
·评论:分布式不只是一个概念
·Apusic1.1.2安装过程中遇到的jdk相关问题解
·J2EE的客户端
·J2EE应用开发阶段划分
·让界面更加绚丽 Java SE 6.0 GUI体验
·基于MVC设计模式的WEB应用框架研究
·实现基于Spring框架应用的权限控制系统
·玩玩Spring之Rod Johnson与轮子理论
·Java SE 6第一印象:赢在桌面
·用Java代码处理本地对象的事件
·把JBoss缓存用作POJO缓存的实战演练
·浅析Spring提供的事务管理方法
·JSF的中文化与国际化的简便方法
·结合第三方工具工具对Weblogic进行调优
最近更新
人气最热
·Spring破冰之旅 始于足下
·彻底明白 Java 语言中的IO系统
·RFT与Spring结合进行自动化脚本开发之一
·Java 6.0 操作脚本语言基础
·使用Java操作Windows系统注册表
·动态调用动态语言之Java脚本API
·Spring集成XFire开发WebService
·Java对象的序列化和反序列化实践
·Java开发中的事件驱动模型实例详解
·反射在Java Swing编程中的应用
·深入研究Servlet线程安全性问题
·Java编程思想:面向对象的逻辑思维方法
·强强携手 将AJAX带入Eclipse
·利用Stripes实现Java Web开发
·Spring Framework中的AOP编程之入门篇
·Java应用中的反模式开发介绍
·JavaSE 6基于JSR105的XML签名之实践篇
·Spring MVC 开发快速入门
·利用Java Servlets 2.4实现过滤
·用Java事件处理机制实现录制回放功能

 
·[硬件]尊贵时尚 劲永512MB U3优盘现售价145元
·[数码]nano强劲对手 三星T9系列MP3降价
·[汽车]江南汽车降价让利6000元 基本型2.88万
·[开发]细说SYBASE数据库日志
·[资讯]纳斯达克股市同意苹果财报延迟二个月
·[游戏]天堂2:因为是暴君,所以坚强!!
·[本本]随时随地享受 华硕W6送CDMA无线上网卡
·[办公]创新 日本印刷推出高对比度投影屏幕
·[手机]手机撒谎软件遭诚信质疑 短信骗子跟风
·[考试]报关员考试2005年复习笔记二十一
·[学院]创建FLASH 塑料质感按钮
·[娱乐]与大力士猜拳
 

关于我们 | 联系我们 | 广告服务 | 工作机会 | 版权声明 | 欢迎投稿 | 网站地图
Copyright © 2000-2008 , www.21tx.com , All Rights Reserved .
© 晨新科技 版权所有 Created by TXSite.net