gpt4 book ai didi

c++ - 将回声效果添加到 .wav 文件

转载 作者:行者123 更新时间:2023-12-03 02:30:56 25 4
gpt4 key购买 nike

我用 C++(示例代码)编写了以下代码来修改原始 .wav 文件中存在的数据并将修改后的数据写入新创建的文件。该程序为声音提供“回声效果”(注意:- 这是为只有 2 个 channel 的 wav 文件编写的)。

#include <iostream>
#include <conio.h>
#include <fstream>
#ifndef endl
#define endl "\n"
#endif

#define wav_eco(filin, fileout, eco_rate) \
char temp[2]; \
char ch[eco_rate][2], ch2[eco_rate][2]; \
int i,j; \
for(i=0; i<eco_rate; i++) \
for(j=0; j<2; j++) \
ch2[i][j] = 0; \
while(!filin.eof()) \
{ \
for(i=0; i<eco_rate && !filin.eof(); i++) \
filin.read((char*)&ch[i], sizeof(char[2])); \
for(i=0; i<eco_rate; i++) \
{ \
temp[0] = ch[i][0]; \
temp[1] = ch[i][1]; \
ch[i][0]+=ch2[i][0]; \
ch[i][1]+=ch2[i][1]; \
fileout.write((char*)&ch[i], sizeof(char[2])); \
ch2[i][0] = temp[0]; \
ch2[i][1] = temp[1]; \
} \
}

using namespace std;
struct WAVEFILEHEADER
{
char ChunkId[4];
int ChunkSize;
char Format[4];
char SubChunkFmt[4];
int SubChunkFmtSize;
short int AudioFormat;
short int NumChannels;

int SampleRate;
int ByteRate;
short int BlockAlign;
short int BitsPerSample;

char ChunkData[4];
int SubChunkDataSize;
};

int main()
{
fstream filin("C:\\Users\\chess.Admin-PC.000\\Music\\ExampleRead.wav", ios::in|ios::binary);
fstream fileout("C:\\Users\\chess.Admin-PC.000\\Music\\ExampleWrite.wav",ios::out| ios::binary);
WAVEFILEHEADER wav;
filin.read((char*)&wav,sizeof(wav));
//to display the contents of the header
cout<<wav.ByteRate
<<endl<<wav.ChunkSize
<<endl<<wav.SampleRate// no of samples per second
<<endl<<wav.SubChunkDataSize
<<endl<<wav.SubChunkFmtSize
<<endl<<wav.ChunkData
<<endl<<wav.ChunkId
<<endl<<wav.Format
<<endl<<wav.SubChunkFmt
<<endl<<wav.AudioFormat
<<endl<<wav.AudioFormat
<<endl<<wav.BitsPerSample//no of bits per second
<<endl<<wav.BlockAlign
<<endl<<wav.NumChannels
<<endl<<endl<<sizeof(wav); /* size of the wav variable*/
getch();
fileout.write((char*)&wav, sizeof(wav));/// write the header to output file
wav_eco(filin,fileout,10000) ///modify the data and update the output file
filin.close();
fileout.close();
return 0;
}

/*algorithm implemented by the wav_eco function(this is not some stranded algorithm. I wrote it myself) :-
1) obtain the 'echo_rate' of the samples
2) read the data present in the original wav file
3) write this data, by adding each sample from the previously obtained data to the data that was read now
4) follow steps 2 and 3 until eof is reached
*/

该程序运行良好,当我使用 windows 媒体播放器播放输出文件时,我得到了回声效果,但另外我得到了“嘶嘶”的声音。是什么原因造成的,我必须以什么方式修改上面的代码来避免它?是否可以简化 wav_eco()宏以减少程序的计算时间?

我对嘶嘶声的猜测是因为添加了 ch[i][0] += ch2[i][0]; ch[i][1]+=ch2[i][1]; .它是否以错误的方式修改声音? (这是我第一次编辑声音)

最佳答案

此 .wav 文件有多种格式,格式列表为 here .只有知道格式(无论是 8 位还是 16 位),才能回答上述问题。要调试问题中给出的代码,我们不需要 bit_rate 所以我们不需要知道格式是否为 PCM 等。因此,如果文件是 16 位,那么 wav_echo() 的以下代码可以使用:

#define  wav_echo2_16(filin, fileout, eco_rate)                     \
short int temp; \
short int ch[eco_rate], ch2[eco_rate]; \
int i,j; \
for(i=0; i<eco_rate; i++) \
ch2[i] = 0; \
while(!filin.eof()) \
{ \
for(i=0; i<eco_rate && !filin.eof(); i++) \
filin.read((char*)&ch[i], sizeof(short int)); \
for(i=0; i<eco_rate; i++) \
{ \
temp = ch[i]; \
ch[i]+=ch2[i]; \
fileout.write((char*)&ch[i], sizeof(short int));\
ch2[i] = temp; \
} \
\
}

上述宏 wav_echo2_16()为 16 位文件提供回声效果(注意 echo_rate 常数应该是偶数,因为有 2 个 channel )。
下面显示了 8 位格式的代码:
#define  wav_echo2_8(filin, fileout, eco_rate)\
char temp;\
char ch[eco_rate], ch2[eco_rate];\
int i,j;\
for(i=0; i<eco_rate; i++)\
ch2[i] = 0;\
while(!filin.eof())\
{\
for(i=0; i<eco_rate && !filin.eof(); i++)\
filin.read((char*)&ch[i], sizeof(char));\
for(i=0; i<eco_rate; i++)\
{\
temp = ch[i];\
ch[i]+=ch2[i];\
fileout.write((char*)&ch[i], sizeof(char));\
ch2[i] = temp;\
}\
\
}

并且将 8 位宏用于 16 位格式会导致嘶嘶声!

关于c++ - 将回声效果添加到 .wav 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23745811/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com