|
@@ -32,7 +32,7 @@ public class UserChannelContext {
|
|
|
|
|
|
private final static Logger LOGGER = LoggerFactory.getLogger(UserChannelContext.class);
|
|
|
|
|
|
- private int offsetMS = 0;
|
|
|
+ private int offsetMS = 300;
|
|
|
|
|
|
private Long recordId;
|
|
|
|
|
@@ -42,8 +42,6 @@ public class UserChannelContext {
|
|
|
|
|
|
private int beatByteLength;
|
|
|
|
|
|
- private boolean handleSwitch;
|
|
|
-
|
|
|
// 曲目与musicxml对应关系
|
|
|
private ConcurrentHashMap<Integer, MusicXmlBasicInfo> songMusicXmlMap = new ConcurrentHashMap<Integer, MusicXmlBasicInfo>();
|
|
|
|
|
@@ -149,7 +147,6 @@ public class UserChannelContext {
|
|
|
receivedTime = 0;
|
|
|
offsetMS = 0;
|
|
|
lastChunkAnalysisList = new ArrayList<ChunkAnalysis>();
|
|
|
- handleSwitch = false;
|
|
|
}
|
|
|
|
|
|
public MusicXmlBasicInfo getMusicXmlBasicInfo(Integer songId){
|
|
@@ -270,14 +267,6 @@ public class UserChannelContext {
|
|
|
|
|
|
double durationTime = 1000 * (samples.length * 2) / audioFormat.getSampleRate() / (audioFormat.getSampleSizeInBits() / 8);
|
|
|
|
|
|
- if(handleSwitch == false && rms > 0.01){
|
|
|
- handleSwitch = true;
|
|
|
- }
|
|
|
-
|
|
|
- if(handleSwitch == false){
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
receivedTime += durationTime;
|
|
|
|
|
|
if(receivedTime <= offsetMS){
|
|
@@ -308,7 +297,8 @@ public class UserChannelContext {
|
|
|
LOGGER.info("------ Frequency:{} splDb:{} Power:{} amplitude:{} time:{}------", playFrequency, splDb, power, amplitude, playTime);
|
|
|
|
|
|
ChunkAnalysis lastChunkAnalysis = new ChunkAnalysis(playTime - durationTime, playTime, playFrequency, splDb, power, amplitude);
|
|
|
- if(Math.abs(chunkAnalysisList.get(chunkAnalysisList.size() - 1).getFrequency() - lastChunkAnalysis.getFrequency()) > hardLevel.getFrequencyOffset()){
|
|
|
+
|
|
|
+ if(Math.abs(chunkAnalysisList.get(chunkAnalysisList.size() - 1).getFrequency() - lastChunkAnalysis.getFrequency()) > hardLevel.getFrequencyThreshold()){
|
|
|
lastChunkAnalysis.setFrequency(-1);
|
|
|
}
|
|
|
if(chunkAnalysisList.get(chunkAnalysisList.size() - 1).getAmplitude() + 2 < lastChunkAnalysis.getAmplitude()){
|
|
@@ -331,21 +321,21 @@ public class UserChannelContext {
|
|
|
|
|
|
}
|
|
|
|
|
|
- noteAnalysis.setPlayFrequency(computeFrequency(chunkAnalysisList, lastChunkAnalysis, hardLevel.getFrequencyOffset()));
|
|
|
+ noteAnalysis.setPlayFrequency(computeFrequency(chunkAnalysisList, lastChunkAnalysis, hardLevel.getFrequencyThreshold()));
|
|
|
|
|
|
//判断节奏(音符持续时间内有不间断的音高,就节奏正确)
|
|
|
boolean tempo = true;
|
|
|
- if (subjectId == 23) {
|
|
|
+ if (subjectId == 23 || subjectId == 113) {
|
|
|
if (musicXmlNote.getFrequency() == -1) {// 休止符
|
|
|
tempo = chunkAnalysisList.stream().filter(t -> t.getAmplitude() > hardLevel.getAmplitudeThreshold()).count() <= 0;
|
|
|
}else{
|
|
|
- tempo = computeTempoWithAmplitude2(chunkAnalysisList, lastChunkAnalysis);
|
|
|
+ tempo = computeTempoWithAmplitude2(musicXmlNote, chunkAnalysisList, lastChunkAnalysis);
|
|
|
}
|
|
|
}else{
|
|
|
if (musicXmlNote.getFrequency() == -1) {// 休止符
|
|
|
tempo = chunkAnalysisList.stream().filter(t -> t.getFrequency() > 100).count() <= 1;
|
|
|
}else{
|
|
|
- tempo = computeTempoWithFrequency(chunkAnalysisList, lastChunkAnalysis);
|
|
|
+ tempo = computeTempoWithFrequency(musicXmlNote, chunkAnalysisList, lastChunkAnalysis);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -380,12 +370,6 @@ public class UserChannelContext {
|
|
|
|
|
|
} else {
|
|
|
|
|
|
- /*double skip = 0;
|
|
|
- if (firstNoteIndexPerSectionList.contains(noteAnalysis.getMusicalNotesIndex())) {
|
|
|
- skip = offsetMSOfSection;
|
|
|
- }*/
|
|
|
- //skip = noteAnalysis.getStandardDurationTime() * 0.2;
|
|
|
-
|
|
|
LOGGER.info("Frequency:{} splDb:{} Power:{} amplitude:{} rms:{}", playFrequency, splDb, power, amplitude, rms);
|
|
|
|
|
|
chunkAnalysisList.add(new ChunkAnalysis(playTime - durationTime, playTime, playFrequency, splDb, power, amplitude));
|
|
@@ -468,7 +452,7 @@ public class UserChannelContext {
|
|
|
int score = socre / noteAnalysisList.size();
|
|
|
|
|
|
// 平均得分
|
|
|
- if (getMusicXmlBasicInfo(null).getSubjectId() == 23) {
|
|
|
+ if (getMusicXmlBasicInfo(null).getSubjectId() == 23 || getMusicXmlBasicInfo(null).getSubjectId() == 113) {
|
|
|
score = tempoScore;
|
|
|
}
|
|
|
result.put("score", score);
|
|
@@ -481,7 +465,7 @@ public class UserChannelContext {
|
|
|
|
|
|
double playDurationTime = 0;
|
|
|
|
|
|
- if (subjectId == 23) {
|
|
|
+ if (subjectId == 23 || subjectId == 113) {
|
|
|
if (noteAnalysis.getFrequency() == -1) {// 休止符
|
|
|
if (!noteAnalysis.isTempo()) {
|
|
|
noteAnalysis.setMusicalErrorType(NoteErrorType.CADENCE_WRONG);
|
|
@@ -508,7 +492,7 @@ public class UserChannelContext {
|
|
|
noteAnalysis.setMusicalErrorType(NoteErrorType.CADENCE_WRONG);
|
|
|
} else if (playDurationTime * 100 / noteAnalysis.getDurationTime() < hardLevel.getIntegrityRange()) {
|
|
|
noteAnalysis.setMusicalErrorType(NoteErrorType.INTEGRITY_WRONG);
|
|
|
- } else if (Math.abs(noteAnalysis.getFrequency() - noteAnalysis.getPlayFrequency()) > hardLevel.getFrequencyOffset()) {
|
|
|
+ } else if (Math.abs(noteAnalysis.getFrequency() - noteAnalysis.getPlayFrequency()) > hardLevel.getFrequencyThreshold()) {
|
|
|
noteAnalysis.setMusicalErrorType(NoteErrorType.INTONATION_WRONG);
|
|
|
} else {
|
|
|
noteAnalysis.setMusicalErrorType(NoteErrorType.RIGHT);
|
|
@@ -523,7 +507,7 @@ public class UserChannelContext {
|
|
|
noteAnalysis.setMusicalErrorType(NoteErrorType.INTEGRITY_WRONG);
|
|
|
} else if (!noteAnalysis.isTempo()) {
|
|
|
noteAnalysis.setMusicalErrorType(NoteErrorType.CADENCE_WRONG);
|
|
|
- } else if (Math.abs(noteAnalysis.getFrequency() - noteAnalysis.getPlayFrequency()) > hardLevel.getFrequencyOffset()) {
|
|
|
+ } else if (Math.abs(noteAnalysis.getFrequency() - noteAnalysis.getPlayFrequency()) > hardLevel.getFrequencyThreshold()) {
|
|
|
noteAnalysis.setMusicalErrorType(NoteErrorType.INTONATION_WRONG);
|
|
|
} else {
|
|
|
noteAnalysis.setMusicalErrorType(NoteErrorType.RIGHT);
|
|
@@ -535,7 +519,7 @@ public class UserChannelContext {
|
|
|
int tempoScore = 0;
|
|
|
int integrityScore = 0;
|
|
|
int intonationScore = 100 - new BigDecimal(Math.abs(YINPitchDetector.hertzToAbsoluteCent(noteAnalysis.getPlayFrequency())
|
|
|
- - YINPitchDetector.hertzToAbsoluteCent(noteAnalysis.getFrequency()))).multiply(new BigDecimal(10)).divide(new BigDecimal(17), BigDecimal.ROUND_UP)
|
|
|
+ - YINPitchDetector.hertzToAbsoluteCent(noteAnalysis.getFrequency()))).multiply(new BigDecimal(20)).divide(new BigDecimal(17), BigDecimal.ROUND_UP)
|
|
|
.setScale(0, BigDecimal.ROUND_UP).intValue();
|
|
|
if (intonationScore < 0) {
|
|
|
intonationScore = 0;
|
|
@@ -561,7 +545,7 @@ public class UserChannelContext {
|
|
|
noteAnalysis.setIntegrityScore(integrityScore);
|
|
|
}
|
|
|
noteAnalysis.setIntonationScore(intonationScore);
|
|
|
- if (subjectId == 23) {
|
|
|
+ if (subjectId == 23 || subjectId == 113) {
|
|
|
noteAnalysis.setScore(tempoScore);
|
|
|
} else {
|
|
|
noteAnalysis.setScore(new BigDecimal(intonationScore + tempoScore + integrityScore).divide(new BigDecimal(3), 2).setScale(0, BigDecimal.ROUND_UP)
|
|
@@ -650,7 +634,7 @@ public class UserChannelContext {
|
|
|
return frequency;
|
|
|
}
|
|
|
|
|
|
- private boolean computeTempoWithFrequency(List<ChunkAnalysis> chunkAnalysisList, ChunkAnalysis lastChunkAnalysis){
|
|
|
+ private boolean computeTempoWithFrequency(MusicXmlNote musicXmlNote, List<ChunkAnalysis> chunkAnalysisList, ChunkAnalysis lastChunkAnalysis){
|
|
|
|
|
|
List<ChunkAnalysis> chunkList = new ArrayList<ChunkAnalysis>(chunkAnalysisList);
|
|
|
|
|
@@ -659,7 +643,7 @@ public class UserChannelContext {
|
|
|
double lastFrequency = lastChunkAnalysis.getFrequency();
|
|
|
Iterator<ChunkAnalysis> iterable = chunkList.iterator();
|
|
|
while (iterable.hasNext()) {
|
|
|
- if (Math.abs(lastFrequency - iterable.next().getFrequency()) > hardLevel.getFrequencyOffset()) {
|
|
|
+ if (Math.abs(lastFrequency - iterable.next().getFrequency()) > hardLevel.getFrequencyThreshold()) {
|
|
|
break;
|
|
|
}
|
|
|
iterable.remove();
|
|
@@ -707,7 +691,7 @@ public class UserChannelContext {
|
|
|
|
|
|
if (tempo) {
|
|
|
// 判断进入时间点
|
|
|
- if((chunkAnalysisList.size() - chunkList.size() + firstPeakIndex) * 100 /chunkAnalysisList.size() > hardLevel.getTempoOffsetOfPercent()){
|
|
|
+ if((chunkAnalysisList.size() - chunkList.size() + firstPeakIndex) * 100 /chunkAnalysisList.size() > hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator())){
|
|
|
tempo = false;
|
|
|
}
|
|
|
}
|
|
@@ -715,7 +699,7 @@ public class UserChannelContext {
|
|
|
return tempo;
|
|
|
}
|
|
|
|
|
|
- private boolean computeTempoWithAmplitude2(List<ChunkAnalysis> chunkAnalysisList, ChunkAnalysis lastChunkAnalysis) {
|
|
|
+ private boolean computeTempoWithAmplitude2(MusicXmlNote musicXmlNote, List<ChunkAnalysis> chunkAnalysisList, ChunkAnalysis lastChunkAnalysis) {
|
|
|
|
|
|
List<Integer> chunkAmplitudeList = chunkAnalysisList.stream().map(ChunkAnalysis::getAmplitude).collect(Collectors.toList());
|
|
|
|
|
@@ -759,7 +743,7 @@ public class UserChannelContext {
|
|
|
|
|
|
if (tempo) {
|
|
|
// 判断进入时间点
|
|
|
- if((firstPeakIndex - 1) * 100 /chunkAmplitudeList.size() > hardLevel.getTempoOffsetOfPercent()){
|
|
|
+ if((firstPeakIndex - 1) * 100 /chunkAmplitudeList.size() > hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator())){
|
|
|
tempo = false;
|
|
|
}
|
|
|
}
|
|
@@ -767,7 +751,7 @@ public class UserChannelContext {
|
|
|
return tempo;
|
|
|
}
|
|
|
|
|
|
- private boolean computeTempoWithAmplitude(List<ChunkAnalysis> chunkAnalysisList, ChunkAnalysis lastChunkAnalysis) {
|
|
|
+ private boolean computeTempoWithAmplitude(MusicXmlNote musicXmlNote, List<ChunkAnalysis> chunkAnalysisList, ChunkAnalysis lastChunkAnalysis) {
|
|
|
|
|
|
boolean tempo = false;
|
|
|
|
|
@@ -817,7 +801,7 @@ public class UserChannelContext {
|
|
|
|
|
|
// 检测是否延迟进入
|
|
|
if (tempo == true) {
|
|
|
- if (minPeakIndex * 100 / chunkAmplitudeList.size() > hardLevel.getTempoOffsetOfPercent() && chunkAmplitudeList.size() > 3) {
|
|
|
+ if (minPeakIndex * 100 / chunkAmplitudeList.size() > hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator()) && chunkAmplitudeList.size() > 3) {
|
|
|
tempo = false;
|
|
|
}
|
|
|
}
|
|
@@ -838,8 +822,11 @@ public class UserChannelContext {
|
|
|
chunkAnalysisList.add(new ChunkAnalysis(f, 0, 0));
|
|
|
}
|
|
|
|
|
|
+ MusicXmlNote musicXmlNote = new MusicXmlNote();
|
|
|
+ musicXmlNote.setDenominator(1);
|
|
|
+
|
|
|
//System.out.println(context.computeFrequency(chunkAnalysisList, lastChunkAnalysis, 5));
|
|
|
- System.out.println(context.computeTempoWithFrequency(chunkAnalysisList, lastChunkAnalysis));
|
|
|
+ System.out.println(context.computeTempoWithFrequency(musicXmlNote, chunkAnalysisList, lastChunkAnalysis));
|
|
|
}
|
|
|
|
|
|
}
|