package eu.bandm.music.haken ; import java.util.List; import java.util.ArrayList; import java.util.Map; import java.util.HashMap; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintWriter ; import eu.bandm.tools.annotations.Opt ; import static eu.bandm.tools.util.FileVisitor.basename ; import eu.bandm.tools.message.SimpleMessage; import eu.bandm.tools.message.MessagePrinter; import eu.bandm.tools.message.MessageReceiver; import eu.bandm.tools.message.MessageFormatter; import eu.bandm.tools.message.MessageCounter; import eu.bandm.tools.message.MessageTee; import eu.bandm.tools.message.XMLDocumentIdentifier; import eu.bandm.tscore.model.TimeScape ; import eu.bandm.tscore.model.Part ; import eu.bandm.tscore.model.Tp ; import eu.bandm.tscore.model.Vox ; import eu.bandm.tscore.model.Event ; import eu.bandm.tscore.base.Util ; /** A first version of a haken score for realization with svg geometric forms. * Input is dura=duration, color = red/yellow/green, pos=bottom/middle/top, * size=tiny/middle/large, form=circle, sixside, triangle *
* Usage: create a new instance with an already raw-parsed TimeScape; * then call update(...) with the six(6) selected voices.
* The {@link #main(String[])} method takes filenames and voice names from the command * line parameters.
*
* See {@link SvgSource} for ducumentation on the generation of dynamic SVG. * That class is NOT used here because this class extends {@link Score_hkn} instead. *
* FIXME PAUSENMODUS einstellbar *
* FIXME Allerletzte taktnummernanzeige */ public class Score_hkn_svg_v00 extends Score_hkn { // This class does NOT extend Svg_source, therefore we need ... /** Source text for "pixel" as an appended unit string.*/ final static String punit = "px" ; /** Only constructor. * @param name of the score, also used to derive output file names * @param ts the raw parsed tscore input data. * @param msg the drain of all messages. * @param parameters controll parsing, if left out, derfaults to "new {@link Parameters}". */ public Score_hkn_svg_v00 (final String name, final Part ts, final MessageReceiver> msg, final @Opt Parameters parameters){ super(name, ts, msg, parameters); } /** FIXME DOC*/ public static Map fromTimeScape (final TimeScape ts, final String topName, final MessageReceiver> msg, final @Opt Parameters parameters){ return Util.partsToScores(ts, topName, "%s_%s", msg, parameters, Score_hkn_svg_v00::new); } // NEW: pauses <=p3 visible, afterwards starts an additional blackout phase // public static final boolean pauseVisible = false ; // FIXME one method "showForm(x,y,size,col,form)" // --------------------------------------------------------------------- /** Create a polygon with radius = 100. COPIED from MovingForms FIXME */ protected static String polyPoints (final int n){ final double inc = 2.0d * Math.PI / (n * 1.0d) ; double start = Math.PI *0.5d - inc ; final StringBuilder sb = new StringBuilder(); for (int i = 0; i", "" , "" }; /** Values for size, by U,M and O.*/ public static final String[] scaleString = { "0.15", "0.5", "0.99"} ; /** Values for colors: green/yellow/red by U,M and O.*/ public static final String[] colorString = { "rgb(0,255,0)", "rgb(255,255,0)", "rgb(255,0,0)" }; /** Convert the K-voices and write out to file. * @param pw where to write the result * @param title for generating html title only * @param subtitle currently not used * @param vpause K-voice controling additional pauses, may be ==null * @param vx K-voice controling the x coordinate, may be ==null * @param vy K-voice controling the y coordinate, may be ==null * @param vcol K-voice controling the color, may be ==null * @param vsiz K-voice controling the size, may be ==null * @param vfrm K-voice controling the form, may be ==null */ public void update(final PrintWriter pw, final String title, final @Opt String subtitle, final @Opt Vox vpause, final @Opt Vox vx, final @Opt Vox vy, final @Opt Vox vcol, final @Opt Vox vsiz, final @Opt Vox vfrm){ super.update(); // = parse top timepoints and all voices into event2relwert, event2haken, etc // write headers, cf SvgSource.java: pw.println(String.format("", screensize, "px", screensize, "px")); // FIXME "px" as parameter? pw.println(" "+title+(subtitle!=null?" -- "+subtitle:"")+""); pw.println(String.format (" ", screensize-2, screensize-2)); final Expansion exp = new Expansion (vx, vy, vcol, vsiz, vfrm); exp.expand(); List wx = vx!=null ? exp.expanded.get(vx) : allMedium ; List wy = vy!=null ? exp.expanded.get(vy) : allMedium ; List wcol = vcol!=null ? exp.expanded.get(vcol) : allMedium ; List wsiz = vsiz!=null ? exp.expanded.get(vsiz) : allMedium ; List wfrm = vfrm!=null ? exp.expanded.get(vfrm) : allMedium ; float start = 0f ; Integer lastTopTp = null ; float lastTopTime = 0.0f ; ; final int s = wx.size(); // FIXME CHECK SIZE IN EXPAND / "allMedium" HAS NO SIZE for (int i = 0 ; i", poss[wx.get(i).getArrayIndex()], screensize-poss[wy.get(i).getArrayIndex()])); pw.println(" "+forms[formI] +" transform='scale("+scaleString[wsiz.get(i).getArrayIndex()] +")' fill='"+colorString[wcol.get(i).getArrayIndex()]+"' " +" opacity='0.0'>"); final float pause = i+1", start)); pw.println(String.format(" ", start+dura)); pw.println(" "+formEnd[formI]+""); start += dura ; start += dark ; // FIXME really zweimal !?!?! }//for i pw.println(""); }//update // --------------------------------------------------------------------- /** Pause stands with a K-Event and means a Pause BEFORE this event start.*/ protected float getPauseByIndex(final List tps, final Vox vpause, final int i /*GLO IN pauseDuras*/){ final int g = getPauseIndexByIndex (tps, vpause, i, maxPause ); return (g>noPauseSelected) ? pauseDuras[g] : 0.0f ; } /** Enter the dynamic display of the top tp (measure number) into the souece text. * (Cf. the svg docu concerning text * */ protected void printTopTp (final PrintWriter pw, final float start, final float end, final Integer barNum){ if(barNum==null) return ; pw.println(String.format("%s", screensize-30, screensize-15, barNum)); pw.println(String.format(" ", start)); pw.println(String.format(" ", end)); pw.println(""); } /** Main method, translates input file in HKN-vox format to svg output file. * @param args[0] input file name * @param args[1] basic score name (also determines the output files) * @param args[2] "subtitle", second part of html title ("-" stands for "none", * first part is stem name of the outputfile) * (FIXME source file inidication in generated comment still missing.) * @param args[3] name of pause voice ("-" stands for "none") * @param args[4] name of H-Voice for "xpos" * @param args[5] name of H-Voice for "ypos" * @param args[6] name of H-Voice for "color" * @param args[7] name of H-Voice for "size" * @param args[8] name of H-Voice for "form" */ public static void main (String[] args) { final MessageCounter mcnt = new MessageCounter(); final MessageReceiver> msg = new MessageTee<>(new MessageFormatter<>(new MessagePrinter<>()), mcnt); if (args.length<6) msg.receive(SimpleMessage.error("not enough command line parameters.")); mcnt.terminateApplicationOnErrors(); String message = null ; final String inputfilename = (args[0]); msg.receive(SimpleMessage.logStart("parsing input file %s to raw data", inputfilename)); final File inputfile = new File(inputfilename) ; final TimeScape ts = Util.parseTimeScape(inputfile, modifiers, msg); msg.receive(SimpleMessage.logEnd("parsing input file")); mcnt.terminateApplicationOnErrors(); // ==================================================================== // convert raw model into Score_haken semantic interpretation // ==================================================================== msg.receive(SimpleMessage.logStart(message="semantic interpretation")); final String scoreNameStem = args[1]; final Map scores = fromTimeScape(ts,scoreNameStem,msg,null); @Opt String subtitle = args[2]; if (noVoiceSelected.equals(subtitle)) subtitle = null ; for (final Score_hkn_svg_v00 score : scores.values()){ if (noVoiceSelected.equals(subtitle)) subtitle = null ; final @Opt Vox v_ps = score.findVoice (args[3], true/*=errorNotWarning on spelling error.*/); // from here different from "vla": final @Opt Vox v_xpos = score.findVoice (args[4], true); final @Opt Vox v_ypos = score.findVoice (args[5], true); final @Opt Vox v_color = score.findVoice (args[6], true); final @Opt Vox v_size = score.findVoice (args[7], true); final @Opt Vox v_form = score.findVoice (args[8], true); if (v_xpos==null && v_ypos==null && v_color==null && v_size==null && v_form==null){ msg.receive(SimpleMessage.error("no single voice has been found")); mcnt.terminateApplicationOnErrors(); } final String outputfilename = score.name + ".svg" ; msg.receive(SimpleMessage.logStart(message = "convert data and write to output file")); try{ final PrintWriter pw = new PrintWriter(new File(outputfilename)); score.update(pw, scoreNameStem, subtitle, v_ps, v_xpos, v_ypos, v_color, v_size, v_form); pw.close(); } catch(FileNotFoundException ex){ msg.receive(SimpleMessage.error("Cannot write output file %s", outputfilename)); } msg.receive(SimpleMessage.logEnd(message)); msg.receive(SimpleMessage.log("result written to %s", outputfilename)); }// for scores }//main() }