浏览代码

update:支持节奏练习打分

yonge 2 年之前
父节点
当前提交
eeba916e4e

+ 23 - 0
audio-analysis/src/main/java/com/yonge/netty/dto/EvaluationCriteriaEnum.java

@@ -0,0 +1,23 @@
+package com.yonge.netty.dto;
+
+import com.ym.mec.common.enums.BaseEnum;
+
+public enum EvaluationCriteriaEnum implements BaseEnum<String, EvaluationCriteriaEnum> {
+
+	AMPLITUDE("振幅"),FREQUENCY("频率"),DECIBELS("分贝");
+	
+	private String desc;
+	
+	EvaluationCriteriaEnum(String desc){
+		this.desc = desc;
+	}
+
+	@Override
+	public String getCode() {
+		return this.name();
+	}
+
+	public String getDesc() {
+		return desc;
+	}
+}

+ 22 - 14
audio-analysis/src/main/java/com/yonge/netty/dto/UserChannelContext.java

@@ -2,7 +2,6 @@ package com.yonge.netty.dto;
 
 import java.math.BigDecimal;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
@@ -15,6 +14,7 @@ import java.util.stream.Collectors;
 
 import javax.sound.sampled.AudioFormat;
 
+import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -36,7 +36,7 @@ public class UserChannelContext {
 	private final static Logger LOGGER = LoggerFactory.getLogger(UserChannelContext.class);
 	
 	//打击乐
-	private final static List<Integer> percussionList = Arrays.asList(23, 113, 121);
+	//private final static List<Integer> percussionList = Arrays.asList(23, 113, 121);
 	
 	private final static int MIN_FREQUECY = 43;
 	
@@ -58,6 +58,8 @@ public class UserChannelContext {
 	
 	private Integer subjectId;
 	
+	private String evaluationCriteria;
+	
 	private float beatDuration;
 	
 	private boolean delayProcessed;
@@ -120,11 +122,12 @@ public class UserChannelContext {
 		return result;
 	}
 	
-	public void init(String platform, String heardLevel, int subjectId, float beatDuration,float sampleRate, int bufferSize) {
-		this.platform = platform;
-		this.subjectId = subjectId;
-		this.beatDuration = beatDuration;
-		hardLevel = HardLevelEnum.valueOf(heardLevel);
+	public void init(MusicXmlBasicInfo musicXmlBasicInfo, float sampleRate, int bufferSize) {
+		this.platform = musicXmlBasicInfo.getPlatform();
+		this.subjectId = musicXmlBasicInfo.getSubjectId();
+		this.beatDuration = musicXmlBasicInfo.getBeatLength();
+		this.hardLevel = HardLevelEnum.valueOf(musicXmlBasicInfo.getHeardLevel());
+		this.evaluationCriteria = musicXmlBasicInfo.getEvaluationCriteria();
 		if(detector == null){
 			detector = new FastYin(sampleRate, bufferSize);
 		}
@@ -327,13 +330,18 @@ public class UserChannelContext {
 		//int playFrequency = (int) frequencyDetector.getFrequency(samples);
 		
 		int playFrequency = -1;
-		if(!percussionList.contains(subjectId)){
+		if(StringUtils.equalsIgnoreCase(evaluationCriteria, EvaluationCriteriaEnum.FREQUENCY.getCode())){
 			playFrequency = (int)detector.getPitch(samples).getPitch();
 		}
 		
 		int splDb = (int) Signals.soundPressureLevel(samples);
 		int power = (int) Signals.power(samples);
-		int amplitude = (int) Signals.norm(samples);
+		int amplitude = 0;
+		if(StringUtils.equalsIgnoreCase(evaluationCriteria, EvaluationCriteriaEnum.AMPLITUDE.getCode())) {
+			amplitude = (int) Signals.norm(samples);
+		}else if(StringUtils.equalsIgnoreCase(evaluationCriteria, EvaluationCriteriaEnum.DECIBELS.getCode())){
+			amplitude = (int) Signals.decibels(samples) >= 38 ? 10 : 1;
+		}
 		//float rms = Signals.rms(samples);
 		
 		double durationTime = 1000 * (samples.length * 2) / audioFormat.getSampleRate() / (audioFormat.getSampleSizeInBits() / 8);
@@ -369,7 +377,7 @@ public class UserChannelContext {
 			totalChunkAnalysisList.add(chunkAnalysis);
 			
 			boolean flag = false; //是否收到有效信号
-			if(percussionList.contains(subjectId)){
+			if(!StringUtils.equalsIgnoreCase(evaluationCriteria, EvaluationCriteriaEnum.FREQUENCY.getCode())){
 				flag = chunkAnalysis.getAmplitude() > hardLevel.getAmplitudeThreshold();
 			}else{
 				flag = chunkAnalysis.getFrequency() > MIN_FREQUECY && chunkAnalysis.getFrequency() < MAX_FREQUECY;
@@ -395,7 +403,7 @@ public class UserChannelContext {
 				
 				//判断节奏(音符持续时间内有不间断的音高,就节奏正确)
 				boolean tempo = true;
-				if (percussionList.contains(subjectId)) {
+				if (!StringUtils.equalsIgnoreCase(evaluationCriteria, EvaluationCriteriaEnum.FREQUENCY.getCode())) {
 					noteAnalysis.setPlayFrequency(-1);
 					tempo = computeTempoWithAmplitude2(musicXmlNote);
 				}else{
@@ -539,7 +547,7 @@ public class UserChannelContext {
 		
 		double playDurationTime = 0;
 		
-		if (percussionList.contains(subjectId)) {
+		if (!StringUtils.equalsIgnoreCase(evaluationCriteria, EvaluationCriteriaEnum.FREQUENCY.getCode())) {
 			if (noteAnalysis.getFrequency() == -1) {// 休止符
 				if (!noteAnalysis.isTempo()) {
 					noteAnalysis.setMusicalErrorType(NoteErrorType.CADENCE_WRONG);
@@ -622,7 +630,7 @@ public class UserChannelContext {
 			noteAnalysis.setIntegrityScore(integrityScore);
 		}
 		noteAnalysis.setIntonationScore(intonationScore);
-		if (percussionList.contains(subjectId)) {
+		if (!StringUtils.equalsIgnoreCase(evaluationCriteria, EvaluationCriteriaEnum.FREQUENCY.getCode())) {
 			noteAnalysis.setScore(tempoScore);
 		} else {
 			noteAnalysis.setScore(new BigDecimal(intonationScore + tempoScore + integrityScore).divide(new BigDecimal(3), 2).setScale(0, BigDecimal.ROUND_UP)
@@ -950,7 +958,7 @@ public class UserChannelContext {
 			return musicXmlNote.getTimeStamp() + dynamicOffset;
 		}
 		
-		if (percussionList.contains(subjectId)) {
+		if (!StringUtils.equalsIgnoreCase(evaluationCriteria, EvaluationCriteriaEnum.FREQUENCY.getCode())) {
 			Optional<ChunkAnalysis> optional = chunkAnalysisList.stream().filter(t -> t.getAmplitude() > hardLevel.getAmplitudeThreshold()).findFirst();
 			if(optional.isPresent()){
 				LOGGER.debug("范围内查询到信号,correctedStartTime:{}", optional.get().getStartTime());

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

@@ -18,6 +18,8 @@ public class MusicXmlBasicInfo {
     private Integer campId;
 	
 	private String clientId;
+	
+	private String evaluationCriteria;
 
 	private Integer detailId;
 
@@ -84,6 +86,14 @@ public class MusicXmlBasicInfo {
 		this.clientId = clientId;
 	}
 
+	public String getEvaluationCriteria() {
+		return evaluationCriteria;
+	}
+
+	public void setEvaluationCriteria(String evaluationCriteria) {
+		this.evaluationCriteria = evaluationCriteria;
+	}
+
 	public Integer getDetailId() {
 		return detailId;
 	}
@@ -160,7 +170,7 @@ public class MusicXmlBasicInfo {
 		return beatLength;
 	}
 
-	public void setBeatLength(int beatLength) {
+	public void setBeatLength(float beatLength) {
 		this.beatLength = beatLength;
 	}
 

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

@@ -26,7 +26,6 @@ import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.JSONPath;
 import com.ym.mec.auth.api.client.SysUserFeignService;
-import com.ym.mec.auth.api.entity.SysUser;
 import com.ym.mec.biz.dal.entity.SysMusicCompareRecord;
 import com.ym.mec.biz.dal.enums.DeviceTypeEnum;
 import com.ym.mec.biz.dal.enums.FeatureType;
@@ -126,8 +125,7 @@ public class AudioCompareHandler implements MessageHandler {
 			channelContext.setHandlerSwitch(false);
 
 			channelContext.getSongMusicXmlMap().put(musicXmlBasicInfo.getExamSongId(), musicXmlBasicInfo);
-			channelContext.init(musicXmlBasicInfo.getPlatform(), musicXmlBasicInfo.getHeardLevel(), musicXmlBasicInfo.getSubjectId(),
-					musicXmlBasicInfo.getBeatLength(), audioFormat.getSampleRate(), bufferSize / 2);
+			channelContext.init(musicXmlBasicInfo, audioFormat.getSampleRate(), bufferSize / 2);
 			channelContext.setUser(user);
 			
 			userChannelContextService.register(channel, channelContext);