Browse Source

最新版

yonge 3 months ago
parent
commit
f2c071bcb6

+ 58 - 26
audio-analysis/pom.xml

@@ -18,113 +18,145 @@
 
 	<dependencies>
 		<dependency>
-			<groupId>org.springframework.cloud</groupId>
-			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
+			<groupId>org.apache.commons</groupId>
+			<artifactId>commons-math3</artifactId>
+			<version>3.6.1</version>
 		</dependency>
 
 		<dependency>
-			<groupId>org.springframework.cloud</groupId>
-			<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+			<groupId>
+				org.springframework.cloud</groupId>
+			<artifactId>
+				spring-cloud-starter-netflix-eureka-client</artifactId>
 		</dependency>
 
 		<dependency>
-			<groupId>de.codecentric</groupId>
+			<groupId>
+				org.springframework.cloud</groupId>
+			<artifactId>
+				spring-cloud-starter-alibaba-nacos-config</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>
+				de.codecentric</groupId>
 			<artifactId>spring-boot-admin-starter-client</artifactId>
 		</dependency>
 
 		<!-- swagger-spring-boot -->
 		<dependency>
-			<groupId>com.spring4all</groupId>
+			<groupId>
+				com.spring4all</groupId>
 			<artifactId>swagger-spring-boot-starter</artifactId>
 		</dependency>
 
 		<dependency>
-			<groupId>com.github.xiaoymin</groupId>
+			<groupId>
+				com.github.xiaoymin</groupId>
 			<artifactId>swagger-bootstrap-ui</artifactId>
 		</dependency>
 
 		<dependency>
-			<groupId>com.alibaba</groupId>
+			<groupId>
+				com.alibaba</groupId>
 			<artifactId>druid-spring-boot-starter</artifactId>
 		</dependency>
 
 		<dependency>
-			<groupId>mysql</groupId>
+			<groupId>
+				mysql</groupId>
 			<artifactId>mysql-connector-java</artifactId>
 		</dependency>
 
 		<dependency>
-			<groupId>com.ym</groupId>
+			<groupId>
+				com.ym</groupId>
 			<artifactId>mec-auth-api</artifactId>
 			<exclusions>
 				<exclusion>
 					<artifactId>netty-common</artifactId>
-					<groupId>io.netty</groupId>
+					<groupId>
+						io.netty</groupId>
 				</exclusion>
 				<exclusion>
-					<artifactId>netty-transport</artifactId>
+					<artifactId>
+						netty-transport</artifactId>
 					<groupId>io.netty</groupId>
 				</exclusion>
 				<exclusion>
-					<artifactId>netty-resolver</artifactId>
+					<artifactId>
+						netty-resolver</artifactId>
 					<groupId>io.netty</groupId>
 				</exclusion>
 				<exclusion>
-					<artifactId>netty-buffer</artifactId>
+					<artifactId>
+						netty-buffer</artifactId>
 					<groupId>io.netty</groupId>
 				</exclusion>
 				<exclusion>
-					<artifactId>netty-resolver-dns</artifactId>
+					<artifactId>
+						netty-resolver-dns</artifactId>
 					<groupId>io.netty</groupId>
 				</exclusion>
 				<exclusion>
-					<artifactId>netty-handler</artifactId>
+					<artifactId>
+						netty-handler</artifactId>
 					<groupId>io.netty</groupId>
 				</exclusion>
 				<exclusion>
-					<artifactId>netty-codec</artifactId>
+					<artifactId>
+						netty-codec</artifactId>
 					<groupId>io.netty</groupId>
 				</exclusion>
 			</exclusions>
 		</dependency>
 
 		<dependency>
-			<groupId>com.ym</groupId>
+			<groupId>
+				com.ym</groupId>
 			<artifactId>mec-biz</artifactId>
 			<exclusions>
 				<exclusion>
 					<artifactId>netty-common</artifactId>
-					<groupId>io.netty</groupId>
+					<groupId>
+						io.netty</groupId>
 				</exclusion>
 				<exclusion>
-					<artifactId>netty-transport</artifactId>
+					<artifactId>
+						netty-transport</artifactId>
 					<groupId>io.netty</groupId>
 				</exclusion>
 				<exclusion>
-					<artifactId>netty-resolver</artifactId>
+					<artifactId>
+						netty-resolver</artifactId>
 					<groupId>io.netty</groupId>
 				</exclusion>
 				<exclusion>
-					<artifactId>netty-buffer</artifactId>
+					<artifactId>
+						netty-buffer</artifactId>
 					<groupId>io.netty</groupId>
 				</exclusion>
 				<exclusion>
-					<artifactId>netty-resolver-dns</artifactId>
+					<artifactId>
+						netty-resolver-dns</artifactId>
 					<groupId>io.netty</groupId>
 				</exclusion>
 				<exclusion>
