|  | @@ -8,11 +8,10 @@ import com.alibaba.fastjson.JSON;
 | 
	
		
			
				|  |  |  import com.alibaba.fastjson.JSONObject;
 | 
	
		
			
				|  |  |  import com.ym.mec.biz.dal.config.SoundCompareConfig;
 | 
	
		
			
				|  |  |  import com.ym.mec.biz.dal.dao.SysMusicScoreAccompanimentDao;
 | 
	
		
			
				|  |  | -import com.ym.mec.biz.dal.dto.MusicPitchDetailDto;
 | 
	
		
			
				|  |  | -import com.ym.mec.biz.dal.dto.SoundCompareHelper;
 | 
	
		
			
				|  |  | -import com.ym.mec.biz.dal.dto.WavHeader;
 | 
	
		
			
				|  |  | -import com.ym.mec.biz.dal.dto.WebSocketInfo;
 | 
	
		
			
				|  |  | +import com.ym.mec.biz.dal.dto.*;
 | 
	
		
			
				|  |  |  import com.ym.mec.biz.dal.enums.DeviceTypeEnum;
 | 
	
		
			
				|  |  | +import com.ym.mec.biz.dal.enums.HeardLevelEnum;
 | 
	
		
			
				|  |  | +import com.ym.mec.biz.dal.enums.MusicalErrorTypeEnum;
 | 
	
		
			
				|  |  |  import com.ym.mec.biz.dal.enums.WebsocketTypeEnum;
 | 
	
		
			
				|  |  |  import com.ym.mec.biz.handler.WebSocketHandler;
 | 
	
		
			
				|  |  |  import com.ym.mec.biz.service.SoundSocketService;
 | 
	
	
		
			
				|  | @@ -23,7 +22,6 @@ import com.ym.mec.common.exception.BizException;
 | 
	
		
			
				|  |  |  import com.ym.mec.thirdparty.storage.StoragePluginContext;
 | 
	
		
			
				|  |  |  import com.ym.mec.thirdparty.storage.provider.KS3StoragePlugin;
 | 
	
		
			
				|  |  |  import com.ym.mec.util.upload.UploadUtil;
 | 
	
		
			
				|  |  | -import org.apache.commons.io.FileUtils;
 | 
	
		
			
				|  |  |  import org.slf4j.Logger;
 | 
	
		
			
				|  |  |  import org.slf4j.LoggerFactory;
 | 
	
		
			
				|  |  |  import org.springframework.beans.factory.annotation.Autowired;
 | 
	
	
		
			
				|  | @@ -31,7 +29,6 @@ import org.springframework.security.oauth2.provider.OAuth2Authentication;
 | 
	
		
			
				|  |  |  import org.springframework.stereotype.Service;
 | 
	
		
			
				|  |  |  import org.springframework.util.CollectionUtils;
 | 
	
		
			
				|  |  |  import org.springframework.web.socket.BinaryMessage;
 | 
	
		
			
				|  |  | -import org.springframework.web.socket.TextMessage;
 | 
	
		
			
				|  |  |  import org.springframework.web.socket.WebSocketSession;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import javax.sound.sampled.UnsupportedAudioFileException;
 | 
	
	
		
			
				|  | @@ -88,15 +85,10 @@ public class SoundCompareHandler implements WebSocketEventHandler {
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  | -    public void receiveTextMessage(WebSocketSession session, String phone, TextMessage message) {
 | 
	
		
			
				|  |  | -        WebSocketInfo webSocketInfo = JSON.parseObject(message.getPayload(), WebSocketInfo.class);
 | 
	
		
			
				|  |  | -        JSONObject bodyObject = (JSONObject) webSocketInfo.getBody();
 | 
	
		
			
				|  |  | +    public void receiveTextMessage(WebSocketSession session, String phone, WebSocketInfo message) {
 | 
	
		
			
				|  |  | +        JSONObject bodyObject = (JSONObject) message.getBody();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        String commond = "";
 | 
	
		
			
				|  |  | -        if(webSocketInfo.getHeader().containsKey(SoundSocketService.COMMOND)){
 | 
	
		
			
				|  |  | -            commond = webSocketInfo.getHeader().get(SoundSocketService.COMMOND);
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        switch (commond){
 | 
	
		
			
				|  |  | +        switch (message.getHeader().getCommond()){
 | 
	
		
			
				|  |  |              case SoundSocketService.MUSIC_XML:
 | 
	
		
			
				|  |  |                  userSoundInfoMap.put(phone, new SoundCompareHelper());
 | 
	
		
			
				|  |  |                  userSoundInfoMap.get(phone).setClientId(((OAuth2Authentication)session.getPrincipal()).getOAuth2Request().getClientId());
 | 
	
	
		
			
				|  | @@ -110,6 +102,18 @@ public class SoundCompareHandler implements WebSocketEventHandler {
 | 
	
		
			
				|  |  |                  if(bodyObject.containsKey("behaviorId")){
 | 
	
		
			
				|  |  |                      userSoundInfoMap.get(phone).setBehaviorId(bodyObject.getString("behaviorId"));
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  | +                if(bodyObject.containsKey("detailId")){
 | 
	
		
			
				|  |  | +                    userSoundInfoMap.get(phone).setDetailId(bodyObject.getInteger("detailId"));
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                if(bodyObject.containsKey("examSongId")){
 | 
	
		
			
				|  |  | +                    userSoundInfoMap.get(phone).setExamSongId(bodyObject.getInteger("examSongId"));
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                if(bodyObject.containsKey("xmlUrl")){
 | 
	
		
			
				|  |  | +                    userSoundInfoMap.get(phone).setXmlUrl(bodyObject.getString("xmlUrl"));
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                if(bodyObject.containsKey("heardLevel")){
 | 
	
		
			
				|  |  | +                    userSoundInfoMap.get(phone).setHeardLevel(HeardLevelEnum.valueOf(bodyObject.getString("heardLevel")));
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  |                  List<Integer> subjectIds = sysMusicScoreAccompanimentDao.findSubjectByMusicScoreId(userSoundInfoMap.get(phone).getMusicScoreId(), null);
 | 
	
		
			
				|  |  |                  if(!CollectionUtils.isEmpty(subjectIds)){
 | 
	
		
			
				|  |  |                      userSoundInfoMap.get(phone).setSubjectId(subjectIds.get(0));
 | 
	
	
		
			
				|  | @@ -154,9 +158,10 @@ public class SoundCompareHandler implements WebSocketEventHandler {
 | 
	
		
			
				|  |  |                              userSoundInfoMap.get(phone).getMeasureEndTime().remove(lastMeasureIndex);
 | 
	
		
			
				|  |  |                          }
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  | +                } catch (IOException | NullPointerException e) {
 | 
	
		
			
				|  |  | +                    LOGGER.error("评分错误:", e);
 | 
	
		
			
				|  |  | +                } finally {
 | 
	
		
			
				|  |  |                      calTotalScore(phone);
 | 
	
		
			
				|  |  | -                } catch (IOException e) {
 | 
	
		
			
				|  |  | -                    throw new BizException("评分错误:", e);
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |                  createHeader(phone);
 | 
	
		
			
				|  |  |                  break;
 | 
	
	
		
			
				|  | @@ -397,6 +402,10 @@ public class SoundCompareHandler implements WebSocketEventHandler {
 | 
	
		
			
				|  |  |                      userSoundInfoMap.get(phone).getMusicalNotePitchMap().put(musicXmlInfo.getMusicalNotesIndex(), (float) pitch);
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +                boolean cadenceRight = false;
 | 
	
		
			
				|  |  | +                boolean intonationRight = false;
 | 
	
		
			
				|  |  | +                boolean integrityRight = false;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |                  //有效节奏占比
 | 
	
		
			
				|  |  |                  float cadenceDuty = cadenceValidNum/compareNum;
 | 
	
		
			
				|  |  |                  //如果频率出现断层或这个音量出现断层,则当前音符节奏无效
 | 
	
	
		
			
				|  | @@ -404,11 +413,13 @@ public class SoundCompareHandler implements WebSocketEventHandler {
 | 
	
		
			
				|  |  |                      cadenceDuty = 0;
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |                  //节奏
 | 
	
		
			
				|  |  | -                if(cadenceDuty>=soundCompareConfig.cadenceValidDuty){
 | 
	
		
			
				|  |  | +                if(cadenceDuty>=userSoundInfoMap.get(phone).getHeardLevel().getCadenceRange()){
 | 
	
		
			
				|  |  |                      cadenceNum++;
 | 
	
		
			
				|  |  | +                    cadenceRight = true;
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  | -                //音准
 | 
	
		
			
				|  |  | +                //音准、完成度
 | 
	
		
			
				|  |  |                  if (!CollectionUtils.isEmpty(measureSoundPitchInfos)){
 | 
	
		
			
				|  |  | +                    //音准
 | 
	
		
			
				|  |  |                      Double avgPitch = measureSoundPitchInfos.stream().filter(pitch -> Math.abs((pitch.getFrequency()-musicXmlInfo.getFrequency()))<5).collect(Collectors.averagingDouble(pitch -> pitch.getFrequency()));
 | 
	
		
			
				|  |  |                      //音分
 | 
	
		
			
				|  |  |                      double recordCents = 0;
 | 
	
	
		
			
				|  | @@ -419,7 +430,7 @@ public class SoundCompareHandler implements WebSocketEventHandler {
 | 
	
		
			
				|  |  |                      if(musicXmlInfo.getFrequency()>0){
 | 
	
		
			
				|  |  |                          cents =  PitchConverter.hertzToAbsoluteCent(musicXmlInfo.getFrequency());
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  | -                    double score = 100 - Math.round(Math.abs(cents - recordCents)) + soundCompareConfig.intonationCentsRange;
 | 
	
		
			
				|  |  | +                    double score = 100 - Math.round(Math.abs(cents - recordCents)) + userSoundInfoMap.get(phone).getHeardLevel().getIntonationCentsRange();
 | 
	
		
			
				|  |  |                      if (score < 0){
 | 
	
		
			
				|  |  |                          score = 0;
 | 
	
		
			
				|  |  |                      }else if(score > 100){
 | 
	
	
		
			
				|  | @@ -427,6 +438,9 @@ public class SoundCompareHandler implements WebSocketEventHandler {
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |                      intonationScore += score;
 | 
	
		
			
				|  |  |                      musicXmlInfo.setAvgFrequency(avgPitch.floatValue());
 | 
	
		
			
				|  |  | +                    intonationRight = score>70;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                    integrityValidNum = measureSoundPitchInfos.stream().filter(pitch -> Math.abs((pitch.getFrequency()-musicXmlInfo.getFrequency()))<5).count();
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |                  //完成度
 | 
	
		
			
				|  |  |                  if(integrityValidNum > compareNum){
 | 
	
	
		
			
				|  | @@ -434,6 +448,17 @@ public class SoundCompareHandler implements WebSocketEventHandler {
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |                  float integrityDuty = integrityValidNum/compareNum;
 | 
	
		
			
				|  |  |                  integrityScore += integrityDuty;
 | 
	
		
			
				|  |  | +                integrityRight = integrityDuty>0.7;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                if(!cadenceRight){
 | 
	
		
			
				|  |  | +                    userSoundInfoMap.get(phone).getMusicalNotesPlayStats().add(new MusicalNotesPlayStatDto(musicXmlInfo.getMusicalNotesIndex(), MusicalErrorTypeEnum.CADENCE_WRONG));
 | 
	
		
			
				|  |  | +                }else if(!intonationRight){
 | 
	
		
			
				|  |  | +                    userSoundInfoMap.get(phone).getMusicalNotesPlayStats().add(new MusicalNotesPlayStatDto(musicXmlInfo.getMusicalNotesIndex(), MusicalErrorTypeEnum.INTONATION_WRONG));
 | 
	
		
			
				|  |  | +                }else if(!integrityRight){
 | 
	
		
			
				|  |  | +                    userSoundInfoMap.get(phone).getMusicalNotesPlayStats().add(new MusicalNotesPlayStatDto(musicXmlInfo.getMusicalNotesIndex(), MusicalErrorTypeEnum.INTEGRITY_WRONG));
 | 
	
		
			
				|  |  | +                }else{
 | 
	
		
			
				|  |  | +                    userSoundInfoMap.get(phone).getMusicalNotesPlayStats().add(new MusicalNotesPlayStatDto(musicXmlInfo.getMusicalNotesIndex(), MusicalErrorTypeEnum.RIGHT));
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              BigDecimal measureNum = new BigDecimal(totalCompareNum);
 | 
	
	
		
			
				|  | @@ -508,9 +533,7 @@ public class SoundCompareHandler implements WebSocketEventHandler {
 | 
	
		
			
				|  |  |      private WebSocketInfo createPushInfo(String phone, String command, Integer measureIndex,
 | 
	
		
			
				|  |  |                                           BigDecimal intonation, BigDecimal cadence, BigDecimal integrity){
 | 
	
		
			
				|  |  |          WebSocketInfo webSocketInfo = new WebSocketInfo();
 | 
	
		
			
				|  |  | -        HashMap<String, String> header = new HashMap<>();
 | 
	
		
			
				|  |  | -        header.put("commond", command);
 | 
	
		
			
				|  |  | -        webSocketInfo.setHeader(header);
 | 
	
		
			
				|  |  | +        webSocketInfo.setHeader(new WebSocketInfo.Head(command));
 | 
	
		
			
				|  |  |          Map<String, Object> result = new HashMap<>(5);
 | 
	
		
			
				|  |  |          BigDecimal score = cadence;
 | 
	
		
			
				|  |  |          if(Objects.isNull(userSoundInfoMap.get(phone).getSubjectId())||userSoundInfoMap.get(phone).getSubjectId()!=23){
 | 
	
	
		
			
				|  | @@ -528,11 +551,7 @@ public class SoundCompareHandler implements WebSocketEventHandler {
 | 
	
		
			
				|  |  |          LOGGER.info("小节频分:{}", JSON.toJSONString(webSocketInfo));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          //推送结果
 | 
	
		
			
				|  |  | -        try {
 | 
	
		
			
				|  |  | -            WebSocketHandler.WS_CLIENTS.get(phone).getSession().sendMessage(new TextMessage(JSON.toJSONString(webSocketInfo)));
 | 
	
		
			
				|  |  | -        } catch (IOException e) {
 | 
	
		
			
				|  |  | -            LOGGER.error("{}评分结果推送失败", phone);
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | +        WebSocketHandler.sendTextMessage(phone, webSocketInfo);
 | 
	
		
			
				|  |  |          return webSocketInfo;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 |