У меня есть программа, которая создает эхо из звукового файла, амплитуды и задержки (в сэмплах) и записывает его в файл. Проблема в том, что в начале и в конце эха слышен щелчок. Я не знаю, как это исправить.
Программа добавляет исходные данные звуковой волны с данными задержанной звуковой волны. Это делается в предположении, что количество каналов всегда равно 2. Левый и правый канал всегда присутствуют. Звуковые файлы, с которыми я тестировал программу, имеют 2 канала. Звуковые файлы всегда являются файлами WAV.
Программа должна запускаться так: ./render_echo {имя входного файла} {имя выходного файла} {задержка в сэмплах} {амплитуда}
Пример: ./render_echo sound1.wav sound2.wav 22050 0,4 Для эха с задержкой в полсекунды, предполагающего частоту дискретизации 44100.
Программа эха:
int check_args(char* inputFile, char* outputFile, int delay, float amplitude){
if (inputFile == NULL){
printf("Error: improper input file name\n");
return 1;
}
if (outputFile == NULL){
printf("Error: improper output file name\n");
return 1;
}
if (delay < 0){
printf("Error: delay cannot be negative\n");
return 1;
}
if (amplitude <= 0.0 || amplitude > 1.0){
printf("Error: amplitude must be between 0 and 1, exclusive.\n");
return 1;
}
return 0;
}
int main(int argc, char** argv){
//Check if the number of arguments equals 5
if (argc != 5){
printf("Error: wrong number of arguments");
return 1;
}
//Make sure arguments are correct
char* inputFileName = argv[1];
char* outputFileName = argv[2];
float amplitude = atof(argv[4]);
if (check_args(inputFileName, outputFileName, atof(argv[3]), amplitude) == 1){
return 1;
}
//Delay is expressed in number of samples
unsigned monodelay = atof(argv[3]);
unsigned delay = monodelay*2;
//printf("amp %f\n", amplitude);
FILE *inputFile = fopen(inputFileName, "rb");
if (inputFile == NULL){
printf("Error: couldn't read file\n");
return 1;
}
//Read wave header
unsigned num_samples_input_monochannel;
read_wave_header(inputFile, &num_samples_input_monochannel);
unsigned num_samples_input = 2*num_samples_input_monochannel;
//printf("Mono %u Dual %u\n", num_samples_input_monochannel, num_samples_input);
//Read wave data
int16_t input_wave[num_samples_input];
read_s16_buf(inputFile, input_wave, num_samples_input);
//New output file info
unsigned num_samples_output_monochannel = num_samples_input_monochannel + monodelay;
unsigned num_samples_output = num_samples_output_monochannel*2;
int16_t output_wave[num_samples_output];
memset(output_wave, 0, num_samples_output);
//New waves
int16_t input_wave_dual[2][num_samples_output_monochannel];
memset(input_wave_dual[0], 0, num_samples_output_monochannel);
memset(input_wave_dual[1], 0, num_samples_output_monochannel);
//Fill input_wave_dual
for (int i=0; i<num_samples_input_monochannel; i++){
input_wave_dual[0][i] = input_wave[i*2]; //left channel
input_wave_dual[1][i] = input_wave[i*2 + 1]; //right channel
}
//Time delayed wave
int16_t delayed_wave_dual[2][num_samples_output_monochannel];
memset(delayed_wave_dual[0], 0, num_samples_output_monochannel);
memset(delayed_wave_dual[1], 0, num_samples_output_monochannel);
//Fill time delayed wave
for (int j=0; j<num_samples_output_monochannel;j++){
delayed_wave_dual[0][monodelay+j-1] = input_wave_dual[0][j]*amplitude;
delayed_wave_dual[1][monodelay+j-1] = input_wave_dual[1][j]*amplitude;
}
//Add the two waves
for (int k=0; k<num_samples_output_monochannel; k++){
for (int l=0; l<2;l++){
//Temp input amplitude
int temp_i_a = input_wave_dual[l][k];
//Temp delay amplitude
int temp_d_a = delayed_wave_dual[l][k];
//Temp sum
int temp_sum = temp_i_a + temp_d_a;
if (temp_sum > INT16_MAX){
temp_sum = INT16_MAX;
} else if (temp_sum < INT16_MIN){
temp_sum = INT16_MIN;
}
output_wave[k*2 +l] = temp_sum;
}
}
//WRITE TO FILE
FILE *outputFile = fopen(outputFileName, "wb+");
if (outputFile == NULL){
printf("Error: could not write file");
return 1;
}
write_wave_header(outputFile, num_samples_output_monochannel);
write_s16_buf(outputFile, output_wave, num_samples_output);
fclose(outputFile);
fclose(inputFile);
printf("Finished\n");
}