speaker_recognition.c
上传用户:bossps2lzz
上传日期:2022-07-07
资源大小:522k
文件大小:15k
源码类别:

DSP编程

开发平台:

C/C++

  1. /***************************************************************************** 
  2.  *
  3.  * speaker_recognition.c
  4.  *
  5.  * Main Program to Identitfy a Speaker.
  6.  *
  7.  * The aim of this project is to determine the identity of the speaker
  8.  * from the speech sample of the speaker and the trained vectors.
  9.  *
  10.  * Trained vectors are derived from the speech sample of the speaker at
  11.  * a different time.
  12.  * 
  13.  * First the input analog speech signal is digitized at 8KhZ Sampling
  14.  * Frequency using the on board ADC (Analog to Digital Converter)
  15.  * The Speech sample is stored in an one-dimensional array.
  16.  * Speech signal's are quasi-stationary. It means that the 
  17.  * speech signal over a very short time frame can be considered to be a
  18.  * stationary. The speech signal is split into frames. Each frame consists
  19.  * of 256 Samples of Speech signal and the subsequent frame will start from
  20.  * the 100th sample of the previous frame. Thus each frame will overlap
  21.  * with two other subsequent other frames. This technique is called
  22.  * Framing. Speech sample in one frame is considered to be stationary.
  23.  *
  24.  * After Framing, to prevent the spectral lekage we apply windowing. 
  25.  * Here  Hamming window with 256 co-efficients is used.
  26.  *
  27.  * Third step is to convert the Time domain speech Signal into Frequency
  28.  * Domain using Discrete Fourier Transform. Here Fast Fourier Transform
  29.  * is used.
  30.  *
  31.  * The resultant transformation will result in a signal beeing complex
  32.  * in nature. Speech is a real signal but its Fourier Transform will be 
  33.  * a complex one (Signal having both real and imaginary). 
  34.  *
  35.  * The power of the signal in Frequency domain is calculated by summing
  36.  * the square of Real and Imaginary part of the signal in Frequency Domain.
  37.  * The power signal will be a real one. Since second half of the samples
  38.  * in the frame will be symmetric to the first half (because the speech signal
  39.  * is a real one) we ignore the second half (second 128 samples in each frame)
  40.  *
  41.  * Triangular filters are designed using Mel Frequency Scale. These bank of 
  42.  * filters will approximate our ears. The power signal is then applied to 
  43.  * these bank of filters to determine the frequency content across each filter.
  44.  * In our implementation we choose total number of filters to be 20.
  45.  * These 20 filters are uniformly spaced in Mel Frequency scale between 
  46.  * 0-4KhZ.
  47.  *
  48.  * After computing the Mel-Frequency Spectrum, log of Mel-Frequency Spectrum
  49.  * is computed.
  50.  *
  51.  * Discrete Cosine Tranform of the resulting signal will result in the 
  52.  * computation of the Mel-Frequency Cepstral Co-efficient.
  53.  *
  54.  * Euclidean distance between the trained vectors and the Mel-Frequency
  55.  * Cepstral Co-efficients are computed for each trained vectors. The
  56.  * trained vector that produces the smallest Euclidean distance will  
  57.  * be identified as the speaker.
  58.  *
  59.  *
  60.  * Written by Vasanthan Rangan and Sowmya Narayanan
  61.  *
  62.  ******************************************************************************/
  63. /*****************************************************************************
  64.  * Include Header Files
  65.  ******************************************************************************/
  66. #include "DSK6713_aic23.h"
  67. Uint32 fs=DSK6713_AIC23_FREQ_8KHZ;
  68. #include <stdio.h>
  69. #include <math.h>
  70. #include "block_dc.h" // Header file for identifying the start of speech signal
  71. #include "detect_envelope.h" // Header file for identfying the start of speech signal
  72. #include "training1.h" // Header file containing the trained vectors.
  73. /*****************************************************************************
  74.  * Definition of Variables
  75.  *****************************************************************************/
  76. #define Number_Of_Filters 20 // Number of Mel-Frequency Filters
  77. #define column_length 256 // Frame Length of the one speech signal
  78. #define row_length 100 // Total number of Frames in the given speech signal
  79. #define PI 3.14159
  80. /*****************************************************************************
  81.  * Custom Structure Definition
  82.  *****************************************************************************/
  83.  
  84. struct complex { 
  85. float real;
  86. float imag;
  87. }; // Generic Structure to represent real and imaginary part of a signal
  88. struct buffer {
  89. struct complex data[row_length][column_length];
  90. }; // Structure to store the input speech sample
  91. struct mfcc {
  92. float data[row_length][Number_Of_Filters];
  93. }; // Structure to store the Mel-Frequency Co-efficients
  94. /*****************************************************************************
  95.  * Assigning the data structures to external memory
  96.  *****************************************************************************/
  97. #pragma DATA_SECTION(real_buffer,".EXTRAM")
  98. struct buffer real_buffer; //real_buffer is used to store the input speech.
  99. #pragma DATA_SECTION(coeff,".EXTRAM")
  100. struct mfcc coeff; //coeff is used to store the Mel-Frequency Spectrum.
  101. #pragma DATA_SECTION(mfcc_ct,".EXTRAM")
  102. struct mfcc mfcc_ct; //mfcc_ct is used to store the Mel-Frequency Cepstral Co-efficients.
  103. /*****************************************************************************
  104.  * Variable Declaration
  105.  *****************************************************************************/
  106. int gain;           /* output gain (Used during Play-Back */
  107. int signal_status; /* Variable to detect speech signal */
  108. int count; /* Variable to count */
  109. int column; /* Variable used for incrementing column (Samples inside Frame)*/
  110. int row; /* Variable used for incrementing row(Number of Frames)*/
  111. /* Variable to identify where the program is Example: program_control=0 means 
  112. program is capturing input speech signal program_control=1 means that program 
  113. has finished capturing input and ready for processing. At this time the 
  114. input speech signal is replayed back program_control=2 means program is 
  115. ready for idenitification. */
  116. int program_control; 
  117. float mfcc_vector[20]; /* Variable to store the vector of the speech signal */
  118. /*****************************************************************************
  119.  * Function Declaration
  120.  *****************************************************************************/
  121. void fft (struct buffer *, int , int ); /* Function to compute Fast Fouruer Transform */
  122. short playback(); /* Function for play back */
  123. void log_energy(struct mfcc *); /* Function to compute Log of Power Signal */
  124. void mfcc_coeff(struct mfcc * , struct mfcc *); /* Function to compute MFCC */
  125. void mfcc_vect(struct mfcc * , float *); /* Funciton to compute MFCC Vector */
  126. /******************************************************************************
  127.  * Function Definition Starts
  128.  ******************************************************************************/
  129. interrupt void c_int11()  {          /* interrupt service routine */
  130. short sample_data;
  131. short out_sample;
  132. if ( program_control == 0 ) { /* Beginning of Capturing input speech */
  133. sample_data = input_sample();           /* input data */
  134. signal_status = framing_windowing(sample_data, &real_buffer); /* Signal Identification
  135.       * and Framing and Windowing */
  136. out_sample = 0; /* Output Data */
  137. if (signal_status > 0) {
  138. program_control = 1;        /* Capturing input signal is done */
  139. }
  140. output_sample(out_sample); /* play nothing */
  141. }
  142. if ( program_control == 1 ) { /* Beginning of the Play back */
  143. out_sample = playback(); /* call the playback funciton to get the 
  144.   * stored speech sample */
  145. output_sample(out_sample); /* play the output speech sample */
  146. }
  147. return;
  148. }
  149. void main()  { /* Main Function of the program */
  150. /****************************************************************************
  151.  * Declaring Local Variables
  152.  *****************************************************************************/
  153.  
  154. int i; /* Variable used for counters */
  155.    int j; /* Variable used for Counters */
  156.    int stages,speaker; /* Variable to identify total number of stages
  157.     * and the speaker */
  158.    float distance,ref_distance; /* Variable for storing Euclidean Distance
  159.      * and the reference Distance for comparision */
  160. /*****************************************************************************
  161.  * Execution of functions start
  162.  ******************************************************************************/
  163. comm_intr();   /* init DSK, codec, McBSP */
  164. /******************************************************************************
  165.  * Initializing Variables
  166.  *****************************************************************************/
  167.   gain = 1;
  168. column = 0;
  169. row = 0;
  170. program_control = 0;
  171. signal_status = 0;
  172. count = 0;   
  173. stages=8; /* Total Number of stages in FFT = 8 */
  174. ref_distance = 9999999999999999.9999999; /* Variable for storing reference Distance */
  175. for ( i=0; i < row_length ; i++ ) { /* Total Number of Frames */
  176.    for ( j = 0; j < column_length ; j++) { /* Total Number of Samples in a Frame */
  177.    real_buffer.data[i][j].real = 0.0; /* Initializing real part to be zero */
  178.    real_buffer.data[i][j].imag = 0.0; /* Initializing imaginary part to be zero*/
  179. }
  180.    }
  181.    for ( i=0; i<row_length; i++) { /* Total Number of Frames */
  182.    for ( j=0; j<Number_Of_Filters; j++) { /* Total Number of Filters */
  183. coeff.data[i][j] = 0.0; /* Initializing the co-effecient array */
  184. mfcc_ct.data[i][j] = 0.0; /* Initializing the array for storing MFCC */
  185. }
  186. } /* End of Initializing the variables to zero */
  187. /*****************************************************************************
  188. * Begining of the execution of the functions.
  189. *****************************************************************************/
  190. while(program_control == 0);      /* infinite loop For Receiving/capturing alone*/
  191.    while(program_control ==1); /* infinite loop for playback alone*/
  192. /* Compute FFT of the input speech signal after Framing and Windowing */
  193. fft(&real_buffer,column_length,stages);
  194. /* Compute Power Spectrum of the speech signal in Frequency Domain Representation */
  195. power_spectrum(&real_buffer);
  196. /* Compute Mel-Frequency Spectrum of the speech signal in Power Spectrum Form */
  197. mel_freq_spectrum(&real_buffer,&coeff);
  198. /* Computation of Log of the Power Spectrum */
  199. log_energy(&coeff);
  200. /* Computation of Discrete Cosine Transform */
  201. mfcc_coeff(&mfcc_ct,&coeff);
  202. /* Compute Vector */
  203. mfcc_vect(&mfcc_ct,mfcc_vector);
  204. /* Identifying the Speaker */
  205. for ( i=0; i<Number_Of_Speakers; i++ ) { /* Total Number of trained Speakers */
  206. distance = 0.0; /* Initialize the distance to be Zero */
  207.    for ( j=0; j<Number_Of_Coefficients; j++ ) { /* Total Number of Stored Co-efficients
  208.           * of the training Vector */
  209. /* Compute Euclidean Distance */
  210.    distance = distance + ((mfcc_vector[j]-training_vector[i][j])*(mfcc_vector[j]-training_vector[i][j]));
  211. }
  212. /* Identify the speaker with least distance */
  213. if ( distance < ref_distance ) { /* check if the distance is less than 
  214.      * previous computed distances */
  215.   speaker = i; /* Identify the speaker to be corresponding sampel */
  216.   ref_distance = distance;  /* Store the new Distance */
  217.   }
  218. }
  219. /* Print the identified Speaker */
  220. printf("Input Speaker is identified to be %d Speaker from the Training Setn",++speaker);
  221. }
  222. /* Function to Compute Fast Fourier Transform */
  223. void fft (struct buffer *input_data, int n, int m) {/* Input speech Data, n = 2^m, m = total number of stages */
  224. int n1,n2,i,j,k,l,row_index; /* Declare Variables
  225.   * n1 is the difference between upper and lower 
  226.   * i,j,k,l are counters
  227.   * row_index is used to index every frame */
  228. float xt,yt,c,s,e,a; /* declare variables for storing temporary values
  229.     * xt,yt for temporary real and Imaginary respectively
  230.     * c for cosine
  231.     * s for sine
  232.     * e and a for computing the input to cosine and sine
  233.     */
  234. for ( row_index = 0; row_index < row_length; row_index++) { /* For every frame */
  235. /* Loop through all the stages */
  236. n2 = n;
  237. for ( k=0; k<m; k++) {
  238. n1 = n2;
  239. n2 = n2/2;
  240. e = PI/n1;
  241. /* Compute Twiddle Factors */
  242. for ( j= 0; j<n2; j++) {
  243. a = j*e;
  244. c = (float) cos(a);
  245. s = (float) sin(a);
  246. /* Do the Butterflies for all 256 samples */
  247. for (i=j; i<n; i+= n1) {
  248. l = i+n2;
  249. xt = input_data->data[row_index][i].real - input_data->data[row_index][l].real;
  250. input_data->data[row_index][i].real = input_data->data[row_index][i].real+input_data->data[row_index][l].real;
  251. yt = input_data->data[row_index][i].imag - input_data->data[row_index][l].imag;
  252. input_data->data[row_index][i].imag = input_data->data[row_index][i].imag+input_data->data[row_index][l].imag;
  253. input_data->data[row_index][l].real = c*xt + s*yt;
  254. input_data->data[row_index][l].imag = c*yt - s*yt;
  255. }
  256. }
  257. }
  258. /* Bit Reversal */
  259. j = 0;
  260. for ( i=0; i<n-1; i++) {
  261. if (i<j) {
  262. xt = input_data->data[row_index][j].real;
  263. input_data->data[row_index][j].real = input_data->data[row_index][i].real;
  264. input_data->data[row_index][i].real = xt;
  265. yt = input_data->data[row_index][j].imag;
  266. input_data->data[row_index][j].imag = input_data->data[row_index][i].imag;
  267. input_data->data[row_index][i].imag = yt;
  268. }
  269. }
  270. }
  271. return;
  272. }
  273. /* Function to compute log of Mel-Frequency spectrum */
  274. void log_energy(struct mfcc *co_eff) {
  275. int i,j; /* Variables declared to act as counters */
  276.    for ( i=0; i<row_length; i++) { /* For all the frames (100 Frames)) */
  277. for ( j=0; j<Number_Of_Filters; j++ ) { /* For all the filters (20 Filters)*/
  278. co_eff->data[i][j] = (float) log((double) co_eff->data[i][j]); /* Compute log of co-efficients */
  279. }
  280.    }
  281. }
  282. /* Function to compute Discrete Cosine Transform */
  283. void mfcc_coeff(struct mfcc *mfccct, struct mfcc *co_eff) {
  284. int i,j,k; /* Variable declared to act as counters */
  285. for ( i=0; i<row_length; i++) { /* For all the frames (100 Frames) */
  286.    for (j=0; j<Number_Of_Filters; j++ ) { /* For all the filters */
  287.    mfccct->data[i][j] = 0.0;
  288. /* Compute Cosine Transform of the Signal */
  289.    for ( k=0; k<Number_Of_Filters; k++) {
  290.   mfccct->data[i][j] = mfccct->data[i][j] + co_eff->data[i][k]*cos((double)((PI*j*(k-1/2))/Number_Of_Filters));
  291.    }
  292.    }
  293.    }
  294. }
  295. /* Function to compute Euclidean distance and conversion to Vector */
  296. void mfcc_vect(struct mfcc *mfccct, float *mfccvector) {
  297. int i,j; /* variables declared to act as counters */
  298. for ( i=0; i< Number_Of_Filters; i++ ) { /* Total Number of Filters */
  299.    mfccvector[i] = 0; /* Initialize the Vector to Zero */
  300.    for (j=0; j< row_length; j++) { /* For all the Frames Compute the distance */
  301.    mfccvector[i] = mfccvector[i] + ((mfccct->data[j][i])*(mfccct->data[j][i]));
  302.    }
  303.    }
  304. }
  305. /* Function to play back the speech signal */
  306. short playback() {
  307. column++; /* Variable to store the index of speech sample in a frame */
  308. if ( column >= column_length ) { /* If Colum >=256 reset it to zero
  309.   * and increment the frame number */
  310. column = 0; /* initialize the sample number back to zero */
  311. row++;  /* Increment the Frame Number */
  312. }
  313. if ( row >= row_length ) { /* If Total Frame Number reaches 100 initialize
  314. * row to be zero
  315. * and change the program control inidcating
  316. * end of playback */
  317. program_control = 2; /* End of Playback */
  318. row = 0; /* Initialize the frame number back to zero */
  319. }
  320. return ((int)real_buffer.data[row][column].real); /* Return the stored speech Sample */
  321. }