From 86f88ea62449645cd38fbb1fa95b878d6e216fbc Mon Sep 17 00:00:00 2001 From: Jim O'Mulloy Date: Mon, 15 Jul 2024 16:46:40 +0100 Subject: [PATCH] chrod arps --- .../control/InstrumentParameterNames.java | 1 + .../workspace/tonemap/NoteTracker.java | 196 ++++++++++++------ .../desktop/monitor/swing/SynthPanel.java | 28 +++ 3 files changed, 158 insertions(+), 67 deletions(-) diff --git a/instrument-core/src/main/java/jomu/instrument/control/InstrumentParameterNames.java b/instrument-core/src/main/java/jomu/instrument/control/InstrumentParameterNames.java index 4eacda4c..dcb88aac 100644 --- a/instrument-core/src/main/java/jomu/instrument/control/InstrumentParameterNames.java +++ b/instrument-core/src/main/java/jomu/instrument/control/InstrumentParameterNames.java @@ -180,6 +180,7 @@ public class InstrumentParameterNames { public static final String PERCEPTION_HEARING_SYNTHESIS_FILL_NOTES_SWITCH = "perception.hearing.synthesis.fillNotesSwitch"; public static final String PERCEPTION_HEARING_SYNTHESIS_FILL_CHORDS_SWITCH = "perception.hearing.synthesis.fillChordsSwitch"; public static final String PERCEPTION_HEARING_SYNTHESIS_FILL_LEGATO_SWITCH = "perception.hearing.synthesis.fillLegatoSwitch"; + public static final String PERCEPTION_HEARING_SYNTHESIS_CHORD_START_TIME_SWITCH = "perception.hearing.synthesis.chordStartTimeSwitch"; public static final String PERCEPTION_HEARING_SYNTHESIS_CHORD_FIRST_SWITCH = "perception.hearing.synthesis.chordFirstSwitch"; public static final String PERCEPTION_HEARING_SYNTHESIS_AGGREGATE_CHORDS_SWITCH = "perception.hearing.synthesis.aggregateChordsSwitch"; public static final String PERCEPTION_HEARING_SYNTHESIS_MIN_TIME_INCREMENT = "perception.hearing.synthesis.minTimeIncrement"; diff --git a/instrument-core/src/main/java/jomu/instrument/workspace/tonemap/NoteTracker.java b/instrument-core/src/main/java/jomu/instrument/workspace/tonemap/NoteTracker.java index c07eff45..b0eb51c8 100644 --- a/instrument-core/src/main/java/jomu/instrument/workspace/tonemap/NoteTracker.java +++ b/instrument-core/src/main/java/jomu/instrument/workspace/tonemap/NoteTracker.java @@ -48,6 +48,8 @@ record SynthBeatParameters(int beatSource, int beatDrum, int beatOffset, int bea private boolean synthFillLegatoSwitch; + private boolean synthChordStartTimeSwitch; + private NoteTrack baseTrack; private int synthBasePattern; @@ -163,6 +165,9 @@ record SynthBeatParameters(int beatSource, int beatDrum, int beatOffset, int bea public class NoteTrack { int number; + boolean isBar; + int beat; + double quantizeRange; double salience; boolean chordPending; List notes = new CopyOnWriteArrayList<>(); @@ -172,6 +177,22 @@ public NoteTrack(int number) { this.number = number; } + public boolean isBar() { + return isBar; + } + + public void setBar(boolean isBar) { + this.isBar = isBar; + } + + public int getBeat() { + return beat; + } + + public void setBeat(int beat) { + this.beat = beat; + } + public int getNumber() { return this.number; } @@ -375,6 +396,14 @@ public NoteListElement getQuantizeNote() { public void setQuantizeNote(NoteListElement quantizeNote) { this.quantizeNote = quantizeNote; } + + public double getQuantizeRange() { + return quantizeRange; + } + + public void setQuantizeRange(double quantizeRange) { + this.quantizeRange = quantizeRange; + } } public NoteTracker(ToneMap toneMap) { @@ -401,6 +430,8 @@ public NoteTracker(ToneMap toneMap) { .getIntParameter(InstrumentParameterNames.PERCEPTION_HEARING_NOTETRACKER_SALIENT_TIME_NOTE_FACTOR); synthFillLegatoSwitch = toneMap.getParameterManager() .getBooleanParameter(InstrumentParameterNames.PERCEPTION_HEARING_SYNTHESIS_FILL_LEGATO_SWITCH); + synthChordStartTimeSwitch = toneMap.getParameterManager() + .getBooleanParameter(InstrumentParameterNames.PERCEPTION_HEARING_SYNTHESIS_CHORD_START_TIME_SWITCH); synthTimeSignature = toneMap.getParameterManager() .getIntParameter(InstrumentParameterNames.PERCEPTION_HEARING_SYNTHESIS_TIME_SIGNATURE); synthBaseMeasure = toneMap.getParameterManager() @@ -930,21 +961,49 @@ private void addChordNotes(NoteTrack track, NoteListElement quantizeNote, double int octave = 0; double startTime = 0; double quantizeStartTime = 0; - double quantizeEndTime = 0; + // double quantizeEndTime = 0; double endTime = 0; - startTime = chordListElement.getStartTime() * 1000; + if (synthChordStartTimeSwitch) { + startTime = chordListElement.getStartTime() * 1000; + } else { + startTime = time * 1000; + } double range = 100; endTime = chordListElement.getEndTime() * 1000 + incrementTime; - if (quantizeNote != null) { - NoteListElement trackQuantizeNote = track.getQuantizeNote(); - if (trackQuantizeNote == null || trackQuantizeNote.startTime < quantizeNote.startTime) { - track.setQuantizeNote(quantizeNote); - quantizeStartTime = quantizeNote.startTime; - quantizeEndTime = quantizeStartTime; - range = quantizeNote.endTime - quantizeNote.startTime; - quantizeEndTime += range > 0 ? range * synthChordParameters.chordMeasure - : synthChordParameters.chordMeasure * 100; + boolean hasBeatNote = false; + NoteListElement trackQuantizeNote = track.getQuantizeNote(); + if (quantizeNote != null && + (trackQuantizeNote == null || trackQuantizeNote.startTime < quantizeNote.startTime)) { + range = quantizeNote.startTime; + if (trackQuantizeNote != null) { + range -= trackQuantizeNote.startTime; + } + track.setQuantizeNote(quantizeNote); + track.setQuantizeRange(range); + track.setBar(true); + track.setBeat(0); + barNote = 0; + hasBeatNote = true; + quantizeStartTime = quantizeNote.startTime; + // quantizeEndTime += range > 0 ? range * synthChordParameters.chordMeasure + // : synthChordParameters.chordMeasure * 100; + } else { + if (trackQuantizeNote != null) { + quantizeStartTime = trackQuantizeNote.startTime; + range = track.getQuantizeRange(); + double barRange = range * synthChordParameters.chordMeasure; + double nextBeatTime = quantizeStartTime + ((track.getBeat() + 1) * barRange) / synthTimeSignature; + if (nextBeatTime < (time * 1000)) { + hasBeatNote = true; + track.setBeat(track.getBeat() + 1); + barNote = track.getBeat(); + LOG.severe( + ">>TRACKER T3 : " + time + ", " + nextBeatTime + ", " + barRange + + ", " + + quantizeStartTime); + } } + } double amplitude = 1.0; @@ -1015,7 +1074,7 @@ public int compare(ChordNote c1, ChordNote c2) { // } } } else { - if (quantizeStartTime > 0) { + if (hasBeatNote && barNote == 0) { for (NoteListElement nnle : newNotes) { for (NoteListElement cnle : currentNotes) { if (lastNote != null && lastNoteEndTime >= startTime) { @@ -1052,7 +1111,7 @@ public int compare(ChordNote c1, ChordNote c2) { if (track.isChordPending() || !newNotes.stream() .allMatch(nle -> currentNoteSet.contains(nle.note))) { - if (quantizeStartTime > 0) { + if (hasBeatNote && barNote == 0) { track.setChordPending(false); for (NoteListElement nnle : newNotes) { nnle.startTime = quantizeStartTime; @@ -1092,7 +1151,7 @@ public int compare(ChordNote c1, ChordNote c2) { } } } else { - if (quantizeStartTime > 0) { + if (hasBeatNote && barNote == 0) { for (NoteListElement nnle : newNotes) { for (NoteListElement cnle : currentNotes) { if (lastNote != null && lastNoteEndTime >= startTime) { @@ -1130,75 +1189,78 @@ public int compare(ChordNote c1, ChordNote c2) { } else { lastNote = track.getLastNote(); - if (synthChordParameters.chordInvert) { - rootNote += 12 * (rootOctave + synthChordParameters.chordOctave); - } else { - rootNote += 12 * synthChordParameters.chordOctave; - } - if (synthChordParameters.chordPattern == 2) { - if (isBar) { - note = rootNote; - amplitude = rootAmp; + if (hasBeatNote) { + if (synthChordParameters.chordInvert) { + rootNote += 12 * (rootOctave + synthChordParameters.chordOctave); } else { - int noteIndex = 0; - if (cnotes.size() > barNote) { - noteIndex = barNote; - } else { - int r = (int) (Math.random() * (cnotes.size())); - noteIndex = r; - } - note = cnotes.get(noteIndex); - amplitude = camps.get(noteIndex); + rootNote += 12 * synthChordParameters.chordOctave; } - } else if (synthChordParameters.chordPattern == 3) { - if (isBar) { - if (lastNote != null && lastNote.note > rootNote) { - note = cnotes.get(cnotes.size() - 1); - amplitude = camps.get(cnotes.size() - 1); - } else { + if (synthChordParameters.chordPattern == 2) { + if (isBar) { note = rootNote; amplitude = rootAmp; + } else { + int noteIndex = 0; + if (cnotes.size() > barNote) { + noteIndex = barNote; + } else { + int r = (int) (Math.random() * (cnotes.size())); + noteIndex = r; + } + note = cnotes.get(noteIndex); + amplitude = camps.get(noteIndex); } - } else { - int noteIndex = 0; - NoteListElement penultimateNote = track.getPenultimateNote(); - if (lastNote != null && penultimateNote != null && penultimateNote.note > lastNote.note) { - for (int i = 1; i < cnotes.size(); i++) { - if (cnotes.get(i) == lastNote.note) { - noteIndex = i - 1; - break; - } + } else if (synthChordParameters.chordPattern == 3) { + if (isBar) { + if (lastNote != null && lastNote.note > rootNote) { + note = cnotes.get(cnotes.size() - 1); + amplitude = camps.get(cnotes.size() - 1); + } else { + note = rootNote; + amplitude = rootAmp; } } else { - for (int i = 0; i < cnotes.size() - 1; i++) { - if (lastNote != null) { + int noteIndex = 0; + NoteListElement penultimateNote = track.getPenultimateNote(); + if (lastNote != null && penultimateNote != null && penultimateNote.note > lastNote.note) { + for (int i = 1; i < cnotes.size(); i++) { if (cnotes.get(i) == lastNote.note) { - noteIndex = i + 1; + noteIndex = i - 1; break; } } + } else { + for (int i = 0; i < cnotes.size() - 1; i++) { + if (lastNote != null) { + if (cnotes.get(i) == lastNote.note) { + noteIndex = i + 1; + break; + } + } + } } + note = cnotes.get(noteIndex); + amplitude = camps.get(noteIndex); } - note = cnotes.get(noteIndex); - amplitude = camps.get(noteIndex); } - } - if (lastNote != null && lastNote.note == note) { - lastNote.endTime = endTime; - } else { - if (lastNote != null) { - lastNote.endTime = startTime - incrementTime; - ; + if (lastNote != null && lastNote.note == note) { + lastNote.endTime = endTime; + } else { + if (lastNote != null) { + lastNote.endTime = startTime - incrementTime; + } + NoteListElement chordNote = new NoteListElement(note, pitchSet.getIndex(note), startTime, endTime, + 0, 0, + amplitude, amplitude, amplitude, 0, false, incrementTime); + track.addNote(chordNote); + LOG.finer( + ">>NT added chord arp note: " + time + ", " + chordNote.startTime + ", " + chordNote.endTime + + ", " + + note + ", " + track.getSize() + ", " + synthTimeSignature + ", " + startTime + + ", " + + endTime); } - NoteListElement chordNote = new NoteListElement(note, pitchSet.getIndex(note), startTime, endTime, 0, 0, - amplitude, amplitude, amplitude, 0, false, incrementTime); - track.addNote(chordNote); - LOG.finer( - ">>NT added chord arp note: " + time + ", " + chordNote.startTime + ", " + chordNote.endTime - + ", " - + note + ", " + track.getSize() + ", " + synthTimeSignature + ", " + startTime + ", " - + endTime); } } } diff --git a/instrument-desktop/src/main/java/jomu/instrument/desktop/monitor/swing/SynthPanel.java b/instrument-desktop/src/main/java/jomu/instrument/desktop/monitor/swing/SynthPanel.java index f612a16a..515fd8e8 100644 --- a/instrument-desktop/src/main/java/jomu/instrument/desktop/monitor/swing/SynthPanel.java +++ b/instrument-desktop/src/main/java/jomu/instrument/desktop/monitor/swing/SynthPanel.java @@ -111,6 +111,8 @@ public class SynthPanel extends JPanel { private JCheckBox synthesisLegatoSwitchCB; + private JCheckBox synthesisChordStartTimeSwitchCB; + private JCheckBox synthesisChordFirstSwitchCB; private JCheckBox synthesisChord1InvertSwitchCB; @@ -373,6 +375,23 @@ public void itemStateChanged(ItemEvent e) { .getBooleanParameter(InstrumentParameterNames.PERCEPTION_HEARING_SYNTHESIS_CHORD_FIRST_SWITCH)); tuningPanel.add(synthesisChordFirstSwitchCB); + synthesisChordStartTimeSwitchCB = new JCheckBox("synthesisChordStartTimeSwitchCB"); + synthesisChordStartTimeSwitchCB.setText("Synthesis Chord Start Time"); + synthesisChordStartTimeSwitchCB.addItemListener(new ItemListener() { + + public void itemStateChanged(ItemEvent e) { + JCheckBox cb = (JCheckBox) e.getSource(); + boolean newValue = cb.isSelected(); + parameterManager.setParameter( + InstrumentParameterNames.PERCEPTION_HEARING_SYNTHESIS_CHORD_START_TIME_SWITCH, + Boolean.toString(newValue)); + } + }); + + synthesisChordStartTimeSwitchCB.setSelected(parameterManager + .getBooleanParameter(InstrumentParameterNames.PERCEPTION_HEARING_SYNTHESIS_CHORD_START_TIME_SWITCH)); + tuningPanel.add(synthesisChordStartTimeSwitchCB); + synthesisChord1InvertSwitchCB = new JCheckBox("synthesisChord1InvertSwitchCB"); synthesisChord1InvertSwitchCB.setText("Synthesis Chord1 Invert"); synthesisChord1InvertSwitchCB.addItemListener(new ItemListener() { @@ -470,6 +489,12 @@ public void itemStateChanged(ItemEvent e) { .getBooleanParameter(InstrumentParameterNames.PERCEPTION_HEARING_SYNTHESIS_BEAT_METRONOME_CALIBRATE)); tuningPanel.add(synthesisMetronomeCalibrateSwitchCB); + tuningPanel.add(new JLabel(" ")); + tuningPanel.add(new JLabel(" ")); + tuningPanel.add(new JLabel(" ")); + tuningPanel.add(new JLabel(" ")); + tuningPanel.add(new JLabel(" ")); + JLabel synthesisChordTimingLabel = new JLabel("Synthesis Chord Timing: "); synthesisChordTimingInput = new JTextField(4); synthesisChordTimingInput.addActionListener(new ActionListener() { @@ -562,6 +587,9 @@ public void actionPerformed(ActionEvent e) { tuningPanel.add(synthesisBeatTimingLabel); tuningPanel.add(synthesisBeatTimingInput); + tuningPanel.add(new JLabel(" ")); + tuningPanel.add(new JLabel(" ")); + JLabel synthesisChord1MeasureLabel = new JLabel("Synthesis Chord1 Measure: "); synthesisChord1MeasureInput = new JTextField(4); synthesisChord1MeasureInput.addActionListener(new ActionListener() {