Browse Source

espeakedit: remove all but the --compile support

This removes the GUI part of espeakedit, keeping the part that is
responsible for compiling the voice and intonation data. The
motivation for this is:

  1.  the voice and intonation data compilation will move into
      libespeak-ng after removing the wxWidgets logic and converting
      the code to C;

  2.  the espeakedit code is tightly coupled to the internals of
      libespeak-ng at a source code level, not a binary/API level,
      making the code harder to maintain;

  3.  a new GUI will be written in Qt that better supports creating
      and editing voices and languages.
master
Reece H. Dunn 10 years ago
parent
commit
50377416cf
18 changed files with 19 additions and 8385 deletions
  1. 1
    8
      Makefile.am
  2. 2
    175
      src/compiledata.cpp
  3. 14
    795
      src/espeakedit.cpp
  4. 0
    2283
      src/extras.cpp
  5. 0
    574
      src/formantdlg.cpp
  6. 0
    190
      src/main.h
  7. 0
    174
      src/menus.cpp
  8. 1
    108
      src/options.cpp
  9. 0
    71
      src/options.h
  10. 0
    601
      src/prosodydisplay.cpp
  11. 0
    50
      src/prosodydisplay.h
  12. 1
    182
      src/spect.cpp
  13. 0
    181
      src/spect.h
  14. 0
    1030
      src/spectdisplay.cpp
  15. 0
    438
      src/spectseq.cpp
  16. 0
    478
      src/transldlg.cpp
  17. 0
    299
      src/voicedlg.cpp
  18. 0
    748
      src/vowelchart.cpp

+ 1
- 8
Makefile.am View File

@@ -82,17 +82,10 @@ libespeak_ng_SOURCE = \
espeakedit_SOURCE = \
src/compiledata.cpp \
src/espeakedit.cpp \
src/extras.cpp \
src/formantdlg.cpp \
src/menus.cpp \
src/options.cpp \
src/prosodydisplay.cpp \
src/spect.cpp \
src/spectdisplay.cpp \
src/spectseq.cpp \
src/transldlg.cpp \
src/voicedlg.cpp \
src/vowelchart.cpp
src/spectseq.cpp

if OPT_KLATT
common_FLAGS += -DINCLUDE_KLATT

+ 2
- 175
src/compiledata.cpp View File

@@ -53,18 +53,16 @@ extern wxString path_dictsource;
extern wxString path_phsource;
extern wxString path_phfile;
extern char path_dsource[sizeof(path_home)+20];
extern char path_source[sizeof(path_home)+20];

extern wxProgressDialog *progress;
extern int progress_max;
extern int gui_flag;
extern char voice_name2[40];

extern void FindPhonemesUsed(void);
extern "C" int utf8_in(int *c, const char *buf);
extern "C" int utf8_out(unsigned int c, char *buf);
extern void DrawEnvelopes();
extern void ReadPhondataManifest();
char path_source[sizeof(path_home)+20];

