作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的目标是通过分析球旋转过程中产生的声音来获得强力球的转速。在Google Play中,有几个应用程序可以通过声音来计算转速和频率,但是每个应用程序都无法找出动力球的转速。我在Google上搜索后发现,“要根据声音计算频率,我们必须使用FFT算法”。
什么是强力球?
强力球旋转并产生声音。
“Powerball®产生的阻力与用户所付出的努力成正比”。
class RecorderThread1 extends Thread {
private static final String TAG = RecorderThread1.class.getSimpleName();
public boolean recording; // variable to start or stop recording
public int frequency; // the public variable that contains the frequency
private PlaceholderFragment placeHolder;
private Handler handler;
private long avgFrequency;
private int avg = 0;
private int sampelRateHz = 8000;
// value "heard", it is updated continually while
// the thread is running.
public RecorderThread1(PlaceholderFragment placeHolder) {
this.placeHolder = placeHolder;
}
@Override
public void run() {
AudioRecord recorder;
int numCrossing, p;
short audioData[];
int bufferSize;
bufferSize = AudioRecord.getMinBufferSize(8000,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT) * 3; // get the buffer size to
// use with this audio
// record
recorder = new AudioRecord(AudioSource.MIC, 8000,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, bufferSize); // instantiate the
// AudioRecorder
recording = true; // variable to use start or stop recording
audioData = new short[bufferSize]; // short array that pcm data is put
// into.
while (recording) { // loop while recording is needed
if (recorder.getState() == android.media.AudioRecord.STATE_INITIALIZED) // check
// to
// see
// if
// the
// recorder
// has
// initialized
// yet.
if (recorder.getRecordingState() == android.media.AudioRecord.RECORDSTATE_STOPPED)
recorder.startRecording(); // check to see if the Recorder
// has stopped or is not
// recording, and make it
// record.
else {
recorder.read(audioData, 0, bufferSize); // read the PCM
// audio data
// into the
// audioData
// array
// Now we need to decode the PCM data using the Zero
// Crossings Method
numCrossing = 0; // initialize your number of zero crossings
// to 0
for (p = 0; p 0 && audioData[p + 1] = 0)
numCrossing++;
if (audioData[p + 1] > 0 && audioData[p + 2] = 0)
numCrossing++;
if (audioData[p + 2] > 0 && audioData[p + 3] = 0)
numCrossing++;
if (audioData[p + 3] > 0 && audioData[p + 4] = 0)
numCrossing++;
}// for p
for (p = (bufferSize / 4) * 4; p 0 && audioData[p + 1] = 0)
numCrossing++;
}
frequency = (8000 / bufferSize) * (numCrossing / 2); // Set
// the audio Frequency to half the number of zero crossings, times the number of samples our buffersize is per second.
avgFrequency = avgFrequency + frequency;
avg++;
Log.d(TAG, " frequency is " + frequency);
if (handler == null) {
handler = new Handler(Looper.getMainLooper());
handler.postDelayed(runnable, 2000);
}
// placeHolder.printFrequency((frequency * 60));
}// else recorder started
} // while recording
最佳答案
除非声音是纯正弦波或方波,否则过零的次数将是不可靠的,更高和更低的频率会增加噪声。
您可以在其中找到FFT算法:FFT library in android Sdk
FFT正在计算频带中的功率(如频谱分析仪所显示的)。您应该尝试从强力球声音中查看曲线图像,并确定哪种是处理它的最佳方法(较低的频率峰值,较高的峰值……)。
关于android - 如何从声音android中找出RPM(每分钟旋转)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23926469/
我是一名优秀的程序员,十分优秀!