/** * saves settings object to a file * * @param settings settings to save * @param file file to write */ public static void settingsToFile(AutomaticVoicingSettings settings, File file) { try { PrintWriter writer = new PrintWriter(file, "UTF-8"); writer.println( "(comments \"Auto Voicing Preset File. Please check parameter limits (in Impro-visor) before modifying.\")"); writer.println("(LH-lower-limit " + settings.getLeftHandLowerLimit() + ")"); writer.println("(RH-lower-limit " + settings.getRightHandLowerLimit() + ")"); writer.println("(LH-upper-limit " + settings.getLeftHandUpperLimit() + ")"); writer.println("(RH-upper-limit " + settings.getRightHandUpperLimit() + ")"); writer.println("(LH-spread " + settings.getLeftHandSpread() + ")"); writer.println("(RH-spread " + settings.getRightHandSpread() + ")"); writer.println("(LH-min-notes " + settings.getLeftHandMinNotes() + ")"); writer.println("(LH-max-notes " + settings.getLeftHandMaxNotes() + ")"); writer.println("(RH-min-notes " + settings.getRightHandMinNotes() + ")"); writer.println("(RH-max-notes " + settings.getRightHandMaxNotes() + ")"); // voice leading controls writer.println("(pref-motion " + settings.getPreferredMotion() + ")"); writer.println("(pref-motion-range " + settings.getPreferredMotionRange() + ")"); writer.println( "(prev-voicing-multiplier " + (int) (settings.getPreviousVoicingMultiplier() * 10) + ")"); // multiplier for notes used in previous voicing writer.println( "(half-step-multiplier " + (int) (settings.getHalfStepAwayMultiplier() * 10) + ")"); writer.println( "(full-step-multiplier " + (int) (settings.getFullStepAwayMultiplier() * 10) + ")"); // voicing control writer.println( "(LH-color-priority " + settings.getLeftColorPriority() + ")"); // priority of any color note writer.println( "(RH-color-priority " + settings.getRightColorPriority() + ")"); // priority of any color note writer.println( "(max-priority " + settings.getMaxPriority() + ")"); // max priority a note in the priority array can have writer.println( "(priority-multiplier " + (int) (+settings.getPriorityMultiplier() * 10) + ")"); // should be between 0 and 1, multiply this by the index in priority array, // subtract result from max priority to get note priority writer.println("(repeat-multiplier " + (int) (settings.getRepeatMultiplier() * 10) + ")"); writer.println("(half-step-reducer " + (int) (settings.getHalfStepReducer() * 10) + ")"); writer.println("(full-step-reducer " + (int) (settings.getFullStepReducer() * 10) + ")"); writer.println("(left-min-interval " + (int) (settings.getLeftMinInterval()) + ")"); writer.println("(right-min-interval " + (int) (settings.getRightMinInterval()) + ")"); if (settings.getInvertM9()) writer.println("(invert-9th on)"); else writer.println("(invert-9th off)"); if (settings.getVoiceAll()) writer.println("(voice-all on)"); else writer.println("(voice-all off)"); if (settings.getRootless()) writer.println("(rootless on)"); else writer.println("(rootless off)"); writer.close(); } catch (Exception f) { ErrorLog.log(ErrorLog.SEVERE, "Error writing Voicing File: " + file.getName()); } }
/** * Creates a Part with the specified number of slots and a rest in the first slot. * * @param size the number of slots to create in the Part */ public Part(int size) { title = DEFAULT_TITLE; volume = DEFAULT_VOLUME; instrument = DEFAULT_INSTRUMENT; setMetre(DEFAULT_METRE[0], DEFAULT_METRE[1]); keySig = DEFAULT_KEYSIG; swing = DEFAULT_SWING; composer = DEFAULT_COMPOSER; this.size = size; try { slots = new ArrayList<Unit>(size); for (int k = 0; k < size; k++) { slots.add(null); } // slots.setSize(size); if (size != 0) { slots.set(0, new Rest(size)); // empty Part has one long rest unitCount = 1; } } catch (OutOfMemoryError e) { ErrorLog.log(ErrorLog.SEVERE, "Not enough memory to create part of size " + size); } }
/** * Gets the closest match Note to a given pitchName, from a polylist of NoteSymbols * * @param pitch * @param tonesPL * @return Note an instance of the 'closest' note in list from the pitchName */ public static Note getClosestMatch(int pitch, Polylist tonesPL) { int originalPitch = pitch; // System.out.println("getClosestMatch to " + pitchName + " " + tonesPL); if (!tonesPL.nonEmpty()) { ErrorLog.log(ErrorLog.WARNING, "*** Error: No tones list to match against."); } Polylist list = tonesPL; int[] tones = new int[list.length()]; /* Make an array of pitches of all acceptable tones to match to */ for (int i = 0; list.nonEmpty(); i++) { try { tones[i] = ((NoteSymbol) list.first()).getMIDI() % OCTAVE; list = list.rest(); } catch (Exception ep) { // ep.printStackTrace(); } } /* Search incrementally within the tones list for the 'closest' * acceptable pitchName. This will fit our contour best. */ int stepSearch = 0; int indexMatch; while ((indexMatch = arrayContains((pitch % OCTAVE), tones)) == OUT_OF_BOUNDS) { stepSearch++; if (stepSearch % 2 == 0) { pitch -= stepSearch; } else { pitch += stepSearch; } } Note note = ((NoteSymbol) tonesPL.nth(indexMatch)).toNote(); note.setPitch(pitch); /* if( pitchName != originalPitch ) { System.out.println("closest match to " + new Note(originalPitch).toLeadsheet() + " is " + note.toLeadsheet() + " among " + tonesPL); } */ return note; }
/** * Gets the closest match Note at or above a given pitchName, from a polylist of NoteSymbols * * @param pitch * @param tonesPL * @param upward * @return Note an instance of the 'closest' note in list from the pitchName */ public static Note getClosestMatchDirectional(int pitch, Polylist tonesPL, boolean upward) { // System.out.println("getClosestMatchDirectional to " + pitchName + " " + tonesPL); if (!tonesPL.nonEmpty()) { ErrorLog.log(ErrorLog.WARNING, "*** Error: No tones list to match against."); } Polylist list = tonesPL; int[] tones = new int[tonesPL.length()]; /* Make an array of pitches of all acceptable tones to match to */ for (int i = 0; i < tones.length; i++) { try { tones[i] = ((NoteSymbol) tonesPL.first()).getMIDI() % OCTAVE; tonesPL = tonesPL.rest(); } catch (Exception ep) { // ep.printStackTrace(); } } /* Search incrementally within the tones list for the 'closest' * acceptable pitchName. This will fit our contour best. */ int indexMatch; if (upward) { pitch++; } else { pitch--; } while ((indexMatch = arrayContains((pitch % OCTAVE), tones)) == OUT_OF_BOUNDS) { if (upward) { pitch++; } else { pitch--; } } Note note = ((NoteSymbol) list.nth(indexMatch)).toNote(); note.setPitch(pitch); return note; }
/** * addSubBlocks / 3 Constructs the subblocks of a brick by reading in a PolyList and using a * BrickLibrary to convert it to bricks with appropriate subbricks. * * @param contents, a PolyList of subbricks * @param bricks, a BrickLibrary */ private void addSubBlocks( Polylist contents, BrickLibrary bricks, LinkedHashMap<String, LinkedList<Polylist>> polymap) { List<Block> subBlockList = new ArrayList<Block>(); while (contents.nonEmpty()) { Object obj = contents.first(); contents = contents.rest(); if (obj instanceof Polylist) { Polylist pList = (Polylist) obj; String blockType = pList.first().toString(); pList = pList.rest(); // If a subblock is a brick, split it into components and then // look up the corresponding brick in the library to construct // the necessary new brick. if (blockType.equals(BRICK_KEYWORD) && (pList.length() == 3 || pList.length() == 4)) { // determine the information about the name, variant, etc. String subBrickName = BrickLibrary.dashless(pList.first().toString()); pList = pList.rest(); String subBrickVariant = ""; if (pList.first() instanceof Polylist) { subBrickVariant = ((Polylist) pList.first()).toStringSansParens(); pList = pList.rest(); } String subBrickKeyString = pList.first().toString(); pList = pList.rest(); // Workaround added by RK for error reporting // in case of missing duration in sub-brick Object durObj = DEFAULT_SUBRICK_DURATION; if (pList.isEmpty()) { ErrorLog.log( ErrorLog.WARNING, "Missing Sub-Brick Duration in " + subBrickName + ", using 1"); } else { durObj = pList.first(); // pList = pList.rest(); } // when all data members are initialized, find the correct // brick scaled appropriately boolean starFlag = isStar(durObj); if (durObj instanceof Long || starFlag) { int dur = starFlag ? 0 : Arith.long2int((Long) durObj); long subBrickKeyNum = BrickLibrary.keyNameToNum(subBrickKeyString); Brick subBrick = null; // if the subbrick already exists in the dictionary if (bricks.hasBrick(subBrickName)) { if (!subBrickVariant.equals("")) { subBrick = bricks.getBrick(subBrickName, subBrickVariant, subBrickKeyNum, dur); } else { subBrick = bricks.getBrick(subBrickName, subBrickKeyNum, dur); } } // if the subbrick has yet to be initialized in the // dictionary, make one to use for now else if (polymap.containsKey(subBrickName)) { // find the appropriate definition to use to assemble // the subbrick LinkedList<Polylist> tokenList = polymap.get(subBrickName); Polylist tokens = null; if (subBrickVariant.equals("")) { tokens = tokenList.getFirst(); } else { for (Polylist p : tokenList) { Object variant = p.rest().rest().first(); if (variant instanceof Polylist && ((Polylist) variant).toStringSansParens().equals(subBrickVariant)) { tokens = p; break; } } if (tokens == null) { ErrorLog.log( ErrorLog.SEVERE, "Dictionary does not contain " + subBrickName + subBrickVariant); } } // find the elements of the subbrick String brickName = BrickLibrary.dashless(subBrickName); tokens = tokens.rest(); tokens = tokens.rest(); String brickVariant = ""; if (tokens.first() instanceof Polylist) { brickVariant = ((Polylist) tokens.first()).toStringSansParens(); tokens = tokens.rest(); } String brickMode = tokens.first().toString(); tokens = tokens.rest(); String brickType = tokens.first().toString(); tokens = tokens.rest(); String brickKeyString = tokens.first().toString(); tokens = tokens.rest(); long brickKeyNum = BrickLibrary.keyNameToNum(brickKeyString); // construct the subbrick subBrick = new Brick( brickName, brickVariant, brickKeyNum, brickType, tokens, bricks, brickMode, polymap); subBrick.transpose(Arith.long2int(subBrickKeyNum - brickKeyNum)); subBrick.setDuration(dur); } else { ErrorLog.log( ErrorLog.SEVERE, "Dictionary does " + "not contain " + subBrickName, true); } subBlockList.add(subBrick); } else { ErrorLog.log( ErrorLog.FATAL, subBrickName + ": " + "Duration not of type long: " + obj, true); } } // If a subblock is a chord, make an appropriate Chord object else if (blockType.equals(CHORD_KEYWORD) && pList.length() == 2) { String chordName = pList.first().toString(); pList = pList.rest(); Object durObj = pList.first(); // pList = pList.rest(); boolean starFlag = isStar(durObj); if (durObj instanceof Long || starFlag) { int dur = starFlag ? 0 : Arith.long2int((Long) durObj); ChordBlock subBlockChord = new ChordBlock(chordName, dur); subBlockList.add(subBlockChord); } else { ErrorLog.log( ErrorLog.FATAL, chordName + ": " + "Duration not of type long: " + durObj, true); } } else { ErrorLog.log( ErrorLog.WARNING, "Incorrect subblock of " + name + ": " + blockType + " " + pList.toStringSansParens()); } } } subBlocks.addAll(subBlockList); }
/** * addSubBlocks / 2 Constructs the subblocks of a brick by reading in a PolyList and using a * BrickLibrary to convert it to bricks with appropriate subbricks. * * @param contents, a PolyList of subbricks * @param bricks, a BrickLibrary */ private void addSubBlocks(Polylist contents, BrickLibrary bricks) { List<Block> subBlockList = new ArrayList<Block>(); while (contents.nonEmpty()) { Object obj = contents.first(); contents = contents.rest(); if (obj instanceof Polylist) { Polylist pList = (Polylist) obj; String blockType = pList.first().toString(); pList = pList.rest(); // If a subblock is a brick, split it into components and then // look up the corresponding brick in the library to construct // the necessary new brick. if (blockType.equals(BRICK_KEYWORD)) { String brickName = BrickLibrary.dashless(pList.first().toString()); pList = pList.rest(); String brickVariant = ""; if (pList.first() instanceof Polylist) { brickVariant = ((Polylist) pList.first()).toStringSansParens(); pList = pList.rest(); } String brickKeyString = pList.first().toString(); pList = pList.rest(); Object durObj = pList.first(); // pList = pList.rest(); boolean starFlag = isStar(durObj); if (durObj instanceof Long || starFlag) { int dur = starFlag ? 0 : Arith.long2int((Long) durObj); long brickKeyNum = BrickLibrary.keyNameToNum(brickKeyString); Brick subBrick; if (brickVariant.equals("")) { subBrick = bricks.getBrick( brickName, brickVariant, brickKeyNum, dur); } else { subBrick = bricks.getBrick(brickName, brickKeyNum, dur); } subBlockList.add(subBrick); } else { ErrorLog.log( ErrorLog.FATAL, brickName + ": " + "Duration not of type long: " + obj, true); } } // If a subblock is a chord, make an appropriate Chord object else if (blockType.equals(CHORD_KEYWORD)) { String chordName = pList.first().toString(); pList = pList.rest(); Object durObj = pList.first(); boolean starFlag = isStar(durObj); if (durObj instanceof Long || starFlag) { int dur = starFlag ? 0 : Arith.long2int((Long) durObj); ChordBlock subBlockChord = new ChordBlock(chordName, dur); subBlockList.add(subBlockChord); } else { ErrorLog.log( ErrorLog.FATAL, chordName + ": " + "Duration not of type long: " + obj, true); } } } } subBlocks.addAll(subBlockList); }
public static void fileToSettings(File file, AutomaticVoicingSettings settings) { lastFileName = file.getName(); try { Scanner sc = new Scanner(file); while (sc.hasNextLine()) { String line = sc.nextLine(); // System.out.println(line); if (line.contains("Auto Voicing Preset File.")) ; else if (!line.contains("(")) throw new Exception(); else if (line.contains("LH-lower-limit")) { line = line.substring( line.indexOf("LH-lower-limit") + "LH-lower-limit".length() + 1, line.indexOf(")")); settings.setLeftHandLowerLimit(Integer.parseInt(line)); } else if (line.contains("RH-lower-limit")) { line = line.substring( line.indexOf("RH-lower-limit") + "RH-lower-limit".length() + 1, line.indexOf(")")); settings.setRightHandLowerLimit(Integer.parseInt(line)); } else if (line.contains("LH-upper-limit")) { line = line.substring( line.indexOf("LH-upper-limit") + "LH-upper-limit".length() + 1, line.indexOf(")")); settings.setLeftHandUpperLimit(Integer.parseInt(line)); } else if (line.contains("RH-upper-limit")) { line = line.substring( line.indexOf("RH-upper-limit") + "RH-upper-limit".length() + 1, line.indexOf(")")); settings.setRightHandUpperLimit(Integer.parseInt(line)); } else if (line.contains("LH-spread")) { line = line.substring( line.indexOf("LH-spread") + "LH-spread".length() + 1, line.indexOf(")")); settings.setLeftHandSpread(Integer.parseInt(line)); } else if (line.contains("RH-spread")) { line = line.substring( line.indexOf("RH-spread") + "RH-spread".length() + 1, line.indexOf(")")); settings.setRightHandSpread(Integer.parseInt(line)); } else if (line.contains("LH-min-notes")) { line = line.substring( line.indexOf("LH-min-notes") + "LH-min-notes".length() + 1, line.indexOf(")")); settings.setLeftHandMinNotes(Integer.parseInt(line)); } else if (line.contains("RH-min-notes")) { line = line.substring( line.indexOf("RH-min-notes") + "RH-min-notes".length() + 1, line.indexOf(")")); settings.setRightHandMinNotes(Integer.parseInt(line)); } else if (line.contains("LH-max-notes")) { line = line.substring( line.indexOf("LH-max-notes") + "LH-max-notes".length() + 1, line.indexOf(")")); settings.setLeftHandMaxNotes(Integer.parseInt(line)); } else if (line.contains("RH-max-notes")) { line = line.substring( line.indexOf("RH-max-notes") + "RH-max-notes".length() + 1, line.indexOf(")")); settings.setRightHandMaxNotes(Integer.parseInt(line)); } else if (line.contains("pref-motion-range")) { line = line.substring( line.indexOf("pref-motion-range") + "pref-motion-range".length() + 1, line.indexOf(")")); settings.setPreferredMotionRange(Integer.parseInt(line)); } else if (line.contains("pref-motion")) { line = line.substring( line.indexOf("pref-motion") + "pref-motion".length() + 1, line.indexOf(")")); settings.setPreferredMotion(Integer.parseInt(line)); } else if (line.contains("prev-voicing-multiplier")) { line = line.substring( line.indexOf("prev-voicing-multiplier") + "prev-voicing-multiplier".length() + 1, line.indexOf(")")); settings.setPreviousVoicingMultiplier(Integer.parseInt(line) / 10.0); } else if (line.contains("half-step-multiplier")) { line = line.substring( line.indexOf("half-step-multiplier") + "half-step-multiplier".length() + 1, line.indexOf(")")); settings.setHalfStepAwayMultiplier(Integer.parseInt(line) / 10.0); } else if (line.contains("full-step-multiplier")) { line = line.substring( line.indexOf("full-step-multiplier") + "full-step-multiplier".length() + 1, line.indexOf(")")); settings.setFullStepAwayMultiplier(Integer.parseInt(line) / 10.0); } else if (line.contains("LH-color-priority")) { line = line.substring( line.indexOf("LH-color-priority") + "LH-color-priority".length() + 1, line.indexOf(")")); settings.setLeftColorPriority(Integer.parseInt(line)); } else if (line.contains("RH-color-priority")) { line = line.substring( line.indexOf("RH-color-priority") + "RH-color-priority".length() + 1, line.indexOf(")")); settings.setRightColorPriority(Integer.parseInt(line)); } else if (line.contains("max-priority")) { line = line.substring( line.indexOf("max-priority") + "max-priority".length() + 1, line.indexOf(")")); settings.setMaxPriority(Integer.parseInt(line)); } else if (line.contains("priority-multiplier")) { line = line.substring( line.indexOf("priority-multiplier") + "priority-multiplier".length() + 1, line.indexOf(")")); settings.setPriorityMultiplier(Integer.parseInt(line) / 10.0); } else if (line.contains("repeat-multiplier")) { line = line.substring( line.indexOf("repeat-multiplier") + "repeat-multiplier".length() + 1, line.indexOf(")")); settings.setRepeatMultiplier(Integer.parseInt(line) / 10.0); } else if (line.contains("half-step-reducer")) { line = line.substring( line.indexOf("half-step-reducer") + "half-step-reducer".length() + 1, line.indexOf(")")); settings.setHalfStepReducer(Integer.parseInt(line) / 10.0); } else if (line.contains("full-step-reducer")) { line = line.substring( line.indexOf("full-step-reducer") + "full-step-reducer".length() + 1, line.indexOf(")")); settings.setFullStepReducer(Integer.parseInt(line) / 10.0); } else if (line.contains("left-min-interval")) { line = line.substring( line.indexOf("min-interval") + "min-interval".length() + 1, line.indexOf(")")); settings.setLeftMinInterval(Integer.parseInt(line)); } else if (line.contains("right-min-interval")) { line = line.substring( line.indexOf("min-interval") + "min-interval".length() + 1, line.indexOf(")")); settings.setRightMinInterval(Integer.parseInt(line)); } else if (line.contains("invert-9th")) { if (line.contains("on")) settings.setInvertM9(true); if (line.contains("off")) settings.setInvertM9(false); } else if (line.contains("voice-all")) { if (line.contains("on")) settings.setVoiceAll(true); if (line.contains("off")) settings.setVoiceAll(false); } else if (line.contains("rootless")) { if (line.contains("on")) settings.setRootless(true); if (line.contains("off")) settings.setRootless(false); } } } catch (Exception ex) { ErrorLog.log(ErrorLog.SEVERE, "Error finding or reading Voicing File: " + lastFileName); } }
public void makeSwing(SectionInfo sectionInfo) { // The index here iterates through the start of every beat Style previousStyle = Style.getStyle("swing"); // TEMP: FIX! for (int i = 0; i + beatValue - 1 < size; i += beatValue) { SectionRecord record = sectionInfo.getSectionRecordBySlot(i); Style s; if (record.getUsePreviousStyle()) { s = previousStyle; } else { s = record.getStyle(); previousStyle = s; } if (s == null) { ErrorLog.log(ErrorLog.FATAL, "It will not be possible to continue"); } double swingValue = s.getSwing(); // System.out.println("i = " + i + ", style = " + s + " swing = " + swingValue); // FIX: Notice the problem here when i < size, the original condition, is used. // we get the Units where a second sixteenth note would fall, // an eighth note, and a fourth sixteenth note Unit unit1 = slots.get(i + 1 * beatValue / 4); Unit unit2 = slots.get(i + 1 * beatValue / 2); Unit unit3 = slots.get(i + 3 * beatValue / 4); // we only use swingValue if there is no second sixteenth note // (we don't want to swingValue a beat of four sixteenths) if (unit1 == null && unit2 != null) { /* formerly: // swingValue if there is a second eighth note if(unit2.getRhythmValue() == beatValue/2) { slots.set(i+beatValue/2, null); slots.set(i+(int)(beatValue*swingValue), unit2); } */ int trailingRhythm = unit2.getRhythmValue(); // swingValue if there is a second eighth note or longer if (trailingRhythm >= beatValue / 2) { int offset = (int) (beatValue * swingValue); Unit unit2mod = unit2.copy(); unit2mod.setRhythmValue(unit2.getRhythmValue() - offset); slots.set(i + beatValue / 2, null); slots.set(i + offset, unit2mod); } } } try { // After the Units are shifted, go through and reset each rhythm value Part.PartIterator i = iterator(); while (i.hasNext()) { int index = i.nextIndex(); slots.get(index).setRhythmValue(getUnitRhythmValue(index)); i.next(); } } catch (Exception e) { } }