30天自制操作系统吧 关注:1,380贴子:4,756
  • 16回复贴,共1

在铁娃娃OS上试做mp2解码实验

只看楼主收藏回复

mpeg1中的音频信号是按mp2标准编码的。
要从mpeg文件里还原音频信号,需要作mp2解码的工作。
mp2解码过程中需要用到浮点数运算。之前因为遇到sprintf( "%f" ,3.1415 )无法正常输出,
无法调试,只好断念。
后来想到用变通的办法,也可以解决浮点数的输出问题,即如果要输出浮点数3.1415,
先乘10000。 再分离出整数部分3和小数部分1415,中间加一个“.”,就能输出完整的浮点数。
%f问题解决后,发现在一定的条件下,其实现在的编译工具还是支持浮点数的四则运算的。
下图,是在桌面显示500Hz的mp2音频信号解码后的波形。看起来,虽说mp2是有损压缩,但
解码后的正弦波还是相当还原的。
用90分钟的16bit,Stereo的语音mp2,与wav相比,压缩比大约10:1。通过铁娃娃系统的mp2解码,
经过声卡播放,与直接播放wav效果一样(听不出差异)。

mpeg1解码,mp2解码和声卡技术问题解决后,下一步的目标是“铁娃娃”播放完整的有声电影。


