使用c程序实现双倍的wav速度



我在c中创建了一个程序,用getchar读取wav文件。

我是这样运行程序的/wavproc<声音.wav

我想把声音的速度提高一倍,并用putchar创建一个新的wav文件。

我必须这样运行程序/wavproc<sound.wav>soundX2.wav

只使用getchar和putchar是必要的,因为这是一个练习。

我把我写的代码放在上

#include <stdio.h>
#include <stdlib.h>
int main(){
unsigned char buffer4[4];
unsigned char buffer2[2];
unsigned int size_of_file;
unsigned int size_of_format_chunck;
unsigned int wave_type_format;
unsigned int mono_stereo;   
unsigned int sample_rate;
unsigned int bytes_per_second;
unsigned int block_alignment;
unsigned int bits_per_sample;
unsigned int size_of_data_chunck;   
char riff[4];
char wave[4];
char fmt[4];
char data[4];
int i;

char c;
while(1) {
c = getchar();
putchar(c);
if(c == EOF)
break;
}   


//read bytes 1-4 to check RIFF
for(i=0;i<4;i++){
riff[i] = getchar();
}
if(riff[0] != 'R') {
fprintf(stderr, "Error! "RIFF" not foundn");
return 1;
} else if(riff[1] != 'I') {
fprintf(stderr, "Error! "RIFF" not foundn");   
return 1;
} else if(riff[2] != 'F') {
fprintf(stderr, "Error! "RIFF" not foundn");   
return 1;
} else if(riff[3] != 'F') {
fprintf(stderr, "Error! "RIFF" not foundn");   
return 1;
}
//read bytes 5-8 for size of file
for(i=0;i<4;i++) {
buffer4[i] = getchar();
}
size_of_file = buffer4[0] | (buffer4[1]<<8) | (buffer4[2]<<16) | (buffer4[3]<<24);
fprintf(stderr, "size of file: %dn",size_of_file);

//read bytes 9-12 to check WAVE 
for(i=0; i<4; i++) {
wave[i] = getchar();
}
if(wave[0] != 'W') {
fprintf(stderr, "Error! "WAVE" not foundn");
return 1;
} else if(wave[1] != 'A') {
fprintf(stderr, "Error! "WAVE" not foundn");
return 1;
} else if(wave[2] != 'V') {
fprintf(stderr, "Error! "WAVE" not foundn");
return 1;
} else if(wave[3] != 'E') {
fprintf(stderr, "Error! "WAVE" not foundn");
return 1;
}
//read bytes 13-16 to check fmt
for(i=0; i<4; i++) {
fmt[i] = getchar();
}
if(fmt[0] != 'f') {
fprintf(stderr, "Error! "fmt " not foundn");
return 1;
} else if(fmt[1] != 'm') {
fprintf(stderr, "Error! "fmt " not foundn");
return 1;
} else if(fmt[2] != 't') {
fprintf(stderr, "Error! "fmt " not foundn");
return 1;
} else if(fmt[3] != ' ') {
fprintf(stderr, "Error! "fmt " not foundn");
return 1;
}
//read bytes 17-20 for size of format chunck
for(i=0; i<4; i++) {
buffer4[i] = getchar();
}
size_of_format_chunck = buffer4[0] | (buffer4[1]<<8) | (buffer4[2]<<16) | (buffer4[3]<<24);
fprintf(stderr, "size of format chunck: %dn",size_of_format_chunck);
if(size_of_format_chunck != 16) {
fprintf(stderr, "Error! size of format chunck should be 16n");
return 1;
}
//read bytes 21-22 for wave type format
for(i=0; i<2; i++) {
buffer2[i] = getchar();
}
wave_type_format = buffer2[0] | (buffer2[1]<<8);
fprintf(stderr, "WAVE type format: %dn",wave_type_format);
if(wave_type_format!=1) {
fprintf(stderr, "Error! WAVE type format should be 1n");
return 1;
}
//read bytes 23-24 for mono stereo
for(i=0; i<2; i++) {
buffer2[i] = getchar();
}
mono_stereo = buffer2[0] | (buffer2[1]<<8);
fprintf(stderr, "mono/stereo: %dn",mono_stereo);
if(mono_stereo!=1 && mono_stereo!=2) {
fprintf(stderr, "Error! mono/stereo should be 1 or 2n");
return 1;
}
//read bytes 25-28 for sample rate
for(i=0; i<4; i++) {
buffer4[i] = getchar();
}
sample_rate = buffer4[0] | (buffer4[1]<<8) | (buffer4[2]<<16) | (buffer4[3]<<24);
fprintf(stderr, "sample rate: %dn",sample_rate);
//read bytes 29-32 for bytes per second
for(i=0; i<4; i++) {
buffer4[i] = getchar();
}
bytes_per_second = buffer4[0] | (buffer4[1]<<8) | (buffer4[2]<<16) | (buffer4[3]<<24);
fprintf(stderr, "bytes/sec: %dn",bytes_per_second);
//read bytes 33-34 for block alignment
for(i=0; i<2; i++) {
buffer2[i] = getchar();
}
block_alignment = buffer2[0] | (buffer2[1]<<8);
fprintf(stderr, "block alignment: %dn",block_alignment);
if(bytes_per_second!=sample_rate*block_alignment) {
fprintf(stderr, "Error! bytes/second should be sample rate x block alignmentn");
return 1;
}
//read bytes 35-36 for bits per sample
for(i=0; i<2; i++) {
buffer2[i] = getchar();
}
bits_per_sample = buffer2[0] | (buffer2[1]<<8);
fprintf(stderr, "bits/sample: %dn",bits_per_sample);
if(bits_per_sample!=8 && bits_per_sample!=16) {
fprintf(stderr, "Error! bits/sample should be 8 or 16n");
return 0;
}
if(block_alignment!=bits_per_sample/8*mono_stereo) {
fprintf(stderr, "Error! block alignment should be bits per sample / 8 x mono/stereon");
return 1;
}
//read bytes 37-40 to check data
for(i=0; i<4; i++) {
data[i] = getchar();
}
if(data[0] != 'd') {
fprintf(stderr, "Error! "data" not foundn");
return 1; 
} else if(data[1] != 'a') {
fprintf(stderr, "Error! "data" not foundn");
return 1; 
} else if(data[2] != 't') {
fprintf(stderr, "Error! "data" not foundn");
return 1; 
} else if(data[3] != 'a') {
fprintf(stderr, "Error! "data" not foundn");
return 1;
}
//read bytes 41-44 for bytes per second
for(i=0; i<4; i++) {
buffer4[i] = getchar();
}
size_of_data_chunck = buffer4[0] | (buffer4[1]<<8) | (buffer4[2]<<16) | (buffer4[3]<<24);
fprintf(stderr, "size of data chunck: %dn",size_of_data_chunck);
//check if file size is correct
i=44;
while(getchar()!=EOF)
i++;
if(i!=size_of_file+8) {
fprintf(stderr,"Error! bad file sizen");
return 1;
}
return 0;
}

