Преглед на файлове

Merge remote-tracking branch 'origin/saas' into saas

zouxuan преди 3 години
родител
ревизия
31e26931eb

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

@@ -51,7 +51,10 @@ public class NoteAnalysis {
 
 	private boolean ignore;
 	
-	public NoteAnalysis(int index, int sectionIndex, int frequency, double durationTime) {
+	private int measureRenderIndex;
+	
+	public NoteAnalysis(int measureRenderIndex, int index, int sectionIndex, int frequency, double durationTime) {
+		this.measureRenderIndex = measureRenderIndex;
 		this.durationTime = durationTime;
 		this.index = index;
 		this.sectionIndex = sectionIndex;
@@ -177,4 +180,8 @@ public class NoteAnalysis {
 		this.integrityScore = integrityScore;
 	}
 
+	public int getMeasureRenderIndex() {
+		return measureRenderIndex;
+	}
+
 }

+ 10 - 0
audio-analysis/src/main/java/com/yonge/netty/dto/SectionAnalysis.java

@@ -18,6 +18,8 @@ public class SectionAnalysis {
 	
 	private boolean isIngore;
 	
+	private int measureRenderIndex;
+	
 	public SectionAnalysis() {
 		// TODO Auto-generated constructor stub
 	}
@@ -70,6 +72,14 @@ public class SectionAnalysis {
 		this.isIngore = isIngore;
 	}
 
+	public int getMeasureRenderIndex() {
+		return measureRenderIndex;
+	}
+
+	public void setMeasureRenderIndex(int measureRenderIndex) {
+		this.measureRenderIndex = measureRenderIndex;
+	}
+
 	@Override
 	public String toString() {
 		return ToStringBuilder.reflectionToString(this);

+ 8 - 5
audio-analysis/src/main/java/com/yonge/netty/dto/UserChannelContext.java

@@ -33,7 +33,7 @@ import com.yonge.netty.server.processor.WaveformWriter;
  */
 public class UserChannelContext {
 	
-	private final static Logger LOGGER = LoggerFactory.getLogger(UserChannelContext3.class);
+	private final static Logger LOGGER = LoggerFactory.getLogger(UserChannelContext.class);
 	
 	//打击乐
 	private final static List<Integer> percussionList = Arrays.asList(23, 113);
@@ -350,7 +350,7 @@ public class UserChannelContext {
 		//取出当前处理中的音符信息
 		NoteAnalysis noteAnalysis = getProcessingNote();
 		if(noteAnalysis == null || noteAnalysis.getDurationTime() == 0) {
-			noteAnalysis = new NoteAnalysis(musicXmlNote.getMusicalNotesIndex(), musicXmlNote.getMeasureIndex(), (int)musicXmlNote.getFrequency(), musicXmlNote.getDuration());
+			noteAnalysis = new NoteAnalysis(musicXmlNote.getMeasureRenderIndex(), musicXmlNote.getMusicalNotesIndex(), musicXmlNote.getMeasureIndex(), (int)musicXmlNote.getFrequency(), musicXmlNote.getDuration());
 		}
 		
 		evaluatingSectionIndex.set(noteAnalysis.getSectionIndex());
@@ -368,7 +368,7 @@ public class UserChannelContext {
 			}
 			totalChunkAnalysisList.add(chunkAnalysis);
 			
-			boolean flag = false;
+			boolean flag = false; //是否收到有效信号
 			if(percussionList.contains(subjectId)){
 				flag = chunkAnalysis.getAmplitude() > hardLevel.getAmplitudeThreshold();
 			}else{
@@ -405,7 +405,7 @@ public class UserChannelContext {
 				
 				noteAnalysis.setTempo(tempo);
 				
-				evaluateForNote(musicXmlNote, noteAnalysis);
+				evaluateForNote(musicXmlNote, noteAnalysis);//对当前音符评分
 
 				LOGGER.debug("当前音符下标[{}] 预计频率:{} 实际频率:{} 节奏:{}", noteAnalysis.getMusicalNotesIndex(), musicXmlNote.getFrequency(), noteAnalysis.getPlayFrequency(),
 						noteAnalysis.isTempo());
@@ -416,13 +416,15 @@ public class UserChannelContext {
 				int nextNoteIndex = musicXmlNote.getMusicalNotesIndex() + 1;
 				float nextNoteFrequence = -1;
 				double standDuration = 0;
+				int measureRenderIndex = 0;
 				MusicXmlNote nextMusicXmlNote = getCurrentMusicNote(null, nextNoteIndex);
 				if(nextMusicXmlNote != null){
 					nextNoteFrequence = nextMusicXmlNote.getFrequency();
 					standDuration = nextMusicXmlNote.getDuration();
+					measureRenderIndex = nextMusicXmlNote.getMeasureRenderIndex();
 				}
 				
-				NoteAnalysis nextNoteAnalysis = new NoteAnalysis(nextNoteIndex, getMusicSectionIndex(null, nextNoteIndex), (int)nextNoteFrequence, standDuration);
+				NoteAnalysis nextNoteAnalysis = new NoteAnalysis(measureRenderIndex, nextNoteIndex, getMusicSectionIndex(null, nextNoteIndex), (int)nextNoteFrequence, standDuration);
 
 				noteAnalysis = nextNoteAnalysis;
 
@@ -450,6 +452,7 @@ public class UserChannelContext {
 		sectionAnalysis.setIndex(sectionIndex);
 		sectionAnalysis.setNoteNum(noteAnalysisList.size());
 		sectionAnalysis.setIsIngore(ignoreSize == noteAnalysisList.size());
+		sectionAnalysis.setMeasureRenderIndex(noteAnalysisList.stream().findFirst().get().getMeasureRenderIndex());
 		
 		//判断是否需要评分
 		MusicXmlSection musicXmlSection = getCurrentMusicSection(null, sectionIndex);

+ 0 - 842
audio-analysis/src/main/java/com/yonge/netty/dto/UserChannelContext2.java

@@ -1,842 +0,0 @@
-package com.yonge.netty.dto;
-
-import java.math.BigDecimal;
-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.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.stream.Collectors;
-
-import javax.sound.sampled.AudioFormat;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.yonge.audio.analysis.Signals;
-import com.yonge.audio.analysis.detector.YINPitchDetector;
-import com.yonge.audio.utils.ArrayUtil;
-import com.yonge.netty.dto.NoteAnalysis.NoteErrorType;
-import com.yonge.netty.entity.MusicXmlBasicInfo;
-import com.yonge.netty.entity.MusicXmlNote;
-import com.yonge.netty.entity.MusicXmlSection;
-import com.yonge.netty.server.processor.WaveformWriter;
-
-/**
- * 用户通道上下文
- */
-public class UserChannelContext2 {
-	
-	private final static Logger LOGGER = LoggerFactory.getLogger(UserChannelContext.class);
-	
-	private int offsetMS = 350;
-	
-	private String platform;
-	
-	private Long recordId;
-	
-	private Integer subjectId;
-	
-	private int beatDuration;
-	
-	private int beatByteLength;
-	
-	// 曲目与musicxml对应关系
-	private ConcurrentHashMap<Integer, MusicXmlBasicInfo> songMusicXmlMap = new ConcurrentHashMap<Integer, MusicXmlBasicInfo>();
-
-	private WaveformWriter waveFileProcessor;
-
-	private NoteAnalysis processingNote = new NoteAnalysis(0, 0, -1);
-	
-	private AtomicInteger evaluatingSectionIndex = new AtomicInteger(0);
-	
-	private List<NoteAnalysis> doneNoteAnalysisList = new ArrayList<NoteAnalysis>();
-	
-	private List<SectionAnalysis> doneSectionAnalysisList = new ArrayList<SectionAnalysis>();
-	
-	private List<ChunkAnalysis> chunkAnalysisList = new ArrayList<ChunkAnalysis>();
-	
-	private byte[] channelBufferBytes = new byte[0];
-	
-	private double playTime;
-	
-	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) {
-		this.platform = platform;
-		this.subjectId = subjectId;
-		this.beatDuration = beatDuration;
-		this.beatByteLength = WaveformWriter.SAMPLE_RATE * WaveformWriter.BITS_PER_SAMPLE / 8 * beatDuration / 1000;
-		hardLevel = HardLevelEnum.valueOf(heardLevel);
-	}
-	
-	public byte[] skipMetronome(byte[] datas) {
-		if (beatByteLength > 0) {
-			if (datas.length <= beatByteLength) {
-				beatByteLength -= datas.length;
-				return new byte[0];
-			}
-			if(beatByteLength % 2 != 0){
-				beatByteLength++;
-			}
-			datas = ArrayUtil.extractByte(datas, beatByteLength, datas.length - 1);
-			beatByteLength = 0;
-		}
-		return datas;
-	}
-	
-	public Long getRecordId() {
-		return recordId;
-	}
-
-	public void setRecordId(Long recordId) {
-		this.recordId = recordId;
-	}
-
-	public int getOffsetMS() {
-		return offsetMS;
-	}
-
-	public void setOffsetMS(int offsetMS) {
-		this.offsetMS = offsetMS;
-	}
-
-	public HardLevelEnum getHardLevel() {
-		return hardLevel;
-	}
-
-	public ConcurrentHashMap<Integer, MusicXmlBasicInfo> getSongMusicXmlMap() {
-		return songMusicXmlMap;
-	}
-
-	public WaveformWriter getWaveFileProcessor() {
-		return waveFileProcessor;
-	}
-
-	public void setWaveFileProcessor(WaveformWriter waveFileProcessor) {
-		this.waveFileProcessor = waveFileProcessor;
-	}
-
-	public NoteAnalysis getProcessingNote() {
-		return processingNote;
-	}
-
-	public void setProcessingNote(NoteAnalysis processingNote) {
-		this.processingNote = processingNote;
-	}
-	
-	public List<SectionAnalysis> getDoneSectionAnalysisList() {
-		return doneSectionAnalysisList;
-	}
-
-	public List<NoteAnalysis> getDoneNoteAnalysisList() {
-		return doneNoteAnalysisList;
-	}
-
-	public void resetUserInfo() {
-		beatByteLength = WaveformWriter.SAMPLE_RATE * WaveformWriter.BITS_PER_SAMPLE / 8 * beatDuration / 1000;
-		waveFileProcessor = null;
-		processingNote = new NoteAnalysis(0,0,-1);
-		evaluatingSectionIndex = new AtomicInteger(0);
-		channelBufferBytes = new byte[0];
-		doneNoteAnalysisList = new ArrayList<NoteAnalysis>();
-		doneSectionAnalysisList = new ArrayList<SectionAnalysis>();
-		chunkAnalysisList = new ArrayList<ChunkAnalysis>();
-		recordId = null;
-		playTime = 0;
-		receivedTime = 0;
-		lastChunkAnalysisList = new ArrayList<ChunkAnalysis>();
-	}
-	
-	public MusicXmlBasicInfo getMusicXmlBasicInfo(Integer songId){
-		MusicXmlBasicInfo musicXmlBasicInfo = null;
-		if (songId == null) {
-			musicXmlBasicInfo = songMusicXmlMap.values().stream().findFirst().get();
-		} else {
-			musicXmlBasicInfo = songMusicXmlMap.get(songId);
-		}
-		return musicXmlBasicInfo;
-	}
-	
-	public MusicXmlSection getCurrentMusicSection(Integer songId, int sectionIndex){
-		MusicXmlBasicInfo musicXmlBasicInfo = getMusicXmlBasicInfo(songId);
-		return musicXmlBasicInfo.getMusicXmlSectionMap().get(sectionIndex);
-	}
-
-	public MusicXmlNote getCurrentMusicNote(Integer songId, Integer noteIndex) {
-		if (songMusicXmlMap.size() == 0) {
-			return null;
-		}
-		if(noteIndex == null){
-			noteIndex = processingNote.getMusicalNotesIndex();
-		}
-		final int index = noteIndex;
-		MusicXmlBasicInfo musicXmlBasicInfo = getMusicXmlBasicInfo(songId);
-
-		if (musicXmlBasicInfo != null && index <= getTotalMusicNoteIndex(null)) {
-			return musicXmlBasicInfo.getMusicXmlInfos().stream().filter(t -> t.getMusicalNotesIndex() == index).findFirst().get();
-		}
-
-		return null;
-	}
-
-	public int getTotalMusicNoteIndex(Integer songId) {
-		if (songMusicXmlMap.size() == 0) {
-			return -1;
-		}
-		MusicXmlBasicInfo musicXmlBasicInfo = getMusicXmlBasicInfo(songId);
-
-		if (musicXmlBasicInfo != null) {
-			return musicXmlBasicInfo.getMusicXmlInfos().stream().map(t -> t.getMusicalNotesIndex()).distinct().max(Integer::compareTo).get();
-		}
-
-		return -1;
-	}
-
-	public List<MusicXmlNote> getCurrentMusicSection(Integer songId, Integer sectionIndex) {
-		if (songMusicXmlMap.size() == 0) {
-			return null;
-		}
-		if(sectionIndex == null){
-			sectionIndex = processingNote.getSectionIndex();
-		}
-		final int index = sectionIndex;
-		MusicXmlBasicInfo musicXmlBasicInfo = getMusicXmlBasicInfo(songId);
-
-		if (musicXmlBasicInfo != null) {
-			return musicXmlBasicInfo.getMusicXmlInfos().stream().filter(t -> t.getMusicalNotesIndex() == index)
-					.sorted(Comparator.comparing(MusicXmlNote::getMusicalNotesIndex)).collect(Collectors.toList());
-		}
-
-		return null;
-	}
-
-	public int getTotalMusicSectionSize(Integer songId) {
-		if (songMusicXmlMap.size() == 0) {
-			return -1;
-		}
-		MusicXmlBasicInfo musicXmlBasicInfo = getMusicXmlBasicInfo(songId);
-
-		if (musicXmlBasicInfo != null) {
-			return (int) musicXmlBasicInfo.getMusicXmlInfos().stream().map(t -> t.getMeasureIndex()).distinct().count();
-		}
-
-		return -1;
-	}
-	
-	public int getMusicSectionIndex(Integer songId, int musicXmlNoteIndex) {
-		if (songMusicXmlMap.size() == 0) {
-			return -1;
-		}
-		
-		if(getTotalMusicNoteIndex(null) < musicXmlNoteIndex){
-			return -1;
-		}
-		
-		MusicXmlBasicInfo musicXmlBasicInfo = getMusicXmlBasicInfo(songId);
-
-		if (musicXmlBasicInfo != null) {
-			return musicXmlBasicInfo.getMusicXmlInfos().stream().filter(t -> t.getMusicalNotesIndex() == musicXmlNoteIndex).findFirst().get().getMeasureIndex();
-		}
-
-		return -1;
-	}
-	
-	public byte[] getChannelBufferBytes() {
-		return channelBufferBytes;
-	}
-
-	public void setChannelBufferBytes(byte[] channelBufferBytes) {
-		this.channelBufferBytes = channelBufferBytes;
-	}
-
-	public AtomicInteger getEvaluatingSectionIndex() {
-		return evaluatingSectionIndex;
-	}
-
-	public void handle(float[] samples, AudioFormat audioFormat){
-		
-		YINPitchDetector frequencyDetector = new YINPitchDetector(samples.length , audioFormat.getSampleRate());
-
-		int playFrequency = (int) frequencyDetector.getFrequency(samples);
-		int splDb = (int) Signals.soundPressureLevel(samples);
-		int power = (int) Signals.power(samples);
-		int amplitude = (int) Signals.norm(samples);
-		float rms = Signals.rms(samples);
-		
-		double durationTime = 1000 * (samples.length * 2) / audioFormat.getSampleRate() / (audioFormat.getSampleSizeInBits() / 8);
-		
-		receivedTime += durationTime;
-		
-		/*if(offsetMS == 0){
-			return;
-		}*/
-		
-		if(receivedTime < offsetMS){
-			return;
-		}
-		
-		playTime += durationTime;
-		
-		// 获取当前音符信息
-		MusicXmlNote musicXmlNote = getCurrentMusicNote(null,null);
-
-		if (musicXmlNote == null) {
-			return;
-		}
-		
-		//取出当前处理中的音符信息
-		NoteAnalysis noteAnalysis = getProcessingNote();
-		if(noteAnalysis == null || noteAnalysis.getDurationTime() == 0) {
-			noteAnalysis = new NoteAnalysis(musicXmlNote.getMusicalNotesIndex(), musicXmlNote.getMeasureIndex(), (int)musicXmlNote.getFrequency(), musicXmlNote.getDuration());
-		}
-		
-		evaluatingSectionIndex.set(noteAnalysis.getSectionIndex());
-		
-		if (noteAnalysis.getMusicalNotesIndex() >= 0 && noteAnalysis.getMusicalNotesIndex() <= getTotalMusicNoteIndex(null)) {
-
-			if (playTime >= (musicXmlNote.getDuration() + musicXmlNote.getTimeStamp())) {
-
-				LOGGER.info("------ Frequency:{}  splDb:{}  Power:{}  amplitude:{} time:{}------", playFrequency, splDb, power, amplitude, playTime);
-				
-				ChunkAnalysis lastChunkAnalysis = new ChunkAnalysis(playTime - durationTime, playTime, playFrequency, splDb, power, amplitude);
-				
-				if(Math.abs(chunkAnalysisList.get(chunkAnalysisList.size() - 1).getFrequency() - lastChunkAnalysis.getFrequency()) > hardLevel.getFrequencyThreshold()){
-					lastChunkAnalysis.setFrequency(-1);
-				}
-				if(chunkAnalysisList.get(chunkAnalysisList.size() - 1).getAmplitude() + 2 < lastChunkAnalysis.getAmplitude()){
-					lastChunkAnalysis.setPeak(true);
-				}
-				
-				//每个音符最后一个块
-				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()));
-				
-				//判断节奏(音符持续时间内有不间断的音高,就节奏正确)
-				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);
-					}
-				}else{
-					if (musicXmlNote.getFrequency() == -1) {// 休止符
-						tempo = chunkAnalysisList.stream().filter(t -> t.getFrequency() > 100).count() <= 1;
-					}else{
-						tempo = computeTempoWithFrequency(musicXmlNote, chunkAnalysisList, lastChunkAnalysis);
-					}
-				}
-				
-				noteAnalysis.setDurationTime(chunkAnalysisList.stream().mapToDouble(t -> t.getDurationTime()).sum());
-				
-				noteAnalysis.setTempo(tempo);
-				
-				evaluateForNote(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;
-				double standDuration = 0;
-				MusicXmlNote nextMusicXmlNote = getCurrentMusicNote(null, nextNoteIndex);
-				if(nextMusicXmlNote != null){
-					nextNoteFrequence = nextMusicXmlNote.getFrequency();
-					standDuration = nextMusicXmlNote.getDuration();
-				}
-				
-				NoteAnalysis nextNoteAnalysis = new NoteAnalysis(nextNoteIndex, getMusicSectionIndex(null, nextNoteIndex), (int)nextNoteFrequence, standDuration);
-
-				noteAnalysis = nextNoteAnalysis;
-
-			} else {
-				
-				LOGGER.info("Frequency:{}  splDb:{}  Power:{}  amplitude:{}  rms:{}", playFrequency, splDb, power, amplitude, rms);
-				
-				chunkAnalysisList.add(new ChunkAnalysis(playTime - durationTime, playTime, playFrequency, splDb, power, amplitude));
-				
-			}
-
-			setProcessingNote(noteAnalysis);
-		}
-		
-	}
-	
-
-	public int evaluateForSection(int sectionIndex, int subjectId){
-
-		int score = -1;
-		if(doneSectionAnalysisList.size() >= getTotalMusicSectionSize(null)){
-			return score;
-		}
-		
-		//取出当前小节的所有音符
-		List<NoteAnalysis> noteAnalysisList = doneNoteAnalysisList.stream().filter(t -> t.getSectionIndex() == sectionIndex).collect(Collectors.toList());
-		
-		long ignoreSize = noteAnalysisList.stream().filter(t -> t.isIgnore()).count();
-
-		SectionAnalysis sectionAnalysis = new SectionAnalysis();
-		sectionAnalysis.setIndex(sectionIndex);
-		sectionAnalysis.setNoteNum(noteAnalysisList.size());
-		sectionAnalysis.setIsIngore(ignoreSize == noteAnalysisList.size());
-		
-		//判断是否需要评分
-		MusicXmlSection musicXmlSection = getCurrentMusicSection(null, sectionIndex);
-		if(noteAnalysisList.size() == musicXmlSection.getNoteNum()){
-			//取出需要评测的音符
-			List<NoteAnalysis>  noteList = noteAnalysisList.stream().filter(t -> t.isIgnore() == false).collect(Collectors.toList());
-			
-			if(noteList != null && noteList.size() > 0){
-				score = noteList.stream().mapToInt(t -> t.getScore()).sum() / noteList.size();
-			}
-			sectionAnalysis.setDurationTime(noteAnalysisList.stream().mapToDouble(t -> t.getDurationTime()).sum());
-			sectionAnalysis.setScore(score);
-
-			LOGGER.info("小节评分:{}",sectionAnalysis);
-			doneSectionAnalysisList.add(sectionAnalysis);
-		}
-		
-		return score;
-	}
-	
-	public Map<String, Integer> evaluateForMusic() {
-
-		Map<String, Integer> result = new HashMap<String, Integer>();
-		
-		result.put("playTime", (int) doneNoteAnalysisList.stream().mapToDouble(t -> t.getDurationTime()).sum());
-		
-		// 取出需要评测的音符
-		List<NoteAnalysis> noteAnalysisList = doneNoteAnalysisList.stream().filter(t -> t.isIgnore() == false).collect(Collectors.toList());
-
-		if (noteAnalysisList != null && noteAnalysisList.size() > 0) {
-			int intonationScore = 0;
-			int tempoScore = 0;
-			int integrityScore = 0;
-			int socre = 0;
-
-			for (NoteAnalysis note : noteAnalysisList) {
-				intonationScore += note.getIntonationScore();
-				tempoScore += note.getTempoScore();
-				integrityScore += note.getIntegrityScore();
-				socre += note.getScore();
-			}
-
-			tempoScore = tempoScore / noteAnalysisList.size();
-			intonationScore = intonationScore / noteAnalysisList.size();
-			integrityScore = integrityScore / noteAnalysisList.size();
-
-			result.put("cadence", tempoScore);
-			result.put("intonation", intonationScore);
-			result.put("integrity", integrityScore);
-	        result.put("recordId", recordId.intValue());
-
-			int score = socre / noteAnalysisList.size();
-
-			// 平均得分
-			if (getMusicXmlBasicInfo(null).getSubjectId() == 23 || getMusicXmlBasicInfo(null).getSubjectId() == 113) {
-				score = tempoScore;
-			}
-			result.put("score", score);
-		}
-		return result;
-	}
-	
-
-	public void evaluateForNote(NoteAnalysis noteAnalysis) {
-
-		double playDurationTime = 0;
-		
-		if (subjectId == 23 || subjectId == 113) {
-			if (noteAnalysis.getFrequency() == -1) {// 休止符
-				if (!noteAnalysis.isTempo()) {
-					noteAnalysis.setMusicalErrorType(NoteErrorType.CADENCE_WRONG);
-				} else {
-					noteAnalysis.setMusicalErrorType(NoteErrorType.RIGHT);
-				}
-			}else{
-				int beatTimes = (int) chunkAnalysisList.stream().filter(t -> t.getAmplitude() > hardLevel.getAmplitudeThreshold()).count();
-				LOGGER.info("Amplitude:{}  beatTimes:{}",chunkAnalysisList.stream().map(t -> t.getAmplitude()).collect(Collectors.toList()),beatTimes);
-				if(beatTimes == 0){
-					noteAnalysis.setMusicalErrorType(NoteErrorType.NOT_PLAY);
-				}else if (!noteAnalysis.isTempo()) {
-					noteAnalysis.setMusicalErrorType(NoteErrorType.CADENCE_WRONG);
-				} else {
-					noteAnalysis.setMusicalErrorType(NoteErrorType.RIGHT);
-				}
-			}
-		} else {
-			if (noteAnalysis.getFrequency() == -1) {// 休止符
-
-				playDurationTime = chunkAnalysisList.stream().filter(t -> t.getFrequency() <= 100).mapToDouble(t -> t.getDurationTime()).sum();
-
-				if (!noteAnalysis.isTempo()) {
-					noteAnalysis.setMusicalErrorType(NoteErrorType.CADENCE_WRONG);
-				} else if (playDurationTime * 100 / noteAnalysis.getDurationTime() < hardLevel.getIntegrityRange()) {
-					noteAnalysis.setMusicalErrorType(NoteErrorType.INTEGRITY_WRONG);
-				} else if (Math.abs(noteAnalysis.getFrequency() - noteAnalysis.getPlayFrequency()) > hardLevel.getFrequencyThreshold()) {
-					noteAnalysis.setMusicalErrorType(NoteErrorType.INTONATION_WRONG);
-				} else {
-					noteAnalysis.setMusicalErrorType(NoteErrorType.RIGHT);
-				}
-			} else {
-				playDurationTime = chunkAnalysisList.stream().filter(t -> t.getFrequency() > 100 && t.getFrequency() < 2000)
-						.mapToDouble(t -> t.getDurationTime()).sum();
-
-				if (playDurationTime * 100 / noteAnalysis.getDurationTime() < hardLevel.getNotPlayRange()) {
-					noteAnalysis.setMusicalErrorType(NoteErrorType.NOT_PLAY);
-				} else if (playDurationTime * 100 / noteAnalysis.getDurationTime() < hardLevel.getIntegrityRange()) {
-					noteAnalysis.setMusicalErrorType(NoteErrorType.INTEGRITY_WRONG);
-				} else if (!noteAnalysis.isTempo()) {
-					noteAnalysis.setMusicalErrorType(NoteErrorType.CADENCE_WRONG);
-				} else if (Math.abs(noteAnalysis.getFrequency() - noteAnalysis.getPlayFrequency()) > hardLevel.getFrequencyThreshold()) {
-					noteAnalysis.setMusicalErrorType(NoteErrorType.INTONATION_WRONG);
-				} else {
-					noteAnalysis.setMusicalErrorType(NoteErrorType.RIGHT);
-				}
-			}
-		}
-
-		// 计算音分
-		int tempoScore = 0;
-		int integrityScore = 0;
-		int intonationScore = 100 - new BigDecimal(Math.abs(YINPitchDetector.hertzToAbsoluteCent(noteAnalysis.getPlayFrequency())
-				- YINPitchDetector.hertzToAbsoluteCent(noteAnalysis.getFrequency()))).multiply(new BigDecimal(20)).divide(new BigDecimal(17), BigDecimal.ROUND_UP)
-				.setScale(0, BigDecimal.ROUND_UP).intValue();
-		if (intonationScore < 0) {
-			intonationScore = 0;
-		} else if (intonationScore > 100) {
-			intonationScore = 100;
-		}
-
-		if (noteAnalysis.getMusicalErrorType() == NoteErrorType.NOT_PLAY) {
-			intonationScore = 0;
-		} else {
-
-			if (noteAnalysis.isTempo()) {
-				tempoScore = 100;
-				noteAnalysis.setTempoScore(tempoScore);
-			}
-
-			double durationPercent = playDurationTime / noteAnalysis.getDurationTime();
-			if (durationPercent >= 0.7) {
-				integrityScore = 100;
-			} else if (durationPercent < 0.7 && durationPercent >= 0.5) {
-				integrityScore = 50;
-			}
-			noteAnalysis.setIntegrityScore(integrityScore);
-		}
-		noteAnalysis.setIntonationScore(intonationScore);
-		if (subjectId == 23 || subjectId == 113) {
-			noteAnalysis.setScore(tempoScore);
-		} else {
-			noteAnalysis.setScore(new BigDecimal(intonationScore + tempoScore + integrityScore).divide(new BigDecimal(3), 2).setScale(0, BigDecimal.ROUND_UP)
-					.intValue());
-		}
-	}
-	
-	private int computeFrequency(List<ChunkAnalysis> chunkAnalysisList, ChunkAnalysis lastChunkAnalysis, int offsetRange) {
-		
-		List<ChunkAnalysis> chunkList = new ArrayList<ChunkAnalysis>(chunkAnalysisList);
-		
-		int tenutoSize = 0;
-		// 剔除上一个音延续下来的信号
-		if (lastChunkAnalysis != null) {
-			int lastFrequency = lastChunkAnalysis.getFrequency();
-			Iterator<ChunkAnalysis> iterable = chunkList.iterator();
-			while (iterable.hasNext()) {
-				if (Math.abs(lastFrequency - iterable.next().getFrequency()) > offsetRange) {
-					break;
-				}
-				iterable.remove();
-				tenutoSize++;
-			}
-
-			if (chunkList.size() == 0) {
-				return lastFrequency < 100 ? -1 : lastFrequency;
-			}
-		}
-
-		List<Integer> chunkFrequencyList = chunkList.stream().map(t -> t.getFrequency()).filter(t -> t.doubleValue() > 100 && t.doubleValue() < 2000)
-				.collect(Collectors.toList());
-		
-		if (chunkFrequencyList.size() == 0) {
-			return -1;
-		}
-		
-		if(tenutoSize * 100 / chunkAnalysisList.size() > 50){
-			return lastChunkAnalysis.getFrequency();
-		}
-		
-		// 排序
-		chunkFrequencyList = chunkFrequencyList.stream().sorted().collect(Collectors.toList());
-		
-		int tempFrequency = chunkFrequencyList.get(0), totalFrequency = chunkFrequencyList.get(0);
-
-		int maxChunkSize = 0;
-		int frequency = chunkFrequencyList.get(0);
-		int chunkSize = 1;
-		int avgFrequency = chunkFrequencyList.get(0);
-		for (int i = 1; i < chunkFrequencyList.size(); i++) {
-			tempFrequency = chunkFrequencyList.get(i);
-
-			if (Math.abs(avgFrequency - tempFrequency) > offsetRange) {
-
-				avgFrequency = totalFrequency / chunkSize;
-
-				if (maxChunkSize < chunkSize) {
-					maxChunkSize = chunkSize;
-					frequency = avgFrequency;
-				}
-
-				chunkSize = 1;
-				avgFrequency = tempFrequency;
-				totalFrequency = tempFrequency;
-			} else {
-				chunkSize++;
-				totalFrequency += tempFrequency;
-			}
-
-			if (i == chunkFrequencyList.size() - 1) {
-				if (maxChunkSize <= chunkSize) {
-					maxChunkSize = chunkSize;
-					frequency = totalFrequency / chunkSize;
-				}
-			}
-		}
-
-		if (chunkFrequencyList.size() < 3) {
-			frequency = (int)chunkFrequencyList.get(chunkFrequencyList.size() - 1);
-		}
-		
-		if(frequency < 100){
-			frequency = -1;
-		}
-
-		return frequency;
-	}
-	
-	private boolean computeTempoWithFrequency(MusicXmlNote musicXmlNote, List<ChunkAnalysis> chunkAnalysisList, ChunkAnalysis lastChunkAnalysis){
-		
-		List<ChunkAnalysis> chunkList = new ArrayList<ChunkAnalysis>(chunkAnalysisList);
-		
-		// 剔除上一个音延续下来的信号
-		if (lastChunkAnalysis != null) {
-			double lastFrequency = lastChunkAnalysis.getFrequency();
-			Iterator<ChunkAnalysis> iterable = chunkList.iterator();
-			while (iterable.hasNext()) {
-				if (Math.abs(lastFrequency - iterable.next().getFrequency()) > hardLevel.getFrequencyThreshold()) {
-					break;
-				}
-				iterable.remove();
-			}
-		}
-		
-		if(chunkList.size() == 0){
-			return false;
-		}
-		
-		ChunkAnalysis chunkAnalysis = null;
-		boolean tempo = false;
-		boolean isContinue = true;
-		int unplayedSize = 0;
-		int firstPeakIndex = -1;
-		for (int i = 0; i < chunkList.size(); i++) {
-			chunkAnalysis = chunkList.get(i);
-			if (chunkAnalysis != null) {
-				if (chunkAnalysis.getFrequency() > 100) {
-					tempo = true;
-					if(firstPeakIndex == -1){
-						firstPeakIndex = i;
-					}
-					if (isContinue == false) {
-						if (chunkAnalysisList.size() < 5) {
-							if (unplayedSize > 0) {
-								tempo = false;
-								break;
-							}
-						} else {
-							if ((unplayedSize * 100 / chunkAnalysisList.size()) > hardLevel.getNotPlayRange() || unplayedSize > 1) {
-								tempo = false;
-								break;
-							}
-						}
-					}
-				} else {
-					if (tempo == true) {
-						isContinue = false;
-						unplayedSize++;
-					}
-				}
-			}
-		}
-		
-		if (tempo) {
-			// 判断进入时间点
-			if((chunkAnalysisList.size() - chunkList.size() + firstPeakIndex) * 100 /chunkAnalysisList.size() > hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator())){
-				tempo = false;
-			}
-		}
-		
-		return tempo;
-	}
-	
-	private boolean computeTempoWithAmplitude2(MusicXmlNote musicXmlNote, List<ChunkAnalysis> chunkAnalysisList, ChunkAnalysis lastChunkAnalysis) {
-
-		List<Integer> chunkAmplitudeList = chunkAnalysisList.stream().map(ChunkAnalysis::getAmplitude).collect(Collectors.toList());
-
-		/*if (chunkAmplitudeList.size() <= 3) {
-			return chunkAmplitudeList.stream().filter(t -> t.floatValue() > hardLevel.getAmplitudeThreshold()).count() > 0;
-		}*/
-		
-		chunkAmplitudeList.add(0, lastChunkAnalysis.getAmplitude());
-		
-		// 检测是否有多个波峰
-		boolean tempo = false;
-		boolean isContinue = true;
-		int firstPeakIndex = -1;
-		int peakSize = 0;
-		for (int i = 1; i < chunkAmplitudeList.size(); i++) {
-			if (chunkAmplitudeList.get(i) > hardLevel.getAmplitudeThreshold() && chunkAmplitudeList.get(i) > chunkAmplitudeList.get(i - 1) + 2) {
-				tempo = true;
-				if(firstPeakIndex == -1){
-					firstPeakIndex = i;
-					peakSize++;
-				}
-				if (isContinue == false) {
-					tempo = false;
-					peakSize++;
-					break;
-				}
-			} else {
-				if (tempo == true) {
-					isContinue = false;
-				}
-			}
-		}
-		
-		if(peakSize == 0){
-			tempo = lastChunkAnalysis.isPeak();
-		}else if(peakSize == 1){
-			tempo = true;
-		}else{
-			tempo = false;
-		}
-		
-		if (tempo) {
-			// 判断进入时间点
-			if((firstPeakIndex - 1) * 100 /chunkAmplitudeList.size() > hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator())){
-				tempo = false;
-			}
-		}
-		
-		return tempo;
-	}
-	
-	private boolean computeTempoWithAmplitude(MusicXmlNote musicXmlNote, List<ChunkAnalysis> chunkAnalysisList, ChunkAnalysis lastChunkAnalysis) {
-
-		boolean tempo = false;
-
-		List<Integer> chunkAmplitudeList = chunkAnalysisList.stream().map(ChunkAnalysis::getAmplitude).collect(Collectors.toList());
-
-		if (chunkAmplitudeList.size() < 3) {
-			return chunkAmplitudeList.stream().filter(t -> t.floatValue() > hardLevel.getAmplitudeThreshold()).count() > 0;
-		}
-		
-		chunkAmplitudeList.add(0, lastChunkAnalysis.getAmplitude());
-
-		// 检测是否有多个波峰
-		int peakSize = 0;
-		int minPeakIndex = -1;
-		for (int i = 1; i < chunkAmplitudeList.size(); i++) {
-			if (chunkAmplitudeList.get(i) < hardLevel.getAmplitudeThreshold()) {
-				continue;
-			}
-			if (i == chunkAmplitudeList.size() - 1) {
-				if (chunkAmplitudeList.get(i) > chunkAmplitudeList.get(i - 1)) {
-					peakSize++;
-					if (minPeakIndex == -1 || minPeakIndex > i) {
-						minPeakIndex = i;
-					}
-				}
-			} else {
-				if (chunkAmplitudeList.get(i - 1) < chunkAmplitudeList.get(i) && chunkAmplitudeList.get(i) >= chunkAmplitudeList.get(i + 1)) {
-					//if(Math.abs(chunkAmplitudeList.get(i - 1) - chunkAmplitudeList.get(i)) > 2 || Math.abs(chunkAmplitudeList.get(i) - chunkAmplitudeList.get(i + 1)) > 2){
-						peakSize++;
-						if (minPeakIndex == -1 || minPeakIndex > i) {
-							minPeakIndex = i;
-						}
-					//}
-				}
-			}
-		}
-
-		if (peakSize == 1) {
-			if (lastChunkAnalysis.isPeak() == false) {
-				tempo = true;
-			}
-		} else if (peakSize == 0) {
-			if (lastChunkAnalysis.isPeak()) {
-				tempo = true;
-			}
-		}
-
-		// 检测是否延迟进入
-		if (tempo == true) {
-			if (minPeakIndex * 100 / chunkAmplitudeList.size() > hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator()) && chunkAmplitudeList.size() > 3) {
-				tempo = false;
-			}
-		}
-
-		return tempo;
-	}
-	
-	public static void main(String[] args) {
-		UserChannelContext2 context = new 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));
-		}
-		
-		MusicXmlNote musicXmlNote = new MusicXmlNote();
-		musicXmlNote.setDenominator(1);
-		
-		//System.out.println(context.computeFrequency(chunkAnalysisList, lastChunkAnalysis, 5));
-		System.out.println(context.computeTempoWithFrequency(musicXmlNote, chunkAnalysisList, lastChunkAnalysis));
-	}
-	
-}

