1. /**
    2. * @brief 波表压缩算法
    3. * @param 原波形数据
    4. * @param 原波形长度
    5. * @param 压缩后的波形数据
    6. * @param 压缩的波形长度
    7. */
    8. void AwgGuiWaveformWidget::waveCompressAlgorithm(u16 *pu16Source, u32 u32SourceNum, u16 *pu16Des, u32 u32DesNum)
    9. {
    10. u32 u32MaxPos, u32MinPos;
    11. u16 u16Dot[4];
    12. // 极值结构体
    13. ExtremumValueStru strExtremum;
    14. // 临时数据压缩数据
    15. f32 *pf32TempDot;
    16. pf32TempDot = (f32 *)malloc(u32DesNum * 2 * sizeof(f32));
    17. // 先将原波形数据压缩成(u32DesNum * 2 - 2)个点
    18. u32 u32CompressNumTemp = u32DesNum * 2 - 2;
    19. // 计算压缩倍率
    20. f32 f32Multiple = (f32)u32SourceNum / (f32)u32CompressNumTemp * 2;
    21. // 计算循环次数
    22. u32 u32Cycle = u32CompressNumTemp / 2;
    23. u32 k = 0;
    24. for (u32 i = 0; i < u32Cycle; i ++)
    25. {
    26. // 查找指定长度的最大值、最小值
    27. if (i == (u32Cycle - 1))
    28. {
    29. this->findExtremum(&pu16Source[(u32)(f32Multiple * i)], (u32SourceNum - (u16)(f32Multiple * i)), &strExtremum);
    30. }
    31. else
    32. {
    33. this->findExtremum(&pu16Source[(u32)(f32Multiple * i)], (u16)f32Multiple, &strExtremum);
    34. }
    35. // 获得最大值、最小值的位置
    36. u32MaxPos = (u32)(f32Multiple * i) + strExtremum.u32MaxPos;
    37. u32MinPos = (u32)(f32Multiple * i) + strExtremum.u32MinPos;
    38. if (u32MinPos < u32MaxPos)
    39. {
    40. pf32TempDot[k] = pu16Source[u32MinPos];
    41. pf32TempDot[k+1] = pu16Source[u32MaxPos];
    42. }
    43. else
    44. {
    45. pf32TempDot[k] = pu16Source[u32MaxPos];
    46. pf32TempDot[k+1] = pu16Source[u32MinPos];
    47. }
    48. k += 2;
    49. }
    50. // 假如有4个数据在pf32TempDot中,pf32TempDot[0] < pf32TempDot[1], pf32TempDot[2] < pf32TempDot[3]
    51. // 在这4个数据中需要选择2点作为最终输出波形数据,重点是比较pf32TempDot[1]和pf32TempDot[2]是否是极值
    52. // 若无极值 pf32TempDot[0] < pf32TempDot[1] < pf32TempDot[2] < pf32TempDot[3],则取pf32Des[j] = (pf32TempDot[1] + pf32TempDot[2]) / 2
    53. // 若都是极值 pf32TempDot[2] < pf32TempDot[3] < pf32TempDot[0] < pf32TempDot[1],则取pf32Des[j] = pf32TempDot[1],pf32TempDot[i+2] = u16Dot[2]
    54. // 若只有一个极值 pf32TempDot[0] < pf32TempDot[2] < pf32TempDot[3] < pf32TempDot[1],则取pf32Des[j] = pf32TempDot[1]
    55. pu16Des[0] = pf32TempDot[0];
    56. for (u32 i = 1, j = 0; i <= k; i +=2, j++)
    57. {
    58. u16Dot[0] = pu16Des[j];
    59. u16Dot[1] = pf32TempDot[i];
    60. u16Dot[2] = pf32TempDot[i+1];
    61. u16Dot[3] = pf32TempDot[i+2];
    62. // 查找最大值、最小值
    63. this->findExtremum(u16Dot, 4, &strExtremum);
    64. u32MaxPos = strExtremum.u32MaxPos;
    65. u32MinPos = strExtremum.u32MinPos;
    66. if ((u32MinPos != 1) && (u32MaxPos != 2) && (u32MinPos != 2) && (u32MaxPos != 1))
    67. {
    68. pu16Des[j] = (u16Dot[1] + u16Dot[2]) / 2;
    69. }
    70. else if (((u32MinPos == 2) && (u32MaxPos == 1)) || ((u32MinPos == 1) && (u32MaxPos == 2)))
    71. {
    72. pu16Des[j] = u16Dot[1];
    73. pf32TempDot[i+2] = u16Dot[2];
    74. }
    75. else if ((u32MaxPos == 1) || (u32MinPos == 1))
    76. {
    77. pu16Des[j] = u16Dot[1];
    78. }
    79. else if ((u32MinPos == 2) || (u32MaxPos == 2))
    80. {
    81. pu16Des[j] = u16Dot[2];
    82. }
    83. pu16Des[j+1] = pf32TempDot[i];
    84. }
    85. free(pf32TempDot);
    86. pf32TempDot = NULL;
    87. }
    1. /**
    2. * @brief 查找极值点
    3. * @param 原数据
    4. * @param 数据长度
    5. * @param 极值结构
    6. */
    7. void AwgGuiWaveformWidget::findExtremum(u16 *pu16Value, u32 u32Length, ExtremumValueStru *pstExtremumValue)
    8. {
    9. u32 u32MinPos = 0, u32MaxPos = 0;
    10. u16 u16Min = 0, u16Max = 0;
    11. if (pu16Value != NULL)
    12. {
    13. u16Min = pu16Value[0];
    14. u16Max = pu16Value[0];
    15. }
    16. // 查找极小值、极大值
    17. for (u32 i = 0; i < u32Length; i ++)
    18. {
    19. if (pu16Value[i] < u16Min)
    20. {
    21. u32MinPos = i;
    22. u16Min = pu16Value[i];
    23. }
    24. else if (pu16Value[i] > u16Max)
    25. {
    26. u32MaxPos = i;
    27. u16Max = pu16Value[i];
    28. }
    29. }
    30. pstExtremumValue->u32MinPos = u32MinPos;
    31. pstExtremumValue->u16Min = u16Min;
    32. pstExtremumValue->u32MaxPos = u32MaxPos;
    33. pstExtremumValue->u16Max = u16Max;
    34. }