MFCC
    
  ![]()  | 
Наши проекты:
 Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту  | 
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS | 
| [216.73.216.5] | 
 
 | 
		
  | 
| Страницы: (3) [1] 2 3 все ( Перейти к последнему сообщению ) | 
    MFCC
    
  | 
         
         
         
          
           Сообщ.
           #1
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
          пожалуйста, дайте формулы по которым считается MFCC.   
        
       | 
    
| 
         
         
         
          
           Сообщ.
           #2
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
          формула обратного косинусоидального преобразования тут 
        
      расскажу в двух словах один из способов, как они высчитываются 1) Сигнал переводится в спектральную область с помощью БПФ (быстрого преобразоавания Фурье) 2) Спектральные коэффициенты усредняются с использованием параметра количества каналов фильтра, которые представляют из себя гребенку треугольных окон, расположенных на мел-шкале (обычно треугольные фильтры перекрывают область частот от нуля и вплоть до частоты Найквиста ). 3) Мел-частотные кепстральные коэффициенты вычисляются при помощи обратного косинусного преобразования (см. формулу по ссылке).  | 
    
| 
         
         
         
          
           Сообщ.
           #3
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
          спасибо   
        
       | 
    
| 
         
         
         
          
           Сообщ.
           #4
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
          Хочу протестировать правильность нахождения мел-частотных кепстральных коэффициентов в моей программе. 
        
      Может кто-нибудь выложить кусок звукового сигнала с выделенными из него MFCC?  | 
    
| 
         
         
         
          
           Сообщ.
           #5
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
| 
         
         
         
          
           Сообщ.
           #6
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
          я не смог разобраться в логических переходах между сообщениями в этой ветке. 
        
      если я правильно понял, http://htk.eng.cam.ac.uk/ - на этом сайте я могу скачать звуковые фрагменты с выделенным MFCC?  | 
    
| 
         
         
         
          
           Сообщ.
           #7
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
          Хм, ну попробую донести мысль всё-таки. 
        
      Вычисленные коэффициенты MFCC зависят от большого числа параметров - числа фильтров, формы фильтров, числа точек в спектре, основания логарифма и т.д. Поэтому с вероятностью 100% две различные реализации MFCC дадут совершенно различные числа. Поэтому рекомендуется перейти по ссылке http://htk.eng.cam.ac.uk, зарегистрироваться там, и скачать уже скомпилированные под Windows приложения, в частности вычисляющие MFCC. Документация к HTK на русском языке доступна здесь: http://aprodeus.narod.ru/mmedia.htm#Rech Используя HCopy и HList для вычисления коэффициентов и сверяясь с исходым кодом HTK возможно проверить работу приложения.  | 
    
| 
         
         
         
          
           Сообщ.
           #8
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
          спасибо огромное   
        
       | 
    