问题是如何将声音的速度提高一倍并创建一个新的wav文件?

首先。除非你纯粹是在练习,否则你不应该从头开始写这样的东西。你应该使用图书馆。有一些。

问题是如何将声音的速度提高一倍并创建一个新的wav文件?

实现这一点最简单的方法就是将采样率提高一倍。将其他内容按原样写入新文件,但先将采样率提高一倍,然后以两倍的速度播放。

如果你想尝试一下,那就用一个六进制编辑器,只需编辑采样率字段。

但请注意,这种方法";作品";。为了正确执行此操作,还应该修改"采样速率"字段后面的"字节速率"字段。我跳过了那个部分。

下面是一个很小的例子:

#include <stdio.h>
#include <stdint.h>
int main(void)
{
// Copy everything before sample rate
for(size_t i=0; i<24; i++)
putchar(getchar());
// Read the sample rate
unsigned char b[4];
for(size_t i=0; i<4; i++)
b[i] = getchar();
// Double it
uint32_t sr = b[0] | (b[1]<<8) | (b[2]<<16) | (b[3]<<24);
sr *= 2;
// Write the doubled rate
for(size_t i=0; i<4; i++)
putchar((sr >> i*8) & 0xFF);
// Copy the rest
int ch;
while((ch = getchar()) != EOF)
putchar(ch);
}

请注意,这是非常小的。我完全跳过了任何错误检查。如果采样率太高,那么这将不起作用。

以上是一种非破坏性方法。如果要保持采样率,则需要删除信息。我不知道怎么做,但我想你可以取两个样本的平均值。或者跳过每一个。如果非要我猜测的话,我认为最好的方法是这样做:

new_sample = exp(log(sample1) + log(sample2))

但我没有尝试过。

最新更新