• pcm原始数据绘制


    最近帮别人做了个东西,这里分享一下pcm原始数据绘图的思路

    1、pcm数据采样位数,根据采样位数选取适合自己绘图的采样点的数量

    2、计算出最大最小的的采样点的值差

    3、根据要显示pcm数据的控件宽高,根据pcm原始数据的在pcm数据的偏移计算出x坐标,根据pcm数据采样的数值大小计算出y坐标

    4、绘图,依次进行相邻数据点绘图

     以下是在Duilb中绘图的代码:

     1     std::vector<char> pcm_buffer;
     2     FILE * file = NULL;
     3     file = fopen("pcm\20180601155322.pcm", "rb");
     4 
     5     if (file != NULL) {
     6         //
     7         pcm_buffer.clear();
     8         pcm_buffer.shrink_to_fit();
     9 
    10         fseek(file, 0, SEEK_END);
    11         unsigned int size_byte = ftell(file);
    12         fseek(file, 0, SEEK_SET);
    13         pcm_buffer.resize(size_byte);
    14         fread(&pcm_buffer[0], size_byte, 1, file);
    15         fclose(file);
    16         size_byte /= 2;
    17         int step = 1, len = size_byte;
    18         if (size_byte > 20000) {
    19             len = 20000;
    20             step = (int)(size_byte / len);
    21         }
    22         short * pcm_16 = (short*)(&pcm_buffer[0]);
    23         std::vector<float> pcm_float;
    24         pcm_float.resize(20000);
    25         for (int i = 0, n = 0; n < len; i += step, n++) {
    26             pcm_float[n] = pcm_16[i];
    27         }
    28 
    29         float max = pcm_float[0], min = pcm_float[0];
    30         for (int i = 1; i< pcm_float.size(); i++){
    31             if (max < pcm_float[i]){
    32                 max = pcm_float[i];
    33             }
    34             if (min > pcm_float[i]){
    35                 min = pcm_float[i];
    36             }
    37         }
    38         int w = m_rcItem.right - m_rcItem.left;
    39         int h = m_rcItem.bottom - m_rcItem.top;
    40         std::vector<PointF> points;
    41         float diffVal = max - min;
    42         for (int i = 0; i < pcm_float.size(); i++){
    43             points.push_back(PointF(i * w / pcm_float.size(), h - (pcm_float[i] - min) / diffVal * h));
    44         }
    45 
    46         const DWORD backColor = 0xFFC9C9C9;
    47         CRenderEngine::DrawColor(hDC, m_rcItem, backColor);
    48         const DWORD backLineColor = 0xFF0000FF;
    49         for (int i = 0; i < points.size() - 1; i++){
    50             RECT rect;
    51             rect.left = points[i].X;
    52             rect.top = points[i].Y + m_rcItem.top;
    53             rect.right = points[i + 1].X;
    54             rect.bottom = points[i + 1].Y + m_rcItem.top;
    55             CRenderEngine::DrawLine(hDC, rect, 1, backLineColor);
    56         }
    57     }

     

    绘图效果:

    测试绘图代码:  https://github.com/karllen/cef3-duilib-YDDemo/tree/master/PcmMediaDemo

  • 相关阅读:
    Oracel基础知识
    64位系统运行32位Oracle程序解决方案
    Oracle 级联删除
    string转DateTime(时间格式转换)
    vs2013 内置IIS Express相关问题
    小马哥课堂-统计学-置信区间(2)
    小马哥课堂-统计学-置信区间
    小马哥课堂-统计学-标准误差
    小马哥课堂-统计学-中心极限定理
    python之histogram
  • 原文地址:https://www.cnblogs.com/Forever-Kenlen-Ja/p/9217215.html
Copyright © 2020-2023  润新知