yonge 3 년 전
부모
커밋
dacfb3fe9a

+ 2 - 12
audio-analysis/src/main/java/com/yonge/netty/dto/NoteAnalysis.java

@@ -31,8 +31,6 @@ public class NoteAnalysis {
 
 	private double endTime;
 	
-	private double standardDurationTime;
-
 	private double durationTime;
 
 	private int frequency;
@@ -53,8 +51,8 @@ public class NoteAnalysis {
 
 	private boolean ignore;
 	
-	public NoteAnalysis(int index, int sectionIndex, int frequency, double standardDurationTime) {
-		this.standardDurationTime = standardDurationTime;
+	public NoteAnalysis(int index, int sectionIndex, int frequency, double durationTime) {
+		this.durationTime = durationTime;
 		this.index = index;
 		this.sectionIndex = sectionIndex;
 		this.frequency = frequency;
@@ -99,14 +97,6 @@ public class NoteAnalysis {
 		this.durationTime = durationTime;
 	}
 
-	public double getStandardDurationTime() {
-		return standardDurationTime;
-	}
-
-	public void setStandardDurationTime(double standardDurationTime) {
-		this.standardDurationTime = standardDurationTime;
-	}
-
 	public double getPlayFrequency() {
 		return playFrequency;
 	}

+ 74 - 68
audio-analysis/src/main/java/com/yonge/netty/dto/UserChannelContext2.java

@@ -57,8 +57,6 @@ public class UserChannelContext2 {
 	
 	private List<SectionAnalysis> doneSectionAnalysisList = new ArrayList<SectionAnalysis>();
 	
-	private List<ChunkAnalysis> chunkAnalysisList = new ArrayList<ChunkAnalysis>();
-	
 	private List<ChunkAnalysis> totalChunkAnalysisList = new ArrayList<ChunkAnalysis>();
 	
 	private byte[] channelBufferBytes = new byte[0];
@@ -67,8 +65,6 @@ public class UserChannelContext2 {
 	
 	private double receivedTime;
 	
-	private List<ChunkAnalysis> lastChunkAnalysisList = new ArrayList<ChunkAnalysis>();
-	
 	private HardLevelEnum hardLevel = HardLevelEnum.ADVANCED;
 	
 	public void init(String platform, String heardLevel, int subjectId, int beatDuration) {
@@ -150,12 +146,10 @@ public class UserChannelContext2 {
 		channelBufferBytes = new byte[0];
 		doneNoteAnalysisList = new ArrayList<NoteAnalysis>();
 		doneSectionAnalysisList = new ArrayList<SectionAnalysis>();
-		chunkAnalysisList = new ArrayList<ChunkAnalysis>();
 		totalChunkAnalysisList = new ArrayList<ChunkAnalysis>();
 		recordId = null;
 		playTime = 0;
 		receivedTime = 0;
-		lastChunkAnalysisList = new ArrayList<ChunkAnalysis>();
 	}
 	
 	public MusicXmlBasicInfo getMusicXmlBasicInfo(Integer songId){
@@ -305,72 +299,42 @@ public class UserChannelContext2 {
 		
 		if (noteAnalysis.getMusicalNotesIndex() >= 0 && noteAnalysis.getMusicalNotesIndex() <= getTotalMusicNoteIndex(null)) {
 			
-			ChunkAnalysis lastChunkAnalysis = new ChunkAnalysis(playTime - durationTime, playTime, playFrequency, splDb, power, amplitude);
+			LOGGER.info("Frequency:{}  splDb:{}  Power:{}  amplitude:{}  rms:{}  time:{}", playFrequency, splDb, power, amplitude, rms, playTime);
+			
+			ChunkAnalysis chunkAnalysis = new ChunkAnalysis(playTime - durationTime, playTime, playFrequency, splDb, power, amplitude);
 			
 			if(totalChunkAnalysisList.size() > 0){
-				if(totalChunkAnalysisList.get(totalChunkAnalysisList.size() - 1).getAmplitude() + 2 < lastChunkAnalysis.getAmplitude()){
-					lastChunkAnalysis.setPeak(true);
+				if(totalChunkAnalysisList.get(totalChunkAnalysisList.size() - 1).getAmplitude() + 2 < chunkAnalysis.getAmplitude()){
+					chunkAnalysis.setPeak(true);//只针对打击乐
 				}
 			}
-			totalChunkAnalysisList.add(lastChunkAnalysis);
+			totalChunkAnalysisList.add(chunkAnalysis);
 			
 			if (playTime >= (musicXmlNote.getDuration() + musicXmlNote.getTimeStamp())) {
 
-				LOGGER.info("------ Frequency:{}  splDb:{}  Power:{}  amplitude:{} time:{}------", playFrequency, splDb, power, amplitude, playTime);
-				
-				if(Math.abs(chunkAnalysisList.get(chunkAnalysisList.size() - 1).getFrequency() - lastChunkAnalysis.getFrequency()) > hardLevel.getFrequencyThreshold()){
-					lastChunkAnalysis.setFrequency(-1);
-				}
-				
-				//每个音符最后一个块
-				lastChunkAnalysisList.add(lastChunkAnalysis);
-				if(noteAnalysis.getMusicalNotesIndex() > 0){
-					lastChunkAnalysis = lastChunkAnalysisList.get(noteAnalysis.getMusicalNotesIndex() - 1);
-				}else{
-					lastChunkAnalysis = new ChunkAnalysis(0, 0, -1, 0, 0, 0);
-				}
-
 				if (musicXmlNote.getDontEvaluating()) {
 					noteAnalysis.setIgnore(true);
 				}
 				
-				if(chunkAnalysisList.size() == 0){// 延音线
-					
-				}
-				
-				noteAnalysis.setPlayFrequency(computeFrequency(chunkAnalysisList, lastChunkAnalysis, hardLevel.getFrequencyThreshold()));
+				noteAnalysis.setPlayFrequency(computeFrequency(musicXmlNote));
 				
 				//判断节奏(音符持续时间内有不间断的音高,就节奏正确)
 				boolean tempo = true;
 				if (subjectId == 23 || subjectId == 113) {
-					if (musicXmlNote.getFrequency() == -1) {// 休止符
-						tempo = chunkAnalysisList.stream().filter(t -> t.getAmplitude() > hardLevel.getAmplitudeThreshold()).count() <= 0;
-					}else{
-						tempo = computeTempoWithAmplitude2(musicXmlNote, chunkAnalysisList, lastChunkAnalysis);
-					}
+					tempo = computeTempoWithAmplitude2(musicXmlNote);
 				}else{
-					if (musicXmlNote.getFrequency() == -1) {// 休止符
-						tempo = chunkAnalysisList.stream().filter(t -> t.getFrequency() > 100).count() <= 1;
-					}else{
-						tempo = computeTempoWithFrequency(musicXmlNote, chunkAnalysisList, lastChunkAnalysis);
-					}
+					tempo = computeTempoWithFrequency(musicXmlNote);
 				}
 				
-				noteAnalysis.setDurationTime(chunkAnalysisList.stream().mapToDouble(t -> t.getDurationTime()).sum());
-				
 				noteAnalysis.setTempo(tempo);
 				
-				evaluateForNote(noteAnalysis);
+				evaluateForNote(musicXmlNote, noteAnalysis);
 
 				LOGGER.info("当前音符下标[{}] 预计频率:{} 实际频率:{} 节奏:{}", noteAnalysis.getMusicalNotesIndex(), musicXmlNote.getFrequency(), noteAnalysis.getPlayFrequency(),
 						noteAnalysis.isTempo());
 				
 				doneNoteAnalysisList.add(noteAnalysis);
 				
-				//lastChunkAnalysis = chunkAnalysisList.get(chunkAnalysisList.size() - 1);
-				
-				chunkAnalysisList.clear();
-
 				// 准备处理下一个音符
 				int nextNoteIndex = musicXmlNote.getMusicalNotesIndex() + 1;
 				float nextNoteFrequence = -1;
@@ -385,11 +349,6 @@ public class UserChannelContext2 {
 
 				noteAnalysis = nextNoteAnalysis;
 
-			} else {
-				
-				LOGGER.info("Frequency:{}  splDb:{}  Power:{}  amplitude:{}  rms:{}", playFrequency, splDb, power, amplitude, rms);
-				
-				chunkAnalysisList.add(lastChunkAnalysis);
 			}
 
 			setProcessingNote(noteAnalysis);
@@ -477,8 +436,14 @@ public class UserChannelContext2 {
 	}
 	
 
-	public void evaluateForNote(NoteAnalysis noteAnalysis) {
-
+	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;
+		
+		List<ChunkAnalysis> chunkAnalysisList = totalChunkAnalysisList.stream().filter(t -> t.getStartTime() >= startTime && t.getEndTime() <= endTime).collect(Collectors.toList());
+		
 		double playDurationTime = 0;
 		
 		if (subjectId == 23 || subjectId == 113) {
@@ -569,7 +534,24 @@ public class UserChannelContext2 {
 		}
 	}
 	
-	private int computeFrequency(List<ChunkAnalysis> chunkAnalysisList, ChunkAnalysis lastChunkAnalysis, int offsetRange) {
+	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;
+		
+		List<ChunkAnalysis> chunkAnalysisList = totalChunkAnalysisList.stream().filter(t -> t.getStartTime() >= startTime && t.getEndTime() <= endTime).collect(Collectors.toList());
+		
+		if(chunkAnalysisList == null || chunkAnalysisList.size() == 0){
+			return -1;
+		}
+		
+		ChunkAnalysis firstChunkAnalysis = chunkAnalysisList.get(0);
+		
+		ChunkAnalysis lastChunkAnalysis = totalChunkAnalysisList.stream().filter(t -> t.getEndTime() == firstChunkAnalysis.getStartTime()).findFirst().get();
+		if(lastChunkAnalysis == null){
+			lastChunkAnalysis = new ChunkAnalysis(0, 0, -1, 0, 0, 0);
+		}
 		
 		List<ChunkAnalysis> chunkList = new ArrayList<ChunkAnalysis>(chunkAnalysisList);
 		
@@ -579,7 +561,7 @@ public class UserChannelContext2 {
 			int lastFrequency = lastChunkAnalysis.getFrequency();
 			Iterator<ChunkAnalysis> iterable = chunkList.iterator();
 			while (iterable.hasNext()) {
-				if (Math.abs(lastFrequency - iterable.next().getFrequency()) > offsetRange) {
+				if (Math.abs(lastFrequency - iterable.next().getFrequency()) > hardLevel.getFrequencyThreshold()) {
 					break;
 				}
 				iterable.remove();
@@ -614,7 +596,7 @@ public class UserChannelContext2 {
 		for (int i = 1; i < chunkFrequencyList.size(); i++) {
 			tempFrequency = chunkFrequencyList.get(i);
 
-			if (Math.abs(avgFrequency - tempFrequency) > offsetRange) {
+			if (Math.abs(avgFrequency - tempFrequency) > hardLevel.getFrequencyThreshold()) {
 
 				avgFrequency = totalFrequency / chunkSize;
 
@@ -650,7 +632,28 @@ public class UserChannelContext2 {
 		return frequency;
 	}
 	
-	private boolean computeTempoWithFrequency(MusicXmlNote musicXmlNote, List<ChunkAnalysis> chunkAnalysisList, ChunkAnalysis lastChunkAnalysis){
+	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 -> t.getStartTime() >= startTime && t.getEndTime() <= endTime).collect(Collectors.toList());
+		
+		if(chunkAnalysisList == null || chunkAnalysisList.size() == 0){
+			return false;
+		}
+		
+		if (musicXmlNote.getFrequency() == -1) {// 休止符
+			return chunkAnalysisList.stream().filter(t -> t.getFrequency() > 100).count() <= 1;
+		}
+		
+		ChunkAnalysis firstChunkAnalysis = chunkAnalysisList.get(0);
+		
+		ChunkAnalysis lastChunkAnalysis = totalChunkAnalysisList.stream().filter(t -> t.getEndTime() == firstChunkAnalysis.getStartTime()).findFirst().get();
+		if(lastChunkAnalysis == null){
+			lastChunkAnalysis = new ChunkAnalysis(0, 0, -1, 0, 0, 0);
+		}
 		
 		List<ChunkAnalysis> chunkList = new ArrayList<ChunkAnalysis>(chunkAnalysisList);
 		
@@ -707,7 +710,7 @@ public class UserChannelContext2 {
 		
 		if (tempo) {
 			// 判断进入时间点
-			if((chunkAnalysisList.size() - chunkList.size() + firstPeakIndex) * 100 /chunkAnalysisList.size() > hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator())){
+			if((chunkAnalysisList.size() - chunkList.size() + firstPeakIndex) * 100 /chunkAnalysisList.size() > hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator()) * 2){
 				tempo = false;
 			}
 		}
@@ -715,20 +718,25 @@ public class UserChannelContext2 {
 		return tempo;
 	}
 	
-	private boolean computeTempoWithAmplitude2(MusicXmlNote musicXmlNote, List<ChunkAnalysis> chunkAnalysisList, ChunkAnalysis lastChunkAnalysis) {
+	private boolean computeTempoWithAmplitude2(MusicXmlNote musicXmlNote) {
 
-		double endTime = (musicXmlNote.getDuration() + musicXmlNote.getTimeStamp());
-		double startTime = musicXmlNote.getTimeStamp() * (100 - hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator())) / 100;
+		double floatingRange = musicXmlNote.getDuration() * hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator()) / 100;
+		double endTime = musicXmlNote.getDuration() + musicXmlNote.getTimeStamp() - floatingRange;
+		double startTime = musicXmlNote.getTimeStamp() + floatingRange;
 		
-		chunkAnalysisList = totalChunkAnalysisList.stream().filter(t -> t.getStartTime() >= startTime && t.getEndTime() <= endTime).collect(Collectors.toList());
+		List<ChunkAnalysis> chunkAnalysisList = totalChunkAnalysisList.stream().filter(t -> t.getStartTime() >= startTime && t.getEndTime() <= endTime).collect(Collectors.toList());
 		
 		if(chunkAnalysisList == null || chunkAnalysisList.size() == 0){
 			return false;
 		}
+
+		if (musicXmlNote.getFrequency() == -1) {// 休止符
+			return chunkAnalysisList.stream().filter(t -> t.getAmplitude() > hardLevel.getAmplitudeThreshold()).count() <= 0;
+		}
 		
-		ChunkAnalysis chunkAnalysis = chunkAnalysisList.get(0);
+		ChunkAnalysis firstChunkAnalysis = chunkAnalysisList.get(0);
 		
-		lastChunkAnalysis = totalChunkAnalysisList.stream().filter(t -> t.getEndTime() == chunkAnalysis.getStartTime()).findFirst().get();
+		ChunkAnalysis lastChunkAnalysis = totalChunkAnalysisList.stream().filter(t -> t.getEndTime() == firstChunkAnalysis.getStartTime()).findFirst().get();
 		if(lastChunkAnalysis == null){
 			lastChunkAnalysis = new ChunkAnalysis(0, 0, -1, 0, 0, 0);
 		}
@@ -771,7 +779,7 @@ public class UserChannelContext2 {
 		
 		if (tempo) {
 			// 判断进入时间点
-			if((firstPeakIndex - 1) * 100 /chunkAmplitudeList.size() > (hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator()) * 2 * 100 / (100 + hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator())))){
+			if((firstPeakIndex - 1) * 100 /chunkAmplitudeList.size() > hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator()) * 2){
 				tempo = false;
 			}
 		}
@@ -785,8 +793,6 @@ public class UserChannelContext2 {
 		//int[] frequencys = {286,291,291,291,291,291,291};
 		int[] frequencys = {312,43,295,294,294,295};
 		
-		ChunkAnalysis lastChunkAnalysis = new ChunkAnalysis(624, 0, 0);
-		
 		List<ChunkAnalysis> chunkAnalysisList = new ArrayList<ChunkAnalysis>();
 		for(int f : frequencys) {
 			chunkAnalysisList.add(new ChunkAnalysis(f, 0, 0));
@@ -796,7 +802,7 @@ public class UserChannelContext2 {
 		musicXmlNote.setDenominator(1);
 		
 		//System.out.println(context.computeFrequency(chunkAnalysisList, lastChunkAnalysis, 5));
-		System.out.println(context.computeTempoWithFrequency(musicXmlNote, chunkAnalysisList, lastChunkAnalysis));
+		System.out.println(context.computeTempoWithFrequency(musicXmlNote));
 	}
 	
 }