/*
* Created on Jul 5, 2005
*
* Copyright (c) 2005 Peter Johan Salomonsen (http://www.petersalomonsen.com)
*
* http://www.frinika.com
*
* This file is part of Frinika.
*
* Frinika 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.
*
* Frinika 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.
*
* You should have received a copy of the GNU General Public License
* along with Frinika; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.frinika.sequencer;
import java.util.Vector;
import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MidiEvent;
import javax.sound.midi.MidiMessage;
import javax.sound.midi.Sequence;
import javax.sound.midi.ShortMessage;
import javax.sound.midi.Track;
public class FrinikaSequence extends Sequence {
Vector<FrinikaTrackWrapper> frinikaTrackWrappers = new Vector<FrinikaTrackWrapper>();
transient FrinikaSequencer sequencer;
public FrinikaSequence(Sequence sequence) throws InvalidMidiDataException
{
super(sequence.getDivisionType(),sequence.getResolution());
for(Track track : sequence.getTracks())
{
FrinikaTrackWrapper trackWrapper = new FrinikaTrackWrapper(track);
trackWrapper.setSequence(this);
tracks.add(track);
frinikaTrackWrappers.add(trackWrapper);
}
}
public FrinikaSequence(float divisionType, int resolution, int tracks) throws InvalidMidiDataException {
super(divisionType,resolution);
for(int n=0;n<tracks;n++)
createTrack();
}
// /**
// * probably a bit naughty to do this ? PJL
// *
// * @param seq
// */
// public Vector<FrinikaTrackWrapper> addSequence(Sequence seq) {
// Vector<FrinikaTrackWrapper> newTracks=new Vector<FrinikaTrackWrapper>();
// for(Track track : seq.getTracks())
// {
// FrinikaTrackWrapper trackWrapper = new FrinikaTrackWrapper(track);
// trackWrapper.setSequence(this);
// tracks.add(track);
// frinikaTrackWrappers.add(trackWrapper);
// newTracks.add(trackWrapper);
// }
// return newTracks;
// }
@Override
public Track createTrack()
{
Track track = super.createTrack();
FrinikaTrackWrapper trackWrapper = new FrinikaTrackWrapper(track);
frinikaTrackWrappers.add(trackWrapper);
trackWrapper.setSequence(this);
return track;
}
public FrinikaTrackWrapper createFrinikaTrack()
{
Track track = super.createTrack();
FrinikaTrackWrapper trackWrapper = new FrinikaTrackWrapper(track);
frinikaTrackWrappers.add(trackWrapper);
trackWrapper.setSequence(this);
return trackWrapper;
}
public Vector<FrinikaTrackWrapper> getFrinikaTrackWrappers() {
return frinikaTrackWrappers;
}
/**
* @return Returns the sequencer.
*/
public FrinikaSequencer getSequencer() {
return sequencer;
}
/**
* Will automatically be set when attached to a sequencer
* @param sequencer The sequencer to set.
*/
void setSequencer(FrinikaSequencer sequencer) {
this.sequencer = sequencer;
}
/**
* Returns a clone of this sequence suitable for Midi file export. What it does is to map the FTW channel setting to all the midi events
* for the corresponding tracks
* @return
* @throws InvalidMidiDataException
*/
public Sequence export() throws InvalidMidiDataException
{
Sequence newSeq = new Sequence(getDivisionType(),getResolution());
for(FrinikaTrackWrapper ftw : frinikaTrackWrappers)
{
Track track = newSeq.createTrack();
for(int n=0;n<ftw.size();n++)
{
MidiEvent sourceMidiEvent = ftw.get(n);
MidiMessage msg = sourceMidiEvent.getMessage();
if(msg instanceof ShortMessage)
{
ShortMessage shm = (ShortMessage)msg;
ShortMessage nshm = new ShortMessage();
nshm.setMessage(shm.getCommand(),ftw.getMidiChannel(),shm.getData1(),shm.getData2());
msg = nshm;
}
MidiEvent newEvent = new MidiEvent(msg,sourceMidiEvent.getTick());
track.add(newEvent);
}
}
return newSeq;
}
}