|
@@ -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信息");
|