找回密码
 -注册-
查看: 9781|回复: 66
打印 上一主题 下一主题

终于从数学原理上明白为什么SACD和CD出来的声音不一样和DSD的电平比较低了

[复制链接]
跳转到指定楼层
发表于 2023-4-13 20:59 | 只看该作者 |只看大图 回帖奖励 |正序浏览 |阅读模式 来自 中国
本帖最后由 zasflower 于 2023-4-13 23:36 编辑

最近在优化DSD解码的代码的cpu性能,突然想到了为什么DSD的声音不一样了。实际上你把CD转成DSD64,然后再用DSD低通滤波器重新滤波再转成CD,声音也是不一样的。

数学原理就是这样,DSD-PCM PCM-DSD转换不是无损的。这和ape转flac或者flac转wav不一样。实际上采用什么滤波器和滤波器截止频率选取在那个点声音都会不一样。

代码是这样子:
//dsf DSD file(SACD)
                public function decodeDsfDSD(dsdBytes:ByteArray,sampleEventOutBytes:ByteArray):void
                {
                        var byte:uint ;
                        var dataLeft:Number;
                        var dataRight:Number;
                        var readInt:uint;
                        var indexL:int=0;
                        var indexR:int =0;
                        
                        if(dsdBytes.position==60){
                                dsdBytes.position = 92;
                        }
                        
                        for (var i:int = 0; i < 8192; ) {
                                for(var mny:int=0;mny<512;mny++){
                                        dataLeft = 0;
                                        for(var m:int=0;m<2;m++){
                                                readInt = dsdBytes.readUnsignedInt();
                                                byte = readInt >> 24 & 0xFF;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte >>   1  ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte >>   2  ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte >>   3  ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte >>   4  ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte >>   5  ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte >>   6  ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte >>   7  ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                byte = readInt >> 16 & 0xFF;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte >>   1  ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte >>   2  ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte >>   3  ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte >>   4  ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte >>   5  ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte >>   6  ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte >>   7  ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                byte = readInt >> 8 & 0xFF;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte >>   1  ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte >>   2  ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte >>   3  ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte >>   4  ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte >>   5  ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte >>   6  ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte >>   7  ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                byte = readInt & 0xFF;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte >>   1  ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte >>   2  ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte >>   3  ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte >>   4  ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte >>   5  ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte >>   6  ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                                lpfdataL = lpfdataL+ cacheAlpha*((( byte >>   7  ) & 0x01)*2-1 - lpfdataL );
                                                lpfdata2L = lpfdata2L+ cacheAlpha*(lpfdataL - lpfdata2L );
                                                dataLeft += lpfdata2L;
                                        }
                                        i++;
                                        // +6.0db SACD
                                        // if +0db set to dataLeft/64
                                        // 64bit
                                        samplesL[indexL]=dataLeft/32;
                                        indexL++;
                                }
                                i -= 512;
                                for(var mnk:int=0;mnk<512;mnk++){
                                        dataRight = 0;
                                        for( m=0;m<2;m++){
                                                readInt = dsdBytes.readUnsignedInt();
                                                byte = readInt >> 24 & 0xFF;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte >>   1  ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte >>   2  ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte >>   3  ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte >>   4  ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte >>   5  ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte >>   6  ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte >>   7  ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                byte = readInt >> 16 & 0xFF;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte >>   1  ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte >>   2  ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte >>   3  ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte >>   4  ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte >>   5  ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte >>   6  ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte >>   7  ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                byte = readInt >> 8 & 0xFF;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte >>   1  ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte >>   2  ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte >>   3  ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte >>   4  ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte >>   5  ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte >>   6  ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte >>   7  ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                byte = readInt & 0xFF;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte >>   1  ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte >>   2  ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte >>   3  ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte >>   4  ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte >>   5  ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte >>   6  ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                                lpfdataR = lpfdataR+ cacheAlpha*((( byte >>   7  ) & 0x01)*2-1 - lpfdataR );
                                                lpfdata2R = lpfdata2R+ cacheAlpha*(lpfdataR - lpfdata2R );
                                                dataRight += lpfdata2R;
                                        }
                                        i++;
                                        // +6.0db SACD
                                        // if +0db set to dataRight/64
                                        // 64bit
                                        samplesR[indexR]=dataRight/32;
                                        indexR++;
                                }
                        }
                        //need write data later
                        for(i=0;i<8192;i++){
                                // 32bit
                                sampleEventOutBytes.writeFloat(samplesL);
                                sampleEventOutBytes.writeFloat(samplesR);
                        }
                }



主要公式是这个:
lpfdataL = lpfdataL+ cacheAlpha*((( byte >>   7  ) & 0x01)*2-1 - lpfdataL )

将二进制右移动7位检查当前1bit二进制是0还是1,0就是-1.0电平 1就是+1.0电平。

