fm_transmitter/wave_reader.cpp

118 wiersze
3.1 KiB
C++
Czysty Zwykły widok Historia

2015-04-01 12:48:43 +00:00
#include "wave_reader.h"
#include <string.h>
#include <exception>
#include <iostream>
#include <fstream>
2015-04-04 14:04:08 +00:00
#include <math.h>
2015-04-01 12:48:43 +00:00
WaveReader::WaveReader(std::string filename)
{
std::vector<char> buffer;
unsigned int length;
int error;
std::ifstream is(filename.c_str(), std::ifstream::binary);
if (!is) {
2015-04-01 13:00:15 +00:00
std::cout << "Error: cannot open '" << filename << "', file does not exist" << std::endl;
2015-04-01 12:48:43 +00:00
throw std::exception();
}
is.seekg(0, is.end);
length = is.tellg();
is.seekg(0, is.beg);
if (length < sizeof(PCMWaveHeader)) {
2015-04-01 13:00:15 +00:00
std::cout << "Error: data corrupted" << std::endl;
2015-04-01 12:48:43 +00:00
throw std::exception();
}
buffer.resize(length);
is.read(&buffer[0], length);
is.close();
memcpy(&header, &buffer[0], sizeof(PCMWaveHeader));
if ((error = checkDataFormat(&header)) > 0) {
2015-04-01 13:00:15 +00:00
std::cout << "Error: unsupported data format (" << error << ")" << std::endl;
2015-04-01 12:48:43 +00:00
throw std::exception();
}
if (length < sizeof(PCMWaveHeader) + header.subchunk2Size) {
2015-04-01 13:00:15 +00:00
std::cout << "Error: data corrupted" << std::endl;
2015-04-01 12:48:43 +00:00
throw std::exception();
}
data.resize(header.subchunk2Size);
memcpy(&data[0], &buffer[sizeof(PCMWaveHeader)], header.subchunk2Size);
}
WaveReader::~WaveReader()
{
}
int WaveReader::checkDataFormat(PCMWaveHeader *header)
{
int error = 0;
if (std::string(header->chunkID, 4) != std::string("RIFF")) {
error |= 0x01;
}
if (std::string(header->format, 4) != std::string("WAVE")) {
error |= (0x01 << 1);
}
if (std::string(header->subchunk1ID, 4) != std::string("fmt ")) {
error |= (0x01 << 2);
}
if (header->subchunk1Size != 16) {
error |= (0x01 << 3);
}
if (header->audioFormat != WAVE_FORMAT_PCM) {
error |= (0x01 << 4);
}
if (header->byteRate != (header->bitsPerSample >> 3) * header->channels * header->sampleRate) {
error |= (0x01 << 5);
}
if (header->blockAlign != (header->bitsPerSample >> 3) * header->channels) {
error |= (0x01 << 6);
}
if (((header->bitsPerSample >> 3) != 1) && ((header->bitsPerSample >> 3) != 2)) {
error |= (0x01 << 7);
}
2015-04-04 14:04:08 +00:00
if (std::string(header->subchunk2ID, 4) != std::string("data")) {
2015-04-01 12:48:43 +00:00
error |= (0x01 << 8);
2015-04-04 14:04:08 +00:00
}
2015-04-01 12:48:43 +00:00
return error;
}
2015-04-04 14:04:08 +00:00
std::vector<float> *WaveReader::getSamples()
2015-04-01 12:48:43 +00:00
{
2015-04-04 14:04:08 +00:00
std::vector<float> *samples = new std::vector<float>();
2015-04-01 12:48:43 +00:00
unsigned char frameSize = header.channels * (header.bitsPerSample >> 3);
2015-04-01 21:12:41 +00:00
unsigned int framesCount = header.subchunk2Size / frameSize;
2015-04-04 14:04:08 +00:00
unsigned int frameOffset = 0, dataOffset;
2015-04-01 12:48:43 +00:00
while (frameOffset < framesCount) {
dataOffset = frameOffset * frameSize;
if (header.channels != 1) {
2015-06-26 20:31:24 +00:00
// TODO: Stereo to mono conversion
2015-04-01 12:48:43 +00:00
} else {
if (header.bitsPerSample != 8) {
2015-04-04 14:04:08 +00:00
samples->push_back((signed char)data[dataOffset + 1] / (float)0x80);
2015-04-01 12:48:43 +00:00
} else {
2015-04-04 14:04:08 +00:00
samples->push_back(data[dataOffset] / (float)0x80 - 1.0f);
2015-04-01 12:48:43 +00:00
}
}
frameOffset++;
}
2015-04-04 14:04:08 +00:00
return samples;
2015-04-01 12:48:43 +00:00
}
PCMWaveHeader *WaveReader::getHeader()
{
return &header;
}