typedef struct {
const char *mnem;
@@ -949,159 +947,6 @@ static void PrintPhonemesUsed(FILE *f, const char *dsource, const char *dictname



static wxString CompileAllDictionaries()
{//=====================================
wxString filename;
wxFileName fname;
wxString dictstr;
wxString filetype;
wxString report = _T("");
int err;
int errors = 0;
int dict_count = 0;
FILE *f_in;
FILE *log;
FILE *f_phused;
char dictname[80];
char fname_log[sizeof(path_dsource)+20];
char save_voice_name[80];
char path[sizeof(path_home)+40]; // path_dsource+20
char buf[200];
char voicename[80];

if(!wxDirExists(path_dictsource))
{
if(gui_flag)
{
wxString dirname = wxDirSelector(_T("Directory of dictionary files"),path_phsource);
if(!dirname.IsEmpty())
{
path_dictsource = dirname;
strncpy0(path_dsource,path_dictsource.mb_str(wxConvLocal),sizeof(path_dsource)-1);
strcat(path_dsource,"/");
}
}
else
{
fprintf(stderr,"Can't find dictionary files: %s\n",path_dsource);
}
}

wxDir dir(path_dictsource);
if(!dir.IsOpened())
{
return(_T(" No dictionaries"));
}

strcpy(save_voice_name,voice_name2);

sprintf(fname_log,"%s%s",path_dsource,"dict_log");
log = fopen(fname_log,"w");
if(log != 0)
{
fprintf(log, "%s", utf8_bom);
}
sprintf(fname_log,"%s%s",path_dsource,"dict_phonemes");
f_phused = fopen(fname_log,"w");

if(f_phused)
{
fprintf(f_phused,"Phonemes which are used in the *_rules and *_list files\n");
}

bool cont = dir.GetFirst(&filename, _T("*_rules*"), wxDIR_FILES);
while ( cont )
{
fname = wxFileName(filename);
filetype = fname.GetName().AfterLast('_');
if((filetype != _T("rules")) && (filetype != _T("rules.txt")))
{
cont = dir.GetNext(&filename);
continue;
}

dictstr = fname.GetName().BeforeLast('_');
strcpy(dictname,dictstr.mb_str(wxConvLocal));

dict_count++;
strcpy(voicename,dictname);

// read the *_rules file to see if a phoneme table is specified though a voice name
sprintf(path,"%s%s_rules.txt",path_dsource,dictname);
if((f_in = fopen(path,"r")) == NULL)
{
sprintf(path,"%s%s_rules",path_dsource,dictname);
f_in = fopen(path,"r");
}

if(f_in != NULL)
{
unsigned int ix;
unsigned int c;

for(ix=0; ix<20; ix++)
{
if(fgets(buf,sizeof(buf),f_in) == NULL)
break;

if(memcmp(buf,"//voice=",8)==0)
{
for(ix=0; ix<sizeof(voicename); ix++)
{
if(isspace(c = buf[ix+8]))
{
break;
}
voicename[ix] = c;
}
voicename[ix] = 0;
break;
}
}
fclose(f_in);
}

if(LoadVoice(voicename,1) == NULL)
{
wxLogError(wxString::Format(_T("Can't find voice '%s' for dictionary '%s'"), wxString(voicename, wxConvLocal).c_str(), dictstr.c_str()));
report = report + dictstr + _T(" No Voice, ");
errors ++;
}
else
if((err = CompileDictionary(path_dsource, dictname,log,NULL,0)) > 0)
{
report = report + dictstr + wxString::Format(_T(" %d, "),err);
errors += err;
}

if(f_phused != NULL)
{
memset(phoneme_tab_flags,0,sizeof(phoneme_tab_flags));
FindPhonemesUsed();
PrintPhonemesUsed(f_phused, path_dsource, dictname);
}

cont = dir.GetNext(&filename);
}
if(log != NULL)
fclose(log);
if(f_phused != NULL)
fclose(f_phused);

LoadVoiceVariant(save_voice_name,0);

if(errors == 0)
return(wxString::Format(_T(" Compiled %d dictionaries"),dict_count));
else
{
return(_T(" Dictionary errors: ") + report);
}

} // end of CompileAllDictionaries




static void error(const char *format, const char *string)
{//======================================================
if(string==NULL)
@@ -3283,9 +3128,6 @@ static void StartPhonemeTable(const char *name)
return;
}

if(gui_flag)
progress->Update(n_phoneme_tabs);

memset(&phoneme_tab_list2[n_phoneme_tabs], 0, sizeof(PHONEME_TAB_LIST));
phoneme_tab_list2[n_phoneme_tabs].phoneme_tab_ptr = phoneme_tab2 = p;
strncpy0(phoneme_tab_list2[n_phoneme_tabs].name, name, N_PHONEME_TAB_NAME);
@@ -3652,14 +3494,7 @@ make_envs();
sprintf(fname,"%scompile_prog_log",path_source);
f_prog_log = fopen_log(f_errors,fname,"wb");

if(gui_flag)
{
progress = new wxProgressDialog(_T("Compiling"),_T(""),progress_max);
}
else
{
fprintf(stderr,"Compiling phoneme data: %s\n",path_source);
}
fprintf(stderr,"Compiling phoneme data: %s\n",path_source);

// write a word so that further data doesn't start at displ=0
Write4Bytes(f_phdata,version_phdata);
@@ -3691,18 +3526,10 @@ fprintf(f_errors,"\nRefs %d, Reused %d\n",count_references,duplicate_references
LoadVoice(voice_name2,0);

CompileReport();
if(gui_flag != 0)
report_dict = CompileAllDictionaries();
#ifdef MAKE_ENVELOPES
DrawEnvelopes();
#endif


if(gui_flag)
{
delete progress;
}

if(resample_count > 0)
{
fprintf(f_errors, "\n%d WAV files resampled to %d Hz\n", resample_count, samplerate_native);

+ 14
- 795
src/espeakedit.cpp View File

@@ -35,15 +35,12 @@
#include "speak_lib.h"
#include "espeak_ng.h"

#include "main.h"
#include "speech.h"
#include "options.h"
#include "phoneme.h"
#include "synthesize.h"
#include "voice.h"
#include "spect.h"
#include "translate.h"
#include "prosodydisplay.h"

static const char *about_string2 = "espeakedit: %s\nAuthor: Jonathan Duddington (c) 2009\n\n"
"Licensed under GNU General Public License version 3\n"
@@ -54,43 +51,20 @@ static const char *about_string = "<font size=0><b>espeakedit </b> %s<br>Author:
"<a href=\"http://espeak.sourceforge.net/\">http://espeak.sourceforge.net</a><br>"
"Licensed under <a href=\"http://espeak.sourceforge.net/license.html\">GNU General Public License version 3</a></font>";

const char *path_data;

extern void TestTest(int control);
extern void CompareLexicon(int);
extern void ConvertToUtf8();
extern void DictionaryFormat(const char *dictname);
extern void DictionarySort(const char *dictname);

extern void init_z();
extern void ConfigInit(bool use_defaults);
extern void CompilePhonemeData(void);
extern void CompileSampleRate(void);
extern espeak_ng_STATUS CompileIntonation(FILE *log);
extern void InitSpectrumDisplay();
extern void InitProsodyDisplay();
extern void InitWaveDisplay();

extern void VowelChart(int control, char *fname);
extern void MakeVowelLists(void);
extern void MakeWordFreqList();

extern wxMenu *speak_menu;
extern wxMenu *data_menu;


MyFrame *myframe = NULL;
SpectDisplay *currentcanvas = NULL;

ProsodyDisplay *prosodycanvas = NULL;
wxNotebook *notebook = NULL;
wxNotebook *screenpages = NULL;

wxProgressDialog *progress;
int progress_max;
int gui_flag = 0;
int frame_x, frame_y, frame_w, frame_h;

int adding_page = 0; // fix for wxWidgets (2,8,7) bug, adding first page to a wxNotebook gives emptystring for GetPageTex() in Notebook_Page_Changed event.
class MyApp: public wxApp
{
public:
bool OnInit(void);
int OnExit(void);
};

IMPLEMENT_APP(MyApp)

@@ -100,7 +74,6 @@ wxString AppName = _T("espeakedit");

int MyApp::OnExit()
{//================
ConfigSave(1);
return(0);
}

@@ -127,6 +100,13 @@ if(argc > 1)
const char *p = argv[1];
while((param[j] = p[j]) != 0) j++;
#endif
}
else
{
param[0] = '-';
param[1] = 'h';
param[2] = 0;
}

if((strcmp(param,"--help")==0) || (strcmp(param,"-h")==0))
{
@@ -151,764 +131,3 @@ if(argc > 1)
}
exit(0);
}

ConfigInit(false);
gui_flag = 1;
// It seems that the wctype functions don't work until the locale has been set
// to something other than the default "C". Then, not only Latin1 but also the
// other characters give the correct results with iswalpha() etc.
if(setlocale(LC_CTYPE,"en_US.UTF-8") == NULL)
{
if(setlocale(LC_CTYPE,"UTF-8") == NULL)
setlocale(LC_CTYPE,"");
}

if((frame_w == 0) || (frame_h == 0))
{
frame_w = 800;
frame_h = 768;
}

// Create the main frame window
myframe = new MyFrame(NULL, -1, AppName, wxPoint(frame_x, frame_y), wxSize(frame_w, frame_h),
wxDEFAULT_FRAME_STYLE |
wxNO_FULL_REPAINT_ON_RESIZE |
wxHSCROLL | wxVSCROLL);


// Make a menubar
myframe->SetMenuBar(MakeMenu(0, voice_name2));
myframe->CreateStatusBar();
myframe->SetVoiceTitle(voice_name2);

// myframe->Maximize();
myframe->Show(TRUE);

SetTopWindow(myframe);
wxInitAllImageHandlers();
// wxImage::AddHandler(wxPNGHandler);
wxLogStatus(_T("Using espeak_data at: ")+wxString(path_home, wxConvLocal));
return TRUE;
}

BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_CHAR(MyFrame::OnKey)
EVT_MENU(MENU_ABOUT, MyFrame::OnAbout)
EVT_MENU(MENU_DOCS, MyFrame::OnAbout)
EVT_MENU(MENU_SPECTRUM, MyFrame::OnNewWindow)
EVT_MENU(MENU_SPECTRUM2, MyFrame::OnNewWindow)
EVT_MENU(MENU_PROSODY, MyFrame::OnProsody)
EVT_MENU(MENU_OPT_SPEED, MyFrame::OnOptions)
EVT_MENU(MENU_OPT_PUNCT, MyFrame::OnOptions)
EVT_MENU(MENU_OPT_SPELL, MyFrame::OnOptions)
EVT_MENU(MENU_OPT_SPELL2, MyFrame::OnOptions)
EVT_MENU(MENU_PATH_DATA, MyFrame::OnOptions)
EVT_MENU(MENU_PATH0, MyFrame::OnOptions)
EVT_MENU(MENU_PATH1, MyFrame::OnOptions)
EVT_MENU(MENU_PATH2, MyFrame::OnOptions)
EVT_MENU(MENU_PATH3, MyFrame::OnOptions)
EVT_MENU(MENU_PATH4, MyFrame::OnOptions)
EVT_MENU(MENU_COMPILE_PH, MyFrame::OnTools)
EVT_MENU(MENU_COMPILE_PH2, MyFrame::OnTools)
EVT_MENU(MENU_COMPILE_DICT, MyFrame::OnTools)
EVT_MENU(MENU_COMPILE_DICT_DEBUG, MyFrame::OnTools)
EVT_MENU(MENU_FORMAT_DICTIONARY, MyFrame::OnTools)
EVT_MENU(MENU_SORT_DICTIONARY, MyFrame::OnTools)
EVT_MENU(MENU_COMPILE_MBROLA, MyFrame::OnTools)
EVT_MENU(MENU_COMPILE_INTONATION, MyFrame::OnTools)
EVT_MENU(MENU_QUIT, MyFrame::OnQuit)
EVT_MENU(MENU_SPEAK_TRANSLATE, MyFrame::OnSpeak)
EVT_MENU(MENU_SPEAK_RULES, MyFrame::OnSpeak)
EVT_MENU(MENU_SPEAK_IPA, MyFrame::OnSpeak)
EVT_MENU(MENU_SPEAK_TEXT, MyFrame::OnSpeak)
EVT_MENU(MENU_SPEAK_FILE, MyFrame::OnSpeak)
EVT_MENU(MENU_SPEAK_STOP, MyFrame::OnSpeak)
EVT_MENU(MENU_SPEAK_PAUSE, MyFrame::OnSpeak)
EVT_MENU(MENU_SPEAK_VOICE, MyFrame::OnSpeak)
EVT_MENU(MENU_SPEAK_VOICE_VARIANT, MyFrame::OnSpeak)
EVT_MENU(MENU_LOAD_WAV, MyFrame::OnTools)
EVT_MENU(MENU_VOWELCHART1, MyFrame::OnTools)
EVT_MENU(MENU_VOWELCHART2, MyFrame::OnTools)
EVT_MENU(MENU_VOWELCHART3, MyFrame::OnTools)
EVT_MENU(MENU_LEXICON_RU, MyFrame::OnTools)
EVT_MENU(MENU_LEXICON_BG, MyFrame::OnTools)
EVT_MENU(MENU_LEXICON_DE, MyFrame::OnTools)
EVT_MENU(MENU_LEXICON_IT, MyFrame::OnTools)
EVT_MENU(MENU_LEXICON_TEST, MyFrame::OnTools)
EVT_MENU(MENU_TO_UTF8, MyFrame::OnTools)
EVT_MENU(MENU_COUNT_WORDS, MyFrame::OnTools)
EVT_MENU(MENU_TEST, MyFrame::OnTools)
EVT_MENU(MENU_TEST2, MyFrame::OnTools)

EVT_MENU(SPECTSEQ_SAVE, MyFrame::PageCmd)
EVT_MENU(SPECTSEQ_SAVEAS, MyFrame::PageCmd)
EVT_MENU(SPECTSEQ_SAVESELECT, MyFrame::PageCmd)
EVT_MENU(SPECTSEQ_CLOSE, MyFrame::PageCmd)
EVT_MENU(SPECTSEQ_SAVEPITCH, MyFrame::PageCmd)
EVT_MENU(MENU_CLOSE_ALL, MyFrame::PageCmd)


EVT_NOTEBOOK_PAGE_CHANGED(ID_SCREENPAGES, MyFrame::OnPageChanged)
EVT_TIMER(1, MyFrame::OnTimer)
END_EVENT_TABLE()


MyFrame::~MyFrame(void)
{//====================
myframe->Maximize(false);
myframe->Show(false);
myframe->Iconize(false); // os=Windows, get the non-iconsized size
myframe->GetPosition(&frame_x, &frame_y);
myframe->GetSize(&frame_w, &frame_h);
}

MyFrame::MyFrame(wxWindow *parent, const wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size,
const long style):
wxFrame(parent, id, title, pos, size, style)
{//===================================================================================================================
// Main Frame constructor

int error_flag = 0;
int result;
int param;
int srate;

notebook = new wxNotebook(this, ID_NOTEBOOK, wxDefaultPosition, wxSize(312,760));
// notebook->AddPage(voicedlg,_T("Voice"),FALSE);
formantdlg = new FormantDlg(notebook);
notebook->AddPage(formantdlg,_T(" Spect"),FALSE);
voicedlg = new VoiceDlg(notebook);

transldlg = new TranslDlg(notebook);
notebook->AddPage(transldlg,_T("Text"),TRUE);


screenpages = new wxNotebook(this, ID_SCREENPAGES, wxDefaultPosition, wxSize(554,702));

wxBoxSizer *framesizer = new wxBoxSizer( wxHORIZONTAL );


framesizer->Add(
notebook,
0, // make horizontally stretchable
wxEXPAND | // make vertically stretchable
wxALL, // and make border all around
4 ); // set border width

framesizer->Add(
screenpages,
1, // make horizontally stretchable
wxEXPAND | // make vertically stretchable
wxALL, // and make border all around
4 ); // set border width

SetSizer( framesizer ); // use the sizer for layout
framesizer->SetSizeHints( this ); // set size hints to honour minimum size
SetSize(pos.x, pos.y, size.GetWidth(), size.GetHeight());

LoadConfig();

if((result = LoadPhData(&srate)) != 1)
{
if(result == -1)
wxLogError(_T("Failed to read espeak-data/phontab,phondata,phonindex\nPath = ")+wxString(path_home,wxConvLocal)+_T("\n\nThe 'eSpeak' package needs to be installed"));
else
wxLogError(_T("Wrong version of espeak-data at:\n")+ wxString(path_home,wxConvLocal)+_T("\nVersion 0x%x (expects 0x%x)"),result,version_phdata);

error_flag = 1;
srate = 22050;
}
WavegenInit(srate,0);
WavegenInitSound();

f_trans = stdout;
option_ssml = 1;
option_phoneme_input = 1;


// if(LoadVoice(voice_name,0) == NULL)
if(SetVoiceByName(voice_name2) != EE_OK)
{
if(error_flag==0)
wxLogError(_T("Failed to load voice data"));
strcpy(dictionary_name,"en");
}
WavegenSetVoice(voice);

for(param=0; param<N_SPEECH_PARAM; param++)
param_stack[0].parameter[param] = param_defaults[param];

SetParameter(espeakRATE,option_speed,0);

SetSpeed(3);
SynthesizeInit();

InitSpectrumDisplay();
InitProsodyDisplay();
// InitWaveDisplay();
espeak_ListVoices(NULL);

m_timer.SetOwner(this,1);

m_timer.Start(500); /* 0.5 timer */

} // end of MyFrame::MyFrame


void MyFrame::SetVoiceTitle(char *voice_name)
{//==========================================
char buf[100];

if(samplerate_native == 22050)
sprintf(buf, " - %s voice", voice_name);
else
sprintf(buf, " - %s voice %dHz", voice_name, samplerate_native);
SetTitle(AppName + wxString(buf,wxConvLocal));

if((data_menu != NULL) && (translator != NULL))
{
sprintf(buf,"Compile &dictionary '%s'",translator->dictionary_name);
data_menu->SetLabel(MENU_COMPILE_DICT, wxString(buf,wxConvLocal));
sprintf(buf,"&Layout '%s_rules' file",translator->dictionary_name);
data_menu->SetLabel(MENU_FORMAT_DICTIONARY, wxString(buf,wxConvLocal));
sprintf(buf,"&Sort '%s_rules' file",translator->dictionary_name);
data_menu->SetLabel(MENU_SORT_DICTIONARY, wxString(buf,wxConvLocal));
}
}



void MyFrame::PageCmd(wxCommandEvent& event)
{//=========================================
int pagenum;
int ix;
int n_pages;
SpectDisplay *page;

// if(currentcanvas != NULL)
{
pagenum = screenpages->GetSelection();

switch(event.GetId())
{
case SPECTSEQ_SAVE:
currentcanvas->Save(currentcanvas->savepath);
break;
case SPECTSEQ_SAVEAS:
currentcanvas->Save();
screenpages->SetPageText(screenpages->GetSelection(), currentcanvas->spectseq->name+_T(" ²"));
break;
case SPECTSEQ_SAVESELECT:
currentcanvas->Save(_T(""), 1);
break;
case SPECTSEQ_CLOSE:
if(screenpages->GetPageText(pagenum) != _T("Prosody"))
{
currentcanvas->OnActivate(0);
}
screenpages->DeletePage(pagenum);

if((n_pages = screenpages->GetPageCount()) > 0)
{
if(pagenum >= n_pages)
pagenum--;
page = (SpectDisplay *)screenpages->GetPage(pagenum);

if(screenpages->GetPageText(pagenum) == _T("Prosody"))
{
MakeMenu(3, NULL);
}
else
{
page->OnActivate(1);
MakeMenu(2, NULL);
}
}
else
{
MakeMenu(1, NULL);
}
break;

case MENU_CLOSE_ALL:
n_pages = screenpages->GetPageCount();
for(ix=n_pages-1; ix>=0; ix--)
{
screenpages->DeletePage(ix);
}
currentcanvas = NULL;
MakeMenu(1, NULL);
break;
case SPECTSEQ_SAVEPITCH:
currentcanvas->SavePitchenv(currentcanvas->spectseq->pitchenv);
break;
}
}
}



void MyFrame::OnPageChanged(wxNotebookEvent& event)
{//=================================================
int pagenum;
wxString title;
SpectDisplay *page;

pagenum = event.GetSelection();

if(event.GetId() == ID_SCREENPAGES)
{
title = screenpages->GetPageText(pagenum);

if((title != _T("Prosody")) && (adding_page != 2))
{
page = (SpectDisplay *)screenpages->GetPage(pagenum);

if(page != currentcanvas)
{
if(currentcanvas != NULL)
{
currentcanvas->OnActivate(0);
}
page->OnActivate(1);
}
MakeMenu(2, NULL);
}
else
{
MakeMenu(3, NULL);
}
}
adding_page = 0; // work around for wxNotebook bug (version 2.8.7)
}


void MyFrame::OnKey(wxKeyEvent& event)
{
int key;

key = event.GetKeyCode();

if((currentcanvas != NULL) && (currentcanvas != FindFocus()))
{
if((key == WXK_F1) || (key == WXK_F2))
{
currentcanvas->OnKey(event);
currentcanvas->SetFocus();
return;
}
}

event.Skip();
}

void MyFrame::OnTimer(wxTimerEvent &event)
//****************************************
{
SynthOnTimer();
}


void MyFrame::OnQuit(wxCommandEvent& event)
{
switch(event.GetId())
{
case MENU_QUIT:
Close(TRUE);
break;
case MENU_CLOSE_ALL:
break;
}
}



class HtmlWindow: public wxHtmlWindow
{
public:

HtmlWindow(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style);
void OnLinkClicked(const wxHtmlLinkInfo& link);
};

HtmlWindow::HtmlWindow(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style):
wxHtmlWindow(parent, id, pos, size, style)
{
}

void HtmlWindow::OnLinkClicked(const wxHtmlLinkInfo& link)
{
if(wxLaunchDefaultBrowser(link.GetHref()) == FALSE)
wxLogStatus(_T("Failed to launch default browser: "+link.GetHref()));
}


void MyFrame::OnAbout(wxCommandEvent& event)
{//=========================================
int result;
char buf[300];
wxString url_docs;

switch(event.GetId())
{
case MENU_ABOUT:
{
wxDialog dlg(this, wxID_ANY, wxString(_("About")));

sprintf(buf,about_string,espeak_Info(NULL));
HtmlWindow *html = new HtmlWindow(&dlg, wxID_ANY, wxDefaultPosition, wxSize(380, 160), wxHW_SCROLLBAR_NEVER);
html -> SetBorders(0);
html -> SetPage(wxString(buf,wxConvLocal));
html -> SetSize(html -> GetInternalRepresentation() -> GetWidth(),
html -> GetInternalRepresentation() -> GetHeight());

wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
topsizer -> Add(html, 1, wxALL, 10);

//#if wxUSE_STATLINE
// topsizer -> Add(new wxStaticLine(&dlg, wxID_ANY), 0, wxEXPAND | wxLEFT | wxRIGHT, 10);
//#endif // wxUSE_STATLINE

wxButton *bu1 = new wxButton(&dlg, wxID_OK, _("OK"));
bu1 -> SetDefault();

topsizer -> Add(bu1, 0, wxALL | wxALIGN_RIGHT, 15);

dlg.SetSizer(topsizer);
topsizer -> Fit(&dlg);

dlg.ShowModal();
}
break;

case MENU_DOCS:
strcpy(buf,"/docs/docindex.html");
url_docs = wxGetCwd() + wxString(buf,wxConvLocal); // look for "docs" in the current directory
if(!wxFileExists(url_docs))
{
strcpy(buf,"http://espeak.sourceforge.net/docindex.html");
url_docs = wxString(buf,wxConvLocal);
}
else
{
url_docs = _T("file://") + url_docs;
}

result = wxLaunchDefaultBrowser(url_docs);
if(result == 0)
wxLogStatus(_T("Failed to launch default browser: "+url_docs));
break;
}
}



void OnOptions2(int event_id)
{//==========================
wxString string;
int value;

switch(event_id)
{
case MENU_OPT_SPEED:
value = wxGetNumberFromUser(_T(""),_T(""),_T("Speed"),option_speed,80,500);
if(value > 0)
{
option_speed = value;
SetParameter(espeakRATE,option_speed,0);
SetSpeed(3);
}
break;

case MENU_OPT_PUNCT:
transldlg->t_source->SetValue(_T("<tts:style field=\"punctuation\" mode=\"all\">\n"));
transldlg->t_source->SetInsertionPointEnd();
notebook->SetSelection(1);
break;

case MENU_OPT_SPELL:
transldlg->t_source->SetValue(_T("<say-as interpret-as=\"characters\">\n"));
transldlg->t_source->SetInsertionPointEnd();
notebook->SetSelection(1);
break;

case MENU_OPT_SPELL2:
transldlg->t_source->SetValue(_T("<say-as interpret-as=\"tts:char\">\n"));
transldlg->t_source->SetInsertionPointEnd();
notebook->SetSelection(1);
break;

case MENU_PATH_DATA:
string = wxDirSelector(_T("espeak_data directory"), path_espeakdata);
if(!string.IsEmpty())
{
if(!wxDirExists(string+_T("/voices")))
{
wxLogError(_T("No 'voices' directory in ") + string);
break;
}
path_espeakdata = string;
wxLogMessage(_T("Quit and restart espeakedit to use the new espeak_data location"));
}
break;

case MENU_PATH0:
string = wxFileSelector(_T("Master phonemes file"),wxFileName(path_phfile).GetPath(),
_T("phonemes"),_T(""),_T("*"),wxOPEN);
if(!string.IsEmpty())
{
path_phfile = string;
}
break;

case MENU_PATH1:
string = wxDirSelector(_T("Phoneme source directory"),path_phsource);
if(!string.IsEmpty())
{
path_phsource = string;
}
break;

case MENU_PATH2:
string = wxDirSelector(_T("Dictionary source directory"),path_dictsource);
if(!string.IsEmpty())
{
path_dictsource = string;
}
break;

case MENU_PATH3:
string = wxFileSelector(_T("Sound output file"),wxFileName(path_speech).GetPath(),
_T(""),_T("WAV"),_T("*"),wxSAVE);
if(!string.IsEmpty())
{
path_speech = string;
}
break;

case MENU_PATH4:
string = wxFileSelector(_T("Voice file to modify formant peaks"),wxFileName(path_speech).GetPath(),
_T(""),_T(""),_T("*"),wxOPEN);
if(!string.IsEmpty())
{
path_modifiervoice = string;
}
break;
}

ConfigSetPaths();
}


void MyFrame::OnOptions(wxCommandEvent& event)
{//===========================================
OnOptions2(event.GetId());
}


void DisplayErrorFile(const char *fname)
{//=====================================
int len;
FILE *f;
char *msg;
wxString msg_string;

len = GetFileLength(fname);
if(len > 0)
{
if(len > 1500)
len = 1500; // restrict length to prevent crash in wxLogMessage()
msg = (char *)malloc(len+1);
if(msg != NULL)
{
f = fopen(fname,"r");
len = fread(msg,1, len, f);
fclose(f);
msg[len] = 0;
msg_string = wxString(msg,wxConvUTF8);
wxLogMessage(msg_string);
free(msg);
}
}
} // end of DisplayErrorFile



void MyFrame::OnTools(wxCommandEvent& event)
{//=========================================
int err;
FILE *log;
int debug_flag=0;
char fname_log[sizeof(path_dsource)+12];
char err_fname[sizeof(path_home)+15];
static unsigned const char utf8_bom[] = {0xef,0xbb,0xbf,0};

switch(event.GetId())
{
case MENU_TEST:
TestTest(0);
break;

case MENU_TEST2:
TestTest(2);
break;

case MENU_TO_UTF8:
ConvertToUtf8();
break;

case MENU_COUNT_WORDS:
MakeWordFreqList();
break;

case MENU_LEXICON_RU:
case MENU_LEXICON_BG:
case MENU_LEXICON_DE:
case MENU_LEXICON_IT:
case MENU_LEXICON_TEST:
CompareLexicon(event.GetId()); // Compare a lexicon with _rules translation
break;

case MENU_COMPILE_PH:
CompilePhonemeData();
SetVoiceTitle(voice_name2);
break;

case MENU_COMPILE_PH2:
CompileSampleRate();
SetVoiceTitle(voice_name2);
break;

case MENU_COMPILE_MBROLA:
{
wxString filepath = wxFileSelector(_T("Read Mbrola phonemes file"),path_phsource+_T("/mbrola"),_T(""),_T(""),_T("*"),wxOPEN);
espeak_ng_CompileMbrolaVoice(filepath.mb_str(wxConvLocal), stdout);
}
break;

case MENU_COMPILE_INTONATION:
{
FILE *f_errors;
char fname_errors[sizeof(path_source)+120];
sprintf(fname_errors,"%s%s",path_source,"error_intonation");
if((f_errors = fopen(fname_errors,"w")) == NULL)
f_errors = stderr;

espeak_ng_STATUS status = CompileIntonation(f_errors);
if (f_errors != stderr)
fclose(f_errors);

if (status == ENE_COMPILE_ERRORS)
DisplayErrorFile(fname_errors);
}
break;

case MENU_COMPILE_DICT_DEBUG:
debug_flag =1; // and drop through to next case
case MENU_COMPILE_DICT:
sprintf(fname_log,"%s%s",path_dsource,"dict_log");
log = fopen(fname_log,"w");
if(log != NULL)
{
fprintf(log, "%s", utf8_bom);
}

LoadDictionary(translator, translator->dictionary_name, 0);
if((err = CompileDictionary(path_dsource,translator->dictionary_name,log,err_fname,debug_flag)) < 0)
{
wxLogError(_T("Can't access file:\n")+wxString(err_fname,wxConvLocal));

wxString dir = wxDirSelector(_T("Directory containing dictionary files"),path_dictsource);
if(!dir.IsEmpty())
{
path_dictsource = dir;
strncpy0(path_dsource,path_dictsource.mb_str(wxConvLocal),sizeof(path_dsource)-1);
strcat(path_dsource,"/");
}
break;
}
wxLogStatus(_T("Compiled '")+wxString(dictionary_name,wxConvLocal)+_T("', %d errors"),err);

if(log != NULL)
{
fclose(log);

if(err > 0)
{
// display the error messages
DisplayErrorFile(fname_log);
}
}
break;

case MENU_FORMAT_DICTIONARY:
DictionaryFormat(dictionary_name);
break;

case MENU_SORT_DICTIONARY:
DictionarySort(dictionary_name);
break;

case MENU_VOWELCHART1:
MakeVowelLists();
break;

case MENU_VOWELCHART2:
VowelChart(2,NULL);
break;

case MENU_VOWELCHART3:
VowelChart(3,NULL);
break;

case MENU_LOAD_WAV:
// LoadWavFile();
break;
}
}

void MyFrame::OnSpeak(wxCommandEvent& event)
{//=========================================
switch(event.GetId())
{
case MENU_SPEAK_TRANSLATE:
case MENU_SPEAK_RULES:
case MENU_SPEAK_IPA:
case MENU_SPEAK_TEXT:
transldlg->OnCommand(event);
break;

case MENU_SPEAK_FILE:
out_ptr = NULL;
transldlg->SpeakFile();
break;

case MENU_SPEAK_STOP:
SpeakNextClause(NULL,NULL,2);
break;

case MENU_SPEAK_PAUSE:
out_ptr = NULL;
SpeakNextClause(NULL,NULL,3);
if(SynthStatus() & 2)
speak_menu->SetLabel(MENU_SPEAK_PAUSE,_T("&Resume"));
else
{
speak_menu->SetLabel(MENU_SPEAK_PAUSE,_T("&Pause"));
}
break;

case MENU_SPEAK_VOICE:
transldlg->ReadVoice(0);
SetVoiceTitle(voice_name2);
break;

case MENU_SPEAK_VOICE_VARIANT:
transldlg->ReadVoice(1);
SetVoiceTitle(voice_name2);
break;
}
}




+ 0
- 2283
src/extras.cpp
File diff suppressed because it is too large
View File


+ 0
- 574
src/formantdlg.cpp View File

@@ -1,574 +0,0 @@
/***************************************************************************
* Copyright (C) 2006 to 2007 by Jonathan Duddington *
* email: [email protected] *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 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 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write see: *
* <http://www.gnu.org/licenses/>. *
***************************************************************************/



// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wx.h"
#include "wx/mdi.h"


#include "speak_lib.h"
#include "main.h"
#include "speech.h"
#include "phoneme.h"
#include "synthesize.h"
#include "voice.h"
#include "spect.h"

#include "wx/textctrl.h"
#include "wx/checkbox.h"

FormantDlg *formantdlg=NULL;
ByteGraph *pitchgraph=NULL;



BEGIN_EVENT_TABLE(FormantDlg, wxPanel)
EVT_BUTTON(T_ZOOMOUT,FormantDlg::OnCommand)
EVT_BUTTON(T_ZOOMIN,FormantDlg::OnCommand)
EVT_SPINCTRL(-1,FormantDlg::OnSpin)
// EVT_SPINCTRL(T_TIMESEQ,FormantDlg::OnSpin)
// EVT_SPINCTRL(T_AMPFRAME,FormantDlg::OnSpin)
// EVT_SPINCTRL(T_TIMEFRAME,FormantDlg::OnSpin)
END_EVENT_TABLE()

int use_spin_controls=0;

void FormantDlg::OnCommand(wxCommandEvent& event)
{//=============================================
int id;

if(currentcanvas == NULL)
return;

switch(id = event.GetId())
{
case T_ZOOMIN:
case T_ZOOMOUT:
currentcanvas->OnZoom(id);
break;

case T_AMPLITUDE:
currentcanvas->RefreshDialogValues(0);
break;

case T_TIMEFRAME:
case T_AMPFRAME:
currentcanvas->RefreshDialogValues(1);
break;
}
currentcanvas->SetFocus();
}

void FormantDlg::OnSpin(wxSpinEvent& event)
{//=============================================
int id;

if(currentcanvas == NULL)
return;

switch(id = event.GetId())
{
case T_AMPFRAME:
currentcanvas->RefreshDialogValues(1);
break;

default:
currentcanvas->RefreshDialogValues(0);
break;
}
currentcanvas->SetFocus();
}

FormantDlg::FormantDlg(wxWindow *parent) : wxPanel(parent,-1,wxDefaultPosition,wxSize(400,800))
{//=============================================================================================
int ix;
int y;
int xplace;
int id;
wxString string;
wxString control_name;

int height;
int width;
int x;
int y2 = 420;
int y3 = 520;

wxClientDisplayRect(&x,&y,&width, &height);
#ifdef PLATFORM_WINDOWS
if(height <= 768)
{
y2 = 410;
y3 = 508;
}
#else
if(height <= 800)
{
y2 = 378;
y3 = 456;
}
#endif
y = 24;
xplace = 28;
id = 201;
new wxStaticText(this,-1,_T("Formants"),wxPoint(4,5));
new wxStaticText(this,-1,_T(" Ht Width (Klatt)"),wxPoint(78,5),wxSize(300,20));
new wxStaticText(this,-1,_T("Bw Ap Bp"),wxPoint(188,29),wxSize(300,20));

for(ix=0; ix < 8; ix++)
{
string.Printf(_T("%d"),ix);
t_labpk[ix] = new wxStaticText(this,id++,string,
wxPoint(xplace-22,y+1+24*ix));

if(ix < 7)
{
control_name.Printf(_T("Formant %d"),ix);
t_pkfreq[ix] = new wxTextCtrl(this,id++,_T(""),
wxPoint(xplace,y+24*ix),wxSize(44,20),
wxTE_CENTRE,wxDefaultValidator,control_name);
}

control_name.Printf(_T("Height %d"),ix);
t_pkheight[ix] = new wxTextCtrl(this,id++,_T(""),
wxPoint(xplace+46,y+24*ix),wxSize(36,20),
wxTE_CENTRE,wxDefaultValidator,control_name);

if(ix < 6)
{
control_name.Printf(_T("Width %d"),ix);
t_pkwidth[ix] = new wxTextCtrl(this,id++,_T(""),
wxPoint(xplace+84,y+24*ix),wxSize(60,20),
wxTE_CENTRE,wxDefaultValidator,control_name);
}

if((ix == 0) || (ix > 6)) continue;

if(ix < 4)
{
control_name.Printf(_T("Klatt bandwidth %d"),ix);
t_klt_bw[ix] = new wxTextCtrl(this,id++,_T(""),
wxPoint(xplace+150,y+24*ix),wxSize(40,20),
wxTE_CENTRE,wxDefaultValidator,control_name);
}

control_name.Printf(_T("Klatt parallal %d"),ix);
t_klt_ap[ix] = new wxTextCtrl(this,id++,_T(""),
wxPoint(xplace+192,y+24*ix),wxSize(36,20),
wxTE_CENTRE,wxDefaultValidator,control_name);

control_name.Printf(_T("Klatt parallel bandwidth %d"),ix);
t_klt_bp[ix] = new wxTextCtrl(this,id++,_T(""),
wxPoint(xplace+230,y+24*ix),wxSize(40,20),
wxTE_CENTRE,wxDefaultValidator,control_name);
}

y=224;
if(use_spin_controls)
{
t_timeframe = new wxSpinCtrl(this,T_TIMEFRAME,_T(""), wxPoint(6,y+0), wxSize(52,24), wxTE_CENTRE,0,500,0,_T("Frame length"));
}
else
{
tt_timeframe = new wxTextCtrl(this,T_TIMEFRAME,_T(""), wxPoint(6,y+0), wxSize(52,24), wxTE_CENTRE,wxDefaultValidator,_T("Frame length"));
}
t_orig_frame = new wxStaticText(this,-1,_T("mS"),wxPoint(61,y+8));
t_ampframe = new wxSpinCtrl(this,T_AMPFRAME,_T(""), wxPoint(104,y+0), wxSize(52,24), wxTE_CENTRE,0,500,0,_T("Frame amplitude"));
t_lab[3] = new wxStaticText(this,-1,_T("% amp - Frame"),wxPoint(159,y+8));

y += 40;
s_klatt[KLATT_AV] = new wxSpinCtrl(this,T_AV,_T(""), wxPoint(6,y), wxSize(52,24), wxTE_CENTRE,0,500,0,_T("Klatt AV"));
t_klatt[KLATT_AV] = new wxStaticText(this,-1,_T("AV"),wxPoint(61,y+4));

s_klatt[KLATT_FNZ] = new wxSpinCtrl(this,T_FNZ,_T(""), wxPoint(104,y), wxSize(52,24), wxTE_CENTRE,0,500,0,_T("Klatt FNZ"));
t_klatt[KLATT_FNZ] = new wxStaticText(this,-1,_T("FNZ"),wxPoint(159,y+4));


y += 28;
s_klatt[KLATT_Tilt] = new wxSpinCtrl(this,T_TILT,_T(""), wxPoint(6,y), wxSize(52,24), wxTE_CENTRE,0,500,0,_T("Klatt tilt"));
t_klatt[KLATT_Tilt] = new wxStaticText(this,-1,_T("Tilt"),wxPoint(61,y+4));

s_klatt[KLATT_Aspr] = new wxSpinCtrl(this,T_ASPR,_T(""), wxPoint(104,y), wxSize(52,24), wxTE_CENTRE,0,500,0,_T("Klatt aspiration"));
t_klatt[KLATT_Aspr] = new wxStaticText(this,-1,_T("Aspr"),wxPoint(159,y+4));

s_klatt[KLATT_Skew] = new wxSpinCtrl(this,T_SKEW,_T(""), wxPoint(202,y), wxSize(52,24), wxTE_CENTRE,0,500,0,_T("Klatt skew"));
t_klatt[KLATT_Skew] = new wxStaticText(this,-1,_T("Skew"),wxPoint(257,y+4));

y += 28;
s_klatt[KLATT_AVp] = new wxSpinCtrl(this,T_AVP,_T(""), wxPoint(6,y), wxSize(52,24), wxTE_CENTRE,0,500,0,_T("Klatt AVp"));
t_klatt[KLATT_AVp] = new wxStaticText(this,-1,_T("AVp"),wxPoint(61,y+4));

s_klatt[KLATT_Fric] = new wxSpinCtrl(this,T_FRIC,_T(""), wxPoint(104,y), wxSize(52,24), wxTE_CENTRE,0,500,0,_T("Klatt fric amp"));
t_klatt[KLATT_Fric] = new wxStaticText(this,-1,_T("Fric"),wxPoint(159,y+4));

s_klatt[KLATT_FricBP] = new wxSpinCtrl(this,T_FRICBP,_T(""), wxPoint(202,y), wxSize(52,24), wxTE_CENTRE,0,500,0,_T("Klatt fric bandwidth"));
t_klatt[KLATT_FricBP] = new wxStaticText(this,-1,_T("FricBP"),wxPoint(257,y+4));

y += 28;
s_klatt[KLATT_Kopen] = new wxSpinCtrl(this,T_KOPEN,_T(""), wxPoint(6,y), wxSize(52,24), wxTE_CENTRE,0,500,0,_T("Klatt KOpen"));
t_klatt[KLATT_Kopen] = new wxStaticText(this,-1,_T("kopen"),wxPoint(61,y+4));

s_klatt[KLATT_Turb] = new wxSpinCtrl(this,T_TURB,_T(""), wxPoint(104,y), wxSize(52,24), wxTE_CENTRE,0,500,0,_T("Klatt turbulence"));
t_klatt[KLATT_Turb] = new wxStaticText(this,-1,_T("Turb"),wxPoint(159,y+4));



t_zoomout = new wxButton(this,T_ZOOMOUT,_T("Zoom-"),wxPoint(16,y2));
t_zoomin = new wxButton(this,T_ZOOMIN,_T("Zoom+"),wxPoint(106,y2));

y = y2 + 46;
t_amplitude = new wxSpinCtrl(this,T_AMPLITUDE,_T(""),
wxPoint(6,y),wxSize(52,24),wxTE_CENTRE,0,y+130,0,_T("Sequence amp"));
t_lab[2] = new wxStaticText(this,-1,_T("% amp - Sequence"),wxPoint(61,y+4));
// t_timeseq = new wxSpinCtrl(this,T_TIMESEQ,_T(""),
// wxPoint(6,400),wxSize(52,24),wxTE_CENTRE,0,500);
t_orig_seq = new wxStaticText(this,-1,_T("mS"),wxPoint(61,y+30));

t_pitch = new wxStaticText(this,-1,_T(""),wxPoint(4,y3),wxSize(192,24));

pitchgraph = new ByteGraph(this,wxPoint(0,y3+18),wxSize(200,140));
pitchgraph->SetData(128,env_fall);
pitchgraph->ShowSpectrum(1);
pitchgraph->Show();
}



void FormantDlg::GetValues(SpectSeq *spectseq, int frame)
{//======================================================
int ix;
wxString value;
long num;
SpectFrame *sf;

if(spectseq->frames == NULL)
return;
sf = spectseq->frames[frame];

if(use_spin_controls == 0)
{
formantdlg->tt_timeframe->GetValue().ToLong(&num);
sf->length_adjust = num - spectseq->GetFrameLength(frame,0,NULL);
}

for(ix=0; ix < 8; ix++)
{
if(ix < 7)
{
num = 0;
value = t_pkfreq[ix]->GetValue();
value.ToLong(&num);
sf->peaks[ix].pkfreq = num;
}

num = 0;
value = t_pkheight[ix]->GetValue();
value.ToLong(&num);
sf->peaks[ix].pkheight = num << 6;

if(ix < 6)
{
num = 0;
value = t_pkwidth[ix]->GetValue();
value.ToLong(&num);
sf->peaks[ix].pkwidth = sf->peaks[ix].pkright = num*2;

if((ix < 3) && ((value = value.AfterFirst('/')) != wxEmptyString))
{
num = 0;
value.ToLong(&num);
sf->peaks[ix].pkright = num*2;
}
}
}

for(ix=1; ix < 7; ix++)
{
if(ix < 4)
{
num = 0;
value = t_klt_bw[ix]->GetValue();
value.ToLong(&num);
sf->peaks[ix].klt_bw = num;
}

num = 0;
value = t_klt_ap[ix]->GetValue();
value.ToLong(&num);
sf->peaks[ix].klt_ap = num;

num = 0;
value = t_klt_bp[ix]->GetValue();
value.ToLong(&num);
sf->peaks[ix].klt_bp = num;
}
} // end of FormantDlg::GetValues



void FormantDlg::ShowFrame(SpectSeq *spectseq, int frame, int pk, int field)
{//==============================================================
int ix;
SpectFrame *sf;
wxString value;
int original_mS;
peak_t *peak;

if(spectseq->frames == NULL)
return;
sf = spectseq->frames[frame];

if(field == 0xff)
{
// indicate the selected peak
// t_select_peak[pk]->SetValue(TRUE);
}

for(ix=0; ix < 8; ix++)
{
if(field != 0xff && pk!=ix)
continue;

if(field == 0xff)
{
if(pk==ix)
value.Printf(_T("%d="),ix);
else
value.Printf(_T("%d"),ix);
t_labpk[ix]->SetLabel(value);
}

peak = &(sf->peaks[ix]);

if((field & 1) && (ix < 7))
{
value.Printf(_T("%4d"),sf->peaks[ix].pkfreq);
t_pkfreq[ix]->SetValue(value);
}
if(field & 2)
{
value.Printf(_T("%3d"),sf->peaks[ix].pkheight >> 6);
t_pkheight[ix]->SetValue(value);
}
if((field & 4) && (ix < 6))
{
if(sf->peaks[ix].pkwidth == sf->peaks[ix].pkright)
value.Printf(_T("%3d"),sf->peaks[ix].pkwidth/2);
else
value.Printf(_T("%3d/%3d"),sf->peaks[ix].pkwidth/2, sf->peaks[ix].pkright/2);
t_pkwidth[ix]->SetValue(value);
}

if((ix > 0) && (ix < 7))
{
if((field & 8) && (ix < 4))
{
value.Printf(_T("%3d"),peak->klt_bw);
t_klt_bw[ix]->SetValue(value);
}

if(field & 16)
{
value.Printf(_T("%3d"),peak->klt_ap);
t_klt_ap[ix]->SetValue(value);
}

if(field & 32)
{
value.Printf(_T("%3d"),peak->klt_bp);
t_klt_bp[ix]->SetValue(value);
}
}
}

// find the time until the next keyframe
value.Printf(_T("%d"),int(spectseq->GetFrameLength(frame,1,&original_mS)+0.5)); // round to nearest integer

if(use_spin_controls)
t_timeframe->SetValue(value);
else
tt_timeframe->SetValue(value);

value.Printf(_T("%d mS"),original_mS);
t_orig_frame->SetLabel(value);
value.Printf(_T("%3d"),sf->amp_adjust);
t_ampframe->SetValue(value);

for(ix=0; ix<N_KLATTP; ix++)
{
SetSpinCtrl(s_klatt[ix], sf->klatt_param[ix]);
}

} // end of FormantDlg::ShowFrame


BEGIN_EVENT_TABLE(ByteGraph,wxScrolledWindow)
EVT_LEFT_DOWN(ByteGraph::OnMouse)
END_EVENT_TABLE()

static wxBrush BRUSH_FORMANT(wxColour(255,100,50),wxSOLID);
static wxPen PEN_KEYFRAME(wxColour(255,220,100),2,wxSOLID);
static wxPen PEN_KEYFORMANT(wxColour(0,0,0),2,wxSOLID);


ByteGraph::ByteGraph(wxWindow *parent, const wxPoint& pos, const wxSize &size):
wxScrolledWindow(parent,-1,pos,size,wxSUNKEN_BORDER)
{//============================================================
npoints = 0;
show_spectrum = 0;
} // end of ByteGraph::ByteGraph


void ByteGraph::SetData(int nx, unsigned char *data)
{//=================================================
npoints = nx;
graph = data;
Refresh();
} // end of ByteGraph::SetData


void ByteGraph::ShowSpectrum(int yes)
{//==================================
show_spectrum = yes;
}


void ByteGraph::DrawSpectrum(wxDC& dc)
{//===================================
SpectSeq *seq;
SpectFrame *sf;
int ix;
int x, y;
int pk;
double length;
int numframes;
int width, height;
double xscale, yscale;

spectrum_scale = 0;
if(currentcanvas==NULL) return;
if((seq = currentcanvas->spectseq) == NULL) return;
numframes = seq->numframes;

if(numframes == 0) return;

GetClientSize(&width,&height);

if(((length = seq->frames[numframes-1]->time)==0) && (numframes>1))
length = seq->frames[numframes-2]->time;

length = length - seq->frames[0]->time;

yscale = height/3000.0;
spectrum_scale = xscale = width/length;

dc.SetBrush(BRUSH_FORMANT);
dc.SetPen(*wxTRANSPARENT_PEN);
for(ix=0; ix<numframes; ix++)
{
sf = seq->frames[ix];
x = int(sf->time*xscale);

if(sf->keyframe)
{
dc.SetPen(PEN_KEYFRAME);
dc.DrawLine(x,0,x,height);
}

dc.SetPen(*wxTRANSPARENT_PEN);
dc.DrawCircle(x,int(height-(sf->formants[1].freq-200)*yscale),3);
dc.DrawCircle(x,int(height-(sf->formants[2].freq-200)*yscale),3);
dc.DrawCircle(x,int(height-(sf->formants[3].freq-200)*yscale),3);

if(sf->keyframe)
{
dc.SetPen(PEN_KEYFORMANT);
for(pk=1; pk<6; pk++)
{
y = height-int((sf->peaks[pk].pkfreq-200)*yscale);
dc.DrawLine(x-3,y,x+3,y);
}
}
}
}


void ByteGraph::OnDraw(wxDC &dc)
{//============================
int x, y, x2, y2, ix;
int width, height;
double xscale, yscale;

if(show_spectrum) DrawSpectrum(dc);

if(npoints==0) return;

GetClientSize(&width,&height);

xscale = double(width) / npoints;
yscale = double(height) / 256.0;

if(npoints > 8)
{
// draw pitch profile
dc.SetPen(*wxMEDIUM_GREY_PEN);
x = 0;
y = height - int(graph[0]*yscale);
for(ix=1; ix<npoints; ix++)
{
dc.DrawLine(x,y,x2=int(ix*xscale),y2=height - int(graph[ix]*yscale));
x = x2;
y = y2;
}
}
} // end of ByteGraph::OnDraw


void ByteGraph::OnMouse(wxMouseEvent& event)
{//========================================
int ix;
SpectSeq *seq;
double time;
double t0, t1;
double t2=0;

if(currentcanvas==NULL) return;
if((seq = currentcanvas->spectseq) == NULL) return;

wxClientDC dc(this);
PrepareDC(dc);

wxPoint pt(event.GetLogicalPosition(dc));
t0 = t2 = seq->frames[0]->time;
time = (double(pt.x) / spectrum_scale) + t0;

for(ix=1; ix<seq->numframes; ix++)
{
t1=t2;
t2 = seq->frames[ix]->time;
if(time <= t1 + (t2-t1)/2)
{
currentcanvas->SelectFrame(ix-1);
break;
}
}
} // end of ByteGraph::OnMouse


+ 0
- 190
src/main.h View File

@@ -1,190 +0,0 @@

#include "wx/toolbar.h"
#include "wx/laywin.h"
#include "wx/progdlg.h"
#include "wx/notebook.h"

typedef unsigned short USHORT;
typedef unsigned char UCHAR;



extern wxMenuBar *MakeMenu(int type, const char *dict_name);

extern wxString path_phsource;
extern wxString path_speaktext;
extern wxString path_speech;
extern wxProgressDialog *progress;
extern int progress_max;
extern int gui_flag;

extern char *WavFileName();
extern char voice_name2[40];

class SpectDisplay;


// Define a new application
class MyApp: public wxApp
{
public:
bool OnInit(void);
int OnExit(void);
};

// Define a new frame
class MyFrame: public wxFrame
{
public:

MyFrame(wxWindow *parent, const wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, const long style);
~MyFrame(void);


void OnAbout(wxCommandEvent& event);
void OnQuit(wxCommandEvent& event);
void OnOptions(wxCommandEvent& event);
void OnSpeak(wxCommandEvent& event);
void OnTools(wxCommandEvent& event);
void OnKey(wxKeyEvent& event);
void OnTimer(wxTimerEvent& event);
void LoadWavFile(void);

void OnNewWindow(wxCommandEvent& event);
void OnProsody(wxCommandEvent& event);
void PageCmd(wxCommandEvent& event);
void SetVoiceTitle(char *voice_name);
void OnPageChanged(wxNotebookEvent& event);

protected:
wxTimer m_timer;

DECLARE_EVENT_TABLE()
};


#ifdef deleted
class MyChild: public wxPanel
{
public:
SpectDisplay *canvas;
MyChild(wxNotebook *parent, const wxString& title, const wxPoint& pos, const wxSize& size, const long style);
~MyChild(void);
void OnActivate(wxActivateEvent& event);

void OnQuit(wxCommandEvent& event);
void OnSave(wxCommandEvent& event);
void OnSaveAs(wxCommandEvent& event);
void OnSaveSelect(wxCommandEvent& event);
void OnSavePitchenv(wxCommandEvent& event);
// void OnVoiceDlg(wxCommandEvent& event);

DECLARE_EVENT_TABLE()
};
#endif


class TranslDlg : public wxPanel
{//=============================
public:
TranslDlg(wxWindow *parent);

void OnKey(wxKeyEvent& event);
void SpeakFile(void);
void ReadVoice(int variant);
void OnCommand(wxCommandEvent& event);
wxTextCtrl* t_source;

private:
wxButton *t_translate;
wxButton *t_process;
wxTextCtrl* t_phonetic;


DECLARE_EVENT_TABLE()
};

extern MyFrame *myframe;
extern wxNotebook* screenpages;
extern TranslDlg *transldlg;
extern wchar_t ipa1[256];


enum {
MENU_QUIT = 1,
MENU_OPEN,
MENU_SPECTRUM,
MENU_SPECTRUM2,
MENU_CLOSE_ALL,
MENU_ABOUT,
MENU_DOCS,

MENU_OPTIONS,
MENU_OPT_SPEED,
MENU_OPT_PUNCT,
MENU_OPT_SPELL,
MENU_OPT_SPELL2,
MENU_PATHS,
MENU_PATH_DATA,
MENU_PATH0,
MENU_PATH1,
MENU_PATH2,
MENU_PATH3,
MENU_PATH4,

MENU_PROSODY,
MENU_COMPILE_PH,
MENU_COMPILE_PH2,
MENU_COMPILE_DICT,
MENU_COMPILE_DICT_DEBUG,
MENU_FORMAT_DICTIONARY,
MENU_SORT_DICTIONARY,
MENU_COMPILE_MBROLA,
MENU_COMPILE_INTONATION,

MENU_SPEAK_TRANSLATE,
MENU_SPEAK_RULES,
MENU_SPEAK_IPA,
MENU_SPEAK_TEXT,
MENU_SPEAK_FILE,
MENU_SPEAK_PAUSE,
MENU_SPEAK_STOP,
MENU_SPEAK_VOICE,
MENU_SPEAK_VOICE_VARIANT,
MENU_LOAD_WAV,

MENU_VOWELCHART,
MENU_VOWELCHART1,
MENU_VOWELCHART2,
MENU_VOWELCHART3,
MENU_LEXICON,
MENU_LEXICON_RU,
MENU_LEXICON_BG,
MENU_LEXICON_DE,
MENU_LEXICON_IT,
MENU_LEXICON_TEST,
MENU_TO_UTF8,
MENU_COUNT_WORDS,
MENU_TEST,
MENU_TEST2,

SPECTSEQ_CLOSE,
SPECTSEQ_SAVE,
SPECTSEQ_SAVEAS,
SPECTSEQ_SAVESELECT,
SPECTSEQ_SAVEPITCH,
SPECTSEQ_VOICEDLG,

ID_SCREENPAGES,
ID_NOTEBOOK
};


// wxWidgets 3 name changes
#if wxCHECK_VERSION(3, 0, 0)
#define wxOPEN wxFD_OPEN
#define wxSAVE wxFD_SAVE
#define WXK_PRIOR WXK_PAGEUP
#define WXK_NEXT WXK_PAGEDOWN
#endif


+ 0
- 174
src/menus.cpp View File

@@ -1,174 +0,0 @@
/***************************************************************************
* Copyright (C) 2005 to 2013 by Jonathan Duddington *
* email: [email protected] *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 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 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 "wx/wx.h"

#include "main.h"

wxMenu *speak_menu;
wxMenu *data_menu = NULL;
wxMenuBar *menu_bar = NULL;


wxMenuBar *MakeMenu(int type, const char *dict_name)
{//===================================================
char buf[100];
wxMenu *old_menu;
wxMenu *file_menu;
wxMenu *help_menu;
wxMenu *option_menu = NULL;
wxMenu *paths_menu;
wxMenu *tools_menu;
wxMenu *voice_menu;
wxMenu *vowelchart_menu;
wxMenu *lexicon_menu;

// FILE MENU
file_menu = new wxMenu;
file_menu->Append(MENU_SPECTRUM, _("&Open..."));
file_menu->Append(MENU_SPECTRUM2, _("O&pen2..."));
// file_menu->Append(MENU_PROSODY, _T("&Prosody window"));
if(type<=1)
{
}
else
if(type==2)
{
file_menu->Append(SPECTSEQ_SAVE, _("&Save"));
file_menu->Append(SPECTSEQ_SAVEAS, _("Save &As..."));
file_menu->Append(SPECTSEQ_SAVESELECT, _("Save Selection"));
file_menu->Append(SPECTSEQ_SAVEPITCH, _T("Save Pitch &Envelope"));
file_menu->Append(SPECTSEQ_CLOSE, _("&Close"));
file_menu->Append(MENU_CLOSE_ALL, _T("Close &All"));
}
else
if(type==3)
{
// file_menu->Append(SPECTSEQ_SAVE, _("&Save"));
// file_menu->Append(SPECTSEQ_SAVEAS, _("Save &As..."));
file_menu->Append(SPECTSEQ_CLOSE, _("&Close"));
file_menu->Append(MENU_CLOSE_ALL, _T("Close &All"));
}
file_menu->Append(MENU_QUIT, _("&Quit"));

if(type==0)
{
// Initialization, make all the menus
// SPEAK_MENU
speak_menu = new wxMenu;
speak_menu->Append(MENU_SPEAK_TRANSLATE, _("&Translate"));
speak_menu->Append(MENU_SPEAK_RULES, _("Show &Rules"));
speak_menu->Append(MENU_SPEAK_IPA, _("Show &IPA"));
speak_menu->Append(MENU_SPEAK_TEXT, _("&Speak"));
speak_menu->AppendSeparator();
speak_menu->Append(MENU_SPEAK_FILE, _("Speak &file..."));
speak_menu->Append(MENU_SPEAK_PAUSE, _("&Pause"));
speak_menu->Append(MENU_SPEAK_STOP, _("St&op"));

// VOICE MENU
voice_menu = new wxMenu;
voice_menu->Append(MENU_SPEAK_VOICE, _("Select &Voice.."));
voice_menu->Append(MENU_SPEAK_VOICE_VARIANT, _("Select Voice Va&riant..."));

// DATA MENU
data_menu = new wxMenu;
data_menu->Append(MENU_COMPILE_DICT, _("Compile &dictionary"));
data_menu->Append(MENU_COMPILE_DICT_DEBUG, _("Compile dictionary (debu&g)"));
data_menu->Append(MENU_COMPILE_PH, _("Compile &phoneme data 22050Hz"));
data_menu->Append(MENU_COMPILE_PH2, _("Compile at sample &rate"));
data_menu->AppendSeparator();
data_menu->Append(MENU_COMPILE_MBROLA, _("Compile &mbrola phonemes list..."));
data_menu->Append(MENU_COMPILE_INTONATION, _("Compile &intonation data"));
data_menu->AppendSeparator();
data_menu->Append(MENU_FORMAT_DICTIONARY, _("&Layout *_rules file"));
data_menu->Append(MENU_SORT_DICTIONARY, _("&Sort *_rules file"));

sprintf(buf,"Compile &dictionary '%s'",dict_name);
data_menu->SetLabel(MENU_COMPILE_DICT, wxString(buf,wxConvLocal));
sprintf(buf,"&Layout '%s_rules' file",dict_name);
data_menu->SetLabel(MENU_FORMAT_DICTIONARY, wxString(buf,wxConvLocal));
sprintf(buf,"&Sort '%s_rules' file",dict_name);
data_menu->SetLabel(MENU_SORT_DICTIONARY, wxString(buf,wxConvLocal));

// OPTIONS MENU
paths_menu = new wxMenu;
paths_menu->Append(MENU_PATH0, _("Master phonemes file..."));
paths_menu->Append(MENU_PATH1, _("Phoneme data source..."));
paths_menu->Append(MENU_PATH2, _("Dictionary data source..."));
paths_menu->Append(MENU_PATH3, _("Synthesized sound WAV file..."));
paths_menu->AppendSeparator();
paths_menu->Append(MENU_PATH4, _("Voice file to modify formant peaks..."));

option_menu = new wxMenu;
option_menu->Append(MENU_PATHS, _("Set &paths"), paths_menu);
option_menu->Append(MENU_OPT_SPEED, _("Speed..."));
option_menu->AppendSeparator();
option_menu->Append(MENU_OPT_PUNCT, _("Speak punctuation"));
option_menu->Append(MENU_OPT_SPELL, _("Speak characters"));
option_menu->Append(MENU_OPT_SPELL2, _("Speak character name"));

// TOOLS
vowelchart_menu = new wxMenu;
vowelchart_menu->Append(MENU_VOWELCHART1, _("From compiled phoneme data"));
// vowelchart_menu->Append(MENU_VOWELCHART2, _("From list of formants..."));
vowelchart_menu->Append(MENU_VOWELCHART3, _("From directory of vowel files..."));

lexicon_menu = new wxMenu;
lexicon_menu->Append(MENU_LEXICON_RU, _("Russian"));
lexicon_menu->Append(MENU_LEXICON_BG, _("Bulgarian"));
lexicon_menu->Append(MENU_LEXICON_DE, _("German"));
lexicon_menu->Append(MENU_LEXICON_IT, _("Italian"));
// lexicon_menu->Append(MENU_LEXICON_TEST, _("Test"));

tools_menu = new wxMenu;
tools_menu->Append(MENU_VOWELCHART, _("Make &Vowels Chart"), vowelchart_menu);
// tools_menu->Append(MENU_LOAD_WAV, _T("Analyse WAV file"));
tools_menu->Append(MENU_LEXICON, _("Process &Lexicon"), lexicon_menu);
tools_menu->Append(MENU_TO_UTF8, _("Convert file to &UTF8..."));
tools_menu->Append(MENU_COUNT_WORDS, _("Count word &frequencies..."));
tools_menu->Append(MENU_TEST , _("Test (temporary)"));
// tools_menu->Append(MENU_TEST2 , _T("Test2"));

// HELP MENU
help_menu = new wxMenu;
help_menu->Append(MENU_DOCS, _("eSpeak &Documentation"));
help_menu->Append(MENU_ABOUT, _("&About"));


menu_bar = new wxMenuBar;

menu_bar->Append(file_menu, _("&File"));
menu_bar->Append(speak_menu, _("&Speak"));
menu_bar->Append(voice_menu, _("&Voice"));
menu_bar->Append(option_menu, _("&Options"));
menu_bar->Append(tools_menu, _("&Tools"));
menu_bar->Append(data_menu, _("&Compile"));
menu_bar->Append(help_menu, _("&Help"));
}
else
{
// Just replace the File menu
old_menu = menu_bar->Replace(0, file_menu, _("&File"));
delete old_menu;
}
return(menu_bar);
} // end of MakeMenu



+ 1
- 108
src/options.cpp View File

@@ -29,86 +29,20 @@
#include "wx/msw/registry.h"
#endif

#include "main.h"

#include "options.h"

extern "C" void WavegenInit(int samplerate, int wavemult_fact);
extern void strncpy0(char *to,const char *from, int size);
extern int GetNumeric(wxTextCtrl *t);
extern void SetNumeric(wxTextCtrl *t, int value);
extern int samplerate;

wxString path_espeakdata;
wxString path_spectload;
wxString path_spectload2;
wxString path_pitches;
wxString path_wave;
wxString path_speech;
wxString path_phfile;
wxString path_phsource;
wxString path_dictsource;
wxString path_speaktext;
wxString path_modifiervoice;
wxString path_dir1;
int option_speed=160;

char path_source[sizeof(path_home)+20];
char path_dsource[sizeof(path_home)+20];
char voice_name2[40];

BEGIN_EVENT_TABLE(Options, wxDialog)
EVT_BUTTON(wxID_SAVE,Options::OnCommand)
EVT_BUTTON(wxID_CLOSE,Options::OnCommand)
END_EVENT_TABLE()


Options::Options(wxWindow *parent) : wxDialog(parent,-1,_T("Options"),wxDefaultPosition,wxDefaultSize)
{//===================================================================================================

m_lab[0] = new wxStaticText(this,-1,_T("Sample rate"),wxPoint(72,84));
m_samplerate = new wxTextCtrl(this,-1,_T(""),wxPoint(8,80),wxSize(60,24));
SetNumeric(m_samplerate,samplerate);

m_save = new wxButton(this,wxID_SAVE,_T("Save"),wxPoint(8,120));
m_close = new wxButton(this,wxID_CLOSE,_T("Cancel"),wxPoint(98,120));
Show();
}


Options::~Options()
{//================
int ix;

for(ix=0; ix < 1; ix++)
delete m_lab[ix];

delete m_samplerate;
delete m_save;
delete m_close;
}

void Options::OnCommand(wxCommandEvent& event)
{//===========================================
int id;
int value;

switch(id = event.GetId())
{
case wxID_SAVE:
value = GetNumeric(m_samplerate);
if(value > 0) WavegenInit(value,0);

Destroy();
break;

case wxID_CLOSE:
Destroy();
break;
}
}



void ConfigSetPaths()
{//==================
// set c_string paths from wxStrings
@@ -188,53 +122,12 @@ void ConfigInit(bool use_defaults)
pConfig->Read(_T("/spectload"),&path_spectload,basedir+_T("/phsource"));
pConfig->Read(_T("/spectload2"),&path_spectload2,basedir+_T("/phsource"));
pConfig->Read(_T("/pitchpath"),&path_pitches,basedir+_T("/pitch"));
pConfig->Read(_T("/wavepath"),&path_wave,wxEmptyString);
pConfig->Read(_T("/speechpath"),&path_speech,wxEmptyString);
pConfig->Read(_T("/voicename"),&string,wxEmptyString);
strcpy(voice_name2,string.mb_str(wxConvLocal));
pConfig->Read(_T("/phsource"),&path_phsource,basedir+_T("/phsource"));
pConfig->Read(_T("/phfile"),&path_phfile,path_phsource+_T("/phonemes"));
pConfig->Read(_T("/dictsource"),&path_dictsource,basedir+_T("/dictsource"));
pConfig->Read(_T("/speaktext"),&path_speaktext,wxEmptyString);
pConfig->Read(_T("/modifiervoice"),&path_modifiervoice,basedir);
pConfig->Read(_T("/dir1"),&path_dir1,basedir);
option_speed = pConfig->Read(_T("/speed"),160);
frame_x = pConfig->Read(_T("/windowx"), 0l);
frame_y = pConfig->Read(_T("/windowy"), 0l);
frame_h = pConfig->Read(_T("/windowh"), 0l);
frame_w = pConfig->Read(_T("/windoww"), 0l);
}
ConfigSetPaths();
} // end of ConfigInit



void ConfigSave(int exit)
{//======================
wxFileConfig *pConfig = (wxFileConfig *)(wxConfigBase::Get());


#ifndef PLATFORM_WINDOWS
// pConfig->Write(_T("/samplerate"),samplerate);
#endif
pConfig->Write(_T("/espeakdata"),path_espeakdata);
pConfig->Write(_T("/spectload"),path_spectload);
pConfig->Write(_T("/spectload2"),path_spectload2);
pConfig->Write(_T("/pitchpath"),path_pitches);
pConfig->Write(_T("/wavepath"),path_wave);
pConfig->Write(_T("/speechpath"),path_speech);
pConfig->Write(_T("/voicename"),wxString(voice_name2,wxConvLocal));
pConfig->Write(_T("/phsource"),path_phsource);
pConfig->Write(_T("/phfile"),path_phfile);
pConfig->Write(_T("/dictsource"),path_dictsource);
pConfig->Write(_T("/speaktext"),path_speaktext);
pConfig->Write(_T("/speed"),option_speed);
pConfig->Write(_T("/modifiervoice"),path_modifiervoice);
pConfig->Write(_T("/dir1"),path_dir1);
pConfig->Write(_T("/windowx"),frame_x);
pConfig->Write(_T("/windowy"),frame_y);
pConfig->Write(_T("/windoww"),frame_w);
pConfig->Write(_T("/windowh"),frame_h);
if(exit)
delete wxFileConfig::Set((wxFileConfig *)NULL);
}

+ 0
- 71
src/options.h View File

@@ -1,71 +0,0 @@
/***************************************************************************
* Copyright (C) 2005 to 2007 by Jonathan Duddington *
* email: [email protected] *
* Copyright (C) 2013 by Reece H. Dunn *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 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 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/>. *
***************************************************************************/

#ifndef OPTIONS_H
#define OPTIONS_H

#include "wx/dialog.h"
#include "wx/spinctrl.h"

/**
*@author Jonathan Duddington
*/

extern void ConfigInit(bool use_defaults);
extern void ConfigSave(int end);
extern void ConfigSetPaths();

extern wxString path_espeakdata;
extern wxString path_spectload;
extern wxString path_spectload2;
extern wxString path_pitches;
extern wxString path_phfile;
extern wxString path_phsource;
extern wxString path_dictsource;
extern wxString path_modifiervoice;
extern wxString path_dir1;
extern int frame_x, frame_y, frame_w, frame_h;

extern char path_source[sizeof(path_home)+20];
extern char path_dsource[sizeof(path_home)+20];

extern int option_speed;

extern void OnOptions2(int event_id);

// not currently used
class Options : public wxDialog {
public:
Options(wxWindow *parent);
~Options();

private:
void OnCommand(wxCommandEvent& event);

wxButton *m_save;
wxButton *m_close;
wxStaticText *m_lab[10];

wxTextCtrl *m_samplerate;

DECLARE_EVENT_TABLE()
};

#endif

+ 0
- 601
src/prosodydisplay.cpp View File

@@ -24,36 +24,11 @@
#include "wx/numdlg.h"

#include "speak_lib.h"
#include "main.h"
#include "speech.h"
#include "phoneme.h"
#include "synthesize.h"
#include "prosodydisplay.h"
#include "translate.h"

extern MyFrame *myframe;
extern ProsodyDisplay *prosodycanvas;

wxMenu *menu_prosody;


BEGIN_EVENT_TABLE(ProsodyDisplay, wxScrolledWindow)
EVT_LEFT_DOWN(ProsodyDisplay::OnMouse)
EVT_RIGHT_DOWN(ProsodyDisplay::OnMouse)
EVT_CHAR(ProsodyDisplay::OnKey)
EVT_MENU(-1, ProsodyDisplay::OnMenu)
END_EVENT_TABLE()


static wxPen PEN_PITCHENV(wxColour(0,0,255),1,wxSOLID);
static wxPen PEN_SAMPLED(wxColour(0,200,200),2,wxSOLID);
static wxPen PEN_PHSELECTED(wxColour(255,0,0),2,wxSOLID);
static wxPen PEN_PHSTRESSED(wxColour(80,80,196),3,wxSOLID);
static wxPen PEN_PHSTRESSED2(wxColour(160,160,255),2,wxSOLID);




typedef struct {
unsigned int value;
char *name;
@@ -131,579 +106,3 @@ void ReadPhondataManifest()
}
fclose(f);
}



