yonge 3 years ago
parent
commit
00878716b8

+ 37 - 27
audio-analysis/src/main/java/com/yonge/nettty/dto/UserChannelContext.java

@@ -3,6 +3,7 @@ package com.yonge.nettty.dto;
 import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -285,8 +286,13 @@ public class UserChannelContext implements PitchDetectionHandler {
 				if (musicXmlNote.getDontEvaluating()) {
 					noteAnalysis.setIgnore(true);
 				}
+				
+				NoteAnalysis lastNoteAnalysis = null;
+				if (doneNoteAnalysisList.size() > 0) {
+					lastNoteAnalysis = doneNoteAnalysisList.get(doneNoteAnalysisList.size() - 1);
+				}
 
-				noteAnalysis.setPlayFrequency(computeFrequency(chunkAnalysisList, 10));
+				noteAnalysis.setPlayFrequency(computeFrequency(chunkAnalysisList, lastNoteAnalysis, 10));
 				
 				//判断节奏(音符持续时间内有不间断的音高,就节奏正确)
 				boolean tempo = true;
@@ -300,10 +306,6 @@ public class UserChannelContext implements PitchDetectionHandler {
 							tempo = computeTempoWithAmplitude(chunkAnalysisList, lastChunkAnalysis.getAmplitude());
 						}
 					} else {
-						NoteAnalysis lastNoteAnalysis = null;
-						if (doneNoteAnalysisList.size() > 0) {
-							lastNoteAnalysis = doneNoteAnalysisList.get(doneNoteAnalysisList.size() - 1);
-						}
 						tempo = computeTempoWithFrequency(chunkAnalysisList, lastNoteAnalysis);
 					}
 				}
@@ -557,13 +559,11 @@ public class UserChannelContext implements PitchDetectionHandler {
 	public void evaluateForNote(NoteAnalysis noteAnalysis){
 		
 		if (noteAnalysis.getFrequency() == -1) {// 休止符
-			if (1 - noteAnalysis.getPlayDurationTime() / noteAnalysis.getDurationTime() < 0.1) {
-				noteAnalysis.setMusicalErrorType(NoteErrorType.NOT_PLAY);
-			} else if (1 - noteAnalysis.getPlayDurationTime() / noteAnalysis.getDurationTime() < 0.6) {
-				noteAnalysis.setMusicalErrorType(NoteErrorType.INTEGRITY_WRONG);
-			} else if (!noteAnalysis.isTempo()) {
+			if (!noteAnalysis.isTempo()) {
 				noteAnalysis.setMusicalErrorType(NoteErrorType.CADENCE_WRONG);
-			} else if (Math.abs(noteAnalysis.getFrequency() - noteAnalysis.getPlayFrequency()) > 10) {
+			}else if (1 - noteAnalysis.getPlayDurationTime() / noteAnalysis.getDurationTime() < 0.6) {
+				noteAnalysis.setMusicalErrorType(NoteErrorType.INTEGRITY_WRONG);
+			}  else if (Math.abs(noteAnalysis.getFrequency() - noteAnalysis.getPlayFrequency()) > 10) {
 				noteAnalysis.setMusicalErrorType(NoteErrorType.INTONATION_WRONG);
 			} else {
 				noteAnalysis.setMusicalErrorType(NoteErrorType.RIGHT);
@@ -625,7 +625,7 @@ public class UserChannelContext implements PitchDetectionHandler {
 		}
 	}
 	
-	private double computeFrequency(List<ChunkAnalysis> chunkAnalysisList, int offsetRange) {
+	private double computeFrequency(List<ChunkAnalysis> chunkAnalysisList, NoteAnalysis lastNoteAnalysis, int offsetRange) {
 
 		List<Double> chunkFrequencyList = chunkAnalysisList.stream().map(t -> t.getFrequency()).filter(t -> t.doubleValue() > 100 && t.doubleValue() < 2000)
 				.collect(Collectors.toList());
@@ -634,6 +634,16 @@ public class UserChannelContext implements PitchDetectionHandler {
 			return -1;
 		}
 		
+		// 剔除上一个音延续到下一个音
+		double lastFrequency = lastNoteAnalysis.getFrequency();
+		Iterator<Double> iterable = chunkFrequencyList.iterator();
+		while(iterable.hasNext()){
+			if(Math.abs(lastFrequency - iterable.next()) > 10){
+				break;
+			}
+			iterable.remove();
+		}
+		
 		// 排序
 		chunkFrequencyList = chunkFrequencyList.stream().sorted().collect(Collectors.toList());
 		
@@ -700,7 +710,7 @@ public class UserChannelContext implements PitchDetectionHandler {
 								break;
 							}
 						} else {
-							if ((unplayedSize * 100 / chunkAnalysisList.size()) > 10 || unplayedSize > 1) {
+							if ((unplayedSize * 100 / chunkAnalysisList.size()) > 10 || unplayedSize > 2) {
 								tempo = false;
 								break;
 							}
@@ -748,14 +758,14 @@ public class UserChannelContext implements PitchDetectionHandler {
 		List<Float> chunkAmplitudeList = chunkAnalysisList.stream().map(ChunkAnalysis::getAmplitude).collect(Collectors.toList());
 
 		if (chunkAmplitudeList.size() < 3) {
-			return chunkAmplitudeList.stream().filter(t -> t.floatValue() > 5).count() > 0;
+			return chunkAmplitudeList.stream().filter(t -> t.floatValue() > 3).count() > 0;
 		}
 
 		// 检测是否有多个波峰
 		int peakSize = 0;
-		int minPeakIndex = chunkAmplitudeList.size() - 1;
-		for (int i = 0; i < chunkAmplitudeList.size() - 1; i++) {
-			if (chunkAmplitudeList.get(i) < 5) {
+		int minPeakIndex = -1;
+		for (int i = 0; i < chunkAmplitudeList.size(); i++) {
+			if (chunkAmplitudeList.get(i) < 3) {
 				continue;
 			}
 			if (i == 0) {
@@ -763,24 +773,24 @@ public class UserChannelContext implements PitchDetectionHandler {
 					peakSize++;
 					minPeakIndex = i;
 				}
-			} else if (chunkAmplitudeList.get(i - 1) < chunkAmplitudeList.get(i) && chunkAmplitudeList.get(i) >= chunkAmplitudeList.get(i + 1)) {
-				peakSize++;
-				if (minPeakIndex > i) {
-					minPeakIndex = i;
+			} else if (i == chunkAmplitudeList.size() - 1) {
+				if (chunkAmplitudeList.get(i) > chunkAmplitudeList.get(i - 1)) {
+					peakSize++;
+					if (minPeakIndex == -1 || minPeakIndex > i) {
+						minPeakIndex = i;
+					}
 				}
-			}
-
-			if (i == chunkAmplitudeList.size() - 2) {
-				if (chunkAmplitudeList.get(i) < chunkAmplitudeList.get(i + 1)) {
+			} else {
+				if (chunkAmplitudeList.get(i - 1) < chunkAmplitudeList.get(i) && chunkAmplitudeList.get(i) >= chunkAmplitudeList.get(i + 1)) {
 					peakSize++;
-					if (minPeakIndex > i) {
+					if (minPeakIndex == -1 || minPeakIndex > i) {
 						minPeakIndex = i;
 					}
 				}
 			}
 		}
 
-		tempo = peakSize == 1;
+		tempo = peakSize <= 1;
 
 		// 检测是否延迟进入
 		if (tempo == true) {