我创建了一个程序来分析输入中插入的file.wav。我想知道我是否可以从原始file.wav中删除时间间隔。 我会在一定时间内剪掉一部分不必进行分析的声音。在消除了声音的这些部分之后,我会得到一种新的连续声音,将声音未被消除的各方合并在一起。 它有可能吗? 你能救我吗?
答案 0 :(得分:1)
一旦读入WAV格式文件,解析标题,并将音频曲线数据点停放到某个数据结构中,您就有两种选择。
到位更新(更难实施)
将好的数据点复制到新的数据结构中(让我们这样做)
WAV格式的好处是它的PCM,这意味着音频曲线表示为该曲线上的离散点。确保您已识别标题中可用的位深度。典型的位深度为16位,这意味着每个样本将占用内存缓冲区中的两个字节的数据。打印出100个左右的样本值,以确认您手边有正确格式的样本。如果是16位,那么可能值的范围将映射到2 ^ 16个不同的整数值。检查这些样本值时,无论是有符号还是无符号都很重要。
作为踏脚石,我首先会得到一些代码,只需读取WAV文件并将每个字节复制到输出文件中。确认您可以播放这个新的输出WAV文件。接下来写相似的代码,除了这次解析标题,识别采样率字段,将其值从44100更新到22050,输出带有此更新的标题,然后输出出现在标题之后的WAV文件中的音频数据字节。播放这个WAV文件,它是加速还是减慢音轨?
当您打开输入WAV文件并读取每个字节后,在头字节之后,获得将两个字节组合成一个16位整数变量的工作能力(如果您的标题表示您有16位样本)。每个音频样本将消耗多个字节(8位音频声音可怕)。因此,如果您有24位音频,那么给定通道中的每个音频样本将跨越您文件的三个字节。注意大端和小端的概念(你的两个字节是从左到右,从右到左)。为简单起见,首先要使用单声道输入WAV文件。 WAV格式可以使用立体声(2声道)或X声道,但单声道更容易。
假设我们有10个样本(每个16位整数)
因此,输出文件将包含忽略不良样本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