ProsodyDisplay::ProsodyDisplay(wxWindow *parent, const wxPoint& pos, const wxSize& size)
: wxScrolledWindow(parent, -1, pos, size,
wxSUNKEN_BORDER | wxNO_FULL_REPAINT_ON_RESIZE)
{//=====================================================================

linewidth = size.GetWidth();
scalex = 0.5;
scaley = double(LINESEP*6)/150.0;
selected_ph = -1;
SetBackgroundColour(wxColour(245,245,245));
} // end of ProsodyDisplay::ProsodyDisplay


ProsodyDisplay::~ProsodyDisplay()
{//==========================
prosodycanvas = NULL;
}

extern MNEM_TAB envelope_names[];

void InitProsodyDisplay()
{//======================
wxMenu *menu_envelopes;
int ix;
wxString string;

ReadPhondataManifest();
menu_envelopes = new wxMenu;
// entries match those in envelope_data[] in intonation.cpp

for(ix=0; envelope_names[ix].mnem != NULL; ix++)
{
string = wxString(envelope_names[ix].mnem, wxConvLocal);
menu_envelopes->Append(0x100+envelope_names[ix].value, string);
}
menu_prosody = new wxMenu;
menu_prosody->Append(1,_T("Pitch envelope"),menu_envelopes);
menu_prosody->Append(2,_T("Amplitude"));
menu_prosody->Append(3,_T("Length"));
menu_prosody->Append(4,_T("Play F2"));
}


