/** * 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); }