Home>

java audio playback,Because you have to rely on the local environment,So java has little advantage in audio processing.In other words, when developing from the java system, there is not much consideration for audio playback factors.You should know that in the earliest version of java 1.1, there was no subsequent javax.sound package, and the audio can only be retrieved through the applet package ...

Regrettably,In graphics program development,However, our program inevitably uses background music, effect sounds, and other image operations.Hey, this is really a joke made by Sun God.Fortunately, afterwards, the sun opened his eyes,Provided javax.sound package, only rescued us

But then the problem is,In the use of javax.sound package,Like the common problems of java multimedia tools,It does not provide a very complete release mechanism.If we do windows development, calling mediaplayer repeatedly n times may be fine.But in java, if the audio program runs repeatedly,Extremely prone to cumulative memory loss,So that at the end a java.lang.outofmemoryerror is thrown, and then ... the program hangs,The user is stupid,We are crazy ...

This is already a question of being intolerable,With that in mind,So in the development of my loonframework framework,Second integration of related methods under sound,Strive for the simplest code,Make the most complete audio control class.Now that loonframework-game hasn't completed yet,First extract some methods,For you to look at officials-shoot bricks!

Corresponding network resource call,Established your own uri class in loonframework, the basic content is as follows:

(Where streamhelper is the own streaming control class of loonframework,Please replace the gethttpstream method.)

