浏览代码

Merge branch 'vip_group_activity'

Joburgess 4 年之前
父节点
当前提交
743e9202cc

+ 68 - 31
mec-biz/src/main/java/com/ym/mec/biz/service/impl/SoundServiceImpl.java

@@ -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);

+ 0 - 3
mec-teacher/src/main/java/com/ym/mec/teacher/controller/SoundController.java

@@ -23,15 +23,12 @@ import org.springframework.web.multipart.MultipartFile;
 @RestController
 public class SoundController extends BaseController {
 
-    private final Logger LOGGER = LoggerFactory.getLogger(SoundController.class);
-
     @Autowired
     private SoundService soundService;
 
     @ApiOperation(value = "评分")
     @PostMapping("compare")
     public HttpResponseResult compare(@RequestParam("record") MultipartFile record, Integer musicScoreId){
-        LOGGER.info("文件名:{},伴奏编号:{}", record.getOriginalFilename(), musicScoreId);
         return soundService.compare(record, musicScoreId);
     }