123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- // This file is part of Spectrum Editor Called SECS.
- //
- // Spectrum Editor Called SECS is free software: you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- //
- // Spectrum Editor Called SECS is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License
- // along with Spectrum Editor Called SECS. If not, see <http://www.gnu.org/licenses/>.
- struct Wave {
- std::vector <unsigned char> header;
- std::vector <std::vector <int> > samples;
- int number_of_channels, sample_rate, byte_rate, block_align, bits_per_sample, maximum_amplitude;
- Wave(std::string file_name) {
- FILE* file = fopen(file_name.c_str(), "rb");
- // get header
- unsigned char header_data[44];
- fread(header_data, sizeof(unsigned char), 44, file);
- for (int i = 0; i < 44; i++)
- header.push_back(header_data[i]);
- // parse header
- number_of_channels = data_to_int(std::vector <unsigned char> (header.begin() + 22, header.begin() + 23));
- sample_rate = data_to_int(std::vector <unsigned char> (header.begin() + 24, header.begin() + 27));
- byte_rate = data_to_int(std::vector <unsigned char> (header.begin() + 28, header.begin() + 31));
- block_align = data_to_int(std::vector <unsigned char> (header.begin() + 32, header.begin() + 33));
- bits_per_sample = data_to_int(std::vector <unsigned char> (header.begin() + 34, header.begin() + 35));
- maximum_amplitude = powi(2, bits_per_sample - 1);
- int bytes_per_sample = bits_per_sample / 8;
- int number_of_samples = data_to_int(std::vector <unsigned char> (header.begin() + 40, header.begin() + 43)) / block_align;
- // get samples
- for (int i = 0; i < number_of_samples; i++) {
- std::vector <int> sample;
- for (int j = 0; j < number_of_channels; j++) {
- unsigned char channel_data[bytes_per_sample];
- fread(channel_data, sizeof(unsigned char), bytes_per_sample, file);
- std::vector <unsigned char> channel_vector;
- for (int k = 0; k < bytes_per_sample; k++)
- channel_vector.push_back(channel_data[k]);
- int channel = data_to_int(channel_vector);
- if (channel > maximum_amplitude)
- channel -= maximum_amplitude * 2;
- sample.push_back(channel);
- }
- samples.push_back(sample);
- }
- }
- int powi(int base, int power) {
- if (power == 0) return 1;
- if (power == 1) return base;
- int half = powi(base, power / 2);
- if (power % 2 == 0)
- return half * half;
- else
- return base * half * half;
- }
- int data_to_int(std::vector <unsigned char> data) {
- int integer = 0;
- for (int i = 0; i < data.size(); i ++)
- integer += data[i] * powi(256, i);
- return (int)integer;
- }
- };
|