如何从录制原始音频中获取频率?
Posted
技术标签:
【中文标题】如何从录制原始音频中获取频率?【英文标题】:how to get frequency from Recording raw audio? 【发布时间】:2017-02-11 08:57:48 【问题描述】:我想同时从我的录音中获取频率
这是我的代码:
我的 SoundProcessing .java 和 Main 类
public class SoundProcessing extends Activity
private WaveformView mRealtimeWaveformView;
private RecordingThread mRecordingThread;
private PlaybackThread mPlaybackThread;
private static final int REQUEST_RECORD_AUDIO = 13;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tab_sound_processing);
mRealtimeWaveformView = (WaveformView) findViewById(R.id.waveformView);
mRecordingThread = new RecordingThread(new AudioDataReceivedListener()
@Override
public void onAudioDataReceived(short[] data)
mRealtimeWaveformView.setSamples(data);
);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
if (!mRecordingThread.recording())
startAudioRecordingSafe();
else
mRecordingThread.stopRecording();
);
和我的 RecordingThread.java:
公共类 RecordingThread
private static final String LOG_TAG = RecordingThread.class.getSimpleName();
private static final int SAMPLE_RATE = 44100;
public RecordingThread(AudioDataReceivedListener listener)
mListener = listener;
private boolean mShouldContinue;
private AudioDataReceivedListener mListener;
private Thread mThread;
public boolean recording()
return mThread != null;
public void startRecording()
if (mThread != null)
return;
mShouldContinue = true;
mThread = new Thread(new Runnable()
@Override
public void run()
record();
);
mThread.start();
public void stopRecording()
if (mThread == null)
return;
mShouldContinue = false;
mThread = null;
private void record()
Log.v(LOG_TAG, "Start");
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_AUDIO);
// buffer size in bytes
int bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT);
if (bufferSize == AudioRecord.ERROR || bufferSize == AudioRecord.ERROR_BAD_VALUE)
bufferSize = SAMPLE_RATE * 2;
short[] audioBuffer = new short[bufferSize / 2];
AudioRecord record = new AudioRecord(MediaRecorder.Audiosource.DEFAULT,
SAMPLE_RATE,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT,
bufferSize);
if (record.getState() != AudioRecord.STATE_INITIALIZED)
Log.e(LOG_TAG, "Audio Record can't initialize!");
return;
record.startRecording();
Log.v(LOG_TAG, "Start recording");
long shortsRead = 0;
while (mShouldContinue)
int numberOfShort = record.read(audioBuffer, 0, audioBuffer.length);
shortsRead += numberOfShort;
// Notify waveform
mListener.onAudioDataReceived(audioBuffer);
record.stop();
record.release();
Log.v(LOG_TAG, String.format("Recording stopped. Samples read: %d", shortsRead));
还有我的 AudioDataReceivedListener.java
public interface AudioDataReceivedListener
void onAudioDataReceived(short[] data);
【问题讨论】:
【参考方案1】:为了获得信号的频率,您必须对其进行分析,例如使用傅里叶变换。在技术应用中,您使用快速/离散傅里叶变换 (FFT)。原始音频是随时间记录的信号,FFT 可让您查看信号中包含哪些频率。
在您的情况下,意味着您需要在 audioBuffer
上应用 FFT。有 Java 类和 C/C++ 代码(使用 NDK)。对于实时应用程序,C/C++ 应该更快。
【讨论】:
以上是关于如何从录制原始音频中获取频率?的主要内容,如果未能解决你的问题,请参考以下文章
在java中录制音频并确定实时是不是播放了x频率的音调,如果是这样的话