xue@0: /* xue@0: Harmonic Visualiser xue@0: xue@0: An audio file viewer and editor. xue@0: Centre for Digital Music, Queen Mary, University of London. xue@0: This file copyright 2011 Wen Xue. xue@0: xue@0: This program is free software; you can redistribute it and/or xue@0: modify it under the terms of the GNU General Public License as xue@0: published by the Free Software Foundation; either version 2 of the xue@0: License, or (at your option) any later version. xue@0: */ xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: #include xue@0: #pragma hdrstop xue@0: xue@0: #include xue@0: #include xue@0: #include "VibratoDemoUnit.h" xue@0: #include "Matrix.h" xue@0: #include "Unit1.h" xue@0: #include "splines.h" xue@0: #include "hssf.h" xue@0: //--------------------------------------------------------------------------- xue@0: #pragma package(smart_init) xue@0: #pragma resource "*.dfm" xue@0: TVibratoDemoForm *VibratoDemoForm; xue@0: //--------------------------------------------------------------------------- xue@0: const double updb=10, downdb=-80, dbrange=updb-downdb; xue@0: const double log10e=Log10(exp(1)); xue@0: const Bdw=5, Bdwc=2; xue@0: xue@0: xue@0: __fastcall TVibratoDemoForm::TVibratoDemoForm(TComponent* Owner) xue@0: : TForm(Owner) xue@0: { xue@0: ForceUpdate=false; xue@0: xue@0: SUThread=0; xue@0: pThread=0; xue@0: memset(ThreadList, 0, sizeof(TSUThread*)*ThreadCaps); xue@0: xue@0: WaveAudio1=new TWaveAudio(NULL); xue@0: WaveAudio1->UseMemoryStream=true; xue@0: WaveAudio1->Channels=1; xue@0: WaveView1=new TWaveView(NULL); xue@0: WaveView1->Parent=Panel2; xue@0: WaveView1->Align=alClient; xue@0: WaveView1->WaveAudio=WaveAudio1; xue@0: WaveView1->OnGetOpMode=WaveView1OpMode; xue@0: WaveView1->CreatePanes(1, 1); xue@0: WaveView1->SetContent(0, 0, 0, 1); xue@0: WaveView1->ClickFocus=true; xue@0: WaveView1->DefaultPopupMenu=false; xue@0: WaveView1->CustomInfo=WaveView1CustomInfo; xue@0: WaveView1->InfoLeft=5; WaveView1->InfoTop=5; xue@0: xue@0: WaveAudio2=new TWaveAudio(NULL); xue@0: WaveAudio2->UseMemoryStream=true; xue@0: WaveAudio2->Channels=1; xue@0: WaveView2=new TWaveView(NULL); xue@0: WaveView2->Parent=Panel3; xue@0: WaveView2->Align=alClient; xue@0: WaveView2->WaveAudio=WaveAudio2; xue@0: WaveView2->CreatePanes(1, 1); xue@0: WaveView2->SetContent(0, 0, 0, 1); xue@0: WaveView2->ClickFocus=true; xue@0: WaveView2->DefaultPopupMenu=false; xue@0: WaveView2->CustomInfo=WaveView1CustomInfo; xue@0: WaveView2->InfoLeft=5; WaveView2->InfoTop=5; xue@0: xue@0: xue@0: HS=0; xue@0: CurrentModCycle=-1; xue@0: peaky=0; xue@0: cyclefrs=0; xue@0: cyclefs=0; xue@0: xue@0: datain=0; xue@0: } xue@0: xue@0: __fastcall TVibratoDemoForm::~TVibratoDemoForm() xue@0: { xue@0: delete WaveAudio1; xue@0: delete WaveAudio2; xue@0: delete WaveView1; xue@0: delete WaveView2; xue@0: delete HS; xue@0: delete[] peaky; xue@0: delete[] cyclefrs; xue@0: delete[] cyclefs; xue@0: for (int i=0; iM<=0 || HS->Fr<=0) return; xue@0: xue@0: if (ListBox1->ItemIndex<0) ListBox1->ItemIndex=0; xue@0: double Fs=WaveView1->SamplesPerSec; xue@0: int FSMode=ListBox1->ItemIndex; xue@0: double FSF=FEdit->Text.ToDouble(); xue@0: int FSFScale=FScaleCombo->ItemIndex; xue@0: if (FSFScale==0) FSF/=Fs; xue@0: else FSF/=Amel*log(1+Fs/700); xue@0: double FStheta=ThetaEdit->Text.ToDouble(); xue@0: xue@0: double sps=WaveView1->SamplesPerSec; xue@0: double h=WaveView1->SpecOffst; xue@0: AnalyzeV(*HS, V, peaky, cyclefrs, cyclefs, sps, h, &cyclefrcount, FSMode, FSF, FSFScale, FStheta); xue@0: SynthesizeV(HS, &V, WaveView1->SamplesPerSec); xue@0: SaveV(); xue@0: UpdateDisplay(); xue@0: } xue@0: xue@0: void TVibratoDemoForm::Copydata() xue@0: { xue@0: int dst, den; xue@0: double* xrec; xue@0: if (HS) xue@0: { xue@0: xrec=SynthesisHSp(HS, dst, den); xue@0: if (dst<0) dst=0; xue@0: xue@0: delete[] datain; xue@0: datain=new __int16[den-dst]; xue@0: xue@0: DoubleToInt(datain, sizeof(__int16), xrec, den-dst); xue@0: xue@0: free8(xrec); xue@0: } xue@0: } xue@0: xue@0: void TVibratoDemoForm::Synthesize() xue@0: { xue@0: int dst, den; xue@0: double* xrec; xue@0: if (HS) xue@0: { xue@0: double t=GetTickCount(); xue@0: xrec=SynthesisHS(HS, dst, den); xue@0: t=GetTickCount()-t; xue@0: Label13->Caption=t; xue@0: } xue@0: int bips=WaveAudio1->BitsPerSample; xue@0: double max=(1<<(bips-1)); for (int i=dst; imax) max=xrec[i]; else if (xrec[i]<-max) max=-xrec[i]; xue@0: if (max>(1<<(bips-1))) xue@0: { xue@0: max=(1<<(bips-1))/max; xue@0: for (int i=dst; iClear(NULL); xue@0: WaveAudio2->GetWaveProperties(WaveAudio1); xue@0: if (HS) xue@0: { xue@0: if (dst<0) dst=0; xue@0: void* data=new char[(den-dst)*bps]; xue@0: DoubleToInt(data, bps, xrec, den-dst); xue@0: xue@0: WaveAudio2->Clear(NULL); xue@0: WaveAudio2->WriteSamples(data, den-dst); xue@0: free8(xrec); xue@0: delete[] data; xue@0: } xue@0: } xue@0: xue@0: //for frequency modulator shape xue@0: void DrawBarMap(Graphics::TBitmap* Bitmap, TRect Rect, int Count, double* data, bool res, int* KX1=0, int* KX2=0) xue@0: { xue@0: TCanvas* Canvas=Bitmap->Canvas; xue@0: Bitmap->Width=Rect.Width(); xue@0: Bitmap->Height=Rect.Height(); xue@0: xue@0: TFont* F=Canvas->Font; F->Color=clWhite; F->Height=12; F->Name="Ariel"; xue@0: int fh=Canvas->TextHeight("0"); xue@0: int DrawCount=res?(Count+1):Count; xue@0: xue@0: double XX=Rect.right-Bdw*2, YY=Rect.bottom-Bdw-Bdwc-fh; xue@0: Canvas->Brush->Color=clBlack; Canvas->Brush->Style=bsSolid; Canvas->FillRect(Rect); xue@0: Canvas->Brush->Color=clAqua; Canvas->Pen->Color=clAqua; Canvas->Brush->Style=bsSolid; xue@0: int empspace=XX/(DrawCount+1)/4; xue@0: double r=0; for (int i=0; i1)?0:sqrt(1-r); xue@0: for (int i=0; i=1) xue@0: { xue@0: Canvas->Brush->Style=bsSolid; Canvas->Brush->Color=TColor(0xFFFF00); xue@0: Canvas->Rectangle(X-empspace, Y, X+empspace, Bdw+YY); xue@0: if (KX1) KX1[i]=X-empspace, KX2[i]=X+empspace-1; xue@0: } xue@0: else xue@0: { xue@0: Canvas->MoveTo(X, Y); Canvas->LineTo(X, Bdw+YY); xue@0: if (KX1) KX1[i]=X-1, KX2[i]=X+1; xue@0: } xue@0: AnsiString S=i; if (i>=Count) S="R"; int fw=Canvas->TextWidth(S); xue@0: Canvas->Brush->Style=bsClear; xue@0: Canvas->TextOut(X-fw/2, Bdw+YY, S); xue@0: S.sprintf("%.3g", 100*ldata*ldata); if (S[1]=='0') S=S.SubString(2, S.Length()-1); fw=Canvas->TextWidth(S); xue@0: if (Y-Bdw>fh) Canvas->TextOut(X-fw/2, Y-fh, S); xue@0: else Canvas->TextOut(X+empspace+1, Y, S); xue@0: } xue@0: Canvas->Brush->Color=clBlack; Canvas->Brush->Style=bsClear; Canvas->Pen->Color=clWhite; xue@0: Canvas->Rectangle(Bdw, Bdw, Bdw+XX, Bdw+YY); xue@0: } xue@0: xue@0: TColor RotateColors[10]={clWhite, clAqua, clLime, clYellow, clRed, clTeal, clGray, clGreen, clFuchsia, clBlue}; xue@0: //draw A-F distribution xue@0: void DrawAF(Graphics::TBitmap* Bitmap, TRect Rect, double xst, double xen, double dbst, double dben, int M, int Fr, atom** Partials, double* A0C, bool MA, bool bars, int FrStart=0, int TextHeight=12) xue@0: { xue@0: Bitmap->Width=Rect.Width(); xue@0: Bitmap->Height=Rect.Height(); xue@0: TCanvas* Canvas=Bitmap->Canvas; xue@0: double idbrange=1.0/(dbst-dben); xue@0: TFont* F=Canvas->Font; F->Color=clWhite; F->Height=TextHeight; F->Name="Ariel"; xue@0: int fh=Canvas->TextHeight("0"); xue@0: xue@0: double XX=Rect.right-Bdw*2, YY=Rect.bottom-Bdw-Bdwc-fh; xue@0: Canvas->Brush->Color=clBlack; Canvas->Brush->Style=bsSolid; Canvas->FillRect(Rect); xue@0: xue@0: Canvas->Pen->Color=clSilver; Canvas->MoveTo(Bdw, Bdw+YY*0.5); Canvas->LineTo(Bdw+XX, Bdw+YY*0.5); xue@0: xue@0: double *x=new double[(Fr-FrStart)*4], *y=&x[Fr-FrStart], *newa=&x[(Fr-FrStart)*2], *neww=&x[(Fr-FrStart)*3]; xue@0: xue@0: for (int m=0; mPen->Color=RotateColors[m%10]; Canvas->Brush->Color=RotateColors[m%10]; xue@0: xue@0: int Sc=0; xue@0: bool visible=false; xue@0: atom* Partialsm=Partials[m]; xue@0: for (int fr=FrStart; fr0 && Partialsm[fr].a>0) xue@0: { xue@0: x[Sc]=Partials[m][fr].f; xue@0: y[Sc]=20*Log10(Partialsm[fr].a/A0C[fr]); xue@0: if (x[Sc]x[c]*0.05) fw=x[c]*0.05; xue@0: xue@0: for (int c1=0; c1xen) continue; xue@0: double ldata=(y[c]-dben)*idbrange; xue@0: int X=floor(Bdw+XX*(x[c]-xst)/(xen-xst)+0.5); xue@0: int Y=floor(Bdw+YY*(1-ldata)+0.5); xue@0: if (bars) {Canvas->MoveTo(X, Y); Canvas->LineTo(X, Bdw+YY);} xue@0: else {Canvas->MoveTo(X-1, Y); Canvas->LineTo(X+2, Y); Canvas->MoveTo(X, Y-1); Canvas->LineTo(X, Y+2);} xue@0: } xue@0: } xue@0: xue@0: AnsiString S="0hz"; Canvas->Brush->Style=bsClear; Canvas->TextOut(Bdw, Bdw+YY, S); xue@0: S="5.5khz"; int fw=Canvas->TextWidth(S); Canvas->TextOut(Bdw+(XX-fw)/2, Bdw+YY, S); xue@0: S="11khz"; fw=Canvas->TextWidth(S); Canvas->TextOut(Bdw+XX-fw, Bdw+YY, S); xue@0: S.sprintf("%gdB", dbst); fw=Canvas->TextWidth(S); Canvas->TextOut(Bdw+XX-fw, Bdw, S); xue@0: S.sprintf("%gdB", (dbst+dben)/2); fw=Canvas->TextWidth(S); Canvas->TextOut(Bdw+XX-fw, Bdw+(YY-fh)/2, S); xue@0: S.sprintf("%gdB", dben); fw=Canvas->TextWidth(S); Canvas->TextOut(Bdw+XX-fw, Bdw+YY-fh, S); xue@0: xue@0: Canvas->Brush->Color=clBlack; Canvas->Brush->Style=bsClear; Canvas->Pen->Color=clWhite; xue@0: Canvas->Rectangle(Bdw, Bdw, Bdw+XX, Bdw+YY); xue@0: xue@0: delete[] x; xue@0: xue@0: } //*/ xue@0: //for source-filter results xue@0: void DrawSFr(Graphics::TBitmap* Bitmap, TRect Rect, double xst, double xen, double dbst, double dben, int M, int Fr, int afres, atom** Partials, double* LogAF, double* LogAS, int TextHeight=12) xue@0: { xue@0: Bitmap->Width=Rect.Width(); xue@0: Bitmap->Height=Rect.Height(); xue@0: TCanvas* Canvas=Bitmap->Canvas; xue@0: TFont* F=Canvas->Font; F->Color=clWhite; F->Height=TextHeight; F->Name="Ariel"; xue@0: int fh=Canvas->TextHeight("0"); xue@0: xue@0: double XX=Rect.right-Bdw*2, YY=Rect.bottom-Bdw-Bdwc-fh; xue@0: Canvas->Brush->Color=clBlack; Canvas->Brush->Style=bsSolid; Canvas->FillRect(Rect); xue@0: xue@0: Canvas->Pen->Color=clSilver; Canvas->MoveTo(Bdw, Bdw+YY*0.5); Canvas->LineTo(Bdw+XX, Bdw+YY*0.5); xue@0: xue@0: double xrange=xen-xst, XXixrange=XX/xrange, xstXXixrange=xst*XXixrange, xue@0: xrangeiXX=xrange/XX, xstafres=xst*afres, xrangeiXXafres=xrangeiXX*afres, xue@0: YYidbrange=YY/(dbst-dben); xue@0: xue@0: int *XRec=new int[XX]; xue@0: for (int m=0; mBrush->Color=RotateColors[m%10]; Canvas->Pen->Color=RotateColors[m%10]; xue@0: memset(XRec, 0, sizeof(int)*XX); xue@0: xue@0: for (int fr=0; fr0 && Partialsm[fr].a>0) xue@0: { xue@0: double xx=Partialsm[fr].f; xue@0: if (xxxen) continue; xue@0: int X=floor(XXixrange*xx-xstXXixrange+0.5); xue@0: if (X>=0 && XMoveTo(X-1, Y); Canvas->LineTo(X+2, Y); xue@0: Canvas->MoveTo(X, Y-1); Canvas->LineTo(X, Y+2); xue@0: } xue@0: } xue@0: } xue@0: if (!visible) break; xue@0: } xue@0: delete[] XRec; xue@0: xue@0: AnsiString S="0hz"; Canvas->Brush->Style=bsClear; Canvas->TextOut(Bdw, Bdw+YY, S); xue@0: S="5.5khz"; int fw=Canvas->TextWidth(S); Canvas->TextOut(Bdw+(XX-fw)/2, Bdw+YY, S); xue@0: S="11khz"; fw=Canvas->TextWidth(S); Canvas->TextOut(Bdw+XX-fw, Bdw+YY, S); xue@0: S.sprintf("%gdB", dbst); fw=Canvas->TextWidth(S); Canvas->TextOut(Bdw+XX-fw, Bdw, S); xue@0: S.sprintf("%gdB", (dbst+dben)/2); fw=Canvas->TextWidth(S); Canvas->TextOut(Bdw+XX-fw, Bdw+(YY-fh)/2, S); xue@0: S.sprintf("%gdB", dben); fw=Canvas->TextWidth(S); Canvas->TextOut(Bdw+XX-fw, Bdw+YY-fh, S); xue@0: xue@0: Canvas->Brush->Color=clBlack; Canvas->Brush->Style=bsClear; Canvas->Pen->Color=clWhite; xue@0: Canvas->Rectangle(Bdw, Bdw, Bdw+XX, Bdw+YY); xue@0: } xue@0: //*for source-filter model xue@0: int DrawSF(Graphics::TBitmap* Bitmap, TRect Rect, double xst, double xen, double dbst, double dben, double f0, int SCount, double* LogAS, double fc0, int FCount, double* LogAF, int* SX=0, TColor* Colors=0, int TextHeight=12) xue@0: { xue@0: Bitmap->Width=Rect.Width(); xue@0: Bitmap->Height=Rect.Height(); xue@0: TCanvas* Canvas=Bitmap->Canvas; xue@0: double *Sx=new double[SCount]; xue@0: for (int i=0; iFont; F->Color=clWhite; F->Height=TextHeight; F->Name="Ariel"; xue@0: int fh=Canvas->TextHeight("0"); xue@0: xue@0: double XX=Rect.right-Bdw*2, YY=Rect.bottom-Bdw-Bdwc-fh; xue@0: Canvas->Brush->Color=clBlack; Canvas->Brush->Style=bsSolid; Canvas->FillRect(Rect); xue@0: Canvas->Pen->Color=clSilver; Canvas->MoveTo(Bdw, Bdw+YY*0.5); Canvas->LineTo(Bdw+XX, Bdw+YY*0.5); xue@0: xue@0: double idbrange=1.0/(dbst-dben), xrange=xen-xst, XXixrange=XX/xrange, xstXXixrange=xst*XXixrange, xue@0: YY20log10eidbrange=YY*20*log10e*idbrange, BdwpYYpYYdbenidbrange=Bdw+YY+YY*dben*idbrange, xue@0: Bdw_xstXXixrange=Bdw-xstXXixrange, YYidbrange=YY*idbrange; xue@0: xue@0: double st=xst/fc0; int ist=ceil(st); if (ist<0) ist=0; xue@0: Canvas->Pen->Color=clWhite; xue@0: Canvas->MoveTo(Bdw+XX*(fc0*ist-xst)/xrange+0.5, BdwpYYpYYdbenidbrange-YY20log10eidbrange*LogAF[ist]+0.5); xue@0: //draw filter contour xue@0: int LineCount=xrange/fc0; xue@0: if (LineCountxen) break; xue@0: int X=floor(Bdw_xstXXixrange+xi*XXixrange+0.5); xue@0: int Y=floor(BdwpYYpYYdbenidbrange-YY20log10eidbrange*LogAF[i]+0.5); xue@0: Canvas->LineTo(X, Y); xue@0: } xue@0: } xue@0: else xue@0: { xue@0: double di=xrange/(XX*fc0); xue@0: for (int x=0; xLineTo(Bdw+x, Y); xue@0: } xue@0: } xue@0: //draw source lines xue@0: for (int i=0; ixen) continue; xue@0: int X=floor(Bdw_xstXXixrange+XXixrange*xi+0.5); xue@0: int Y=floor(BdwpYYpYYdbenidbrange-YYidbrange*Sx[i]+0.5); xue@0: if (Colors) Canvas->Pen->Color=Colors[i]; xue@0: else Canvas->Pen->Color=RotateColors[i%10]; xue@0: xue@0: Canvas->MoveTo(X, Y); Canvas->LineTo(X, Bdw+YY); xue@0: xue@0: if (SX) SX[i]=X, result++; xue@0: } xue@0: AnsiString S="0hz"; Canvas->Brush->Style=bsClear; Canvas->TextOut(Bdw, Bdw+YY, S); xue@0: S="5.5khz"; int fw=Canvas->TextWidth(S); Canvas->TextOut(Bdw+(XX-fw)/2, Bdw+YY, S); xue@0: S="11khz"; fw=Canvas->TextWidth(S); Canvas->TextOut(Bdw+XX-fw, Bdw+YY, S); xue@0: S.sprintf("%gdB", dbst); fw=Canvas->TextWidth(S); Canvas->TextOut(Bdw+XX-fw, Bdw, S); xue@0: S.sprintf("%gdB", (dbst+dben)/2); fw=Canvas->TextWidth(S); Canvas->TextOut(Bdw+XX-fw, Bdw+(YY-fh)/2, S); xue@0: S.sprintf("%gdB", dben); fw=Canvas->TextWidth(S); Canvas->TextOut(Bdw+XX-fw, Bdw+YY-fh, S); xue@0: xue@0: Canvas->Brush->Color=clBlack; Canvas->Brush->Style=bsClear; Canvas->Pen->Color=clWhite; xue@0: Canvas->Rectangle(Bdw, Bdw, Bdw+XX, Bdw+YY); xue@0: delete[] Sx; xue@0: return result; xue@0: } //*/ xue@0: xue@0: void DrawF0(Graphics::TBitmap* Bitmap, TCanvas* Canvas, TRect Rect, double* lp, int npfr, double* F0, double f_c, double f_ex, double sps, double F0Overall, int Fr, atom** Partials, double L, bool Captions=true, TColor F0Color=clLime, bool peakmark=false, TColor peakmarkcolor=clYellow, double* peaky=0, TColor peakycolor=clYellow, double* frs=0, double* fs=0) xue@0: { xue@0: Canvas->Brush->Color=cl3DDkShadow; Canvas->FillRect(Rect); xue@0: int Width=Rect.Width(), Height=Rect.Height(); xue@0: Bitmap->Width=Width; Bitmap->Height=Height; xue@0: TPen* P=Canvas->Pen; xue@0: TFont* F=Canvas->Font; xue@0: xue@0: int X, Y, Y1=0, Y2=Height, Y_; xue@0: AnsiString S, as; xue@0: xue@0: P->Color=clBlack; P->Style=psDot; F->Color=clBlack; F->Height=12; F->Name="Ariel"; xue@0: double f0max=-0.5, f0min=0.5; for (int fr=lp[0]; frF0[fr]) f0min=F0[fr];} xue@0: Y1=Height*(0.5-(f0max-f_c)/f_ex); Canvas->MoveTo(0, Y1); Canvas->LineTo(Width, Y1); xue@0: if (Captions){as=SemitoneToPitch(12*Log2(WV2_LOG_FREQ(f0max*sps)/C4)); S.sprintf("%.4ghz (%s)", f0max*sps, as.c_str()); Canvas->TextOut(1, Y1-Canvas->TextHeight(S)-1, S);} xue@0: Y2=Height*(0.5-(f0min-f_c)/f_ex); Canvas->MoveTo(0, Y2); Canvas->LineTo(Width, Y2); xue@0: if (Captions){as=SemitoneToPitch(12*Log2(WV2_LOG_FREQ(f0min*sps)/C4)); S.sprintf("%.4ghz (%s)", f0min*sps, as.c_str()); Canvas->TextOut(1, Y2+1, S);} xue@0: xue@0: if (peakmark) xue@0: { xue@0: int Y0=0.5*(Y1+Y2), Y0ex=0.5*(Y1-Y2); xue@0: if (peaky) {P->Color=peakmarkcolor; P->Style=psDot; Canvas->MoveTo(0, Y0); Canvas->LineTo(Width, Y0);} xue@0: xue@0: for (int pfr=0; pfrColor=peakmarkcolor; P->Style=psDot; Canvas->MoveTo(X, Y1); Canvas->LineTo(X, Y2); xue@0: if (peaky) xue@0: { xue@0: Y=Y0ex*peaky[pfr]; xue@0: P->Color=peakycolor; P->Style=psSolid; Canvas->MoveTo(X, Y0); Canvas->LineTo(X, Y0+Y); xue@0: } xue@0: } xue@0: } xue@0: xue@0: if (Captions) {Y_=Height*(0.5-(F0Overall-f_c)/f_ex); P->Color=clWhite; Canvas->MoveTo(0, Y_); Canvas->LineTo(Width, Y_);} xue@0: xue@0: P->Style=psSolid; P->Color=F0Color; xue@0: for (int fr=0; fr0) Canvas->MoveTo(X, Y); xue@0: X=Width*Partials[1][fr].t/L, Y=Height*(0.5-(F0[fr]-f_c)/f_ex); xue@0: if (fr>0) Canvas->LineTo(X, Y); xue@0: } xue@0: xue@0: if (frs) xue@0: { xue@0: P->Color=clRed; xue@0: for (int pfr=0; pfrMoveTo(X-4, Y); Canvas->LineTo(X+5, Y); xue@0: Canvas->MoveTo(X, Y-4); Canvas->LineTo(X, Y+5); xue@0: } xue@0: } xue@0: xue@0: if (Captions) xue@0: { xue@0: as=SemitoneToPitch(12*Log2(WV2_LOG_FREQ(F0Overall*sps)/C4)); S.sprintf("%.4ghz (%s)", F0Overall*sps, as.c_str()); xue@0: F->Color=clWhite; F->Style=F->Style<TextOut(Width-Canvas->TextWidth(S), Y_+1, S); F->Style=F->Style>>fsBold; xue@0: F->Color=clSilver; S="F0"; Canvas->TextOut(1, Height-Canvas->TextHeight(S), S); xue@0: double f=(f_c+f_ex/2)*sps; as=SemitoneToPitch(12*Log2(WV2_LOG_FREQ(f)/C4)); S.sprintf("%.4ghz (%s)", f, as.c_str()); Canvas->TextOut(Width-Canvas->TextWidth(S), 0, S); xue@0: f=(f_c-f_ex/2)*sps; as=SemitoneToPitch(12*Log2(WV2_LOG_FREQ(f)/C4)); S.sprintf("%.4ghz (%s)", f, as.c_str()); Canvas->TextOut(Width-Canvas->TextWidth(S), Height-Canvas->TextHeight(S), S); xue@0: } xue@0: } xue@0: xue@0: void DrawF0C(Graphics::TBitmap* Bitmap, TCanvas* Canvas, TRect Rect, double* F0C, double& F0Cmax, double& F0Cmin, double f_c, double f_ex, double sps, double F0Overall, int Fr, atom** Partials, double L, bool clearbackground=true, int frcount=0, double* frs=0, double* fs=0, int* CX1=0, int* CX2=0, int* CY1=0, int* CY2=0) xue@0: { xue@0: //Draw the F0 carrier xue@0: Canvas->Brush->Color=cl3DDkShadow; if (clearbackground) Canvas->FillRect(Rect); xue@0: int Width=Rect.Width(), Height=Rect.Height(); xue@0: Bitmap->Width=Width; Bitmap->Height=Height; xue@0: TPen* P=Canvas->Pen; xue@0: TFont* F=Canvas->Font; xue@0: xue@0: P->Color=clBlack; xue@0: F0Cmax=f_c-f_ex, F0Cmin=f_c+f_ex; xue@0: for (int fr=0; frF0C[fr]) F0Cmin=F0C[fr];} xue@0: P->Style=psDot; xue@0: int X, Y=Height*(0.5-(F0Cmax-f_c)/f_ex); xue@0: Canvas->MoveTo(0, Y); Canvas->LineTo(Width, Y); xue@0: AnsiString as=SemitoneToPitch(12*Log2(WV2_LOG_FREQ(F0Cmax*sps)/C4)); AnsiString S; S.sprintf("%.4ghz (%s)", F0Cmax*sps, as.c_str()); xue@0: F->Color=clBlack; F->Height=12; F->Name="Ariel"; Canvas->TextOut(1, Y-Canvas->TextHeight(S)-1, S); xue@0: Y=Height*(0.5-(F0Cmin-f_c)/f_ex); xue@0: Canvas->MoveTo(0, Y); Canvas->LineTo(Width, Y); xue@0: as=SemitoneToPitch(12*Log2(WV2_LOG_FREQ(F0Cmin*sps)/C4)); S.sprintf("%.4ghz (%s)", F0Cmin*sps, as.c_str()); xue@0: Canvas->TextOut(1, Y+1, S); xue@0: P->Color=clWhite; xue@0: as=SemitoneToPitch(12*Log2(WV2_LOG_FREQ(F0Overall*sps)/C4)); S.sprintf("%.4ghz (%s)", F0Overall*sps, as.c_str()); xue@0: int Y_=Height*(0.5-(F0Overall-f_c)/f_ex); xue@0: Canvas->MoveTo(0, Y_); Canvas->LineTo(Width, Y_); xue@0: F->Color=clWhite; F->Style=F->Style<TextHeight(S)TextOut(Width-Canvas->TextWidth(S), Y_+1, S); xue@0: else Canvas->TextOut(Width-Canvas->TextWidth(S), Y+1, S); xue@0: F->Style=F->Style>>fsBold; xue@0: xue@0: P->Style=psSolid; P->Color=clLime; xue@0: for (int fr=0; fr0) Canvas->MoveTo(X, Y); xue@0: X=Width*Partials[1][fr].t/L, Y=Height*(0.5-(F0C[fr]-f_c)/f_ex); xue@0: if (fr>0) Canvas->LineTo(X, Y); xue@0: } xue@0: xue@0: if (frcount) xue@0: { xue@0: P->Color=clRed; xue@0: for (int p=0; pMoveTo(X-4, Y); Canvas->LineTo(X+5, Y); xue@0: Canvas->MoveTo(X, Y-4); Canvas->LineTo(X, Y+5); xue@0: if (CX1) CX1[p]=X-4; xue@0: if (CX2) CX2[p]=X+4; xue@0: if (CY1) CY1[p]=Y-4; xue@0: if (CY2) CY2[p]=Y+4; xue@0: } xue@0: } xue@0: xue@0: double f=(f_c+f_ex/2)*sps; xue@0: F->Color=clSilver; xue@0: as=SemitoneToPitch(12*Log2(WV2_LOG_FREQ(f)/C4)); S.sprintf("%.4ghz (%s)", f, as.c_str()); xue@0: Canvas->TextOut(Width-Canvas->TextWidth(S), 0, S); xue@0: f=(f_c-f_ex/2)*sps; as=SemitoneToPitch(12*Log2(WV2_LOG_FREQ(f)/C4)); S.sprintf("%.4ghz (%s)", f, as.c_str()); xue@0: Canvas->TextOut(Width-Canvas->TextWidth(S), Height-Canvas->TextHeight(S), S); xue@0: F->Color=clSilver; S="F0 carrier"; xue@0: Canvas->TextOut(1, Height-Canvas->TextHeight(S), S); xue@0: } xue@0: xue@0: void DrawF0D(Graphics::TBitmap* Bitmap, TCanvas* Canvas, TRect Rect, double* lp, int npfr, double* F0D, double& F0Dmax, double& F0Dmin, double f_c, double f_ex, double sps, double F0Overall, int Fr, atom** Partials, double L) xue@0: { xue@0: int Width=Rect.Width(), Height=Rect.Height(); xue@0: Bitmap->Width=Width; Bitmap->Height=Height; xue@0: xue@0: Canvas->Brush->Style=bsSolid; Canvas->Brush->Color=cl3DDkShadow; Canvas->FillRect(Rect); xue@0: xue@0: //this part draws the modulator itself xue@0: F0Dmax=-f_ex, F0Dmin=f_ex; xue@0: for (int fr=lp[0]; frF0D[fr]) F0Dmin=F0D[fr];} xue@0: TPen* P=Canvas->Pen; P->Color=clBlack; P->Style=psDot; xue@0: int X, Y=Height*(0.5-F0Dmax/f_ex); Canvas->MoveTo(0, Y); Canvas->LineTo(Width, Y); xue@0: AnsiString S; S.sprintf("%.4ghz (%.3g%%)", F0Dmax*sps, F0Dmax/F0Overall*100); xue@0: TFont* F=Canvas->Font; F->Color=clBlack; F->Height=12; F->Name="Ariel"; xue@0: Canvas->TextOut(1, Y-Canvas->TextHeight(S)-1, S); xue@0: Y=Height*(0.5-F0Dmin/f_ex); xue@0: Canvas->MoveTo(0, Y); Canvas->LineTo(Width, Y); xue@0: S.sprintf("%.4ghz (%.3g%%)", F0Dmin*sps, F0Dmin/F0Overall*100); Canvas->TextOut(1, Y+1, S); xue@0: xue@0: P->Style=psSolid; P->Color=clSilver; Canvas->MoveTo(0, Height/2); Canvas->LineTo(Width, Height/2); xue@0: Canvas->Pen->Color=clLime; xue@0: for (int fr=0; fr0) Canvas->MoveTo(X, Y); xue@0: X=Width*Partials[1][fr].t/L, Y=Height*(0.5-F0D[fr]/f_ex); xue@0: if (fr>0) Canvas->LineTo(X, Y); xue@0: } xue@0: P->Color=clBlue; xue@0: for (int fr=0; frMoveTo(X-1, Y); Canvas->LineTo(X+2, Y); Canvas->MoveTo(X, Y-1); Canvas->LineTo(X, Y+2); xue@0: } xue@0: F->Color=clSilver; F->Height=12; F->Name="Ariel"; xue@0: S.sprintf("%.4ghz (%.3g%%)", f_ex*sps/2, f_ex/2/F0Overall*100); Canvas->TextOut(Width-Canvas->TextWidth(S), 0, S); xue@0: S.sprintf("%.4ghz (%.3g%%)", -f_ex*sps/2, -f_ex/2/F0Overall*100); Canvas->TextOut(Width-Canvas->TextWidth(S), Height-Canvas->TextHeight(S), S); xue@0: xue@0: F->Color=clSilver; S="F0 modulator"; Canvas->TextOut(1, Height-Canvas->TextHeight(S), S); xue@0: } xue@0: xue@0: //y=ax+b xue@0: void linefit(int n, double* x, double* y, double* indi, double& a, double& b) xue@0: { xue@0: double sx=0, sy=0, sxy=0, sxx=0, m=0; xue@0: for (int i=0; i0) sx+=x[i], sy+=y[i], sxx+=x[i]*x[i], sxy+=x[i]*y[i], m++; xue@0: if (m<=0) {a=-1; b=-1; return;} xue@0: double id=1.0/(m*sxx-sx*sx); xue@0: a=(m*sxy-sx*sy)*id; xue@0: b=(sxx*sy-sx*sxy)*id; xue@0: } xue@0: xue@0: void TVibratoDemoForm::UpdateDisplay(bool f0, bool f0c, bool f0d, bool sf) xue@0: { xue@0: int Fr=HS->Fr; xue@0: atom** Partials=HS->Partials; xue@0: //find the highest point of the 2nd partial xue@0: double f2min=1, f2max=0, fst=0, fen=0.25; xue@0: for (int fr=0; frPartials[1][fr].f) f2min=Partials[1][fr].f; xue@0: } xue@0: f_c=(f2min+f2max)/4; f_ex=f2max-f2min; xue@0: xue@0: if (f0) DrawF0(Image0->Picture->Bitmap, Image0->Canvas, Image0->ClientRect, V.lp, V.P, V.F0, f_c, f_ex, WaveView1->SamplesPerSec, V.F0Overall, Fr, Partials, WaveView2->Length, true, clLime, PeakMarksCheck->Checked, clYellow, 0, TColor(0), 0/*cyclefrs*/, cyclefs); xue@0: if (f0c) xue@0: { xue@0: memset(CX1, 0xFF, sizeof(int)*128); memset(CX2, 0xFF, sizeof(int)*128); memset(CY1, 0xFF, sizeof(int)*128); memset(CY1, 0xFF, sizeof(int)*128); xue@0: DrawF0C(Image1->Picture->Bitmap, Image1->Canvas, Image1->ClientRect, V.F0C, V.F0Cmax, V.F0Cmin, f_c, f_ex, WaveView1->SamplesPerSec, V.F0Overall, Fr, Partials, WaveView2->Length, true, PeakMarksCheck->Checked?cyclefrcount:0, cyclefrs, cyclefs, CX1, CX2, CY1, CY2); xue@0: } xue@0: if (f0d) xue@0: { xue@0: //Draw the F0 modulator xue@0: DrawModulator(); xue@0: // xue@0: double sps=WaveView1->SamplesPerSec; xue@0: DurationEdit->Text=AnsiString().sprintf("%.4gs", WaveView2->Length/sps); xue@0: RegEdit->Text=AnsiString().sprintf("%.4g", V.regularity); xue@0: RateEdit->Text=AnsiString().sprintf("%.4ghz", V.rate); xue@0: if (ResidueCheck->Checked) {FXX[0]=sqrt(1-V.FRes[0]); for (int i=1; iPicture->Bitmap, MImage1->ClientRect, V.K, FXX, ResidueCheck->Checked, KX1, KX2); xue@0: } xue@0: xue@0: if (sf) xue@0: { xue@0: if (SFCheck->Checked) xue@0: DrawSFr(AImage1->Picture->Bitmap, AImage1->ClientRect, fst, fen, updb, downdb, V.M, Fr, V.afres, Partials, V.LogAF, V.LogAS); xue@0: else xue@0: DrawAF(AImage1->Picture->Bitmap, AImage1->ClientRect, fst, fen, updb, downdb, V.M, Fr, Partials, V.A0C, MACheck->Checked, false); xue@0: SXc=DrawSF(AImage3->Picture->Bitmap, AImage3->ClientRect, fst, fen, updb, downdb, V.F0Overall, V.M, V.LogAS, 1.0/V.afres, V.afres/2, V.LogAF, SX); xue@0: } xue@0: xue@0: ForceUpdate=false; xue@0: } xue@0: xue@0: void __fastcall TVibratoDemoForm::WaveView1OpMode(TObject* Sender, TShiftState Shift, int& OpMode) xue@0: { xue@0: if (Shift.Contains(ssShift)) OpMode=0; //drag mode xue@0: else OpMode=1; //select mode xue@0: } xue@0: xue@0: int __fastcall TVibratoDemoForm::WaveView1CustomInfo(TObject* Sender) xue@0: { xue@0: TWaveView* WV=(TWaveView*)Sender; xue@0: TStringList* List=new TStringList; xue@0: double fs=WV->StartPos*1.0/WV->SamplesPerSec, fe=WV->EndPos*1.0/WV->SamplesPerSec; xue@0: List->Add(AnsiString().sprintf(" Time (%.4gs): from %.4gs to %.4gs. ", fe-fs, fs, fe)); xue@0: List->Add(AnsiString().sprintf(" Frequency: from %.1fhz to %.1fhz. ", WV->StartDigiFreq*WV->SamplesPerSec, WV->EndDigiFreq*WV->SamplesPerSec)); xue@0: return int(List); xue@0: } xue@0: xue@0: void __fastcall TVibratoDemoForm::Image1MouseMove(TObject *Sender, xue@0: TShiftState Shift, int X, int Y) xue@0: { xue@0: if (!HS) return; xue@0: TImage* Image=(TImage*)Sender; xue@0: Image->Parent->SetFocus(); xue@0: xue@0: double t, sps=WaveView1->SamplesPerSec, f; AnsiString S, as; TFont* F=Image->Canvas->Font; xue@0: xue@0: if (Sender==Image1) xue@0: { xue@0: if (Shift.Contains(ssLeft)) xue@0: { xue@0: if (CurrentC<0 || CurrentC>=cyclefrcount) return; xue@0: double df=-(Y-StartDrag)*f_ex/Image->Height; xue@0: cyclefs[CurrentC]+=df; xue@0: StartDrag=Y; xue@0: Smooth_Interpolate(V.F0C, V.L, cyclefrcount+1, cyclefs, cyclefrs); xue@0: SynthesizeV(HS, &V, WaveView1->SamplesPerSec); xue@0: UpdateDisplay(true, true, true, false); xue@0: xue@0: t=HS->Partials[0][0].t+V.h*cyclefrs[CurrentC]; xue@0: f=cyclefs[CurrentC]*sps; xue@0: as=SemitoneToPitch(12*Log2(WV2_LOG_FREQ(f)/C4)); xue@0: S.sprintf("%.3gs, %.4ghz (%s) ", t/sps, f, as.c_str()); xue@0: F->Color=clRed; xue@0: Image->Canvas->TextOut(1, Image->Canvas->TextHeight("0"), S); xue@0: xue@0: } xue@0: else xue@0: { xue@0: CurrentC=-1; xue@0: for (int i=0; i=CX1[i] && X<=CX2[i] && Y>=CY1[i] && Y<=CY2[i]) {CurrentC=i; break;} xue@0: } xue@0: if (CurrentC>=0 && CurrentCPartials[0][0].t+V.h*cyclefrs[CurrentC]; xue@0: f=cyclefs[CurrentC]*sps; xue@0: as=SemitoneToPitch(12*Log2(WV2_LOG_FREQ(f)/C4)); xue@0: S.sprintf("%.3gs, %.4ghz (%s) ", t/sps, f, as.c_str()); xue@0: F->Color=clRed; xue@0: Image->Canvas->TextOut(1, Image->Canvas->TextHeight("0"), S); xue@0: } xue@0: else xue@0: { xue@0: S.sprintf(" ", t/sps, f, as.c_str()); xue@0: Image->Canvas->TextOut(1, Image->Canvas->TextHeight("0"), S); xue@0: } xue@0: } xue@0: xue@0: t=WaveView2->Length*1.0*(X+0.5)/Image->Width; xue@0: f=(f_c-(Y-0.5*Image->Height)*f_ex/Image->Height)*sps; xue@0: as=SemitoneToPitch(12*Log2(WV2_LOG_FREQ(f)/C4)); xue@0: S.sprintf("%.3gs, %.4ghz (%s) ", t/sps, f, as.c_str()); xue@0: F->Color=clAqua; F->Height=12; F->Name="Ariel"; xue@0: Image->Canvas->TextOut(1, 0, S); xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: void __fastcall TVibratoDemoForm::Image2MouseMove(TObject *Sender, xue@0: TShiftState Shift, int X, int Y) xue@0: { xue@0: if (!HS) return; xue@0: if (Shift.Contains(ssLeft)) return; xue@0: atom** Partials=HS->Partials; xue@0: Image2->Parent->SetFocus(); xue@0: double t=WaveView2->Length*1.0*(X+0.5)/Image2->Width, sps=WaveView1->SamplesPerSec; xue@0: double f=-(Y-0.5*Image2->Height)*f_ex/Image2->Height; xue@0: xue@0: if (true || Shift.Contains(ssShift)) xue@0: { xue@0: int modcycle=0; xue@0: if (tPartials[0][0].t+V.lp[V.P-1]*V.h) modcycle=-1; xue@0: else while (t>Partials[0][0].t+V.lp[modcycle]*V.h) modcycle++; xue@0: if (CurrentModCycle!=modcycle) xue@0: { xue@0: CurrentModCycle=modcycle; xue@0: xue@0: if (CurrentModCycle==-1) xue@0: { xue@0: if (PageControl1->ActivePage==ModCycleSheet) xue@0: { xue@0: PageControl1->ActivePage=ModOverSheet; xue@0: ResidueCheck->Parent=ModOverSheet; xue@0: } xue@0: else if (PageControl1->ActivePage==AmpCycleSheet) xue@0: { xue@0: PageControl1->ActivePage=AmpOverSheet; xue@0: SFCheck->Parent=AmpOverSheet; xue@0: MACheck->Parent=AmpOverSheet; xue@0: } xue@0: } xue@0: else xue@0: { xue@0: if (PageControl1->ActivePage==ModOverSheet) xue@0: { xue@0: PageControl1->ActivePage=ModCycleSheet; xue@0: ResidueCheck->Parent=ModCycleSheet; xue@0: } xue@0: else if (PageControl1->ActivePage==AmpOverSheet) xue@0: { xue@0: PageControl1->ActivePage=AmpCycleSheet; xue@0: SFCheck->Parent=AmpCycleSheet; xue@0: MACheck->Parent=AmpCycleSheet; xue@0: } xue@0: ModCycleSheet->Caption="Modulator Cycle "+AnsiString(CurrentModCycle); xue@0: AmpCycleSheet->Caption="Amplitudes Cycle "+AnsiString(CurrentModCycle); xue@0: } xue@0: DrawModulator(); xue@0: } xue@0: } xue@0: xue@0: AnsiString S; xue@0: S.sprintf("%.3gs, %.4ghz (%.3g%%) ", t/sps, f*sps, f/V.F0Overall*100); xue@0: TFont* F=Image2->Canvas->Font; F->Color=clAqua; F->Height=12; F->Name="Ariel"; xue@0: Image2->Canvas->TextOut(1, 0, S); xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: void TVibratoDemoForm::DrawModulator() xue@0: { xue@0: double fst=0, fen=0.25; xue@0: xue@0: Image2->Picture->Bitmap->Width=Image2->Width; xue@0: Image2->Picture->Bitmap->Height=Image2->Height; xue@0: xue@0: int X, Y, L=WaveView2->Length, Fr=HS->Fr; xue@0: double sps=WaveView2->SamplesPerSec; xue@0: atom** Partials=HS->Partials; xue@0: TCanvas* I2Canvas=Image2->Canvas; I2Canvas->Brush->Style=bsSolid; I2Canvas->Brush->Color=cl3DDkShadow; I2Canvas->FillRect(Image2->ClientRect); xue@0: if (CurrentModCycle>=1 && CurrentModCycleSpecOffst; xue@0: CurrentModCycleEnd=Partials[0][0].t+V.lp[CurrentModCycle]*WaveView1->SpecOffst; xue@0: xue@0: int X1=Image2->Width*CurrentModCycleStart/L; xue@0: int X2=Image2->Width*CurrentModCycleEnd/L; xue@0: I2Canvas->Brush->Color=clDkGray; I2Canvas->FillRect(TRect(X1, 0, X2, Image2->Height)); xue@0: I2Canvas->Brush->Color=cl3DDkShadow; xue@0: xue@0: //this part update the tab sheet xue@0: int frst=V.peakfr[CurrentModCycle-1], fren=V.peakfr[CurrentModCycle]; xue@0: if (PageControl1->ActivePage==ModCycleSheet) xue@0: { xue@0: CycleDurationEdit->Text=AnsiString().sprintf("%.4gs (%.4gs~%.4gs)", (CurrentModCycleEnd-CurrentModCycleStart)/sps, CurrentModCycleStart/sps, CurrentModCycleEnd/sps); xue@0: CycleRateEdit->Text=AnsiString().sprintf("%.4ghz", sps/(CurrentModCycleEnd-CurrentModCycleStart)); xue@0: xue@0: double af0c=(V.F0C[frst]+V.F0C[fren])*0.5, f0dmax=V.F0D[frst], f0dmin=V.F0D[frst]; xue@0: double np=1, nn=0; xue@0: double pdp=(V.F0D[frst]*V.F0D[frst]+V.F0D[fren]*V.F0D[fren])*0.5, pdn=0; xue@0: for (int fr=frst+1; frf0dmax) f0dmax=V.F0D[fr]; xue@0: if (V.F0D[fr]0) pdp+=V.F0D[fr]*V.F0D[fr], np+=1; xue@0: else if (V.F0D[fr]<0) pdn+=V.F0D[fr]*V.F0D[fr], nn+=1; xue@0: } xue@0: af0c/=(fren-frst); xue@0: pdp=(np>0)?sqrt(pdp/np):0, pdn=(nn>0)?sqrt(pdn/nn):0; xue@0: AnsiString S=SemitoneToPitch(12*Log2(WV2_LOG_FREQ(af0c*sps)/C4)); xue@0: CyclePitchEdit->Text=AnsiString().sprintf("%.4ghz (%s)", af0c*sps, S.c_str()); xue@0: CycleExtentEdit->Text=AnsiString().sprintf("%.3g%%~%.3g%%", f0dmin/af0c*100, f0dmax/af0c*100); xue@0: CycleAvgPDEdit->Text=AnsiString().sprintf("-%.3g%%~%.3g%%", pdn/af0c*100, pdp/af0c*100); xue@0: xue@0: xue@0: if (ResidueCheck->Checked) {FXX[0]=sqrt(1-V.fres[CurrentModCycle][0]); for (int i=1; iPicture->Bitmap, MImage2->ClientRect, V.K, FXX, ResidueCheck->Checked, KX1, KX2); xue@0: } xue@0: else if (PageControl1->ActivePage==AmpCycleSheet) xue@0: { xue@0: if (SFCheck->Checked) xue@0: DrawSFr(AImage2->Picture->Bitmap, AImage2->ClientRect, fst, fen, updb, downdb, V.M, Fr, V.afres, Partials, V.LogAF, V.LogASp[CurrentModCycle]); xue@0: else xue@0: DrawAF(AImage2->Picture->Bitmap, AImage2->ClientRect, fst, fen, updb, downdb, V.M, V.peakfr[CurrentModCycle], Partials, V.A0C, MACheck->Checked, false, V.peakfr[CurrentModCycle-1]); xue@0: double cf0=0; for (int i=frst; iPicture->Bitmap, AImage4->ClientRect, 0, 0.25, updb, downdb, cf0, V.M, V.LogASp[CurrentModCycle], 1.0/V.afres, V.afres/2, V.LogAF, SXcycle); xue@0: } xue@0: } xue@0: else //CurrentCycle==-1 xue@0: { xue@0: } xue@0: xue@0: //this part draws the modulator itself xue@0: V.F0Dmax=-f_ex, V.F0Dmin=f_ex; xue@0: for (int fr=V.peakfr[0]; fr<=V.peakfr[V.P-1]; fr++){if (V.F0DmaxV.F0D[fr]) V.F0Dmin=V.F0D[fr];} xue@0: I2Canvas->Pen->Color=clBlack; I2Canvas->Pen->Style=psDot; xue@0: Y=Image2->Height*(0.5-V.F0Dmax/f_ex); xue@0: I2Canvas->MoveTo(0, Y); I2Canvas->LineTo(Image2->Width, Y); xue@0: AnsiString S; S.sprintf("%.4ghz (%.3g%%)", V.F0Dmax*sps, V.F0Dmax/V.F0Overall*100); xue@0: TFont* F=I2Canvas->Font; F->Color=clBlack; F->Height=12; F->Name="Ariel"; xue@0: I2Canvas->TextOut(1, Y-I2Canvas->TextHeight(S)-1, S); xue@0: Y=Image2->Height*(0.5-V.F0Dmin/f_ex); xue@0: I2Canvas->MoveTo(0, Y); I2Canvas->LineTo(Image2->Width, Y); xue@0: S.sprintf("%.4ghz (%.3g%%)", V.F0Dmin*sps, V.F0Dmin/V.F0Overall*100); xue@0: I2Canvas->TextOut(1, Y+1, S); xue@0: I2Canvas->Pen->Style=psSolid; xue@0: xue@0: I2Canvas->Pen->Color=clSilver; xue@0: I2Canvas->MoveTo(0, Image2->Height/2); I2Canvas->LineTo(Image2->Width, Image2->Height/2); xue@0: I2Canvas->Pen->Color=clBlue; xue@0: for (int fr=0; fr0) I2Canvas->MoveTo(X, Y); xue@0: X=Image2->Width*Partials[1][fr].t/L, Y=Image2->Height*(0.5-V.F0D[fr]/f_ex); xue@0: if (fr>0) I2Canvas->LineTo(X, Y); xue@0: } xue@0: I2Canvas->Pen->Color=clLime; xue@0: for (int fr=0; frWidth*Partials[1][fr].t/L, Y=Image2->Height*(0.5-V.F0D[fr]/f_ex); xue@0: I2Canvas->MoveTo(X-1, Y); I2Canvas->LineTo(X+2, Y); I2Canvas->MoveTo(X, Y-1); I2Canvas->LineTo(X, Y+2); xue@0: } xue@0: F->Color=clSilver; F->Height=12; F->Name="Ariel"; xue@0: S.sprintf("%.4ghz (%.3g%%)", f_ex*sps/2, f_ex/2/V.F0Overall*100); xue@0: I2Canvas->TextOut(Image2->Width-I2Canvas->TextWidth(S), 0, S); xue@0: S.sprintf("%.4ghz (%.3g%%)", -f_ex*sps/2, -f_ex/2/V.F0Overall*100); xue@0: I2Canvas->TextOut(Image2->Width-I2Canvas->TextWidth(S), Image2->Height-I2Canvas->TextHeight(S), S); xue@0: xue@0: F->Color=clSilver; S="F0 modulator"; xue@0: I2Canvas->TextOut(1, Image2->Height-I2Canvas->TextHeight(S), S); xue@0: xue@0: } xue@0: xue@0: xue@0: void __fastcall TVibratoDemoForm::SFCheckClick(TObject *Sender) xue@0: { xue@0: if (Sender==SFCheck) xue@0: { xue@0: MACheck->Visible=!SFCheck->Checked; xue@0: } xue@0: UpdateDisplay(); xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: xue@0: void __fastcall TVibratoDemoForm::RegButtonClick(TObject *Sender) xue@0: { xue@0: RegularizeV(*HS, V, WaveView1->SamplesPerSec, WaveView1->SpecOffst); xue@0: AnalyzeV(*HS, V, peaky, cyclefrs, cyclefs, WaveView1->SamplesPerSec, WaveView1->SpecOffst, &cyclefrcount); xue@0: SaveV(); xue@0: Synthesize(); xue@0: UpdateDisplay(); xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: xue@0: void __fastcall TVibratoDemoForm::ExternalInput() xue@0: { xue@0: AnsiString FileName=ExtractFilePath(Application->ExeName)+"tvoin"; xue@0: FILE* file; xue@0: if ((file=fopen(FileName.c_str(), "rb"))!=NULL) xue@0: { xue@0: V.LoadFromFileHandle(file); xue@0: fclose(file); xue@0: DeleteFile(FileName); xue@0: SynthesizeV(HS, &V, WaveView1->SamplesPerSec); xue@0: SaveV(); xue@0: Synthesize(); xue@0: UpdateDisplay(); xue@0: } xue@0: } xue@0: xue@0: //--------------------------------------------------------------------------- xue@0: void __fastcall TVibratoDemoForm::SaveV() xue@0: { xue@0: FILE* file; xue@0: if ((file=fopen((ExtractFilePath(Application->ExeName)+"tvoout").c_str(), "wb"))!=NULL) xue@0: { xue@0: V.SaveToFileHandle(file); xue@0: fclose(file); xue@0: } xue@0: } xue@0: xue@0: //--------------------------------------------------------------------------- xue@0: void __fastcall TVibratoDemoForm::MouseWheelHandler(TMessage& Msg) xue@0: { xue@0: TWMMouseWheel* WMsg=(TWMMouseWheel*)&Msg; xue@0: xue@0: bool Handled=false; xue@0: TMouseWheelEvent Event=NULL; xue@0: TControl* Sender; xue@0: TShiftState Shift; memcpy(&Shift, &WMsg->Keys, 1); xue@0: xue@0: if (ActiveControl==Image1->Parent) Event=Image1MouseWheel, Sender=Image1; xue@0: else if (ActiveControl==Image2->Parent) Event=Image2MouseWheel, Sender=Image2; xue@0: else if (ActiveControl==AImage3->Parent) Event=AImage3MouseWheel, Sender=AImage3; xue@0: else if (ActiveControl==AImage1->Parent) Event=AImage3MouseWheel, Sender=AImage1; xue@0: else if (ActiveControl==AImage4->Parent) Event=AImage4MouseWheel, Sender=AImage4; xue@0: else if (ActiveControl==AImage2->Parent) Event=AImage4MouseWheel, Sender=AImage2; xue@0: else if (ActiveControl==MImage1->Parent) Event=MImage1MouseWheel, Sender=MImage1; xue@0: else if (ActiveControl==MImage2->Parent) Event=MImage1MouseWheel, Sender=MImage2; xue@0: else if (ActiveControl==RateEdit || ActiveControl==CycleRateEdit) Event=RateEditMouseWheel, Sender=ActiveControl; xue@0: else if (ActiveControl==DurationEdit || ActiveControl==CycleDurationEdit) Event=DurationEditMouseWheel, Sender=ActiveControl; xue@0: else if (ActiveControl==CyclePitchEdit) Event=PitchEditMouseWheel, Sender=ActiveControl; xue@0: xue@0: if (Event) Event(Sender, Shift, WMsg->WheelDelta, Sender->ScreenToClient(TPoint(WMsg->Pos.x, WMsg->Pos.y)), Handled); xue@0: WMsg->Result=Handled; xue@0: xue@0: if (!Handled) TCustomForm::MouseWheelHandler(Msg); xue@0: } xue@0: xue@0: //--------------------------------------------------------------------------- xue@0: void __fastcall TVibratoDemoForm::Image1MouseWheel(TObject* Sender, TShiftState Shift, int WheelDelta, const TPoint &MousePos, bool &Handled) xue@0: { xue@0: double cent; xue@0: if (Shift.Contains(ssShift)) cent=1; xue@0: else if (Shift.Contains(ssCtrl)) cent=100; xue@0: else cent=10; xue@0: xue@0: if (WheelDelta<0) cent=-cent; xue@0: double rate=pow(2, cent/1200); xue@0: xue@0: for (int l=0; lSamplesPerSec); xue@0: SaveV(); xue@0: S_U(); xue@0: Handled=true; xue@0: } xue@0: xue@0: void __fastcall TVibratoDemoForm::Image2MouseWheel(TObject* Sender, TShiftState Shift, int WheelDelta, const TPoint &MousePos, bool &Handled) xue@0: { xue@0: double rate; xue@0: if (Shift.Contains(ssShift)) rate=1.01; xue@0: else if (Shift.Contains(ssCtrl)) rate=1.282432; xue@0: else rate=1.05101; xue@0: if (WheelDelta<0) rate=1.0/rate; xue@0: if (CurrentModCycle>0) V.Dp[CurrentModCycle]=V.Dp[CurrentModCycle]*rate; xue@0: else for (int p=1; pSamplesPerSec); xue@0: SaveV(); xue@0: S_U(); xue@0: Handled=true; xue@0: } xue@0: xue@0: void __fastcall TVibratoDemoForm::AImage3MouseWheel(TObject* Sender, TShiftState Shift, int WheelDelta, const TPoint &MousePos, bool &Handled) xue@0: { xue@0: double ddb; xue@0: if (Shift.Contains(ssShift)) ddb=0.2; xue@0: else if (Shift.Contains(ssCtrl)) ddb=5; xue@0: else ddb=1; xue@0: double db=20*log10e*V.LogAS[CurrentPartial]; xue@0: if (WheelDelta<0) ddb=-ddb; xue@0: xue@0: db+=ddb; xue@0: AnsiString S; S.sprintf("Partial %d: %.2fdB", CurrentPartial+1, db); xue@0: if (Sender==AImage3) Label7->Caption=S; xue@0: else Label8->Caption=S; xue@0: ddb=ddb/(20*log10e); xue@0: xue@0: for (int p=1; pSamplesPerSec); xue@0: SaveV(); xue@0: S_U(true); xue@0: Handled=true; xue@0: } xue@0: xue@0: void __fastcall TVibratoDemoForm::AImage4MouseWheel(TObject* Sender, TShiftState Shift, int WheelDelta, const TPoint &MousePos, bool &Handled) xue@0: { xue@0: double ddb; xue@0: if (Shift.Contains(ssShift)) ddb=0.2; xue@0: else if (Shift.Contains(ssCtrl)) ddb=5; xue@0: else ddb=1; xue@0: double db=20*log10e*V.LogASp[CurrentModCycle][CurrentPartial]; xue@0: if (WheelDelta<0) ddb=-ddb; xue@0: xue@0: db+=ddb; xue@0: AnsiString S; S.sprintf("Partial %d: %.2fdB", CurrentPartial+1, db); xue@0: if (Sender==AImage4) Label9->Caption=S; xue@0: else Label10->Caption=S; xue@0: ddb=ddb/(20*log10e); xue@0: xue@0: V.LogASp[CurrentModCycle][CurrentPartial]+=ddb; xue@0: xue@0: SynthesizeV(HS, &V, WaveView1->SamplesPerSec); xue@0: SaveV(); xue@0: S_U(true); xue@0: Handled=true; xue@0: } xue@0: xue@0: void __fastcall TVibratoDemoForm::MImage1MouseWheel(TObject* Sender, TShiftState Shift, int WheelDelta, const TPoint &MousePos, bool &Handled) xue@0: { xue@0: double rate; xue@0: if (Shift.Contains(ssShift)) rate=1.0192448764914566206520666016133; xue@0: else if (Shift.Contains(ssCtrl)) rate=1.61051; xue@0: else rate=1.1; xue@0: if (WheelDelta<0) rate=1.0/rate; xue@0: xue@0: double* FXR; xue@0: TLabel* Label; xue@0: if (Sender==MImage1) FXR=V.FXR, Label=Label11; xue@0: else if (ActiveControl==MImage2->Parent) FXR=V.fxr[CurrentModCycle], Label=Label12; xue@0: xue@0: if (CurrentK==0) xue@0: { xue@0: FXR[0]*=rate; xue@0: if (Sender==MImage1) for (int p=1; p0) S.sprintf("%d: %.3g", CurrentK, sqrt(FXR[CurrentK*2-1]*FXR[CurrentK*2-1]+FXR[CurrentK*2]*FXR[CurrentK*2])); xue@0: else if (CurrentK==0) S.sprintf("%d: %.3g", CurrentK, fabs(FXR[0])); xue@0: Label->Caption=S; xue@0: Label->Left=ActiveControl->Left+0.5*(KX1[CurrentK]+KX2[CurrentK]-Label->Width); xue@0: xue@0: SynthesizeV(HS, &V, WaveView1->SamplesPerSec); xue@0: SaveV(); xue@0: S_U(); xue@0: Handled=true; xue@0: } xue@0: xue@0: void __fastcall TVibratoDemoForm::RateEditMouseWheel(TObject* Sender, TShiftState Shift, int WheelDelta, const TPoint &MousePos, bool &Handled) xue@0: { xue@0: double rate, irate; xue@0: if (Shift.Contains(ssShift)) rate=1.01; xue@0: else if (Shift.Contains(ssCtrl)) rate=1.282432; xue@0: else rate=1.05101; xue@0: if (WheelDelta<0) {irate=rate; rate=1.0/rate;} xue@0: else irate=1.0/rate; xue@0: xue@0: if (Sender==CycleRateEdit) xue@0: { xue@0: if (CurrentModCycle>0) xue@0: { xue@0: double dlp=(V.lp[CurrentModCycle]-V.lp[CurrentModCycle-1])*(irate-1); xue@0: for (int p=CurrentModCycle; pV.L) {V.P=p; break;} xue@0: } xue@0: } xue@0: } xue@0: else if (Sender==RateEdit) xue@0: { xue@0: double newP=V.GetOldP()*rate; xue@0: if (newP>2.5) xue@0: { xue@0: TVo* newV=InterpolateV(newP, rate, V); xue@0: V.~TVo(); xue@0: memcpy(&V, newV, sizeof(TVo)); memset(newV, 0, sizeof(TVo)); xue@0: delete newV; xue@0: } xue@0: } xue@0: SynthesizeV(HS, &V, WaveView1->SamplesPerSec); xue@0: RateAndReg(V.rate, V.regularity, V.F0D, V.peakfr[0], V.peakfr[V.P-1], 8, WaveView1->SamplesPerSec, WaveView1->SpecOffst); xue@0: SaveV(); xue@0: S_U(); xue@0: Handled=true; xue@0: } xue@0: xue@0: void __fastcall TVibratoDemoForm::DurationEditMouseWheel(TObject* Sender, TShiftState Shift, int WheelDelta, const TPoint &MousePos, bool &Handled) xue@0: { xue@0: double rate; xue@0: if (Shift.Contains(ssShift)) rate=1.01; xue@0: else if (Shift.Contains(ssCtrl)) rate=1.282432; xue@0: else rate=1.05101; xue@0: if (WheelDelta<0) rate=1.0/rate; xue@0: xue@0: if (Sender==CycleDurationEdit) xue@0: { xue@0: if (CurrentModCycle>0) xue@0: { xue@0: double dlp=(V.lp[CurrentModCycle]-V.lp[CurrentModCycle-1])*(rate-1); xue@0: xue@0: for (int p=CurrentModCycle; p=oldL-1) xue@0: { xue@0: V.F0C[l]=F0C[oldL-1]; xue@0: V.A0C[l]=A0C[oldL-1]; xue@0: } xue@0: else xue@0: { xue@0: V.F0C[l]=F0C[il]*(1-rl)+F0C[il+1]*rl; xue@0: V.A0C[l]=A0C[il]*(1-rl)+A0C[il+1]*rl; xue@0: } xue@0: } xue@0: xue@0: for (int c=0; c2.5) xue@0: { xue@0: TVo* newV=InterpolateV(newP, 1, V); V.~TVo(); xue@0: memcpy(&V, newV, sizeof(TVo)); memset(newV, 0, sizeof(TVo)); xue@0: delete newV; xue@0: xue@0: for (int c=0; cSamplesPerSec); xue@0: RateAndReg(V.rate, V.regularity, V.F0D, V.peakfr[0], V.peakfr[V.P-1], 8, WaveView1->SamplesPerSec, WaveView1->SpecOffst); xue@0: SaveV(); xue@0: S_U(); xue@0: Handled=true; xue@0: } xue@0: xue@0: void __fastcall TVibratoDemoForm::PitchEditMouseWheel(TObject* Sender, TShiftState Shift, int WheelDelta, const TPoint &MousePos, bool &Handled) xue@0: { xue@0: if (CurrentModCycle<=0) return; xue@0: xue@0: double cent; xue@0: if (Shift.Contains(ssShift)) cent=1; xue@0: else if (Shift.Contains(ssCtrl)) cent=100; xue@0: else cent=10; xue@0: xue@0: if (WheelDelta<0) cent=-cent; xue@0: double rate_1=pow(2, cent/1200)-1; xue@0: xue@0: int frst=ceil(V.lp[CurrentModCycle-1]), freninc=floor(V.lp[CurrentModCycle]); xue@0: for (int fr=frst; fr<=freninc; fr++) V.F0C[fr]=V.F0C[fr]*(1+rate_1);//(1+rate_1*0.5*(1-cos(2*M_PI*(fr-V.lp[CurrentModCycle-1])/(V.lp[CurrentModCycle]-V.lp[CurrentModCycle-1])))); xue@0: xue@0: xue@0: SynthesizeV(HS, &V, WaveView1->SamplesPerSec); xue@0: SaveV(); xue@0: S_U(); xue@0: Handled=true; xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: xue@0: void __fastcall TVibratoDemoForm::AImage3MouseMove(TObject *Sender, xue@0: TShiftState Shift, int X, int Y) xue@0: { xue@0: if (!HS) return; xue@0: TImage* Image=(TImage*)Sender; xue@0: xue@0: if (Shift.Contains(ssLeft)) xue@0: { xue@0: if (CurrentPartial<0) return; xue@0: int fh=Image->Canvas->TextHeight("0"); xue@0: int YY=Image->Height-Bdw-Bdwc-fh; xue@0: double dbperpixel=dbrange/YY; xue@0: int dY=Y-StartDrag; xue@0: StartDrag=Y; xue@0: double ddb=-dY*dbperpixel; xue@0: xue@0: if (Sender==AImage1 || Sender==AImage3) xue@0: { xue@0: double db=20*log10e*V.LogAS[CurrentPartial]; xue@0: db+=ddb; xue@0: AnsiString S; S.sprintf("Partial %d: %.2fdB", CurrentPartial+1, db); xue@0: if (Sender==AImage3) Label7->Caption=S; xue@0: else Label8->Caption=S; xue@0: ddb=ddb/(20*log10e); xue@0: xue@0: for (int p=1; pCaption=S; xue@0: else Label10->Caption=S; xue@0: ddb=ddb/(20*log10e); xue@0: xue@0: V.LogASp[CurrentModCycle][CurrentPartial]+=ddb; xue@0: } xue@0: xue@0: SynthesizeV(HS, &V, WaveView1->SamplesPerSec); xue@0: UpdateDisplay(); xue@0: } xue@0: else xue@0: { xue@0: Image->Parent->SetFocus(); xue@0: xue@0: int lSXc, *lSX; xue@0: double* LogAS; xue@0: if (Sender==AImage1 || Sender==AImage3) lSXc=SXc, lSX=SX, LogAS=V.LogAS, X=Bdw+(X-Bdw)*AImage3->Width/((TImage*)Sender)->Width; xue@0: else if (Sender==AImage2 || Sender==AImage4) lSXc=SXcyclec, lSX=SXcycle, LogAS=V.LogASp[CurrentModCycle], X=Bdw+(X-Bdw)*AImage4->Width/((TImage*)Sender)->Width; xue@0: xue@0: if (lSXc<=0) return; xue@0: xue@0: xue@0: CurrentPartial=0; while (CurrentPartial=lSXc) CurrentPartial=lSXc-1; xue@0: if (CurrentPartial>=1 && X-lSX[CurrentPartial-1]Font->Color=RotateColors[CurrentPartial%10]; Label->Caption=S; xue@0: } xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: void __fastcall TVibratoDemoForm::MImage1MouseMove(TObject *Sender, xue@0: TShiftState Shift, int X, int Y) xue@0: { xue@0: if (!HS) return; xue@0: if (Shift.Contains(ssLeft)) xue@0: { xue@0: if (CurrentK<0) return; xue@0: xue@0: } xue@0: else xue@0: { xue@0: TImage* Image=(TImage*)Sender; xue@0: Image->Parent->SetFocus(); xue@0: CurrentK=-1; for (int i=0; i=KX1[i] && X<=KX2[i]) {CurrentK=i; break;} xue@0: if (CurrentK<0) return; xue@0: xue@0: double* FXR; xue@0: TLabel* Label; xue@0: if (Sender==MImage1) FXR=V.FXR, Label=Label11; xue@0: else if (Sender==MImage2) xue@0: { xue@0: if (CurrentModCycle<0) return; xue@0: FXR=V.fxr[CurrentModCycle], Label=Label12; xue@0: } xue@0: xue@0: AnsiString S; xue@0: if (CurrentK>0) S.sprintf("%d: %.3g", CurrentK, sqrt(FXR[CurrentK*2-1]*FXR[CurrentK*2-1]+FXR[CurrentK*2]*FXR[CurrentK*2])); xue@0: else if (CurrentK==0) S.sprintf("%d: %.3g", CurrentK, fabs(FXR[0])); xue@0: Label->Caption=S; Label->Left=Image->Parent->Left+0.5*(KX1[CurrentK]+KX2[CurrentK]-Label->Width); xue@0: } xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: xue@0: void __fastcall TVibratoDemoForm::Image2DblClick(TObject *Sender) xue@0: { xue@0: TPoint P1; GetCursorPos(&P1); xue@0: TPoint P2=MImage1->ClientToScreen(TPoint(0, MImage1->Height*0.3819)); xue@0: SetCursorPos(P1.x, P2.y); xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: xue@0: xue@0: void __fastcall TVibratoDemoForm::AImage1MouseDown(TObject *Sender, xue@0: TMouseButton Button, TShiftState Shift, int X, int Y) xue@0: { xue@0: FirstStartDrag=StartDrag=Y; xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: void __fastcall TVibratoDemoForm::AImage1MouseUp(TObject *Sender, xue@0: TMouseButton Button, TShiftState Shift, int X, int Y) xue@0: { xue@0: if (Y!=FirstStartDrag) xue@0: { xue@0: SaveV(); xue@0: Synthesize(); xue@0: UpdateDisplay(); xue@0: } xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: void __fastcall TVibratoDemoForm::CycleRateEditMouseMove(TObject *Sender, xue@0: TShiftState Shift, int X, int Y) xue@0: { xue@0: TEdit* Edit=(TEdit*)Sender; xue@0: Edit->SetFocus(); xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: void __fastcall TVibratoDemoForm::PageControl1Change(TObject *Sender) xue@0: { xue@0: if (PageControl1->ActivePage==ModOverSheet || PageControl1->ActivePage==ModCycleSheet) xue@0: ResidueCheck->Parent=PageControl1->ActivePage; xue@0: else if (PageControl1->ActivePage==AmpOverSheet || PageControl1->ActivePage==AmpCycleSheet) xue@0: {SFCheck->Parent=PageControl1->ActivePage; MACheck->Parent=PageControl1->ActivePage;} xue@0: UpdateDisplay(); xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: xue@0: void SourceResponse(double* SV, TVo* V) xue@0: { xue@0: int N=V->afres/2; xue@0: memset(SV, 0, sizeof(double)*N); xue@0: for (int p=1; pP; p++) xue@0: { xue@0: double F0p=0; xue@0: int frst=V->lp[p-1], fren=V->lp[p]; xue@0: for (int fr=frst; frF0C[fr]; xue@0: F0p/=(fren-frst); xue@0: F0p*=V->afres; xue@0: int lastfp; xue@0: double lastsv; xue@0: for (int m=0; mM; m++) xue@0: { xue@0: int fp=F0p*(m+1); xue@0: double sv=V->LogASp[p][m]; xue@0: if (m==0) for (int n=0; nP-1); xue@0: } xue@0: xue@0: //S_U implements delayed updating of lengthy synthesizing to speed up operation xue@0: // in case the HS is updated frequently, s.a. during mouse wheeling. xue@0: //This allows a later synthesis to start before an earlier synthesis finishes, xue@0: // at which the latter is terminated and its incomplete result is discarded. xue@0: void __fastcall TVibratoDemoForm::S_U(bool sf) xue@0: { xue@0: if (SUThread) xue@0: { xue@0: SUThread->Terminate(); xue@0: } xue@0: SUThread=new TSUThread(true); xue@0: SUThread->sf=sf; xue@0: SUThread->OnTerminate=SUTerminate; xue@0: SUThread->HS=new THS(HS); xue@0: ThreadList[pThread++]=SUThread; xue@0: if (pThread==ThreadCaps/2 && ThreadList[pThread]) xue@0: for (int i=pThread; iResume(); xue@0: } xue@0: xue@0: void __fastcall TVibratoDemoForm::SUTerminate(TObject* Sender) xue@0: { xue@0: TSUThread* CurrentThread=(TSUThread*)Sender; xue@0: if (CurrentThread==SUThread) xue@0: { xue@0: double* xrec=CurrentThread->xrec; xue@0: if (xrec) xue@0: { xue@0: int dst=CurrentThread->dst, den=CurrentThread->den; xue@0: if (dst<0) dst=0; xue@0: __int16* data=new __int16[den]; xue@0: memset(data, 0, sizeof(__int16)*dst); xue@0: DoubleToInt(&data[dst], sizeof(__int16), xrec, den-dst); xue@0: WaveAudio2->Clear(NULL); xue@0: WaveAudio2->WriteSamples(data, den-dst); xue@0: delete[] data; xue@0: UpdateDisplay(); xue@0: } xue@0: SUThread=0; xue@0: } xue@0: else xue@0: { xue@0: UpdateDisplay(true, true, true, CurrentThread->sf); xue@0: } xue@0: free8(CurrentThread->xrec); CurrentThread->xrec=0; xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: void __fastcall TVibratoDemoForm::Panel4Resize(TObject *Sender) xue@0: { xue@0: Panel10->Height=Panel4->Height/3; xue@0: ForceUpdate=true; xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: void __fastcall TVibratoDemoForm::Panel8Resize(TObject *Sender) xue@0: { xue@0: int H=(Panel8->Height-Splitter4->Height-Splitter5->Height)/3; xue@0: Panel9->Height=H; Panel7->Height=H; xue@0: ForceUpdate=true; xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: void __fastcall TVibratoDemoForm::Panel1Resize(TObject *Sender) xue@0: { xue@0: Panel2->Height=(Panel1->Height-Splitter1->Height)/2; xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: xue@0: void __fastcall TVibratoDemoForm::AmpOverSheetResize(TObject *Sender) xue@0: { xue@0: double W=(AmpOverSheet->Width-24)/20.0; xue@0: AImage3->Parent->Width=W*9; xue@0: Label7->Width=AImage3->Parent->Width; xue@0: AImage1->Parent->Left=AImage3->Parent->Left+AImage3->Parent->Width+8; xue@0: AImage1->Parent->Width=W*11; xue@0: Label8->Left=AImage1->Parent->Left; xue@0: Label8->Width=AImage1->Parent->Width; xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: void __fastcall TVibratoDemoForm::AmpCycleSheetResize(TObject *Sender) xue@0: { xue@0: double W=(AmpCycleSheet->Width-24)/20.0; xue@0: AImage4->Parent->Width=W*9; xue@0: Label9->Width=AImage4->Parent->Width; xue@0: AImage2->Parent->Left=AImage4->Parent->Left+AImage4->Parent->Width+8; xue@0: AImage2->Parent->Width=W*11; xue@0: Label10->Left=AImage2->Parent->Left; xue@0: Label10->Width=AImage2->Parent->Width; xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: xue@0: void __fastcall TVibratoDemoForm::ListBox1Click(TObject *Sender) xue@0: { xue@0: if (ListBox1->ItemIndex==1) ThetaEdit->Enabled=true; xue@0: else ThetaEdit->Enabled=false; xue@0: Reset(); xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: void __fastcall TVibratoDemoForm::Button1Click(TObject *Sender) xue@0: { xue@0: int N=WaveView1->Length, Channel=Form1->HS->Channel; xue@0: xue@0: if (GetKeyState(VK_SHIFT)<0) xue@0: { xue@0: __int16* d2=WaveView2->Data16[0]; xue@0: Form1->PostWaveViewData(d2, Channel, StartPos, StartPos+N, Form1->FadeInCheck->Checked, Form1->FadeInCombo->Text.ToInt()); xue@0: } xue@0: else xue@0: { xue@0: __int16 *data=new __int16[N], *data1=WaveView1->Data16[0], *data2=WaveView2->Data16[0]; xue@0: int NN=N; xue@0: if (NN>WaveView2->Length) NN=WaveView2->Length; xue@0: for (int n=0; nPostWaveViewData(data, Channel, StartPos, StartPos+NN, Form1->FadeInCheck->Checked, Form1->FadeInCombo->Text.ToInt()); xue@0: if (NN!=N) Form1->PostWaveViewData(&data[NN], Channel, StartPos+NN, StartPos+N, Form1->FadeInCheck->Checked, Form1->FadeInCombo->Text.ToInt()); xue@0: delete[] data; xue@0: } xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: xue@0: xue@0: void __fastcall TVibratoDemoForm::Panel9Resize(TObject *Sender) xue@0: { xue@0: ForceUpdate=true; xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: void __fastcall TVibratoDemoForm::Panel7Resize(TObject *Sender) xue@0: { xue@0: ForceUpdate=true; xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: