mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-22 08:04:49 -05:00
M17 modulator: SMS packet +
This commit is contained in:
parent
dd2233f763
commit
f10da64717
@ -39,6 +39,7 @@ public:
|
|||||||
using codec_frame_t = std::array<uint8_t, 16>;
|
using codec_frame_t = std::array<uint8_t, 16>;
|
||||||
using payload_t = std::array<uint8_t, 34>; // Bytes in the payload of a data frame.
|
using payload_t = std::array<uint8_t, 34>; // Bytes in the payload of a data frame.
|
||||||
using frame_t = std::array<uint8_t, 46>; // M17 frame (without sync word).
|
using frame_t = std::array<uint8_t, 46>; // M17 frame (without sync word).
|
||||||
|
using packet_t = std::array<uint8_t, 25>; // Packet payload
|
||||||
|
|
||||||
static constexpr std::array<uint8_t, 2> SYNC_WORD = {0x32, 0x43};
|
static constexpr std::array<uint8_t, 2> SYNC_WORD = {0x32, 0x43};
|
||||||
static constexpr std::array<uint8_t, 2> LSF_SYNC_WORD = {0x55, 0xF7};
|
static constexpr std::array<uint8_t, 2> LSF_SYNC_WORD = {0x55, 0xF7};
|
||||||
@ -57,6 +58,31 @@ public:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, size_t N>
|
||||||
|
static std::array<int8_t, N * 4> bytes_to_symbols(const std::array<T, N>& bytes)
|
||||||
|
{
|
||||||
|
std::array<int8_t, N * 4> result;
|
||||||
|
size_t index = 0;
|
||||||
|
|
||||||
|
for (auto b : bytes)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i != 4; ++i)
|
||||||
|
{
|
||||||
|
result[index++] = bits_to_symbol(b >> 6);
|
||||||
|
b <<= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void make_preamble(std::array<uint8_t, 48>& preamble_bytes)
|
||||||
|
{
|
||||||
|
// Preamble is simple... bytes -> symbols.
|
||||||
|
preamble_bytes.fill(0x77);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encode each LSF segment into a Golay-encoded LICH segment bitstream.
|
* Encode each LSF segment into a Golay-encoded LICH segment bitstream.
|
||||||
*/
|
*/
|
||||||
@ -109,7 +135,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Construct the link setup frame and split into LICH segments.
|
* Construct the link setup frame and split into LICH segments.
|
||||||
*/
|
*/
|
||||||
void make_link_setup(lich_t& lich, mobilinkd::M17Modulator::frame_t lsf)
|
void make_link_setup(lich_t& lich, mobilinkd::M17Modulator::frame_t lsf_frame)
|
||||||
{
|
{
|
||||||
using namespace mobilinkd;
|
using namespace mobilinkd;
|
||||||
|
|
||||||
@ -141,12 +167,14 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto encoded = conv_encode(lsf);
|
auto encoded = conv_encode(lsf);
|
||||||
|
auto size = puncture_bytes(encoded, lsf_frame, P1);
|
||||||
|
|
||||||
auto size = puncture_bytes(encoded, lsf, P1);
|
if (size != 368) {
|
||||||
assert(size == 368);
|
std::cerr << "make_link_setup: incorrect size (not 368)" << size;
|
||||||
|
}
|
||||||
|
|
||||||
interleaver_.interleave(lsf);
|
interleaver_.interleave(lsf_frame);
|
||||||
randomizer_(lsf);
|
randomizer_(lsf_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -168,7 +196,7 @@ public:
|
|||||||
* Assemble the audio frame payload by appending the frame number, encoded audio,
|
* Assemble the audio frame payload by appending the frame number, encoded audio,
|
||||||
* and CRC, then convolutionally coding and puncturing the data.
|
* and CRC, then convolutionally coding and puncturing the data.
|
||||||
*/
|
*/
|
||||||
payload_t make_payload(uint16_t frame_number, const codec_frame_t& payload)
|
payload_t make_audio_payload(uint16_t frame_number, const codec_frame_t& payload)
|
||||||
{
|
{
|
||||||
std::array<uint8_t, 20> data; // FN, Audio, CRC = 2 + 16 + 2;
|
std::array<uint8_t, 20> data; // FN, Audio, CRC = 2 + 16 + 2;
|
||||||
data[0] = uint8_t((frame_number >> 8) & 0xFF);
|
data[0] = uint8_t((frame_number >> 8) & 0xFF);
|
||||||
@ -188,7 +216,47 @@ public:
|
|||||||
|
|
||||||
payload_t punctured;
|
payload_t punctured;
|
||||||
auto size = puncture_bytes(encoded, punctured, mobilinkd::P2);
|
auto size = puncture_bytes(encoded, punctured, mobilinkd::P2);
|
||||||
assert(size == 272);
|
|
||||||
|
if (size != 272) {
|
||||||
|
std::cerr << "mobilinkd::M17Modulator::make_audio_payload: incorrect size (not 272)" << size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return punctured;
|
||||||
|
}
|
||||||
|
|
||||||
|
frame_t make_packet_frame(uint8_t packet_number, bool last_packet, packet_t packet, int packet_size)
|
||||||
|
{
|
||||||
|
std::array<uint8_t, 26> packet_assembly;
|
||||||
|
packet_assembly.fill(0);
|
||||||
|
std::copy(packet.begin(), packet.begin() + packet_size, packet_assembly.begin());
|
||||||
|
|
||||||
|
if (packet_number == 0) {
|
||||||
|
crc_.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < packet_size; i++) {
|
||||||
|
crc_(packet[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last_packet)
|
||||||
|
{
|
||||||
|
packet_assembly[25] = 0x80 | (packet_size<<2);
|
||||||
|
packet_assembly[packet_size] = crc_.get_bytes()[1];
|
||||||
|
packet_assembly[packet_size+1] = crc_.get_bytes()[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
packet_assembly[25] = (packet_number<<2);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::array<uint8_t, 2*26+1> encoded = conv_encode(packet_assembly);
|
||||||
|
frame_t punctured;
|
||||||
|
auto size = puncture_bytes(encoded, punctured, mobilinkd::P3);
|
||||||
|
|
||||||
|
if (size != 368) {
|
||||||
|
std::cerr << "mobilinkd::M17Modulator::make_packet_frame: incorrect size (not 368)" << size;
|
||||||
|
}
|
||||||
|
|
||||||
return punctured;
|
return punctured;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,24 +348,6 @@ private:
|
|||||||
return encoded_call;
|
return encoded_call;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, size_t N>
|
|
||||||
static std::array<int8_t, N * 4> bytes_to_symbols(const std::array<T, N>& bytes)
|
|
||||||
{
|
|
||||||
std::array<int8_t, N * 4> result;
|
|
||||||
size_t index = 0;
|
|
||||||
|
|
||||||
for (auto b : bytes)
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i != 4; ++i)
|
|
||||||
{
|
|
||||||
result[index++] = bits_to_symbol(b >> 6);
|
|
||||||
b <<= 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, size_t N>
|
template <typename T, size_t N>
|
||||||
static std::array<T, N * 2 + 1> conv_encode(std::array<T, N> data)
|
static std::array<T, N * 2 + 1> conv_encode(std::array<T, N> data)
|
||||||
{
|
{
|
||||||
|
@ -4,6 +4,7 @@ set(modm17_SOURCES
|
|||||||
m17mod.cpp
|
m17mod.cpp
|
||||||
m17modbaseband.cpp
|
m17modbaseband.cpp
|
||||||
m17modsource.cpp
|
m17modsource.cpp
|
||||||
|
m17modprocessor.cpp
|
||||||
m17modplugin.cpp
|
m17modplugin.cpp
|
||||||
m17modsettings.cpp
|
m17modsettings.cpp
|
||||||
m17modwebapiadapter.cpp
|
m17modwebapiadapter.cpp
|
||||||
@ -13,6 +14,7 @@ set(modm17_HEADERS
|
|||||||
m17mod.h
|
m17mod.h
|
||||||
m17modbaseband.h
|
m17modbaseband.h
|
||||||
m17modsource.h
|
m17modsource.h
|
||||||
|
m17modprocessor.h
|
||||||
m17modplugin.h
|
m17modplugin.h
|
||||||
m17modsettings.h
|
m17modsettings.h
|
||||||
m17modwebapiadapter.h
|
m17modwebapiadapter.h
|
||||||
@ -20,6 +22,8 @@ set(modm17_HEADERS
|
|||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client
|
${CMAKE_SOURCE_DIR}/swagger/sdrangel/code/qt5/client
|
||||||
|
${CODEC2_INCLUDE_DIR}
|
||||||
|
${CMAKE_SOURCE_DIR}/modems
|
||||||
)
|
)
|
||||||
|
|
||||||
if(NOT SERVER_MODE)
|
if(NOT SERVER_MODE)
|
||||||
@ -48,12 +52,18 @@ add_library(${TARGET_NAME} SHARED
|
|||||||
${modm17_SOURCES}
|
${modm17_SOURCES}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(CODEC2_EXTERNAL)
|
||||||
|
add_dependencies(${TARGET_NAME} codec2)
|
||||||
|
endif()
|
||||||
|
|
||||||
target_link_libraries(${TARGET_NAME}
|
target_link_libraries(${TARGET_NAME}
|
||||||
Qt5::Core
|
Qt5::Core
|
||||||
${TARGET_LIB}
|
${TARGET_LIB}
|
||||||
sdrbase
|
sdrbase
|
||||||
${TARGET_LIB_GUI}
|
${TARGET_LIB_GUI}
|
||||||
swagger
|
swagger
|
||||||
|
${CODEC2_LIBRARIES}
|
||||||
|
modems
|
||||||
)
|
)
|
||||||
|
|
||||||
install(TARGETS ${TARGET_NAME} DESTINATION ${INSTALL_FOLDER})
|
install(TARGETS ${TARGET_NAME} DESTINATION ${INSTALL_FOLDER})
|
||||||
|
@ -294,7 +294,9 @@ void M17Mod::applySettings(const M17ModSettings& settings, bool force)
|
|||||||
<< " m_toneFrequency: " << settings.m_toneFrequency
|
<< " m_toneFrequency: " << settings.m_toneFrequency
|
||||||
<< " m_channelMute: " << settings.m_channelMute
|
<< " m_channelMute: " << settings.m_channelMute
|
||||||
<< " m_playLoop: " << settings.m_playLoop
|
<< " m_playLoop: " << settings.m_playLoop
|
||||||
<< " m_modAFInput " << settings.m_modAFInput
|
<< " m_m17Mode " << settings.m_m17Mode
|
||||||
|
<< " m_audioType " << settings.m_audioType
|
||||||
|
<< " m_packetType " << settings.m_packetType
|
||||||
<< " m_audioDeviceName: " << settings.m_audioDeviceName
|
<< " m_audioDeviceName: " << settings.m_audioDeviceName
|
||||||
<< " m_useReverseAPI: " << settings.m_useReverseAPI
|
<< " m_useReverseAPI: " << settings.m_useReverseAPI
|
||||||
<< " m_reverseAPIAddress: " << settings.m_reverseAPIAddress
|
<< " m_reverseAPIAddress: " << settings.m_reverseAPIAddress
|
||||||
@ -320,8 +322,14 @@ void M17Mod::applySettings(const M17ModSettings& settings, bool force)
|
|||||||
if ((settings.m_playLoop != m_settings.m_playLoop) || force) {
|
if ((settings.m_playLoop != m_settings.m_playLoop) || force) {
|
||||||
reverseAPIKeys.append("playLoop");
|
reverseAPIKeys.append("playLoop");
|
||||||
}
|
}
|
||||||
if ((settings.m_modAFInput != m_settings.m_modAFInput) || force) {
|
if ((settings.m_audioType != m_settings.m_audioType) || force) {
|
||||||
reverseAPIKeys.append("modAFInput");
|
reverseAPIKeys.append("audioType");
|
||||||
|
}
|
||||||
|
if ((settings.m_packetType != m_settings.m_packetType) || force) {
|
||||||
|
reverseAPIKeys.append("packetType");
|
||||||
|
}
|
||||||
|
if ((settings.m_m17Mode != m_settings.m_m17Mode) || force) {
|
||||||
|
reverseAPIKeys.append("m17Mode");
|
||||||
}
|
}
|
||||||
if((settings.m_rfBandwidth != m_settings.m_rfBandwidth) || force) {
|
if((settings.m_rfBandwidth != m_settings.m_rfBandwidth) || force) {
|
||||||
reverseAPIKeys.append("rfBandwidth");
|
reverseAPIKeys.append("rfBandwidth");
|
||||||
@ -470,8 +478,14 @@ void M17Mod::webapiUpdateChannelSettings(
|
|||||||
if (channelSettingsKeys.contains("inputFrequencyOffset")) {
|
if (channelSettingsKeys.contains("inputFrequencyOffset")) {
|
||||||
settings.m_inputFrequencyOffset = response.getM17ModSettings()->getInputFrequencyOffset();
|
settings.m_inputFrequencyOffset = response.getM17ModSettings()->getInputFrequencyOffset();
|
||||||
}
|
}
|
||||||
if (channelSettingsKeys.contains("modAFInput")) {
|
if (channelSettingsKeys.contains("m17Mode")) {
|
||||||
settings.m_modAFInput = (M17ModSettings::M17ModInputAF) response.getM17ModSettings()->getModAfInput();
|
settings.m_m17Mode = (M17ModSettings::M17Mode) response.getM17ModSettings()->getM17Mode();
|
||||||
|
}
|
||||||
|
if (channelSettingsKeys.contains("audioType")) {
|
||||||
|
settings.m_audioType = (M17ModSettings::AudioType) response.getM17ModSettings()->getAudioType();
|
||||||
|
}
|
||||||
|
if (channelSettingsKeys.contains("packetType")) {
|
||||||
|
settings.m_packetType = (M17ModSettings::PacketType) response.getM17ModSettings()->getPacketType();
|
||||||
}
|
}
|
||||||
if (channelSettingsKeys.contains("playLoop")) {
|
if (channelSettingsKeys.contains("playLoop")) {
|
||||||
settings.m_playLoop = response.getM17ModSettings()->getPlayLoop() != 0;
|
settings.m_playLoop = response.getM17ModSettings()->getPlayLoop() != 0;
|
||||||
@ -533,7 +547,9 @@ void M17Mod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& respon
|
|||||||
response.getM17ModSettings()->setChannelMute(settings.m_channelMute ? 1 : 0);
|
response.getM17ModSettings()->setChannelMute(settings.m_channelMute ? 1 : 0);
|
||||||
response.getM17ModSettings()->setFmDeviation(settings.m_fmDeviation);
|
response.getM17ModSettings()->setFmDeviation(settings.m_fmDeviation);
|
||||||
response.getM17ModSettings()->setInputFrequencyOffset(settings.m_inputFrequencyOffset);
|
response.getM17ModSettings()->setInputFrequencyOffset(settings.m_inputFrequencyOffset);
|
||||||
response.getM17ModSettings()->setModAfInput((int) settings.m_modAFInput);
|
response.getM17ModSettings()->setM17Mode((int) settings.m_m17Mode);
|
||||||
|
response.getM17ModSettings()->setAudioType((int) settings.m_audioType);
|
||||||
|
response.getM17ModSettings()->setPacketType((int) settings.m_packetType);
|
||||||
response.getM17ModSettings()->setPlayLoop(settings.m_playLoop ? 1 : 0);
|
response.getM17ModSettings()->setPlayLoop(settings.m_playLoop ? 1 : 0);
|
||||||
response.getM17ModSettings()->setRfBandwidth(settings.m_rfBandwidth);
|
response.getM17ModSettings()->setRfBandwidth(settings.m_rfBandwidth);
|
||||||
response.getM17ModSettings()->setRgbColor(settings.m_rgbColor);
|
response.getM17ModSettings()->setRgbColor(settings.m_rgbColor);
|
||||||
@ -673,8 +689,14 @@ void M17Mod::webapiFormatChannelSettings(
|
|||||||
if (channelSettingsKeys.contains("inputFrequencyOffset") || force) {
|
if (channelSettingsKeys.contains("inputFrequencyOffset") || force) {
|
||||||
swgM17ModSettings->setInputFrequencyOffset(settings.m_inputFrequencyOffset);
|
swgM17ModSettings->setInputFrequencyOffset(settings.m_inputFrequencyOffset);
|
||||||
}
|
}
|
||||||
if (channelSettingsKeys.contains("modAFInput") || force) {
|
if (channelSettingsKeys.contains("m17Mode") || force) {
|
||||||
swgM17ModSettings->setModAfInput((int) settings.m_modAFInput);
|
swgM17ModSettings->setM17Mode((int) settings.m_m17Mode);
|
||||||
|
}
|
||||||
|
if (channelSettingsKeys.contains("audioType") || force) {
|
||||||
|
swgM17ModSettings->setAudioType((int) settings.m_audioType);
|
||||||
|
}
|
||||||
|
if (channelSettingsKeys.contains("packetType") || force) {
|
||||||
|
swgM17ModSettings->setPacketType((int) settings.m_packetType);
|
||||||
}
|
}
|
||||||
if (channelSettingsKeys.contains("audioDeviceName") || force) {
|
if (channelSettingsKeys.contains("audioDeviceName") || force) {
|
||||||
swgM17ModSettings->setAudioDeviceName(new QString(settings.m_audioDeviceName));
|
swgM17ModSettings->setAudioDeviceName(new QString(settings.m_audioDeviceName));
|
||||||
@ -764,3 +786,8 @@ int M17Mod::getFeedbackAudioSampleRate() const
|
|||||||
{
|
{
|
||||||
return m_basebandSource->getFeedbackAudioSampleRate();
|
return m_basebandSource->getFeedbackAudioSampleRate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void M17Mod::sendPacket()
|
||||||
|
{
|
||||||
|
m_basebandSource->sendPacket();
|
||||||
|
}
|
||||||
|
@ -233,6 +233,7 @@ public:
|
|||||||
uint32_t getNumberOfDeviceStreams() const;
|
uint32_t getNumberOfDeviceStreams() const;
|
||||||
int getAudioSampleRate() const;
|
int getAudioSampleRate() const;
|
||||||
int getFeedbackAudioSampleRate() const;
|
int getFeedbackAudioSampleRate() const;
|
||||||
|
void sendPacket();
|
||||||
|
|
||||||
static const char* const m_channelIdURI;
|
static const char* const m_channelIdURI;
|
||||||
static const char* const m_channelId;
|
static const char* const m_channelId;
|
||||||
|
@ -196,12 +196,12 @@ void M17ModBaseband::applySettings(const M17ModSettings& settings, bool force)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((settings.m_modAFInput != m_settings.m_modAFInput) || force)
|
if ((settings.m_audioType != m_settings.m_audioType) || force)
|
||||||
{
|
{
|
||||||
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
|
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
|
||||||
int audioDeviceIndex = audioDeviceManager->getInputDeviceIndex(settings.m_audioDeviceName);
|
int audioDeviceIndex = audioDeviceManager->getInputDeviceIndex(settings.m_audioDeviceName);
|
||||||
|
|
||||||
if (settings.m_modAFInput == M17ModSettings::M17ModInputAudio) {
|
if (settings.m_audioType == M17ModSettings::AudioInput) {
|
||||||
audioDeviceManager->addAudioSource(getAudioFifo(), getInputMessageQueue(), audioDeviceIndex);
|
audioDeviceManager->addAudioSource(getAudioFifo(), getInputMessageQueue(), audioDeviceIndex);
|
||||||
} else {
|
} else {
|
||||||
audioDeviceManager->removeAudioSource(getAudioFifo());
|
audioDeviceManager->removeAudioSource(getAudioFifo());
|
||||||
|
@ -70,6 +70,7 @@ public:
|
|||||||
AudioFifo *getAudioFifo() { return m_source.getAudioFifo(); }
|
AudioFifo *getAudioFifo() { return m_source.getAudioFifo(); }
|
||||||
AudioFifo *getFeedbackAudioFifo() { return m_source.getFeedbackAudioFifo(); }
|
AudioFifo *getFeedbackAudioFifo() { return m_source.getFeedbackAudioFifo(); }
|
||||||
void setChannel(ChannelAPI *channel);
|
void setChannel(ChannelAPI *channel);
|
||||||
|
void sendPacket() { m_source.sendPacket(); }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
/**
|
/**
|
||||||
|
@ -182,6 +182,22 @@ void M17ModGUI::on_toneFrequency_valueChanged(int value)
|
|||||||
applySettings();
|
applySettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void M17ModGUI::on_fmAudio_toggled(bool checked)
|
||||||
|
{
|
||||||
|
m_fmAudioMode = checked;
|
||||||
|
|
||||||
|
if ((checked) && (m_settings.m_m17Mode == M17ModSettings::M17Mode::M17ModeM17Audio))
|
||||||
|
{
|
||||||
|
m_settings.m_m17Mode = M17ModSettings::M17Mode::M17ModeFMAudio;
|
||||||
|
applySettings();
|
||||||
|
}
|
||||||
|
else if ((!checked) && (m_settings.m_m17Mode == M17ModSettings::M17Mode::M17ModeFMAudio))
|
||||||
|
{
|
||||||
|
m_settings.m_m17Mode = M17ModSettings::M17Mode::M17ModeM17Audio;
|
||||||
|
applySettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void M17ModGUI::on_channelMute_toggled(bool checked)
|
void M17ModGUI::on_channelMute_toggled(bool checked)
|
||||||
{
|
{
|
||||||
m_settings.m_channelMute = checked;
|
m_settings.m_channelMute = checked;
|
||||||
@ -196,9 +212,13 @@ void M17ModGUI::on_playLoop_toggled(bool checked)
|
|||||||
|
|
||||||
void M17ModGUI::on_play_toggled(bool checked)
|
void M17ModGUI::on_play_toggled(bool checked)
|
||||||
{
|
{
|
||||||
ui->tone->setEnabled(!checked); // release other source inputs
|
m_settings.m_audioType = checked ? M17ModSettings::AudioFile : M17ModSettings::AudioNone;
|
||||||
ui->mic->setEnabled(!checked);
|
m_settings.m_m17Mode = checked ?
|
||||||
m_settings.m_modAFInput = checked ? M17ModSettings::M17ModInputFile : M17ModSettings::M17ModInputNone;
|
m_fmAudioMode ?
|
||||||
|
M17ModSettings::M17Mode::M17ModeFMAudio
|
||||||
|
: M17ModSettings::M17Mode::M17ModeM17Audio
|
||||||
|
: M17ModSettings::M17ModeNone;
|
||||||
|
displayModes();
|
||||||
applySettings();
|
applySettings();
|
||||||
ui->navTimeSlider->setEnabled(!checked);
|
ui->navTimeSlider->setEnabled(!checked);
|
||||||
m_enableNavTime = !checked;
|
m_enableNavTime = !checked;
|
||||||
@ -206,17 +226,20 @@ void M17ModGUI::on_play_toggled(bool checked)
|
|||||||
|
|
||||||
void M17ModGUI::on_tone_toggled(bool checked)
|
void M17ModGUI::on_tone_toggled(bool checked)
|
||||||
{
|
{
|
||||||
ui->play->setEnabled(!checked); // release other source inputs
|
m_settings.m_m17Mode = checked ? M17ModSettings::M17ModeFMTone : M17ModSettings::M17ModeNone;
|
||||||
ui->mic->setEnabled(!checked);
|
displayModes();
|
||||||
m_settings.m_modAFInput = checked ? M17ModSettings::M17ModInputTone : M17ModSettings::M17ModInputNone;
|
|
||||||
applySettings();
|
applySettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
void M17ModGUI::on_mic_toggled(bool checked)
|
void M17ModGUI::on_mic_toggled(bool checked)
|
||||||
{
|
{
|
||||||
ui->play->setEnabled(!checked); // release other source inputs
|
m_settings.m_audioType = checked ? M17ModSettings::AudioInput : M17ModSettings::AudioNone;
|
||||||
ui->tone->setEnabled(!checked); // release other source inputs
|
m_settings.m_m17Mode = checked ?
|
||||||
m_settings.m_modAFInput = checked ? M17ModSettings::M17ModInputAudio : M17ModSettings::M17ModInputNone;
|
m_fmAudioMode ?
|
||||||
|
M17ModSettings::M17Mode::M17ModeFMAudio
|
||||||
|
: M17ModSettings::M17Mode::M17ModeM17Audio
|
||||||
|
: M17ModSettings::M17ModeNone;
|
||||||
|
displayModes();
|
||||||
applySettings();
|
applySettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,6 +284,66 @@ void M17ModGUI::on_showFileDialog_clicked(bool checked)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void M17ModGUI::on_packetMode_toggled(bool checked)
|
||||||
|
{
|
||||||
|
m_settings.m_m17Mode = checked ? M17ModSettings::M17ModeM17Packet : M17ModSettings::M17ModeNone;
|
||||||
|
displayModes();
|
||||||
|
applySettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void M17ModGUI::on_sendPacket_clicked(bool)
|
||||||
|
{
|
||||||
|
m_m17Mod->sendPacket();
|
||||||
|
}
|
||||||
|
|
||||||
|
void M17ModGUI::on_loopPacket_toggled(bool checked)
|
||||||
|
{
|
||||||
|
(void) checked;
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void M17ModGUI::on_loopPacketInterval_valueChanged(int value)
|
||||||
|
{
|
||||||
|
(void) value;
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void M17ModGUI::on_packetDataWidget_currentChanged(int index)
|
||||||
|
{
|
||||||
|
m_settings.m_packetType = indexToPacketType(index);
|
||||||
|
applySettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void M17ModGUI::on_source_editingFinished()
|
||||||
|
{
|
||||||
|
m_settings.m_sourceCall = ui->source->text();
|
||||||
|
applySettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void M17ModGUI::on_destination_editingFinished()
|
||||||
|
{
|
||||||
|
m_settings.m_destCall = ui->destination->text();
|
||||||
|
applySettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void M17ModGUI::on_insertPosition_toggled(bool checked)
|
||||||
|
{
|
||||||
|
m_settings.m_insertPosition = checked;
|
||||||
|
applySettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void M17ModGUI::on_can_valueChanged(int value)
|
||||||
|
{
|
||||||
|
m_settings.m_can = value;
|
||||||
|
applySettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void M17ModGUI::on_smsText_editingFinished()
|
||||||
|
{
|
||||||
|
m_settings.m_smsText = ui->smsText->toPlainText();
|
||||||
|
applySettings();
|
||||||
|
}
|
||||||
|
|
||||||
void M17ModGUI::configureFileName()
|
void M17ModGUI::configureFileName()
|
||||||
{
|
{
|
||||||
qDebug() << "M17ModGUI::configureFileName: " << m_fileName.toStdString().c_str();
|
qDebug() << "M17ModGUI::configureFileName: " << m_fileName.toStdString().c_str();
|
||||||
@ -333,6 +416,7 @@ M17ModGUI::M17ModGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSam
|
|||||||
m_deviceCenterFrequency(0),
|
m_deviceCenterFrequency(0),
|
||||||
m_basebandSampleRate(1),
|
m_basebandSampleRate(1),
|
||||||
m_doApplySettings(true),
|
m_doApplySettings(true),
|
||||||
|
m_fmAudioMode(false),
|
||||||
m_recordLength(0),
|
m_recordLength(0),
|
||||||
m_recordSampleRate(48000),
|
m_recordSampleRate(48000),
|
||||||
m_samplesCount(0),
|
m_samplesCount(0),
|
||||||
@ -447,23 +531,101 @@ void M17ModGUI::displaySettings()
|
|||||||
ui->channelMute->setChecked(m_settings.m_channelMute);
|
ui->channelMute->setChecked(m_settings.m_channelMute);
|
||||||
ui->playLoop->setChecked(m_settings.m_playLoop);
|
ui->playLoop->setChecked(m_settings.m_playLoop);
|
||||||
|
|
||||||
ui->tone->setEnabled((m_settings.m_modAFInput == M17ModSettings::M17ModInputAF::M17ModInputTone) || (m_settings.m_modAFInput == M17ModSettings::M17ModInputAF::M17ModInputNone));
|
displayModes();
|
||||||
ui->mic->setEnabled((m_settings.m_modAFInput == M17ModSettings::M17ModInputAF::M17ModInputAudio) || (m_settings.m_modAFInput == M17ModSettings::M17ModInputAF::M17ModInputNone));
|
ui->fmAudio->setChecked(m_fmAudioMode);
|
||||||
ui->play->setEnabled((m_settings.m_modAFInput == M17ModSettings::M17ModInputAF::M17ModInputFile) || (m_settings.m_modAFInput == M17ModSettings::M17ModInputAF::M17ModInputNone));
|
ui->packetDataWidget->setCurrentIndex(packetTypeToIndex(m_settings.m_packetType));
|
||||||
|
|
||||||
ui->tone->setChecked(m_settings.m_modAFInput == M17ModSettings::M17ModInputAF::M17ModInputTone);
|
|
||||||
ui->mic->setChecked(m_settings.m_modAFInput == M17ModSettings::M17ModInputAF::M17ModInputAudio);
|
|
||||||
ui->play->setChecked(m_settings.m_modAFInput == M17ModSettings::M17ModInputAF::M17ModInputFile);
|
|
||||||
|
|
||||||
ui->feedbackEnable->setChecked(m_settings.m_feedbackAudioEnable);
|
ui->feedbackEnable->setChecked(m_settings.m_feedbackAudioEnable);
|
||||||
ui->feedbackVolume->setValue(roundf(m_settings.m_feedbackVolumeFactor * 100.0));
|
ui->feedbackVolume->setValue(roundf(m_settings.m_feedbackVolumeFactor * 100.0));
|
||||||
ui->feedbackVolumeText->setText(QString("%1").arg(m_settings.m_feedbackVolumeFactor, 0, 'f', 2));
|
ui->feedbackVolumeText->setText(QString("%1").arg(m_settings.m_feedbackVolumeFactor, 0, 'f', 2));
|
||||||
|
|
||||||
|
ui->source->setText(m_settings.m_sourceCall);
|
||||||
|
ui->destination->setText(m_settings.m_destCall);
|
||||||
|
ui->insertPosition->setChecked(m_settings.m_insertPosition);
|
||||||
|
ui->can->setValue(m_settings.m_can);
|
||||||
|
|
||||||
|
ui->smsText->setText(m_settings.m_smsText);
|
||||||
|
|
||||||
|
ui->aprsFromText->setText(m_settings.m_aprsCallsign);
|
||||||
|
ui->aprsData->setText(m_settings.m_aprsData);
|
||||||
|
ui->aprsTo->lineEdit()->setText(m_settings.m_aprsTo);
|
||||||
|
ui->aprsVia->lineEdit()->setText(m_settings.m_aprsVia);
|
||||||
|
|
||||||
getRollupContents()->restoreState(m_rollupState);
|
getRollupContents()->restoreState(m_rollupState);
|
||||||
updateAbsoluteCenterFrequency();
|
updateAbsoluteCenterFrequency();
|
||||||
blockApplySettings(false);
|
blockApplySettings(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void M17ModGUI::displayModes()
|
||||||
|
{
|
||||||
|
qDebug("M17ModGUI::displayModes: m_m17Mode: %d m_audioType: %d",
|
||||||
|
(int) m_settings.m_m17Mode, (int) m_settings.m_audioType);
|
||||||
|
|
||||||
|
if (m_settings.m_m17Mode == M17ModSettings::M17Mode::M17ModeM17Packet)
|
||||||
|
{
|
||||||
|
ui->packetMode->setChecked(true);
|
||||||
|
ui->packetMode->setEnabled(true);
|
||||||
|
ui->tone->setChecked(false);
|
||||||
|
ui->mic->setChecked(false);
|
||||||
|
ui->play->setChecked(false);
|
||||||
|
ui->tone->setEnabled(false);
|
||||||
|
ui->mic->setEnabled(false);
|
||||||
|
ui->play->setEnabled(false);
|
||||||
|
}
|
||||||
|
else if (m_settings.m_m17Mode == M17ModSettings::M17Mode::M17ModeFMTone)
|
||||||
|
{
|
||||||
|
ui->tone->setChecked(true);
|
||||||
|
ui->tone->setEnabled(true);
|
||||||
|
ui->packetMode->setChecked(false);
|
||||||
|
ui->mic->setChecked(false);
|
||||||
|
ui->play->setChecked(false);
|
||||||
|
ui->packetMode->setEnabled(false);
|
||||||
|
ui->mic->setEnabled(false);
|
||||||
|
ui->play->setEnabled(false);
|
||||||
|
}
|
||||||
|
else if ((m_settings.m_m17Mode == M17ModSettings::M17Mode::M17ModeFMAudio) ||
|
||||||
|
(m_settings.m_m17Mode == M17ModSettings::M17Mode::M17ModeM17Audio))
|
||||||
|
{
|
||||||
|
ui->tone->setChecked(false);
|
||||||
|
ui->packetMode->setChecked(false);
|
||||||
|
ui->tone->setEnabled(false);
|
||||||
|
ui->packetMode->setEnabled(false);
|
||||||
|
|
||||||
|
if (m_settings.m_audioType == M17ModSettings::AudioType::AudioInput)
|
||||||
|
{
|
||||||
|
ui->mic->setChecked(true);
|
||||||
|
ui->mic->setEnabled(true);
|
||||||
|
ui->play->setChecked(false);
|
||||||
|
ui->play->setEnabled(false);
|
||||||
|
}
|
||||||
|
else if (m_settings.m_audioType == M17ModSettings::AudioType::AudioFile)
|
||||||
|
{
|
||||||
|
ui->play->setChecked(true);
|
||||||
|
ui->play->setEnabled(true);
|
||||||
|
ui->mic->setChecked(false);
|
||||||
|
ui->mic->setEnabled(false);
|
||||||
|
}
|
||||||
|
else if (m_settings.m_audioType == M17ModSettings::AudioType::AudioNone)
|
||||||
|
{
|
||||||
|
ui->mic->setChecked(false);
|
||||||
|
ui->play->setChecked(false);
|
||||||
|
ui->mic->setEnabled(true);
|
||||||
|
ui->play->setEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_settings.m_m17Mode == M17ModSettings::M17Mode::M17ModeNone)
|
||||||
|
{
|
||||||
|
ui->packetMode->setChecked(false);
|
||||||
|
ui->tone->setChecked(false);
|
||||||
|
ui->mic->setChecked(false);
|
||||||
|
ui->play->setChecked(false);
|
||||||
|
ui->packetMode->setEnabled(true);
|
||||||
|
ui->tone->setEnabled(true);
|
||||||
|
ui->mic->setEnabled(true);
|
||||||
|
ui->play->setEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void M17ModGUI::leaveEvent(QEvent* event)
|
void M17ModGUI::leaveEvent(QEvent* event)
|
||||||
{
|
{
|
||||||
m_channelMarker.setHighlighted(false);
|
m_channelMarker.setHighlighted(false);
|
||||||
@ -534,7 +696,7 @@ void M17ModGUI::tick()
|
|||||||
m_feedbackAudioSampleRate = feedbackAudioSampleRate;
|
m_feedbackAudioSampleRate = feedbackAudioSampleRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((++m_tickCount & 0xf) == 0) && (m_settings.m_modAFInput == M17ModSettings::M17ModInputFile))
|
if (((++m_tickCount & 0xf) == 0) && (m_settings.m_audioType == M17ModSettings::AudioFile))
|
||||||
{
|
{
|
||||||
M17Mod::MsgConfigureFileSourceStreamTiming* message = M17Mod::MsgConfigureFileSourceStreamTiming::create();
|
M17Mod::MsgConfigureFileSourceStreamTiming* message = M17Mod::MsgConfigureFileSourceStreamTiming::create();
|
||||||
m_m17Mod->getInputMessageQueue()->push(message);
|
m_m17Mod->getInputMessageQueue()->push(message);
|
||||||
@ -591,9 +753,41 @@ void M17ModGUI::makeUIConnections()
|
|||||||
QObject::connect(ui->showFileDialog, &QPushButton::clicked, this, &M17ModGUI::on_showFileDialog_clicked);
|
QObject::connect(ui->showFileDialog, &QPushButton::clicked, this, &M17ModGUI::on_showFileDialog_clicked);
|
||||||
QObject::connect(ui->feedbackEnable, &QToolButton::toggled, this, &M17ModGUI::on_feedbackEnable_toggled);
|
QObject::connect(ui->feedbackEnable, &QToolButton::toggled, this, &M17ModGUI::on_feedbackEnable_toggled);
|
||||||
QObject::connect(ui->feedbackVolume, &QDial::valueChanged, this, &M17ModGUI::on_feedbackVolume_valueChanged);
|
QObject::connect(ui->feedbackVolume, &QDial::valueChanged, this, &M17ModGUI::on_feedbackVolume_valueChanged);
|
||||||
|
QObject::connect(ui->fmAudio, &ButtonSwitch::toggled, this, &M17ModGUI::on_fmAudio_toggled);
|
||||||
|
QObject::connect(ui->packetMode, &ButtonSwitch::toggled, this, &M17ModGUI::on_packetMode_toggled);
|
||||||
|
QObject::connect(ui->sendPacket, &QPushButton::clicked, this, &M17ModGUI::on_sendPacket_clicked);
|
||||||
|
QObject::connect(ui->loopPacket, &ButtonSwitch::toggled, this, &M17ModGUI::on_loopPacket_toggled);
|
||||||
|
QObject::connect(ui->loopPacketInterval, &QDial::valueChanged, this, &M17ModGUI::on_loopPacketInterval_valueChanged);
|
||||||
|
QObject::connect(ui->smsText, &CustomTextEdit::editingFinished, this, &M17ModGUI::on_smsText_editingFinished);
|
||||||
}
|
}
|
||||||
|
|
||||||
void M17ModGUI::updateAbsoluteCenterFrequency()
|
void M17ModGUI::updateAbsoluteCenterFrequency()
|
||||||
{
|
{
|
||||||
setStatusFrequency(m_deviceCenterFrequency + m_settings.m_inputFrequencyOffset);
|
setStatusFrequency(m_deviceCenterFrequency + m_settings.m_inputFrequencyOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
M17ModSettings::PacketType M17ModGUI::indexToPacketType(int index)
|
||||||
|
{
|
||||||
|
switch(index)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return M17ModSettings::PacketType::PacketSMS;
|
||||||
|
case 1:
|
||||||
|
return M17ModSettings::PacketType::PacketAPRS;
|
||||||
|
default:
|
||||||
|
return M17ModSettings::PacketType::PacketNone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int M17ModGUI::packetTypeToIndex(M17ModSettings::PacketType type)
|
||||||
|
{
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
case M17ModSettings::PacketType::PacketSMS:
|
||||||
|
return 0;
|
||||||
|
case M17ModSettings::PacketType::PacketAPRS:
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -76,6 +76,7 @@ private:
|
|||||||
qint64 m_deviceCenterFrequency;
|
qint64 m_deviceCenterFrequency;
|
||||||
int m_basebandSampleRate;
|
int m_basebandSampleRate;
|
||||||
bool m_doApplySettings;
|
bool m_doApplySettings;
|
||||||
|
bool m_fmAudioMode;
|
||||||
|
|
||||||
M17Mod* m_m17Mod;
|
M17Mod* m_m17Mod;
|
||||||
MovingAverageUtil<double, double, 20> m_channelPowerDbAvg;
|
MovingAverageUtil<double, double, 20> m_channelPowerDbAvg;
|
||||||
@ -88,7 +89,6 @@ private:
|
|||||||
int m_feedbackAudioSampleRate;
|
int m_feedbackAudioSampleRate;
|
||||||
std::size_t m_tickCount;
|
std::size_t m_tickCount;
|
||||||
bool m_enableNavTime;
|
bool m_enableNavTime;
|
||||||
M17ModSettings::M17ModInputAF m_modAFInput;
|
|
||||||
MessageQueue m_inputMessageQueue;
|
MessageQueue m_inputMessageQueue;
|
||||||
QRegExpValidator m_dcsCodeValidator;
|
QRegExpValidator m_dcsCodeValidator;
|
||||||
|
|
||||||
@ -98,11 +98,14 @@ private:
|
|||||||
void blockApplySettings(bool block);
|
void blockApplySettings(bool block);
|
||||||
void applySettings(bool force = false);
|
void applySettings(bool force = false);
|
||||||
void displaySettings();
|
void displaySettings();
|
||||||
|
void displayModes();
|
||||||
void updateWithStreamData();
|
void updateWithStreamData();
|
||||||
void updateWithStreamTime();
|
void updateWithStreamTime();
|
||||||
bool handleMessage(const Message& message);
|
bool handleMessage(const Message& message);
|
||||||
void makeUIConnections();
|
void makeUIConnections();
|
||||||
void updateAbsoluteCenterFrequency();
|
void updateAbsoluteCenterFrequency();
|
||||||
|
M17ModSettings::PacketType indexToPacketType(int index);
|
||||||
|
int packetTypeToIndex(M17ModSettings::PacketType type);
|
||||||
|
|
||||||
void leaveEvent(QEvent*);
|
void leaveEvent(QEvent*);
|
||||||
void enterEvent(QEvent*);
|
void enterEvent(QEvent*);
|
||||||
@ -115,6 +118,7 @@ private slots:
|
|||||||
void on_rfBW_valueChanged(int value);
|
void on_rfBW_valueChanged(int value);
|
||||||
void on_fmDev_valueChanged(int value);
|
void on_fmDev_valueChanged(int value);
|
||||||
void on_toneFrequency_valueChanged(int value);
|
void on_toneFrequency_valueChanged(int value);
|
||||||
|
void on_fmAudio_toggled(bool checked);
|
||||||
void on_volume_valueChanged(int value);
|
void on_volume_valueChanged(int value);
|
||||||
void on_channelMute_toggled(bool checked);
|
void on_channelMute_toggled(bool checked);
|
||||||
void on_tone_toggled(bool checked);
|
void on_tone_toggled(bool checked);
|
||||||
@ -128,6 +132,17 @@ private slots:
|
|||||||
void on_feedbackEnable_toggled(bool checked);
|
void on_feedbackEnable_toggled(bool checked);
|
||||||
void on_feedbackVolume_valueChanged(int value);
|
void on_feedbackVolume_valueChanged(int value);
|
||||||
|
|
||||||
|
void on_packetMode_toggled(bool checked);
|
||||||
|
void on_sendPacket_clicked(bool checked);
|
||||||
|
void on_loopPacket_toggled(bool checked);
|
||||||
|
void on_loopPacketInterval_valueChanged(int value);
|
||||||
|
void on_packetDataWidget_currentChanged(int index);
|
||||||
|
void on_source_editingFinished();
|
||||||
|
void on_destination_editingFinished();
|
||||||
|
void on_insertPosition_toggled(bool checked);
|
||||||
|
void on_can_valueChanged(int value);
|
||||||
|
void on_smsText_editingFinished();
|
||||||
|
|
||||||
void onWidgetRolled(QWidget* widget, bool rollDown);
|
void onWidgetRolled(QWidget* widget, bool rollDown);
|
||||||
void onMenuDialogCalled(const QPoint& p);
|
void onMenuDialogCalled(const QPoint& p);
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>360</width>
|
<width>360</width>
|
||||||
<height>278</height>
|
<height>568</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@ -40,13 +40,13 @@
|
|||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>M17 Modulator</string>
|
<string>M17 Modulator</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="settingsContainer" native="true">
|
<widget class="QWidget" name="aSettingsContainer" native="true">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>358</width>
|
<width>358</width>
|
||||||
<height>271</height>
|
<height>105</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
@ -286,13 +286,6 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="Line" name="line_5">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="volumeLayout">
|
<layout class="QHBoxLayout" name="volumeLayout">
|
||||||
<item>
|
<item>
|
||||||
@ -364,12 +357,42 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="bAudioContainer" native="true">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>107</y>
|
||||||
|
<width>361</width>
|
||||||
|
<height>140</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Audio</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="recordFileSelectLayout">
|
<layout class="QHBoxLayout" name="recordFileSelectLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="ButtonSwitch" name="tone">
|
<widget class="ButtonSwitch" name="tone">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>FM tone modulation</string>
|
<string>Analog FM tone modulation</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>...</string>
|
<string>...</string>
|
||||||
@ -424,6 +447,22 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="ButtonSwitch" name="fmAudio">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>35</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Modulate audio as analog FM (for testing)</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>FM</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="ButtonSwitch" name="mic">
|
<widget class="ButtonSwitch" name="mic">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
@ -532,13 +571,6 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="Line" name="line_4">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="fileNameLayout">
|
<layout class="QHBoxLayout" name="fileNameLayout">
|
||||||
<item>
|
<item>
|
||||||
@ -704,6 +736,606 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QWidget" name="cPacketContainer" native="true">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>247</y>
|
||||||
|
<width>358</width>
|
||||||
|
<height>193</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Packet</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="ButtonSwitch" name="packetMode">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Packet mode</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>PKT</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="sendPacket">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Send packet</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../../sdrgui/resources/res.qrc">
|
||||||
|
<normaloff>:/stream.png</normaloff>:/stream.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="ButtonSwitch" name="loopPacket">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Send packets in a loop</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../../sdrgui/resources/res.qrc">
|
||||||
|
<normaloff>:/playloop.png</normaloff>:/playloop.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDial" name="loopPacketInterval">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>24</width>
|
||||||
|
<height>24</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Interval between packets (s)</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>600</number>
|
||||||
|
</property>
|
||||||
|
<property name="pageStep">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>60</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="loopPacketIntervalText">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Interval between packets (s)</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>600</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_4">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QTabWidget" name="packetDataWidget">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Packet data</string>
|
||||||
|
</property>
|
||||||
|
<property name="tabPosition">
|
||||||
|
<enum>QTabWidget::East</enum>
|
||||||
|
</property>
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="pktSMS">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>SMS data</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="icon">
|
||||||
|
<iconset resource="../../../sdrgui/resources/res.qrc">
|
||||||
|
<normaloff>:/sms.png</normaloff>:/sms.png</iconset>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="title">
|
||||||
|
<string/>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="toolTip">
|
||||||
|
<string>SMS</string>
|
||||||
|
</attribute>
|
||||||
|
<widget class="CustomTextEdit" name="smsText">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>10</y>
|
||||||
|
<width>307</width>
|
||||||
|
<height>120</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>SMS text</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="pktAPRS">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>APRS data</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="icon">
|
||||||
|
<iconset resource="../../../sdrgui/resources/res.qrc">
|
||||||
|
<normaloff>:/world.png</normaloff>:/world.png</iconset>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="title">
|
||||||
|
<string/>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="toolTip">
|
||||||
|
<string>APRS</string>
|
||||||
|
</attribute>
|
||||||
|
<widget class="QWidget" name="horizontalLayoutWidget">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>40</y>
|
||||||
|
<width>301</width>
|
||||||
|
<height>34</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="toLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="aprsToLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>To</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="aprsTo">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>100</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Enter destination</string>
|
||||||
|
</property>
|
||||||
|
<property name="editable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="currentText">
|
||||||
|
<string>APRS</string>
|
||||||
|
</property>
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>APRS</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>APZ</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>CQ</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>BEACON</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>CALLSIGN-SSID</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="aprsViaLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Via</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="aprsVia">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Enter routing</string>
|
||||||
|
</property>
|
||||||
|
<property name="editable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>WIDE2-2</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>ARISS</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_5">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="horizontalLayoutWidget_2">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>80</y>
|
||||||
|
<width>301</width>
|
||||||
|
<height>34</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="aprsDataLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="aprsDataLabel">
|
||||||
|
<property name="layoutDirection">
|
||||||
|
<enum>Qt::LeftToRight</enum>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Data</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="aprsData">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Enter data to transmit.
|
||||||
|
</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>>Using SDRangel</string>
|
||||||
|
</property>
|
||||||
|
<property name="maxLength">
|
||||||
|
<number>256</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="horizontalLayoutWidget_3">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>301</width>
|
||||||
|
<height>34</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="fromLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>From</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="aprsFromText">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Enter your amateur radio callsign and optionally a SSID. E.g. M7RCE or M7RCE-1</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>MYCALL</string>
|
||||||
|
</property>
|
||||||
|
<property name="maxLength">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="ButtonSwitch" name="aprsInsertPosition">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Insert position (latitude and longitude)</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset>
|
||||||
|
<normalon>:/gps.png</normalon>
|
||||||
|
</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="aprsFromLabel">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="dDigitalContainer" native="true">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>442</y>
|
||||||
|
<width>358</width>
|
||||||
|
<height>120</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Digital</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_4" stretch="0">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="TVScreen" name="screenTV" native="true">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>100</width>
|
||||||
|
<height>100</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QFrame" name="frame">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::StyledPanel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
<widget class="QComboBox" name="baudRate">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>10</x>
|
||||||
|
<y>10</y>
|
||||||
|
<width>60</width>
|
||||||
|
<height>24</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>35</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>16777215</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Baud rate: 2.4k: NXDN48, dPMR 4.8k: DMR, D-Star, YSF, NXDN96</string>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>4.8k</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLabel" name="sourceLabel">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>10</x>
|
||||||
|
<y>40</y>
|
||||||
|
<width>21</width>
|
||||||
|
<height>28</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Src</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLineEdit" name="source">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>40</x>
|
||||||
|
<y>40</y>
|
||||||
|
<width>100</width>
|
||||||
|
<height>24</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLabel" name="destinationLabel">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>10</x>
|
||||||
|
<y>70</y>
|
||||||
|
<width>21</width>
|
||||||
|
<height>28</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Dst</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLineEdit" name="destination">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>40</x>
|
||||||
|
<y>70</y>
|
||||||
|
<width>100</width>
|
||||||
|
<height>24</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="ButtonSwitch" name="insertPosition">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>150</x>
|
||||||
|
<y>40</y>
|
||||||
|
<width>24</width>
|
||||||
|
<height>24</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Insert position (latitude and longitude)</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset>
|
||||||
|
<normalon>:/gps.png</normalon>
|
||||||
|
</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLabel" name="destinationLabel_2">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>150</x>
|
||||||
|
<y>70</y>
|
||||||
|
<width>30</width>
|
||||||
|
<height>28</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>CAN</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QSpinBox" name="can">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>180</x>
|
||||||
|
<y>70</y>
|
||||||
|
<width>56</width>
|
||||||
|
<height>28</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>255</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
@ -723,12 +1355,23 @@
|
|||||||
<extends>QToolButton</extends>
|
<extends>QToolButton</extends>
|
||||||
<header>gui/buttonswitch.h</header>
|
<header>gui/buttonswitch.h</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>TVScreen</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>gui/tvscreen.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>LevelMeterVU</class>
|
<class>LevelMeterVU</class>
|
||||||
<extends>QWidget</extends>
|
<extends>QWidget</extends>
|
||||||
<header>gui/levelmeter.h</header>
|
<header>gui/levelmeter.h</header>
|
||||||
<container>1</container>
|
<container>1</container>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>CustomTextEdit</class>
|
||||||
|
<extends>QTextEdit</extends>
|
||||||
|
<header>gui/customtextedit.h</header>
|
||||||
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../../../sdrgui/resources/res.qrc"/>
|
<include location="../../../sdrgui/resources/res.qrc"/>
|
||||||
|
99
plugins/channeltx/modm17/m17modprocessor.cpp
Normal file
99
plugins/channeltx/modm17/m17modprocessor.cpp
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Copyright (C) 2022 Edouard Griffiths, F4EXB //
|
||||||
|
// //
|
||||||
|
// 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 as version 3 of the License, 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 V3 for more details. //
|
||||||
|
// //
|
||||||
|
// You should have received a copy of the GNU General Public License //
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "m17/M17Modulator.h"
|
||||||
|
|
||||||
|
#include "m17modprocessor.h"
|
||||||
|
|
||||||
|
M17ModProcessor::M17ModProcessor()
|
||||||
|
{
|
||||||
|
m_basebandFifo.setSampleSize(sizeof(int16_t), 48000);
|
||||||
|
connect(&m_inputMessageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages()));
|
||||||
|
}
|
||||||
|
|
||||||
|
M17ModProcessor::~M17ModProcessor()
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool M17ModProcessor::handleMessage(const Message& cmd)
|
||||||
|
{
|
||||||
|
if (MsgSendSMS::match(cmd))
|
||||||
|
{
|
||||||
|
const MsgSendSMS& notif = (const MsgSendSMS&) cmd;
|
||||||
|
QByteArray packetBytes = notif.getSMSText().toUtf8();
|
||||||
|
packetBytes.prepend(0x05); // SMS standard type
|
||||||
|
packetBytes.truncate(798); // Maximum packet size is 798 payload + 2 bytes CRC = 800 bytes (32*25)
|
||||||
|
processPacket(notif.getSourceCall(), notif.getDestCall(), packetBytes);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void M17ModProcessor::handleInputMessages()
|
||||||
|
{
|
||||||
|
Message* message;
|
||||||
|
|
||||||
|
while ((message = m_inputMessageQueue.pop()) != nullptr)
|
||||||
|
{
|
||||||
|
if (handleMessage(*message)) {
|
||||||
|
delete message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void M17ModProcessor::processPacket(const QString& sourceCall, const QString& destCall, const QByteArray& packetBytes)
|
||||||
|
{
|
||||||
|
mobilinkd::M17Modulator modulator(sourceCall.toStdString(), destCall.toStdString());
|
||||||
|
// preamble
|
||||||
|
std::array<uint8_t, 48> preamble_bytes;
|
||||||
|
mobilinkd::M17Modulator::make_preamble(preamble_bytes);
|
||||||
|
std::array<int8_t, 48 * 4> fullframe_symbols = mobilinkd::M17Modulator::bytes_to_symbols(preamble_bytes);
|
||||||
|
std::array<int16_t, 1920> baseband = mobilinkd::M17Modulator::symbols_to_baseband(fullframe_symbols);
|
||||||
|
m_basebandFifo.write((const quint8*) baseband.data(), 1920);
|
||||||
|
// LSF
|
||||||
|
mobilinkd::M17Modulator::lich_t lichSegments; // Not used for packet
|
||||||
|
mobilinkd::M17Modulator::frame_t frame;
|
||||||
|
modulator.make_link_setup(lichSegments, frame);
|
||||||
|
std::array<int8_t, 46 * 4> frame_symbols = mobilinkd::M17Modulator::bytes_to_symbols(frame);
|
||||||
|
std::copy(mobilinkd::M17Modulator::LSF_SYNC_WORD.begin(), mobilinkd::M17Modulator::LSF_SYNC_WORD.end(), fullframe_symbols.begin());
|
||||||
|
std::copy(frame_symbols.begin(), frame_symbols.end(), fullframe_symbols.begin()+2);
|
||||||
|
baseband = mobilinkd::M17Modulator::symbols_to_baseband(fullframe_symbols);
|
||||||
|
m_basebandFifo.write((const quint8*) baseband.data(), 1920);
|
||||||
|
// Packets
|
||||||
|
std::copy(mobilinkd::M17Modulator::DATA_SYNC_WORD.begin(), mobilinkd::M17Modulator::DATA_SYNC_WORD.end(), fullframe_symbols.begin());
|
||||||
|
mobilinkd::M17Modulator::packet_t packet;
|
||||||
|
int remainderCount = packetBytes.size();
|
||||||
|
int packetCount = 0;
|
||||||
|
|
||||||
|
while (remainderCount > 25)
|
||||||
|
{
|
||||||
|
std::copy(packetBytes.begin() + (packetCount*25), packetBytes.begin() + ((packetCount+1)*25), packet.begin());
|
||||||
|
frame = modulator.make_packet_frame(packetCount, false, packet, 25);
|
||||||
|
std::copy(frame_symbols.begin(), frame_symbols.end(), fullframe_symbols.begin()+2);
|
||||||
|
baseband = mobilinkd::M17Modulator::symbols_to_baseband(fullframe_symbols);
|
||||||
|
m_basebandFifo.write((const quint8*) baseband.data(), 1920);
|
||||||
|
remainderCount -= 25;
|
||||||
|
packetCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::copy(packetBytes.begin() + (packetCount*25), packetBytes.begin() + (packetCount*25) + remainderCount, packet.begin());
|
||||||
|
frame = modulator.make_packet_frame(packetCount, true, packet, remainderCount);
|
||||||
|
std::copy(frame_symbols.begin(), frame_symbols.end(), fullframe_symbols.begin()+2);
|
||||||
|
baseband = mobilinkd::M17Modulator::symbols_to_baseband(fullframe_symbols);
|
||||||
|
m_basebandFifo.write((const quint8*) baseband.data(), 1920);
|
||||||
|
}
|
@ -29,22 +29,28 @@ class M17ModProcessor : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
class MsgSendPacket : public Message {
|
class MsgSendSMS : public Message {
|
||||||
MESSAGE_CLASS_DECLARATION
|
MESSAGE_CLASS_DECLARATION
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const QByteArray& getPacket() const { return m_packet; }
|
const QString& getSourceCall() const { return m_sourceCall; }
|
||||||
|
const QString& getDestCall() const { return m_destCall; }
|
||||||
|
const QString& getSMSText() const { return m_smsText; }
|
||||||
|
|
||||||
static MsgSendPacket* create(const QByteArray& packet) {
|
static MsgSendSMS* create(const QString& sourceCall, const QString& destCall, const QString& smsText) {
|
||||||
return new MsgSendPacket(packet);
|
return new MsgSendSMS(sourceCall, destCall, smsText);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QByteArray m_packet;
|
QString m_sourceCall;
|
||||||
|
QString m_destCall;
|
||||||
|
QString m_smsText;
|
||||||
|
|
||||||
MsgSendPacket(const QByteArray& bytes) :
|
MsgSendSMS(const QString& sourceCall, const QString& destCall, const QString& smsText) :
|
||||||
Message(),
|
Message(),
|
||||||
m_packet(bytes)
|
m_sourceCall(sourceCall),
|
||||||
|
m_destCall(destCall),
|
||||||
|
m_smsText(smsText)
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -59,6 +65,7 @@ private:
|
|||||||
AudioFifo m_basebandFifo; //!< Samples are 16 bit integer baseband 48 kS/s samples
|
AudioFifo m_basebandFifo; //!< Samples are 16 bit integer baseband 48 kS/s samples
|
||||||
|
|
||||||
bool handleMessage(const Message& cmd);
|
bool handleMessage(const Message& cmd);
|
||||||
|
void processPacket(const QString& sourceCall, const QString& destCall, const QByteArray& packetBytes);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void handleInputMessages();
|
void handleInputMessages();
|
||||||
|
@ -42,7 +42,9 @@ void M17ModSettings::resetToDefaults()
|
|||||||
m_playLoop = false;
|
m_playLoop = false;
|
||||||
m_rgbColor = QColor(255, 0, 255).rgb();
|
m_rgbColor = QColor(255, 0, 255).rgb();
|
||||||
m_title = "M17 Modulator";
|
m_title = "M17 Modulator";
|
||||||
m_modAFInput = M17ModInputAF::M17ModInputNone;
|
m_m17Mode = M17Mode::M17ModeNone;
|
||||||
|
m_audioType = AudioType::AudioNone;
|
||||||
|
m_packetType = PacketType::PacketNone;
|
||||||
m_audioDeviceName = AudioDeviceManager::m_defaultDeviceName;
|
m_audioDeviceName = AudioDeviceManager::m_defaultDeviceName;
|
||||||
m_feedbackAudioDeviceName = AudioDeviceManager::m_defaultDeviceName;
|
m_feedbackAudioDeviceName = AudioDeviceManager::m_defaultDeviceName;
|
||||||
m_feedbackVolumeFactor = 0.5f;
|
m_feedbackVolumeFactor = 0.5f;
|
||||||
@ -55,6 +57,16 @@ void M17ModSettings::resetToDefaults()
|
|||||||
m_reverseAPIChannelIndex = 0;
|
m_reverseAPIChannelIndex = 0;
|
||||||
m_workspaceIndex = 0;
|
m_workspaceIndex = 0;
|
||||||
m_hidden = false;
|
m_hidden = false;
|
||||||
|
m_sourceCall = "";
|
||||||
|
m_destCall = "";
|
||||||
|
m_insertPosition = false;
|
||||||
|
m_can = 10;
|
||||||
|
m_smsText = "";
|
||||||
|
m_aprsCallsign = "MYCALL";
|
||||||
|
m_aprsTo = "APRS";
|
||||||
|
m_aprsVia = "WIDE2-2";
|
||||||
|
m_aprsData = ">Using SDRangel";
|
||||||
|
m_aprsInsertPosition = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray M17ModSettings::serialize() const
|
QByteArray M17ModSettings::serialize() const
|
||||||
@ -67,13 +79,15 @@ QByteArray M17ModSettings::serialize() const
|
|||||||
s.writeU32(5, m_rgbColor);
|
s.writeU32(5, m_rgbColor);
|
||||||
s.writeReal(6, m_toneFrequency);
|
s.writeReal(6, m_toneFrequency);
|
||||||
s.writeReal(7, m_volumeFactor);
|
s.writeReal(7, m_volumeFactor);
|
||||||
|
s.writeS32(8, (int) m_m17Mode);
|
||||||
|
s.writeS32(9, (int) m_audioType);
|
||||||
|
s.writeS32(10, (int) m_packetType);
|
||||||
|
|
||||||
if (m_channelMarker) {
|
if (m_channelMarker) {
|
||||||
s.writeBlob(11, m_channelMarker->serialize());
|
s.writeBlob(11, m_channelMarker->serialize());
|
||||||
}
|
}
|
||||||
|
|
||||||
s.writeString(12, m_title);
|
s.writeString(12, m_title);
|
||||||
s.writeS32(13, (int) m_modAFInput);
|
|
||||||
s.writeString(14, m_audioDeviceName);
|
s.writeString(14, m_audioDeviceName);
|
||||||
s.writeBool(15, m_useReverseAPI);
|
s.writeBool(15, m_useReverseAPI);
|
||||||
s.writeString(16, m_reverseAPIAddress);
|
s.writeString(16, m_reverseAPIAddress);
|
||||||
@ -93,6 +107,19 @@ QByteArray M17ModSettings::serialize() const
|
|||||||
s.writeBlob(29, m_geometryBytes);
|
s.writeBlob(29, m_geometryBytes);
|
||||||
s.writeBool(30, m_hidden);
|
s.writeBool(30, m_hidden);
|
||||||
|
|
||||||
|
s.writeString(40, m_sourceCall);
|
||||||
|
s.writeString(41, m_destCall);
|
||||||
|
s.writeBool(42, m_insertPosition);
|
||||||
|
s.writeU32(43, m_can);
|
||||||
|
|
||||||
|
s.writeString(50, m_smsText);
|
||||||
|
|
||||||
|
s.writeString(60, m_aprsCallsign);
|
||||||
|
s.writeString(61, m_aprsTo);
|
||||||
|
s.writeString(62, m_aprsVia);
|
||||||
|
s.writeString(63, m_aprsData);
|
||||||
|
s.writeBool(64, m_aprsInsertPosition);
|
||||||
|
|
||||||
return s.final();
|
return s.final();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +146,13 @@ bool M17ModSettings::deserialize(const QByteArray& data)
|
|||||||
d.readU32(5, &m_rgbColor);
|
d.readU32(5, &m_rgbColor);
|
||||||
d.readReal(6, &m_toneFrequency, 1000.0);
|
d.readReal(6, &m_toneFrequency, 1000.0);
|
||||||
d.readReal(7, &m_volumeFactor, 1.0);
|
d.readReal(7, &m_volumeFactor, 1.0);
|
||||||
d.readBlob(8, &bytetmp);
|
d.readS32(8, &tmp, 0);
|
||||||
|
m_m17Mode = tmp < 0 ? M17ModeNone : tmp > (int) M17ModeM17BERT ? M17ModeM17BERT : (M17Mode) tmp;
|
||||||
|
d.readS32(9, &tmp, 0);
|
||||||
|
m_audioType = tmp < 0 ? AudioNone : tmp > (int) AudioInput ? AudioInput : (AudioType) tmp;
|
||||||
|
m_packetType = tmp < 0 ? PacketNone : tmp > (int) PacketSMS ? PacketSMS : (PacketType) tmp;
|
||||||
|
|
||||||
|
d.readBlob(11, &bytetmp);
|
||||||
|
|
||||||
if (m_channelMarker)
|
if (m_channelMarker)
|
||||||
{
|
{
|
||||||
@ -129,13 +162,6 @@ bool M17ModSettings::deserialize(const QByteArray& data)
|
|||||||
|
|
||||||
d.readString(12, &m_title, "M17 Modulator");
|
d.readString(12, &m_title, "M17 Modulator");
|
||||||
|
|
||||||
d.readS32(13, &tmp, 0);
|
|
||||||
if ((tmp < 0) || (tmp > (int) M17ModInputAF::M17ModInputTone)) {
|
|
||||||
m_modAFInput = M17ModInputNone;
|
|
||||||
} else {
|
|
||||||
m_modAFInput = (M17ModInputAF) tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
d.readString(14, &m_audioDeviceName, AudioDeviceManager::m_defaultDeviceName);
|
d.readString(14, &m_audioDeviceName, AudioDeviceManager::m_defaultDeviceName);
|
||||||
d.readBool(15, &m_useReverseAPI, false);
|
d.readBool(15, &m_useReverseAPI, false);
|
||||||
d.readString(16, &m_reverseAPIAddress, "127.0.0.1");
|
d.readString(16, &m_reverseAPIAddress, "127.0.0.1");
|
||||||
@ -167,6 +193,20 @@ bool M17ModSettings::deserialize(const QByteArray& data)
|
|||||||
d.readBlob(29, &m_geometryBytes);
|
d.readBlob(29, &m_geometryBytes);
|
||||||
d.readBool(30, &m_hidden, false);
|
d.readBool(30, &m_hidden, false);
|
||||||
|
|
||||||
|
d.readString(40, &m_sourceCall, "");
|
||||||
|
d.readString(41, &m_destCall, "");
|
||||||
|
d.readBool(42, &m_insertPosition, false);
|
||||||
|
d.readU32(43, &utmp);
|
||||||
|
m_can = utmp < 255 ? utmp : 255;
|
||||||
|
|
||||||
|
d.readString(50, &m_smsText, "");
|
||||||
|
|
||||||
|
d.readString(60, &m_aprsCallsign, "MYCALL");
|
||||||
|
d.readString(61, &m_aprsTo, "");
|
||||||
|
d.readString(62, &m_aprsVia, "");
|
||||||
|
d.readString(63, &m_aprsData, "");
|
||||||
|
d.readBool(64, &m_aprsInsertPosition, false);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -26,12 +26,28 @@ class Serializable;
|
|||||||
|
|
||||||
struct M17ModSettings
|
struct M17ModSettings
|
||||||
{
|
{
|
||||||
enum M17ModInputAF
|
enum M17Mode
|
||||||
{
|
{
|
||||||
M17ModInputNone,
|
M17ModeNone,
|
||||||
M17ModInputFile,
|
M17ModeFMTone,
|
||||||
M17ModInputAudio,
|
M17ModeFMAudio,
|
||||||
M17ModInputTone
|
M17ModeM17Audio,
|
||||||
|
M17ModeM17Packet,
|
||||||
|
M17ModeM17BERT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum AudioType
|
||||||
|
{
|
||||||
|
AudioNone,
|
||||||
|
AudioFile,
|
||||||
|
AudioInput
|
||||||
|
};
|
||||||
|
|
||||||
|
enum PacketType
|
||||||
|
{
|
||||||
|
PacketNone,
|
||||||
|
PacketSMS,
|
||||||
|
PacketAPRS
|
||||||
};
|
};
|
||||||
|
|
||||||
qint64 m_inputFrequencyOffset;
|
qint64 m_inputFrequencyOffset;
|
||||||
@ -43,7 +59,9 @@ struct M17ModSettings
|
|||||||
bool m_playLoop;
|
bool m_playLoop;
|
||||||
quint32 m_rgbColor;
|
quint32 m_rgbColor;
|
||||||
QString m_title;
|
QString m_title;
|
||||||
M17ModInputAF m_modAFInput;
|
M17Mode m_m17Mode;
|
||||||
|
AudioType m_audioType;
|
||||||
|
PacketType m_packetType;
|
||||||
QString m_audioDeviceName; //!< This is the audio device you get the audio samples from
|
QString m_audioDeviceName; //!< This is the audio device you get the audio samples from
|
||||||
QString m_feedbackAudioDeviceName; //!< This is the audio device you send the audio samples to for audio feedback
|
QString m_feedbackAudioDeviceName; //!< This is the audio device you send the audio samples to for audio feedback
|
||||||
float m_feedbackVolumeFactor;
|
float m_feedbackVolumeFactor;
|
||||||
@ -58,6 +76,19 @@ struct M17ModSettings
|
|||||||
QByteArray m_geometryBytes;
|
QByteArray m_geometryBytes;
|
||||||
bool m_hidden;
|
bool m_hidden;
|
||||||
|
|
||||||
|
QString m_sourceCall;
|
||||||
|
QString m_destCall;
|
||||||
|
bool m_insertPosition;
|
||||||
|
uint8_t m_can;
|
||||||
|
|
||||||
|
QString m_smsText;
|
||||||
|
|
||||||
|
QString m_aprsCallsign;
|
||||||
|
QString m_aprsTo;
|
||||||
|
QString m_aprsVia;
|
||||||
|
QString m_aprsData;
|
||||||
|
bool m_aprsInsertPosition;
|
||||||
|
|
||||||
Serializable *m_channelMarker;
|
Serializable *m_channelMarker;
|
||||||
Serializable *m_rollupState;
|
Serializable *m_rollupState;
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "util/messagequeue.h"
|
#include "util/messagequeue.h"
|
||||||
#include "maincore.h"
|
#include "maincore.h"
|
||||||
|
|
||||||
|
#include "m17modprocessor.h"
|
||||||
#include "m17modsource.h"
|
#include "m17modsource.h"
|
||||||
|
|
||||||
const int M17ModSource::m_levelNbSamples = 480; // every 10ms
|
const int M17ModSource::m_levelNbSamples = 480; // every 10ms
|
||||||
@ -53,12 +54,15 @@ M17ModSource::M17ModSource() :
|
|||||||
|
|
||||||
m_magsq = 0.0;
|
m_magsq = 0.0;
|
||||||
|
|
||||||
|
m_processor = new M17ModProcessor();
|
||||||
|
|
||||||
applySettings(m_settings, true);
|
applySettings(m_settings, true);
|
||||||
applyChannelSettings(m_channelSampleRate, m_channelFrequencyOffset, true);
|
applyChannelSettings(m_channelSampleRate, m_channelFrequencyOffset, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
M17ModSource::~M17ModSource()
|
M17ModSource::~M17ModSource()
|
||||||
{
|
{
|
||||||
|
delete m_processor;
|
||||||
}
|
}
|
||||||
|
|
||||||
void M17ModSource::pull(SampleVector::iterator begin, unsigned int nbSamples)
|
void M17ModSource::pull(SampleVector::iterator begin, unsigned int nbSamples)
|
||||||
@ -140,13 +144,22 @@ void M17ModSource::pullAudio(unsigned int nbSamplesAudio)
|
|||||||
void M17ModSource::modulateSample()
|
void M17ModSource::modulateSample()
|
||||||
{
|
{
|
||||||
Real t1, t;
|
Real t1, t;
|
||||||
|
bool carrier;
|
||||||
|
|
||||||
pullAF(t);
|
if ((m_settings.m_m17Mode == M17ModSettings::M17ModeFMTone) || (m_settings.m_m17Mode == M17ModSettings::M17ModeFMAudio)) {
|
||||||
|
pullAF(t, carrier);
|
||||||
|
} else if (m_settings.m_m17Mode != M17ModSettings::M17ModeNone) {
|
||||||
|
pullM17(t, carrier);
|
||||||
|
} else {
|
||||||
|
t = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_settings.m_feedbackAudioEnable) {
|
if (m_settings.m_feedbackAudioEnable) {
|
||||||
pushFeedback(t * m_settings.m_feedbackVolumeFactor * 16384.0f);
|
pushFeedback(t * m_settings.m_feedbackVolumeFactor * 16384.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (carrier)
|
||||||
|
{
|
||||||
calculateLevel(t);
|
calculateLevel(t);
|
||||||
t1 = m_lowpass.filter(t) * 1.2f;
|
t1 = m_lowpass.filter(t) * 1.2f;
|
||||||
|
|
||||||
@ -159,6 +172,12 @@ void M17ModSource::modulateSample()
|
|||||||
|
|
||||||
m_modSample.real(cos(m_modPhasor) * 0.891235351562f * SDR_TX_SCALEF); // -1 dB
|
m_modSample.real(cos(m_modPhasor) * 0.891235351562f * SDR_TX_SCALEF); // -1 dB
|
||||||
m_modSample.imag(sin(m_modPhasor) * 0.891235351562f * SDR_TX_SCALEF);
|
m_modSample.imag(sin(m_modPhasor) * 0.891235351562f * SDR_TX_SCALEF);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_modSample.real(0.0f);
|
||||||
|
m_modSample.imag(0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
m_demodBuffer[m_demodBufferFill] = t1 * std::numeric_limits<int16_t>::max();
|
m_demodBuffer[m_demodBufferFill] = t1 * std::numeric_limits<int16_t>::max();
|
||||||
++m_demodBufferFill;
|
++m_demodBufferFill;
|
||||||
@ -186,14 +205,18 @@ void M17ModSource::modulateSample()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void M17ModSource::pullAF(Real& sample)
|
void M17ModSource::pullAF(Real& sample, bool& carrier)
|
||||||
{
|
{
|
||||||
switch (m_settings.m_modAFInput)
|
carrier = true;
|
||||||
|
|
||||||
|
if (m_settings.m_m17Mode == M17ModSettings::M17ModeFMTone)
|
||||||
{
|
{
|
||||||
case M17ModSettings::M17ModInputTone:
|
|
||||||
sample = m_toneNco.next();
|
sample = m_toneNco.next();
|
||||||
break;
|
}
|
||||||
case M17ModSettings::M17ModInputFile:
|
else if (m_settings.m_m17Mode == M17ModSettings::M17ModeFMAudio)
|
||||||
|
{
|
||||||
|
if (m_settings.m_audioType == M17ModSettings::AudioFile)
|
||||||
|
{
|
||||||
// sox f4exb_call.wav --encoding float --endian little f4exb_call.raw
|
// sox f4exb_call.wav --encoding float --endian little f4exb_call.raw
|
||||||
// ffplay -f f32le -ar 48k -ac 1 f4exb_call.raw
|
// ffplay -f f32le -ar 48k -ac 1 f4exb_call.raw
|
||||||
if (m_ifstream && m_ifstream->is_open())
|
if (m_ifstream && m_ifstream->is_open())
|
||||||
@ -221,8 +244,9 @@ void M17ModSource::pullAF(Real& sample)
|
|||||||
{
|
{
|
||||||
sample = 0.0f;
|
sample = 0.0f;
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case M17ModSettings::M17ModInputAudio:
|
else if (m_settings.m_audioType == M17ModSettings::AudioInput)
|
||||||
|
{
|
||||||
if (m_audioBufferFill < m_audioBuffer.size())
|
if (m_audioBufferFill < m_audioBuffer.size())
|
||||||
{
|
{
|
||||||
sample = ((m_audioBuffer[m_audioBufferFill].l + m_audioBuffer[m_audioBufferFill].r) / 65536.0f) * m_settings.m_volumeFactor;
|
sample = ((m_audioBuffer[m_audioBufferFill].l + m_audioBuffer[m_audioBufferFill].r) / 65536.0f) * m_settings.m_volumeFactor;
|
||||||
@ -234,13 +258,19 @@ void M17ModSource::pullAF(Real& sample)
|
|||||||
qDebug("NFMModSource::pullAF: starve audio samples: size: %u", size);
|
qDebug("NFMModSource::pullAF: starve audio samples: size: %u", size);
|
||||||
sample = ((m_audioBuffer[size-1].l + m_audioBuffer[size-1].r) / 65536.0f) * m_settings.m_volumeFactor;
|
sample = ((m_audioBuffer[size-1].l + m_audioBuffer[size-1].r) / 65536.0f) * m_settings.m_volumeFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
|
||||||
case M17ModSettings::M17ModInputNone:
|
|
||||||
default:
|
|
||||||
sample = 0.0f;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sample = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void M17ModSource::pullM17(Real& sample, bool& carrier)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
carrier = false;
|
||||||
|
sample = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void M17ModSource::pushFeedback(Real sample)
|
void M17ModSource::pushFeedback(Real sample)
|
||||||
@ -368,9 +398,9 @@ void M17ModSource::applySettings(const M17ModSettings& settings, bool force)
|
|||||||
m_toneNco.setFreq(settings.m_toneFrequency, m_audioSampleRate);
|
m_toneNco.setFreq(settings.m_toneFrequency, m_audioSampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((settings.m_modAFInput != m_settings.m_modAFInput) || force)
|
if ((settings.m_audioType != m_settings.m_audioType) || force)
|
||||||
{
|
{
|
||||||
if (settings.m_modAFInput == M17ModSettings::M17ModInputAudio) {
|
if (settings.m_audioType == M17ModSettings::AudioInput) {
|
||||||
connect(&m_audioFifo, SIGNAL(dataReady()), this, SLOT(handleAudio()));
|
connect(&m_audioFifo, SIGNAL(dataReady()), this, SLOT(handleAudio()));
|
||||||
} else {
|
} else {
|
||||||
disconnect(&m_audioFifo, SIGNAL(dataReady()), this, SLOT(handleAudio()));
|
disconnect(&m_audioFifo, SIGNAL(dataReady()), this, SLOT(handleAudio()));
|
||||||
@ -416,3 +446,16 @@ void M17ModSource::handleAudio()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void M17ModSource::sendPacket()
|
||||||
|
{
|
||||||
|
if (m_settings.m_packetType == M17ModSettings::PacketType::PacketSMS)
|
||||||
|
{
|
||||||
|
M17ModProcessor::MsgSendSMS *msg = M17ModProcessor::MsgSendSMS::create(
|
||||||
|
m_settings.m_sourceCall,
|
||||||
|
m_settings.m_destCall,
|
||||||
|
m_settings.m_smsText
|
||||||
|
);
|
||||||
|
m_processor->getInputMessageQueue()->push(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include "m17modsettings.h"
|
#include "m17modsettings.h"
|
||||||
|
|
||||||
class ChannelAPI;
|
class ChannelAPI;
|
||||||
|
class M17ModProcessor;
|
||||||
|
|
||||||
class M17ModSource : public QObject, public ChannelSampleSource
|
class M17ModSource : public QObject, public ChannelSampleSource
|
||||||
{
|
{
|
||||||
@ -67,6 +68,8 @@ public:
|
|||||||
void applySettings(const M17ModSettings& settings, bool force = false);
|
void applySettings(const M17ModSettings& settings, bool force = false);
|
||||||
void applyChannelSettings(int channelSampleRate, int channelFrequencyOffset, bool force = false);
|
void applyChannelSettings(int channelSampleRate, int channelFrequencyOffset, bool force = false);
|
||||||
|
|
||||||
|
void sendPacket();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_channelSampleRate;
|
int m_channelSampleRate;
|
||||||
int m_channelFrequencyOffset;
|
int m_channelFrequencyOffset;
|
||||||
@ -115,6 +118,7 @@ private:
|
|||||||
Real m_levelSum;
|
Real m_levelSum;
|
||||||
|
|
||||||
std::ifstream *m_ifstream;
|
std::ifstream *m_ifstream;
|
||||||
|
M17ModProcessor *m_processor;
|
||||||
|
|
||||||
QMutex m_mutex;
|
QMutex m_mutex;
|
||||||
|
|
||||||
@ -122,7 +126,8 @@ private:
|
|||||||
static const float m_preemphasis;
|
static const float m_preemphasis;
|
||||||
|
|
||||||
void processOneSample(Complex& ci);
|
void processOneSample(Complex& ci);
|
||||||
void pullAF(Real& sample);
|
void pullAF(Real& sample, bool& carrier);
|
||||||
|
void pullM17(Real& sample, bool& carrier);
|
||||||
void pullAudio(unsigned int nbSamples);
|
void pullAudio(unsigned int nbSamples);
|
||||||
void pushFeedback(Real sample);
|
void pushFeedback(Real sample);
|
||||||
void calculateLevel(Real& sample);
|
void calculateLevel(Real& sample);
|
||||||
|
@ -8390,8 +8390,17 @@ margin-bottom: 20px;
|
|||||||
"audioDeviceName" : {
|
"audioDeviceName" : {
|
||||||
"type" : "string"
|
"type" : "string"
|
||||||
},
|
},
|
||||||
"modAFInput" : {
|
"m17Mode" : {
|
||||||
"type" : "integer"
|
"type" : "integer",
|
||||||
|
"description" : "M17Mode"
|
||||||
|
},
|
||||||
|
"audioType" : {
|
||||||
|
"type" : "integer",
|
||||||
|
"description" : "AudioType"
|
||||||
|
},
|
||||||
|
"packetType" : {
|
||||||
|
"type" : "integer",
|
||||||
|
"description" : "PacketType"
|
||||||
},
|
},
|
||||||
"streamIndex" : {
|
"streamIndex" : {
|
||||||
"type" : "integer",
|
"type" : "integer",
|
||||||
@ -56380,7 +56389,7 @@ except ApiException as e:
|
|||||||
</div>
|
</div>
|
||||||
<div id="generator">
|
<div id="generator">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
Generated 2022-06-09T22:25:54.513+02:00
|
Generated 2022-06-10T22:26:56.056+02:00
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -26,8 +26,15 @@ M17ModSettings:
|
|||||||
type: string
|
type: string
|
||||||
audioDeviceName:
|
audioDeviceName:
|
||||||
type: string
|
type: string
|
||||||
modAFInput:
|
m17Mode:
|
||||||
type: integer
|
type: integer
|
||||||
|
description: M17Mode
|
||||||
|
audioType:
|
||||||
|
type: integer
|
||||||
|
description: AudioType
|
||||||
|
packetType:
|
||||||
|
type: integer
|
||||||
|
description: PacketType
|
||||||
streamIndex:
|
streamIndex:
|
||||||
description: MIMO channel. Not relevant when connected to SI (single Rx).
|
description: MIMO channel. Not relevant when connected to SI (single Rx).
|
||||||
type: integer
|
type: integer
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
<file>bell_fill.png</file>
|
<file>bell_fill.png</file>
|
||||||
<file>bell_gradient.png</file>
|
<file>bell_gradient.png</file>
|
||||||
<file>bell_line.png</file>
|
<file>bell_line.png</file>
|
||||||
|
<file>world.png</file>
|
||||||
|
<file>sms.png</file>
|
||||||
<file>ruler.png</file>
|
<file>ruler.png</file>
|
||||||
<file>sort.png</file>
|
<file>sort.png</file>
|
||||||
<file>audio_mic.png</file>
|
<file>audio_mic.png</file>
|
||||||
|
BIN
sdrgui/resources/sms.png
Normal file
BIN
sdrgui/resources/sms.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 821 B |
BIN
sdrgui/resources/world.png
Normal file
BIN
sdrgui/resources/world.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.6 KiB |
@ -26,8 +26,15 @@ M17ModSettings:
|
|||||||
type: string
|
type: string
|
||||||
audioDeviceName:
|
audioDeviceName:
|
||||||
type: string
|
type: string
|
||||||
modAFInput:
|
m17Mode:
|
||||||
type: integer
|
type: integer
|
||||||
|
description: M17Mode
|
||||||
|
audioType:
|
||||||
|
type: integer
|
||||||
|
description: AudioType
|
||||||
|
packetType:
|
||||||
|
type: integer
|
||||||
|
description: PacketType
|
||||||
streamIndex:
|
streamIndex:
|
||||||
description: MIMO channel. Not relevant when connected to SI (single Rx).
|
description: MIMO channel. Not relevant when connected to SI (single Rx).
|
||||||
type: integer
|
type: integer
|
||||||
|
@ -8390,8 +8390,17 @@ margin-bottom: 20px;
|
|||||||
"audioDeviceName" : {
|
"audioDeviceName" : {
|
||||||
"type" : "string"
|
"type" : "string"
|
||||||
},
|
},
|
||||||
"modAFInput" : {
|
"m17Mode" : {
|
||||||
"type" : "integer"
|
"type" : "integer",
|
||||||
|
"description" : "M17Mode"
|
||||||
|
},
|
||||||
|
"audioType" : {
|
||||||
|
"type" : "integer",
|
||||||
|
"description" : "AudioType"
|
||||||
|
},
|
||||||
|
"packetType" : {
|
||||||
|
"type" : "integer",
|
||||||
|
"description" : "PacketType"
|
||||||
},
|
},
|
||||||
"streamIndex" : {
|
"streamIndex" : {
|
||||||
"type" : "integer",
|
"type" : "integer",
|
||||||
@ -56380,7 +56389,7 @@ except ApiException as e:
|
|||||||
</div>
|
</div>
|
||||||
<div id="generator">
|
<div id="generator">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
Generated 2022-06-09T22:25:54.513+02:00
|
Generated 2022-06-10T22:26:56.056+02:00
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -48,8 +48,12 @@ SWGM17ModSettings::SWGM17ModSettings() {
|
|||||||
m_title_isSet = false;
|
m_title_isSet = false;
|
||||||
audio_device_name = nullptr;
|
audio_device_name = nullptr;
|
||||||
m_audio_device_name_isSet = false;
|
m_audio_device_name_isSet = false;
|
||||||
mod_af_input = 0;
|
m17_mode = 0;
|
||||||
m_mod_af_input_isSet = false;
|
m_m17_mode_isSet = false;
|
||||||
|
audio_type = 0;
|
||||||
|
m_audio_type_isSet = false;
|
||||||
|
packet_type = 0;
|
||||||
|
m_packet_type_isSet = false;
|
||||||
stream_index = 0;
|
stream_index = 0;
|
||||||
m_stream_index_isSet = false;
|
m_stream_index_isSet = false;
|
||||||
use_reverse_api = 0;
|
use_reverse_api = 0;
|
||||||
@ -94,8 +98,12 @@ SWGM17ModSettings::init() {
|
|||||||
m_title_isSet = false;
|
m_title_isSet = false;
|
||||||
audio_device_name = new QString("");
|
audio_device_name = new QString("");
|
||||||
m_audio_device_name_isSet = false;
|
m_audio_device_name_isSet = false;
|
||||||
mod_af_input = 0;
|
m17_mode = 0;
|
||||||
m_mod_af_input_isSet = false;
|
m_m17_mode_isSet = false;
|
||||||
|
audio_type = 0;
|
||||||
|
m_audio_type_isSet = false;
|
||||||
|
packet_type = 0;
|
||||||
|
m_packet_type_isSet = false;
|
||||||
stream_index = 0;
|
stream_index = 0;
|
||||||
m_stream_index_isSet = false;
|
m_stream_index_isSet = false;
|
||||||
use_reverse_api = 0;
|
use_reverse_api = 0;
|
||||||
@ -133,6 +141,8 @@ SWGM17ModSettings::cleanup() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(reverse_api_address != nullptr) {
|
if(reverse_api_address != nullptr) {
|
||||||
delete reverse_api_address;
|
delete reverse_api_address;
|
||||||
}
|
}
|
||||||
@ -178,7 +188,11 @@ SWGM17ModSettings::fromJsonObject(QJsonObject &pJson) {
|
|||||||
|
|
||||||
::SWGSDRangel::setValue(&audio_device_name, pJson["audioDeviceName"], "QString", "QString");
|
::SWGSDRangel::setValue(&audio_device_name, pJson["audioDeviceName"], "QString", "QString");
|
||||||
|
|
||||||
::SWGSDRangel::setValue(&mod_af_input, pJson["modAFInput"], "qint32", "");
|
::SWGSDRangel::setValue(&m17_mode, pJson["m17Mode"], "qint32", "");
|
||||||
|
|
||||||
|
::SWGSDRangel::setValue(&audio_type, pJson["audioType"], "qint32", "");
|
||||||
|
|
||||||
|
::SWGSDRangel::setValue(&packet_type, pJson["packetType"], "qint32", "");
|
||||||
|
|
||||||
::SWGSDRangel::setValue(&stream_index, pJson["streamIndex"], "qint32", "");
|
::SWGSDRangel::setValue(&stream_index, pJson["streamIndex"], "qint32", "");
|
||||||
|
|
||||||
@ -242,8 +256,14 @@ SWGM17ModSettings::asJsonObject() {
|
|||||||
if(audio_device_name != nullptr && *audio_device_name != QString("")){
|
if(audio_device_name != nullptr && *audio_device_name != QString("")){
|
||||||
toJsonValue(QString("audioDeviceName"), audio_device_name, obj, QString("QString"));
|
toJsonValue(QString("audioDeviceName"), audio_device_name, obj, QString("QString"));
|
||||||
}
|
}
|
||||||
if(m_mod_af_input_isSet){
|
if(m_m17_mode_isSet){
|
||||||
obj->insert("modAFInput", QJsonValue(mod_af_input));
|
obj->insert("m17Mode", QJsonValue(m17_mode));
|
||||||
|
}
|
||||||
|
if(m_audio_type_isSet){
|
||||||
|
obj->insert("audioType", QJsonValue(audio_type));
|
||||||
|
}
|
||||||
|
if(m_packet_type_isSet){
|
||||||
|
obj->insert("packetType", QJsonValue(packet_type));
|
||||||
}
|
}
|
||||||
if(m_stream_index_isSet){
|
if(m_stream_index_isSet){
|
||||||
obj->insert("streamIndex", QJsonValue(stream_index));
|
obj->insert("streamIndex", QJsonValue(stream_index));
|
||||||
@ -374,13 +394,33 @@ SWGM17ModSettings::setAudioDeviceName(QString* audio_device_name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
qint32
|
qint32
|
||||||
SWGM17ModSettings::getModAfInput() {
|
SWGM17ModSettings::getM17Mode() {
|
||||||
return mod_af_input;
|
return m17_mode;
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
SWGM17ModSettings::setModAfInput(qint32 mod_af_input) {
|
SWGM17ModSettings::setM17Mode(qint32 m17_mode) {
|
||||||
this->mod_af_input = mod_af_input;
|
this->m17_mode = m17_mode;
|
||||||
this->m_mod_af_input_isSet = true;
|
this->m_m17_mode_isSet = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
qint32
|
||||||
|
SWGM17ModSettings::getAudioType() {
|
||||||
|
return audio_type;
|
||||||
|
}
|
||||||
|
void
|
||||||
|
SWGM17ModSettings::setAudioType(qint32 audio_type) {
|
||||||
|
this->audio_type = audio_type;
|
||||||
|
this->m_audio_type_isSet = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
qint32
|
||||||
|
SWGM17ModSettings::getPacketType() {
|
||||||
|
return packet_type;
|
||||||
|
}
|
||||||
|
void
|
||||||
|
SWGM17ModSettings::setPacketType(qint32 packet_type) {
|
||||||
|
this->packet_type = packet_type;
|
||||||
|
this->m_packet_type_isSet = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
qint32
|
qint32
|
||||||
@ -498,7 +538,13 @@ SWGM17ModSettings::isSet(){
|
|||||||
if(audio_device_name && *audio_device_name != QString("")){
|
if(audio_device_name && *audio_device_name != QString("")){
|
||||||
isObjectUpdated = true; break;
|
isObjectUpdated = true; break;
|
||||||
}
|
}
|
||||||
if(m_mod_af_input_isSet){
|
if(m_m17_mode_isSet){
|
||||||
|
isObjectUpdated = true; break;
|
||||||
|
}
|
||||||
|
if(m_audio_type_isSet){
|
||||||
|
isObjectUpdated = true; break;
|
||||||
|
}
|
||||||
|
if(m_packet_type_isSet){
|
||||||
isObjectUpdated = true; break;
|
isObjectUpdated = true; break;
|
||||||
}
|
}
|
||||||
if(m_stream_index_isSet){
|
if(m_stream_index_isSet){
|
||||||
|
@ -74,8 +74,14 @@ public:
|
|||||||
QString* getAudioDeviceName();
|
QString* getAudioDeviceName();
|
||||||
void setAudioDeviceName(QString* audio_device_name);
|
void setAudioDeviceName(QString* audio_device_name);
|
||||||
|
|
||||||
qint32 getModAfInput();
|
qint32 getM17Mode();
|
||||||
void setModAfInput(qint32 mod_af_input);
|
void setM17Mode(qint32 m17_mode);
|
||||||
|
|
||||||
|
qint32 getAudioType();
|
||||||
|
void setAudioType(qint32 audio_type);
|
||||||
|
|
||||||
|
qint32 getPacketType();
|
||||||
|
void setPacketType(qint32 packet_type);
|
||||||
|
|
||||||
qint32 getStreamIndex();
|
qint32 getStreamIndex();
|
||||||
void setStreamIndex(qint32 stream_index);
|
void setStreamIndex(qint32 stream_index);
|
||||||
@ -135,8 +141,14 @@ private:
|
|||||||
QString* audio_device_name;
|
QString* audio_device_name;
|
||||||
bool m_audio_device_name_isSet;
|
bool m_audio_device_name_isSet;
|
||||||
|
|
||||||
qint32 mod_af_input;
|
qint32 m17_mode;
|
||||||
bool m_mod_af_input_isSet;
|
bool m_m17_mode_isSet;
|
||||||
|
|
||||||
|
qint32 audio_type;
|
||||||
|
bool m_audio_type_isSet;
|
||||||
|
|
||||||
|
qint32 packet_type;
|
||||||
|
bool m_packet_type_isSet;
|
||||||
|
|
||||||
qint32 stream_index;
|
qint32 stream_index;
|
||||||
bool m_stream_index_isSet;
|
bool m_stream_index_isSet;
|
||||||
|
Loading…
Reference in New Issue
Block a user