+ 0 - 841
audio-analysis/src/main/java/com/yonge/netty/dto/UserChannelContext3.java

@@ -1,841 +0,0 @@
-package com.yonge.netty.dto;
-
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.stream.Collectors;
-
-import javax.sound.sampled.AudioFormat;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.yonge.audio.analysis.Signals;
-import com.yonge.audio.analysis.detector.YINPitchDetector;
-import com.yonge.audio.utils.ArrayUtil;
-import com.yonge.netty.dto.NoteAnalysis.NoteErrorType;
-import com.yonge.netty.entity.MusicXmlBasicInfo;
-import com.yonge.netty.entity.MusicXmlNote;
-import com.yonge.netty.entity.MusicXmlSection;
-import com.yonge.netty.server.processor.WaveformWriter;
-
-/**
- * 用户通道上下文
- */
-public class UserChannelContext3 {
-	
-	private final static Logger LOGGER = LoggerFactory.getLogger(UserChannelContext.class);
-	
-	private double standardFrequecy = 442;
-	
-	private int offsetMS;
-	
-	private double dynamicOffset;
-	
-	private String platform;
-	
-	private Long recordId;
-	
-	private Integer subjectId;
-	
-	private int beatDuration;
-	
-	private int beatByteLength;
-	
-	private boolean delayProcessed;
-	
-	// 曲目与musicxml对应关系
-	private ConcurrentHashMap<Integer, MusicXmlBasicInfo> songMusicXmlMap = new ConcurrentHashMap<Integer, MusicXmlBasicInfo>();
-
-	private WaveformWriter waveFileProcessor;
-
-	private NoteAnalysis processingNote = new NoteAnalysis(0, 0, -1);
-	
-	private AtomicInteger evaluatingSectionIndex = new AtomicInteger(0);
-	
-	private List<NoteAnalysis> doneNoteAnalysisList = new ArrayList<NoteAnalysis>();
-	
-	private List<SectionAnalysis> doneSectionAnalysisList = new ArrayList<SectionAnalysis>();
-	
-	private List<ChunkAnalysis> totalChunkAnalysisList = new ArrayList<ChunkAnalysis>();
-	
-	private byte[] channelBufferBytes = new byte[0];
-	
-	private double playTime;
-	
-	private double receivedTime;
-	
-	private HardLevelEnum hardLevel = HardLevelEnum.ADVANCED;
-	
-	private NotePlayResult queryNoteFrequency(MusicXmlNote xmlNote, double playFrequency) {
-
-		NotePlayResult result = new NotePlayResult();
-
-		boolean status = false;
-		double migrationRate = 0;
-
-		if (Math.round(xmlNote.getFrequency()) == Math.round(playFrequency)) {
-			status = true;
-			migrationRate = 0;
-		} else {
-			NoteFrequencyRange noteFrequencyRange = new NoteFrequencyRange(standardFrequecy, xmlNote.getFrequency());
-
-			if (noteFrequencyRange.getMinFrequency() > playFrequency || playFrequency > noteFrequencyRange.getMaxFrequency()) {
-				status = false;
-			} else {
-
-				status = true;
-
-				if (Math.round(playFrequency) < Math.round(xmlNote.getFrequency())) {
-					double min = Math.abs(xmlNote.getFrequency() - noteFrequencyRange.getMinFrequency()) / 2;
-					migrationRate = Math.abs(playFrequency - xmlNote.getFrequency()) / min;
-				} else {
-					double max = Math.abs(xmlNote.getFrequency() - noteFrequencyRange.getMaxFrequency()) / 2;
-					migrationRate = Math.abs(playFrequency - xmlNote.getFrequency()) / max;
-				}
-			}
-		}
-
-		result.setStatus(status);
-		result.setMigrationRate(migrationRate);
-
-		return result;
-	}
-	
-	public void init(String platform, String heardLevel, int subjectId, int beatDuration) {
-		this.platform = platform;
-		this.subjectId = subjectId;
-		this.beatDuration = beatDuration;
-		this.beatByteLength = WaveformWriter.SAMPLE_RATE * WaveformWriter.BITS_PER_SAMPLE / 8 * beatDuration / 1000;
-		hardLevel = HardLevelEnum.valueOf(heardLevel);
-	}
-	
-	public byte[] skipMetronome(byte[] datas) {
-		if (beatByteLength > 0) {
-			if (datas.length <= beatByteLength) {
-				beatByteLength -= datas.length;
-				return new byte[0];
-			}
-			if(beatByteLength % 2 != 0){
-				beatByteLength++;
-			}
-			datas = ArrayUtil.extractByte(datas, beatByteLength, datas.length - 1);
-			beatByteLength = 0;
-		}
-		return datas;
-	}
-	
-	public Long getRecordId() {
-		return recordId;
-	}
-
-	public void setRecordId(Long recordId) {
-		this.recordId = recordId;
-	}
-
-	public int getOffsetMS() {
-		return offsetMS;
-	}
-
-	public void setOffsetMS(int offsetMS) {
-		this.offsetMS = offsetMS;
-	}
-
-	public HardLevelEnum getHardLevel() {
-		return hardLevel;
-	}
-
-	public ConcurrentHashMap<Integer, MusicXmlBasicInfo> getSongMusicXmlMap() {
-		return songMusicXmlMap;
-	}
-
-	public WaveformWriter getWaveFileProcessor() {
-		return waveFileProcessor;
-	}
-
-	public void setWaveFileProcessor(WaveformWriter waveFileProcessor) {
-		this.waveFileProcessor = waveFileProcessor;
-	}
-
-	public NoteAnalysis getProcessingNote() {
-		return processingNote;
-	}
-
-	public void setProcessingNote(NoteAnalysis processingNote) {
-		this.processingNote = processingNote;
-	}
-	
-	public List<SectionAnalysis> getDoneSectionAnalysisList() {
-		return doneSectionAnalysisList;
-	}
-
-	public List<NoteAnalysis> getDoneNoteAnalysisList() {
-		return doneNoteAnalysisList;
-	}
-
-	public void resetUserInfo() {
-		beatByteLength = WaveformWriter.SAMPLE_RATE * WaveformWriter.BITS_PER_SAMPLE / 8 * beatDuration / 1000;
-		waveFileProcessor = null;
-		processingNote = new NoteAnalysis(0,0,-1);
-		evaluatingSectionIndex = new AtomicInteger(0);
-		channelBufferBytes = new byte[0];
-		doneNoteAnalysisList = new ArrayList<NoteAnalysis>();
-		doneSectionAnalysisList = new ArrayList<SectionAnalysis>();
-		totalChunkAnalysisList = new ArrayList<ChunkAnalysis>();
-		recordId = null;
-		playTime = 0;
-		receivedTime = 0;
-		delayProcessed = false;
-		dynamicOffset = 0;
-	}
-	
-	public MusicXmlBasicInfo getMusicXmlBasicInfo(Integer songId){
-		MusicXmlBasicInfo musicXmlBasicInfo = null;
-		if (songId == null) {
-			musicXmlBasicInfo = songMusicXmlMap.values().stream().findFirst().get();
-		} else {
-			musicXmlBasicInfo = songMusicXmlMap.get(songId);
-		}
-		return musicXmlBasicInfo;
-	}
-	
-	public MusicXmlSection getCurrentMusicSection(Integer songId, int sectionIndex){
-		MusicXmlBasicInfo musicXmlBasicInfo = getMusicXmlBasicInfo(songId);
-		return musicXmlBasicInfo.getMusicXmlSectionMap().get(sectionIndex);
-	}
-
-	public MusicXmlNote getCurrentMusicNote(Integer songId, Integer noteIndex) {
-		if (songMusicXmlMap.size() == 0) {
-			return null;
-		}
-		if(noteIndex == null){
-			noteIndex = processingNote.getMusicalNotesIndex();
-		}
-		final int index = noteIndex;
-		MusicXmlBasicInfo musicXmlBasicInfo = getMusicXmlBasicInfo(songId);
-
-		if (musicXmlBasicInfo != null && index <= getTotalMusicNoteIndex(null)) {
-			return musicXmlBasicInfo.getMusicXmlInfos().stream().filter(t -> t.getMusicalNotesIndex() == index).findFirst().get();
-		}
-
-		return null;
-	}
-
-	public int getTotalMusicNoteIndex(Integer songId) {
-		if (songMusicXmlMap.size() == 0) {
-			return -1;
-		}
-		MusicXmlBasicInfo musicXmlBasicInfo = getMusicXmlBasicInfo(songId);
-
-		if (musicXmlBasicInfo != null) {
-			return musicXmlBasicInfo.getMusicXmlInfos().stream().map(t -> t.getMusicalNotesIndex()).distinct().max(Integer::compareTo).get();
-		}
-
-		return -1;
-	}
-
-	public List<MusicXmlNote> getCurrentMusicSection(Integer songId, Integer sectionIndex) {
-		if (songMusicXmlMap.size() == 0) {
-			return null;
-		}
-		if(sectionIndex == null){
-			sectionIndex = processingNote.getSectionIndex();
-		}
-		final int index = sectionIndex;
-		MusicXmlBasicInfo musicXmlBasicInfo = getMusicXmlBasicInfo(songId);
-
-		if (musicXmlBasicInfo != null) {
-			return musicXmlBasicInfo.getMusicXmlInfos().stream().filter(t -> t.getMusicalNotesIndex() == index)
-					.sorted(Comparator.comparing(MusicXmlNote::getMusicalNotesIndex)).collect(Collectors.toList());
-		}
-
-		return null;
-	}
-
-	public int getTotalMusicSectionSize(Integer songId) {
-		if (songMusicXmlMap.size() == 0) {
-			return -1;
-		}
-		MusicXmlBasicInfo musicXmlBasicInfo = getMusicXmlBasicInfo(songId);
-
-		if (musicXmlBasicInfo != null) {
-			return (int) musicXmlBasicInfo.getMusicXmlInfos().stream().map(t -> t.getMeasureIndex()).distinct().count();
-		}
-
-		return -1;
-	}
-	
-	public int getMusicSectionIndex(Integer songId, int musicXmlNoteIndex) {
-		if (songMusicXmlMap.size() == 0) {
-			return -1;
-		}
-		
-		if(getTotalMusicNoteIndex(null) < musicXmlNoteIndex){
-			return -1;
-		}
-		
-		MusicXmlBasicInfo musicXmlBasicInfo = getMusicXmlBasicInfo(songId);
-
-		if (musicXmlBasicInfo != null) {
-			return musicXmlBasicInfo.getMusicXmlInfos().stream().filter(t -> t.getMusicalNotesIndex() == musicXmlNoteIndex).findFirst().get().getMeasureIndex();
-		}
-
-		return -1;
-	}
-	
-	public byte[] getChannelBufferBytes() {
-		return channelBufferBytes;
-	}
-
-	public void setChannelBufferBytes(byte[] channelBufferBytes) {
-		this.channelBufferBytes = channelBufferBytes;
-	}
-
-	public AtomicInteger getEvaluatingSectionIndex() {
-		return evaluatingSectionIndex;
-	}
-
-	public void handle(float[] samples, AudioFormat audioFormat){
-		
-		YINPitchDetector frequencyDetector = new YINPitchDetector(samples.length , audioFormat.getSampleRate());
-
-		int playFrequency = (int) frequencyDetector.getFrequency(samples);
-		int splDb = (int) Signals.soundPressureLevel(samples);
-		int power = (int) Signals.power(samples);
-		int amplitude = (int) Signals.norm(samples);
-		float rms = Signals.rms(samples);
-		
-		double durationTime = 1000 * (samples.length * 2) / audioFormat.getSampleRate() / (audioFormat.getSampleSizeInBits() / 8);
-		
-		receivedTime += durationTime;
-		
-		if(receivedTime < offsetMS){
-			return;
-		}
-		
-		playTime += durationTime;
-		
-		// 获取当前音符信息
-		MusicXmlNote musicXmlNote = getCurrentMusicNote(null,null);
-
-		if (musicXmlNote == null) {
-			return;
-		}
-		
-		//取出当前处理中的音符信息
-		NoteAnalysis noteAnalysis = getProcessingNote();
-		if(noteAnalysis == null || noteAnalysis.getDurationTime() == 0) {
-			noteAnalysis = new NoteAnalysis(musicXmlNote.getMusicalNotesIndex(), musicXmlNote.getMeasureIndex(), (int)musicXmlNote.getFrequency(), musicXmlNote.getDuration());
-		}
-		
-		evaluatingSectionIndex.set(noteAnalysis.getSectionIndex());
-		
-		if (noteAnalysis.getMusicalNotesIndex() >= 0 && noteAnalysis.getMusicalNotesIndex() <= getTotalMusicNoteIndex(null)) {
-			
-			LOGGER.info("delayPrcessed:{} dynamicOffset:{}  Frequency:{}  splDb:{}  Power:{}  amplitude:{}  rms:{}  time:{}", delayProcessed, dynamicOffset, 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 < chunkAnalysis.getAmplitude()){
-					chunkAnalysis.setPeak(true);//只针对打击乐
-				}
-			}
-			totalChunkAnalysisList.add(chunkAnalysis);
-			
-			if(delayProcessed == false && chunkAnalysis.getFrequency() > 100){
-				
-				delayProcessed = true;
-				//计算延迟偏移值
-				//playTime = musicXmlNote.getTimeStamp() + durationTime;
-				dynamicOffset = chunkAnalysis.getStartTime() - musicXmlNote.getTimeStamp();
-				/*if(100 * dynamicOffset / musicXmlNote.getDuration() > (100 - hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator()))){
-					dynamicOffset = 0;
-				}*/
-			}
-			
-			if (playTime >= (musicXmlNote.getDuration() + musicXmlNote.getTimeStamp() + dynamicOffset)) {
-
-				if (musicXmlNote.getDontEvaluating()) {
-					noteAnalysis.setIgnore(true);
-				}
-				
-				noteAnalysis.setPlayFrequency(computeFrequency(musicXmlNote));
-				
-				//判断节奏(音符持续时间内有不间断的音高,就节奏正确)
-				boolean tempo = true;
-				if (subjectId == 23 || subjectId == 113) {
-					tempo = computeTempoWithAmplitude2(musicXmlNote);
-				}else{
-					tempo = computeTempoWithFrequency(musicXmlNote);
-				}
-				
-				noteAnalysis.setTempo(tempo);
-				
-				evaluateForNote(musicXmlNote, noteAnalysis);
-
-				LOGGER.info("当前音符下标[{}] 预计频率:{} 实际频率:{} 节奏:{}", noteAnalysis.getMusicalNotesIndex(), musicXmlNote.getFrequency(), noteAnalysis.getPlayFrequency(),
-						noteAnalysis.isTempo());
-				
-				doneNoteAnalysisList.add(noteAnalysis);
-				
-				// 准备处理下一个音符
-				int nextNoteIndex = musicXmlNote.getMusicalNotesIndex() + 1;
-				float nextNoteFrequence = -1;
-				double standDuration = 0;
-				MusicXmlNote nextMusicXmlNote = getCurrentMusicNote(null, nextNoteIndex);
-				if(nextMusicXmlNote != null){
-					nextNoteFrequence = nextMusicXmlNote.getFrequency();
-					standDuration = nextMusicXmlNote.getDuration();
-				}
-				
-				NoteAnalysis nextNoteAnalysis = new NoteAnalysis(nextNoteIndex, getMusicSectionIndex(null, nextNoteIndex), (int)nextNoteFrequence, standDuration);
-
-				noteAnalysis = nextNoteAnalysis;
-
-			}
-
-			setProcessingNote(noteAnalysis);
-		}
-		
-	}
-	
-
-	public int evaluateForSection(int sectionIndex, int subjectId){
-
-		int score = -1;
-		if(doneSectionAnalysisList.size() >= getTotalMusicSectionSize(null)){
-			return score;
-		}
-		
-		//取出当前小节的所有音符
-		List<NoteAnalysis> noteAnalysisList = doneNoteAnalysisList.stream().filter(t -> t.getSectionIndex() == sectionIndex).collect(Collectors.toList());
-		
-		long ignoreSize = noteAnalysisList.stream().filter(t -> t.isIgnore()).count();
-
-		SectionAnalysis sectionAnalysis = new SectionAnalysis();
-		sectionAnalysis.setIndex(sectionIndex);
-		sectionAnalysis.setNoteNum(noteAnalysisList.size());
-		sectionAnalysis.setIsIngore(ignoreSize == noteAnalysisList.size());
-		
-		//判断是否需要评分
-		MusicXmlSection musicXmlSection = getCurrentMusicSection(null, sectionIndex);
-		if(noteAnalysisList.size() == musicXmlSection.getNoteNum()){
-			//取出需要评测的音符
-			List<NoteAnalysis>  noteList = noteAnalysisList.stream().filter(t -> t.isIgnore() == false).collect(Collectors.toList());
-			
-			if(noteList != null && noteList.size() > 0){
-				score = noteList.stream().mapToInt(t -> t.getScore()).sum() / noteList.size();
-			}
-			sectionAnalysis.setDurationTime(noteAnalysisList.stream().mapToDouble(t -> t.getDurationTime()).sum());
-			sectionAnalysis.setScore(score);
-
-			LOGGER.info("小节评分:{}",sectionAnalysis);
-			doneSectionAnalysisList.add(sectionAnalysis);
-		}
-		
-		return score;
-	}
-	
-	public Map<String, Integer> evaluateForMusic() {
-
-		Map<String, Integer> result = new HashMap<String, Integer>();
-		
-		result.put("playTime", (int) doneNoteAnalysisList.stream().mapToDouble(t -> t.getDurationTime()).sum());
-		
-		// 取出需要评测的音符
-		List<NoteAnalysis> noteAnalysisList = doneNoteAnalysisList.stream().filter(t -> t.isIgnore() == false).collect(Collectors.toList());
-
-		if (noteAnalysisList != null && noteAnalysisList.size() > 0) {
-			int intonationScore = 0;
-			int tempoScore = 0;
-			int integrityScore = 0;
-			int socre = 0;
-
-			for (NoteAnalysis note : noteAnalysisList) {
-				intonationScore += note.getIntonationScore();
-				tempoScore += note.getTempoScore();
-				integrityScore += note.getIntegrityScore();
-				socre += note.getScore();
-			}
-
-			tempoScore = tempoScore / noteAnalysisList.size();
-			intonationScore = intonationScore / noteAnalysisList.size();
-			integrityScore = integrityScore / noteAnalysisList.size();
-
-			result.put("cadence", tempoScore);
-			result.put("intonation", intonationScore);
-			result.put("integrity", integrityScore);
-	        result.put("recordId", recordId.intValue());
-
-			int score = socre / noteAnalysisList.size();
-
-			// 平均得分
-			if (getMusicXmlBasicInfo(null).getSubjectId() == 23 || getMusicXmlBasicInfo(null).getSubjectId() == 113) {
-				score = tempoScore;
-			}
-			result.put("score", score);
-		}
-		return result;
-	}
-	
-
-	public void evaluateForNote(MusicXmlNote musicXmlNote, NoteAnalysis noteAnalysis) {
-		
-		double floatingRange = musicXmlNote.getDuration() * hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator()) / 100;
-		double endTime = musicXmlNote.getDuration() + musicXmlNote.getTimeStamp() + dynamicOffset;
-		double startTime = musicXmlNote.getTimeStamp() + dynamicOffset;
-		
-		List<ChunkAnalysis> chunkAnalysisList = totalChunkAnalysisList.stream().filter(t -> Double.doubleToLongBits(t.getStartTime()) >= Double.doubleToLongBits(startTime) && Double.doubleToLongBits(t.getEndTime()) <= Double.doubleToLongBits(endTime)).collect(Collectors.toList());
-
-		//根据完整度取部分有效信号
-		int elementSize = chunkAnalysisList.size() * (100 - hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator())) / 100;
-		chunkAnalysisList = chunkAnalysisList.subList(0, elementSize);
-		
-		double playDurationTime = 0;
-		
-		if (subjectId == 23 || subjectId == 113) {
-			if (noteAnalysis.getFrequency() == -1) {// 休止符
-				if (!noteAnalysis.isTempo()) {
-					noteAnalysis.setMusicalErrorType(NoteErrorType.CADENCE_WRONG);
-				} else {
-					noteAnalysis.setMusicalErrorType(NoteErrorType.RIGHT);
-				}
-			}else{
-				int beatTimes = (int) chunkAnalysisList.stream().filter(t -> t.getAmplitude() > hardLevel.getAmplitudeThreshold()).count();
-				LOGGER.info("Amplitude:{}  beatTimes:{}  Denominator:{}",chunkAnalysisList.stream().map(t -> t.getAmplitude()).collect(Collectors.toList()), beatTimes, musicXmlNote.getDenominator());
-				if(beatTimes == 0){
-					noteAnalysis.setMusicalErrorType(NoteErrorType.NOT_PLAY);
-				}else if (!noteAnalysis.isTempo()) {
-					noteAnalysis.setMusicalErrorType(NoteErrorType.CADENCE_WRONG);
-				} else {
-					noteAnalysis.setMusicalErrorType(NoteErrorType.RIGHT);
-				}
-			}
-		} else {
-			
-			NotePlayResult notePlayResult = queryNoteFrequency(musicXmlNote, noteAnalysis.getPlayFrequency());
-			
-			if (noteAnalysis.getFrequency() == -1) {// 休止符
-
-				playDurationTime = chunkAnalysisList.stream().filter(t -> t.getFrequency() <= 100).mapToDouble(t -> t.getDurationTime()).sum();
-
-				if (!noteAnalysis.isTempo()) {
-					noteAnalysis.setMusicalErrorType(NoteErrorType.CADENCE_WRONG);
-				} else if (playDurationTime * 100 / noteAnalysis.getDurationTime() < hardLevel.getIntegrityRange()) {
-					noteAnalysis.setMusicalErrorType(NoteErrorType.INTEGRITY_WRONG);
-				} else if (notePlayResult.getStatus() == false) {
-					noteAnalysis.setMusicalErrorType(NoteErrorType.INTONATION_WRONG);
-				} else {
-					noteAnalysis.setMusicalErrorType(NoteErrorType.RIGHT);
-				}
-			} else {
-				playDurationTime = chunkAnalysisList.stream().filter(t -> t.getFrequency() > 100 && t.getFrequency() < 2000)
-						.mapToDouble(t -> t.getDurationTime()).sum();
-
-				if (playDurationTime * 100 / noteAnalysis.getDurationTime() < hardLevel.getNotPlayRange()) {
-					noteAnalysis.setMusicalErrorType(NoteErrorType.NOT_PLAY);
-				} else if (playDurationTime * 100 / noteAnalysis.getDurationTime() < hardLevel.getIntegrityRange()) {
-					noteAnalysis.setMusicalErrorType(NoteErrorType.INTEGRITY_WRONG);
-				} else if (!noteAnalysis.isTempo()) {
-					noteAnalysis.setMusicalErrorType(NoteErrorType.CADENCE_WRONG);
-				} else if (notePlayResult.getStatus() == false) {
-					noteAnalysis.setMusicalErrorType(NoteErrorType.INTONATION_WRONG);
-				} else {
-					noteAnalysis.setMusicalErrorType(NoteErrorType.RIGHT);
-				}
-			}
-		}
-
-		// 计算音分
-		int tempoScore = 0;
-		int integrityScore = 0;
-		int intonationScore = 100 - new BigDecimal(Math.abs(YINPitchDetector.hertzToAbsoluteCent(noteAnalysis.getPlayFrequency())
-				- YINPitchDetector.hertzToAbsoluteCent(noteAnalysis.getFrequency()))).multiply(new BigDecimal(20)).divide(new BigDecimal(17), BigDecimal.ROUND_UP)
-				.setScale(0, BigDecimal.ROUND_UP).intValue();
-		if (intonationScore < 0) {
-			intonationScore = 0;
-		} else if (intonationScore > 100) {
-			intonationScore = 100;
-		}
-
-		if (noteAnalysis.getMusicalErrorType() == NoteErrorType.NOT_PLAY) {
-			intonationScore = 0;
-		} else {
-
-			if (noteAnalysis.isTempo()) {
-				tempoScore = 100;
-				noteAnalysis.setTempoScore(tempoScore);
-			}
-
-			double durationPercent = playDurationTime / noteAnalysis.getDurationTime();
-			if (durationPercent >= 0.7) {
-				integrityScore = 100;
-			} else if (durationPercent < 0.7 && durationPercent >= 0.5) {
-				integrityScore = 50;
-			}
-			noteAnalysis.setIntegrityScore(integrityScore);
-		}
-		noteAnalysis.setIntonationScore(intonationScore);
-		if (subjectId == 23 || subjectId == 113) {
-			noteAnalysis.setScore(tempoScore);
-		} else {
-			noteAnalysis.setScore(new BigDecimal(intonationScore + tempoScore + integrityScore).divide(new BigDecimal(3), 2).setScale(0, BigDecimal.ROUND_UP)
-					.intValue());
-		}
-	}
-	
-	private int computeFrequency(MusicXmlNote musicXmlNote) {
-		
-		double floatingRange = musicXmlNote.getDuration() * hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator()) / 100;
-		double endTime = musicXmlNote.getDuration() + musicXmlNote.getTimeStamp() + dynamicOffset - floatingRange;
-		double startTime = musicXmlNote.getTimeStamp() + dynamicOffset;
-		
-		List<ChunkAnalysis> chunkAnalysisList = totalChunkAnalysisList.stream().filter(t -> Double.doubleToLongBits(t.getStartTime()) >= Double.doubleToLongBits(startTime) && Double.doubleToLongBits(t.getEndTime()) <= Double.doubleToLongBits(endTime)).collect(Collectors.toList());
-		
-		//根据完整度取部分有效信号
-		int elementSize = chunkAnalysisList.size() * (100 - hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator())) / 100;
-		chunkAnalysisList = chunkAnalysisList.subList(0, elementSize);
-		
-		if(chunkAnalysisList == null || chunkAnalysisList.size() == 0){
-			return -1;
-		}
-		
-		ChunkAnalysis firstChunkAnalysis = chunkAnalysisList.get(0);
-		
-		LOGGER.info("-------startTime:{}  endTime:{}------", firstChunkAnalysis.getStartTime(), chunkAnalysisList.get(chunkAnalysisList.size() - 1)
-				.getEndTime());
-		
-		List<ChunkAnalysis> chunkList = new ArrayList<ChunkAnalysis>(chunkAnalysisList);
-		
-		List<Integer> chunkFrequencyList = chunkList.stream().map(t -> t.getFrequency()).filter(t -> t.doubleValue() > 100 && t.doubleValue() < 2000)
-				.collect(Collectors.toList());
-		
-		if (chunkFrequencyList.size() == 0) {
-			return -1;
-		}
-
-		int frequency = (int) (chunkFrequencyList.stream().mapToInt(t -> t).sum() / chunkFrequencyList.size());
-
-		return frequency;
-	}
-	
-	/**
-	 * 时值范围内有且只有一个音,且不能间断,且在合理范围内需开始演奏
-	 * 与上一个音相同时,2个音之间需要间断
-	 * @param musicXmlNote
-	 * @return
-	 */
-	private boolean computeTempoWithFrequency(MusicXmlNote musicXmlNote){
-		
-		double floatingRange = musicXmlNote.getDuration() * hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator()) / 100;
-		double endTime = musicXmlNote.getDuration() + musicXmlNote.getTimeStamp() + dynamicOffset - floatingRange;
-		double startTime = musicXmlNote.getTimeStamp() + dynamicOffset;
-		
-		List<ChunkAnalysis> chunkAnalysisList = totalChunkAnalysisList.stream().filter(t -> Double.doubleToLongBits(t.getStartTime()) >= Double.doubleToLongBits(startTime) && Double.doubleToLongBits(t.getEndTime()) <= Double.doubleToLongBits(endTime)).collect(Collectors.toList());
-
-		//根据完整度取部分有效信号
-		int elementSize = chunkAnalysisList.size() * (100 - hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator())) / 100;
-		chunkAnalysisList = chunkAnalysisList.subList(0, elementSize);
-		
-		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);
-		
-		Optional<ChunkAnalysis> chunkAnalysisOptional = totalChunkAnalysisList.stream().filter(t -> Double.doubleToLongBits(t.getEndTime()) == Double.doubleToLongBits(firstChunkAnalysis.getStartTime())).findFirst();
-
-		ChunkAnalysis lastChunkAnalysis = null;
-		if (chunkAnalysisOptional.isPresent()) {
-			lastChunkAnalysis = chunkAnalysisOptional.get();
-		}
-		
-		if(lastChunkAnalysis == null){
-			lastChunkAnalysis = new ChunkAnalysis(0, 0, -1, 0, 0, 0);
-		}
-		
-		List<ChunkAnalysis> chunkList = new ArrayList<ChunkAnalysis>(chunkAnalysisList);
-		
-		if(chunkList.size() == 0){
-			return false;
-		}
-		
-		NoteFrequencyRange noteFrequencyRange = null;
-		ChunkAnalysis chunkAnalysis = null;
-		boolean tempo = false;
-		boolean isContinue = true;
-		int unplayedSize = 0;
-		int firstPeakIndex = -1;
-		for (int i = 0; i < chunkList.size(); i++) {
-			chunkAnalysis = chunkList.get(i);
-			if (chunkAnalysis != null) {
-				if (chunkAnalysis.getFrequency() > 100) {
-					
-					tempo = true;
-					if (firstPeakIndex == -1) {
-						firstPeakIndex = i;
-						noteFrequencyRange = new NoteFrequencyRange(standardFrequecy, chunkAnalysis.getFrequency());
-					} else if (noteFrequencyRange.getMinFrequency() > chunkAnalysis.getFrequency()
-							|| chunkAnalysis.getFrequency() > noteFrequencyRange.getMaxFrequency()) {
-						// 判断是否是同一个音
-						tempo = false;
-						LOGGER.info("节奏错误原因:不是同一个音[{}]:{}-{}", chunkAnalysis.getFrequency(), noteFrequencyRange.getMinFrequency(), noteFrequencyRange.getMaxFrequency());
-						break;
-					}
-					if (isContinue == false) {
-						if ((i + 1) / chunkAnalysisList.size() < hardLevel.getIntegrityRange()) {
-							if (unplayedSize > 0) {
-								tempo = false;
-								LOGGER.info("节奏错误原因:信号不连续");
-								break;
-							}
-						}
-					}
-				} else {
-					if (tempo == true) {
-						isContinue = false;
-						unplayedSize++;
-					}
-				}
-			}
-		}
-		
-		if (tempo) {
-			// 判断进入时间点
-			if(firstPeakIndex * 100 /chunkAnalysisList.size() > hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator())){
-				tempo = false;
-				LOGGER.info("节奏错误原因:进入时间点太晚");
-			}
-			if(tempo){
-				//判断是否与上一个音延续下来的
-				if(firstChunkAnalysis.getFrequency() > 100 && lastChunkAnalysis.getFrequency() > 100){
-					tempo = new NoteFrequencyRange(standardFrequecy, firstChunkAnalysis.getFrequency()).equals(new NoteFrequencyRange(standardFrequecy, lastChunkAnalysis.getFrequency())) == false;
-					LOGGER.info("节奏错误原因:上一个音延续下来导致的");
-				}
-			}
-		}
-		
-		return tempo;
-	}
-	
-	private boolean computeTempoWithAmplitude2(MusicXmlNote musicXmlNote) {
-
-		double floatingRange = musicXmlNote.getDuration() * hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator()) / 100;
-		
-		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;
-		}
-
-		if (musicXmlNote.getFrequency() == -1) {// 休止符
-			return chunkAnalysisList.stream().filter(t -> t.getAmplitude() > hardLevel.getAmplitudeThreshold()).count() <= 0;
-		}
-		
-		ChunkAnalysis firstChunkAnalysis = chunkAnalysisList.get(0);
-		
-		Optional<ChunkAnalysis> chunkAnalysisOptional = totalChunkAnalysisList.stream().filter(t -> Double.doubleToLongBits(t.getEndTime()) == Double.doubleToLongBits(firstChunkAnalysis.getStartTime())).findFirst();
-
-		ChunkAnalysis lastChunkAnalysis = null;
-		if (chunkAnalysisOptional.isPresent()) {
-			lastChunkAnalysis = chunkAnalysisOptional.get();
-		}
-		if(lastChunkAnalysis == null){
-			lastChunkAnalysis = new ChunkAnalysis(0, 0, -1, 0, 0, 0);
-		}
-		
-		List<Integer> chunkAmplitudeList = chunkAnalysisList.stream().map(ChunkAnalysis::getAmplitude).collect(Collectors.toList());
-
-		chunkAmplitudeList.add(0, lastChunkAnalysis.getAmplitude());
-		
-		// 检测是否有多个波峰
-		boolean tempo = false;
-		boolean isContinue = true;
-		int firstPeakIndex = -1;
-		int peakSize = 0;
-		for (int i = 1; i < chunkAmplitudeList.size(); i++) {
-			if (chunkAmplitudeList.get(i) > hardLevel.getAmplitudeThreshold() && chunkAmplitudeList.get(i) > chunkAmplitudeList.get(i - 1) + 2) {
-				tempo = true;
-				if(firstPeakIndex == -1){
-					firstPeakIndex = i;
-					peakSize++;
-				}
-				if (isContinue == false) {
-					tempo = false;
-					peakSize++;
-					break;
-				}
-			} else {
-				if (tempo == true) {
-					isContinue = false;
-				}
-			}
-		}
-		
-		if(peakSize == 0){
-			tempo = lastChunkAnalysis.isPeak();
-		}else if(peakSize == 1){
-			tempo = true;
-		}else{
-			tempo = false;
-		}
-		
-		if (tempo) {
-			// 判断进入时间点
-			if((firstPeakIndex - 1) * 100 /chunkAmplitudeList.size() > hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator()) * 2){
-				LOGGER.info("超过范围:{}", (firstPeakIndex - 1) * 100 /chunkAmplitudeList.size());
-				tempo = false;
-			}
-		}
-		
-		return tempo;
-	}
-	
-	private double queryFirstNoteStartTime(List<ChunkAnalysis> chunkAnalysisList, MusicXmlNote musicXmlNote) {
-		
-		if(chunkAnalysisList == null || chunkAnalysisList.size() == 0){
-			return musicXmlNote.getTimeStamp() + dynamicOffset;
-		}
-
-		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 chunkAnalysisList.get(chunkAnalysisList.size() - 1).getEndTime();
-	}
-	
-	public static void main(String[] args) {
-		
-		NoteFrequencyRange range = new NoteFrequencyRange(440, 466);
-		
-		System.out.println("Min:" + range.getMinFrequency() + "  Max:" + range.getMaxFrequency());
-		
-	}
-	
-}

