trackNameMessage = (MetaMessage)msg;
trackName = new String(trackNameMessage.getData());
}
- } else if (status >= 192 && status <= 207) {
+ } else if (status >= 192 && status < 208) {
programChangeMessage = (ShortMessage)msg;
+ // System.out.println("Program change " + programChangeMessage.getData1());
channel = status - 192;
}
}
if (record.getText() == "Record") {
/* Show a dialog with:
"Track" combo box,
- ("Channel" combo box,)
+ "Channel" combo box (disabled?,
"Quantize" checkbox and
"Start Recording" button.
*/
mtv.disableKeyboardRecording();
sequencer.stopRecording();
sequencer.recordDisable(track);
- mtv.placeNoteElements(quantize);
+ Moosique.convertTrack(track, quantize);
+ mtv.placeNoteElements();
}
}
}
private Insets insets;
private Rectangle box;
private int ticksPerSixteenth, popupY = 0;
- private boolean leftMouseButtonPressed = false, quantizeRecording = false;
+ private boolean leftMouseButtonPressed = false;
+ private static boolean snapToSixteenths = true;
protected static int viewLength = 0;
protected static int extraHeight = 0;
public static final int NOTE_HEIGHT = 10, NOTE_WIDTH = 40, VIEW_WIDTH = 200;
setLayout(null);
setPreferredSize(new Dimension(VIEW_WIDTH, 140 * NOTE_HEIGHT));
- placeNoteElements(false);
+ placeNoteElements();
// Creates panel pop-up menu.
popup = new JPopupMenu();
/**
* Creates note elements for all MooNotes in the track, and places them in the appropriate place.
*/
- public void placeNoteElements(boolean quantize) {
- // Converts the track.
- Moosique.convertTrack(track);
-
+ public void placeNoteElements() {
// Empties the container
removeAll();
coords = new ArrayList(track.size() / 2);
// Calculates coordinates.
x = insets.left;
- if (quantizeRecording) {
- // Snap to nearest sixteenth
- y = insets.top + Math.round(mn.getTick() / ticksPerSixteenth) * NOTE_HEIGHT;
- height = (mn.getDuration() / ticksPerSixteenth) * NOTE_HEIGHT;
- } else {
- y = insets.top + (int)((mn.getTick() * NOTE_HEIGHT) / ticksPerSixteenth);
- height = (mn.getDuration() * NOTE_HEIGHT) / ticksPerSixteenth;
- }
+ y = insets.top + (int)((mn.getTick() * NOTE_HEIGHT) / ticksPerSixteenth);
+ height = (mn.getDuration() * NOTE_HEIGHT) / ticksPerSixteenth;
if (height == 0) height = NOTE_HEIGHT;
+ if (snapToSixteenths && height < NOTE_HEIGHT) height = NOTE_HEIGHT;
r = new Rectangle(x, y, NOTE_WIDTH, height);
// Places the element in the appropriate place.
private static long editPosition;
private static boolean makeGUI = true, initSound = true, edited = false, drawEmptyTracks = false;
public static final int DEFAULT_RESOLUTION = 96, DEFAULT_TRACKS = 4;
+ public static final int WHOLE_NOTE = 0, HALF_NOTE = 1, QUARTER_NOTE = 2, EIGHTH_NOTE = 3, SIXTEENTH_NOTE = 4;
/**
* Starts the application.
// Acquires MIDI devices and connects them.
System.out.print("Initializing MIDI devices.");
try {
+ // Configures sequencer
sequencer = MidiSystem.getSequencer();
System.out.print(".");
sequencer.open();
+ sequencer.addMetaEventListener(new SongEndListener());
+
+ // Configures synthesizer
synthesizer = MidiSystem.getSynthesizer();
System.out.print(".");
synthesizer.open();
+
+ // Configures receiver, transmitter and channels.
receiver = synthesizer.getReceiver();
sequencer.getTransmitter().setReceiver(receiver);
channels = synthesizer.getChannels();
* Calculates the position (measures, beats, ticks) in the current sequence for the given tick position.
* @return an array of integers where index 0 is measures, 1 is beats and 2 is ticks.
*/
- public static int[] getPositionForTick(long ticks) {
+ public static int[] getPositionForTicks(long ticks) {
/*
int measures, beats, ticks;
for (int i = 0; i < timeSignatures.length; i++) {
/**
* Wraps each NoteOn event in the track with its NoteOff event in a MooNote.
+ * @param track the track to convert
+ * @param quantize whether to round locations and durations in the track to nearest 16th
+ * @return a list of the created MooNotes
*/
- public static List convertTrack(Track track) {
+ public static List convertTrack(Track track, boolean quantize) {
// Searches the track for NoteOn and NoteOff events
ArrayList noteOns = new ArrayList(track.size() / 2);
ArrayList noteOffs = new ArrayList(track.size() / 2);
- ArrayList mooNotes = new ArrayList();
+ ArrayList newMooNotes = new ArrayList();
MidiEvent event;
for (int j = 0; j < track.size(); j++) {
event = track.get(j);
mn = new MooNote(on, new MidiEvent((ShortMessage)on.getMessage().clone(), on.getTick() + 48));
}
track.add(mn);
- mooNotes.add(mn);
+ newMooNotes.add(mn);
iOn.remove();
}
}
- return mooNotes;
+ if (quantize) quantize(newMooNotes, SIXTEENTH_NOTE, true, true);
+ return newMooNotes;
}
/**
public static boolean load(String file) {
// Loads sequence from file
filename = file;
- try {
- seq = MidiSystem.getSequence(new File(filename));
- } catch (InvalidMidiDataException e) {
- return false;
- } catch (IOException e) {
- return false;
- }
+ try {seq = MidiSystem.getSequence(new File(filename));}
+ catch (Exception e) {return false;}
edited = false;
Track[] tracks = seq.getTracks();
// Converts tracks.
for (int i = 0; i < tracks.length; i++) {
- convertTrack(tracks[i]);
+ convertTrack(tracks[i], false);
}
// Sends sequence to GUI and sequencer, then returns
return true;
}
+ /**
+ * Quantizes the given list of MIDI events
+ * @param notes a list of the notes to quantize
+ * @param resolution the note size to round each note to
+ * @param location whether the quantize should affect the location of the note
+ * @param duration whether the quantize should affect the duration of the note
+ */
+ public static void quantize(List notes, int resolution, boolean location, boolean duration) {
+ // Math.round(mn.getTick() / ticksPerSixteenth);
+ }
+
/**
* Loads the user preferences.
*/
}
/**
- * A Comparator for sorting lists of MidiEvents.
+ * A Ccmparator for sorting lists of MidiEvents.
*/
public static class MidiEventComparator implements Comparator {
public int compare(Object o1, Object o2) {
return (int)(((MidiEvent)o1).getTick() - ((MidiEvent)o2).getTick());
}
}
+
+ /**
+ * A listener for detecting the end of the sequence.
+ */
+ public static void class SongEndListener implements MetaEventListener {
+ public void meta(MetaMessage event) {
+ if (event.getType() == 47 ) sequencer.stop(); // End of stream
+ }
+ }
}
\f
-jar cmf manif Moosique.jar *.class *.java midi\*.mid images\*.gif Manual.txt
-manif: Main-Class: Moosique
+AKTIVITET
+Björn Menyn
+Einar Tempo / taktart
+Mike
+Rolle Spara konfiguration
+ Arbetskatalog
+ Fem senaste öppnade filerna
+ Preferences (se nedan)
\f
-Varför ritar den ut de tomma spåren i en ny fil? Rätt, men hur?
-Lägg till redigeringsfunktionerna i menyn. Metoderna flyttas till MooView?
-Fixa kanalnummer 1,2,10 i nya filer.
-Kopiera/flytta spår, möjligt?
+BUGGAR
+x Varför ritar den ut de tomma spåren i en ny fil? Rätt, men hur?
+x Varför hänger sig Play om man ändrar duration på en not?
+x Kopiera/flytta spår, möjligt?
\f
-IO
-x Lägg till alla metameddelanden i filerna vi skapar. Annars är det lite dumt.
-x Play hänger sig om man ändrar duration på en not.
-x Spara konfiguration?
- Arbetskatalog
- Fem senaste öppnade filerna
- Valda MIDI-enheter
-
-x Stopp
-sequencer.addMetaEventListener(new MetaEventListener() {
- public void meta(MetaMessage event) {
- if (event.getType() == 47 ) sequencer.stop(); // End of stream
- }
-};
-
TEMPO / TAKTART
-x Räkna ut tempo och taktart. Skicka (på nåt sätt) tempovektorn till MooToolbar.
-x Räkna ut position (takt, slag, cent) för tick i Moosique. Behövs i NoteProp, ViewCounter, Menu etc.
-x Gör en ruta för taktarten i MooViews övre vänstra hörn.
-x Gör en ruta för tempot i MooToolbar.
-
-SWING
-x Lägg till en tom panel i MooGUI för att fylla ut skärmen. Använd BoxLayout!!
-x Fixa så att toolbarens rutor sitter fast! Använd BoxLayout!!
-x Implementera klart menyn, med alla dialoger.
-x Mnemonicsarna i menyn är konstiga...
+x Räkna ut tempo och taktart. Tempo > MooToolbar.
+x Implementera getTicksForPosition, getPositionForTicks och quantize i Moosique.
+x Lägg till event för tempo, time signature, program change (inkl. kanal 1,2,10) i nya filer.
ANNAT
x Fixa InstrumentList.
x Textfält som gör att man bara kan skriva in siffror? (MooNoteProp)
-MooToolbar
-
-Volymkontroll? - Använd Moosique.setVolume(long volume);
-Progress Bar? - getTickLength() för max, getTickPosition() för position.
+\f
+PREFERENCES
-MooTrackView
+x MIDI Devices - Comboboxar över tillgängliga sequencers och synthesizers.
+x "Allow smaller note elements than 1/16" - Checkbox mot variabeln MooTrackView.snapToSixteenths
+Vilka mer booleaner ska man kunna ändra?
-x Highlighta noter som spelas? (Enligt kravspec.)
-x Ändra längden på MooNoteElement (JPanel).
- Känn av klick på panelens gräns, MouseMotionListener känner av när ny ruta nås.
- void mouseDragged(MouseEvent)
- Called in response to the user moving the mouse while holding a mouse button down.
- This event is fired by the component that fired the most recent mouse-pressed event,
- even if the cursor is no longer over that component.
- Eller.. ComponentListener.componentMoved(ComponentEvent e)
+\f
+SWING
+ MooView
+ Lägg till en tom panel för att fylla ut skärmen. Med BoxLayout?
+
+ MooMenu
+ Mnemonicsarna är konstiga.
+
+ MooToolbar
+ Fixa så att allt sitter fast! Med BoxLayout?
+ Lägg till?
+ Volymkontroll Använd Moosique.setVolume(long volume);
+ Progress Bar getTickLength() för max, getTickPosition() för position.
+ Lablar för tempo och taktart
+ Fler knappar - Preferences, Octave up/down,
+
+ MooTrackView
+ Ändra längden på MooNoteElement (JPanel).
+ Känn av klick på panelens gräns, MouseMotionListener känner av när ny ruta nås.
+ Integrera MooViewCounter i MooTrackView genom att variera de horisontella streckens gråa nyanser?!?
+ (Omöjligt att följa strecken till högra änden av skärmen.)
+ Highlighta noter som spelas? (Enligt kravspec.)
-x Integrera MooViewCounter i MooTrackView genom att istället variera de horisontella streckens gråa nyanser?!?
- (Omöjligt att följa strecken till högra änden av skärmen.)
+\f
+jar cmf manif Moosique.jar *.class *.java midi\*.mid images\*.gif Manual.txt
+manif: Main-Class: Moosique
\f
\ No newline at end of file