然后输出 lpfdataL  会加上高频的目标电平。会缓慢逼近目标电平。相当于 y += (dsd-y) * cacheAlpha
cacheAlpha 取值为0-0.05-0.2-0.5-0.7-1,0则会切除所有频率。1不会动任何频率。(取中间则数则切除DSD高频噪声)

因为在逼近目标电平+1.0 -1.0(因为要切除高频噪声所以cacheAlpha不可能取值1,不然任何频率不会动) 所以DSD出来的声音默认就是比较小的。



66
发表于 2023-4-16 07:49 | 只看该作者 来自 浙江
番茄炒蛋饭 发表于 2023-4-14 13:33
我最近开发了PCM转DSD播放器 用DAC直解DSD 音质动态都不错 本身DAC内部也是PCM转DSD模块 但因为元件限制 ...

非常正确,顶
回复

使用道具 举报

65
发表于 2023-4-16 07:47 | 只看该作者 来自 浙江
番茄炒蛋饭 发表于 2023-4-14 13:33
我最近开发了PCM转DSD播放器 用DAC直解DSD 音质动态都不错 本身DAC内部也是PCM转DSD模块 但因为元件限制 ...

非常正确,&#128077;&#127995;&#128077;&#127995;
回复

使用道具 举报

64
发表于 2023-4-16 01:06 | 只看该作者 来自 陕西西安
本帖最后由 hytcqq 于 2023-4-16 01:07 编辑

既然用cpu了,就不要用一阶二阶这些初级的滤波器了,而且你没有加噪声整形,dsp工具箱里很多高级滤波器,tap动辄256的,这也是hqplayer厉害的地方。
回复

使用道具 举报

63
发表于 2023-4-14 17:38 来自手机 | 只看该作者 来自 亚太地区
仰望
回复

使用道具 举报

62
发表于 2023-4-14 15:31 来自手机 | 只看该作者 来自 中国
leonbernieni 发表于 2023-4-14 15:07
可以实现,你搜一个Simple DSD modulator for DSC2的帖子,提到个CSD的文档,有个性的“大作业”!

早就看过 他需要fpga来做插值和噪音整形 他的fpga算法我都写过,很熟
回复

使用道具 举报

61
 楼主| 发表于 2023-4-14 15:29 | 只看该作者 来自 中国
二师兄 发表于 2023-4-14 10:12
我试过不少机器
马兰士红宝石CD 、力士D-03X CD、NAIM ATOM HE、SONY黑砖、双木三林DP5、乐图PAW6000等 ...

我写了个小软件。我自己听歌就用自己写的软件听,可以播放CD DSD。
https://github.com/sulinhuang/KMusicPlayerWindows/releases/tag/v172Release




你先按照图片这样设置,然后再打开一首DSD64,看声音是不是不硬很柔和,和CD区别明显。

这个是DSD这个格式的特点。

回复

使用道具 举报

60
发表于 2023-4-14 15:07 来自手机 | 只看该作者 来自 上海
番茄炒蛋饭 发表于 2023-4-14 13:49
大部分滤波器都需要乘法,重采样和噪音整形都有大量乘法 这个避免不了

可以实现,你搜一个Simple DSD modulator for DSC2的帖子,提到个CSD的文档,有个性的“大作业”!
回复

使用道具 举报

59
发表于 2023-4-14 13:49 来自手机 | 只看该作者 来自 中国
leonbernieni 发表于 2023-4-14 13:45
能自己搭转换器是一种享受!我对代码是一窍不通有没耐心学。据说用纯加法器比直接调用乘法模块更好,直觉 ...

大部分滤波器都需要乘法,重采样和噪音整形都有大量乘法 这个避免不了
回复

使用道具 举报

58
发表于 2023-4-14 13:45 来自手机 | 只看该作者 来自 中国
abccbaa 发表于 2023-4-14 12:46
ok  明白了 那r2r(1bit)的解码 是不是就不用先叠加成一个字节
但为什么r2r听上去比9038这种糊

R2R糊是因为电阻矩阵精度不高 细节丢失严重,DSD解码对元件精度要求不高 可以做到很高精度 所以现在主流DAC先转类DSD格式再赚模拟信号
回复

使用道具 举报

57
发表于 2023-4-14 13:45 来自手机 | 只看该作者 来自 上海
番茄炒蛋饭 发表于 2023-4-14 13:33
我最近开发了PCM转DSD播放器 用DAC直解DSD 音质动态都不错 本身DAC内部也是PCM转DSD模块 但因为元件限制 ...

能自己搭转换器是一种享受!我对代码是一窍不通有没耐心学。据说用纯加法器比直接调用乘法模块更好,直觉上。
回复

