diff --git a/audio_format.h b/audio_format.h
index 985d135..84f80d8 100644
--- a/audio_format.h
+++ b/audio_format.h
@@ -8,6 +8,7 @@
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.
diff --git a/error_reporter.cpp b/error_reporter.cpp
index 2a73984..5fc40e4 100644
--- a/error_reporter.cpp
+++ b/error_reporter.cpp
@@ -8,6 +8,7 @@
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.
diff --git a/error_reporter.h b/error_reporter.h
index 5e8c168..ab5b958 100644
--- a/error_reporter.h
+++ b/error_reporter.h
@@ -8,6 +8,7 @@
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.
diff --git a/fm_transmitter.cbp b/fm_transmitter.cbp
index f6cd1b1..b302fbd 100644
--- a/fm_transmitter.cbp
+++ b/fm_transmitter.cbp
@@ -43,6 +43,8 @@
+
+
diff --git a/fm_transmitter.depend b/fm_transmitter.depend
index 7db4c44..207e4af 100644
--- a/fm_transmitter.depend
+++ b/fm_transmitter.depend
@@ -52,31 +52,33 @@
1437597555 /home/pi/Projects/fm_transmitter/error_reporter.h
-1435357888 source:/home/marcin/Repozytoria/fm_transmitter/error_reporter.cpp
+1438083081 source:/home/marcin/Repozytoria/fm_transmitter/error_reporter.cpp
"error_reporter.h"
-1435358040 /home/marcin/Repozytoria/fm_transmitter/error_reporter.h
+1438083081 /home/marcin/Repozytoria/fm_transmitter/error_reporter.h
-1436380561 source:/home/marcin/Repozytoria/fm_transmitter/main.cpp
+1438083081 source:/home/marcin/Repozytoria/fm_transmitter/main.cpp
"transmitter.h"
-1436384608 /home/marcin/Repozytoria/fm_transmitter/transmitter.h
+1438084671 /home/marcin/Repozytoria/fm_transmitter/transmitter.h
"wave_reader.h"
- "audio_format.h"
+ "stdin_reader.h"
+ "error_reporter.h"
-1436380561 /home/marcin/Repozytoria/fm_transmitter/wave_reader.h
+1438090504 /home/marcin/Repozytoria/fm_transmitter/wave_reader.h
- "error_reporter.h"
+ "audio_format.h"
"pcm_wave_header.h"
+ "error_reporter.h"
-1435355417 /home/marcin/Repozytoria/fm_transmitter/pcm_wave_header.h
+1438083081 /home/marcin/Repozytoria/fm_transmitter/pcm_wave_header.h
-1436384617 source:/home/marcin/Repozytoria/fm_transmitter/transmitter.cpp
+1438084940 source:/home/marcin/Repozytoria/fm_transmitter/transmitter.cpp
"transmitter.h"
@@ -85,11 +87,10 @@
-
-1435675612 /home/marcin/Repozytoria/fm_transmitter/audio_format.h
+1438083081 /home/marcin/Repozytoria/fm_transmitter/audio_format.h
-1436380561 source:/home/marcin/Repozytoria/fm_transmitter/wave_reader.cpp
+1438090504 source:/home/marcin/Repozytoria/fm_transmitter/wave_reader.cpp
"wave_reader.h"
@@ -236,3 +237,15 @@
1437741006 source:/home/pi/new_transmitter/stdin_reader.cpp
"stdin_reader.h"
+1438091088 /home/marcin/Repozytoria/fm_transmitter/stdin_reader.h
+
+
+ "audio_format.h"
+ "error_reporter.h"
+
+1438085397 source:/home/marcin/Repozytoria/fm_transmitter/stdin_reader.cpp
+ "stdin_reader.h"
+
+
+
+
diff --git a/main.cpp b/main.cpp
index 9635632..e8f76dc 100644
--- a/main.cpp
+++ b/main.cpp
@@ -8,6 +8,7 @@
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.
@@ -51,11 +52,11 @@ int main(int argc, char **argv)
try {
transmitter = new Transmitter(filename, frequency);
- AudioFormat *format = transmitter->getFormat();
+ AudioFormat format = transmitter->getFormat();
cout << "Playing: " << filename << ", "
- << format->sampleRate << " Hz, "
- << format->bitsPerSample << " bits, "
- << ((format->channels > 0x01) ? "stereo" : "mono") << endl;
+ << format.sampleRate << " Hz, "
+ << format.bitsPerSample << " bits, "
+ << ((format.channels > 0x01) ? "stereo" : "mono") << endl;
transmitter->play();
} catch (exception &e) {
diff --git a/pcm_wave_header.h b/pcm_wave_header.h
index 152cd31..fd74de2 100644
--- a/pcm_wave_header.h
+++ b/pcm_wave_header.h
@@ -8,6 +8,7 @@
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.
diff --git a/stdin_reader.cpp b/stdin_reader.cpp
index 570b75f..0dfcf43 100644
--- a/stdin_reader.cpp
+++ b/stdin_reader.cpp
@@ -1,22 +1,124 @@
+/*
+ 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
+#include
+#include
+
+using std::exception;
+using std::ostringstream;
+
StdinReader::StdinReader()
-{
- //ctor
-}
-
-StdinReader::~StdinReader()
-{
- //dtor
+{
+ ostringstream oss;
+
+ doStop = false;
+
+ int returnCode = pthread_create(&thread, NULL, (volatile void*)(&this->readStdin), NULL);
+ if (returnCode) {
+ oss << "Cannot create new thread (code: " << returnCode << ")";
+ errorMessage = oss.str();
+ throw exception();
+ }
}
-vector *StdinReader::getFrames(unsigned int count)
+StdinReader::~StdinReader()
{
- return new vector();
+ doStop = true;
+ pthread_join(thread, NULL);
+}
+
+StdinReader *StdinReader::getInstance()
+{
+ static StdinReader instance;
+ return &instance;
+}
+
+void StdinReader::readStdin()
+{
+ char *readBuffer = new char[BUFFER_SIZE];
+ while(!doStop) {
+ int bytes = read(STDIN_FILENO, readBuffer, BUFFER_SIZE);
+ buffer.insert(buffer.end(), readBuffer, readBuffer + bytes);
+ usleep(1);
+ }
+}
+
+vector *StdinReader::getFrames(unsigned int frameCount)
+{
+ unsigned int bytesToRead, bufferSize, bytesPerFrame, offset, zeroOffset, restBytes;
+ vector *frames = new vector();
+
+ bufferSize = buffer.size();
+ bytesPerFrame = (BITS_PER_SAMPLE >> 3) * CHANNELS;
+ bytesToRead = frameCount * bytesPerFrame;
+ restBytes = bufferSize % bytesPerFrame;
+
+ if (bytesToRead > bufferSize) {
+ bytesToRead = bufferSize - restBytes;
+ frameCount = bytesToRead / bytesPerFrame;
+ }
+
+ zeroOffset = bufferSize - bytesToRead - restBytes;
+
+ for (unsigned int i = 0; i < frameCount; i++) {
+ offset = zeroOffset + bytesPerFrame * i;
+ if (CHANNELS != 1) {
+ if (BITS_PER_SAMPLE != 8) {
+ frames->push_back(((int)(signed char)buffer[offset + 1] + (int)(signed char)buffer[offset + 3]) / (float)0x100);
+ } else {
+ frames->push_back(((int)buffer[offset] + (int)buffer[offset + 1]) / (float)0x100 - 1.0f);
+ }
+ } else {
+ if (BITS_PER_SAMPLE != 8) {
+ frames->push_back((signed char)buffer[offset + 1] / (float)0x80);
+ } else {
+ frames->push_back(buffer[offset] / (float)0x80 - 1.0f);
+ }
+ }
+ }
+
+ buffer.clear();
+
+ return frames;
}
AudioFormat *StdinReader::getFormat()
{
AudioFormat *format = new AudioFormat;
+ format->sampleRate = SAMPLE_RATE;
+ format->bitsPerSample = BITS_PER_SAMPLE;
+ format->channels = CHANNELS;
return format;
}
diff --git a/stdin_reader.h b/stdin_reader.h
index d9e1d4f..a281836 100644
--- a/stdin_reader.h
+++ b/stdin_reader.h
@@ -1,19 +1,66 @@
+/*
+ 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 BUFFER_SIZE 128
+#define SAMPLE_RATE 22500
+#define BITS_PER_SAMPLE 1
+#define CHANNELS 1
using std::vector;
-class StdinReader
+class StdinReader : public ErrorReporter
{
public:
- StdinReader();
virtual ~StdinReader();
- vector *getFrames(unsigned int count);
+ pthread_t thread;
+ static StdinReader *getInstance();
+ vector *getFrames(unsigned int frameCount);
AudioFormat *getFormat();
+ private:
+ StdinReader();
+
+ bool doStop;
+ void readStdin();
+ vector buffer;
};
#endif // STDIN_READER_H
diff --git a/transmitter.cpp b/transmitter.cpp
index 343e6bc..7c46e47 100644
--- a/transmitter.cpp
+++ b/transmitter.cpp
@@ -8,6 +8,7 @@
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.
@@ -46,8 +47,6 @@ using std::ostringstream;
#define ACCESS64(base, offset) *(volatile unsigned long long*)((int)base + offset)
bool Transmitter::isTransmitting = false;
-vector *Transmitter::buffer = NULL;
-unsigned int Transmitter::frameOffset = 0;
Transmitter::Transmitter(string filename, double frequency) :
readStdin(filename == "-")
@@ -88,16 +87,15 @@ Transmitter::Transmitter(string filename, double frequency) :
peripherals = (volatile unsigned*)peripheralsMap;
+ AudioFormat *audioFormat;
if (!readStdin) {
waveReader = new WaveReader(filename);
- format = waveReader->getFormat();
+ audioFormat = waveReader->getFormat();
} else {
- stdinReader = new StdinReader();
- format = stdinReader->getFormat();
+ stdinReader = StdinReader::getInstance();
+ audioFormat = stdinReader->getFormat();
}
-
- ACCESS(peripherals, 0x00200000) = (ACCESS(peripherals, 0x00200000) & 0xFFFF8FFF) | (0x01 << 14);
- ACCESS(peripherals, 0x00101070) = (0x5A << 24) | (0x01 << 9) | (0x01 << 4) | 0x06;
+ format = *audioFormat;
clockDivisor = (unsigned int)((500 << 12) / frequency + 0.5);
}
@@ -112,22 +110,15 @@ void Transmitter::play()
throw exception();
}
+ frameOffset = 0;
isTransmitting = true;
pthread_t thread;
- int returnCode;
- frameOffset = 0;
-
- unsigned int bufferFrames = (unsigned int)((unsigned long long)format->sampleRate * BUFFER_TIME / 1000000);
+ unsigned int bufferFrames = (unsigned int)((unsigned long long)format.sampleRate * BUFFER_TIME / 1000000);
buffer = (!readStdin) ? waveReader->getFrames(bufferFrames, frameOffset) : stdinReader->getFrames(bufferFrames);
- void *params[3];
- params[0] = &format->sampleRate;
- params[1] = &clockDivisor;
- params[2] = peripherals;
-
- returnCode = pthread_create(&thread, NULL, &Transmitter::transmit, (void*)params);
+ int returnCode = pthread_create(&thread, NULL, (volatile void*)(&this->transmit), NULL);
if (returnCode) {
oss << "Cannot create new thread (code: " << returnCode << ")";
errorMessage = oss.str();
@@ -147,16 +138,15 @@ void Transmitter::play()
pthread_join(thread, NULL);
}
-void Transmitter::transmit(void *params)
+void Transmitter::transmit(void*)
{
unsigned long long current, start, playbackStart;
unsigned int offset = 0, length, temp;
vector *frames;
float *data;
- unsigned int sampleRate = *((unsigned int**)params)[0];
- unsigned int clockDivisor = *((unsigned int**)params)[1];
- volatile unsigned *peripherals = ((unsigned int**)params)[2];
+ ACCESS(peripherals, 0x00200000) = (ACCESS(peripherals, 0x00200000) & 0xFFFF8FFF) | (0x01 << 14);
+ ACCESS(peripherals, 0x00101070) = (0x5A << 24) | (0x01 << 9) | (0x01 << 4) | 0x06;
playbackStart = ACCESS64(peripherals, 0x00003004);
current = playbackStart;
@@ -168,7 +158,7 @@ void Transmitter::transmit(void *params)
current = ACCESS64(peripherals, 0x00003004);
}
frames = buffer;
- frameOffset = (current - playbackStart) * sampleRate / 1000000;
+ frameOffset = (current - playbackStart) * format.sampleRate / 1000000;
buffer = NULL;
length = frames->size();
@@ -189,7 +179,7 @@ void Transmitter::transmit(void *params)
usleep(1);
current = ACCESS64(peripherals, 0x00003004);
- offset = (current - start) * sampleRate / 1000000;
+ offset = (current - start) * format.sampleRate / 1000000;
}
}
@@ -197,21 +187,21 @@ void Transmitter::transmit(void *params)
delete frames;
}
+
+ ACCESS(peripherals, 0x00101070) = (0x5A << 24);
}
Transmitter::~Transmitter()
{
- ACCESS(peripherals, 0x00101070) = (0x5A << 24);
munmap(peripherals, 0x002FFFFF);
if (!readStdin) {
delete waveReader;
} else {
delete stdinReader;
}
- delete format;
}
-AudioFormat *Transmitter::getFormat()
+AudioFormat& Transmitter::getFormat()
{
return format;
}
diff --git a/transmitter.h b/transmitter.h
index 2bc3bda..af04c51 100644
--- a/transmitter.h
+++ b/transmitter.h
@@ -8,6 +8,7 @@
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.
@@ -35,6 +36,7 @@
#include "wave_reader.h"
#include "stdin_reader.h"
+#include "error_reporter.h"
#define BUFFER_TIME 1000000
@@ -46,21 +48,21 @@ class Transmitter : public ErrorReporter
Transmitter(string filename, double frequency);
virtual ~Transmitter();
- AudioFormat *getFormat();
+ AudioFormat &getFormat();
void play();
private:
bool readStdin;
- AudioFormat *format;
+ AudioFormat format;
WaveReader *waveReader;
StdinReader *stdinReader;
unsigned int clockDivisor;
volatile unsigned *peripherals;
- static vector *buffer;
+ vector *buffer;
+ unsigned int frameOffset;
static bool isTransmitting;
- static unsigned int frameOffset;
- static void transmit(void *params);
+ void transmit(void*);
};
#endif // TRANSMITTER_H
diff --git a/wave_reader.cpp b/wave_reader.cpp
index 7a14e1b..ee9c446 100644
--- a/wave_reader.cpp
+++ b/wave_reader.cpp
@@ -8,6 +8,7 @@
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.
@@ -35,8 +36,6 @@
#include
#include
-#include
-
using std::exception;
using std::ostringstream;
@@ -142,12 +141,11 @@ vector *WaveReader::readData(unsigned int bytesToRead, bool closeFileOnExc
return data;
}
-vector *WaveReader::getFrames(unsigned int count, unsigned int frameOffset) {
- unsigned int bytesToRead, bytesLeft, bytesPerFrame, frameCount, offset;
+vector *WaveReader::getFrames(unsigned int frameCount, unsigned int frameOffset) {
+ unsigned int bytesToRead, bytesLeft, bytesPerFrame, offset;
vector *frames = new vector();
vector *data;
- frameCount = count;
bytesPerFrame = (header.bitsPerSample >> 3) * header.channels;
bytesToRead = frameCount * bytesPerFrame;
bytesLeft = header.subchunk2Size - frameOffset * bytesPerFrame;
diff --git a/wave_reader.h b/wave_reader.h
index e411ee3..40fd245 100644
--- a/wave_reader.h
+++ b/wave_reader.h
@@ -8,6 +8,7 @@
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.
@@ -36,9 +37,9 @@
#include
#include
#include
-#include "error_reporter.h"
-#include "pcm_wave_header.h"
#include "audio_format.h"
+#include "pcm_wave_header.h"
+#include "error_reporter.h"
using std::vector;
using std::string;
@@ -51,7 +52,7 @@ class WaveReader : public ErrorReporter
virtual ~WaveReader();
AudioFormat *getFormat();
- vector *getFrames(unsigned int count, unsigned int offset);
+ vector *getFrames(unsigned int frameCount, unsigned int frameOffset);
bool isEnd();
private:
string filename;