Skip to content

Commit

Permalink
Merge pull request #108 from markondej/rpi4-fix
Browse files Browse the repository at this point in the history
Rpi4 fix
  • Loading branch information
markondej authored Mar 30, 2020
2 parents 7c623eb + f4c1d03 commit 24d1a85
Show file tree
Hide file tree
Showing 10 changed files with 451 additions and 447 deletions.
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,22 @@ Other options:
* -r - Loops the playback

After transmission has begun, simply tune an FM receiver to chosen frequency, You should hear the playback.
### Raspberry Pi 4
On Raspberry Pi 4 other built-in hardware probably interfers somehow with this software making transmitting not possible on all standard FM broadcasting frequencies. In this case it is recommended to:
1. Compile executable with option to use GPIO21 instead of GPIO4 (PIN 40 on GPIO header):
```
make GPIO21=1
```
2. Change either ARM core frequency scaling governor settings to "performance" or to change ARM minium and maximum core frequencies to one constant value (see: https://www.raspberrypi.org/forums/viewtopic.php?t=152692 ).
```
echo "performance"| sudo tee /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
```
3. Using lower FM broadcasting frequencies (below 93 MHz) when transmitting.
### Supported audio formats
You can transmitt uncompressed WAV (.wav) files directly or read audio data from stdin, eg.:
```
sudo apt-get install sox
sox star_wars.wav -r 22050 -c 1 -b 16 -t wav - | sudo ./fm_transmitter -f 100.6 -
sox acoustic_guitar_duet.wav -r 22050 -c 1 -b 16 -t wav - | sudo ./fm_transmitter -f 100.6 -
```
Please note only uncompressed WAV files are supported. If you receive the "corrupted data" error try converting the file, eg. by using SoX:
```
Expand Down
38 changes: 22 additions & 16 deletions main.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
fm_transmitter - use Raspberry Pi as FM transmitter
FM Transmitter - use Raspberry Pi as FM transmitter
Copyright (c) 2019, Marcin Kondej
Copyright (c) 2020, Marcin Kondej
All rights reserved.
See https://github.com/markondej/fm_transmitter
Expand Down Expand Up @@ -37,21 +37,21 @@
#include <iostream>
#include <unistd.h>

bool play = true;
Transmitter *transmitter = NULL;
bool stop = false;
Transmitter *transmitter = nullptr;

void sigIntHandler(int sigNum)
{
if (transmitter != NULL) {
if (transmitter != nullptr) {
std::cout << "Stopping..." << std::endl;
transmitter->stop();
play = false;
transmitter->Stop();
stop = true;
}
}

int main(int argc, char** argv)
{
float frequency = 100.f, bandwidth = 100.f;
float frequency = 100.f, bandwidth = 200.f;
uint16_t dmaChannel = 0;
bool showUsage = true, loop = false;
int opt, filesOffset;
Expand Down Expand Up @@ -87,27 +87,33 @@ int main(int argc, char** argv)
signal(SIGINT, sigIntHandler);
signal(SIGTSTP, sigIntHandler);

auto finally = [&]() {
delete transmitter;
transmitter = nullptr;
};
try {
transmitter = &Transmitter::getInstance();
transmitter = new Transmitter();
std::cout << "Broadcasting at " << frequency << " MHz with "
<< bandwidth << " kHz bandwidth" << std::endl;
do {
std::string filename = argv[optind++];
if ((optind == argc) && loop) {
optind = filesOffset;
}
WaveReader reader(filename != "-" ? filename : std::string(), play);
PCMWaveHeader header = reader.getHeader();
std::cout << "Broadcasting at " << frequency << " MHz with "
<< bandwidth << " kHz bandwidth" << std::endl;
std::cout << "Playing: " << reader.getFilename() << ", "
WaveReader reader(filename != "-" ? filename : std::string(), stop);
WaveHeader header = reader.GetHeader();
std::cout << "Playing: " << reader.GetFilename() << ", "
<< header.sampleRate << " Hz, "
<< header.bitsPerSample << " bits, "
<< ((header.channels > 0x01) ? "stereo" : "mono") << std::endl;
transmitter->transmit(reader, frequency, bandwidth, dmaChannel, optind < argc);
} while (play && (optind < argc));
transmitter->Transmit(reader, frequency, bandwidth, dmaChannel, optind < argc);
} while (!stop && (optind < argc));
} catch (std::exception &catched) {
std::cout << "Error: " << catched.what() << std::endl;
finally();
return 1;
}
finally();

return 0;
}
8 changes: 6 additions & 2 deletions makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
EXECUTABLE = fm_transmitter
VERSION = 0.9.3
VERSION = 0.9.4
FLAGS = -Wall -O3 -std=c++11
TRANSMITTER = -fno-strict-aliasing -I/opt/vc/include
ifeq ($(GPIO21), 1)
TRANSMITTER += -DGPIO21
endif

all: main.o mailbox.o sample.o wave_reader.o transmitter.o
g++ -L/opt/vc/lib -lm -lpthread -lbcm_host -o $(EXECUTABLE) main.o mailbox.o sample.o wave_reader.o transmitter.o
Expand All @@ -15,7 +19,7 @@ wave_reader.o: wave_reader.cpp wave_reader.hpp
g++ $(FLAGS) -c wave_reader.cpp

transmitter.o: transmitter.cpp transmitter.hpp
g++ $(FLAGS) -fno-strict-aliasing -I/opt/vc/include -c transmitter.cpp
g++ $(FLAGS) $(TRANSMITTER) -c transmitter.cpp

main.o: main.cpp
g++ $(FLAGS) -DVERSION=\"$(VERSION)\" -DEXECUTABLE=\"$(EXECUTABLE)\" -c main.cpp
Expand Down
58 changes: 0 additions & 58 deletions pcm_wave_header.hpp

This file was deleted.

26 changes: 14 additions & 12 deletions sample.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
fm_transmitter - use Raspberry Pi as FM transmitter
FM Transmitter - use Raspberry Pi as FM transmitter
Copyright (c) 2019, Marcin Kondej
Copyright (c) 2020, Marcin Kondej
All rights reserved.
See https://github.com/markondej/fm_transmitter
Expand Down Expand Up @@ -34,25 +34,27 @@
#include "sample.hpp"
#include <climits>

Sample::Sample(uint8_t *data, uint16_t channels, uint16_t bitsPerChannel)
Sample::Sample(uint8_t *data, unsigned channels, unsigned bitsPerChannel)
: value(0.f)
{
int32_t sum = 0;
int sum = 0;
int16_t *channelValues = new int16_t[channels];
int16_t multiplier = bitsPerChannel >> 3;
for (uint32_t i = 0; i < channels; i++) {
if (multiplier > 1) {
channelValues[i] = (data[(i + 1) * multiplier - 1] << 8) | data[(i + 1) * multiplier - 2];
} else {
for (unsigned i = 0; i < channels; i++) {
switch (bitsPerChannel >> 3) {
case 2:
channelValues[i] = (data[((i + 1) << 1) - 1] << 8) | data[((i + 1) << 1) - 2];
break;
case 1:
channelValues[i] = (static_cast<int16_t>(data[i]) - 0x80) << 8;
break;
}
sum += channelValues[i];
}
value = 2 * sum / channels / static_cast<float>(USHRT_MAX);
value = 2 * sum / (static_cast<float>(USHRT_MAX) * channels);
delete[] channelValues;
}

float Sample::getMonoValue() const
float Sample::GetMonoValue() const
{
return value;
}
}
8 changes: 4 additions & 4 deletions sample.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
fm_transmitter - use Raspberry Pi as FM transmitter
FM Transmitter - use Raspberry Pi as FM transmitter
Copyright (c) 2019, Marcin Kondej
Copyright (c) 2020, Marcin Kondej
All rights reserved.
See https://github.com/markondej/fm_transmitter
Expand Down Expand Up @@ -39,8 +39,8 @@
class Sample
{
public:
Sample(uint8_t *data, uint16_t channels, uint16_t bitsPerChannel);
float getMonoValue() const;
Sample(uint8_t *data, unsigned channels, unsigned bitsPerChannel);
float GetMonoValue() const;
protected:
float value;
};
Expand Down
Loading

0 comments on commit 24d1a85

Please sign in to comment.