eSpeak NG is an open source speech synthesizer that supports more than hundred languages and accents.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

spectseq.cpp 22KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085
  1. /***************************************************************************
  2. * Copyright (C) 2005,2006 by Jonathan Duddington *
  3. * [email protected] *
  4. * *
  5. * This program is free software; you can redistribute it and/or modify *
  6. * it under the terms of the GNU General Public License as published by *
  7. * the Free Software Foundation; either version 2 of the License, or *
  8. * (at your option) any later version. *
  9. * *
  10. * This program is distributed in the hope that it will be useful, *
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  13. * GNU General Public License for more details. *
  14. * *
  15. * You should have received a copy of the GNU General Public License *
  16. * along with this program; if not, write to the *
  17. * Free Software Foundation, Inc., *
  18. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  19. ***************************************************************************/
  20. #include "wx/wx.h"
  21. #include <math.h>
  22. #include "speech.h"
  23. #include "voice.h"
  24. #include "spect.h"
  25. #include "main.h"
  26. #include "wx/numdlg.h"
  27. #include "wx/txtstrm.h"
  28. #include "wx/datstrm.h"
  29. #define MAX_HARMONIC 400 // 400 * 50Hz = 20 kHz, more than enough
  30. int SpeakNextClause(FILE *f_text, const void *text_in, int control);
  31. extern void SetSynth(int length, int modn, frame_t *fr1, frame_t *fr2);
  32. static int frame_width;
  33. int pk_select;
  34. wxBrush CREAM_BRUSH(wxColour(255,253,245),wxSOLID);
  35. wxPen BORDER_PEN(wxColour(255,240,0),4,wxSOLID);
  36. wxPen VLIGHT_GREY_PEN(wxColour(230,230,230),1,wxSOLID);
  37. float polint(float xa[],float ya[],int n,float x)
  38. {//==============================================
  39. // General polinomial interpolation routine, xa[1...n] ya[1...n]
  40. int i,m,ns=1;
  41. float den,dif,dift,ho,hp,w;
  42. float y; // result
  43. float c[9],d[9];
  44. dif=fabs(x-xa[1]);
  45. for(i=1;i<=n;i++){
  46. if((dift=fabs(x-xa[i])) < dif) {
  47. ns=i;
  48. dif=dift;
  49. }
  50. c[i]=ya[i];
  51. d[i]=ya[i];
  52. }
  53. y=ya[ns--];
  54. for(m=1;m<n;m++) {
  55. for(i=1;i<=n-m;i++) {
  56. ho=xa[i]-x;
  57. hp=xa[i+m]-x;
  58. w=c[i+1]-d[i];
  59. if((den=ho-hp) == 0.0)
  60. {
  61. // fprintf(stderr,"Error in routine 'polint'");
  62. return(ya[2]); // two input xa are identical
  63. }
  64. den=w/den;
  65. d[i]=hp*den;
  66. c[i]=ho*den;
  67. }
  68. y += ((2*ns < (n-m) ? c[ns+1] : d[ns--]));
  69. }
  70. return(y);
  71. } // end of polint
  72. static void PeaksZero(peak_t *sp, peak_t *zero)
  73. {//=====================================
  74. int pk;
  75. memcpy(zero,sp,sizeof(peak_t)*N_PEAKS);
  76. for(pk=0; pk<N_PEAKS; pk++)
  77. zero[pk].pkheight = 0;
  78. } // end of PeaksZero
  79. SpectSeq::SpectSeq(int n)
  80. {//======================
  81. numframes = n;
  82. if(n > 0)
  83. frames = new SpectFrame* [n];
  84. else
  85. frames = NULL;
  86. pk_select = 1;
  87. grid = 1;
  88. duration = 0;
  89. pitch1 = 0;
  90. pitch2 = 0;
  91. bass_reduction = 0;
  92. max_x = 3000;
  93. max_y = 1;
  94. }
  95. SpectSeq::~SpectSeq()
  96. {//==================
  97. int ix;
  98. if(frames != NULL)
  99. {
  100. for(ix=0; ix<numframes; ix++)
  101. {
  102. if(frames[ix] != NULL)
  103. delete frames[ix];
  104. }
  105. delete frames;
  106. }
  107. }
  108. void SpectSeq::SelectAll(int yes)
  109. {//==============================
  110. // select of deselect all frames in the sequence
  111. int ix;
  112. for(ix=0; ix<numframes; ix++)
  113. frames[ix]->selected = yes;
  114. }
  115. int SpectSeq::CountSelected()
  116. {//==========================
  117. int ix;
  118. int count=0;
  119. for(ix=0; ix<numframes; ix++)
  120. {
  121. if(frames[ix]->selected)
  122. count++;
  123. }
  124. return(count);
  125. } // end of SpectSeq::CountSelected
  126. void SpectSeq::DeleteSelected()
  127. {//============================
  128. int ix;
  129. int count=0;
  130. for(ix=0; ix<numframes; ix++)
  131. {
  132. if(frames[ix]->selected)
  133. {
  134. count++;
  135. }
  136. else
  137. if(count > 0)
  138. {
  139. *frames[ix-count] = *frames[ix];
  140. }
  141. }
  142. numframes = numframes - count;
  143. } // end of SpectSeq::DeleteSelected
  144. void SpectSeq::ClipboardCopy()
  145. {//===========================
  146. int ix;
  147. int nframes;
  148. int count=0;
  149. nframes = CountSelected();
  150. if(nframes == 0) return;
  151. if(clipboard_spect != NULL)
  152. delete clipboard_spect;
  153. if((clipboard_spect = new SpectSeq(nframes))==NULL) return;
  154. for(ix=0; ix<numframes; ix++)
  155. {
  156. if(frames[ix]->selected)
  157. {
  158. if((clipboard_spect->frames[count] = new SpectFrame(frames[ix])) == NULL)
  159. break;
  160. count++;
  161. }
  162. }
  163. } // end of SpectSeq::ClipboardCopy
  164. int SpectSeq::ClipboardInsert(int insert_at)
  165. {//=========================================
  166. int ix;
  167. int j;
  168. int total;
  169. int result=insert_at;
  170. float thistime=0;
  171. float timeinc=0;
  172. float timeoffset=0;
  173. SpectFrame **frames2;
  174. if(clipboard_spect == NULL) return(result);
  175. if(clipboard_spect->numframes == 0) return(result);
  176. timeoffset = clipboard_spect->frames[0]->time;
  177. if(CountSelected() == 0)
  178. insert_at = -1;
  179. total = numframes + clipboard_spect->numframes;
  180. frames2 = new SpectFrame* [total];
  181. if(frames2 == NULL) return(result);
  182. total = 0;
  183. for(ix=0; ix<numframes; ix++)
  184. {
  185. thistime = frames[ix]->time;
  186. if(ix == insert_at)
  187. {
  188. result = total;
  189. for(j=0; j<clipboard_spect->numframes; j++)
  190. {
  191. frames2[total] = new SpectFrame(clipboard_spect->frames[j]);
  192. frames2[total]->time += (thistime - timeoffset);
  193. timeinc = frames2[total]->time - thistime + (frames2[total]->length/1000);
  194. total++;
  195. }
  196. }
  197. frames2[total] = new SpectFrame(frames[ix]);
  198. frames2[total++]->time += timeinc;
  199. }
  200. if(insert_at == -1)
  201. {
  202. // insert at the end
  203. result = total;
  204. for(j=0; j<clipboard_spect->numframes; j++)
  205. {
  206. frames2[total] = new SpectFrame(clipboard_spect->frames[j]);
  207. frames2[total++]->time += (thistime - timeoffset);
  208. }
  209. }
  210. delete frames;
  211. frames = frames2;
  212. numframes = total;
  213. return(result);
  214. } // end of SpectSeq::ClipboardInsert
  215. void SpectSeq::SetFrameLengths()
  216. {//=============================
  217. int frame;
  218. for(frame=0; frame<numframes; frame++)
  219. {
  220. if(frames[frame]->keyframe)
  221. frames[frame]->length = GetFrameLength(frame,1,NULL);
  222. else
  223. frames[frame]->length = 0;
  224. }
  225. } // end of SetFrameLengths
  226. float SpectSeq::GetFrameLength(int frame, int plus, int *original)
  227. {//===============================================================
  228. int ix;
  229. float adjust=0;
  230. if(frame >= numframes-1) return(0);
  231. // include the adjustment for this frame ?
  232. if(plus) adjust = frames[frame]->length_adjust;
  233. for(ix=frame+1; ix<numframes-1; ix++)
  234. {
  235. if(frames[ix]->keyframe) break; // reached next keyframe
  236. adjust += frames[ix]->length_adjust;
  237. }
  238. if(original != NULL)
  239. *original = int((frames[ix]->time - frames[frame]->time) * 1000.0 + 0.5);
  240. return ((frames[ix]->time - frames[frame]->time) * 1000.0 + adjust);
  241. }
  242. float SpectSeq::GetKeyedLength()
  243. {//=============================
  244. int ix;
  245. int first;
  246. int last=0;
  247. float adjust=0;
  248. first = -1;
  249. for(ix=0; ix<numframes; ix++)
  250. {
  251. if(frames[ix]->keyframe)
  252. {
  253. last = ix;
  254. if(first == -1) first = ix;
  255. }
  256. }
  257. if(first == -1)
  258. return(0); // no keyframes
  259. for(ix=first; ix<last; ix++)
  260. adjust += frames[ix]->length_adjust;
  261. return((frames[last]->time - frames[first]->time) * 1000 + adjust);
  262. }
  263. void SpectSeq::Load2(wxInputStream& stream, int import, int n)
  264. {//===========================================================
  265. // continuation of load/import
  266. int ix;
  267. wxString string;
  268. float time_offset;
  269. float time_acc=0;
  270. int set_max_y=0;
  271. if(n==0) return;
  272. if(frames != NULL) delete frames;
  273. frames = new SpectFrame* [n];
  274. numframes = 0;
  275. max_x = 3000;
  276. if(max_y == 0)
  277. {
  278. set_max_y = 1;
  279. max_y = 1;
  280. }
  281. for(ix = 0; ix < n; ix++)
  282. {
  283. SpectFrame *frame = new SpectFrame;
  284. if(import==1)
  285. {
  286. if(frame->Import(stream) != 0) break;
  287. }
  288. else
  289. if(import==2)
  290. {
  291. if(frame->ImportSPC2(stream,time_acc) != 0) break;
  292. }
  293. else
  294. {
  295. if(frame->Load(stream) != 0) break;
  296. }
  297. frames[numframes++] = frame;
  298. if(set_max_y && (frame->max_y > max_y))
  299. max_y = frame->max_y;
  300. if(frame->nx * frame->dx > max_x) max_x = int(frame->nx * frame->dx);
  301. }
  302. max_x = 9000; // disable auto-xscaling
  303. frame_width = int((FRAME_WIDTH*max_x)/MAX_DISPLAY_FREQ);
  304. if(frame_width > FRAME_WIDTH) frame_width = FRAME_WIDTH;
  305. // start times from zero
  306. time_offset = frames[0]->time;
  307. for(ix=0; ix<numframes; ix++)
  308. frames[ix]->time -= time_offset;
  309. pitch1 = pitchenv.pitch1;
  310. pitch2 = pitchenv.pitch2;
  311. duration = int(frames[numframes-1]->time * 1000);
  312. if(max_y < 400)
  313. max_y = 200;
  314. else
  315. max_y = 29000; // disable auto height scaling
  316. } // end of SpectSeq::Load2
  317. int SpectSeq::Import(wxInputStream& stream)
  318. {//========================================
  319. int n = 0;
  320. wxTextInputStream text_stream(stream);
  321. name = _T("");
  322. text_stream >> n;
  323. amplitude = 100;
  324. max_y = 0;
  325. Load2(stream,1,n);
  326. return(0);
  327. } // end of SpectSeq::Import
  328. int SPC2_size_cycle(CYCLE *cy)
  329. /****************************/
  330. /* Find number of bytes in cycle record */
  331. {
  332. int i;
  333. i = 44 + cy->n_harm;
  334. if(cy->flags & 1)
  335. {
  336. i += 4; /* label */
  337. }
  338. return(i);
  339. } /* end of size_cycle */
  340. int SpectSeq::ImportSPC2(wxInputStream & stream)
  341. {//=============================================
  342. // load an spectrum with an old "SPC2" format
  343. int n_cycles = 0;
  344. int x;
  345. CYCLE cy;
  346. int pos;
  347. /* count number of cycles */
  348. while(!stream.Eof())
  349. {
  350. pos = stream.TellI();
  351. stream.Read(&cy,44);
  352. pos = stream.TellI();
  353. if(stream.Eof()) break;
  354. n_cycles++;
  355. x = SPC2_size_cycle(&cy) - 44;
  356. stream.SeekI(x,wxFromCurrent);
  357. }
  358. if(n_cycles == 0) return(0);
  359. name = _T("");
  360. amplitude = 100;
  361. max_y = 0;
  362. stream.SeekI(4); // rewind and skip header
  363. Load2(stream,2,n_cycles);
  364. return(0);
  365. }
  366. int SpectSeq::Load(wxInputStream & stream)
  367. {//=======================================
  368. int n;
  369. int ix;
  370. unsigned int id1, id2;
  371. wxDataInputStream s(stream);
  372. id1 = s.Read32();
  373. id2 = s.Read32();
  374. if(id1 == FILEID1_SPC2)
  375. {
  376. stream.SeekI(4);
  377. return(ImportSPC2(stream));
  378. }
  379. if(id1 != FILEID1_SPECTSEQ || id2 != FILEID2_SPECTSEQ)
  380. {
  381. stream.SeekI(0);
  382. return(Import(stream));
  383. }
  384. name = s.ReadString();
  385. n = s.Read16();
  386. amplitude = s.Read16();
  387. max_y = s.Read16();
  388. s.Read16();
  389. Load2(stream,0,n);
  390. for(ix=0; ix<numframes; ix++)
  391. {
  392. if(frames[ix]->keyframe)
  393. frames[ix]->length_adjust = frames[ix]->length - GetFrameLength(ix,0,NULL);
  394. }
  395. return(0);
  396. } // end of SpectSeq::Load
  397. int SpectSeq::Save(wxOutputStream &stream, int selection)
  398. {//======================================================
  399. int ix;
  400. int count=numframes;
  401. if(selection)
  402. {
  403. count = CountSelected();
  404. }
  405. SetFrameLengths();
  406. wxDataOutputStream s(stream);
  407. s.Write32(FILEID1_SPECTSEQ);
  408. s.Write32(FILEID2_SPECTSEQ);
  409. s.WriteString(name);
  410. s.Write16(count);
  411. s.Write16(amplitude);
  412. s.Write16(selection ? max_y : 0);
  413. s.Write16(0); // spare
  414. for(ix=0; ix<numframes; ix++)
  415. {
  416. if((selection==0) || frames[ix]->selected)
  417. {
  418. if(frames[ix]->Save(stream) != 0) return(1);
  419. }
  420. }
  421. return(0);
  422. } // end of SpectSeq::Save
  423. void SpectSeq::ConstructVowel(void)
  424. {//================================
  425. // not completed
  426. int ix;
  427. int j=0;
  428. int frames_selected[4];
  429. for(ix=0; ix<numframes; ix++)
  430. {
  431. if(frames[ix]->selected)
  432. {
  433. if(ix >= 4)
  434. break;
  435. frames_selected[j++] = ix;
  436. }
  437. }
  438. if(j==0 || j>= 4)
  439. return;
  440. if(frames_selected[0] == 0)
  441. return;
  442. } // end of ConstructVowel
  443. void SpectSeq::Draw(wxDC& dc, int start_y, int end_y)
  444. {//==================================================
  445. int fm;
  446. int f, f1, f2;
  447. int x;
  448. if(end_y < start_y) return;
  449. if((start_y -= 4) < 0) start_y = 0;
  450. f1 = start_y / FRAME_HEIGHT;
  451. f2 = end_y / FRAME_HEIGHT;
  452. scaley = double(FRAME_HEIGHT) / max_y;
  453. scalex = double(frame_width) / max_x;
  454. // scalex = 0.6;
  455. for(fm=f1; fm <= f2 && fm < numframes; fm++)
  456. {
  457. if(frames[fm]->keyframe)
  458. {
  459. dc.SetBrush(CREAM_BRUSH);
  460. dc.SetPen(BORDER_PEN);
  461. }
  462. else
  463. {
  464. dc.SetBrush(*wxWHITE_BRUSH);
  465. dc.SetPen(*wxTRANSPARENT_PEN);
  466. }
  467. if(frames[fm]->selected)
  468. dc.SetPen(*wxRED_PEN);
  469. dc.DrawRectangle(0,FRAME_HEIGHT*fm+2,frame_width,
  470. FRAME_HEIGHT-2);
  471. }
  472. if(grid==1)
  473. {
  474. for(f=500; f<=MAX_DISPLAY_FREQ; f+=500)
  475. {
  476. x = int(f * scalex);
  477. if(x > max_x) break;
  478. if(f==3000 || f==6000 || f==9000)
  479. dc.SetPen(*wxLIGHT_GREY_PEN);
  480. else
  481. dc.SetPen(VLIGHT_GREY_PEN);
  482. dc.DrawLine(x,start_y,x,numframes*FRAME_HEIGHT);
  483. }
  484. }
  485. for(fm=f1; fm <= f2 && fm < numframes; fm++)
  486. {
  487. frames[fm]->Draw(dc,FRAME_HEIGHT*(fm+1),frame_width,
  488. scalex,scaley);
  489. }
  490. } // end of SpectSeq::Draw
  491. void SpectSeq::InterpolatePeak(int peak)
  492. {//=====================================
  493. int f, f1=0, f2;
  494. peak_t *p, *p1=NULL, *p2;
  495. double t1=0, t2;
  496. double interval;
  497. double ratio;
  498. int first = 1;
  499. for(f2=0; f2 < numframes; f2++)
  500. {
  501. if(frames[f2]->keyframe)
  502. {
  503. t2 = frames[f2]->time;
  504. p2 = &frames[f2]->peaks[peak];
  505. if(first)
  506. first = 0;
  507. else
  508. {
  509. interval = t2 - t1;
  510. for(f=f1+1; f<f2; f++)
  511. {
  512. p = &frames[f]->peaks[peak];
  513. ratio = (frames[f]->time - t1)/interval;
  514. p->pkfreq = p1->pkfreq + int((p2->pkfreq - p1->pkfreq)*ratio);
  515. p->pkheight=p1->pkheight+int((p2->pkheight-p1->pkheight)*ratio);
  516. p->pkwidth = p1->pkwidth + int((p2->pkwidth - p1->pkwidth)*ratio);
  517. p->pkright =p1->pkright + int((p2->pkright - p2->pkright)*ratio);
  518. }
  519. }
  520. f1 = f2;
  521. t1 = t2;
  522. p1 = p2;
  523. }
  524. }
  525. } // end of SpectSeq::InterpolatePeak
  526. void SpectSeq::InterpolateAdjacent(void)
  527. {//=====================================
  528. int ix;
  529. int f1 = -1;
  530. int select = -1;
  531. int f2 = -1;
  532. float ratio;
  533. peak_t *p = NULL;
  534. peak_t *p1 = NULL;
  535. peak_t *p2 = NULL;
  536. for(ix=0; ix<numframes; ix++)
  537. {
  538. if(frames[ix]->selected)
  539. select = ix;
  540. else
  541. if(frames[ix]->keyframe)
  542. {
  543. if(select >= 0)
  544. {
  545. f2 = ix;
  546. break;
  547. }
  548. else
  549. f1 = ix;
  550. }
  551. }
  552. if(f1 < 0)
  553. {
  554. wxLogError(_T("No previous keyframe"));
  555. return;
  556. }
  557. if(select < 0)
  558. {
  559. wxLogError(_T("No selected frame"));
  560. return;
  561. }
  562. if(f2 < 0)
  563. {
  564. wxLogError(_T("No subsequent keyframe"));
  565. return;
  566. }
  567. // get ratio
  568. ix = wxGetNumberFromUser(_T("Interpolate between adjacent frames"),_T("percent"),_T(""),50);
  569. ratio = (float)ix/100.0;
  570. for(ix=0; ix<N_PEAKS; ix++)
  571. {
  572. p = &frames[select]->peaks[ix];
  573. p1 = &frames[f1]->peaks[ix];
  574. p2 = &frames[f2]->peaks[ix];
  575. p->pkfreq = p1->pkfreq + int((p2->pkfreq - p1->pkfreq)*ratio);
  576. p->pkheight=p1->pkheight+int((p2->pkheight-p1->pkheight)*ratio);
  577. p->pkwidth = p1->pkwidth + int((p2->pkwidth - p1->pkwidth)*ratio);
  578. p->pkright =p1->pkright + int((p2->pkright - p2->pkright)*ratio);
  579. }
  580. frames[select]->keyframe = 1;
  581. formantdlg->ShowFrame(this,select,1,0xff);
  582. }
  583. void SpectSeq::InterpolatePeaks(int control)
  584. {//=========================================
  585. // 0=turn off 1=turn on
  586. int f, peak;
  587. if(control==1)
  588. {
  589. for(peak=0; peak<N_PEAKS; peak++)
  590. {
  591. InterpolatePeak(peak);
  592. }
  593. }
  594. else
  595. {
  596. for(f=0; f<numframes; f++)
  597. {
  598. if(frames[f]->keyframe == 0)
  599. frames[f]->ZeroPeaks();
  600. }
  601. }
  602. } // end of SpectSeq::InterpolatePeaks
  603. void SpectSeq::CopyDown(int frame, int direction)
  604. {//==============================================
  605. // Copy peaks down from next earlier/later keyframe
  606. int f1;
  607. int pk;
  608. for(f1=frame+direction; f1>=0 && f1<numframes; f1 += direction)
  609. {
  610. if(frames[f1]->keyframe)
  611. {
  612. for(pk=0; pk<N_PEAKS; pk++)
  613. {
  614. frames[frame]->peaks[pk].pkfreq = frames[f1]->peaks[pk].pkfreq;
  615. frames[frame]->peaks[pk].pkheight = frames[f1]->peaks[pk].pkheight;
  616. frames[frame]->peaks[pk].pkwidth = frames[f1]->peaks[pk].pkwidth;
  617. frames[frame]->peaks[pk].pkright = frames[f1]->peaks[pk].pkright;
  618. }
  619. break;
  620. }
  621. }
  622. } // end of CopyDown
  623. void SpectSeq::MakePitchenv(PitchEnvelope &pitchenv)
  624. {//=================================================
  625. double f;
  626. double min=8000;
  627. double max=0;
  628. double diff;
  629. double t_start = -1;
  630. double t_end=0, t_diff;
  631. double yy;
  632. int ix;
  633. int x, y;
  634. int xx;
  635. int nx=0;
  636. float *ax, *ay;
  637. memset(pitchenv.env,127,128);
  638. for(ix=0; ix<numframes; ix++)
  639. {
  640. if((f = frames[ix]->pitch) == 0) continue;
  641. nx++;
  642. t_end = frames[ix]->time;
  643. if(t_start < 0) t_start = t_end;
  644. if(f < min) min = f;
  645. if(f > max) max = f;
  646. }
  647. diff = max-min;
  648. t_diff = t_end - t_start;
  649. if(nx<2 || diff<=0 || t_diff<=0)
  650. {
  651. // no pitch info, use defaults
  652. pitchenv.pitch1=80;
  653. pitchenv.pitch2=120;
  654. return;
  655. }
  656. pitchenv.pitch1 = int(min);
  657. pitchenv.pitch2 = int(max);
  658. ax = new float [nx+1];
  659. ay = new float[nx+1];
  660. nx = 0;
  661. for(ix=0; ix<numframes; ix++)
  662. {
  663. if((f = frames[ix]->pitch) == 0) continue;
  664. ax[++nx] = (frames[ix]->time - t_start) * 128 / t_diff;
  665. ay[nx] = (frames[ix]->pitch - min) * 255 / diff;
  666. }
  667. pitchenv.env[0] = int(ay[1]);
  668. pitchenv.env[127] = int(ay[nx]);
  669. // create pitch envelope by interpolating the time/pitch
  670. // values from the spectrum sequence
  671. xx = 1;
  672. for(x=1; x<127; x++)
  673. {
  674. while((ax[xx] < x) && (xx < nx)) xx++;
  675. if(xx < 3)
  676. yy = polint(&ax[xx-1],&ay[xx-1],3,(float)x);
  677. else if(xx > nx-1)
  678. yy = polint(&ax[xx-2],&ay[xx-2],3,(float)x);
  679. else
  680. yy = polint(&ax[xx-2],&ay[xx-2],4,(float)x);
  681. y = int(yy);
  682. if(y < 0) y = 0;
  683. if(y > 255) y = 255;
  684. pitchenv.env[x] = y;
  685. }
  686. delete ax;
  687. delete ay;
  688. } // end of SpectSeq::MakePitchenv
  689. void SpectSeq::ApplyAmp_adjust(SpectFrame *sp, peak_t *peaks)
  690. {//=============================================================
  691. int ix;
  692. int y;
  693. memcpy(peaks,sp->peaks,sizeof(*peaks)*N_PEAKS);
  694. for(ix=0; ix<N_PEAKS; ix++)
  695. {
  696. y = peaks[ix].pkheight * sp->amp_adjust * amplitude;
  697. peaks[ix].pkheight = y / 10000;
  698. }
  699. } // end of ApplyAmp_adjust
  700. void PeaksToFrame(peak_t *pks, frame_t *fr)
  701. {//========================================
  702. int ix;
  703. int x;
  704. for(ix=0; ix<N_PEAKS; ix++)
  705. {
  706. fr->ffreq[ix] = pks[ix].pkfreq;
  707. fr->fheight[ix] = pks[ix].pkheight >> 6;
  708. if(ix < 6)
  709. {
  710. if((x = (pks[ix].pkwidth >> 2)) > 255)
  711. x = 255;
  712. fr->fwidth[ix] = x;
  713. if((x = (pks[ix].pkright >> 2)) > 255)
  714. x = 255;
  715. fr->fright[ix] = x;
  716. }
  717. }
  718. }
  719. static void SetSynth_mS(int length_mS, peak_t *sp1, peak_t *sp2)
  720. {//=============================================================
  721. static frame_t fr1, fr2;
  722. PeaksToFrame(sp1,&fr1);
  723. PeaksToFrame(sp2,&fr2);
  724. SetSynth((length_mS * samplerate) / 1000, 0, &fr1, &fr2); // convert mS to samples
  725. }
  726. void SpectSeq::MakeWave(int start, int end, PitchEnvelope &pitch)
  727. {//==============================================================
  728. int ix;
  729. int length;
  730. int len_samples;
  731. int total_length;
  732. float sum_length=0;
  733. float prev_length=0;
  734. int first;
  735. int pbase;
  736. char *fname_speech;
  737. SpectFrame *sp1 = NULL;
  738. SpectFrame *sp2;
  739. double lfactor;
  740. peak_t peaks0[N_PEAKS];
  741. peak_t peaks1[N_PEAKS];
  742. peak_t peaks2[N_PEAKS];
  743. SpeakNextClause(NULL,NULL,2); // stop speaking file
  744. if(numframes==0) return;
  745. SetFrameLengths();
  746. // find overall length of sequence
  747. for(ix=0; ix<numframes; ix++)
  748. {
  749. if(frames[ix]->keyframe)
  750. {
  751. sum_length += prev_length;
  752. prev_length = frames[ix]->length;
  753. sp2 = frames[ix];
  754. if(sp1 == NULL)
  755. sp1 = sp2;
  756. }
  757. }
  758. if(sp1 == NULL)
  759. {
  760. wxLogError(_T("(No frames have peaks set"));
  761. return;
  762. }
  763. total_length = int(sum_length);
  764. pbase = voice->pitch_base >> 12;
  765. if((start==end) || (total_length == 0))
  766. {
  767. sp1->MakeWave(0,voicedlg->pitchenv,amplitude,duration);
  768. return;
  769. }
  770. if((duration > 0) && (duration < 40000))
  771. lfactor = double(duration)/double(total_length);
  772. else
  773. {
  774. duration = total_length;
  775. lfactor = 1;
  776. }
  777. // if((start==end) || (total_length == 0))
  778. // {
  779. // sp1->MakeWave(1, pitch, amplitude, duration);
  780. // return;
  781. // }
  782. len_samples = int(((total_length * lfactor + 50) * samplerate) / 1000);
  783. SetPitch(len_samples,pitch.env,pitch.pitch1-pbase,pitch.pitch2-pbase);
  784. fname_speech = WavFileName();
  785. OpenWaveFile2(fname_speech);
  786. first=1;
  787. sp2 = NULL;
  788. for(ix=start; ix<=end; ix++)
  789. {
  790. if(frames[ix]->keyframe)
  791. {
  792. sp1 = sp2;
  793. sp2 = frames[ix];
  794. if(sp1 != NULL)
  795. {
  796. ApplyAmp_adjust(sp1,peaks1);
  797. ApplyAmp_adjust(sp2,peaks2);
  798. if(first)
  799. {
  800. PeaksZero(peaks1,peaks0); // fade in
  801. SetSynth_mS(20,peaks0,peaks1);
  802. MakeWaveFile();
  803. first=0;
  804. }
  805. length = int(sp1->length * lfactor);
  806. SetSynth_mS(length,peaks1,peaks2);
  807. MakeWaveFile();
  808. }
  809. }
  810. }
  811. PeaksZero(peaks2,peaks0); // fade out
  812. SetSynth_mS(30,peaks2,peaks0);
  813. MakeWaveFile();
  814. CloseWaveFile(samplerate);
  815. PlayWavFile(fname_speech);
  816. } // end of SpectSeq::MakeWave
  817. void SpectFrame::MakeHtab(int numh, int *htab, int pitch)
  818. {//======================================================
  819. // interpolate the spectrum to give a harmonic table for
  820. // the given pitch (Hz<<12)
  821. } // end of SpectFrame::MakeHtab
  822. void SpectFrame::MakeWave(int control, PitchEnvelope &pitche, int amplitude, int duration)
  823. {//======================================================================================
  824. // amplitude: percentage adjustment
  825. int ix;
  826. int length; // mS
  827. int len_samples;
  828. int y;
  829. peak_t peaks0[N_PEAKS];
  830. peak_t peaks1[N_PEAKS];
  831. int ipitch;
  832. int pbase;
  833. char *fname_speech;
  834. // USHORT htab0[600];
  835. SpeakNextClause(NULL,NULL,2); // stop speaking file
  836. length = duration;
  837. ipitch = int(pitch) << 16;
  838. if(length==0)
  839. length = 200; // default length, mS
  840. len_samples = (length * samplerate) / 1000;
  841. pbase = voice->pitch_base >> 12;
  842. SetPitch(len_samples + 50,pitche.env,pitche.pitch1-pbase,pitche.pitch2-pbase);
  843. fname_speech = WavFileName();
  844. if(OpenWaveFile2(fname_speech) != 0)
  845. return;
  846. if(control==0)
  847. {
  848. memcpy(peaks1,peaks,sizeof(peaks1));
  849. for(ix=0; ix<N_PEAKS; ix++)
  850. {
  851. y = peaks1[ix].pkheight * amp_adjust * amplitude;
  852. peaks1[ix].pkheight = y/10000;
  853. }
  854. PeaksZero(peaks1,peaks0);
  855. SetSynth_mS(20,peaks0,peaks1);
  856. MakeWaveFile();
  857. SetSynth_mS(length,peaks1,peaks1);
  858. MakeWaveFile();
  859. SetSynth_mS(30,peaks1,peaks0);
  860. MakeWaveFile();
  861. }
  862. else
  863. {
  864. #ifdef SPECT_EDITOR
  865. maxh = nx;
  866. if(maxh >= 600)
  867. maxh = 600-1;
  868. for(ix=0; ix<=maxh; ix++)
  869. htab0[ix] = 0;
  870. SetSynthHtab(20,htab0,maxh,dx,spect,maxh,dx);
  871. MakeWaveFile();
  872. SetSynthHtab(length,spect,maxh,dx,spect,maxh,dx);
  873. MakeWaveFile();
  874. SetSynthHtab(30,spect,maxh,dx,htab0,maxh,dx);
  875. MakeWaveFile();
  876. #endif
  877. }
  878. CloseWaveFile(samplerate);
  879. PlayWavFile(fname_speech);
  880. } // end of SpectFrame::MakeWaveFrame