Выявление доминирующей частоты в записанном звуке в Android - PullRequest
0 голосов
/ 14 ноября 2018

Я пытаюсь преобразовать программу Python, расположенную в https://github.com/rraval/pied-piper/blob/master/decode.py, в файл Android Java.

Первый шаг - определить доминирующую частоту.Я написал следующую Java-программу для этого

private class RecordAudio
        extends AsyncTask<Void, Void, Void> {

    @Override
    protected Void doInBackground(Void... paramVarArgs) {
        int audioSource = AudioSource.MIC;
        int sampleRateInHz = 44100;
        int channelConfig = AudioFormat.CHANNEL_IN_MONO;
        int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
        int bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);
        byte Data[] = new byte[bufferSizeInBytes];

        AudioRecord audioRecorder = new AudioRecord(audioSource,
                sampleRateInHz,
                channelConfig,
                audioFormat,
                bufferSizeInBytes);
        audioRecorder.startRecording();

        boolean isRecording = true;
        while (isRecording) {
            audioRecorder.read(Data, 0, Data.length);
            fftPrint(Data, bufferSizeInBytes);
        }
        return null;
    }

    boolean fftPrint(byte[] waveArray, int bufferSizeInBytes) {
        double HANDSHAKE_START_HZ = 8192;
        double HANDSHAKE_END_HZ = 8192 + 512;
        int len = waveArray.length;
        double[] waveTransformReal = new double[len];
        double[] waveTransformImg = new double[len];

        for (int i = 0; i < len; i++) {
            waveTransformReal[i] = waveArray[i]; //copy of original
            waveTransformImg[i] = waveArray[i]; //FFT transformed below
        }

        RealDoubleFFT p = new RealDoubleFFT(bufferSizeInBytes);
        p.ft(waveTransformImg);

        //Calculating abs
        double[] abs = new double[len];
        for (int i = 0; i < len; i++) {
            abs[i] = (Math.sqrt(waveTransformReal[i] * waveTransformReal[i] + waveTransformImg[i] * waveTransformImg[i]));
        }

        //calculating maxIndex
        int maxIndex = 0;
        for (int i = 0; i < len; i++) {
            if (abs[i] > abs[maxIndex])
                maxIndex = i;
        }

        double dominantFrequency = (maxIndex * 44100) / len;
        if (dominantFrequency > 0) Log.d("Freq: ", String.format("%f", dominantFrequency));

        if (match(dominantFrequency, HANDSHAKE_START_HZ)) {
            Log.i("Handshake start:", "FOUND START");
        }
        if (match(dominantFrequency, HANDSHAKE_END_HZ)) {
            Log.i("Handshake end:", "FOUND END");
            return true;
        }
        return false;
    }

    boolean match(double freq1, double freq2) {
        return (Math.abs(freq1 - freq2) < 20);
    }

Примечание: RealDoubleFFT из ca.uol.aig.fftpack

Не уверен, правильно ли я это сделал.Я получаю частоты, напечатанные в Logcat, но они не находят HANDSHAKE_START_HZ, который присутствует в воспроизводимом аудио.Что я делаю не так?

1 Ответ

0 голосов
/ 16 ноября 2018

Обратите внимание, что разрешение по частоте пика величины БПФ зависит от длины БПФ (и окна, и т. Д.).Эта длина не указана или не ограничена в вашем коде, поэтому вы не будете знать, возможно ли, чтобы какой-либо результирующий блок FFT находился в пределах 20 Гц от ваших целевых частот.

...