mbed 5 experimental branch

Fork of dsp by Simon Ford

Committer:
nprobably
Date:
Thu Jun 29 06:56:55 2017 +0000
Revision:
3:ad02f4ea1fbe
Parent:
0:1014af42efd9
A hack to make it compile with mbed 5

Who changed what in which revision?

UserRevisionLine numberNew contents of line
simon 0:1014af42efd9 1 /* ----------------------------------------------------------------------
simon 0:1014af42efd9 2 * Copyright (C) 2010 ARM Limited. All rights reserved.
simon 0:1014af42efd9 3 *
simon 0:1014af42efd9 4 * $Date: 29. November 2010
simon 0:1014af42efd9 5 * $Revision: V1.0.3
simon 0:1014af42efd9 6 *
simon 0:1014af42efd9 7 * Project: CMSIS DSP Library
simon 0:1014af42efd9 8 *
simon 0:1014af42efd9 9 * Title: math_helper.c
simon 0:1014af42efd9 10 *
simon 0:1014af42efd9 11 * Description: Definition of all helper functions required.
simon 0:1014af42efd9 12 *
simon 0:1014af42efd9 13 * Target Processor: Cortex-M4/Cortex-M3
simon 0:1014af42efd9 14 *
simon 0:1014af42efd9 15 * Version 1.0.3 2010/11/29
simon 0:1014af42efd9 16 * Re-organized the CMSIS folders and updated documentation.
simon 0:1014af42efd9 17 *
simon 0:1014af42efd9 18 * Version 1.0.2 2010/11/11
simon 0:1014af42efd9 19 * Documentation updated.
simon 0:1014af42efd9 20 *
simon 0:1014af42efd9 21 * Version 1.0.1 2010/10/05
simon 0:1014af42efd9 22 * Production release and review comments incorporated.
simon 0:1014af42efd9 23 *
simon 0:1014af42efd9 24 * Version 1.0.0 2010/09/20
simon 0:1014af42efd9 25 * Production release and review comments incorporated.
simon 0:1014af42efd9 26 *
simon 0:1014af42efd9 27 * Version 0.0.7 2010/06/10
simon 0:1014af42efd9 28 * Misra-C changes done
simon 0:1014af42efd9 29 * -------------------------------------------------------------------- */
simon 0:1014af42efd9 30
simon 0:1014af42efd9 31 /* ----------------------------------------------------------------------
simon 0:1014af42efd9 32 * Include standard header files
simon 0:1014af42efd9 33 * -------------------------------------------------------------------- */
simon 0:1014af42efd9 34 #include<math.h>
simon 0:1014af42efd9 35
simon 0:1014af42efd9 36 /* ----------------------------------------------------------------------
simon 0:1014af42efd9 37 * Include project header files
simon 0:1014af42efd9 38 * -------------------------------------------------------------------- */
simon 0:1014af42efd9 39 #include "math_helper.h"
simon 0:1014af42efd9 40
simon 0:1014af42efd9 41 /**
simon 0:1014af42efd9 42 * @brief Caluclation of SNR
simon 0:1014af42efd9 43 * @param float* Pointer to the reference buffer
simon 0:1014af42efd9 44 * @param float* Pointer to the test buffer
simon 0:1014af42efd9 45 * @param uint32_t total number of samples
simon 0:1014af42efd9 46 * @return float SNR
simon 0:1014af42efd9 47 * The function Caluclates signal to noise ratio for the reference output
simon 0:1014af42efd9 48 * and test output
simon 0:1014af42efd9 49 */
simon 0:1014af42efd9 50
simon 0:1014af42efd9 51 float arm_snr_f32(float *pRef, float *pTest, uint32_t buffSize)
simon 0:1014af42efd9 52 {
simon 0:1014af42efd9 53 float EnergySignal = 0.0, EnergyError = 0.0;
simon 0:1014af42efd9 54 uint32_t i;
simon 0:1014af42efd9 55 float SNR;
simon 0:1014af42efd9 56
simon 0:1014af42efd9 57 for (i = 0; i < buffSize; i++)
simon 0:1014af42efd9 58 {
simon 0:1014af42efd9 59 EnergySignal += pRef[i] * pRef[i];
simon 0:1014af42efd9 60 EnergyError += (pRef[i] - pTest[i]) * (pRef[i] - pTest[i]);
simon 0:1014af42efd9 61 }
simon 0:1014af42efd9 62
simon 0:1014af42efd9 63
simon 0:1014af42efd9 64 SNR = 10 * log10 (EnergySignal / EnergyError);
simon 0:1014af42efd9 65
simon 0:1014af42efd9 66 return (SNR);
simon 0:1014af42efd9 67
simon 0:1014af42efd9 68 }
simon 0:1014af42efd9 69
simon 0:1014af42efd9 70
simon 0:1014af42efd9 71 /**
simon 0:1014af42efd9 72 * @brief Provide guard bits for Input buffer
simon 0:1014af42efd9 73 * @param q15_t* Pointer to input buffer
simon 0:1014af42efd9 74 * @param uint32_t blockSize
simon 0:1014af42efd9 75 * @param uint32_t guard_bits
simon 0:1014af42efd9 76 * @return none
simon 0:1014af42efd9 77 * The function Provides the guard bits for the buffer
simon 0:1014af42efd9 78 * to avoid overflow
simon 0:1014af42efd9 79 */
simon 0:1014af42efd9 80
simon 0:1014af42efd9 81 void arm_provide_guard_bits_q15 (q15_t * input_buf, uint32_t blockSize,
simon 0:1014af42efd9 82 uint32_t guard_bits)
simon 0:1014af42efd9 83 {
simon 0:1014af42efd9 84 uint32_t i;
simon 0:1014af42efd9 85
simon 0:1014af42efd9 86 for (i = 0; i < blockSize; i++)
simon 0:1014af42efd9 87 {
simon 0:1014af42efd9 88 input_buf[i] = input_buf[i] >> guard_bits;
simon 0:1014af42efd9 89 }
simon 0:1014af42efd9 90 }
simon 0:1014af42efd9 91
simon 0:1014af42efd9 92 /**
simon 0:1014af42efd9 93 * @brief Converts float to fixed in q12.20 format
simon 0:1014af42efd9 94 * @param uint32_t number of samples in the buffer
simon 0:1014af42efd9 95 * @return none
simon 0:1014af42efd9 96 * The function converts floating point values to fixed point(q12.20) values
simon 0:1014af42efd9 97 */
simon 0:1014af42efd9 98
simon 0:1014af42efd9 99 void arm_float_to_q12_20(float *pIn, q31_t * pOut, uint32_t numSamples)
simon 0:1014af42efd9 100 {
simon 0:1014af42efd9 101 uint32_t i;
simon 0:1014af42efd9 102
simon 0:1014af42efd9 103 for (i = 0; i < numSamples; i++)
simon 0:1014af42efd9 104 {
simon 0:1014af42efd9 105 /* 1048576.0f corresponds to pow(2, 20) */
simon 0:1014af42efd9 106 pOut[i] = (q31_t) (pIn[i] * 1048576.0f);
simon 0:1014af42efd9 107
simon 0:1014af42efd9 108 pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
simon 0:1014af42efd9 109
simon 0:1014af42efd9 110 if (pIn[i] == (float) 1.0)
simon 0:1014af42efd9 111 {
simon 0:1014af42efd9 112 pOut[i] = 0x000FFFFF;
simon 0:1014af42efd9 113 }
simon 0:1014af42efd9 114 }
simon 0:1014af42efd9 115 }
simon 0:1014af42efd9 116
simon 0:1014af42efd9 117 /**
simon 0:1014af42efd9 118 * @brief Compare MATLAB Reference Output and ARM Test output
simon 0:1014af42efd9 119 * @param q15_t* Pointer to Ref buffer
simon 0:1014af42efd9 120 * @param q15_t* Pointer to Test buffer
simon 0:1014af42efd9 121 * @param uint32_t number of samples in the buffer
simon 0:1014af42efd9 122 * @return none
simon 0:1014af42efd9 123 */
simon 0:1014af42efd9 124
simon 0:1014af42efd9 125 uint32_t arm_compare_fixed_q15(q15_t *pIn, q15_t * pOut, uint32_t numSamples)
simon 0:1014af42efd9 126 {
simon 0:1014af42efd9 127 uint32_t i;
simon 0:1014af42efd9 128 int32_t diff, diffCrnt = 0;
simon 0:1014af42efd9 129 uint32_t maxDiff = 0;
simon 0:1014af42efd9 130
simon 0:1014af42efd9 131 for (i = 0; i < numSamples; i++)
simon 0:1014af42efd9 132 {
simon 0:1014af42efd9 133 diff = pIn[i] - pOut[i];
simon 0:1014af42efd9 134 diffCrnt = (diff > 0) ? diff : -diff;
simon 0:1014af42efd9 135
simon 0:1014af42efd9 136 if(diffCrnt > maxDiff)
simon 0:1014af42efd9 137 {
simon 0:1014af42efd9 138 maxDiff = diffCrnt;
simon 0:1014af42efd9 139 }
simon 0:1014af42efd9 140 }
simon 0:1014af42efd9 141
simon 0:1014af42efd9 142 return(maxDiff);
simon 0:1014af42efd9 143 }
simon 0:1014af42efd9 144
simon 0:1014af42efd9 145 /**
simon 0:1014af42efd9 146 * @brief Compare MATLAB Reference Output and ARM Test output
simon 0:1014af42efd9 147 * @param q31_t* Pointer to Ref buffer
simon 0:1014af42efd9 148 * @param q31_t* Pointer to Test buffer
simon 0:1014af42efd9 149 * @param uint32_t number of samples in the buffer
simon 0:1014af42efd9 150 * @return none
simon 0:1014af42efd9 151 */
simon 0:1014af42efd9 152
simon 0:1014af42efd9 153 uint32_t arm_compare_fixed_q31(q31_t *pIn, q31_t * pOut, uint32_t numSamples)
simon 0:1014af42efd9 154 {
simon 0:1014af42efd9 155 uint32_t i;
simon 0:1014af42efd9 156 int32_t diff, diffCrnt = 0;
simon 0:1014af42efd9 157 uint32_t maxDiff = 0;
simon 0:1014af42efd9 158
simon 0:1014af42efd9 159 for (i = 0; i < numSamples; i++)
simon 0:1014af42efd9 160 {
simon 0:1014af42efd9 161 diff = pIn[i] - pOut[i];
simon 0:1014af42efd9 162 diffCrnt = (diff > 0) ? diff : -diff;
simon 0:1014af42efd9 163
simon 0:1014af42efd9 164 if(diffCrnt > maxDiff)
simon 0:1014af42efd9 165 {
simon 0:1014af42efd9 166 maxDiff = diffCrnt;
simon 0:1014af42efd9 167 }
simon 0:1014af42efd9 168 }
simon 0:1014af42efd9 169
simon 0:1014af42efd9 170 return(maxDiff);
simon 0:1014af42efd9 171 }
simon 0:1014af42efd9 172
simon 0:1014af42efd9 173 /**
simon 0:1014af42efd9 174 * @brief Provide guard bits for Input buffer
simon 0:1014af42efd9 175 * @param q31_t* Pointer to input buffer
simon 0:1014af42efd9 176 * @param uint32_t blockSize
simon 0:1014af42efd9 177 * @param uint32_t guard_bits
simon 0:1014af42efd9 178 * @return none
simon 0:1014af42efd9 179 * The function Provides the guard bits for the buffer
simon 0:1014af42efd9 180 * to avoid overflow
simon 0:1014af42efd9 181 */
simon 0:1014af42efd9 182
simon 0:1014af42efd9 183 void arm_provide_guard_bits_q31 (q31_t * input_buf,
simon 0:1014af42efd9 184 uint32_t blockSize,
simon 0:1014af42efd9 185 uint32_t guard_bits)
simon 0:1014af42efd9 186 {
simon 0:1014af42efd9 187 uint32_t i;
simon 0:1014af42efd9 188
simon 0:1014af42efd9 189 for (i = 0; i < blockSize; i++)
simon 0:1014af42efd9 190 {
simon 0:1014af42efd9 191 input_buf[i] = input_buf[i] >> guard_bits;
simon 0:1014af42efd9 192 }
simon 0:1014af42efd9 193 }
simon 0:1014af42efd9 194
simon 0:1014af42efd9 195 /**
simon 0:1014af42efd9 196 * @brief Provide guard bits for Input buffer
simon 0:1014af42efd9 197 * @param q31_t* Pointer to input buffer
simon 0:1014af42efd9 198 * @param uint32_t blockSize
simon 0:1014af42efd9 199 * @param uint32_t guard_bits
simon 0:1014af42efd9 200 * @return none
simon 0:1014af42efd9 201 * The function Provides the guard bits for the buffer
simon 0:1014af42efd9 202 * to avoid overflow
simon 0:1014af42efd9 203 */
simon 0:1014af42efd9 204
simon 0:1014af42efd9 205 void arm_provide_guard_bits_q7 (q7_t * input_buf,
simon 0:1014af42efd9 206 uint32_t blockSize,
simon 0:1014af42efd9 207 uint32_t guard_bits)
simon 0:1014af42efd9 208 {
simon 0:1014af42efd9 209 uint32_t i;
simon 0:1014af42efd9 210
simon 0:1014af42efd9 211 for (i = 0; i < blockSize; i++)
simon 0:1014af42efd9 212 {
simon 0:1014af42efd9 213 input_buf[i] = input_buf[i] >> guard_bits;
simon 0:1014af42efd9 214 }
simon 0:1014af42efd9 215 }
simon 0:1014af42efd9 216
simon 0:1014af42efd9 217
simon 0:1014af42efd9 218
simon 0:1014af42efd9 219 /**
simon 0:1014af42efd9 220 * @brief Caluclates number of guard bits
simon 0:1014af42efd9 221 * @param uint32_t number of additions
simon 0:1014af42efd9 222 * @return none
simon 0:1014af42efd9 223 * The function Caluclates the number of guard bits
simon 0:1014af42efd9 224 * depending on the numtaps
simon 0:1014af42efd9 225 */
simon 0:1014af42efd9 226
simon 0:1014af42efd9 227 uint32_t arm_calc_guard_bits (uint32_t num_adds)
simon 0:1014af42efd9 228 {
simon 0:1014af42efd9 229 uint32_t i = 1, j = 0;
simon 0:1014af42efd9 230
simon 0:1014af42efd9 231 if (num_adds == 1)
simon 0:1014af42efd9 232 {
simon 0:1014af42efd9 233 return (0);
simon 0:1014af42efd9 234 }
simon 0:1014af42efd9 235
simon 0:1014af42efd9 236 while (i < num_adds)
simon 0:1014af42efd9 237 {
simon 0:1014af42efd9 238 i = i * 2;
simon 0:1014af42efd9 239 j++;
simon 0:1014af42efd9 240 }
simon 0:1014af42efd9 241
simon 0:1014af42efd9 242 return (j);
simon 0:1014af42efd9 243 }
simon 0:1014af42efd9 244
simon 0:1014af42efd9 245 /**
simon 0:1014af42efd9 246 * @brief Converts Q15 to floating-point
simon 0:1014af42efd9 247 * @param uint32_t number of samples in the buffer
simon 0:1014af42efd9 248 * @return none
simon 0:1014af42efd9 249 */
simon 0:1014af42efd9 250
simon 0:1014af42efd9 251 void arm_apply_guard_bits (float32_t * pIn,
simon 0:1014af42efd9 252 uint32_t numSamples,
simon 0:1014af42efd9 253 uint32_t guard_bits)
simon 0:1014af42efd9 254 {
simon 0:1014af42efd9 255 uint32_t i;
simon 0:1014af42efd9 256
simon 0:1014af42efd9 257 for (i = 0; i < numSamples; i++)
simon 0:1014af42efd9 258 {
simon 0:1014af42efd9 259 pIn[i] = pIn[i] * arm_calc_2pow(guard_bits);
simon 0:1014af42efd9 260 }
simon 0:1014af42efd9 261 }
simon 0:1014af42efd9 262
simon 0:1014af42efd9 263 /**
simon 0:1014af42efd9 264 * @brief Calculates pow(2, numShifts)
simon 0:1014af42efd9 265 * @param uint32_t number of shifts
simon 0:1014af42efd9 266 * @return pow(2, numShifts)
simon 0:1014af42efd9 267 */
simon 0:1014af42efd9 268 uint32_t arm_calc_2pow(uint32_t numShifts)
simon 0:1014af42efd9 269 {
simon 0:1014af42efd9 270
simon 0:1014af42efd9 271 uint32_t i, val = 1;
simon 0:1014af42efd9 272
simon 0:1014af42efd9 273 for (i = 0; i < numShifts; i++)
simon 0:1014af42efd9 274 {
simon 0:1014af42efd9 275 val = val * 2;
simon 0:1014af42efd9 276 }
simon 0:1014af42efd9 277
simon 0:1014af42efd9 278 return(val);
simon 0:1014af42efd9 279 }
simon 0:1014af42efd9 280
simon 0:1014af42efd9 281
simon 0:1014af42efd9 282
simon 0:1014af42efd9 283 /**
simon 0:1014af42efd9 284 * @brief Converts float to fixed q14
simon 0:1014af42efd9 285 * @param uint32_t number of samples in the buffer
simon 0:1014af42efd9 286 * @return none
simon 0:1014af42efd9 287 * The function converts floating point values to fixed point values
simon 0:1014af42efd9 288 */
simon 0:1014af42efd9 289
simon 0:1014af42efd9 290 void arm_float_to_q14 (float *pIn, q15_t * pOut,
simon 0:1014af42efd9 291 uint32_t numSamples)
simon 0:1014af42efd9 292 {
simon 0:1014af42efd9 293 uint32_t i;
simon 0:1014af42efd9 294
simon 0:1014af42efd9 295 for (i = 0; i < numSamples; i++)
simon 0:1014af42efd9 296 {
simon 0:1014af42efd9 297 /* 16384.0f corresponds to pow(2, 14) */
simon 0:1014af42efd9 298 pOut[i] = (q15_t) (pIn[i] * 16384.0f);
simon 0:1014af42efd9 299
simon 0:1014af42efd9 300 pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
simon 0:1014af42efd9 301
simon 0:1014af42efd9 302 if (pIn[i] == (float) 2.0)
simon 0:1014af42efd9 303 {
simon 0:1014af42efd9 304 pOut[i] = 0x7FFF;
simon 0:1014af42efd9 305 }
simon 0:1014af42efd9 306
simon 0:1014af42efd9 307 }
simon 0:1014af42efd9 308
simon 0:1014af42efd9 309 }
simon 0:1014af42efd9 310
simon 0:1014af42efd9 311
simon 0:1014af42efd9 312 /**
simon 0:1014af42efd9 313 * @brief Converts float to fixed q30 format
simon 0:1014af42efd9 314 * @param uint32_t number of samples in the buffer
simon 0:1014af42efd9 315 * @return none
simon 0:1014af42efd9 316 * The function converts floating point values to fixed point values
simon 0:1014af42efd9 317 */
simon 0:1014af42efd9 318
simon 0:1014af42efd9 319 void arm_float_to_q30 (float *pIn, q31_t * pOut,
simon 0:1014af42efd9 320 uint32_t numSamples)
simon 0:1014af42efd9 321 {
simon 0:1014af42efd9 322 uint32_t i;
simon 0:1014af42efd9 323
simon 0:1014af42efd9 324 for (i = 0; i < numSamples; i++)
simon 0:1014af42efd9 325 {
simon 0:1014af42efd9 326 /* 1073741824.0f corresponds to pow(2, 30) */
simon 0:1014af42efd9 327 pOut[i] = (q31_t) (pIn[i] * 1073741824.0f);
simon 0:1014af42efd9 328
simon 0:1014af42efd9 329 pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
simon 0:1014af42efd9 330
simon 0:1014af42efd9 331 if (pIn[i] == (float) 2.0)
simon 0:1014af42efd9 332 {
simon 0:1014af42efd9 333 pOut[i] = 0x7FFFFFFF;
simon 0:1014af42efd9 334 }
simon 0:1014af42efd9 335 }
simon 0:1014af42efd9 336 }
simon 0:1014af42efd9 337
simon 0:1014af42efd9 338 /**
simon 0:1014af42efd9 339 * @brief Converts float to fixed q30 format
simon 0:1014af42efd9 340 * @param uint32_t number of samples in the buffer
simon 0:1014af42efd9 341 * @return none
simon 0:1014af42efd9 342 * The function converts floating point values to fixed point values
simon 0:1014af42efd9 343 */
simon 0:1014af42efd9 344
simon 0:1014af42efd9 345 void arm_float_to_q29 (float *pIn, q31_t * pOut,
simon 0:1014af42efd9 346 uint32_t numSamples)
simon 0:1014af42efd9 347 {
simon 0:1014af42efd9 348 uint32_t i;
simon 0:1014af42efd9 349
simon 0:1014af42efd9 350 for (i = 0; i < numSamples; i++)
simon 0:1014af42efd9 351 {
simon 0:1014af42efd9 352 /* 1073741824.0f corresponds to pow(2, 30) */
simon 0:1014af42efd9 353 pOut[i] = (q31_t) (pIn[i] * 536870912.0f);
simon 0:1014af42efd9 354
simon 0:1014af42efd9 355 pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
simon 0:1014af42efd9 356
simon 0:1014af42efd9 357 if (pIn[i] == (float) 4.0)
simon 0:1014af42efd9 358 {
simon 0:1014af42efd9 359 pOut[i] = 0x7FFFFFFF;
simon 0:1014af42efd9 360 }
simon 0:1014af42efd9 361 }
simon 0:1014af42efd9 362 }
simon 0:1014af42efd9 363
simon 0:1014af42efd9 364
simon 0:1014af42efd9 365 /**
simon 0:1014af42efd9 366 * @brief Converts float to fixed q28 format
simon 0:1014af42efd9 367 * @param uint32_t number of samples in the buffer
simon 0:1014af42efd9 368 * @return none
simon 0:1014af42efd9 369 * The function converts floating point values to fixed point values
simon 0:1014af42efd9 370 */
simon 0:1014af42efd9 371
simon 0:1014af42efd9 372 void arm_float_to_q28 (float *pIn, q31_t * pOut,
simon 0:1014af42efd9 373 uint32_t numSamples)
simon 0:1014af42efd9 374 {
simon 0:1014af42efd9 375 uint32_t i;
simon 0:1014af42efd9 376
simon 0:1014af42efd9 377 for (i = 0; i < numSamples; i++)
simon 0:1014af42efd9 378 {
simon 0:1014af42efd9 379 /* 268435456.0f corresponds to pow(2, 28) */
simon 0:1014af42efd9 380 pOut[i] = (q31_t) (pIn[i] * 268435456.0f);
simon 0:1014af42efd9 381
simon 0:1014af42efd9 382 pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
simon 0:1014af42efd9 383
simon 0:1014af42efd9 384 if (pIn[i] == (float) 8.0)
simon 0:1014af42efd9 385 {
simon 0:1014af42efd9 386 pOut[i] = 0x7FFFFFFF;
simon 0:1014af42efd9 387 }
simon 0:1014af42efd9 388 }
simon 0:1014af42efd9 389 }
simon 0:1014af42efd9 390
simon 0:1014af42efd9 391 /**
simon 0:1014af42efd9 392 * @brief Clip the float values to +/- 1
simon 0:1014af42efd9 393 * @param pIn input buffer
simon 0:1014af42efd9 394 * @param numSamples number of samples in the buffer
simon 0:1014af42efd9 395 * @return none
simon 0:1014af42efd9 396 * The function converts floating point values to fixed point values
simon 0:1014af42efd9 397 */
simon 0:1014af42efd9 398
simon 0:1014af42efd9 399 void arm_clip_f32 (float *pIn, uint32_t numSamples)
simon 0:1014af42efd9 400 {
simon 0:1014af42efd9 401 uint32_t i;
simon 0:1014af42efd9 402
simon 0:1014af42efd9 403 for (i = 0; i < numSamples; i++)
simon 0:1014af42efd9 404 {
simon 0:1014af42efd9 405 if(pIn[i] > 1.0f)
simon 0:1014af42efd9 406 {
simon 0:1014af42efd9 407 pIn[i] = 1.0;
simon 0:1014af42efd9 408 }
simon 0:1014af42efd9 409 else if( pIn[i] < -1.0f)
simon 0:1014af42efd9 410 {
simon 0:1014af42efd9 411 pIn[i] = -1.0;
simon 0:1014af42efd9 412 }
simon 0:1014af42efd9 413
simon 0:1014af42efd9 414 }
simon 0:1014af42efd9 415 }
simon 0:1014af42efd9 416
simon 0:1014af42efd9 417
simon 0:1014af42efd9 418
simon 0:1014af42efd9 419