kopia lustrzana https://github.com/markondej/fm_transmitter
read from stdin
rodzic
bc0b0d4a33
commit
e47723a788
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification, are
|
Redistribution and use in source and binary forms, with or without modification, are
|
||||||
permitted provided that the following conditions are met:
|
permitted provided that the following conditions are met:
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this list
|
1. Redistributions of source code must retain the above copyright notice, this list
|
||||||
of conditions and the following disclaimer.
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification, are
|
Redistribution and use in source and binary forms, with or without modification, are
|
||||||
permitted provided that the following conditions are met:
|
permitted provided that the following conditions are met:
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this list
|
1. Redistributions of source code must retain the above copyright notice, this list
|
||||||
of conditions and the following disclaimer.
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification, are
|
Redistribution and use in source and binary forms, with or without modification, are
|
||||||
permitted provided that the following conditions are met:
|
permitted provided that the following conditions are met:
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this list
|
1. Redistributions of source code must retain the above copyright notice, this list
|
||||||
of conditions and the following disclaimer.
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,8 @@
|
||||||
<Unit filename="error_reporter.h" />
|
<Unit filename="error_reporter.h" />
|
||||||
<Unit filename="main.cpp" />
|
<Unit filename="main.cpp" />
|
||||||
<Unit filename="pcm_wave_header.h" />
|
<Unit filename="pcm_wave_header.h" />
|
||||||
|
<Unit filename="stdin_reader.cpp" />
|
||||||
|
<Unit filename="stdin_reader.h" />
|
||||||
<Unit filename="transmitter.cpp" />
|
<Unit filename="transmitter.cpp" />
|
||||||
<Unit filename="transmitter.h" />
|
<Unit filename="transmitter.h" />
|
||||||
<Unit filename="wave_reader.cpp" />
|
<Unit filename="wave_reader.cpp" />
|
||||||
|
|
|
@ -52,31 +52,33 @@
|
||||||
1437597555 /home/pi/Projects/fm_transmitter/error_reporter.h
|
1437597555 /home/pi/Projects/fm_transmitter/error_reporter.h
|
||||||
<string>
|
<string>
|
||||||
|
|
||||||
1435357888 source:/home/marcin/Repozytoria/fm_transmitter/error_reporter.cpp
|
1438083081 source:/home/marcin/Repozytoria/fm_transmitter/error_reporter.cpp
|
||||||
"error_reporter.h"
|
"error_reporter.h"
|
||||||
|
|
||||||
1435358040 /home/marcin/Repozytoria/fm_transmitter/error_reporter.h
|
1438083081 /home/marcin/Repozytoria/fm_transmitter/error_reporter.h
|
||||||
<string>
|
<string>
|
||||||
|
|
||||||
1436380561 source:/home/marcin/Repozytoria/fm_transmitter/main.cpp
|
1438083081 source:/home/marcin/Repozytoria/fm_transmitter/main.cpp
|
||||||
<iostream>
|
<iostream>
|
||||||
"transmitter.h"
|
"transmitter.h"
|
||||||
<cstdlib>
|
<cstdlib>
|
||||||
|
|
||||||
1436384608 /home/marcin/Repozytoria/fm_transmitter/transmitter.h
|
1438084671 /home/marcin/Repozytoria/fm_transmitter/transmitter.h
|
||||||
"wave_reader.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
|
||||||
<string>
|
<string>
|
||||||
<vector>
|
<vector>
|
||||||
<fstream>
|
<fstream>
|
||||||
"error_reporter.h"
|
"audio_format.h"
|
||||||
"pcm_wave_header.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"
|
"transmitter.h"
|
||||||
<exception>
|
<exception>
|
||||||
<sstream>
|
<sstream>
|
||||||
|
@ -85,11 +87,10 @@
|
||||||
<unistd.h>
|
<unistd.h>
|
||||||
<sys/mman.h>
|
<sys/mman.h>
|
||||||
<fcntl.h>
|
<fcntl.h>
|
||||||
<pthread.h>
|
|
||||||
|
|
||||||
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"
|
"wave_reader.h"
|
||||||
<exception>
|
<exception>
|
||||||
<sstream>
|
<sstream>
|
||||||
|
@ -236,3 +237,15 @@
|
||||||
1437741006 source:/home/pi/new_transmitter/stdin_reader.cpp
|
1437741006 source:/home/pi/new_transmitter/stdin_reader.cpp
|
||||||
"stdin_reader.h"
|
"stdin_reader.h"
|
||||||
|
|
||||||
|
1438091088 /home/marcin/Repozytoria/fm_transmitter/stdin_reader.h
|
||||||
|
<vector>
|
||||||
|
<fcntl.h>
|
||||||
|
"audio_format.h"
|
||||||
|
"error_reporter.h"
|
||||||
|
|
||||||
|
1438085397 source:/home/marcin/Repozytoria/fm_transmitter/stdin_reader.cpp
|
||||||
|
"stdin_reader.h"
|
||||||
|
<exception>
|
||||||
|
<sstream>
|
||||||
|
<unistd.h>
|
||||||
|
|
||||||
|
|
9
main.cpp
9
main.cpp
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification, are
|
Redistribution and use in source and binary forms, with or without modification, are
|
||||||
permitted provided that the following conditions are met:
|
permitted provided that the following conditions are met:
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this list
|
1. Redistributions of source code must retain the above copyright notice, this list
|
||||||
of conditions and the following disclaimer.
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
@ -51,11 +52,11 @@ int main(int argc, char **argv)
|
||||||
try {
|
try {
|
||||||
transmitter = new Transmitter(filename, frequency);
|
transmitter = new Transmitter(filename, frequency);
|
||||||
|
|
||||||
AudioFormat *format = transmitter->getFormat();
|
AudioFormat format = transmitter->getFormat();
|
||||||
cout << "Playing: " << filename << ", "
|
cout << "Playing: " << filename << ", "
|
||||||
<< format->sampleRate << " Hz, "
|
<< format.sampleRate << " Hz, "
|
||||||
<< format->bitsPerSample << " bits, "
|
<< format.bitsPerSample << " bits, "
|
||||||
<< ((format->channels > 0x01) ? "stereo" : "mono") << endl;
|
<< ((format.channels > 0x01) ? "stereo" : "mono") << endl;
|
||||||
|
|
||||||
transmitter->play();
|
transmitter->play();
|
||||||
} catch (exception &e) {
|
} catch (exception &e) {
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification, are
|
Redistribution and use in source and binary forms, with or without modification, are
|
||||||
permitted provided that the following conditions are met:
|
permitted provided that the following conditions are met:
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this list
|
1. Redistributions of source code must retain the above copyright notice, this list
|
||||||
of conditions and the following disclaimer.
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
|
122
stdin_reader.cpp
122
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 "stdin_reader.h"
|
||||||
|
#include <exception>
|
||||||
|
#include <sstream>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
using std::exception;
|
||||||
|
using std::ostringstream;
|
||||||
|
|
||||||
StdinReader::StdinReader()
|
StdinReader::StdinReader()
|
||||||
{
|
{
|
||||||
//ctor
|
ostringstream oss;
|
||||||
}
|
|
||||||
|
doStop = false;
|
||||||
StdinReader::~StdinReader()
|
|
||||||
{
|
int returnCode = pthread_create(&thread, NULL, (volatile void*)(&this->readStdin), NULL);
|
||||||
//dtor
|
if (returnCode) {
|
||||||
|
oss << "Cannot create new thread (code: " << returnCode << ")";
|
||||||
|
errorMessage = oss.str();
|
||||||
|
throw exception();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<float> *StdinReader::getFrames(unsigned int count)
|
StdinReader::~StdinReader()
|
||||||
{
|
{
|
||||||
return new vector<float>();
|
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<float> *StdinReader::getFrames(unsigned int frameCount)
|
||||||
|
{
|
||||||
|
unsigned int bytesToRead, bufferSize, bytesPerFrame, offset, zeroOffset, restBytes;
|
||||||
|
vector<float> *frames = new vector<float>();
|
||||||
|
|
||||||
|
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 *StdinReader::getFormat()
|
||||||
{
|
{
|
||||||
AudioFormat *format = new AudioFormat;
|
AudioFormat *format = new AudioFormat;
|
||||||
|
format->sampleRate = SAMPLE_RATE;
|
||||||
|
format->bitsPerSample = BITS_PER_SAMPLE;
|
||||||
|
format->channels = CHANNELS;
|
||||||
return format;
|
return format;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
#ifndef STDIN_READER_H
|
||||||
#define STDIN_READER_H
|
#define STDIN_READER_H
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <fcntl.h>
|
||||||
#include "audio_format.h"
|
#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;
|
using std::vector;
|
||||||
|
|
||||||
class StdinReader
|
class StdinReader : public ErrorReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
StdinReader();
|
|
||||||
virtual ~StdinReader();
|
virtual ~StdinReader();
|
||||||
|
|
||||||
vector<float> *getFrames(unsigned int count);
|
pthread_t thread;
|
||||||
|
static StdinReader *getInstance();
|
||||||
|
vector<float> *getFrames(unsigned int frameCount);
|
||||||
AudioFormat *getFormat();
|
AudioFormat *getFormat();
|
||||||
|
private:
|
||||||
|
StdinReader();
|
||||||
|
|
||||||
|
bool doStop;
|
||||||
|
void readStdin();
|
||||||
|
vector<char> buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // STDIN_READER_H
|
#endif // STDIN_READER_H
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification, are
|
Redistribution and use in source and binary forms, with or without modification, are
|
||||||
permitted provided that the following conditions are met:
|
permitted provided that the following conditions are met:
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this list
|
1. Redistributions of source code must retain the above copyright notice, this list
|
||||||
of conditions and the following disclaimer.
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
@ -46,8 +47,6 @@ using std::ostringstream;
|
||||||
#define ACCESS64(base, offset) *(volatile unsigned long long*)((int)base + offset)
|
#define ACCESS64(base, offset) *(volatile unsigned long long*)((int)base + offset)
|
||||||
|
|
||||||
bool Transmitter::isTransmitting = false;
|
bool Transmitter::isTransmitting = false;
|
||||||
vector<float> *Transmitter::buffer = NULL;
|
|
||||||
unsigned int Transmitter::frameOffset = 0;
|
|
||||||
|
|
||||||
Transmitter::Transmitter(string filename, double frequency) :
|
Transmitter::Transmitter(string filename, double frequency) :
|
||||||
readStdin(filename == "-")
|
readStdin(filename == "-")
|
||||||
|
@ -88,16 +87,15 @@ Transmitter::Transmitter(string filename, double frequency) :
|
||||||
|
|
||||||
peripherals = (volatile unsigned*)peripheralsMap;
|
peripherals = (volatile unsigned*)peripheralsMap;
|
||||||
|
|
||||||
|
AudioFormat *audioFormat;
|
||||||
if (!readStdin) {
|
if (!readStdin) {
|
||||||
waveReader = new WaveReader(filename);
|
waveReader = new WaveReader(filename);
|
||||||
format = waveReader->getFormat();
|
audioFormat = waveReader->getFormat();
|
||||||
} else {
|
} else {
|
||||||
stdinReader = new StdinReader();
|
stdinReader = StdinReader::getInstance();
|
||||||
format = stdinReader->getFormat();
|
audioFormat = stdinReader->getFormat();
|
||||||
}
|
}
|
||||||
|
format = *audioFormat;
|
||||||
ACCESS(peripherals, 0x00200000) = (ACCESS(peripherals, 0x00200000) & 0xFFFF8FFF) | (0x01 << 14);
|
|
||||||
ACCESS(peripherals, 0x00101070) = (0x5A << 24) | (0x01 << 9) | (0x01 << 4) | 0x06;
|
|
||||||
|
|
||||||
clockDivisor = (unsigned int)((500 << 12) / frequency + 0.5);
|
clockDivisor = (unsigned int)((500 << 12) / frequency + 0.5);
|
||||||
}
|
}
|
||||||
|
@ -112,22 +110,15 @@ void Transmitter::play()
|
||||||
throw exception();
|
throw exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
frameOffset = 0;
|
||||||
isTransmitting = true;
|
isTransmitting = true;
|
||||||
pthread_t thread;
|
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);
|
buffer = (!readStdin) ? waveReader->getFrames(bufferFrames, frameOffset) : stdinReader->getFrames(bufferFrames);
|
||||||
|
|
||||||
void *params[3];
|
int returnCode = pthread_create(&thread, NULL, (volatile void*)(&this->transmit), NULL);
|
||||||
params[0] = &format->sampleRate;
|
|
||||||
params[1] = &clockDivisor;
|
|
||||||
params[2] = peripherals;
|
|
||||||
|
|
||||||
returnCode = pthread_create(&thread, NULL, &Transmitter::transmit, (void*)params);
|
|
||||||
if (returnCode) {
|
if (returnCode) {
|
||||||
oss << "Cannot create new thread (code: " << returnCode << ")";
|
oss << "Cannot create new thread (code: " << returnCode << ")";
|
||||||
errorMessage = oss.str();
|
errorMessage = oss.str();
|
||||||
|
@ -147,16 +138,15 @@ void Transmitter::play()
|
||||||
pthread_join(thread, NULL);
|
pthread_join(thread, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transmitter::transmit(void *params)
|
void Transmitter::transmit(void*)
|
||||||
{
|
{
|
||||||
unsigned long long current, start, playbackStart;
|
unsigned long long current, start, playbackStart;
|
||||||
unsigned int offset = 0, length, temp;
|
unsigned int offset = 0, length, temp;
|
||||||
vector<float> *frames;
|
vector<float> *frames;
|
||||||
float *data;
|
float *data;
|
||||||
|
|
||||||
unsigned int sampleRate = *((unsigned int**)params)[0];
|
ACCESS(peripherals, 0x00200000) = (ACCESS(peripherals, 0x00200000) & 0xFFFF8FFF) | (0x01 << 14);
|
||||||
unsigned int clockDivisor = *((unsigned int**)params)[1];
|
ACCESS(peripherals, 0x00101070) = (0x5A << 24) | (0x01 << 9) | (0x01 << 4) | 0x06;
|
||||||
volatile unsigned *peripherals = ((unsigned int**)params)[2];
|
|
||||||
|
|
||||||
playbackStart = ACCESS64(peripherals, 0x00003004);
|
playbackStart = ACCESS64(peripherals, 0x00003004);
|
||||||
current = playbackStart;
|
current = playbackStart;
|
||||||
|
@ -168,7 +158,7 @@ void Transmitter::transmit(void *params)
|
||||||
current = ACCESS64(peripherals, 0x00003004);
|
current = ACCESS64(peripherals, 0x00003004);
|
||||||
}
|
}
|
||||||
frames = buffer;
|
frames = buffer;
|
||||||
frameOffset = (current - playbackStart) * sampleRate / 1000000;
|
frameOffset = (current - playbackStart) * format.sampleRate / 1000000;
|
||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
|
|
||||||
length = frames->size();
|
length = frames->size();
|
||||||
|
@ -189,7 +179,7 @@ void Transmitter::transmit(void *params)
|
||||||
usleep(1);
|
usleep(1);
|
||||||
|
|
||||||
current = ACCESS64(peripherals, 0x00003004);
|
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;
|
delete frames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ACCESS(peripherals, 0x00101070) = (0x5A << 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
Transmitter::~Transmitter()
|
Transmitter::~Transmitter()
|
||||||
{
|
{
|
||||||
ACCESS(peripherals, 0x00101070) = (0x5A << 24);
|
|
||||||
munmap(peripherals, 0x002FFFFF);
|
munmap(peripherals, 0x002FFFFF);
|
||||||
if (!readStdin) {
|
if (!readStdin) {
|
||||||
delete waveReader;
|
delete waveReader;
|
||||||
} else {
|
} else {
|
||||||
delete stdinReader;
|
delete stdinReader;
|
||||||
}
|
}
|
||||||
delete format;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioFormat *Transmitter::getFormat()
|
AudioFormat& Transmitter::getFormat()
|
||||||
{
|
{
|
||||||
return format;
|
return format;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification, are
|
Redistribution and use in source and binary forms, with or without modification, are
|
||||||
permitted provided that the following conditions are met:
|
permitted provided that the following conditions are met:
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this list
|
1. Redistributions of source code must retain the above copyright notice, this list
|
||||||
of conditions and the following disclaimer.
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
@ -35,6 +36,7 @@
|
||||||
|
|
||||||
#include "wave_reader.h"
|
#include "wave_reader.h"
|
||||||
#include "stdin_reader.h"
|
#include "stdin_reader.h"
|
||||||
|
#include "error_reporter.h"
|
||||||
|
|
||||||
#define BUFFER_TIME 1000000
|
#define BUFFER_TIME 1000000
|
||||||
|
|
||||||
|
@ -46,21 +48,21 @@ class Transmitter : public ErrorReporter
|
||||||
Transmitter(string filename, double frequency);
|
Transmitter(string filename, double frequency);
|
||||||
virtual ~Transmitter();
|
virtual ~Transmitter();
|
||||||
|
|
||||||
AudioFormat *getFormat();
|
AudioFormat &getFormat();
|
||||||
void play();
|
void play();
|
||||||
private:
|
private:
|
||||||
bool readStdin;
|
bool readStdin;
|
||||||
AudioFormat *format;
|
AudioFormat format;
|
||||||
WaveReader *waveReader;
|
WaveReader *waveReader;
|
||||||
StdinReader *stdinReader;
|
StdinReader *stdinReader;
|
||||||
unsigned int clockDivisor;
|
unsigned int clockDivisor;
|
||||||
volatile unsigned *peripherals;
|
volatile unsigned *peripherals;
|
||||||
|
|
||||||
static vector<float> *buffer;
|
vector<float> *buffer;
|
||||||
|
unsigned int frameOffset;
|
||||||
static bool isTransmitting;
|
static bool isTransmitting;
|
||||||
static unsigned int frameOffset;
|
|
||||||
|
|
||||||
static void transmit(void *params);
|
void transmit(void*);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TRANSMITTER_H
|
#endif // TRANSMITTER_H
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification, are
|
Redistribution and use in source and binary forms, with or without modification, are
|
||||||
permitted provided that the following conditions are met:
|
permitted provided that the following conditions are met:
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this list
|
1. Redistributions of source code must retain the above copyright notice, this list
|
||||||
of conditions and the following disclaimer.
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
@ -35,8 +36,6 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
using std::exception;
|
using std::exception;
|
||||||
using std::ostringstream;
|
using std::ostringstream;
|
||||||
|
|
||||||
|
@ -142,12 +141,11 @@ vector<char> *WaveReader::readData(unsigned int bytesToRead, bool closeFileOnExc
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<float> *WaveReader::getFrames(unsigned int count, unsigned int frameOffset) {
|
vector<float> *WaveReader::getFrames(unsigned int frameCount, unsigned int frameOffset) {
|
||||||
unsigned int bytesToRead, bytesLeft, bytesPerFrame, frameCount, offset;
|
unsigned int bytesToRead, bytesLeft, bytesPerFrame, offset;
|
||||||
vector<float> *frames = new vector<float>();
|
vector<float> *frames = new vector<float>();
|
||||||
vector<char> *data;
|
vector<char> *data;
|
||||||
|
|
||||||
frameCount = count;
|
|
||||||
bytesPerFrame = (header.bitsPerSample >> 3) * header.channels;
|
bytesPerFrame = (header.bitsPerSample >> 3) * header.channels;
|
||||||
bytesToRead = frameCount * bytesPerFrame;
|
bytesToRead = frameCount * bytesPerFrame;
|
||||||
bytesLeft = header.subchunk2Size - frameOffset * bytesPerFrame;
|
bytesLeft = header.subchunk2Size - frameOffset * bytesPerFrame;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification, are
|
Redistribution and use in source and binary forms, with or without modification, are
|
||||||
permitted provided that the following conditions are met:
|
permitted provided that the following conditions are met:
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this list
|
1. Redistributions of source code must retain the above copyright notice, this list
|
||||||
of conditions and the following disclaimer.
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
@ -36,9 +37,9 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include "error_reporter.h"
|
|
||||||
#include "pcm_wave_header.h"
|
|
||||||
#include "audio_format.h"
|
#include "audio_format.h"
|
||||||
|
#include "pcm_wave_header.h"
|
||||||
|
#include "error_reporter.h"
|
||||||
|
|
||||||
using std::vector;
|
using std::vector;
|
||||||
using std::string;
|
using std::string;
|
||||||
|
@ -51,7 +52,7 @@ class WaveReader : public ErrorReporter
|
||||||
virtual ~WaveReader();
|
virtual ~WaveReader();
|
||||||
|
|
||||||
AudioFormat *getFormat();
|
AudioFormat *getFormat();
|
||||||
vector<float> *getFrames(unsigned int count, unsigned int offset);
|
vector<float> *getFrames(unsigned int frameCount, unsigned int frameOffset);
|
||||||
bool isEnd();
|
bool isEnd();
|
||||||
private:
|
private:
|
||||||
string filename;
|
string filename;
|
||||||
|
|
Ładowanie…
Reference in New Issue