12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079 |
- package com.yonge.netty.dto;
- import java.math.BigDecimal;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Comparator;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.Map.Entry;
- import java.util.Optional;
- import java.util.concurrent.ConcurrentHashMap;
- import java.util.concurrent.atomic.AtomicInteger;
- import java.util.stream.Collectors;
- import javax.sound.sampled.AudioFormat;
- import org.apache.commons.lang3.StringUtils;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import be.tarsos.dsp.pitch.FastYin;
- import com.yonge.audio.analysis.Signals;
- import com.yonge.audio.analysis.detector.YINPitchDetector;
- import com.yonge.netty.dto.NoteAnalysis.NoteErrorType;
- import com.yonge.netty.entity.MusicXmlBasicInfo;
- import com.yonge.netty.entity.MusicXmlNote;
- import com.yonge.netty.entity.MusicXmlSection;
- import com.yonge.netty.server.processor.WaveformWriter;
- /**
- * 用户通道上下文
- */
- public class UserChannelContext {
-
- private final static Logger LOGGER = LoggerFactory.getLogger(UserChannelContext.class);
-
- //打击乐
- //private final static List<Integer> percussionList = Arrays.asList(23, 113, 121);
-
- private final static int MIN_FREQUECY = 43;
-
- private final static int MAX_FREQUECY = 2000;
-
- private FastYin detector;
-
- private String user;
-
- private double standardFrequecy = 442;
-
- private float offsetMS;
-
- private float micDelayMS;
-
- private double dynamicOffset;
-
- private String platform;
-
- private Long recordId;
-
- private Integer subjectId;
-
- private String evaluationCriteria;
-
- private float beatDuration;
-
- private boolean delayProcessed;
-
- // 曲目与musicxml对应关系
- private ConcurrentHashMap<Integer, MusicXmlBasicInfo> songMusicXmlMap = new ConcurrentHashMap<Integer, MusicXmlBasicInfo>();
- private WaveformWriter waveFileProcessor;
- private NoteAnalysis processingNote = new NoteAnalysis(0, 0, -1);
-
- private AtomicInteger evaluatingSectionIndex = new AtomicInteger(0);
-
- private List<NoteAnalysis> doneNoteAnalysisList = new ArrayList<NoteAnalysis>();
-
- private List<SectionAnalysis> doneSectionAnalysisList = new ArrayList<SectionAnalysis>();
-
- private List<ChunkAnalysis> totalChunkAnalysisList = new ArrayList<ChunkAnalysis>();
-
- private byte[] channelBufferBytes = new byte[0];
-
- private double playTime;
-
- private HardLevelEnum hardLevel = HardLevelEnum.ADVANCED;
-
- private boolean handlerSwitch;
-
- private NotePlayResult queryNoteFrequency(MusicXmlNote xmlNote, double playFrequency) {
- NotePlayResult result = new NotePlayResult();
- boolean status = false;
- double migrationRate = 0;
- if (Math.round(xmlNote.getFrequency()) == Math.round(playFrequency)) {
- status = true;
- migrationRate = 0;
- } else {
- NoteFrequencyRange noteFrequencyRange = new NoteFrequencyRange(standardFrequecy, xmlNote.getFrequency());
- if (noteFrequencyRange.getMinFrequency() > playFrequency || playFrequency > noteFrequencyRange.getMaxFrequency()) {
- status = false;
- } else {
- status = true;
- if (Math.round(playFrequency) < Math.round(xmlNote.getFrequency())) {
- double min = Math.abs(xmlNote.getFrequency() - noteFrequencyRange.getMinFrequency()) / 2;
- migrationRate = Math.abs(playFrequency - xmlNote.getFrequency()) / min;
- } else {
- double max = Math.abs(xmlNote.getFrequency() - noteFrequencyRange.getMaxFrequency()) / 2;
- migrationRate = Math.abs(playFrequency - xmlNote.getFrequency()) / max;
- }
- }
- }
- result.setStatus(status);
- result.setMigrationRate(migrationRate);
- return result;
- }
-
- public void init(MusicXmlBasicInfo musicXmlBasicInfo, float sampleRate, int bufferSize) {
- this.platform = musicXmlBasicInfo.getPlatform();
- this.subjectId = musicXmlBasicInfo.getSubjectId();
- this.beatDuration = musicXmlBasicInfo.getBeatLength();
- this.hardLevel = HardLevelEnum.valueOf(musicXmlBasicInfo.getHeardLevel());
- this.evaluationCriteria = musicXmlBasicInfo.getEvaluationCriteria();
- if(detector == null){
- detector = new FastYin(sampleRate, bufferSize);
- }
- }
-
- public void setUser(String user) {
- this.user = user;
- }
- public Long getRecordId() {
- return recordId;
- }
- public void setRecordId(Long recordId) {
- this.recordId = recordId;
- }
- public boolean getHandlerSwitch() {
- return handlerSwitch;
- }
- public void setHandlerSwitch(boolean handlerSwitch) {
- this.handlerSwitch = handlerSwitch;
- }
- public float getOffsetMS() {
- return offsetMS;
- }
- public void setOffsetMS(float offsetMS) {
- this.offsetMS = offsetMS;
- }
- public float getMicDelayMS() {
- return micDelayMS;
- }
- public void setMicDelayMS(float micDelayMS) {
- this.micDelayMS = micDelayMS;
- }
- public float getBeatDuration() {
- return beatDuration;
- }
- public void setBeatDuration(float beatDuration) {
- this.beatDuration = beatDuration;
- }
- public HardLevelEnum getHardLevel() {
- return hardLevel;
- }
- public ConcurrentHashMap<Integer, MusicXmlBasicInfo> getSongMusicXmlMap() {
- return songMusicXmlMap;
- }
- public WaveformWriter getWaveFileProcessor() {
- return waveFileProcessor;
- }
- public void setWaveFileProcessor(WaveformWriter waveFileProcessor) {
- this.waveFileProcessor = waveFileProcessor;
- }
- public NoteAnalysis getProcessingNote() {
- return processingNote;
- }
- public void setProcessingNote(NoteAnalysis processingNote) {
- this.processingNote = processingNote;
- }
-
- public List<SectionAnalysis> getDoneSectionAnalysisList() {
- return doneSectionAnalysisList;
- }
- public List<NoteAnalysis> getDoneNoteAnalysisList() {
- return doneNoteAnalysisList;
- }
- public void resetUserInfo() {
- waveFileProcessor = null;
- processingNote = new NoteAnalysis(0,0,-1);
- evaluatingSectionIndex = new AtomicInteger(0);
- channelBufferBytes = new byte[0];
- doneNoteAnalysisList = new ArrayList<NoteAnalysis>();
- doneSectionAnalysisList = new ArrayList<SectionAnalysis>();
- totalChunkAnalysisList = new ArrayList<ChunkAnalysis>();
- recordId = null;
- playTime = 0;
- delayProcessed = false;
- offsetMS = 0;
- dynamicOffset = 0;
- handlerSwitch = false;
- }
-
- public MusicXmlBasicInfo getMusicXmlBasicInfo(Integer songId){
- MusicXmlBasicInfo musicXmlBasicInfo = null;
- if (songId == null) {
- musicXmlBasicInfo = songMusicXmlMap.values().stream().findFirst().get();
- } else {
- musicXmlBasicInfo = songMusicXmlMap.get(songId);
- }
- return musicXmlBasicInfo;
- }
-
- public MusicXmlSection getCurrentMusicSection(Integer songId, int sectionIndex){
- MusicXmlBasicInfo musicXmlBasicInfo = getMusicXmlBasicInfo(songId);
- return musicXmlBasicInfo.getMusicXmlSectionMap().get(sectionIndex);
- }
- public MusicXmlNote getCurrentMusicNote(Integer songId, Integer noteIndex) {
- if (songMusicXmlMap.size() == 0) {
- return null;
- }
- if(noteIndex == null){
- noteIndex = processingNote.getMusicalNotesIndex();
- }
- final int index = noteIndex;
- MusicXmlBasicInfo musicXmlBasicInfo = getMusicXmlBasicInfo(songId);
- int totalNoteIndex = getTotalMusicNoteIndex(null);
- if (musicXmlBasicInfo != null && index <= totalNoteIndex) {
- return musicXmlBasicInfo.getMusicXmlInfos().stream().filter(t -> t.getMusicalNotesIndex() == index).findFirst().get();
- }
- return null;
- }
- public int getTotalMusicNoteIndex(Integer songId) {
- if (songMusicXmlMap.size() == 0) {
- return -1;
- }
- MusicXmlBasicInfo musicXmlBasicInfo = getMusicXmlBasicInfo(songId);
- if (musicXmlBasicInfo != null) {
- return musicXmlBasicInfo.getMusicXmlInfos().stream().map(t -> t.getMusicalNotesIndex()).distinct().max(Integer::compareTo).get();
- }
- return -1;
- }
- public List<MusicXmlNote> getCurrentMusicSection(Integer songId, Integer sectionIndex) {
- if (songMusicXmlMap.size() == 0) {
- return null;
- }
- if(sectionIndex == null){
- sectionIndex = processingNote.getSectionIndex();
- }
- final int index = sectionIndex;
- MusicXmlBasicInfo musicXmlBasicInfo = getMusicXmlBasicInfo(songId);
- if (musicXmlBasicInfo != null) {
- return musicXmlBasicInfo.getMusicXmlInfos().stream().filter(t -> t.getMusicalNotesIndex() == index)
- .sorted(Comparator.comparing(MusicXmlNote::getMusicalNotesIndex)).collect(Collectors.toList());
- }
- return null;
- }
- public int getTotalMusicSectionSize(Integer songId) {
- if (songMusicXmlMap.size() == 0) {
- return -1;
- }
- MusicXmlBasicInfo musicXmlBasicInfo = getMusicXmlBasicInfo(songId);
- if (musicXmlBasicInfo != null) {
- return (int) musicXmlBasicInfo.getMusicXmlInfos().stream().map(t -> t.getMeasureIndex()).distinct().count();
- }
- return -1;
- }
-
- public int getMusicSectionIndex(Integer songId, int musicXmlNoteIndex) {
- if (songMusicXmlMap.size() == 0) {
- return -1;
- }
-
- if(getTotalMusicNoteIndex(null) < musicXmlNoteIndex){
- return -1;
- }
-
- MusicXmlBasicInfo musicXmlBasicInfo = getMusicXmlBasicInfo(songId);
- if (musicXmlBasicInfo != null) {
- return musicXmlBasicInfo.getMusicXmlInfos().stream().filter(t -> t.getMusicalNotesIndex() == musicXmlNoteIndex).findFirst().get().getMeasureIndex();
- }
- return -1;
- }
-
- public byte[] getChannelBufferBytes() {
- return channelBufferBytes;
- }
- public void setChannelBufferBytes(byte[] channelBufferBytes) {
- this.channelBufferBytes = channelBufferBytes;
- }
- public AtomicInteger getEvaluatingSectionIndex() {
- return evaluatingSectionIndex;
- }
- public void handle(float[] samples, AudioFormat audioFormat){
-
- //YINPitchDetector frequencyDetector = new YINPitchDetector(samples.length , audioFormat.getSampleRate());
- //int playFrequency = (int) frequencyDetector.getFrequency(samples);
-
- int playFrequency = -1;
- if(StringUtils.equalsIgnoreCase(evaluationCriteria, EvaluationCriteriaEnum.FREQUENCY.getCode())){
- playFrequency = (int)detector.getPitch(samples).getPitch();
- }
-
- int splDb = (int) Signals.soundPressureLevel(samples);
- float power = Signals.power(samples);
- int amplitude = (int) Signals.norm(samples);
-
- int decibels = (int) Signals.decibels(samples);
- if(StringUtils.equalsIgnoreCase(evaluationCriteria, EvaluationCriteriaEnum.AMPLITUDE.getCode())) {
- amplitude = (int) Signals.norm(samples);
- }else if(StringUtils.equalsIgnoreCase(evaluationCriteria, EvaluationCriteriaEnum.DECIBELS.getCode())){
- amplitude = (int) Signals.decibels(samples);
- amplitude = amplitude >= 60 ? amplitude : 0;
- }
- //float rms = Signals.rms(samples);
-
- double durationTime = 1000 * (samples.length * 2) / audioFormat.getSampleRate() / (audioFormat.getSampleSizeInBits() / 8);
-
- playTime += durationTime;
-
- // 获取当前音符信息
- MusicXmlNote musicXmlNote = getCurrentMusicNote(null,null);
- if (musicXmlNote == null) {
- return;
- }
-
- //取出当前处理中的音符信息
- NoteAnalysis noteAnalysis = getProcessingNote();
- if(noteAnalysis == null || noteAnalysis.getDurationTime() == 0) {
- noteAnalysis = new NoteAnalysis(musicXmlNote.getMeasureRenderIndex(), musicXmlNote.getMusicalNotesIndex(), musicXmlNote.getMeasureIndex(), (int)musicXmlNote.getFrequency(), musicXmlNote.getDuration());
- }
-
- evaluatingSectionIndex.set(noteAnalysis.getSectionIndex());
-
- if (noteAnalysis.getMusicalNotesIndex() >= 0 && noteAnalysis.getMusicalNotesIndex() <= getTotalMusicNoteIndex(null)) {
-
- LOGGER.debug("user:{} delayProcessed:{} dynamicOffset:{} Frequency:{} splDb:{} power:{} amplitude:{} decibels:{} time:{}", user, delayProcessed, dynamicOffset, playFrequency, splDb, power, amplitude, decibels, playTime);
-
- ChunkAnalysis chunkAnalysis = new ChunkAnalysis(playTime - durationTime, playTime, playFrequency, splDb, power, amplitude);
-
- if(totalChunkAnalysisList.size() > 0){
- if(totalChunkAnalysisList.get(totalChunkAnalysisList.size() - 1).getAmplitude() + 2 < chunkAnalysis.getAmplitude()){
- chunkAnalysis.setPeak(true);//只针对打击乐
- }
- }
- totalChunkAnalysisList.add(chunkAnalysis);
-
- //是否收到有效信号
- /*if(!StringUtils.equalsIgnoreCase(evaluationCriteria, EvaluationCriteriaEnum.FREQUENCY.getCode())){
- delayProcessed = chunkAnalysis.getAmplitude() > hardLevel.getAmplitudeThreshold();
- }else{
- delayProcessed = chunkAnalysis.getFrequency() > MIN_FREQUECY && chunkAnalysis.getFrequency() < MAX_FREQUECY;
- }
-
- if(delayProcessed){
-
- //计算延迟偏移值
- //playTime = musicXmlNote.getTimeStamp() + durationTime;
- dynamicOffset = chunkAnalysis.getStartTime() - musicXmlNote.getTimeStamp();
- if(100 * dynamicOffset / musicXmlNote.getDuration() > (100 - hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator(), musicXmlNote.getDuration()))){
- dynamicOffset = 0;
- }
- }*/
-
- if (playTime >= (musicXmlNote.getDuration() + micDelayMS + musicXmlNote.getTimeStamp() + dynamicOffset)) {
-
- musicXmlNote.setTimeStamp(musicXmlNote.getTimeStamp() + micDelayMS);
- if (musicXmlNote.getDontEvaluating()) {
- noteAnalysis.setIgnore(true);
- }
-
- //判断节奏(音符持续时间内有不间断的音高,就节奏正确)
- boolean tempo = true;
- if (!StringUtils.equalsIgnoreCase(evaluationCriteria, EvaluationCriteriaEnum.FREQUENCY.getCode())) {
- noteAnalysis.setPlayFrequency(-1);
- tempo = computeTempoWithAmplitude2(musicXmlNote);
- }else{
- noteAnalysis.setPlayFrequency(computeFrequency(musicXmlNote));
- tempo = computeTempoWithFrequency(musicXmlNote);
- }
-
- noteAnalysis.setTempo(tempo);
-
- evaluateForNote(musicXmlNote, noteAnalysis);//对当前音符评分
- LOGGER.debug("当前音符下标[{}] 预计频率:{} 实际频率:{} 节奏:{}", noteAnalysis.getMusicalNotesIndex(), musicXmlNote.getFrequency(), noteAnalysis.getPlayFrequency(),
- noteAnalysis.isTempo());
-
- doneNoteAnalysisList.add(noteAnalysis);
-
- // 准备处理下一个音符
- int nextNoteIndex = musicXmlNote.getMusicalNotesIndex() + 1;
- float nextNoteFrequence = -1;
- double standDuration = 0;
- int measureRenderIndex = 0;
- MusicXmlNote nextMusicXmlNote = getCurrentMusicNote(null, nextNoteIndex);
- if(nextMusicXmlNote != null){
- nextNoteFrequence = nextMusicXmlNote.getFrequency();
- standDuration = nextMusicXmlNote.getDuration();
- measureRenderIndex = nextMusicXmlNote.getMeasureRenderIndex();
- }
-
- NoteAnalysis nextNoteAnalysis = new NoteAnalysis(measureRenderIndex, nextNoteIndex, getMusicSectionIndex(null, nextNoteIndex), (int)nextNoteFrequence, standDuration);
- noteAnalysis = nextNoteAnalysis;
- }
- setProcessingNote(noteAnalysis);
- }
-
- }
-
- public int evaluateForSection(int sectionIndex, int subjectId){
- int score = -1;
- if(doneSectionAnalysisList.size() >= getTotalMusicSectionSize(null)){
- return score;
- }
-
- //取出当前小节的所有音符
- List<NoteAnalysis> noteAnalysisList = doneNoteAnalysisList.stream().filter(t -> t.getSectionIndex() == sectionIndex).collect(Collectors.toList());
-
- long ignoreSize = noteAnalysisList.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);
- if(noteAnalysisList.size() == musicXmlSection.getNoteNum()){
- sectionAnalysis.setMeasureRenderIndex(noteAnalysisList.stream().findFirst().get().getMeasureRenderIndex());
- //取出需要评测的音符
- List<NoteAnalysis> noteList = noteAnalysisList.stream().filter(t -> t.isIgnore() == false).collect(Collectors.toList());
-
- if(noteList != null && noteList.size() > 0){
- score = noteList.stream().mapToInt(t -> t.getScore()).sum() / noteList.size();
- }
- sectionAnalysis.setDurationTime(noteAnalysisList.stream().mapToDouble(t -> t.getDurationTime()).sum());
- sectionAnalysis.setScore(score);
- LOGGER.debug("小节评分:{}",sectionAnalysis);
- doneSectionAnalysisList.add(sectionAnalysis);
- }
-
- return score;
- }
-
- public Map<String, Integer> evaluateForMusic() {
- Map<String, Integer> result = new HashMap<String, Integer>();
-
- result.put("playTime", (int) doneNoteAnalysisList.stream().mapToDouble(t -> t.getDurationTime()).sum());
- result.put("recordId", recordId.intValue());
-
- // 取出需要评测的音符
- List<NoteAnalysis> noteAnalysisList = doneNoteAnalysisList.stream().filter(t -> t.isIgnore() == false).collect(Collectors.toList());
- if (noteAnalysisList != null && noteAnalysisList.size() > 0) {
- int intonationScore = 0;
- int tempoScore = 0;
- int integrityScore = 0;
- int socre = 0;
- for (NoteAnalysis note : noteAnalysisList) {
- intonationScore += note.getIntonationScore();
- tempoScore += note.getTempoScore();
- integrityScore += note.getIntegrityScore();
- socre += note.getScore();
- }
- tempoScore = tempoScore / noteAnalysisList.size();
- intonationScore = intonationScore / noteAnalysisList.size();
- integrityScore = integrityScore / noteAnalysisList.size();
- result.put("cadence", tempoScore);
- result.put("intonation", intonationScore);
- result.put("integrity", integrityScore);
- int score = socre / noteAnalysisList.size();
- // 平均得分
- if (getMusicXmlBasicInfo(null).getSubjectId() == 23 || getMusicXmlBasicInfo(null).getSubjectId() == 113) {
- score = tempoScore;
- }
- result.put("score", score);
- } else {
- result.put("cadence", 0);
- result.put("intonation", 0);
- result.put("integrity", 0);
- result.put("score", 0);
- }
- return result;
- }
-
- public void evaluateForNote(MusicXmlNote musicXmlNote, NoteAnalysis noteAnalysis) {
-
- double floatingRange = musicXmlNote.getDuration() * hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator(), musicXmlNote.getDuration()) / 100;
-
- double endTime = musicXmlNote.getTimeStamp() + dynamicOffset + floatingRange;
- double startTime = musicXmlNote.getTimeStamp() + dynamicOffset - floatingRange;
-
- List<ChunkAnalysis> chunkAnalysisList = totalChunkAnalysisList.stream().filter(t -> Double.doubleToLongBits(t.getStartTime()) >= Double.doubleToLongBits(startTime) && Double.doubleToLongBits(t.getEndTime()) <= Double.doubleToLongBits(endTime)).collect(Collectors.toList());
-
- double correctedStartTime = queryFirstNoteStartTime(chunkAnalysisList, musicXmlNote);
- double correctedEndTime = correctedStartTime + musicXmlNote.getDuration();
-
- chunkAnalysisList = totalChunkAnalysisList.stream().filter(t -> Double.doubleToLongBits(t.getStartTime()) >= Double.doubleToLongBits(correctedStartTime) && Double.doubleToLongBits(t.getEndTime()) <= Double.doubleToLongBits(correctedEndTime)).collect(Collectors.toList());
-
- double durationTime = chunkAnalysisList.get(chunkAnalysisList.size() - 1).getEndTime() - chunkAnalysisList.get(0).getStartTime();
-
- double playDurationTime = 0;
-
- if (!StringUtils.equalsIgnoreCase(evaluationCriteria, EvaluationCriteriaEnum.FREQUENCY.getCode())) {
- if (noteAnalysis.getFrequency() == -1) {// 休止符
- if (!noteAnalysis.isTempo()) {
- noteAnalysis.setMusicalErrorType(NoteErrorType.CADENCE_WRONG);
- } else {
- noteAnalysis.setMusicalErrorType(NoteErrorType.RIGHT);
- }
- }else{
- int beatTimes = (int) chunkAnalysisList.stream().filter(t -> t.getAmplitude() > hardLevel.getAmplitudeThreshold()).count();
- if(beatTimes == 0){
- noteAnalysis.setMusicalErrorType(NoteErrorType.NOT_PLAY);
- }else if (!noteAnalysis.isTempo()) {
- noteAnalysis.setMusicalErrorType(NoteErrorType.CADENCE_WRONG);
- } else {
- noteAnalysis.setMusicalErrorType(NoteErrorType.RIGHT);
- }
- }
- } else {
-
- NotePlayResult notePlayResult = queryNoteFrequency(musicXmlNote, noteAnalysis.getPlayFrequency());
-
- if (noteAnalysis.getFrequency() == -1) {// 休止符
- playDurationTime = chunkAnalysisList.stream().filter(t -> t.getFrequency() <= MIN_FREQUECY).mapToDouble(t -> t.getDurationTime()).sum();
- if (!noteAnalysis.isTempo()) {
- noteAnalysis.setMusicalErrorType(NoteErrorType.CADENCE_WRONG);
- } else if (playDurationTime * 100 / durationTime < hardLevel.getIntegrityRange()) {
- noteAnalysis.setMusicalErrorType(NoteErrorType.INTEGRITY_WRONG);
- } else if (notePlayResult.getStatus() == false) {
- noteAnalysis.setMusicalErrorType(NoteErrorType.INTONATION_WRONG);
- } else {
- noteAnalysis.setMusicalErrorType(NoteErrorType.RIGHT);
- }
- } else {
- playDurationTime = chunkAnalysisList.stream().filter(t -> t.getFrequency() > MIN_FREQUECY && t.getFrequency() < MAX_FREQUECY)
- .mapToDouble(t -> t.getDurationTime()).sum();
- if (playDurationTime * 100 / durationTime < hardLevel.getNotPlayRange()) {
- noteAnalysis.setMusicalErrorType(NoteErrorType.NOT_PLAY);
- LOGGER.debug("未演奏:{}", playDurationTime * 100 / durationTime);
- } else if (playDurationTime * 100 / durationTime < hardLevel.getIntegrityRange()) {
- noteAnalysis.setMusicalErrorType(NoteErrorType.INTEGRITY_WRONG);
- LOGGER.debug("完整度不足:{}", playDurationTime * 100 / durationTime);
- } else if (!noteAnalysis.isTempo()) {
- noteAnalysis.setMusicalErrorType(NoteErrorType.CADENCE_WRONG);
- } else if (notePlayResult.getStatus() == false) {
- noteAnalysis.setMusicalErrorType(NoteErrorType.INTONATION_WRONG);
- } else {
- noteAnalysis.setMusicalErrorType(NoteErrorType.RIGHT);
- }
- }
-
- }
- // 计算音分
- int tempoScore = 0;
- int integrityScore = 0;
- int intonationScore = 100 - new BigDecimal(Math.abs(YINPitchDetector.hertzToAbsoluteCent(noteAnalysis.getPlayFrequency())
- - 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;
- } else if (intonationScore > 100) {
- intonationScore = 100;
- }
- if (noteAnalysis.getMusicalErrorType() == NoteErrorType.NOT_PLAY) {
- intonationScore = 0;
- } else {
- if (noteAnalysis.isTempo()) {
- tempoScore = 100;
- noteAnalysis.setTempoScore(tempoScore);
- }
- integrityScore = (int) (playDurationTime * 100 * 100 / hardLevel.getIntegrityRange() / durationTime);
- if (integrityScore > 100) {
- integrityScore = 100;
- }
- noteAnalysis.setIntegrityScore(integrityScore);
- }
- noteAnalysis.setIntonationScore(intonationScore);
- if (!StringUtils.equalsIgnoreCase(evaluationCriteria, EvaluationCriteriaEnum.FREQUENCY.getCode())) {
- noteAnalysis.setScore(tempoScore);
- } else {
- noteAnalysis.setScore(new BigDecimal(intonationScore + tempoScore + integrityScore).divide(new BigDecimal(3), 2).setScale(0, BigDecimal.ROUND_UP)
- .intValue());
- }
- }
-
- private int computeFrequency(MusicXmlNote musicXmlNote) {
-
- double floatingRange = musicXmlNote.getDuration() * hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator(), musicXmlNote.getDuration()) / 100;
-
- double endTime = musicXmlNote.getTimeStamp() + dynamicOffset + floatingRange;
- double startTime = musicXmlNote.getTimeStamp() + dynamicOffset - floatingRange;
-
- LOGGER.debug("------------TimeStamp:{} Duration:{} floatingRange:{} StartTime:{} EndTime:{}------------", musicXmlNote.getTimeStamp(), musicXmlNote.getDuration(), floatingRange, startTime, endTime);
-
- List<ChunkAnalysis> chunkAnalysisList = totalChunkAnalysisList.stream().filter(t -> Double.doubleToLongBits(t.getStartTime()) >= Double.doubleToLongBits(startTime) && Double.doubleToLongBits(t.getEndTime()) <= Double.doubleToLongBits(endTime)).collect(Collectors.toList());
-
- double correctedStartTime = queryFirstNoteStartTime(chunkAnalysisList, musicXmlNote);
- double correctedEndTime = correctedStartTime + musicXmlNote.getDuration();
-
- chunkAnalysisList = totalChunkAnalysisList.stream().filter(t -> Double.doubleToLongBits(t.getStartTime()) >= Double.doubleToLongBits(correctedStartTime) && Double.doubleToLongBits(t.getEndTime()) <= Double.doubleToLongBits(correctedEndTime)).collect(Collectors.toList());
- LOGGER.debug("------------ correctedStartTime:{} correctedEndTime:{}------------", correctedStartTime, correctedEndTime);
-
- //根据完整度取部分有效信号
- int elementSize = chunkAnalysisList.size() * (100 - hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator(), musicXmlNote.getDuration())) / 100;
- chunkAnalysisList = chunkAnalysisList.subList(0, elementSize);
- if(chunkAnalysisList == null || chunkAnalysisList.size() == 0){
- return -1;
- }
-
- reduceNoise(chunkAnalysisList, EvaluationCriteriaEnum.FREQUENCY);
-
- ChunkAnalysis firstChunkAnalysis = chunkAnalysisList.get(0);
-
- LOGGER.debug("-------startTime:{} endTime:{}------", firstChunkAnalysis.getStartTime(), chunkAnalysisList.get(chunkAnalysisList.size() - 1)
- .getEndTime());
-
- List<ChunkAnalysis> chunkList = new ArrayList<ChunkAnalysis>(chunkAnalysisList);
-
- List<Integer> chunkFrequencyList = chunkList.stream().map(t -> t.getFrequency()).filter(t -> t.doubleValue() > MIN_FREQUECY && t.doubleValue() < MAX_FREQUECY)
- .collect(Collectors.toList());
-
- if (chunkFrequencyList.size() == 0) {
- return -1;
- }
- int frequency = (int) (chunkFrequencyList.stream().mapToInt(t -> t).sum() / chunkFrequencyList.size());
- return frequency;
- }
-
- /**
- * 时值范围内有且只有一个音,且不能间断,且在合理范围内需开始演奏
- * 与上一个音相同时,2个音之间需要间断
- * @param musicXmlNote
- * @return
- */
- private boolean computeTempoWithFrequency(MusicXmlNote musicXmlNote){
-
- double floatingRange = musicXmlNote.getDuration() * hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator(), musicXmlNote.getDuration()) / 100;
-
- double endTime = musicXmlNote.getTimeStamp() + dynamicOffset + floatingRange;
- double startTime = musicXmlNote.getTimeStamp() + dynamicOffset - floatingRange;
-
- List<ChunkAnalysis> chunkAnalysisList = totalChunkAnalysisList.stream().filter(t -> Double.doubleToLongBits(t.getStartTime()) >= Double.doubleToLongBits(startTime) && Double.doubleToLongBits(t.getEndTime()) <= Double.doubleToLongBits(endTime)).collect(Collectors.toList());
-
- double correctedStartTime = queryFirstNoteStartTime(chunkAnalysisList, musicXmlNote);
- double correctedEndTime = correctedStartTime + musicXmlNote.getDuration();
-
- chunkAnalysisList = totalChunkAnalysisList.stream().filter(t -> Double.doubleToLongBits(t.getStartTime()) >= Double.doubleToLongBits(correctedStartTime) && Double.doubleToLongBits(t.getEndTime()) <= Double.doubleToLongBits(correctedEndTime)).collect(Collectors.toList());
-
- //根据完整度取部分有效信号
- int elementSize = chunkAnalysisList.size() * (100 - hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator(), musicXmlNote.getDuration())) / 100;
- List<ChunkAnalysis> chunkList = chunkAnalysisList.subList(0, elementSize);
-
- if(chunkList == null || chunkList.size() == 0){
- return false;
- }
-
- reduceNoise(chunkList, EvaluationCriteriaEnum.FREQUENCY);
-
- if (musicXmlNote.getFrequency() == -1) {// 休止符
- return chunkList.stream().filter(t -> t.getFrequency() > MIN_FREQUECY).count() <= 1;
- }
- ChunkAnalysis firstChunkAnalysis = chunkAnalysisList.get(0);
-
- Optional<ChunkAnalysis> chunkAnalysisOptional = totalChunkAnalysisList.stream().filter(t -> Double.doubleToLongBits(t.getEndTime()) <= Double.doubleToLongBits(firstChunkAnalysis.getStartTime())).reduce((first, second) -> second);
- ChunkAnalysis lastChunkAnalysis = null;
- if (chunkAnalysisOptional.isPresent()) {
- lastChunkAnalysis = chunkAnalysisOptional.get();
- }
-
- if(lastChunkAnalysis == null){
- lastChunkAnalysis = new ChunkAnalysis(0, 0, -1, 0, 0, 0);
- }
-
- /*List<ChunkAnalysis> chunkList = new ArrayList<ChunkAnalysis>(chunkAnalysisList);
-
- if(chunkList.size() == 0){
- return false;
- }*/
-
- NoteFrequencyRange noteFrequencyRange = null;
- ChunkAnalysis chunkAnalysis = null;
- boolean tempo = true;
- //boolean isContinue = true;
- //int unplayedSize = 0;
- int firstPeakIndex = -1;
-
- //将信号分堆归类
- Map<NoteFrequencyRange, Integer> signalGrouping = new HashMap<NoteFrequencyRange, Integer>();
-
- for (int i = 0; i < chunkList.size(); i++) {
- chunkAnalysis = chunkList.get(i);
- if (chunkAnalysis != null) {
- if (chunkAnalysis.getFrequency() > MIN_FREQUECY || firstPeakIndex > -1) {
-
- if (firstPeakIndex == -1) {
- firstPeakIndex = i;
- }
-
- noteFrequencyRange = new NoteFrequencyRange(standardFrequecy, chunkAnalysis.getFrequency());
-
- if (signalGrouping.containsKey(noteFrequencyRange)) {
- signalGrouping.put(noteFrequencyRange, signalGrouping.get(noteFrequencyRange) + 1);
- } else {
- signalGrouping.put(noteFrequencyRange, 1);
- }
- }
- }
- }
-
- Integer maxTimes = 0, totalTimes = 0;
-
- for (Entry<NoteFrequencyRange, Integer> entry : signalGrouping.entrySet()) {
- if (entry.getValue() > maxTimes) {
- maxTimes = entry.getValue();
- }
- totalTimes = totalTimes + entry.getValue();
- }
-
- if(totalTimes == 0){
- totalTimes = chunkList.size();
- }
-
- /**
- if (maxTimes * 100 / totalTimes < hardLevel.getIntegrityRange()) {
- LOGGER.debug("节奏错误原因:信号分堆后的最大数量不足指定的完成比例");
- return false;
- }
- */
-
- // 判断进入时间点
- if(firstPeakIndex * 100 /chunkList.size() > hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator(), musicXmlNote.getDuration())){
- LOGGER.debug("节奏错误原因:进入时间点太晚");
- return false;
- }else{
- //判断是否与上一个音延续下来的
- if(correctedStartTime == musicXmlNote.getTimeStamp() + dynamicOffset) {
- if(firstChunkAnalysis.getFrequency() > MIN_FREQUECY && lastChunkAnalysis.getFrequency() > MIN_FREQUECY){
- tempo = new NoteFrequencyRange(standardFrequecy, firstChunkAnalysis.getFrequency()).equals(new NoteFrequencyRange(standardFrequecy, lastChunkAnalysis.getFrequency())) == false;
- if(tempo == false){
- LOGGER.debug("节奏错误原因:上一个音[{}]延续下来导致的", lastChunkAnalysis.getFrequency());
- return false;
- }
- }
- }
- }
-
- //判断过程中声音是否有起伏
- float minValue = 0;
- int depth = 0;
-
- for (int i = 1; i < chunkList.size(); i++) {
-
- if(i == 1) {
- minValue = chunkList.get(i - 1).getSplDb();
- }
- if (Math.abs(minValue - chunkList.get(i).getSplDb()) >= 6) {
- LOGGER.debug("范围内查询到音波信号,correctedStartTime:{}", chunkList.get(i).getStartTime());
- break;
- }
-
- minValue = Math.min(minValue , chunkList.get(i).getSplDb());
-
- /**
- if (depth >= 2 && Math.max(chunkList.get(i - 1).getPower(), chunkList.get(i).getPower()) / Math.min(chunkList.get(i - 1).getPower(), chunkList.get(i).getPower()) >= 2) {
- tempo = false;
- depth++;
- LOGGER.debug("节奏错误原因:声波不稳定[{}]", chunkList.get(i).getEndTime());
- break;
- }
- */
- }
-
- return tempo;
- }
-
- private boolean computeTempoWithAmplitude2(MusicXmlNote musicXmlNote) {
- double floatingRange = musicXmlNote.getDuration() * hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator(), musicXmlNote.getDuration()) / 100;
-
- double endTime = musicXmlNote.getTimeStamp() + dynamicOffset + floatingRange;
- double startTime = musicXmlNote.getTimeStamp() + dynamicOffset - floatingRange;
-
- LOGGER.debug("------------TimeStamp:{} floatingRange:{} StartTime:{} EndTime:{}------------", musicXmlNote.getTimeStamp(), floatingRange, startTime, endTime);
-
- List<ChunkAnalysis> chunkAnalysisList = totalChunkAnalysisList.stream().filter(t -> Double.doubleToLongBits(t.getStartTime()) >= Double.doubleToLongBits(startTime) && Double.doubleToLongBits(t.getEndTime()) <= Double.doubleToLongBits(endTime)).collect(Collectors.toList());
-
- double correctedStartTime = queryFirstNoteStartTime(chunkAnalysisList, musicXmlNote);
- double correctedEndTime = correctedStartTime + musicXmlNote.getDuration();
-
- chunkAnalysisList = totalChunkAnalysisList.stream().filter(t -> Double.doubleToLongBits(t.getStartTime()) >= Double.doubleToLongBits(correctedStartTime) && Double.doubleToLongBits(t.getEndTime()) <= Double.doubleToLongBits(correctedEndTime)).collect(Collectors.toList());
-
- //根据完整度取部分有效信号
- int elementSize = chunkAnalysisList.size() * (100 - hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator(), musicXmlNote.getDuration())) / 100;
- List<ChunkAnalysis> chunkList = chunkAnalysisList.subList(0, elementSize);
-
- if(chunkList == null || chunkList.size() == 0){
- return false;
- }
-
- reduceNoise(chunkList, EvaluationCriteriaEnum.AMPLITUDE);
-
- ChunkAnalysis firstChunkAnalysis = chunkAnalysisList.get(0);
-
- LOGGER.debug("-------startTime:{} endTime:{}------", firstChunkAnalysis.getStartTime(), chunkList.get(chunkList.size() - 1)
- .getEndTime());
- if (musicXmlNote.getFrequency() == -1) {// 休止符
-
- LOGGER.debug("--Amplitude:{} Denominator:{}",chunkList.stream().map(t -> t.getAmplitude()).collect(Collectors.toList()), musicXmlNote.getDenominator());
- return chunkList.stream().filter(t -> t.getAmplitude() > hardLevel.getAmplitudeThreshold()).count() <= 0;
- }
-
- Optional<ChunkAnalysis> chunkAnalysisOptional = totalChunkAnalysisList.stream().filter(t -> Double.doubleToLongBits(t.getEndTime()) <= Double.doubleToLongBits(firstChunkAnalysis.getStartTime())).reduce((first, second) -> second);
- ChunkAnalysis lastChunkAnalysis = new ChunkAnalysis(0, 0, -1, 0, 0, 0);;
- if (chunkAnalysisOptional.isPresent()) {
- lastChunkAnalysis = chunkAnalysisOptional.get();
- }
-
- List<Integer> chunkAmplitudeList = chunkList.stream().map(ChunkAnalysis::getAmplitude).collect(Collectors.toList());
-
- chunkAmplitudeList.add(0, lastChunkAnalysis.getAmplitude());
-
- LOGGER.debug("--Amplitude:{} Denominator:{}",chunkAmplitudeList.stream().map(t -> t).collect(Collectors.toList()), musicXmlNote.getDenominator());
-
- // 检测是否有多个波峰
- boolean tempo = false;
- boolean isContinue = false;
- int firstPeakIndex = -1;
- int firstPeakValue = 0;
- int peakSize = 0;
-
- //int range = hardLevel.getAmplitudeThreshold();
- int range = 5;
-
- if(StringUtils.equalsIgnoreCase(evaluationCriteria, EvaluationCriteriaEnum.DECIBELS.getCode())) {
- range = 50;
- }
- for (int i = 1; i < chunkAmplitudeList.size(); i++) {
- if (chunkAmplitudeList.get(i - 1) + range >= chunkAmplitudeList.get(i)) {
- isContinue = false;
- continue;
- }
- if(isContinue == false && chunkAmplitudeList.get(i - 1) + range < chunkAmplitudeList.get(i)){
- isContinue = true;
- peakSize++;
-
- if(firstPeakIndex == -1){
- firstPeakIndex = i;
- firstPeakValue = chunkAmplitudeList.get(i);
- }
- }
- }
-
- LOGGER.debug("PeakSize:" + peakSize + " FirstPeakIndex:" + firstPeakIndex + " FirstPeakValue:" + firstPeakValue);
-
- /*for (int i = 1; i < chunkAmplitudeList.size(); i++) {
- if (Math.abs(chunkAmplitudeList.get(i) - chunkAmplitudeList.get(i - 1)) < hardLevel.getAmplitudeThreshold()) {
- continue;
- }
- if (chunkAmplitudeList.get(i) > hardLevel.getAmplitudeThreshold() && chunkAmplitudeList.get(i) > chunkAmplitudeList.get(i - 1)) {
- tempo = true;
- if(firstPeakIndex == -1){
- firstPeakIndex = i;
- peakSize++;
- }
- if (isContinue == false) {
- tempo = false;
- peakSize++;
- break;
- }
- } else {
- if (tempo == true) {
- isContinue = false;
- }
- }
- }*/
-
- if(peakSize == 0){
- tempo = lastChunkAnalysis.isPeak();
- }else if(peakSize == 1){
- tempo = true;
- }else{
- tempo = false;
- LOGGER.debug("有多个波峰");
- }
-
- if (tempo) {
- // 判断进入时间点
- if((firstPeakIndex - 1) * 100 /chunkAmplitudeList.size() > hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator(), musicXmlNote.getDuration())){
- LOGGER.debug("超过范围:{}", (firstPeakIndex - 1) * 100 /chunkAmplitudeList.size());
- tempo = false;
- }
- }
-
- return tempo;
- }
-
- private double queryFirstNoteStartTime(List<ChunkAnalysis> chunkAnalysisList, MusicXmlNote musicXmlNote) {
-
- if(chunkAnalysisList == null || chunkAnalysisList.size() == 0){
- LOGGER.debug("找不到数据,correctedStartTime:{}", musicXmlNote.getTimeStamp() + dynamicOffset);
- return musicXmlNote.getTimeStamp() + dynamicOffset;
- }
-
- if (!StringUtils.equalsIgnoreCase(evaluationCriteria, EvaluationCriteriaEnum.FREQUENCY.getCode())) {
- Optional<ChunkAnalysis> optional = chunkAnalysisList.stream().filter(t -> t.getAmplitude() > hardLevel.getAmplitudeThreshold()).findFirst();
- if(optional.isPresent()){
- LOGGER.debug("范围内查询到信号,correctedStartTime:{}", optional.get().getStartTime());
- return optional.get().getStartTime();
- }else{
- LOGGER.debug("范围内未查询到信号,correctedStartTime:{}", musicXmlNote.getTimeStamp() + dynamicOffset);
- return musicXmlNote.getTimeStamp() + dynamicOffset;
- }
- }
-
- double startTime = 0;
- float minValue = 0;
- for (int i = 1; i < chunkAnalysisList.size(); i++) {
-
- if(i == 1) {
- minValue = chunkAnalysisList.get(i - 1).getSplDb();
- }
- if (Math.abs(minValue - chunkAnalysisList.get(i).getSplDb()) >= 6) {
- LOGGER.debug("范围内查询到音波信号,correctedStartTime:{}", chunkAnalysisList.get(i).getStartTime());
- startTime = chunkAnalysisList.get(i).getStartTime();
- break;
- }
-
- minValue = Math.min(minValue , chunkAnalysisList.get(i).getSplDb());
-
- /**
- if (Math.max(chunkAnalysisList.get(i - 1).getPower(), chunkAnalysisList.get(i).getPower()) / Math.min(chunkAnalysisList.get(i - 1).getPower(), chunkAnalysisList.get(i).getPower()) >= 2) {
- LOGGER.debug("范围内查询到音波信号,correctedStartTime:{}", chunkAnalysisList.get(i).getStartTime());
- startTime = chunkAnalysisList.get(i).getStartTime();
- break;
- }
- */
- }
-
- //判断是否与上一个音是同一个音符
- if(musicXmlNote.getMusicalNotesIndex() > 0){
- MusicXmlNote preMusicXmlNote = getCurrentMusicNote(null, musicXmlNote.getMusicalNotesIndex() - 1);
- if((int)preMusicXmlNote.getFrequency() == (int)musicXmlNote.getFrequency()){
- Optional<ChunkAnalysis> optional = chunkAnalysisList.stream().filter(t -> t.getFrequency() <= MIN_FREQUECY).findFirst();
- if(optional.isPresent()){
- LOGGER.debug("与上一个音同音,有断开,correctedStartTime:{}", optional.get().getEndTime());
- return Math.max(optional.get().getEndTime(), startTime);
- }
- }
- }
- NoteFrequencyRange standardNote = new NoteFrequencyRange(standardFrequecy, musicXmlNote.getFrequency());
- NoteFrequencyRange noteFrequencyRange = null;
- for (ChunkAnalysis ca : chunkAnalysisList) {
- noteFrequencyRange = new NoteFrequencyRange(standardFrequecy, ca.getFrequency());
- if (standardNote.equals(noteFrequencyRange)) {
- LOGGER.debug("范围内查询到音高信号,correctedStartTime:{}", ca.getStartTime());
- return Math.max(ca.getStartTime(), startTime);
- }
- }
-
- if(startTime == 0) {
- LOGGER.debug("范围内未查询到信号,correctedStartTime:{}", musicXmlNote.getTimeStamp() + dynamicOffset);
- }
- //return chunkAnalysisList.get(chunkAnalysisList.size() - 1).getEndTime();
- return Math.max(musicXmlNote.getTimeStamp() + dynamicOffset, startTime);
- }
- private void reduceNoise(List<ChunkAnalysis> chunkAnalysisList, EvaluationCriteriaEnum criteria) {
- ChunkAnalysis chunkAnalysis = null;
- for (int i = 1; i < chunkAnalysisList.size(); i++) {
- if (i < chunkAnalysisList.size() - 1) {
- chunkAnalysis = chunkAnalysisList.get(i);
- if (EvaluationCriteriaEnum.AMPLITUDE == criteria) {
- if (chunkAnalysisList.get(i - 1).getAmplitude() == 0 && chunkAnalysisList.get(i + 1).getAmplitude() == 0
- && chunkAnalysis.getAmplitude() > 0) {
-
- chunkAnalysis.setAmplitude(0);
- //chunkAnalysisList.set(i, chunkAnalysis);
- }
- }else if(EvaluationCriteriaEnum.FREQUENCY == criteria) {
- if (chunkAnalysisList.get(i - 1).getFrequency() == -1 && chunkAnalysisList.get(i + 1).getFrequency() == -1
- && chunkAnalysis.getFrequency() > 0) {
-
- chunkAnalysis.setFrequency(-1);
- //chunkAnalysisList.set(i, chunkAnalysis);
- }
- }
- }
- }
-
- }
-
-
- }
|