void ProsodyDisplay::RefreshLine(int line)
{//=====================================
int x,y;

CalcScrolledPosition(0,line*FRAMEHEIGHT,&x,&y);
RefreshRect(wxRect(0,y,linewidth,FRAMEHEIGHT));
}


int ProsodyDisplay::GetWidth(PHONEME_LIST *p)
{//========================================
int w;

if(p->ph == NULL)
return(0);

w = (p->ph->std_length * 2);
if(w == 0) w = 60;

if(p->length != 0)
w = (w * p->length) / 256;

return(int((w + p->prepause)* scalex) + 1);
}


void ProsodyDisplay::SelectPh(int index)
{//=====================================
// A phoneme has been selected
PHONEME_LIST *p;
const char *emphasized;
int y1, y2;
int ix;
const char *name = "?";
char buf[120];
char len_string[20];
char param_string[20];

if(index < 0) return;

p = &phlist[index];
if((p == NULL) || (p->ph == NULL)) return;

emphasized = "";
if(p->stresslevel & 8)
emphasized = "*";

for(ix=0; envelope_names[ix].mnem != NULL; ix++)
{
if(envelope_names[ix].value == (p->env & 0xfe))
{
name = envelope_names[ix].mnem;
break;
}
}
y1 = p->pitch1;
y2 = p->pitch2;
len_string[0] = 0;
param_string[0] = 0;
if(p->std_length > 0)
sprintf(len_string," Length %d", p->std_length*2);
if(p->sound_param != 0)
sprintf(param_string,", %d", p->sound_param);

sprintf(buf,"Stress %s%d Amp %2d LengthMod %2d Pitch %3d %3d %s PhFlags %.2x (%s%s)%s",
emphasized,p->stresslevel&0x7,p->amp, p->length,y1,y2,name,p->ph->phflags, LookupManifest(p->phontab_addr), param_string, len_string);
wxLogStatus(wxString(buf,wxConvLocal));
}


void ProsodyDisplay::ChangePh(int pitch1, int pitch2)
{//================================================
PHONEME_LIST *p;
int sign1;
int sign2;

if(selected_ph < 0)
return;

p = &phlist[selected_ph];
sign1 = p->pitch1 - p->pitch2;
p->pitch1 += pitch1;
p->pitch2 += (pitch1 + pitch2);
sign2 = p->pitch1 - p->pitch2;

if((sign1 != 0) && ((sign1 * sign2) <= 0))
{
// change of sign, change rise to fall
if(p->env == 1)
p->env = 0;
else
if(p->env == 0)
p->env = 1;
}
}


