Newer
Older
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079
7080
7081
7082
7083
7084
7085
7086
7087
7088
7089
7090
7091
7092
7093
7094
7095
7096
7097
7098
7099
7100
7101
7102
7103
7104
7105
7106
7107
7108
7109
7110
7111
7112
7113
7114
7115
7116
7117
7118
7119
7120
7121
7122
7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
7141
7142
7143
7144
7145
7146
7147
7148
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158
7159
7160
7161
7162
7163
7164
7165
7166
7167
7168
7169
7170
7171
7172
7173
7174
7175
7176
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200
7201
7202
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
7218
7219
7220
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232
7233
7234
7235
7236
7237
7238
7239
7240
7241
7242
7243
7244
7245
7246
7247
7248
7249
7250
7251
7252
7253
7254
7255
7256
7257
7258
7259
7260
7261
7262
7263
7264
7265
7266
7267
7268
7269
7270
7271
7272
7273
7274
7275
7276
7277
7278
7279
7280
7281
7282
7283
7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
7320
7321
7322
7323
7324
7325
7326
7327
7328
7329
7330
7331
7332
7333
7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
7349
7350
7351
7352
7353
7354
7355
7356
7357
7358
7359
7360
7361
7362
7363
7364
7365
7366
7367
7368
7369
7370
7371
7372
7373
7374
7375
7376
7377
7378
7379
7380
7381
7382
7383
7384
7385
7386
7387
7388
7389
7390
7391
7392
7393
7394
7395
7396
7397
7398
7399
7400
7401
7402
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416
7417
7418
7419
7420
7421
7422
7423
7424
7425
7426
7427
7428
7429
7430
7431
7432
7433
7434
7435
7436
7437
7438
7439
7440
7441
7442
7443
7444
7445
7446
7447
7448
7449
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
7469
7470
7471
7472
7473
7474
7475
7476
7477
7478
7479
7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504
7505
7506
7507
7508
7509
7510
7511
7512
7513
7514
7515
7516
7517
7518
7519
7520
7521
7522
7523
7524
7525
7526
7527
7528
7529
7530
7531
7532
7533
7534
7535
7536
7537
7538
7539
7540
7541
7542
7543
7544
7545
7546
7547
7548
7549
7550
7551
7552
7553
7554
7555
7556
7557
7558
7559
* @param[in] blockSize length of the input vector
* @param[out] *pResult maximum value returned here
* @param[out] *pIndex index of maximum value returned here
* @return none.
*/
void arm_max_q15(
q15_t * pSrc,
uint32_t blockSize,
q15_t * pResult,
uint32_t * pIndex);
/**
* @brief Maximum value of a Q31 vector.
* @param[in] *pSrc points to the input buffer
* @param[in] blockSize length of the input vector
* @param[out] *pResult maximum value returned here
* @param[out] *pIndex index of maximum value returned here
* @return none.
*/
void arm_max_q31(
q31_t * pSrc,
uint32_t blockSize,
q31_t * pResult,
uint32_t * pIndex);
/**
* @brief Maximum value of a floating-point vector.
* @param[in] *pSrc points to the input buffer
* @param[in] blockSize length of the input vector
* @param[out] *pResult maximum value returned here
* @param[out] *pIndex index of maximum value returned here
* @return none.
*/
void arm_max_f32(
float32_t * pSrc,
uint32_t blockSize,
float32_t * pResult,
uint32_t * pIndex);
/**
* @brief Q15 complex-by-complex multiplication
* @param[in] *pSrcA points to the first input vector
* @param[in] *pSrcB points to the second input vector
* @param[out] *pDst points to the output vector
* @param[in] numSamples number of complex samples in each vector
* @return none.
*/
void arm_cmplx_mult_cmplx_q15(
q15_t * pSrcA,
q15_t * pSrcB,
q15_t * pDst,
uint32_t numSamples);
/**
* @brief Q31 complex-by-complex multiplication
* @param[in] *pSrcA points to the first input vector
* @param[in] *pSrcB points to the second input vector
* @param[out] *pDst points to the output vector
* @param[in] numSamples number of complex samples in each vector
* @return none.
*/
void arm_cmplx_mult_cmplx_q31(
q31_t * pSrcA,
q31_t * pSrcB,
q31_t * pDst,
uint32_t numSamples);
/**
* @brief Floating-point complex-by-complex multiplication
* @param[in] *pSrcA points to the first input vector
* @param[in] *pSrcB points to the second input vector
* @param[out] *pDst points to the output vector
* @param[in] numSamples number of complex samples in each vector
* @return none.
*/
void arm_cmplx_mult_cmplx_f32(
float32_t * pSrcA,
float32_t * pSrcB,
float32_t * pDst,
uint32_t numSamples);
/**
* @brief Converts the elements of the floating-point vector to Q31 vector.
* @param[in] *pSrc points to the floating-point input vector
* @param[out] *pDst points to the Q31 output vector
* @param[in] blockSize length of the input vector
* @return none.
*/
void arm_float_to_q31(
float32_t * pSrc,
q31_t * pDst,
uint32_t blockSize);
/**
* @brief Converts the elements of the floating-point vector to Q15 vector.
* @param[in] *pSrc points to the floating-point input vector
* @param[out] *pDst points to the Q15 output vector
* @param[in] blockSize length of the input vector
* @return none
*/
void arm_float_to_q15(
float32_t * pSrc,
q15_t * pDst,
uint32_t blockSize);
/**
* @brief Converts the elements of the floating-point vector to Q7 vector.
* @param[in] *pSrc points to the floating-point input vector
* @param[out] *pDst points to the Q7 output vector
* @param[in] blockSize length of the input vector
* @return none
*/
void arm_float_to_q7(
float32_t * pSrc,
q7_t * pDst,
uint32_t blockSize);
/**
* @brief Converts the elements of the Q31 vector to Q15 vector.
* @param[in] *pSrc is input pointer
* @param[out] *pDst is output pointer
* @param[in] blockSize is the number of samples to process
* @return none.
*/
void arm_q31_to_q15(
q31_t * pSrc,
q15_t * pDst,
uint32_t blockSize);
/**
* @brief Converts the elements of the Q31 vector to Q7 vector.
* @param[in] *pSrc is input pointer
* @param[out] *pDst is output pointer
* @param[in] blockSize is the number of samples to process
* @return none.
*/
void arm_q31_to_q7(
q31_t * pSrc,
q7_t * pDst,
uint32_t blockSize);
/**
* @brief Converts the elements of the Q15 vector to floating-point vector.
* @param[in] *pSrc is input pointer
* @param[out] *pDst is output pointer
* @param[in] blockSize is the number of samples to process
* @return none.
*/
void arm_q15_to_float(
q15_t * pSrc,
float32_t * pDst,
uint32_t blockSize);
/**
* @brief Converts the elements of the Q15 vector to Q31 vector.
* @param[in] *pSrc is input pointer
* @param[out] *pDst is output pointer
* @param[in] blockSize is the number of samples to process
* @return none.
*/
void arm_q15_to_q31(
q15_t * pSrc,
q31_t * pDst,
uint32_t blockSize);
/**
* @brief Converts the elements of the Q15 vector to Q7 vector.
* @param[in] *pSrc is input pointer
* @param[out] *pDst is output pointer
* @param[in] blockSize is the number of samples to process
* @return none.
*/
void arm_q15_to_q7(
q15_t * pSrc,
q7_t * pDst,
uint32_t blockSize);
/**
* @ingroup groupInterpolation
*/
/**
* @defgroup BilinearInterpolate Bilinear Interpolation
*
* Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid.
* The underlying function <code>f(x, y)</code> is sampled on a regular grid and the interpolation process
* determines values between the grid points.
* Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension.
* Bilinear interpolation is often used in image processing to rescale images.
* The CMSIS DSP library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types.
*
* <b>Algorithm</b>
* \par
* The instance structure used by the bilinear interpolation functions describes a two dimensional data table.
* For floating-point, the instance structure is defined as:
* <pre>
* typedef struct
* {
* uint16_t numRows;
* uint16_t numCols;
* float32_t *pData;
* } arm_bilinear_interp_instance_f32;
* </pre>
*
* \par
* where <code>numRows</code> specifies the number of rows in the table;
* <code>numCols</code> specifies the number of columns in the table;
* and <code>pData</code> points to an array of size <code>numRows*numCols</code> values.
* The data table <code>pTable</code> is organized in row order and the supplied data values fall on integer indexes.
* That is, table element (x,y) is located at <code>pTable[x + y*numCols]</code> where x and y are integers.
*
* \par
* Let <code>(x, y)</code> specify the desired interpolation point. Then define:
* <pre>
* XF = floor(x)
* YF = floor(y)
* </pre>
* \par
* The interpolated output point is computed as:
* <pre>
* f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
* + f(XF+1, YF) * (x-XF)*(1-(y-YF))
* + f(XF, YF+1) * (1-(x-XF))*(y-YF)
* + f(XF+1, YF+1) * (x-XF)*(y-YF)
* </pre>
* Note that the coordinates (x, y) contain integer and fractional components.
* The integer components specify which portion of the table to use while the
* fractional components control the interpolation processor.
*
* \par
* if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output.
*/
/**
* @addtogroup BilinearInterpolate
* @{
*/
/**
*
* @brief Floating-point bilinear interpolation.
* @param[in,out] *S points to an instance of the interpolation structure.
* @param[in] X interpolation coordinate.
* @param[in] Y interpolation coordinate.
* @return out interpolated value.
*/
__STATIC_INLINE float32_t arm_bilinear_interp_f32(
const arm_bilinear_interp_instance_f32 * S,
float32_t X,
float32_t Y)
{
float32_t out;
float32_t f00, f01, f10, f11;
float32_t *pData = S->pData;
int32_t xIndex, yIndex, index;
float32_t xdiff, ydiff;
float32_t b1, b2, b3, b4;
xIndex = (int32_t) X;
yIndex = (int32_t) Y;
/* Care taken for table outside boundary */
/* Returns zero output when values are outside table boundary */
if(xIndex < 0 || xIndex > (S->numRows - 1) || yIndex < 0
|| yIndex > (S->numCols - 1))
{
return (0);
}
/* Calculation of index for two nearest points in X-direction */
index = (xIndex - 1) + (yIndex - 1) * S->numCols;
/* Read two nearest points in X-direction */
f00 = pData[index];
f01 = pData[index + 1];
/* Calculation of index for two nearest points in Y-direction */
index = (xIndex - 1) + (yIndex) * S->numCols;
/* Read two nearest points in Y-direction */
f10 = pData[index];
f11 = pData[index + 1];
/* Calculation of intermediate values */
b1 = f00;
b2 = f01 - f00;
b3 = f10 - f00;
b4 = f00 - f01 - f10 + f11;
/* Calculation of fractional part in X */
xdiff = X - xIndex;
/* Calculation of fractional part in Y */
ydiff = Y - yIndex;
/* Calculation of bi-linear interpolated output */
out = b1 + b2 * xdiff + b3 * ydiff + b4 * xdiff * ydiff;
/* return to application */
return (out);
}
/**
*
* @brief Q31 bilinear interpolation.
* @param[in,out] *S points to an instance of the interpolation structure.
* @param[in] X interpolation coordinate in 12.20 format.
* @param[in] Y interpolation coordinate in 12.20 format.
* @return out interpolated value.
*/
__STATIC_INLINE q31_t arm_bilinear_interp_q31(
arm_bilinear_interp_instance_q31 * S,
q31_t X,
q31_t Y)
{
q31_t out; /* Temporary output */
q31_t acc = 0; /* output */
q31_t xfract, yfract; /* X, Y fractional parts */
q31_t x1, x2, y1, y2; /* Nearest output values */
int32_t rI, cI; /* Row and column indices */
q31_t *pYData = S->pData; /* pointer to output table values */
uint32_t nCols = S->numCols; /* num of rows */
/* Input is in 12.20 format */
/* 12 bits for the table index */
/* Index value calculation */
rI = ((X & 0xFFF00000) >> 20u);
/* Input is in 12.20 format */
/* 12 bits for the table index */
/* Index value calculation */
cI = ((Y & 0xFFF00000) >> 20u);
/* Care taken for table outside boundary */
/* Returns zero output when values are outside table boundary */
if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1))
{
return (0);
}
/* 20 bits for the fractional part */
/* shift left xfract by 11 to keep 1.31 format */
xfract = (X & 0x000FFFFF) << 11u;
/* Read two nearest output values from the index */
x1 = pYData[(rI) + nCols * (cI)];
x2 = pYData[(rI) + nCols * (cI) + 1u];
/* 20 bits for the fractional part */
/* shift left yfract by 11 to keep 1.31 format */
yfract = (Y & 0x000FFFFF) << 11u;
/* Read two nearest output values from the index */
y1 = pYData[(rI) + nCols * (cI + 1)];
y2 = pYData[(rI) + nCols * (cI + 1) + 1u];
/* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */
out = ((q31_t) (((q63_t) x1 * (0x7FFFFFFF - xfract)) >> 32));
acc = ((q31_t) (((q63_t) out * (0x7FFFFFFF - yfract)) >> 32));
/* x2 * (xfract) * (1-yfract) in 3.29(q29) and adding to acc */
out = ((q31_t) ((q63_t) x2 * (0x7FFFFFFF - yfract) >> 32));
acc += ((q31_t) ((q63_t) out * (xfract) >> 32));
/* y1 * (1 - xfract) * (yfract) in 3.29(q29) and adding to acc */
out = ((q31_t) ((q63_t) y1 * (0x7FFFFFFF - xfract) >> 32));
acc += ((q31_t) ((q63_t) out * (yfract) >> 32));
/* y2 * (xfract) * (yfract) in 3.29(q29) and adding to acc */
out = ((q31_t) ((q63_t) y2 * (xfract) >> 32));
acc += ((q31_t) ((q63_t) out * (yfract) >> 32));
/* Convert acc to 1.31(q31) format */
return (acc << 2u);
}
/**
* @brief Q15 bilinear interpolation.
* @param[in,out] *S points to an instance of the interpolation structure.
* @param[in] X interpolation coordinate in 12.20 format.
* @param[in] Y interpolation coordinate in 12.20 format.
* @return out interpolated value.
*/
__STATIC_INLINE q15_t arm_bilinear_interp_q15(
arm_bilinear_interp_instance_q15 * S,
q31_t X,
q31_t Y)
{
q63_t acc = 0; /* output */
q31_t out; /* Temporary output */
q15_t x1, x2, y1, y2; /* Nearest output values */
q31_t xfract, yfract; /* X, Y fractional parts */
int32_t rI, cI; /* Row and column indices */
q15_t *pYData = S->pData; /* pointer to output table values */
uint32_t nCols = S->numCols; /* num of rows */
/* Input is in 12.20 format */
/* 12 bits for the table index */
/* Index value calculation */
rI = ((X & 0xFFF00000) >> 20);
/* Input is in 12.20 format */
/* 12 bits for the table index */
/* Index value calculation */
cI = ((Y & 0xFFF00000) >> 20);
/* Care taken for table outside boundary */
/* Returns zero output when values are outside table boundary */
if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1))
{
return (0);
}
/* 20 bits for the fractional part */
/* xfract should be in 12.20 format */
xfract = (X & 0x000FFFFF);
/* Read two nearest output values from the index */
x1 = pYData[(rI) + nCols * (cI)];
x2 = pYData[(rI) + nCols * (cI) + 1u];
/* 20 bits for the fractional part */
/* yfract should be in 12.20 format */
yfract = (Y & 0x000FFFFF);
/* Read two nearest output values from the index */
y1 = pYData[(rI) + nCols * (cI + 1)];
y2 = pYData[(rI) + nCols * (cI + 1) + 1u];
/* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 13.51 format */
/* x1 is in 1.15(q15), xfract in 12.20 format and out is in 13.35 format */
/* convert 13.35 to 13.31 by right shifting and out is in 1.31 */
out = (q31_t) (((q63_t) x1 * (0xFFFFF - xfract)) >> 4u);
acc = ((q63_t) out * (0xFFFFF - yfract));
/* x2 * (xfract) * (1-yfract) in 1.51 and adding to acc */
out = (q31_t) (((q63_t) x2 * (0xFFFFF - yfract)) >> 4u);
acc += ((q63_t) out * (xfract));
/* y1 * (1 - xfract) * (yfract) in 1.51 and adding to acc */
out = (q31_t) (((q63_t) y1 * (0xFFFFF - xfract)) >> 4u);
acc += ((q63_t) out * (yfract));
/* y2 * (xfract) * (yfract) in 1.51 and adding to acc */
out = (q31_t) (((q63_t) y2 * (xfract)) >> 4u);
acc += ((q63_t) out * (yfract));
/* acc is in 13.51 format and down shift acc by 36 times */
/* Convert out to 1.15 format */
return (acc >> 36);
}
/**
* @brief Q7 bilinear interpolation.
* @param[in,out] *S points to an instance of the interpolation structure.
* @param[in] X interpolation coordinate in 12.20 format.
* @param[in] Y interpolation coordinate in 12.20 format.
* @return out interpolated value.
*/
__STATIC_INLINE q7_t arm_bilinear_interp_q7(
arm_bilinear_interp_instance_q7 * S,
q31_t X,
q31_t Y)
{
q63_t acc = 0; /* output */
q31_t out; /* Temporary output */
q31_t xfract, yfract; /* X, Y fractional parts */
q7_t x1, x2, y1, y2; /* Nearest output values */
int32_t rI, cI; /* Row and column indices */
q7_t *pYData = S->pData; /* pointer to output table values */
uint32_t nCols = S->numCols; /* num of rows */
/* Input is in 12.20 format */
/* 12 bits for the table index */
/* Index value calculation */
rI = ((X & 0xFFF00000) >> 20);
/* Input is in 12.20 format */
/* 12 bits for the table index */
/* Index value calculation */
cI = ((Y & 0xFFF00000) >> 20);
/* Care taken for table outside boundary */
/* Returns zero output when values are outside table boundary */
if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1))
{
return (0);
}
/* 20 bits for the fractional part */
/* xfract should be in 12.20 format */
xfract = (X & 0x000FFFFF);
/* Read two nearest output values from the index */
x1 = pYData[(rI) + nCols * (cI)];
x2 = pYData[(rI) + nCols * (cI) + 1u];
/* 20 bits for the fractional part */
/* yfract should be in 12.20 format */
yfract = (Y & 0x000FFFFF);
/* Read two nearest output values from the index */
y1 = pYData[(rI) + nCols * (cI + 1)];
y2 = pYData[(rI) + nCols * (cI + 1) + 1u];
/* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 16.47 format */
out = ((x1 * (0xFFFFF - xfract)));
acc = (((q63_t) out * (0xFFFFF - yfract)));
/* x2 * (xfract) * (1-yfract) in 2.22 and adding to acc */
out = ((x2 * (0xFFFFF - yfract)));
acc += (((q63_t) out * (xfract)));
/* y1 * (1 - xfract) * (yfract) in 2.22 and adding to acc */
out = ((y1 * (0xFFFFF - xfract)));
acc += (((q63_t) out * (yfract)));
/* y2 * (xfract) * (yfract) in 2.22 and adding to acc */
out = ((y2 * (yfract)));
acc += (((q63_t) out * (xfract)));
/* acc in 16.47 format and down shift by 40 to convert to 1.7 format */
return (acc >> 40);
}
/**
* @} end of BilinearInterpolate group
*/