Java 如何修改WhistAPI以获得另一种声音
我想修改WhistAPI以用于另一种我想检测的声音。我想知道如何定义这些属性的值以及如何检测Java 如何修改WhistAPI以获得另一种声音,java,android,audio,detection,musicg,Java,Android,Audio,Detection,Musicg,我想修改WhistAPI以用于另一种我想检测的声音。我想知道如何定义这些属性的值以及如何检测 public WhistleApi(int sampleRate, int bitsPerSample, int channel) { this.numFrequencyUnit = this.fftSampleSize / 2; this.unitFrequency = (double)this.sampleRate / 2.0D / (double)this.numFrequency
public WhistleApi(int sampleRate, int bitsPerSample, int channel) {
this.numFrequencyUnit = this.fftSampleSize / 2;
this.unitFrequency = (double)this.sampleRate / 2.0D / (double)this.numFrequencyUnit;
this.passFrequency = 400.0D;
this.passIntensity = 100.0D;
this.passStandardDeviation = 0.2D;
this.highPass = 400;
this.lowPass = 4000;
this.minNumZeroCross = 60;
this.maxNumZeroCross = 90;
this.numRobust = 2;
this.sampleRate = sampleRate;
this.bitsPerSample = bitsPerSample;
if(channel != 1) {
System.out.println("Support mono channel only.");
}
}
public boolean isWhistle(byte[] audioBytes) {
int bytesPerSample = this.bitsPerSample / 8;
int numSamples = audioBytes.length / bytesPerSample;
if(Integer.bitCount(numSamples) == 1) {
this.fftSampleSize = numSamples;
short[] amplitudes = this.getAmplitudes(audioBytes, this.bitsPerSample);
double[] spectrum = this.getSpectrum(amplitudes);
double intensity = 0.0D;
int lowerBoundary;
for(lowerBoundary = 0; lowerBoundary < spectrum.length; ++lowerBoundary) {
intensity += spectrum[lowerBoundary];
}
intensity /= (double)spectrum.length;
this.normalizeSpectrum(spectrum);
lowerBoundary = (int)((double)this.highPass / this.unitFrequency);
int upperBoundary = (int)((double)this.lowPass / this.unitFrequency);
double[] temp = new double[upperBoundary - lowerBoundary + 1];
System.arraycopy(spectrum, lowerBoundary, temp, 0, temp.length);
StandardDeviation standardDeviation = new StandardDeviation();
standardDeviation.setValues(temp);
double sd = standardDeviation.evaluate();
if(sd < this.passStandardDeviation) {
ArrayRankDouble arrayRankDouble = new ArrayRankDouble();
double maxFrequency = (double)arrayRankDouble.getMaxValueIndex(temp) * this.unitFrequency;
double[] robustFrequencies = new double[this.numRobust];
double nthValue = arrayRankDouble.getNthOrderedValue(temp, this.numRobust, false);
int count = 0;
for(int pitchHandler = lowerBoundary; pitchHandler <= upperBoundary; ++pitchHandler) {
if(spectrum[pitchHandler] >= nthValue) {
robustFrequencies[count++] = (double)pitchHandler * this.unitFrequency;
if(count >= this.numRobust) {
break;
}
}
}
PitchHandler var25 = new PitchHandler();
if(maxFrequency >= this.passFrequency && intensity > this.passIntensity) {
double probability = var25.getHarmonicProbability(robustFrequencies);
if(probability < 0.5D) {
int zc = this.getNumZeroCrosses(amplitudes);
if(zc >= this.minNumZeroCross && zc <= this.maxNumZeroCross) {
return true;
}
}
}
}
} else {
System.out.print("The sample size must be a power of 2");
}
return false;
}
private short[] getAmplitudes(byte[] audioBytes, int bitsPerSample) {
int bytesPerSample = bitsPerSample / 8;
int numSamples = audioBytes.length / bytesPerSample;
short[] amplitudes = new short[numSamples];
int pointer = 0;
for(int i = 0; i < numSamples; ++i) {
short amplitude = 0;
for(int byteNumber = 0; byteNumber < bytesPerSample; ++byteNumber) {
amplitude |= (short)((audioBytes[pointer++] & 255) << byteNumber * 8);
}
amplitudes[i] = amplitude;
}
return amplitudes;
}
private double[] getSpectrum(short[] amplitudes) {
int sampleSize = amplitudes.length;
WindowFunction window = new WindowFunction();
window.setWindowType("Hamming");
double[] win = window.generate(sampleSize);
double[] signals = new double[sampleSize];
for(int fft = 0; fft < sampleSize; ++fft) {
signals[fft] = (double)amplitudes[fft] * win[fft];
}
FastFourierTransform var8 = new FastFourierTransform();
double[] spectrum = new double[sampleSize];
spectrum = var8.getMagnitudes(signals);
return spectrum;
}
private int getNumZeroCrosses(short[] amplitudes) {
int numZC = 0;
int size = amplitudes.length;
for(int i = 0; i < size - 1; ++i) {
if(amplitudes[i] >= 0 && amplitudes[i + 1] < 0 || amplitudes[i] < 0 && amplitudes[i + 1] >= 0) {
++numZC;
}
}
return numZC;
}
private void normalizeSpectrum(double[] spectrum) {
double maxAmp = 4.9E-324D;
double minAmp = 1.7976931348623157E308D;
for(int minValidAmp = 0; minValidAmp < spectrum.length; ++minValidAmp) {
if(spectrum[minValidAmp] > maxAmp) {
maxAmp = spectrum[minValidAmp];
} else if(spectrum[minValidAmp] < minAmp) {
minAmp = spectrum[minValidAmp];
}
}
double var11 = 9.999999960041972E-12D;
if(minAmp == 0.0D) {
minAmp = var11;
}
double diff = Math.log10(maxAmp / minAmp);
for(int i = 0; i < spectrum.length; ++i) {
if(spectrum[i] < var11) {
spectrum[i] = 0.0D;
} else {
spectrum[i] = Math.log10(spectrum[i] / minAmp) / diff;
}
}
}
publicWhistAPI(int-sampleRate、int-bitsPerSample、int-channel){
this.numFrequencyUnit=this.fft样本大小/2;
this.unitFrequency=(双)this.sampleRate/2.0D/(双)this.numFrequencyUnit;
该频率=400.0D;
该点强度=100.0D;
该标准偏差=0.2D;
这是高通=400;
这个低通=4000;
此.minNumZeroCross=60;
此.maxNumZeroCross=90;
this.numRobust=2;
this.sampleRate=sampleRate;
this.bitsPerSample=bitsPerSample;
如果(通道!=1){
System.out.println(“仅支持单通道”);
}
}
公共布尔值isWhistle(字节[]音频字节){
int bytesPerSample=this.bitsPerSample/8;
int numSamples=audioBytes.length/bytesPerSample;
if(整数位计数(numSamples)==1){
this.fftSampleSize=numSamples;
short[]振幅=this.getAmplications(音频字节,this.bitsPerSample);
double[]频谱=此.getSpectrum(振幅);
双强度=0.0D;
int-lowerBoundary;
对于(下二元=0;下三元=this.numRobust){
打破
}
}
}
PitchHandler var25=新PitchHandler();
如果(maxFrequency>=this.passFrequency&&intensity>this.passIntensity){
双重概率=var25.getHarmonicProbability(鲁棒频率);
如果(概率<0.5D){
int zc=此.GetNumZeroCross(振幅);
如果(zc>=this.minNumZeroCross&&zc=0){
++numZC;
}
}
返回numZC;
}
私有频谱(双[]频谱){
双最大放大器=4.9E-324D;
双minAmp=1.7976931348623157E308D;
对于(int-minValidAmp=0;minValidAmpmaxAmp){
最大振幅=频谱[最小阻尼];
}else if(光谱[minValidAmp]
}
来自此链接的代码
我使用musicg-sound-api-1.2.0.1.jar
请帮忙
多谢各位