package org.loon.framework.game.net;
import org.loon.framework.game.helper.streamhelper;
/** * //**
 *<p>
 * title:loonframework
 *</p>
 *<p>
 * description:Loonframework dedicated URI (Uniform Resource Identifier)
 *</p>
 *<p>
 * copyright:copyright (c) 2007
 *</p>
 *<p>
 * company:loonframework
 *</p>
 *
 * @author chenpeng
 * @email:[email protected]
 * @version 0.1
 * /
public class uri ... {
  //Transmission protocol type
  public static final int _l_uri_http=1;
  public static final int _l_uri_udp=2;
  private string _uri;
  private int _type;
  /** * //**
   * Destructor,For injecting uri and type
   *
   * @param uri
   * @param type
   * /
  public uri (string uri, int type) ... {
    _uri=new string (uri);
    _type=type;
  }
  /** * //**
   * Destructor,Used to inject uri
   *
   * @param uri
   * /
  public uri (string uri) ... {
    _uri=new string (uri);
    _type=uri._l_uri_http;
  }
  /** * //**
   * Returns a byte array of the resource where the uri is located.
   *
   * @return
   * /
  public byte [] getdata () ... {
    if (_uri == null) ... {
      return null;
    }
    return streamhelper.gethttpstream (_uri);
  }
  public string geturi () ... {
    return _uri;
  }
  public int gettype () ... {
    return _type;
  }
}
In the loanframework framework, a basic sounddata class is customized for unified management of audio data sources.
package org.loon.framework.game.sound;
import org.loon.framework.game.helper.streamhelper;
import org.loon.framework.game.net.uri;
/** * //**
 *<p>
 * title:loonframework
 *</p>
 *<p>
 * description:Used to obtain and cache sound file data (for further content operations, see the moonframework-game framework)
 *</p>
 *<p>
 * copyright:copyright (c) 2007
 *</p>
 *<p>
 * company:loonframework
 *</p>
 *
 * @author chenpeng
 * @email:[email protected]
 * @version 0.1
 * /
public class sounddata ... {
  private byte [] _data;
  private boolean _loop;
  private int _type;
  public static final int _l_soundtype_midi=1;
  public static final int _l_soundtype_wav=2;
  /** * //**
   * Destructor,Used to inject uri, type, loop
   *
   * @param uri
   * @param type
   * @param loop
   * /
  public sounddata (uri uri, int type, boolean loop) ... {
    if (uri!=null) ... {
      _data=uri.getdata ();
    }
    _type=type;
    _loop=loop;
  }
  /** * //**
   * Destructor,Used to inject data, type, loop
   *
   * @param data
   * @param type
   * @param loop
   * /
  public sounddata (byte [] data, int type, boolean loop) ... {
    if (data!=null&&data.length>0) ... {
      _data=new byte [data.length];
      //Copy the byte array directly
      system.arraycopy (data, 0, _data, 0, _data.length);
    }
    _type=type;
    _loop=loop;
  }
  /** * //**
   * Destructor,Resname, type, loop used to inject a limited position
   * @param resname
   * @param type
   * @param loop
   * /
  public sounddata (string resname, int type, boolean loop) ... {
    this (streamhelper.getdatasource (resname), type, loop);
  }
  public byte [] getdata () ... {
    return _data;
  }
  public boolean getloop () ... {
    return _loop;
  }
  public void setloop (boolean loop) ... {
    _loop=loop;
  }
  public int gettype () ... {
    return _type;
  }
}

loonframework will play audio related methods,In encapsulation and soundplay, programmers can ignore the internal details of javax.sound,And directly call soundplay to complete the relevant operations.

package 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.midi.sequence;
import 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>
 * title:loonframework
 *</p>
 *<p>
 * description:Used for sound file operations (only some methods in loanframework,(See loonframework-game framework for more details.)
 *</p>
 *<p>
 * copyright:copyright (c) 2007
 *</p>
 *<p>
 * company:loonframework
 *</p>
 *
 * @author chenpeng
 * @email:[email protected]
 * @version 0.1
 * /
public class soundplay implements metaeventlistener, runnable ... {
  private int _sleeptime;
  private clip _audio;
  private sequencer _midi;
  private boolean _loop;
  private int _soundtype;
  private boolean _playing;
  private thread _thread=null;
  private boolean _isrun=false;
  /** * //**
   * Destructor,Initialize soundplay
   *
   * /
  public soundplay () ... {
    _loop=false;
    _soundtype=0;
    _sleeptime=1000;
    _playing=false;
  }
  //load sound file
  public boolean load (sounddata data) ... {
    reset ();
    if (data == null || data.getdata () == null) ... {
      return false;
    }
    return init (data.getdata (), data.gettype (), data.getloop ());
  }
  /** * //**
   * Play url file directly
   *
   * @param uri
   * @param ftype
   * @param loop
   * @return
   * /
  public boolean load (uri uri, int ftype, boolean loop) ... {
    //refresh the data
    reset ();
    if (uri == null) ... {
      return false;
    }
    //get sounddata
    sounddata data=new sounddata (uri, ftype, loop);
    if (data == null || data.getdata () == null) ... {
      return false;
    }
    return init (data.getdata (), data.gettype (), data.getloop ());
  }
  /** * //**
   * Initialize sound related data
   *
   * @param data
   * @param ftype
   * @param loop
   * @return
   * /
  private boolean init (byte [] data, int ftype, boolean loop) ... {
    boolean result=false;
    bytearrayinputstream bis=null;
    try ... {
      bis=new bytearrayinputstream (data);
    } catch (exception e) ... {
      bis=null;
    }
    if (bis == null) ... {
      return false;
    }
    //determine the type
    switch (ftype) ... {
    //midi
    case sounddata._l_soundtype_midi:
      //when midi does not exist
      if (_midi == null) ... {
        try ... {
          //get sequencer
          _midi=midisystem.getsequencer ();
          _midi.open ();
        } catch (exception ex) ... {
          _midi=null;
        }
        if (_midi!=null) ... {
          _midi.addmetaeventlistener (this);
        }
      }
      //when midi is still not obtained
      if (_midi!=null) ... {
        //recreate sequence
        sequence sc=null;
        try ... {
          sc=midisystem.getsequence (bis);
        } catch (exception e) ... {
          sc=null;
        }
        if (sc!=null) ... {
          try ... {
            _midi.setsequence (sc);
            //get whether to loop play
            _loop=loop;
            //get whether to load
            result=true;
          } catch (exception ee) ... {
          }
          //get sound type
          _soundtype=sounddata._l_soundtype_midi;
        }
      }
      try ... {
        bis.close ();
      } catch (exception ee) ... {
      }
      break;
    //wav
    case sounddata._l_soundtype_wav:
      audiofileformat type=null;
      //get audio
      try ... {
        type=audiosystem.getaudiofileformat (bis);
      } catch (exception e) ... {
        type=null;
      }
      //close stream
      try ... {
        bis.close ();
      } catch (exception ex) ... {
      }
      if (type == null) ... {
        return false;
      }
      //Construct the information object of the data row based on the specified information
      dataline.info di=new dataline.info (clip.class, type.getformat ());
      //turn to clip
      try ... {
        _audio=(clip) audiosystem.getline (di);
      } catch (exception e) ... {
      }
      //play the file
      try ... {
        _audio.open (type.getformat (), data, 0, data.length);
        _loop=loop;
        result=true;
      } catch (exception e) ... {
      }
      //get file type
      _soundtype=sounddata._l_soundtype_wav;
      break;
    }
    return result;
  }
  public boolean play (sounddata data) ... {
    if (! load (data)) ... {
      return false;
    }
    return play ();
  }
  public boolean play () ... {
    switch (_soundtype) ... {
    case sounddata._l_soundtype_midi:
      try ... {
        _midi.start ();
        _playing=true;
        _soundtype=sounddata._l_soundtype_midi;
      } catch (exception ee) ... {
      }
      break;
    case sounddata._l_soundtype_wav:
      if (_audio!=null) ... {
        if (_loop) ... {
          //Set the loop
          _audio.setlooppoints (0, -1);
          _audio.setframeposition (0);
          _audio.loop (clip.loop_continuously);
        } else ... {
          //Force the playback position to 0
          _audio.setframeposition (0);
          _audio.start ();
        }
        _playing=true;
      }
      break;
    }
    return _playing;
  }
  /** * //**
   * Autoplay,It ends when the cycle stops.
   *
   * @param data
   * @return
   * /
  public boolean autoplay (sounddata data) ... {
    if (! load (data)) ... {
      return false;
    }
    return autoplay ();
  }
  /** * //**
   * Autoplay,It ends when the cycle stops.
   *
   * @return
   * /
  public boolean autoplay () ... {
    _isrun=true;
    _thread=new thread (this);
    _thread.start ();
    return _playing;
  }
  /** * //**
   * Stop play
   * /
  public void stop () ... {
    if (_audio!=null&&_audio.isactive ()) ... {
      try ... {
        _audio.stop ();
      } catch (exception e) ... {
      }
    }
    if (_midi!=null) ... {
      _midi.stop ();
    }
    _playing=false;
    _isrun=false;
  }
  /** * //**
   * Release data
   *
   * /
  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) ... {
    //determine whether to play midi in a loop
    if (_loop &&_soundtype == sounddata._l_soundtype_midi
        &&meta.gettype () == 47) ... {
      if (_midi!=null&&_midi.isopen ()) ... {
        _midi.setmicrosecondposition (0);
        _midi.start ();
      }
    }
  }
  public void run () ... {
    while (_isrun) ... {
      play ();
      //Because the play type is unique,So it will only return a _playing result.
      if (_midi!=null) ... {
        _playing=_midi.isrunning ();
      }
      if (_audio!=null) ... {
        _playing=_audio.isrunning ();
      }
      //when playback stops
      if (! _playing) ... {
        //freed
        reset ();
      }
      try ... {
        thread.sleep (_sleeptime);
      } catch (interruptedexception e) ... {
        e.printstacktrace ();
      }
    }
  }
  public int getsleeptime () ... {
    return _sleeptime;
  }
  /** * //**
   * Set autoplay thread cycle time.
   *
   * @param time
   * /
  public void setsleeptime (int time) ... {
    _sleeptime=time;
  }
}

What we need to face at this time,It is just the sounddata data and soundplay operations that are encapsulated as entities, without having to deal with the complicated javax.sound.

The calling method is as follows:

package 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.framework.game.sound.soundplay;
/** * //**
 *<p>title:loonframework</p>
 *<p>description:soundplay playback test</p>
 *<p>copyright:copyright (c) 2007</p>
 *<p>company:loonframework</p>
 * @author chenpeng
 * @email:[email protected]
 * @version 0.1
 * /
public class soundplaytest ... {
  static void selectplay (int ftype) ... {
    sounddata data=null;
    switch (ftype) ... {
    //Play music from the network through loonframework uri
    case 0:
      data=new sounddata (new uri ("http://looframework.sourceforge.net/midi/Who is the big hero.
mid "), sounddata._l_soundtype_midi, false);
      break;
    //Play music through the byte [] object of the music file under local resources
    case 1:
      byte [] bytes=streamhelper.getresourcedata ("/midi/Who is the big hero.
mid ");
      data=new sounddata (bytes, sounddata._l_soundtype_midi, false);
      break;
      //Play music through the music file path
    case 2:
      data=new sounddata ("c:/Who is a big hero.
mid ", sounddata._l_soundtype_midi, false);
      break;
    }
    soundplay play=new soundplay ();
    //The difference between autoplay and play methods is that
After autoplay is finished, it will automatically stop and release resources.
Play needs to be aborted manually.
    //play.play(data);
    play.autoplay (data);
  }
  public static void main (string [] args) ... {
    selectplay (2);
  }
}

A more detailed approach,After the full release of loanframework-game,Explain again.

In addition:because streamhelper is associated with other methods in loanframework, it is not given for the time being,inputstream to byte [] can be written as follows:

//is the inputstream obtained
  bytearrayoutputstream bytearrayoutputstream=new bytearrayoutputstream ();
//Used to accept byte []
    byte [] arraybyte=null;
    try ... {
      //The size of each transmission is 4096
      byte [] bytes=new byte [4096];
      bytes=new byte [is.available ()];
      int read;
      while ((read=is.read (bytes))>= 0) ... {
        bytearrayoutputstream.write (bytes, 0, read);
      }
      arraybyte=bytearrayoutputstream.tobytearray ();
    } catch (ioexception e) ... {
      return null;
    } finally ... {
      try ... {
        if (bytearrayoutputstream!=null) ... {
          bytearrayoutputstream.close ();
          bytearrayoutputstream=null;
        }
        if (is!=null) ... {
          is.close ();
          is=null;
        }
      } catch (ioexception e) ... {
      }
    }
  • Previous Oracle database using sqlplus connection error and direction key garbled solution
  • Next jQuery custom scroll bar complete example