objective-c – 从Float32到SInt16的位移音频样本导致严重削波

objective-c – 从Float32到SInt16的位移音频样本导致严重削波,第1张

概述我是iOS及其C基础的新手,但不是一般的编程.我的困境是这样的.我正在基于AudioUnits的复杂应用程序中实现回声效果.该应用程序需要混响,回声和压缩等功能.但是,当我在我的应用程序中生成的音频样本使用特定的AudioStreamBasicDescription格式时,回声才有效.但是,此格式不适用于其他AudioUnits. 虽然还有其他方法可以解决这个问题,但修复回声算法中的位错可能是最直 我是iOS及其C基础的新手,但不是一般的编程.我的困境是这样的.我正在基于AudioUnits的复杂应用程序中实现回声效果.该应用程序需要混响,回声和压缩等功能.但是,当我在我的应用程序中生成的音频样本使用特定的AudioStreamBasicDescription格式时,回声才有效.但是,此格式不适用于其他AudioUnits.
虽然还有其他方法可以解决这个问题,但修复回声算法中的位错可能是最直接的方法.

与echo一起使用的* AudioStreamBasicDescription *具有mFormatFlag:kAudioFormatFlagsAudioUnitCanonical;具体是:

AudioUnit Stream Format (ECHO works,NO AUdio UNITS)Sample Rate:              44100Format ID:                 lpcmFormat Flags:              3116 = kAudioFormatFlagsAudioUnitCanonicalBytes per Packet:             4Frames per Packet:            1Bytes per Frame:              4Channels per Frame:           2Bits per Channel:            32Set ASBD on inputSet ASBD on  outputau SampleRate rate: 0.000000,2 channels,12 formatflags,1819304813 mFormatID,16 bits per channel

除了mFormatFlag之外,与AudioUnit一起使用的流格式是相同的:kAudioFormatFlagIsfloat | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsNonInterleaved – 具体如下:

AudioUnit Stream Format (NO ECHO,AUdio UNITS WORK)Sample Rate:              44100Format ID:                 lpcmFormat Flags:                41 Bytes per Packet:             4Frames per Packet:            1Bytes per Frame:              4Channels per Frame:           2Bits per Channel:            32Set ASBD on inputSet ASBD on  outputau SampleRate rate: 44100.000000,41 formatflags,32 bits per channel

为了创建回声效果,我使用两个函数将样本数据按位移位到SInt16空间,然后返回.正如我所说,这适用于kAudioFormatFlagsAudioUnitCanonical格式,但不适用于其他格式.当它失败时,声音被剪裁和扭曲,但它们在那里.我认为这表明这两种格式之间的区别在于如何在float32中排列数据.

// convert sample vector from fixed point 8.24 to SInt16voID fixedPointToSInt16( SInt32 * source,SInt16 * target,int length ) {    int i;    for(i = 0;i < length; i++ ) {        target[i] =  (SInt16) (source[i] >> 9);        //target[i] *= 0.003;    }}

*正如你所看到的,我试图修改样本的幅度以摆脱剪辑 – 显然这是行不通的.

// convert sample vector from SInt16 to fixed point 8.24 voID SInt16ToFixedPoint( SInt16 * source,SInt32 * target,int length ) {    int i;    for(i = 0;i < length; i++ ) {        target[i] =  (SInt32) (source[i] << 9);        if(source[i] < 0) {             target[i] |= 0xFF000000;        }        else {            target[i] &= 0x00FFFFFF;        }    }}

如果我可以确定kAudioFormatFlagIsfloat |之间的区别kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsNonInterleaved,然后我可以相应地修改上面的方法.但我不知道如何解决这个问题. CoreAudio中的文档是神秘的,但是从我在那里读到的,并从CoreAudioTypes.h文件中收集到的,两个mFormatFlag都引用了相同的Fixed Point 8.24格式.显然有些不同,但我无法弄清楚是什么.

感谢您阅读这个长期的问题,并提前感谢您提供的任何见解.

解决方法 kAudioFormatFlagIsfloat表示缓冲区包含浮点值.如果mBitsPerChannel是32,那么你正在处理浮点数据(也称为float32),如果它是64,你正在处理双数据.

kAudioFormatFlagsNativeEndian指的是缓冲区中的数据与处理器的字节序匹配,因此您不必担心字节交换.

kAudioFormatFlagIsPacked意味着数据中的每个位都很重要.例如,如果以32位存储24位音频数据,则不会设置此标志.

kAudioFormatFlagIsNonInterleaved表示每个缓冲区由一个数据通道组成.音频数据交错是常见的,样本在L和R通道之间交替:LRLRLRLR.对于DSP应用,通常更容易对数据进行解交织并一次在一个通道上工作.

我认为在您的情况下,错误是您将浮点数据视为固定点.浮点数据通常缩放到区间[-1,1).要将float转换为SInt16,您需要将每个样本乘以最大16位值(1u << 15,32768),然后剪切到间隔[-32768,32767].

总结

以上是内存溢出为你收集整理的objective-c – 从Float32到SInt16的位移音频样本导致严重削波全部内容,希望文章能够帮你解决objective-c – 从Float32到SInt16的位移音频样本导致严重削波所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1082643.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-27
下一篇 2022-05-27

发表评论

登录后才能评论

评论列表(0条)

保存