yonge 3 년 전
부모
커밋
1ca0f13a26

+ 1 - 1
audio-analysis/src/main/java/com/yonge/netty/dto/HardLevelEnum.java

@@ -14,7 +14,7 @@ public enum HardLevelEnum implements BaseEnum<String, HardLevelEnum> {
 	 * 节奏有效范围(1分音符), 节奏有效范围(2分音符), 节奏有效范围(4分音符), 节奏有效范围(8分音符), 节奏有效范围(16分音符), 节奏有效范围(32分音符)<br>
 	 * 完成度范围, 未演奏的范围
 	 */
-	ADVANCED("进阶级", 3, 5, 8, 8, 15, 15, 30, 30, 80, 10),
+	ADVANCED("进阶级", 3, 5, 8, 8, 15, 15, 30, 30, 60, 10),
 	//ADVANCED("进阶级", 3, 5, 50, 50, 50, 50, 50, 5, 80, 10),
 	/**
 	 * 大师级, 振幅阈值, 频率阈值 <br>

+ 56 - 16
audio-analysis/src/main/java/com/yonge/netty/dto/UserChannelContext.java

@@ -36,6 +36,8 @@ public class UserChannelContext {
 	
 	private int offsetMS;
 	
+	private double dynamicOffset;
+	
 	private String platform;
 	
 	private Long recordId;
@@ -190,6 +192,7 @@ public class UserChannelContext {
 		playTime = 0;
 		receivedTime = 0;
 		delayPrcessed = false;
+		dynamicOffset = 0;
 	}
 	
 	public MusicXmlBasicInfo getMusicXmlBasicInfo(Integer songId){
@@ -312,10 +315,6 @@ public class UserChannelContext {
 		
 		receivedTime += durationTime;
 		
-		/*if(offsetMS == 0){
-			return;
-		}*/
-		
 		if(receivedTime < offsetMS){
 			return;
 		}
@@ -339,7 +338,7 @@ public class UserChannelContext {
 		
 		if (noteAnalysis.getMusicalNotesIndex() >= 0 && noteAnalysis.getMusicalNotesIndex() <= getTotalMusicNoteIndex(null)) {
 			
-			LOGGER.info("Frequency:{}  splDb:{}  Power:{}  amplitude:{}  rms:{}  time:{}", playFrequency, splDb, power, amplitude, rms, playTime);
+			LOGGER.info("delayPrcessed:{} dynamicOffset:{}  Frequency:{}  splDb:{}  Power:{}  amplitude:{}  rms:{}  time:{}", delayPrcessed, dynamicOffset, playFrequency, splDb, power, amplitude, rms, playTime);
 			
 			ChunkAnalysis chunkAnalysis = new ChunkAnalysis(playTime - durationTime, playTime, playFrequency, splDb, power, amplitude);
 			
@@ -354,10 +353,11 @@ public class UserChannelContext {
 				
 				delayPrcessed = true;
 				//计算延迟偏移值
-				playTime = musicXmlNote.getTimeStamp() + durationTime;
+				//playTime = musicXmlNote.getTimeStamp() + durationTime;
+				dynamicOffset = chunkAnalysis.getStartTime();
 			}
 			
-			if (playTime >= (musicXmlNote.getDuration() + musicXmlNote.getTimeStamp())) {
+			if (playTime >= (dynamicOffset + musicXmlNote.getDuration() + musicXmlNote.getTimeStamp())) {
 
 				if (musicXmlNote.getDontEvaluating()) {
 					noteAnalysis.setIgnore(true);
@@ -486,11 +486,17 @@ public class UserChannelContext {
 	public void evaluateForNote(MusicXmlNote musicXmlNote, NoteAnalysis noteAnalysis) {
 		
 		double floatingRange = musicXmlNote.getDuration() * hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator()) / 100;
-		double endTime = musicXmlNote.getDuration() + musicXmlNote.getTimeStamp() - floatingRange;
-		double startTime = musicXmlNote.getTimeStamp() - floatingRange;
+		
+		double endTime = musicXmlNote.getTimeStamp() + dynamicOffset + floatingRange;
+		double startTime = musicXmlNote.getTimeStamp() + dynamicOffset - floatingRange;
 		
 		List<ChunkAnalysis> chunkAnalysisList = totalChunkAnalysisList.stream().filter(t -> Double.doubleToLongBits(t.getStartTime()) >= Double.doubleToLongBits(startTime) && Double.doubleToLongBits(t.getEndTime()) <= Double.doubleToLongBits(endTime)).collect(Collectors.toList());
 		
+		double correctedStartTime = queryFirstNoteStartTime(chunkAnalysisList, musicXmlNote);
+		double correctedEndTime = correctedStartTime + musicXmlNote.getDuration();
+		
+		chunkAnalysisList = totalChunkAnalysisList.stream().filter(t -> Double.doubleToLongBits(t.getStartTime()) >= Double.doubleToLongBits(correctedStartTime) && Double.doubleToLongBits(t.getEndTime()) <= Double.doubleToLongBits(correctedEndTime)).collect(Collectors.toList());
+		
 		double playDurationTime = 0;
 		
 		if (subjectId == 23 || subjectId == 113) {
@@ -587,11 +593,17 @@ public class UserChannelContext {
 	private int computeFrequency(MusicXmlNote musicXmlNote) {
 		
 		double floatingRange = musicXmlNote.getDuration() * hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator()) / 100;
-		double endTime = musicXmlNote.getDuration() + musicXmlNote.getTimeStamp() - floatingRange;
-		double startTime = musicXmlNote.getTimeStamp() - floatingRange;
+		
+		double endTime = musicXmlNote.getTimeStamp() + dynamicOffset + floatingRange;
+		double startTime = musicXmlNote.getTimeStamp() + dynamicOffset - floatingRange;
 		
 		List<ChunkAnalysis> chunkAnalysisList = totalChunkAnalysisList.stream().filter(t -> Double.doubleToLongBits(t.getStartTime()) >= Double.doubleToLongBits(startTime) && Double.doubleToLongBits(t.getEndTime()) <= Double.doubleToLongBits(endTime)).collect(Collectors.toList());
 		
+		double correctedStartTime = queryFirstNoteStartTime(chunkAnalysisList, musicXmlNote);
+		double correctedEndTime = correctedStartTime + musicXmlNote.getDuration();
+		
+		chunkAnalysisList = totalChunkAnalysisList.stream().filter(t -> Double.doubleToLongBits(t.getStartTime()) >= Double.doubleToLongBits(correctedStartTime) && Double.doubleToLongBits(t.getEndTime()) <= Double.doubleToLongBits(correctedEndTime)).collect(Collectors.toList());
+		
 		if(chunkAnalysisList == null || chunkAnalysisList.size() == 0){
 			return -1;
 		}
@@ -624,10 +636,16 @@ public class UserChannelContext {
 	private boolean computeTempoWithFrequency(MusicXmlNote musicXmlNote){
 		
 		double floatingRange = musicXmlNote.getDuration() * hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator()) / 100;
-		double endTime = musicXmlNote.getDuration() + musicXmlNote.getTimeStamp() - floatingRange;
-		double startTime = musicXmlNote.getTimeStamp() - floatingRange;
 		
-		List<ChunkAnalysis>  chunkAnalysisList = totalChunkAnalysisList.stream().filter(t -> Double.doubleToLongBits(t.getStartTime()) >= Double.doubleToLongBits(startTime) && Double.doubleToLongBits(t.getEndTime()) <= Double.doubleToLongBits(endTime)).collect(Collectors.toList());
+		double endTime = musicXmlNote.getTimeStamp() + dynamicOffset + floatingRange;
+		double startTime = musicXmlNote.getTimeStamp() + dynamicOffset - floatingRange;
+		
+		List<ChunkAnalysis> chunkAnalysisList = totalChunkAnalysisList.stream().filter(t -> Double.doubleToLongBits(t.getStartTime()) >= Double.doubleToLongBits(startTime) && Double.doubleToLongBits(t.getEndTime()) <= Double.doubleToLongBits(endTime)).collect(Collectors.toList());
+		
+		double correctedStartTime = queryFirstNoteStartTime(chunkAnalysisList, musicXmlNote);
+		double correctedEndTime = correctedStartTime + musicXmlNote.getDuration();
+		
+		chunkAnalysisList = totalChunkAnalysisList.stream().filter(t -> Double.doubleToLongBits(t.getStartTime()) >= Double.doubleToLongBits(correctedStartTime) && Double.doubleToLongBits(t.getEndTime()) <= Double.doubleToLongBits(correctedEndTime)).collect(Collectors.toList());
 		
 		if(chunkAnalysisList == null || chunkAnalysisList.size() == 0){
 			return false;
@@ -712,11 +730,17 @@ public class UserChannelContext {
 	private boolean computeTempoWithAmplitude2(MusicXmlNote musicXmlNote) {
 
 		double floatingRange = musicXmlNote.getDuration() * hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator()) / 100;
-		double endTime = musicXmlNote.getDuration() + musicXmlNote.getTimeStamp() - floatingRange;
-		double startTime = musicXmlNote.getTimeStamp() - floatingRange;
+		
+		double endTime = musicXmlNote.getTimeStamp() + dynamicOffset + floatingRange;
+		double startTime = musicXmlNote.getTimeStamp() + dynamicOffset - floatingRange;
 		
 		List<ChunkAnalysis> chunkAnalysisList = totalChunkAnalysisList.stream().filter(t -> Double.doubleToLongBits(t.getStartTime()) >= Double.doubleToLongBits(startTime) && Double.doubleToLongBits(t.getEndTime()) <= Double.doubleToLongBits(endTime)).collect(Collectors.toList());
 		
+		double correctedStartTime = queryFirstNoteStartTime(chunkAnalysisList, musicXmlNote);
+		double correctedEndTime = correctedStartTime + musicXmlNote.getDuration();
+		
+		chunkAnalysisList = totalChunkAnalysisList.stream().filter(t -> Double.doubleToLongBits(t.getStartTime()) >= Double.doubleToLongBits(correctedStartTime) && Double.doubleToLongBits(t.getEndTime()) <= Double.doubleToLongBits(correctedEndTime)).collect(Collectors.toList());
+		
 		if(chunkAnalysisList == null || chunkAnalysisList.size() == 0){
 			return false;
 		}
@@ -784,6 +808,22 @@ public class UserChannelContext {
 		return tempo;
 	}
 	
+	private double queryFirstNoteStartTime(List<ChunkAnalysis> chunkAnalysisList, MusicXmlNote musicXmlNote) {
+
+		NoteFrequencyRange standardNote = new NoteFrequencyRange(standardFrequecy, musicXmlNote.getFrequency());
+
+		NoteFrequencyRange noteFrequencyRange = null;
+
+		for (ChunkAnalysis ca : chunkAnalysisList) {
+			noteFrequencyRange = new NoteFrequencyRange(standardFrequecy, ca.getFrequency());
+			if (standardNote.equals(noteFrequencyRange)) {
+				return ca.getStartTime();
+			}
+		}
+
+		return musicXmlNote.getTimeStamp();
+	}
+	
 	public static void main(String[] args) {
 		double[] midi = new double[128];;
 		int standardPitch = 440; // a is 440 hz...

+ 3 - 0
audio-analysis/src/main/java/com/yonge/netty/server/service/AudioCompareHandler.java

@@ -310,6 +310,9 @@ public class AudioCompareHandler implements MessageHandler {
 		}
 		
 		totalLength = channelContext.getChannelBufferBytes().length;
+		if(totalLength % 2 != 0){
+			totalLength--;
+		}
 
 		while (totalLength >= bufferSize) {
 			byte[] bufferData = ArrayUtil.extractByte(channelContext.getChannelBufferBytes(), 0, bufferSize - 1);