yonge 2 years ago
parent
commit
2b005b77cd

+ 18 - 8
audio-analysis/src/main/java/com/yonge/netty/dto/UserChannelContext.java

@@ -50,6 +50,8 @@ public class UserChannelContext {
 	
 	private float offsetMS;
 	
+	private float micDelayMS;
+	
 	private double dynamicOffset;
 	
 	private String platform;
@@ -161,6 +163,14 @@ public class UserChannelContext {
 		this.offsetMS = offsetMS;
 	}
 
+	public float getMicDelayMS() {
+		return micDelayMS;
+	}
+
+	public void setMicDelayMS(float micDelayMS) {
+		this.micDelayMS = micDelayMS;
+	}
+
 	public float getBeatDuration() {
 		return beatDuration;
 	}
@@ -356,6 +366,8 @@ public class UserChannelContext {
 			return;
 		}
 		
+		musicXmlNote.setTimeStamp(musicXmlNote.getTimeStamp() + micDelayMS);
+		
 		//取出当前处理中的音符信息
 		NoteAnalysis noteAnalysis = getProcessingNote();
 		if(noteAnalysis == null || noteAnalysis.getDurationTime() == 0) {
@@ -377,16 +389,14 @@ public class UserChannelContext {
 			}
 			totalChunkAnalysisList.add(chunkAnalysis);
 			
-			boolean flag = false; //是否收到有效信号
-			if(!StringUtils.equalsIgnoreCase(evaluationCriteria, EvaluationCriteriaEnum.FREQUENCY.getCode())){
-				flag = chunkAnalysis.getAmplitude() > hardLevel.getAmplitudeThreshold();
+			//是否收到有效信号
+			/*if(!StringUtils.equalsIgnoreCase(evaluationCriteria, EvaluationCriteriaEnum.FREQUENCY.getCode())){
+				delayProcessed = chunkAnalysis.getAmplitude() > hardLevel.getAmplitudeThreshold();
 			}else{
-				flag = chunkAnalysis.getFrequency() > MIN_FREQUECY && chunkAnalysis.getFrequency() < MAX_FREQUECY;
+				delayProcessed = chunkAnalysis.getFrequency() > MIN_FREQUECY && chunkAnalysis.getFrequency() < MAX_FREQUECY;
 			}
 			
-			if(delayProcessed == false && flag){
-				
-				delayProcessed = true;
+			if(delayProcessed){
 				
 				//计算延迟偏移值
 				//playTime = musicXmlNote.getTimeStamp() + durationTime;
@@ -394,7 +404,7 @@ public class UserChannelContext {
 				if(100 * dynamicOffset / musicXmlNote.getDuration() > (100 - hardLevel.getTempoEffectiveRange(musicXmlNote.getDenominator(), musicXmlNote.getDuration()))){
 					dynamicOffset = 0;
 				}
-			}
+			}*/
 			
 			if (playTime >= (musicXmlNote.getDuration() + musicXmlNote.getTimeStamp() + dynamicOffset)) {
 

+ 3 - 0
audio-analysis/src/main/java/com/yonge/netty/server/service/AudioCompareHandler.java

@@ -233,6 +233,9 @@ public class AudioCompareHandler implements MessageHandler {
 			break;
 		case "audioPlayStart": // ???
 			
+			Integer micDelay = dataObj.getInteger("micDelay");
+			channelContext.setMicDelayMS(micDelay);
+			
 			Integer offsetTime = dataObj.getInteger("offsetTime");
 			if(offsetTime != null){
 				channelContext.setOffsetMS(offsetTime);

+ 109 - 0
audio-analysis/src/main/java/com/yonge/netty/server/service/DelayCheckHandler.java

@@ -0,0 +1,109 @@
+package com.yonge.netty.server.service;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.sound.sampled.AudioFormat;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.alibaba.fastjson.JSONPath;
+import com.yonge.audio.analysis.AudioFloatConverter;
+import com.yonge.audio.analysis.detector.YINPitchDetector;
+import com.yonge.netty.dto.WebSocketResponse;
+import com.yonge.netty.server.handler.NettyChannelManager;
+import com.yonge.netty.server.handler.message.MessageHandler;
+
+import io.netty.channel.Channel;
+
+public class DelayCheckHandler implements MessageHandler {
+	
+	private final static Logger LOGGER = LoggerFactory.getLogger(DelayCheckHandler.class);
+	
+	private final static int MIN_FREQUECY = 43;
+
+	/**
+	 * @describe 采样率
+	 */
+	private float sampleRate = 44100;
+
+	/**
+	 * 每个采样大小(Bit)
+	 */
+	private int bitsPerSample = 16;
+
+	/**
+	 * 通道数
+	 */
+	private int channels = 1;
+	
+	private boolean signed = true;
+
+	private boolean bigEndian = false;
+
+	private AudioFormat audioFormat = new AudioFormat(sampleRate, bitsPerSample, channels, signed, bigEndian);
+
+	private AudioFloatConverter converter = AudioFloatConverter.getConverter(audioFormat);
+	
+	private double playTime;
+	
+	@Autowired
+	private NettyChannelManager nettyChannelManager;
+
+	@Override
+	public String getAction() {
+		return "DELAY_CHECK";
+	}
+
+	@Override
+	public boolean handleTextMessage(String userId, Channel channel, String jsonMsg) {
+		
+		String command = (String) JSONPath.extract(jsonMsg, "$.header.commond");
+		
+		switch (command) {
+		case "recordEnd":
+			
+			Map<String, Object> params = new HashMap<String, Object>();
+			params.put("firstNoteDelayDuration", playTime);
+
+			WebSocketResponse<Map<String, Object>> resp = new WebSocketResponse<Map<String, Object>>(getAction(), params);
+
+			nettyChannelManager.sendTextMessage(userId, resp);
+			break;
+
+		default:
+			break;
+		}
+		
+		return true;
+	}
+
+	@Override
+	public boolean handleBinaryMessage(String userId, Channel channel, byte[] bytes) {
+		
+		float[] samples = new float[bytes.length / 2];
+
+		if (samples.length == 0) {
+			return false;
+		}
+
+		converter.toFloatArray(bytes, samples);
+
+		YINPitchDetector frequencyDetector = new YINPitchDetector(samples.length, audioFormat.getSampleRate());
+
+		int playFrequency = (int) frequencyDetector.getFrequency(samples);
+		
+		if(playFrequency > MIN_FREQUECY) {
+			return true;
+		}
+		
+		double durationTime = 1000 * (samples.length * 2) / audioFormat.getSampleRate() / (audioFormat.getSampleSizeInBits() / 8);
+		
+		playTime += durationTime;
+
+		return true;
+	}
+
+}