我创建了一个程序来分析插入输入中的 file.wav。我想知道是否可以从原始 file.wav 中删除时间间隔。我会剪掉一部分在一定时间内对分析不必要的声音。消除这些部分声音后,我会得到一个新的连续声音,它将所有未消除的声音合并在一起。这是可能的?你能帮助我吗?
1 回答
一旦你读入了你的 WAV 格式文件,解析了标题,并将音频曲线数据点存放到一些数据结构中,你有两个选择。
就地更新(实施起来更棘手)
将好的数据点复制到新的数据结构中(让我们这样做)
WAV 格式的一个很好的方面是它的 PCM,这意味着音频曲线表示为该曲线上的离散点。确保您已确定标题中可用的位深度。典型的位深度为 16 位,这意味着每个样本将消耗内存缓冲区中的两个字节数据。打印出 100 个左右的样本值,以确认您手头有正确格式的样本。如果是 16 位,则可能值的范围将映射到 2^16 个不同的整数值。检查这些样本值时,您是否已签名或未签名很重要。
作为垫脚石,我首先会得到一些代码,它只是读取 WAV 文件并将每个字节复制到输出文件中。确认您可以播放这个新的输出 WAV 文件。接下来编写类似的代码,除了这次解析标头,识别采样率字段,将其值从 44100 更新为 22050,输出带有此更新的标头,然后是出现在 WAV 文件中标头之后的音频数据字节。播放这个 WAV 文件,它是加快还是减慢了音轨?
当您打开输入 WAV 文件并读取每个字节时,在标头字节之后,可以获得将两个字节组合成一个 16 位整数变量的工作能力(如果您的标头说您有 16 位样本)。每个音频样本将消耗多个字节(8 位音频听起来很可怕)。因此,如果您有 24 位音频,当然给定通道中的每个音频样本将跨越文件的三个字节。注意大端和小端的概念(你的两个字节是从左到右还是从右到左出现)。为简单起见,首先使用单声道输入 WAV 文件。立体声(2 通道)或 X 通道可以采用 WAV 格式,但单声道更容易。
假设我们有 10 个样本(每个样本都是 16 位整数)
- 0 - 3 好
- 4 - 7 坏(我们将丢弃这些)
- 8 - 9 好
所以输出文件将包含忽略坏样本 4 - 7 后剩下的内容,因此它只有 6 个样本。
遍历所有样本 -> 确定当前样本是否良好 -> 仅将好的样本复制到输出数据结构中
int out_index = 0;
int bit_depth = 16; // get this 16 from header, could be 24 for example
// how many bytes in bit depth, 2 if 16 bit, 3 if 24 bit
int incr_index = bit_depth / 8;
for (int in_index = 0; in_index < size; in_index += incr_index) {
if (is_sample_good(in_index)) { // is this sample good or bad
output_data[out_index] = input_data[in_index];
output_data[out_index + 1] = input_data[in_index + 1];
out_index += incr_index;
}
}
请注意,在这段代码中,输入和输出数据结构都有自己的索引......很重要,因为我们只在好的样本上推进输出索引
WAV 格式的文件头总是 WAV 文件的前 X 个字节(如果我没记错的话是 32 个字节)。在此标头中是总数据大小的指标。跟踪好样本的数量,这些样本将驱动这个数据长度标题标签的值,您将把它放入输出 WAV 文件的标题部分。遍历输入文件并生成输出数据结构(内存缓冲区)后,打开新的输出文件,将新标头与长度标签的更新值写入此文件,然后写入新的内存缓冲区,关闭文件并玩。
这是一些WAV格式的链接
http://unusedino.de/ec64/technical/formats/wav.html
https://www.gamedev.net/resources/_/technical/game-programming/loading-a-wave-file-r709
http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html
http://www.topherlee.com/software/pcm-tut-wavformat.html
http://www.labbookpages.co.uk/audio/javaWavFiles.html
http://www.drdobbs.com/database/inside-the-riff-specification/184409308