MSHV-269-Non-Gendered/src/HvMsPlayer/msplayerhv.cpp
2024-02-12 11:29:54 +11:00

659 lines
20 KiB
C++

/* MSHV MsPlayerHV
* Copyright 2015 Hrisimir Hristov, LZ2HV
* (Edited by Harper Innes, VK1TTY - to remove Gendered Language and Replace with Non-Gendered language) NOTE:May be used under the terms of the GNU General Public License (GPL)
*/
#include "msplayerhv.h"
#include <QTime>
static const double SAVE_SAMPLE_RATE_11025 = 11025.0;
static const double SAVE_SAMPLE_RATE_12000 = 12000.0;
//#include <QtGui>
MsPlayerHV::MsPlayerHV(QString path)
{
s_mod_ident=2; //2.12
filenamehv=(char*)"none"; //2.12
s_period_time_sec = 30;
SAVE_SAMPLE_RATE = SAVE_SAMPLE_RATE_11025;//HV important set to default mode fsk441 sample rate
App_Path = path;
//s_MyGridLoc = "GRID";
s_tx_freq = 1200.0; //ft8 for the moment 1.43
f_message_or_file = true;
music.RealStop = true;
music.pause = false;
music.quit = false;
//music.setframeflag = false;
musics.stop = false;
musics.restart = false;
musics.errorflag = false;
musics.error_repat = false;
//music.setframenumber = 0;
musics.move = 1;//???? 1 netragva na 32 ako e 0
musics.currentrun = 0;
musics.errorcode = 0;
/*int po = sched_getscheduler(0);
qDebug()<<po<<sched_get_priority_max(po);
qDebug()<<po<<sched_get_priority_min(po);*/
/*
#if defined _LINUX_
Rawplayer::setvolume_lin(70);//pcm channel
#endif
*/
thtx = 0;
startuplock = PTHREAD_MUTEX_INITIALIZER; //ok win and lin -> linux no TX error
//pthread_mutex_init(&startuplock, NULL); //or this
pthread_attr_t thread_attr;
struct sched_param param;
pthread_attr_init(&thread_attr);
pthread_attr_getschedparam(&thread_attr, &param);//2.38
param.sched_priority = param.sched_priority + 1;//2.38
//param.sched_priority = 15;//2.38 stop
pthread_attr_setschedpolicy(&thread_attr, SCHED_OTHER); //2.38 stop <-no needed need Linux test OTHER=0 FIFO=1 RR=2 policy
pthread_attr_setschedparam(&thread_attr, &param);
//pthread_create(&th,NULL,MsPlayerHV::ThreadEntry,(void*)this);
pthread_create(&thtx,&thread_attr,MsPlayerHV::ThreadEntry,(void*)this);
pthread_mutex_unlock(&startuplock); // za da ne tragva s puskanet
/*int apoly,poly;
pthread_getschedparam(thtx,&apoly,&param);
pthread_attr_getschedpolicy(&thread_attr,&poly);
qDebug()<<"th="<<thtx<<param.sched_priority<<poly;*/
pthread_attr_destroy(&thread_attr);
}
MsPlayerHV::~MsPlayerHV()
{}
void MsPlayerHV::SetModeForWavSaves(int mode)
{
/*if (mode==0 || mode==7 || mode==8 || mode==9 || mode==10 || mode==11 || mode==12 || mode==13 ||
mode==14 || mode==15 || mode==16 || mode==17)//jt65abc msk144 pi4 ft8 ft4
{
SAVE_SAMPLE_RATE = SAVE_SAMPLE_RATE_12000;
#if defined _LINUX_
Rawplayer::pa_sa_rate = 48000;
#endif
}
else //if (mode>0 && mode<7)
{
SAVE_SAMPLE_RATE = SAVE_SAMPLE_RATE_11025;
#if defined _LINUX_
Rawplayer::pa_sa_rate = 44100;
#endif
}*/
if (mode>0 && mode<7)//2.65
{
SAVE_SAMPLE_RATE = SAVE_SAMPLE_RATE_11025;
#if defined _LINUX_
Rawplayer::pa_sa_rate = 44100;
#endif
}
else
{
SAVE_SAMPLE_RATE = SAVE_SAMPLE_RATE_12000;
#if defined _LINUX_
Rawplayer::pa_sa_rate = 48000;
#endif
}
}
void MsPlayerHV::SetSoundDevice(QString dev_in_number, int buffer)
{
strncpy(dev_in_p,dev_in_number.toUtf8(),127);//2.50 for pulse audio max is 512 ???
Rawplayer::defaultdevice = dev_in_p;
Rawplayer::buffering = buffer;
//qDebug()<<"MsPlayerHV========"<<Rawplayer::defaultdevice<<dev_in_number;
}
void MsPlayerHV::music_move(int value)
{
pthread_mutex_lock(&musics.movelock); // zada mal4i pri smiana na pesen veroiatno stawa i za pevartane
musics.move+=value; //qDebug()<<"gore.move"<<musics.move;
pthread_mutex_unlock(&musics.movelock);
}
void MsPlayerHV::music_done(void) // da preska4a pesen ako e error
{
music.RealStop=true;// za stop start ot edno i sa6to kop4e
music_move(1);
}
void MsPlayerHV::music_term(void)
{
music.pause=false;
music.quit=true;
}
void MsPlayerHV::seterrorcode(int errcode)
{
musics.errorcode=errcode;
musics.errorflag=true;
musics.error_repat=true;
music_done();
}
void MsPlayerHV::SaveFile(short*raw,int count,QString name)
{
//if(name.contains("/"))
//name.replace("/","_DROP_");
QString str = App_Path+"/RxWavs/"+name+".WAV";
//qDebug()<<str;
Rawtofile_wr *recorder;
recorder = Rawtofile_wr::opendevice(qstrdup(qPrintable(str)));
if (recorder == NULL)
return;
(recorder && ((Rawtofile_wr*)recorder)->setfiletype(WAV));
//qDebug()<<"q-strdup(qPrintable(name))";
if (!recorder->setsoundtype(0,16,SAVE_SAMPLE_RATE))//SAVE_SAMPLE_RATE 6000.0
{
seterrorcode(recorder->geterrorcode());
//qDebug()<<"1111";
return;
}
recorder->set8bitmode();
byte01_ *f = new byte01_[count*2];
int j = 0;
for (int i = 0; i < count; i++)
{
f[j]=(byte01_)(raw[i] & 0xff);
f[j+1]=(byte01_)((raw[i] >> 8) & 0xff);
j+=2;
}
recorder->putblock(f,count*2);
delete [] f;
delete recorder;
}
void MsPlayerHV::OpenFile(char *filename)
{
bool splay_forcetomonoflag;
splay_forcetomonoflag = false;
//int frequency;
Soundinputstream *loader;
int err;
Rawtodata *player;
Wavetoraw *server;
player=new Rawtodata;
if (player==NULL)
{
seterrorcode(SOUND_ERROR_MEMORYNOTENOUGH);
return;
}
if (!player->initialize(filename))
{
//2.12 error garmi
//delete player;//2.13 no delete crash
//qDebug()<<"player";
seterrorcode(player->geterrorcode());
return;
}
if ((loader=Soundinputstream::hopen(filename,&err))==NULL)
{
//qDebug()<<"loader";
seterrorcode(err);
delete loader;
return;
}
if ((server=new Wavetoraw(loader,player))==NULL)
{
//qDebug()<<"server";
seterrorcode(SOUND_ERROR_MEMORYNOTENOUGH);
return;
}
server->initialize((int)SAVE_SAMPLE_RATE);//check for diferent samplerates
server->setforcetomono(splay_forcetomonoflag);
//Setsongname(stripfilename(filename)); izliza na displea i zaradi tova go skasiavat hv
//music.pause=music.quit=music.setframeflag=false; //2.47 no needed in Open File
if (!server->run()) // Initialize Wave player
{
//qDebug()<<"server->run";
seterrorcode(server->geterrorcode());
delete server;
return;
}
emit SentFileClarDisplay();
connect(player, SIGNAL(SentData(short*, int, bool)), this, SIGNAL(SentData(short*, int, bool)));
///////////////////////////////tova ne triabva ve4e hv /////////////////////////////
int q=server->getfrequency()*(server->isstereo()+1);
if (server->getsamplesize()==16)
{
if (!splay_forcetomonoflag)q<<=1;
}
q>>=1;
player->setquota(q);
///////////////////////////////tova ne triabva ve4e hv /////////////////////////////
for (;;)
{
if (!server->run())
{
// music_done();
break;
}
}
//qDebug()<<"reset_wav";
delete server;
delete player;
delete loader;
return;
}
void MsPlayerHV::SetTxFreq(double f)
{
s_tx_freq = f;
}
void MsPlayerHV::xplaymessage(char *message,Rawplayer *player)
{
bool splay_forcetomonoflag;
splay_forcetomonoflag = false;
GenMessage *server;
//qDebug()<<"New Server"<<(QString)message<<ttt.elapsed();
//QTime ttt; ttt.start();
// Server
if ((server = new GenMessage(player))==NULL)//App_Path,
{
seterrorcode(SOUND_ERROR_MEMORYNOTENOUGH);
return;
}
//qDebug()<<"1 initialize="<<(QString)message<<ttt.elapsed();
server->initialize(message,s_mod_ident,s_tx_freq,s_period_time_sec);
//qDebug()<<"2 initialize="<<(QString)message<<ttt.elapsed();
QString new_tx_msg;
if ((s_mod_ident==0 || s_mod_ident==12) && message[0]!='@')//msk144 1.31 for " R " msg is same but not after unpack
new_tx_msg=server->TGenMsk->GetUnpackMsg();
else if ((s_mod_ident==7 || s_mod_ident==8 || s_mod_ident==9) && message[0]!='@')//jt65abc
{
new_tx_msg=server->TGen65->GetUnpackMsg();
}
else if (s_mod_ident==11 && message[0]!='@')//zasega ft8 s tova ->msk144 1.31 for " R " msg is same but not after unpack
{
new_tx_msg=server->TGenFt8->GetUnpackMsg();
}
else if (s_mod_ident==13 && message[0]!='@')//zasega ft4 s tova ->msk144 1.31 for " R " msg is same but not after unpack
new_tx_msg=server->TGenFt4->GetUnpackMsg();
else if ((s_mod_ident==14 || s_mod_ident==15 || s_mod_ident==16 || s_mod_ident==17) && message[0]!='@')//q64
new_tx_msg=server->TGenQ65->GetUnpackMsg();
else
new_tx_msg=(QString)message;
//qDebug()<<"Unpack"<<(QString)message<<ttt.elapsed();
//qDebug()<<"ss_prev_msg="<<ss_prev_msg<<"NewREAL="<<real_tx_msg<<"RealIn="<<(QString)message;
if (!music.RealStop)//s_prev_tx_msg!=new_tx_msg &&
{
//qDebug()<<new_tx_msg;
QString tmp = new_tx_msg;
if (tmp[0]=='@')
{
if (tmp=="@TUNE") tmp="TUNE";
if (tmp[1]=='A') tmp="882 Hz";
if (tmp[1]=='B') tmp="1323 Hz";
if (tmp[1]=='C') tmp="1764 Hz";
if (tmp[1]=='D') tmp="2205 Hz";
if (tmp[0]=='@')
{
tmp.remove("@");
if (tmp.toInt()>=100 && tmp.toInt()<=3500)
tmp= tmp+" Hz";
}
//SendTxMsgLabTxkkk(tmp);
}
//else
//emit SendTxMsgLabTx(tmp);
emit SendTxMsgAllTxt(tmp,s_tx_freq);
if (s_prev_tx_msg!=new_tx_msg)
{
emit SendTxMsgLabTx(tmp);
if (new_tx_msg!="@TUNE")
{
s_prev_disp_msg=tmp; //1.31
s_prev_tx_msg=new_tx_msg; //1.31 za da ne izpra6ta ako massg e sa6toto
}
}
}
server->setforcetomono(splay_forcetomonoflag);
//music.pause=music.quit=music.setframeflag=false; //2.47 stop move UP in xplay()
if (!server->run()) // Initialize Wave player
{
//PlayerStatus(0,0,0,(char*)"none");
seterrorcode(server->geterrorcode());
delete server;
return;
}
///////////////////////////////tova ne triabva ve4e hv /////////////////////////////
int q=server->getfrequency()*(server->isstereo()+1);
if (server->getsamplesize()==16)
{
if (!splay_forcetomonoflag)q<<=1;
}
q>>=1;
player->setquota(q);
///////////////////////////////tova ne triabva ve4e hv /////////////////////////////
int min_delayft = 200;
int delayft = min_delayft;
if (s_mod_ident==7 || s_mod_ident==8 || s_mod_ident==9)//jt65 wheit 1s in begining
usleep(700000);// tested 1.35
else if (s_mod_ident==11)//ft8
{
QTime ctt = QTime::currentTime();
int ss_s = ctt.toString("ss").toInt();
int ms_s = ctt.toString("zzz").toInt();//"z"<--- error QT > QT5 v5.9.x
if (ss_s % 15 == 0)
{
int xlat = 450 - ms_s;//500 real s wsjt2
if (xlat>50)// min 100-50ms delay
{
delayft = xlat;
//qDebug()<<"Start="<<ss_s<<ms_s<<xlat<<delayft8<<"FullLat="<<(ms_s + delayft8);
}
//else
//qDebug()<<"ERROR > 50===="<<ss_s<<ms_s<<delayft8<<"FullLat="<<(delayft8);
}
else
{
delayft = min_delayft;
//qDebug()<<"ERROR % 15===="<<ss_s<<ms_s<<delayft8<<"FullLat="<<(delayft8);
}
int lindelayft = (delayft * 1000);
usleep(lindelayft);//350000 400000 ft8 2.03
}
else if (s_mod_ident==13)//ft4
{
QTime ctt = QTime::currentTime();
int ss_s = ctt.toString("ss").toInt();
int ms_s = ctt.toString("zzz").toInt();//"z"<--- error QT > QT5 v5.9.x
if (ss_s == 7 || ss_s == 22 || ss_s == 37 || ss_s == 52)
{
ss_s=0;
ms_s -= 500;
}
if (ss_s % 15 == 0)
{
int xlat = 350 - ms_s;//350 real s wsjt2 rc7 ???? my be =400ms
if (xlat>50)// min 100-50ms delay
{
delayft = xlat;
//qDebug()<<"Start="<<ss_s<<ms_s<<xlat<<delayft8<<"FullLat="<<(ms_s + delayft8);
}
//else
//qDebug()<<"ERROR > 50===="<<ss_s<<ms_s<<delayft8<<"FullLat="<<(delayft8);
}
else
{
delayft = min_delayft;
//qDebug()<<"ERROR % 15===="<<ss_s<<ms_s<<delayft8<<"FullLat="<<(delayft8);
}
int lindelayft = (delayft * 1000);
usleep(lindelayft);//350000 400000 ft8 2.03
}
else if (s_mod_ident==14 || s_mod_ident==15 || s_mod_ident==16 || s_mod_ident==17)
{
QTime ctt = QTime::currentTime();
int mm_s = ctt.toString("mm").toInt();
int ss_s = ctt.toString("ss").toInt();
int ms_s = ctt.toString("zzz").toInt();
int mmss = (mm_s*60)+ss_s;
if (mmss % s_period_time_sec == 0)
{
int xlat = 950 - ms_s;
if (s_period_time_sec<60) xlat = 450 - ms_s;
if (xlat>50)
{
delayft = xlat;
//qDebug()<<"Start="<<ss_s<<ms_s<<xlat<<delayft8<<"FullLat="<<(ms_s + delayft8);
}
//else
//qDebug()<<"ERROR > 50===="<<ss_s<<ms_s<<delayft8<<"FullLat="<<(delayft8);
}
else
{
delayft = min_delayft;
//qDebug()<<"ERROR % 15===="<<ss_s<<ms_s<<delayft8<<"FullLat="<<(delayft8);
}
int lindelayft = (delayft * 1000);
usleep(lindelayft);
}
else
usleep(250000);//wsjt-x 200ms mshv -> 250000us tx delay offset 250ms
//qDebug()<<"Reall_TX==AUDIO=="<<QTime::currentTime().toString("ss:zzz");
for (;;)
{
if (music.pause)
{
player->abort();
player->resetsoundtype();
while (music.pause)
{
usleep(1000); //1.27 32-64bit qt4 gcc492 =100 //qt5 gcc530 = 1000
//#if defined _WIN64_
//usleep(1000);//v1.14 HV problem pod 1000 ne raboti GCC4.9.2 win64
//#endif
}
}
if (music.RealStop) // slagam go tuk za da ne proswirva pri stop pri malka pauza v na4aloto
{
server->mute_hv(true);//player->mute_hv(true);
//f_real_start = false;
music.pause = true;
//SentFrame(0/FRAMESIZE,server->gettotallength()/FRAMESIZE,FRAMESIZE,frequency);
}
else
{
server->mute_hv(false);//player->mute_hv(false);//tuk zastoto ina4e na vbr_wma Proswirwa w samia krai malko hv
}
if (music.quit)
{
player->getprocessed();
player->abort();
player->resetsoundtype();
break;
}
if (!server->run())
{
music_done();
break;
}
}
delete server;
if (new_tx_msg=="@TUNE")
emit SendTxMsgLabTx(s_prev_disp_msg);
//qDebug()<<"ELETE";
return;
}
void MsPlayerHV::xplayfile(char *filename)
{
char *device=Rawplayer::defaultdevice;
if (f_message_or_file)
{
if (device==NULL) device=Rawplayer::defaultdevice;
if (device[0]!='/') device=Rawplayer::defaultdevice;
Rawplayer *player = new Rawplayer; //qDebug()<<"create player";
if (player==NULL)
{
seterrorcode(SOUND_ERROR_MEMORYNOTENOUGH);
usleep(2000);// 2.48
return;
}
//qDebug()<<"initialize";
if (!player->initialize(device))
{
//qDebug()<<"FALSE player->initialize";//<<errr;
seterrorcode(player->geterrorcode());
//2.12 error garmi
//usleep(1000); // no 100% thread
//delete player;//2.39 old->2.13 stoped no delete crash
usleep(2000);// 2.48
return;
}
//qDebug()<<"EEEEEE==TX="<<QTime::currentTime().toString("mm:ss:zzz");;
//qDebug()<<"initialize";
xplaymessage(filename,player);
usleep(1000); // no 100% thread
delete player;
usleep(1000); //2.39 no 100% thread
//musics.stop=true;//hv 2.39 possyble but no recomended
return;
}
}
void MsPlayerHV::xplay()
{
musics.restart=true;
musics.errorflag=false;
//qDebug()<<"pthread_mutex_init";
pthread_mutex_init(&musics.movelock,NULL);//2.39 inportent crash win lin
for (;;)
{
/*if (music.RealStop)
{
SendTxRx(false);
}
else if ((QString)filenamehv != "%")
{
SendTxRx(true);
}*/
if (musics.restart)
{
musics.stop=false;
musics.restart=false;
musics.currentrun=0;
}
if (musics.errorflag)
musics.errorflag=false;
if (musics.move!=0)
{
pthread_mutex_lock(&musics.movelock);//2.39 inportent crash win lin
musics.currentrun+=musics.move;
if (!musics.stop)
{
musics.stop=true;
}
musics.move=0;
pthread_mutex_unlock(&musics.movelock);//2.39 inportent crash win lin
}
if (musics.stop)
{
usleep(2000); //2.37=2000 2.48=2000
}
else
{
if (filenamehv != NULL) // if(musics.currentrun<splay_listsize)
{
//qDebug()<<"START-------------------------------";
musics.error_repat=false; // vazno hv da e to4no tuk
music.pause=music.quit=false; //2.47 moved here KP4HF no the fly
//QTextCodec *codec = QTextCodec::codecForName(TXT_CODEC_WIN);
//QTextCodec *codec = QTextCodec::codecForName("Windows-1251");
//xplayfile(codec->fromUnicode(filenamehv).data());
xplayfile(filenamehv);//2.37 w10 no Windows-1251 crash
}
else
musics.restart=true;
}
}
}
void *MsPlayerHV::ThreadEntry(void *ar)
{
MsPlayerHV* pt = (MsPlayerHV*)ar;
pthread_mutex_lock(&pt->startuplock);
pt->xplay();
pthread_detach(pt->thtx); //2.48
pthread_exit(NULL);
return NULL;
}
void MsPlayerHV::Stop()
{
//qDebug()<<"MsPlayerHV::Stop()===================== ";
music.RealStop = true;
music_term();
}
void MsPlayerHV::Restart() //promenena
{
music.RealStop = false;
}
void MsPlayerHV::setfile_play(char *filename, bool msg_file, int mod_ident,int preiod_t)
{
int nmsg = strlen(filename); //if (nmsg<1) return;
if (nmsg<1) filename = (char*)" ";// 2.37 protect system
f_message_or_file = msg_file;
filenamehv = filename;
s_mod_ident = mod_ident;
s_period_time_sec = preiod_t;
if (msg_file)// not needed hv
{
//qDebug()<<"setfile_play"<<(QString)filename;
music_term();
musics.restart = true;
Restart(); // zaradi parvoto puskane
}
/*else
{
if (!only_one_start_cw_gen)
{
music_term();
musics.restart = true;
Restart();
only_one_start_cw_gen = true;
}
if (stop_cw_global || emidiatly_start_cw)
{
stop_cw_global = false;
count_txt_1 = 0;
count_read_letter_1=0;
get_decode(filenamehv[count_txt_1],tex_digits_1);
count_txt_1++;
}
else
stop_cw_global = true;
}*/
}
void MsPlayerHV::SetVolume(int volume)
{
GenMessage::setvolume_all(volume);
}