mirror of
https://github.com/rhasspy/espeak-ng.git
synced 2026-11-02 14:04:27 +00:00
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.
This commit is contained in:
+1
-8
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
-2283
File diff suppressed because it is too large
Load Diff
@@ -1,574 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 to 2007 by Jonathan Duddington *
|
||||
* email: jonsd@users.sourceforge.net *
|
||||
* *
|
||||
* 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
|
||||
|
||||
-190
@@ -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
|
||||
|
||||
-174
@@ -1,174 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2005 to 2013 by Jonathan Duddington *
|
||||
* email: jonsd@users.sourceforge.net *
|
||||
* *
|
||||
* 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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2005 to 2007 by Jonathan Duddington *
|
||||
* email: jonsd@users.sourceforge.net *
|
||||
* 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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -1,7 +1,7 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2005 to 2007 by Jonathan Duddington *
|
||||
* email: jonsd@users.sourceforge.net *
|
||||
* 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
|
||||
|
||||
-181
@@ -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;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -1,478 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2005 to 2013 by Jonathan Duddington *
|
||||
* email: jonsd@users.sourceforge.net *
|
||||
* 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
|
||||
@@ -1,299 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2005 to 2007 by Jonathan Duddington *
|
||||
* email: jonsd@users.sourceforge.net *
|
||||
* *
|
||||
* 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
|
||||
|
||||
@@ -1,748 +0,0 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2005 to 2013 by Jonathan Duddington *
|
||||
* email: jonsd@users.sourceforge.net *
|
||||
* 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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user