Wave.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. // This file is part of Spectrum Editor Called SECS.
  2. //
  3. // Spectrum Editor Called SECS is free software: you can redistribute it and/or modify
  4. // it under the terms of the GNU General Public License as published by
  5. // the Free Software Foundation, either version 3 of the License, or
  6. // (at your option) any later version.
  7. //
  8. // Spectrum Editor Called SECS is distributed in the hope that it will be useful,
  9. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. // GNU General Public License for more details.
  12. //
  13. // You should have received a copy of the GNU General Public License
  14. // along with Spectrum Editor Called SECS. If not, see <http://www.gnu.org/licenses/>.
  15. struct Wave {
  16. std::vector <unsigned char> header;
  17. std::vector <std::vector <int> > samples;
  18. int number_of_channels, sample_rate, byte_rate, block_align, bits_per_sample, maximum_amplitude;
  19. Wave(std::string file_name) {
  20. FILE* file = fopen(file_name.c_str(), "rb");
  21. // get header
  22. unsigned char header_data[44];
  23. fread(header_data, sizeof(unsigned char), 44, file);
  24. for (int i = 0; i < 44; i++)
  25. header.push_back(header_data[i]);
  26. // parse header
  27. number_of_channels = data_to_int(std::vector <unsigned char> (header.begin() + 22, header.begin() + 23));
  28. sample_rate = data_to_int(std::vector <unsigned char> (header.begin() + 24, header.begin() + 27));
  29. byte_rate = data_to_int(std::vector <unsigned char> (header.begin() + 28, header.begin() + 31));
  30. block_align = data_to_int(std::vector <unsigned char> (header.begin() + 32, header.begin() + 33));
  31. bits_per_sample = data_to_int(std::vector <unsigned char> (header.begin() + 34, header.begin() + 35));
  32. maximum_amplitude = powi(2, bits_per_sample - 1);
  33. int bytes_per_sample = bits_per_sample / 8;
  34. int number_of_samples = data_to_int(std::vector <unsigned char> (header.begin() + 40, header.begin() + 43)) / block_align;
  35. // get samples
  36. for (int i = 0; i < number_of_samples; i++) {
  37. std::vector <int> sample;
  38. for (int j = 0; j < number_of_channels; j++) {
  39. unsigned char channel_data[bytes_per_sample];
  40. fread(channel_data, sizeof(unsigned char), bytes_per_sample, file);
  41. std::vector <unsigned char> channel_vector;
  42. for (int k = 0; k < bytes_per_sample; k++)
  43. channel_vector.push_back(channel_data[k]);
  44. int channel = data_to_int(channel_vector);
  45. if (channel > maximum_amplitude)
  46. channel -= maximum_amplitude * 2;
  47. sample.push_back(channel);
  48. }
  49. samples.push_back(sample);
  50. }
  51. }
  52. int powi(int base, int power) {
  53. if (power == 0) return 1;
  54. if (power == 1) return base;
  55. int half = powi(base, power / 2);
  56. if (power % 2 == 0)
  57. return half * half;
  58. else
  59. return base * half * half;
  60. }
  61. int data_to_int(std::vector <unsigned char> data) {
  62. int integer = 0;
  63. for (int i = 0; i < data.size(); i ++)
  64. integer += data[i] * powi(256, i);
  65. return (int)integer;
  66. }
  67. };