IP属地:上海1楼2021-12-26 19:09回复
    上图中的一个App是在文本文件显示器中,加入了水平/垂直的Scroll功能。
    用鼠标点击三角记号按钮,滑块会移动,窗口中的文字也会上下左右跟着移动。


    IP属地:上海2楼2021-12-26 19:14
    回复
      点击桌面上的图标,



      即能直接打开对应的App。不需要用键盘输入命令了。


      IP属地:上海3楼2021-12-26 19:40
      收起回复
        用现在提供的工具,在APP用浮点数处理,是有条件限制的。
        网上看到有人试验过在mp3解码中,不用浮点数,而用整数。这是一个不错的解放思路。
        一个浮点数,不就是两个整数的相除吗? 估计运算速度也会提高不少。缺点可能就是精度会降低。
        一个声音的采样值精度高的有24bit,常用的是16bit,也有8bit的。如果能做到8bit精度也是不错的。
        有时间的话,很想尝试一下用整数参数,作mp2解码。


        IP属地:上海4楼2022-01-03 20:49
        收起回复
          之前,在App中是采用搞浮点数解码,还是整数解码,一直左右为难,
          摇摆不定。因为两种办法,对本人水平来说,都不是轻而易举的。总
          想找个容易解决的路子走。后来,还是选择了走整数解码的路子。用
          整数替代浮点数解码,一楼时期只是粗粗一想,觉得问题不大。
          实际做起来,就碰到困难。我采取的方法是:各个浮点数参数乘放
          大系数,观察输出的波形,以不失真为标准。输出值再除比例系数,
          使波形不切峰。再接着调整放大系数。比如原来的小数是0.1234,如
          果最终改为乘1234,而输出结果再除10000,那么问题就非常简单了。
          开始我试着乘2,结果是波形增大而不失真,感到有希望。结果在这
          上面浪费了不少时间。因为当乘4时,上面的规律就消失了。用其他补
          救方法也看不出规律,没有了头绪。
          后来知道有人采用整数解码成功,还发表论文。知道整数形式解码
          的问题是有份量的。当然论文里面并没有告诉大家是怎么解决的。
          这次重新捡起整数形式解码,一步步不厌其烦地推导一大组公式,
          终于把所有的公式一个个推导出来,每一个公式都是一个大矩阵。推
          导公式过程中,很容易犯错,只有在最后通过所有公式计算的得到结
          果,是标准的正弦波,才能证明公式正确。这里面只要一个分项公式
          是错误的,即使其他公式是正确的,输出的结果也可能是面目全非。
          而且还不知道是哪个分项公式错了。这是几十个计算公式“与"的问题。
          真是前面错,后面再认真,结果也是错的。这是考验人的细心和耐心。
          万幸,第一次试验测试结果,看上去有点正弦波的样子。信心大增。
          否则,要放弃了。
          对比:
          图一:这是用浮点数计算解码的正弦波波形,很标准。

          图二: 这是初次用整数形式解码得到的波形,看到希望,可以走通。


          IP属地:上海5楼2022-05-15 12:58
          回复
            图二,是初次用整数形式解码输出的波形,仔细看正弦波并不规则。
            反映到实机播放mp2解码的音源时,噪音就很大。很像以前自己装收
            音机听到那种啸叫,还有“金属声”。
            图三,是第三次全部重新推导公式后的结果:

            看上去,已经很接近正弦波了。但实际播音时,仍然有噪音,虽然好像减少了一些。
            图四: 是第五次重新推导公式后,得到的输出波形:

            这次的输出波形与用浮点数解码的正弦波,完全一致。实机上播放解码后音乐也没有噪音。
            至此,完成了整数型解码。一共做了5次推导,每次都是几十个公式。慢慢地有了感觉,一
            看推导出来的公式,就大致知道,有没有推导错了。
            现在我是把小数点数,乘10000倍。最后再用除法除掉。当然乘的倍数越大,也就是小数
            点的位数越长,精度也越高。但因为一个数受32bit的限制,扩大倍数不能溢出32bit。实际
            因有正负数,只有31bit。考虑到音频数据也就16bit,所以基本上没有误差造成的失真。即
            只有1/10000的误差。
            曾经有一次,试过最大扩大倍数是40000,竟然也能通过。可后来再没有实现过,可能是
            哪个地方搞错了,或者一时脑子坏了。目前做到的是扩大倍数10000。
            现在,在App中,可以放心大胆地使用mp2解码了。在笔记本电脑上用自制操作系统#播
            放一部有声电影指日可待。
            旁记:
            在推导几十个公式时,想起看过的电视剧《无名英雄之于敏》中,于敏对基地的军代表
            老马讲的话,推导公式就像搭纸牌,搭错了倒了,再重新搭。(呵呵)


            IP属地:上海6楼2022-05-15 13:33
            收起回复
              把整数解码程序移植到App里。图5是App读取一个mpg(含视频,音频)文件后,提取出内部
              的mp2压缩数据,解码后的得到的波形。

              因为在mpg文件中,音频数据与视频数据是夹杂着摆放的。要把音频信号抽取出来。
              有时一帧音频数据会被一大段视频数据打断,则就要正确找到被打断的音频数据的后
              半段部分。这后半部分是没有起始标示符的,如果位置错了一个字节,后面解码的结
              果都面目全非了。现已经解决了。
              剩下的任务是考虑怎么把视频解码和音频解码的代码合为一个程序。届时上面
              的App显示的就不是音频波形,而是活动的视频图像。解码后的音频由声卡去处理了。


              IP属地:上海7楼2022-05-15 19:36
              回复
                补充一下,
                其实,还有一半的转换公式还没有推导。现在急用先推导的都是奇次
                谐波的公式。因为绝大部分的音频信号都是由有正负值的不同频率正弦
                波的组合而成。偶次谐波部分的运算结果几乎都是等于0。
                等以后抽时间再推导偶次谐波部分的公式,程序显得完整一些。
                什么情况下,会遇到偶次谐波呢? 当信号只有正半周,没有负半周,
                或者只有负半周,没有正半周的情况下才会产生。比如像半波(整流)
                的波形。


                IP属地:上海8楼2022-05-15 19:48
                回复
                  mpeg图像解码,要处理3种I,P,B帧。I帧相当于一幅jpg图像,是一帧完整的图像。
                  P帧是前面的I帧或前面的P帧图像,加上变化矢量▲P计算得到,即P=前P+▲P(P=前I+▲P)。
                  因为mpeg文件只提供▲P,所以P帧的数据量要小于I帧。在编码阶段P帧也称向前预测帧,
                  这里是解码,所以不是预测而是还原。B帧,是前I帧或P帧与后P帧或I帧的中间值。简单粗暴
                  地讲这个帧就是(前帧+后帧)/2,是本地计算出来的。其实mpg文件还是为B帧提供某些I块的
                  信息数据的。从占据mpg文件的数量量讲,I帧数据量最大,P帧次之,B帧最小。I帧解码过程
                  很像jpg的解码,有霍夫曼变换,DCT变换。我最初尝试做I帧解码是选择最小尺寸的I帧,即一
                  个16x16个像素的微块,也不考虑彩色,取材于黑白电影。
                  这是最初解码成功的图像,隐隐约约看到了图像。虽然只有16x16,而且上侧1/4是错误的,
                  但证明程序计算是成功的。

                  在此基础上,扩大到352x288。计算方法是相同的。然后加上Cb,Cr彩色信号。然后是P
                  帧解码,B帧解码。最后在实机上播放。


                  IP属地:上海9楼2022-11-20 16:39
                  回复
                    这是一位少校军官的头像,大盖帽因上侧的缓存区地址偏移没有显示出来,可隐隐约约看到肩章。
                    当初看到这幅图像时,还是有些激动的。
                    mpg视频解码与mp2整数解码问题解决之后,原来觉得合在一起播放应该不是太困难的事情。
                    实际操作起来却是很费事的。需要从混合在一起音视频的mpeg文件里,分别搜索出图像数据与音频
                    数据。原来只要按文件排好的顺序播放即可,现在要重新在缓存区里排队。而且要注意关键的开始码
                    不能被打断。比如,mp2的开始码是FF FD(B2 00),就有可能被00 00 01 BA 无端打断。还要考虑音
                    频解码不能走得太快,图像解码一般要慢一些。总之,意外的问题多多。但最终大致解决了。现在以
                    声卡的中断为标准时间基准,按44100Hz采样频率速度播放,图像显示,限制在1秒25帧。
                    基本上音声与图像同步。目测大约会有正负20ms的误差吧。系统时钟与App定时器本身就是10ms。
                    声卡采用High Definition Audio。chipset 是ICH9,CODEC芯片是ALC268。
                    实现在笔记本电脑Satellite L20实机上,完整地放映一部约95分钟的有声彩色电影。铁娃娃系统中的
                    视频实验,告一段落。
                    下一步,再做什么好呢? 考虑中......


                    IP属地:上海10楼2022-11-20 17:19
                    回复