void ProsodyDisplay::OnMenu(wxCommandEvent& event)
{//===============================================
int id;
int value;
PHONEME_LIST *p;

id = event.GetId();
p = &phlist[selected_ph];

if((id & 0xf00) == 0x100)
{
// selected a pitch envelope
p->env = id - 0x100;
}

switch(id)
{
case 2:
value = wxGetNumberFromUser(_T(""),_T("Amplitude"),_T(""),p->amp,0,40);
if(value >= 0)
p->amp = value;
break;
case 3:
value = wxGetNumberFromUser(_T(""),_T("Length"),_T(""),p->length,1,500);
if(value >= 0)
p->length = value;
break;
case 4:
MakeWave2(phlist,numph);
break;
}
SelectPh(selected_ph);
Refresh();
}


void ProsodyDisplay::OnMouse(wxMouseEvent& event)
{//============================================
int line;
int ix;
int xpos=0;


wxClientDC dc(this);
PrepareDC(dc);
wxPoint pt(event.GetLogicalPosition(dc));

if(selected_ph >= 0)
{
// find line for previously selected phoneme
for(line=0; line<num_lines; line++)
if(linetab[line+1] > selected_ph) break;
RefreshLine(line);
selected_ph = -1;
}

line = pt.y / FRAMEHEIGHT;

if(line < num_lines)
{
// find which phoneme is selected on this line
for(ix=linetab[line]; (ix<linetab[line+1]) && (ix<numph); ix++)
{
xpos += GetWidth(&phlist[ix]);
if(xpos > pt.x)
{
selected_ph = ix;
SelectPh(selected_ph);
break;
}
}

RefreshLine(line);
}

if(event.RightDown())
{
PopupMenu(menu_prosody);
}

} // end of ProsodyDisplay::OnMouse


void ProsodyDisplay::OnKey(wxKeyEvent& event)
{//========================================
PHONEME_LIST *p;
int display=1;

if(selected_ph < 0)
selected_ph = 0;

p = &phlist[selected_ph];

switch(event.GetKeyCode())
{
case WXK_F2:
// make and play from this clause
MakeWave2(phlist,numph);
break;

case WXK_LEFT:
if(selected_ph > 1)
selected_ph--;
break;

case WXK_RIGHT:
if(selected_ph < (numph-2))
selected_ph++;
break;

case WXK_UP:
if(event.ControlDown())
ChangePh(-1,2);
else
ChangePh(1,0);
display = 1;
break;

case WXK_DOWN:
if(event.ControlDown())
ChangePh(1,-2);
else
ChangePh(-1,0);
break;

case ',':
case '<':
if(p->length > 0)
p->length--;
break;

case '.':
case '>':
p->length++;
break;

case WXK_TAB:
display = 0;
event.Skip();
transldlg->SetFocus();
break;

default:
display = 0;
event.Skip();
break;
}

if(display)
{
Refresh();
SelectPh(selected_ph);
}
} // end of ProsodyDisplay::OnKey


void ProsodyDisplay::DrawEnv(wxDC& dc, int x1, int y1, int width, PHONEME_LIST *ph)
{//==============================================================================
int pitchr;
int pitch;
int p1;
int ix;
int x,y;
int y2=0;
unsigned char *env;
PHONEME_DATA phdata_tone;

if(width <= 0) return;

if((pitchr = ph->pitch2 - ph->pitch1) < 0)
{
pitchr = -pitchr;
p1 = ph->pitch2;
}
else
{
p1 = ph->pitch1;
}

if(p1 == 255) return;

dc.SetPen(PEN_PITCHENV);

env = envelope_data[ph->env];
if((ph->type == phVOWEL) && (ph->tone_ph != 0))
{
// the envelope is given by a Tone phoneme acting on this vowel
InterpretPhoneme2(ph->tone_ph, &phdata_tone);
env = GetEnvelope(phdata_tone.pitch_env);
}

if(env == NULL)
return;

for(ix=0; ix<=width; ix+=4)
{
x = int((ix * 127.9)/width);
pitch = p1 + (pitchr * env[x])/256;
y = y1-int(pitch * scaley);
if(ix > 0)
dc.DrawLine(x1+ix-4,y2,x1+ix,y);
y2 = y;
}
} // end of DrawEnv



static void GetPhonemeName(PHONEME_TAB *ph, wxString& string)
{//==========================================================
string = wxString(WordToString(ph->mnemonic),wxConvLocal);
}


void ProsodyDisplay::DrawPitchline(wxDC& dc, int line, int x1, int x2)
{//=================================================================
int ix;
int endix;
int y;
int offy;
int xpos;
int width; // total width, including pre-pause
int width2; // width without pre-pause
int width_env;
int textwidth, textheight;
wxString string;
PHONEME_LIST *p;

if(linetab[line] >= numph) return;

offy = (line+1) * FRAMEHEIGHT - 1;

y = LINEBASE+LINESEP;
dc.SetPen(*wxLIGHT_GREY_PEN);
// dc.SetPen(*wxCYAN_PEN);
for(ix=0; ix<5; ix++)
{
dc.DrawLine(0,offy-y,linewidth,offy-y);
y += LINESEP;
}

endix = linetab[line+1];

xpos = 0;
for(ix=linetab[line]; ix<endix; ix++)
{
if(ix < 0 || ix > numph-2) break;
if(xpos > x2) break; // past the redraw region

p = &phlist[ix];

width = GetWidth(p);
width2 = width - int(p->prepause * scalex) - 1;

if(xpos+width < x1)
{
xpos += width;
continue; // before the redraw region
}

// is this a stressed vowel ?
if((p->type == phVOWEL) && (p->stresslevel >= 2))
{
if(p->stresslevel >= 4)
dc.SetPen(PEN_PHSTRESSED);
else
dc.SetPen(PEN_PHSTRESSED2);
dc.DrawLine(xpos,offy-LINEBASE-1,xpos+width,offy-LINEBASE-1);
}

// is this phoneme selected ?
if(ix == selected_ph)
{
dc.SetPen(PEN_PHSELECTED);
dc.DrawLine(xpos,offy-LINEBASE,xpos+width,offy-LINEBASE);
}

// draw separator bar
if(p->newword)
dc.SetPen(*wxBLACK_PEN); // word boundary
else
dc.SetPen(*wxLIGHT_GREY_PEN);

dc.DrawLine(xpos,offy-LINEBASE,xpos,offy-LINEBASE-LINESEP*6);

// draw pitch envelope
if(((p->ph->phflags & phWAVE) == 0) && (p->ph->type != phPAUSE))
{
if(!(p->synthflags & SFLAG_SEQCONTINUE))
{
width_env = width2;
if(phlist[ix+1].synthflags & SFLAG_SEQCONTINUE)
width_env += GetWidth(&phlist[ix+1]);
DrawEnv(dc,xpos+1+(width-width2),offy-LINEBASE,width_env,p);
}
}
else
if(p->type != phPAUSE)
{
// sampled sound, draw a flat line
dc.SetPen(PEN_SAMPLED);
dc.DrawLine(xpos+1+(width-width2),offy-LINEBASE-LINESEP,
xpos+1+width,offy-LINEBASE-LINESEP);
}

// show phoneme name from the PHONEME_TAB
GetPhonemeName(p->ph,string);
dc.GetTextExtent(string,&textwidth,&textheight);
dc.DrawText(string,xpos+(width-textwidth/2)/2, offy-LINEBASE);

xpos += width;
}

// draw the separator bar at the end of the line
if(ix==endix && ix<numph && phlist[ix].newword)
dc.SetPen(*wxLIGHT_GREY_PEN);
else
dc.SetPen(*wxBLACK_PEN); // word boundary or end of list
dc.DrawLine(xpos,offy-LINEBASE,xpos,offy-LINEBASE-LINESEP*6);

} // end of ProsodyDisplay::DrawPitchline


void ProsodyDisplay::OnDraw(wxDC& dc)
{//================================
int x1,y1;
int vX,vY,vW,vH; // Dimensions of client area in pixels

int line, start, end;

GetClientSize(&x1, &y1);
if(x1 != linewidth)
{
LayoutData(NULL, 0);
}

wxRegionIterator upd(GetUpdateRegion()); // get the update rect list

while (upd)
{
vX = upd.GetX();
vY = upd.GetY();
vW = upd.GetW();
vH = upd.GetH();

CalcUnscrolledPosition(vX,vY,&x1,&y1);

// Repaint this rectangle, find which lines to redraw
start = y1/FRAMEHEIGHT;
end = (y1+vH)/FRAMEHEIGHT;

for(line=start; line<=end && line<num_lines; line++)
DrawPitchline(dc,line,x1,x1+vW);

upd ++ ;
}
} // end of ProsodyDisplay::OnDraw


void ProsodyDisplay::LayoutData(PHONEME_LIST *ph_list, int n_ph)
{//===========================================================
// divide the phoneme list into lines for display
int xpos;
int w;
int ix;
int height;
PHONEME_LIST *p;

if(ph_list != NULL)
{
numph = n_ph;
phlist = ph_list;
}

num_lines = 0;
linetab[0] = 1;
GetClientSize(&linewidth, &height);
xpos = linewidth;

// could improve this to do 'wordwrap' - only split on word boundary
// or unvoiced phonemes

for(ix=1; ix<numph-2; ix++)
{
p = &phlist[ix];
w = GetWidth(p);

if(w + xpos >= linewidth)
{
linetab[num_lines++] = ix;
xpos = 0;
}
xpos += w;
}
linetab[num_lines]=numph-2;

SetScrollbars(SCROLLUNITS,SCROLLUNITS,linewidth/SCROLLUNITS,
(num_lines*FRAMEHEIGHT)/SCROLLUNITS+1);

Refresh();
} // end of ProsodyDisplay::LayoutData


extern int adding_page;

void MyFrame::OnProsody(wxCommandEvent& WXUNUSED(event))
{//=====================================================
// Open the Prosody display window
int width, height;
int ix, npages;

if(prosodycanvas != NULL)
{
// The Prosody window is already open

// ?? select the prosody page ??
npages = screenpages->GetPageCount();
for(ix=0; ix<npages; ix++)
{
if(screenpages->GetPage(ix) == (wxWindow*)prosodycanvas)
{
screenpages->ChangeSelection(ix);
break;
}
}
return;
}


screenpages->GetClientSize(&width, &height);
prosodycanvas = new ProsodyDisplay(screenpages, wxPoint(0, 50), wxSize(width-10, height));
adding_page = 2; // work around for wxNotebook bug (version 2.8.7)
screenpages->AddPage(prosodycanvas, _T("Prosody"), true);
}

+ 0
- 50
src/prosodydisplay.h View File

@@ -1,50 +0,0 @@



#define FRAMEHEIGHT 120
#define LINEBASE 20
#define LINESEP 16

#define SCROLLUNITS 20




class ProsodyDisplay: public wxScrolledWindow
{//========================================
public:
ProsodyDisplay(wxWindow *parent, const wxPoint& pos, const wxSize& size);
~ProsodyDisplay();

virtual void OnDraw(wxDC& dc);
void OnMouse(wxMouseEvent& event);
void OnKey(wxKeyEvent& event);
void OnMenu(wxCommandEvent& event);

void Save(const wxString &path=_T(""));
void LayoutData(PHONEME_LIST *phlist, int n_ph);

private:
void Redraw(wxDC& dc, int x1, int y1, int x2, int y2);
void DrawEnv(wxDC& dc, int x1, int y1, int width, PHONEME_LIST *ph);
void DrawPitchline(wxDC& dc, int line, int x1, int x2);
void RefreshLine(int line);
int GetWidth(PHONEME_LIST *p);
void ChangePh(int pitch1, int pitch2);
void SelectPh(int index);

int linewidth; // height for drawing pitch
double scalex; // scale length values
double scaley; // scale pitch values
int selected_ph;

int numph;
PHONEME_LIST *phlist;
int num_lines;
short linetab[N_PHONEME_LIST/2];

DECLARE_EVENT_TABLE()
}; // end class ProsodyDisplay




+ 1
- 182
src/spect.cpp View File

