/// <summary>
        /// Метод класса, реализующий обратное дискретное преобразование Фурье
        /// На выходе получаем массив 16-битных сэмплов
        /// </summary>
        /// <param name="spectre">Спектр</param>
        /// <param name="N">Длина исходного массива сэмплов</param>
        /// <returns>Выходной массив сэмплов</returns>
        public unsafe static Int16[] ReverseFourierTransform16bit(Structures.Spectre spectre, int N)
        {
            Int16[] sampleArray = new Int16[N];

            for (int i = 0; i < N; i++)
            {
                double ans = 0;

                for (int j = 0; j < (N / 2); j++)
                {
                    ans += (spectre.a[j] * Math.Cos((2 * Math.PI * j * i) / (N))) + (spectre.b[j] * Math.Sin((2 * Math.PI * j * i) / (N)));
                }

                sampleArray[i] = (Int16)((double)((double)ans * (double)((double)2 / (double)N)));
            }

            return(sampleArray);
        }
Beispiel #2
0
        /// <summary>
        /// Метод класса, выполняющий инверсию спектра
        /// </summary>
        /// <param name="spectre">Спектр в исходном порядке</param>
        /// <param name="lenght">Длина массивов в структуре</param>
        /// <returns>Спектр в обратном порядке</returns>
        private unsafe Structures.Spectre Inverse(Structures.Spectre spectre, int lenght)
        {
            Structures.Spectre ret_spectre;

            try
            {
                for (int i = 0; i < lenght; i++)
                {
                    ret_spectre.a[i] = spectre.a[(lenght - 1) - i];
                    ret_spectre.b[i] = spectre.b[(lenght - 1) - i];
                }
            }

            catch (Exception e)
            {
                ErrorShow.Print(e.Message, e.StackTrace, e.Source);
            }

            return(ret_spectre);
        }
Beispiel #3
0
        /// <summary>
        /// Метод класса, производящий поблочное преобразование массива сэмплов
        /// Преобрахование включает в себя такие операции с каждым блоком:
        /// 1. Преобразование Фурье на участке в 128 сэмплов, который, собственно и является блоком;
        /// 2. Инверсия спектра;
        /// 3. Обратное дискретное преобразование Фурье;
        /// </summary>
        /// <param name="pcm">Глубина кодирования в битах</param>
        public void BlockTransform(int pcm)
        {
            switch (pcm)
            {
            case 16:
            {
                List <Int16> tmpFinal = new List <Int16>();                  // Создаём временный список для работы

                for (int i = 0; i < InputSampleArray_16bit.Length; i += 128) // Цикл, обрабатывающий один блок из 128 сэмплов
                {
                    Int16[] tmp = new Int16[128];                            // Создаём массив для данного блока

                    for (int j = 0; j < 128; j++)                            // И записываем в него сэмплы из общего массива
                    {
                        tmp[j] = InputSampleArray_16bit[i + j];
                    }

                    Structures.Spectre spectre = DiscreteFourierTransformClass.DiscreteFourierTransform(tmp); // Создаём структуру, хранящую спектр данного блока

                    Structures.Spectre tmpSpectre = Inverse(spectre, 64);                                     // Делаем инверсию полученного спектра, результат храним во временной структуре

                    spectre = tmpSpectre;

                    tmp = DiscreteFourierTransformClass.ReverseFourierTransform16bit(spectre, 128); // Проводим обратное преобразование Фурье

                    tmpFinal.AddRange(tmp);                                                         // Получившийся блок записываем во временный список

                    if ((InputSampleArray_16bit.Length - (i + 128)) < 128)                          // Если размер файла не кратен 128, во избежание переполнения игнорируем последний неполный блок. Оставшиеся несколько сэмплов не будут иметь значения.
                    {
                        break;
                    }
                }

                FinalSampleArray16 = tmpFinal.ToArray();
            }

            break;
            }
        }