Forráskód Böngészése

Merge remote-tracking branch 'origin/master'

zouxuan 4 éve
szülő
commit
41418a5110

+ 3 - 3
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/SoundCompareHelper.java

@@ -33,7 +33,7 @@ public class SoundCompareHelper {
     @ApiModelProperty(value = "小节分数记录")
     private Map<String, BigDecimal> userScoreMap = new HashMap<>();
 
-    private Map<Integer, Map<String, BigDecimal>> userMeasureScoreMap = new HashMap<>();
+    private Map<Integer, Map<String, Object>> userMeasureScoreMap = new HashMap<>();
 
     @ApiModelProperty(value = "音符频率字典")
     private Map<Integer, Float> musicalNotePitchMap = new HashMap<>();
@@ -133,11 +133,11 @@ public class SoundCompareHelper {
         this.userScoreMap = userScoreMap;
     }
 
-    public Map<Integer, Map<String, BigDecimal>> getUserMeasureScoreMap() {
+    public Map<Integer, Map<String, Object>> getUserMeasureScoreMap() {
         return userMeasureScoreMap;
     }
 
-    public void setUserMeasureScoreMap(Map<Integer, Map<String, BigDecimal>> userMeasureScoreMap) {
+    public void setUserMeasureScoreMap(Map<Integer, Map<String, Object>> userMeasureScoreMap) {
         this.userMeasureScoreMap = userMeasureScoreMap;
     }
 }

+ 53 - 209
mec-biz/src/main/java/com/ym/mec/biz/handler/WebSocketHandler.java

@@ -169,6 +169,9 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
                 int preTimeStamp = CollectionUtils.isEmpty(userSoundInfoMap.get(phone).getRecordMeasurePithInfo())?0:userSoundInfoMap.get(phone).getRecordMeasurePithInfo().get(userSoundInfoMap.get(phone).getRecordMeasurePithInfo().size()-1).getTimeStamp();
                 calOffsetTime(phone, timeStamp - (timeStamp - preTimeStamp)/2);
             }
+            if(silenceDetecor.currentSPL()<-70){
+                pitch = -1;
+            }
 //            LOGGER.info("时间:{}, 频率:{}, 分贝:{}, 音分:{}", timeStamp, pitch, silenceDetecor.currentSPL(), cents);
             userSoundInfoMap.get(phone).getRecordMeasurePithInfo().add(new MusicPitchDetailDto(timeStamp, pitch, silenceDetecor.currentSPL()));
         }));
@@ -293,7 +296,7 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
             //节奏匹配数量
             float cadenceNum = 0;
             //节奏有效阈值
-            float cadenceValidDuty = 0.01f;
+            float cadenceValidDuty = 0.09f;
 
             //完整性误差范围
             float integrityRange = 30;
@@ -323,35 +326,35 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
                 //时间范围内匹配次数
                 float compareNum = 0;
 
