/* * Created on 17 Nov 2007 * * Copyright (c) 2004-2007 Paul John Leonard * * 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.chart; import java.io.IOException; import java.io.Serializable; import java.util.List; import java.util.Observable; import java.util.StringTokenizer; import java.util.Vector; import uk.org.toot.music.tonality.Key; import uk.org.toot.music.tonality.Keys; import uk.org.toot.music.tonality.Pitch; import uk.org.toot.music.tonality.Scale; import uk.org.toot.music.tonality.Scales; public class Chart extends Observable implements Serializable { /** * */ private static final long serialVersionUID = 1L; private Vector<Bar> bars; private int beatsPerBar=4; // TODO look at time sig private String keyRoot; private String scale; public Chart() { bars = new Vector<Bar>(); } public void appendBar() { bars.add(new Bar(beatsPerBar)); } public void appendBar(String string, int beats) { Bar bar = new Bar(beats); bars.add(bar); bar.set(string,keyRoot,scale); setChanged(); } public void appendBar(String string,String keyRoot,String scale, int beats) { Bar bar = new Bar(beats); bars.add(bar); bar.set(string,keyRoot,scale); setChanged(); } public List<Bar> getBars() { return bars; } public class Bar implements Serializable { /** * */ private static final long serialVersionUID = 1L; Vector<Chord> chords; int beats; private Bar(int beats) { chords = new Vector<Chord>(); this.beats = beats; } private void addChord(String string,String keyRoot,String scaleName) { string=string.trim(); if (!string.equals("/")) { chords.add(new Chord(string,keyRoot,scaleName)); }else { chords.add(new Chord(chords.lastElement())); } } public int getBeats() { return beats; } public List<Chord> getChords() { return chords; } private void spaceChords() { int n = chords.size(); if (n == 1) chords.get(0).setDuration(beats); else if (n == beats) { for (Chord chord : chords) chord.setDuration(1); } else { int inc=beats/chords.size(); int bb=0; for (Chord chord : chords) chord.setDuration(bb+inc); try { throw new Exception(" chords do not fit the bar"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public String toString() { StringBuffer str=new StringBuffer(); for (Chord chord:chords) { str.append(chord.toString()+" "); } return str.toString(); } private void set(String string,String keyRoot,String scale) { chords.clear(); StringTokenizer toker = new StringTokenizer(string); while (toker.hasMoreTokens()) { addChord(toker.nextToken(),keyRoot,scale); } spaceChords(); setChanged(); } } public class Chord implements Serializable { String name; private static final long serialVersionUID = 1L; transient uk.org.toot.music.tonality.Chord chord; transient int root; transient Key key; int beats; String scaleName; String scaleRoot; int [] chordInt; private Chord(Chord cloneMe) { this.name = cloneMe.name; this.root=cloneMe.root; this.beats=cloneMe.beats; this.chord=cloneMe.chord; this.chordInt=cloneMe.chordInt; this.scaleName=cloneMe.scaleName; this.scaleRoot=cloneMe.scaleRoot; this.key=cloneMe.key; } private Chord(String name,String keyRoot,String scaleName) { this.name=name; this.scaleName=scaleName; Scale scale=Scales.getScale(scaleName); int kr=Pitch.classValue(keyRoot); key=new Key(kr,scale); buildFromName(); } private void buildFromName() { root = Pitch.classValue(name); String string=name; if (string.length() > 1) { char c = string.charAt(1); if (c == 'b' || c == '#') { string = string.substring(2, string.length()); } else { string = string.substring(1, string.length()); } } else { string = string.substring(1, string.length()); } chord = uk.org.toot.music.tonality.Chords.withSymbol(string); assert(chord != null); // chordInt=chord.getIntervals(); // assert(chordInt != null); } private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); buildFromName(); } private void setDuration(int beats) { this.beats = beats; } public int getDuration() { return beats; } public int getRoot() { return root; } public String toString() { return name; } public int getChordNoteAt(int i) { return root+chord.getIntervals()[i%chordInt.length]; } public Key getKey() { return key; } } public void setbarAt(int index, String string) { bars.get(index).set(string,keyRoot,scale); setChanged(); notifyObservers(); } public void setbarAt(int index, String string,String keyRoot,String scale) { bars.get(index).set(string,keyRoot,scale); } public String toString() { StringBuffer buff=new StringBuffer(); for(Bar bar:bars) { buff.append(bar.toString()); buff.append("|"); } return buff.toString(); } public void setDefaultKey(String keyRoot, String scale) { this.keyRoot=keyRoot; this.scale=scale; } }