c# – 从.WAV文件中读取24位样本
我理解如何读取8位,16位&来自.wav文件的32位样本(PCM和浮点),因为(方便地).Net Framework具有用于那些精确大小的内置整数类型.但是,我不知道如何读取(和存储)24位(3字节)样本.
如何读取24位音频?有没有什么方法可以改变我当前的方法(下面)来读取32位音频来解决我的问题? private List<float> Read32BitSamples(FileStream stream,int sampleStartIndex,int sampleEndIndex) { var samples = new List<float>(); var bytes = ReadChannelBytes(stream,Channels.Left,sampleStartIndex,sampleEndIndex); // Reads bytes of a single channel. if (audioFormat == WavFormat.PCM) // audioFormat determines whether to process sample bytes as PCM or floating point. { for (var i = 0; i < bytes.Length / 4; i++) { samples.Add(BitConverter.ToInt32(bytes,i * 4) / 2147483648f); } } else { for (var i = 0; i < bytes.Length / 4; i++) { samples.Add(BitConverter.ToSingle(bytes,i * 4)); } } return samples; } 解决方法
读取(和存储)24位样本非常简单.现在,正如你所说的那样,框架中不存在3字节整数类型,这意味着你有两种选择;要么创建自己的类型,要么通过在样本的字节数组的开头插入一个空字节(0)来填充24位样本,从而使它们成为32位样本(这样你就可以使用int来存储/操纵它们).
我将解释并演示如何做到以后(这也是我认为更简单的方法). 首先,我们必须看看如何将24位样本存储在int中,
MSB =最高有效字节,LSB =无效有效字节. 正如您所看到的,24位样本的LSB为0,因此您只需要声明一个包含4个元素的byte [],然后将样本的3个字节读入数组(从元素1开始),这样您的数组如下所示(有效地向左移位8位),
一旦你的字节数组已满,就可以将它传递给 所以,把所有这些放在一起你应该最终得到这样的东西, 注意,我编写了以下代码,意图是“易于遵循”,因此这不是最高效的方法,对于更快的解决方案,请参阅下面的代码. private List<float> Read24BitSamples(FileStream stream,int startIndex,int endIndex) { var samples = new List<float>(); var bytes = ReadChannelBytes(stream,startIndex,endIndex); var temp = new List<byte>(); var paddedBytes = new byte[bytes.Length / 3 * 4]; // Right align our samples to 32-bit (effectively bit shifting 8 places to the left). for (var i = 0; i < bytes.Length; i += 3) { temp.Add(0); // LSB temp.Add(bytes[i]); // 2nd LSB temp.Add(bytes[i + 1]); // 2nd MSB temp.Add(bytes[i + 2]); // MSB } // BitConverter requires collection to be an array. paddedBytes = temp.ToArray(); temp = null; bytes = null; for (var i = 0; i < paddedBytes.Length / 4; i++) { samples.Add(BitConverter.ToInt32(paddedBytes,i * 4) / 2147483648f); // Skip the bit shift and just divide,since our sample has been "shited" 8 places to the right we need to divide by 2147483648,not 8388608. } return samples; } 对于quick1实现,您可以执行以下操作, private List<float> Read24BitSamples(FileStream stream,int endIndex) { var bytes = ReadChannelBytes(stream,endIndex); var samples = new float[bytes.Length / 3]; for (var i = 0; i < bytes.Length; i += 3) { samples[i / 3] = (bytes[i] << 8 | bytes[i + 1] << 16 | bytes[i + 2] << 24) / 2147483648f; } return samples.ToList(); } 1将上述代码与之前的方法进行基准测试后,此解决方案的速度提高了约450%至550%. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- ruby-on-rails – Rails3控制器Plural / Singula
- postgresql – DataGrip Postgres SSL错误:sun.
- c# – 将自定义依赖项属性绑定到自定义WPF样式
- Swift 1.2不使用相同的函数名和不同的参数
- ruby-on-rails – 可以“触摸”在Rails中的belon
- c# – LINQ方法链接和粒度错误处理
- Micro2440 Nand Flash存储操作之写
- 介绍[fleXive] - 一个互补方法的Java EE 5 Web开
- 完美解决ajax跨域请求下parsererror的错误
- 正则表达式小结(Regular Expressions)