#include "wx/wx.h" | #include "wx/wx.h" | ||||
#include "wx/wfstream.h" | |||||
#include "wx/image.h" | |||||
#include "wx/filename.h" | |||||
#include "wx/numdlg.h" | |||||
#include "wx/mdi.h" | |||||
#include "wx/laywin.h" | |||||
#include "wx/sashwin.h" | |||||
#include "wx/utils.h" | |||||
#include "wx/html/htmlwin.h" | |||||
#include <locale.h> | #include <locale.h> | ||||
#include "speak_lib.h" | #include "speak_lib.h" |
#include "wx/wx.h" | #include "wx/wx.h" | ||||
#include "wx/fileconf.h" | #include "wx/fileconf.h" | ||||
#include "wx/filename.h" | |||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
#include "speech.h" | #include "speech.h" | ||||
#include "wx/msw/registry.h" | #include "wx/msw/registry.h" | ||||
#endif | #endif | ||||
wxString path_espeakdata; | |||||
wxString path_spectload; | |||||
wxString path_spectload2; | |||||
wxString path_pitches; | |||||
wxString path_phfile; | wxString path_phfile; | ||||
wxString path_phsource; | wxString path_phsource; | ||||
wxString path_dictsource; | wxString path_dictsource; | ||||
wxString path_modifiervoice; | |||||
wxString path_dir1; | |||||
char path_source[sizeof(path_home)+20]; | char path_source[sizeof(path_home)+20]; | ||||
char path_dsource[sizeof(path_home)+20]; | char path_dsource[sizeof(path_home)+20]; | ||||
wxFileConfig::Set(pConfig); | wxFileConfig::Set(pConfig); | ||||
basedir = wxString(path_base,wxConvLocal); // this is only used to set defaults for other paths if they are not in the config file | basedir = wxString(path_base,wxConvLocal); // this is only used to set defaults for other paths if they are not in the config file | ||||
if (use_defaults) | |||||
{ | |||||
path_spectload = basedir + _T("/../phsource"); | |||||
path_spectload2 = basedir + _T("/../phsource"); | |||||
path_pitches = basedir + _T("/pitch"); | |||||
path_phsource = basedir + _T("/../phsource"); | |||||
path_phfile = path_phsource + _T("/phonemes"); | |||||
path_dictsource = basedir + _T("/../dictsource"); | |||||
path_modifiervoice = basedir; | |||||
path_dir1 = basedir; | |||||
} | |||||
else | |||||
{ | |||||
pConfig->Read(_T("/espeakdata"),&path_espeakdata,wxEmptyString); | |||||
if(path_espeakdata != wxEmptyString) | |||||
{ | |||||
strcpy(path_home, path_espeakdata.mb_str(wxConvLocal)); | |||||
} | |||||
path_phsource = basedir + _T("/../phsource"); | |||||
path_phfile = path_phsource + _T("/phonemes"); | |||||
path_dictsource = basedir + _T("/../dictsource"); | |||||
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("/voicename"),&string,wxEmptyString); | |||||
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("/modifiervoice"),&path_modifiervoice,basedir); | |||||
pConfig->Read(_T("/dir1"),&path_dir1,basedir); | |||||
} | |||||
ConfigSetPaths(); | ConfigSetPaths(); | ||||
} // end of ConfigInit | } // end of ConfigInit |
#include "wx/wx.h" | #include "wx/wx.h" | ||||
#include "wx/numdlg.h" | |||||
#include "speak_lib.h" | #include "speak_lib.h" | ||||
#include "speech.h" | #include "speech.h" |
#include "voice.h" | #include "voice.h" | ||||
#include "spect.h" | #include "spect.h" | ||||
#include "wx/txtstrm.h" | #include "wx/txtstrm.h" | ||||
#include "wx/brush.h" | |||||
#include "wx/datstrm.h" | #include "wx/datstrm.h" | ||||
extern int pk_select; | extern int pk_select; | ||||
extern char voice_name[]; | extern char voice_name[]; | ||||
wxPen BLUE_PEN(wxColour(0,0,255),2,wxSOLID); | |||||
wxBrush BRUSH_SELECTED_PEAK(wxColour(255,180,180),wxSOLID); | |||||
wxBrush BRUSH_MARKER[N_MARKERS] = { | |||||
wxBrush(wxColour(200,0,255),wxSOLID), | |||||
wxBrush(wxColour(255,0,0),wxSOLID), | |||||
wxBrush(wxColour(255,200,0),wxSOLID), | |||||
wxBrush(wxColour(0,255,0),wxSOLID), | |||||
wxBrush(wxColour(0,255,255),wxSOLID), | |||||
wxBrush(wxColour(200,0,255),wxSOLID), | |||||
wxBrush(wxColour(200,0,255),wxSOLID), | |||||
wxBrush(wxColour(255,0,200),wxSOLID) }; | |||||
#define DRAWPEAKWIDTH 2000 | #define DRAWPEAKWIDTH 2000 | ||||
#define PEAKSHAPEW 256 | #define PEAKSHAPEW 256 | ||||
int ix; | int ix; | ||||
FONT_SMALL = wxFont(8, wxSWISS, wxNORMAL, wxNORMAL); // wxWidgets 3, Font creation needs a GTK+ Window | |||||
FONT_MEDIUM = wxFont(9, wxSWISS, wxNORMAL, wxNORMAL); | |||||
selected = 0; | selected = 0; | ||||
keyframe = 0; | keyframe = 0; | ||||
spect = NULL; | spect = NULL; | ||||
} // End of SpectFrame::Load | } // End of SpectFrame::Load | ||||
int SpectFrame::Save(wxOutputStream& stream, int file_format_type) | |||||
{//=============================================================== | |||||
int ix; | |||||
wxDataOutputStream s(stream); | |||||
s.WriteDouble(time); | |||||
s.WriteDouble(pitch); | |||||
s.WriteDouble(length); | |||||
s.WriteDouble(dx); | |||||
s.Write16(nx); | |||||
s.Write16(markers); | |||||
s.Write16(amp_adjust); | |||||
if(file_format_type == 2) | |||||
{ | |||||
s.Write16(0); // spare | |||||
s.Write16(0); // spare | |||||
} | |||||
for(ix=0; ix<N_PEAKS; ix++) | |||||
{ | |||||
s.Write16(formants[ix].freq); | |||||
s.Write16(formants[ix].bandw); | |||||
s.Write16(peaks[ix].pkfreq); | |||||
s.Write16(keyframe ? peaks[ix].pkheight : 0); | |||||
s.Write16(peaks[ix].pkwidth); | |||||
s.Write16(peaks[ix].pkright); | |||||
if(file_format_type == 2) | |||||
{ | |||||
s.Write16(peaks[ix].klt_bw); | |||||
s.Write16(peaks[ix].klt_ap); | |||||
s.Write16(peaks[ix].klt_bp); | |||||
} | |||||
} | |||||
if(file_format_type > 0) | |||||
{ | |||||
for(ix=0; ix<N_KLATTP2; ix++) | |||||
{ | |||||
s.Write16(klatt_param[ix]); | |||||
} | |||||
} | |||||
for(ix=0; ix<nx; ix++) | |||||
{ | |||||
s.Write16(spect[ix]); | |||||
} | |||||
return(0); | |||||
} // end of SpectFrame::Save | |||||
void SpectFrame::ZeroPeaks() | void SpectFrame::ZeroPeaks() | ||||
{//========================= | {//========================= | ||||
total += ((htab[h] * htab[h]) >> 10); | total += ((htab[h] * htab[h]) >> 10); | ||||
} | } | ||||
rms = sqrt(total) / 7.25; | rms = sqrt(total) / 7.25; | ||||
// DrawPeaks(NULL,0,0,amp); | |||||
return(rms); | return(rms); | ||||
} | } | ||||
void SpectFrame::DrawPeaks(wxDC *dc, int offy, int frame_width, int seq_amplitude, double scale_x) | |||||
{//============================================================================================== | |||||
// dc==NULL means don't draw, just calculate RMS | |||||
int peak; | |||||
peak_t *pk; | |||||
int x1,x2,x3,width,ix; | |||||
int y1, y2; | |||||
double yy; | |||||
int max_ix; | |||||
int height; | |||||
int pkright; | |||||
int pkwidth; | |||||
int buf[DRAWPEAKWIDTH*2]; | |||||
max_ix = int(9000 * scale_x); | |||||
memset(buf,0,sizeof(buf)); | |||||
for(peak=0; peak<N_PEAKS; peak++) | |||||
{ | |||||
pk = &peaks[peak]; | |||||
if((pk->pkfreq == 0) || (pk->pkheight==0)) continue; | |||||
height = pk->pkheight; | |||||
pkright = pk->pkright; | |||||
pkwidth = pk->pkwidth; | |||||
x1 = (int)(pk->pkfreq*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 | |||||
if((width = x2-x1) <= 0) continue; | |||||
for(ix=0; ix<width; ix++) | |||||
{ | |||||
buf[x1+ix] += height * pk_shape1[(ix*PEAKSHAPEW)/width]; | |||||
} | |||||
if((width = x1-x3) <= 0) continue; | |||||
for(ix=1; ix<width; ix++) | |||||
{ | |||||
if(x3+ix >= 0) | |||||
{ | |||||
buf[x3+ix] += height * pk_shape1[((width-ix)*PEAKSHAPEW)/width]; | |||||
} | |||||
} | |||||
} | |||||
rms = buf[0]>>12; | |||||
rms = rms*rms*23; | |||||
rms = rms*rms; | |||||
if(dc != NULL) dc->SetPen(*wxGREEN_PEN); | |||||
x1 = 0; | |||||
y1 = offy - ((buf[0] * FRAME_HEIGHT) >> 21); | |||||
for(ix=1; ix<max_ix; ix++) | |||||
{ | |||||
yy = buf[ix]>>12; | |||||
yy = yy*yy*23; | |||||
rms += (yy*yy); | |||||
x2 = ix; | |||||
y2 = offy - ((buf[ix] * FRAME_HEIGHT) >> 21); | |||||
if(dc != NULL) dc->DrawLine(x1,y1,x2,y2); | |||||
x1 = x2; | |||||
y1 = y2; | |||||
} | |||||
rms = sqrt(rms)/200000.0; | |||||
// apply adjustment from spectseq amplitude | |||||
rms = rms * seq_amplitude * amp_adjust / 10000.0; | |||||
rms = GetRms(seq_amplitude); | |||||
} // end of SpectFrame::DrawPeaks | |||||
void SpectFrame::KlattDefaults() | void SpectFrame::KlattDefaults() | ||||
{//============================ | {//============================ | ||||
// set default values for Klatt parameters | // set default values for Klatt parameters |
* <http://www.gnu.org/licenses/>. * | * <http://www.gnu.org/licenses/>. * | ||||
***************************************************************************/ | ***************************************************************************/ | ||||
#include "wx/spinctrl.h" | |||||
#include "wx/notebook.h" | |||||
#define PROGRAM_NAME _T("Voice Editor") | #define PROGRAM_NAME _T("Voice Editor") | ||||
#define FRAME_WIDTH 1000 // max width for 8000kHz frame | #define FRAME_WIDTH 1000 // max width for 8000kHz frame | ||||
int Import(wxInputStream &stream); | int Import(wxInputStream &stream); | ||||
int ImportSPC2(wxInputStream &stream, float &time_acc); | int ImportSPC2(wxInputStream &stream, float &time_acc); | ||||
int Load(wxInputStream &stream, int file_format_type); | int Load(wxInputStream &stream, int file_format_type); | ||||
int Save(wxOutputStream &stream, int file_format_type); | |||||
void ZeroPeaks(); | void ZeroPeaks(); | ||||
void CopyPeaks(SpectFrame *sf); | void CopyPeaks(SpectFrame *sf); | ||||
formant_t formants[N_PEAKS]; // this is just the estimate given by Praat | formant_t formants[N_PEAKS]; // this is just the estimate given by Praat | ||||
peak_t peaks[N_PEAKS]; | peak_t peaks[N_PEAKS]; | ||||
private: | |||||
void DrawPeaks(wxDC *dc, int offy, int frame_width, int seq_amplitude, double scalex); | |||||
wxFont FONT_SMALL; | |||||
wxFont FONT_MEDIUM; | |||||
}; | }; | ||||
class SpectSeq | class SpectSeq | ||||
~SpectSeq(); | ~SpectSeq(); | ||||
int Import(wxInputStream& stream); | int Import(wxInputStream& stream); | ||||
int ImportSPC2(wxInputStream& stream); | int ImportSPC2(wxInputStream& stream); | ||||
int Save(wxOutputStream& stream, int selection); | |||||
int Load(wxInputStream& stream); | int Load(wxInputStream& stream); | ||||
void MakePitchenv(PitchEnvelope &pitch, int start_frame, int end_frame); | |||||
void InterpolatePeaks(int on); | void InterpolatePeaks(int on); | ||||
void CopyDown(int frame, int direction); | void CopyDown(int frame, int direction); | ||||
float GetFrameLength(int frame, int plus, int *original_mS); | float GetFrameLength(int frame, int plus, int *original_mS); | ||||
float GetKeyedLength(); | float GetKeyedLength(); | ||||
void SetFrameLengths(); | void SetFrameLengths(); | ||||
void ConstructVowel(void); | |||||
int numframes; | int numframes; | ||||
int amplitude; | int amplitude; | ||||
private: | private: | ||||
void Load2(wxInputStream& stream, int import, int n); | void Load2(wxInputStream& stream, int import, int n); | ||||
void InterpolatePeak(int peak); | void InterpolatePeak(int peak); | ||||
void ApplyAmp_adjust(SpectFrame *sp, peak_t *peaks); | |||||
double scalex; | |||||
double scaley; | |||||
}; | }; |
#include "synthesize.h" | #include "synthesize.h" | ||||
#include "voice.h" | #include "voice.h" | ||||
#include "spect.h" | #include "spect.h" | ||||
#include "wx/numdlg.h" | |||||
#include "wx/txtstrm.h" | #include "wx/txtstrm.h" | ||||
#include "wx/datstrm.h" | #include "wx/datstrm.h" | ||||
} // end of SpectSeq::Load | } // end of SpectSeq::Load | ||||
int SpectSeq::Save(wxOutputStream &stream, int selection) | |||||
{//====================================================== | |||||
int ix; | |||||
int count=numframes; | |||||
if(selection) | |||||
{ | |||||
count = CountSelected(); | |||||
} | |||||
SetFrameLengths(); | |||||
wxDataOutputStream s(stream); | |||||
file_format = 2; // inclue Klatt data in new saves | |||||
s.Write32(FILEID1_SPECTSEQ); | |||||
if(file_format == 2) | |||||
s.Write32(FILEID2_SPECTSQ2); | |||||
else | |||||
if(file_format == 1) | |||||
s.Write32(FILEID2_SPECTSEK); | |||||
else | |||||
s.Write32(FILEID2_SPECTSEQ); | |||||
s.WriteString(name); | |||||
s.Write16(count); | |||||
s.Write16(amplitude); | |||||
s.Write16(selection ? max_y : 0); | |||||
s.Write16(0); // spare | |||||
for(ix=0; ix<numframes; ix++) | |||||
{ | |||||
if((selection==0) || frames[ix]->selected) | |||||
{ | |||||
if(frames[ix]->Save(stream, file_format) != 0) return(1); | |||||
} | |||||
} | |||||
return(0); | |||||
} // end of SpectSeq::Save | |||||
void SpectSeq::ConstructVowel(void) | |||||
{//================================ | |||||
// not completed | |||||
int ix; | |||||
int j=0; | |||||
int frames_selected[4]; | |||||
for(ix=0; ix<numframes; ix++) | |||||
{ | |||||
if(frames[ix]->selected) | |||||
{ | |||||
if(ix >= 4) | |||||
break; | |||||
frames_selected[j++] = ix; | |||||
} | |||||
} | |||||
if(j==0 || j>= 4) | |||||
return; | |||||
if(frames_selected[0] == 0) | |||||
return; | |||||
} // end of ConstructVowel | |||||
void SpectSeq::InterpolatePeak(int peak) | void SpectSeq::InterpolatePeak(int peak) | ||||
{//===================================== | {//===================================== | ||||
int f, f1=0, f2; | int f, f1=0, f2; | ||||
} // end of CopyDown | } // end of CopyDown | ||||
void SpectSeq::MakePitchenv(PitchEnvelope &pitchenv, int start_frame, int end_frame) | |||||
{//================================================================================= | |||||
double f; | |||||
double min=8000; | |||||
double max=0; | |||||
double diff; | |||||
double t_start = -1; | |||||
double t_end=0, t_diff; | |||||
double yy; | |||||
int ix; | |||||
int x, y; | |||||
int xx; | |||||
int nx=0; | |||||
float *ax, *ay; | |||||
memset(pitchenv.env,127,128); | |||||
for(ix=start_frame; ix<=end_frame; ix++) | |||||
{ | |||||
if((f = frames[ix]->pitch) == 0) continue; | |||||
nx++; | |||||
t_end = frames[ix]->time; | |||||
if(t_start < 0) t_start = t_end; | |||||
if(f < min) min = f; | |||||
if(f > max) max = f; | |||||
} | |||||
diff = max-min; | |||||
t_diff = t_end - t_start; | |||||
if(nx<2 || diff<=0 || t_diff<=0) | |||||
{ | |||||
// no pitch info, use defaults | |||||
pitchenv.pitch1=80; | |||||
pitchenv.pitch2=120; | |||||
return; | |||||
} | |||||
pitchenv.pitch1 = int(min); | |||||
pitchenv.pitch2 = int(max); | |||||
ax = new float [nx+1]; | |||||
ay = new float[nx+1]; | |||||
nx = 0; | |||||
for(ix=start_frame; ix<=end_frame; ix++) | |||||
{ | |||||
if((f = frames[ix]->pitch) == 0) continue; | |||||
ax[++nx] = (frames[ix]->time - t_start) * 128 / t_diff; | |||||
ay[nx] = (frames[ix]->pitch - min) * 255 / diff; | |||||
} | |||||
pitchenv.env[0] = int(ay[1]); | |||||
pitchenv.env[127] = int(ay[nx]); | |||||
// create pitch envelope by interpolating the time/pitch | |||||
// values from the spectrum sequence | |||||
xx = 1; | |||||
for(x=1; x<127; x++) | |||||
{ | |||||
while((ax[xx] < x) && (xx < nx)) xx++; | |||||
if(xx < 3) | |||||
yy = polint(&ax[xx-1],&ay[xx-1],3,(float)x); | |||||
else if(xx > nx-1) | |||||
yy = polint(&ax[xx-2],&ay[xx-2],3,(float)x); | |||||
else | |||||
yy = polint(&ax[xx-2],&ay[xx-2],4,(float)x); | |||||
y = int(yy); | |||||
if(y < 0) y = 0; | |||||
if(y > 255) y = 255; | |||||
pitchenv.env[x] = y; | |||||
} | |||||
delete ax; | |||||
delete ay; | |||||
} // end of SpectSeq::MakePitchenv | |||||
void SpectSeq::ApplyAmp_adjust(SpectFrame *sp, peak_t *peaks) | |||||
{//============================================================= | |||||
int ix; | |||||
int y; | |||||
memcpy(peaks,sp->peaks,sizeof(*peaks)*N_PEAKS); | |||||
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(SpectFrame *sp1, peak_t *pks, frame_t *fr) | void PeaksToFrame(SpectFrame *sp1, peak_t *pks, frame_t *fr) | ||||
{//========================================================= | {//========================================================= | ||||
int ix; | int ix; |