⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 music.java

📁 把音乐音符的音调转换成频率输出
💻 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 + -