pcm原始数据绘制

Posted forever-kenlen-ja

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

 


以上是关于pcm原始数据绘制的主要内容,如果未能解决你的问题,请参考以下文章

PCM原始数据到用户空间

使用 Core Audio 从 PCM 原始数据中获取电平值

使用 Android SDK 从原始 PCM 数据创建 WAV 文件

如何解释 MP3 文件中的原始 pcm 数据

使用 CoreAudio 中的 AudioQueue 从网络播放原始 pcm

将原始PCM数据转换为RIFF WAV