import jm.music.data.*; import jm.JMC; import jm.util.*; import jm.music.tools.*; /** * Class that holds an element in a song * @author Mark Guzdial * @author Barb Ericson */ public class SongElement { /** the next song element */ private SongElement next; /** a part (notes) in the song */ private Part myPart; /** * Constructor that takes no arguments. * The next part is empty, and ours is a blank new part */ public SongElement(){ this.next = null; this.myPart = new Part(); } /** This method takes a phrase and makes it the one for this element * at the desired start time with the given instrument * @param myPhrase the phrase to use * @param startTime the time to start this phrase * @param instrument the instrument to use to play this */ public void setPhrase(Phrase myPhrase, double startTime, int instrument) { myPhrase.setStartTime(startTime); this.myPart.addPhrase(myPhrase); this.myPart.setInstrument(instrument); } /** * Method to set the next element in the song * @param nextOne the element that should be next */ public void setNext(SongElement nextOne) { this.next = nextOne; } /** * Method to get the next element in the song * @return the next element or null if none */ public SongElement getNext() { return this.next; } /** * Method to get the part associated with this element * @return the part */ private Part getPart() { return this.myPart; } /** * Method to get the end time for this element. * @return the time this element ends */ public double getEndTime(){ return this.myPart.getPhrase(0).getEndTime(); } /** * We need setChannel because each part has to be in its * own channel if it has different start times. * So, we'll set the channel when we assemble the score. * @param channel the channel to use */ private void setChannel(int channel) { myPart.setChannel(channel); } /** * Method to show the song from this element */ public void showFromMeOn() { // Make the score that we'll assemble the elements into // We'll set it up with a default time signature and tempo we like // (Should probably make it possible to change these -- // maybe with inputs?) Score myScore = new Score("My Song"); myScore.setTimeSignature(3,4); myScore.setTempo(120.0); // Each element will be in its own channel int channelCount = 1; // Start from this element (this) SongElement current = this; // While we're not through... while (current != null) { // Set the channel, increment the channel, then add it in. current.setChannel(channelCount); channelCount = channelCount + 1; myScore.addPart(current.getPart()); // Now, move on to the next element // which we already know isn't null current = current.getNext(); } // At the end, let's see it! View.notate(myScore); } }