@@ -1,7 +1,7 @@
/***************************************************************************
* Copyright (C) 2005 to 2007 by Jonathan Duddington *
* email: [email protected] *
* Copyright (C) 2013 by Reece H. Dunn *
* Copyright (C) 2013-2015 by Reece H. Dunn *
* *
* 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 *
@@ -23,12 +23,10 @@

#include "speak_lib.h"
#include "speech.h"
#include "main.h"
#include "phoneme.h"
#include "synthesize.h"
#include "voice.h"
#include "spect.h"
#include "options.h"
#include "wx/txtstrm.h"
#include "wx/brush.h"
#include "wx/datstrm.h"
@@ -65,33 +63,6 @@ static int default_width[N_PEAKS] =
static int default_klt_bw[N_PEAKS] =
{89,90,140,260,260,260,500,500,500};

float SpectTilt(int value, int freq)
{//=================================
float x;
float y;

if((currentcanvas == NULL) || (currentcanvas->spectseq->bass_reduction == 0))
return(float(value));

y = value*value*2;

if(freq < 600)
{
return(sqrt(y/2.5));
}
else
if(freq < 1050)
{
x = 1.0 + ((1050.0-freq)* 1.5)/450.0;
return(sqrt(y/x));
}
else
{
return(sqrt(y));
}
}


SpectFrame::SpectFrame(SpectFrame *copy)
{//=====================================

@@ -442,34 +413,6 @@ void SpectFrame::ToggleMarker(int n)
}


void SpectFrame::ApplyVoiceMods()
{//==============================
// apply the modifications to the formants which are defined in the current voice
int pk;
char voice_name1[40];

strcpy(voice_name1, voice_name2); // remember current voice name

if(LoadVoice(path_modifiervoice.mb_str(wxConvLocal),0x13) == NULL)
{
wxLogError(_T("Can't read voice: ")+path_modifiervoice);
OnOptions2(MENU_PATH4);
return;
}

wxLogStatus(_T("Convert using voice: ")+path_modifiervoice);

for(pk=0; pk<N_PEAKS; pk++)
{
peaks[pk].pkfreq = (peaks[pk].pkfreq * voice->freq2[pk])/256;
peaks[pk].pkheight = (peaks[pk].pkheight * voice->height2[pk])/256;
peaks[pk].pkwidth = (peaks[pk].pkwidth * voice->width2[pk])/256;
peaks[pk].pkright = (peaks[pk].pkright * voice->width2[pk])/256;
}
LoadVoice(voice_name1,1);
}



double SpectFrame::GetRms(int seq_amplitude)
{//=========================================
@@ -581,130 +524,6 @@ rms = GetRms(seq_amplitude);



void SpectFrame::Draw(wxDC& dc, int offy, int frame_width, double scalex, double scaley)
{//=====================================================================================
int pt;
int peak;
peak_t *pk;
int ix;
double x0, x1;
int y0, y1;
int x, x2, x3;
double xinc;
double yf;
int font_height;
wxString text;

if(currentcanvas == NULL)
return;

dc.SetFont(*wxSWISS_FONT);

xinc = dx * scalex;

x0 = xinc;
x1 = nx * xinc;

if(selected) // this frame is selected
{
// highlight selected peak by drawing a red triangle
pk = &peaks[pk_select];

x2 = int(pk->pkright * scalex * 0.44);
x3 = int(pk->pkwidth * scalex * 0.44);
x = int((pk->pkfreq) * scalex);
y1 = (pk->pkheight * FRAME_HEIGHT) >> 14;
if(y1 < 5) y1 = 5;

wxPoint triangle[3];
dc.SetBrush(BRUSH_SELECTED_PEAK);
dc.SetPen(*wxTRANSPARENT_PEN);
triangle[0] = wxPoint(0,-y1);
triangle[1] = wxPoint(x2,0);
triangle[2] = wxPoint(-x3,0);
dc.DrawPolygon(3,triangle,x,offy);
}

// draw the measured formants
dc.SetPen(BLUE_PEN);
for(peak=1; peak<=5; peak++)
{
if(formants[peak].freq != 0)
{
// set height from linear interpolation of the adjacent
// points in the spectrum
pt = (int)(formants[peak].freq / dx);
y0 = spect[pt-1];
y1 = spect[pt];
yf = (y1-y0) * (formants[peak].freq - pt*dx)/dx;

y1 = offy - (int)((y0+yf) * scaley);
x1 = formants[peak].freq * scalex;
dc.DrawLine((int)x1,offy,(int)x1,y1);

}
}

// draw the spectrum outline
if(keyframe)
dc.SetPen(*wxBLACK_PEN);
else
dc.SetPen(*wxMEDIUM_GREY_PEN);

if(spect != NULL)
{
y0 = offy - (int)(spect[0] * scaley);
for(pt=1; pt<nx; pt++)
{
x1 = x0 + xinc;
y1 = offy - (int)(SpectTilt(spect[pt],int(pt*dx)) * scaley);
dc.DrawLine((int)x0,y0,(int)x1,y1);
x0 = x1;
y0 = y1;
}
}

if(currentcanvas->zoom < 2)
dc.SetFont(FONT_SMALL);
else
dc.SetFont(FONT_MEDIUM);


// Markers
x = frame_width - 120 - 32;
for(ix=0; ix<N_MARKERS; ix++)
{
if(markers & 1<<ix)
{
dc.SetBrush(BRUSH_MARKER[ix]);
y0 = offy-FRAME_HEIGHT+22;
dc.DrawRectangle(x,y0,22,22);
if(currentcanvas->zoom > 2)
{
text.Printf(_T("%d"),ix);
dc.DrawText(text,x+2,y0);
}
x -= 26;
}
}

DrawPeaks(&dc,offy,frame_width,currentcanvas->spectseq->amplitude,scalex);

font_height = int(15 / currentcanvas->zoomy);

text.Printf(_T("%3dmS %.1fHz"),int(time*1000),pitch);
dc.DrawText(text,frame_width-130,offy-FRAME_HEIGHT+20+font_height);
if(keyframe || rms > 0)
{
text.Printf(_T("%3d"),(int)rms);
dc.DrawText(text,frame_width-130,offy-FRAME_HEIGHT+20+font_height*2);
}
dc.SetPen(*wxBLACK_PEN);
dc.DrawLine(0,offy,frame_width,offy); // base line

} // end of SpectFrame::Draw


void SpectFrame::KlattDefaults()
{//============================
// set default values for Klatt parameters

+ 0
- 181
src/spect.h View File

@@ -66,8 +66,6 @@
#define FILEID2_PRAATSEQ 0x51455354


class MyFrame;

typedef struct {
unsigned short pitch1;
unsigned short pitch2;
@@ -137,14 +135,11 @@ public:
int ImportSPC2(wxInputStream &stream, float &time_acc);
int Load(wxInputStream &stream, int file_format_type);
int Save(wxOutputStream &stream, int file_format_type);
void Draw(wxDC &dc, int offy, int frame_width, double scalex, double scaley);

void ZeroPeaks();
void CopyPeaks(SpectFrame *sf);
void ToggleMarker(int n);
void ApplyVoiceMods();

void MakeWaveF(int peaks, PitchEnvelope &pitch, int amplitude, int duration);
void MakeHtab(int numh, int *htab, int pitch);
double GetRms(int amp);
void KlattDefaults();
@@ -185,18 +180,13 @@ public:
int ImportSPC2(wxInputStream& stream);
int Save(wxOutputStream& stream, int selection);
int Load(wxInputStream& stream);
void Draw(wxDC &dc, int start_y, int end_y);
void MakePitchenv(PitchEnvelope &pitch, int start_frame, int end_frame);
void MakeWave(int start, int end, PitchEnvelope &pitch);

void InterpolatePeaks(int on);
void InterpolateAdjacent(void);
void CopyDown(int frame, int direction);
void SelectAll(int yes);
int CountSelected();
void DeleteSelected();
void ClipboardCopy();
int ClipboardInsert(int insert_at);
float GetFrameLength(int frame, int plus, int *original_mS);
float GetKeyedLength();
void SetFrameLengths();
@@ -227,174 +217,3 @@ private:
double scaley;

};


class SpectDisplay: public wxScrolledWindow
{//========================================
public:
SpectDisplay(wxWindow *parent, const wxPoint& pos, const wxSize& size, SpectSeq *spect);
~SpectDisplay();
virtual void OnDraw(wxDC& dc);
void OnMouse(wxMouseEvent& event);
void OnKey(wxKeyEvent& event);
void OnActivate(int active);
void OnMenu(wxCommandEvent& event);

void Save(const wxString &path=_T(""),int selection=0);
void SavePitchenv(PitchEnvelope &pitch);

void OnZoom(int command);

SpectSeq *spectseq;
float zoomx;
float zoomy;
int zoom;
wxString savepath;
void ReadDialogValues();
void WriteDialogValues();
void WriteDialogLength();
void RefreshDialogValues(int type);
int ScrollToFrame(int frame, int centre);
void SelectFrame(int frame);

private:
void RefreshFrame(int frame);
void SetKeyframe(SpectFrame *sf, int yes);
void SetExtent();
int sframe;
int pk_num;


DECLARE_EVENT_TABLE()
};


class ByteGraph: public wxScrolledWindow
{//=====================================
public:
ByteGraph(wxWindow *parent, const wxPoint& pos, const wxSize &size);
virtual void OnDraw(wxDC &dc);
void SetData(int nx, unsigned char *data);
void ShowSpectrum(int yes);
private:
int npoints;
unsigned char *graph;
int show_spectrum;
double spectrum_scale;
void DrawSpectrum(wxDC &dc);
void OnMouse(wxMouseEvent& event);

DECLARE_EVENT_TABLE()
};


class FormantDlg : public wxPanel
{//==============================
public:
FormantDlg(wxWindow *parent);
void ShowFrame(SpectSeq *spectseq, int frame, int pk, int field);
void GetValues(SpectSeq *spectseq, int frame);
void OnCommand(wxCommandEvent& event);
void OnSpin(wxSpinEvent& event);
void HideFields(int synth_type);

wxCheckBox *usepitchenv;

wxSpinCtrl *t_amplitude;
wxSpinCtrl *t_ampframe;
wxSpinCtrl *t_timeframe;
wxTextCtrl *tt_timeframe;
wxSpinCtrl *t_timeseq;
wxStaticText *t_pitch;
wxStaticText *t_orig_frame;
wxStaticText *t_orig_seq;

wxSpinCtrl *s_klatt[N_KLATTP];
wxStaticText *t_klatt[N_KLATTP];

private:
wxStaticText *t_lab[10];
wxStaticText *t_labpk[N_PEAKS];
wxTextCtrl *t_pkfreq[N_PEAKS];
wxTextCtrl *t_pkheight[N_PEAKS];
wxTextCtrl *t_pkwidth[N_PEAKS];
wxTextCtrl *t_klt_bw[N_PEAKS];
wxTextCtrl *t_klt_ap[N_PEAKS];
wxTextCtrl *t_klt_bp[N_PEAKS];
wxRadioButton *t_select_peak[N_PEAKS];

wxButton *t_zoomout;
wxButton *t_zoomin;

DECLARE_EVENT_TABLE()
};



class VoiceDlg : public wxPanel
{//=============================
public:
VoiceDlg(wxWindow *parent);
void ReadParams();
void WriteParams();
void Save();
void Load();
void SetFromSpect(SpectSeq *spect);

voice_t *voice_p;
PitchEnvelope pitchenv;
wxSpinCtrl* vd_pitch1;
wxSpinCtrl* vd_pitch2;
wxTextCtrl* vd_duration;

private:
wxButton *vd_defaults;
wxButton *vd_load;
wxButton *vd_save;

wxStaticText* vd_labpk[N_PEAKS+1];
wxSpinCtrl* vd[N_PEAKS+1][3];
wxCheckBox* vd_usepitch;

wxStaticText* vd_lab[3];
ByteGraph *vd_pitchgraph;
wxComboBox *vd_pitchchoice;

int pitch1;
int pitch2;

void OnCommand(wxCommandEvent& event);
void OnSpin(wxSpinEvent& event);

DECLARE_EVENT_TABLE()
};



extern SpectSeq *clipboard_spect;
extern int pk_select;
extern int samplerate;
extern unsigned char env_fall[];
extern FormantDlg* formantdlg;
extern VoiceDlg* voicedlg;
extern wxNotebook* notebook;
extern ByteGraph* pitchgraph;
extern SpectDisplay *currentcanvas;
extern float polint(float xa[],float ya[],int n,float x);
extern void WavegenInit(int samplerate, int wavemult_fact);
extern void WavegenInitPkData(int); // initialise envelope data
extern "C" void SetPitch(int length, unsigned char *env, int pitch1, int pitch2);
extern void SetSynthHtab(int length_mS, USHORT *ht1, int nh1, float pitch1, USHORT *ht2, int nh2, float pitch2);
extern void MakeWaveFile(int synthesis_method);
extern void MakeWaveBuf(int length, UCHAR *buf);

extern int OpenWaveFile(const char *path, int samplerate);
extern int OpenWaveFile2(const char *path);
extern void CloseWaveFile(int rate);
extern void PlayWavFile(const char *fname);

extern void SetSpinCtrl(wxSpinCtrl *t, int value);
extern int GetNumeric(wxTextCtrl *t);
extern void SetNumeric(wxTextCtrl *t, int value);

extern int use_spin_controls;

+ 0
- 1030
src/spectdisplay.cpp
File diff suppressed because it is too large
View File


+ 0
- 438
src/spectseq.cpp View File

@@ -28,7 +28,6 @@
#include "synthesize.h"
#include "voice.h"
#include "spect.h"
#include "main.h"
#include "wx/numdlg.h"
#include "wx/txtstrm.h"
#include "wx/datstrm.h"
@@ -107,33 +106,6 @@ static void PeaksZero(peak_t *sp, peak_t *zero)



void MakeWaveFile(int synthesis_method)
{//====================================
int result=1;
int resume=0;
unsigned char wav_outbuf[1024];

while(result != 0)
{
out_ptr = out_start = wav_outbuf;
out_end = &wav_outbuf[sizeof(wav_outbuf)];

#ifdef INCLUDE_KLATT
if(synthesis_method == 1)
result = Wavegen_Klatt(resume);
else
#endif
result = Wavegen();

if(f_wave != NULL)
fwrite(wav_outbuf, 1, out_ptr - wav_outbuf, f_wave);
resume=1;
}
} // end of MakeWaveFile




SpectSeq::SpectSeq(int n)
{//======================
numframes = n;
@@ -212,91 +184,6 @@ void SpectSeq::DeleteSelected()
} // end of SpectSeq::DeleteSelected


void SpectSeq::ClipboardCopy()
{//===========================
int ix;
int nframes;
int count=0;

nframes = CountSelected();
if(nframes == 0) return;

if(clipboard_spect != NULL)
delete clipboard_spect;

if((clipboard_spect = new SpectSeq(nframes))==NULL) return;

for(ix=0; ix<numframes; ix++)
{
if(frames[ix]->selected)
{
if((clipboard_spect->frames[count] = new SpectFrame(frames[ix])) == NULL)
break;

count++;
}
}
} // end of SpectSeq::ClipboardCopy



int SpectSeq::ClipboardInsert(int insert_at)
{//=========================================
int ix;
int j;
int total;
int result=insert_at;
float thistime=0;
float timeinc=0;
float timeoffset=0;
SpectFrame **frames2;

if(clipboard_spect == NULL) return(result);
if(clipboard_spect->numframes == 0) return(result);
timeoffset = clipboard_spect->frames[0]->time;

if(CountSelected() == 0)
insert_at = -1;

total = numframes + clipboard_spect->numframes;
frames2 = new SpectFrame* [total];
if(frames2 == NULL) return(result);

total = 0;
for(ix=0; ix<numframes; ix++)
{
thistime = frames[ix]->time;
if(ix == insert_at)
{
result = total;
for(j=0; j<clipboard_spect->numframes; j++)
{
frames2[total] = new SpectFrame(clipboard_spect->frames[j]);
frames2[total]->time += (thistime - timeoffset);
timeinc = frames2[total]->time - thistime + (frames2[total]->length/1000);
total++;
}
}
frames2[total] = new SpectFrame(frames[ix]);
frames2[total++]->time += timeinc;
}
if(insert_at == -1)
{
// insert at the end
result = total;
for(j=0; j<clipboard_spect->numframes; j++)
{
frames2[total] = new SpectFrame(clipboard_spect->frames[j]);
frames2[total++]->time += (thistime - timeoffset);
}
}
delete frames;
frames = frames2;
numframes = total;
return(result);
} // end of SpectSeq::ClipboardInsert


void SpectSeq::SetFrameLengths()
{//=============================
int frame;
@@ -630,68 +517,6 @@ void SpectSeq::ConstructVowel(void)
} // end of ConstructVowel




void SpectSeq::Draw(wxDC& dc, int start_y, int end_y)
{//==================================================
int fm;
int f, f1, f2;
int x;

if(end_y < start_y) return;

if((start_y -= 4) < 0) start_y = 0;

f1 = start_y / FRAME_HEIGHT;
f2 = end_y / FRAME_HEIGHT;

scaley = double(FRAME_HEIGHT) / max_y;
scalex = double(frame_width) / max_x;
// scalex = 0.6;

for(fm=f1; fm <= f2 && fm < numframes; fm++)
{
if(frames[fm]->keyframe)
{
dc.SetBrush(CREAM_BRUSH);
dc.SetPen(BORDER_PEN);
}
else
{
dc.SetBrush(*wxWHITE_BRUSH);
dc.SetPen(*wxTRANSPARENT_PEN);
}

if(frames[fm]->selected)
dc.SetPen(*wxRED_PEN);

dc.DrawRectangle(0,FRAME_HEIGHT*fm+2,frame_width,
FRAME_HEIGHT-2);
}

if(grid==1)
{
for(f=500; f<=MAX_DISPLAY_FREQ; f+=500)
{
x = int(f * scalex);
if(x > max_x) break;
if(f==3000 || f==6000 || f==9000)
dc.SetPen(*wxLIGHT_GREY_PEN);
else
dc.SetPen(VLIGHT_GREY_PEN);
dc.DrawLine(x,start_y,x,numframes*FRAME_HEIGHT);
}
}

for(fm=f1; fm <= f2 && fm < numframes; fm++)
{
frames[fm]->Draw(dc,FRAME_HEIGHT*(fm+1),frame_width,
scalex,scaley);
}

} // end of SpectSeq::Draw


void SpectSeq::InterpolatePeak(int peak)
{//=====================================
int f, f1=0, f2;
@@ -734,69 +559,6 @@ void SpectSeq::InterpolatePeak(int peak)
} // end of SpectSeq::InterpolatePeak


void SpectSeq::InterpolateAdjacent(void)
{//=====================================
int ix;
int f1 = -1;
int select = -1;
int f2 = -1;
float ratio;
peak_t *p = NULL;
peak_t *p1 = NULL;
peak_t *p2 = NULL;

for(ix=0; ix<numframes; ix++)
{
if(frames[ix]->selected)
select = ix;
else
if(frames[ix]->keyframe)
{
if(select >= 0)
{
f2 = ix;
break;
}
else
f1 = ix;
}
}

if(f1 < 0)
{
wxLogError(_T("No previous keyframe"));
return;
}
if(select < 0)
{
wxLogError(_T("No selected frame"));
return;
}
if(f2 < 0)
{
wxLogError(_T("No subsequent keyframe"));
return;
}
// get ratio
ix = wxGetNumberFromUser(_T("Interpolate between adjacent frames"),_T("percent"),_T(""),50);
ratio = (float)ix/100.0;

for(ix=0; ix<N_PEAKS; ix++)
{
p = &frames[select]->peaks[ix];
p1 = &frames[f1]->peaks[ix];
p2 = &frames[f2]->peaks[ix];

p->pkfreq = p1->pkfreq + int((p2->pkfreq - p1->pkfreq)*ratio);
p->pkheight=p1->pkheight+int((p2->pkheight-p1->pkheight)*ratio);
p->pkwidth = p1->pkwidth + int((p2->pkwidth - p1->pkwidth)*ratio);
p->pkright =p1->pkright + int((p2->pkright - p1->pkright)*ratio);
}
frames[select]->keyframe = 1;
formantdlg->ShowFrame(this,select,1,0xff);
}


void SpectSeq::InterpolatePeaks(int control)
{//=========================================
// 0=turn off 1=turn on
@@ -1000,209 +762,9 @@ static void SetSynth_mS(int length_mS, SpectFrame *sp1, SpectFrame *sp2, peak_t
};




void SpectSeq::MakeWave(int start, int end, PitchEnvelope &pitch)
{//==============================================================
int ix;
int length;
int len_samples;
int total_length;
float sum_length=0;
float prev_length=0;
int first;
char *fname_speech;
SpectFrame *sp1 = NULL;
SpectFrame *sp2;
double lfactor;
peak_t peaks0[N_PEAKS];
peak_t peaks1[N_PEAKS];
peak_t peaks2[N_PEAKS];
int synthesizer_type = 0;

if(voice->klattv[0])
{
synthesizer_type = 1;
#ifdef INCLUDE_KLATT
KlattReset(2);
#endif
}

SpeakNextClause(NULL,NULL,2); // stop speaking file

if(numframes==0) return;
SetFrameLengths();

// find overall length of sequence
for(ix=0; ix<numframes; ix++)
{
if(frames[ix]->keyframe)
{
sum_length += prev_length;
prev_length = frames[ix]->length;
sp2 = frames[ix];
if(sp1 == NULL)
sp1 = sp2;
}
}
if(sp1 == NULL)
{
wxLogError(_T("(No frames have peaks set"));
return;
}

total_length = int(sum_length);

if((start==end) || (total_length == 0))
{
sp1->MakeWaveF(0,voicedlg->pitchenv,amplitude,duration);
return;
}


if((duration > 0) && (duration < 40000))
lfactor = double(duration)/double(total_length);
else
{
duration = total_length;
lfactor = 1;
}

len_samples = int(((total_length * lfactor + 50) * samplerate) / 1000);
SetPitch(len_samples,pitch.env,9,44);

fname_speech = WavFileName();
OpenWaveFile2(fname_speech);

first = 0;
if(start > 0)
first=1; // a selection, use fade-in

sp2 = NULL;
for(ix=start; ix<=end; ix++)
{
if(frames[ix]->keyframe)
{
sp1 = sp2;
sp2 = frames[ix];
if(sp1 != NULL)
{
ApplyAmp_adjust(sp1,peaks1);
ApplyAmp_adjust(sp2,peaks2);

if(first)
{
PeaksZero(peaks1,peaks0); // fade in

SetSynth_mS(20,sp1,sp1,peaks0,peaks1,0);
MakeWaveFile(synthesizer_type);
first=0;
}

length = int(sp1->length * lfactor);
SetSynth_mS(length,sp1,sp2,peaks1,peaks2,0);
MakeWaveFile(synthesizer_type);
}
}
}

PeaksZero(peaks2,peaks0); // fade out

SetSynth_mS(30,sp2,sp2,peaks2,peaks0,2);
MakeWaveFile(synthesizer_type);

CloseWaveFile2();
PlayWavFile(fname_speech);

} // end of SpectSeq::MakeWave


void SpectFrame::MakeHtab(int numh, int *htab, int pitch)
{//======================================================
// interpolate the spectrum to give a harmonic table for
// the given pitch (Hz<<12)

} // end of SpectFrame::MakeHtab


void SpectFrame::MakeWaveF(int control, PitchEnvelope &pitche, int amplitude, int duration)
{//======================================================================================
// amplitude: percentage adjustment

int ix;
int length; // mS
int len_samples;
int y;
peak_t peaks0[N_PEAKS];
peak_t peaks1[N_PEAKS];
char *fname_speech;
int synthesizer_type = 0;

if(voice->klattv[0])
{
synthesizer_type = 1;
#ifdef INCLUDE_KLATT
KlattReset(2);
#endif
}

SpeakNextClause(NULL,NULL,2); // stop speaking file

length = duration;
if(length==0)
length = 200; // default length, mS

len_samples = (length * samplerate) / 1000;
SetPitch(len_samples + 50,pitche.env,9,44);

fname_speech = WavFileName();
if(OpenWaveFile2(fname_speech) != 0)
return;


if(control==0)
{
memcpy(peaks1,peaks,sizeof(peaks1));

for(ix=0; ix<N_PEAKS; ix++)
{
y = peaks1[ix].pkheight * amp_adjust * amplitude;
peaks1[ix].pkheight = y/10000;
}
PeaksZero(peaks1,peaks0);
SetSynth_mS(20,this,this,peaks0,peaks1,0);
MakeWaveFile(synthesizer_type);
SetSynth_mS(length,this,this,peaks1,peaks1,0);
MakeWaveFile(synthesizer_type);
SetSynth_mS(30,this,this,peaks1,peaks0,2);
MakeWaveFile(synthesizer_type);
}
else
{
#ifdef SPECT_EDITOR
int maxh;
USHORT htab0[600];

maxh = nx;
if(maxh >= 600)
maxh = 600-1;
for(ix=0; ix<=maxh; ix++)
htab0[ix] = 0;
// SetSynthHtab(20,htab0,maxh,dx,spect,maxh,dx);
SetSynthHtab(20,spect,maxh,dx,spect,maxh,dx);
MakeWaveFile(0);
SetSynthHtab(length,spect,maxh,dx,spect,maxh,dx);
MakeWaveFile(0);
SetSynthHtab(30,spect,maxh,dx,htab0,maxh,dx);
MakeWaveFile(0);
#endif
}

CloseWaveFile2();
PlayWavFile(fname_speech);

} // end of SpectFrame::MakeWaveFrame



+ 0
- 478
src/transldlg.cpp View File

@@ -1,478 +0,0 @@
/***************************************************************************
* Copyright (C) 2005 to 2013 by Jonathan Duddington *
* email: [email protected] *
* Copyright (C) 2013 Reece H. Dunn *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 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 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 "wx/wx.h"


#include "speak_lib.h"
#include "speech.h"
#include "phoneme.h"
#include "main.h"
#include "synthesize.h"
#include "voice.h"
#include "translate.h"
#include "prosodydisplay.h"

#ifdef PLATFORM_POSIX
#include <unistd.h>
#endif


#include "wx/font.h"
#include "wx/textctrl.h"
#include "wx/button.h"
#include "wx/checkbox.h"
#include "wx/filename.h"
#include "wx/sound.h"

#define T_SOURCE 501
#define T_PHONETIC 502
#define T_TRANSLATE 503
#define T_PROCESS 504
#define T_RULES 505
#define T_TRANSLATE_IPA 506

TranslDlg *transldlg = NULL;
extern char *speech_to_phonemes(char *data, char *phout);
extern ProsodyDisplay *prosodycanvas;
extern void Write4Bytes(FILE *f, int value);

BEGIN_EVENT_TABLE(TranslDlg, wxPanel)
EVT_BUTTON(T_TRANSLATE,TranslDlg::OnCommand)
EVT_BUTTON(T_PROCESS,TranslDlg::OnCommand)
EVT_BUTTON(T_RULES,TranslDlg::OnCommand)
EVT_BUTTON(T_TRANSLATE_IPA,TranslDlg::OnCommand)
END_EVENT_TABLE()


FILE *f_wave = NULL;
wxFont font_phonetic;
wxTextAttr style_phonetic;
wxFont font_phonetic_large;
wxTextAttr style_phonetic_large;


void PlayWavFile(const char *fname)
{//================================
char command[120];

#ifdef PLATFORM_WINDOWS
wxSound(wxString(fname,wxConvLocal)).Play(wxSOUND_SYNC);
#else
// wxSound(wxString(fname,wxConvLocal)).Play(wxSOUND_SYNC); // This gives a click at the start of each play
sprintf(command,"aplay %s",fname);
if(system(command) == -1)
{
sprintf(command,"play %s",fname);
if(system(command) == -1)
{
wxLogError(_T("Failed to run system command:\n\n"+wxString(command,wxConvLocal)));
}
}
#endif
}


char *WavFileName(void)
{//====================
static char f_speech[120];
if(!wxDirExists(wxPathOnly(path_speech)))
{
path_speech = wxFileSelector(_T("Speech output file"),
path_phsource,_T("speech.wav"),_T("*"),_T("*"),wxSAVE);
}
strcpy(f_speech,path_speech.mb_str(wxConvLocal));
return(f_speech);
}



int OpenWaveFile2(const char *path)
/*********************************/
{
// Set the length of 0x7fffffff for --stdout
// This will be changed to the correct length for -w (write to file)
static unsigned char wave_hdr[44] = {
'R','I','F','F',0,0,0,0,'W','A','V','E','f','m','t',' ',
0x10,0,0,0,1,0,1,0, 9,0x3d,0,0,0x12,0x7a,0,0,
2,0,0x10,0,'d','a','t','a', 0xff,0xff,0xff,0x7f};

if(path == NULL)
return(2);

if(strcmp(path,"stdout")==0)
f_wave = stdout;
else
f_wave = fopen(path,"wb");

if(f_wave != NULL)
{
fwrite(wave_hdr,1,24,f_wave);
Write4Bytes(f_wave,samplerate);
Write4Bytes(f_wave,samplerate * 2);
fwrite(&wave_hdr[32],1,12,f_wave);
return(0);
}
wxLogStatus(_T("Can't write to WAV file: '"+wxString(path,wxConvLocal))+_T("'"));
return(1);
} // end of OpenWaveFile




