delphi 音频字节混合

sqougxex  于 2023-04-20  发布在  其他
关注(0)|答案(2)|浏览(109)

只是不能获得一个正确的声音,当我试图混合波字节与其他人...
根据a _style(sOverlay或sOverwrite),我循环采样并调用OverByte,其中包含指向前一个SmallInt的指针和一个新的字节值...

procedure OverByte(var _pbyte : ^TByte; const _byte : TByte);
begin
     case _style of
          sOverlay   : _pbyte^ := Math.Min(0, Math.Max(255, (_pbyte^ + _byte) div 2));
          sOverwrite : _pbyte^ := _byte;
     end;
end;

当我用sOverWrite填充缓冲区时,我有一个正确的声音...当我用sOverlay填充缓冲区时,我没有正确的声音...
我知道的很简单:
我在左和右通道上以2400 hz填充2000 ms:正确的声音我只在左声道上以4800填充相同的缓冲区1000 ms:声音是一样的...所以不正确...
2 audiobytes的公式RESTRICT(0..255,(A + B)/ 2)是否正确?

q43xntqr

q43xntqr1#

你忘了告诉我们TByte是什么,但我假设它是Byte
你的公式基本上是

Min(0, Max(255, (A + B) div 2));

假设A = 70,B = 150。
则AVG =(A + B)div 2 = 110。
则Max(255,AVG)= Max(255,110)= 255,因为255大于110。
最后,Min(0,255)= 0,因为0小于255。
你看到问题了吗?
你显然想

Max(0, Min(255, (A + B) div 2));

可以写成

EnsureRange((A + B) div 2, 0, 255).

然而,由于A和B是字节,因此A〉= 0且B〉= 0,使得A + B〉= 0且因此(A + B)div 2〉= 0。
出于同样的原因,A〈= 255且B〈= 255,因此A + B〈= 510,因此(A + B)div 2〈= 255。
因此

EnsureRange((A + B) div 2, 0, 255) = (A + B) div 2.

所以你把事情搞复杂了!

slwdgvem

slwdgvem2#

经过测试,添加两个SmallInt可能会溢出,因此Min应用作获得256以下Integer的第一个限制...
然后是最大值,以获得一个正值…
然后转换为一个简单的SmallInt就可以正确执行了……
但是你指出了一个事实,即两个字节相加并除以2不能超过255或低于0!!!
我现在两个频道都有正确的声音...
谢谢...

相关问题