/*
*
* Copyright (c) 2004-2008 Paul John Leonard
*
* http://www.frinika.com
*
* This file is part of Frinika.
*
* Frinika is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* Frinika is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with Frinika; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.frinika.simphoney;
import com.frinika.project.RecordingManager;
import com.frinika.project.gui.ProjectFrame;
import com.frinika.sequencer.FrinikaTrackWrapper;
import com.frinika.sequencer.model.ControllerEvent;
import com.frinika.sequencer.model.Lane;
import com.frinika.sequencer.model.MidiLane;
import com.frinika.sequencer.model.MidiPart;
import com.frinika.sequencer.model.MultiEvent;
import com.frinika.sequencer.model.NoteEvent;
import com.frinika.sequencer.model.PitchBendEvent;
import javax.sound.midi.ShortMessage;
import uk.org.toot.control.BooleanControl;
/**
*
* @author pjl
*/
public class SimphoneyRecordManager extends RecordingManager {
// MultiEvent puncEvent;
private ProjectFrame frame;
// boolean armed=false;
BooleanControl loopMarker;
private boolean createTakeRequest=false;
public SimphoneyRecordManager(ProjectFrame frame) {
super(frame.getProjectContainer(), 1000);
this.frame = frame;
// puncEvent = null;
loopMarker = new BooleanControl(0, "loopMarker", false, true) {
@Override
public void setValue(boolean flag) {
System.out.println(" LOOP MARKER " + flag );
if (true) {
createTakeRequest=true;
}
notifyParent(this);
}
};
// frame.setStatusBarMessage(" Hit special key to define ");
}
public BooleanControl getLoopMarkerControl() {
return loopMarker;
}
/**
*
* Do the processing on a low priority Tick notification thread
*
* @param tick
*/
@Override
public void notifyTickPosition(long tick) {
if (createTakeRequest) {
createTake();
createTakeRequest=false;
}
processEvents();
}
void processEvents() {
// if (currentRecordingTake.size() == 0 && (!stack.isEmpty())) {
// if (lastPart != null) {
// project.getEditHistoryContainer().mark(" Recording take ");
// if (!isDrumTake) detachLastTake();
// project.getEditHistoryContainer().notifyEditHistoryListeners();
// }
// }
Event e = null;
while ((e = stack.pop()) != null) {
ShortMessage shm = e.mess;
long tick = e.stamp;
if (shm.getCommand() == ShortMessage.NOTE_ON || shm.getCommand() == ShortMessage.NOTE_OFF) {
//Note off
if (shm.getCommand() == ShortMessage.NOTE_OFF || shm.getData2() == 0) {
// Generate a note event
NoteEvent noteEvent = pendingNoteEvents.get(shm.getChannel() << 8 | shm.getData1());
if (noteEvent != null) {
long duration = tick - noteEvent.getStartTick();
if (duration < 0) { // PJL if we hold a note after the loop end then correct the tick
duration = duration + sequencer.getLoopEndPoint() - sequencer.getLoopStartPoint();
}
noteEvent.setDuration(duration);
pendingNoteEvents.remove(shm.getChannel() << 8 | shm.getData1());
// if (puncEvent == null) {
// puncEvent = noteEvent;
// frame.setStatusBarMessage(" Special key defined. Hit it when take is ready ");
//// armed=false;
// }
addEventToRecordingTracks(noteEvent);
}
} else {
//Note on
// if (puncEvent != null) {
// if (shm.getData1() == ((NoteEvent) puncEvent).getNote()) {
// frame.setStatusBarMessage(" creating a take ");
// createTake();
// }
// }
pendingNoteEvents.put(shm.getChannel() << 8 | shm.getData1(),
new NoteEvent((FrinikaTrackWrapper) null, tick, shm.getData1(), shm.getData2(), shm.getChannel(), 0));
}
} else if (shm.getCommand() == ShortMessage.CONTROL_CHANGE) {
addEventToRecordingTracks(new ControllerEvent((FrinikaTrackWrapper) null, tick, shm.getData1(), shm.getData2()));
} else if (shm.getCommand() == ShortMessage.PITCH_BEND) {
addEventToRecordingTracks(new PitchBendEvent((FrinikaTrackWrapper) null, tick, ((shm.getData1()) | (shm.getData2() << 7)) & 0x7fff));
}
}
}
void createTake() {
System.out.println(" CREATE A TAKE ");
MidiLane ml = null;
if (currentRecordingTake.size() == 0) {
return;
}
for (Lane lane : project.getLanes()) {
if (!(lane instanceof MidiLane)) {
continue;
}
if (!((MidiLane)lane).isRecording()) continue;
ml = (MidiLane)lane;
break;
}
if (ml == null) {
return;
}
project.getEditHistoryContainer().mark(" Recording take ");
MidiPart part = new MidiPart(ml);
for (MultiEvent event : currentRecordingTake) {
try {
part.add((MultiEvent) event.clone());
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
part.setBoundsFromEvents();
project.getEditHistoryContainer().notifyEditHistoryListeners();
currentRecordingTake.clear();
}
}