Main.java 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. package com.yonge;
  2. import be.tarsos.dsp.AudioDispatcher;
  3. import be.tarsos.dsp.AudioEvent;
  4. import be.tarsos.dsp.AudioProcessor;
  5. import be.tarsos.dsp.io.jvm.JVMAudioInputStream;
  6. import be.tarsos.dsp.mfcc.MFCC;
  7. import be.tarsos.dsp.pitch.FastYin;
  8. import be.tarsos.dsp.pitch.PitchDetectionHandler;
  9. import be.tarsos.dsp.pitch.PitchDetectionResult;
  10. import be.tarsos.dsp.pitch.PitchProcessor;
  11. import com.yonge.audio.analysis.AudioFloatConverter;
  12. import com.yonge.audio.analysis.detector.YINPitchDetector;
  13. import com.yonge.audio.utils.ArrayUtil;
  14. import com.yonge.netty.server.processor.WaveformWriter;
  15. import org.apache.commons.io.IOUtils;
  16. import org.apache.commons.lang3.ArrayUtils;
  17. import javax.sound.sampled.AudioFormat;
  18. import javax.sound.sampled.AudioInputStream;
  19. import javax.sound.sampled.AudioSystem;
  20. import javax.sound.sampled.UnsupportedAudioFileException;
  21. import java.io.*;
  22. import java.net.URL;
  23. import java.util.Arrays;
  24. import java.util.Date;
  25. /**
  26. * Description
  27. *
  28. * @author liujunchi
  29. * @date 2022-06-24
  30. */
  31. public class Main {
  32. private final static int audioBufferSize = 2048;
  33. private final static int bufferOverlap = 1024;
  34. private final static int amountOfMelFilters = 20;
  35. private final static int amountOfCepstrumCoef = 30;
  36. private final static float lowerFilterFreq = 133.33f;
  37. private final static float upperFilterFreq = 8000f;
  38. private static AudioFormat audioFormat = new AudioFormat(44100, 16, 1, true, false);
  39. // private AudioFloatConverter converter = AudioFloatConverter.getConverter(audioFormat);
  40. public static void main(String[] args){
  41. try{
  42. float sampleRate = 44100;
  43. int audioBufferSize = 1024 *2;
  44. int bufferOverlap = 0;
  45. AudioFloatConverter converter = AudioFloatConverter.getConverter(audioFormat);
  46. //Create an AudioInputStream from my .wav file
  47. URL soundURL = Main.class.getResource("/WAV.wav");
  48. AudioInputStream stream = AudioSystem.getAudioInputStream(soundURL);
  49. // final MFCC mfccProcessor = new MFCC(audioBufferSize, stream.getFormat().getSampleRate(),
  50. // amountOfCepstrumCoef, amountOfMelFilters, lowerFilterFreq, upperFilterFreq);
  51. FastYin detector = new FastYin(sampleRate, audioBufferSize *2);
  52. byte[] bytes = IOUtils.toByteArray(stream);
  53. AudioFormat format = stream.getFormat();
  54. int b = 0;
  55. int frequency = 0;
  56. File file = new File("D:\\project\\cooleshow\\audio-analysis\\target\\wav1.wav");
  57. WaveformWriter waveFileProcessor = new WaveformWriter(file.getAbsolutePath());
  58. byte[] bytes1 = new byte[0];
  59. // for (int i = 0; i < bytes.length; i++) {
  60. // if (i%2 ==1) {
  61. // System.out.println(bytes[i] + "----------" + bytes[i-1]);
  62. // }
  63. // }
  64. while (bytes.length > audioBufferSize *2) {
  65. byte[] bufferData = ArrayUtil.extractByte(bytes, 0, audioBufferSize*2 - 1);
  66. bytes1 = ArrayUtil.mergeByte(bytes1, bufferData);
  67. byte[] bytes2 = new byte[bytes1.length *2];
  68. for (int i = 0; i < bytes1.length; i =i+2) {
  69. bytes2[(i+1) *2] = bytes2[i*2] = bytes1[i];
  70. bytes2[(i+1) *2 +1] = bytes2[i*2 + 1] = bytes1[i +1];
  71. }
  72. // byte ff = bytes1[bytes1.length -1];
  73. // for (int start = 0, end = bytes1.length - 2; start < end; start++, end--) {
  74. // byte temp = bytes1[end];
  75. // bytes1[end] = bytes1[start];
  76. // bytes1[start] = temp;
  77. // }
  78. // bytes1[bytes1.length -1] = ff;
  79. //
  80. // bytes1 = ArrayUtil.mergeByte(bufferData, bytes1);
  81. if (bytes2.length == audioBufferSize *4) {
  82. waveFileProcessor.process(bytes2);
  83. float[] sampleFloats = new float[audioBufferSize *2];
  84. converter.toFloatArray(bytes2, sampleFloats);
  85. int playFrequency = (int) detector.getPitch(sampleFloats).getPitch();
  86. if (playFrequency != -1) {
  87. System.out.println("play frequency is " + playFrequency);
  88. }
  89. bytes1 = new byte[0];
  90. }
  91. // YINPitchDetector frequencyDetector = new YINPitchDetector(sampleFloats.length, audioFormat.getSampleRate());
  92. //
  93. // playFrequency = (int) frequencyDetector.getFrequency(sampleFloats);
  94. //
  95. // System.out.println("frequencyDetector play frequency is " + playFrequency);
  96. // ArrayUtil.extractByte(channelContext.getChannelBufferBytes(), bufferSize, totalLength - 1)
  97. bytes = ArrayUtil.extractByte(bytes, audioBufferSize, bytes.length - 1);
  98. // if (b == 1) {
  99. // frequency += playFrequency;
  100. // System.out.println("play frequency is " +frequency/2);
  101. // b = 0;
  102. // frequency = 0;
  103. // } else {
  104. // frequency += playFrequency;
  105. // b ++;
  106. // }
  107. }
  108. waveFileProcessor.processingFinished();
  109. //Convert into TarsosDSP API
  110. // JVMAudioInputStream audioStream = new JVMAudioInputStream(stream);
  111. // AudioDispatcher dispatcher = new AudioDispatcher(audioStream, audioBufferSize, bufferOverlap);
  112. // MyPitchDetector myPitchDetector = new MyPitchDetector();
  113. // dispatcher.addAudioProcessor(mfccProcessor);
  114. // dispatcher.addAudioProcessor(new AudioProcessor() {
  115. // @Override
  116. // public boolean process(AudioEvent audioEvent) {
  117. // float[] mfccs = mfccProcessor.getMFCC();
  118. //
  119. // // System.out.println(Arrays.toString(mfccs));
  120. //
  121. // YINPitchDetector frequencyDetector = new YINPitchDetector(mfccs.length, sampleRate);
  122. //
  123. // int playFrequency = (int)detector.getPitch(audioEvent.getFloatBuffer()).getPitch();
  124. // // int playFrequency = (int) frequencyDetector.getFrequency(mfccs);
  125. // System.out.println("play frequency is " +playFrequency);
  126. // return true;
  127. // }
  128. //
  129. // @Override
  130. // public void processingFinished() {
  131. //
  132. // }
  133. // });
  134. // // dispatcher.addAudioProcessor(new MyPitchProcessor(PitchProcessor.PitchEstimationAlgorithm.FFT_YIN, sampleRate, audioBufferSize, myPitchDetector));
  135. // dispatcher.run();
  136. }
  137. catch(FileNotFoundException fne){fne.printStackTrace();}
  138. catch(UnsupportedAudioFileException uafe){uafe.printStackTrace();}
  139. catch(IOException ie){ie.printStackTrace();}
  140. }
  141. }
  142. class MyPitchDetector implements PitchDetectionHandler {
  143. //Here the result of pitch is always less than half.
  144. @Override
  145. public void handlePitch(PitchDetectionResult pitchDetectionResult,
  146. AudioEvent audioEvent) {
  147. if(pitchDetectionResult.getPitch() != -1){
  148. double timeStamp = audioEvent.getTimeStamp();
  149. float pitch = pitchDetectionResult.getPitch();
  150. float probability = pitchDetectionResult.getProbability();
  151. double rms = audioEvent.getRMS() * 100;
  152. String message = String.format("Pitch detected at %.2fs: %.2fHz ( %.2f probability, RMS: %.5f )\n", timeStamp,pitch,probability,rms);
  153. System.out.println(message);
  154. }
  155. }
  156. }
  157. class MyPitchProcessor extends PitchProcessor {
  158. /**
  159. * Initialize a new pitch processor.
  160. *
  161. * @param algorithm An enum defining the algorithm.
  162. * @param sampleRate The sample rate of the buffer (Hz).
  163. * @param bufferSize The size of the buffer in samples.
  164. * @param handler
  165. */
  166. public MyPitchProcessor(PitchEstimationAlgorithm algorithm, float sampleRate, int bufferSize, PitchDetectionHandler handler) {
  167. super(algorithm, sampleRate, bufferSize, handler);
  168. }
  169. @Override
  170. public boolean process(AudioEvent audioEvent) {
  171. return super.process(audioEvent);
  172. }
  173. }