mirror of
https://github.com/rhasspy/espeak-ng.git
synced 2026-11-11 16:39:15 +00:00
[1.39.28]
Added experimental Klatt synthesizer. Klatt phonemes use a new format of phoneme data. espeakedit, new dialog fields and layout for Klatt phonemes. Added Klatt versions of English phonemes. Fixed some compilation warnings on Windows. Fixed bug in Lettergroups > L10 Increased amplitude of harmonics below F1 peak, to increase bass. Allow 5 (up from 4) pairs of values in "tone" command in voice files. Default to slightly wider pk_shape1. If words are separated by hyphens, don't add word-gap, and don't pass new-word flag onto phoneme processing. git-svn-id: https://espeak.svn.sourceforge.net/svnroot/espeak/trunk@203 d46cf337-b52f-0410-862d-fd96e6ae7743
This commit is contained in:
+78
-36
@@ -597,17 +597,21 @@ int Compile::LoadSpect(const char *path, int control)
|
||||
int peak;
|
||||
int displ;
|
||||
int frame;
|
||||
int n_frames;
|
||||
int ix;
|
||||
int x;
|
||||
int x, x2;
|
||||
int rms;
|
||||
float total;
|
||||
float pkheight;
|
||||
int marker1_set=0;
|
||||
int frame_vowelbreak=0;
|
||||
int klatt_flag=0;
|
||||
SpectFrame *fr;
|
||||
frame_t *fr_out;
|
||||
wxString path_sep = _T("/");
|
||||
|
||||
SPECT_SEQ seq_out;
|
||||
SPECT_SEQK seqk_out;
|
||||
|
||||
// create SpectSeq and import data
|
||||
spectseq = new SpectSeq;
|
||||
@@ -627,11 +631,14 @@ int Compile::LoadSpect(const char *path, int control)
|
||||
}
|
||||
spectseq->Load(stream);
|
||||
|
||||
if(spectseq->synthesizer_type == 1)
|
||||
klatt_flag = FRFLAG_KLATT;
|
||||
|
||||
displ = ftell(f_phdata);
|
||||
|
||||
seq_out.n_frames=0;
|
||||
seq_out.flags=0;
|
||||
seq_out.length=0;
|
||||
seq_out.length_total=0;
|
||||
|
||||
total = 0;
|
||||
for(frame=0; frame < spectseq->numframes; frame++)
|
||||
@@ -669,7 +676,7 @@ for(ix=0; ix<8; ix++)
|
||||
total += spectseq->frames[frame-1]->length;
|
||||
}
|
||||
}
|
||||
seq_out.length = int(total);
|
||||
seq_out.length_total = int(total);
|
||||
|
||||
if((control & 1) && (marker1_set == 0))
|
||||
{
|
||||
@@ -678,68 +685,103 @@ for(ix=0; ix<8; ix++)
|
||||
spectseq->frames[frame_vowelbreak]->markers |= FRFLAG_VOWEL_CENTRE;
|
||||
}
|
||||
|
||||
ix = 0;
|
||||
n_frames = 0;
|
||||
for(frame=0; frame < spectseq->numframes; frame++)
|
||||
{
|
||||
fr = spectseq->frames[frame];
|
||||
|
||||
if(fr->keyframe)
|
||||
{
|
||||
if(klatt_flag)
|
||||
fr_out = &seqk_out.frame[n_frames];
|
||||
else
|
||||
fr_out = (frame_t *)&seq_out.frame[n_frames];
|
||||
|
||||
x = int(fr->length + 0.5); // round to nearest mS
|
||||
if(x > 255) x = 255;
|
||||
seq_out.frame[ix].length = x;
|
||||
fr_out->length = x;
|
||||
|
||||
fr_out->frflags = fr->markers | klatt_flag;
|
||||
|
||||
seq_out.frame[ix].frflags = fr->markers;
|
||||
rms = int(fr->GetRms(spectseq->amplitude));
|
||||
if(rms > 255) rms = 255;
|
||||
seq_out.frame[ix].rms = rms;
|
||||
fr_out->rms = rms;
|
||||
|
||||
if(n_frames == (seq_out.n_frames-1))
|
||||
fr_out->length = 0; // give last frame zero length
|
||||
|
||||
if(ix == (seq_out.n_frames-1))
|
||||
seq_out.frame[ix].length = 0; // give last frame zero length
|
||||
|
||||
// write: peak data
|
||||
count_frames++;
|
||||
for(peak=0; peak<N_PEAKS; peak++)
|
||||
{
|
||||
seq_out.frame[ix].ffreq[peak] = fr->peaks[peak].pkfreq;
|
||||
pkheight = spectseq->amplitude * fr->amp_adjust * fr->peaks[peak].pkheight;
|
||||
pkheight = pkheight/640000;
|
||||
if(pkheight > 255) pkheight = 255;
|
||||
seq_out.frame[ix].fheight[peak] = int(pkheight);
|
||||
fr_out->ffreq[peak] = fr->peaks[peak].pkfreq;
|
||||
|
||||
if(klatt_flag)
|
||||
{
|
||||
pkheight = fr->peaks[peak].pkheight / 128;
|
||||
}
|
||||
else
|
||||
{
|
||||
pkheight = spectseq->amplitude * fr->amp_adjust * fr->peaks[peak].pkheight;
|
||||
pkheight = pkheight/640000;
|
||||
if(pkheight > 255) pkheight = 255;
|
||||
}
|
||||
fr_out->fheight[peak] = int(pkheight);
|
||||
|
||||
if(peak < 6)
|
||||
{
|
||||
x = fr->peaks[peak].pkwidth/4;
|
||||
x = fr->peaks[peak].pkwidth/2;
|
||||
x2 = fr->peaks[peak].pkright;
|
||||
if(klatt_flag == 0)
|
||||
{
|
||||
x /= 2;
|
||||
x2 /= 4;
|
||||
}
|
||||
if(x > 255) x = 255;
|
||||
seq_out.frame[ix].fwidth[peak] = x;
|
||||
fr_out->fwidth[peak] = x;
|
||||
|
||||
x = fr->peaks[peak].pkright/4;
|
||||
if(x > 255) x = 255;
|
||||
seq_out.frame[ix].fright[peak] = x;
|
||||
if(x2 > 255) x2 = 255;
|
||||
fr_out->fright[peak] = x2;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef LOG_DETAIL
|
||||
fprintf(f_errors,"Frame %d %3dmS rms=%3d flags=%2d pk=%4d %4d %4d",ix,seq_out.frame[ix].length,
|
||||
seq_out.frame[ix].rms,seq_out.frame[ix].flags,
|
||||
seq_out.frame[ix].peaks[1].pkfreq,seq_out.frame[ix].peaks[2].pkfreq,seq_out.frame[ix].peaks[3].pkfreq);
|
||||
if(klatt_flag)
|
||||
{
|
||||
if(fr->klatt_param[KLATT_Kopen] == 0)
|
||||
{
|
||||
Error("Klatt_Kopen has value 0");
|
||||
}
|
||||
|
||||
if(fr->markers != 0)
|
||||
{
|
||||
fprintf(f_errors," [%x]",fr->markers);
|
||||
}
|
||||
fputc('\n',f_errors);
|
||||
#endif
|
||||
|
||||
ix++;
|
||||
// additional fields
|
||||
for(ix=0; ix<N_KLATTP; ix++)
|
||||
{
|
||||
fr_out->klattp[ix] = fr->klatt_param[ix];
|
||||
}
|
||||
fr_out->fwidth6 = fr->peaks[6].pkwidth/2;
|
||||
fr_out->fright6 = fr->peaks[6].pkright;
|
||||
}
|
||||
|
||||
n_frames++;
|
||||
}
|
||||
}
|
||||
|
||||
ix = (char *)(&seq_out.frame[seq_out.n_frames]) - (char *)(&seq_out);
|
||||
ix = (ix+3) & 0xfffc; // round up to multiple of 4 bytes
|
||||
if(klatt_flag)
|
||||
{
|
||||
seqk_out.n_frames = seq_out.n_frames;
|
||||
seqk_out.flags = seq_out.flags;
|
||||
seqk_out.length_total = seq_out.length_total;
|
||||
|
||||
ix = (char *)(&seqk_out.frame[seqk_out.n_frames]) - (char *)(&seqk_out);
|
||||
ix = (ix+3) & 0xfffc; // round up to multiple of 4 bytes
|
||||
fwrite(&seqk_out,ix,1,f_phdata);
|
||||
}
|
||||
else
|
||||
{
|
||||
ix = (char *)(&seq_out.frame[seq_out.n_frames]) - (char *)(&seq_out);
|
||||
ix = (ix+3) & 0xfffc; // round up to multiple of 4 bytes
|
||||
fwrite(&seq_out,ix,1,f_phdata);
|
||||
}
|
||||
|
||||
fwrite(&seq_out,ix,1,f_phdata);
|
||||
|
||||
delete spectseq;
|
||||
return(displ);
|
||||
} // end of Compile::LoadSpect
|
||||
|
||||
+1
-1
@@ -1268,7 +1268,7 @@ static int compile_lettergroup(char *input, FILE *f_out)
|
||||
group = atoi(&p[0]);
|
||||
if(group >= N_LETTER_GROUPS)
|
||||
{
|
||||
fprintf(f_log,"%5d: lettergroup out of range (01-%.2d)\n",linenum,N_LETTER_GROUPS);
|
||||
fprintf(f_log,"%5d: lettergroup out of range (01-%.2d)\n",linenum,N_LETTER_GROUPS-1);
|
||||
error_count++;
|
||||
return(1);
|
||||
}
|
||||
|
||||
+1
-1
@@ -232,7 +232,7 @@ wxSashLayoutWindow *win;
|
||||
win = new wxSashLayoutWindow(this, ID_WINDOW_LEFT2,
|
||||
wxDefaultPosition, wxSize(200, 30),
|
||||
wxNO_BORDER | wxSW_3D | wxCLIP_CHILDREN);
|
||||
win->SetDefaultSize(wxSize(208, 1000));
|
||||
win->SetDefaultSize(wxSize(212, 1000));
|
||||
win->SetOrientation(wxLAYOUT_VERTICAL);
|
||||
win->SetAlignment(wxLAYOUT_LEFT);
|
||||
// win->SetBackgroundColour(wxColour(0, 255, 255));
|
||||
|
||||
+117
-32
@@ -43,10 +43,10 @@ ByteGraph *pitchgraph=NULL;
|
||||
BEGIN_EVENT_TABLE(FormantDlg, wxPanel)
|
||||
EVT_BUTTON(T_ZOOMOUT,FormantDlg::OnCommand)
|
||||
EVT_BUTTON(T_ZOOMIN,FormantDlg::OnCommand)
|
||||
EVT_SPINCTRL(T_AMPLITUDE,FormantDlg::OnSpin)
|
||||
EVT_SPINCTRL(T_TIMESEQ,FormantDlg::OnSpin)
|
||||
EVT_SPINCTRL(T_AMPFRAME,FormantDlg::OnSpin)
|
||||
EVT_SPINCTRL(T_TIMEFRAME,FormantDlg::OnSpin)
|
||||
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()
|
||||
|
||||
|
||||
@@ -79,21 +79,19 @@ void FormantDlg::OnSpin(wxSpinEvent& event)
|
||||
|
||||
switch(id = event.GetId())
|
||||
{
|
||||
case T_AMPLITUDE:
|
||||
case T_TIMESEQ:
|
||||
case T_TIMEFRAME:
|
||||
currentcanvas->RefreshDialogValues(0);
|
||||
break;
|
||||
|
||||
case T_AMPFRAME:
|
||||
currentcanvas->RefreshDialogValues(1);
|
||||
break;
|
||||
|
||||
default:
|
||||
currentcanvas->RefreshDialogValues(0);
|
||||
break;
|
||||
}
|
||||
currentcanvas->SetFocus();
|
||||
}
|
||||
|
||||
FormantDlg::FormantDlg(wxWindow *parent) : wxPanel(parent,-1,wxDefaultPosition,wxSize(400,1000))
|
||||
{//==========================================================================
|
||||
{//=============================================================================================
|
||||
int ix;
|
||||
int y;
|
||||
int xplace;
|
||||
@@ -104,6 +102,7 @@ FormantDlg::FormantDlg(wxWindow *parent) : wxPanel(parent,-1,wxDefaultPosition,w
|
||||
xplace = 28;
|
||||
id = 201;
|
||||
new wxStaticText(this,-1,_T("Formants"),wxPoint(4,5));
|
||||
t_lab[4] = new wxStaticText(this,-1,_T(" BW BWp Ap"),wxPoint(78,5),wxSize(300,20));
|
||||
|
||||
for(ix=0; ix<N_PEAKS; ix++)
|
||||
{
|
||||
@@ -115,48 +114,124 @@ FormantDlg::FormantDlg(wxWindow *parent) : wxPanel(parent,-1,wxDefaultPosition,w
|
||||
wxPoint(xplace,y+24*ix),wxSize(48,20),
|
||||
wxTE_CENTRE+wxTE_READONLY);
|
||||
t_pkheight[ix] = new wxTextCtrl(this,id++,_T(""),
|
||||
wxPoint(xplace+52,y+24*ix),wxSize(36,20),
|
||||
wxPoint(xplace+50,y+24*ix),wxSize(36,20),
|
||||
wxTE_CENTRE+wxTE_READONLY);
|
||||
t_pkwidth[ix] = new wxTextCtrl(this,id++,_T(""),
|
||||
wxPoint(xplace+92,y+24*ix),wxSize(48,20),
|
||||
wxPoint(xplace+88,y+24*ix),wxSize(48,20),
|
||||
wxTE_CENTRE+wxTE_READONLY);
|
||||
#ifdef WIDTH2
|
||||
t_pkright[ix] = new wxTextCtrl(this,id++,_T(""),
|
||||
wxPoint(xplace+132,y+24*ix),wxSize(36,20),
|
||||
wxPoint(xplace+138,y+24*ix),wxSize(36,20),
|
||||
wxTE_CENTRE+wxTE_READONLY);
|
||||
#endif
|
||||
if(ix>5) t_pkwidth[ix]->Hide();
|
||||
}
|
||||
|
||||
t_ampframe = new wxSpinCtrl(this,T_AMPFRAME,_T(""),
|
||||
wxPoint(6,244),wxSize(52,24),wxTE_CENTRE,0,500);
|
||||
t_lab[3] = new wxStaticText(this,-1,_T("% amp - Frame"),wxPoint(61,248));
|
||||
t_timeframe = new wxSpinCtrl(this,T_TIMEFRAME,_T(""),
|
||||
wxPoint(6,272),wxSize(52,24),wxTE_CENTRE,0,500);
|
||||
t_orig_frame = new wxStaticText(this,-1,_T("mS"),wxPoint(61,276));
|
||||
y=240;
|
||||
t_timeframe = new wxSpinCtrl(this,T_TIMEFRAME,_T(""), wxPoint(6,y+0), wxSize(52,24), wxTE_CENTRE,0,500);
|
||||
t_orig_frame = new wxStaticText(this,-1,_T("mS"),wxPoint(57,y+8));
|
||||
t_ampframe = new wxSpinCtrl(this,T_AMPFRAME,_T(""), wxPoint(100,y+0), wxSize(52,24), wxTE_CENTRE,0,500);
|
||||
t_lab[3] = new wxStaticText(this,-1,_T("% amp - Frame"),wxPoint(151,y+8));
|
||||
|
||||
t_zoomout = new wxButton(this,T_ZOOMOUT,_T("Zoom-"),wxPoint(16,310));
|
||||
t_zoomin = new wxButton(this,T_ZOOMIN,_T("Zoom+"),wxPoint(106,310));
|
||||
s_klatt[KLATT_AV] = new wxSpinCtrl(this,T_AV,_T(""), wxPoint(6,y+32), wxSize(52,24), wxTE_CENTRE,0,500);
|
||||
t_klatt[KLATT_AV] = new wxStaticText(this,-1,_T("AV"),wxPoint(61,y+36));
|
||||
s_klatt[KLATT_AVp] = new wxSpinCtrl(this,T_AVP,_T(""), wxPoint(100,y+32), wxSize(52,24), wxTE_CENTRE,0,500);
|
||||
t_klatt[KLATT_AVp] = new wxStaticText(this,-1,_T("AVp"),wxPoint(155,y+36));
|
||||
|
||||
s_klatt[KLATT_Fric] = new wxSpinCtrl(this,T_FRIC,_T(""), wxPoint(6,y+60), wxSize(52,24), wxTE_CENTRE,0,500);
|
||||
t_klatt[KLATT_Fric] = new wxStaticText(this,-1,_T("Fric"),wxPoint(61,y+64));
|
||||
s_klatt[KLATT_FricBP] = new wxSpinCtrl(this,T_FRICBP,_T(""), wxPoint(100,y+60), wxSize(52,24), wxTE_CENTRE,0,500);
|
||||
t_klatt[KLATT_FricBP] = new wxStaticText(this,-1,_T("FricBP"),wxPoint(155,y+64));
|
||||
|
||||
s_klatt[KLATT_Aspr] = new wxSpinCtrl(this,T_ASPR,_T(""), wxPoint(6,y+88), wxSize(52,24), wxTE_CENTRE,0,500);
|
||||
t_klatt[KLATT_Aspr] = new wxStaticText(this,-1,_T("Aspr"),wxPoint(61,y+92));
|
||||
s_klatt[KLATT_Turb] = new wxSpinCtrl(this,T_TURB,_T(""), wxPoint(100,y+88), wxSize(52,24), wxTE_CENTRE,0,500);
|
||||
t_klatt[KLATT_Turb] = new wxStaticText(this,-1,_T("Turb"),wxPoint(155,y+92));
|
||||
|
||||
s_klatt[KLATT_Skew] = new wxSpinCtrl(this,T_SKEW,_T(""), wxPoint(6,y+116), wxSize(52,24), wxTE_CENTRE,0,500);
|
||||
t_klatt[KLATT_Skew] = new wxStaticText(this,-1,_T("Skew"),wxPoint(61,y+120));
|
||||
s_klatt[KLATT_Tilt] = new wxSpinCtrl(this,T_TILT,_T(""), wxPoint(100,y+116), wxSize(52,24), wxTE_CENTRE,0,500);
|
||||
t_klatt[KLATT_Tilt] = new wxStaticText(this,-1,_T("Tilt"),wxPoint(155,y+120));
|
||||
|
||||
s_klatt[KLATT_Kopen] = new wxSpinCtrl(this,T_KOPEN,_T(""), wxPoint(6,y+144), wxSize(52,24), wxTE_CENTRE,0,500);
|
||||
t_klatt[KLATT_Kopen] = new wxStaticText(this,-1,_T("kopen"),wxPoint(61,y+148));
|
||||
|
||||
|
||||
// usepitchenv = new wxCheckBox(this,T_USEPITCHENV,_T("???"),wxPoint(20,320));
|
||||
t_zoomout = new wxButton(this,T_ZOOMOUT,_T("Zoom-"),wxPoint(16,420));
|
||||
t_zoomin = new wxButton(this,T_ZOOMIN,_T("Zoom+"),wxPoint(106,420));
|
||||
|
||||
y=468;
|
||||
t_amplitude = new wxSpinCtrl(this,T_AMPLITUDE,_T(""),
|
||||
wxPoint(6,370),wxSize(52,24),wxTE_CENTRE,0,500);
|
||||
t_lab[2] = new wxStaticText(this,-1,_T("% amp - Sequence"),wxPoint(61,374));
|
||||
wxPoint(6,y),wxSize(52,24),wxTE_CENTRE,0,y+130);
|
||||
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,404));
|
||||
t_orig_seq = new wxStaticText(this,-1,_T("mS"),wxPoint(61,y+30));
|
||||
|
||||
t_pitch = new wxStaticText(this,-1,_T(""),wxPoint(4,440),wxSize(192,24));
|
||||
t_pitch = new wxStaticText(this,-1,_T(""),wxPoint(4,520),wxSize(192,24));
|
||||
|
||||
pitchgraph = new ByteGraph(this,wxPoint(0,460),wxSize(200,140));
|
||||
pitchgraph = new ByteGraph(this,wxPoint(0,538),wxSize(200,140));
|
||||
pitchgraph->SetData(128,env_fall);
|
||||
pitchgraph->ShowSpectrum(1);
|
||||
pitchgraph->Show();
|
||||
}
|
||||
|
||||
|
||||
void FormantDlg::HideFields(int synth_type)
|
||||
{//=======================================
|
||||
int ix;
|
||||
static int prev_synth_type = -1;
|
||||
|
||||
if(synth_type == prev_synth_type)
|
||||
return; // no change
|
||||
|
||||
if(synth_type == 0)
|
||||
{
|
||||
for(ix=0; ix<9; ix++)
|
||||
{
|
||||
s_klatt[ix]->Hide();
|
||||
t_klatt[ix]->Hide();
|
||||
}
|
||||
for(ix=6; ix<9; ix++)
|
||||
{
|
||||
t_pkfreq[ix]->Show();
|
||||
t_pkheight[ix]->Show();
|
||||
t_pkwidth[ix]->Hide();
|
||||
t_pkright[ix]->Hide();
|
||||
}
|
||||
t_ampframe->Show();
|
||||
t_amplitude->Show();
|
||||
t_lab[2]->Show();
|
||||
t_lab[3]->Show();
|
||||
t_labpk[7]->Show();
|
||||
t_labpk[8]->Show();
|
||||
t_lab[4]->Hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
for(ix=0; ix<9; ix++)
|
||||
{
|
||||
s_klatt[ix]->Show();
|
||||
t_klatt[ix]->Show();
|
||||
}
|
||||
for(ix=7; ix<9; ix++)
|
||||
{
|
||||
t_pkfreq[ix]->Hide();
|
||||
t_pkheight[ix]->Hide();
|
||||
t_pkwidth[ix]->Hide();
|
||||
t_pkright[ix]->Hide();
|
||||
}
|
||||
t_pkwidth[6]->Show(1);
|
||||
t_pkright[6]->Show(1);
|
||||
t_ampframe->Hide();
|
||||
t_amplitude->Hide();
|
||||
t_lab[2]->Hide();
|
||||
t_lab[3]->Hide();
|
||||
t_labpk[7]->Hide();
|
||||
t_labpk[8]->Hide();
|
||||
t_lab[4]->Show();
|
||||
}
|
||||
prev_synth_type = synth_type;
|
||||
}
|
||||
|
||||
|
||||
void FormantDlg::ShowFrame(SpectSeq *spectseq, int frame, int pk, int field)
|
||||
{//==============================================================
|
||||
@@ -169,6 +244,8 @@ void FormantDlg::ShowFrame(SpectSeq *spectseq, int frame, int pk, int field)
|
||||
return;
|
||||
sf = spectseq->frames[frame];
|
||||
|
||||
HideFields(spectseq->synthesizer_type);
|
||||
|
||||
if(field == 0xff)
|
||||
{
|
||||
// indicate the selected peak
|
||||
@@ -203,10 +280,8 @@ void FormantDlg::ShowFrame(SpectSeq *spectseq, int frame, int pk, int field)
|
||||
{
|
||||
value.Printf(_T("%3d"),sf->peaks[ix].pkwidth);
|
||||
t_pkwidth[ix]->SetValue(value);
|
||||
#ifdef WIDTH2
|
||||
value.Printf(_T("%3d"),sf->peaks[ix].pkright);
|
||||
t_pkright[ix]->SetValue(value);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,6 +291,16 @@ void FormantDlg::ShowFrame(SpectSeq *spectseq, int frame, int pk, int field)
|
||||
t_orig_frame->SetLabel(value);
|
||||
value.Printf(_T("%3d"),sf->amp_adjust);
|
||||
t_ampframe->SetValue(value);
|
||||
|
||||
if(spectseq->synthesizer_type == 1)
|
||||
{
|
||||
for(ix=0; ix<9; ix++)
|
||||
{
|
||||
SetSpinCtrl(s_klatt[ix], sf->klatt_param[ix]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // end of FormantDlg::ShowFrame
|
||||
|
||||
|
||||
|
||||
+1282
File diff suppressed because it is too large
Load Diff
+138
@@ -0,0 +1,138 @@
|
||||
|
||||
|
||||
#define CASCADE_PARALLEL 1 /* Type of synthesis model */
|
||||
#define ALL_PARALLEL 2
|
||||
|
||||
#define IMPULSIVE 1 /* Type of voicing source */
|
||||
#define NATURAL 2
|
||||
#define SAMPLED 3
|
||||
|
||||
#define PI 3.1415927
|
||||
|
||||
|
||||
/* typedef's that need to be exported */
|
||||
|
||||
typedef long flag;
|
||||
|
||||
/* Resonator Structure */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double a;
|
||||
double b;
|
||||
double c;
|
||||
double p1;
|
||||
double p2;
|
||||
double a_inc;
|
||||
double b_inc;
|
||||
double c_inc;
|
||||
} resonator_t, *resonator_ptr;
|
||||
|
||||
/* Structure for Klatt Globals */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
flag synthesis_model; /* cascade-parallel or all-parallel */
|
||||
flag outsl; /* Output waveform selector */
|
||||
long samrate; /* Number of output samples per second */
|
||||
long FLPhz ; /* Frequeny of glottal downsample low-pass filter */
|
||||
long BLPhz ; /* Bandwidth of glottal downsample low-pass filter */
|
||||
flag glsource; /* Type of glottal source */
|
||||
int f0_flutter; /* Percentage of f0 flutter 0-100 */
|
||||
long nspfr; /* number of samples per frame */
|
||||
long nper; /* Counter for number of samples in a pitch period */
|
||||
long ns;
|
||||
long T0; /* Fundamental period in output samples times 4 */
|
||||
long nopen; /* Number of samples in open phase of period */
|
||||
long nmod; /* Position in period to begin noise amp. modul */
|
||||
long nrand; /* Varible used by random number generator */
|
||||
double pulse_shape_a; /* Makes waveshape of glottal pulse when open */
|
||||
double pulse_shape_b; /* Makes waveshape of glottal pulse when open */
|
||||
double minus_pi_t;
|
||||
double two_pi_t;
|
||||
double onemd;
|
||||
double decay;
|
||||
double amp_bypas; /* AB converted to linear gain */
|
||||
double amp_voice; /* AVdb converted to linear gain */
|
||||
double par_amp_voice; /* AVpdb converted to linear gain */
|
||||
double amp_aspir; /* AP converted to linear gain */
|
||||
double amp_frica; /* AF converted to linear gain */
|
||||
double amp_breth; /* ATURB converted to linear gain */
|
||||
double amp_gain0; /* G0 converted to linear gain */
|
||||
int num_samples; /* number of glottal samples */
|
||||
double sample_factor; /* multiplication factor for glottal samples */
|
||||
short *natural_samples; /* pointer to an array of glottal samples */
|
||||
long original_f0; /* original value of f0 not modified by flutter */
|
||||
|
||||
int fadeout; // set to 64 to cause fadeout over 64 samples
|
||||
int scale_wav; // depends on the voicing source
|
||||
|
||||
#define N_RSN 20
|
||||
#define Rnpc 0
|
||||
#define R1c 1
|
||||
#define R2c 2
|
||||
#define R3c 3
|
||||
#define R4c 4
|
||||
#define R5c 5
|
||||
#define R6c 6
|
||||
#define R7c 7
|
||||
#define R8c 8
|
||||
#define Rnz 9
|
||||
|
||||
#define Rparallel 10
|
||||
#define Rnpp 10
|
||||
#define R1p 11
|
||||
#define R2p 12
|
||||
#define R3p 13
|
||||
#define R4p 14
|
||||
#define R5p 15
|
||||
#define R6p 16
|
||||
|
||||
#define RGL 17
|
||||
#define RLP 18
|
||||
#define Rout 19
|
||||
|
||||
resonator_t rsn[N_RSN]; // internal storage for resonators
|
||||
resonator_t rsn_next[N_RSN];
|
||||
|
||||
} klatt_global_t, *klatt_global_ptr;
|
||||
|
||||
/* Structure for Klatt Parameters */
|
||||
|
||||
#define F_NP 0 // nasal zero formant
|
||||
#define F1 1
|
||||
#define F2 2
|
||||
#define F3 3
|
||||
#define F4 4
|
||||
#define F5 5
|
||||
#define F6 6
|
||||
#define F_NZ 9 // nasal pole formant
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
long F0hz10; /* Voicing fund freq in Hz */
|
||||
long AVdb; /* Amp of voicing in dB, 0 to 70 */
|
||||
int Fhz[10]; // formant Hz, F_NZ to F6 to F_NP
|
||||
int Bhz[10];
|
||||
int Ap[10]; /* Amp of parallel formants in dB, 0 to 80 */
|
||||
int Bphz[10]; /* Parallel formants bw in Hz, 40 to 1000 */
|
||||
|
||||
long ASP; /* Amp of aspiration in dB, 0 to 70 */
|
||||
long Kopen; /* # of samples in open period, 10 to 65 */
|
||||
long Aturb; /* Breathiness in voicing, 0 to 80 */
|
||||
long TLTdb; /* Voicing spectral tilt in dB, 0 to 24 */
|
||||
long AF; /* Amp of frication in dB, 0 to 80 */
|
||||
long Kskew; /* Skewness of alternate periods, 0 to 40 in sample#/2 */
|
||||
|
||||
long AB; /* Amp of bypass fric. in dB, 0 to 80 */
|
||||
long AVpdb; /* Amp of voicing, par in dB, 0 to 70 */
|
||||
long Gain0; /* Overall gain, 60 dB is unity, 0 to 60 */
|
||||
|
||||
long AVdb_tmp; //copy of AVdb, which is changed within parwave()
|
||||
int Fhz_next[10]; // Fhz for the next chunk, so we can do interpolation of resonator (a,b,c) parameters
|
||||
int Bhz_next[10];
|
||||
} klatt_frame_t, *klatt_frame_ptr;
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -1186,7 +1186,7 @@ static int attr_prosody_value(int param_type, const wchar_t *pw, int *value_out)
|
||||
pw++;
|
||||
sign = -1;
|
||||
}
|
||||
value = wcstod(pw,&tail);
|
||||
value = (float)wcstod(pw,&tail);
|
||||
if(tail == pw)
|
||||
{
|
||||
// failed to find a number, return 100%
|
||||
|
||||
+2
-2
@@ -300,10 +300,10 @@ static void init_path(const char *path)
|
||||
}
|
||||
|
||||
buf[0] = 0;
|
||||
RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Speech\\Voices\\Tokens\\eSpeak", 0, KEY_READ, &RegKey);
|
||||
RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Speech\\Voices\\Tokens\\eSpeak", 0, KEY_READ, &RegKey);
|
||||
size = sizeof(buf);
|
||||
var_type = REG_SZ;
|
||||
RegQueryValueEx(RegKey, "path", 0, &var_type, buf, &size);
|
||||
RegQueryValueExA(RegKey, "path", 0, &var_type, buf, &size);
|
||||
|
||||
sprintf(path_home,"%s\\espeak-data",buf);
|
||||
|
||||
|
||||
+113
-8
@@ -137,7 +137,8 @@ int SpectFrame::Import(wxInputStream& stream1)
|
||||
double x;
|
||||
unsigned short *spect_data;
|
||||
|
||||
wxTextInputStream stream(stream1);
|
||||
synthesizer_type = 0;
|
||||
wxTextInputStream stream(stream1);
|
||||
|
||||
stream >> time;
|
||||
stream >> pitch;
|
||||
@@ -273,12 +274,13 @@ int SpectFrame::ImportSPC2(wxInputStream& stream, float &time_acc)
|
||||
|
||||
|
||||
|
||||
int SpectFrame::Load(wxInputStream& stream)
|
||||
{//========================================
|
||||
int SpectFrame::Load(wxInputStream& stream, int synth_type)
|
||||
{//========================================================
|
||||
int ix;
|
||||
int x;
|
||||
unsigned short *spect_data;
|
||||
|
||||
synthesizer_type = synth_type;
|
||||
wxDataInputStream s(stream);
|
||||
|
||||
time = s.ReadDouble();
|
||||
@@ -300,6 +302,14 @@ int SpectFrame::Load(wxInputStream& stream)
|
||||
peaks[ix].pkright = s.Read16();
|
||||
}
|
||||
|
||||
if(synthesizer_type == 1)
|
||||
{
|
||||
for(ix=0; ix<N_KLATTP; ix++)
|
||||
{
|
||||
klatt_param[ix] = s.Read16();
|
||||
}
|
||||
}
|
||||
|
||||
spect_data = new USHORT[nx];
|
||||
|
||||
if(spect_data == NULL)
|
||||
@@ -324,7 +334,7 @@ int SpectFrame::Save(wxOutputStream& stream)
|
||||
{//=========================================
|
||||
int ix;
|
||||
|
||||
wxDataOutputStream s(stream);
|
||||
wxDataOutputStream s(stream);
|
||||
|
||||
s.WriteDouble(time);
|
||||
s.WriteDouble(pitch);
|
||||
@@ -345,6 +355,14 @@ int SpectFrame::Save(wxOutputStream& stream)
|
||||
s.Write16(peaks[ix].pkright);
|
||||
}
|
||||
|
||||
if(synthesizer_type == 1)
|
||||
{
|
||||
for(ix=0; ix<N_KLATTP; ix++)
|
||||
{
|
||||
s.Write16(klatt_param[ix]);
|
||||
}
|
||||
}
|
||||
|
||||
for(ix=0; ix<nx; ix++)
|
||||
{
|
||||
s.Write16(spect[ix]);
|
||||
@@ -367,6 +385,7 @@ void SpectFrame::ZeroPeaks()
|
||||
void SpectFrame::CopyPeaks(SpectFrame *sf)
|
||||
{//=======================================
|
||||
memcpy(peaks,sf->peaks,sizeof(peaks));
|
||||
memcpy(klatt_param, sf->klatt_param, sizeof(klatt_param));
|
||||
keyframe = sf->keyframe;
|
||||
}
|
||||
|
||||
@@ -448,6 +467,9 @@ void SpectFrame::DrawPeaks(wxDC *dc, int offy, int frame_width, int seq_amplitud
|
||||
int y1, y2;
|
||||
double yy;
|
||||
int max_ix;
|
||||
int height;
|
||||
int pkright;
|
||||
int pkwidth;
|
||||
int buf[DRAWPEAKWIDTH*2];
|
||||
|
||||
max_ix = int(9000 * scale_x);
|
||||
@@ -459,9 +481,24 @@ void SpectFrame::DrawPeaks(wxDC *dc, int offy, int frame_width, int seq_amplitud
|
||||
|
||||
if((pk->pkfreq == 0) || (pk->pkheight==0)) continue;
|
||||
|
||||
if(synthesizer_type==1)
|
||||
{
|
||||
if(peak==0) continue;
|
||||
|
||||
height = pk->pkheight + (64 * 64);
|
||||
height = (500000/height) * 100;
|
||||
pkright = pkwidth = pk->pkheight / 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
height = pk->pkheight;
|
||||
pkright = pk->pkright;
|
||||
pkwidth = pk->pkwidth;
|
||||
}
|
||||
|
||||
x1 = (int)(pk->pkfreq*scale_x);
|
||||
x2 = (int)((pk->pkfreq + pk->pkright)*scale_x);
|
||||
x3 = (int)((pk->pkfreq - pk->pkwidth)*scale_x);
|
||||
x2 = (int)((pk->pkfreq + pkright)*scale_x);
|
||||
x3 = (int)((pk->pkfreq - pkwidth)*scale_x);
|
||||
|
||||
if(x3 >= DRAWPEAKWIDTH)
|
||||
continue; // whole peak is off the scale
|
||||
@@ -469,7 +506,7 @@ void SpectFrame::DrawPeaks(wxDC *dc, int offy, int frame_width, int seq_amplitud
|
||||
if((width = x2-x1) <= 0) continue;
|
||||
for(ix=0; ix<width; ix++)
|
||||
{
|
||||
buf[x1+ix] += pk->pkheight * pk_shape1[(ix*PEAKSHAPEW)/width];
|
||||
buf[x1+ix] += height * pk_shape1[(ix*PEAKSHAPEW)/width];
|
||||
}
|
||||
|
||||
if((width = x1-x3) <= 0) continue;
|
||||
@@ -477,7 +514,7 @@ void SpectFrame::DrawPeaks(wxDC *dc, int offy, int frame_width, int seq_amplitud
|
||||
{
|
||||
if(x3+ix >= 0)
|
||||
{
|
||||
buf[x3+ix] += pk->pkheight * pk_shape1[((width-ix)*PEAKSHAPEW)/width];
|
||||
buf[x3+ix] += height * pk_shape1[((width-ix)*PEAKSHAPEW)/width];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -633,3 +670,71 @@ void SpectFrame::Draw(wxDC& dc, int offy, int frame_width, double scalex, double
|
||||
|
||||
} // end of SpectFrame::Draw
|
||||
|
||||
|
||||
void SpectFrame::KlattDefaults()
|
||||
{//============================
|
||||
// set default values for Klatt parameters
|
||||
int pk;
|
||||
int bw;
|
||||
int bw3;
|
||||
|
||||
synthesizer_type = 1;
|
||||
|
||||
klatt_param[KLATT_AV] = 59;
|
||||
klatt_param[KLATT_AVp] = 0;
|
||||
klatt_param[KLATT_Fric] = 0;
|
||||
klatt_param[KLATT_FricBP] = 0;
|
||||
klatt_param[KLATT_Aspr] = 0;
|
||||
klatt_param[KLATT_Turb] = 0;
|
||||
klatt_param[KLATT_Skew] = 0;
|
||||
klatt_param[KLATT_Tilt] = 0;
|
||||
klatt_param[KLATT_Kopen] = 40;
|
||||
klatt_param[KLATT_spare1] = 0;
|
||||
|
||||
bw = 60;
|
||||
if(peaks[1].pkfreq < 400)
|
||||
bw = 55;
|
||||
if(peaks[1].pkfreq > 600)
|
||||
bw = 70;
|
||||
if(peaks[1].pkfreq > 650)
|
||||
bw = 80;
|
||||
if(peaks[1].pkfreq > 750)
|
||||
bw = 90;
|
||||
peaks[1].pkwidth = bw;
|
||||
|
||||
bw = 90;
|
||||
bw3 = 150;
|
||||
if(peaks[2].pkfreq < 1000)
|
||||
{
|
||||
bw = 80;
|
||||
bw3 = 120;
|
||||
}
|
||||
if(peaks[2].pkfreq > 1600)
|
||||
{
|
||||
bw = 100;
|
||||
bw3 = 200;
|
||||
}
|
||||
if(peaks[2].pkfreq > 2000)
|
||||
{
|
||||
bw = 110;
|
||||
bw3 = 250;
|
||||
}
|
||||
peaks[2].pkwidth = bw;
|
||||
peaks[3].pkwidth = bw3;
|
||||
peaks[4].pkwidth = 200;
|
||||
peaks[5].pkwidth = 200;
|
||||
peaks[6].pkwidth = 500;
|
||||
peaks[0].pkfreq = 280; // FNP
|
||||
peaks[0].pkwidth = 280; // FNZ
|
||||
|
||||
peaks[7].pkfreq = 7800;
|
||||
peaks[7].pkwidth = 0;
|
||||
peaks[8].pkfreq = 9000;
|
||||
peaks[8].pkwidth = 0;
|
||||
|
||||
for(pk=0; pk<=8; pk++)
|
||||
{
|
||||
peaks[pk].pkheight = peaks[pk].pkwidth << 6;
|
||||
peaks[pk].pkright = 0;
|
||||
}
|
||||
}
|
||||
|
||||
+29
-6
@@ -39,8 +39,20 @@
|
||||
#define T_TIMEFRAME 310
|
||||
#define T_TIMESEQ 311
|
||||
|
||||
#define T_AV 312
|
||||
#define T_AVP 313
|
||||
#define T_FRIC 314
|
||||
#define T_FRICBP 315
|
||||
#define T_ASPR 316
|
||||
#define T_TURB 317
|
||||
#define T_SKEW 318
|
||||
#define T_TILT 319
|
||||
#define T_KOPEN 320
|
||||
|
||||
|
||||
#define FILEID1_SPECTSEQ 0x43455053
|
||||
#define FILEID2_SPECTSEQ 0x51455354
|
||||
#define FILEID2_SPECTSEQ 0x51455354 // for eSpeak sequence
|
||||
#define FILEID2_SPECTSEK 0x4b455354 // for Klatt sequence
|
||||
|
||||
#define FILEID1_SPC2 0x32435053 // an old format for spectrum files
|
||||
|
||||
@@ -110,7 +122,7 @@ public:
|
||||
~SpectFrame();
|
||||
int Import(wxInputStream &stream);
|
||||
int ImportSPC2(wxInputStream &stream, float &time_acc);
|
||||
int Load(wxInputStream &stream);
|
||||
int Load(wxInputStream &stream, int synthesizer_type);
|
||||
int Save(wxOutputStream &stream);
|
||||
void Draw(wxDC &dc, int offy, int frame_width, double scalex, double scaley);
|
||||
|
||||
@@ -122,6 +134,7 @@ public:
|
||||
void MakeWave(int peaks, PitchEnvelope &pitch, int amplitude, int duration);
|
||||
void MakeHtab(int numh, int *htab, int pitch);
|
||||
double GetRms(int amp);
|
||||
void KlattDefaults();
|
||||
|
||||
int selected;
|
||||
int keyframe;
|
||||
@@ -136,8 +149,11 @@ public:
|
||||
int nx;
|
||||
int markers;
|
||||
int max_y;
|
||||
int synthesizer_type; // 0=eSpeak, 1=Klatt
|
||||
USHORT *spect; // sqrt of harmonic amplitudes, 1-nx at 'pitch'
|
||||
|
||||
short klatt_param[N_KLATTP];
|
||||
|
||||
formant_t formants[N_PEAKS]; // this is just the estimate given by Praat
|
||||
peak_t peaks[N_PEAKS];
|
||||
|
||||
@@ -171,7 +187,8 @@ public:
|
||||
float GetKeyedLength();
|
||||
void SetFrameLengths();
|
||||
void ConstructVowel(void);
|
||||
|
||||
void SetKlattDefaults(void);
|
||||
|
||||
int numframes;
|
||||
int amplitude;
|
||||
int spare;
|
||||
@@ -186,6 +203,8 @@ public:
|
||||
int bass_reduction;
|
||||
int max_x;
|
||||
int max_y;
|
||||
int synthesizer_type;
|
||||
|
||||
|
||||
private:
|
||||
void Load2(wxInputStream& stream, int import, int n);
|
||||
@@ -262,8 +281,9 @@ class FormantDlg : public wxPanel
|
||||
public:
|
||||
FormantDlg(wxWindow *parent);
|
||||
void ShowFrame(SpectSeq *spectseq, int frame, int pk, int field);
|
||||
void OnCommand(wxCommandEvent& event);
|
||||
void OnSpin(wxSpinEvent& event);
|
||||
void OnCommand(wxCommandEvent& event);
|
||||
void OnSpin(wxSpinEvent& event);
|
||||
void HideFields(int synth_type);
|
||||
|
||||
wxCheckBox *usepitchenv;
|
||||
|
||||
@@ -275,6 +295,9 @@ class FormantDlg : public wxPanel
|
||||
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];
|
||||
@@ -346,7 +369,7 @@ extern void WavegenInit(int samplerate, int wavemult_fact);
|
||||
extern void WavegenInitPkData(int); // initialise envelope data
|
||||
extern 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();
|
||||
extern void MakeWaveFile(int synthesis_method);
|
||||
extern void MakeWaveBuf(int length, UCHAR *buf);
|
||||
|
||||
extern int OpenWaveFile(const char *path, int samplerate);
|
||||
|
||||
+69
-25
@@ -244,10 +244,19 @@ void SpectDisplay::ReadDialogValues()
|
||||
void SpectDisplay::RefreshDialogValues(int type)
|
||||
//{=============================================
|
||||
{
|
||||
int ix;
|
||||
SpectFrame *sf;
|
||||
|
||||
sf = spectseq->frames[sframe];
|
||||
|
||||
spectseq->amplitude = formantdlg->t_amplitude->GetValue();
|
||||
spectseq->frames[sframe]->amp_adjust = formantdlg->t_ampframe->GetValue();
|
||||
spectseq->frames[sframe]->length_adjust =
|
||||
formantdlg->t_timeframe->GetValue() - spectseq->GetFrameLength(sframe,0,NULL);
|
||||
sf->amp_adjust = formantdlg->t_ampframe->GetValue();
|
||||
sf->length_adjust = formantdlg->t_timeframe->GetValue() - spectseq->GetFrameLength(sframe,0,NULL);
|
||||
|
||||
for(ix=0; ix<9; ix++)
|
||||
{
|
||||
sf->klatt_param[ix] = formantdlg->s_klatt[ix]->GetValue();
|
||||
}
|
||||
|
||||
if(type==0)
|
||||
{
|
||||
@@ -472,7 +481,7 @@ void SpectDisplay::OnMenu(wxCommandEvent& event)
|
||||
int code;
|
||||
wxKeyEvent keyevent;
|
||||
SpectFrame *sf;
|
||||
static int key[] = {0x1044,0x3044,0x104e,0x1047,0x105a,0x1051,0x3051,WXK_F1,WXK_F2,0x1049,WXK_F10};
|
||||
static int key[] = {0x1044,0x3044,0x104e,0x1047,0x105a,0x1051,0x3051,WXK_F1,WXK_F2,0x1049,WXK_F10,0x104b};
|
||||
|
||||
id = event.GetId();
|
||||
|
||||
@@ -624,13 +633,19 @@ void SpectDisplay::OnKey(wxKeyEvent& event)
|
||||
if(event.ControlDown())
|
||||
{
|
||||
// CTRL, rotate, make right slope steeper
|
||||
pk->pkright-= 5;
|
||||
if(spectseq->synthesizer_type==0)
|
||||
pk->pkright-= 5;
|
||||
pk->pkwidth += 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
pk->pkright -= 10;
|
||||
if(spectseq->synthesizer_type==0)
|
||||
pk->pkright -= 10;
|
||||
pk->pkwidth -= 10;
|
||||
if(pk->pkright < 0)
|
||||
pk->pkright = 0;
|
||||
if(pk->pkwidth < 0)
|
||||
pk->pkwidth = 0;
|
||||
}
|
||||
field = 4;
|
||||
display = 1;
|
||||
@@ -640,12 +655,14 @@ void SpectDisplay::OnKey(wxKeyEvent& event)
|
||||
if(event.ControlDown())
|
||||
{
|
||||
// CTRL: rotate, make left slope steeper
|
||||
pk->pkright += 5;
|
||||
if(spectseq->synthesizer_type==0)
|
||||
pk->pkright += 5;
|
||||
pk->pkwidth -= 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
pk->pkright += 10;
|
||||
if(spectseq->synthesizer_type==0)
|
||||
pk->pkright += 10;
|
||||
pk->pkwidth += 10;
|
||||
}
|
||||
field = 4;
|
||||
@@ -653,19 +670,37 @@ void SpectDisplay::OnKey(wxKeyEvent& event)
|
||||
break;
|
||||
|
||||
case '<': // width--
|
||||
pk->pkright -= 2;
|
||||
if(spectseq->synthesizer_type==0)
|
||||
pk->pkright -= 2;
|
||||
pk->pkwidth -= 2;
|
||||
if(pk->pkwidth < 0)
|
||||
pk->pkwidth = 0;
|
||||
display = 1;
|
||||
field = 4;
|
||||
break;
|
||||
|
||||
case '>': // width++
|
||||
pk->pkright += 2;
|
||||
if(spectseq->synthesizer_type==0)
|
||||
pk->pkright += 2;
|
||||
pk->pkwidth += 2;
|
||||
display = 1;
|
||||
field = 4;
|
||||
break;
|
||||
|
||||
case '[': // width--
|
||||
pk->pkright -= 1;
|
||||
if(pk->pkright < 0)
|
||||
pk->pkright = 0;
|
||||
display = 1;
|
||||
field = 4;
|
||||
break;
|
||||
|
||||
case ']': // width++
|
||||
pk->pkright += 1;
|
||||
display = 1;
|
||||
field = 4;
|
||||
break;
|
||||
|
||||
case '/': // make left=right
|
||||
i = pk->pkwidth + pk->pkright;
|
||||
pk->pkwidth = pk->pkright = i/2;
|
||||
@@ -708,6 +743,11 @@ void SpectDisplay::OnKey(wxKeyEvent& event)
|
||||
display = 2;
|
||||
break;
|
||||
|
||||
case 0x104b: // CTRL-K
|
||||
spectseq->SetKlattDefaults();
|
||||
display = 3;
|
||||
break;
|
||||
|
||||
case 0x104d: // CTRL-M
|
||||
sf->ToggleMarker(1);
|
||||
display = 2;
|
||||
@@ -825,25 +865,28 @@ void SpectDisplay::OnKey(wxKeyEvent& event)
|
||||
sf = spectseq->frames[sframe];
|
||||
pk = &sf->peaks[pk_num];
|
||||
|
||||
if(pk->pkwidth < 50) pk->pkwidth = 50; // min. width
|
||||
if(pk->pkright < 50) pk->pkright = 50;
|
||||
if(spectseq->synthesizer_type==0)
|
||||
{
|
||||
if(pk->pkwidth < 50) pk->pkwidth = 50; // min. width
|
||||
if(pk->pkright < 50) pk->pkright = 50;
|
||||
|
||||
// ensure minimum separation between peaks & prevent crossover
|
||||
if(direction > 0)
|
||||
{
|
||||
for(i=pk_num+1; i<N_PEAKS; i++)
|
||||
// ensure minimum separation between peaks & prevent crossover
|
||||
if(direction > 0)
|
||||
{
|
||||
if(sf->peaks[i].pkfreq < sf->peaks[i-1].pkfreq + 100)
|
||||
sf->peaks[i].pkfreq = sf->peaks[i-1].pkfreq + 100;
|
||||
for(i=pk_num+1; i<N_PEAKS; i++)
|
||||
{
|
||||
if(sf->peaks[i].pkfreq < sf->peaks[i-1].pkfreq + 100)
|
||||
sf->peaks[i].pkfreq = sf->peaks[i-1].pkfreq + 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if(direction < 0)
|
||||
{
|
||||
for(i=pk_num-1; i>=0; i--)
|
||||
else
|
||||
if(direction < 0)
|
||||
{
|
||||
if(sf->peaks[i].pkfreq > sf->peaks[i+1].pkfreq - 100)
|
||||
sf->peaks[i].pkfreq = sf->peaks[i+1].pkfreq - 100;
|
||||
for(i=pk_num-1; i>=0; i--)
|
||||
{
|
||||
if(sf->peaks[i].pkfreq > sf->peaks[i+1].pkfreq - 100)
|
||||
sf->peaks[i].pkfreq = sf->peaks[i+1].pkfreq - 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1008,6 +1051,7 @@ void InitSpectrumDisplay()
|
||||
menu_spectdisplay->Append(202,_T("Copy Peaks Up SHIFT+CTRL+D"));
|
||||
menu_spectdisplay->Append(204,_T("Grid (toggle) CTRL+G"));
|
||||
menu_spectdisplay->Append(210,_T("Interpolate (percentage) CTRL+I"));
|
||||
menu_spectdisplay->Append(212,_T("Convert sequence to Klatt format CTRL+K"));
|
||||
menu_spectdisplay->Append(203,_T("Marker (toggle) CTRL+N"));
|
||||
menu_spectdisplay->Append(206,_T("Show Interpolation CTRL+Q"));
|
||||
menu_spectdisplay->Append(207,_T("Hide Interpolation CTRL+SHIFT+Q"));
|
||||
|
||||
+160
-46
@@ -34,8 +34,12 @@
|
||||
|
||||
#define MAX_HARMONIC 400 // 400 * 50Hz = 20 kHz, more than enough
|
||||
|
||||
int SpeakNextClause(FILE *f_text, const void *text_in, int control);
|
||||
extern void SetSynth(int length, int modn, frame_t *fr1, frame_t *fr2);
|
||||
#define KLATT_TEST
|
||||
|
||||
extern void SetSynth_Klatt(int length, int modn, frame_t *fr1, frame_t *fr2, voice_t *v, int control);
|
||||
extern int Wavegen_Klatt(int resume);
|
||||
|
||||
extern void SetSynth(int length, int modn, frame_t *fr1, frame_t *fr2, voice_t *v);
|
||||
extern int Wavegen();
|
||||
extern void CloseWaveFile2();
|
||||
extern FILE *f_wave;
|
||||
@@ -100,18 +104,27 @@ static void PeaksZero(peak_t *sp, peak_t *zero)
|
||||
|
||||
|
||||
|
||||
void MakeWaveFile()
|
||||
{//================
|
||||
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)];
|
||||
result = Wavegen();
|
||||
|
||||
#ifdef KLATT_TEST
|
||||
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
|
||||
|
||||
@@ -135,6 +148,7 @@ SpectSeq::SpectSeq(int n)
|
||||
|
||||
max_x = 3000;
|
||||
max_y = 1;
|
||||
synthesizer_type = 0;
|
||||
}
|
||||
|
||||
SpectSeq::~SpectSeq()
|
||||
@@ -378,7 +392,7 @@ void SpectSeq::Load2(wxInputStream& stream, int import, int n)
|
||||
}
|
||||
else
|
||||
{
|
||||
if(frame->Load(stream) != 0) break;
|
||||
if(frame->Load(stream, synthesizer_type) != 0) break;
|
||||
}
|
||||
|
||||
frames[numframes++] = frame;
|
||||
@@ -493,8 +507,19 @@ int SpectSeq::Load(wxInputStream & stream)
|
||||
stream.SeekI(4);
|
||||
return(ImportSPC2(stream));
|
||||
}
|
||||
if(id1 != FILEID1_SPECTSEQ || id2 != FILEID2_SPECTSEQ)
|
||||
else
|
||||
if((id1 == FILEID1_SPECTSEQ) && (id2 == FILEID2_SPECTSEQ))
|
||||
{
|
||||
synthesizer_type = 0; // eSpeak formants
|
||||
}
|
||||
else
|
||||
if((id1 == FILEID1_SPECTSEQ) && (id2 == FILEID2_SPECTSEK))
|
||||
{
|
||||
synthesizer_type = 1; // formants for Klatt synthesizer
|
||||
}
|
||||
else
|
||||
{
|
||||
// Praat analysis data
|
||||
stream.SeekI(0);
|
||||
return(Import(stream));
|
||||
}
|
||||
@@ -530,7 +555,10 @@ int SpectSeq::Save(wxOutputStream &stream, int selection)
|
||||
wxDataOutputStream s(stream);
|
||||
|
||||
s.Write32(FILEID1_SPECTSEQ);
|
||||
s.Write32(FILEID2_SPECTSEQ);
|
||||
if(synthesizer_type == 1)
|
||||
s.Write32(FILEID2_SPECTSEK);
|
||||
else
|
||||
s.Write32(FILEID2_SPECTSEQ);
|
||||
|
||||
s.WriteString(name);
|
||||
s.Write16(count);
|
||||
@@ -549,6 +577,23 @@ int SpectSeq::Save(wxOutputStream &stream, int selection)
|
||||
|
||||
|
||||
|
||||
void SpectSeq::SetKlattDefaults(void)
|
||||
{//==================================
|
||||
int ix;
|
||||
|
||||
synthesizer_type = 1;
|
||||
|
||||
for(ix=0; ix<numframes; ix++)
|
||||
{
|
||||
if(frames[ix]->keyframe)
|
||||
{
|
||||
frames[ix]->KlattDefaults();
|
||||
}
|
||||
frames[ix]->synthesizer_type = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SpectSeq::ConstructVowel(void)
|
||||
{//================================
|
||||
@@ -785,6 +830,7 @@ void SpectSeq::CopyDown(int frame, int direction)
|
||||
frames[frame]->peaks[pk].pkwidth = frames[f1]->peaks[pk].pkwidth;
|
||||
frames[frame]->peaks[pk].pkright = frames[f1]->peaks[pk].pkright;
|
||||
}
|
||||
memcpy(frames[frame]->klatt_param, frames[f1]->klatt_param, sizeof(frames[frame]->klatt_param));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -878,46 +924,88 @@ void SpectSeq::ApplyAmp_adjust(SpectFrame *sp, peak_t *peaks)
|
||||
int y;
|
||||
|
||||
memcpy(peaks,sp->peaks,sizeof(*peaks)*N_PEAKS);
|
||||
for(ix=0; ix<N_PEAKS; ix++)
|
||||
|
||||
if(synthesizer_type == 0)
|
||||
{
|
||||
y = peaks[ix].pkheight * sp->amp_adjust * amplitude;
|
||||
peaks[ix].pkheight = y / 10000;
|
||||
for(ix=0; ix<N_PEAKS; ix++)
|
||||
{
|
||||
y = peaks[ix].pkheight * sp->amp_adjust * amplitude;
|
||||
peaks[ix].pkheight = y / 10000;
|
||||
}
|
||||
}
|
||||
} // end of ApplyAmp_adjust
|
||||
|
||||
|
||||
|
||||
void PeaksToFrame(peak_t *pks, frame_t *fr)
|
||||
{//========================================
|
||||
void PeaksToFrame(SpectFrame *sp1, peak_t *pks, frame_t *fr)
|
||||
{//=========================================================
|
||||
int ix;
|
||||
int x;
|
||||
int x, x2;
|
||||
|
||||
for(ix=0; ix<N_PEAKS; ix++)
|
||||
{
|
||||
fr->ffreq[ix] = pks[ix].pkfreq;
|
||||
fr->fheight[ix] = pks[ix].pkheight >> 6;
|
||||
|
||||
if(sp1->synthesizer_type==0)
|
||||
{
|
||||
x = pks[ix].pkheight >> 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = pks[ix].pkheight >> 7;
|
||||
fr->fwidth6 = pks[6].pkwidth >> 1;
|
||||
fr->fright6 = pks[6].pkright;
|
||||
}
|
||||
|
||||
if(x > 255)
|
||||
x = 255;
|
||||
fr->fheight[ix] = x;
|
||||
|
||||
if(ix < 6)
|
||||
{
|
||||
if((x = (pks[ix].pkwidth >> 2)) > 255)
|
||||
x = pks[ix].pkwidth/2;
|
||||
x2 = pks[ix].pkright;
|
||||
|
||||
if(sp1->synthesizer_type == 0)
|
||||
{
|
||||
x /= 2;
|
||||
x2 /= 4;
|
||||
}
|
||||
if(x > 255)
|
||||
x = 255;
|
||||
fr->fwidth[ix] = x;
|
||||
|
||||
if((x = (pks[ix].pkright >> 2)) > 255)
|
||||
x = 255;
|
||||
fr->fright[ix] = x;
|
||||
if(x2 > 255)
|
||||
x2 = 255;
|
||||
fr->fright[ix] = x2;
|
||||
}
|
||||
}
|
||||
|
||||
for(ix=0; ix<N_KLATTP; ix++)
|
||||
{
|
||||
fr->klattp[ix] = sp1->klatt_param[ix];
|
||||
}
|
||||
}
|
||||
|
||||
static void SetSynth_mS(int length_mS, peak_t *sp1, peak_t *sp2)
|
||||
{//=============================================================
|
||||
static void SetSynth_mS(int length_mS, SpectFrame *sp1, SpectFrame *sp2, peak_t *pks1, peak_t *pks2, int control)
|
||||
{//==============================================================================================================
|
||||
static frame_t fr1, fr2;
|
||||
|
||||
PeaksToFrame(sp1,&fr1);
|
||||
PeaksToFrame(sp2,&fr2);
|
||||
PeaksToFrame(sp1,pks1,&fr1);
|
||||
PeaksToFrame(sp2,pks2,&fr2);
|
||||
|
||||
#ifdef KLATT_TEST
|
||||
if(sp1->synthesizer_type == 1)
|
||||
{
|
||||
SetSynth_Klatt((length_mS * samplerate) / 1000, 0, &fr1, &fr2, voice, control); // convert mS to samples
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
SetSynth((length_mS * samplerate) / 1000, 0, &fr1, &fr2, voice); // convert mS to samples
|
||||
}
|
||||
};
|
||||
|
||||
SetSynth((length_mS * samplerate) / 1000, 0, &fr1, &fr2); // convert mS to samples
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -939,6 +1027,7 @@ void SpectSeq::MakeWave(int start, int end, PitchEnvelope &pitch)
|
||||
peak_t peaks1[N_PEAKS];
|
||||
peak_t peaks2[N_PEAKS];
|
||||
|
||||
KlattInit();
|
||||
SpeakNextClause(NULL,NULL,2); // stop speaking file
|
||||
|
||||
if(numframes==0) return;
|
||||
@@ -1007,23 +1096,39 @@ void SpectSeq::MakeWave(int start, int end, PitchEnvelope &pitch)
|
||||
{
|
||||
ApplyAmp_adjust(sp1,peaks1);
|
||||
ApplyAmp_adjust(sp2,peaks2);
|
||||
|
||||
if(first)
|
||||
{
|
||||
PeaksZero(peaks1,peaks0); // fade in
|
||||
SetSynth_mS(20,peaks0,peaks1);
|
||||
MakeWaveFile();
|
||||
if(synthesizer_type == 1)
|
||||
{
|
||||
memcpy(peaks0,peaks1,sizeof(peaks0));
|
||||
}
|
||||
else
|
||||
{
|
||||
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,peaks1,peaks2);
|
||||
MakeWaveFile();
|
||||
SetSynth_mS(length,sp1,sp2,peaks1,peaks2,0);
|
||||
MakeWaveFile(synthesizer_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
PeaksZero(peaks2,peaks0); // fade out
|
||||
SetSynth_mS(30,peaks2,peaks0);
|
||||
MakeWaveFile();
|
||||
|
||||
if(synthesizer_type == 1)
|
||||
{
|
||||
memcpy(peaks0,peaks2,sizeof(peaks0));
|
||||
}
|
||||
else
|
||||
{
|
||||
PeaksZero(peaks2,peaks0); // fade out
|
||||
}
|
||||
SetSynth_mS(30,sp2,sp2,peaks2,peaks0,2);
|
||||
MakeWaveFile(synthesizer_type);
|
||||
|
||||
CloseWaveFile2();
|
||||
PlayWavFile(fname_speech);
|
||||
@@ -1054,6 +1159,7 @@ void SpectFrame::MakeWave(int control, PitchEnvelope &pitche, int amplitude, int
|
||||
char *fname_speech;
|
||||
// USHORT htab0[600];
|
||||
|
||||
KlattInit();
|
||||
SpeakNextClause(NULL,NULL,2); // stop speaking file
|
||||
|
||||
length = duration;
|
||||
@@ -1069,23 +1175,31 @@ void SpectFrame::MakeWave(int control, PitchEnvelope &pitche, int amplitude, int
|
||||
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,peaks0,peaks1);
|
||||
MakeWaveFile();
|
||||
SetSynth_mS(length,peaks1,peaks1);
|
||||
MakeWaveFile();
|
||||
SetSynth_mS(30,peaks1,peaks0);
|
||||
MakeWaveFile();
|
||||
if(synthesizer_type == 0)
|
||||
{
|
||||
for(ix=0; ix<N_PEAKS; ix++)
|
||||
{
|
||||
y = peaks1[ix].pkheight * amp_adjust * amplitude;
|
||||
peaks1[ix].pkheight = y/10000;
|
||||
}
|
||||
PeaksZero(peaks1,peaks0);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(peaks0,peaks1,sizeof(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
|
||||
{
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
// conditional compilation options
|
||||
#define INCLUDE_KLATT
|
||||
|
||||
#if defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN
|
||||
#define ARCH_BIG
|
||||
|
||||
@@ -77,7 +77,7 @@ BOOL load_MBR()
|
||||
if(hinstDllMBR != NULL)
|
||||
return TRUE; // already loaded
|
||||
|
||||
if (!(hinstDllMBR=LoadLibrary("mbrola.dll")))
|
||||
if (!(hinstDllMBR=LoadLibraryA("mbrola.dll")))
|
||||
return FALSE;
|
||||
init_MBR =(PROCIC) GetProcAddress(hinstDllMBR,"init_MBR");
|
||||
write_MBR =(PROCIC) GetProcAddress(hinstDllMBR,"write_MBR");
|
||||
@@ -179,7 +179,7 @@ espeak_ERROR LoadMbrolaTable(const char *mbrola_voice, const char *phtrans, int
|
||||
|
||||
#ifdef USE_MBROLA_LIB
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
setVolumeRatio_MBR((float)(mbrola_control & 0xff) /16.0);
|
||||
setVolumeRatio_MBR((float)(mbrola_control & 0xff) /16.0f);
|
||||
#else
|
||||
mbrolib_get_parameter(mb_handle,&m_parameters);
|
||||
m_parameters.ignore_error = 1;
|
||||
|
||||
+26
-10
@@ -35,7 +35,7 @@
|
||||
#include "translate.h"
|
||||
#include "wave.h"
|
||||
|
||||
const char *version_string = "1.39.26 15.Nov.08";
|
||||
const char *version_string = "1.39.28 22.Nov.08";
|
||||
const int version_phdata = 0x013900;
|
||||
|
||||
int option_device_number = -1;
|
||||
@@ -375,9 +375,10 @@ frameref_t *LookupSpect(PHONEME_TAB *this_ph, PHONEME_TAB *prev_ph, PHONEME_TAB
|
||||
int length1;
|
||||
int length_std;
|
||||
int length_factor;
|
||||
SPECT_SEQ *seq;
|
||||
SPECT_SEQ *seq2;
|
||||
SPECT_SEQ *seq, *seq2;
|
||||
SPECT_SEQK *seqk, *seqk2;
|
||||
PHONEME_TAB *next2_ph;
|
||||
frame_t *frame;
|
||||
static frameref_t frames_buf[N_SEQ_FRAMES];
|
||||
|
||||
PHONEME_TAB *other_ph;
|
||||
@@ -389,6 +390,7 @@ frameref_t *LookupSpect(PHONEME_TAB *this_ph, PHONEME_TAB *prev_ph, PHONEME_TAB
|
||||
if((ix = LookupSound(this_ph,other_ph,which,match_level,0)) < 4)
|
||||
return(NULL);
|
||||
seq = (SPECT_SEQ *)(&spects_data[ix]);
|
||||
seqk = (SPECT_SEQK *)seq;
|
||||
nf = seq->n_frames;
|
||||
|
||||
|
||||
@@ -397,15 +399,20 @@ frameref_t *LookupSpect(PHONEME_TAB *this_ph, PHONEME_TAB *prev_ph, PHONEME_TAB
|
||||
|
||||
seq_break = 0;
|
||||
length1 = 0;
|
||||
|
||||
for(ix=0; ix<nf; ix++)
|
||||
{
|
||||
frames_buf[ix].frame = &seq->frame[ix];
|
||||
frames_buf[ix].frflags = seq->frame[ix].frflags;
|
||||
frames_buf[ix].length = seq->frame[ix].length;
|
||||
if(seq->frame[ix].frflags & FRFLAG_VOWEL_CENTRE)
|
||||
if(seq->frame[0].frflags & FRFLAG_KLATT)
|
||||
frame = &seqk->frame[ix];
|
||||
else
|
||||
frame = (frame_t *)&seq->frame[ix];
|
||||
frames_buf[ix].frame = frame;
|
||||
frames_buf[ix].frflags = frame->frflags;
|
||||
frames_buf[ix].length = frame->length;
|
||||
if(frame->frflags & FRFLAG_VOWEL_CENTRE)
|
||||
seq_break = ix;
|
||||
}
|
||||
|
||||
|
||||
frames = &frames_buf[0];
|
||||
if(seq_break > 0)
|
||||
{
|
||||
@@ -462,14 +469,23 @@ frameref_t *LookupSpect(PHONEME_TAB *this_ph, PHONEME_TAB *prev_ph, PHONEME_TAB
|
||||
// a secondary reference has been returned, which is not a wavefile
|
||||
// add these spectra to the main sequence
|
||||
seq2 = (SPECT_SEQ *)(&spects_data[wavefile_ix]);
|
||||
seqk2 = (SPECT_SEQK *)seq2;
|
||||
|
||||
// first frame of the addition just sets the length of the last frame of the main seq
|
||||
nf--;
|
||||
for(ix=0; ix<seq2->n_frames; ix++)
|
||||
{
|
||||
frames[nf].length = seq2->frame[ix].length;
|
||||
if(seq2->frame[0].frflags & FRFLAG_KLATT)
|
||||
frame = &seqk2->frame[ix];
|
||||
else
|
||||
frame = (frame_t *)&seq2->frame[ix];
|
||||
|
||||
frames[nf].length = frame->length;
|
||||
if(ix > 0)
|
||||
frames[nf].frame = &seq2->frame[ix];
|
||||
{
|
||||
frames[nf].frame = frame;
|
||||
frames[nf].frflags = frame->frflags;
|
||||
}
|
||||
nf++;
|
||||
}
|
||||
wavefile_ix = 0;
|
||||
|
||||
+31
-5
@@ -354,6 +354,15 @@ static void set_frame_rms(frame_t *fr, int new_rms)
|
||||
849,851,853,856,858,861,863,865,868,870,872,875,877,879,882,884,
|
||||
886,889,891,893,896,898,900,902};
|
||||
|
||||
if(fr->frflags & FRFLAG_KLATT)
|
||||
{
|
||||
if(new_rms == -1)
|
||||
{
|
||||
fr->klattp[KLATT_AV] = 50;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(fr->rms == 0) return; // check for divide by zero
|
||||
x = (new_rms * 64)/fr->rms;
|
||||
if(x >= 200) x = 199;
|
||||
@@ -375,6 +384,9 @@ static void formants_reduce_hf(frame_t *fr, int level)
|
||||
int ix;
|
||||
int x;
|
||||
|
||||
if(fr->frflags & FRFLAG_KLATT)
|
||||
return;
|
||||
|
||||
for(ix=2; ix<N_PEAKS; ix++)
|
||||
{
|
||||
x = fr->fheight[ix] * level;
|
||||
@@ -540,6 +552,10 @@ static short vcolouring[N_VCOLOUR][5] = {
|
||||
|
||||
next_rms = seq[1].frame->rms;
|
||||
|
||||
if(fr->frflags & FRFLAG_KLATT)
|
||||
{
|
||||
fr->klattp[KLATT_AV] = 53; // reduce the amplituide of the start of a vowel
|
||||
}
|
||||
if(f2 != 0)
|
||||
{
|
||||
if(rms & 0x20)
|
||||
@@ -661,6 +677,9 @@ static void SmoothSpect(void)
|
||||
q = wcmdq[syllable_centre];
|
||||
frame_centre = (frame_t *)q[2];
|
||||
|
||||
//if(frame_centre->frflags & FRFLAG_KLATT)
|
||||
// return; // TESTING
|
||||
|
||||
// backwards
|
||||
ix = syllable_centre -1;
|
||||
frame = frame2 = frame_centre;
|
||||
@@ -672,7 +691,7 @@ static void SmoothSpect(void)
|
||||
if(q[0] == WCMD_PAUSE || q[0] == WCMD_WAVE)
|
||||
break;
|
||||
|
||||
if(q[0] == WCMD_SPECT || q[0] == WCMD_SPECT2)
|
||||
if(q[0] <= WCMD_SPECT2)
|
||||
{
|
||||
len = q[1] & 0xffff;
|
||||
|
||||
@@ -759,7 +778,7 @@ static void SmoothSpect(void)
|
||||
if(q[0] == WCMD_PAUSE || q[0] == WCMD_WAVE)
|
||||
break;
|
||||
|
||||
if(q[0] == WCMD_SPECT || q[0] == WCMD_SPECT2)
|
||||
if(q[0] <= WCMD_SPECT2)
|
||||
{
|
||||
|
||||
len = q[1] & 0xffff;
|
||||
@@ -834,7 +853,7 @@ static void SmoothSpect(void)
|
||||
}
|
||||
|
||||
syllable_start = syllable_end;
|
||||
}
|
||||
} // end of SmoothSpect
|
||||
|
||||
|
||||
static void StartSyllable(void)
|
||||
@@ -891,22 +910,29 @@ if(which==1)
|
||||
if(frames == NULL)
|
||||
return(0); // not found
|
||||
|
||||
frame1 = frames[0].frame;
|
||||
frame1_length = frames[0].length;
|
||||
if(frame1->frflags & FRFLAG_KLATT)
|
||||
wcmd_spect = WCMD_KLATT;
|
||||
|
||||
if(wavefile_ix == 0)
|
||||
{
|
||||
if(wave_flag)
|
||||
{
|
||||
// cancel any wavefile that was playing previously
|
||||
wcmd_spect = WCMD_SPECT2;
|
||||
if(frame1->frflags & FRFLAG_KLATT)
|
||||
wcmd_spect = WCMD_KLATT2;
|
||||
wave_flag = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
wcmd_spect = WCMD_SPECT;
|
||||
if(frame1->frflags & FRFLAG_KLATT)
|
||||
wcmd_spect = WCMD_KLATT;
|
||||
}
|
||||
}
|
||||
|
||||
frame1 = frames[0].frame;
|
||||
frame1_length = frames[0].length;
|
||||
if(last_frame != NULL)
|
||||
{
|
||||
if(((last_frame->length < 2) || (last_frame->frflags & FRFLAG_VOWEL_CENTRE))
|
||||
|
||||
+66
-7
@@ -22,11 +22,13 @@
|
||||
|
||||
#define MAX_HARMONIC 400 // 400 * 50Hz = 20 kHz, more than enough
|
||||
#define N_SEQ_FRAMES 25 // max frames in a spectrum sequence (real max is ablut 8)
|
||||
#define STEPSIZE 64 // 2.9mS at 22 kHz sample rate
|
||||
|
||||
#define PITCHfall 0
|
||||
#define PITCHrise 1
|
||||
|
||||
// flags set for frames within a spectrum sequence
|
||||
#define FRFLAG_KLATT 0x01 // this frame includes extra data for Klatt synthesizer
|
||||
#define FRFLAG_VOWEL_CENTRE 0x02 // centre point of vowel
|
||||
#define FRFLAG_LEN_MOD 0x04 // reduce effect of length adjustment
|
||||
#define FRFLAG_BREAK_LF 0x08 // but keep f3 upwards
|
||||
@@ -75,6 +77,18 @@ typedef struct {
|
||||
short pkright;
|
||||
} peak_t;
|
||||
|
||||
#define N_KLATTP 10 // this affects the phoneme data file format
|
||||
#define KLATT_AV 0
|
||||
#define KLATT_Kopen 1
|
||||
#define KLATT_Skew 2
|
||||
#define KLATT_Tilt 3
|
||||
#define KLATT_Turb 4
|
||||
#define KLATT_Aspr 5
|
||||
#define KLATT_AVp 6 // this is after the parameters which can be change by the Voice
|
||||
#define KLATT_Fric 7
|
||||
#define KLATT_FricBP 8
|
||||
#define KLATT_spare1 9
|
||||
|
||||
typedef struct {
|
||||
short frflags;
|
||||
unsigned char length;
|
||||
@@ -83,8 +97,20 @@ typedef struct {
|
||||
unsigned char fheight[9];
|
||||
unsigned char fwidth[6]; // width/4
|
||||
unsigned char fright[6]; // width/4
|
||||
unsigned char fwidth6, fright6;
|
||||
unsigned char klattp[N_KLATTP];
|
||||
} frame_t;
|
||||
|
||||
typedef struct {
|
||||
short frflags;
|
||||
unsigned char length;
|
||||
unsigned char rms;
|
||||
short ffreq[9];
|
||||
unsigned char fheight[9];
|
||||
unsigned char fwidth[6]; // width/4
|
||||
unsigned char fright[6]; // width/4
|
||||
} frame_t2; // the original, without Klatt additions, used for file "phondata"
|
||||
|
||||
|
||||
|
||||
// formant data used by wavegen
|
||||
@@ -103,6 +129,26 @@ typedef struct {
|
||||
DOUBLEX right_inc;
|
||||
} wavegen_peaks_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned char *pitch_env;
|
||||
int pitch; // pitch Hz*256
|
||||
int pitch_ix; // index into pitch envelope (*256)
|
||||
int pitch_inc; // increment to pitch_ix
|
||||
int pitch_base; // Hz*256 low, before modified by envelope
|
||||
int pitch_range; // Hz*256 range of envelope
|
||||
|
||||
unsigned char *mix_wavefile; // wave file to be added to synthesis
|
||||
int n_mix_wavefile; // length in bytes
|
||||
int mix_wave_scale; // 0=2 byte samples
|
||||
int mix_wave_amp;
|
||||
int mix_wavefile_ix;
|
||||
|
||||
int amplitude;
|
||||
int amplitude_v;
|
||||
int prev_was_synth; // previous sound was synthesized (not a played wave or pause)
|
||||
} WGEN_DATA;
|
||||
|
||||
|
||||
typedef struct {
|
||||
double a;
|
||||
double b;
|
||||
@@ -113,11 +159,19 @@ typedef struct {
|
||||
|
||||
|
||||
typedef struct {
|
||||
short length;
|
||||
short length_total; // not used
|
||||
unsigned char n_frames;
|
||||
unsigned char flags;
|
||||
frame_t2 frame[N_SEQ_FRAMES]; // max. frames in a spectrum sequence
|
||||
} SPECT_SEQ; // sequence of espeak formant frames
|
||||
|
||||
typedef struct {
|
||||
short length_total; // not used
|
||||
unsigned char n_frames;
|
||||
unsigned char flags;
|
||||
frame_t frame[N_SEQ_FRAMES]; // max. frames in a spectrum sequence
|
||||
} SPECT_SEQ;
|
||||
} SPECT_SEQK; // sequence of klatt formants frames
|
||||
|
||||
|
||||
typedef struct {
|
||||
short length;
|
||||
@@ -176,16 +230,18 @@ extern unsigned char env_frise[128];
|
||||
extern unsigned char pitch_adjust_tab[MAX_PITCH_VALUE+1];
|
||||
|
||||
// queue of commands for wavegen
|
||||
#define WCMD_AMPLITUDE 1
|
||||
#define WCMD_PITCH 2
|
||||
#define WCMD_KLATT 1
|
||||
#define WCMD_KLATT2 2
|
||||
#define WCMD_SPECT 3
|
||||
#define WCMD_SPECT2 4
|
||||
#define WCMD_PAUSE 5
|
||||
#define WCMD_WAVE 6
|
||||
#define WCMD_WAVE2 7
|
||||
#define WCMD_MARKER 8
|
||||
#define WCMD_VOICE 9
|
||||
#define WCMD_EMBEDDED 10
|
||||
#define WCMD_AMPLITUDE 8
|
||||
#define WCMD_PITCH 9
|
||||
#define WCMD_MARKER 10
|
||||
#define WCMD_VOICE 11
|
||||
#define WCMD_EMBEDDED 12
|
||||
|
||||
|
||||
#define N_WCMDQ 160
|
||||
@@ -278,3 +334,6 @@ int PauseLength(int pause, int control);
|
||||
int LookupPhonemeTable(const char *name);
|
||||
|
||||
void InitBreath(void);
|
||||
|
||||
void KlattInit();
|
||||
int Wavegen_Klatt2(int length, int modulation, int resume, frame_t *fr1, frame_t *fr2);
|
||||
|
||||
@@ -515,6 +515,7 @@ SetLengthMods(tr,3); // all equal
|
||||
tr->langopts.param[LOPT_SONORANT_MIN] = 130; // limit the shortening of sonorants before short vowels
|
||||
tr->langopts.param[LOPT_REDUCE] = 1; // reduce vowels even if phonemes are specified in it_list
|
||||
tr->langopts.numbers = 0x2709 + NUM_ROMAN;
|
||||
tr->langopts.accents = 2; // Say "Capital" after the letter.
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -769,8 +770,9 @@ SetLengthMods(tr,3); // all equal
|
||||
static const unsigned char stress_amps_sq[8] = {17,12, 17,17, 20,20, 24,22 };
|
||||
tr = new Translator();
|
||||
SetupTranslator(tr,stress_lengths_sq,stress_amps_sq);
|
||||
tr->langopts.stress_flags = 0x4;
|
||||
tr->langopts.stress_flags = 0x4 + 0x10;
|
||||
SetLetterVowel(tr,'y');
|
||||
tr->langopts.numbers = 0x69 + 0x8000;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
+5
-1
@@ -1747,7 +1747,11 @@ int Translator::TranslateWord2(char *word, WORD_TAB *wtab, int pre_pause, int ne
|
||||
first_phoneme = 0;
|
||||
}
|
||||
}
|
||||
plist2->sourceix = source_ix; // ????
|
||||
// don't set new-word if there is a hyphen before it
|
||||
if((word_flags & FLAG_HYPHEN) == 0)
|
||||
{
|
||||
plist2->sourceix = source_ix;
|
||||
}
|
||||
|
||||
end_stressed_vowel = 0;
|
||||
if((stress >= 4) && (phoneme_tab[ph_list2[n_ph_list2-1].phcode]->type == phVOWEL))
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@
|
||||
#define N_RULE_GROUP2 120 // max num of two-letter rule chains
|
||||
#define N_HASH_DICT 1024
|
||||
#define N_CHARSETS 20
|
||||
#define N_LETTER_GROUPS 25
|
||||
#define N_LETTER_GROUPS 26
|
||||
|
||||
|
||||
/* dictionary flags, word 1 */
|
||||
|
||||
+3
-2
@@ -249,6 +249,7 @@ void MakeWave2(PHONEME_LIST *p, int n_phonemes)
|
||||
char *fname_speech;
|
||||
int n_ph;
|
||||
|
||||
KlattInit();
|
||||
n_ph = n_phonemes;
|
||||
fname_speech = WavFileName();
|
||||
OpenWaveFile2(fname_speech);
|
||||
@@ -275,9 +276,9 @@ TranslDlg::TranslDlg(wxWindow *parent) : wxPanel(parent)
|
||||
{//=====================================================
|
||||
|
||||
t_source = new wxTextCtrl(this,T_SOURCE,_T(""),wxPoint(0,4),
|
||||
wxSize(200,250),wxTE_MULTILINE);
|
||||
wxSize(204,250),wxTE_MULTILINE);
|
||||
t_phonetic = new wxTextCtrl(this,T_PHONETIC,_T(""),wxPoint(0,262),
|
||||
wxSize(200,350),wxTE_MULTILINE);
|
||||
wxSize(204,350),wxTE_MULTILINE);
|
||||
|
||||
t_translate = new wxButton(this,T_TRANSLATE,_T("Translate"),wxPoint(4,620));
|
||||
t_translate = new wxButton(this,T_RULES,_T("Show Rules"),wxPoint(4,652));
|
||||
|
||||
+2
-1
@@ -40,6 +40,7 @@ typedef struct {
|
||||
int formant_factor; // adjust nominal formant frequencies by this because of the voice's pitch (256ths)
|
||||
int consonant_amp; // amplitude of unvoiced consonants
|
||||
int consonant_ampv; // amplitude of the noise component of voiced consonants
|
||||
int klatt[8];
|
||||
|
||||
// parameters used by Wavegen
|
||||
short freq[N_PEAKS]; // 100% = 256
|
||||
@@ -68,7 +69,7 @@ extern USHORT voice_pcnt[N_PEAKS+1][3];
|
||||
|
||||
|
||||
extern voice_t *voice;
|
||||
extern int tone_points[10];
|
||||
extern int tone_points[12];
|
||||
|
||||
const char *SelectVoice(espeak_VOICE *voice_select);
|
||||
espeak_VOICE *SelectVoiceByName(espeak_VOICE **voices, const char *name);
|
||||
|
||||
+24
-15
@@ -49,8 +49,8 @@ MNEM_TAB genders [] = {
|
||||
{"female", 2},
|
||||
{NULL, 0 }};
|
||||
|
||||
//int tone_points[10] = {250,140, 1200,110, -1,0, -1,0, -1,0};
|
||||
int tone_points[10] = {600,170, 1200,135, 2000,110, 3000,110, -1,0};
|
||||
int tone_points[12] = {600,170, 1200,135, 2000,110, 3000,110, -1,0};
|
||||
//int tone_points[12] = {250,200, 400,170, 600,170, 1200,135, 2000,110, -1,0};
|
||||
|
||||
// limit the rate of change for each formant number
|
||||
//static int formant_rate_22050[9] = {50, 104, 165, 230, 220, 220, 220, 220, 220}; // values for 22kHz sample rate
|
||||
@@ -101,11 +101,13 @@ espeak_VOICE voice_selected;
|
||||
#define V_NUMBERS 25
|
||||
#define V_OPTION 26
|
||||
|
||||
#define V_MBROLA 27
|
||||
#define V_MBROLA 27
|
||||
#define V_KLATT 28
|
||||
|
||||
// these need a phoneme table to have been specified
|
||||
#define V_REPLACE 28
|
||||
#define V_CONSONANTS 29
|
||||
#define V_REPLACE 29
|
||||
#define V_CONSONANTS 30
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
@@ -144,6 +146,7 @@ static keywtab_t keyword_tab[] = {
|
||||
{"option", V_OPTION},
|
||||
{"mbrola", V_MBROLA},
|
||||
{"consonants", V_CONSONANTS},
|
||||
{"klatt", V_KLATT},
|
||||
|
||||
// these just set a value in langopts.param[]
|
||||
{"l_dieresis", 0x100+LOPT_DIERESES},
|
||||
@@ -195,7 +198,7 @@ void SetToneAdjust(voice_t *voice, int *tone_pts)
|
||||
int height2;
|
||||
double rate;
|
||||
|
||||
for(pt=0; pt<10; pt+=2)
|
||||
for(pt=0; pt<12; pt+=2)
|
||||
{
|
||||
if(tone_pts[pt] == -1)
|
||||
{
|
||||
@@ -225,15 +228,16 @@ void SetToneAdjust(voice_t *voice, int *tone_pts)
|
||||
|
||||
void ReadTonePoints(char *string, int *tone_pts)
|
||||
{//=============================================
|
||||
// tone_pts[] is int[10]
|
||||
// tone_pts[] is int[12]
|
||||
int ix;
|
||||
|
||||
for(ix=0; ix<10; ix++)
|
||||
for(ix=0; ix<12; ix++)
|
||||
tone_pts[ix] = -1;
|
||||
|
||||
sscanf(string,"%d %d %d %d %d %d %d %d",
|
||||
sscanf(string,"%d %d %d %d %d %d %d %d %d %d",
|
||||
&tone_pts[0],&tone_pts[1],&tone_pts[2],&tone_pts[3],
|
||||
&tone_pts[4],&tone_pts[5],&tone_pts[6],&tone_pts[7]);
|
||||
&tone_pts[4],&tone_pts[5],&tone_pts[6],&tone_pts[7],
|
||||
&tone_pts[8],&tone_pts[9]);
|
||||
}
|
||||
|
||||
|
||||
@@ -369,10 +373,11 @@ void VoiceReset(int tone_only)
|
||||
voice->echo_amp = 0;
|
||||
voice->flutter = 64;
|
||||
voice->n_harmonic_peaks = 5;
|
||||
voice->peak_shape = 1;
|
||||
voice->peak_shape = 0;
|
||||
voice->voicing = 64;
|
||||
voice->consonant_amp = 100;
|
||||
voice->consonant_ampv = 100;
|
||||
memset(voice->klatt,0,sizeof(voice->klatt));
|
||||
|
||||
#ifdef PLATFORM_RISCOS
|
||||
voice->roughness = 1;
|
||||
@@ -864,6 +869,11 @@ voice_t *LoadVoice(const char *vname, int control)
|
||||
}
|
||||
break;
|
||||
|
||||
case V_KLATT:
|
||||
Read8Numbers(p,voice->klatt);
|
||||
voice->klatt[KLATT_Kopen] -= 40;
|
||||
break;
|
||||
|
||||
default:
|
||||
if((key & 0xff00) == 0x100)
|
||||
{
|
||||
@@ -1493,13 +1503,12 @@ void GetVoices(const char *path)
|
||||
}
|
||||
#else
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
WIN32_FIND_DATA FindFileData;
|
||||
WIN32_FIND_DATAA FindFileData;
|
||||
HANDLE hFind = INVALID_HANDLE_VALUE;
|
||||
DWORD dwError;
|
||||
|
||||
#undef UNICODE // we need FindFirstFileA() which takes an 8-bit c-string
|
||||
sprintf(fname,"%s\\*",path);
|
||||
hFind = FindFirstFile(fname, &FindFileData);
|
||||
hFind = FindFirstFileA(fname, &FindFileData);
|
||||
if(hFind == INVALID_HANDLE_VALUE)
|
||||
return;
|
||||
|
||||
@@ -1529,7 +1538,7 @@ void GetVoices(const char *path)
|
||||
voices_list[n_voices_list++] = voice_data;
|
||||
}
|
||||
}
|
||||
} while(FindNextFile(hFind, &FindFileData) != 0);
|
||||
} while(FindNextFileA(hFind, &FindFileData) != 0);
|
||||
FindClose(hFind);
|
||||
|
||||
#else
|
||||
|
||||
+13
-2
@@ -510,6 +510,7 @@ void MakeVowelLists(void)
|
||||
PHONEME_TAB *ph;
|
||||
FILE *f;
|
||||
SPECT_SEQ *seq;
|
||||
SPECT_SEQK *seqk;
|
||||
frame_t *frame;
|
||||
int match_level;
|
||||
char dirname[sizeof(path_source)+20];
|
||||
@@ -547,10 +548,20 @@ void MakeVowelLists(void)
|
||||
continue;
|
||||
|
||||
seq = (SPECT_SEQ *)(&spects_data[ix]);
|
||||
frame = &seq->frame[1];
|
||||
seqk = (SPECT_SEQK *)seq;
|
||||
|
||||
if(seq->frame[0].frflags & FRFLAG_KLATT)
|
||||
frame = &seqk->frame[1];
|
||||
else
|
||||
frame = (frame_t *)&seq->frame[1];
|
||||
|
||||
fprintf(f,"%s\t %3d %4d %4d",WordToString(ph->mnemonic),
|
||||
frame->ffreq[1],frame->ffreq[2],frame->ffreq[3]);
|
||||
frame = &seq->frame[seq->n_frames-1];
|
||||
|
||||
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);
|
||||
|
||||
+81
-68
@@ -34,6 +34,8 @@
|
||||
#include "synthesize.h"
|
||||
#include "voice.h"
|
||||
|
||||
//#undef INCLUDE_KLATT
|
||||
|
||||
#ifdef USE_PORTAUDIO
|
||||
#include "portaudio.h"
|
||||
#undef USE_PORTAUDIO
|
||||
@@ -51,10 +53,9 @@
|
||||
|
||||
#define PI 3.1415927
|
||||
#define PI2 6.283185307
|
||||
#define STEPSIZE 64 // 2.9mS at 22 kHz sample rate
|
||||
#define N_WAV_BUF 10
|
||||
|
||||
static voice_t *wvoice;
|
||||
voice_t *wvoice;
|
||||
|
||||
FILE *f_log = NULL;
|
||||
int option_waveout = 0;
|
||||
@@ -98,24 +99,13 @@ static int hspect[2][MAX_HARMONIC]; // 2 copies, we interpolate between
|
||||
static int max_hval=0;
|
||||
|
||||
static int nsamples=0; // number to do
|
||||
static int amplitude = 32;
|
||||
static int amplitude_v = 0;
|
||||
static int modulation_type = 0;
|
||||
static int glottal_flag = 0;
|
||||
static int glottal_reduce = 0;
|
||||
|
||||
static unsigned char *mix_wavefile = NULL; // wave file to be added to synthesis
|
||||
static int n_mix_wavefile = 0; // length in bytes
|
||||
static int mix_wave_scale = 0; // 0=2 byte samples
|
||||
static int mix_wave_amp = 32;
|
||||
static int mix_wavefile_ix = 0;
|
||||
|
||||
static int pitch; // pitch Hz*256
|
||||
static int pitch_ix; // index into pitch envelope (*256)
|
||||
static int pitch_inc; // increment to pitch_ix
|
||||
static unsigned char *pitch_env=NULL;
|
||||
static int pitch_base; // Hz*256 low, before modified by envelope
|
||||
static int pitch_range; // Hz*256 range of envelope
|
||||
WGEN_DATA wdata;
|
||||
|
||||
static int amp_ix;
|
||||
static int amp_inc;
|
||||
static unsigned char *amplitude_env = NULL;
|
||||
@@ -385,8 +375,8 @@ static void WcmdqIncHead()
|
||||
// data points from which to make the presets for pk_shape1 and pk_shape2
|
||||
#define PEAKSHAPEW 256
|
||||
static const float pk_shape_x[2][8] = {
|
||||
{0,-0.6, 0.0, 0.6, 1.4, 2.5, 4.5, 5.5},
|
||||
{0,-0.6, 0.0, 0.6, 1.4, 2.0, 4.5, 5.5 }};
|
||||
{0,-0.6f, 0.0f, 0.6f, 1.4f, 2.5f, 4.5f, 5.5f},
|
||||
{0,-0.6f, 0.0f, 0.6f, 1.4f, 2.0f, 4.5f, 5.5f }};
|
||||
static const float pk_shape_y[2][8] = {
|
||||
{0, 67, 81, 67, 31, 14, 0, -6} ,
|
||||
{0, 77, 81, 77, 31, 7, 0, -6 }};
|
||||
@@ -737,6 +727,7 @@ void WavegenInit(int rate, int wavemult_fact)
|
||||
if(wavemult_fact == 0)
|
||||
wavemult_fact=60; // default
|
||||
|
||||
wvoice = NULL;
|
||||
samplerate = samplerate_native = rate;
|
||||
PHASE_INC_FACTOR = 0x8000000 / samplerate; // assumes pitch is Hz*32
|
||||
Flutter_inc = (64 * samplerate)/rate;
|
||||
@@ -745,6 +736,9 @@ void WavegenInit(int rate, int wavemult_fact)
|
||||
wavephase = 0x7fffffff;
|
||||
max_hval = 0;
|
||||
|
||||
wdata.amplitude = 32;
|
||||
wdata.prev_was_synth = 0;
|
||||
|
||||
for(ix=0; ix<N_EMBEDDED_VALUES; ix++)
|
||||
embedded_value[ix] = embedded_default[ix];
|
||||
|
||||
@@ -769,7 +763,11 @@ void WavegenInit(int rate, int wavemult_fact)
|
||||
|
||||
WavegenInitPkData(1);
|
||||
WavegenInitPkData(0);
|
||||
pk_shape = pk_shape2; // ph_shape2
|
||||
pk_shape = pk_shape2; // pk_shape2
|
||||
|
||||
#ifdef INCLUDE_KLATT
|
||||
KlattInit();
|
||||
#endif
|
||||
|
||||
#ifdef LOG_FRAMES
|
||||
remove("log-espeakedit");
|
||||
@@ -784,7 +782,7 @@ int GetAmplitude(void)
|
||||
// normal, none, reduced, moderate, strong
|
||||
static const unsigned char amp_emphasis[5] = {16, 16, 10, 16, 22};
|
||||
|
||||
amp = (embedded_value[EMBED_A])*60/100;
|
||||
amp = (embedded_value[EMBED_A])*55/100;
|
||||
general_amplitude = amp * amp_emphasis[embedded_value[EMBED_F]] / 16;
|
||||
return(general_amplitude);
|
||||
}
|
||||
@@ -903,6 +901,13 @@ int PeaksToHarmspect(wavegen_peaks_t *peaks, int pitch, int *htab, int control)
|
||||
}
|
||||
}
|
||||
|
||||
// increase bass, up to the F1 peak
|
||||
h=1;
|
||||
for(f=pitch; f<peaks[1].freq; f+=pitch)
|
||||
{
|
||||
htab[h++] += (peaks[1].height * 16);
|
||||
}
|
||||
|
||||
// find the nearest harmonic for HF peaks where we don't use shape
|
||||
for(; pk<N_PEAKS; pk++)
|
||||
{
|
||||
@@ -961,10 +966,10 @@ static void AdvanceParameters()
|
||||
static int Flutter_ix = 0;
|
||||
|
||||
// advance the pitch
|
||||
pitch_ix += pitch_inc;
|
||||
if((ix = pitch_ix>>8) > 127) ix = 127;
|
||||
x = pitch_env[ix] * pitch_range;
|
||||
pitch = (x>>8) + pitch_base;
|
||||
wdata.pitch_ix += wdata.pitch_inc;
|
||||
if((ix = wdata.pitch_ix>>8) > 127) ix = 127;
|
||||
x = wdata.pitch_env[ix] * wdata.pitch_range;
|
||||
wdata.pitch = (x>>8) + wdata.pitch_base;
|
||||
|
||||
amp_ix += amp_inc;
|
||||
|
||||
@@ -973,9 +978,9 @@ static void AdvanceParameters()
|
||||
Flutter_ix = 0;
|
||||
x = ((int)(Flutter_tab[Flutter_ix >> 6])-0x80) * flutter_amp;
|
||||
Flutter_ix += Flutter_inc;
|
||||
pitch += x;
|
||||
if(pitch < 102400)
|
||||
pitch = 102400; // min pitch, 25 Hz (25 << 12)
|
||||
wdata.pitch += x;
|
||||
if(wdata.pitch < 102400)
|
||||
wdata.pitch = 102400; // min pitch, 25 Hz (25 << 12)
|
||||
|
||||
if(samplecount == samplecount_start)
|
||||
return;
|
||||
@@ -1159,26 +1164,26 @@ int Wavegen()
|
||||
{
|
||||
hswitch = 0;
|
||||
harmspect = hspect[0];
|
||||
maxh2 = PeaksToHarmspect(peaks,pitch<<4,hspect[0],0);
|
||||
maxh2 = PeaksToHarmspect(peaks, wdata.pitch<<4, hspect[0], 0);
|
||||
|
||||
// adjust amplitude to compensate for fewer harmonics at higher pitch
|
||||
amplitude2 = (amplitude * pitch)/(100 << 11);
|
||||
amplitude2 = (wdata.amplitude * wdata.pitch)/(100 << 11);
|
||||
|
||||
// switch sign of harmonics above about 900Hz, to reduce max peak amplitude
|
||||
h_switch_sign = 890 / (pitch >> 12);
|
||||
h_switch_sign = 890 / (wdata.pitch >> 12);
|
||||
}
|
||||
else
|
||||
AdvanceParameters();
|
||||
|
||||
// pitch is Hz<<12
|
||||
phaseinc = (pitch>>7) * PHASE_INC_FACTOR;
|
||||
cycle_samples = samplerate/(pitch >> 12); // sr/(pitch*2)
|
||||
hf_factor = pitch >> 11;
|
||||
phaseinc = (wdata.pitch>>7) * PHASE_INC_FACTOR;
|
||||
cycle_samples = samplerate/(wdata.pitch >> 12); // sr/(pitch*2)
|
||||
hf_factor = wdata.pitch >> 11;
|
||||
|
||||
maxh = maxh2;
|
||||
harmspect = hspect[hswitch];
|
||||
hswitch ^= 1;
|
||||
maxh2 = PeaksToHarmspect(peaks,pitch<<4,hspect[hswitch],1);
|
||||
maxh2 = PeaksToHarmspect(peaks, wdata.pitch<<4, hspect[hswitch], 1);
|
||||
|
||||
SetBreath();
|
||||
}
|
||||
@@ -1211,11 +1216,11 @@ int Wavegen()
|
||||
for(pk=wvoice->n_harmonic_peaks+1; pk<N_PEAKS; pk++)
|
||||
{
|
||||
// find the nearest harmonic for HF peaks where we don't use shape
|
||||
peak_harmonic[pk] = peaks[pk].freq / (pitch*16);
|
||||
peak_harmonic[pk] = peaks[pk].freq / (wdata.pitch*16);
|
||||
}
|
||||
|
||||
// adjust amplitude to compensate for fewer harmonics at higher pitch
|
||||
amplitude2 = (amplitude * pitch)/(100 << 11);
|
||||
amplitude2 = (wdata.amplitude * wdata.pitch)/(100 << 11);
|
||||
|
||||
if(glottal_flag > 0)
|
||||
{
|
||||
@@ -1337,22 +1342,22 @@ int Wavegen()
|
||||
|
||||
// mix with sampled wave if required
|
||||
z2 = 0;
|
||||
if(mix_wavefile_ix < n_mix_wavefile)
|
||||
if(wdata.mix_wavefile_ix < wdata.n_mix_wavefile)
|
||||
{
|
||||
if(mix_wave_scale == 0)
|
||||
if(wdata.mix_wave_scale == 0)
|
||||
{
|
||||
// a 16 bit sample
|
||||
c = mix_wavefile[mix_wavefile_ix+1];
|
||||
sample = mix_wavefile[mix_wavefile_ix] + (c * 256);
|
||||
mix_wavefile_ix += 2;
|
||||
c = wdata.mix_wavefile[wdata.mix_wavefile_ix+1];
|
||||
sample = wdata.mix_wavefile[wdata.mix_wavefile_ix] + (c * 256);
|
||||
wdata.mix_wavefile_ix += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// a 8 bit sample, scaled
|
||||
sample = (signed char)mix_wavefile[mix_wavefile_ix++] * mix_wave_scale;
|
||||
sample = (signed char)wdata.mix_wavefile[wdata.mix_wavefile_ix++] * wdata.mix_wave_scale;
|
||||
}
|
||||
z2 = (sample * amplitude_v) >> 10;
|
||||
z2 = (z2 * mix_wave_amp)/32;
|
||||
z2 = (sample * wdata.amplitude_v) >> 10;
|
||||
z2 = (z2 * wdata.mix_wave_amp)/32;
|
||||
}
|
||||
|
||||
z1 = z2 + (((total>>8) * amplitude2) >> 13);
|
||||
@@ -1587,8 +1592,8 @@ static void SetAmplitude(int length, unsigned char *amp_env, int value)
|
||||
else
|
||||
amp_inc = (256 * ENV_LEN * STEPSIZE)/length;
|
||||
|
||||
amplitude = (value * general_amplitude)/16;
|
||||
amplitude_v = (amplitude * wvoice->consonant_ampv * 15)/100; // for wave mixed with voiced sounds
|
||||
wdata.amplitude = (value * general_amplitude)/16;
|
||||
wdata.amplitude_v = (wdata.amplitude * wvoice->consonant_ampv * 15)/100; // for wave mixed with voiced sounds
|
||||
|
||||
amplitude_env = amp_env;
|
||||
}
|
||||
@@ -1641,18 +1646,18 @@ if(option_log_frames)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if((pitch_env = env)==NULL)
|
||||
pitch_env = env_fall; // default
|
||||
if((wdata.pitch_env = env)==NULL)
|
||||
wdata.pitch_env = env_fall; // default
|
||||
|
||||
pitch_ix = 0;
|
||||
wdata.pitch_ix = 0;
|
||||
if(length==0)
|
||||
pitch_inc = 0;
|
||||
wdata.pitch_inc = 0;
|
||||
else
|
||||
pitch_inc = (256 * ENV_LEN * STEPSIZE)/length;
|
||||
wdata.pitch_inc = (256 * ENV_LEN * STEPSIZE)/length;
|
||||
|
||||
SetPitch2(wvoice, pitch1, pitch2, &pitch_base, &pitch_range);
|
||||
SetPitch2(wvoice, pitch1, pitch2, &wdata.pitch_base, &wdata.pitch_range);
|
||||
// set initial pitch
|
||||
pitch = ((pitch_env[0]*pitch_range)>>8) + pitch_base; // Hz << 12
|
||||
wdata.pitch = ((wdata.pitch_env[0] * wdata.pitch_range) >>8) + wdata.pitch_base; // Hz << 12
|
||||
|
||||
flutter_amp = wvoice->flutter;
|
||||
|
||||
@@ -1662,15 +1667,14 @@ if(option_log_frames)
|
||||
|
||||
|
||||
|
||||
void SetSynth(int length, int modn, frame_t *fr1, frame_t *fr2)
|
||||
{//============================================================
|
||||
void SetSynth(int length, int modn, frame_t *fr1, frame_t *fr2, voice_t *v)
|
||||
{//========================================================================
|
||||
int ix;
|
||||
DOUBLEX next;
|
||||
int length2;
|
||||
int length4;
|
||||
int qix;
|
||||
int cmd;
|
||||
voice_t *v;
|
||||
static int glottal_reduce_tab1[4] = {0x30, 0x30, 0x40, 0x50}; // vowel before [?], amp * 1/256
|
||||
// static int glottal_reduce_tab1[4] = {0x30, 0x40, 0x50, 0x60}; // vowel before [?], amp * 1/256
|
||||
static int glottal_reduce_tab2[4] = {0x90, 0xa0, 0xb0, 0xc0}; // vowel after [?], amp * 1/256
|
||||
@@ -1724,8 +1728,6 @@ if(option_log_frames)
|
||||
break; // next is not from spectrum, so continue until end of wave cycle
|
||||
}
|
||||
|
||||
v = wvoice;
|
||||
|
||||
// round the length to a multiple of the stepsize
|
||||
length2 = (length + STEPSIZE/2) & ~0x3f;
|
||||
if(length2 == 0)
|
||||
@@ -1767,7 +1769,7 @@ if(option_log_frames)
|
||||
static int Wavegen2(int length, int modulation, int resume, frame_t *fr1, frame_t *fr2)
|
||||
{//====================================================================================
|
||||
if(resume==0)
|
||||
SetSynth(length,modulation,fr1,fr2);
|
||||
SetSynth(length, modulation, fr1, fr2, wvoice);
|
||||
|
||||
return(Wavegen());
|
||||
}
|
||||
@@ -1839,35 +1841,46 @@ int WavegenFill(int fill_zeros)
|
||||
{
|
||||
echo_complete -= length;
|
||||
}
|
||||
n_mix_wavefile = 0;
|
||||
wdata.n_mix_wavefile = 0;
|
||||
wdata.prev_was_synth = 0;
|
||||
result = PlaySilence(length,resume);
|
||||
break;
|
||||
|
||||
case WCMD_WAVE:
|
||||
echo_complete = echo_length;
|
||||
n_mix_wavefile = 0;
|
||||
wdata.n_mix_wavefile = 0;
|
||||
wdata.prev_was_synth = 0;
|
||||
result = PlayWave(length,resume,(unsigned char*)q[2], q[3] & 0xff, q[3] >> 8);
|
||||
break;
|
||||
|
||||
case WCMD_WAVE2:
|
||||
// wave file to be played at the same time as synthesis
|
||||
mix_wave_amp = q[3] >> 8;
|
||||
mix_wave_scale = q[3] & 0xff;
|
||||
if(mix_wave_scale == 0)
|
||||
n_mix_wavefile = length*2;
|
||||
wdata.mix_wave_amp = q[3] >> 8;
|
||||
wdata.mix_wave_scale = q[3] & 0xff;
|
||||
if(wdata.mix_wave_scale == 0)
|
||||
wdata.n_mix_wavefile = length*2;
|
||||
else
|
||||
n_mix_wavefile = length;
|
||||
mix_wavefile_ix = 0;
|
||||
mix_wavefile = (unsigned char *)q[2];
|
||||
wdata.n_mix_wavefile = length;
|
||||
wdata.mix_wavefile_ix = 0;
|
||||
wdata.mix_wavefile = (unsigned char *)q[2];
|
||||
break;
|
||||
|
||||
case WCMD_SPECT2: // as WCMD_SPECT but stop any concurrent wave file
|
||||
n_mix_wavefile = 0; // ... and drop through to WCMD_SPECT case
|
||||
wdata.n_mix_wavefile = 0; // ... and drop through to WCMD_SPECT case
|
||||
case WCMD_SPECT:
|
||||
echo_complete = echo_length;
|
||||
result = Wavegen2(length & 0xffff,q[1] >> 16,resume,(frame_t *)q[2],(frame_t *)q[3]);
|
||||
break;
|
||||
|
||||
#ifdef INCLUDE_KLATT
|
||||
case WCMD_KLATT2: // as WCMD_SPECT but stop any concurrent wave file
|
||||
wdata.n_mix_wavefile = 0; // ... and drop through to WCMD_SPECT case
|
||||
case WCMD_KLATT:
|
||||
echo_complete = echo_length;
|
||||
result = Wavegen_Klatt2(length & 0xffff,q[1] >> 16,resume,(frame_t *)q[2],(frame_t *)q[3]);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case WCMD_MARKER:
|
||||
MarkerEvent(q[1],q[2],q[3],out_ptr);
|
||||
#ifdef LOG_FRAMES
|
||||
|
||||
Reference in New Issue
Block a user