-                boolean newMeasure = false;
-                float preMusicalNotesPitch = 0;
-                if(userSoundInfoMap.get(phone).getMusicalNotePitchMap().containsKey(musicXmlInfo.getMusicalNotesIndex()-1)){
-                    preMusicalNotesPitch = userSoundInfoMap.get(phone).getMusicalNotePitchMap().get(musicXmlInfo.getMusicalNotesIndex()-1);
-                }
-                if(userSoundInfoMap.get(phone).getMusicalNotePitchMap().get(musicXmlInfo.getMusicalNotesIndex())==-1){
-                    newMeasure = true;
-                }
-                int newNum = 0;
-
-                for (MusicPitchDetailDto recordInfo : userSoundInfoMap.get(phone).getRecordMeasurePithInfo()) {
-                    if(musicXmlInfo.getMusicalNotesIndex()==0){
-                        newMeasure = true;
-                    }
-                    if(newMeasure){
-                        break;
-                    }
-                    if(recordInfo.getTimeStamp()<preMeasureEndTimeStamp||recordInfo.getTimeStamp()>startTimeStamp){
-                        continue;
-                    }
-                    if(Math.abs(recordInfo.getFrequency()-preMusicalNotesPitch)>10){
-                        newNum++;
-                    }else{
-                        newNum = 0;
-                    }
-                    if(newNum>=2){
-                        newMeasure = true;
-                    }
-                }
+//                boolean newMeasure = false;
+//                float preMusicalNotesPitch = 0;
+//                if(userSoundInfoMap.get(phone).getMusicalNotePitchMap().containsKey(musicXmlInfo.getMusicalNotesIndex()-1)){
+//                    preMusicalNotesPitch = userSoundInfoMap.get(phone).getMusicalNotePitchMap().get(musicXmlInfo.getMusicalNotesIndex()-1);
+//                }
+//                if(userSoundInfoMap.get(phone).getMusicalNotePitchMap().get(musicXmlInfo.getMusicalNotesIndex())==-1){
+//                    newMeasure = true;
+//                }
+//                int newNum = 0;
+//
+//                for (MusicPitchDetailDto recordInfo : userSoundInfoMap.get(phone).getRecordMeasurePithInfo()) {
+//                    if(musicXmlInfo.getMusicalNotesIndex()==0){
+//                        newMeasure = true;
+//                    }
+//                    if(newMeasure){
+//                        break;
+//                    }
+//                    if(recordInfo.getTimeStamp()<preMeasureEndTimeStamp||recordInfo.getTimeStamp()>startTimeStamp){
+//                        continue;
+//                    }
+//                    if(Math.abs(recordInfo.getFrequency()-preMusicalNotesPitch)>10){
+//                        newNum++;
+//                    }else{
+//                        newNum = 0;
+//                    }
+//                    if(newNum>=2){
+//                        newMeasure = true;
+//                    }
+//                }
 
 //                List<Float> musicalNotesPitchs = new ArrayList<>();
 //                List<Float> decibels = new ArrayList<>();
@@ -367,9 +370,6 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
 //                    decibels.add(recordInfo.getDecibel());
                     measureSoundPitchInfos.add(recordInfo);
                     compareNum++;
-                    if(!newMeasure){
-                        continue;
-                    }
 //                    LOGGER.info("{}频率({}-{}):{}, {}", recordInfo.getTimeStamp(), startTimeStamp, endTimeStamp, musicXmlInfo.getFrequency(), recordInfo.getFrequency());
                     //如果在最低有效频率以下则跳过
                     if(recordInfo.getFrequency()<minValidFrequency&&musicXmlInfo.getFrequency()!=-1){
@@ -404,6 +404,8 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
                     boolean ing = false;
                     //当前分贝
                     double cd = 0;
+                    //分贝变化方向,-1变小,1变大
+                    int dcd = -1;
                     //分贝持续数量
                     int dnum = 0;
                     for (MusicPitchDetailDto musicalNotesPitch : measureSoundPitchInfos) {
@@ -421,13 +423,17 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
                             }
                         }
                         //计算声音大小断层册数
-                        if(ing && Math.abs(musicalNotesPitch.getDecibel() - cd) > 5){
+                        if(ing && Math.abs(musicalNotesPitch.getDecibel() - cd) > 10){
                             dnum ++;
                         }
                         if (dnum > 2){
+                            int tdcd = cd > musicalNotesPitch.getDecibel() ? -1 : 1;
                             cd = musicalNotesPitch.getDecibel();
                             dnum = 0;
-                            decibelChangeNum++;
+                            if (tdcd != dcd) {
+                                decibelChangeNum++;
+                            }
+                            dcd = tdcd;
                         }
                     }
                     userSoundInfoMap.get(phone).getMusicalNotePitchMap().put(musicXmlInfo.getMusicalNotesIndex(), (float) pitch);
@@ -500,177 +506,8 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
             userSoundInfoMap.get(phone).getUserScoreMap().put("integrity", integrity);
         }
 
