/** * Sounds for a linked list **/ public class SoundElement { /** * The sound this element is associated with **/ Sound mySound; /** * The next element to process **/ public SoundElement next; /** * Constructor sets next to null * and references the input sound. **/ public SoundElement(Sound aSound){ next = null; mySound = aSound; } /** * Provide a printable representation of me **/ public String toString(){ return "SoundElement with sound: "+mySound+" (and next: "+next+")."; } /** * Methods to set and get next elements * @param nextOne next element in list **/ public void setNext(SoundElement nextOne){ this.next = nextOne; } public SoundElement getNext(){ return this.next; } /** * Play the list of sound elements * after me **/ public void playFromMeOn(){ this.collect().play(); } /** * Collect all the sounds from me on, * recursively. **/ public Sound collect(){ if (this.getNext() == null) {return mySound;} else {return mySound.append(this.getNext().collect());} } /** Method to remove node from list, fixing links appropriately. * @param node element to remove from list. **/ public void remove(SoundElement node){ if (node==this) { System.out.println("I can't remove the first node from the list."); return; }; SoundElement current = this; // While there are more nodes to consider while (current.getNext() != null) { if (current.getNext() == node){ // Simply make node's next be this next current.setNext(node.getNext()); // Make this node point to nothing node.setNext(null); return; } current = current.getNext(); } } /** * Insert the input node after this node. * @param node element to insert after this. **/ public void insertAfter(SoundElement node){ // Save what "this" currently points at SoundElement oldNext = this.getNext(); this.setNext(node); node.setNext(oldNext); } /** * Return the last element in the list **/ public SoundElement last() { SoundElement current; current = this; while (current.getNext() != null) { current = current.getNext(); }; return current; } /** * Add the input node after the last node in this list. * @param node element to insert after this. **/ public void add(SoundElement node){ this.last().insertAfter(node); } /** * copyNode returns a copy of this element * @return another element with the same sound */ public SoundElement copyNode(){ Sound copySound; if (this.mySound.getFileName() == null) {copySound = this.mySound.scale(1.0);} // Does nothing -- copies else {copySound = new Sound(this.mySound.getFileName());} // Copy from file SoundElement returnMe = new SoundElement(copySound); return returnMe; } /** * Repeat the input phrase for the number of times specified. * It always appends to the current node, NOT insert. * @param nextOne node to be copied in to list * @param count number of times to copy it in. */ public void repeatNext(SoundElement nextOne,int count) { SoundElement current = this; // Start from here SoundElement copy; // Where we keep the current copy for (int i=1; i <= count; i++) { copy = nextOne.copyNode(); // Make a copy current.setNext(copy); // Set as next current = copy; // Now append to copy } } /** * Weave the input sound count times every skipAmount elements * @param nextOne SoundElement to be copied into the list * @param count how many times to copy * @param skipAmount how many nodes to skip per weave */ public void weave(SoundElement nextOne, int count, int skipAmount) { SoundElement current = this; // Start from here SoundElement copy; // Where we keep the one to be weaved in SoundElement oldNext; // Need this to insert properly int skipped; // Number skipped currently for (int i=1; i <= count; i++) { copy = nextOne.copyNode(); // Make a copy //Skip skipAmount nodes skipped = 1; while ((current.getNext() != null) && (skipped < skipAmount)) { current = current.getNext(); skipped++; }; if (current.getNext() == null) // Did we actually get to the end early? break; // Leave the loop oldNext = current.getNext(); // Save its next current.insertAfter(copy); // Insert the copy after this one current = oldNext; // Continue on with the rest } } /** * Replace the one sound with the other sound * in all the elements from me on. * Decide two sounds are equal if come from same filename * @param oldSound sound to be replaced * @param newSOund sound to put in its place **/ public void replace(Sound oldSound, Sound newSound){ if (mySound.getFileName() != null) {if (mySound.getFileName().equals(oldSound.getFileName())) {mySound = newSound;}} if (next != null) {next.replace(oldSound,newSound);} } }