Как решить проблему с android.media.audiofx.Visualizer?

Здравствуйте, никак не пойму, что в byte[] fft, который передается в onFftDataCapture.

В доках


public int getFft (byte[] fft)

Since: API Level 9 Returns a frequency capture of currently playing audio content.


This method must be called when the Visualizer is enabled.


The capture is an 8-bit magnitude FFT, the frequency range covered being 0 (DC) to half of the sampling rate returned by getSamplingRate(). The capture returns the real and imaginary parts of a number of frequency points equal to half of the capture size plus one.


Note: only the real part is returned for the first point (DC) and the last point (sampling frequency / 2).


The layout in the returned byte array is as follows:


•n is the capture size returned by getCaptureSize()

•Rfk, Ifk are respectively the real and imaginary parts of the kth frequency component

•If Fs is the sampling frequency retuned by getSamplingRate() the kth frequency is: (k*Fs)/(n/2)


Чтобы посчитать «magnitude» для диапазона частот написал так

@Override
    public void onFftDataCapture(Visualizer visualizer, byte[] fft,
            int samplingRate) {
        if(mVisualizer==null)
            return;

        int redCount=0;
        int redValue=0;
        int yelloCount=0;
        int yelloValue=0;    
        int greenCount=0;
        int greenValue=0;    
        int blueCount=0;
        int blueValue=0;        
        for(int i=2; i<fft.length; i+=2){
            int Fsi = i*((samplingRate/2)/(fft.length/2));
            double value = Math.sqrt(fft[i]*fft[i]+fft[i+1]*fft[i+1]);

            if(Fsi<=200){
                redCount++;
                redValue+=value;
            }
            if(Fsi>200&&Fsi<=800){
                yelloCount++;
                yelloValue+=value;
            }    
            if(Fsi>800&&Fsi<=3500){
                greenCount++;
                greenValue+=value;
            }    
            if(Fsi>3500){
                blueCount++;
                blueValue+=value;
            }            
        }
        blueValue=blueCount==0?0:blueValue/blueCount;
        greenValue=greenCount==0?0:greenValue/greenCount;
        yelloValue=yelloCount==0?0:yelloValue/yelloCount;
        redValue=redCount==0?0:redValue/redCount;
        Log.i("MyLog","Red="+redValue + " Yello="+yelloValue+ " Green="+greenValue+ " Blue="+blueValue);
    }



И получаю примерно такое

09-28 11:47:59.917: INFO/MyLog(29701): Red=48 Yello=12 Green=5 Blue=0

09-28 11:48:00.089: INFO/MyLog(29701): Red=44 Yello=9 Green=1 Blue=0

09-28 11:48:00.175: INFO/MyLog(29701): Red=45 Yello=12 Green=3 Blue=0

09-28 11:48:00.296: INFO/MyLog(29701): Red=43 Yello=11 Green=4 Blue=1

09-28 11:48:00.402: INFO/MyLog(29701): Red=32 Yello=10 Green=3 Blue=0

09-28 11:48:00.531: INFO/MyLog(29701): Red=47 Yello=13 Green=4 Blue=0


Что, по-моему, никак не соответствует проигрываемой композиции (Запрещенные барабанщики — Куба).

Помогите, пожалуйста, разобраться:

Что же на самом деле в fft[i]+fft[i+1], какое максимальное значение этого элемента (я так понимаю 127, если это число может быть отрицательным)?

Каким частотам соответствуют начальные элементы массива (такое впечатление, что в обратной последовательности они приведены в массиве)?

Здесь по-моему ошибка в доках?

If Fs is the sampling frequency retuned by getSamplingRate() the kth frequency is: (k*Fs)/(n/2)


т.к. выше они пишут

range covered being 0 (DC) to half of the sampling rate returned by getSamplingRate()
  • Вопрос задан
  • 3853 просмотра
Решения вопроса 1
@constv Автор вопроса
Разобрался с помощью тестовых сэмплов, ошибка в моем коде, я считал среднее значение для диапозонов частот, а так как, например, в диапазон низких частот попадает очень маленькое количество элементов fff, то значение получается большим, и наоборот, в диапазон >3500 очень много элементов, значение большинства которых около 0, то общее значения диапазона получалось маленьким. Т.о. надо считать не среднее, а пики для диапазонов.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы