浏览代码

Merge branch 'master' of http://git.dayaedu.com/yonge/mec

yonge 4 年之前
父节点
当前提交
5f801372b1

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

@@ -35,6 +35,17 @@ public class SoundCompareHelper {
 
     private Map<Integer, Map<String, BigDecimal>> userMeasureScoreMap = new HashMap<>();
 
+    @ApiModelProperty(value = "偏移时间量,解决客户端录音播放不同步导致的声音留白")
+    private int offsetTime;
+
+    public int getOffsetTime() {
+        return offsetTime;
+    }
+
+    public void setOffsetTime(int offsetTime) {
+        this.offsetTime = offsetTime;
+    }
+
     public Integer getMusicScoreId() {
         return musicScoreId;
     }

+ 40 - 11
mec-biz/src/main/java/com/ym/mec/biz/handler/WebSocketHandler.java

@@ -44,7 +44,11 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
     //存储客户端链接
     public static final Map<String, WebSocketSession> WS_CLIENTS = new ConcurrentHashMap<>();
 
-    private BigDecimal oneHundred = new BigDecimal(100);
+    private final BigDecimal oneHundred = new BigDecimal(100);
+
+    //检测偏移时长的最终时间
+    private final int endCheckOffsetTime = 500;
+
     private final float simpleRate = 44100;
     private int simpleSize = 1024;
 
@@ -53,6 +57,7 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
 
     private static final String tmpDir = FileUtils.getTempDirectoryPath() + "/soundCompare/";
 
+    //用户对应评分信息
     private Map<String, SoundCompareHelper> userSoundInfoMap = new ConcurrentHashMap<>();
 
     @Autowired
@@ -146,25 +151,51 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
         dispatcher.addAudioProcessor(new PitchProcessor(algo, simpleRate, simpleSize, (pitchDetectionResult, audioEvent) -> {
             int timeStamp = (int) (userSoundInfoMap.get(phone).getMeasureStartTime() + audioEvent.getTimeStamp()*1000);
             float pitch = pitchDetectionResult.getPitch();
-            LOGGER.info("频率:{}, {}", timeStamp, pitch);
+//            LOGGER.info("频率:{}, {}", timeStamp, pitch);
             recordInfo.add(new MusicPitchDetailDto(timeStamp, pitch));
         }));
         dispatcher.run();
         if(Objects.isNull(userSoundInfoMap.get(phone).getAccessFile())){
             return;
         }
+
         double recordTime = userSoundInfoMap.get(phone).getAccessFile().length()/(audioFormat.getFrameSize()*audioFormat.getFrameRate())*1000;
+
         userSoundInfoMap.get(phone).setMeasureStartTime(recordTime);
         userSoundInfoMap.get(phone).getRecordMeasurePithInfo().addAll(recordInfo);
+
+        //如果是第一小节,需要计算出录音与播放不同步导致的空白时间偏移量
+        if(userSoundInfoMap.get(phone).getOffsetTime()<=0&&recordTime<endCheckOffsetTime){
+            int hasPitchNum = 0;
+            for (MusicPitchDetailDto ri : userSoundInfoMap.get(phone).getRecordMeasurePithInfo()) {
+                if(hasPitchNum<=0){
+                    userSoundInfoMap.get(phone).setOffsetTime(ri.getTimeStamp());
+                }
+                if(ri.getFrequency()>0){
+                    hasPitchNum++;
+                }else{
+                    hasPitchNum=0;
+                }
+                if(hasPitchNum>=3){
+                    LOGGER.info("偏移时间:{}", userSoundInfoMap.get(phone).getOffsetTime());
+                    break;
+                }
+            }
+            if(hasPitchNum<3){
+                userSoundInfoMap.get(phone).setOffsetTime(0);
+            }
+        }
+
+        if(userSoundInfoMap.get(phone).getOffsetTime()<=0&&recordTime<endCheckOffsetTime){
+            return;
+        }
         for (Map.Entry<Integer, Integer> userMeasureEndTimeMapEntry : userSoundInfoMap.get(phone).getMeasureEndTime().entrySet()) {
-            if(recordTime>userMeasureEndTimeMapEntry.getValue()){
-//                LOGGER.info("评测时间:{}", recordTime);
+            if((recordTime - userSoundInfoMap.get(phone).getOffsetTime())>userMeasureEndTimeMapEntry.getValue()){
                 measureCompare(phone, userMeasureEndTimeMapEntry.getKey());
                 userSoundInfoMap.get(phone).getMeasureEndTime().remove(userMeasureEndTimeMapEntry.getKey());
                 break;
             }
         }
-
     }
 
     @Override
@@ -233,8 +264,6 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
      * @return void
      */
     private void measureCompare(String phone, int measureIndex) throws IOException {
-        //总分
-        BigDecimal score = BigDecimal.ZERO;
         //相似度
         BigDecimal intonation = BigDecimal.ZERO;
         //节奏
@@ -268,8 +297,8 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
             int totalCompareNum = userSoundInfoMap.get(phone).getMeasureXmlInfoMap().get(measureIndex).size();
 
             for (MusicPitchDetailDto musicXmlInfo : userSoundInfoMap.get(phone).getMeasureXmlInfoMap().get(measureIndex)) {
-                int startTimeStamp = musicXmlInfo.getTimeStamp();
-                int endTimeStamp = musicXmlInfo.getTimeStamp()+musicXmlInfo.getDuration();
+                int startTimeStamp = musicXmlInfo.getTimeStamp()-100 + userSoundInfoMap.get(phone).getOffsetTime();
+                int endTimeStamp = musicXmlInfo.getTimeStamp()+musicXmlInfo.getDuration()-100 + userSoundInfoMap.get(phone).getOffsetTime();
 
                 //时间范围内有效音准数量
                 float recordValidIntonationNum = 0;
@@ -280,14 +309,14 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
                 //时间范围内匹配次数
                 float compareNum = 0;
                 for (MusicPitchDetailDto recordInfo : userSoundInfoMap.get(phone).getRecordMeasurePithInfo()) {
-//                    LOGGER.info("频率:{}, {}", musicXmlInfo.getFrequency(), recordInfo.getFrequency());
                     //如果在时间范围之外直接跳过
                     if(recordInfo.getTimeStamp()<startTimeStamp||recordInfo.getTimeStamp()>endTimeStamp){
                         continue;
                     }
+//                    LOGGER.info("{}频率({}-{}):{}, {}", recordInfo.getTimeStamp(), startTimeStamp, endTimeStamp, musicXmlInfo.getFrequency(), recordInfo.getFrequency());
                     compareNum++;
                     //如果在最低有效频率以下则跳过
-                    if(recordInfo.getFrequency()<minValidFrequency){
+                    if(recordInfo.getFrequency()<minValidFrequency&&musicXmlInfo.getFrequency()!=-1){
                         continue;
                     }
                     recordValidNum++;