kopia lustrzana https://github.com/markondej/fm_transmitter
Using mutex to synchronize threads
rodzic
3a68f2f3e8
commit
a85a77342a
|
@ -120,7 +120,8 @@ struct AllocatedMemory {
|
||||||
bool Transmitter::transmitting = false;
|
bool Transmitter::transmitting = false;
|
||||||
volatile ClockRegisters *Transmitter::output = nullptr;
|
volatile ClockRegisters *Transmitter::output = nullptr;
|
||||||
uint32_t Transmitter::sampleOffset, Transmitter::clockDivisor, Transmitter::divisorRange, Transmitter::sampleRate;
|
uint32_t Transmitter::sampleOffset, Transmitter::clockDivisor, Transmitter::divisorRange, Transmitter::sampleRate;
|
||||||
std::vector<Sample> *Transmitter::loadedSamples;
|
std::vector<Sample> Transmitter::samples;
|
||||||
|
std::mutex Transmitter::samplesAccess;
|
||||||
void *Transmitter::peripherals;
|
void *Transmitter::peripherals;
|
||||||
|
|
||||||
Transmitter::Transmitter()
|
Transmitter::Transmitter()
|
||||||
|
@ -311,7 +312,7 @@ void Transmitter::transmit(WaveReader &reader, float frequency, float bandwidth,
|
||||||
|
|
||||||
void Transmitter::transmitViaCpu(WaveReader &reader, uint32_t bufferSize)
|
void Transmitter::transmitViaCpu(WaveReader &reader, uint32_t bufferSize)
|
||||||
{
|
{
|
||||||
std::vector<Sample> samples = reader.getSamples(bufferSize, transmitting);
|
samples = reader.getSamples(bufferSize, transmitting);
|
||||||
if (!samples.size()) {
|
if (!samples.size()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -327,20 +328,23 @@ void Transmitter::transmitViaCpu(WaveReader &reader, uint32_t bufferSize)
|
||||||
auto finally = [&]() {
|
auto finally = [&]() {
|
||||||
transmitting = false;
|
transmitting = false;
|
||||||
txThread.join();
|
txThread.join();
|
||||||
|
samples.clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
while (!eof && transmitting) {
|
while (!eof && transmitting) {
|
||||||
if (loadedSamples == nullptr) {
|
if (samplesAccess.try_lock() && samples.size()) {
|
||||||
if (!reader.setSampleOffset(sampleOffset + bufferSize)) {
|
if (!reader.setSampleOffset(sampleOffset + bufferSize)) {
|
||||||
break;
|
samplesAccess.unlock();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
samples = reader.getSamples(bufferSize, transmitting);
|
samples = reader.getSamples(bufferSize, transmitting);
|
||||||
if (!samples.size()) {
|
if (!samples.size()) {
|
||||||
break;
|
samplesAccess.unlock();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
eof = samples.size() < bufferSize;
|
eof = samples.size() < bufferSize;
|
||||||
loadedSamples = &samples;
|
samplesAccess.unlock();
|
||||||
}
|
}
|
||||||
usleep(BUFFER_TIME / 2);
|
usleep(BUFFER_TIME / 2);
|
||||||
}
|
}
|
||||||
|
@ -358,7 +362,7 @@ void Transmitter::transmitViaDma(WaveReader &reader, uint32_t bufferSize, uint8_
|
||||||
throw std::runtime_error("DMA channel number out of range (0 - 15)");
|
throw std::runtime_error("DMA channel number out of range (0 - 15)");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Sample> samples = reader.getSamples(bufferSize, transmitting);
|
samples = reader.getSamples(bufferSize, transmitting);
|
||||||
if (!samples.size()) {
|
if (!samples.size()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -422,6 +426,7 @@ void Transmitter::transmitViaDma(WaveReader &reader, uint32_t bufferSize, uint8_
|
||||||
|
|
||||||
freeMemory(dmaMemory);
|
freeMemory(dmaMemory);
|
||||||
transmitting = false;
|
transmitting = false;
|
||||||
|
samples.clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -465,26 +470,27 @@ void Transmitter::transmitThread()
|
||||||
while (transmitting) {
|
while (transmitting) {
|
||||||
uint64_t start = current;
|
uint64_t start = current;
|
||||||
|
|
||||||
while ((loadedSamples == nullptr) && transmitting) {
|
while (!samplesAccess.try_lock() && transmitting) {
|
||||||
usleep(1);
|
usleep(1);
|
||||||
current = *(reinterpret_cast<volatile uint64_t *>(&timer->low));
|
current = *(reinterpret_cast<volatile uint64_t *>(&timer->low));
|
||||||
}
|
}
|
||||||
if (!transmitting) {
|
if (!transmitting) {
|
||||||
|
samplesAccess.unlock();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Sample> samples(*loadedSamples);
|
std::vector<Sample> loaded(std::move(samples));
|
||||||
loadedSamples = nullptr;
|
samplesAccess.unlock();
|
||||||
|
|
||||||
sampleOffset = (current - playbackStart) * sampleRate / 1000000;
|
sampleOffset = (current - playbackStart) * sampleRate / 1000000;
|
||||||
uint32_t offset = (current - start) * sampleRate / 1000000;
|
uint32_t offset = (current - start) * sampleRate / 1000000;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (offset >= samples.size()) {
|
if (offset >= loaded.size()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
uint32_t prevOffset = offset;
|
uint32_t prevOffset = offset;
|
||||||
float value = samples[offset].getMonoValue();
|
float value = loaded[offset].getMonoValue();
|
||||||
#ifndef NO_PREEMP
|
#ifndef NO_PREEMP
|
||||||
value = preEmphasis.filter(value);
|
value = preEmphasis.filter(value);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#define TRANSMITTER_HPP
|
#define TRANSMITTER_HPP
|
||||||
|
|
||||||
#include "wave_reader.hpp"
|
#include "wave_reader.hpp"
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
struct AllocatedMemory;
|
struct AllocatedMemory;
|
||||||
struct PWMRegisters;
|
struct PWMRegisters;
|
||||||
|
@ -77,7 +78,8 @@ class Transmitter
|
||||||
static bool transmitting;
|
static bool transmitting;
|
||||||
static uint32_t sampleOffset, clockDivisor, divisorRange, sampleRate;
|
static uint32_t sampleOffset, clockDivisor, divisorRange, sampleRate;
|
||||||
static volatile ClockRegisters *output;
|
static volatile ClockRegisters *output;
|
||||||
static std::vector<Sample> *loadedSamples;
|
static std::vector<Sample> samples;
|
||||||
|
static std::mutex samplesAccess;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TRANSMITTER_HPP
|
#endif // TRANSMITTER_HPP
|
||||||
|
|
Ładowanie…
Reference in New Issue