/* * Created on 5.3.2007 * * Copyright (c) 2007 Karl Helgason * * 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.renderer; import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import javax.sound.midi.MidiDevice; import javax.swing.JFrame; import javax.swing.JOptionPane; import com.frinika.project.ProjectContainer; import com.frinika.sequencer.FrinikaSequence; import com.frinika.sequencer.FrinikaSequencer; import com.frinika.sequencer.FrinikaTrackWrapper; import com.frinika.sequencer.SequencerListener; import com.frinika.sequencer.gui.mixer.SynthWrapper; import com.frinika.sequencer.model.Lane; import com.frinika.sequencer.model.MidiLane; import com.frinika.sequencer.model.MidiPlayOptions; public class FrinikaRenderer implements SequencerListener { ProjectContainer project; FrinikaSequencer seqr; ArrayList<FrinikaDeviceRenderer> deviceRenderers = new ArrayList<FrinikaDeviceRenderer>(); public FrinikaDeviceRenderer getDeviceRenderer(MidiDevice mididevice) { for(FrinikaDeviceRenderer render : deviceRenderers) if(render.getDevice() == mididevice) return render; FrinikaDeviceRenderer render = new FrinikaDeviceRenderer(this, mididevice); deviceRenderers.add(render); return render; } public FrinikaRenderer(ProjectContainer project) { this.project = project; seqr = project.getSequencer(); seqr.addSequencerListener(this); } boolean started = false; public MidiLane findLane(FrinikaTrackWrapper track) { for(Lane lane : project.getLanes()) { if(lane instanceof MidiLane) { MidiLane midilane = (MidiLane)lane; if(midilane.getTrack() == track) { return midilane; } } } return null; } public boolean anyLaneWithPreRendering() { for(Lane lane : project.getLanes()) { if(lane instanceof MidiLane) { MidiLane midilane = (MidiLane)lane; if(midilane.getPlayOptions() != null) { if(midilane.getPlayOptions().preRendered) return true; } } } return false; } public void beforeStart() { if(started) return; started = true; FrinikaSequence seq = project.getSequence(); for(FrinikaTrackWrapper track : seq.getFrinikaTrackWrappers()) { MidiPlayOptions opt = seqr.getPlayOptions(track); if(opt != null) { if(rendermode > 0) opt.preRenderedUsed = true; else opt.preRenderedUsed = false; } } Collection<FrinikaTrackWrapper> tracks; if(seqr.getSoloFrinikaTrackWrappers().size()>0) tracks = seqr.getSoloFrinikaTrackWrappers(); else tracks = seq.getFrinikaTrackWrappers(); HashSet<MidiDevice> supress_candidates = new HashSet<MidiDevice>(); for(FrinikaTrackWrapper track : tracks) if(track.getMidiDevice() != null) { MidiPlayOptions opt = seqr.getPlayOptions(track); if(opt != null) if(!opt.muted) { if(opt.preRendered) { MidiDevice dev = track.getMidiDevice(); if(dev instanceof SynthWrapper) { SynthWrapper synth = (SynthWrapper)dev; if(synth.isRenderable()) { if(suppress_realtime) supress_candidates.add(synth); opt.preRenderedUsed = true; getDeviceRenderer(synth).addTrack(track); } } } } } for(FrinikaTrackWrapper track : tracks) { MidiDevice dev = track.getMidiDevice(); if(supress_candidates.contains(dev)); { MidiPlayOptions opt = seqr.getPlayOptions(track); if(opt != null) if(!opt.preRendered) { supress_candidates.remove(dev); continue; } MidiLane lane = findLane(track); if(lane != null) { if(lane.isRecording()) { supress_candidates.remove(dev); continue; } } } } for(MidiDevice synth : supress_candidates) { if(synth instanceof SynthWrapper) ((SynthWrapper)synth).setSupressAudio(true); } for(FrinikaDeviceRenderer render : deviceRenderers) render.beforeStart(); } public void start() { for(FrinikaDeviceRenderer render : deviceRenderers) render.start(); } public void stop() { if(!started) return; started = false; for(FrinikaDeviceRenderer render : deviceRenderers) { render.stop(); if(render.dev instanceof SynthWrapper) { ((SynthWrapper)render.dev).setSupressAudio(false); } } deviceRenderers.clear(); } public void close() { stop(); seqr.removeSequencerListener(this); } public void purgeRenderCache() { File projectfile = project.getFile(); File parentdir = projectfile.getParentFile(); String name = projectfile.getName(); if(name.toLowerCase().endsWith(".frinika")) name = name.substring(0, name.length() - 8); name += "."; String suffix = ".rendercache"; File[] filelist = parentdir.listFiles(); if(filelist != null) { for(File f : filelist) { if(f.getName().startsWith(name)) if(f.getName().endsWith(suffix)) { f.delete(); } } } } int rendermode = 0; public void render(JFrame frame, long tickfrom, long tickto) { if(!anyLaneWithPreRendering()) { JOptionPane.showMessageDialog(frame, "No lane with prerender flag was found.", "Render Selected Timeline", JOptionPane.WARNING_MESSAGE); return; } rendermode = 1; new RenderDialog(frame, project, tickfrom, tickto); project.getSequencer().stop(); rendermode = 0; } public void rerender(JFrame frame, long tickfrom, long tickto) { if(!anyLaneWithPreRendering()) { JOptionPane.showMessageDialog(frame, "No lane with prerender flag was found.", "Rerender Selected Timeline", JOptionPane.WARNING_MESSAGE); return; } rendermode = 2; new RenderDialog(frame, project, tickfrom, tickto); project.getSequencer().stop(); rendermode = 0; } boolean suppress_realtime = true; public void setSupressRealTime(boolean suppress_realtime) { } }