// Sets probabilities of note types into an array from a polylist private int[] setProb(Polylist probs) { int chord, color, random, scale; chord = Integer.parseInt((String) probs.first().toString()); color = Integer.parseInt((String) probs.second().toString()); random = Integer.parseInt((String) probs.third().toString()); scale = Integer.parseInt((String) probs.fourth().toString()); int[] result = new int[4]; result[0] = chord; result[1] = color; result[2] = random; result[3] = scale; return result; }
/** * toRoadmapSave is used to create a Polylist for saving to a RoadMap This is NOT the same as the * Polylist usedd to save in the dictionary. Returns a Polylist representation of a Brick. * * @return a Polylist containing the Brick's contents */ @Override public Polylist toRoadmapSave() { PolylistBuffer buffer = new PolylistBuffer(); buffer.append(BRICK_KEYWORD); buffer.append(Polylist.list("name", dashed(name))); buffer.append(Polylist.list("variant", variant)); buffer.append(Polylist.list("type", type)); buffer.append(Polylist.list("key", BrickLibrary.keyNumToName(key))); buffer.append(Polylist.list("mode", mode)); buffer.append(Polylist.list("duration", duration)); buffer.append(Polylist.list("overlap", overlap)); buffer.append(Polylist.list("end", endValue)); buffer.append(subBlocksToRoadmapSave()); return buffer.toPolylist(); }
/** * toBrickDefinition Returns a Polylist formatted specifically to replicate the Brick's original * definition format * * @return a Polylist containing the Brick's definition information */ public Polylist toBrickDefinition() { PolylistBuffer buffer = new PolylistBuffer(); for (Block b : getSubBlocks()) { buffer.append(b.toPolylist()); } if (!variant.equals("")) { return Polylist.list( BrickLibrary.DEF_BRICK, dashed(name) + "(" + variant + ")", mode, dashed(type), BrickLibrary.keyNumToName(key)) .append(buffer.toPolylist()); } else { return Polylist.list( BrickLibrary.DEF_BRICK, dashed(name), mode, dashed(type), BrickLibrary.keyNumToName(key)) .append(buffer.toPolylist()); } }
/** * 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; }
public NoteChooser(boolean noOctaveSwitch) { // if this is true, never transpose pitch an octave if out of bounds doNotSwitchOctave = noOctaveSwitch; /* The first number in each line represents which type of note we are * looking for - 0 for chord, 1 for color, 2 for random, 3 for scale * The next three numbers represent which notes are present of chord, * color, and then random * The last 4 numbers are probabilities for which will be chosen: * in order - chord, color, random, scale */ String probString = "( (0 1 1 1 100 0 0 0) " + // looking for chord, have chord, color, random "(0 1 1 0 100 0 0 0) " + // looking for chord, have chord, color "(0 1 0 1 100 0 0 0) " + // looking for chord, have chord, random "(0 1 0 0 100 0 0 0) " + // looking for chord, have chord "(0 0 1 1 0 100 0 0) " + // looking for chord, have color, random "(0 0 1 0 0 100 0 0) " + // looking for chord, have color "(0 0 0 1 0 0 100 0) " + // looking for chord, have random "(1 1 1 1 0 100 0 0) " + // looking for color, have chord, color, random "(1 1 1 0 10 90 0 0) " + // looking for color, have chord, color "(1 1 0 1 85 0 15 0) " + // looking for color, have chord, random "(1 1 0 0 100 0 0 0) " + // looking for color, have chord "(1 0 1 1 0 100 0 0) " + // looking for color, have color, random "(1 0 1 0 0 100 0 0) " + // looking for color, have color "(1 0 0 1 0 0 100 0) " + // looking for color, have random "(3 1 1 1 0 0 0 100) " + // looking for scale, have chord, color, random "(3 1 1 0 0 0 0 100) " + // looking for scale, have chord, color "(3 1 0 1 0 0 0 100) " + // looking for scale, have chord, random "(3 1 0 0 0 0 0 100) " + // looking for scale, have chord "(3 0 1 1 0 0 0 100) " + // looking for scale, have color, random "(3 0 1 0 0 0 0 100) " + // looking for scale, have color "(3 0 0 1 0 0 100 0) " + // looking for scale, have random "(2 1 1 1 50 25 25 0) " + // looking for random, have chord, color, random "(2 1 1 0 80 20 0 0) " + // looking for random, have chord, color "(2 1 0 1 50 0 50 0) " + // looking for random, have chord, random "(2 1 0 0 100 0 0 0) " + // looking for random, have chord "(2 0 1 1 0 50 50 0) " + // looking for random, have color, random "(2 0 1 0 0 100 0 0) " + // looking for random, have color "(2 0 0 1 0 0 100 0) )"; // looking for random, have random probabilities = (Polylist) (Polylist.PolylistFromString(probString)).first(); }
/* Called from chooseNote in Lickgen * Given an interval, the desired type of note, * the types of notes in the interval, and the occurences of each type of note, * looks up the probabilities for what type of note to choose in a table * and returns a note chosen based on the probabilities * attempts is a counter for the number of times we have tried to get all pitches within range */ public int getNote( int minPitch, int maxPitch, int low, int high, int type, int[] numTypes, int[] noteTypes, int attempts) { if (type == CHORD) type = 0; if (type == COLOR) type = 1; if (type == RANDOM) type = 2; if (type == SCALE) type = 3; Polylist prob = new Polylist(); // integers representing whether a certain type is present int haveChord, haveColor, haveRandom; if (numTypes[0] != 0) haveChord = 1; else haveChord = 0; if (numTypes[1] != 0) haveColor = 1; else haveColor = 0; if (numTypes[2] != 0) haveRandom = 1; else haveRandom = 0; // special case for chord tones - they are more important than staying // in the interval // if(type == 0 && haveChord == 0) { // for(int i = low - 4; i <= low + 4; i++) { // // } // } Polylist identifier = Polylist.list(type, haveChord, haveColor, haveRandom); // look for match for (Polylist L = probabilities; L.nonEmpty(); L = L.rest()) { // get first list in probabilities Polylist tempProb = (Polylist) L.first(); // chop off the probabilities so we just have the identifier Polylist tempIdentifier = tempProb.prefix(4); if (identifier.equals(tempIdentifier)) { prob = tempProb.coprefix(4); } } // put the matched probabilities into an array int[] probs = setProb(prob); Random rand = new Random(); // generate note type from probabilities int randNum = rand.nextInt(100) + 1; int newType = 0; // -1; for (int i = 0; i < probs.length; i++) { randNum = randNum - probs[i]; if (randNum <= 0) { newType = i; i = probs.length; } } // get note pitch randNum = rand.nextInt(numTypes[newType]) + 1; int pitchdiff = 0; for (int i = 0; i < noteTypes.length; i++) { if (noteTypes[i] == typeMap[newType] || (newType == 3 && (noteTypes[i] == CHORD || noteTypes[i] == COLOR))) { randNum--; } if (randNum <= 0) { pitchdiff = i; i = noteTypes.length; } } int finalPitch = low + pitchdiff; if (attempts >= LickGen.MELODY_GEN_LIMIT - 1 && doNotSwitchOctave == false) { // raise or lower by an octave if outside bounds while (finalPitch > maxPitch) { finalPitch -= 12; } while (finalPitch < minPitch) { finalPitch += 12; } } return finalPitch; }
/** * toPolylist Returns a Polylist representation of a Brick. * * @return a Polylist containing the Brick's contents */ @Override public Polylist toPolylist() { return Polylist.list(BRICK_KEYWORD, dashed(name), BrickLibrary.keyNumToName(key), duration); }
/** * 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); }
/** * Make a Brick from a Polylist in the external representation of a RoadMap * * @param blockPolylist * @return */ public static Block fromPolylist(Polylist blockPolylist) { // Need to populate sub-blocks before calling constructor! Polylist temp; temp = blockPolylist.assoc("name"); String name = (String) temp.second(); temp = blockPolylist.assoc("variant"); String variant = temp.rest().nonEmpty() ? (String) temp.second() : DEFAULT_VARIANT; temp = blockPolylist.assoc("type"); String type = (String) temp.second(); temp = blockPolylist.assoc("key"); String key = (String) temp.second(); temp = blockPolylist.assoc("duration"); int duration = ((Number) temp.second()).intValue(); temp = blockPolylist.assoc("overlap"); boolean overlap = temp.second().equals("true"); temp = blockPolylist.assoc("end"); int endValue = ((Number) temp.second()).intValue(); temp = blockPolylist.assoc("mode"); String mode = (String) temp.second(); temp = blockPolylist.assoc("blocks"); ArrayList<Block> blocks = new ArrayList<Block>(); Polylist polyBlocks = temp.rest(); while (polyBlocks.nonEmpty()) { Polylist polyBlock = (Polylist) polyBlocks.first(); Block block = Block.fromPolylist(polyBlock); blocks.add(block); polyBlocks = polyBlocks.rest(); } Brick brick = new Brick(name, variant, BrickLibrary.keyNameToNum(key), type, blocks, mode); brick.setOverlap(overlap); brick.setSectionEnd(endValue); // Above, we are targeting this constructor: // // public Brick(String brickName, // long brickKey, // String type, // List<Block> brickList) return brick; }
// Determine whether '#' or 'b' is visible in the lick triage utility, based on // whatever the current chord is. public boolean[] getCurrentEnharmonics(int index, Polylist tones) { boolean[] enh = new boolean[5]; // We set the default visible accidental to '#' if we're in a sharp key; otherwise, set // the default to 'b'. if (keySig >= 0) { enh[CSHARP] = true; enh[DSHARP] = true; enh[FSHARP] = true; enh[GSHARP] = true; enh[ASHARP] = true; } else { enh[CSHARP] = false; enh[DSHARP] = false; enh[FSHARP] = false; enh[GSHARP] = false; enh[ASHARP] = false; } // Get the current chord if there is one. Chord current = chordProg.getCurrentChord(index); if (current == null || current.getName().equals(NOCHORD)) { return enh; } if (tones == null || tones.isEmpty()) { return enh; } // Look at all the chord tones in the list and determine whether we need to change // any accidental labels from '#' to 'b' while (tones.nonEmpty()) { NoteSymbol first = (NoteSymbol) tones.first(); tones = tones.rest(); if (first.getPitchString().length() > 1) { switch (first.getPitchString().charAt(0)) { case 'c': if (first.getPitchString().charAt(1) == '#') { enh[CSHARP] = true; } break; case 'd': if (first.getPitchString().charAt(1) == 'b') { enh[CSHARP] = false; } else if (first.getPitchString().charAt(1) == '#') { enh[DSHARP] = true; } break; case 'e': if (first.getPitchString().charAt(1) == 'b') { enh[DSHARP] = false; } break; case 'f': if (first.getPitchString().charAt(1) == '#') { enh[FSHARP] = true; } case 'g': if (first.getPitchString().charAt(1) == 'b') { enh[FSHARP] = false; } else if (first.getPitchString().charAt(1) == '#') { enh[GSHARP] = true; } break; case 'a': if (first.getPitchString().charAt(1) == 'b') { enh[GSHARP] = false; } else if (first.getPitchString().charAt(1) == '#') { enh[ASHARP] = true; } break; case 'b': if (first.getPitchString().charAt(1) == 'b') { enh[ASHARP] = false; } break; } } } return enh; }
public void setDefaultLayout() { this.layout = Polylist.list(DEFAULT_BARS_PER_LINE); }