void CloseWaveFile2()
/******************/
{
unsigned int pos;

if((f_wave == NULL) || (f_wave == stdout))
return;

fflush(f_wave);
pos = ftell(f_wave);

fseek(f_wave,4,SEEK_SET);
Write4Bytes(f_wave,pos - 8);

fseek(f_wave,40,SEEK_SET);
Write4Bytes(f_wave,pos - 44);


fclose(f_wave);
f_wave = NULL;

} // end of CloseWaveFile




int WavegenFile2(void)
{//==================
int finished;
unsigned char wav_outbuf[1024];

out_ptr = out_start = wav_outbuf;
out_end = wav_outbuf + sizeof(wav_outbuf);

finished = WavegenFill(0);

if(f_wave != NULL)
{
fwrite(wav_outbuf, 1, out_ptr-wav_outbuf, f_wave);
}
return(finished);
} // end of WavegenFile


void MakeWave2(PHONEME_LIST *p, int n_phonemes)
{//============================================
int result;
char *fname_speech;
int n_ph;

#ifdef KLATT_TEST
KlattInit();
#endif
n_ph = n_phonemes;
fname_speech = WavFileName();
OpenWaveFile2(fname_speech);

Generate(p,&n_ph,0);

for(;;)
{
result = WavegenFile2();
if(result != 0)
break;
Generate(p,&n_ph,1);
}

CloseWaveFile2();
PlayWavFile(fname_speech);

} // end of MakeWave2




TranslDlg::TranslDlg(wxWindow *parent) : wxPanel(parent)
{//=====================================================

int height;
int width;
int x,y;
int font_size;
int height_ph = 350;


wxTextAttr attr;
wxFont font = wxFont(12,wxFONTFAMILY_ROMAN,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_LIGHT,false,_T(""),wxFONTENCODING_SYSTEM);

attr.SetFont(font);

wxClientDisplayRect(&x,&y,&width, &height);
#ifdef PLATFORM_WINDOWS
if(height <= 768)
height_ph = height - 416;
#else
if(height <= 800)
height_ph = 280;
#endif


t_source = new wxTextCtrl(this,T_SOURCE,_T(""),wxPoint(0,4),
wxSize(298,250),wxTE_MULTILINE,wxDefaultValidator,_T("Text input window"));
t_source->SetDefaultStyle(attr);


t_phonetic = new wxTextCtrl(this,T_PHONETIC,_T(""),wxPoint(0,262),
wxSize(298,height_ph),wxTE_MULTILINE | wxTE_READONLY, wxDefaultValidator,_T("Phoneme translation window"));

style_phonetic = t_phonetic->GetDefaultStyle();
font_phonetic = style_phonetic.GetFont();
font_size = font_phonetic.GetPointSize();
font_phonetic_large = font_phonetic;
style_phonetic_large = style_phonetic;
//font_phonetic_large.SetFamily(wxFONTFAMILY_SWISS);
font_phonetic_large.SetPointSize(font_size+1);
style_phonetic_large.SetFont(font_phonetic_large);

y = height_ph + 270;
t_translate = new wxButton(this,T_TRANSLATE,_T("Translate"),wxPoint(4,y));
t_translate = new wxButton(this,T_RULES,_T("Show Rules"),wxPoint(4,y+32));
t_translate = new wxButton(this,T_TRANSLATE_IPA,_T("Show IPA"),wxPoint(100,y+32));
t_process = new wxButton(this,T_PROCESS,_T("Speak"),wxPoint(100,y));

t_source->SetFocus();
} // end of TransDlg::TransDlg



void TranslDlg::SpeakFile(void)
{//============================
wxString file;
wxFileName fname;
FILE *f_text;
char buf[200];

fname = wxFileName(path_speaktext);

file = wxFileSelector(_T("Text file to speak"),fname.GetPath(),fname.GetName(),_T(""),_T("*"),wxOPEN);
if(file == wxEmptyString) return;

strcpy(buf,file.mb_str(wxConvLocal));
f_text = fopen(buf,"r");
if(f_text == NULL)
{
wxLogError(_T("Failed to read: ")+file);
return;
}

path_speaktext = file;

InitText(0);
SpeakNextClause(f_text,NULL,0);
return;
} // end of SpeakFile



void TranslDlg::ReadVoice(int variant)
{//===================================
wxString path;
wxString filename;
char *p;
char vname[40];
char fname[sizeof(path_home)+30];

if(variant)
{
// remove variant from the previous voice name
if((p = strchr(voice_name2,'+')) != NULL)
*p = 0;

sprintf(fname,"%s/voices/!v",path_home);
path = wxFileSelector(_T("Load voice variant"),wxString(fname,wxConvLocal),_T(""),_T(""),_T("*"),wxOPEN);
if(path.IsEmpty())
{
strcpy(fname,voice_name2);
}
else
{
filename = path.Mid(strlen(fname)+1);
strcpy(vname,filename.mb_str(wxConvLocal));
sprintf(fname,"%s+%s",voice_name2,vname);
}
}
else
{
sprintf(fname,"%s/voices",path_home);
path = wxFileSelector(_T("Load voice"),wxString(fname,wxConvLocal),_T(""),_T(""),_T("*"),wxOPEN);
if(path.IsEmpty())
return;

filename = path.Mid(strlen(fname)+1);
strcpy(fname,filename.mb_str(wxConvLocal));
}

if(SetVoiceByName(fname) != EE_OK)
{
wxLogError(_T("Failed to load voice data"));
}
else
{
strcpy(voice_name2,fname);
}
WavegenSetVoice(voice);
}


void TranslDlg::OnCommand(wxCommandEvent& event)
{//=============================================
#define N_PH_LIST N_PHONEME_LIST

void *vp;
int translate_text = 0;
char buf[1000];
char phon_out[N_PH_LIST*2];
const char *phon_out2;
int clause_tone;
int clause_count;
FILE *f;
int fd_temp;
char fname_temp[100];
static int n_ph_list;
static PHONEME_LIST ph_list[N_PH_LIST+1];

if(translator==NULL)
{
wxLogError(_T("Voice not set"));
return;
}

option_phonemes = 0;

switch(event.GetId())
{
case T_RULES:
case MENU_SPEAK_RULES:
#ifdef PLATFORM_POSIX
strcpy(fname_temp,"/tmp/espeakXXXXXX");
if((fd_temp = mkstemp(fname_temp)) >= 0)
{
close(fd_temp);

if((f = fopen(fname_temp,"w+")) != NULL)
{
f_trans = f; // write translation rule trace to a temp file
}
}
#else
strcpy(fname_temp,tmpnam(NULL));
if((f = fopen(fname_temp,"w+")) != NULL)
{
f_trans = f; // write translation rule trace to a temp file
}
#endif
t_phonetic->SetDefaultStyle(style_phonetic);
translate_text = espeakPHONEMES_TRACE;
break;

case T_TRANSLATE:
case MENU_SPEAK_TRANSLATE:
t_phonetic->SetDefaultStyle(style_phonetic);
translate_text = espeakPHONEMES_SHOW;
break;

case T_TRANSLATE_IPA:
case MENU_SPEAK_IPA:
t_phonetic->SetDefaultStyle(style_phonetic_large);

translate_text = espeakPHONEMES_IPA;
break;

case T_PROCESS:
case MENU_SPEAK_TEXT:
myframe->OnProsody(event);
prosodycanvas->LayoutData(ph_list,n_ph_list);
myframe->Refresh();
option_phoneme_events = espeakINITIALIZE_PHONEME_EVENTS;
option_log_frames = 1;
MakeWave2(ph_list,n_ph_list);
option_log_frames = 0;
break;
}

if(translate_text)
{
option_phonemes = translate_text;

option_multibyte = espeakCHARS_AUTO;
SpeakNextClause(NULL,NULL,2); // stop speaking file

strncpy0(buf,t_source->GetValue().mb_str(wxConvUTF8),sizeof(buf));
phon_out[0] = 0;
n_ph_list = 0;
clause_count = 0;

vp = buf;
InitText(0);
while((vp != NULL) && (n_ph_list < N_PH_LIST))
{
vp = TranslateClause(translator,NULL,vp,&clause_tone,NULL);
CalcPitches(translator,clause_tone);
CalcLengths(translator);

phon_out2 = GetTranslatedPhonemeString(option_phonemes);
if(clause_count++ > 0)
strcat(phon_out," ||");
strcat(phon_out, phon_out2);
t_phonetic->SetValue(wxString(phon_out2, wxConvUTF8));

if((n_ph_list + n_phoneme_list) >= N_PH_LIST)
{
n_phoneme_list = N_PH_LIST - n_ph_list;
}

memcpy(&ph_list[n_ph_list],phoneme_list,sizeof(PHONEME_LIST)*n_phoneme_list);
n_ph_list += n_phoneme_list;
}

ph_list[N_PH_LIST].ph = NULL; // to recognize overrun off list (in Generate() )

t_phonetic->Clear();
if(option_phonemes & espeakPHONEMES_TRACE)
{
option_phonemes=0;
rewind(f_trans);
while(fgets(buf,sizeof(buf),f_trans) != NULL)
{
t_phonetic->AppendText(wxString(buf,wxConvUTF8));
}
t_phonetic->AppendText(_T("---\n"));
if(f_trans != NULL)
fclose(f_trans);
remove(fname_temp);
}
t_phonetic->AppendText(wxString(phon_out,wxConvUTF8));
}
} // end of TranslDlg::OnCommand

+ 0
- 299
src/voicedlg.cpp View File

@@ -1,299 +0,0 @@
/***************************************************************************
* Copyright (C) 2005 to 2007 by Jonathan Duddington *
* email: [email protected] *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 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 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write see: *
* <http://www.gnu.org/licenses/>. *
***************************************************************************/


#include "wx/wx.h"


#include "speak_lib.h"
#include "main.h"
#include "speech.h"
#include "phoneme.h"
#include "synthesize.h"
#include "voice.h"
#include "spect.h"
#include "options.h"

#include "wx/dialog.h"
#include "wx/textctrl.h"
#include "wx/checkbox.h"
#include "wx/txtstrm.h"
#include "wx/wfstream.h"
#include "wx/filename.h"

VoiceDlg *voicedlg = NULL;

voice_t voice_data;
USHORT voice_pcnt[N_PEAKS+1][3];

static void VoiceSetup()
{//=====================
int pk;
voice_t *v = &voice_data;

for(pk=0; pk<N_PEAKS; pk++)
{
v->freq[pk] = int(voice_pcnt[pk][0] * 2.56001 * voice_pcnt[N_PEAKS][0] / 100.0);
v->height[pk] = int(voice_pcnt[pk][1] * 2.56001 * voice_pcnt[N_PEAKS][1] / 100.0);
v->width[pk] = int(voice_pcnt[pk][2] * 2.56001 * voice_pcnt[N_PEAKS][2] / 100.0);
}
}


static void VoiceInit()
{//====================
int pk, j;
voice_t *v;

v = &voice_data;

v->pitch_base = 71 << 12;
v->pitch_range = 0x1000; // default = 0x1000
for(pk=0; pk<N_PEAKS+1; pk++)
{
for(j=0; j<3; j++)
voice_pcnt[pk][j] = 100;
}
VoiceSetup();

voice = v;
} // end of voice_init


#define VD_DEFAULTS 401
#define VD_LOAD 402
#define VD_SAVE 403
#define VD_PITCHCHOICE 404
#define VD_PITCH1 405
#define VD_PITCH2 406
#define VD_USEPITCH 407

wxString pitchchoices[3] = {_T("From spectrum"),_T("Standard"),_T("Monotone")};

BEGIN_EVENT_TABLE(VoiceDlg, wxPanel)
EVT_BUTTON(VD_DEFAULTS,VoiceDlg::OnCommand)
EVT_BUTTON(VD_LOAD,VoiceDlg::OnCommand)
EVT_BUTTON(VD_SAVE,VoiceDlg::OnCommand)
EVT_SPINCTRL(VD_PITCH1,VoiceDlg::OnSpin)
EVT_SPINCTRL(VD_PITCH2,VoiceDlg::OnSpin)
EVT_CHECKBOX(VD_USEPITCH,VoiceDlg::OnCommand)
EVT_COMBOBOX(VD_PITCHCHOICE,VoiceDlg::OnCommand)
END_EVENT_TABLE()

VoiceDlg::VoiceDlg(wxWindow *parent) : wxPanel(parent)
{//=========================================================
int ix, j;
int y;
wxString string;
voice_t *v;
wxString captions[3] = {_T("Freq"),_T("Height"),_T("Width")};

voice_p = v = &voice_data;
VoiceInit();

pitch1 = 80;
pitch2 = 120;
for(j=0; j<3; j++)
new wxStaticText(this,-1,captions[j],wxPoint(34+j*56,6));

y = 26;
for(ix=0; ix<N_PEAKS+1; ix++)
{
if(ix==N_PEAKS)
{
string = _T("All");
y += 8;
}
else
string.Printf(_T("%2d"),ix);
vd_labpk[ix] = new wxStaticText(this,-1,string,wxPoint(8,y+2));

for(j=0; j<3; j++)
{
string.Printf(_T("%d"),voice_pcnt[ix][j]);
vd[ix][j] = new wxSpinCtrl(this,-1,string,
wxPoint(32+j*56,y),wxSize(52,22),wxSP_ARROW_KEYS,0,300);
}
y += 26;
}
for(ix=6; ix<N_PEAKS; ix++)
vd[ix][2]->Hide();

vd_defaults = new wxButton(this,VD_DEFAULTS,_T("Defaults"),wxPoint(32,293));

y = 324;
vd_pitch1 = new wxSpinCtrl(this,VD_PITCH1,_T("80"),
wxPoint(32,y),wxSize(52,24),wxTE_CENTRE,60,500);
vd_pitch2 = new wxSpinCtrl(this,VD_PITCH2,_T("120"),
wxPoint(88,y),wxSize(52,24),wxTE_CENTRE,60,500);
vd_lab[1] = new wxStaticText(this,-1,_T("Hz"),wxPoint(142,y+2));
vd_usepitch = new wxCheckBox(this,VD_USEPITCH,_T("Pitch from spectrum"),
wxPoint(4,y+24));
// vd_load = new wxButton(this,VD_LOAD,_T("Load"),wxPoint(16,y+56));
// vd_save = new wxButton(this,VD_SAVE,_T("Save"),wxPoint(106,y+56));

y = 422;
vd_duration = new wxTextCtrl(this,-1,_T(""),
wxPoint(4,y),wxSize(52,24),wxTE_CENTRE);
vd_lab[2] = new wxStaticText(this,-1,_T("Duration"),wxPoint(60,y+2));

y = 422;
vd_pitchchoice = new wxComboBox(this,VD_PITCHCHOICE,_T("Standard"),
wxPoint(4,y+30),wxSize(192,24),3,pitchchoices);
vd_pitchgraph = new ByteGraph(this,wxPoint(0,y+60),wxSize(200,100));
vd_pitchgraph->SetData(128,env_fall);
vd_pitchgraph->Show();

} // end of VoiceDlg::VoiceDlg


void VoiceDlg::OnCommand(wxCommandEvent& event)
{//============================================

// JSD EVT_COMBOBOX causes GDB lockup if a breakpoint is set

int id;
int ix, j;

switch(id = event.GetId())
{
case VD_DEFAULTS:
for(ix=0; ix<N_PEAKS+1; ix++)
{
for(j=0; j<3; j++)
{
voice_pcnt[ix][j] = 100;
vd[ix][j]->SetValue(_T("100"));
}
}
VoiceSetup();
break;

case VD_LOAD:
// Load();
break;

case VD_SAVE:
// Save();
break;

case VD_USEPITCH:
case VD_PITCHCHOICE:
if(currentcanvas != NULL)
SetFromSpect(currentcanvas->spectseq);
break;
}

if(currentcanvas != NULL) currentcanvas->SetFocus();
} // end of VoiceDlg::OnCommand



void VoiceDlg::ReadParams()
{//========================
int ix, j;

pitchenv.pitch1 = vd_pitch1->GetValue();
pitchenv.pitch2 = vd_pitch2->GetValue();

voice_data.pitch_base = (pitchenv.pitch1 - 9) << 12;
voice_data.pitch_range = (pitchenv.pitch2 - pitchenv.pitch1) * 108;
for(ix=0; ix<N_PEAKS+1; ix++)
{
for(j=0; j<3; j++)
{
voice_pcnt[ix][j] = vd[ix][j]->GetValue();
}
}
VoiceSetup();

} // end of VoiceDlg::ReadParams


void VoiceDlg::WriteParams()
{//========================
int ix;
voice_t *v = voice;
int val1, val2;

val1 = (v->pitch_base >> 12) + 9;
val2 = v->pitch_range/108 + val1;
vd_pitch1->SetValue(val1);
vd_pitch2->SetValue(val2);

for(ix=0; ix<N_PEAKS; ix++)
{
vd[ix][0]->SetValue(int(float(v->freq[ix]) / 2.56001 + 0.5));
vd[ix][1]->SetValue(int(float(v->height[ix]) / 2.56001 + 0.5));
vd[ix][2]->SetValue(int(float(v->width[ix]) / 2.56001 + 0.5));
}
vd[ix][0]->SetValue(100);
vd[ix][1]->SetValue(100);
vd[ix][2]->SetValue(100);

} // end of VoiceDlg::WriteParams



void VoiceDlg::OnSpin(wxSpinEvent& event)
{//======================================

ReadParams();
}


void VoiceDlg::SetFromSpect(SpectSeq* spect)
{//=========================================
if(spect==NULL) return;
if(vd_pitchchoice->GetValue() == _T("From spectrum"))
{
pitchenv = spect->pitchenv;
}
else
if(vd_pitchchoice->GetValue() == _T("Monotone"))
{
memset(pitchenv.env,127,128);
}
else
if(vd_pitchchoice->GetValue() == _T("Standard"))
{
memcpy(pitchenv.env,env_fall,128);
}
vd_pitchgraph->SetData(128,pitchenv.env);
vd_pitchgraph->Show();

if(vd_usepitch->GetValue())
{
SetSpinCtrl(vd_pitch1,spect->pitch1);
SetSpinCtrl(vd_pitch2,spect->pitch2);
}
else
{
SetSpinCtrl(vd_pitch1,pitch1);
SetSpinCtrl(vd_pitch2,pitch2);
}
} // end of VoiceDlg::SetFromSpect


