如何从录制原始音频中获取频率?

时间:2017-02-11 08:57:49

标签: java audio frequency recording visualize

我希望同时从录音中获取频率

这是我的代码:

我的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:

public class 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 个答案:

答案 0 :(得分:1)

为了获得信号的频率,您必须对其进行分析,例如使用傅立叶变换。在技​​术应用中,您使用快速/离散傅立叶变换(FFT)。原始音频是随时间记录的信号,FFT使您可以查看信号中包含哪些频率。

在您的情况下,您需要在audioBuffer上应用FFT。有Java类和C / C ++代码(使用NDK)。对于实时应用程序,C / C ++应该更快。