| 
         
         
         
          
           Сообщ.
           #9
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
         Доброго всем дня. 
        
      Вопрос знатокам HTK по MFCC: код написанный с использованием IPP и HList выдают разные результаты, с чем это может быть связано? IPP: 01: -29.003057 02: -20.139099 03: -4.3270502 04: -13.346766 05: -18.708612 06: -5.8949571 07: 31.116928 08: 27.441202 09: 21.219500 10: 39.831188 11: 13.616776 12: -3.3898118 E: 9.6506577 HList: ------------------------------------------------- Source: ru_0001.wav -------------------------------------------------- Sample Bytes: 2 Sample Kind: WAVEFORM Num Comps: 1 Sample Period: 62.5 us Num Samples: 257278 File Format: WAV -------------------------------------------------------- Target -------------------------------------------------------- Sample Bytes: 52 Sample Kind: MFCC_E Num Comps: 13 Sample Period: 10000.0 us Num Samples: 1606 File Format: HTK ------------------------------------------------ Observation Structure ------------------------------------------------- x: MFCC-1 MFCC-2 MFCC-3 MFCC-4 MFCC-5 MFCC-6 MFCC-7 MFCC-8 MFCC-9 MFCC-10 MFCC-11 MFCC-12 E ---------------------------------------------------- Samples: 0->0 ----------------------------------------------------- 0: -10.925 -10.630 -1.796 -8.355 -11.068 -5.632 19.115 14.508 12.260 21.412 7.453 -1.746 9.651 --------------------------------------------------------- END ---------------------------------------------------------- config: # Coding parameters SOURCEFORMAT = WAV TARGETKIND = MFCC_E TARGETRATE = 100000.0 WINDOWSIZE = 250000.0 USEHAMMING = T PREEMCOEF = 0.97 NUMCHANS = 24 CEPLIFTER = 22 NUMCEPS = 12 ENORMALISE = F LOFREQ = 100 HIFREQ = 4000 ESCALE = 1.0 SILFLOOR = 50.0 USEPOWER = T код: ![]() ![]()     /* Initialize the structures */     ippsMelFBankInitAlloc_32f(&fbank, /* return the structure pointer */         &fft_order, /* return the FFT length */         400,    /* 25ms window/512 point FFT */         16000,  /* sample rate */         100,    /* lowest frequency of interest */         4000,   /* highest frequency of interest */         24,     /* number of filter banks */         1127, /* mel-scale factor 1 */         700,    /* mel-scale factor 2 */         (IppMelMode)(IPP_FBANK_MELWGT | IPP_POWER_SPECTRUM));     ippsDCTLifterInitAlloc_32f(&dctl, /* return the structure pointer */         24, /* filter bank channels */         12, /* number of MFCC coefficients */         22, /* liftering */         1.0f); /* no scaling */     fft_len=1<<fft_order;     frame_buffer=ippsMalloc_32f(fft_len);     fbank_buffer=ippsMalloc_32f(24);     tempmfccs=ippsMalloc_32f(13*(sample_num-400+160)/160);     mfcc_cur=tempmfccs;     /* Calculate MFCC features */     for (i=j=0; i+WindowSize<=sample_num; i+=StepSize,mfcc_cur+=13,j++) {         /* Organize the input wave data into a frame */         ippsCopyWithPadding_32f(&samples[i],400,frame_buffer,fft_len);         ippsDotProd_32f(frame_buffer,frame_buffer,fft_len,&LogEnergy);         /* Pre-emphasize the input signal with factor 0.97 */         ippsPreemphasize_32f(frame_buffer,400,0.97f);         frame_buffer[0]*=(1.0f-0.97f);         /* Add the hamming window to the input signal */         ippsWinHamming_32f_I(frame_buffer,WindowSize);         /* Perform the filter bank analysis */         ippsEvalFBank_32f(frame_buffer,fbank_buffer,fbank);         ippsThreshold_LTVal_32f_I(fbank_buffer, 24, 1.0f, 1.0f);         ippsLn_32f_I(fbank_buffer, 24);          /* Perform the DCT analysis and liftering */         ippsDCTLifter_32f(fbank_buffer,mfcc_cur,dctl);         mfcc_cur[12] = (float) log ((double) LogEnergy);     }     /* Normalize log energy */     //ippsNormEnergy_32f(tempmfccs+12,13,(sample_num-400+160)/160,50.0f,1.0f);  | 
    
