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

feat:小节评分

Joburgess 4 éve
szülő
commit
14185c6e10

+ 10 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/MusicPitchDetailDto.java

@@ -20,6 +20,8 @@ public class MusicPitchDetailDto {
     @ApiModelProperty("频率Hz")
     private float frequency;
 
+    private float avgFrequency;
+
     @ApiModelProperty("小节数")
     private int measureIndex;
 
@@ -29,6 +31,14 @@ public class MusicPitchDetailDto {
     @ApiModelProperty("不需要评分")
     private Boolean dontEvaluating;
 
+    public float getAvgFrequency() {
+        return avgFrequency;
+    }
+
+    public void setAvgFrequency(float avgFrequency) {
+        this.avgFrequency = avgFrequency;
+    }
+
     public Boolean getDontEvaluating() {
         return dontEvaluating;
     }

+ 41 - 46
mec-biz/src/main/java/com/ym/mec/biz/handler/WebSocketHandler.java

@@ -167,12 +167,12 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
             float pitch = pitchDetectionResult.getPitch();
             double cents = 0;
             if (pitch > 0) {
-                cents = PitchConverter.hertzToRelativeCent(pitch);
+                cents = PitchConverter.hertzToAbsoluteCent(pitch);
             }
             LOGGER.info("时间:{}, 频率:{}, 分贝:{}, 音分:{}", timeStamp, pitch, silenceDetecor.currentSPL(), cents);
-            if (silenceDetecor.currentSPL() <= -50){
-                pitch = -1;
-            }
+//            if (silenceDetecor.currentSPL() <= -60){
+//                pitch = -1;
+//            }
             recordInfo.add(new MusicPitchDetailDto(timeStamp, pitch));
         }));
         dispatcher.run();
@@ -288,28 +288,19 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
             //最低有效频率
             float minValidFrequency = 20;
 
-            //音准匹配数量
-            float intonationNum = 0;
-            //音准匹配误差范围
-            float intonationErrRange = 15;
-            //音准有效阈值
-            float intonationValidDuty = 0.01f;
+            //音准分数
+            float intonationScore = 0;
 
             //节奏匹配数量
             float cadenceNum = 0;
-            //节奏匹配误差范围
-            float cadenceErrRange = 30;
             //节奏有效阈值
             float cadenceValidDuty = 0.01f;
 
-            //完整性数量
-            float integrityNum = 0;
             //完整性误差范围
             float integrityRange = 30;
-            //完整性有效阈值
-            float integrityValidDuty = 0.5f;
+            //完整性分数
+            float integrityScore = 0;
 
-            float td = 0;
 
             int totalCompareNum = userSoundInfoMap.get(phone).getMeasureXmlInfoMap().get(measureIndex).size();
 
@@ -320,8 +311,6 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
                 int startTimeStamp = musicXmlInfo.getTimeStamp() + userSoundInfoMap.get(phone).getOffsetTime() - ot5;
                 int endTimeStamp = musicXmlInfo.getTimeStamp()  + userSoundInfoMap.get(phone).getOffsetTime() + musicXmlInfo.getDuration() + ot5;
 
-                //时间范围内有效音准数量
-                float recordValidIntonationNum = 0;
                 //时间范围内有效节奏数量
                 float cadenceValidNum = 0;
                 //时间范围内有效音频数量
@@ -359,7 +348,7 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
                     }
                 }
 
