/* * File : JavaSoundActiveMediaPlayer.java * Created : 16-jun-2004 15:59 * By : fbusquets * * JClic - Authoring and playing system for educational activities * * Copyright (C) 2000 - 2005 Francesc Busquets & Departament * d'Educacio de la Generalitat de Catalunya * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details (see the LICENSE file). */ package edu.xtec.jclic.media; import edu.xtec.util.ExtendedByteArrayInputStream; import edu.xtec.util.StreamIO; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.ByteArrayInputStream; import java.io.InputStream; import javax.sound.midi.MidiSystem; import javax.sound.sampled.*; import javax.swing.Timer; /** * * @author Francesc Busquets (fbusquets@xtec.cat) */ public class JavaSoundActiveMediaPlayer extends ActiveMediaPlayer { PseudoClip clip; Timer timer; boolean midi; ByteArrayInputStream midiIs; public static javax.sound.midi.Sequencer sequencer=null; /** Creates a new instance of JavaSoundActiveMediaPlayer */ public JavaSoundActiveMediaPlayer(edu.xtec.jclic.media.MediaContent mc, edu.xtec.jclic.bags.MediaBag mb, edu.xtec.jclic.PlayStation ps) { super(mc, mb, ps); InputStream is; midi=false; midiIs=null; if(!useAudioBuffer){ try{ switch(mc.mediaType){ case MediaContent.PLAY_MIDI: midi=true; is=mb.getInputStream(mc.mediaFileName); if(is instanceof ByteArrayInputStream) midiIs=(ByteArrayInputStream)is; else midiIs=new ExtendedByteArrayInputStream(StreamIO.readInputStream(is), mc.mediaFileName); break; case MediaContent.PLAY_AUDIO: if(mc.to>0 || mc.from>0) clip=ClipWrapper.getClipWrapper(mb, mc.mediaFileName); else clip=FalseClip.getFalseClip(mb, mc.mediaFileName); if(clip !=null && !mc.loop && mc.to>Math.max(0, mc.from)){ timer=new Timer(mc.to-Math.max(0, mc.from), new ActionListener(){ public void actionPerformed(ActionEvent ev){ if(clip!=null && clip.isRunning()) clip.stop(); } }); timer.setCoalesce(false); timer.setRepeats(false); } break; default: break; } } catch(Exception ex){ System.err.println("Error reading media \""+mc.mediaFileName+"\":\n"+ex); } } } public AudioBuffer createAudioBuffer(int seconds) throws Exception{ return new JavaSoundAudioBuffer(mc.length); } public static void closeMidiSequencer(){ if(sequencer!=null){ if(sequencer.isRunning()) sequencer.stop(); if(sequencer.isOpen()) sequencer.close(); } } public void realize(){ if(!useAudioBuffer){ try{ if(midi){ if(sequencer==null) sequencer=MidiSystem.getSequencer(); } else{ if(clip!=null && !clip.isOpen()){ clip.open(); } } } catch(Exception e){ System.err.println("Error realizing media \""+mc.mediaFileName+"\"\n"+e); //e.printStackTrace(); } } } @Override protected void playNow(edu.xtec.jclic.boxes.ActiveBox setBx){ if(useAudioBuffer) super.playNow(setBx); else{ try{ if(midi){ if(sequencer==null) realize(); if(sequencer!=null && midiIs!=null){ if(sequencer.isRunning()) sequencer.stop(); if(!sequencer.isOpen()) sequencer.open(); midiIs.reset(); sequencer.setSequence(midiIs); sequencer.stop(); setTimeRanges(); sequencer.start(); } } else if(clip!=null){ if(!clip.isOpen()) realize(); setTimeRanges(); attachVisualComponent(); if(mc.loop){ clip.loop(Clip.LOOP_CONTINUOUSLY); } else{ clip.start(); if(timer!=null) timer.start(); } } } catch(Exception e){ System.err.println("Error playing media \""+mc.mediaFileName+"\":\n"+e); } } } @Override public void stop() { super.stop(); if(!useAudioBuffer){ try{ if(midi && sequencer!=null){ closeMidiSequencer(); } else if (clip!=null && clip.isActive()){ if(timer!=null && timer.isRunning()) timer.stop(); clip.stop(); } } catch(Exception e){ System.err.println("Error stopping media \""+mc.mediaFileName+"\":\n"+e); } } } @Override public void clear(){ super.clear(); if(!useAudioBuffer){ try{ if(midi){ if(sequencer!=null){ sequencer.close(); sequencer=null; } if(midiIs!=null){ midiIs.close(); midiIs=null; } } else if(clip!=null){ stop(); clip.close(); destroyVisualComponent(); clip=null; timer=null; } } catch(Exception e){ System.err.println("Error closing media \""+mc.mediaFileName+"\":\n"+e); } } } protected void setTimeRanges(){ if(useAudioBuffer) return; try{ if(midi && sequencer!=null){ sequencer.setTickPosition(0L); /* if(mc.from!=-1){ //sequencer.setTickPosition(sequencer.getSequence().getResolution()*mc.from/2); } else sequencer.setTickPosition(0L); //if(mc.to!=-1){ // sequencer. //} */ } else if(clip!=null && clip.isOpen()){ if(mc.from>=0 || mc.to>=0){ int from=mc.from>0 ? (int)((clip.getFormat().getFrameRate()*mc.from)/1000) : 0; int to=mc.to>=0 ? (int)((clip.getFormat().getFrameRate()*mc.to)/1000) : -1; if(mc.loop) clip.setLoopPoints(from, to); clip.setFramePosition(from); } else{ clip.setFramePosition(0); } } } catch(Exception e){ System.err.println("Error setting time ranges for \""+mc.mediaFileName+"\":\n"+e); } } protected java.awt.Component getVisualComponent(){ return null; } }