用c程序实现双波速度
Double wav speed with c program
我已经在 c 中创建了一个程序,它使用 getchar 读取 wav 文件。
我运行程序是这样的./wavproc
我想将声音的速度加倍并用 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 found\n");
return 1;
} else if(riff[1] != 'I') {
fprintf(stderr, "Error! \"RIFF\" not found\n");
return 1;
} else if(riff[2] != 'F') {
fprintf(stderr, "Error! \"RIFF\" not found\n");
return 1;
} else if(riff[3] != 'F') {
fprintf(stderr, "Error! \"RIFF\" not found\n");
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: %d\n",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 found\n");
return 1;
} else if(wave[1] != 'A') {
fprintf(stderr, "Error! \"WAVE\" not found\n");
return 1;
} else if(wave[2] != 'V') {
fprintf(stderr, "Error! \"WAVE\" not found\n");
return 1;
} else if(wave[3] != 'E') {
fprintf(stderr, "Error! \"WAVE\" not found\n");
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 found\n");
return 1;
} else if(fmt[1] != 'm') {
fprintf(stderr, "Error! \"fmt \" not found\n");
return 1;
} else if(fmt[2] != 't') {
fprintf(stderr, "Error! \"fmt \" not found\n");
return 1;
} else if(fmt[3] != ' ') {
fprintf(stderr, "Error! \"fmt \" not found\n");
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: %d\n",size_of_format_chunck);
if(size_of_format_chunck != 16) {
fprintf(stderr, "Error! size of format chunck should be 16\n");
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: %d\n",wave_type_format);
if(wave_type_format!=1) {
fprintf(stderr, "Error! WAVE type format should be 1\n");
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: %d\n",mono_stereo);
if(mono_stereo!=1 && mono_stereo!=2) {
fprintf(stderr, "Error! mono/stereo should be 1 or 2\n");
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: %d\n",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: %d\n",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: %d\n",block_alignment);
if(bytes_per_second!=sample_rate*block_alignment) {
fprintf(stderr, "Error! bytes/second should be sample rate x block alignment\n");
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: %d\n",bits_per_sample);
if(bits_per_sample!=8 && bits_per_sample!=16) {
fprintf(stderr, "Error! bits/sample should be 8 or 16\n");
return 0;
}
if(block_alignment!=bits_per_sample/8*mono_stereo) {
fprintf(stderr, "Error! block alignment should be bits per sample / 8 x mono/stereo\n");
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 found\n");
return 1;
} else if(data[1] != 'a') {
fprintf(stderr, "Error! \"data\" not found\n");
return 1;
} else if(data[2] != 't') {
fprintf(stderr, "Error! \"data\" not found\n");
return 1;
} else if(data[3] != 'a') {
fprintf(stderr, "Error! \"data\" not found\n");
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: %d\n",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 size\n");
return 1;
}
return 0;
}
问题是如何将声音的速度加倍并创建一个新的 wav 文件?
首先。除非您将此作为纯粹的练习,否则您不应该从头开始编写此类内容。你应该使用图书馆。那里有一些。
The question is how to double sound's speed and create a new wav file?
实现这一点的绝对最简单的方法就是简单地将采样率加倍。将其他所有内容都写入一个新文件,但首先将采样率加倍,然后将以双倍速度播放。
如果您想尝试一下,请获取一个 hexeditor,然后只需编辑采样率字段即可。
但请注意,这种方法“有效”。为了正确地做到这一点,您还应该修改 ByteRate 字段,它紧跟在 SampleRate 字段之后。我跳过了那部分。
这是一个非常小的例子,可以完成这项工作:
#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))
不过我没试过
我已经在 c 中创建了一个程序,它使用 getchar 读取 wav 文件。
我运行程序是这样的./wavproc 我想将声音的速度加倍并用 putchar 创建一个新的 wav 文件。 我必须 运行 这样的程序 ./wavproc < sound.wav > soundX2.wav 因为是练习,所以必须只使用getchar和putchar。 我把我写的代码放上去 问题是如何将声音的速度加倍并创建一个新的 wav 文件?#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 found\n");
return 1;
} else if(riff[1] != 'I') {
fprintf(stderr, "Error! \"RIFF\" not found\n");
return 1;
} else if(riff[2] != 'F') {
fprintf(stderr, "Error! \"RIFF\" not found\n");
return 1;
} else if(riff[3] != 'F') {
fprintf(stderr, "Error! \"RIFF\" not found\n");
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: %d\n",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 found\n");
return 1;
} else if(wave[1] != 'A') {
fprintf(stderr, "Error! \"WAVE\" not found\n");
return 1;
} else if(wave[2] != 'V') {
fprintf(stderr, "Error! \"WAVE\" not found\n");
return 1;
} else if(wave[3] != 'E') {
fprintf(stderr, "Error! \"WAVE\" not found\n");
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 found\n");
return 1;
} else if(fmt[1] != 'm') {
fprintf(stderr, "Error! \"fmt \" not found\n");
return 1;
} else if(fmt[2] != 't') {
fprintf(stderr, "Error! \"fmt \" not found\n");
return 1;
} else if(fmt[3] != ' ') {
fprintf(stderr, "Error! \"fmt \" not found\n");
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: %d\n",size_of_format_chunck);
if(size_of_format_chunck != 16) {
fprintf(stderr, "Error! size of format chunck should be 16\n");
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: %d\n",wave_type_format);
if(wave_type_format!=1) {
fprintf(stderr, "Error! WAVE type format should be 1\n");
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: %d\n",mono_stereo);
if(mono_stereo!=1 && mono_stereo!=2) {
fprintf(stderr, "Error! mono/stereo should be 1 or 2\n");
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: %d\n",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: %d\n",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: %d\n",block_alignment);
if(bytes_per_second!=sample_rate*block_alignment) {
fprintf(stderr, "Error! bytes/second should be sample rate x block alignment\n");
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: %d\n",bits_per_sample);
if(bits_per_sample!=8 && bits_per_sample!=16) {
fprintf(stderr, "Error! bits/sample should be 8 or 16\n");
return 0;
}
if(block_alignment!=bits_per_sample/8*mono_stereo) {
fprintf(stderr, "Error! block alignment should be bits per sample / 8 x mono/stereo\n");
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 found\n");
return 1;
} else if(data[1] != 'a') {
fprintf(stderr, "Error! \"data\" not found\n");
return 1;
} else if(data[2] != 't') {
fprintf(stderr, "Error! \"data\" not found\n");
return 1;
} else if(data[3] != 'a') {
fprintf(stderr, "Error! \"data\" not found\n");
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: %d\n",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 size\n");
return 1;
}
return 0;
}
首先。除非您将此作为纯粹的练习,否则您不应该从头开始编写此类内容。你应该使用图书馆。那里有一些。
The question is how to double sound's speed and create a new wav file?
实现这一点的绝对最简单的方法就是简单地将采样率加倍。将其他所有内容都写入一个新文件,但首先将采样率加倍,然后将以双倍速度播放。
如果您想尝试一下,请获取一个 hexeditor,然后只需编辑采样率字段即可。
但请注意,这种方法“有效”。为了正确地做到这一点,您还应该修改 ByteRate 字段,它紧跟在 SampleRate 字段之后。我跳过了那部分。
这是一个非常小的例子,可以完成这项工作:
#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))
不过我没试过