Почему в начале и в конце звуков, воспроизводимых моей эхо-программой, слышен щелчок? - PullRequest
1 голос
/ 16 октября 2019

У меня есть программа, которая создает эхо из звукового файла, амплитуды и задержки (в сэмплах) и записывает его в файл. Проблема в том, что в начале и в конце эха слышен щелчок. Я не знаю, как это исправить.

Программа добавляет исходные данные звуковой волны с данными задержанной звуковой волны. Это делается в предположении, что количество каналов всегда равно 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");

}
...