-        Map<String, BigDecimal> scoreData = new HashMap<>();
-        scoreData.put("intonation", intonation);
-        scoreData.put("cadence", cadence);
-        scoreData.put("integrity", integrity);
-
-        userSoundInfoMap.get(phone).getUserMeasureScoreMap().put(measureIndex, scoreData);
-
-        WS_CLIENTS.get(phone).sendMessage(new TextMessage(JSON.toJSONString(createPushInfo("measureScore", measureIndex, intonation, cadence, integrity))));
-    }
-
-    private void measureCompare2(String phone, MusicPitchDetailDto measureTimeInfo) throws IOException, UnsupportedAudioFileException {
-        //小节总时长
-        double measureTime = measureTimeInfo.getEndTimeStamp()-measureTimeInfo.getTimeStamp();
-        double ot = measureTime * 0.1;
-        measureTime += ot;
-        //小节时长占用字节数
-        int measureByteNum = (int) (measureTime/1000*(audioFormat.getFrameSize()*audioFormat.getFrameRate()));
-
-        List<MusicPitchDetailDto> recordInfo = new ArrayList<>();
-        byte[] bytes = new byte[measureByteNum];
-        long startOffset = (userSoundInfoMap.get(phone).getAccessFile().length()-measureByteNum);
-        userSoundInfoMap.get(phone).getAccessFile().seek(startOffset);
-//        userSoundInfoMap.get(phone).getAccessFile().seek(0);
-        userSoundInfoMap.get(phone).getAccessFile().readFully(bytes);
-
-        userSoundInfoMap.get(phone).getAccessFile().seek(userSoundInfoMap.get(phone).getAccessFile().length());
-
-        AudioDispatcher dispatcher = AudioDispatcherFactory.fromByteArray(bytes, audioFormat, simpleSize, 128);
-        dispatcher.addAudioProcessor(new PitchProcessor(algo, simpleRate, simpleSize, (pitchDetectionResult, audioEvent) -> {
-            int timeStamp = (int) (measureTimeInfo.getTimeStamp() - (ot>measureTimeInfo.getTimeStamp()?0:ot) + audioEvent.getTimeStamp()*1000);
-            float pitch = pitchDetectionResult.getPitch();
-            recordInfo.add(new MusicPitchDetailDto(timeStamp, pitch));
-        }));
-        dispatcher.run();
-        userSoundInfoMap.get(phone).getRecordMeasurePithInfo().addAll(recordInfo);
-        LOGGER.info("小节评分频率{}:{}", measureTimeInfo.getMeasureIndex(), JSON.toJSONString(recordInfo));
-        scoreCal(phone, measureTimeInfo, recordInfo);
-    }
-
-    private void scoreCal(String phone, MusicPitchDetailDto measureTimeInfo, List<MusicPitchDetailDto> recordPitchDetails) throws IOException {
-        //相似度
-        BigDecimal intonation = BigDecimal.ZERO;
-        //节奏
-        BigDecimal cadence = BigDecimal.ZERO;
-        //完整度
-        BigDecimal integrity = BigDecimal.ZERO;
-
-        try {
-            //最低有效频率
-            float minValidFrequency = 20;
-
-            //音准匹配数量
-            float intonationNum = 0;
-            //音准匹配误差范围
-            float intonationErrRange = 15;
-            //音准有效阈值
-            float intonationValidDuty = 0.1f;
-
-            //节奏匹配数量
-            float cadenceNum = 0;
-            //节奏有效阈值
-            float cadenceValidDuty = 0.1f;
-
-            //完整性数量
-            float integrityNum = 0;
-            //完整性误差范围
-            float integrityRange = 30;
-            //完整性有效阈值
-            float integrityValidDuty = 0.5f;
-
-            int totalCompareNum = userSoundInfoMap.get(phone).getMeasureXmlInfoMap().get(measureTimeInfo.getMeasureIndex()).size();
-
-            for (MusicPitchDetailDto musicXmlInfo : userSoundInfoMap.get(phone).getMeasureXmlInfoMap().get(measureTimeInfo.getMeasureIndex())) {
-                int ot5 = (int) (musicXmlInfo.getDuration()*0.1);
-                int startTimeStamp = musicXmlInfo.getTimeStamp() - ot5;
-                int endTimeStamp = musicXmlInfo.getTimeStamp() + ot5;
-
-                //时间范围内有效音准数量
-                float recordValidIntonationNum = 0;
-                //时间范围内有效节奏数量
-                float cadenceValidNum = 0;
-                //时间范围内有效音频数量
-                float integrityValidNum = 0;
-                //时间范围内匹配次数
-                float compareNum = 0;
-                int faultNum = 0;
-                for (int i = 0; i < recordPitchDetails.size(); i++) {
-                    MusicPitchDetailDto recordInfo = recordPitchDetails.get(i);
-                    if(recordInfo.getTimeStamp()>(startTimeStamp-ot5)&&Math.abs((recordInfo.getFrequency()-musicXmlInfo.getFrequency()))>20){
-                        faultNum++;
-                    }else{
-                        if(faultNum<6)
-                            faultNum = 0;
-                    }
-                    if(faultNum<6){
-                        continue;
-                    }
-                    //如果在时间范围之外直接跳过
-                    if(recordInfo.getTimeStamp()<startTimeStamp||recordInfo.getTimeStamp()>endTimeStamp){
-                        continue;
-                    }
-//                    LOGGER.info("{}频率({}-{}):{}, {}", recordInfo.getTimeStamp(), startTimeStamp, endTimeStamp, musicXmlInfo.getFrequency(), recordInfo.getFrequency());
-                    compareNum++;
-                    //如果在最低有效频率以下则跳过
-                    if(recordInfo.getFrequency()<minValidFrequency&&musicXmlInfo.getFrequency()!=-1){
-                        continue;
-                    }
-                    cadenceValidNum++;
-                    if(recordInfo.getTimeStamp()<startTimeStamp||recordInfo.getTimeStamp()>endTimeStamp){
-                        continue;
-                    }
-                    //如果频率差值在节奏误差范围内
-                    if(Math.abs(recordInfo.getFrequency()-musicXmlInfo.getFrequency())<=integrityRange){
-                        integrityValidNum++;
-                    }
-                    //如果频率差值在音准误差范围内
-                    if(Math.abs(recordInfo.getFrequency()-musicXmlInfo.getFrequency())<=intonationErrRange){
-                        recordValidIntonationNum++;
-                    }
-                }
-                //有效音频占比
-                float integrityDuty = integrityValidNum/compareNum;
-                //有效音高占比
-                float intonationDuty = recordValidIntonationNum/compareNum;
-                //有效节奏占比
-                float cadenceDuty = cadenceValidNum/compareNum;
-                //节奏
-                if(cadenceDuty>=cadenceValidDuty){
-                    cadenceNum++;
-                    if(intonationDuty>=intonationValidDuty){
-                        intonationNum++;
-                    }
-                    if(integrityDuty>=integrityValidDuty){
-                        integrityNum++;
-                    }
-                }
-            }
-
-            intonation = new BigDecimal(intonationNum).divide(new BigDecimal(totalCompareNum), CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN).multiply(oneHundred).setScale(0, BigDecimal.ROUND_HALF_UP);
-            cadence = new BigDecimal(cadenceNum).divide(new BigDecimal(totalCompareNum), CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN).multiply(oneHundred).setScale(0, BigDecimal.ROUND_HALF_UP);
-            integrity = new BigDecimal(integrityNum).divide(new BigDecimal(totalCompareNum), CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN).multiply(oneHundred).setScale(0, BigDecimal.ROUND_HALF_UP);
-        } catch (ArithmeticException e){
-            LOGGER.info("无musicXml信息");
-        }
-
-        if(userSoundInfoMap.get(phone).getUserScoreMap().containsKey("intonation")){
-            userSoundInfoMap.get(phone).getUserScoreMap().put("intonation", intonation.add(userSoundInfoMap.get(phone).getUserScoreMap().get("intonation")));
-        }else{
-            userSoundInfoMap.get(phone).getUserScoreMap().put("intonation", intonation);
-        }
-
-        if(userSoundInfoMap.get(phone).getUserScoreMap().containsKey("cadence")){
-            userSoundInfoMap.get(phone).getUserScoreMap().put("cadence", cadence.add(userSoundInfoMap.get(phone).getUserScoreMap().get("cadence")));
-        }else{
-            userSoundInfoMap.get(phone).getUserScoreMap().put("cadence", cadence);
-        }
-
-        if(userSoundInfoMap.get(phone).getUserScoreMap().containsKey("integrity")){
-            userSoundInfoMap.get(phone).getUserScoreMap().put("integrity", integrity.add(userSoundInfoMap.get(phone).getUserScoreMap().get("integrity")));
-        }else{
-            userSoundInfoMap.get(phone).getUserScoreMap().put("integrity", integrity);
-        }
-
-        Map<String, BigDecimal> scoreData = new HashMap<>();
-        scoreData.put("intonation", intonation);
-        scoreData.put("cadence", cadence);
-        scoreData.put("integrity", integrity);
-
-        userSoundInfoMap.get(phone).getUserMeasureScoreMap().put(measureTimeInfo.getMeasureIndex(), scoreData);
-
-        WS_CLIENTS.get(phone).sendMessage(new TextMessage(JSON.toJSONString(createPushInfo("measureScore", measureTimeInfo.getMeasureIndex(), intonation, cadence, integrity))));
+        //计算分数并推送
+        createPushInfo(phone, "measureScore", measureIndex, intonation, cadence, integrity);
     }
 
     /**
@@ -693,7 +530,8 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
             integrity = userSoundInfoMap.get(phone).getUserScoreMap().get("integrity").divide(new BigDecimal(currentCompareNum), 0, BigDecimal.ROUND_DOWN);
         }
 
-        WS_CLIENTS.get(phone).sendMessage(new TextMessage(JSON.toJSONString(createPushInfo("overall", -1, intonation, cadence, integrity))));
+        //计算分数并推送
+        createPushInfo(phone, "overall", -1, intonation, cadence, integrity);
 
         //存储评分数据
         sysMusicCompareRecordService.saveMusicCompareData(phone, userSoundInfoMap.get(phone).getMusicScoreId(), userSoundInfoMap.get(phone).getUserMeasureScoreMap());
@@ -712,8 +550,8 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
      * @param integrity:
      * @return com.ym.mec.biz.dal.dto.WebSocketInfo
      */
