0

我想同时从我的录音中获取频率

这是我的代码:

我的 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);
}
4

1 回答 1

1

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

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

于 2017-09-19T15:49:02.020 回答