|  | @@ -6,37 +6,34 @@ import be.tarsos.dsp.AudioProcessor;
 | 
	
		
			
				|  |  |  import be.tarsos.dsp.SilenceDetector;
 | 
	
		
			
				|  |  |  import be.tarsos.dsp.beatroot.BeatRootOnsetEventHandler;
 | 
	
		
			
				|  |  |  import be.tarsos.dsp.io.PipedAudioStream;
 | 
	
		
			
				|  |  | -import be.tarsos.dsp.io.TarsosDSPAudioFormat;
 | 
	
		
			
				|  |  |  import be.tarsos.dsp.io.TarsosDSPAudioInputStream;
 | 
	
		
			
				|  |  |  import be.tarsos.dsp.io.jvm.AudioDispatcherFactory;
 | 
	
		
			
				|  |  |  import be.tarsos.dsp.onsets.ComplexOnsetDetector;
 | 
	
		
			
				|  |  |  import be.tarsos.dsp.onsets.OnsetHandler;
 | 
	
		
			
				|  |  | -import com.alibaba.fastjson.JSON;
 | 
	
		
			
				|  |  | +import com.ym.mec.biz.dal.dao.SysMusicScoreAccompanimentDao;
 | 
	
		
			
				|  |  |  import com.ym.mec.biz.dal.dao.SysMusicScoreDao;
 | 
	
		
			
				|  |  |  import com.ym.mec.biz.dal.entity.SysMusicScore;
 | 
	
		
			
				|  |  | +import com.ym.mec.biz.dal.entity.SysMusicScoreAccompaniment;
 | 
	
		
			
				|  |  |  import com.ym.mec.biz.service.SoundService;
 | 
	
		
			
				|  |  |  import com.ym.mec.common.constant.CommonConstants;
 | 
	
		
			
				|  |  |  import com.ym.mec.common.controller.BaseController;
 | 
	
		
			
				|  |  |  import com.ym.mec.common.entity.HttpResponseResult;
 | 
	
		
			
				|  |  |  import com.ym.mec.common.exception.BizException;
 | 
	
		
			
				|  |  | +import com.ym.mec.common.service.IdGeneratorService;
 | 
	
		
			
				|  |  |  import org.apache.commons.io.FileUtils;
 | 
	
		
			
				|  |  |  import org.apache.commons.lang3.StringUtils;
 | 
	
		
			
				|  |  | +import org.slf4j.Logger;
 | 
	
		
			
				|  |  | +import org.slf4j.LoggerFactory;
 | 
	
		
			
				|  |  |  import org.springframework.beans.factory.annotation.Autowired;
 | 
	
		
			
				|  |  |  import org.springframework.stereotype.Service;
 | 
	
		
			
				|  |  |  import org.springframework.web.multipart.MultipartFile;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -import javax.sound.sampled.AudioFileFormat;
 | 
	
		
			
				|  |  |  import javax.sound.sampled.AudioFormat;
 | 
	
		
			
				|  |  | -import javax.sound.sampled.AudioSystem;
 | 
	
		
			
				|  |  |  import javax.sound.sampled.UnsupportedAudioFileException;
 | 
	
		
			
				|  |  |  import java.io.File;
 | 
	
		
			
				|  |  | -import java.io.FileOutputStream;
 | 
	
		
			
				|  |  |  import java.io.IOException;
 | 
	
		
			
				|  |  | -import java.io.InputStream;
 | 
	
		
			
				|  |  |  import java.math.BigDecimal;
 | 
	
		
			
				|  |  | -import java.net.MalformedURLException;
 | 
	
		
			
				|  |  |  import java.net.URL;
 | 
	
		
			
				|  |  | -import java.net.URLConnection;
 | 
	
		
			
				|  |  |  import java.util.*;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /**
 | 
	
	
		
			
				|  | @@ -46,10 +43,16 @@ import java.util.*;
 | 
	
		
			
				|  |  |  @Service
 | 
	
		
			
				|  |  |  public class SoundServiceImpl implements SoundService {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    private final Logger LOGGER = LoggerFactory.getLogger(SoundServiceImpl.class);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      private float sampleRate = 44100;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Autowired
 | 
	
		
			
				|  |  |      private SysMusicScoreDao sysMusicScoreDao;
 | 
	
		
			
				|  |  | +    @Autowired
 | 
	
		
			
				|  |  | +    private SysMusicScoreAccompanimentDao sysMusicScoreAccompanimentDao;
 | 
	
		
			
				|  |  | +    @Autowired
 | 
	
		
			
				|  |  | +    private IdGeneratorService idGeneratorService;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  |       * @describe 音频节拍信息提取
 | 
	
	
		
			
				|  | @@ -57,7 +60,7 @@ public class SoundServiceImpl implements SoundService {
 | 
	
		
			
				|  |  |       * @date 2021/5/19 0019
 | 
	
		
			
				|  |  |       * @return
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  | -    private List<Double> beatExtractor(byte[] bytes, String url) throws UnsupportedAudioFileException, IOException {
 | 
	
		
			
				|  |  | +    private List<Double> beatExtractor(byte[] bytes, String url) throws UnsupportedAudioFileException {
 | 
	
		
			
				|  |  |          List<Double> times = new ArrayList<>();
 | 
	
		
			
				|  |  |          int size = 256;
 | 
	
		
			
				|  |  |          int overlap = 128;
 | 
	
	
		
			
				|  | @@ -86,7 +89,7 @@ public class SoundServiceImpl implements SoundService {
 | 
	
		
			
				|  |  |       * @param bytes: 文件字节
 | 
	
		
			
				|  |  |       * @return java.util.List<java.lang.Double>
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  | -    private List<Double> soundPressureLevelExtractor(byte[] bytes, String url, BigDecimal duration) throws UnsupportedAudioFileException, IOException {
 | 
	
		
			
				|  |  | +    private List<Double> soundPressureLevelExtractor(byte[] bytes, String url) throws UnsupportedAudioFileException {
 | 
	
		
			
				|  |  |          List<Double> pitchs = new ArrayList<>();
 | 
	
		
			
				|  |  |          int size = 2048;
 | 
	
		
			
				|  |  |          int overlap = 0;
 | 
	
	
		
			
				|  | @@ -108,7 +111,7 @@ public class SoundServiceImpl implements SoundService {
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          });
 | 
	
		
			
				|  |  |          dispatcher.run();
 | 
	
		
			
				|  |  | -        duration = new BigDecimal(t[0]);
 | 
	
		
			
				|  |  | +        pitchs.add(t[0]);
 | 
	
		
			
				|  |  |          return pitchs;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -118,7 +121,7 @@ public class SoundServiceImpl implements SoundService {
 | 
	
		
			
				|  |  |          return dispatcher;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    private AudioDispatcher getFromFile(String url, int size, int overlap) throws UnsupportedAudioFileException, IOException {
 | 
	
		
			
				|  |  | +    private AudioDispatcher getFromFile(String url, int size, int overlap) {
 | 
	
		
			
				|  |  |          PipedAudioStream file = new PipedAudioStream(url);
 | 
	
		
			
				|  |  |          TarsosDSPAudioInputStream stream = file.getMonoStream(44100,0);
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -138,62 +141,90 @@ public class SoundServiceImpl implements SoundService {
 | 
	
		
			
				|  |  |          BigDecimal intonation = BigDecimal.ZERO;
 | 
	
		
			
				|  |  |          BigDecimal cadence = BigDecimal.ZERO;
 | 
	
		
			
				|  |  |          BigDecimal integrity = BigDecimal.ZERO;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +        File f = null;
 | 
	
		
			
				|  |  | +        File f_r = null;
 | 
	
		
			
				|  |  |          try {
 | 
	
		
			
				|  |  |              URL url = new URL(sysMusicScore.getUrl());
 | 
	
		
			
				|  |  | -            String filePath = FileUtils.getTempDirectoryPath()+ System.currentTimeMillis() + ".mp3";
 | 
	
		
			
				|  |  | -            File f = new File(filePath);
 | 
	
		
			
				|  |  | +            String filePath = FileUtils.getTempDirectoryPath()+ idGeneratorService.generatorId("sound") + ".mp3";
 | 
	
		
			
				|  |  | +            f = new File(filePath);
 | 
	
		
			
				|  |  |              FileUtils.copyURLToFile(url, f);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +            LOGGER.info("文件名:{},伴奏编号:{},源文件:{}", record.getOriginalFilename(), musicScoreId, filePath);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |              BigDecimal oneHandred = new BigDecimal(100);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              BigDecimal l_s = new BigDecimal(0);
 | 
	
		
			
				|  |  |              BigDecimal l_r = new BigDecimal(0);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +            String filePath_r = FileUtils.getTempDirectoryPath()+ idGeneratorService.generatorId("sound") + ".mp3";
 | 
	
		
			
				|  |  | +            f_r = new File(filePath_r);
 | 
	
		
			
				|  |  | +            FileUtils.copyToFile(record.getInputStream(), f_r);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |              //相似度
 | 
	
		
			
				|  |  | -            List<Double> pitchs_s = soundPressureLevelExtractor(null, filePath, l_s);
 | 
	
		
			
				|  |  | -            List<Double> pitchs_r = soundPressureLevelExtractor(record.getBytes(), null, l_r);
 | 
	
		
			
				|  |  | +            List<Double> pitchs_s = soundPressureLevelExtractor(null, filePath);
 | 
	
		
			
				|  |  | +//            List<Double> pitchs_r = soundPressureLevelExtractor(record.getBytes(), null);
 | 
	
		
			
				|  |  | +            List<Double> pitchs_r = soundPressureLevelExtractor(null, filePath_r);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              int maxLength = pitchs_s.size();
 | 
	
		
			
				|  |  |              if(pitchs_r.size()<maxLength){
 | 
	
		
			
				|  |  |                  maxLength = pitchs_r.size();
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            Double pitchSize = Double.valueOf(0);
 | 
	
		
			
				|  |  | -            Double allPitchGap = Double.valueOf(0);
 | 
	
		
			
				|  |  | +            if(maxLength>0){
 | 
	
		
			
				|  |  | +                l_s = new BigDecimal(pitchs_s.get(pitchs_s.size() - 1));
 | 
	
		
			
				|  |  | +                pitchs_s.remove(pitchs_s.size() - 1);
 | 
	
		
			
				|  |  | +                l_r = new BigDecimal(pitchs_r.get(pitchs_r.size() - 1));
 | 
	
		
			
				|  |  | +                pitchs_r.remove(pitchs_r.size() - 1);
 | 
	
		
			
				|  |  | +                maxLength = maxLength-1;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            double pitchSize = 0;
 | 
	
		
			
				|  |  | +            double allPitchGap = 0;
 | 
	
		
			
				|  |  |              for(int i=0;i<maxLength;i++){
 | 
	
		
			
				|  |  | -                Double pitch1 = Math.abs(pitchs_s.get(i));
 | 
	
		
			
				|  |  | -                Double pitch2 = Math.abs(pitchs_r.get(i));
 | 
	
		
			
				|  |  | -                Double pitchGap = Math.abs(pitch1-pitch2);
 | 
	
		
			
				|  |  | +                double pitch1 = Math.abs(pitchs_s.get(i));
 | 
	
		
			
				|  |  | +                double pitch2 = Math.abs(pitchs_r.get(i));
 | 
	
		
			
				|  |  | +                double pitchGap = Math.abs(pitch1-pitch2);
 | 
	
		
			
				|  |  |                  if(pitchGap>pitch1){
 | 
	
		
			
				|  |  |                      pitchGap = pitch1;
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |                  allPitchGap+=pitchGap;
 | 
	
		
			
				|  |  |                  pitchSize+=pitch1;
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | -            Double intonation_d = 1-(allPitchGap/pitchSize);
 | 
	
		
			
				|  |  | +            double intonation_d = 0;
 | 
	
		
			
				|  |  | +            if(pitchSize>0){
 | 
	
		
			
				|  |  | +                intonation_d = 1-(allPitchGap/pitchSize);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |              intonation = new BigDecimal(intonation_d).multiply(oneHandred).setScale(0, BigDecimal.ROUND_HALF_UP);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              //节奏
 | 
	
		
			
				|  |  |              List<Double> times_s = beatExtractor(null, filePath);
 | 
	
		
			
				|  |  | -            List<Double> times_r = beatExtractor(record.getBytes(), null);
 | 
	
		
			
				|  |  | +//            List<Double> times_r = beatExtractor(record.getBytes(), null);
 | 
	
		
			
				|  |  | +            List<Double> times_r = beatExtractor(null, filePath_r);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              float sameTimes = 0;
 | 
	
		
			
				|  |  |              for (Double time1 : times_s) {
 | 
	
		
			
				|  |  |                  for (Double time2 : times_r) {
 | 
	
		
			
				|  |  | -                    if(Math.abs(time2-time1)<0.1){
 | 
	
		
			
				|  |  | +                    if(Math.abs(time2-time1)<1.5){
 | 
	
		
			
				|  |  |                          sameTimes++;
 | 
	
		
			
				|  |  | +                        break;
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | -            Double cadence_d = Double.valueOf(sameTimes/times_s.size());
 | 
	
		
			
				|  |  | +            double cadence_d = 0;
 | 
	
		
			
				|  |  | +            if (times_r.size()>0){
 | 
	
		
			
				|  |  | +                cadence_d = sameTimes/times_r.size();
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |              cadence = new BigDecimal(cadence_d).multiply(oneHandred).setScale(0, BigDecimal.ROUND_HALF_UP);
 | 
	
		
			
				|  |  | -            System.out.printf("节奏:%.2f", cadence);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            integrity = new BigDecimal(1);
 | 
	
		
			
				|  |  | -            if(l_r.compareTo(l_s)<0){
 | 
	
		
			
				|  |  | -                integrity = l_r.divide(l_s, 0, BigDecimal.ROUND_HALF_UP);
 | 
	
		
			
				|  |  | +            integrity = new BigDecimal(0);
 | 
	
		
			
				|  |  | +            if(l_r.compareTo(BigDecimal.ZERO)<=0||l_s.compareTo(BigDecimal.ZERO)<=0){
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            }else if(l_r.compareTo(l_s)<0){
 | 
	
		
			
				|  |  | +                integrity = l_r.divide(l_s, CommonConstants.DECIMAL_PLACE, BigDecimal.ROUND_HALF_UP).multiply(oneHandred).setScale(0, BigDecimal.ROUND_HALF_UP);
 | 
	
		
			
				|  |  | +            }else{
 | 
	
		
			
				|  |  | +                integrity = new BigDecimal(100);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | +            integrity = integrity;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              score = intonation.add(cadence).add(integrity).divide(new BigDecimal(3), 0, BigDecimal.ROUND_HALF_UP);
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -202,9 +233,15 @@ public class SoundServiceImpl implements SoundService {
 | 
	
		
			
				|  |  |              e.printStackTrace();
 | 
	
		
			
				|  |  |          } catch (IOException e) {
 | 
	
		
			
				|  |  |              e.printStackTrace();
 | 
	
		
			
				|  |  | +        }finally {
 | 
	
		
			
				|  |  | +            if(f!=null){
 | 
	
		
			
				|  |  | +                f.delete();
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            if(f_r!=null){
 | 
	
		
			
				|  |  | +                f_r.delete();
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |          result.put("score", score);
 | 
	
		
			
				|  |  |          result.put("intonation", intonation);
 | 
	
		
			
				|  |  |          result.put("cadence", cadence);
 |