/*
* Copyright (C) 2013 たんらる
*/
package fourthline.mmlTools;
import fourthline.mmlTools.core.MMLTokenizer;
import fourthline.mmlTools.core.MelodyParser;
import fourthline.mmlTools.core.ParserWarn3ML;
import fourthline.mmlTools.core.UndefinedTickException;
/**
* MML修正ツール
* 連続している音符を置換する(ノイズ除去目的)
* @author たんらる
*/
public class MMLOptTools {
private String analysisString;
private int replaceCount = 0;
public int getReplaceCount() {
return replaceCount;
}
private String orig_tick[] = {
"32",
"32.",
"16",
"16.",
"8",
"8.",
"4",
"4.",
"2",
"2.",
"1",
"1.",
"6",
"12",
"24"
};
/**
* 変換パターン
* space: 休符
*/
private String pattern64_tick[] = {
"64 64",
"32 64",
"21 64",
"19. 64",
"9 64",
"8&21 64",
"8&9 64",
"4&9 64",
"4.&9 64",
"2&8&9 64",
"2&4.&9 64",
"1&4.&9 64",
"9&24 64",
"19&64 64",
"38 64"
};
/**
* フルートノイズを消すための、後方64休符置換
* @param mml (例:c4,f8,e-32)
* @return 合成後の token
*/
public String replaceNoise(String mml) throws UndefinedTickException {
MMLTokenizer mt = new MMLTokenizer(mml);
MelodyParser parser = new MelodyParser(null);
int beforeNoteNumber = -1;
String beforeToken = "";
String anlyToken = "";
String beforeWidth = "";
StringBuilder sb = new StringBuilder();
StringBuilder anly = new StringBuilder();
replaceCount = 0;
while (mt.hasNext()) {
String token = mt.next();
int gate = 0;
try {
gate = parser.noteGT(token);
} catch (ParserWarn3ML e) {}
int noteNumber = parser.getNoteNumber();
if (gate <= 0) {
noteNumber = 0;
}
if ( (gate > 0) && (noteNumber > 0) && (beforeNoteNumber == noteNumber) ) {
System.out.println("...."+beforeToken);
String note = toNote(beforeToken);
beforeToken = replaceTail64(note, beforeWidth);
anlyToken = " ["+note+"] ";
}
sb.append(beforeToken);
anly.append(anlyToken);
beforeToken = token;
beforeNoteNumber = noteNumber;
beforeWidth = parser.getGt();
anlyToken = beforeToken;
}
sb.append(beforeToken);
anly.append(anlyToken);
analysisString = anly.toString();
return sb.toString();
}
public String getAnalysisString() {
return analysisString;
}
private String toNote(String token) {
int noteIndex = 1;
if ( (token.length() > 1) && (!Character.isDigit(token.charAt(1))) ) {
noteIndex++;
}
String note = token.substring(0, noteIndex);
return note;
}
/**
* 後方64休符置換
* @param note ノート文字 ("c", "c+")
* @param width Length文字 ("64", "8")
* @return 合成後の token
*/
public String replaceTail64(String note, String width) throws UndefinedTickException {
int patternIndex = -1;
for (int i = 0; i < orig_tick.length; i++) {
if ( width.equals(orig_tick[i]) ) {
patternIndex = i;
break;
}
}
if (patternIndex < 0) {
return note;
}
String pattern = pattern64_tick[patternIndex];
int patternLength = pattern.length();
StringBuilder sb = new StringBuilder(note);
for (int i = 0; i < patternLength; i++) {
char c = pattern.charAt(i);
switch (c) {
case '&':
sb.append('&').append(note);
break;
case ' ':
sb.append('r');
break;
default:
sb.append(c);
break;
}
}
replaceCount++;
return sb.toString();
}
}