Finish adding Flite Text-to-sppech support

pull/3/head
Doug McLain 3 years ago
parent 27284d9013
commit b6bff5c93a

@ -12,6 +12,7 @@ win32:LIBS += -L/mnt/data/src/mxe/usr/lib64
win32:QMAKE_LFLAGS += -static
QMAKE_LFLAGS_WINDOWS += --enable-stdcall-fixup
RC_ICONS = images/droidstar.ico
ICON = images/droidstar.icns
macx:QT += serialport
macx::INCLUDEPATH += /usr/local/include
macx:LIBS += -L/usr/local/lib -framework AVFoundation
@ -24,80 +25,6 @@ DEFINES += VERSION_NUMBER=\"\\\"$${VERSION_BUILD}\\\"\"
DEFINES += QT_DEPRECATED_WARNINGS
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
#DEFINES += USE_FLITE
ICON = images/droidstar.icns
SOURCES += \
CRCenc.cpp \
DMRData.cpp \
Golay24128.cpp \
M17Convolution.cpp \
SHA256.cpp \
YSFConvolution.cpp \
YSFFICH.cpp \
androidserialport.cpp \
audioengine.cpp \
cbptc19696.cpp \
cgolay2087.cpp \
chamming.cpp \
codec.cpp \
codec2/codebooks.cpp \
codec2/codec2.cpp \
codec2/kiss_fft.cpp \
codec2/lpc.cpp \
codec2/nlp.cpp \
codec2/pack.cpp \
codec2/qbase.cpp \
codec2/quantise.cpp \
crs129.cpp \
dcscodec.cpp \
dmrcodec.cpp \
droidstar.cpp \
httpmanager.cpp \
iaxcodec.cpp \
m17codec.cpp \
main.cpp \
nxdncodec.cpp \
p25codec.cpp \
refcodec.cpp \
serialambe.cpp \
serialmodem.cpp \
xrfcodec.cpp \
ysfcodec.cpp
macx:OBJECTIVE_SOURCES += micpermission.mm
ios:OBJECTIVE_SOURCES += micpermission.mm
RESOURCES += qml.qrc
QML_IMPORT_PATH =
QML_DESIGNER_IMPORT_PATH =
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
DISTFILES += \
android/AndroidManifest.xml \
android/build.gradle \
android/gradle/wrapper/gradle-wrapper.jar \
android/gradle/wrapper/gradle-wrapper.properties \
android/gradlew \
android/gradlew.bat \
android/res/values/libs.xml \
images/log.png
contains(ANDROID_TARGET_ARCH,armeabi-v7a) {
LIBS += -L$$(HOME)/Android/local/lib
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
OTHER_FILES += android/src
}
contains(ANDROID_TARGET_ARCH,arm64-v8a) {
LIBS += -L$$(HOME)/Android/local/lib64
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
OTHER_FILES += android/src
}
ANDROID_ABIS = armeabi-v7a arm64-v8a
HEADERS += \
CRCenc.h \
@ -142,6 +69,80 @@ HEADERS += \
ysfcodec.h
macx:HEADERS += micpermission.h
SOURCES += \
CRCenc.cpp \
DMRData.cpp \
Golay24128.cpp \
M17Convolution.cpp \
SHA256.cpp \
YSFConvolution.cpp \
YSFFICH.cpp \
androidserialport.cpp \
audioengine.cpp \
cbptc19696.cpp \
cgolay2087.cpp \
chamming.cpp \
codec.cpp \
codec2/codebooks.cpp \
codec2/codec2.cpp \
codec2/kiss_fft.cpp \
codec2/lpc.cpp \
codec2/nlp.cpp \
codec2/pack.cpp \
codec2/qbase.cpp \
codec2/quantise.cpp \
crs129.cpp \
dcscodec.cpp \
dmrcodec.cpp \
droidstar.cpp \
httpmanager.cpp \
iaxcodec.cpp \
m17codec.cpp \
main.cpp \
nxdncodec.cpp \
p25codec.cpp \
refcodec.cpp \
serialambe.cpp \
serialmodem.cpp \
xrfcodec.cpp \
ysfcodec.cpp
macx:OBJECTIVE_SOURCES += micpermission.mm
ios:OBJECTIVE_SOURCES += micpermission.mm
RESOURCES += qml.qrc
QML_IMPORT_PATH =
QML_DESIGNER_IMPORT_PATH =
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
DISTFILES += \
android/AndroidManifest.xml \
android/build.gradle \
android/gradle/wrapper/gradle-wrapper.jar \
android/gradle/wrapper/gradle-wrapper.properties \
android/gradlew \
android/gradlew.bat \
android/res/values/libs.xml \
images/log.png
contains(ANDROID_TARGET_ARCH,armeabi-v7a) {
LIBS += -L$$(HOME)/Android/local/lib
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
OTHER_FILES += android/src
}
contains(ANDROID_TARGET_ARCH,arm64-v8a) {
LIBS += -L$$(HOME)/Android/local/lib64
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
OTHER_FILES += android/src
}
ANDROID_ABIS = armeabi-v7a arm64-v8a
contains(DEFINES, USE_FLITE){
LIBS += -lflite_cmu_us_slt -lflite_cmu_us_kal16 -lflite_cmu_us_awb -lflite_cmu_us_rms -lflite_usenglish -lflite_cmulex -lflite -lasound
}