| 
         
         
         
          
           Сообщ.
           #10
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
          Нашёл на просторах интернета вот такой класс MFCC! 
        
      Каково мнение гуру? По идее,я посмотрел,там есть всё!И БПФ,и окно Хемминга,и логарифмирование и DCT и на выходе массив кепстров!На входе должен быть массив double[].Я пока провожу "эксперимент"... ![]() ![]() using System; using System.Collections.Generic; using System.Text; namespace speakerRecognition {     class Mfcc     {         static int my_rint(double x)         {             if (2 * x == (double)Math.Round(2 * x))                 x += 0.0001;             return ((int)Math.Round(x));         }         static public double[] mfcc(ref double[] signal)         {             double lowestFrequency = 133.3333;             double linearFilters = 13;             double linearSpacing = 66.66666666;             double logFilters = 27;             double logSpacing = 1.0711703;             double fftSize = 512;             double cepstralCoefficients = 13;             double windowSize = 256;             double samplingRate = 44100;             double totalFilters;             double[] mfccFilterWeights;             double[] freqs;             double[] triangleHeight;             double[] lower;             double[] upper;             double[] center;             double[] fftFreqs;             double[] hamWindow;             double[] mfccDCTMatrix;             double[] preEmphasized;             double first;             double last;             double[] fftData;             double[] empreinte;             double maxi;             double[] earMag;              double[] ceps;              double loga;              double windowStep;              double cols;              double frameRate = 100;             double[] result;             int i, j, k;             preEmphasized = new double[1024];             totalFilters = linearFilters + logFilters;             freqs = new double[(int)totalFilters + 2];             for (i = 0; i < linearFilters; i++)                 freqs[i] = lowestFrequency + i * linearSpacing;             for (i = (int)linearFilters; i < (int)totalFilters + 2; i++)                 freqs[i] = freqs[(int)linearFilters - 1] * Math.Pow(logSpacing, i - linearFilters + 1);             lower = new double[(int)totalFilters];             upper = new double[(int)totalFilters];             center = new double[(int)totalFilters];             triangleHeight = new double[(int)totalFilters];             fftData = new double[(int)fftSize];             for (i = 0; i < (int)totalFilters; i++)                 lower[i] = freqs[i];             for (i = 1; i < (int)totalFilters + 1; i++)                 center[i - 1] = freqs[i];             for (i = 2; i < (int)totalFilters + 2; i++)                 upper[i - 2] = freqs[i];             hamWindow = new double[(int)windowSize];             mfccFilterWeights = new double [(int)(totalFilters * fftSize)];             for (i = 0; i < totalFilters; i++)                 triangleHeight[i] = 2 / (upper[i] - lower[i]);             fftFreqs = new double[(int)fftSize];             for (i = 0; i < fftSize; i++)                 fftFreqs[i] = (i / fftSize) * samplingRate;             for (i = 0; i < totalFilters; i++)             {                 for (j = 0; j < (int)fftSize; j++)                 {                     if ((fftFreqs[j] > lower[i]) && (fftFreqs[j] <= center[i]))                         mfccFilterWeights[(int)fftSize * i + j] = triangleHeight[i] * (fftFreqs[j] - lower[i]) / (center[i] - lower[i]);                     if ((fftFreqs[j] > center[i]) && (fftFreqs[j] < upper[i]))                          mfccFilterWeights[(int)fftSize * i + j] = (triangleHeight[i] * (fftFreqs[j] - lower[i]) / (center[i] - lower[i])) + (triangleHeight[i] * (upper[i] - fftFreqs[j]) / (upper[i] - center[i]));                 }             }             for (i = 0; i < windowSize; i++)                 hamWindow[i] = 0.54 - 0.46 * Math.Cos(2 * Math.PI * i / windowSize);             mfccDCTMatrix = new double[(int)(cepstralCoefficients * totalFilters)];             for (i = 0; i < cepstralCoefficients; i++)                 for (j = 0; j < totalFilters; j++)                     mfccDCTMatrix[j * (int)cepstralCoefficients + i] = 1 / Math.Sqrt(totalFilters / 2) * Math.Cos(i * (2 * j + 1) * Math.PI / 2 / totalFilters);             for (i = 0; i < totalFilters; i++)                 mfccDCTMatrix[i * (int)cepstralCoefficients] *= 1 / Math.Sqrt(2);             for (i = 1; i < 1024; i++)                 preEmphasized[i] = signal[i] + signal[i - 1] * -0.97;             preEmphasized[0] = signal[0];             earMag = new double[(int)totalFilters];             windowStep = samplingRate / frameRate;             cols = (int)((1024 - windowSize) / windowStep);             ceps = new double[(int)(sizeof(double) * cols * linearFilters)];             for (i = 0; i < cols; i++)             {                 first = i * windowStep + 1;                 last = first + windowSize - 1;                 for (j = 0; j < fftSize; j++)                     fftData[j] = 0;                 for (j = 0; j < windowSize; j++)                     fftData[j] = preEmphasized[(int)my_rint(first + j - 1)] *  hamWindow[j];                 double[] fftMag = FourierTransform.FFT(ref signal);                 for (j = 0; j < totalFilters; j++)                 {                     loga = 0;                     for (k = 0; k < fftSize; k++)                         loga += fftMag[k] * mfccFilterWeights[k + j * (int)fftSize];                     earMag[j] = Math.Log10(loga);                 }                 for (j = 0; j < linearFilters; j++)                 {                     loga = 0;                     for (k = 0; k < totalFilters; k++)                         loga +=                           earMag[k] * mfccDCTMatrix[j + k * (int)linearFilters];                     ceps[j + i * (int)linearFilters] = loga;                 }             }             empreinte = new double[12];             for (i = 1; i < 13; i++)                 empreinte[i - 1] = (ceps[i] + ceps[i + 13] + ceps[i + 26] + ceps[i + 39] + ceps[i + 52] + ceps[i + 65]);             maxi = 0;             for (i = 0; i < 12; i++)              {                  if (maxi * maxi < empreinte[i] * empreinte[i])                      maxi = empreinte[i];               }             for (i = 0; i < 12; i++) empreinte[i] = (empreinte[i] / Math.Abs(maxi)) * 2;             return empreinte;         }     } }  | 
    