-					<artifactId>netty-handler</artifactId>
+					<artifactId>
+						netty-handler</artifactId>
 					<groupId>io.netty</groupId>
 				</exclusion>
 				<exclusion>
-					<artifactId>netty-codec</artifactId>
+					<artifactId>
+						netty-codec</artifactId>
 					<groupId>io.netty</groupId>
 				</exclusion>
 			</exclusions>
 		</dependency>
 
 		<dependency>
-			<groupId>io.netty</groupId>
+			<groupId>
+				io.netty</groupId>
 			<artifactId>netty-all</artifactId>
 			<version>4.1.68.Final</version>
 		</dependency>

+ 5 - 5
audio-analysis/src/main/java/com/yonge/audio/analysis/Signals.java

@@ -15,14 +15,14 @@ public class Signals {
 		return mean;
 	}
 
-	public static float energy(float[] signal) {
-		float totalEnergy = 0;
+	public static double energy(float[] signal) {
+		double totalEnergy = 0;
 		for (int i = 0; i < signal.length; i++)
 			totalEnergy += Math.pow(signal[i], 2);
 		return totalEnergy;
 	}
 
-	public static float power(float[] signal) {
+	public static double power(float[] signal) {
 		return energy(signal) / signal.length;
 	}
 
@@ -55,9 +55,9 @@ public class Signals {
 		}
 	}
 
-	public static float rms(float[] samples) {
+	public static double rms(float[] samples) {
 		// 均方根 (RMS) 功率
-		return (float) Math.sqrt(power(samples));
+		return Math.sqrt(power(samples));
 
 	}
 

+ 15 - 0
audio-analysis/src/main/java/com/yonge/audio/analysis/detector/YINPitchDetector.java

@@ -62,6 +62,17 @@ public class YINPitchDetector {
 		}
 		return pitchInAbsCent;
 	}
+	
+	public static double getDeviationCent(final double hertzValue, final double targetHertzValue) {
+		if (targetHertzValue < 0) {
+			return 0;
+		}
+		double pitchInAbsCent = 0.0;
+		if (hertzValue > 0) {
+			pitchInAbsCent = 1200 * Math.log(hertzValue / targetHertzValue) / LOG_TWO;
+		}
+		return pitchInAbsCent;
+	}
 
     public double getFrequency(float[] wave) {
         int tau;
@@ -220,4 +231,8 @@ public class YINPitchDetector {
 
         return betterTau;
     }
+    
+    public static void main(String[] args) {
+    	System.out.println(YINPitchDetector.getDeviationCent(353, 342));
+	}
 }

+ 16 - 8
audio-analysis/src/main/java/com/yonge/netty/dto/ChunkAnalysis.java

@@ -1,5 +1,8 @@
 package com.yonge.netty.dto;
 
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.logging.log4j.util.StringBuilders;
+
 public class ChunkAnalysis {
 
 	private double startTime;
@@ -10,15 +13,15 @@ public class ChunkAnalysis {
 
 	private int frequency;
 
-	private int splDb;
+	private double splDb;
 
-	private float power;
+	private double power;
 	
 	private int amplitude;
 	
 	private boolean isPeak;
 
-	public ChunkAnalysis(double startTime, double endTime, int frequency, int splDb, float power, int amplitude) {
+	public ChunkAnalysis(double startTime, double endTime, int frequency, double splDb, double power, int amplitude) {
 		this.startTime = startTime;
 		this.endTime = endTime;
 		this.frequency = frequency;
@@ -28,7 +31,7 @@ public class ChunkAnalysis {
 		this.durationTime = endTime - startTime;
 	}
 
-	public ChunkAnalysis(int frequency, int splDb, int power) {
+	public ChunkAnalysis(int frequency, double splDb, double power) {
 		this.frequency = frequency;
 		this.splDb = splDb;
 		this.power = power;
@@ -66,19 +69,19 @@ public class ChunkAnalysis {
 		this.frequency = frequency;
 	}
 
-	public int getSplDb() {
+	public double getSplDb() {
 		return splDb;
 	}
 
-	public void setSplDb(int splDb) {
+	public void setSplDb(double splDb) {
 		this.splDb = splDb;
 	}
 
-	public float getPower() {
+	public double getPower() {
 		return power;
 	}
 
-	public void setPower(float power) {
+	public void setPower(double power) {
 		this.power = power;
 	}
 
@@ -97,4 +100,9 @@ public class ChunkAnalysis {
 	public void setPeak(boolean isPeak) {
 		this.isPeak = isPeak;
 	}
+
+	@Override
+	public String toString() {
+		return ToStringBuilder.reflectionToString(this);
+	}
 }

+ 7 - 14
audio-analysis/src/main/java/com/yonge/netty/dto/HardLevelEnum.java

@@ -4,33 +4,31 @@ import com.ym.mec.common.enums.BaseEnum;
 
 public enum HardLevelEnum implements BaseEnum<String, HardLevelEnum> {
 	/**
-	 * 入门级, 振幅阈值, 频率阈值 <br>
+	 * 入门级, 振幅阈值 <br>
 	 * 节奏有效范围(1分音符), 节奏有效范围(2分音符), 节奏有效范围(4分音符), 节奏有效范围(8分音符), 节奏有效范围(16分音符), 节奏有效范围(32分音符)<br>
 	 * 完成度范围, 未演奏的范围
 	 */
 	//BEGINNER("入门级", 3, 5, 5, 5, 10, 10, 13, 15, 60, 10), 
-	BEGINNER("入门级", 3, 5, 10, 10, 15, 15, 22, 22, 75, 10), 
+	BEGINNER("入门级", 3, 10, 10, 15, 15, 22, 22, 75, 10), 
 	/**
-	 * 进阶级, 振幅阈值, 频率阈值 <br>
+	 * 进阶级, 振幅阈值 <br>
 	 * 节奏有效范围(1分音符), 节奏有效范围(2分音符), 节奏有效范围(4分音符), 节奏有效范围(8分音符), 节奏有效范围(16分音符), 节奏有效范围(32分音符)<br>
 	 * 完成度范围, 未演奏的范围
 	 */
-	ADVANCED("进阶级", 3, 5, 8, 8, 12, 12, 20, 20, 85, 15),
+	ADVANCED("进阶级", 3, 8, 8, 12, 12, 20, 20, 85, 15),
 	//ADVANCED("进阶级", 3, 5, 50, 50, 50, 50, 50, 5, 80, 10),
 	/**
-	 * 大师级, 振幅阈值, 频率阈值 <br>
+	 * 大师级, 振幅阈值 <br>
 	 * 节奏有效范围(1分音符), 节奏有效范围(2分音符), 节奏有效范围(4分音符), 节奏有效范围(8分音符), 节奏有效范围(16分音符), 节奏有效范围(32分音符)<br>
 	 * 完成度范围, 未演奏的范围
 	 */
 	//PERFORMER("大师级", 3, 3, 3, 5, 10, 10, 13, 15, 95, 10);
-	PERFORMER("大师级", 3, 3, 3, 3, 6, 8, 13, 15, 95, 10);
+	PERFORMER("大师级", 3, 3, 3, 6, 8, 13, 15, 95, 10);
 
 	private String msg;
 
 	private int amplitudeThreshold;
 
-	private int frequencyThreshold;
-
 	private int tempoEffectiveRangeOf1;
 
 	private int tempoEffectiveRangeOf2;
@@ -61,12 +59,11 @@ public enum HardLevelEnum implements BaseEnum<String, HardLevelEnum> {
 	 * @param integrityRange 完成度范围
 	 * @param notPlayRange 未演奏的范围
 	 */
-	HardLevelEnum(String msg, int amplitudeThreshold, int frequencyThreshold, int tempoEffectiveRangeOf1, int tempoEffectiveRangeOf2,
+	HardLevelEnum(String msg, int amplitudeThreshold, int tempoEffectiveRangeOf1, int tempoEffectiveRangeOf2,
 			int tempoEffectiveRangeOf4, int tempoEffectiveRangeOf8, int tempoEffectiveRangeOf16, int tempoEffectiveRangeOf32, int integrityRange,
 			int notPlayRange) {
 		this.msg = msg;
 		this.amplitudeThreshold = amplitudeThreshold;
-		this.frequencyThreshold = frequencyThreshold;
 		this.tempoEffectiveRangeOf1 = tempoEffectiveRangeOf1;
 		this.tempoEffectiveRangeOf2 = tempoEffectiveRangeOf2;
 		this.tempoEffectiveRangeOf4 = tempoEffectiveRangeOf4;
@@ -85,10 +82,6 @@ public enum HardLevelEnum implements BaseEnum<String, HardLevelEnum> {
 		return amplitudeThreshold;
 	}
 
-	public int getFrequencyThreshold() {
-		return frequencyThreshold;
-	}
-
 	public int getTempoEffectiveRange(int denominator, double duration) {
 		
 		int tempoEffectiveRange = 0;

+ 58 - 5
audio-analysis/src/main/java/com/yonge/netty/dto/NoteAnalysis.java

@@ -34,10 +34,19 @@ public class NoteAnalysis {
 	private double durationTime;
 
 	private int frequency;
+	
+	private double dBSPL;
+	
+	private double amplitude;
+	
+	private double power;
+	
+	private double decibels;
 
 	private int playFrequency = -1;
 
-	private boolean tempo = true;
+	//节奏状态(0-节奏错误,1-音高识别的节奏,2-声压识别的节奏,3-振幅识别的节奏,99-其他)
+	private int tempoStatus = 0;
 
 	private NoteErrorType noteErrorType = NoteErrorType.RIGHT;
 
@@ -116,12 +125,20 @@ public class NoteAnalysis {
 		this.frequency = frequency;
 	}
 
-	public boolean isTempo() {
-		return tempo;
+	/**
+	 * 节奏状态(-1-未演奏,0-节奏错误,1-音高识别的节奏,2-声压识别的节奏,3-振幅识别的节奏,99-其他)
+	 * @return
+	 */
+	public int getTempoStatus() {
+		return tempoStatus;
 	}
 
-	public void setTempo(boolean tempo) {
-		this.tempo = tempo;
+	/**
+	 * 节奏状态(0-节奏错误,1-音高识别的节奏,2-声压识别的节奏,3-振幅识别的节奏,99-其他)
+	 * @param tempoStatus
+	 */
+	public void setTempoStatus(int tempoStatus) {
+		this.tempoStatus = tempoStatus;
 	}
 
 	public int getSectionIndex() {
@@ -184,4 +201,40 @@ public class NoteAnalysis {
 		return measureRenderIndex;
 	}
 
+	public double getDBSPL() {
+		return dBSPL;
+	}
+
+	public void setDBSPL(double dBSPL) {
+		this.dBSPL = dBSPL;
+	}
+
+	public double getAmplitude() {
+		return amplitude;
+	}
+
+	public void setAmplitude(double amplitude) {
+		this.amplitude = amplitude;
+	}
+
+	public double getPower() {
+		return power;
+	}
+
+	public void setPower(double power) {
+		this.power = power;
+	}
+
+	public double getDecibels() {
+		return decibels;
+	}
+
+	public void setDecibels(double decibels) {
+		this.decibels = decibels;
+	}
+
+	public int getIndex() {
+		return index;
+	}
+
 }

File diff suppressed because it is too large
+ 582 - 460
audio-analysis/src/main/java/com/yonge/netty/dto/UserChannelContext.java


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

@@ -331,6 +331,8 @@ public class AudioCompareHandler implements MessageHandler {
 			float[] sampleFloats = new float[bufferSize / 2];
 
 			converter.toFloatArray(bufferData, sampleFloats);
+			
+			//hanning(sampleFloats);
 
 			channelContext.handle(sampleFloats, audioFormat);
 
@@ -357,4 +359,16 @@ public class AudioCompareHandler implements MessageHandler {
 		return true;
 	}
 
+	
+	public static void hamming(float[] samples) {
+		for (int i = 0; i < samples.length; i++) {
+			samples[i] *= (0.54f - 0.46f * Math.cos((2 * Math.PI) * i / (samples.length - 1)));
+		}
+	}
+	
+	public static void hanning(float[] samples) {
+		for (int i = 0; i < samples.length; i++) {
+			samples[i] *= 0.5 * (1 + Math.cos((2 * Math.PI) * i / (samples.length - 1)));
+		}
+	}
 }

+ 4 - 5
audio-analysis/src/test/java/com/yonge/netty/client/NettyClient.java

@@ -53,8 +53,7 @@ public class NettyClient {
 			 */
 			b.channel(NioSocketChannel.class);
 			/**设置选项
-			 * 参数:Socket的标准参数(key,value),可自行百度
-			   保持呼吸,不要断气!
+			 * 参数:Socket的标准参数(key,value)
 			 * */
 			b.option(ChannelOption.SO_KEEPALIVE, true);
 			
@@ -90,11 +89,11 @@ public class NettyClient {
 			String step2 = "{\"header\":{\"commond\":\"recordStart\",\"type\":\"SOUND_COMPARE\",\"status\":200}}";
 			channel.writeAndFlush(new TextWebSocketFrame(step2));
 			
-			String step3 = "{\"body\":{\"micDelay\":18,\"offsetTime\":178},\"uuid\":\"1662715309875118846\",\"header\":{\"commond\":\"audioPlayStart\",\"type\":\"SOUND_COMPARE\"}}";
+			String step3 = "{\"body\":{\"micDelay\":-1,\"offsetTime\":2274},\"uuid\":\"1662715309875118846\",\"header\":{\"commond\":\"audioPlayStart\",\"type\":\"SOUND_COMPARE\"}}";
 			channel.writeAndFlush(new TextWebSocketFrame(step3));
-			
+			//51. "micDelay\":122,\"offsetTime\":431
 			//step4 发送wav
-			String fileName = "/84.wav";
+			String fileName = "/2265947_2406111127832.wav";
 			AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(FileUtils.toFile(WebSocketClientHandler.class.getResource(fileName)));
 			
 			AudioFormat baseFormat = audioInputStream.getFormat();

File diff suppressed because it is too large
+ 1 - 1
audio-analysis/src/test/resoures/9550.json