+ 1 - 0
audio-analysis/src/main/java/com/yonge/netty/entity/MusicXmlBasicInfo.java

@@ -167,6 +167,7 @@ public class MusicXmlBasicInfo {
 				section.setDuration(noteList.stream().mapToDouble(t -> t.getDuration()).sum());
 				section.setNoteNum(noteList.size());
 				section.setIndex(entry.getKey());
+				section.setMeasureRenderIndex(noteList.stream().findFirst().get().getMeasureRenderIndex());
 
 				musicXmlSectionMap.put(entry.getKey(), section);
 			}

+ 10 - 0
audio-analysis/src/main/java/com/yonge/netty/entity/MusicXmlNote.java

@@ -31,6 +31,8 @@ public class MusicXmlNote {
 	
 	// 多少分音符
 	private int denominator;
+	
+	private int measureRenderIndex;
 
 	public double getTimeStamp() {
 		return timeStamp;
@@ -103,4 +105,12 @@ public class MusicXmlNote {
 	public void setDenominator(int denominator) {
 		this.denominator = denominator;
 	}
+
+	public int getMeasureRenderIndex() {
+		return measureRenderIndex;
+	}
+
+	public void setMeasureRenderIndex(int measureRenderIndex) {
+		this.measureRenderIndex = measureRenderIndex;
+	}
 }

+ 10 - 0
audio-analysis/src/main/java/com/yonge/netty/entity/MusicXmlSection.java

@@ -14,6 +14,8 @@ public class MusicXmlSection {
 	private int noteNum;
 
 	private int index;
+	
+	private int measureRenderIndex;
 
 	public double getDuration() {
 		return duration;
@@ -47,4 +49,12 @@ public class MusicXmlSection {
 		this.index = index;
 	}
 
+	public int getMeasureRenderIndex() {
+		return measureRenderIndex;
+	}
+
+	public void setMeasureRenderIndex(int measureRenderIndex) {
+		this.measureRenderIndex = measureRenderIndex;
+	}
+
 }

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

@@ -343,6 +343,7 @@ public class AudioCompareHandler implements MessageHandler {
 				Map<String, Object> params = new HashMap<String, Object>();
 				params.put("score", score);
 				params.put("measureIndex", sectionIndex);
+				params.put("measureRenderIndex", channelContext.getCurrentMusicSection(null, sectionIndex).getMeasureRenderIndex());
 
 				WebSocketResponse<Map<String, Object>> resp = new WebSocketResponse<Map<String, Object>>("measureScore", params);