| 
         
         
         
          
           Сообщ.
           #11
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
          Насчёт БПФ. 
        
      Там вроде и прямое и обратное можно. Брал вот этот модуль: ![]() ![]() /// <license> /// This is a port of the SciMark2a Java Benchmark to C# by /// Chris Re (cmr28@cornell.edu) and Werner Vogels (vogels@cs.cornell.edu) ///  /// For details on the original authors see http://math.nist.gov/scimark2 ///  /// This software is likely to burn your processor, bitflip your memory chips /// anihilate your screen and corrupt all your disks, so you it at your /// own risk. /// </license> using System; namespace SciMark2 {     /// <summary>Computes FFT's of complex, double precision data where n is an integer power of 2.     /// This appears to be slower than the Radix2 method,     /// but the code is smaller and simpler, and it requires no extra storage.     /// </P>     /// </summary>     ///      /// <author>      /// Bruce R. Miller bruce.miller@nist.gov,     /// Derived from GSL (Gnu Scientific Library),      /// GSL's FFT Code by Brian Gough bjg@vvv.lanl.gov     /// </author>     public class FFT     {         public static double num_flops(int N)         {             double Nd = (double) N;             double logN = (double) log2(N);             return (5.0 * Nd - 2) * logN + 2 * (Nd + 1);         }         /// <summary>         /// Compute Fast Fourier Transform of (complex) data, in place.         /// </summary>         public static void  transform(double[] data)         {             transform_internal(data, - 1);         }         /// <summary>         /// Compute Inverse Fast Fourier Transform of (complex) data, in place.         /// </summary>         public static void  inverse(double[] data)         {             transform_internal(data, + 1);             // Normalize             int nd = data.Length;             int n = nd / 2;             double norm = 1 / ((double) n);              for (int i = 0; i < nd; i++)                 data[i] *= norm;         }         /// <summary>         /// Accuracy check on FFT of data. Make a copy of data, Compute the FFT, then         /// the inverse and compare to the original.  Returns the rms difference.         /// </summary>         public static double test(double[] data)         {             int nd = data.Length;             // Make duplicate for comparison             double[] copy = new double[nd];             Array.Copy(data, 0, copy, 0, nd);             // Transform & invert             transform(data);             inverse(data);             // Compute RMS difference.             double diff = 0.0;              for (int i = 0; i < nd; i++)             {                 double d = data[i] - copy[i];                 diff += d * d;             }             return Math.Sqrt(diff / nd);         }         /// <summary>         /// Make a random array of n (complex) elements.          /// </summary>         public static double[] makeRandom(int n)         {             int nd = 2 * n;             double[] data = new double[nd];             System.Random r = new System.Random();             for (int i = 0; i < nd; i++)                 data[i] = r.NextDouble();             return data;         }         protected internal static int log2(int n)         {             int log = 0;              for (int k = 1; k < n; k *= 2, log++)                 ;             if (n != (1 << log))                 throw new ApplicationException("FFT: Data length is not a power of 2!: " + n);             return log;         }         protected internal static void  transform_internal(double[] data, int direction)         {             if (data.Length == 0)                 return ;             int n = data.Length / 2;             if (n == 1)                 return ;             // Identity operation!             int logn = log2(n);             /* bit reverse the input data for decimation in time algorithm */             bitreverse(data);             /* apply fft recursion */             /* this loop executed log2(N) times */              for (int bit = 0, dual = 1; bit < logn; bit++, dual *= 2)             {                 double w_real = 1.0;                 double w_imag = 0.0;                 double theta = 2.0 * direction * Math.PI / (2.0 * (double) dual);                 double s = Math.Sin(theta);                 double t = Math.Sin(theta / 2.0);                 double s2 = 2.0 * t * t;                 /* a = 0 */                  for (int b = 0; b < n; b += 2 * dual)                 {                     int i = 2 * b;                     int j = 2 * (b + dual);                     double wd_real = data[j];                     double wd_imag = data[j + 1];                     data[j] = data[i] - wd_real;                     data[j + 1] = data[i + 1] - wd_imag;                     data[i] += wd_real;                     data[i + 1] += wd_imag;                 }                 /* a = 1 .. (dual-1) */                  for (int a = 1; a < dual; a++)                 {                     /* trignometric recurrence for w-> exp(i theta) w */                     {                         double tmp_real = w_real - s * w_imag - s2 * w_real;                         double tmp_imag = w_imag + s * w_real - s2 * w_imag;                         w_real = tmp_real;                         w_imag = tmp_imag;                     }                      for (int b = 0; b < n; b += 2 * dual)                     {                         int i = 2 * (b + a);                         int j = 2 * (b + a + dual);                         double z1_real = data[j];                         double z1_imag = data[j + 1];                         double wd_real = w_real * z1_real - w_imag * z1_imag;                         double wd_imag = w_real * z1_imag + w_imag * z1_real;                         data[j] = data[i] - wd_real;                         data[j + 1] = data[i + 1] - wd_imag;                         data[i] += wd_real;                         data[i + 1] += wd_imag;                     }                 }             }         }         protected internal static void  bitreverse(double[] data)         {             /* This is the Goldrader bit-reversal algorithm */             int n = data.Length / 2;             int nm1 = n - 1;             int i = 0;             int j = 0;              for (; i < nm1; i++)             {                 //int ii = 2*i;                 int ii = i << 1;                 //int jj = 2*j;                 int jj = j << 1;                 //int k = n / 2 ;                 int k = n >> 1;                 if (i < j)                 {                     double tmp_real = data[ii];                     double tmp_imag = data[ii + 1];                     data[ii] = data[jj];                     data[ii + 1] = data[jj + 1];                     data[jj] = tmp_real;                     data[jj + 1] = tmp_imag;                 }                 while (k <= j)                 {                     //j = j - k ;                     j -= k;                     //k = k / 2 ;                      k >>= 1;                 }                 j += k;             }         }     } }  | 
    
