Updated ReadMe and added minor tweaks

pull/70/head
Marcin Kondej 2019-01-08 09:54:44 +01:00
rodzic f0354b15ee
commit 56407e5fa3
4 zmienionych plików z 22 dodań i 28 usunięć

Wyświetl plik

@ -1,8 +1,7 @@
# fm_transmitter
Use Raspberry Pi as FM transmitter. Works on any Raspberry Pi board.
Use Raspberry Pi as FM transmitter. Works on every Raspberry Pi board.
This project uses the general clock output to produce frequency modulated radio communication. It is based on idea originaly presented by [Oliver Mattos and Oskar Weigl](http://icrobotics.co.uk/wiki/index.php/Turning_the_Raspberry_Pi_Into_an_FM_Transmitter) on [PiFM project](http://icrobotics.co.uk/wiki/index.php/Turning_the_Raspberry_Pi_Into_an_FM_Transmitter).
Just get an FM receiver and connect 20 - 40 cm plain wire to GPIO4 (PIN 7 on Raspberry Pi GPIO header) to act as an antena.
## How to use it
To use this project You will have to build it. First, clone this repository, then use "make" command as shown below:
```
@ -17,11 +16,11 @@ sudo ./fm_transmitter -f 102.0 acoustic_guitar_duet.wav
Where:
* -f frequency - Specifies the frequency in MHz, 100.0 by default if not passed
* acoustic_guitar_duet.wav - Sample WAVE file, You can use your own
Other options:
* -d dma_channel - Specifies the used DMA channel (0 by default), pass 255 in order to disable DMA and use CPU
* -d dma_channel - Specifies DMA channel to be used (0 by default), type 255 to disable DMA transfer, CPU will be used instead
* -b bandwidth - Specifies the bandwidth in kHz, 100 by default
* -r - Loops the playback
After transmission has begun, simply tune an FM receiver to chosen frequency, You should hear the playback.
### Supported audio formats
You can transmitt uncompressed WAVE (.wav) files directly or read audio data from stdin, eg.:
```
@ -38,14 +37,12 @@ In order to use a USB microphone input use arecord command, eg.:
arecord -D hw:1,0 -c1 -d 0 -r 22050 -f S16_LE | sudo ./fm_transmitter -f 100.6 -
```
In case of performance drop down use ```plughw:1,0``` instead of ```hw:1,0```.
## Legal note
Please keep in mind that transmitting on certain frequencies without special permissions may be illegal in your country.
## New features
* DMA peripheral support
* works on any Raspberry Pi model
* Allows custom frequency and bandwidth settings
* works on every Raspberry Pi model
* reads mono and stereo files
* reads data from stdin
Included sample audio was created by [graham_makes](https://freesound.org/people/graham_makes/sounds/449409/) and published on [freesound.org](https://freesound.org/)

Wyświetl plik

@ -54,7 +54,7 @@ void sigIntHandler(int sigNum)
int main(int argc, char** argv)
{
double frequency = 100.0;
double bandwidth = 0.1;
double bandwidth = 100.0;
unsigned short dmaChannel = 0;
bool loop = false;
string filename;

Wyświetl plik

@ -1,11 +1,11 @@
EXECUTABLE = fm_transmitter
VERSION = 0.9.1
FLAGS = -Wall -fexceptions -pthread -O3 -fpermissive -fno-strict-aliasing
FLAGS = -Wall -O3
LIBS = -lm
all: main.o mailbox.o error_reporter.o sample.o preemp.o wave_reader.o transmitter.o
g++ $(FLAGS) -L/opt/vc/lib -lm -lbcm_host -o $(EXECUTABLE) main.o mailbox.o sample.o preemp.o error_reporter.o wave_reader.o transmitter.o
g++ -L/opt/vc/lib -lm -lpthread -lbcm_host -o $(EXECUTABLE) main.o mailbox.o sample.o preemp.o error_reporter.o wave_reader.o transmitter.o
mailbox.o: mailbox.c mailbox.h
g++ $(FLAGS) -c mailbox.c
@ -23,7 +23,7 @@ wave_reader.o: wave_reader.cpp wave_reader.h
g++ $(FLAGS) -c wave_reader.cpp
transmitter.o: transmitter.cpp transmitter.h
g++ $(FLAGS) -I/opt/vc/include -c transmitter.cpp
g++ $(FLAGS) -fno-strict-aliasing -I/opt/vc/include -c transmitter.cpp
main.o: main.cpp
g++ $(FLAGS) -DVERSION=\"$(VERSION)\" -DEXECUTABLE=\"$(EXECUTABLE)\" -c main.cpp

Wyświetl plik

@ -195,8 +195,8 @@ void Transmitter::play(WaveReader &reader, double frequency, double bandwidth, u
}
bool eof = samples->size() < bufferSize;
unsigned clockDivisor = (unsigned)((500 << 12) / frequency + 0.5);
unsigned divisorRange = (unsigned)((500 << 12) / (frequency + 0.5 * bandwidth) + 0.5) - clockDivisor;
unsigned clockDivisor = (unsigned)round((500 << 12) / frequency);
unsigned divisorRange = clockDivisor - (unsigned)round((500 << 12) / (frequency + 0.0005 * bandwidth));
bool isError = false;
string errorMessage;
@ -206,7 +206,7 @@ void Transmitter::play(WaveReader &reader, double frequency, double bandwidth, u
throw ErrorReporter("DMA channel number out of range (0 - 15)");
}
if (!allocateMemory(sizeof(unsigned) * ((bufferSize << 1) + 1) + sizeof(DMAControllBlock) * (bufferSize << 1))) {
if (!allocateMemory(sizeof(unsigned) * ((2 * bufferSize) + 1) + sizeof(DMAControllBlock) * (2 * bufferSize))) {
delete samples;
throw ErrorReporter("Cannot allocate memory");
}
@ -246,8 +246,8 @@ void Transmitter::play(WaveReader &reader, double frequency, double bandwidth, u
#endif
volatile DMAControllBlock *dmaCb = (DMAControllBlock *)memAllocated;
volatile unsigned *clkDiv = (unsigned *)memAllocated + ((sizeof(DMAControllBlock) / sizeof(unsigned)) << 1) * bufferSize;
volatile unsigned *pwmFifoData = (unsigned *)memAllocated + (((sizeof(DMAControllBlock) / sizeof(unsigned)) << 1) + 1) * bufferSize;
volatile unsigned *clkDiv = (unsigned *)memAllocated + 2 * (sizeof(DMAControllBlock) / sizeof(unsigned)) * bufferSize;
volatile unsigned *pwmFifoData = (unsigned *)memAllocated + 2 * ((sizeof(DMAControllBlock) / sizeof(unsigned)) + 1) * bufferSize;
for (i = 0; i < bufferSize; i++) {
value = (*samples)[i].getMonoValue();
#ifndef NO_PREEMP
@ -280,7 +280,7 @@ void Transmitter::play(WaveReader &reader, double frequency, double bandwidth, u
dma->cbAddress = getAddress(dmaCb);
dma->ctlStatus = (0xFF << 16) | 0x01;
usleep(BUFFER_TIME >> 2);
usleep(BUFFER_TIME / 4);
try {
while (!eof && transmitting) {
@ -295,7 +295,7 @@ void Transmitter::play(WaveReader &reader, double frequency, double bandwidth, u
#ifndef NO_PREEMP
value = preEmp.filter(value);
#endif
while (i == (((dma->cbAddress - getAddress(dmaCb)) / sizeof(DMAControllBlock)) >> 1)) {
while (i == ((dma->cbAddress - getAddress(dmaCb)) / (2 *sizeof(DMAControllBlock)))) {
usleep(1);
}
clkDiv[i] = (0x5A << 24) | (clockDivisor - (int)round(value * divisorRange));
@ -309,11 +309,8 @@ void Transmitter::play(WaveReader &reader, double frequency, double bandwidth, u
isError = true;
}
if (eof || isError) {
dmaCb[cbIndex].nextCbAddress = 0x00;
} else {
dmaCb[(bufferSize - 1) << 1].nextCbAddress = 0x00;
}
cbIndex -= 2;
dmaCb[cbIndex].nextCbAddress = 0x00;
while (dma->cbAddress != 0x00) {
usleep(1);
}
@ -348,7 +345,7 @@ void Transmitter::play(WaveReader &reader, double frequency, double bandwidth, u
throw ErrorReporter(oss.str());
}
usleep(BUFFER_TIME >> 1);
usleep(BUFFER_TIME / 2);
try {
while (!eof && transmitting) {
@ -363,7 +360,7 @@ void Transmitter::play(WaveReader &reader, double frequency, double bandwidth, u
eof = samples->size() < bufferSize;
buffer = samples;
}
usleep(BUFFER_TIME >> 1);
usleep(BUFFER_TIME / 2);
}
}
catch (ErrorReporter &error) {