/* Copyright (c) Haojun Wang, University of Southern California
* April 2005
*
* This program of a preliminary version of software that
* convert Humdrum format file into MuseData format file.
* You are free to use it for personal study and usage only.
* This program is provided "AS IS", with absolutely no
* warranties. I hope to make a revised version of this program
* that supports more ocmplete Humdrum format and MuseData format.
*
* To compile it, type javac Kern2muse.java
*
* To run it type java Kern2muse
* By Default, the program will read in test.krn, and generate test.md as output
*
* Haojun Wang
* Wed Apr 27 18:40:50 PST 2005
*/
import java.util.*;
import java.io.*;
import java.lang.reflect.Array;
public class Kern2Muse
{
private LinkedList scores;
private String input;
private String output;
public Kern2Muse(String input, String output)
{
scores = new LinkedList();
this.input = input;
this.output = output;
processData();
}
/**
*
* To read in Humdrum file and generate MuseData file
* Parse the header of Humdrum first, and generate the header in Musedata file,
* then parse the body of Humdrum file, and generate the body of Musedata
* accordingly.
*/
public void processData()
{
try
{
//Definitions of input and output streams
BufferedReader reader1 = new BufferedReader(new FileReader(this.input));
OutputStream stream1;
stream1 = new FileOutputStream(this.output,true);
PrintStream out1 = new PrintStream(stream1);
// start reading data
String line = new String();;
String[] fields;
Vector staff = new Vector();
Vector clef = new Vector();
String tempo = new String();
boolean header = false;
String temp = new String();
String temp1 = new String();
boolean body = true;
int i =1;
// process the header here
while (!header)
{
line = reader1.readLine();
if (line.contains("kern")) {
// generate the number of staffs, need to support chord
fields = line.split("\t");
//System.out.println(fields[0]);
for (int j = 0; j=0; j--){
temp1 = (String)(clef.get(j));
//System.out.println(temp1);
// need to support more clef symbols here
if (temp1.contains("G2")) {
temp = temp.concat(" C" + i +":04");
}
if (temp1.contains("F4")) {
temp = temp.concat(" C" + i +":22");
}
i++;
}
out1.println(temp);
//process score part here
String duration = new String();
String noteType = new String();
String stemDirection = new String();
String flat = new String();
String beam = new String();
String slur = new String();
int k = 2;
while((line = reader1.readLine()) != null&& (body == true))
{
fields = line.split("\t");
if (fields[0].contains("-")) {
// end of file
body = false;
out1.println("/END");
}else if (fields[0].contains("=")) {
// generate scores in one messure at a time
for (int j =0; j< scores.size();j++){
for (int l = 0; l<((Vector)(scores.get(j))).size(); l++) {
out1.println( ((Vector)(scores.get(j))).get(l));
}
((Vector)(scores.get(j))).clear();
if (j < scores.size()-1)
out1.println("back");
}
out1.println("measure " + k);
k ++;
}else {
for (int j = Array.getLength(fields)-1 ; j>=0; j--){
flat = "";
stemDirection ="";
beam = "";
slur = "";
// Parse the duration and notetype here
if (fields[j].startsWith("16")){
duration = "1";
noteType = "s";
fields[j]=fields[j].substring(2);
}else if (fields[j].startsWith("8")){
duration = "2";
noteType = "e";
fields[j]=fields[j].substring(1);
}else if (fields[j].startsWith("4")){
duration = "4";
noteType = "q";
fields[j]=fields[j].substring(1);
}else if (fields[j].startsWith("2")){
duration = "8";
noteType = "h";
fields[j]=fields[j].substring(1);
}else if (fields[j].startsWith("1")){
duration = "16";
noteType = "w";
fields[j]=fields[j].substring(1);
}
// Parse the slur, beam, stem direction, flat and # here, need to support nested slur and beam
if (fields[j].contains("/")){
stemDirection = "u";
}
if (fields[j].contains("\\")){
stemDirection = "d";
}
if (fields[j].contains("L")){
beam = "[";
}
if (fields[j].contains("J")){
beam = "]";
}
if (fields[j].contains("(")){
slur = "(";
}
if (fields[j].contains(")")){
slur = ")";
}
if (fields[j].contains("#")){
flat = "#";
}
if (fields[j].contains("-")){
flat = "b";
}
//only keep notes, rest symbols here for next step parsing
fields[j]= fields[j].replaceAll("[^a-gr.A-G]","");
fields[j]=fields[j].trim();
//System.out.println(fields[j]);
i = fields[j].length();
if (fields[j].contains("r")) {
temp = "rest";
} else if (Character.isLowerCase(fields[j].charAt(0))) {
temp = (fields[j].substring(0,1)).toUpperCase() + flat + String.valueOf(i+3);
}else {
temp = fields[j].substring(0,1) + flat + String.valueOf(4-i);
}
temp = temp + "\t" + duration + "\t" + noteType + "\t" + stemDirection + "\t" + beam + "\t" + slur;
//System.out.println(temp);
if (!fields[j].startsWith("."))
((Vector)(scores.get(j))).add(temp);
}
}
}
reader1.close();
}
catch(IOException ex)
{
System.out.println(ex.toString());
}
}
/**
*
* To eliminate the duplicated information in Humdrum header
*/
public Vector parseHeader(String[] fields)
{
Vector header = new Vector();
header.add(fields[0]);
boolean newHeader = true;
String temp = new String();
for (int j = 1; j