From 52267359a0492732b7943a1f66fc179a6840e7b8 Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Tue, 6 Dec 2016 03:24:52 +0000 Subject: [PATCH 01/34] Code refactor and optimalizations --- transmitter.cpp | 50 +++++++++++++++++++++---------------------------- transmitter.h | 2 +- 2 files changed, 22 insertions(+), 30 deletions(-) diff --git a/transmitter.cpp b/transmitter.cpp index c67ac21..38c53df 100644 --- a/transmitter.cpp +++ b/transmitter.cpp @@ -44,6 +44,8 @@ using std::ostringstream; #define GPIO_BASE 0x00200000 #define CLK0_BASE 0x00101070 + + #define CLK0DIV_BASE 0x00101074 #define TCNT_BASE 0x00003004 @@ -53,6 +55,7 @@ using std::ostringstream; #define ACCESS64(base, offset) *(volatile unsigned long long*)((int)base + offset) bool Transmitter::isTransmitting = false; +bool Transmitter::isRestart = false; unsigned Transmitter::clockDivisor = 0; unsigned Transmitter::frameOffset = 0; vector* Transmitter::buffer = NULL; @@ -124,12 +127,16 @@ void Transmitter::play(string filename, double frequency, bool loop) } clockDivisor = (unsigned)((500 << 12) / frequency + 0.5); + unsigned bufferFrames = (unsigned)((unsigned long long)format->sampleRate * BUFFER_TIME / 1000000); + + ACCESS(peripherals, GPIO_BASE) = (ACCESS(peripherals, GPIO_BASE) & 0xFFFF8FFF) | (0x01 << 14); + ACCESS(peripherals, CLK0_BASE) = (0x5A << 24) | (0x01 << 9) | (0x01 << 4) | 0x06; + frameOffset = 0; isTransmitting = true; + isRestart = false; doStop = false; - unsigned bufferFrames = (unsigned)((unsigned long long)format->sampleRate * BUFFER_TIME / 1000000); - buffer = (!readStdin) ? file->getFrames(bufferFrames, 0) : stdin->getFrames(bufferFrames, doStop); pthread_t thread; @@ -148,8 +155,7 @@ void Transmitter::play(string filename, double frequency, bool loop) usleep(BUFFER_TIME / 2); - bool doPlay = true; - while (doPlay && !doStop) { + while (!doStop) { while ((readStdin || !file->isEnd(frameOffset + bufferFrames)) && !doStop) { if (buffer == NULL) { buffer = (!readStdin) ? file->getFrames(bufferFrames, frameOffset + bufferFrames) : stdin->getFrames(bufferFrames, doStop); @@ -157,26 +163,12 @@ void Transmitter::play(string filename, double frequency, bool loop) usleep(BUFFER_TIME / 2); } if (loop && !readStdin && !doStop) { - isTransmitting = false; - + frameOffset = 0; + isRestart = true; buffer = file->getFrames(bufferFrames, 0); - - pthread_join(thread, NULL); - - isTransmitting = true; - - returnCode = pthread_create(&thread, NULL, &Transmitter::transmit, params); - if (returnCode) { - if (!readStdin) { - delete file; - } - delete format; - ostringstream oss; - oss << "Cannot create new thread (code: " << returnCode << ")"; - throw ErrorReporter(oss.str()); - } + usleep(BUFFER_TIME / 2); } else { - doPlay = false; + doStop = true; } } isTransmitting = false; @@ -206,15 +198,11 @@ void* Transmitter::transmit(void* params) float preemp = 0.75 - 250000.0 / (float)(sampleRate * 75); #endif - ACCESS(peripherals, GPIO_BASE) = (ACCESS(peripherals, GPIO_BASE) & 0xFFFF8FFF) | (0x01 << 14); - ACCESS(peripherals, CLK0_BASE) = (0x5A << 24) | (0x01 << 9) | (0x01 << 4) | 0x06; - - frameOffset = 0; playbackStart = ACCESS64(peripherals, TCNT_BASE); current = playbackStart; - start = playbackStart; while (isTransmitting) { + start = current; while ((buffer == NULL) && isTransmitting) { usleep(1); current = ACCESS64(peripherals, TCNT_BASE); @@ -222,9 +210,14 @@ void* Transmitter::transmit(void* params) if (!isTransmitting) { break; } + if (isRestart) { + playbackStart = current; + start = current; + isRestart = false; + } frames = buffer; frameOffset = (current - playbackStart) * (sampleRate) / 1000000; - buffer = NULL; + buffer = NULL; length = frames->size(); data = &(*frames)[0]; @@ -256,7 +249,6 @@ void* Transmitter::transmit(void* params) #endif } - start = ACCESS64(peripherals, TCNT_BASE); delete frames; } diff --git a/transmitter.h b/transmitter.h index 607b990..6db2eac 100644 --- a/transmitter.h +++ b/transmitter.h @@ -61,8 +61,8 @@ class Transmitter static void* peripherals; static vector* buffer; + static bool isTransmitting, isRestart; static unsigned frameOffset, clockDivisor; - static bool isTransmitting; static void* transmit(void* params); }; From 323e24090fb4920e701b6ea5467bb9c9c64b1e34 Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Tue, 6 Dec 2016 03:29:47 +0000 Subject: [PATCH 02/34] Reverted some unnecessary changes --- transmitter.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/transmitter.cpp b/transmitter.cpp index 38c53df..23a6c8a 100644 --- a/transmitter.cpp +++ b/transmitter.cpp @@ -44,8 +44,6 @@ using std::ostringstream; #define GPIO_BASE 0x00200000 #define CLK0_BASE 0x00101070 - - #define CLK0DIV_BASE 0x00101074 #define TCNT_BASE 0x00003004 @@ -129,9 +127,6 @@ void Transmitter::play(string filename, double frequency, bool loop) clockDivisor = (unsigned)((500 << 12) / frequency + 0.5); unsigned bufferFrames = (unsigned)((unsigned long long)format->sampleRate * BUFFER_TIME / 1000000); - ACCESS(peripherals, GPIO_BASE) = (ACCESS(peripherals, GPIO_BASE) & 0xFFFF8FFF) | (0x01 << 14); - ACCESS(peripherals, CLK0_BASE) = (0x5A << 24) | (0x01 << 9) | (0x01 << 4) | 0x06; - frameOffset = 0; isTransmitting = true; isRestart = false; @@ -198,6 +193,9 @@ void* Transmitter::transmit(void* params) float preemp = 0.75 - 250000.0 / (float)(sampleRate * 75); #endif + ACCESS(peripherals, GPIO_BASE) = (ACCESS(peripherals, GPIO_BASE) & 0xFFFF8FFF) | (0x01 << 14); + ACCESS(peripherals, CLK0_BASE) = (0x5A << 24) | (0x01 << 9) | (0x01 << 4) | 0x06; + playbackStart = ACCESS64(peripherals, TCNT_BASE); current = playbackStart; @@ -217,7 +215,7 @@ void* Transmitter::transmit(void* params) } frames = buffer; frameOffset = (current - playbackStart) * (sampleRate) / 1000000; - buffer = NULL; + buffer = NULL; length = frames->size(); data = &(*frames)[0]; From a4594ed48c989e85e2dfe5e2d436ce82d0136a6a Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Tue, 6 Dec 2016 17:07:30 +0100 Subject: [PATCH 03/34] Universal reader for stdin and WAVE files --- wave_reader.cpp | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/wave_reader.cpp b/wave_reader.cpp index a59483a..a6d0600 100644 --- a/wave_reader.cpp +++ b/wave_reader.cpp @@ -39,8 +39,8 @@ using std::ostringstream; using std::exception; -WaveReader::WaveReader(string filename) : - filename(filename) +WaveReader::WaveReader(string filename, bool &forceStop) : + filename(filename), inputReady(false), fileSize(0) { char* headerData; vector* data; @@ -55,13 +55,15 @@ WaveReader::WaveReader(string filename) : throw ErrorReporter(oss.str()); } - ifs.seekg(0, ifs.end); - fileSize = ifs.tellg(); - ifs.seekg(0, ifs.beg); + if (!filename.empty()) { + ifs.seekg(0, ifs.end); + fileSize = ifs.tellg(); + ifs.seekg(0, ifs.beg); + } try { bytesToRead = sizeof(PCMWaveHeader::chunkID) + sizeof(PCMWaveHeader::chunkSize) + sizeof(PCMWaveHeader::format); - data = readData(bytesToRead, true); + data = readData(bytesToRead, forceStop, true); memcpy(headerData, &(*data)[0], bytesToRead); headerOffset = bytesToRead; delete data; @@ -72,7 +74,7 @@ WaveReader::WaveReader(string filename) : } bytesToRead = sizeof(PCMWaveHeader::subchunk1ID) + sizeof(PCMWaveHeader::subchunk1Size); - data = readData(bytesToRead, true); + data = readData(bytesToRead, forceStop, true); memcpy(&headerData[headerOffset], &(*data)[0], bytesToRead); headerOffset += bytesToRead; delete data; @@ -83,7 +85,7 @@ WaveReader::WaveReader(string filename) : throw ErrorReporter(oss.str()); } - data = readData(header.subchunk1Size, true); + data = readData(header.subchunk1Size, forceStop, true); memcpy(&headerData[headerOffset], &(*data)[0], subchunk1MinSize); headerOffset += subchunk1MinSize; delete data; @@ -97,7 +99,7 @@ WaveReader::WaveReader(string filename) : } bytesToRead = sizeof(PCMWaveHeader::subchunk2ID) + sizeof(PCMWaveHeader::subchunk2Size); - data = readData(bytesToRead, true); + data = readData(bytesToRead, forceStop, true); memcpy(&headerData[headerOffset], &(*data)[0], bytesToRead); headerOffset += bytesToRead; delete data; @@ -107,7 +109,9 @@ WaveReader::WaveReader(string filename) : throw ErrorReporter(oss.str()); } } catch (ErrorReporter &error) { - ifs.close(); + if (filename.empty()) { + ifs.close(); + } throw error; } @@ -116,11 +120,16 @@ WaveReader::WaveReader(string filename) : WaveReader::~WaveReader() { - ifs.close(); + if (filename.empty()) { + ifs.close(); + } } -vector* WaveReader::readData(unsigned bytesToRead, bool closeFileOnException) +vector* WaveReader::readData(unsigned bytesToRead, &bool forceStop, bool closeFileOnException) { + vector* data = new vector(); + data->resize(bytesToRead); + if (fileSize < (unsigned)ifs.tellg() + bytesToRead) { ostringstream oss; oss << "Error while reading " << filename << ", data corrupted"; From c9ccbd584d93967d4cf1ea3b82132299e4472fc9 Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Wed, 7 Dec 2016 01:21:44 +0100 Subject: [PATCH 04/34] New reader --- wave_reader.cpp | 108 ++++++++++++++++++++++++++++++++---------------- wave_reader.h | 10 +++-- 2 files changed, 79 insertions(+), 39 deletions(-) diff --git a/wave_reader.cpp b/wave_reader.cpp index a6d0600..34168b7 100644 --- a/wave_reader.cpp +++ b/wave_reader.cpp @@ -33,59 +33,73 @@ #include "wave_reader.h" #include "error_reporter.h" +#include #include #include using std::ostringstream; using std::exception; +using std::cin; WaveReader::WaveReader(string filename, bool &forceStop) : - filename(filename), inputReady(false), fileSize(0) + filename(filename), fileSize(0) { - char* headerData; + char* headerData = (char*)((void*)&header); vector* data; unsigned bytesToRead, headerOffset; ostringstream oss; - ifs.open(filename.c_str(), ifstream::binary); - headerData = (char*)((void*)&header); + if (!filename.empty()) { + ifs.open(filename.c_str(), ifstream::binary); - if (!ifs.is_open()) { - oss << "Cannot open " << filename << ", file does not exist"; - throw ErrorReporter(oss.str()); - } + if (!ifs.is_open()) { + oss << "Cannot open " << filename << ", file does not exist"; + throw ErrorReporter(oss.str()); + } - if (!filename.empty()) { - ifs.seekg(0, ifs.end); - fileSize = ifs.tellg(); - ifs.seekg(0, ifs.beg); + is = &ifs; + + is->seekg(0, is->end); + fileSize = is->tellg(); + is->seekg(0, is->beg); + } else { + is = &cin; } try { bytesToRead = sizeof(PCMWaveHeader::chunkID) + sizeof(PCMWaveHeader::chunkSize) + sizeof(PCMWaveHeader::format); data = readData(bytesToRead, forceStop, true); + if (forceStop) { + return; + } memcpy(headerData, &(*data)[0], bytesToRead); headerOffset = bytesToRead; delete data; if ((string(header.chunkID, 4) != string("RIFF")) || (string(header.format, 4) != string("WAVE"))) { - oss << "Error while opening " << filename << ", WAVE file expected"; + oss << "Error while opening " << getFilename() << ", WAVE file expected"; throw ErrorReporter(oss.str()); } bytesToRead = sizeof(PCMWaveHeader::subchunk1ID) + sizeof(PCMWaveHeader::subchunk1Size); data = readData(bytesToRead, forceStop, true); + if (forceStop) { + return; + } memcpy(&headerData[headerOffset], &(*data)[0], bytesToRead); headerOffset += bytesToRead; delete data; unsigned subchunk1MinSize = sizeof(PCMWaveHeader) - headerOffset - sizeof(PCMWaveHeader::subchunk2ID) - sizeof(PCMWaveHeader::subchunk2Size); if ((string(header.subchunk1ID, 4) != string("fmt ")) || (header.subchunk1Size < subchunk1MinSize)) { - oss << "Error while opening " << filename << ", data corrupted"; + oss << "Error while opening " << getFilename() << ", data corrupted"; throw ErrorReporter(oss.str()); } data = readData(header.subchunk1Size, forceStop, true); + if (forceStop) { + return; + } memcpy(&headerData[headerOffset], &(*data)[0], subchunk1MinSize); headerOffset += subchunk1MinSize; delete data; @@ -94,73 +108,90 @@ WaveReader::WaveReader(string filename, bool &forceStop) : (header.byteRate != (header.bitsPerSample >> 3) * header.channels * header.sampleRate) || (header.blockAlign != (header.bitsPerSample >> 3) * header.channels) || (((header.bitsPerSample >> 3) != 1) && ((header.bitsPerSample >> 3) != 2))) { - oss << "Error while opening " << filename << ", unsupported WAVE format"; + oss << "Error while opening " << getFilename() << ", unsupported WAVE format"; throw ErrorReporter(oss.str()); } bytesToRead = sizeof(PCMWaveHeader::subchunk2ID) + sizeof(PCMWaveHeader::subchunk2Size); data = readData(bytesToRead, forceStop, true); + if (forceStop) { + return; + } memcpy(&headerData[headerOffset], &(*data)[0], bytesToRead); headerOffset += bytesToRead; delete data; if ((string(header.subchunk2ID, 4) != string("data")) || (header.subchunk2Size + ifs.tellg() < fileSize)) { - oss << "Error while opening " << filename << ", data corrupted"; + oss << "Error while opening " << getFilename() << ", data corrupted"; throw ErrorReporter(oss.str()); } } catch (ErrorReporter &error) { - if (filename.empty()) { + if (!filename.empty()) { ifs.close(); } throw error; } - dataOffset = ifs.tellg(); + if (!filename.empty()) { + dataOffset = is->tellg(); + } } WaveReader::~WaveReader() { - if (filename.empty()) { + if (!filename.empty()) { ifs.close(); } } -vector* WaveReader::readData(unsigned bytesToRead, &bool forceStop, bool closeFileOnException) +vector* WaveReader::readData(unsigned bytesToRead, bool &forceStop, bool closeFileOnException) { + unsigned bytesRead = 0; vector* data = new vector(); data->resize(bytesToRead); - if (fileSize < (unsigned)ifs.tellg() + bytesToRead) { - ostringstream oss; - oss << "Error while reading " << filename << ", data corrupted"; - if (closeFileOnException) ifs.close(); - throw ErrorReporter(oss.str()); + while ((bytesRead < bytesToRead) && !forceStop) { + if (is->eof()) { + delete data; + + if (closeFileOnException && !filename.empty()) { + ifs.close(); + } + + ostringstream oss; + oss << "Error while reading " << getFilename() << ", data corrupted"; + throw ErrorReporter(oss.str()); + } + bytesRead += is->readsome(&(*data)[0], bytesToRead - bytesRead); + } + + if (forceStop) { + delete data; + data = NULL; } - vector* data = new vector(); - data->resize(bytesToRead); - ifs.read(&(*data)[0], bytesToRead); return data; } -vector* WaveReader::getFrames(unsigned frameCount, unsigned frameOffset) { +vector* WaveReader::getFrames(unsigned frameCount, unsigned frameOffset, bool &forceStop) { unsigned bytesToRead, bytesLeft, bytesPerFrame, offset; vector* frames = new vector(); vector* data; bytesPerFrame = (header.bitsPerSample >> 3) * header.channels; bytesToRead = frameCount * bytesPerFrame; - bytesLeft = header.subchunk2Size - frameOffset * bytesPerFrame; - if (bytesToRead > bytesLeft) { - bytesToRead = bytesLeft - bytesLeft % bytesPerFrame; - frameCount = bytesToRead / bytesPerFrame; + if (!filename.empty()) { + bytesLeft = header.subchunk2Size - frameOffset * bytesPerFrame; + if (bytesToRead > bytesLeft) { + bytesToRead = bytesLeft - bytesLeft % bytesPerFrame; + frameCount = bytesToRead / bytesPerFrame; + } + is->seekg(dataOffset + frameOffset * bytesPerFrame); } - ifs.seekg(dataOffset + frameOffset * bytesPerFrame); - try { - data = readData(bytesToRead, false); + data = readData(bytesToRead, forceStop, false); } catch (ErrorReporter &error) { delete frames; throw error; @@ -192,6 +223,11 @@ bool WaveReader::isEnd(unsigned frameOffset) return header.subchunk2Size <= frameOffset * (header.bitsPerSample >> 3) * header.channels; } +string WaveReader::getFilename() +{ + return filename.empty() ? "STDIN" : filename; +} + AudioFormat* WaveReader::getFormat() { AudioFormat* format = new AudioFormat; diff --git a/wave_reader.h b/wave_reader.h index 490f6a9..c450a22 100644 --- a/wave_reader.h +++ b/wave_reader.h @@ -36,30 +36,34 @@ #include #include +#include #include #include "audio_format.h" #include "pcm_wave_header.h" using std::vector; using std::string; +using std::istream; using std::ifstream; class WaveReader { public: - WaveReader(string filename); + WaveReader(string filename, bool &forceStop); virtual ~WaveReader(); AudioFormat* getFormat(); - vector* getFrames(unsigned frameCount, unsigned frameOffset); + vector* getFrames(unsigned frameCount, unsigned frameOffset, bool &forceStop); bool isEnd(unsigned frameOffset); private: string filename; PCMWaveHeader header; unsigned fileSize, dataOffset; ifstream ifs; + istream* is; - vector* readData(unsigned bytesToRead, bool closeFileOnException); + vector* readData(unsigned bytesToRead, bool &forceStop, bool closeFileOnException); + string getFilename(); }; #endif // WAVE_READER_H From 7c5bc916bb04926ea746225d1954f8baf7b2b0fa Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Wed, 7 Dec 2016 12:32:47 +0100 Subject: [PATCH 05/34] New universal reader --- makefile | 7 +- stdin_reader.cpp | 166 ----------------------------------------------- stdin_reader.h | 67 ------------------- wave_reader.cpp | 47 +++++++------- wave_reader.h | 7 +- 5 files changed, 27 insertions(+), 267 deletions(-) delete mode 100644 stdin_reader.cpp delete mode 100644 stdin_reader.h diff --git a/makefile b/makefile index 6e47aa6..1094a22 100644 --- a/makefile +++ b/makefile @@ -3,15 +3,12 @@ TARGET = fm_transmitter CPP=$(CCPREFIX)g++ -all: main.o error_reporter.o wave_reader.o stdin_reader.o transmitter.o - $(CPP) $(CFLAGS) -o $(TARGET) main.o error_reporter.o wave_reader.o stdin_reader.o transmitter.o +all: main.o error_reporter.o wave_reader.o transmitter.o + $(CPP) $(CFLAGS) -o $(TARGET) main.o error_reporter.o wave_reader.o transmitter.o wave_reader.o: wave_reader.cpp wave_reader.h $(CPP) $(CFLAGS) -c wave_reader.cpp -stdin_reader.o: stdin_reader.cpp stdin_reader.h - $(CPP) $(CFLAGS) -c stdin_reader.cpp - error_reporter.o: error_reporter.cpp error_reporter.h $(CPP) $(CFLAGS) -c error_reporter.cpp diff --git a/stdin_reader.cpp b/stdin_reader.cpp deleted file mode 100644 index ef51a66..0000000 --- a/stdin_reader.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* - fm_transmitter - use Raspberry Pi as FM transmitter - - Copyright (c) 2015, Marcin Kondej - All rights reserved. - - See https://github.com/markondej/fm_transmitter - - Redistribution and use in source and binary forms, with or without modification, are - permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or other - materials provided with the distribution. - - 3. Neither the name of the copyright holder nor the names of its contributors may be - used to endorse or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY - WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "stdin_reader.h" -#include "error_reporter.h" -#include -#include -#include -#include - -using std::ostringstream; - -bool StdinReader::doStop = false; -bool StdinReader::isReading = false; -bool StdinReader::isDataAccess = false; -vector StdinReader::stream; - -StdinReader::StdinReader() -{ - int returnCode = pthread_create(&thread, NULL, &StdinReader::readStdin, NULL); - if (returnCode) { - ostringstream oss; - oss << "Cannot create new thread (code: " << returnCode << ")"; - throw ErrorReporter(oss.str()); - } - - while (!isReading) { - usleep(1); - } -} - -StdinReader::~StdinReader() -{ - doStop = true; - pthread_join(thread, NULL); -} - -StdinReader* StdinReader::getInstance() -{ - static StdinReader instance; - return &instance; -} - -void *StdinReader::readStdin(void *params) -{ - long flag = fcntl(STDIN_FILENO, F_GETFL, 0); - fcntl(STDIN_FILENO, F_SETFL, flag | O_NONBLOCK); - - char *readBuffer = new char[1024]; - while (!doStop) { - isReading = true; - - while (isDataAccess && !doStop) { - usleep(1); - } - if (doStop) { - break; - } - unsigned streamSize = stream.size(); - if (streamSize < MAX_STREAM_SIZE) { - int bytes = read(STDIN_FILENO, readBuffer, (streamSize + 1024 > MAX_STREAM_SIZE) ? MAX_STREAM_SIZE - streamSize : 1024); - if (bytes > 0) { - stream.insert(stream.end(), readBuffer, readBuffer + bytes); - } - } - - isReading = false; - usleep(1); - } - delete readBuffer; - - return NULL; -} - -vector* StdinReader::getFrames(unsigned frameCount, bool &forceStop) -{ - while (isReading && !forceStop) { - usleep(1); - } - if (forceStop) { - doStop = true; - return NULL; - } - - isDataAccess = true; - - unsigned offset, bytesToRead, bytesPerFrame; - unsigned streamSize = stream.size(); - if (!streamSize) { - isDataAccess = false; - return NULL; - } - - vector *frames = new vector(); - bytesPerFrame = (STREAM_BITS_PER_SAMPLE >> 3) * STREAM_CHANNELS; - bytesToRead = frameCount * bytesPerFrame; - - if (bytesToRead > streamSize) { - bytesToRead = streamSize - streamSize % bytesPerFrame; - frameCount = bytesToRead / bytesPerFrame; - } - - vector data; - data.resize(bytesToRead); - memcpy(&(data[0]), &(stream[0]), bytesToRead); - stream.erase(stream.begin(), stream.begin() + bytesToRead); - isDataAccess = false; - - for (unsigned i = 0; i < frameCount; i++) { - offset = bytesPerFrame * i; - if (STREAM_CHANNELS != 1) { - if (STREAM_BITS_PER_SAMPLE != 8) { - frames->push_back(((int)(signed char)data[offset + 1] + (int)(signed char)data[offset + 3]) / (float)0x100); - } else { - frames->push_back(((int)data[offset] + (int)data[offset + 1]) / (float)0x100 - 1.0f); - } - } else { - if (STREAM_BITS_PER_SAMPLE != 8) { - frames->push_back((signed char)data[offset + 1] / (float)0x80); - } else { - frames->push_back(data[offset] / (float)0x80 - 1.0f); - } - } - } - - return frames; -} - -AudioFormat* StdinReader::getFormat() -{ - AudioFormat* format = new AudioFormat; - format->sampleRate = STREAM_SAMPLE_RATE; - format->bitsPerSample = STREAM_BITS_PER_SAMPLE; - format->channels = STREAM_CHANNELS; - return format; -} diff --git a/stdin_reader.h b/stdin_reader.h deleted file mode 100644 index d902e95..0000000 --- a/stdin_reader.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - fm_transmitter - use Raspberry Pi as FM transmitter - - Copyright (c) 2015, Marcin Kondej - All rights reserved. - - See https://github.com/markondej/fm_transmitter - - Redistribution and use in source and binary forms, with or without modification, are - permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this list - of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or other - materials provided with the distribution. - - 3. Neither the name of the copyright holder nor the names of its contributors may be - used to endorse or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY - WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef STDIN_READER_H -#define STDIN_READER_H - -#include -#include -#include "audio_format.h" -#include "error_reporter.h" - -#define MAX_STREAM_SIZE 2097152 -#define STREAM_SAMPLE_RATE 22050 -#define STREAM_BITS_PER_SAMPLE 16 -#define STREAM_CHANNELS 1 - -using std::vector; - -class StdinReader -{ - public: - virtual ~StdinReader(); - - pthread_t thread; - vector* getFrames(unsigned frameCount, bool &forceStop); - AudioFormat* getFormat(); - - static StdinReader* getInstance(); - private: - StdinReader(); - - static vector stream; - static void* readStdin(void* params); - static bool doStop, isDataAccess, isReading; -}; - -#endif // STDIN_READER_H diff --git a/wave_reader.cpp b/wave_reader.cpp index 34168b7..8db44d7 100644 --- a/wave_reader.cpp +++ b/wave_reader.cpp @@ -33,13 +33,12 @@ #include "wave_reader.h" #include "error_reporter.h" -#include #include #include +#include using std::ostringstream; using std::exception; -using std::cin; WaveReader::WaveReader(string filename, bool &forceStop) : filename(filename), fileSize(0) @@ -50,20 +49,19 @@ WaveReader::WaveReader(string filename, bool &forceStop) : ostringstream oss; if (!filename.empty()) { - ifs.open(filename.c_str(), ifstream::binary); - - if (!ifs.is_open()) { - oss << "Cannot open " << filename << ", file does not exist"; - throw ErrorReporter(oss.str()); - } + fileDescriptor = open(filename.c_str(), O_RDONLY); + } else { + fileDescriptor = STDIN_FILENO; + } - is = &ifs; + if (fileDescriptor == -1) { + oss << "Cannot open " << getFilename() << ", file does not exist"; + throw ErrorReporter(oss.str()); + } - is->seekg(0, is->end); - fileSize = is->tellg(); - is->seekg(0, is->beg); - } else { - is = &cin; + if (!filename.empty()) { + fileSize = lseek(fileDescriptor, 0, SEEK_END); + lseek(fileDescriptor, 0, SEEK_SET); } try { @@ -121,26 +119,26 @@ WaveReader::WaveReader(string filename, bool &forceStop) : headerOffset += bytesToRead; delete data; - if ((string(header.subchunk2ID, 4) != string("data")) || (header.subchunk2Size + ifs.tellg() < fileSize)) { + if ((string(header.subchunk2ID, 4) != string("data")) || (header.subchunk2Size + lseek(fileDescriptor, 0, SEEK_CUR) < fileSize)) { oss << "Error while opening " << getFilename() << ", data corrupted"; throw ErrorReporter(oss.str()); } } catch (ErrorReporter &error) { if (!filename.empty()) { - ifs.close(); + close(fileDescriptor); } throw error; } if (!filename.empty()) { - dataOffset = is->tellg(); + dataOffset = lseek(fileDescriptor, 0, SEEK_CUR); } } WaveReader::~WaveReader() { if (!filename.empty()) { - ifs.close(); + close(fileDescriptor); } } @@ -151,18 +149,19 @@ vector* WaveReader::readData(unsigned bytesToRead, bool &forceStop, bool c data->resize(bytesToRead); while ((bytesRead < bytesToRead) && !forceStop) { - if (is->eof()) { + int bytes = read(fileDescriptor, &(*data)[0], bytesToRead - bytesRead); + if (bytes == -1) { delete data; if (closeFileOnException && !filename.empty()) { - ifs.close(); + close(fileDescriptor); } ostringstream oss; - oss << "Error while reading " << getFilename() << ", data corrupted"; + oss << "Error while reading " << getFilename() << ", file is corrupted"; throw ErrorReporter(oss.str()); } - bytesRead += is->readsome(&(*data)[0], bytesToRead - bytesRead); + bytesRead += bytes; } if (forceStop) { @@ -187,7 +186,9 @@ vector* WaveReader::getFrames(unsigned frameCount, unsigned frameOffset, bytesToRead = bytesLeft - bytesLeft % bytesPerFrame; frameCount = bytesToRead / bytesPerFrame; } - is->seekg(dataOffset + frameOffset * bytesPerFrame); + if (lseek(fileDescriptor, dataOffset + frameOffset * bytesPerFrame, SEEK_SET) == -1) { + throw new ErrorReporter("File is corrupted!"); + } } try { diff --git a/wave_reader.h b/wave_reader.h index c450a22..cfd700f 100644 --- a/wave_reader.h +++ b/wave_reader.h @@ -36,15 +36,11 @@ #include #include -#include -#include #include "audio_format.h" #include "pcm_wave_header.h" using std::vector; using std::string; -using std::istream; -using std::ifstream; class WaveReader { @@ -59,8 +55,7 @@ class WaveReader string filename; PCMWaveHeader header; unsigned fileSize, dataOffset; - ifstream ifs; - istream* is; + int fileDescriptor; vector* readData(unsigned bytesToRead, bool &forceStop, bool closeFileOnException); string getFilename(); From 54631c13640c74cf8dc2476be8c43ad55d5e36e5 Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Wed, 7 Dec 2016 13:11:06 +0100 Subject: [PATCH 06/34] New universal reader --- transmitter.cpp | 49 +++++++++++++------------------------------------ wave_reader.cpp | 1 + 2 files changed, 14 insertions(+), 36 deletions(-) diff --git a/transmitter.cpp b/transmitter.cpp index 23a6c8a..f2656e8 100644 --- a/transmitter.cpp +++ b/transmitter.cpp @@ -33,7 +33,6 @@ #include "transmitter.h" #include "wave_reader.h" -#include "stdin_reader.h" #include #include #include @@ -109,18 +108,9 @@ void Transmitter::play(string filename, double frequency, bool loop) throw ErrorReporter("Cannot play, transmitter already in use"); } - WaveReader* file = NULL; - StdinReader* stdin = NULL; - AudioFormat* format; - - bool readStdin = filename == "-"; - - if (!readStdin) { - file = new WaveReader(filename); - format = file->getFormat(); - } else { - stdin = StdinReader::getInstance(); - format = stdin->getFormat(); + WaveReader* reader = new WaveReader(filename != "-" ? filename : string()); + AudioFormat* format = reader->getFormat(); + if (filename == "-") { usleep(STDIN_READ_DELAY); } @@ -132,16 +122,14 @@ void Transmitter::play(string filename, double frequency, bool loop) isRestart = false; doStop = false; - buffer = (!readStdin) ? file->getFrames(bufferFrames, 0) : stdin->getFrames(bufferFrames, doStop); + buffer = reader->getFrames(bufferFrames, 0, doStop); pthread_t thread; void* params = (void*)&format->sampleRate; int returnCode = pthread_create(&thread, NULL, &Transmitter::transmit, params); if (returnCode) { - if (!readStdin) { - delete file; - } + delete reader; delete format; ostringstream oss; oss << "Cannot create new thread (code: " << returnCode << ")"; @@ -151,16 +139,16 @@ void Transmitter::play(string filename, double frequency, bool loop) usleep(BUFFER_TIME / 2); while (!doStop) { - while ((readStdin || !file->isEnd(frameOffset + bufferFrames)) && !doStop) { + while ((readStdin || !reader->isEnd(frameOffset + bufferFrames)) && !doStop) { if (buffer == NULL) { - buffer = (!readStdin) ? file->getFrames(bufferFrames, frameOffset + bufferFrames) : stdin->getFrames(bufferFrames, doStop); + buffer = reader->getFrames(bufferFrames, frameOffset + bufferFrames, doStop); } usleep(BUFFER_TIME / 2); } if (loop && !readStdin && !doStop) { frameOffset = 0; isRestart = true; - buffer = file->getFrames(bufferFrames, 0); + buffer = reader->getFrames(bufferFrames, 0, doStop); usleep(BUFFER_TIME / 2); } else { doStop = true; @@ -170,9 +158,7 @@ void Transmitter::play(string filename, double frequency, bool loop) pthread_join(thread, NULL); - if (!readStdin) { - delete file; - } + delete reader; delete format; } @@ -257,19 +243,10 @@ void* Transmitter::transmit(void* params) AudioFormat* Transmitter::getFormat(string filename) { - WaveReader* file; - StdinReader* stdin; - AudioFormat* format; - - if (filename != "-") { - file = new WaveReader(filename); - format = file->getFormat(); - delete file; - } else { - stdin = StdinReader::getInstance(); - format = stdin->getFormat(); - } - + WaveReader* reader = new WaveReader(filename); + AudioFormat* format = file->getFormat(); + delete reader; + return format; } diff --git a/wave_reader.cpp b/wave_reader.cpp index 8db44d7..8c9fadb 100644 --- a/wave_reader.cpp +++ b/wave_reader.cpp @@ -35,6 +35,7 @@ #include "error_reporter.h" #include #include +#include #include using std::ostringstream; From 4dd8ab5dce0124623bd87934f125086e55b4bee1 Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Wed, 7 Dec 2016 13:11:06 +0100 Subject: [PATCH 07/34] New universal reader --- transmitter.cpp | 51 ++++++++++++++----------------------------------- wave_reader.cpp | 1 + 2 files changed, 15 insertions(+), 37 deletions(-) diff --git a/transmitter.cpp b/transmitter.cpp index 23a6c8a..89b3f83 100644 --- a/transmitter.cpp +++ b/transmitter.cpp @@ -33,11 +33,10 @@ #include "transmitter.h" #include "wave_reader.h" -#include "stdin_reader.h" #include #include #include -#include +#include #include using std::ostringstream; @@ -109,18 +108,9 @@ void Transmitter::play(string filename, double frequency, bool loop) throw ErrorReporter("Cannot play, transmitter already in use"); } - WaveReader* file = NULL; - StdinReader* stdin = NULL; - AudioFormat* format; - - bool readStdin = filename == "-"; - - if (!readStdin) { - file = new WaveReader(filename); - format = file->getFormat(); - } else { - stdin = StdinReader::getInstance(); - format = stdin->getFormat(); + WaveReader* reader = new WaveReader(filename != "-" ? filename : string()); + AudioFormat* format = reader->getFormat(); + if (filename == "-") { usleep(STDIN_READ_DELAY); } @@ -132,16 +122,14 @@ void Transmitter::play(string filename, double frequency, bool loop) isRestart = false; doStop = false; - buffer = (!readStdin) ? file->getFrames(bufferFrames, 0) : stdin->getFrames(bufferFrames, doStop); + buffer = reader->getFrames(bufferFrames, 0, doStop); pthread_t thread; void* params = (void*)&format->sampleRate; int returnCode = pthread_create(&thread, NULL, &Transmitter::transmit, params); if (returnCode) { - if (!readStdin) { - delete file; - } + delete reader; delete format; ostringstream oss; oss << "Cannot create new thread (code: " << returnCode << ")"; @@ -151,16 +139,16 @@ void Transmitter::play(string filename, double frequency, bool loop) usleep(BUFFER_TIME / 2); while (!doStop) { - while ((readStdin || !file->isEnd(frameOffset + bufferFrames)) && !doStop) { + while ((readStdin || !reader->isEnd(frameOffset + bufferFrames)) && !doStop) { if (buffer == NULL) { - buffer = (!readStdin) ? file->getFrames(bufferFrames, frameOffset + bufferFrames) : stdin->getFrames(bufferFrames, doStop); + buffer = reader->getFrames(bufferFrames, frameOffset + bufferFrames, doStop); } usleep(BUFFER_TIME / 2); } if (loop && !readStdin && !doStop) { frameOffset = 0; isRestart = true; - buffer = file->getFrames(bufferFrames, 0); + buffer = reader->getFrames(bufferFrames, 0, doStop); usleep(BUFFER_TIME / 2); } else { doStop = true; @@ -170,9 +158,7 @@ void Transmitter::play(string filename, double frequency, bool loop) pthread_join(thread, NULL); - if (!readStdin) { - delete file; - } + delete reader; delete format; } @@ -257,19 +243,10 @@ void* Transmitter::transmit(void* params) AudioFormat* Transmitter::getFormat(string filename) { - WaveReader* file; - StdinReader* stdin; - AudioFormat* format; - - if (filename != "-") { - file = new WaveReader(filename); - format = file->getFormat(); - delete file; - } else { - stdin = StdinReader::getInstance(); - format = stdin->getFormat(); - } - + WaveReader* reader = new WaveReader(filename); + AudioFormat* format = file->getFormat(); + delete reader; + return format; } diff --git a/wave_reader.cpp b/wave_reader.cpp index 8db44d7..8c9fadb 100644 --- a/wave_reader.cpp +++ b/wave_reader.cpp @@ -35,6 +35,7 @@ #include "error_reporter.h" #include #include +#include #include using std::ostringstream; From bb107a84acf63ad0aa6e443ca978339afb44965a Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Wed, 7 Dec 2016 13:17:26 +0100 Subject: [PATCH 08/34] Bug fixes --- transmitter.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/transmitter.cpp b/transmitter.cpp index 89b3f83..17644fe 100644 --- a/transmitter.cpp +++ b/transmitter.cpp @@ -108,7 +108,10 @@ void Transmitter::play(string filename, double frequency, bool loop) throw ErrorReporter("Cannot play, transmitter already in use"); } - WaveReader* reader = new WaveReader(filename != "-" ? filename : string()); + isTransmitting = true; + doStop = false; + + WaveReader* reader = new WaveReader(filename != "-" ? filename : string(), doStop); AudioFormat* format = reader->getFormat(); if (filename == "-") { usleep(STDIN_READ_DELAY); @@ -118,9 +121,7 @@ void Transmitter::play(string filename, double frequency, bool loop) unsigned bufferFrames = (unsigned)((unsigned long long)format->sampleRate * BUFFER_TIME / 1000000); frameOffset = 0; - isTransmitting = true; isRestart = false; - doStop = false; buffer = reader->getFrames(bufferFrames, 0, doStop); @@ -139,13 +140,13 @@ void Transmitter::play(string filename, double frequency, bool loop) usleep(BUFFER_TIME / 2); while (!doStop) { - while ((readStdin || !reader->isEnd(frameOffset + bufferFrames)) && !doStop) { + while (!reader->isEnd(frameOffset + bufferFrames) && !doStop) { if (buffer == NULL) { buffer = reader->getFrames(bufferFrames, frameOffset + bufferFrames, doStop); } usleep(BUFFER_TIME / 2); } - if (loop && !readStdin && !doStop) { + if (loop && !doStop) { frameOffset = 0; isRestart = true; buffer = reader->getFrames(bufferFrames, 0, doStop); @@ -243,7 +244,7 @@ void* Transmitter::transmit(void* params) AudioFormat* Transmitter::getFormat(string filename) { - WaveReader* reader = new WaveReader(filename); + WaveReader* reader = new WaveReader(filename, false); AudioFormat* format = file->getFormat(); delete reader; From c5efc8a135e51e650604f0f81e9916a4f0a44054 Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Wed, 7 Dec 2016 13:20:14 +0100 Subject: [PATCH 09/34] Bug fix --- transmitter.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/transmitter.cpp b/transmitter.cpp index 17644fe..8ffd96c 100644 --- a/transmitter.cpp +++ b/transmitter.cpp @@ -244,8 +244,10 @@ void* Transmitter::transmit(void* params) AudioFormat* Transmitter::getFormat(string filename) { - WaveReader* reader = new WaveReader(filename, false); - AudioFormat* format = file->getFormat(); + doStop = false; + + WaveReader* reader = new WaveReader(filename, doStop); + AudioFormat* format = reader->getFormat(); delete reader; return format; From 5db134df12c4df4ce54a1c8a280c4ce82445b131 Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Wed, 7 Dec 2016 13:23:54 +0100 Subject: [PATCH 10/34] Bug fixes --- transmitter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/transmitter.cpp b/transmitter.cpp index 8ffd96c..517f819 100644 --- a/transmitter.cpp +++ b/transmitter.cpp @@ -244,9 +244,9 @@ void* Transmitter::transmit(void* params) AudioFormat* Transmitter::getFormat(string filename) { - doStop = false; + bool forceStop = false; - WaveReader* reader = new WaveReader(filename, doStop); + WaveReader* reader = new WaveReader(filename, forceStop); AudioFormat* format = reader->getFormat(); delete reader; From 2c181ea8eeb2b7814c88964cf913c336732bd851 Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Wed, 7 Dec 2016 13:26:42 +0100 Subject: [PATCH 11/34] Bug fix --- transmitter.cpp | 2 +- wave_reader.cpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/transmitter.cpp b/transmitter.cpp index 517f819..feda224 100644 --- a/transmitter.cpp +++ b/transmitter.cpp @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include using std::ostringstream; diff --git a/wave_reader.cpp b/wave_reader.cpp index 8c9fadb..8db44d7 100644 --- a/wave_reader.cpp +++ b/wave_reader.cpp @@ -35,7 +35,6 @@ #include "error_reporter.h" #include #include -#include #include using std::ostringstream; From 79e05050e5ff22d5e8126b797e8fda1ea186f618 Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Wed, 7 Dec 2016 13:28:06 +0100 Subject: [PATCH 12/34] bug fix --- wave_reader.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wave_reader.cpp b/wave_reader.cpp index 8db44d7..920a863 100644 --- a/wave_reader.cpp +++ b/wave_reader.cpp @@ -35,7 +35,8 @@ #include "error_reporter.h" #include #include -#include +#include +//#include using std::ostringstream; using std::exception; From f72876af12c5188b757af07d852569c9d1dd8e4b Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Wed, 7 Dec 2016 13:29:07 +0100 Subject: [PATCH 13/34] Bug fix --- wave_reader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wave_reader.cpp b/wave_reader.cpp index 920a863..8c9fadb 100644 --- a/wave_reader.cpp +++ b/wave_reader.cpp @@ -36,7 +36,7 @@ #include #include #include -//#include +#include using std::ostringstream; using std::exception; From aa5615d5daa1889c4a11d054118111763786aad8 Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Wed, 7 Dec 2016 13:32:30 +0100 Subject: [PATCH 14/34] Bug fix --- transmitter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/transmitter.cpp b/transmitter.cpp index feda224..39b8872 100644 --- a/transmitter.cpp +++ b/transmitter.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include using std::ostringstream; From 0fa8f4f08aee748bf59c6095ff900d456a5acda4 Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Wed, 7 Dec 2016 13:34:19 +0100 Subject: [PATCH 15/34] Bug fix --- transmitter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/transmitter.cpp b/transmitter.cpp index 39b8872..f03950d 100644 --- a/transmitter.cpp +++ b/transmitter.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include using std::ostringstream; From 5a120f53c17b259e8705e19adf07cb2f0502fca4 Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Mon, 12 Dec 2016 23:49:55 +0100 Subject: [PATCH 16/34] Bug fix --- main.cpp | 24 ++++++++++++++++++------ transmitter.cpp | 11 ----------- transmitter.h | 3 +-- wave_reader.cpp | 1 + 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/main.cpp b/main.cpp index e63f2cb..90c3a8e 100644 --- a/main.cpp +++ b/main.cpp @@ -40,6 +40,14 @@ using namespace std; Transmitter* transmitter = NULL; +AudioFormat* getFormat(string filename) { + bool doStop = false; + WaveReader* reader = new WaveReader(filename, doStop); + AudioFormat* format = reader->getFormat(); + delete reader; + return format; +} + void sigIntHandler(int sigNum) { if (transmitter != NULL) { @@ -80,12 +88,16 @@ int main(int argc, char** argv) try { transmitter = Transmitter::getInstance(); - AudioFormat* format = Transmitter::getFormat(filename); - cout << "Playing: " << ((filename != "-") ? filename : "stdin") << ", " - << format->sampleRate << " Hz, " - << format->bitsPerSample << " bits, " - << ((format->channels > 0x01) ? "stereo" : "mono") << endl; - delete format; + if (filename != "-") { + AudioFormat* format = getFormat(filename); + cout << "Playing: " << filename << ", " + << format->sampleRate << " Hz, " + << format->bitsPerSample << " bits, " + << ((format->channels > 0x01) ? "stereo" : "mono") << endl; + delete format; + } else { + cout << "Playing: STDIN" << endl; + } transmitter->play(filename, frequency, loop); } catch (exception &error) { diff --git a/transmitter.cpp b/transmitter.cpp index f03950d..0fd57e9 100644 --- a/transmitter.cpp +++ b/transmitter.cpp @@ -244,17 +244,6 @@ void* Transmitter::transmit(void* params) return NULL; } -AudioFormat* Transmitter::getFormat(string filename) -{ - bool forceStop = false; - - WaveReader* reader = new WaveReader(filename, forceStop); - AudioFormat* format = reader->getFormat(); - delete reader; - - return format; -} - void Transmitter::stop() { doStop = true; diff --git a/transmitter.h b/transmitter.h index 6db2eac..0ecdfeb 100644 --- a/transmitter.h +++ b/transmitter.h @@ -52,8 +52,7 @@ class Transmitter void play(string filename, double frequency, bool loop); void stop(); - static Transmitter* getInstance(); - static AudioFormat* getFormat(string filename); + static Transmitter* getInstance(); private: Transmitter(); diff --git a/wave_reader.cpp b/wave_reader.cpp index 8c9fadb..af170c6 100644 --- a/wave_reader.cpp +++ b/wave_reader.cpp @@ -52,6 +52,7 @@ WaveReader::WaveReader(string filename, bool &forceStop) : if (!filename.empty()) { fileDescriptor = open(filename.c_str(), O_RDONLY); } else { + fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL, 0) | O_NONBLOCK); fileDescriptor = STDIN_FILENO; } From d8a55ac17aa6c22da230ba5cc97042af88291f84 Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Mon, 12 Dec 2016 23:13:32 +0000 Subject: [PATCH 17/34] Bug fix --- main.cpp | 1 + wave_reader.cpp | 13 +++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/main.cpp b/main.cpp index 90c3a8e..fc15844 100644 --- a/main.cpp +++ b/main.cpp @@ -32,6 +32,7 @@ */ #include +#include "wave_reader.h" #include "transmitter.h" #include #include diff --git a/wave_reader.cpp b/wave_reader.cpp index af170c6..c089551 100644 --- a/wave_reader.cpp +++ b/wave_reader.cpp @@ -38,6 +38,8 @@ #include #include +#include + using std::ostringstream; using std::exception; @@ -52,9 +54,9 @@ WaveReader::WaveReader(string filename, bool &forceStop) : if (!filename.empty()) { fileDescriptor = open(filename.c_str(), O_RDONLY); } else { - fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL, 0) | O_NONBLOCK); fileDescriptor = STDIN_FILENO; } + fcntl(fileDescriptor, F_SETFL, fcntl(fileDescriptor, F_GETFL, 0) | O_NONBLOCK); if (fileDescriptor == -1) { oss << "Cannot open " << getFilename() << ", file does not exist"; @@ -151,8 +153,9 @@ vector* WaveReader::readData(unsigned bytesToRead, bool &forceStop, bool c data->resize(bytesToRead); while ((bytesRead < bytesToRead) && !forceStop) { - int bytes = read(fileDescriptor, &(*data)[0], bytesToRead - bytesRead); - if (bytes == -1) { + int bytes = read(fileDescriptor, &(*data)[bytesRead], bytesToRead - bytesRead); + printf("BYTES: %d\n", bytes); + /*if (bytes == -1) { delete data; if (closeFileOnException && !filename.empty()) { @@ -162,8 +165,10 @@ vector* WaveReader::readData(unsigned bytesToRead, bool &forceStop, bool c ostringstream oss; oss << "Error while reading " << getFilename() << ", file is corrupted"; throw ErrorReporter(oss.str()); + }*/ + if (bytes > 0) { + bytesRead += bytes; } - bytesRead += bytes; } if (forceStop) { From 7be6ef591d0ef92f5deb49185beebb22798ecb00 Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Tue, 13 Dec 2016 00:37:24 +0100 Subject: [PATCH 18/34] Bug fix --- main.cpp | 5 +++-- wave_reader.cpp | 27 +++++++++++++++++---------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/main.cpp b/main.cpp index fc15844..fe5a055 100644 --- a/main.cpp +++ b/main.cpp @@ -39,11 +39,11 @@ using namespace std; +bool stop = false; Transmitter* transmitter = NULL; AudioFormat* getFormat(string filename) { - bool doStop = false; - WaveReader* reader = new WaveReader(filename, doStop); + WaveReader* reader = new WaveReader(filename, stop); AudioFormat* format = reader->getFormat(); delete reader; return format; @@ -54,6 +54,7 @@ void sigIntHandler(int sigNum) if (transmitter != NULL) { cout << "Stopping..." << endl; transmitter->stop(); + stop = true; } } diff --git a/wave_reader.cpp b/wave_reader.cpp index c089551..69ab6dd 100644 --- a/wave_reader.cpp +++ b/wave_reader.cpp @@ -38,6 +38,7 @@ #include #include +#include #include using std::ostringstream; @@ -54,22 +55,23 @@ WaveReader::WaveReader(string filename, bool &forceStop) : if (!filename.empty()) { fileDescriptor = open(filename.c_str(), O_RDONLY); } else { + fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL, 0) | O_NONBLOCK); fileDescriptor = STDIN_FILENO; } - fcntl(fileDescriptor, F_SETFL, fcntl(fileDescriptor, F_GETFL, 0) | O_NONBLOCK); if (fileDescriptor == -1) { oss << "Cannot open " << getFilename() << ", file does not exist"; throw ErrorReporter(oss.str()); } - if (!filename.empty()) { + if (fileDescriptor != STDIN_FILENO) { fileSize = lseek(fileDescriptor, 0, SEEK_END); lseek(fileDescriptor, 0, SEEK_SET); } try { - bytesToRead = sizeof(PCMWaveHeader::chunkID) + sizeof(PCMWaveHeader::chunkSize) + sizeof(PCMWaveHeader::format); + bytesToRead = sizeof(PCMWaveHeader::chunkID) + sizeof(PCMWaveHeader::chunkSize) + + sizeof(PCMWaveHeader::format); data = readData(bytesToRead, forceStop, true); if (forceStop) { return; @@ -92,7 +94,9 @@ WaveReader::WaveReader(string filename, bool &forceStop) : headerOffset += bytesToRead; delete data; - unsigned subchunk1MinSize = sizeof(PCMWaveHeader) - headerOffset - sizeof(PCMWaveHeader::subchunk2ID) - sizeof(PCMWaveHeader::subchunk2Size); + unsigned subchunk1MinSize = sizeof(PCMWaveHeader::audioFormat) + sizeof(PCMWaveHeader::channels) + + sizeof(PCMWaveHeader::sampleRate) + sizeof(PCMWaveHeader::byteRate) + sizeof(PCMWaveHeader::blockAlign) + + sizeof(PCMWaveHeader::bitsPerSample); if ((string(header.subchunk1ID, 4) != string("fmt ")) || (header.subchunk1Size < subchunk1MinSize)) { oss << "Error while opening " << getFilename() << ", data corrupted"; throw ErrorReporter(oss.str()); @@ -123,25 +127,25 @@ WaveReader::WaveReader(string filename, bool &forceStop) : headerOffset += bytesToRead; delete data; - if ((string(header.subchunk2ID, 4) != string("data")) || (header.subchunk2Size + lseek(fileDescriptor, 0, SEEK_CUR) < fileSize)) { + if (string(header.subchunk2ID, 4) != string("data")) { oss << "Error while opening " << getFilename() << ", data corrupted"; throw ErrorReporter(oss.str()); } } catch (ErrorReporter &error) { - if (!filename.empty()) { + if (fileDescriptor != STDIN_FILENO) { close(fileDescriptor); } throw error; } - if (!filename.empty()) { + if (!fileDescriptor != STDIN_FILENO) { dataOffset = lseek(fileDescriptor, 0, SEEK_CUR); } } WaveReader::~WaveReader() { - if (!filename.empty()) { + if (!fileDescriptor != STDIN_FILENO) { close(fileDescriptor); } } @@ -155,6 +159,9 @@ vector* WaveReader::readData(unsigned bytesToRead, bool &forceStop, bool c while ((bytesRead < bytesToRead) && !forceStop) { int bytes = read(fileDescriptor, &(*data)[bytesRead], bytesToRead - bytesRead); printf("BYTES: %d\n", bytes); + if (bytes == -1) { + printf("ERROR: %d\n", errno); + } /*if (bytes == -1) { delete data; @@ -187,7 +194,7 @@ vector* WaveReader::getFrames(unsigned frameCount, unsigned frameOffset, bytesPerFrame = (header.bitsPerSample >> 3) * header.channels; bytesToRead = frameCount * bytesPerFrame; - if (!filename.empty()) { + if (fileDescriptor != STDIN_FILENO) { bytesLeft = header.subchunk2Size - frameOffset * bytesPerFrame; if (bytesToRead > bytesLeft) { bytesToRead = bytesLeft - bytesLeft % bytesPerFrame; @@ -233,7 +240,7 @@ bool WaveReader::isEnd(unsigned frameOffset) string WaveReader::getFilename() { - return filename.empty() ? "STDIN" : filename; + return fileDescriptor != STDIN_FILENO ? filename : "STDIN"; } AudioFormat* WaveReader::getFormat() From a6fdc6a0407e0c8bed0ce1f485ae95fb5eccad50 Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Tue, 13 Dec 2016 01:37:54 +0100 Subject: [PATCH 19/34] Should be working now --- transmitter.cpp | 14 +++++++++---- transmitter.h | 2 +- wave_reader.cpp | 55 ++++++++++++++++++++++++++++--------------------- wave_reader.h | 2 +- 4 files changed, 44 insertions(+), 29 deletions(-) diff --git a/transmitter.cpp b/transmitter.cpp index 0fd57e9..5e89389 100644 --- a/transmitter.cpp +++ b/transmitter.cpp @@ -125,7 +125,9 @@ void Transmitter::play(string filename, double frequency, bool loop) frameOffset = 0; isRestart = false; - buffer = reader->getFrames(bufferFrames, 0, doStop); + vector* frames = reader->getFrames(bufferFrames, 0, doStop); + isEof = frames.size() < bufferFrames; + buffer = frames; pthread_t thread; void* params = (void*)&format->sampleRate; @@ -142,9 +144,11 @@ void Transmitter::play(string filename, double frequency, bool loop) usleep(BUFFER_TIME / 2); while (!doStop) { - while (!reader->isEnd(frameOffset + bufferFrames) && !doStop) { + while (!isEof && !doStop) { if (buffer == NULL) { - buffer = reader->getFrames(bufferFrames, frameOffset + bufferFrames, doStop); + frames = reader->getFrames(bufferFrames, frameOffset + bufferFrames, doStop); + isEof = frames.size() < bufferFrames; + buffer = frames; } usleep(BUFFER_TIME / 2); } @@ -152,6 +156,8 @@ void Transmitter::play(string filename, double frequency, bool loop) frameOffset = 0; isRestart = true; buffer = reader->getFrames(bufferFrames, 0, doStop); + isEof = frames.size() < bufferFrames; + buffer = frames; usleep(BUFFER_TIME / 2); } else { doStop = true; @@ -170,8 +176,8 @@ void* Transmitter::transmit(void* params) unsigned long long current, start, playbackStart; unsigned offset, length, temp; vector* frames = NULL; - float value = 0.0; float* data; + float value; #ifndef NO_PREEMP float prevValue = 0.0; #endif diff --git a/transmitter.h b/transmitter.h index 0ecdfeb..746af87 100644 --- a/transmitter.h +++ b/transmitter.h @@ -56,7 +56,7 @@ class Transmitter private: Transmitter(); - bool doStop; + bool doStop, isEof; static void* peripherals; static vector* buffer; diff --git a/wave_reader.cpp b/wave_reader.cpp index 69ab6dd..4eef1da 100644 --- a/wave_reader.cpp +++ b/wave_reader.cpp @@ -37,15 +37,13 @@ #include #include #include - #include -#include using std::ostringstream; using std::exception; WaveReader::WaveReader(string filename, bool &forceStop) : - filename(filename), fileSize(0) + filename(filename), fileSize(0), isHeaderRead(false) { char* headerData = (char*)((void*)&header); vector* data; @@ -72,7 +70,7 @@ WaveReader::WaveReader(string filename, bool &forceStop) : try { bytesToRead = sizeof(PCMWaveHeader::chunkID) + sizeof(PCMWaveHeader::chunkSize) + sizeof(PCMWaveHeader::format); - data = readData(bytesToRead, forceStop, true); + data = readData(bytesToRead, forceStop); if (forceStop) { return; } @@ -86,7 +84,7 @@ WaveReader::WaveReader(string filename, bool &forceStop) : } bytesToRead = sizeof(PCMWaveHeader::subchunk1ID) + sizeof(PCMWaveHeader::subchunk1Size); - data = readData(bytesToRead, forceStop, true); + data = readData(bytesToRead, forceStop); if (forceStop) { return; } @@ -102,7 +100,7 @@ WaveReader::WaveReader(string filename, bool &forceStop) : throw ErrorReporter(oss.str()); } - data = readData(header.subchunk1Size, forceStop, true); + data = readData(header.subchunk1Size, forceStop); if (forceStop) { return; } @@ -119,7 +117,7 @@ WaveReader::WaveReader(string filename, bool &forceStop) : } bytesToRead = sizeof(PCMWaveHeader::subchunk2ID) + sizeof(PCMWaveHeader::subchunk2Size); - data = readData(bytesToRead, forceStop, true); + data = readData(bytesToRead, forceStop); if (forceStop) { return; } @@ -131,6 +129,8 @@ WaveReader::WaveReader(string filename, bool &forceStop) : oss << "Error while opening " << getFilename() << ", data corrupted"; throw ErrorReporter(oss.str()); } + + isHeaderRead = true; } catch (ErrorReporter &error) { if (fileDescriptor != STDIN_FILENO) { close(fileDescriptor); @@ -150,7 +150,7 @@ WaveReader::~WaveReader() } } -vector* WaveReader::readData(unsigned bytesToRead, bool &forceStop, bool closeFileOnException) +vector* WaveReader::readData(unsigned bytesToRead, bool &forceStop) { unsigned bytesRead = 0; vector* data = new vector(); @@ -158,21 +158,22 @@ vector* WaveReader::readData(unsigned bytesToRead, bool &forceStop, bool c while ((bytesRead < bytesToRead) && !forceStop) { int bytes = read(fileDescriptor, &(*data)[bytesRead], bytesToRead - bytesRead); - printf("BYTES: %d\n", bytes); - if (bytes == -1) { - printf("ERROR: %d\n", errno); - } - /*if (bytes == -1) { + if (((bytes == -1) && ((fileDescriptor != STDIN_FILENO) || (errno != EAGAIN))) || + ((bytes == 0) && !isHeaderRead && (fileDescriptor != STDIN_FILENO))) { delete data; - if (closeFileOnException && !filename.empty()) { + if (!isHeaderRead && (fileDescriptor != STDIN_FILENO)) { close(fileDescriptor); } ostringstream oss; oss << "Error while reading " << getFilename() << ", file is corrupted"; throw ErrorReporter(oss.str()); - }*/ + } + if ((bytes == 0) && (fileDescriptor != STDIN_FILENO)) { + data->resize(bytesRead); + break; + } if (bytes > 0) { bytesRead += bytes; } @@ -188,6 +189,12 @@ vector* WaveReader::readData(unsigned bytesToRead, bool &forceStop, bool c vector* WaveReader::getFrames(unsigned frameCount, unsigned frameOffset, bool &forceStop) { unsigned bytesToRead, bytesLeft, bytesPerFrame, offset; + + if (!isHeaderRead) { + ostringstream oss; + throw ErrorReporter("Header wasn't read successfully!"); + } + vector* frames = new vector(); vector* data; @@ -201,16 +208,24 @@ vector* WaveReader::getFrames(unsigned frameCount, unsigned frameOffset, frameCount = bytesToRead / bytesPerFrame; } if (lseek(fileDescriptor, dataOffset + frameOffset * bytesPerFrame, SEEK_SET) == -1) { - throw new ErrorReporter("File is corrupted!"); + return frames; } } try { - data = readData(bytesToRead, forceStop, false); + data = readData(bytesToRead, forceStop); } catch (ErrorReporter &error) { delete frames; throw error; } + if (forceStop) { + delete frames; + return NULL; + } + if (data->size() < bytesToRead) { + frameCount = data->size() / bytesPerFrame; + } + for (unsigned i = 0; i < frameCount; i++) { offset = bytesPerFrame * i; if (header.channels != 1) { @@ -229,15 +244,9 @@ vector* WaveReader::getFrames(unsigned frameCount, unsigned frameOffset, } delete data; - return frames; } -bool WaveReader::isEnd(unsigned frameOffset) -{ - return header.subchunk2Size <= frameOffset * (header.bitsPerSample >> 3) * header.channels; -} - string WaveReader::getFilename() { return fileDescriptor != STDIN_FILENO ? filename : "STDIN"; diff --git a/wave_reader.h b/wave_reader.h index cfd700f..161d2e2 100644 --- a/wave_reader.h +++ b/wave_reader.h @@ -50,12 +50,12 @@ class WaveReader AudioFormat* getFormat(); vector* getFrames(unsigned frameCount, unsigned frameOffset, bool &forceStop); - bool isEnd(unsigned frameOffset); private: string filename; PCMWaveHeader header; unsigned fileSize, dataOffset; int fileDescriptor; + bool isHeaderRead; vector* readData(unsigned bytesToRead, bool &forceStop, bool closeFileOnException); string getFilename(); From 6dfe49b64052f9c1ea6bc7a43e4f650d8c3446b1 Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Tue, 13 Dec 2016 01:41:20 +0100 Subject: [PATCH 20/34] Compilation error --- wave_reader.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wave_reader.h b/wave_reader.h index 161d2e2..b9fffbf 100644 --- a/wave_reader.h +++ b/wave_reader.h @@ -57,7 +57,7 @@ class WaveReader int fileDescriptor; bool isHeaderRead; - vector* readData(unsigned bytesToRead, bool &forceStop, bool closeFileOnException); + vector* readData(unsigned bytesToRead, bool &forceStop); string getFilename(); }; From 437d96aae908c64b5647b17916e8e50e1296f90d Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Tue, 13 Dec 2016 01:43:50 +0100 Subject: [PATCH 21/34] Compilation error fix --- transmitter.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/transmitter.cpp b/transmitter.cpp index 5e89389..99ddcfc 100644 --- a/transmitter.cpp +++ b/transmitter.cpp @@ -126,7 +126,7 @@ void Transmitter::play(string filename, double frequency, bool loop) isRestart = false; vector* frames = reader->getFrames(bufferFrames, 0, doStop); - isEof = frames.size() < bufferFrames; + isEof = frames->size() < bufferFrames; buffer = frames; pthread_t thread; @@ -147,7 +147,7 @@ void Transmitter::play(string filename, double frequency, bool loop) while (!isEof && !doStop) { if (buffer == NULL) { frames = reader->getFrames(bufferFrames, frameOffset + bufferFrames, doStop); - isEof = frames.size() < bufferFrames; + isEof = frames->size() < bufferFrames; buffer = frames; } usleep(BUFFER_TIME / 2); @@ -155,8 +155,8 @@ void Transmitter::play(string filename, double frequency, bool loop) if (loop && !doStop) { frameOffset = 0; isRestart = true; - buffer = reader->getFrames(bufferFrames, 0, doStop); - isEof = frames.size() < bufferFrames; + frames = reader->getFrames(bufferFrames, 0, doStop); + isEof = frames->size() < bufferFrames; buffer = frames; usleep(BUFFER_TIME / 2); } else { From 479643f836aa162c3a6a1edd114bf8c435de0129 Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Tue, 13 Dec 2016 02:08:43 +0100 Subject: [PATCH 22/34] Bug fix --- wave_reader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wave_reader.cpp b/wave_reader.cpp index 4eef1da..f13a3bc 100644 --- a/wave_reader.cpp +++ b/wave_reader.cpp @@ -138,7 +138,7 @@ WaveReader::WaveReader(string filename, bool &forceStop) : throw error; } - if (!fileDescriptor != STDIN_FILENO) { + if (fileDescriptor != STDIN_FILENO) { dataOffset = lseek(fileDescriptor, 0, SEEK_CUR); } } From 0312b1ff2b170f823a18d01090224e17887241e3 Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Tue, 13 Dec 2016 02:09:32 +0100 Subject: [PATCH 23/34] Bug fix --- wave_reader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wave_reader.cpp b/wave_reader.cpp index f13a3bc..2fe8779 100644 --- a/wave_reader.cpp +++ b/wave_reader.cpp @@ -145,7 +145,7 @@ WaveReader::WaveReader(string filename, bool &forceStop) : WaveReader::~WaveReader() { - if (!fileDescriptor != STDIN_FILENO) { + if (fileDescriptor != STDIN_FILENO) { close(fileDescriptor); } } From ac213e04fffe72329f56e47885578a75b82ba9de Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Tue, 13 Dec 2016 02:30:14 +0100 Subject: [PATCH 24/34] Variable name changes --- transmitter.cpp | 44 ++++++++++++++++++++++---------------------- transmitter.h | 4 ++-- wave_reader.cpp | 3 +++ 3 files changed, 27 insertions(+), 24 deletions(-) diff --git a/transmitter.cpp b/transmitter.cpp index 99ddcfc..5b9e3f1 100644 --- a/transmitter.cpp +++ b/transmitter.cpp @@ -53,8 +53,8 @@ using std::ostringstream; #define ACCESS(base, offset) *(volatile unsigned*)((int)base + offset) #define ACCESS64(base, offset) *(volatile unsigned long long*)((int)base + offset) -bool Transmitter::isTransmitting = false; -bool Transmitter::isRestart = false; +bool Transmitter::transmitting = false; +bool Transmitter::restart = false; unsigned Transmitter::clockDivisor = 0; unsigned Transmitter::frameOffset = 0; vector* Transmitter::buffer = NULL; @@ -106,12 +106,12 @@ Transmitter* Transmitter::getInstance() void Transmitter::play(string filename, double frequency, bool loop) { - if (isTransmitting) { + if (transmitting) { throw ErrorReporter("Cannot play, transmitter already in use"); } - isTransmitting = true; - doStop = false; + transmitting = true; + stop = false; WaveReader* reader = new WaveReader(filename != "-" ? filename : string(), doStop); AudioFormat* format = reader->getFormat(); @@ -123,10 +123,10 @@ void Transmitter::play(string filename, double frequency, bool loop) unsigned bufferFrames = (unsigned)((unsigned long long)format->sampleRate * BUFFER_TIME / 1000000); frameOffset = 0; - isRestart = false; + restart = false; vector* frames = reader->getFrames(bufferFrames, 0, doStop); - isEof = frames->size() < bufferFrames; + eof = frames->size() < bufferFrames; buffer = frames; pthread_t thread; @@ -143,27 +143,27 @@ void Transmitter::play(string filename, double frequency, bool loop) usleep(BUFFER_TIME / 2); - while (!doStop) { - while (!isEof && !doStop) { + while (!stop) { + while (!eof && !stop) { if (buffer == NULL) { - frames = reader->getFrames(bufferFrames, frameOffset + bufferFrames, doStop); - isEof = frames->size() < bufferFrames; + frames = reader->getFrames(bufferFrames, frameOffset + bufferFrames, stop); + eof = frames->size() < bufferFrames; buffer = frames; } usleep(BUFFER_TIME / 2); } if (loop && !doStop) { frameOffset = 0; - isRestart = true; - frames = reader->getFrames(bufferFrames, 0, doStop); - isEof = frames->size() < bufferFrames; + restart = true; + frames = reader->getFrames(bufferFrames, 0, stop); + eof = frames->size() < bufferFrames; buffer = frames; usleep(BUFFER_TIME / 2); } else { - doStop = true; + stop = true; } } - isTransmitting = false; + transmitting = false; pthread_join(thread, NULL); @@ -194,19 +194,19 @@ void* Transmitter::transmit(void* params) playbackStart = ACCESS64(peripherals, TCNT_BASE); current = playbackStart; - while (isTransmitting) { + while (transmitting) { start = current; - while ((buffer == NULL) && isTransmitting) { + while ((buffer == NULL) && transmitting) { usleep(1); current = ACCESS64(peripherals, TCNT_BASE); } - if (!isTransmitting) { + if (!transmitting) { break; } - if (isRestart) { + if (restart) { playbackStart = current; start = current; - isRestart = false; + restart = false; } frames = buffer; frameOffset = (current - playbackStart) * (sampleRate) / 1000000; @@ -252,5 +252,5 @@ void* Transmitter::transmit(void* params) void Transmitter::stop() { - doStop = true; + stop = true; } diff --git a/transmitter.h b/transmitter.h index 746af87..47c0ba5 100644 --- a/transmitter.h +++ b/transmitter.h @@ -56,11 +56,11 @@ class Transmitter private: Transmitter(); - bool doStop, isEof; + bool stop, eof; static void* peripherals; static vector* buffer; - static bool isTransmitting, isRestart; + static bool transmitting, restart; static unsigned frameOffset, clockDivisor; static void* transmit(void* params); }; diff --git a/wave_reader.cpp b/wave_reader.cpp index 2fe8779..e5f3bd5 100644 --- a/wave_reader.cpp +++ b/wave_reader.cpp @@ -177,6 +177,9 @@ vector* WaveReader::readData(unsigned bytesToRead, bool &forceStop) if (bytes > 0) { bytesRead += bytes; } + if (bytesRead < bytesToRead) { + usleep(1); + } } if (forceStop) { From 6ea43912782ceab0129ce8708f296e4fddc11b90 Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Tue, 13 Dec 2016 02:43:28 +0100 Subject: [PATCH 25/34] Bug fix --- transmitter.cpp | 48 ++++++++++++++++++++++++++++++------------------ transmitter.h | 2 +- 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/transmitter.cpp b/transmitter.cpp index 5b9e3f1..aed7c4a 100644 --- a/transmitter.cpp +++ b/transmitter.cpp @@ -111,9 +111,9 @@ void Transmitter::play(string filename, double frequency, bool loop) } transmitting = true; - stop = false; + forceStop = false; - WaveReader* reader = new WaveReader(filename != "-" ? filename : string(), doStop); + WaveReader* reader = new WaveReader(filename != "-" ? filename : string(), forceStop); AudioFormat* format = reader->getFormat(); if (filename == "-") { usleep(STDIN_READ_DELAY); @@ -125,9 +125,15 @@ void Transmitter::play(string filename, double frequency, bool loop) frameOffset = 0; restart = false; - vector* frames = reader->getFrames(bufferFrames, 0, doStop); - eof = frames->size() < bufferFrames; - buffer = frames; + vector* frames = reader->getFrames(bufferFrames, 0, forceStop); + if (!forceStop) { + eof = frames->size() < bufferFrames; + buffer = frames; + } else { + delete format; + delete reader; + return; + } pthread_t thread; void* params = (void*)&format->sampleRate; @@ -143,24 +149,30 @@ void Transmitter::play(string filename, double frequency, bool loop) usleep(BUFFER_TIME / 2); - while (!stop) { - while (!eof && !stop) { + while (!forceStop) { + while (!eof && !forceStop) { if (buffer == NULL) { - frames = reader->getFrames(bufferFrames, frameOffset + bufferFrames, stop); - eof = frames->size() < bufferFrames; - buffer = frames; + frames = reader->getFrames(bufferFrames, frameOffset + bufferFrames, forceStop); + if (!forceStop) { + eof = frames->size() < bufferFrames; + buffer = frames; + } + } + if (!forceStop) { + usleep(BUFFER_TIME / 2); } - usleep(BUFFER_TIME / 2); } - if (loop && !doStop) { + if (loop && !forceStop) { frameOffset = 0; restart = true; - frames = reader->getFrames(bufferFrames, 0, stop); - eof = frames->size() < bufferFrames; - buffer = frames; - usleep(BUFFER_TIME / 2); + frames = reader->getFrames(bufferFrames, 0, forceStop); + if (!forceStop) { + eof = frames->size() < bufferFrames; + buffer = frames; + usleep(BUFFER_TIME / 2); + } } else { - stop = true; + forceStop = true; } } transmitting = false; @@ -252,5 +264,5 @@ void* Transmitter::transmit(void* params) void Transmitter::stop() { - stop = true; + forceStop = true; } diff --git a/transmitter.h b/transmitter.h index 47c0ba5..b7f2523 100644 --- a/transmitter.h +++ b/transmitter.h @@ -56,7 +56,7 @@ class Transmitter private: Transmitter(); - bool stop, eof; + bool forceStop, eof; static void* peripherals; static vector* buffer; From 0ab9e9d58689869412e762d4c79fb80b5e5a7fd9 Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Tue, 13 Dec 2016 02:49:36 +0100 Subject: [PATCH 26/34] Bug fixes --- wave_reader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wave_reader.cpp b/wave_reader.cpp index e5f3bd5..c97b532 100644 --- a/wave_reader.cpp +++ b/wave_reader.cpp @@ -170,8 +170,8 @@ vector* WaveReader::readData(unsigned bytesToRead, bool &forceStop) oss << "Error while reading " << getFilename() << ", file is corrupted"; throw ErrorReporter(oss.str()); } - if ((bytes == 0) && (fileDescriptor != STDIN_FILENO)) { - data->resize(bytesRead); + if ((bytes < bytesToRead - bytesRead) && (fileDescriptor != STDIN_FILENO)) { + data->resize(bytes); break; } if (bytes > 0) { From ca18d99e767d4be0b2d95112bc06ce649b2d894d Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Tue, 13 Dec 2016 02:53:57 +0100 Subject: [PATCH 27/34] Bug fixes --- wave_reader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wave_reader.cpp b/wave_reader.cpp index c97b532..533b787 100644 --- a/wave_reader.cpp +++ b/wave_reader.cpp @@ -170,7 +170,7 @@ vector* WaveReader::readData(unsigned bytesToRead, bool &forceStop) oss << "Error while reading " << getFilename() << ", file is corrupted"; throw ErrorReporter(oss.str()); } - if ((bytes < bytesToRead - bytesRead) && (fileDescriptor != STDIN_FILENO)) { + if ((bytes == 0) && (fileDescriptor != STDIN_FILENO)) { data->resize(bytes); break; } From d992c03d123096226b241115937a232989fa8bf7 Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Tue, 13 Dec 2016 21:23:27 +0100 Subject: [PATCH 28/34] Changed variable name --- transmitter.cpp | 14 +++++++------- transmitter.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/transmitter.cpp b/transmitter.cpp index aed7c4a..eb04b9a 100644 --- a/transmitter.cpp +++ b/transmitter.cpp @@ -53,7 +53,7 @@ using std::ostringstream; #define ACCESS(base, offset) *(volatile unsigned*)((int)base + offset) #define ACCESS64(base, offset) *(volatile unsigned long long*)((int)base + offset) -bool Transmitter::transmitting = false; +bool Transmitter::isTransmitting = false; bool Transmitter::restart = false; unsigned Transmitter::clockDivisor = 0; unsigned Transmitter::frameOffset = 0; @@ -106,11 +106,11 @@ Transmitter* Transmitter::getInstance() void Transmitter::play(string filename, double frequency, bool loop) { - if (transmitting) { + if (isTransmitting) { throw ErrorReporter("Cannot play, transmitter already in use"); } - transmitting = true; + isTransmitting = true; forceStop = false; WaveReader* reader = new WaveReader(filename != "-" ? filename : string(), forceStop); @@ -175,7 +175,7 @@ void Transmitter::play(string filename, double frequency, bool loop) forceStop = true; } } - transmitting = false; + isTransmitting = false; pthread_join(thread, NULL); @@ -206,13 +206,13 @@ void* Transmitter::transmit(void* params) playbackStart = ACCESS64(peripherals, TCNT_BASE); current = playbackStart; - while (transmitting) { + while (isTransmitting) { start = current; - while ((buffer == NULL) && transmitting) { + while ((buffer == NULL) && isTransmitting) { usleep(1); current = ACCESS64(peripherals, TCNT_BASE); } - if (!transmitting) { + if (!isTransmitting) { break; } if (restart) { diff --git a/transmitter.h b/transmitter.h index b7f2523..c8b0762 100644 --- a/transmitter.h +++ b/transmitter.h @@ -60,7 +60,7 @@ class Transmitter static void* peripherals; static vector* buffer; - static bool transmitting, restart; + static bool isTransmitting, restart; static unsigned frameOffset, clockDivisor; static void* transmit(void* params); }; From daf16ba29bd4b689b5628c2bfb8b2b070e48c02f Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Thu, 15 Dec 2016 00:55:21 +0100 Subject: [PATCH 29/34] Refactor --- transmitter.cpp | 102 ++++++++++++++++++++++++------------------------ transmitter.h | 2 +- wave_reader.cpp | 42 +++++++++----------- wave_reader.h | 1 - 4 files changed, 72 insertions(+), 75 deletions(-) diff --git a/transmitter.cpp b/transmitter.cpp index eb04b9a..29536eb 100644 --- a/transmitter.cpp +++ b/transmitter.cpp @@ -48,12 +48,10 @@ using std::ostringstream; #define CLK0DIV_BASE 0x00101074 #define TCNT_BASE 0x00003004 -#define STDIN_READ_DELAY 700000 - #define ACCESS(base, offset) *(volatile unsigned*)((int)base + offset) #define ACCESS64(base, offset) *(volatile unsigned long long*)((int)base + offset) -bool Transmitter::isTransmitting = false; +bool Transmitter::transmitting = false; bool Transmitter::restart = false; unsigned Transmitter::clockDivisor = 0; unsigned Transmitter::frameOffset = 0; @@ -106,18 +104,15 @@ Transmitter* Transmitter::getInstance() void Transmitter::play(string filename, double frequency, bool loop) { - if (isTransmitting) { + if (transmitting) { throw ErrorReporter("Cannot play, transmitter already in use"); } - isTransmitting = true; + transmitting = true; forceStop = false; - WaveReader* reader = new WaveReader(filename != "-" ? filename : string(), forceStop); + WaveReader* reader = reader = new WaveReader(filename != "-" ? filename : string(), forceStop); AudioFormat* format = reader->getFormat(); - if (filename == "-") { - usleep(STDIN_READ_DELAY); - } clockDivisor = (unsigned)((500 << 12) / frequency + 0.5); unsigned bufferFrames = (unsigned)((unsigned long long)format->sampleRate * BUFFER_TIME / 1000000); @@ -125,63 +120,70 @@ void Transmitter::play(string filename, double frequency, bool loop) frameOffset = 0; restart = false; - vector* frames = reader->getFrames(bufferFrames, 0, forceStop); - if (!forceStop) { + try { + vector* frames = reader->getFrames(bufferFrames, 0, forceStop); + if (frames == NULL) { + delete format; + delete reader; + return; + } eof = frames->size() < bufferFrames; buffer = frames; - } else { - delete format; - delete reader; - return; - } - - pthread_t thread; - void* params = (void*)&format->sampleRate; - int returnCode = pthread_create(&thread, NULL, &Transmitter::transmit, params); - if (returnCode) { - delete reader; - delete format; - ostringstream oss; - oss << "Cannot create new thread (code: " << returnCode << ")"; - throw ErrorReporter(oss.str()); - } + pthread_t thread; + void* params = (void*)&format->sampleRate; + + int returnCode = pthread_create(&thread, NULL, &Transmitter::transmit, params); + if (returnCode) { + delete reader; + delete format; + delete frames; + ostringstream oss; + oss << "Cannot create new thread (code: " << returnCode << ")"; + throw ErrorReporter(oss.str()); + } - usleep(BUFFER_TIME / 2); + usleep(BUFFER_TIME / 2); - while (!forceStop) { - while (!eof && !forceStop) { - if (buffer == NULL) { - frames = reader->getFrames(bufferFrames, frameOffset + bufferFrames, forceStop); - if (!forceStop) { + while (!forceStop) { + while (!eof && !forceStop) { + if (buffer == NULL) { + frames = reader->getFrames(bufferFrames, frameOffset + bufferFrames, forceStop); + if (frames == NULL) { + forceStop = true; + break; + } eof = frames->size() < bufferFrames; buffer = frames; } - } - if (!forceStop) { usleep(BUFFER_TIME / 2); } - } - if (loop && !forceStop) { - frameOffset = 0; - restart = true; - frames = reader->getFrames(bufferFrames, 0, forceStop); - if (!forceStop) { + if (loop && !forceStop) { + frameOffset = 0; + restart = true; + frames = reader->getFrames(bufferFrames, 0, forceStop); + if (frames == NULL) { + break; + } eof = frames->size() < bufferFrames; buffer = frames; usleep(BUFFER_TIME / 2); + } else { + forceStop = true; } - } else { - forceStop = true; } - } - isTransmitting = false; + transmitting = false; - pthread_join(thread, NULL); + pthread_join(thread, NULL); + } catch (ErrorReporter &error) { + delete reader; + delete format; + throw error; + } delete reader; delete format; -} + } void* Transmitter::transmit(void* params) { @@ -206,13 +208,13 @@ void* Transmitter::transmit(void* params) playbackStart = ACCESS64(peripherals, TCNT_BASE); current = playbackStart; - while (isTransmitting) { + while (transmitting) { start = current; - while ((buffer == NULL) && isTransmitting) { + while ((buffer == NULL) && transmitting) { usleep(1); current = ACCESS64(peripherals, TCNT_BASE); } - if (!isTransmitting) { + if (!transmitting) { break; } if (restart) { diff --git a/transmitter.h b/transmitter.h index c8b0762..b7f2523 100644 --- a/transmitter.h +++ b/transmitter.h @@ -60,7 +60,7 @@ class Transmitter static void* peripherals; static vector* buffer; - static bool isTransmitting, restart; + static bool transmitting, restart; static unsigned frameOffset, clockDivisor; static void* transmit(void* params); }; diff --git a/wave_reader.cpp b/wave_reader.cpp index 533b787..28d2bd8 100644 --- a/wave_reader.cpp +++ b/wave_reader.cpp @@ -43,7 +43,7 @@ using std::ostringstream; using std::exception; WaveReader::WaveReader(string filename, bool &forceStop) : - filename(filename), fileSize(0), isHeaderRead(false) + filename(filename), fileSize(0), headerComplete(false) { char* headerData = (char*)((void*)&header); vector* data; @@ -71,8 +71,8 @@ WaveReader::WaveReader(string filename, bool &forceStop) : bytesToRead = sizeof(PCMWaveHeader::chunkID) + sizeof(PCMWaveHeader::chunkSize) + sizeof(PCMWaveHeader::format); data = readData(bytesToRead, forceStop); - if (forceStop) { - return; + if (data == NULL) { + throw ErrorReporter("Cannot obtain header, program interrupted"); } memcpy(headerData, &(*data)[0], bytesToRead); headerOffset = bytesToRead; @@ -85,8 +85,8 @@ WaveReader::WaveReader(string filename, bool &forceStop) : bytesToRead = sizeof(PCMWaveHeader::subchunk1ID) + sizeof(PCMWaveHeader::subchunk1Size); data = readData(bytesToRead, forceStop); - if (forceStop) { - return; + if (data == NULL) { + throw ErrorReporter("Cannot obtain header, program interrupted"); } memcpy(&headerData[headerOffset], &(*data)[0], bytesToRead); headerOffset += bytesToRead; @@ -101,8 +101,8 @@ WaveReader::WaveReader(string filename, bool &forceStop) : } data = readData(header.subchunk1Size, forceStop); - if (forceStop) { - return; + if (data == NULL) { + throw ErrorReporter("Cannot obtain header, program interrupted"); } memcpy(&headerData[headerOffset], &(*data)[0], subchunk1MinSize); headerOffset += subchunk1MinSize; @@ -118,8 +118,8 @@ WaveReader::WaveReader(string filename, bool &forceStop) : bytesToRead = sizeof(PCMWaveHeader::subchunk2ID) + sizeof(PCMWaveHeader::subchunk2Size); data = readData(bytesToRead, forceStop); - if (forceStop) { - return; + if (data == NULL) { + throw ErrorReporter("Cannot obtain header, program interrupted"); } memcpy(&headerData[headerOffset], &(*data)[0], bytesToRead); headerOffset += bytesToRead; @@ -129,8 +129,6 @@ WaveReader::WaveReader(string filename, bool &forceStop) : oss << "Error while opening " << getFilename() << ", data corrupted"; throw ErrorReporter(oss.str()); } - - isHeaderRead = true; } catch (ErrorReporter &error) { if (fileDescriptor != STDIN_FILENO) { close(fileDescriptor); @@ -150,6 +148,10 @@ WaveReader::~WaveReader() } } +bool WaveReader::isHeaderLoaded() { + return isHeader; +} + vector* WaveReader::readData(unsigned bytesToRead, bool &forceStop) { unsigned bytesRead = 0; @@ -162,7 +164,7 @@ vector* WaveReader::readData(unsigned bytesToRead, bool &forceStop) ((bytes == 0) && !isHeaderRead && (fileDescriptor != STDIN_FILENO))) { delete data; - if (!isHeaderRead && (fileDescriptor != STDIN_FILENO)) { + if (fileDescriptor != STDIN_FILENO) { close(fileDescriptor); } @@ -170,14 +172,14 @@ vector* WaveReader::readData(unsigned bytesToRead, bool &forceStop) oss << "Error while reading " << getFilename() << ", file is corrupted"; throw ErrorReporter(oss.str()); } - if ((bytes == 0) && (fileDescriptor != STDIN_FILENO)) { - data->resize(bytes); - break; - } if (bytes > 0) { bytesRead += bytes; } if (bytesRead < bytesToRead) { + if (fileDescriptor != STDIN_FILENO) { + data->resize(bytes); + break; + } usleep(1); } } @@ -192,12 +194,6 @@ vector* WaveReader::readData(unsigned bytesToRead, bool &forceStop) vector* WaveReader::getFrames(unsigned frameCount, unsigned frameOffset, bool &forceStop) { unsigned bytesToRead, bytesLeft, bytesPerFrame, offset; - - if (!isHeaderRead) { - ostringstream oss; - throw ErrorReporter("Header wasn't read successfully!"); - } - vector* frames = new vector(); vector* data; @@ -221,7 +217,7 @@ vector* WaveReader::getFrames(unsigned frameCount, unsigned frameOffset, delete frames; throw error; } - if (forceStop) { + if (data == NULL) { delete frames; return NULL; } diff --git a/wave_reader.h b/wave_reader.h index b9fffbf..e27f323 100644 --- a/wave_reader.h +++ b/wave_reader.h @@ -55,7 +55,6 @@ class WaveReader PCMWaveHeader header; unsigned fileSize, dataOffset; int fileDescriptor; - bool isHeaderRead; vector* readData(unsigned bytesToRead, bool &forceStop); string getFilename(); From 68e05b2af9ed011019e8a40eacef76afa43b076e Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Thu, 15 Dec 2016 00:57:25 +0100 Subject: [PATCH 30/34] Code refactored --- wave_reader.cpp | 11 +---------- wave_reader.h | 2 +- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/wave_reader.cpp b/wave_reader.cpp index 28d2bd8..810fe3f 100644 --- a/wave_reader.cpp +++ b/wave_reader.cpp @@ -43,7 +43,7 @@ using std::ostringstream; using std::exception; WaveReader::WaveReader(string filename, bool &forceStop) : - filename(filename), fileSize(0), headerComplete(false) + filename(filename) { char* headerData = (char*)((void*)&header); vector* data; @@ -62,11 +62,6 @@ WaveReader::WaveReader(string filename, bool &forceStop) : throw ErrorReporter(oss.str()); } - if (fileDescriptor != STDIN_FILENO) { - fileSize = lseek(fileDescriptor, 0, SEEK_END); - lseek(fileDescriptor, 0, SEEK_SET); - } - try { bytesToRead = sizeof(PCMWaveHeader::chunkID) + sizeof(PCMWaveHeader::chunkSize) + sizeof(PCMWaveHeader::format); @@ -148,10 +143,6 @@ WaveReader::~WaveReader() } } -bool WaveReader::isHeaderLoaded() { - return isHeader; -} - vector* WaveReader::readData(unsigned bytesToRead, bool &forceStop) { unsigned bytesRead = 0; diff --git a/wave_reader.h b/wave_reader.h index e27f323..dea9cbc 100644 --- a/wave_reader.h +++ b/wave_reader.h @@ -53,7 +53,7 @@ class WaveReader private: string filename; PCMWaveHeader header; - unsigned fileSize, dataOffset; + unsigned dataOffset; int fileDescriptor; vector* readData(unsigned bytesToRead, bool &forceStop); From 36c44ebadc55b729ad277d56e097f31764a450ae Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Thu, 15 Dec 2016 01:11:05 +0100 Subject: [PATCH 31/34] Code refactored --- wave_reader.cpp | 14 +++++++------- wave_reader.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/wave_reader.cpp b/wave_reader.cpp index 810fe3f..1ce891e 100644 --- a/wave_reader.cpp +++ b/wave_reader.cpp @@ -65,7 +65,7 @@ WaveReader::WaveReader(string filename, bool &forceStop) : try { bytesToRead = sizeof(PCMWaveHeader::chunkID) + sizeof(PCMWaveHeader::chunkSize) + sizeof(PCMWaveHeader::format); - data = readData(bytesToRead, forceStop); + data = readData(bytesToRead, true, forceStop); if (data == NULL) { throw ErrorReporter("Cannot obtain header, program interrupted"); } @@ -79,7 +79,7 @@ WaveReader::WaveReader(string filename, bool &forceStop) : } bytesToRead = sizeof(PCMWaveHeader::subchunk1ID) + sizeof(PCMWaveHeader::subchunk1Size); - data = readData(bytesToRead, forceStop); + data = readData(bytesToRead, true, forceStop); if (data == NULL) { throw ErrorReporter("Cannot obtain header, program interrupted"); } @@ -95,7 +95,7 @@ WaveReader::WaveReader(string filename, bool &forceStop) : throw ErrorReporter(oss.str()); } - data = readData(header.subchunk1Size, forceStop); + data = readData(header.subchunk1Size, true, forceStop); if (data == NULL) { throw ErrorReporter("Cannot obtain header, program interrupted"); } @@ -112,7 +112,7 @@ WaveReader::WaveReader(string filename, bool &forceStop) : } bytesToRead = sizeof(PCMWaveHeader::subchunk2ID) + sizeof(PCMWaveHeader::subchunk2Size); - data = readData(bytesToRead, forceStop); + data = readData(bytesToRead, true, forceStop); if (data == NULL) { throw ErrorReporter("Cannot obtain header, program interrupted"); } @@ -143,7 +143,7 @@ WaveReader::~WaveReader() } } -vector* WaveReader::readData(unsigned bytesToRead, bool &forceStop) +vector* WaveReader::readData(unsigned bytesToRead, bool requireAll, bool &forceStop) { unsigned bytesRead = 0; vector* data = new vector(); @@ -152,7 +152,7 @@ vector* WaveReader::readData(unsigned bytesToRead, bool &forceStop) while ((bytesRead < bytesToRead) && !forceStop) { int bytes = read(fileDescriptor, &(*data)[bytesRead], bytesToRead - bytesRead); if (((bytes == -1) && ((fileDescriptor != STDIN_FILENO) || (errno != EAGAIN))) || - ((bytes == 0) && !isHeaderRead && (fileDescriptor != STDIN_FILENO))) { + ((bytes < bytesToRead) && requireAll && (fileDescriptor != STDIN_FILENO))) { delete data; if (fileDescriptor != STDIN_FILENO) { @@ -203,7 +203,7 @@ vector* WaveReader::getFrames(unsigned frameCount, unsigned frameOffset, } try { - data = readData(bytesToRead, forceStop); + data = readData(bytesToRead, false, forceStop); } catch (ErrorReporter &error) { delete frames; throw error; diff --git a/wave_reader.h b/wave_reader.h index dea9cbc..0b3022a 100644 --- a/wave_reader.h +++ b/wave_reader.h @@ -56,7 +56,7 @@ class WaveReader unsigned dataOffset; int fileDescriptor; - vector* readData(unsigned bytesToRead, bool &forceStop); + vector* readData(unsigned bytesToRead, bool requireAll, bool &forceStop); string getFilename(); }; From df3cec44242ee346f7bf0a8fbf4848cca579d8f8 Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Thu, 15 Dec 2016 01:14:25 +0100 Subject: [PATCH 32/34] Code refactored --- wave_reader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wave_reader.cpp b/wave_reader.cpp index 1ce891e..f04c3ac 100644 --- a/wave_reader.cpp +++ b/wave_reader.cpp @@ -152,7 +152,7 @@ vector* WaveReader::readData(unsigned bytesToRead, bool requireAll, bool & while ((bytesRead < bytesToRead) && !forceStop) { int bytes = read(fileDescriptor, &(*data)[bytesRead], bytesToRead - bytesRead); if (((bytes == -1) && ((fileDescriptor != STDIN_FILENO) || (errno != EAGAIN))) || - ((bytes < bytesToRead) && requireAll && (fileDescriptor != STDIN_FILENO))) { + (((unsigned)bytes < bytesToRead) && requireAll && (fileDescriptor != STDIN_FILENO))) { delete data; if (fileDescriptor != STDIN_FILENO) { From 5b4a4c65c7ca0c8b949db8e488cf904b86b66c54 Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Thu, 15 Dec 2016 01:15:38 +0100 Subject: [PATCH 33/34] Code refactored --- transmitter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/transmitter.cpp b/transmitter.cpp index 29536eb..2dc8ef8 100644 --- a/transmitter.cpp +++ b/transmitter.cpp @@ -111,7 +111,7 @@ void Transmitter::play(string filename, double frequency, bool loop) transmitting = true; forceStop = false; - WaveReader* reader = reader = new WaveReader(filename != "-" ? filename : string(), forceStop); + WaveReader* reader = new WaveReader(filename != "-" ? filename : string(), forceStop); AudioFormat* format = reader->getFormat(); clockDivisor = (unsigned)((500 << 12) / frequency + 0.5); From 49c68dc493dd04d90f1137eb126a7f862a31cb27 Mon Sep 17 00:00:00 2001 From: Marcin Kondej Date: Mon, 19 Dec 2016 18:02:24 +0100 Subject: [PATCH 34/34] Fixed issue #46 --- main.cpp | 1 + transmitter.cpp | 12 +++++++++--- wave_reader.cpp | 36 ++++++++++++++++++++++-------------- wave_reader.h | 7 ++++--- 4 files changed, 36 insertions(+), 20 deletions(-) diff --git a/main.cpp b/main.cpp index fe5a055..0191937 100644 --- a/main.cpp +++ b/main.cpp @@ -43,6 +43,7 @@ bool stop = false; Transmitter* transmitter = NULL; AudioFormat* getFormat(string filename) { + stop = false; WaveReader* reader = new WaveReader(filename, stop); AudioFormat* format = reader->getFormat(); delete reader; diff --git a/transmitter.cpp b/transmitter.cpp index 2dc8ef8..a1be702 100644 --- a/transmitter.cpp +++ b/transmitter.cpp @@ -121,7 +121,7 @@ void Transmitter::play(string filename, double frequency, bool loop) restart = false; try { - vector* frames = reader->getFrames(bufferFrames, 0, forceStop); + vector* frames = reader->getFrames(bufferFrames, forceStop); if (frames == NULL) { delete format; delete reader; @@ -148,7 +148,10 @@ void Transmitter::play(string filename, double frequency, bool loop) while (!forceStop) { while (!eof && !forceStop) { if (buffer == NULL) { - frames = reader->getFrames(bufferFrames, frameOffset + bufferFrames, forceStop); + if (!reader->setFrameOffset(frameOffset + bufferFrames)) { + break; + } + frames = reader->getFrames(bufferFrames, forceStop); if (frames == NULL) { forceStop = true; break; @@ -161,7 +164,10 @@ void Transmitter::play(string filename, double frequency, bool loop) if (loop && !forceStop) { frameOffset = 0; restart = true; - frames = reader->getFrames(bufferFrames, 0, forceStop); + if (reader->setFrameOffset(0)) { + break; + } + frames = reader->getFrames(bufferFrames, forceStop); if (frames == NULL) { break; } diff --git a/wave_reader.cpp b/wave_reader.cpp index f04c3ac..336a073 100644 --- a/wave_reader.cpp +++ b/wave_reader.cpp @@ -43,7 +43,7 @@ using std::ostringstream; using std::exception; WaveReader::WaveReader(string filename, bool &forceStop) : - filename(filename) + filename(filename), currentOffset(0) { char* headerData = (char*)((void*)&header); vector* data; @@ -143,7 +143,7 @@ WaveReader::~WaveReader() } } -vector* WaveReader::readData(unsigned bytesToRead, bool requireAll, bool &forceStop) +vector* WaveReader::readData(unsigned bytesToRead, bool headerBytes, bool &forceStop) { unsigned bytesRead = 0; vector* data = new vector(); @@ -152,7 +152,7 @@ vector* WaveReader::readData(unsigned bytesToRead, bool requireAll, bool & while ((bytesRead < bytesToRead) && !forceStop) { int bytes = read(fileDescriptor, &(*data)[bytesRead], bytesToRead - bytesRead); if (((bytes == -1) && ((fileDescriptor != STDIN_FILENO) || (errno != EAGAIN))) || - (((unsigned)bytes < bytesToRead) && requireAll && (fileDescriptor != STDIN_FILENO))) { + (((unsigned)bytes < bytesToRead) && headerBytes && (fileDescriptor != STDIN_FILENO))) { delete data; if (fileDescriptor != STDIN_FILENO) { @@ -175,6 +175,10 @@ vector* WaveReader::readData(unsigned bytesToRead, bool requireAll, bool & } } + if (!headerBytes) { + currentOffset += bytesRead; + } + if (forceStop) { delete data; data = NULL; @@ -183,23 +187,17 @@ vector* WaveReader::readData(unsigned bytesToRead, bool requireAll, bool & return data; } -vector* WaveReader::getFrames(unsigned frameCount, unsigned frameOffset, bool &forceStop) { +vector* WaveReader::getFrames(unsigned frameCount, bool &forceStop) { unsigned bytesToRead, bytesLeft, bytesPerFrame, offset; vector* frames = new vector(); vector* data; bytesPerFrame = (header.bitsPerSample >> 3) * header.channels; bytesToRead = frameCount * bytesPerFrame; - - if (fileDescriptor != STDIN_FILENO) { - bytesLeft = header.subchunk2Size - frameOffset * bytesPerFrame; - if (bytesToRead > bytesLeft) { - bytesToRead = bytesLeft - bytesLeft % bytesPerFrame; - frameCount = bytesToRead / bytesPerFrame; - } - if (lseek(fileDescriptor, dataOffset + frameOffset * bytesPerFrame, SEEK_SET) == -1) { - return frames; - } + bytesLeft = header.subchunk2Size - currentOffset; + if (bytesToRead > bytesLeft) { + bytesToRead = bytesLeft - bytesLeft % bytesPerFrame; + frameCount = bytesToRead / bytesPerFrame; } try { @@ -237,6 +235,16 @@ vector* WaveReader::getFrames(unsigned frameCount, unsigned frameOffset, return frames; } +bool WaveReader::setFrameOffset(unsigned frameOffset) { + if (fileDescriptor != STDIN_FILENO) { + currentOffset = frameOffset * (header.bitsPerSample >> 3) * header.channels; + if (lseek(fileDescriptor, dataOffset + currentOffset, SEEK_SET) == -1) { + return false; + } + } + return true; +} + string WaveReader::getFilename() { return fileDescriptor != STDIN_FILENO ? filename : "STDIN"; diff --git a/wave_reader.h b/wave_reader.h index 0b3022a..a9b2317 100644 --- a/wave_reader.h +++ b/wave_reader.h @@ -49,14 +49,15 @@ class WaveReader virtual ~WaveReader(); AudioFormat* getFormat(); - vector* getFrames(unsigned frameCount, unsigned frameOffset, bool &forceStop); + vector* getFrames(unsigned frameCount, bool &forceStop); + bool setFrameOffset(unsigned frameOffset); private: string filename; PCMWaveHeader header; - unsigned dataOffset; + unsigned dataOffset, currentOffset; int fileDescriptor; - vector* readData(unsigned bytesToRead, bool requireAll, bool &forceStop); + vector* readData(unsigned bytesToRead, bool headerBytes, bool &forceStop); string getFilename(); };