Аудиовход FFT

#android #audio #fft

#Android #Аудио #БПФ

Вопрос:

Я хочу применить FFT к сигналу, записанному AudioRecorder и сохраненному в wav-файле. используемый мной FFT имеет сложный входной параметр []. Я в замешательстве, есть ли разница между преобразованием из байтов в комплексное деление на 32768 и преобразованием путем простого добавления 0 к мнимой части и оставления реальной части в виде байта?

Редактировать:

 public Complex[] convertToComplex(byte[] file)
{


    int size= file.length;
    double[]x=new double[size];
    Complex[]data= new Complex[size];
    for(int i=0;i<size;i  )
    {
        x[i]=file[i]/32768.0;
        data[i]=new Complex(x[i],0);
        //  Log.d("tag", "indice" i ":" data[i]);
    }
    return data;
}
  

Комментарии:

1. Просто чтобы подтвердить, что ваш звук 16-битный PCM, верно? Если это так, то, к сожалению, ваше приведение неверно, посмотрите, как я сделал приведение в своем коде.

2. да, это 16-битный PCM. я не понимаю, почему вы используете short.

3. длина myAudioSamples составляет 1/2 myAudioBytes?

4. Да, длина myAudioSamples составляет 1/2 myAudioBytes. Я использую «short», потому что в нем ровно 16 бит, вы также можете использовать double (64 бита) или float (32 бита), потому что ваши сэмплы все равно будут вписываться.

Ответ №1:

Если вы работаете со звуком с разрядностью 16 бит (каждая выборка имеет 16 бит), то каждый байт будет содержать только половину выборки.Что вам нужно сделать, это преобразовать ваши байты в 16-битные выборки, а затем разделить полученное число на 32768 (это величина наименьшего числа, которое может хранить 16-битное число, дополняющее 2, т.е. 2 ^ 15), чтобы получить фактический образец звука, который представляет собой число от -1 до 1.Затем вы преобразуете это число в комплексное число, установив для его мнимой составляющей значение 0.

Небольшой пример C # можно увидеть ниже (ориентировочный код):

     byte[] myAudioBytes = readAudio();
    int numBytes = myAudioBytes.Length;

    var myAudioSamples = new List<short>();

    for( int i = 0; i < numBytes; i = i   2)
    {
      //Cast to 16 bit audio and then add sample
       short sample = (short) ((myAudioBytes[i] << 8 | myAudioBytes[i   1]) / 32768 ); 
       myAudioSamples.Add(sample);
    }

    //Change real audio to Complex audio

    var complexAudio = new Complex[myAudioSamples.Length];

    int i = 0;
    foreach(short sample in myAudioSamples)
       complexAudio[i  ] = new Complex(){ Real = sample, Imaginary = 0 };

   //Now you can proceed to getting the FFT of your Audio here
  

Надеюсь, код подсказал вам, как вы должны обрабатывать свой звук.

Комментарии:

1. спасибо, ребята. я отредактировал свой вопрос, чтобы добавить сделанное мной преобразование. я надеюсь, что это не так.

Ответ №2:

Обобщенные функции FFT похожи на работу с массивами сложных входов и выходов. Итак, для ввода вам может потребоваться создать массив комплексных чисел, которые соответствуют сложной структуре данных, требуемой библиотекой FFT. Вероятно, это будет состоять из реального и воображаемого компонента для каждого. Просто установите для мнимой части значение 0. Реальная часть, вероятно, представляет собой число с плавающей запятой со знаком, которое, как ожидается, будет находиться в диапазоне от -1.0 ..1.0, так что вы на правильном пути с разделением целых выборок PCM. Однако, когда вы написали «преобразование байтов«, это вызвало красный флаг. Вероятно, это 16-разрядные целочисленные образцы PCM со знаком, с небольшим конечным порядком, поэтому обязательно приведите их соответствующим образом, прежде чем делить на 32768 (но это Java, поэтому типы в любом случае будут применяться более строго).