-    private WebSocketInfo createPushInfo(String command, Integer measureIndex,
-                                         BigDecimal intonation, BigDecimal cadence, BigDecimal integrity){
+    private WebSocketInfo createPushInfo(String phone, String command, Integer measureIndex,
+                                         BigDecimal intonation, BigDecimal cadence, BigDecimal integrity) throws IOException {
         WebSocketInfo webSocketInfo = new WebSocketInfo();
         HashMap<String, String> header = new HashMap<>();
         header.put("commond", command);
@@ -728,7 +566,13 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
         result.put("integrity", integrity);
         result.put("measureIndex", measureIndex);
         webSocketInfo.setBody(result);
+
+        userSoundInfoMap.get(phone).getUserMeasureScoreMap().put(measureIndex, result);
+
         LOGGER.info("小节频分:{}", JSON.toJSONString(webSocketInfo));
+
+        //推送结果
+        WS_CLIENTS.get(phone).sendMessage(new TextMessage(JSON.toJSONString(webSocketInfo)));
         return webSocketInfo;
     }
 }

+ 1 - 1
mec-biz/src/main/java/com/ym/mec/biz/service/SysMusicCompareRecordService.java

@@ -16,6 +16,6 @@ public interface SysMusicCompareRecordService extends BaseService<Long, SysMusic
      * @param userMeasureScoreMap:
      * @return void
      */
-    void saveMusicCompareData(String phone, Integer sysMusicScoreId, Map<Integer, Map<String, BigDecimal>> userMeasureScoreMap);
+    void saveMusicCompareData(String phone, Integer sysMusicScoreId, Map<Integer, Map<String, Object>> userMeasureScoreMap);
 
 }

+ 1 - 1
mec-biz/src/main/java/com/ym/mec/biz/service/impl/SysMusicCompareRecordServiceImpl.java

@@ -29,7 +29,7 @@ public class SysMusicCompareRecordServiceImpl extends BaseServiceImpl<Long, SysM
 	}
 
 	@Override
-	public void saveMusicCompareData(String phone, Integer sysMusicScoreId, Map<Integer, Map<String, BigDecimal>> userMeasureScoreMap) {
+	public void saveMusicCompareData(String phone, Integer sysMusicScoreId, Map<Integer, Map<String, Object>> userMeasureScoreMap) {
 		SysUser user = teacherDao.getUserWithPhone(phone);
 		if(Objects.isNull(user)){
 			return;