-                List<Integer> musicalNotesPitchs = new ArrayList<>();
+                List<Float> musicalNotesPitchs = new ArrayList<>();
 
                 for (int j = 0; j < userSoundInfoMap.get(phone).getRecordMeasurePithInfo().size(); j++) {
                     MusicPitchDetailDto recordInfo = userSoundInfoMap.get(phone).getRecordMeasurePithInfo().get(j);
@@ -367,7 +356,7 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
                     if(recordInfo.getTimeStamp()<startTimeStamp||recordInfo.getTimeStamp()>endTimeStamp){
                         continue;
                     }
-                    musicalNotesPitchs.add((int) recordInfo.getFrequency());
+                    musicalNotesPitchs.add(recordInfo.getFrequency());
                     compareNum++;
                     if(!newMeasure){
                         continue;
@@ -385,10 +374,6 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
                     if(Math.abs(recordInfo.getFrequency()-musicXmlInfo.getFrequency())<=integrityRange){
                         integrityValidNum++;
                     }
-                    //如果频率差值在音准误差范围内
-                    if(Math.abs(recordInfo.getFrequency()-musicXmlInfo.getFrequency())<=intonationErrRange){
-                        recordValidIntonationNum++;
-                    }
                 }
 
                 //非正常频率次数
@@ -397,12 +382,12 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
                 if(CollectionUtils.isEmpty(musicalNotesPitchs)){
                     userSoundInfoMap.get(phone).getMusicalNotePitchMap().put(musicXmlInfo.getMusicalNotesIndex(), (float) 0);
                 }else{
-                    Map<Integer, Long> collect = musicalNotesPitchs.stream().collect(Collectors.groupingBy(Integer::intValue, Collectors.counting()));
+                    Map<Integer, Long> collect = musicalNotesPitchs.stream().map(pitch -> pitch.intValue()).collect(Collectors.groupingBy(Integer::intValue, Collectors.counting()));
                     //出现次数最多的频率
                     Integer pitch = collect.entrySet().stream().max(Comparator.comparing(e -> e.getValue())).get().getKey();
                     boolean ing = false;
                     int dnum = 0;
-                    for (Integer musicalNotesPitch : musicalNotesPitchs) {
+                    for (Float musicalNotesPitch : musicalNotesPitchs) {
                         if (Math.abs(musicalNotesPitch - pitch) <= 10){
                             dnum = 0;
                             ing = true;
@@ -420,17 +405,6 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
                     userSoundInfoMap.get(phone).getMusicalNotePitchMap().put(musicXmlInfo.getMusicalNotesIndex(), (float) pitch);
                 }
 
-                //有效音频占比
-                if(integrityValidNum>0){
-                    integrityValidNum = integrityValidNum + (float) (compareNum * 0.05);
-                }
-                if(integrityValidNum > compareNum){
-                    integrityValidNum = compareNum;
-                }
-                float integrityDuty = integrityValidNum/compareNum;
-                td += integrityDuty;
-                //有效音高占比
-                float intonationDuty = recordValidIntonationNum/compareNum;
                 //有效节奏占比
                 float cadenceDuty = cadenceValidNum/compareNum;
                 //如果错误频率达到一定数值,则当前小节无效
@@ -440,20 +414,41 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
                 //节奏
                 if(cadenceDuty>=cadenceValidDuty){
                     cadenceNum++;
-                    if(intonationDuty>=intonationValidDuty){
-                        intonationNum++;
+                    //音准
+                    if (!CollectionUtils.isEmpty(musicalNotesPitchs)){
+                        Double avgPitch = musicalNotesPitchs.stream().filter(pitch -> Math.abs((pitch-musicXmlInfo.getFrequency()))<5).collect(Collectors.averagingDouble(pitch -> pitch));
+                        //音分
+                        double recordCents = 0;
+                        if (avgPitch > 0){
+                            recordCents = PitchConverter.hertzToAbsoluteCent(avgPitch);
+                        }
+                        double cents = PitchConverter.hertzToAbsoluteCent(musicXmlInfo.getFrequency());
+                        double score = 100 - Math.round(Math.abs(cents - recordCents)) + 10;
+                        if (score < 0){
+                            score = 0;
+                        }else if(score > 100){
+                            score = 100;
+                        }
+                        intonationScore += score;
+                        musicXmlInfo.setAvgFrequency(avgPitch.floatValue());
                     }
-                    if(integrityDuty>=integrityValidDuty){
-                        integrityNum++;
+                    //完成度
+                    if(integrityValidNum>0){
+                        integrityValidNum = integrityValidNum + (float) (compareNum * 0.05);
                     }
+                    if(integrityValidNum > compareNum){
+                        integrityValidNum = compareNum;
+                    }
+                    float integrityDuty = integrityValidNum/compareNum;
+                    integrityScore += integrityDuty;
                 }
             }
 
-            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);
+            BigDecimal measureNum = new BigDecimal(totalCompareNum);
 
-            integrity = new BigDecimal(td).divide(new BigDecimal(totalCompareNum), CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN).multiply(oneHundred).setScale(0, BigDecimal.ROUND_HALF_UP);
+            intonation = new BigDecimal(intonationScore).divide(measureNum, CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN).setScale(0, BigDecimal.ROUND_HALF_UP);
+            cadence = new BigDecimal(cadenceNum).divide(measureNum, CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN).multiply(oneHundred).setScale(0, BigDecimal.ROUND_HALF_UP);
+            integrity = new BigDecimal(integrityScore).divide(measureNum, CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_DOWN).multiply(oneHundred).setScale(0, BigDecimal.ROUND_HALF_UP);
 
         } catch (ArithmeticException e){
             LOGGER.info("无musicXml信息");