Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rpi4 fix #108

Merged
merged 6 commits into from
Mar 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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