kopia lustrzana https://github.com/markondej/fm_transmitter
commit
ae347b1faa
10
sample.cpp
10
sample.cpp
|
@ -44,11 +44,11 @@ Sample::Sample(uint8_t *data, uint16_t channels, uint16_t bitsPerChannel)
|
||||||
if (multiplier > 1) {
|
if (multiplier > 1) {
|
||||||
channelValues[i] = (data[(i + 1) * multiplier - 1] << 8) | data[(i + 1) * multiplier - 2];
|
channelValues[i] = (data[(i + 1) * multiplier - 1] << 8) | data[(i + 1) * multiplier - 2];
|
||||||
} else {
|
} else {
|
||||||
channelValues[i] = ((int16_t)data[i] - 0x80) << 8;
|
channelValues[i] = (static_cast<int16_t>(data[i]) - 0x80) << 8;
|
||||||
}
|
}
|
||||||
sum += channelValues[i];
|
sum += channelValues[i];
|
||||||
}
|
}
|
||||||
value = 2 * (sum / channels) / (double)USHRT_MAX;
|
value = 2 * sum / channels / static_cast<double>(USHRT_MAX);
|
||||||
delete[] channelValues;
|
delete[] channelValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,14 +59,14 @@ double Sample::getMonoValue()
|
||||||
|
|
||||||
#ifndef NO_PREEMP
|
#ifndef NO_PREEMP
|
||||||
PreEmphasis::PreEmphasis(uint32_t sampleRate)
|
PreEmphasis::PreEmphasis(uint32_t sampleRate)
|
||||||
: timeConst(sampleRate * 75.0e-6), prevValue(0.0)
|
: timeConst(sampleRate * 75.0e-6), prevValue(0.)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
double PreEmphasis::filter(double value)
|
double PreEmphasis::filter(double value)
|
||||||
{
|
{
|
||||||
prevValue = value;
|
prevValue = value;
|
||||||
value = value + (prevValue - value) / (1.0 - timeConst);
|
value = value + (prevValue - value) / (1. - timeConst);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -172,16 +172,16 @@ double Transmitter::getSourceFreq()
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Transmitter::getPeripheralPhysAddress(volatile void *object) {
|
uint32_t Transmitter::getPeripheralPhysAddress(volatile void *object) {
|
||||||
return PERIPHERALS_PHYS_BASE + ((uint32_t)object - (uint32_t)peripherals);
|
return PERIPHERALS_PHYS_BASE + (reinterpret_cast<uint32_t>(object) - reinterpret_cast<uint32_t>(peripherals));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Transmitter::getPeripheralVirtAddress(uint32_t offset) {
|
uint32_t Transmitter::getPeripheralVirtAddress(uint32_t offset) {
|
||||||
return (uint32_t)peripherals + offset;
|
return reinterpret_cast<uint32_t>(peripherals) + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Transmitter::getMemoryPhysAddress(AllocatedMemory &memory, volatile void *object)
|
uint32_t Transmitter::getMemoryPhysAddress(AllocatedMemory &memory, volatile void *object)
|
||||||
{
|
{
|
||||||
return memory.physicalBase + ((uint32_t)object - memory.virtualBase);
|
return memory.physicalBase + (reinterpret_cast<uint32_t>(object) - memory.virtualBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
AllocatedMemory Transmitter::allocateMemory(uint32_t size)
|
AllocatedMemory Transmitter::allocateMemory(uint32_t size)
|
||||||
|
@ -198,14 +198,14 @@ AllocatedMemory Transmitter::allocateMemory(uint32_t size)
|
||||||
return memory;
|
return memory;
|
||||||
}
|
}
|
||||||
memory.physicalBase = mem_lock(memory.mBoxFd, memory.handle);
|
memory.physicalBase = mem_lock(memory.mBoxFd, memory.handle);
|
||||||
memory.virtualBase = (uint32_t)mapmem(memory.physicalBase & ~0xC0000000, size);
|
memory.virtualBase = reinterpret_cast<uint32_t>(mapmem(memory.physicalBase & ~0xC0000000, size));
|
||||||
memory.size = size;
|
memory.size = size;
|
||||||
return memory;
|
return memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transmitter::freeMemory(AllocatedMemory &memory)
|
void Transmitter::freeMemory(AllocatedMemory &memory)
|
||||||
{
|
{
|
||||||
unmapmem((void *)memory.virtualBase, memory.size);
|
unmapmem(reinterpret_cast<void *>(memory.virtualBase), memory.size);
|
||||||
mem_unlock(memory.mBoxFd, memory.handle);
|
mem_unlock(memory.mBoxFd, memory.handle);
|
||||||
mem_free(memory.mBoxFd, memory.handle);
|
mem_free(memory.mBoxFd, memory.handle);
|
||||||
mbox_close(memory.mBoxFd);
|
mbox_close(memory.mBoxFd);
|
||||||
|
@ -214,14 +214,14 @@ void Transmitter::freeMemory(AllocatedMemory &memory)
|
||||||
|
|
||||||
volatile PWMRegisters *Transmitter::initPwmController()
|
volatile PWMRegisters *Transmitter::initPwmController()
|
||||||
{
|
{
|
||||||
volatile ClockRegisters *pwmClk = (ClockRegisters *)getPeripheralVirtAddress(PWMCLK_BASE_OFFSET);
|
volatile ClockRegisters *pwmClk = reinterpret_cast<ClockRegisters *>(getPeripheralVirtAddress(PWMCLK_BASE_OFFSET));
|
||||||
double pwmClkFreq = PWM_WRITES_PER_SAMPLE * PWM_CHANNEL_RANGE * sampleRate / 1000000;
|
double pwmClkFreq = PWM_WRITES_PER_SAMPLE * PWM_CHANNEL_RANGE * sampleRate / 1000000;
|
||||||
pwmClk->ctl = (0x5A << 24) | 0x06;
|
pwmClk->ctl = (0x5A << 24) | 0x06;
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
pwmClk->div = (0x5A << 24) | (uint32_t)(getSourceFreq() * (0x01 << 12) / pwmClkFreq);
|
pwmClk->div = (0x5A << 24) | static_cast<uint32_t>(getSourceFreq() * (0x01 << 12) / pwmClkFreq);
|
||||||
pwmClk->ctl = (0x5A << 24) | (0x01 << 4) | 0x06;
|
pwmClk->ctl = (0x5A << 24) | (0x01 << 4) | 0x06;
|
||||||
|
|
||||||
volatile PWMRegisters *pwm = (PWMRegisters *)getPeripheralVirtAddress(PWM_BASE_OFFSET);
|
volatile PWMRegisters *pwm = reinterpret_cast<PWMRegisters *>(getPeripheralVirtAddress(PWM_BASE_OFFSET));
|
||||||
pwm->ctl = 0x00000000;
|
pwm->ctl = 0x00000000;
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
pwm->status = 0x01FC;
|
pwm->status = 0x01FC;
|
||||||
|
@ -240,7 +240,7 @@ void Transmitter::closePwmController(volatile PWMRegisters *pwm)
|
||||||
|
|
||||||
volatile DMARegisters *Transmitter::startDma(AllocatedMemory &memory, volatile DMAControllBlock *dmaCb, uint8_t dmaChannel)
|
volatile DMARegisters *Transmitter::startDma(AllocatedMemory &memory, volatile DMAControllBlock *dmaCb, uint8_t dmaChannel)
|
||||||
{
|
{
|
||||||
volatile DMARegisters *dma = (DMARegisters *)getPeripheralVirtAddress((dmaChannel < 15) ? DMA0_BASE_OFFSET + dmaChannel * 0x100 : DMA15_BASE_OFFSET);
|
volatile DMARegisters *dma = reinterpret_cast<DMARegisters *>(getPeripheralVirtAddress((dmaChannel < 15) ? DMA0_BASE_OFFSET + dmaChannel * 0x100 : DMA15_BASE_OFFSET));
|
||||||
dma->ctlStatus = (0x01 << 31);
|
dma->ctlStatus = (0x01 << 31);
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
dma->ctlStatus = (0x01 << 2) | (0x01 << 1);
|
dma->ctlStatus = (0x01 << 2) | (0x01 << 1);
|
||||||
|
@ -256,8 +256,8 @@ void Transmitter::closeDma(volatile DMARegisters *dma)
|
||||||
|
|
||||||
volatile ClockRegisters *Transmitter::initClockOutput()
|
volatile ClockRegisters *Transmitter::initClockOutput()
|
||||||
{
|
{
|
||||||
volatile ClockRegisters *clock = (ClockRegisters *)getPeripheralVirtAddress(CLK0_BASE_OFFSET);
|
volatile ClockRegisters *clock = reinterpret_cast<ClockRegisters *>(getPeripheralVirtAddress(CLK0_BASE_OFFSET));
|
||||||
volatile uint32_t *gpio = (uint32_t *)getPeripheralVirtAddress(GPIO_BASE_OFFSET);
|
volatile uint32_t *gpio = reinterpret_cast<uint32_t *>(getPeripheralVirtAddress(GPIO_BASE_OFFSET));
|
||||||
clock->ctl = (0x5A << 24) | 0x06;
|
clock->ctl = (0x5A << 24) | 0x06;
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
clock->div = (0x5A << 24) | clockDivisor;
|
clock->div = (0x5A << 24) | clockDivisor;
|
||||||
|
@ -280,11 +280,11 @@ void Transmitter::transmit(WaveReader &reader, double frequency, double bandwidt
|
||||||
transmitting = true;
|
transmitting = true;
|
||||||
|
|
||||||
PCMWaveHeader header = reader.getHeader();
|
PCMWaveHeader header = reader.getHeader();
|
||||||
uint32_t bufferSize = (uint32_t)((uint64_t)header.sampleRate * BUFFER_TIME / 1000000);
|
uint32_t bufferSize = static_cast<uint32_t>(static_cast<uint64_t>(header.sampleRate) * BUFFER_TIME / 1000000);
|
||||||
|
|
||||||
preserveCarrier = preserveCarrierOnExit;
|
preserveCarrier = preserveCarrierOnExit;
|
||||||
clockDivisor = (uint32_t)round(getSourceFreq() * (0x01 << 12) / frequency);
|
clockDivisor = static_cast<uint32_t>(round(getSourceFreq() * (0x01 << 12) / frequency));
|
||||||
divisorRange = clockDivisor - (uint32_t)round(getSourceFreq() * (0x01 << 12) / (frequency + 0.0005 * bandwidth));
|
divisorRange = clockDivisor - static_cast<uint32_t>(round(getSourceFreq() * (0x01 << 12) / (frequency + 0.0005 * bandwidth)));
|
||||||
sampleRate = header.sampleRate;
|
sampleRate = header.sampleRate;
|
||||||
|
|
||||||
if (!clockInitialized) {
|
if (!clockInitialized) {
|
||||||
|
@ -383,15 +383,15 @@ void Transmitter::transmitViaDma(WaveReader &reader, uint32_t bufferSize, uint8_
|
||||||
PreEmphasis preEmphasis(sampleRate);
|
PreEmphasis preEmphasis(sampleRate);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
volatile DMAControllBlock *dmaCb = (DMAControllBlock *)dmaMemory.virtualBase;
|
volatile DMAControllBlock *dmaCb = reinterpret_cast<DMAControllBlock *>(dmaMemory.virtualBase);
|
||||||
volatile uint32_t *clkDiv = (uint32_t *)((uint32_t)dmaCb + 2 * sizeof(DMAControllBlock) * bufferSize);
|
volatile uint32_t *clkDiv = reinterpret_cast<uint32_t *>(reinterpret_cast<uint32_t>(dmaCb) + 2 * sizeof(DMAControllBlock) * bufferSize);
|
||||||
volatile uint32_t *pwmFifoData = (uint32_t *)((uint32_t)clkDiv + sizeof(uint32_t) * bufferSize);
|
volatile uint32_t *pwmFifoData = reinterpret_cast<uint32_t *>(reinterpret_cast<uint32_t>(clkDiv) + sizeof(uint32_t) * bufferSize);
|
||||||
for (i = 0; i < bufferSize; i++) {
|
for (i = 0; i < bufferSize; i++) {
|
||||||
value = (*samples)[i].getMonoValue();
|
value = (*samples)[i].getMonoValue();
|
||||||
#ifndef NO_PREEMP
|
#ifndef NO_PREEMP
|
||||||
value = preEmphasis.filter(value);
|
value = preEmphasis.filter(value);
|
||||||
#endif
|
#endif
|
||||||
clkDiv[i] = (0x5A << 24) | (clockDivisor - (int32_t)round(value * divisorRange));
|
clkDiv[i] = (0x5A << 24) | (clockDivisor - static_cast<int32_t>(round(value * divisorRange)));
|
||||||
dmaCb[cbOffset].transferInfo = (0x01 << 26) | (0x01 << 3);
|
dmaCb[cbOffset].transferInfo = (0x01 << 26) | (0x01 << 3);
|
||||||
dmaCb[cbOffset].srcAddress = getMemoryPhysAddress(dmaMemory, &clkDiv[i]);
|
dmaCb[cbOffset].srcAddress = getMemoryPhysAddress(dmaMemory, &clkDiv[i]);
|
||||||
dmaCb[cbOffset].dstAddress = getPeripheralPhysAddress(&output->div);
|
dmaCb[cbOffset].dstAddress = getPeripheralPhysAddress(&output->div);
|
||||||
|
@ -432,7 +432,7 @@ void Transmitter::transmitViaDma(WaveReader &reader, uint32_t bufferSize, uint8_
|
||||||
while (i == ((dma->cbAddress - getMemoryPhysAddress(dmaMemory, dmaCb)) / (2 * sizeof(DMAControllBlock)))) {
|
while (i == ((dma->cbAddress - getMemoryPhysAddress(dmaMemory, dmaCb)) / (2 * sizeof(DMAControllBlock)))) {
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
}
|
}
|
||||||
clkDiv[i] = (0x5A << 24) | (clockDivisor - (int32_t)round(value * divisorRange));
|
clkDiv[i] = (0x5A << 24) | (clockDivisor - static_cast<int32_t>(round(value * divisorRange)));
|
||||||
cbOffset += 2;
|
cbOffset += 2;
|
||||||
}
|
}
|
||||||
delete samples;
|
delete samples;
|
||||||
|
@ -470,8 +470,8 @@ void Transmitter::transmitThread()
|
||||||
PreEmphasis preEmphasis(sampleRate);
|
PreEmphasis preEmphasis(sampleRate);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
volatile TimerRegisters *timer = (TimerRegisters *)getPeripheralVirtAddress(TIMER_BASE_OFFSET);
|
volatile TimerRegisters *timer = reinterpret_cast<TimerRegisters *>(getPeripheralVirtAddress(TIMER_BASE_OFFSET));
|
||||||
uint64_t current = *(uint64_t *)&timer->low;
|
uint64_t current = *(reinterpret_cast<volatile uint64_t *>(&timer->low));
|
||||||
uint64_t playbackStart = current;
|
uint64_t playbackStart = current;
|
||||||
|
|
||||||
while (transmitting) {
|
while (transmitting) {
|
||||||
|
@ -479,7 +479,7 @@ void Transmitter::transmitThread()
|
||||||
|
|
||||||
while ((buffer == nullptr) && transmitting) {
|
while ((buffer == nullptr) && transmitting) {
|
||||||
usleep(1);
|
usleep(1);
|
||||||
current = *(uint64_t *)&timer->low;
|
current = *(reinterpret_cast<volatile uint64_t *>(&timer->low));
|
||||||
}
|
}
|
||||||
if (!transmitting) {
|
if (!transmitting) {
|
||||||
break;
|
break;
|
||||||
|
@ -501,10 +501,10 @@ void Transmitter::transmitThread()
|
||||||
#ifndef NO_PREEMP
|
#ifndef NO_PREEMP
|
||||||
value = preEmphasis.filter(value);
|
value = preEmphasis.filter(value);
|
||||||
#endif
|
#endif
|
||||||
output->div = (0x5A << 24) | (clockDivisor - (int32_t)round(value * divisorRange));
|
output->div = (0x5A << 24) | (clockDivisor - static_cast<int32_t>(round(value * divisorRange)));
|
||||||
while (offset == prevOffset) {
|
while (offset == prevOffset) {
|
||||||
usleep(1); // asm("nop");
|
usleep(1); // asm("nop");
|
||||||
current = *(uint64_t *)&timer->low;
|
current = *(reinterpret_cast<volatile uint64_t *>(&timer->low));;
|
||||||
offset = (current - start) * sampleRate / 1000000;
|
offset = (current - start) * sampleRate / 1000000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ WaveReader::WaveReader(std::string filename, bool &continueFlag) :
|
||||||
|
|
||||||
try {
|
try {
|
||||||
readData(sizeof(PCMWaveHeader::chunkID) + sizeof(PCMWaveHeader::chunkSize) + sizeof(PCMWaveHeader::format), true, continueFlag);
|
readData(sizeof(PCMWaveHeader::chunkID) + sizeof(PCMWaveHeader::chunkSize) + sizeof(PCMWaveHeader::format), true, continueFlag);
|
||||||
if ((std::string((char *)header.chunkID, 4) != std::string("RIFF")) || (std::string((char *)header.format, 4) != std::string("WAVE"))) {
|
if ((std::string(reinterpret_cast<char *>(header.chunkID), 4) != std::string("RIFF")) || (std::string(reinterpret_cast<char *>(header.format), 4) != std::string("WAVE"))) {
|
||||||
throw ErrorReporter(std::string("Error while opening ") + getFilename() + std::string(", WAVE file expected"));
|
throw ErrorReporter(std::string("Error while opening ") + getFilename() + std::string(", WAVE file expected"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ WaveReader::WaveReader(std::string filename, bool &continueFlag) :
|
||||||
uint32_t subchunk1MinSize = sizeof(PCMWaveHeader::audioFormat) + sizeof(PCMWaveHeader::channels) +
|
uint32_t subchunk1MinSize = sizeof(PCMWaveHeader::audioFormat) + sizeof(PCMWaveHeader::channels) +
|
||||||
sizeof(PCMWaveHeader::sampleRate) + sizeof(PCMWaveHeader::byteRate) + sizeof(PCMWaveHeader::blockAlign) +
|
sizeof(PCMWaveHeader::sampleRate) + sizeof(PCMWaveHeader::byteRate) + sizeof(PCMWaveHeader::blockAlign) +
|
||||||
sizeof(PCMWaveHeader::bitsPerSample);
|
sizeof(PCMWaveHeader::bitsPerSample);
|
||||||
if ((std::string((char *)header.subchunk1ID, 4) != std::string("fmt ")) || (header.subchunk1Size < subchunk1MinSize)) {
|
if ((std::string(reinterpret_cast<char *>(header.subchunk1ID), 4) != std::string("fmt ")) || (header.subchunk1Size < subchunk1MinSize)) {
|
||||||
throw ErrorReporter(std::string("Error while opening ") + getFilename() + std::string(", data corrupted"));
|
throw ErrorReporter(std::string("Error while opening ") + getFilename() + std::string(", data corrupted"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ WaveReader::WaveReader(std::string filename, bool &continueFlag) :
|
||||||
}
|
}
|
||||||
|
|
||||||
readData(sizeof(PCMWaveHeader::subchunk2ID) + sizeof(PCMWaveHeader::subchunk2Size), true, continueFlag);
|
readData(sizeof(PCMWaveHeader::subchunk2ID) + sizeof(PCMWaveHeader::subchunk2Size), true, continueFlag);
|
||||||
if (std::string((char *)header.subchunk2ID, 4) != std::string("data")) {
|
if (std::string(reinterpret_cast<char *>(header.subchunk2ID), 4) != std::string("data")) {
|
||||||
throw ErrorReporter(std::string("Error while opening ") + getFilename() + std::string(", data corrupted"));
|
throw ErrorReporter(std::string("Error while opening ") + getFilename() + std::string(", data corrupted"));
|
||||||
}
|
}
|
||||||
} catch (ErrorReporter &error) {
|
} catch (ErrorReporter &error) {
|
||||||
|
@ -105,7 +105,7 @@ std::vector<uint8_t> *WaveReader::readData(uint32_t bytesToRead, bool headerByte
|
||||||
while ((bytesRead < bytesToRead) && continueFlag) {
|
while ((bytesRead < bytesToRead) && continueFlag) {
|
||||||
int bytes = read(fileDescriptor, &(*data)[bytesRead], bytesToRead - bytesRead);
|
int bytes = read(fileDescriptor, &(*data)[bytesRead], bytesToRead - bytesRead);
|
||||||
if (((bytes == -1) && ((fileDescriptor != STDIN_FILENO) || (errno != EAGAIN))) ||
|
if (((bytes == -1) && ((fileDescriptor != STDIN_FILENO) || (errno != EAGAIN))) ||
|
||||||
(((uint32_t)bytes < bytesToRead) && headerBytes && (fileDescriptor != STDIN_FILENO))) {
|
((static_cast<uint32_t>(bytes) < bytesToRead) && headerBytes && (fileDescriptor != STDIN_FILENO))) {
|
||||||
delete data;
|
delete data;
|
||||||
throw ErrorReporter(std::string("Error while opening ") + getFilename() + std::string(", data corrupted"));
|
throw ErrorReporter(std::string("Error while opening ") + getFilename() + std::string(", data corrupted"));
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,7 @@ std::vector<uint8_t> *WaveReader::readData(uint32_t bytesToRead, bool headerByte
|
||||||
if (data == NULL) {
|
if (data == NULL) {
|
||||||
throw ErrorReporter("Cannot obtain header, program interrupted");
|
throw ErrorReporter("Cannot obtain header, program interrupted");
|
||||||
}
|
}
|
||||||
memcpy(&((uint8_t *)&header)[headerOffset], &(*data)[0], bytesRead);
|
memcpy(&(reinterpret_cast<uint8_t *>(&header))[headerOffset], &(*data)[0], bytesRead);
|
||||||
headerOffset += bytesRead;
|
headerOffset += bytesRead;
|
||||||
delete data;
|
delete data;
|
||||||
data = NULL;
|
data = NULL;
|
||||||
|
|
Ładowanie…
Reference in New Issue