@ -23,7 +23,25 @@ import QtQuick.Controls 2.3
Item {
id: mainTab
property int rows: 18;
//property int rows: 18;
//property bool tts: false;
property int rows: {
if(USE_FLITE){
rows = 20;
}
else{
rows = 18;
}
}
property bool tts: {
if(USE_FLITE){
tts = true;
}
else{
tts = false;
}
}
onWidthChanged:{
if(_comboMode.currentText == "DMR"){
_comboMode.width = (mainTab.width / 5) - 5;
@ -616,7 +634,69 @@ Item {
border.width: 1
radius: 5
}
ButtonGroup {
id: ttsvoicegroup
onClicked: {
droidstar.tts_changed(button.text);
}
}
CheckBox {
id: mic
visible: tts ? true : false;
x: 5
y: (parent.height / rows + 1) * 15;
height: 25
spacing: 1
text: qsTr("Mic")
checked: true
ButtonGroup.group: ttsvoicegroup
}
CheckBox {
id: tts1
visible: tts ? true : false;
x: parent.width / 4
y: (parent.height / rows + 1) * 15;
height: 25
spacing: 1
text: qsTr("TTS1")
ButtonGroup.group: ttsvoicegroup
}
CheckBox {
id: tts2
visible: tts ? true : false;
x: parent.width * 2 / 4
y: (parent.height / rows + 1) * 15;
height: 25
spacing: 1
text: qsTr("TTS2")
checked: true
ButtonGroup.group: ttsvoicegroup
}
CheckBox {
id: tts3
visible: tts ? true : false;
x: parent.width * 3 / 4
y: (parent.height / rows + 1) * 15;
height: 25
spacing: 1
text: qsTr("TTS3")
ButtonGroup.group: ttsvoicegroup
}
TextField {
id: _ttstxtedit
visible: tts ? true : false;
x: 5
y: (parent.height / rows + 1) * 16;
width: parent.width - 10
height: parent.height / rows
font.pixelSize: parent.height / 35
selectByMouse: true
inputMethodHints: "ImhPreferNumbers"
text: qsTr("")
onEditingFinished: {
droidstar.tts_text_changed(_ttstxtedit.text)
}
}
Button {
Timer {
id: _txtimer
@ -649,7 +729,7 @@ Item {
}
}
x: 10
y: (parent.height / rows + 1) * 15;
y: (parent.height / rows + 1) * ( tts ? 17 : 15);
//y: parent.height - ((parent.height / 5) + 5);
width: parent.width - 20
height: parent.height - y - 10

@ -65,7 +65,7 @@ Port: UDP port of node, usually 4569.
Add DTMF commands like \*3node, \*1node, \*70, etc in the IAX DTMF box and hit send to send the DTMF string. The asterisk (*) character is already added on the Droidstar app, so only input the numeric portion of the command (70 instead of *70, etc). Details on various commands can be found at the AllStar wiki and others.
# General building instructions
This software is written primarily in C++ on Linux and requires Qt5 >= Qt5.15, and natually the devel packages to build. Java, QML (Javascript based), and C# code is also used where necessary. The preffered way to obtain Qt 5.15 is to use the Qt open source online installer from the Qt website. Run this installer as a user (not root) to keep the Qt installation separate from your system libs. Select the option as shown in this pic https://imgur.com/i0WuFCY which will install everything under ~/Qt.
This software is written primarily in C++ on Linux and requires Qt5 >= Qt5.15, and natually the devel packages to build. Java, QML (Javascript based), and C# code is also used where necessary. The preferred way to obtain Qt 5.15 is to use the Qt open source online installer from the Qt website. Run this installer as a user (not root) to keep the Qt installation separate from your system libs. Select the option as shown in this pic https://imgur.com/i0WuFCY which will install everything under ~/Qt.
## Note for building on Raspbian/RaspiOS
The Qt online installer does not support RPi, but fortunately there is a great Qt 5.15.2 installer for RaspiOS:

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<manifest package="org.dudetronics.droidstar" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="-- %%INSERT_VERSION_NAME%% --" android:versionCode="60" android:installLocation="auto">
<manifest package="org.dudetronics.droidstar" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="-- %%INSERT_VERSION_NAME%% --" android:versionCode="61" android:installLocation="auto">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30"/>
<!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application.

@ -42,7 +42,6 @@ private slots:
void transmit();
void format_callsign(QString &s);
void hostname_lookup(QHostInfo i);
void input_src_changed(int id, QString t) { m_ttsid = id; m_ttstext = t; }
void module_changed(int m) { m_module = 0x41 + m; m_modeinfo.streamid = 0; }
void usrtxt_changed(QString t) { m_txusrtxt = t; }
void send_frame(uint8_t *);

@ -965,7 +965,7 @@ void DMRCodec::process_rx_data()
emit update_output_level(m_audio->level());
}
}
else if ( (m_modeinfo.stream_state == STREAM_END) || (m_modeinfo.stream_state == STREAM_LOST) ){
else if ( ((m_modeinfo.stream_state == STREAM_END) || (m_modeinfo.stream_state == STREAM_LOST)) && (m_rxmodemq.size() > 50) ){
m_rxtimer->stop();
m_audio->stop_playback();
m_rxwatchdog = 0;

@ -204,6 +204,29 @@ void DroidStar::dtmf_send_clicked(QString dtmf)
emit send_dtmf(tx);
}
void DroidStar::tts_changed(QString tts)
{
if(tts == "Mic"){
m_tts = 0;
}
else if(tts == "TTS1"){
m_tts = 1;
}
else if(tts == "TTS2"){
m_tts = 2;
}
else if(tts == "TTS3"){
m_tts = 3;
}
emit input_source_changed(m_tts, m_ttstxt);
}
void DroidStar::tts_text_changed(QString ttstxt)
{
m_ttstxt = ttstxt;
emit input_source_changed(m_tts, m_ttstxt);
}
void DroidStar::process_connect()
{
if(connect_status != Codec::DISCONNECTED){
@ -318,6 +341,7 @@ void DroidStar::process_connect()
connect(m_ref, SIGNAL(update_output_level(unsigned short)), this, SLOT(update_output_level(unsigned short)));
connect(m_modethread, SIGNAL(started()), m_ref, SLOT(send_connect()));
connect(m_modethread, SIGNAL(finished()), m_ref, SLOT(deleteLater()));
connect(this, SIGNAL(input_source_changed(int, QString)), m_ref, SLOT(input_src_changed(int, QString)));
connect(this, SIGNAL(swrx_state_changed(int)), m_ref, SLOT(swrx_state_changed(int)));
connect(this, SIGNAL(swtx_state_changed(int)), m_ref, SLOT(swtx_state_changed(int)));
connect(this, SIGNAL(agc_state_changed(int)), m_ref, SLOT(agc_state_changed(int)));
@ -348,6 +372,7 @@ void DroidStar::process_connect()
connect(m_dcs, SIGNAL(update_output_level(unsigned short)), this, SLOT(update_output_level(unsigned short)));
connect(m_modethread, SIGNAL(started()), m_dcs, SLOT(send_connect()));
connect(m_modethread, SIGNAL(finished()), m_dcs, SLOT(deleteLater()));
connect(this, SIGNAL(input_source_changed(int, QString)), m_dcs, SLOT(input_src_changed(int, QString)));
connect(this, SIGNAL(swrx_state_changed(int)), m_dcs, SLOT(swrx_state_changed(int)));
connect(this, SIGNAL(swtx_state_changed(int)), m_dcs, SLOT(swtx_state_changed(int)));
connect(this, SIGNAL(agc_state_changed(int)), m_dcs, SLOT(agc_state_changed(int)));
@ -377,6 +402,7 @@ void DroidStar::process_connect()
connect(m_xrf, SIGNAL(update_output_level(unsigned short)), this, SLOT(update_output_level(unsigned short)));
connect(m_modethread, SIGNAL(started()), m_xrf, SLOT(send_connect()));
connect(m_modethread, SIGNAL(finished()), m_xrf, SLOT(deleteLater()));
connect(this, SIGNAL(input_source_changed(int, QString)), m_xrf, SLOT(input_src_changed(int, QString)));
connect(this, SIGNAL(swrx_state_changed(int)), m_xrf, SLOT(swrx_state_changed(int)));
connect(this, SIGNAL(swtx_state_changed(int)), m_xrf, SLOT(swtx_state_changed(int)));
connect(this, SIGNAL(agc_state_changed(int)), m_xrf, SLOT(agc_state_changed(int)));
@ -420,6 +446,7 @@ void DroidStar::process_connect()
connect(m_dmr, SIGNAL(update_output_level(unsigned short)), this, SLOT(update_output_level(unsigned short)));
connect(m_modethread, SIGNAL(started()), m_dmr, SLOT(send_connect()));
connect(m_modethread, SIGNAL(finished()), m_dmr, SLOT(deleteLater()));
connect(this, SIGNAL(input_source_changed(int, QString)), m_dmr, SLOT(input_src_changed(int, QString)));
connect(this, SIGNAL(swrx_state_changed(int)), m_dmr, SLOT(swrx_state_changed(int)));
connect(this, SIGNAL(swtx_state_changed(int)), m_dmr, SLOT(swtx_state_changed(int)));
connect(this, SIGNAL(agc_state_changed(int)), m_dmr, SLOT(agc_state_changed(int)));
@ -444,6 +471,7 @@ void DroidStar::process_connect()
connect(this, SIGNAL(m17_rate_changed(int)), m_ysf, SLOT(rate_changed(int)));
connect(m_modethread, SIGNAL(started()), m_ysf, SLOT(send_connect()));
connect(m_modethread, SIGNAL(finished()), m_ysf, SLOT(deleteLater()));
connect(this, SIGNAL(input_source_changed(int, QString)), m_ysf, SLOT(input_src_changed(int, QString)));
connect(this, SIGNAL(swrx_state_changed(int)), m_ysf, SLOT(swrx_state_changed(int)));
connect(this, SIGNAL(swtx_state_changed(int)), m_ysf, SLOT(swtx_state_changed(int)));
connect(this, SIGNAL(agc_state_changed(int)), m_ysf, SLOT(agc_state_changed(int)));
@ -463,6 +491,7 @@ void DroidStar::process_connect()
connect(m_p25, SIGNAL(update_output_level(unsigned short)), this, SLOT(update_output_level(unsigned short)));
connect(m_modethread, SIGNAL(started()), m_p25, SLOT(send_connect()));
connect(m_modethread, SIGNAL(finished()), m_p25, SLOT(deleteLater()));
connect(this, SIGNAL(input_source_changed(int, QString)), m_p25, SLOT(input_src_changed(int, QString)));
connect(this, SIGNAL(agc_state_changed(int)), m_p25, SLOT(agc_state_changed(int)));
connect(this, SIGNAL(tx_clicked(bool)), m_p25, SLOT(toggle_tx(bool)));
connect(this, SIGNAL(tx_pressed()), m_p25, SLOT(start_tx()));
@ -479,6 +508,7 @@ void DroidStar::process_connect()
connect(m_nxdn, SIGNAL(update_output_level(unsigned short)), this, SLOT(update_output_level(unsigned short)));
connect(m_modethread, SIGNAL(started()), m_nxdn, SLOT(send_connect()));
connect(m_modethread, SIGNAL(finished()), m_nxdn, SLOT(deleteLater()));
connect(this, SIGNAL(input_source_changed(int, QString)), m_nxdn, SLOT(input_src_changed(int, QString)));
connect(this, SIGNAL(swrx_state_changed(int)), m_nxdn, SLOT(swrx_state_changed(int)));
connect(this, SIGNAL(swtx_state_changed(int)), m_nxdn, SLOT(swtx_state_changed(int)));
connect(this, SIGNAL(agc_state_changed(int)), m_nxdn, SLOT(agc_state_changed(int)));
@ -497,6 +527,7 @@ void DroidStar::process_connect()
connect(m_m17, SIGNAL(update(Codec::MODEINFO)), this, SLOT(update_m17_data(Codec::MODEINFO)));
connect(m_m17, SIGNAL(update_output_level(unsigned short)), this, SLOT(update_output_level(unsigned short)));
connect(this, SIGNAL(m17_rate_changed(int)), m_m17, SLOT(rate_changed(int)));
connect(this, SIGNAL(input_source_changed(int, QString)), m_m17, SLOT(input_src_changed(int, QString)));
connect(m_modethread, SIGNAL(started()), m_m17, SLOT(send_connect()));
connect(m_modethread, SIGNAL(finished()), m_m17, SLOT(deleteLater()));
connect(this, SIGNAL(agc_state_changed(int)), m_m17, SLOT(agc_state_changed(int)));
@ -514,6 +545,7 @@ void DroidStar::process_connect()
connect(m_iax, SIGNAL(update_output_level(unsigned short)), this, SLOT(update_output_level(unsigned short)));
connect(m_modethread, SIGNAL(started()), m_iax, SLOT(send_connect()));
connect(m_modethread, SIGNAL(finished()), m_iax, SLOT(deleteLater()));
connect(this, SIGNAL(input_source_changed(int, QString)), m_iax, SLOT(input_src_changed(int, QString)));
//connect(this, SIGNAL(agc_state_changed(int)), m_xrf, SLOT(agc_state_changed(int)));
connect(this, SIGNAL(tx_clicked(bool)), m_iax, SLOT(toggle_tx(bool)));
connect(this, SIGNAL(tx_pressed()), m_iax, SLOT(start_tx()));

@ -39,6 +39,7 @@ public:
~DroidStar();
signals:
void input_source_changed(int, QString);
void mode_changed();
void module_changed(char);
void slot_changed(int);
@ -255,6 +256,8 @@ public slots:
void url_downloaded(QString);
unsigned short get_output_level(){ return m_outlevel; }
void set_output_level(unsigned short l){ m_outlevel = l; }
void tts_changed(QString); // { m_tts = tts; };
void tts_text_changed(QString); // { m_ttstxt = ttstxt; };
private:
int connect_status;
bool m_update_host_files;
@ -352,6 +355,9 @@ private:
QStringList m_playbacks;
QStringList m_captures;
int m_tts;
QString m_ttstxt;
QString m_modemRxFreq;
QString m_modemTxFreq;
QString m_modemRxOffset;

@ -60,7 +60,6 @@ private slots:
void send_voice_frame(int16_t *);
void send_dtmf(QByteArray);
void send_radio_key(bool);
void input_src_changed(int id, QString t) { m_ttsid = id; m_ttstext = t; }
void in_audio_vol_changed(qreal v){ m_audio->set_input_volume(v); }
void out_audio_vol_changed(qreal v){ m_audio->set_output_volume(v); }
private:

@ -17,6 +17,7 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QQuickStyle>
#include <QIcon>
#include <fcntl.h>
@ -31,6 +32,11 @@ int main(int argc, char *argv[])
app.setWindowIcon(QIcon(":/images/droidstar.png"));
qmlRegisterType<DroidStar>("org.dudetronics.droidstar", 1, 0, "DroidStar");
QQmlApplicationEngine engine;
#ifdef USE_FLITE
engine.rootContext()->setContextProperty("USE_FLITE", QVariant(true));
#else
engine.rootContext()->setContextProperty("USE_FLITE", QVariant(false));
#endif
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {

@ -250,7 +250,7 @@ void P25Codec::transmit()
m_ttscnt++;
}
}
encode_4400(pcm, imbe);
vocoder.encode_4400(pcm, imbe);
}
#endif
if(m_ttsid == 0){

@ -41,7 +41,6 @@ private slots:
void transmit();
void hostname_lookup(QHostInfo i);
void dmr_tgid_changed(unsigned int id) { m_txdstid = id; }
void input_src_changed(int id, QString t) { m_ttsid = id; m_ttstext = t; }
};
#endif // P25CODEC_H

@ -200,7 +200,6 @@ void REFCodec::process_udp()
}
if((buf.size() == 0x1d) && (!memcmp(buf.data()+1, header, 5)) ){ //29
const uint16_t streamid = (buf.data()[14] << 8) | (buf.data()[15] & 0xff);
//qDebug() << "streamid:s == " << m_streamid << ":" << s;
if(streamid != m_modeinfo.streamid){
return;
}
@ -267,7 +266,6 @@ void REFCodec::process_udp()
sd_sync = 0;
sd_seq = 0;
m_modeinfo.usertxt = QString(user_data);
//ui->usertxt->setText(QString::fromUtf8(user_data.data()));
}
for(int i = 0; i < 9; ++i){
m_rxcodecq.append(buf.data()[17+i]);

@ -41,7 +41,6 @@ private slots:
void transmit();
void format_callsign(QString &s);
void hostname_lookup(QHostInfo i);
void input_src_changed(int id, QString t) { m_ttsid = id; m_ttstext = t; }
void module_changed(int m) { m_module = 0x41 + m; m_modeinfo.streamid = 0; }
void send_frame(uint8_t *);
};

@ -316,7 +316,6 @@ void SerialModem::set_config()
c |= 0x40U;
out.append(c);
out.append(m_txDelay / 10U); // In 10ms units
out.append(MODE_IDLE);
out.append((uint8_t)(m_rxLevel * 2.55F + 0.5F));

@ -42,7 +42,6 @@ private slots:
void send_disconnect();
void transmit();
void hostname_lookup(QHostInfo i);
void input_src_changed(int id, QString t) { m_ttsid = id; m_ttstext = t; }
void usrtxt_changed(QString t) { m_txusrtxt = t; }
void send_frame(uint8_t *);
};

Loading…
Cancel
Save