|
@@ -500,177 +500,8 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
|
|
userSoundInfoMap.get(phone).getUserScoreMap().put("integrity", integrity);
|
|
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 +524,8 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
|
|
integrity = userSoundInfoMap.get(phone).getUserScoreMap().get("integrity").divide(new BigDecimal(currentCompareNum), 0, BigDecimal.ROUND_DOWN);
|
|
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());
|
|
sysMusicCompareRecordService.saveMusicCompareData(phone, userSoundInfoMap.get(phone).getMusicScoreId(), userSoundInfoMap.get(phone).getUserMeasureScoreMap());
|
|
@@ -712,8 +544,8 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
|
|
* @param integrity:
|
|
* @param integrity:
|
|
* @return com.ym.mec.biz.dal.dto.WebSocketInfo
|
|
* @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();
|
|
WebSocketInfo webSocketInfo = new WebSocketInfo();
|
|
HashMap<String, String> header = new HashMap<>();
|
|
HashMap<String, String> header = new HashMap<>();
|
|
header.put("commond", command);
|
|
header.put("commond", command);
|
|
@@ -728,7 +560,13 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
|
|
result.put("integrity", integrity);
|
|
result.put("integrity", integrity);
|
|
result.put("measureIndex", measureIndex);
|
|
result.put("measureIndex", measureIndex);
|
|
webSocketInfo.setBody(result);
|
|
webSocketInfo.setBody(result);
|
|
|
|
+
|
|
|
|
+ userSoundInfoMap.get(phone).getUserMeasureScoreMap().put(measureIndex, result);
|
|
|
|
+
|
|
LOGGER.info("小节频分:{}", JSON.toJSONString(webSocketInfo));
|
|
LOGGER.info("小节频分:{}", JSON.toJSONString(webSocketInfo));
|
|
|
|
+
|
|
|
|
+ //推送结果
|
|
|
|
+ WS_CLIENTS.get(phone).sendMessage(new TextMessage(JSON.toJSONString(webSocketInfo)));
|
|
return webSocketInfo;
|
|
return webSocketInfo;
|
|
}
|
|
}
|
|
}
|
|
}
|