+ 0
- 748
src/vowelchart.cpp View File

@@ -1,748 +0,0 @@
/***************************************************************************
* Copyright (C) 2005 to 2013 by Jonathan Duddington *
* email: [email protected] *
* Copyright (C) 2013-2015 Reece H. Dunn *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 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 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write see: *
* <http://www.gnu.org/licenses/>. *
***************************************************************************/


#include <math.h>
#include "wx/wx.h"
#include <wx/dcmemory.h>
#include <wx/dc.h>
#include <wx/bitmap.h>
#include <wx/dirdlg.h>
#include "wx/filename.h"
#include "wx/wfstream.h"

#include "speak_lib.h"
#include "main.h"
#include "speech.h"
#include "phoneme.h"
#include "synthesize.h"
#include "voice.h"
#include "spect.h"
#include "translate.h"
#include "options.h"

/* Read a file of vowel symbols and f1,f2 formants, and produce a vowel diagram
*/
extern wxString path_phsource;

extern char *phondata_ptr;
extern USHORT *phoneme_index;
extern int n_phoneme_tables;


// size of the vowelchart png
#define WIDTH 1580
#define HEIGHT 800


#define ROUND(x) ((int) ((x) + 0.5))

static int HslValue (double n1, double n2, double hue)
{//===================================================
double value;
if (hue > 255)
hue -= 255;
else if (hue < 0)
hue += 255;
if (hue < 42.5)
value = n1 + (n2 - n1) * (hue / 42.5);
else if (hue < 127.5)
value = n2;
else if (hue < 170)
value = n1 + (n2 - n1) * ((170 - hue) / 42.5);
else
value = n1;
return ROUND (value * 255.0);
}

/**
* @hue: Hue channel, returns Red channel
* @saturation: Saturation channel, returns Green channel
* @lightness: Lightness channel, returns Blue channel
*
* The arguments are pointers to int, with the values pointed to in the
* following ranges: H [0, 360], L [0, 255], S [0, 255].
*
* The function changes the arguments to point to the RGB value
* corresponding, with the returned values all in the range [0, 255].
**/
void HslToRgb (int *hue, int *saturation, int *lightness)
{//======================================================
double h, s, l;

h = (*hue * 256)/360;
s = *saturation;
l = *lightness;

if (s == 0)
{
/* achromatic case */
*hue = (int)l;
*lightness = (int)l;
*saturation = (int)l;
}
else
{
double m1, m2;

if (l < 128)
m2 = (l * (255 + s)) / 65025.0;
else
m2 = (l + s - (l * s) / 255.0) / 255.0;

m1 = (l / 127.5) - m2;

/* chromatic case */
*hue = HslValue (m1, m2, h + 85);
*saturation = HslValue (m1, m2, h);
*lightness = HslValue (m1, m2, h - 85);
}
}


static int vowel_posn[N_PHONEME_TAB];
static int vowel_posn_ix;


static double log2a(double x)
{//========================
// log2(x) = log(x) / log(2)
return(log(x) / 0.693147);
}

static int VowelX(int f2)
{//======================
return(WIDTH - int((log2a(f2) - 9.40)*WIDTH/1.9));
// return(WIDTH - int((log2a(f2) - 9.49)*WIDTH/1.8));
}

static int VowelY(int f1)
{//======================
return(int((log2a(f1) - 7.85)*HEIGHT/2.15));
}

static int VowelZ(int f3)
{//======================
int z;
// range 2000-3000Hz, log2= 10.96 to 11.55
z = int((log2a(f3) - 11.05)*256/0.50);
if(z < 0) z = 0;
if(z > 255) z = 255;
return(z);
}


static void DrawVowel(wxDC *dc, wxString name, int f1, int f2, int f3, int g1, int g2)
{//==================================================================================
int ix;
int posn;
int collisions;
int x,y,z,x2,y2;
int r,g,b;
wxBrush brush;


y = VowelY(f1);
x = VowelX(f2);
z = VowelZ(f3);

if(y < 0) y = 0;
if(y > (HEIGHT-4)) y= (HEIGHT-4);
if(x < 0) x = 0;
if(x > (WIDTH-12)) x = (WIDTH-12);

r = z;
g = 255;
b = 100 + z/2;
HslToRgb(&r,&g,&b);
brush.SetColour(r,g,b);
dc->SetBrush(brush);
dc->DrawCircle(x,y,4);

// check for a label already at this position
collisions = 0;
posn = (x/8)*WIDTH + (y/8);
for(ix=0; ix<vowel_posn_ix; ix++)
{
if(posn == vowel_posn[ix])
collisions++;
}
vowel_posn[vowel_posn_ix++] = posn;

dc->DrawText(name,x+4,y+(collisions*10));

if(g2 != 0xffff)
{
y2 = VowelY(g1);
x2 = VowelX(g2);
dc->DrawLine(x,y,x2,y2);
}
}



static int VowelChartDir(wxDC *dc, wxBitmap *bitmap)
{//=================================================
int ix;
int nf;
int count = 0;
SpectSeq *spectseq;
SpectFrame *frame1;
SpectFrame *frame2=NULL;
wxFileName filename;

wxString dir = wxDirSelector(_T("Directory of vowel files"),path_phsource);
if(dir.IsEmpty()) return(0);

wxString path = wxFindFirstFile(dir+_T("/*"),wxFILE);

while (!path.empty())
{
if((spectseq = new SpectSeq) == NULL) break;

filename = wxFileName(path);
wxFileInputStream stream(path);
if(stream.Ok() == FALSE)
{
path = wxFindNextFile();
delete spectseq;
continue;
}
spectseq->Load(stream);

nf = 0;
frame1 = NULL;

if(spectseq->numframes > 0)
{
frame2 = spectseq->frames[0];
}
for(ix=0; ix<spectseq->numframes; ix++)
{
if(spectseq->frames[ix]->keyframe)
{
nf++;
frame2 = spectseq->frames[ix];
if(frame2->markers & FRFLAG_VOWEL_CENTRE)
frame1 = frame2;
}
}
if((nf >= 3) && (frame1 != NULL))
{
DrawVowel(dc,wxString(filename.GetName()),
frame1->peaks[1].pkfreq, frame1->peaks[2].pkfreq, frame1->peaks[3].pkfreq,
frame2->peaks[1].pkfreq, frame2->peaks[2].pkfreq);

count++;
}
delete spectseq;
path = wxFindNextFile();
}
filename.SetPath(dir);
filename.SetFullName(_T("vowelchart.png"));
bitmap->SaveFile(filename.GetFullPath(),wxBITMAP_TYPE_PNG);
return(count);
}


static int VowelChartList(wxDC *dc, wxBitmap *bitmap, char *fname)
{//===============================================================
// Plot a graph of vowel formants.
// y-axis is decreasing f1 (closeness)
// x-axis is decreasing f2 (backness)
FILE *f_in;
int ix;
int f1,f2,f3,g1,g2;
int colour;
int count=0;
wxFileName filename;
char name[40];
char buf[200];
wxString path;

if(fname != NULL)
{
path = wxString(fname,wxConvLocal);
}
else
{
path = wxFileSelector(_T("Read file of vowel formants"),path_phsource,
_T(""),_T(""),_T("*"),wxOPEN);
}
if(path.IsEmpty())
{
return(0);
}

filename = wxFileName(path);
strcpy(buf,path.mb_str(wxConvLocal));
f_in = fopen(buf,"r");
if(f_in == NULL)
{
wxLogError(_T("Can't read file: %s"),buf);
return(0);
}


while(fgets(buf,sizeof(buf),f_in) != NULL)
{
g2 = 0xffff;
ix = sscanf(buf,"%s %d %d %d %d %d %d",name,&colour,&f1,&f2,&f3,&g1,&g2);
if(ix >= 4)
{
if(colour == 1)
{
dc->SetPen(*wxMEDIUM_GREY_PEN);
dc->SetTextForeground(wxColour(100,100,128));
}
else
{
dc->SetPen(*wxBLACK_PEN);
dc->SetTextForeground(*wxBLACK);
}

DrawVowel(dc,wxString(name,wxConvLocal),
f1,f2,f3,g1,g2);
count++;
}
}

filename.SetExt(_T("png"));
bitmap->SaveFile(filename.GetFullPath(),wxBITMAP_TYPE_PNG);
fclose(f_in);
return(count);
}


void VowelChart(int control, char *fname)
{//======================================
// Plot a graph of vowel formants.
// y-axis is decreasing f1 (closeness)
// x-axis is decreasing f2 (backness)
// control=1 from directory of lists
// control=2 from single list
// control=3 from directory of phoneme source data files

int ix;
int x,y;
int count;
wxFileName filename;

wxBitmap bitmap(WIDTH,HEIGHT);

// Create a memory DC
wxMemoryDC dc;
dc.SelectObject(bitmap);
dc.SetBrush(*wxWHITE_BRUSH);
dc.SetFont(*wxSWISS_FONT);
dc.Clear();

// draw grid
dc.SetPen(*wxLIGHT_GREY_PEN);
for(ix=200; ix<=1000; ix+=50)
{
y = VowelY(ix);
dc.DrawLine(0,y,WIDTH,y);
if((ix % 100) == 0)
dc.DrawText(wxString::Format(_T("%d"),ix),1,y);
}
for(ix=700; ix<=2400; ix+=100)
{
x = VowelX(ix);
dc.DrawLine(x,0,x,HEIGHT);
if((ix % 200)==0)
dc.DrawText(wxString::Format(_T("%d"),ix),x+1,0);
}
dc.SetPen(*wxBLACK_PEN);
vowel_posn_ix = 0;
if(control==3)
count = VowelChartDir(&dc, &bitmap);
else
count = VowelChartList(&dc, &bitmap, fname);

dc.SetTextForeground(*wxBLACK);

if(control != 1)
wxLogStatus(_T("Plotted %d vowels"),count);
}



void FindPhonemesUsed(void)
{//========================
int hash;
char *p;
unsigned int *pw;
char *next;
unsigned char c;
int count = 0;
int ignore;
char phonetic[N_WORD_PHONEMES];

// look through all the phoneme strings in the **_rules data
// and mark these phoneme codes as used.
p = translator->data_dictrules;
while(*p != 0)
{
if(*p == RULE_CONDITION)
p+=2;
if(*p == RULE_LINENUM)
p+=3;
if(*p == RULE_GROUP_END)
{
p++;
if(*p == 0) break;
}
if(*p == RULE_GROUP_START)
{
if(p[1] == RULE_REPLACEMENTS)
{
p++;
pw = (unsigned int *)(((long)p+4) & ~3); // advance to next word boundary
while(pw[0] != 0)
{
pw += 2; // find the end of the replacement list, each entry is 2 words.
}
p = (char *)(pw+1);
continue;
}

if(p[1] == RULE_LETTERGP2)
{
while(*p != RULE_GROUP_END) p++;
continue;
}

p += (strlen(p)+1);
}

while((c = *p) != 0)
{
if(c == RULE_CONDITION)
p++; // next byte is the condition number, which may be 3 (= RULE_PHONEMES)
if(c == RULE_PHONEMES)
break;
p++;
}


count++;
if(c == RULE_PHONEMES)
{
ignore = 0;
p++;
while((c = *p) != 0)
{
if(c == phonSWITCH)
ignore = 1;

if(ignore == 0)
phoneme_tab_flags[c] |= 2;
p++;
}
}
p++;
}

// NOTE, we should recognise langopts.textmode and ignore the *_list file (lang=zh)

for(hash=0; hash<N_HASH_DICT; hash++)
{
p = translator->dict_hashtab[hash];
if(p == NULL)
continue;

while(*p != 0)
{
next = p + p[0];
if((p[1] & 0x80) == 0)
{
p += ((p[1] & 0x3f) + 2);
strcpy(phonetic,p);
p += strlen(phonetic) +1;

// examine flags
ignore = 0;
while(p < next)
{
if(*p == BITNUM_FLAG_TEXTMODE)
{
ignore = 1;
break;
}
p++;
}

if(ignore == 0)
{
p = phonetic;
while((c = *p) != 0)
{
if(c == phonSWITCH)
break;

phoneme_tab_flags[c] |= 2;
p++;
}
}
}
p = next;
}
}
} // end of FindPhonemesUsed




#define N_VOWELFMT_ADDR 20
int n_vowelfmt_addr;
int vowelfmt_addr[N_VOWELFMT_ADDR]; // FMT() statements found in a phoneme definition

static void FindVowelFmt(int prog_start, int length)
{//=================================================
USHORT *prog;
USHORT instn;
int prog_end;

prog_end = prog_start + length;
n_vowelfmt_addr = 0;

for(prog = &phoneme_index[prog_start]; prog < &phoneme_index[prog_end]; prog += NumInstnWords(prog))
{
instn = *prog;
if((instn >> 12) == 11)
{
// FMT instruction
if(n_vowelfmt_addr < N_VOWELFMT_ADDR)
{
vowelfmt_addr[n_vowelfmt_addr++] = ((instn & 0xf) << 18) + (prog[1] << 2);
}
}
}
} // end of FindVowelFmt


static int prog_log_sorter(PHONEME_PROG_LOG *p1, PHONEME_PROG_LOG *p2)
{//===================================================================
return(p1->addr - p2->addr);
}

void MakeVowelLists(void)
{//======================
// For each phoneme table, make a list of its vowels and their
// formant frequencies (f1,f2,f3) for use by VowelChart()

int table;
int ix;
int phcode;
PHONEME_TAB *ph;
FILE *f;
FILE *f_prog_log;
SPECT_SEQ *seq;
SPECT_SEQK *seqk;
frame_t *frame;
int n_prog_log;
int vowelfmt_ix;
int colour;
int voice_found;
PHONEME_PROG_LOG *prog_log_table;
PHONEME_PROG_LOG *found_prog;
PHONEME_PROG_LOG this_prog;
char dirname[sizeof(path_source)+20];
char fname[sizeof(dirname)+40];
char save_voice_name[80];

strcpy(save_voice_name,voice_name2);

sprintf(fname,"%s%s",path_source,"compile_prog_log");
if((f_prog_log = fopen(fname,"rb")) == NULL)
{
wxLogError(_T("Can't read 'compile_prog_log;"));
return;
}
ix = GetFileLength(fname);
prog_log_table = (PHONEME_PROG_LOG *)malloc(ix);
if(prog_log_table == NULL)
{
fclose(f_prog_log);
return;
}
ix = fread(prog_log_table, 1, ix, f_prog_log);
fclose(f_prog_log);
n_prog_log = ix / sizeof(PHONEME_PROG_LOG);

progress = new wxProgressDialog(_T("Vowel charts"),_T(""),n_phoneme_tables);

sprintf(dirname,"%s%s",path_source,"vowelcharts");
mkdir(dirname,S_IRWXU | S_IRGRP | S_IROTH);

sprintf(fname,"%s/vowel_log",dirname);

for(table=0; table<n_phoneme_tables; table++)
{
sprintf(fname,"%s/%s",dirname,phoneme_tab_list[table].name);
if((f = fopen(fname,"w"))==NULL) continue;

progress->Update(table);

// select the phoneme table by name
// if(SetVoiceByName(phoneme_tab_list[table].name) != 0) continue;
if(SelectPhonemeTableName(phoneme_tab_list[table].name) < 0)
{
fclose(f);
continue;
}

voice_found = 0;
if((LoadVoice(phoneme_tab_list[table].name, 0) != NULL) && (translator->data_dictrules != NULL))
{
voice_found = 1;
FindPhonemesUsed();
}

// phoneme table is terminated by a phoneme with no name (=0)
for(phcode=1; phcode < n_phoneme_tab; phcode++)
{
ph = phoneme_tab[phcode];

if((ph==NULL) || (ph->type != phVOWEL) || (ph->program == 0))
continue;

if(voice_found && (phoneme_tab_flags[phcode] & 3) == 0)
{
continue; // inherited, and not used
}

// find the size of this program
this_prog.addr = ph->program;
found_prog = (PHONEME_PROG_LOG *)bsearch((void *)&this_prog, (void *)prog_log_table, n_prog_log, sizeof(PHONEME_PROG_LOG), (int(*)(const void *,const void *))prog_log_sorter);

FindVowelFmt(ph->program, found_prog->length);

for(vowelfmt_ix=0; vowelfmt_ix < n_vowelfmt_addr; vowelfmt_ix++)
{
ix = vowelfmt_addr[vowelfmt_ix];

seq = (SPECT_SEQ *)(&phondata_ptr[ix]);
seqk = (SPECT_SEQK *)seq;
if(seq->frame[0].frflags & FRFLAG_KLATT)
frame = &seqk->frame[1];
else
frame = (frame_t *)&seq->frame[1];

if((n_vowelfmt_addr - vowelfmt_ix) == 1)
colour = 0;
else
colour = 1;

fprintf(f,"%s\t %d %3d %4d %4d",WordToString(ph->mnemonic), colour,
frame->ffreq[1],frame->ffreq[2],frame->ffreq[3]);
if(seq->frame[0].frflags & FRFLAG_KLATT)
frame = &seqk->frame[seqk->n_frames-1];
else
frame = (frame_t *)&seq->frame[seq->n_frames-1];
fprintf(f," %3d %4d %4d\n",frame->ffreq[1],frame->ffreq[2],frame->ffreq[3]);
}
}
fclose(f);

VowelChart(1,fname); // draw the vowel chart
}
free(prog_log_table);
LoadVoice(voice_name2,0); // reset the original phoneme table
delete progress;
LoadVoiceVariant(save_voice_name,0);
}


#define N_ENVELOPES 30
extern int n_envelopes;
extern char envelope_paths[N_ENVELOPES][80];
extern unsigned char envelope_dat[N_ENVELOPES][ENV_LEN];

#define HT_ENV 140
#define WD_ENV 128*2

void DrawEnvelopes()
{//================
int ix_env;
int y_base;
int x;
FILE *f_txt=NULL;
unsigned char *env;
char name[200];

wxBitmap bitmap(WD_ENV,HT_ENV*n_envelopes);

// Create a memory DC
wxMemoryDC dc;
dc.SelectObject(bitmap);
dc.SetBrush(*wxWHITE_BRUSH);
dc.SetFont(*wxSWISS_FONT);
dc.Clear();

sprintf(name,"%s%s",path_source,"envelopes.txt");
// f_txt = fopen(name,"w");

for(ix_env=0; ix_env<n_envelopes; ix_env++)
{
y_base = HT_ENV * ix_env;
dc.SetPen(*wxLIGHT_GREY_PEN);
dc.DrawLine(0,y_base+0,256,y_base+0);
dc.DrawLine(0,y_base+64,256,y_base+64);
dc.DrawLine(0,y_base+128,256,y_base+128);
dc.DrawLine(128,y_base+0,128,y_base+128);

dc.SetPen(*wxBLACK_PEN);
strncpy0(name,envelope_paths[ix_env],sizeof(name));
dc.DrawText(wxString(name,wxConvLocal),1,y_base);

env = envelope_dat[ix_env];
y_base = y_base+128;
for(x=0; x<127; x++)
{
dc.DrawLine(x*2, y_base-env[x]/2, (x+1)*2, y_base-env[x+1]/2);
}

if(f_txt != NULL)
{
fprintf(f_txt,"%s\n",name);
for(x=0; x<128; x++)
{
fprintf(f_txt," 0x%.2x,",env[x]);
if((x & 0xf) == 0xf)
fputc('\n',f_txt);
}
fputc('\n',f_txt);
}
}

bitmap.SaveFile(path_phsource+_T("/envelopes.png"),wxBITMAP_TYPE_PNG);
if(f_txt != NULL)
fclose(f_txt);
}


Loading…
Cancel
Save