14a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*---------------------------------------------------------------------------* 24a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * spec_anl.c * 34a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * * 44a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * Copyright 2007, 2008 Nuance Communciations, Inc. * 54a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * * 64a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the 'License'); * 74a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * you may not use this file except in compliance with the License. * 84a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * * 94a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * You may obtain a copy of the License at * 104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 * 114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * * 124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software * 134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * distributed under the License is distributed on an 'AS IS' BASIS, * 144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * See the License for the specific language governing permissions and * 164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * limitations under the License. * 174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * * 184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *---------------------------------------------------------------------------*/ 194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <stdlib.h> 234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#ifndef _RTT 244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <stdio.h> 254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif 264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <string.h> 274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <math.h> 284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <limits.h> 294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <assert.h> 304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "hmm_desc.h" 324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "front.h" 334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "pendian.h" 344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "portable.h" 354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "LCHAR.h" 364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "../clib/memmove.h" 384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define DEBUG 0 404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "sh_down.h" 424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic int sort_ints_unique(int *list, int *num); 444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//static void mask_fft_taps(fftdata *data, int num, front_freq *freqobj); 454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid peakpick(front_freq *freqobj, fftdata *density, int num_freq); 474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid magsq(fftdata *x, fftdata *y, fftdata *z, int ns); 484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid preemph(fftdata *data, int window_len, samdata *wav_data, 504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int num_samples, coefdata pre_mel, 514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project bigdata *last_sample); 524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid filtbank(front_freq *freqobj, fftdata *density, cepdata *fbo); 534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid filterbank_emulation(front_channel * channel, front_wave *waveobj, 574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project front_freq *freqobj, front_cep *cepobj, samdata *income, 584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project samdata *outgo, int num_samples) 594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* Part II. Mel cepstrum coefficients 614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ** 624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ** Maintain parameter queue */ 634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project MEMMOVE(channel->cep + (channel->mel_dim + 1), channel->cep, 644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project (Q2 - 1) *(channel->mel_dim + 1), sizeof(cepdata)); 654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project channel->shift = 0; 664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* 2.01 Pre-emphasize waveform 684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project Only the new samples are preemphasized. To carry on from the previous call, 694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project the last sample value is stored in lastx. 704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */ 714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project preemph(channel->prebuff, freqobj->window_length, income, num_samples, 724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project waveobj->pre_mel, &channel->lastx); 734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG 754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project log_report("preemphasized data\n"); 764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project write_scaled_frames(freqobj->window_length, 1, channel->prebuff, D_FIXED, (float) 1 / (0x01 << WAVE_SHIFT)); 774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif 784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /****************************************************************************** 794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ** The "NEW" fft performs shifting operations in fixed point, to maximise 804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ** precision. 814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ** 824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *******************************************************************************/ 834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project channel->shift += place_sample_data(&freqobj->fft, channel->prebuff, 844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project freqobj->ham, freqobj->window_length); 854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG 864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project log_report("windowed data\n"); 874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (channel->shift >= 0) 884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project write_scaled_frames(freqobj->fft.size, 1, freqobj->fft.real, D_FIXED, (float)(0x01 << channel->shift)); 904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project write_scaled_frames(freqobj->fft.size, 1, freqobj->fft.imag, D_FIXED, (float)(0x01 << channel->shift)); 914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project write_scaled_frames(freqobj->fft.size, 1, freqobj->fft.real, D_FIXED, (float)1 / (0x01 << -channel->shift)); 954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project write_scaled_frames(freqobj->fft.size, 1, freqobj->fft.imag, D_FIXED, (float)1 / (0x01 << -channel->shift)); 964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif 984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project channel->shift *= 2; 994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project channel->shift += fft_perform_and_magsq(&freqobj->fft); 1004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG 1024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project log_report("After magnitude squared (%d)\n", channel->frame_count); 1034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (channel->shift >= 0) 1044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project write_scaled_frames(freqobj->fft.size, 1, freqobj->fft.real, D_FIXED, (float)(0x01 << (channel->shift))); 1054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 1064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project write_scaled_frames(freqobj->fft.size, 1, freqobj->fft.real, D_FIXED, (float)1 / (0x01 << (- channel->shift))); 1074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif 1084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG 1104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project log_report("After magnitude squared: "); 1114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (channel->shift >= 0) 1124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project write_scaled_frames(freqobj->fft.size, 1, (void *)freqobj->fft.real, D_FIXED, (float)(0x01 << channel->shift)); 1134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 1144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project write_scaled_frames(freqobj->fft.size, 1, (void *)freqobj->fft.real, D_FIXED, (float)1 / (0x01 << -channel->shift)); 1154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif 1164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (freqobj->do_nonlinear_filter) 1184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project peakpick(freqobj, freqobj->fft.real, freqobj->fft.size + 1); 1194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG 1214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project log_report("After peakpick: "); 1224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (channel->shift >= 0) 1234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project write_scaled_frames(freqobj->fft.size + 1, 1, (void *)freqobj->fft.real, D_FIXED, (float)(0x01 << channel->shift)); 1244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 1254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project write_scaled_frames(freqobj->fft.size + 1, 1, (void *)freqobj->fft.real, D_FIXED, (float)1 / (0x01 << -channel->shift)); 1264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif 1274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* 2.23 Apply filterbank emulation */ 1294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project channel->shift += RAMP_SHIFT; 1304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project filtbank(freqobj, freqobj->fft.real, channel->filterbank); 1314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#if DEBUG 1324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project log_report("After filterbanked: "); 1334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (channel->shift >= 0) 1344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project write_scaled_frames(freqobj->nf, 1, channel->filterbank, D_FIXED, (float)(0x01 << channel->shift)); 1354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 1364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project write_scaled_frames(freqobj->nf, 1, channel->filterbank, D_FIXED, (float)1 / (0x01 << -channel->shift)); 1374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif 1384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return; 1404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid preemph(fftdata *data, int window_len, samdata *wav_data, 1444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int num_samples, coefdata pre_mel, 1454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project bigdata *last_sample) 1464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* 1474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project** pre-emphasize on speech data, check for end of data */ 1484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* SCALE: In this stage we're introducing a scale factor of 2 */ 1494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 1504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int i; 1514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project bigdata temp; 1524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT(data); 1544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT(last_sample); 1554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT(wav_data); 1564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT(num_samples >= 0); 1574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (num_samples > window_len) 1584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project num_samples = window_len; 1594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (num_samples < window_len) 1614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project MEMMOVE(data, data + num_samples, (window_len - num_samples), 1624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project sizeof(fftdata)); 1634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project data += window_len - num_samples; 1644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* If no preemphasis to do 1664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */ 1674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (pre_mel == 0) 1684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { /* dont't shift */ 1694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (i = 0; i < num_samples; i++) 1704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project data[i] = (fftdata) wav_data[i]; 1714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return; 1724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* Otherwise do the preemphasis 1754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */ 1764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (i = 0; i < num_samples; i++) 1774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 1784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project temp = SHIFT_UP((bigdata)wav_data[i], COEFDATA_SHIFT); 1794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project data[i] = (fftdata)(SHIFT_DOWN(temp - (*last_sample), COEFDATA_SHIFT)); 1804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *last_sample = (bigdata)pre_mel * wav_data[i]; 1814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return; 1844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 1854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid magsq(fftdata *x, fftdata *y, fftdata *z, int ns) 1874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* 1884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project** magnitude squared, tailored for TI FFT routines 1894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project** The dynamic range should fit 32 - RAMP_SHIFT */ 1904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 1914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int i; 1924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT((float)x[0] *(float)x[0] < LONG_MAX); 1944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT((float)x[0] *(float)x[0] > LONG_MIN); 1954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project z[0] = (fftdata)((bigdata)x[0] * (bigdata)x[0]); 1964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (i = 1; i < ns; i++) 1974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 1984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT(((fftdata)x[i] *(fftdata)x[i]) >= 0); 1994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT(((fftdata)y[i] *(fftdata)y[i]) >= 0); 2004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT((float)x[i] *(float)x[i] < LONG_MAX); 2014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT((float)x[i] *(float)x[i] > LONG_MIN); 2024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT((float)y[i] *(float)y[i] < LONG_MAX); 2034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT((float)y[i] *(float)y[i] > LONG_MIN); 2044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* z[i]= (fftdata) SHIFT_DOWN ((bigdata)x[i] * (bigdata)x[i] + (bigdata)y[i] * (bigdata)y[i], RAMP_SHIFT); 2054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */ 2064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project z[i] = (fftdata)(((bigdata)x[i] * (bigdata)x[i]) 2074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project + ((bigdata)y[i] * (bigdata)y[i])); 2084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (z[i] <= 0) 2094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project z[i] = (fftdata) 1; 2104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 2114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return; 2124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 2134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid peakpick(front_freq *freqobj, fftdata *density, int num_freq) 2154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 2164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int i; 2174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fftdata peak; 2184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fftdata bdecay; 2194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fftdata fdecay; 2204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int first; 2214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int last; 2224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT(freqobj); 2244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* Fixed pt requires scale up of COEFDATA_SHIFT on these pars (coefdata) */ 2254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project bdecay = freqobj->peakpickdown; 2264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fdecay = freqobj->peakpickup; 2274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if ((bdecay <= (fftdata) 0.0) && (fdecay <= (fftdata) 0.0)) 2294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return; 2304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project first = freqobj->cut_off_below; 2324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project last = freqobj->cut_off_above; 2334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* this filters from cut_off_below to */ 2344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* cut_off_above inclusive */ 2354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (last >= num_freq) 2374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project last = num_freq - 1; 2384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* as most routines seem to check both */ 2394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* limits */ 2404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (bdecay > 0.0) 2424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 2434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT(density[last] >= 0); 2444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project peak = density[last]; 2454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (i = last - 1; i >= first; i--) 2464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 2474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project peak = (fftdata)(SHIFT_DOWN((bigdata)peak, COEFDATA_SHIFT) * (bigdata)bdecay); 2484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT(peak >= 0); 2494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (density[i] > peak) 2504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project peak = density[i]; 2514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 2524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project density[i] = peak; 2534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 2544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 2554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (fdecay > 0.0) 2564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 2574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project peak = density[first]; 2584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (i = first + 1; i <= last; i++) 2594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 2604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project peak = (fftdata)(SHIFT_DOWN((bigdata)peak, COEFDATA_SHIFT) * (bigdata)fdecay); 2614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (density[i] > peak) 2624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project peak = density[i]; 2634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 2644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project density[i] = peak; 2654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 2664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 2674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return; 2684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 2694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid filtbank(front_freq *freqobj, fftdata *density, cepdata *fbo) 2714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* 2724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project** pwr spect -> filter bank output (linear) */ 2734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 2744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int i, j, k; 2754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project bigdata t, sum, mom, nxt; 2764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* Scale down before starting mel-filterbank operations 2784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */ 2794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (i = 0; i < freqobj->cut_off_above; i++) 2804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project density[i] = SHIFT_DOWN(density[i], RAMP_SHIFT); 2814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project j = MAX(freqobj->fcmid[0], freqobj->cut_off_below); 2834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project nxt = 0; 2844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (; j < freqobj->fcmid[1]; j++) 2854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 2864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT(((float)nxt + (float)freqobj->framp[j] *(float)density[j]) < LONG_MAX); 2874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT(((float)nxt + (float)freqobj->framp[j] *(float)density[j]) > -LONG_MAX); 2884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project nxt += (bigdata) SHIFT_DOWN((bigdata)freqobj->framp[j] * (bigdata)density[j], RAMP_SHIFT); 2894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 2904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (i = 0, k = 2; i < freqobj->nf; i++, k++) 2914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 2924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project sum = mom = 0; 2934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (; j < freqobj->fcmid[k]; j++) 2944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 2954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* TODO: Tidy up this fixed pt shifting. BP */ 2964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT((float) freqobj->framp[j] *(float) density[j] < LONG_MAX); 2984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT((float) freqobj->framp[j] *(float) density[j] > LONG_MIN); 2994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT((float) sum + (float)density[j] < LONG_MAX); 3004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT((float) sum + (float)density[j] > LONG_MIN); 3014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project sum += (bigdata) density[j]; 3024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT((float) mom + (float) freqobj->framp[j] *(float) density[j] < LONG_MAX); 3034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT((float) mom + (float) freqobj->framp[j] *(float) density[j] > LONG_MIN); 3044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project mom += (bigdata)(long) SHIFT_DOWN((bigdata)freqobj->framp[j] * (bigdata)density[j], RAMP_SHIFT); 3064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 3074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT(((float)nxt + (float)sum - (float)mom) < LONG_MAX); 3094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT(((float)nxt + (float)sum - (float)mom) > LONG_MIN); 3104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* TODO: refine this expression. Shift down fcscl in advance. */ 3124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project t = (bigdata)((SHIFT_UP(nxt + sum - mom, HALF_RAMP_SHIFT) 3134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project + SHIFT_DOWN(freqobj->fcscl[i+1], HALF_RAMP_SHIFT + 1)) 3144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project / SHIFT_DOWN(freqobj->fcscl[i+1], HALF_RAMP_SHIFT)); 3154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* TODO: cleanup and also check for division by zero */ 3164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project nxt = mom; 3174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fbo[i] = (cepdata) t; 3184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 3194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return; 3204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 3214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectint create_spectrum_filter(front_freq *freqobj, int *freq, int *spread) 3234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 3244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int ii, jj, freq_step; 3254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int lo, hi; 3264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT(freqobj); 3274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT(freqobj->spectrum_filter_num == 0); 3284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT(freqobj->samplerate > 0); 3294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* Convert to FFT taps. Mark adjacent taps as well as taps within spread */ 3304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project freq_step = (freqobj->samplerate << 12) / (2 * freqobj->fft.size); 3314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project freqobj->spectrum_filter = (int *) CALLOC_CLR(freqobj->fft.size + 1, sizeof(int), "cfront.spectrum_filter"); 3324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project freqobj->spectrum_filter_num = 0; 3334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (ii = 0 ; ii < MAX_FILTER_NUM; ii++) 3344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 3354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (freq[ii] == 0) 3364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project continue; 3374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project lo = (((freq[ii] - spread[ii]) * 2 * freqobj->fft.size) + freqobj->samplerate / 2) / freqobj->samplerate; 3384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project hi = (((freq[ii] + spread[ii]) * 2 * freqobj->fft.size) + freqobj->samplerate / 2) / freqobj->samplerate; 3394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (jj = lo; jj <= hi;jj++) 3424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 3434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (freqobj->spectrum_filter_num >= (int) freqobj->fft.size) 3444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project SERVICE_ERROR(MAX_FILTER_POINTS_EXCEEDED); 3454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project freqobj->spectrum_filter[freqobj->spectrum_filter_num++] = jj; 3464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 3474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* jj=0; 3484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project while (((jj+1)*freq_step)>>12 <= freq[ii]-spread[ii]) 3494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project jj++; 3504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project while (((jj-1)*freq_step>>12) < freq[ii]+spread[ii]){ 3514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (freqobj->spectrum_filter_num >= (int) freqobj->fft.size) 3524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project SERVICE_ERROR (MAX_FILTER_POINTS_EXCEEDED); 3534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project freqobj->spectrum_filter[freqobj->spectrum_filter_num++]= jj; 3544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project jj++; 3554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 3564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */ 3574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 3584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project sort_ints_unique(freqobj->spectrum_filter, &freqobj->spectrum_filter_num); 3594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return (freqobj->spectrum_filter_num); 3604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 3614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid clear_spectrum_filter(front_freq *freqobj) 3634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 3644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT(freqobj->spectrum_filter); 3654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (freqobj->spectrum_filter) 3664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project FREE((char *) freqobj->spectrum_filter); 3674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project freqobj->spectrum_filter = NULL; 3684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project freqobj->spectrum_filter_num = 0; 3694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return; 3704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 3714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic int sort_ints_unique(int *list, int *num) 3734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 3744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* Sort a list of ints and make unique */ 3754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int ii, jj, temp; 3764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (ii = 1; ii < *num; ii++) 3774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 3784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (jj = 0; jj < ii; jj++) 3794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 3804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project temp = list[ii]; 3814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (temp < list[jj]) 3824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 3834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project MEMMOVE(&list[jj+1], &list[jj], (ii - jj), sizeof(int)); 3844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project list[jj] = temp; 3854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project break; 3864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 3874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (temp == list[jj]) 3884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 3894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project MEMMOVE(&list[ii], &list[ii+1], (*num - ii), sizeof(int)); 3904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 3934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project (*num)--; 3944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 3954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 3964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 3974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return *num; 3984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 3994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//static void mask_fft_taps(fftdata *data, int num, front_freq *freqobj) 4014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//{ 4024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// for (int i = 0; i < freqobj->spectrum_filter_num; ++i) 4034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// { 4044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// ASSERT(freqobj->spectrum_filter[i] < num); 4054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// data[freqobj->spectrum_filter[i]] = 0; 4064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// } 4074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project//} 4084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/* -------------------------------------------------- 4104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project freq_warp will do pure linear warping if the warp 4114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project scale > 1.0. Otherwise it will do piecewise warp 4124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project which means warping the second part, from xstart 4134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project to the bandwidth with another scale which is 4144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project determined by b and c in the formulation. 4154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project In general, 0.7 < wscale < 1.4, and xstart <= 1 4164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 08/15/01, Puming Zhan 4174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project --------------------------------------------------- */ 4184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectvoid freq_warp(front_freq *freqobj, fftdata *inbuf, int ns) 4194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{ 4204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int i; 4214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int nsE; 4224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project float x1, y1, b, c, wscale; 4234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project fftdata *tmpbuf; 4244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT(freqobj && inbuf); 4264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ASSERT(freqobj->warp_scale != 0); 4284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project wscale = freqobj->warp_scale; 4304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project x1 = freqobj->piecewise_start; 4314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project tmpbuf = (fftdata *) CALLOC(ns, sizeof(fftdata), "cfront.tmpbuf"); 4324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (wscale < MIN_WARP_SCALE || wscale > MAX_WARP_SCALE) 4344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 4354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project SERVICE_ERROR(WARP_SCALE); 4364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 4374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (x1 > 1.0 || x1 < 0.5) 4384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 4394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project SERVICE_ERROR(PIECEWISE_START); 4404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 4414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project y1 = x1 < wscale ? (float)x1 / wscale : (float)1.0; 4434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project b = y1 < 1.0 ? (float)((1.0 - x1) / (1.0 - y1)) : (float)0.0; 4454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project c = (float)((1.0 - b) * (ns - 1)); 4474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project nsE = (int)(y1 * (ns - 1)); 4494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (i = 0; i < ns; i++) 4514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 4524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project float x = i > nsE ? b * i + c : wscale * i; 4534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int u = (int)ceil((double)x); 4544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project int l = (int)floor((double)x); 4554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project float w1 = x - l; 4564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project float w2 = 1 - w1; 4574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (u < ns) 4594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 4604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project tmpbuf[i] = (int)(w1 * inbuf[u] + w2 * inbuf[l]); 4614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 4624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project else 4634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project { 4644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project tmpbuf[i] = inbuf[ns-1]; 4654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 4664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 4674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* need to copy the warped fft into inbuf */ 4694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* because the following function filtbank() */ 4704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* will take inbuf as input */ 4714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* considering that this function will be */ 4724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* for every frame, it may not be a good idea*/ 4734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project /* to do malloc here */ 4744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (i = 0; i < ns; i++) 4764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project inbuf[i] = tmpbuf[i]; 4774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 4784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project FREE((char *) tmpbuf); 4794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 480