|
@@ -38,6 +38,8 @@ public class UserChannelContext implements PitchDetectionHandler {
|
|
|
|
|
|
private Long recordId;
|
|
|
|
|
|
+ private Integer subjectId;
|
|
|
+
|
|
|
// 曲目与musicxml对应关系
|
|
|
private ConcurrentHashMap<Integer, MusicXmlBasicInfo> songMusicXmlMap = new ConcurrentHashMap<Integer, MusicXmlBasicInfo>();
|
|
|
|
|
@@ -57,12 +59,12 @@ public class UserChannelContext implements PitchDetectionHandler {
|
|
|
|
|
|
private double receivedTime;
|
|
|
|
|
|
- private List<Integer> firstNoteIndexPerSectionList;
|
|
|
-
|
|
|
private List<ChunkAnalysis> chunkAnalysisList = new ArrayList<ChunkAnalysis>();
|
|
|
|
|
|
+ private ChunkAnalysis lastChunkAnalysis;
|
|
|
+
|
|
|
public void init(){
|
|
|
- firstNoteIndexPerSectionList = getFirstNoteIndexPerSection(null);
|
|
|
+
|
|
|
}
|
|
|
|
|
|
public Long getRecordId() {
|
|
@@ -73,6 +75,10 @@ public class UserChannelContext implements PitchDetectionHandler {
|
|
|
this.recordId = recordId;
|
|
|
}
|
|
|
|
|
|
+ public void setSubjectId(Integer subjectId) {
|
|
|
+ this.subjectId = subjectId;
|
|
|
+ }
|
|
|
+
|
|
|
public ConcurrentHashMap<Integer, MusicXmlBasicInfo> getSongMusicXmlMap() {
|
|
|
return songMusicXmlMap;
|
|
|
}
|
|
@@ -110,8 +116,10 @@ public class UserChannelContext implements PitchDetectionHandler {
|
|
|
doneSectionAnalysisList = new ArrayList<SectionAnalysis>();
|
|
|
chunkAnalysisList = new ArrayList<ChunkAnalysis>();
|
|
|
recordId = null;
|
|
|
+ subjectId = null;
|
|
|
playTime = 0;
|
|
|
receivedTime = 0;
|
|
|
+ lastChunkAnalysis = null;
|
|
|
}
|
|
|
|
|
|
public MusicXmlBasicInfo getMusicXmlBasicInfo(Integer songId){
|
|
@@ -243,7 +251,7 @@ public class UserChannelContext implements PitchDetectionHandler {
|
|
|
double playFrequency = frequencyDetector.getFrequency(samples);
|
|
|
double splDb = Signals.soundPressureLevel(samples);
|
|
|
float power = Signals.power(samples);
|
|
|
- float energy = Signals.energy(samples);
|
|
|
+ float amplitude = Signals.norm(samples);
|
|
|
|
|
|
double durationTime = 1000 * (samples.length * 2) / audioFormat.getSampleRate() / (audioFormat.getSampleSizeInBits() / 8);
|
|
|
|
|
@@ -278,70 +286,39 @@ public class UserChannelContext implements PitchDetectionHandler {
|
|
|
noteAnalysis.setIgnore(true);
|
|
|
}
|
|
|
|
|
|
- if(noteAnalysis.getChunkFrequencyList().size() > 0){
|
|
|
- noteAnalysis.setPlayFrequency(computeFrequency(noteAnalysis.getChunkFrequencyList(), 10));
|
|
|
- }
|
|
|
-
|
|
|
- final double avgFrequency = noteAnalysis.getPlayFrequency();
|
|
|
+ noteAnalysis.setPlayFrequency(computeFrequency(chunkAnalysisList, 10));
|
|
|
|
|
|
//判断节奏(音符持续时间内有不间断的音高,就节奏正确)
|
|
|
- ChunkAnalysis chunkAnalysis = null;
|
|
|
- boolean tempo = false;
|
|
|
- boolean isContinue = true;
|
|
|
- for (int i = 0; i < chunkAnalysisList.size(); i++) {
|
|
|
- chunkAnalysis = chunkAnalysisList.get(i);
|
|
|
- if (chunkAnalysis != null) {
|
|
|
- if (chunkAnalysis.getFrequency() > 100) {
|
|
|
- tempo = true;
|
|
|
- if (isContinue == false) {
|
|
|
- tempo = false;
|
|
|
- break;
|
|
|
- }
|
|
|
+ boolean tempo = true;
|
|
|
+ if (musicXmlNote.getFrequency() == -1) {// 休止符
|
|
|
+ tempo = chunkAnalysisList.stream().filter(t -> t.getAmplitude() > 5).count() == 0;
|
|
|
+ } else {
|
|
|
+ if (subjectId == 23) {
|
|
|
+ if (lastChunkAnalysis == null) {
|
|
|
+ tempo = computeTempoWithAmplitude(chunkAnalysisList, 0);
|
|
|
} else {
|
|
|
- if (tempo == true) {
|
|
|
- isContinue = false;
|
|
|
- }
|
|
|
+ tempo = computeTempoWithAmplitude(chunkAnalysisList, lastChunkAnalysis.getAmplitude());
|
|
|
}
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (tempo) {
|
|
|
- // 获取上一个音符信息
|
|
|
- if (doneNoteAnalysisList.size() > 0) {
|
|
|
- NoteAnalysis lastNoteAnalysis = doneNoteAnalysisList.get(doneNoteAnalysisList.size() - 1);
|
|
|
- if (lastNoteAnalysis != null) {
|
|
|
- double pf = lastNoteAnalysis.getPlayFrequency();
|
|
|
- int continueSize = 0;
|
|
|
- for (int i = 0; i < chunkAnalysisList.size(); i++) {
|
|
|
- chunkAnalysis = chunkAnalysisList.get(i);
|
|
|
- if (chunkAnalysis != null) {
|
|
|
- if (Math.abs(chunkAnalysis.getFrequency() - pf) > 10) {
|
|
|
- break;
|
|
|
- }
|
|
|
- continueSize++;
|
|
|
- }
|
|
|
- }
|
|
|
- if(continueSize * 100 / chunkAnalysisList.size() > 40){
|
|
|
- tempo = false;
|
|
|
- }
|
|
|
+ } else {
|
|
|
+ NoteAnalysis lastNoteAnalysis = null;
|
|
|
+ if (doneNoteAnalysisList.size() > 0) {
|
|
|
+ lastNoteAnalysis = doneNoteAnalysisList.get(doneNoteAnalysisList.size() - 1);
|
|
|
}
|
|
|
+ tempo = computeTempoWithFrequency(chunkAnalysisList, lastNoteAnalysis);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
noteAnalysis.setTempo(tempo);
|
|
|
|
|
|
- /*long wrongChunkSize = chunkAnalysisList.stream().filter(t -> Math.abs(t.getFrequency() - avgFrequency) > 10).count();
|
|
|
- if(wrongChunkSize * 100 /chunkAnalysisList.size() > 40){
|
|
|
- noteAnalysis.setTempo(false);
|
|
|
- }
|
|
|
- */
|
|
|
evaluateForNote(noteAnalysis);
|
|
|
|
|
|
- LOGGER.info("当前音符下标[{}] 预计频率:{} 实际频率:{} 持续时间:{}", noteAnalysis.getMusicalNotesIndex(), musicXmlNote.getFrequency(), noteAnalysis.getPlayFrequency(),
|
|
|
- noteAnalysis.getDurationTime() - durationTime);
|
|
|
+ LOGGER.info("当前音符下标[{}] 预计频率:{} 实际频率:{} 节奏:{}", noteAnalysis.getMusicalNotesIndex(), musicXmlNote.getFrequency(), noteAnalysis.getPlayFrequency(),
|
|
|
+ noteAnalysis.isTempo());
|
|
|
|
|
|
doneNoteAnalysisList.add(noteAnalysis);
|
|
|
|
|
|
+ lastChunkAnalysis = chunkAnalysisList.get(chunkAnalysisList.size() - 1);
|
|
|
+
|
|
|
chunkAnalysisList.clear();
|
|
|
|
|
|
// 准备处理下一个音符
|
|
@@ -355,10 +332,6 @@ public class UserChannelContext implements PitchDetectionHandler {
|
|
|
}
|
|
|
|
|
|
NoteAnalysis nextNoteAnalysis = new NoteAnalysis(nextNoteIndex, getMusicSectionIndex(null, nextNoteIndex), nextNoteFrequence, standDuration);
|
|
|
- /*if (noteAnalysis.isTempo() == true && wrongChunkSize == 0) {
|
|
|
- nextNoteAnalysis.setTempo(false);
|
|
|
- LOGGER.info("节奏错误:频率没变");
|
|
|
- }*/
|
|
|
|
|
|
noteAnalysis = nextNoteAnalysis;
|
|
|
|
|
@@ -371,20 +344,13 @@ public class UserChannelContext implements PitchDetectionHandler {
|
|
|
}*/
|
|
|
//skip = noteAnalysis.getStandardDurationTime() * 0.2;
|
|
|
|
|
|
- LOGGER.info("Frequency:{} splDb:{} Power:{} energy:{}", playFrequency, splDb, power, energy);
|
|
|
+ LOGGER.info("Frequency:{} splDb:{} Power:{} amplitude:{}", playFrequency, splDb, power, amplitude);
|
|
|
|
|
|
- /*int chunkSize = noteAnalysis.getChunkFrequencyList().size();
|
|
|
- if (chunkSize > 0 && Math.abs(noteAnalysis.getChunkFrequencyList().stream().mapToDouble(t -> t).sum() / chunkSize - playFrequency) > 10) {
|
|
|
- noteAnalysis.setTempo(false);
|
|
|
- LOGGER.info("节奏错误:频率发生变化");
|
|
|
- }*/
|
|
|
-
|
|
|
if (playFrequency < 2000 && playFrequency > 100) {
|
|
|
- noteAnalysis.getChunkFrequencyList().add(playFrequency);
|
|
|
noteAnalysis.setPlayDurationTime(noteAnalysis.getPlayDurationTime() + durationTime);
|
|
|
}
|
|
|
|
|
|
- chunkAnalysisList.add(new ChunkAnalysis(receivedTime - durationTime, receivedTime, playFrequency, splDb, power));
|
|
|
+ chunkAnalysisList.add(new ChunkAnalysis(receivedTime - durationTime, receivedTime, playFrequency, splDb, power, amplitude));
|
|
|
|
|
|
}
|
|
|
|
|
@@ -403,6 +369,8 @@ public class UserChannelContext implements PitchDetectionHandler {
|
|
|
|
|
|
float power = Signals.power(samples);
|
|
|
|
|
|
+ float energy = Signals.energy(samples);
|
|
|
+
|
|
|
LOGGER.info("Frequency:{} SplDb:{} Power:{}", frequency, splDb, power);
|
|
|
|
|
|
double durationTime = 1000 * (samples.length * 2) / audioFormat.getSampleRate() / (audioFormat.getSampleSizeInBits() / 8);
|
|
@@ -433,7 +401,7 @@ public class UserChannelContext implements PitchDetectionHandler {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- chunkAnalysisList.add(new ChunkAnalysis(startTime, startTime + durationTime, frequency, splDb, power));
|
|
|
+ chunkAnalysisList.add(new ChunkAnalysis(startTime, startTime + durationTime, frequency, splDb, power, energy));
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -462,14 +430,14 @@ public class UserChannelContext implements PitchDetectionHandler {
|
|
|
noteAnalysis.setDurationTime(noteDurationTime);
|
|
|
|
|
|
if(pitch != -1){
|
|
|
- noteAnalysis.getChunkFrequencyList().add((double) pitch);
|
|
|
+ //noteAnalysis.getChunkFrequencyList().add((double) pitch);
|
|
|
}
|
|
|
|
|
|
setProcessingNote(noteAnalysis);
|
|
|
|
|
|
if(noteAnalysis.getMusicalNotesIndex() <= getTotalMusicNoteIndex(null) && noteDurationTime >= musicXmlNote.getDuration()){
|
|
|
|
|
|
- noteAnalysis.setPlayFrequency(noteAnalysis.getChunkFrequencyList().stream().mapToDouble(t -> t).sum()/noteAnalysis.getChunkFrequencyList().size());
|
|
|
+ //noteAnalysis.setPlayFrequency(noteAnalysis.getChunkFrequencyList().stream().mapToDouble(t -> t).sum()/noteAnalysis.getChunkFrequencyList().size());
|
|
|
|
|
|
LOGGER.info("当前音符下标[{}] 预计频率:{} 实际频率:{} 持续时间:{}", noteAnalysis.getMusicalNotesIndex() , musicXmlNote.getFrequency(), noteAnalysis.getPlayFrequency(), noteAnalysis.getDurationTime());
|
|
|
|
|
@@ -518,10 +486,13 @@ public class UserChannelContext implements PitchDetectionHandler {
|
|
|
|
|
|
//取出当前小节的所有音符
|
|
|
List<NoteAnalysis> noteAnalysisList = doneNoteAnalysisList.stream().filter(t -> t.getSectionIndex() == sectionIndex).collect(Collectors.toList());
|
|
|
+
|
|
|
+ long ignoreSize = doneNoteAnalysisList.stream().filter(t -> t.isIgnore()).count();
|
|
|
|
|
|
SectionAnalysis sectionAnalysis = new SectionAnalysis();
|
|
|
sectionAnalysis.setIndex(sectionIndex);
|
|
|
sectionAnalysis.setNoteNum(noteAnalysisList.size());
|
|
|
+ sectionAnalysis.setIsIngore(ignoreSize == noteAnalysisList.size());
|
|
|
|
|
|
//判断是否需要评分
|
|
|
MusicXmlSection musicXmlSection = getCurrentMusicSection(null, sectionIndex);
|
|
@@ -585,16 +556,38 @@ public class UserChannelContext implements PitchDetectionHandler {
|
|
|
|
|
|
public void evaluateForNote(NoteAnalysis noteAnalysis){
|
|
|
|
|
|
- if (noteAnalysis.getPlayDurationTime() / noteAnalysis.getDurationTime() < 0.1) {
|
|
|
- noteAnalysis.setMusicalErrorType(NoteErrorType.NOT_PLAY);
|
|
|
- } else if (noteAnalysis.getPlayDurationTime() / noteAnalysis.getDurationTime() < 0.5) {
|
|
|
- noteAnalysis.setMusicalErrorType(NoteErrorType.INTEGRITY_WRONG);
|
|
|
- } else if (!noteAnalysis.isTempo()) {
|
|
|
- noteAnalysis.setMusicalErrorType(NoteErrorType.CADENCE_WRONG);
|
|
|
- } else if (Math.abs(noteAnalysis.getFrequency() - noteAnalysis.getPlayFrequency()) > 10) {
|
|
|
- noteAnalysis.setMusicalErrorType(NoteErrorType.INTONATION_WRONG);
|
|
|
+ if (noteAnalysis.getFrequency() == -1) {// 休止符
|
|
|
+ if (1 - noteAnalysis.getPlayDurationTime() / noteAnalysis.getDurationTime() < 0.1) {
|
|
|
+ noteAnalysis.setMusicalErrorType(NoteErrorType.NOT_PLAY);
|
|
|
+ } else if (1 - noteAnalysis.getPlayDurationTime() / noteAnalysis.getDurationTime() < 0.6) {
|
|
|
+ noteAnalysis.setMusicalErrorType(NoteErrorType.INTEGRITY_WRONG);
|
|
|
+ } else if (!noteAnalysis.isTempo()) {
|
|
|
+ noteAnalysis.setMusicalErrorType(NoteErrorType.CADENCE_WRONG);
|
|
|
+ } else if (Math.abs(noteAnalysis.getFrequency() - noteAnalysis.getPlayFrequency()) > 10) {
|
|
|
+ noteAnalysis.setMusicalErrorType(NoteErrorType.INTONATION_WRONG);
|
|
|
+ } else {
|
|
|
+ noteAnalysis.setMusicalErrorType(NoteErrorType.RIGHT);
|
|
|
+ }
|
|
|
} else {
|
|
|
- noteAnalysis.setMusicalErrorType(NoteErrorType.RIGHT);
|
|
|
+ if (subjectId == 23) {
|
|
|
+ if (!noteAnalysis.isTempo()) {
|
|
|
+ noteAnalysis.setMusicalErrorType(NoteErrorType.CADENCE_WRONG);
|
|
|
+ } else {
|
|
|
+ noteAnalysis.setMusicalErrorType(NoteErrorType.RIGHT);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (noteAnalysis.getPlayDurationTime() / noteAnalysis.getDurationTime() < 0.1) {
|
|
|
+ noteAnalysis.setMusicalErrorType(NoteErrorType.NOT_PLAY);
|
|
|
+ } else if (noteAnalysis.getPlayDurationTime() / noteAnalysis.getDurationTime() < 0.6) {
|
|
|
+ noteAnalysis.setMusicalErrorType(NoteErrorType.INTEGRITY_WRONG);
|
|
|
+ } else if (!noteAnalysis.isTempo()) {
|
|
|
+ noteAnalysis.setMusicalErrorType(NoteErrorType.CADENCE_WRONG);
|
|
|
+ } else if (Math.abs(noteAnalysis.getFrequency() - noteAnalysis.getPlayFrequency()) > 10) {
|
|
|
+ noteAnalysis.setMusicalErrorType(NoteErrorType.INTONATION_WRONG);
|
|
|
+ } else {
|
|
|
+ noteAnalysis.setMusicalErrorType(NoteErrorType.RIGHT);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
//计算音分
|
|
@@ -625,14 +618,25 @@ public class UserChannelContext implements PitchDetectionHandler {
|
|
|
noteAnalysis.setIntegrityScore(integrityScore);
|
|
|
}
|
|
|
noteAnalysis.setIntonationScore(intonationScore);
|
|
|
- noteAnalysis.setScore((int)((intonationScore + tempoScore + integrityScore) / 3));
|
|
|
+ if (subjectId == 23) {
|
|
|
+ noteAnalysis.setScore((int)tempoScore);
|
|
|
+ }else{
|
|
|
+ noteAnalysis.setScore((int)((intonationScore + tempoScore + integrityScore) / 3));
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- private double computeFrequency(List<Double> chunkFrequencyList, int offsetRange) {
|
|
|
+ private double computeFrequency(List<ChunkAnalysis> chunkAnalysisList, int offsetRange) {
|
|
|
|
|
|
+ List<Double> chunkFrequencyList = chunkAnalysisList.stream().map(t -> t.getFrequency()).filter(t -> t.doubleValue() > 100 && t.doubleValue() < 2000)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ if (chunkFrequencyList.size() == 0) {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
// 排序
|
|
|
chunkFrequencyList = chunkFrequencyList.stream().sorted().collect(Collectors.toList());
|
|
|
-
|
|
|
+
|
|
|
double tempFrequency = chunkFrequencyList.get(0), totalFrequency = chunkFrequencyList.get(0);
|
|
|
|
|
|
int maxChunkSize = 0;
|
|
@@ -643,7 +647,7 @@ public class UserChannelContext implements PitchDetectionHandler {
|
|
|
tempFrequency = chunkFrequencyList.get(i);
|
|
|
|
|
|
if (Math.abs(avgFrequency - tempFrequency) > offsetRange) {
|
|
|
-
|
|
|
+
|
|
|
avgFrequency = totalFrequency / chunkSize;
|
|
|
|
|
|
if (maxChunkSize < chunkSize) {
|
|
@@ -658,8 +662,8 @@ public class UserChannelContext implements PitchDetectionHandler {
|
|
|
chunkSize++;
|
|
|
totalFrequency += tempFrequency;
|
|
|
}
|
|
|
-
|
|
|
- if(i == chunkFrequencyList.size() - 1){
|
|
|
+
|
|
|
+ if (i == chunkFrequencyList.size() - 1) {
|
|
|
if (maxChunkSize <= chunkSize) {
|
|
|
maxChunkSize = chunkSize;
|
|
|
frequency = avgFrequency;
|
|
@@ -667,30 +671,152 @@ public class UserChannelContext implements PitchDetectionHandler {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (maxChunkSize * 100 / chunkFrequencyList.size() < 40) {
|
|
|
- return chunkFrequencyList.stream().collect(Collectors.summingDouble(t -> t)) / chunkFrequencyList.size();
|
|
|
+ if (chunkFrequencyList.size() < 3 || maxChunkSize * 100 / chunkFrequencyList.size() < 40) {
|
|
|
+ frequency = chunkFrequencyList.stream().collect(Collectors.summingDouble(t -> t)) / chunkFrequencyList.size();
|
|
|
+ }
|
|
|
+
|
|
|
+ if(frequency < 100){
|
|
|
+ frequency = -1;
|
|
|
}
|
|
|
|
|
|
return frequency;
|
|
|
}
|
|
|
+
|
|
|
+ private boolean computeTempoWithFrequency(List<ChunkAnalysis> chunkAnalysisList, NoteAnalysis lastNoteAnalysis){
|
|
|
+ ChunkAnalysis chunkAnalysis = null;
|
|
|
+ boolean tempo = false;
|
|
|
+ boolean isContinue = true;
|
|
|
+ boolean lastestNotePlayStatus = true;
|
|
|
+ int unplayedSize = 0;
|
|
|
+ for (int i = 0; i < chunkAnalysisList.size(); i++) {
|
|
|
+ chunkAnalysis = chunkAnalysisList.get(i);
|
|
|
+ if (chunkAnalysis != null) {
|
|
|
+ if (chunkAnalysis.getFrequency() > 100) {
|
|
|
+ tempo = true;
|
|
|
+ if (isContinue == false) {
|
|
|
+ if (chunkAnalysisList.size() < 5) {
|
|
|
+ if (unplayedSize > 0) {
|
|
|
+ tempo = false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if ((unplayedSize * 100 / chunkAnalysisList.size()) > 10 || unplayedSize > 1) {
|
|
|
+ tempo = false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (tempo == true) {
|
|
|
+ isContinue = false;
|
|
|
+ unplayedSize++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(i == chunkAnalysisList.size() - 1){
|
|
|
+ lastestNotePlayStatus = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (tempo && lastestNotePlayStatus) {
|
|
|
+ // 获取上一个音符信息
|
|
|
+ if (lastNoteAnalysis != null) {
|
|
|
+ double pf = lastNoteAnalysis.getPlayFrequency();
|
|
|
+ int continueSize = 0;
|
|
|
+ for (int i = 0; i < chunkAnalysisList.size(); i++) {
|
|
|
+ chunkAnalysis = chunkAnalysisList.get(i);
|
|
|
+ if (chunkAnalysis != null) {
|
|
|
+ if (Math.abs(chunkAnalysis.getFrequency() - pf) > 10) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ continueSize++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(continueSize * 100 / chunkAnalysisList.size() > 40){
|
|
|
+ tempo = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return tempo;
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean computeTempoWithAmplitude(List<ChunkAnalysis> chunkAnalysisList, float lastChunkAmplitude) {
|
|
|
+
|
|
|
+ boolean tempo = false;
|
|
|
+
|
|
|
+ List<Float> chunkAmplitudeList = chunkAnalysisList.stream().map(ChunkAnalysis::getAmplitude).collect(Collectors.toList());
|
|
|
+
|
|
|
+ if (chunkAmplitudeList.size() < 3) {
|
|
|
+ return chunkAmplitudeList.stream().filter(t -> t.floatValue() > 5).count() > 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检测是否有多个波峰
|
|
|
+ int peakSize = 0;
|
|
|
+ int minPeakIndex = chunkAmplitudeList.size() - 1;
|
|
|
+ for (int i = 0; i < chunkAmplitudeList.size() - 1; i++) {
|
|
|
+ if (chunkAmplitudeList.get(i) < 5) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (i == 0) {
|
|
|
+ if (lastChunkAmplitude > 0 && chunkAmplitudeList.get(i) > lastChunkAmplitude) {
|
|
|
+ peakSize++;
|
|
|
+ minPeakIndex = i;
|
|
|
+ }
|
|
|
+ } else if (chunkAmplitudeList.get(i - 1) < chunkAmplitudeList.get(i) && chunkAmplitudeList.get(i) >= chunkAmplitudeList.get(i + 1)) {
|
|
|
+ peakSize++;
|
|
|
+ if (minPeakIndex > i) {
|
|
|
+ minPeakIndex = i;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (i == chunkAmplitudeList.size() - 2) {
|
|
|
+ if (chunkAmplitudeList.get(i) < chunkAmplitudeList.get(i + 1)) {
|
|
|
+ peakSize++;
|
|
|
+ if (minPeakIndex > i) {
|
|
|
+ minPeakIndex = i;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ tempo = peakSize == 1;
|
|
|
+
|
|
|
+ // 检测是否延迟进入
|
|
|
+ if (tempo == true) {
|
|
|
+ if ((minPeakIndex + 1) * 100 / chunkAmplitudeList.size() > 40 && chunkAmplitudeList.size() > 3) {
|
|
|
+ tempo = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return tempo;
|
|
|
+ }
|
|
|
|
|
|
- private double majorityElement(List<Double> nums) {
|
|
|
- double major = nums.get(0);
|
|
|
- int count = 1;
|
|
|
-
|
|
|
- for(int i = 1; i < nums.size(); i++) {
|
|
|
- double num = nums.get(i);
|
|
|
- if(count == 0) {
|
|
|
- count++;
|
|
|
- major = num;
|
|
|
- } else if(major == num) {
|
|
|
- count++;
|
|
|
- } else {
|
|
|
- count--;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return major;
|
|
|
+ private boolean getPeak(List<Float> chunkList, float last){
|
|
|
+
|
|
|
+ if(chunkList.size()<3){
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ int peakSize = 0;
|
|
|
+ for(int i = 0;i<chunkList.size() - 1;i++){
|
|
|
+ if(i == 0){
|
|
|
+ if(chunkList.get(i) > last){
|
|
|
+ peakSize++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if(chunkList.get(i-1) < chunkList.get(i) && chunkList.get(i) >= chunkList.get(i + 1)){
|
|
|
+ peakSize++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(i == chunkList.size() - 2){
|
|
|
+ if(chunkList.get(i) < chunkList.get(i + 1)){
|
|
|
+ peakSize++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return peakSize == 1;
|
|
|
}
|
|
|
|
|
|
}
|