使用道具 举报

56
发表于 2023-4-14 13:33 来自手机 | 只看该作者 来自 中国
abccbaa 发表于 2023-4-14 13:28
相对dsd  我觉得dxd更好听 dsd动态有损失

我最近开发了PCM转DSD播放器 用DAC直解DSD 音质动态都不错 本身DAC内部也是PCM转DSD模块 但因为元件限制和精度问题 算法有取舍 在PC上使用更高阶算法然后直连DAC 会比PCM音质好
回复

使用道具 举报

55
发表于 2023-4-14 13:28 | 只看该作者 来自 上海长宁区
本帖最后由 abccbaa 于 2023-4-14 13:29 编辑
番茄炒蛋饭 发表于 2023-4-14 13:23
网上有格式说明文档 你找找应该能找到 格式相当简单比flac ape这种格式简单太多

相对dsd  我觉得dxd更好听 dsd动态有损失
回复

使用道具 举报

54
发表于 2023-4-14 13:23 来自手机 | 只看该作者 来自 中国
abccbaa 发表于 2023-4-14 12:49
有没有格式文件看看

网上有格式说明文档 你找找应该能找到 格式相当简单比flac ape这种格式简单太多
回复

使用道具 举报

53
发表于 2023-4-14 12:49 | 只看该作者 来自 上海长宁区
番茄炒蛋饭 发表于 2023-4-14 10:00
dff和dsf的差异是文件头和DSD数据大小端差异 本质没啥差别

有没有格式文件看看
回复

使用道具 举报

52
发表于 2023-4-14 12:46 | 只看该作者 来自 上海长宁区
zasflower 发表于 2023-4-14 11:13
8bit是cpu读取按照8bit 8bit来读取的,dsd是1bit的,所以我要反复移位。

叠加是加法器,参见rc模拟滤 ...

ok  明白了 那r2r(1bit)的解码 是不是就不用先叠加成一个字节
但为什么r2r听上去比9038这种糊

回复

使用道具 举报

51
发表于 2023-4-14 12:14 | 只看该作者 来自 北京
同一个解码器dsd的动态测量指标都低于pcm
回复

使用道具 举报

50
 楼主| 发表于 2023-4-14 11:13 | 只看该作者 来自 亚太地区
本帖最后由 zasflower 于 2023-4-14 11:18 编辑
abccbaa 发表于 2023-4-14 09:58
它这反复跳1 2 3 4 5 6 7个bit 叠加 dsd格式是8bit代表一个时间点吗 最后一个是校验位?

dsd格式规范 ...

8bit是cpu读取按照8bit 8bit来读取的,dsd是1bit的,所以我要反复移位。

叠加是加法器,参见rc模拟滤波器一阶电子电路里面的加法器。然后还有个乘法器。乘法器对应的是dsd模拟滤波器电子电路的电阻。
回复

使用道具 举报

49
发表于 2023-4-14 11:11 来自手机 | 只看该作者 来自 中国
leonbernieni 发表于 2023-4-14 11:01
+1
另外cd带限在22.05Hz也是个坑,现实世界不能全听香农的,把一个pcm脉冲信号转换为dsd后看频谱会塞满 ...

这个问题确实要频域/时域分析,噪音整形本质是为了提高精度更好的做数字转模拟 传统的R2R依赖电阻精度 成本极高,使用DS架构之后 对数字转模拟部分元件要求低多了,当然对数字电路要求很高,不过这个在现在不是问题。
回复

使用道具 举报

48
发表于 2023-4-14 11:08 来自手机 | 只看该作者 来自 亚太地区
这个起点有点高啊?看不懂
回复

使用道具 举报

47
发表于 2023-4-14 11:01 来自手机 | 只看该作者 来自 上海
番茄炒蛋饭 发表于 2023-4-14 10:25
现在的DAC除了R2R架构 其他的都是DS架构 也就是说内部都会做噪音整形 除了CS厂其他几家都不是1bit ,大家听 ...

+1
另外cd带限在22.05Hz也是个坑,现实世界不能全听香农的,把一个pcm脉冲信号转换为dsd后看频谱会塞满视图方框,按理dsd可以扩展通带,但是原信号又是cd通带,滤波后必然是衰减了能量谱。dxd的情况就好得多。其实从频域/时域分析思路会更清晰。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | -注册-

本版积分规则

Archiver|手机版|粤icp备09046054号|耳机网-耳机大家坛

粤公网安备 44030602000598号 耳机大家坛、www.erji.net、网站LOGO图形均为注册商标

GMT+8, 2025-2-18 18:49

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表