1.读取音乐文件(20分)
//解析Json文件并以字符串的形式进行返回
private fun getJson(): String { //String是返回值的类型
val assetManager=assets //定义一个assets对象,用于获取assets文件夹下的文件
val fd= InputStreamReader(assetManager.open("read.json")) //读取音谱json文件
val bf=fd.buffered() //定义一个缓冲区进行存放数据
var bd=StringBuilder() //创建一个构造其对象
bf.forEachLine { //遍历出里边的每一行数据
if (it!=null){ //过滤掉空行
bd.append(it) //将其存放到构造器中
}
}
return bd.toString() //以字符串的形式进行返回
}
2.解析JSON格式文件,获得音符序列(20分)
3.将音符序列构建成Note对象组成的数组(20分)
//解析Json字符串,并用数字来表示每一个音符,以一个可变的列表返回
private fun parseJSONWithJSONObject(): MutableList<Int> { //返回值是一个可变的列表
val result = getJson() //调用读取Json的函数
var musicValue = mutableListOf<Int>() //定义一个泛类可变列表进行存储转化的音谱
try {
//第一层:
//在json格式中不能直接进入到最底层的键值对中,需要一层层的进去
//这里先是进入到containerList中,我只要一层一层的进去就成功了
val jsonArray = JSONArray(result) //将字符串转化为Json格式
for (i in 0 until jsonArray.length()) { //遍历Json找键值对
val jsonObject1 = jsonArray.getJSONObject(i)
val containerList = jsonObject1.getString("containerList")
//第二层:
val jsonArray = JSONArray(containerList)
for (i in 0 until jsonArray.length()) {
val jsonObject2 = jsonArray.getJSONObject(i)
val notes = jsonObject2.getString("notes")
//第三层:
val jsonArray = JSONArray(notes)
for (i in 0 until jsonArray.length()) {
val jsonObject3 = jsonArray.getJSONObject(i)
val name = jsonObject3.getString("name")
val octave = jsonObject3.getString("octave")
when (name) { //将音符以数值的形式进行表示,when相当于Java的switch
"C" -> musicValue.add(0 + (12 * octave.toInt()))
"C#" -> musicValue.add(1 + (12 * octave.toInt()))
"D" -> musicValue.add(2 + (12 * octave.toInt()))
"D#" -> musicValue.add(3 + (12 * octave.toInt()))
"E" -> musicValue.add(4 + (12 * octave.toInt()))
"F" -> musicValue.add(5 + (12 * octave.toInt()))
"F#" -> musicValue.add(6 + (12 * octave.toInt()))
"G" -> musicValue.add(7 + (12 * octave.toInt()))
"G#" -> musicValue.add(8 + (12 * octave.toInt()))
"A" -> musicValue.add(9 + (12 * octave.toInt()))
"A#" -> musicValue.add(10 + (12 * octave.toInt()))
"B" -> musicValue.add(11 + (12 * octave.toInt()))
}
}
}
}
} catch (e: Exception) {
e.printStackTrace()
}
return musicValue //返回一个音谱列表
}
4.对音高进行统计分析(最高音、最低音、音域)(20分)
//求出音域的范围,同时输出最高音和最低发音,以及音域
private fun MinMax(musicValue: MutableList<Int>) {
println("音域数组如下:")
var count=0
for(v in musicValue){
count++ //控制每行输出十个数
print("${v} ")
if (count%10==0){
println()
}
}
var min:Int=107 //将最低音初始化为最大值
var max:Int=0 //将最高音初始化为最小值
for(v in musicValue){ //找出最高音和最低音
if(v!=0){
if(v<min) min=v
}
if (v>max) max=v
}
println() //直接输出音域
println("最高音为: ${max}")
println("最低音为: ${min}")
println("音域的范围:${min}--${max}")
println("音总的个数为:${musicValue.count()}")
}
5.按音名统计各音出现的频率,并分析音乐的调性(20分)
//统计每个音出现的次数,并以字典的形式返回
private fun Count(musicValue: MutableList<Int>): HashMap<Int, Int> {
//统计每个音出现的次数
val map=HashMap<Int,Int>() //定义一个字典存放每个音出现的次数
musicValue.forEach { it ->
val count=map[it] //转化为键值对
if(count==null)map[it]=1
else map[it]=count+1
}
//对处理好键值对的字典进行按keys进行排序
val musicMap = map.entries.sortedBy { it.key}.associateBy({ it.key }, { it.value }) as HashMap<Int, Int>
println()
for((key,value) in musicMap){
println("音名为 ${key} 出现的次数为: ${value}")
}
return musicMap
}