| 
         
         
         
          
           Сообщ.
           #12
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
          Dj_SheLL, спасибо за информацию. Поделись пожалуйста впечатлениями от использования класса MFCC. Просто я начал писать свой класс, но столкнулся с некоторыми сложностями, так что возможно буду использовать тот, который ты нашел. Как вообще проверить, правильные ли результаты выдает MFCC или нет?   
        
       | 
    
| 
         
         
         
          
           Сообщ.
           #13
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
          Внешне всё вроде реализованно верно,НО! 
        
      Я так и не добился получения кепстров-у меня при вычислениях +/- "бесконечность" получается.Проблемы с длинной чисел. Если что, данные я получал с буфера с помощью NAudio.По идее с других библиотек данные не должны отличаться ни чем! Так что надо допиливать класс под "народные нужды",чтобы всем пригодилось...либо пользоваться другими инструментами!  | 
    
| 
         
         
         
          
           Сообщ.
           #14
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
          Насчет +/- "бесконечности" ничего не могу посоветовать) Я проверил алгоритм и сравнил с теми, которые реализованы на других языках и лежат на просторах интернета. В целом он не вызывает подозрений.  
        
      Что касается кепстров, то у меня они получились в интервале [2;-1]. NAudio я не использовал. У меня вопрос: перед тем, как записывать звук, мне нужно указать AudioFrameSize. Я так понимаю, что в этот параметр записывается сколько милисекунд будет длится каждый сэмпл. Вляет ли этот параметр на значение кепстров и если да, то сколько мс там указывать?  | 
    
| 
         
         
         
          
           Сообщ.
           #15
          
          , 
          
         
         
        
       | 
    |
| 
         | 
      
         Цитата Lohoboishe @  Что касается кепстров, то у меня они получились в интервале [2;-1] А вообще какой диапозон должен быть?   Цитата Lohoboishe @  У меня вопрос: перед тем, как записывать звук, мне нужно указать AudioFrameSize. Я так понимаю, что в этот параметр записывается сколько милисекунд будет длится каждый сэмпл. Вляет ли этот параметр на значение кепстров и если да, то сколько мс там указывать? Ну все берут от 20 до 30.Насчёт влияния-не знаю.  |