Tone generator class

This commit is contained in:
furrtek
2017-11-10 00:25:04 +00:00
parent 32ae059c44
commit 1b93dd53e8
16 changed files with 143 additions and 78 deletions

View File

@@ -136,6 +136,7 @@ set(CPPSRC
${COMMON}/chibios_cpp.cpp
${COMMON}/debug.cpp
${COMMON}/gcc.cpp
tone_gen.cpp
)
# C sources to be compiled in ARM mode regardless of the global setting.

View File

@@ -52,16 +52,10 @@ void AudioTXProcessor::execute(const buffer_c8_t& buffer){
as--;
}
if (ctcss_enabled) {
ctcss_sample = sine_table_i8[(ctcss_phase & 0xFF000000U) >> 24];
sample_mixed = ((sample * 205) + (ctcss_sample * 50)) / 256; // ~20%
ctcss_phase += ctcss_phase_inc;
} else {
sample_mixed = sample;
}
sample = tone_gen.process(sample);
// FM
delta = sample_mixed * fm_delta;
delta = sample * fm_delta;
phase += delta;
sphase = phase + (64 << 24);
@@ -82,9 +76,9 @@ void AudioTXProcessor::on_message(const Message* const msg) {
case Message::ID::AudioTXConfig:
fm_delta = message.fm_delta * (0xFFFFFFULL / 1536000);
divider = message.divider;
ctcss_enabled = message.ctcss_enabled;
ctcss_phase_inc = message.ctcss_phase_inc;
as = 0;
tone_gen.configure(message.tone_key_delta, message.tone_key_mix_weight);
configured = true;
break;

View File

@@ -26,6 +26,7 @@
#include "fifo.hpp"
#include "baseband_processor.hpp"
#include "baseband_thread.hpp"
#include "tone_gen.hpp"
class AudioTXProcessor : public BasebandProcessor {
public:
@@ -41,14 +42,14 @@ private:
int8_t audio_fifo_data[2048] { };
FIFO<int8_t> audio_fifo = { audio_fifo_data, 11 }; // 43ms @ 48000Hz
ToneGen tone_gen { };
uint32_t fm_delta { 0 };
uint32_t divider { };
uint32_t as { 0 };
bool ctcss_enabled { false };
uint32_t ctcss_phase_inc { };
uint32_t ctcss_phase { 0 }, phase { 0 }, sphase { 0 };
uint32_t phase { 0 }, sphase { 0 };
int8_t out_sample { };
int32_t ctcss_sample { 0 }, sample { 0 }, sample_mixed { }, delta { };
int32_t sample { 0 }, delta { };
int8_t re { 0 }, im { 0 };

View File

@@ -39,48 +39,43 @@ void MicTXProcessor::execute(const buffer_c8_t& buffer){
for (size_t i = 0; i < buffer.count; i++) {
if (!play_beep) {
sample = audio_buffer.p[i >> 6] >> 8; // 1536000 / 64 = 24000
sample = audio_buffer.p[i >> 6] >> 8; // 1536000 / 64 = 24000
sample = (sample * (int32_t)gain_x10) / 10;
power += (sample < 0) ? -sample : sample; // Power average for UI vu-meter
power_acc += (sample < 0) ? -sample : sample; // Power average for UI vu-meter
if (!as) {
as = divider;
level_message.value = power / (divider / 4); // Why ?
shared_memory.application_queue.push(level_message);
power = 0;
if (power_acc_count) {
power_acc_count--;
} else {
as--;
power_acc_count = divider;
level_message.value = power_acc / (divider / 4); // Why ?
shared_memory.application_queue.push(level_message);
power_acc = 0;
}
} else {
if (beep_timer) {
beep_timer--;
} else {
beep_timer = 76800; // 50ms @ 1536000Hz
beep_timer = baseband_fs * 0.05; // 50ms
if (beep_index == BEEP_TONES_NB) {
configured = false;
fm_delta = 0; // Zero-out the IQ output for the rest of the buffer
shared_memory.application_queue.push(txprogress_message);
} else {
beep_phase_inc = beep_deltas[beep_index];
beep_gen.configure(beep_deltas[beep_index], 1.0);
beep_index++;
}
}
sample = sine_table_i8[(beep_phase & 0xFF000000U) >> 24];
beep_phase += beep_phase_inc;
sample = beep_gen.process(0);
}
if (ctcss_enabled) {
ctcss_sample = sine_table_i8[(ctcss_phase & 0xFF000000U) >> 24];
sample_mixed = ((sample * 205) + (ctcss_sample * 50)) / 256; // ~20%
ctcss_phase += ctcss_phase_inc;
} else {
sample_mixed = sample;
}
sample = tone_gen.process(sample);
// FM
if (fm_delta) {
delta = sample_mixed * fm_delta;
delta = sample * fm_delta;
phase += delta;
sphase = phase + (64 << 24);
@@ -105,8 +100,9 @@ void MicTXProcessor::on_message(const Message* const msg) {
fm_delta = config_message.fm_delta * (0xFFFFFFULL / baseband_fs);
gain_x10 = config_message.gain_x10;
divider = config_message.divider;
ctcss_enabled = config_message.ctcss_enabled;
ctcss_phase_inc = config_message.ctcss_phase_inc;
power_acc_count = 0;
tone_gen.configure(config_message.tone_key_delta, config_message.tone_key_mix_weight);
txprogress_message.done = true;

View File

@@ -23,9 +23,10 @@
#ifndef __PROC_MICTX_H__
#define __PROC_MICTX_H__
#include "audio_input.hpp"
#include "baseband_processor.hpp"
#include "baseband_thread.hpp"
#include "audio_input.hpp"
#include "tone_gen.hpp"
class MicTXProcessor : public BasebandProcessor {
public:
@@ -47,17 +48,17 @@ private:
};
AudioInput audio_input { };
ToneGen tone_gen { };
ToneGen beep_gen { };
uint32_t divider { }, gain_x10 { };
uint32_t as { 0 };
uint32_t fm_delta { 0 };
uint64_t power_acc { 0 };
uint32_t power_acc_count { 0 };
bool play_beep { false };
bool ctcss_enabled { false };
uint32_t ctcss_phase_inc { };
uint32_t ctcss_phase { 0 }, phase { 0 }, sphase { 0 };
int32_t ctcss_sample { 0 }, sample { 0 }, sample_mixed { }, delta { };
uint32_t beep_phase { 0 }, beep_phase_inc { }, beep_index { }, beep_timer { };
uint64_t power { 0 };
uint32_t fm_delta { 0 };
uint32_t phase { 0 }, sphase { 0 };
int32_t sample { 0 }, delta { };
uint32_t beep_index { }, beep_timer { };
int8_t re { 0 }, im { 0 };

View File

@@ -0,0 +1,40 @@
/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2017 Furrtek
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "tone_gen.hpp"
#include "sine_table_int8.hpp"
void ToneGen::configure(const uint32_t delta, const float tone_mix_weight) {
delta_ = delta;
tone_mix_weight_ = tone_mix_weight;
input_mix_weight_ = 1.0 - tone_mix_weight;
}
int32_t ToneGen::process(const int32_t sample_in) {
if (!delta_)
return sample_in;
int32_t tone_sample = sine_table_i8[(tone_phase_ & 0xFF000000U) >> 24];
tone_phase_ += delta_;
return (sample_in * input_mix_weight_) + (tone_sample * tone_mix_weight_);
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2017 Furrtek
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef __TONE_GEN_H__
#define __TONE_GEN_H__
#include <cstdint>
#include <cstddef>
class ToneGen {
public:
/*ToneGen(const size_t sample_rate
) : sample_rate_ { sample_rate }
{};*/
void configure(const uint32_t delta, const float tone_mix_weight);
int32_t process(const int32_t sample_in);
private:
//size_t sample_rate_;
float input_mix_weight_ { 1 };
float tone_mix_weight_ { 0 };
uint32_t delta_ { 0 };
uint32_t tone_phase_ { 0 };
};
#endif