00001
00020 #include <stdlib.hch>
00021 #include "pal_master.hch"
00022
00023 #include "audio.hch"
00024 #include "weights_256.hch"
00025 #include "configuration.hch"
00026 #include "xilinxmult.hch"
00027 #include "fft.hch"
00028
00029 #if HAVE_DEBUG
00030 #include "debug.hch"
00031 #endif
00032
00033
00034
00035
00036
00037
00038 #if HARDWARE_MULTIPLY
00039 mpram
00040 {
00041 ram signed 18 rwrite[256];
00042 rom signed 18 read[256];
00043 } real with {block = "BlockRAM"};
00044
00045 mpram
00046 {
00047 ram signed 18 rwrite[256];
00048 rom signed 18 read[256];
00049 } imaginary with {block = "BlockRAM"};
00050 #else
00051 mpram
00052 {
00053 ram signed 24 rwrite[256];
00054 rom signed 24 read[256];
00055 } real with {block = "BlockRAM"};
00056
00057 mpram
00058 {
00059 ram signed 24 rwrite[256];
00060 rom signed 24 read[256];
00061 } imaginary with {block = "BlockRAM"};
00062 #endif
00063
00064 ram signed 7 eq_settings[16] = {0,2,4,7,10,13,16,19,22,26,30,35,41,48,55,63};
00065
00066 #if HARDWARE_MULTIPLY
00067 #define DC_COMPONENT 0
00068 #else
00069 #define DC_COMPONENT 8470527
00070 #endif
00071
00082 macro proc multiply(result, op_a, op_b)
00083 {
00084 #if HARDWARE_MULTIPLY
00085 xilinxmult(result, op_a, adjs(op_b,18));
00086 #else
00087 result = (adjs(op_a,38))*(adjs(op_a,38));
00088 #endif
00089 }
00090
00091
00092
00093
00104 void calculate_fft(unsigned 1 select_inverse)
00105 {
00106 unsigned 4 level;
00107 unsigned 8 point1,point2,j,f,k;
00108 unsigned 9 e,i;
00109 signed 16 weight1,weight2;
00110 #if HARDWARE_MULTIPLY
00111 signed 18 p,q,r,t;
00112 #else
00113 signed 24 p,q,r,t;
00114 #endif
00115 signed a,b;
00116
00117 #if HARDWARE_MULTIPLY
00118
00119
00120
00121
00122 macro expr rescale (x) = (x[35] @ x[30:14]);
00123 #else
00124
00125 macro expr rescale (x) = ((x>>FRACBITS)<-24);
00126 #endif
00127
00128 for(level=1;level<=NUMBER_OF_COLUMNS;level++)
00129 {
00130 e=1<<(NUMBER_OF_COLUMNS-level+1);
00131 f=(e>>1)<-8;
00132
00133 for(j=1;j<=f;j++)
00134 {
00135 par
00136 {
00137
00138 weight1 = weight_re[((j-1)<<(level-1))<-7];
00139
00140
00141
00142 weight2 = (!select_inverse) ? (weight_im[((j-1)<<(level-1))<-7]) : -(weight_im[((j-1)<<(level-1))<-7]);
00143
00144
00145
00146
00147
00148
00149
00150 for(i=0@j;i<=NUMBER_OF_POINTS;i+=e)
00151 {
00152 par
00153 {
00154 point1 = ((i<-8)-1);
00155 point2 = (((i<-8)+f)-1);
00156 }
00157
00158 par
00159 {
00160 p = (real.read[point1] >> 1) + (real.rwrite[point2] >> 1);
00161 q = (imaginary.read[point1] >> 1) + (imaginary.rwrite[point2] >> 1);
00162 }
00163
00164 par
00165 {
00166 r = (real.read[point1] >> 1) - (real.rwrite[point2] >> 1);
00167 t = (imaginary.read[point1] >> 1) - (imaginary.rwrite[point2] >> 1);
00168 }
00169
00170 multiply(a,r,weight1);
00171 multiply(b,t,weight2);
00172
00173 par
00174 {
00175 real.rwrite[point2] = (rescale(a-b));
00176 imaginary.rwrite[point1] = q;
00177 }
00178
00179 multiply(a,t,weight1);
00180 multiply(b,r,weight2);
00181
00182 par
00183 {
00184 real.rwrite[point1] = p;
00185 imaginary.rwrite[point2] = (rescale(a+b));
00186 }
00187
00188 }
00189 }
00190 }
00191 }
00192
00193 j=1;
00194 for(i=1;i<NUMBER_OF_POINTS;i++)
00195 {
00196 if(i<(0@j))
00197 {
00198 par
00199 {
00200 point1=j-1;
00201 point2=(i-1)<-8;
00202 }
00203
00204
00205
00206
00207
00208
00209 par
00210 {
00211 p = real.read[point1];
00212 q = imaginary.read[point1];
00213 }
00214 par
00215 {
00216 r = real.read[point2];
00217 t = imaginary.read[point2];
00218 }
00219 par
00220 {
00221 real.rwrite[point1] = r;
00222 imaginary.rwrite[point1] = t;
00223 }
00224 par
00225 {
00226 real.rwrite[point2] = p;
00227 imaginary.rwrite[point2] = q;
00228 }
00229 }
00230
00231 k = NUMBER_OF_POINTS>>1;
00232
00233
00234 while(k<j)
00235 {
00236 j = j-k;
00237 k = k>>1;
00238 }
00239
00240 j+=k;
00241 }
00242
00243 }
00244
00256 #if HARDWARE_MULTIPLY
00257 void perform_fft(signed 18 *pcm_audio)
00258 #else
00259 void perform_fft(signed 16 *pcm_audio)
00260 #endif
00261 {
00262 unsigned 8 k;
00263 #if HARDWARE_MULTIPLY
00264 signed 18 sample;
00265 k=0;
00266 sample = adjs(pcm_audio[k],18);
00267 #else
00268 signed 24 sample;
00269 k=0;
00270 sample = adjs(pcm_audio[k],24);
00271 #endif
00272
00273
00274
00275
00276
00277
00278 do
00279 {
00280
00281
00282
00283
00284 par
00285 {
00286
00287
00288 #if HARDWARE_MULTIPLY
00289 sample = adjs(pcm_audio[k+1],18);
00290 #else
00291 sample = adjs(pcm_audio[k+1],24);
00292 #endif
00293 real.rwrite[k] = sample;
00294 imaginary.rwrite[k] = 0;
00295 k++;
00296 }
00297 } while (k);
00298
00299
00300
00301 #if PERFORM_FFT_CALCULATION
00302 calculate_fft(0);
00303 #endif
00304
00305
00306 }
00307
00321 #if HARDWARE_MULTIPLY
00322 void perform_ifft(signed 18 *modified_audio, unsigned 6 *ifft_info)
00323 #else
00324 void perform_ifft(signed 16 *modified_audio, unsigned 6 *ifft_info)
00325 #endif
00326 {
00327 unsigned 6 k;
00328 #if HARDWARE_MULTIPLY
00329 signed 18 p;
00330 #else
00331 signed 24 p;
00332 #endif
00333 #if PERFORM_FFT_CALCULATION
00334 calculate_fft(1);
00335 #endif
00336
00337 k=0;
00338
00339 #if PERFORM_FFT_CALCULATION
00340 #if HARDWARE_MULTIPLY
00341 p = (real.read[(0@k)+95] << NUMBER_OF_COLUMNS);
00342 #else
00343 p = (real.read[(0@k)+95] >> NUMBER_OF_COLUMNS);
00344 #endif
00345 #else
00346 p = (real.read[(0@k)+95]);
00347 #endif
00348
00349 do
00350 {
00351
00352
00353
00354
00355 par
00356 {
00357
00358
00359
00360
00361
00362
00363
00364 #if PERFORM_FFT_CALCULATION
00365 #if HARDWARE_MULTIPLY
00366 p = (real.read[(0@k)+95] << NUMBER_OF_COLUMNS);
00367 #else
00368 p = (real.read[(0@k)+95] >> NUMBER_OF_COLUMNS);
00369 #endif
00370 #else
00371 p = (real.read[(0@k)+95]);
00372 #endif
00373
00374 #if HARDWARE_MULTIPLY
00375 modified_audio[k] = p ;
00376 #else
00377 modified_audio[k] = (p<-16);
00378 #endif
00379
00380 ifft_info[k] = (unsigned 6)(32+(p[17:12]));
00381 k++;
00382 }
00383 } while(k);
00384 }
00385
00398 void equalize_audio(audiodata_t *audiodata)
00399 {
00400 #if HARDWARE_MULTIPLY
00401 signed 18 p,q;
00402 #else
00403 signed 24 p,q;
00404 #endif
00405 signed 18 a;
00406 unsigned 8 i, mirror_i, bit, m, n;
00407 unsigned 7 old_value;
00408 unsigned 9 tmp;
00409
00410
00411
00412 macro proc equalize_bar(retval)
00413 {
00414 signed result;
00415 multiply(result, q,a);
00416 #if HARDWARE_MULTIPLY
00417 retval = result[23:6];
00418 #else
00419 retval = result[29:6];
00420 #endif
00421 }
00422
00423 p = real.read[0] - DC_COMPONENT;
00424 real.rwrite[0] = p;
00425
00426 for(i=0;i!=NUMBER_OF_FREQUENCIES;i++)
00427 {
00428
00429
00430 a = adjs(eq_settings[audiodata->equalizer_levels_ptr[i <- 7]],18);
00431
00432
00433
00434 q = real.read[i];
00435 equalize_bar(p);
00436 real.rwrite[i] = p;
00437
00438 q = imaginary.read[i];
00439 equalize_bar(p);
00440 imaginary.rwrite[i] = p;
00441
00442
00443
00444 if ((i<-7)!=0)
00445 {
00446 mirror_i = (NUMBER_OF_POINTS-1)-i+1;
00447 q = real.read[mirror_i];
00448 equalize_bar(p);
00449 real.rwrite[mirror_i] = p;
00450
00451 q = imaginary.read[mirror_i];
00452 equalize_bar(p);
00453 imaginary.rwrite[mirror_i] = p;
00454 }
00455 }
00456
00457
00458 for(i=0;i<NUMBER_OF_FREQUENCIES;i++)
00459 {
00460 p = real.read[i];
00461 q = imaginary.read[i];
00462 #if HARDWARE_MULTIPLY
00463 if (p[17] == 1) p = -p; else delay;
00464 if (q[17] == 1) q = -q; else delay;
00465 #else
00466 if (p[23] == 1) p = -p; else delay;
00467 if (q[23] == 1) q = -q; else delay;
00468 #endif
00469 p = (p<q) ? q : p;
00470
00471 if (!audiodata->display_log)
00472 {
00473
00474 bit=126;
00475 #if HARDWARE_MULTIPLY
00476 while ((p[15] == 0) && (bit != 0))
00477 #else
00478 while ((p[21] == 0) && (bit != 0))
00479 #endif
00480 par
00481 {
00482 p = p<<1;
00483 bit = bit - 18;
00484 }
00485 old_value = audiodata->fft_info.write[0 @ (i <- 7)];
00486 tmp = ((0@old_value) + (0@bit))>>1;
00487 audiodata->fft_info.write[0 @ (i <- 7)] = (old_value <= (tmp<-7)) ? (tmp<-7) : old_value-1;
00488 }
00489 else
00490 {
00491 old_value = audiodata->fft_info.write[0 @ (i <- 7)];
00492 #if HARDWARE_MULTIPLY
00493 audiodata->fft_info.write[0 @ (i <- 7)] = (old_value<=(unsigned)(p[15:9])) ? (unsigned)(p[15:9]) : old_value-1;
00494 #else
00495 audiodata->fft_info.write[0 @ (i <- 7)] = (old_value<=(unsigned)(p[21:15])) ? (unsigned)(p[21:15]) : old_value-1;
00496 #endif
00497 }
00498 }
00499
00500
00501
00502 p = real.read[0] + DC_COMPONENT;
00503 real.rwrite[0] = p;
00504 }
00505