📄 music.java
字号:
public class Music
{
public static void main(String[] args)
{
String FileName=null;
PlayMusic PM1 = new PlayMusic("o3e2g.o4d#8e2.o3b8o4d7c8o3g.f#8f2.");
PM1.Play();
}
}
/// <summary>
/// This is a class of an origin type of Score
/// </summary>
class Score
{
private String score; //Use to store the score
public void printScore()
{
System.out.println(score);
}
/// <summary>
/// Return the String-format score
/// </summary>
/// <returns></returns>
public String getScore()
{
return score;
}
}
/// <summary>
/// This class contains the relative functions of playing the score
/// </summary>
class PlayMusic
{
String musicScore; //Use to store the score
char[] s; //A array to store the score in array
double[] convertedScore = new double[1024]; //Use to store the converted score
double[] noteLength = new double[1024]; //Use to store the length of each note
int LenOfScor = 0; //Use to denote the total number of the notes in the score
/// <summary>
/// Use a String-format score as parameter
/// </summary>
/// <param name="MusicScore"></param>
public PlayMusic(String MusicScore) //Constructor
{
musicScore = MusicScore;
Convert();
}
/// <summary>
/// Use a blank parameter, it will use La-ra to be the score automatically
/// </summary>
public PlayMusic() //Constructor
{
musicScore = "o3e2g.o4d#8e2.o3b8o4d7c8o3g.f#8f2.";
Convert();
}
/// <summary>
/// Use a Score Class as parameter
/// </summary>
/// <param name="scr"></param>
public PlayMusic(Score scr) //Constructor
{
musicScore = scr.getScore();
Convert();
}
///<summary>
/// Playing music function
/// </summary>
public void Play()
{
for (int i = 0; i < LenOfScor; i++)
{
if ((int)convertedScore[i] == 0) convertedScore[i] = 20000; //Most of human beings can't hear a sound with a frequency more than 20k,
//So we can use this frequency to be a rest note.
//Console.Beep((int)convertedScore[i], (int)noteLength[i]);
System.out.print((int)convertedScore[i]+"-");
System.out.print((int)noteLength[i]+"|");
}
}
/// <summary>
///T:Tempo
///O:Octave
///A-G:Note
///R:Rest
///#:Sharp
///-:Flat
///.:3/2 length
/// </summary>
private void Convert() //Convert the score into an easy-understood format for C#
{
try
{
s = musicScore.toUpperCase().toCharArray(); //Convert all the letter to capitalization
String note = "PCDEFGAB"; //This is all the notes, 1234567 and rest note 'P'
double xishu = Math.pow(2.0, 1 / 12.0); //To understand these, you need know some music knowledge,
//you'd better have learned an instrument.
double C1 = 261.626 / 16;
double[] Note = new double[8];
double tempo = 120;
Note[1] = C1;
Note[2] = C1 * Math.pow(xishu, 2);
Note[3] = C1 * Math.pow(xishu, 4);
Note[4] = C1 * Math.pow(xishu, 5);
Note[5] = C1 * Math.pow(xishu, 7);
Note[6] = C1 * Math.pow(xishu, 9);
Note[7] = C1 * Math.pow(xishu, 11);
Note[0] = 0;
double octave = 4;
int countcS = 0;
int countnL = 0;
for (int i = 0; i < s.length; i++) //This cycle can convert the orgin score format into 'convertedScore' and 'noteLength' arrays.
{
if (Character.isLetter(s[i])) //The dealing character is a note or command word.
{
if (s[i] == 'O' || s[i] == 'T') //The dealing character is a command word.
{
if (s[i] == 'O') //The dealing character is Octave command.
{
Digit dO = readDigit(++i); //Get the parameter of Octave.
octave = dO.Val; //modify the octave
i = dO.fixI - 1; //modify the pointer
continue;
}
else
{
Digit dT = readDigit(++i); //This is a tempo command, it does almost same thing as octave command
tempo = dT.Val;
i = dT.fixI - 1;
continue;
}
}
else
{ //This brance means the dealing char is a note
if (countnL < countcS) //This deal the circumstance when two notes meet directly, such as 'CD'.
{
noteLength[countnL++] = 60000 / tempo; //In the case, you should designate C the defalut length 4
}
convertedScore[countcS++] = Note[note.indexOf(s[i])] * Math.pow(2, octave); //Write the frequency to the convertedScore
if (i >= s.length - 1) //This deal the circumstance of the end of the score
{
if (countnL < countcS)
noteLength[countnL++] = 60000 / tempo;
}
continue;
}
}
else
{
if (s[i] == '#')
convertedScore[countcS - 1] *= xishu; //Modify the converted frequency to Sharp
else if (s[i] == '-')
convertedScore[countcS - 1] /= xishu; //Modify the converted frequency to Flat
else if (s[i] == '.')
{
if (countnL < countcS)
noteLength[countnL++] = 60000 / tempo * 1.5; //Modify the converted frequency to 1.5 times long
else
noteLength[countnL - 1] *= 1.5;
}
else if (Character.isDigit(s[i])) //Extract the digital number info such as length and octave...
{
Digit dL = readDigit(i);
noteLength[countnL++] = 60000 / tempo / dL.Val * 4;
i = dL.fixI - 1;
}
}
}
LenOfScor = countcS; //The total notes' number
}
catch (Exception e)
{
e.printStackTrace();
}
}
/// <summary>
/// This convert the number in origin score from String to integer
/// It used by the cycle above.
/// </summary>
/// <param name="i"></param>
/// <returns></returns>
private Digit readDigit(int i)
{
Digit digit = new Digit();
int count = 0;
for (count = 0; Character.isDigit(s[i]); count++)
{
i++;
if (i > s.length - 1)
{
count++;
break;
}
}
digit.fixI = i;
for (int j = 0; count > 0; count--, j++)
{
digit.Val += Integer.parseInt(String.valueOf(s[i-j-1])) * Math.pow(10, j);
}
return digit;
}
class Digit //It contains a value of the String-formatted number
//and adjust the pointer to the origin score after convertion.
{
public double Val;
public int fixI;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -