00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 #include <stdio.h>
00059 #include <stdlib.h>
00060 #include <math.h>
00061 #include <string.h>
00062
00063 #ifdef _MSC_VER
00064 #pragma warning (disable: 4996)
00065 #endif
00066
00067 #include "strfuncs.h"
00068 #include "err.h"
00069 #include "fe_warp.h"
00070 #include "fe_warp_piecewise_linear.h"
00071
00072 #define N_PARAM 2
00073 #define YES 1
00074 #define NO 0
00075
00076
00077
00078
00079
00080 static float params[N_PARAM] = { 1.0f, 6800.0f };
00081 static float final_piece[2];
00082 static int32 is_neutral = YES;
00083 static char p_str[256] = "";
00084 static float nyquist_frequency = 0.0f;
00085
00086
00087 const char *
00088 fe_warp_piecewise_linear_doc()
00089 {
00090 return "piecewise_linear :== < w' = a * w, w < F >";
00091 }
00092
00093 uint32
00094 fe_warp_piecewise_linear_id()
00095 {
00096 return FE_WARP_ID_PIECEWISE_LINEAR;
00097 }
00098
00099 uint32
00100 fe_warp_piecewise_linear_n_param()
00101 {
00102 return N_PARAM;
00103 }
00104
00105 void
00106 fe_warp_piecewise_linear_set_parameters(char const *param_str,
00107 float sampling_rate)
00108 {
00109 char *tok;
00110 char *seps = " \t";
00111 char temp_param_str[256];
00112 int param_index = 0;
00113
00114 nyquist_frequency = sampling_rate / 2;
00115 if (param_str == NULL) {
00116 is_neutral = YES;
00117 return;
00118 }
00119
00120 if (strcmp(param_str, p_str) == 0) {
00121 return;
00122 }
00123 is_neutral = NO;
00124 strcpy(temp_param_str, param_str);
00125 memset(params, 0, N_PARAM * sizeof(float));
00126 memset(final_piece, 0, 2 * sizeof(float));
00127 strcpy(p_str, param_str);
00128
00129 tok = strtok(temp_param_str, seps);
00130 while (tok != NULL) {
00131 params[param_index++] = (float) atof_c(tok);
00132 tok = strtok(NULL, seps);
00133 if (param_index >= N_PARAM) {
00134 break;
00135 }
00136 }
00137 if (tok != NULL) {
00138 E_INFO
00139 ("Piecewise linear warping takes up to two arguments, %s ignored.\n",
00140 tok);
00141 }
00142 if (params[1] < sampling_rate) {
00143
00144
00145
00146
00147
00148 if (params[1] == 0) {
00149 params[1] = sampling_rate * 0.85f;
00150 }
00151 final_piece[0] =
00152 (sampling_rate -
00153 params[0] * params[1]) / (sampling_rate - params[1]);
00154 final_piece[1] =
00155 sampling_rate * params[1] * (params[0] -
00156 1.0f) / (sampling_rate -
00157 params[1]);
00158 }
00159 else {
00160 memset(final_piece, 0, 2 * sizeof(float));
00161 }
00162 if (params[0] == 0) {
00163 is_neutral = YES;
00164 E_INFO
00165 ("Piecewise linear warping cannot have slope zero, warping not applied.\n");
00166 }
00167 }
00168
00169 float
00170 fe_warp_piecewise_linear_warped_to_unwarped(float nonlinear)
00171 {
00172 if (is_neutral) {
00173 return nonlinear;
00174 }
00175 else {
00176
00177 float temp;
00178 if (nonlinear < params[0] * params[1]) {
00179 temp = nonlinear / params[0];
00180 }
00181 else {
00182 temp = nonlinear - final_piece[1];
00183 temp /= final_piece[0];
00184 }
00185 if (temp > nyquist_frequency) {
00186 E_WARN
00187 ("Warp factor %g results in frequency (%.1f) higher than Nyquist (%.1f)\n",
00188 params[0], temp, nyquist_frequency);
00189 }
00190 return temp;
00191 }
00192 }
00193
00194 float
00195 fe_warp_piecewise_linear_unwarped_to_warped(float linear)
00196 {
00197 if (is_neutral) {
00198 return linear;
00199 }
00200 else {
00201 float temp;
00202
00203 if (linear < params[1]) {
00204 temp = linear * params[0];
00205 }
00206 else {
00207 temp = final_piece[0] * linear + final_piece[1];
00208 }
00209 return temp;
00210 }
00211 }
00212
00213 void
00214 fe_warp_piecewise_linear_print(const char *label)
00215 {
00216 uint32 i;
00217
00218 for (i = 0; i < N_PARAM; i++) {
00219 printf("%s[%04u]: %6.3f ", label, i, params[i]);
00220 }
00221 printf("\n");
00222 }
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255