Mercurial > hg > hv
view Unit1.cpp @ 0:a6a46af64546
first upload
author | wenx <xue.wen@eecs.qmul.ac.uk> |
---|---|
date | Wed, 10 Aug 2011 14:55:38 +0100 |
parents | |
children |
line wrap: on
line source
/* Harmonic Visualiser An audio file viewer and editor. Centre for Digital Music, Queen Mary, University of London. This file copyright 2011 Wen Xue. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. */ //--------------------------------------------------------------------------- #pragma hdrstop #include <vcl.h> #include <inifiles.hpp> #include "Unit1.h" #include "BackUpTool.h" #include <math.h> #include <Math.hpp> #include "UnitRangeEdit.h" #include "EditorPanelUnit.h" #include "VibratoDemoUnit.h" #include "RecordingUnit.h" #include "opt.h" #include "Matrix.h" #include "SFDemoUnit.h" #include "SinEst.h" #include "splines.h" #include "SinSyn.h" #include "hsedit.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; extern timestamp1; //--------------------------------------------------------------------------- char ReturnKey=VK_RETURN; int BAR=2; #define ASMALLNEGATIVEVALUE -1.1e-24 __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { Application->HintPause=0.1; WaveAudio1=new TWaveAudio(NULL); WaveAudio1->AutoUseMemoryStream=true; WaveAudio1->OnLoad=WaveAudio1Load; WaveView1=new TWaveView(NULL, true, false); WaveView1->Parent=PanelWaveView; WaveView1->Align=alClient; WaveView1->ScrollBar=ScrollBar1; WaveView1->WaveAudio=WaveAudio1; WaveView1->ClickFocus=true; WaveView1->WaveBackColor=clWhite; WaveView1->WaveColor=clBlack; WaveView1->AxisColor=clGray; WaveView1->CustomInfo=WaveView1CustomInfo; WaveView1->CustomPaneInfo=WaveView1CustomPaneInfo; WaveView1->OnGetOpMode=WaveView1OpMode; WaveView1->OnGetPlaybackStartAndEndPos=WaveView1PlaybackStartAndEndPos; WaveView1->OnInfoDblClick=WaveView1InfoDblClick; WaveView1->OnPaint=WaveView1AfterPaint; WaveView1->OnPlaybackStart=WaveView1PlaybackStart; WaveView1->OnPlaybackDone=WaveView1PlaybackDone; WaveView1->OnKeyPress=WaveView1KeyPress; WaveView1->OnMouseDown=WaveView1MouseDown; WaveView1->OnMouseMove=WaveView1MouseMove; WaveView1->OnMousePointer=WaveView1MousePointer; WaveView1->OnMouseUp=WaveView1MouseUp; WaveView1->OnMouseWheel=WaveView1MouseWheel; WaveView1->SelectedFrameColorX=clGreen; WaveView1->SelectedAreaColorX=clGreen; WaveView1->BeforePlayback=WaveView1BeforePlayback; WaveView1->Hint=""; WaveView1->ShowHint=true; WaveView1->DefaultPopupMenu=false; WaveView1->PopupMenu=WaveView1PopupMenu; WaveView1->Tools<<wvtPlayNote; WaveView1->PlayNoteInSemitone=true; WaveAudio2=0; TWaveViewObject Obj; memset(&Obj, 0, sizeof(TWaveViewObject)); Obj.DrawObject=WaveView1DrawObject; Obj.OnClick=WaveView1ObjectClick; for (int i=0; i<6; i++){Obj.Id=i; WaveView1->FObjects.Add(Obj);} WaveView1->FObjects.Items[5].OnClick=0; WaveView1->FObjects.Items[5].OnDblClick=WaveView1ObjectDblClick; WaveView1->FObjects.Items[5].OnMouseWheel=WaveView1ObjectMouseWheel; Navigator1=new TNavigator(NULL); Navigator1->Parent=PanelNavigator; Navigator1->Align=alClient; Navigator1->AreaColorX=clYellow; Navigator1->OnAreaChange=Navigator1AreaChange; Navigator1->OnBackground=Navigator1Background; NavButton=new TSpeedButton(this); NavButton->Parent=Navigator1; NavButton->Left=0; NavButton->Top=0; NavButton->Width=24; NavButton->Height=16; NavButton->Transparent=true; NavButton->Font->Name="Ariel"; NavButton->Font->Height=12; NavButton->Font->Color=clBlack; NavButton->Caption="W/S"; NavButton->Flat=true; NavButton->OnClick=NavButtonClick; Initialize(); SetWaveViewContents(); BitmapPlay=new Graphics::TBitmap; BitmapPlay->LoadFromResourceID((int)HInstance, 100); BitmapStop=new Graphics::TBitmap; BitmapStop->LoadFromResourceID((int)HInstance, 101); SpeedButtonPlay->Glyph=BitmapPlay; BitmapSpectrogram=new Graphics::TBitmap; BitmapSpectrogram->LoadFromResourceID((int)HInstance, 102); BitmapWaveform=new Graphics::TBitmap; BitmapWaveform->LoadFromResourceID((int)HInstance, 103); SpeedButtonS->Glyph=BitmapSpectrogram; BitmapRecord=new Graphics::TBitmap; BitmapRecord->LoadFromResourceID((int)HInstance, 104); BitmapRecording=new Graphics::TBitmap; BitmapRecording->LoadFromResourceID((int)HInstance, 105); SpeedButtonRecord->Glyph=BitmapRecord; BitmapTimeSelect=new Graphics::TBitmap; BitmapTimeSelect->LoadFromResourceID((int)HInstance, 106); SpeedButtonT->Glyph=BitmapTimeSelect; BitmapFreqSelect=new Graphics::TBitmap; BitmapFreqSelect->LoadFromResourceID((int)HInstance, 107); SpeedButtonF->Glyph=BitmapFreqSelect; BitmapMultiSelect=new Graphics::TBitmap; BitmapMultiSelect->LoadFromResourceID((int)HInstance, 108); SpeedButtonM->Glyph=BitmapMultiSelect; BitmapHSSelect=new Graphics::TBitmap; BitmapHSSelect->LoadFromResourceID((int)HInstance, 109); SpeedButtonSelect->Glyph=BitmapHSSelect; BitmapCursorText=new Graphics::TBitmap; BitmapCursorText->LoadFromResourceID((int)HInstance, 110); SpeedButtonCursorText->Glyph=BitmapCursorText; BitmapPaneInfo=new Graphics::TBitmap; BitmapPaneInfo->LoadFromResourceID((int)HInstance, 111); SpeedButtonPaneInfo->Glyph=BitmapPaneInfo; SpectrogramView=false; HS=0; PartialSelectCombo->ItemIndex=0; ancps=0; ancfrs=0; ancfs=0; ancts=0; onset.f0s=0; onset.pitches=0; onset.xfr=0; Application->OnIdle=ApplicationIdle; for (int i=0; i<MaxRecents; i++) { int ind=File1->IndexOf(Recent00); TMenuItem* Item=new TMenuItem(this); Item->Tag=i; Item->Caption=i+1; Item->OnClick=Recent11Click; File1->Insert(ind, Item); Recents[i]=Item; } ExePath=ExtractFilePath(Application->ExeName); TmpInFileName=ExePath+"tvoin"; TmpOutFileName=ExePath+"tvoout"; IniFileName=ChangeFileExt(Application->ExeName, ".ini"); RecentFile(""); } __fastcall TForm1::~TForm1() { TIniFile* Ini=0; try{ Ini=new TIniFile(ChangeFileExt(Application->ExeName, ".ini")); Ini->WriteString("CurrentFile", "FileName", WaveAudio1->FileName); Ini->WriteInteger("CurrentView", "Start", WaveView1->StartPos); Ini->WriteInteger("CurrentView", "End", WaveView1->EndPos); Ini->WriteFloat("CurrentView", "StartF", WaveView1->StartDigiFreq); Ini->WriteFloat("CurrentView", "EndF", WaveView1->EndDigiFreq); Ini->WriteInteger("CurrentView", "SpecRes", WindowSizeCombo->ItemIndex); Ini->WriteInteger("CurrentView", "WindowType", WindowTypeCombo->ItemIndex); Ini->WriteString("HS", "delp", HSDelpEdit1->Text); Ini->WriteString("HS", "delm", HSDelmEdit1->Text); Ini->WriteInteger("Settings", "MouseWheelZoom", MouseWheelZoom->Checked); Ini->WriteInteger("Settings", "Mixer", false); } catch(...) {} delete Ini; delete WaveAudio1; delete WaveView1; delete Navigator1; delete BitmapPlay; delete BitmapStop; delete BitmapSpectrogram; delete BitmapWaveform; delete BitmapRecord; delete BitmapRecording; delete BitmapTimeSelect; delete BitmapFreqSelect; delete BitmapMultiSelect; delete BitmapHSSelect; delete BitmapCursorText; delete BitmapPaneInfo; free(ancps); free(ancfrs); free(ancfs); free(ancts); DeAlloc2(onset.f0s); DeAlloc2(onset.pitches); delete[] onset.xfr; } //--------------------------------------------------------------------------- void __fastcall TForm1::ApplicationIdle(TObject* Sender, bool& Done) { if (FileExists(TmpInFileName)) VibratoDemoForm->ExternalInput(); if (VibratoDemoForm->ForceUpdate) VibratoDemoForm->UpdateDisplay(); Done=true; } //--------------------------------------------------------------------------- void __fastcall TForm1::Backup1Click(TObject *Sender) { BackupForm1->ShowModal(); } //--------------------------------------------------------------------------- void __fastcall TForm1::Exit1Click(TObject *Sender) { Close(); } //--------------------------------------------------------------------------- void __fastcall TForm1::ZoomToSelection1Click(TObject *Sender) { WaveView1->DoExtract(Sender); if (GetKeyState(VK_SHIFT)>=0) WaveView1->RemoveSelection(-1); } //--------------------------------------------------------------------------- void TForm1::Initialize() { TIniFile* Ini=new TIniFile(ChangeFileExt(Application->ExeName, ".ini")); AnsiString FileName=Ini->ReadString("CurrentFile", "FileName", ""); if (FileExists(FileName)) { WaveAudio1->LoadFromFile(FileName); int Start=Ini->ReadInteger("CurrentView", "Start", 0); int End=Ini->ReadInteger("CurrentView", "End", WaveAudio1->Length); double StartDF=Ini->ReadFloat("CurrentView", "StartF", 0); double EndDF=Ini->ReadFloat("CurrentView", "EndF", 0.5); WaveView1->SetArea(Start, End, StartDF, EndDF); WindowTypeCombo->ItemIndex=Ini->ReadInteger("CurrentView", "WindowType", 2); WindowTypeComboChange(NULL); WindowSizeCombo->ItemIndex=Ini->ReadInteger("CurrentView", "SpecRes", 5); WindowSizeComboChange(NULL); HSDelpEdit1->Text=Ini->ReadString("HS", "delp", "1.0"); HSDelmEdit1->Text=Ini->ReadString("HS", "delm", "1.0"); MouseWheelZoom->Checked=Ini->ReadInteger("Settings", "MouseWheelZoom", true); WaveView1->DisableMouseWheelZoom=!MouseWheelZoom->Checked; } delete Ini; } //--------------------------------------------------------------------------- void __fastcall TForm1::LogFreqCheckClick(TObject *Sender) { SetWaveViewContents(); } //--------------------------------------------------------------------------- void __fastcall TForm1::NavButtonClick(TObject*) { NavButton->Font->Color=(NavButton->Font->Color==clBlack)?clYellow:clBlack; Navigator1->Resize(); } //--------------------------------------------------------------------------- void __fastcall TForm1::Navigator1AreaChange(TObject*) { WaveView1->SetArea(WaveView1->Length*Navigator1->x1, WaveView1->Length*Navigator1->x2, (1-Navigator1->y2)*0.5, (1-Navigator1->y1)*0.5); } //--------------------------------------------------------------------------- void __fastcall TForm1::Navigator1Background(TObject*) { if (WaveAudio1->Length<=0) Navigator1->BkgBmp->Canvas->FillRect(Navigator1->ClientRect); else if (NavButton->Font->Color==clYellow) { TWaveViewSelection Sel={0, WaveView1->Length, 0, 0.5}; WaveView1->DrawSpectrogramX(0, Sel, 0, Navigator1->BkgBmp->Canvas, Navigator1->ClientRect, 10, false, false, 1); } else WaveView1->DrawWaveForm(0, Navigator1->BkgBmp->Canvas, Navigator1->ClientRect, 0, WaveView1->Length); } //--------------------------------------------------------------------------- void __fastcall TForm1::Open1Click(TObject *Sender) { OpenDialog1->FilterIndex=1; if (OpenDialog1->Execute()) { if (WaveAudio1->FileName!=OpenDialog1->FileName) RecentFile(WaveAudio1->FileName); WaveAudio1->LoadFromFile(OpenDialog1->FileName); } } //--------------------------------------------------------------------------- void __fastcall TForm1::PanelRightButtonMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { TShape* Shape=(TShape*)Sender; if (Button==mbLeft && X>=0 && Y>=0 && X<Shape->Width && Y<Shape->Height) { TPanel* APanel; TSplitter* ASplitter; if (Shape==PanelRightButton) APanel=PanelRight, ASplitter=Splitter1; else if (Shape==PanelRightButton2) APanel=PanelGrid, ASplitter=Splitter3; ShowPanel(APanel, APanel->Visible); ASplitter->Visible=!ASplitter->Visible; } } //--------------------------------------------------------------------------- void __fastcall TForm1::Play1Click(TObject *Sender) { WaveView1->StartPlayback(Sender); } //--------------------------------------------------------------------------- void TForm1::PrepareNMSettings(NMSettings* settings) { memset(settings, 0, sizeof(NMSettings)); int wid=WaveView1->SpecRes, sps=WaveView1->SamplesPerSec; windowspec(WaveView1->SpecWindowType, wid, &settings->M, settings->c, &settings->iH2); settings->hB=3; settings->maxp=HSMaxpEdit1->Text.ToInt(); settings->maxB=HSMaxBEdit1->Text.ToDouble(); settings->epf=2.0e-4; settings->epf0=2; settings->delm=HSDelmEdit1->Text.ToDouble(); settings->delp=HSDelpEdit1->Text.ToDouble(); settings->minf0=HSMinF0Edit1->Text.ToDouble()/sps*wid; settings->maxf0=HSMaxF0Edit1->Text.ToDouble()/sps*wid; settings->pin0=PartialSelectCombo->ItemIndex+1; settings->pcount=0; } //--------------------------------------------------------------------------- void TForm1::RecentFile(AnsiString FileName) { TIniFile* Ini=0; try{ Ini=new TIniFile(IniFileName); int newi=0, start[MaxRecents+1], end[MaxRecents+1]; double fstart[MaxRecents+1], fend[MaxRecents+1]; AnsiString Names[MaxRecents+1]; if (FileExists(FileName)) { Names[0]=FileName; start[0]=WaveView1->StartPos, end[0]=WaveView1->EndPos; fstart[0]=WaveView1->StartDigiFreq, fend[0]=WaveView1->EndDigiFreq; newi=1; } AnsiString S0="RecentFile"; for (int i=1; i<=MaxRecents; i++) { AnsiString S=S0+i; if (!Ini->SectionExists(S)) continue; AnsiString LName=Ini->ReadString(S, "FileName", ""); if (FileExists(LName) && LName!=FileName) { Names[newi]=LName; start[newi]=Ini->ReadInteger(S, "Start", 0); end[newi]=Ini->ReadInteger(S, "End", -1); fstart[newi]=Ini->ReadFloat(S, "StartF", 0); fend[newi]=Ini->ReadFloat(S, "EndF", 0.5); newi++; } Ini->EraseSection(S); } if (newi>MaxRecents) newi=MaxRecents; for (int i=0; i<newi; i++) { AnsiString S="RecentFile"; S=S+(i+1); Ini->WriteString(S, "FileName", Names[i]); Ini->WriteInteger(S, "Start", start[i]); Ini->WriteInteger(S, "End", end[i]); Ini->WriteFloat(S, "StartF", fstart[i]); Ini->WriteFloat(S, "EndF", fend[i]); } for (int i=0; i<newi; i++) { Recents[i]->Caption=AnsiString(i+1)+". "+Names[i]; Recents[i]->Visible=true; } for (int i=newi; i<MaxRecents; i++) Recents[i]->Visible=false; Recent00->Visible=(newi>0); }catch(...){} delete Ini; } //--------------------------------------------------------------------------- void TForm1::SetGridContents() { if (!PanelGrid->Visible) return; if (WaveView1->CurrentPane<0) return; GridSourcePane=WaveView1->CurrentPane; int Wid=WaveView1->SpecRes, hWid=Wid/2, Offst=WaveView1->SpecOffst; double t=WaveView1->CurrentTime, f=WaveView1->CurrentDigiFreq, amp=sqrt(1.0/Wid), prange=100, i2pi=0.5*prange/M_PI; int Channel=WaveView1->FPanes.Channel[GridSourcePane]; if (WaveView1->FPanes.HasFreqAxis[GridSourcePane] && (AmpTab->Visible || ArcTab->Visible)) { TStringGrid* Grid; if (AmpTab->Visible) Grid=AmpGrid; else if (ArcTab->Visible) Grid=PhaseGrid; Grid->RowCount=Grid->Height/(Grid->DefaultRowHeight+1); Grid->ColCount=Grid->Width/(Grid->DefaultColWidth+1); int maxfr=(WaveView1->Length-Wid)/Offst+1; if (Grid->ColCount>maxfr+1) Grid->ColCount=maxfr+1; if (Grid->RowCount>hWid+1) Grid->ColCount=hWid+1; int CurrentBin=floor(f*Wid+0.5), CurrentFr=floor((t-hWid)*1.0/Offst+0.5); if (CurrentFr<0) CurrentFr=0; else if (CurrentFr>maxfr-1) CurrentFr=maxfr-1; if (CurrentBin<0) CurrentBin=0; if (CurrentBin>hWid-1) CurrentBin=hWid-1; int frst=CurrentFr-Grid->ColCount/2; if (frst<0) frst=0; int fren=frst+Grid->ColCount-1; if (fren>maxfr) fren=maxfr, frst=maxfr-Grid->ColCount+1; int binst=CurrentBin-Grid->RowCount/2; if (binst<0) binst=0; int binen=binst+Grid->RowCount-1; if (binen>hWid) binen=hWid, binst=hWid-Grid->RowCount+1; char format[128]; memcpy(format, FormatEdit->Text.c_str(), FormatEdit->Text.Length()+1); double *dw=0, *tw=0; cdouble *W, *X=0; for (int fr=frst; fr<fren; fr++) { if (AmpTab->Visible) { QSPEC_FORMAT* data=WaveView1->A[Channel][fr]; for (int bin=binst; bin<binen; bin++) Grid->Cells[fr-frst+1][binen-bin]=AnsiString().sprintf(format, data[bin]*amp); } else if (ArcTab->Visible) { cmplx<QSPEC_FORMAT>* data=WaveView1->Spec[Channel][fr]; for (int bin=binst; bin<binen; bin++) { double pvalue=arg(data[bin])*i2pi; if (bin%2) pvalue+=prange/2; if (pvalue>prange/2) pvalue-=prange; Grid->Cells[fr-frst+1][binen-bin]=AnsiString().sprintf(format, pvalue); } } Grid->Cells[fr-frst+1][0]=fr; for (int bin=binst; bin<binen; bin++) Grid->Cells[0][binen-bin]=bin; } Grid->Row=binen-CurrentBin; Grid->Col=CurrentFr-frst+1; delete[] dw; delete[] tw; delete[] X; } else if (WaveView1->FPanes.HasFreqAxis[GridSourcePane] && QPkTab->Visible) { TStringGrid* Grid=QPkGrid; Grid->RowCount=Grid->Height/(Grid->DefaultRowHeight+1); int maxfr=(WaveView1->Length-Wid)/Offst+1; if (Grid->RowCount>hWid+1) Grid->ColCount=hWid+1; TStringList* List=new TStringList; for (int c=0; c<Grid->ColCount; c++) for (int r=0; r<Grid->RowCount; r++) Grid->Cells[c][r]=""; delete List; int CurrentBin=floor(f*Wid+0.5), CurrentFr=floor((t-hWid)*1.0/Offst+0.5); if (CurrentFr<0) CurrentFr=0; else if (CurrentFr>maxfr-1) CurrentFr=maxfr-1; if (CurrentBin<0) CurrentBin=0; if (CurrentBin>hWid-1) CurrentBin=hWid-1; int binst=CurrentBin-Grid->RowCount/2; if (binst<0) binst=0; int binen=binst+Grid->RowCount-1; if (binen>hWid) binen=hWid, binst=hWid-Grid->RowCount+1; int frst=CurrentFr-Grid->ColCount/2; if (frst<0) frst=0; int fren=frst+Grid->ColCount-1; if (fren>maxfr) fren=maxfr, frst=maxfr-Grid->ColCount+1; char format[128]; memcpy(format, FormatEdit->Text.c_str(), FormatEdit->Text.Length()+1); Grid->Cells[0][0]=AnsiString().sprintf("fr.%d", CurrentFr); for (int bin=binst; bin<binen; bin++) Grid->Cells[0][binen-bin]=bin; Grid->Cells[1][0]="f"; Grid->Cells[2][0]="a"; double *f=new double[(binen-binst)*3], *a=&f[binen-binst]; cmplx<QSPEC_FORMAT>* spec=WaveView1->Spec[Channel][CurrentFr]; cdouble *x=new cdouble[Wid/2+1]; memset(x, 0, sizeof(cdouble)*(Wid/2+1)); int bnst=binst-2, bnen=binen+2; if (bnst<0) bnst=0; if (bnen>Wid/2) bnen=Wid/2; for (int i=bnst; i<bnen; i++) x[i]=spec[i]; int M; double c[6], iH2; windowspec(WaveView1->SpecWindowType, Wid, &M, c, &iH2); int p=QuickPeaks(f, a, Wid, x, M, c, iH2, 0.0005, binst, binen); MList* mlist=0; int M_, I, p0, q0, *p0s; double **h, *s; cdouble **u, **du; if (p>0) { mlist=new MList; s=new double[Wid]; mlist->Add(s, 1); __int16* data=&WaveView1->Data16[Channel][Offst*CurrentFr]; for (int n=0; n<Wid; n++) s[n]=data[n]; } for (int ip=0; ip<p; ip++) { int bin=floor(f[ip]+0.5); Grid->Cells[1][binen-bin]=AnsiString().sprintf(format, f[ip]); Grid->Cells[2][binen-bin]=AnsiString().sprintf(format, a[ip]); } delete mlist; delete[] x; delete[] f; Grid->Row=binen-CurrentBin; } } //--------------------------------------------------------------------------- void TForm1::SetWaveViewContents() { int rulers=(WaveView1->FPanes.Count>0)?WaveView1->FPanes.Rulers[0]:7; if (WaveView1->ShowInfo) WaveView1->FPanes.MarginOut=TRect(5, WaveView1->DefaultInfoFont->Height, 5, WaveView1->DefaultInfoFont->Height); else WaveView1->FPanes.MarginOut=TRect(5, 5, 5, WaveView1->DefaultInfoFont->Height); if (WaveView1->Channels>=2 && DisplayChannelRadio->ItemIndex==0) { int Columns=PanesRadio->ItemIndex+1; WaveView1->CreatePanes(Columns, 2); int type=SpectrogramView?(FreqLineCheck->Checked?2:1):0; WaveView1->SetContent(0, 0, 0, type); WaveView1->SetContent(0, 1, 1, type); if (Columns>1) { type=SpectrogramView?0:(FreqLineCheck->Checked?2:1); WaveView1->SetContent(1, 0, 0, type); WaveView1->SetContent(1, 1, 1, type); } } else { int Rows=PanesRadio->ItemIndex+1; WaveView1->CreatePanes(1, Rows); int type=SpectrogramView?(FreqLineCheck->Checked?2:1):0; int channel=(WaveView1->Channels>=2 && DisplayChannelRadio->ItemIndex==2)?1:0; WaveView1->SetContent(0, 0, channel, type); if (Rows>1) { type=SpectrogramView?0:(FreqLineCheck->Checked?2:1); WaveView1->SetContent(0, 1, channel, type); } } int yscale=LogFreqCheck->Checked?1:0; for (int i=0; i<4; i++) WaveView1->SetYScale(i, yscale), WaveView1->SetRulers(i, rulers); WaveView1->ShowCursorText=SpeedButtonCursorText->Down; WaveView1->ShowPaneInfo=SpeedButtonPaneInfo->Down; } //--------------------------------------------------------------------------- void TForm1::ShowPanel(TPanel* APanel, bool Hide) { APanel->Visible=!Hide; if (APanel==PanelRight) PanelRightButton->Brush->Color=Hide?clTeal:clSilver; else if (APanel==PanelGrid) PanelRightButton2->Brush->Color=Hide?clTeal:clSilver; } //--------------------------------------------------------------------------- void __fastcall TForm1::SpectrogramBrightness1Click(TObject *Sender) { WaveView1->SpecAmp=1; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- void __fastcall TForm1::SpeedButtonFClick(TObject *Sender) { if (SpeedButtonF->Down) { WaveView1->SelectMode=WaveView1->SelectMode|WV2_VSELECT; if (GetKeyState(VK_SHIFT)>=0 && SpeedButtonT->Down) { SpeedButtonT->Down=false; WaveView1->SelectMode=WaveView1->SelectMode&(~WV2_HSELECT); } } else WaveView1->SelectMode=WaveView1->SelectMode&(~WV2_VSELECT); } //--------------------------------------------------------------------------- void __fastcall TForm1::SpeedButtonMClick(TObject *Sender) { WaveView1->MultiSelect=(SpeedButtonM->Down); } //--------------------------------------------------------------------------- void __fastcall TForm1::SpeedButtonTClick(TObject *Sender) { if (SpeedButtonT->Down) { WaveView1->SelectMode=WaveView1->SelectMode|WV2_HSELECT; if (GetKeyState(VK_SHIFT)>=0 && SpeedButtonF->Down) { SpeedButtonF->Down=false; WaveView1->SelectMode=WaveView1->SelectMode&(~WV2_VSELECT); } } else WaveView1->SelectMode=WaveView1->SelectMode&(~WV2_HSELECT); } //--------------------------------------------------------------------------- void __fastcall TForm1::UndoZoom1Click(TObject *Sender) { WaveView1->UndoExtract(Sender); } //--------------------------------------------------------------------------- void ClearObjectByShortTag0(TWaveView* WV, int tag0) { if (WV->ObjectAtPointer && WV->ObjectAtPointer->ShortTag[0]==tag0) WV->ObjectAtPointer=0; int ind=0; for (int i=0; i<WV->FObjects.Count; i++) if (WV->FObjects.Items[i].ShortTag[0]!=tag0) WV->FObjects.Items[ind++]=WV->FObjects.Items[i]; WV->FObjects.Count=ind; } void __fastcall TForm1::WaveAudio1Load(TObject*) { DisplayChannelRadio->Enabled=(WaveAudio1->Channels>1); PlayChannelRadio->Enabled=(WaveAudio1->Channels>1); ClearObjectByShortTag0(WaveView1, stAtom); ClearObjectByShortTag0(WaveView1, stOnset); SetWaveViewContents(); Caption="hv - "+WaveAudio1->FileName; if (EventBox) {EventBox->Load(NULL);} Navigator1->SetArea(0, 1, 1-WaveView1->EndDigiFreq*2, 1-WaveView1->StartDigiFreq*2); Navigator1->Resize(); } //--------------------------------------------------------------------------- void __fastcall TForm1::WaveView1AfterPaint(TObject*) { Navigator1->SetArea(WaveView1->StartPos*1.0/WaveView1->Length, WaveView1->EndPos*1.0/WaveView1->Length, 1-WaveView1->EndDigiFreq*2, 1-WaveView1->StartDigiFreq*2); fcalculatespcount=WaveView1->TimeStamp1; } //--------------------------------------------------------------------------- void __fastcall TForm1::WaveView1BeforePlayback(TObject*) { if (WaveView1->Selections->Count) WaveView1->PlaybackFilter=(TWaveViewPlaybackFilter)PlayFilterCombo->ItemIndex; else WaveView1->PlaybackFilter=wvfNone; WaveView1->StereoMode=(TWaveViewStereoMode)PlayChannelRadio->ItemIndex; } //--------------------------------------------------------------------------- int __fastcall TForm1::WaveView1CustomInfo(TObject* Sender) { TStringList* List=new TStringList; List->Add(AnsiString().sprintf(" %d-channel, %dhz, %dbit. ", WaveView1->Channels, WaveView1->SamplesPerSec, WaveView1->BytesPerSample*8)); if (WaveView1->RulerUnitTime==0) List->Add(AnsiString().sprintf(" Time(%d): from %d to %d. ", WaveView1->EndPos-WaveView1->StartPos, WaveView1->StartPos, WaveView1->EndPos)); else { double fs=WaveView1->StartPos*1.0/WaveView1->SamplesPerSec, fe=WaveView1->EndPos*1.0/WaveView1->SamplesPerSec; List->Add(AnsiString().sprintf(" Time(%.4gs): from %.4gs to %.4gs. ", fe-fs, fs, fe)); } if (WaveView1->RulerUnitFreq==0) { double fs=WaveView1->StartDigiFreq*WaveView1->SamplesPerSec, fe=WaveView1->EndDigiFreq*WaveView1->SamplesPerSec; AnsiString as=SemitoneToPitch(12*Log2(WV2_LOG_FREQ(fs)/C4)), ae=SemitoneToPitch(12*Log2(WV2_LOG_FREQ(fe)/C4)); List->Add(AnsiString().sprintf(" Frequency: from %.1fhz(%s) to %.1fhz(%s). ", fs, as.c_str(), fe, ae.c_str())); } else List->Add(AnsiString().sprintf(" Frequency: from %.4gbin to %.4gbin. ", WaveView1->StartDigiFreq*WaveView1->SpecRes, WaveView1->EndDigiFreq*WaveView1->SpecRes)); return (int)List; } int __fastcall TForm1::WaveView1CustomPaneInfo(TObject* Sender) { TStringList* List=new TStringList; if (WaveView1->Channels>1) List->Add(WaveView1->FPanes.Channel[WaveView1->CurrentPane]==0?"Channel: left":"Channel: right"); if (WaveView1->Selections->Count>0 && WaveView1->Selections->Focus>=0) { List->Add("Current Selection"); int st=WaveView1->Selections->StartPos, en=WaveView1->Selections->EndPos; List->Add(AnsiString().sprintf("Time(%d): from %d to %d", en-st, st, en)); // List->Add(AnsiString().sprintf("Frequency: from %.1fhz to %.1fhz", WaveView1->Selections->StartDigiFreq*WaveView1->SamplesPerSec, WaveView1->Selections->EndDigiFreq*WaveView1->SamplesPerSec)); } if (WaveView1->ObjectAtPointer && WaveView1->ObjectAtPointer->ShortTag[0]==stAtom) { atom* part=(atom*)WaveView1->ObjectAtPointer->Buffer; List->Add("Current Atom"); List->Add(AnsiString().sprintf("Partial %d", WaveView1->ObjectAtPointer->ShortTag[2])); List->Add(AnsiString().sprintf("Frame %d", WaveView1->ObjectAtPointer->Tag[2])); if (WaveView1->RulerUnitTime==0) List->Add(AnsiString().sprintf("Time %d", int(part->t))); else List->Add(AnsiString().sprintf("Time %.4fs", part->t/WaveView1->SamplesPerSec)); if (WaveView1->RulerUnitFreq==0) List->Add(AnsiString().sprintf("Freq %.2fhz", part->f*WaveView1->SamplesPerSec)); else List->Add(AnsiString().sprintf("Freq %.2fbin", part->f*WaveView1->SpecRes)); List->Add(AnsiString().sprintf("Phase%% %.2f", part->p*50/M_PI)); List->Add(AnsiString().sprintf("Amplitude %.4g", part->a)); List->Add(AnsiString().sprintf("Scale %d", int(part->s))); } return (int)List; } //--------------------------------------------------------------------------- void __fastcall TForm1::WaveView1DrawFreqLimiter(TObject* Sender, TWaveViewObject& Obj) { TCanvas* Canv=WaveView1->Canvas; Canv->Pen->Color=clGreen; Canv->Pen->Mode=pmCopy; Canv->Pen->Style=psDot; int X=Obj.Tag[1], Y=WaveView1->FromDigiFreqToPixel(WaveView1->StartPane, f1/WaveView1->SpecRes); Canv->MoveTo(X-10, Y); Canv->LineTo(X+10, Y); Y=WaveView1->FromDigiFreqToPixel(WaveView1->StartPane, f2/WaveView1->SpecRes); Canv->MoveTo(X-10, Y); Canv->LineTo(X+10, Y); Canv->Pen->Style=psSolid; double delm=HSDelmEdit1->Text.ToDouble(); Y=WaveView1->FromDigiFreqToPixel(WaveView1->StartPane, (f1-delm)/WaveView1->SpecRes); Canv->MoveTo(X-10, Y); Canv->LineTo(X+10, Y); Y=WaveView1->FromDigiFreqToPixel(WaveView1->StartPane, (f2+delm)/WaveView1->SpecRes); Canv->MoveTo(X-10, Y); Canv->LineTo(X+10, Y); } //--------------------------------------------------------------------------- void __fastcall TForm1::WaveView1DrawObject(TObject* Sender, TWaveViewObject& Obj) { TCanvas* Canv=WaveView1->Canvas; int Y=WaveView1->Height; if (Obj.Id>=0) { if (WaveView1->ObjectAtPointer==&Obj) { Canv->Brush->Color=clRed; Canv->Brush->Style=bsSolid; Canv->Font=WaveView1->DefaultInfoFont; Canv->Font->Color=clWhite; } else { Canv->Brush->Color=clBlack; Canv->Brush->Style=bsSolid; Canv->Font=WaveView1->DefaultInfoFont; Canv->Font->Color=clWhite; } AnsiString text; int left, top; if (Obj.Id==0) { text=(WaveView1->RulerUnitTime==1)?AnsiString(" [seconds] "):AnsiString(" [samples] "); left=WaveView1->FPanes.MarginOut.left, top=Y-WaveView1->FPanes.MarginOut.bottom; } else if (Obj.Id==1) { if (WaveView1->RulerUnitFreq==1) { if (LogFreqCheck->Checked) text=" [pitch] "; else text= " [bin] "; } else text=" [hz] "; left=WaveView1->FObjects.Items[0].Rect.right, top=WaveView1->FObjects.Items[0].Rect.top; } else if (Obj.Id==2) { text=(WaveView1->RulerUnitAmp==1)?AnsiString(" [abs. amp] "):AnsiString(" [rel. amp] "); left=WaveView1->FObjects.Items[1].Rect.right, top=WaveView1->FObjects.Items[0].Rect.top; } else if (Obj.Id==3) { if (WaveView1->FPanes.Rulers[0] & WV2_HSELECT) text=(WaveView1->RulerAlignX==alTop)?AnsiString(" [X axis: top] "):AnsiString(" [X axis: bottom] "); else text=" [X axis: off] "; left=WaveView1->FObjects.Items[2].Rect.right, top=WaveView1->FObjects.Items[0].Rect.top; } else if (Obj.Id==4) { if (WaveView1->FPanes.Rulers[0] & WV2_VSELECT) text=(WaveView1->RulerAlignY==alLeft)?AnsiString(" [Y axis: left] "):AnsiString(" [Y axis: right] "); else text=" [Y axis: off] "; left=WaveView1->FObjects.Items[3].Rect.right, top=WaveView1->FObjects.Items[0].Rect.top; } else if (Obj.Id==5) { if (WaveView1->AutoSpecAmp) text=AnsiString().sprintf(" [spec. amp (auto): %.3g] ", log(WaveView1->SpecAmp)/log(2.0)); else text=AnsiString().sprintf(" [spec. amp: %.3g] ", log(WaveView1->SpecAmp)/log(2.0)); left=WaveView1->FObjects.Items[4].Rect.right, top=WaveView1->FObjects.Items[0].Rect.top; } Canv->TextOut(left, top, text); Obj.Rect.left=left, Obj.Rect.top=top, Obj.Rect.right=left+Canv->TextWidth(text), Obj.Rect.bottom=top+Canv->TextHeight(text); } } //--------------------------------------------------------------------------- void __fastcall TForm1::WaveView1DrawAtom(TObject* Sender, TWaveViewObject& Obj) { int pane=0; while (pane<WaveView1->FPanes.Count && (!WaveView1->FPanes.HasFreqAxis[pane] ||WaveView1->FPanes.Channel[pane]!=Obj.ShortTag[1])) pane++; if (pane>=WaveView1->FPanes.Count) {Obj.Rect.left=0, Obj.Rect.right=-1, Obj.Rect.top=0, Obj.Rect.bottom=-1; return;} atom* par=(atom*)Obj.Buffer; if (par->t<WaveView1->StartPos || par->t>=WaveView1->EndPos || par->f<WaveView1->StartDigiFreq || par->f>WaveView1->EndDigiFreq || par->f<=0) {Obj.Rect.left=0, Obj.Rect.right=-1, Obj.Rect.top=0, Obj.Rect.bottom=-1; return;} TCanvas* Canv=WaveView1->Canvas; TRect Rect=WaveView1->FPanes.Rect[pane]; HRGN Rgn=CreateRectRgn(Rect.left, Rect.top, Rect.right, Rect.bottom); SelectClipRgn(Canv->Handle, Rgn); int Wid=WaveView1->SpecRes, HOffst=WaveView1->SpecOffst/2; double df=1.0/Wid; int X=WaveView1->FromSampleToPixel(pane, par->t), X1=WaveView1->FromSampleToPixel(pane, par->t-HOffst), X2=WaveView1->FromSampleToPixel(pane, par->t+HOffst); int Y=WaveView1->FromDigiFreqToPixel(pane, par->f), Y1=WaveView1->FromDigiFreqToPixel(pane, par->f+df), Y2=WaveView1->FromDigiFreqToPixel(pane, par->f-df); if (X1>X-1) X1=X-1; if (X2<X+2) X2=X+2; if (Y1>Y-1) Y1=Y-1; if (Y2<Y+2) Y2=Y+2; Canv->Pen->Mode=pmCopy; Canv->Pen->Style=psSolid; bool shiftdown=(GetKeyState(VK_SHIFT)<0), ctrldown=(GetKeyState(VK_CONTROL)<0), onobj=(WaveView1->ObjectAtPointer && WaveView1->ObjectAtPointer->ShortTag[0]==stAtom); if (!shiftdown && !ctrldown && onobj || !shiftdown && ctrldown && onobj && Obj.ShortTag[2]==WaveView1->ObjectAtPointer->ShortTag[2] || shiftdown && !ctrldown && onobj && Obj.Tag[2]==WaveView1->ObjectAtPointer->Tag[2]) { switch (par->type) { case atAnchor: case atPeak: Canv->Pen->Color=clWhite; break; case atInfered: Canv->Pen->Color=clLime; break; case atMuted: case atBuried: Canv->Pen->Color=clRed; break; } } else { switch (par->type) { case atAnchor: case atPeak: Canv->Pen->Color=clGray; break; case atInfered: Canv->Pen->Color=clGreen; break; case atMuted: case atBuried: Canv->Pen->Color=TColor(RGB(128, 0, 0)); break; } } Canv->MoveTo(X-1, Y); Canv->LineTo(X+2, Y); Canv->MoveTo(X, Y-1); Canv->LineTo(X, Y+2); if (par->type==atAnchor) {Canv->MoveTo(X, Y+3); Canv->LineTo(X-3, Y); Canv->LineTo(X, Y-3); Canv->LineTo(X+3, Y); Canv->LineTo(X, Y+3);} if (WaveView1->ObjectAtPointer==&Obj) { if (par->type==atAnchor) {Canv->MoveTo(X, Y+4); Canv->LineTo(X-4, Y); Canv->LineTo(X, Y-4); Canv->LineTo(X+4, Y); Canv->LineTo(X, Y+4);} else {Canv->Brush->Style=bsClear; Canv->Rectangle(X1, Y1, X2, Y2);} } Obj.Rect.left=X1, Obj.Rect.right=X2; Obj.Rect.top=(Y1<Y-5)?(Y-5):Y1, Obj.Rect.bottom=(Y2>Y+6)?(Y+6):Y2; SelectClipRgn(Canv->Handle, NULL); DeleteObject(Rgn); } //--------------------------------------------------------------------------- void __fastcall TForm1::WaveView1InfoDblClick(TObject* Sender) { if (WaveView1->InfoRectAtPointer==1) //time range { bool timeunit=(WaveView1->RulerUnitTime==0); RangeEdit->Caption="Edit time range"; if (timeunit){RangeEdit->Edit1->Text=WaveView1->StartPos; RangeEdit->Edit2->Text=WaveView1->EndPos;} else {RangeEdit->Edit1->Text=WaveView1->StartPos*1.0/WaveView1->SamplesPerSec; RangeEdit->Edit2->Text=WaveView1->EndPos*1.0/WaveView1->SamplesPerSec;} if (RangeEdit->ShowModal()) { int NewStartPos, NewEndPos; if (timeunit) NewStartPos=RangeEdit->Edit1->Text.ToInt(), NewEndPos=RangeEdit->Edit2->Text.ToInt(); else NewStartPos=RangeEdit->Edit1->Text.ToDouble()*WaveView1->SamplesPerSec, NewEndPos=RangeEdit->Edit2->Text.ToDouble()*WaveView1->SamplesPerSec; if (NewStartPos>NewEndPos) {int tmp=NewStartPos; NewStartPos=NewEndPos; NewEndPos=tmp;} if (NewStartPos<0) NewStartPos=0; if (NewEndPos>WaveView1->Length) NewEndPos=WaveView1->Length; WaveView1->SetStartAndEndPos(NewStartPos, NewEndPos); } } else if (WaveView1->InfoRectAtPointer==2) { bool frequnit=(WaveView1->RulerUnitFreq==0); RangeEdit->Caption="Edit frequency range"; if (frequnit){RangeEdit->Edit1->Text=WaveView1->StartDigiFreq*WaveView1->SamplesPerSec; RangeEdit->Edit2->Text=WaveView1->EndDigiFreq*WaveView1->SamplesPerSec;} else {RangeEdit->Edit1->Text=WaveView1->StartDigiFreq*WaveView1->SpecRes; RangeEdit->Edit2->Text=WaveView1->EndDigiFreq*WaveView1->SpecRes;} if (RangeEdit->ShowModal()) { double NewStartDigiFreq, NewEndDigiFreq; if (frequnit) NewStartDigiFreq=RangeEdit->Edit1->Text.ToDouble()/WaveView1->SamplesPerSec, NewEndDigiFreq=RangeEdit->Edit2->Text.ToDouble()/WaveView1->SamplesPerSec; else NewStartDigiFreq=RangeEdit->Edit1->Text.ToDouble()/WaveView1->SpecRes, NewEndDigiFreq=RangeEdit->Edit2->Text.ToDouble()/WaveView1->SpecRes; if (NewStartDigiFreq>NewEndDigiFreq) {double tmp=NewStartDigiFreq; NewStartDigiFreq=NewEndDigiFreq; NewEndDigiFreq=tmp;} if (NewStartDigiFreq<0) NewStartDigiFreq=0; if (NewEndDigiFreq>0.5) NewEndDigiFreq=0.5; WaveView1->SetStartAndEndDigiFreq(NewStartDigiFreq, NewEndDigiFreq); } } } //--------------------------------------------------------------------------- void __fastcall TForm1::WaveView1KeyPress(TObject* Sender, char &Key) { if (Key=='a') { if (PanelGrid->Visible) { PageControl2->SelectNextPage(true, true); } } else if (Key=='A') { if (PanelGrid->Visible) { PageControl2->SelectNextPage(false, true); } } else if (Key=='E') { if (GetKeyState(VK_SHIFT)<0) { if (EventBox->HSCount<1) return; int idx=-1; double delf; double f=WaveView1->CurrentDigiFreq; int t=WaveView1->CurrentTime, ch=WaveView1->FPanes.Channel[WaveView1->CurrentPane]; for (int ev=0; ev<EventBox->HSCount; ev++) { THS* hs=EventBox->HS[ev]; if (t<hs->StartPos() || t>hs->EndPos()) continue; int offst=hs->StdOffst(); int fr=(t-hs->StartPos())/offst; int m=f/hs->Partials[0][fr].f-1; if (m<0) m=0; if (m>hs->M-1) m=hs->M-1; double ldelf=fabs(f-hs->Partials[m][fr].f); while (m>0 && ldelf>fabs(f-hs->Partials[m-1][fr].f)) { ldelf=ldelf>fabs(f-hs->Partials[m-1][fr].f); m--; } while (m<hs->M-1 && ldelf>fabs(f-hs->Partials[m+1][fr].f)) { ldelf=fabs(f-hs->Partials[m+1][fr].f); m++; } if (idx==-1 || delf>ldelf) { delf=ldelf; idx=ev; } } if (idx>=0) EventBox->SetItemIndex(idx); }} } void __fastcall TForm1::AddHSObject(THS* aHS) { for (int m=0; m<aHS->M; m++) for (int fr=0; fr<aHS->Fr; fr++) { if (aHS->Partials[m][fr].f>0) { TWaveViewObject Obj; memset(&Obj, 0, sizeof(TWaveViewObject)); Obj.ShortTag[0]=stAtom; Obj.ShortTag[1]=aHS->Channel; Obj.ShortTag[2]=m+1; Obj.ShortTag[3]=0; Obj.Tag[2]=fr; Obj.DrawObject=WaveView1DrawAtom; Obj.Buffer=&aHS->Partials[m][fr]; Obj.OnKeyDown=WaveView1ParKeyDown; Obj.OnMouseDown=WaveView1ParMouseDown; Obj.OnMouseMove=WaveView1ParMouseMove; Obj.OnMouseUp=WaveView1ParMouseUp; Obj.OnMouseWheel=WaveView1ParMouseWheel; WaveView1->FObjects.Add(Obj); } } } void __fastcall TForm1::WaveView1MouseDown(TObject* Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { if (WaveView1->OpMode!=wopCrop) WaveView1PopupMenu->AutoPopup=true; else WaveView1PopupMenu->AutoPopup=false; if (WaveView1->Playing && Shift.Contains(ssCtrl) && Button==mbRight) {WaveView1->PBPR=WaveView1->CurrentTime, WaveView1->ForceOLA=true; WaveView1PopupMenu->AutoPopup=false; return;} if (WaveView1->OpMode==wopHS && WaveView1->FPanes.HasFreqAxis[WaveView1->CurrentPane] && Shift.Contains(ssLeft)) { if (WaveView1->CurrentPane<0) return; if (WaveView1->ObjectAtPointer && WaveView1->ObjectAtPointer->ShortTag[0]==stAtom) PartialSelectCombo->ItemIndex=WaveView1->ObjectAtPointer->ShortTag[2]-1; if (Shift.Contains(ssShift) || !(WaveView1->ObjectAtPointer && WaveView1->ObjectAtPointer->ShortTag[0]==stAtom)) { double _f=WaveView1->CurrentDigiFreq; int _t=WaveView1->CurrentTime, SpecRes=WaveView1->SpecRes, SpecOffst=WaveView1->SpecOffst; int frst=(WaveView1->StartPos-SpecRes/2)/SpecOffst, fren=(WaveView1->EndPos-SpecRes/2)/SpecOffst; if (frst<0) frst=0; int M, Fr; atom** Partials; int Channel=WaveView1->FPanes.Channel[WaveView1->CurrentPane]; NMSettings settings; PrepareNMSettings(&settings); int tag=FindNote(_t, _f, M, Fr, Partials, frst, fren, SpecRes, SpecOffst, WaveView1->Spectrogram[Channel], settings); if (M>0) { if (!HS) HS=EventBox->NewHS(0, 0); else { ClearObjectByShortTag0(WaveView1, stAtom); if (HS->Partials) DeAlloc2(HS->Partials); if (HS->startamp) {DeAlloc2(HS->startamp); HS->st_count=0;} } HS->M=M, HS->Fr=Fr; HS->Partials=Partials; HS->Channel=Channel; AddHSObject(HS); if (tag) HS->isconstf=1; EventBox->ListBox1->Items->Strings[EventBox->ListBox1->ItemIndex] =((HS->Channel==0)?"left: ":"right: ") +AnsiString().sprintf("%.2fs, ", HS->Partials[0][0].t*1.0/WaveView1->SamplesPerSec) +SemitoneToPitch(Log2(HS->Partials[0][0].f*WaveView1->SamplesPerSec/C4)*12); if (!EventBox->Visible) { EventBox->Left=Left+Width; EventBox->Top=Top; EventBox->Height=Height; EventBox->Show(); } } } } } //--------------------------------------------------------------------------- void __fastcall TForm1::WaveView1MouseMove(TObject* Sender, TShiftState Shift, int X, int Y) { if (Shift.Contains(ssRight) && (X!=WaveView1->StartSelX || Y!=WaveView1->StartSelY)) if (WaveView1PopupMenu->AutoPopup) WaveView1PopupMenu->AutoPopup=false; if (PanelGrid->Visible && (!MBCheck->Checked || Shift.Contains(ssShift))) SetGridContents(); if (Shift.Contains(ssLeft) && WaveView1->OpMode==wopSample) { int channel=WaveView1->FPanes.Channel[WaveView1->StartPane], t=WaveView1->StartSel; WaveView1->Data16[channel][t]=WaveView1->FromPixelToAmplitude(WaveView1->StartPane, Y); WaveView1->ExtDataChange(Sender, channel, t, t); } } //--------------------------------------------------------------------------- void __fastcall TForm1::WaveView1MousePointer(TObject* Sender, int Pane, int t, double f) { } //--------------------------------------------------------------------------- void __fastcall TForm1::WaveView1MouseUp(TObject* Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { } //--------------------------------------------------------------------------- void __fastcall TForm1::WaveView1MouseWheel(TObject* Sender, TShiftState Shift, int WheelDelta, const TPoint& MousePos, bool& Handled) { if (Shift.Contains(ssRight)) { if (WaveView1PopupMenu->AutoPopup) WaveView1PopupMenu->AutoPopup=false; if (WaveView1->OpMode==wopDrag) WaveView1->StartDrag(WaveView1->LastX, WaveView1->LastY); //dragmode=false; } } //--------------------------------------------------------------------------- void __fastcall TForm1::WaveView1ObjectClick(TObject*) { if (WaveView1->ObjectAtPointer->Id==0) WaveView1->RulerUnitTime=1-WaveView1->RulerUnitTime; else if (WaveView1->ObjectAtPointer->Id==1) WaveView1->RulerUnitFreq=1-WaveView1->RulerUnitFreq; else if (WaveView1->ObjectAtPointer->Id==2) WaveView1->RulerUnitAmp=1-WaveView1->RulerUnitAmp; else if (WaveView1->ObjectAtPointer->Id==3){ if (WaveView1->FPanes.Rulers[0] & WV2_HSELECT){if (WaveView1->RulerAlignX==alTop) WaveView1->RulerAlignX=alBottom; else {int rulers=WaveView1->FPanes.Rulers[0] & ~WV2_HSELECT; for (int i=0; i<WaveView1->FPanes.Count; i++) WaveView1->FPanes.Rulers[i]=rulers; WaveView1->InvalidateBasic(-1, 0); WaveView1->RulerAlignX=alTop;}} else {int rulers=WaveView1->FPanes.Rulers[0] | WV2_HSELECT; for (int i=0; i<WaveView1->FPanes.Count; i++) WaveView1->FPanes.Rulers[i]=rulers; WaveView1->InvalidateBasic(-1, 0); WaveView1->RulerAlignX=alTop;}} else if (WaveView1->ObjectAtPointer->Id==4){ if (WaveView1->FPanes.Rulers[0] & (WV2_VSELECT|WV2_AMP)){if (WaveView1->RulerAlignY==alLeft) WaveView1->RulerAlignY=alRight; else {int rulers=WaveView1->FPanes.Rulers[0] & ~WV2_VSELECT & ~WV2_AMP; for (int i=0; i<WaveView1->FPanes.Count; i++) WaveView1->FPanes.Rulers[i]=rulers; WaveView1->InvalidateBasic(-1, 0); WaveView1->RulerAlignY=alLeft;}} else {int rulers=WaveView1->FPanes.Rulers[0] | WV2_VSELECT | WV2_AMP; for (int i=0; i<WaveView1->FPanes.Count; i++) WaveView1->FPanes.Rulers[i]=rulers; WaveView1->InvalidateBasic(-1, 0); WaveView1->RulerAlignY=alLeft;}} } //--------------------------------------------------------------------------- void __fastcall TForm1::WaveView1ObjectDblClick(TObject*) { if (WaveView1->ObjectAtPointer->Id==5) { if (GetKeyState(VK_CONTROL)<0) WaveView1->AutoSpecAmp=!WaveView1->AutoSpecAmp; else WaveView1->SpecAmp=1; } } //--------------------------------------------------------------------------- void __fastcall TForm1::WaveView1ObjectMouseWheel(TObject* Sender, TShiftState Shift, int WheelDelta, const TPoint& MousePos, bool& Handled) { if (WaveView1->ObjectAtPointer->Id==5) { double amp=(WheelDelta>0)?sqrt(2.0):sqrt(0.5); if (WaveView1->AutoSpecAmp) WaveView1->maxv_specamp*=amp; WaveView1->SpecAmp*=amp; } } //--------------------------------------------------------------------------- void __fastcall TForm1::WaveView1OpMode(TObject* Sender, TShiftState Shift, int& OpMode) { AnsiString S=""; if (WaveView1->Length<=0) OpMode=wopIdle; else if (GetKeyState('X')<0) {OpMode=wopCrop; S="Crop"; WaveView1PopupMenu->AutoPopup=false;} //crop mode else if ((SpeedButtonSelect->Down || GetKeyState('S')<0) && !EditorPanel->Visible) {OpMode=wopHS; WaveView1->Cursor=crArrow, S="Sinusoid"; WaveView1PopupMenu->AutoPopup=false;}//special select mode else if (WaveView1->ObjectAtPointer && WaveView1->ObjectAtPointer->ShortTag[0]==stAtom) {OpMode=wopEdit; WaveView1->Cursor=crHandPoint; S="Edit";} //Edit mode else if (Shift.Contains(ssCtrl)) OpMode=wopReselect, S="Reselect"; //re-select mode else if (Shift.Contains(ssRight)) OpMode=wopDrag, S="Drag"; //drag mode else if (WaveView1->CurrentPane>=0 && WaveView1->FPanes.Type[WaveView1->CurrentPane]==0 && (WaveView1->EndPos-WaveView1->StartPos)*10<WaveView1->FPanes.Rect[WaveView1->CurrentPane].Width() && abs(WaveView1->CurrentSampleInPixel-WaveView1->CurrentY)<5) { OpMode=wopSample, S="Edit"; if (WaveView1->Cursor!=crHandPoint){WaveView1->Cursor=crHandPoint; ::SetCursor(Screen->Cursors[crHandPoint]);} } else OpMode=wopSelect, S="Select"; //select mode StatusBar1->Panels->Items[0]->Text=S; } //--------------------------------------------------------------------------- void __fastcall TForm1::CropEventStart(TObject*, TShiftState Shift) { int dfr=WaveView1->ObjectAtPointer->Tag[2]; if (Shift.Contains(ssShift)) { int dm=WaveView1->ObjectAtPointer->ShortTag[2]; for (int i=0; i<WaveView1->FObjects.Count; i++) { TWaveViewObject Obj=WaveView1->FObjects.Items[i]; if (Obj.ShortTag[0]==stAtom && Obj.ShortTag[2]==dm && Obj.Tag[2]<dfr) ((atom*)Obj.Buffer)->type=atMuted; } } else { for (int m=0; m<HS->M; m++) for (int fr=0; fr<HS->Fr-dfr; fr++) HS->Partials[m][fr]=HS->Partials[m][fr+dfr]; HS->Fr-=dfr; int ind=0; for (int i=0; i<WaveView1->FObjects.Count; i++) { TWaveViewObject Obj=WaveView1->FObjects.Items[i]; if (Obj.ShortTag[0]==stAtom) { { if (Obj.Tag[2]>=dfr) { Obj.Tag[2]-=dfr; Obj.Buffer=&HS->Partials[Obj.ShortTag[2]-1][Obj.Tag[2]]; if (WaveView1->ObjectAtPointer==&WaveView1->FObjects.Items[i]) WaveView1->ObjectAtPointer=&WaveView1->FObjects.Items[ind]; if (WaveView1->StartObject==&WaveView1->FObjects.Items[i]) WaveView1->StartObject=&WaveView1->FObjects.Items[ind]; WaveView1->FObjects.Items[ind++]=Obj; } else {} } } else WaveView1->FObjects.Items[ind++]=Obj; } WaveView1->FObjects.Count=ind; int EBLI=EventBox->ListBox1->ItemIndex; if (HS==EventBox->HS[EBLI]) { EventBox->ListBox1->Items->Strings[EBLI]=(HS->Channel==0?"left: ":"right: ") +AnsiString().sprintf("%.2fs, ", HS->Partials[0][0].t*1.0/WaveView1->SamplesPerSec) +SemitoneToPitch(Log2(HS->Partials[0][0].f*WaveView1->SamplesPerSec/C4)*12); } } } void __fastcall TForm1::CropEventEnd(TObject*, TShiftState Shift) { int dfr=WaveView1->ObjectAtPointer->Tag[2]; if (Shift.Contains(ssShift)) { int dm=WaveView1->ObjectAtPointer->ShortTag[2]; for (int i=0; i<WaveView1->FObjects.Count; i++) { TWaveViewObject Obj=WaveView1->FObjects.Items[i]; if (Obj.ShortTag[0]==stAtom && Obj.ShortTag[2]==dm && Obj.Tag[2]>dfr) ((atom*)Obj.Buffer)->type=atMuted; } return; } HS->Fr=dfr+1; int ind=0; for (int i=0; i<WaveView1->FObjects.Count; i++) { TWaveViewObject Obj=WaveView1->FObjects.Items[i]; if (Obj.ShortTag[0]==stAtom && Obj.Tag[2]>dfr) {} else { if (WaveView1->ObjectAtPointer==&WaveView1->FObjects.Items[i]) WaveView1->ObjectAtPointer=&WaveView1->FObjects.Items[ind]; if (WaveView1->StartObject==&WaveView1->FObjects.Items[i]) WaveView1->StartObject=&WaveView1->FObjects.Items[ind]; WaveView1->FObjects.Items[ind++]=Obj; } } WaveView1->FObjects.Count=ind; } void __fastcall TForm1::WaveView1ParKeyDown(TObject*, Word& Key, TShiftState Shift) { if ((WaveView1->OpMode==wopHS || WaveView1->OpMode==wopEdit) && WaveView1->ObjectAtPointer->ShortTag[0]==stAtom) { if (Key==VK_DELETE) { atom* par=(atom*)WaveView1->ObjectAtPointer->Buffer; if (par->type==atAnchor) { if (Shift.Contains(ssShift) && Shift.Contains(ssCtrl)) { atom** Partials=HS->Partials; for (int m=0; m<HS->M; m++) for (int fr=0; fr<HS->Fr; fr++) if (Partials[m][fr].type==atAnchor) Partials[m][fr].type=atPeak; } else if (Shift.Contains(ssShift)) { atom** Partials=HS->Partials; int fr=WaveView1->ObjectAtPointer->Tag[2]; for (int m=0; m<HS->M; m++) if (Partials[m][fr].type==atAnchor) Partials[m][fr].type=atPeak; } else {par->type=atPeak;} WaveView1->Invalidate(); } } } } //--------------------------------------------------------------------------- #define ExFpStiff ExFmStiff void __fastcall TForm1::WaveView1ParMouseDown(TObject* Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { if (WaveView1->OpMode==wopHS && Shift.Contains(ssShift)) return; if (WaveView1->ObjectAtPointer->ShortTag[0]!=stAtom) return; if (WaveView1->OpMode==wopHS) { if (!Shift.Contains(ssLeft)) return; edfr=WaveView1->ObjectAtPointer->Tag[2]; int M=HS->M, Fr=HS->Fr, p=WaveView1->ObjectAtPointer->ShortTag[2]; anccount=0; ancps=(int*)realloc(ancps, sizeof(int)*M); ancfs=(double*)realloc(ancfs, sizeof(double)*M); ancfrs=(int*)realloc(ancfrs, sizeof(int)*M); atom** Partials=HS->Partials; int frst=edfr, fren=edfr+1; if (HS->isconstf) frst=0, fren=HS->Fr; int N=WaveView1->SpecRes; for (int m=0; m<M; m++) { for (int fr=frst; fr<fren; fr++) { if (m+1==p) continue; double f=Partials[m][fr].f; if (f>0 && HS->Partials[m][fr].type==atAnchor) { ancps[anccount]=m+1, ancfs[anccount]=f*N; ancfrs[anccount]=(HS->Partials[m][fr].tags&ATOM_LOCALANCHOR)?fr:(-1); //fr>=0: local anchor, used in constant-f tracking anccount++; break; } } } if (anccount>0) { double delm=HSDelmEdit1->Text.ToDouble(), maxB=HSMaxBEdit1->Text.ToDouble(); TPolygon* R=new TPolygon(4+anccount*2); InitializeR(R, ancps[0], ancfs[0], delm, maxB); for (int i=1; i<anccount; i++) CutR(R, ancps[i], ancfs[i], delm); ExFpStiff(f1, f2, p, R->N, R->X, R->Y); TWaveViewObject Obj; memset(&Obj, 0, sizeof(TWaveViewObject)); Obj.ShortTag[0]=stFreqDelimiter; Obj.Tag[1]=WaveView1->FromSampleToPixel(WaveView1->StartPane, Partials[p-1][edfr].t); Obj.DrawObject=WaveView1DrawFreqLimiter; WaveView1->FObjects.Add(Obj); delete R; } } else if (WaveView1->OpMode==wopCrop) { bool refresh=false; if (Button==mbLeft) CropEventStart(0, Shift), refresh=true; else if (Button==mbRight) CropEventEnd(0, Shift), refresh=true; if (refresh) WaveView1->Invalidate(); } } void __fastcall TForm1::WaveView1ParMouseMove(TObject* Sender, TShiftState Shift, int X, int Y) { if (Shift.Contains(ssLeft)) { WaveView1->ObjectAtPointer=WaveView1->StartObject; if (Y==WaveView1->LastY) return; if (WaveView1->OpMode==wopHS) //harmonic sinusoid estimation mode { //* if (!WaveView1->StartObject) return; atom* par=(atom*)WaveView1->StartObject->Buffer; int t=par->t, wid=WaveView1->SpecRes, offst=WaveView1->SpecOffst; int hwid=wid/2, fr=(t-hwid)/offst; double f0=WaveView1->CurrentDigiFreq*wid, B; int Channel=WaveView1->StartObject->ShortTag[1]; cdouble *x=new cdouble[hwid+1]; cmplx<QSPEC_FORMAT>* spec=WaveView1->Spec[Channel][fr]; for (int i=0; i<=hwid; i++) x[i]=spec[i]; TPolygon* R=new TPolygon(1024); R->N=0; NMSettings settings; PrepareNMSettings(&settings); settings.pcount=anccount; settings.pin=ancps; settings.pinf=ancfs; settings.pin0asanchor=true; settings.pinfr=ancfrs; if (!HS->isconstf) { double fpp[1024], *vfpp=&fpp[256], *pfpp=&fpp[512]; atomtype *ptype=(atomtype*)&fpp[768]; memset(fpp, 0, sizeof(double)*1024); NMResults results={fpp, vfpp, pfpp, ptype}; NoteMatchStiff3(R, f0, B, 1, &x, wid, 0, &settings, &results, 0, 0, ds0); atom part; part.t=par->t; part.s=par->s; if (f0>0) { int Fr=WaveView1->StartObject->Tag[2]; for (int i=0; i<settings.maxp; i++) { if (fpp[i]>0) { if (i<HS->M) { part.f=fpp[i]/wid; part.a=vfpp[i]; part.p=pfpp[i]; part.pin=i+1; part.type=ptype[i]; HS->Partials[i][Fr]=part; } } else { for (int j=i; j<HS->M; j++) HS->Partials[j][Fr].f=0; break; } } } } else //HS->isconstf==true { int Fr=HS->Fr, maxp=settings.maxp; Alloc2(Fr*3, maxp+2, fpp); double **vfpp=&fpp[Fr], **pfpp=&fpp[Fr*2]; atomtype** Allocate2(atomtype, Fr, maxp+2, ptype); NMResults* results=new NMResults[Fr]; for (int fr=0; fr<Fr; fr++) results[fr].fp=fpp[fr], results[fr].vfp=vfpp[fr], results[fr].pfp=pfpp[fr], results[fr].ptype=ptype[fr]; cdouble** Allocate2(cdouble, Fr, hwid+1, xx); int frst=(HS->Partials[0][0].t-hwid)/offst; for (int fr=0; fr<Fr; fr++) { cmplx<QSPEC_FORMAT>* spec=WaveView1->Spec[Channel][frst+fr]; for (int i=0; i<=hwid; i++) xx[fr][i]=spec[i]; } if (Shift.Contains(ssCtrl)) NoteMatchStiff3(R, f0, B, Fr, xx, wid, offst, &settings, results, 0, 0, ds0, true, WaveView1->StartObject->Tag[2], 3); else NoteMatchStiff3(R, f0, B, Fr, xx, wid, offst, &settings, results, 0, 0, ds0, false, WaveView1->StartObject->Tag[2], 3); if (f0>0) { for (int fr=0; fr<Fr; fr++) { double *fppfr=fpp[fr], *vfppfr=vfpp[fr], *pfppfr=pfpp[fr]; atomtype *ptypefr=ptype[fr]; for (int i=0; i<HS->M; i++) { atom* part=&HS->Partials[i][fr]; if (fppfr[i]>0) { if (i<HS->M) { part->f=fppfr[i]/wid; part->a=vfppfr[i]; part->p=pfppfr[i]; part->pin=i+1; if (ptypefr[i]) part->type=ptypefr[i]; else if (i==settings.pin0-1) part->type=atPeak; } } else { for (int j=i; j<HS->M; j++) HS->Partials[j][fr].f=0; break; } } } atom* atm=&HS->Partials[settings.pin0-1][WaveView1->StartObject->Tag[2]]; atm->type=atAnchor; if (Shift.Contains(ssCtrl)) atm->tags=atm->tags|ATOM_LOCALANCHOR; else atm->tags=atm->tags&~ATOM_LOCALANCHOR; } DeAlloc2(xx); delete[] results; DeAlloc2(fpp); DeAlloc2(ptype); } delete R; delete[] x; } else if (WaveView1->OpMode==wopCrop) //crop mode { } else if (WaveView1->OpMode==wopEdit) //HS edit mode { if (GetKeyState('F')<0) { Amplify1Click(FM1); } else { Amplify1Click(Pitchshifting1); double f1=WaveView1->FromPixelToDigiFreq(WaveView1->StartPane, WaveView1->StartSelY), f2=WaveView1->FromPixelToDigiFreq(WaveView1->StartPane, Y); double dp=12*Log2(f2/f1); EditorPanel->PitchEdit1->Text=dp; EditorPanel->AmpEdit1KeyPress(EditorPanel->PitchEdit1, ReturnKey); } } } } TPolygon* RFromAtoms(int& startp, double* vfped, double starts, int M, int fr, atom** Partials, int wid, double delm, double maxB) { TPolygon* R=new TPolygon(M*2+4); R->N=0; memset(vfped, 0, sizeof(double)*M); startp=M; for (int m=0; m<M; m++) { double lf=Partials[m][fr].f*wid, la=Partials[m][fr].a; if (lf>0) { if (Partials[m][fr].type<=1) { if (R->N==0) InitializeR(R, m+1, lf, delm, maxB); else if (la>1) CutR(R, m+1, lf, delm, true); } vfped[m]=la; starts+=la*la; } else {startp=m; break;} } return R; } void __fastcall TForm1::WaveView1ParMouseUp(TObject* Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { if (Button==mbRight) return; if (WaveView1->OpMode==wopHS) { if (!WaveView1->StartObject) return; ClearObjectByShortTag0(WaveView1, stFreqDelimiter); //erase the delimiter int M=HS->M, Fr=HS->Fr; atom** Partials=HS->Partials; //* edfr=WaveView1->StartObject->Tag[2]; int channel=WaveView1->StartObject->ShortTag[1]; int wid=WaveView1->SpecRes, offst=WaveView1->SpecOffst, hwid=wid/2; NMSettings settings; PrepareNMSettings(&settings); int maxp=settings.maxp; if (HS->isconstf) { double brake=0.1; if (edfr==0 || edfr==Fr-1) { int frst, fren, edt=HS->Partials[0][edfr].t, startfr=(edt-hwid)/offst; atom* part; if (edfr==0) { frst=ceil((WaveView1->StartPos-hwid)*1.0/offst); if (frst<0) frst=0; part=new atom[M*(Fr+startfr-frst+1)]; } else //edfr==Fr-1 { fren=floor((WaveView1->EndPos-hwid)*1.0/offst); part=new atom[M*(Fr+fren-startfr+1)]; } int k=0; for (int fr=0; fr<Fr; fr++) for (int m=0; m<M; m++) if (Partials[m][fr].f>0) part[k++]=Partials[m][fr]; double ene0=0; for (int m=0; m<HS->M; m++) { if (HS->Partials[m][edfr].f>0) { double tmp=HS->Partials[m][edfr].a; ene0+=tmp*tmp; } else break; } int t=edt, dt=(edfr==0)?(-offst):offst; int channel=WaveView1->StartObject->ShortTag[1]; cdouble* x=new cdouble[hwid+1]; if (edfr==0) { for (int fr=startfr-1; fr>=frst; fr--) { t+=dt; cmplx<QSPEC_FORMAT>* spec=WaveView1->Spec[channel][fr]; for (int i=0; i<=hwid; i++) x[i]=spec[i]; double ene=0; for (int m=0; m<HS->M; m++) { double f=HS->Partials[m][edfr].f*wid; cdouble r=IPWindowC(f, x, wid, settings.M, settings.c, settings.iH2, ceil(f-settings.hB), floor(f+settings.hB)); double la=abs(r); atomtype ltype=HS->Partials[m][edfr].type; if (!ltype) ltype=atPeak; atom lpart={t, wid, f/wid, la, arg(r), m+1, ltype}; part[k++]=lpart; ene+=la*la; } if (ene<ene0*brake) break; if (ene>ene0) ene0=ene; } } else //edfr==Fr-1 { for (int fr=startfr+1; fr<=fren; fr++) { t+=dt; cmplx<QSPEC_FORMAT>* spec=WaveView1->Spec[channel][fr]; for (int i=0; i<=hwid; i++) x[i]=spec[i]; double ene=0; for (int m=0; m<HS->M; m++) { double f=HS->Partials[m][edfr].f*wid; cdouble r=IPWindowC(f, x, wid, settings.M, settings.c, settings.iH2, ceil(f-settings.hB), floor(f+settings.hB)); double la=abs(r); atomtype ltype=HS->Partials[m][edfr].type; if (!ltype) ltype=atPeak; atom lpart={t, wid, f/wid, la, arg(r), m+1, ltype}; part[k++]=lpart; ene+=la*la; } if (ene<ene0*brake) break; if (ene>ene0) ene0=ene; } } delete[] x; DeAlloc2(HS->Partials); AtomsToPartials(k, part, HS->M, HS->Fr, HS->Partials, offst); ClearObjectByShortTag0(WaveView1, stAtom); AddHSObject(HS); delete[] part; if (edfr==0) { int EBLI=EventBox->ListBox1->ItemIndex; if (HS==EventBox->HS[EBLI]) { EventBox->ListBox1->Items->Strings[EBLI]=(HS->Channel==0?"left: ":"right: ") +AnsiString().sprintf("%.2fs, ", HS->Partials[0][0].t*1.0/WaveView1->SamplesPerSec) +SemitoneToPitch(Log2(HS->Partials[0][0].f*WaveView1->SamplesPerSec/C4)*12); } } } return; } double delm=settings.delm, maxB=settings.maxB; double *vfped=new double[M], starts=0; int startp; TPolygon* R=RFromAtoms(startp, vfped, starts, M, edfr, Partials, wid, delm, maxB); int fr1=edfr-1; while (fr1>=0){int m; for (m=0; m<M; m++) if (Partials[m][fr1].f>0 && Partials[m][fr1].type==atAnchor) break; if (m<M) break; fr1--;} int fr2=edfr+1; while (fr2<Fr){int m; for (m=0; m<M; m++) if (Partials[m][fr2].f>0 && Partials[m][fr2].type==atAnchor) break; if (m<M) break; fr2++;} int fred=(Partials[0][edfr].t-wid/2)/offst, frst=(WaveView1->StartPos-wid/2)/offst, fren=(WaveView1->EndPos-wid/2)/offst; if (fr1>=0) { int startpst; double startsst, *vfpst=new double[M]; TPolygon* Rst=RFromAtoms(startpst, vfpst, startsst, M, fr1, Partials, wid, delm, maxB); FindNoteFB(fr1, Rst, vfpst, edfr, R, vfped, M, Partials, wid, offst, WaveView1->Spectrogram[channel], settings); delete Rst; delete[] vfpst; if (fr2<Fr) { int startpen; double startsen, *vfpen=new double[M]; TPolygon* Ren=RFromAtoms(startpen, vfpen, startsen, M, fr2, Partials, wid, delm, maxB); FindNoteFB(edfr, R, vfped, fr2, Ren, vfpen, M, Partials, wid, offst, WaveView1->Spectrogram[channel], settings); delete Ren; delete[] vfpen; } else { atom* part=new atom[M*Fr+maxp*(fren-frst)]; int k=0; for (int fr=0; fr<=edfr; fr++) for (int m=0; m<M; m++) if (Partials[m][fr].f>0) part[k++]=Partials[m][fr]; k+=FindNoteF(&part[k], starts, R, startp, vfped, fred, fren, wid, offst, WaveView1->Spectrogram[channel], settings, 0.02); DeAlloc2(HS->Partials); AtomsToPartials(k, part, HS->M, HS->Fr, HS->Partials, offst); ClearObjectByShortTag0(WaveView1, stAtom); AddHSObject(HS); delete[] part; } } else //fr1<0 { if (fr2<Fr) { int startpen; double startsen, *vfpen=new double[M]; TPolygon* Ren=RFromAtoms(startpen, vfpen, startsen, M, fr2, Partials, wid, delm, maxB); FindNoteFB(edfr, R, vfped, fr2, Ren, vfpen, M, Partials, wid, offst, WaveView1->Spectrogram[channel], settings); delete Ren; delete[] vfpen; } atom* part=new atom[M*Fr+maxp*(fren-frst)]; int k=0, keepst=edfr, keepen=(fr2>=Fr)?edfr:(Fr-1); for (int fr=keepst; fr<=keepen; fr++) for (int m=0; m<M; m++) if (Partials[m][fr].f>0) part[k++]=Partials[m][fr]; k+=FindNoteF(&part[k], starts, R, startp, vfped, fred, (frst>=0)?(frst-1):-1, wid, offst, WaveView1->Spectrogram[channel], settings, 0.02); if (fr2>=Fr) k+=FindNoteF(&part[k], starts, R, startp, vfped, fred, fren, wid, offst, WaveView1->Spectrogram[channel], settings, 0.02); DeAlloc2(HS->Partials); AtomsToPartials(k, part, HS->M, HS->Fr, HS->Partials, offst); ClearObjectByShortTag0(WaveView1, stAtom); AddHSObject(HS); delete[] part; } delete R; delete[] vfped; } } //--------------------------------------------------------------------------- void __fastcall TForm1::WaveView1ParMouseWheel(TObject* Sender, TShiftState Shift, int WheelDelta, const TPoint& MousePos, bool& Handled) { if (WaveView1->OpMode==wopEdit) { if (GetKeyState('A')<0) { Amplify1Click(AM1); EditorPanel->AMAEdit1MouseWheel(WheelDelta); } else if (GetKeyState('D')<0) { Amplify1Click(DeFM1); EditorPanel->DeFMEdit1MouseWheel(WheelDelta); } else if (GetKeyState('F')<0) { Amplify1Click(FM1); EditorPanel->FMAEdit1MouseWheel(WheelDelta); } else { Amplify1Click(Amplify1); EditorPanel->AmpEdit1MouseWheel(WheelDelta); } } } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- void __fastcall TForm1::WaveView1PlaybackDone(TObject*) { SpeedButtonPlay->Glyph=BitmapPlay; } //--------------------------------------------------------------------------- void __fastcall TForm1::WaveView1PlaybackStart(TObject*) { SpeedButtonPlay->Glyph=BitmapStop; } //--------------------------------------------------------------------------- void __fastcall TForm1::WaveView1PopupMenuPopup(TObject *Sender) { ZoomToSelection1->Visible=(WaveView1->Selections->Count>0 && WaveView1->Selections->Focus>=0); UndoZoom1->Visible=(WaveView1->UndoExtractSelection.EndPos>=0); TimeZoom1->Visible=(WaveView1->StartPos!=0 || WaveView1->EndPos!=WaveView1->Length); FrequencyZoom1->Visible=(WaveView1->StartDigiFreq!=0 || WaveView1->EndDigiFreq!=0.5); AmplitudeZoom1->Visible=(WaveView1->YZoomRate!=1); SpectrogramBrightness1->Visible=(WaveView1->SpecAmp!=1); Restore1->Visible=TimeZoom1->Visible || FrequencyZoom1->Visible || AmplitudeZoom1->Visible || SpectrogramBrightness1->Visible; Play1->Visible=(WaveView1->Length>0); Play1->Caption=WaveView1->Playing?"Stop":"Play"; Cut1->Visible=(WaveView1->OpMode<=2 && WaveView1->Selections->Count>0 && WaveView1->FPanes.HasFreqAxis[WaveView1->CurrentPane]) || (WaveView1->ObjectAtPointer && WaveView1->ObjectAtPointer->ShortTag[0]==stAtom); Extract1->Visible=Cut1->Visible; Editorpanel1->Visible=(WaveView1->ObjectAtPointer && WaveView1->ObjectAtPointer->ShortTag[0]==stAtom); } //--------------------------------------------------------------------------- void __fastcall TForm1::WindowSizeComboChange(TObject *Sender) { WaveView1->SpecRes=WindowSizeCombo->Text.ToInt(); } //--------------------------------------------------------------------------- void __fastcall TForm1::WindowTypeComboChange(TObject *Sender) { WindowType types[]={wtRectangle, wtHamming, wtHann, wtBlackman, wtGaussian}; WaveView1->SpecWindowType=types[WindowTypeCombo->ItemIndex]; } //--------------------------------------------------------------------------- void __fastcall TForm1::SpeedButtonSClick(TObject *Sender) { SpectrogramView=!SpectrogramView; SpeedButtonS->Glyph=SpectrogramView?BitmapWaveform:BitmapSpectrogram; Spectrogram2->Caption=SpectrogramView?"Waveform":"Spectrogram"; SetWaveViewContents(); } //--------------------------------------------------------------------------- void __fastcall TForm1::AmplitudeZoom1Click(TObject *Sender) { WaveView1->YZoomRate=1; } //--------------------------------------------------------------------------- void __fastcall TForm1::Extract1Click(TObject *Sender) { if (WaveView1->ObjectAtPointer && WaveView1->ObjectAtPointer->ShortTag[0]==stAtom || Sender==EventBox->Extract1 && HS) { int dst, den; double* xrec=SynthesisHSp(HS, dst, den); memset(&WaveView1->Data8[HS->Channel][WaveView1->BytesPerSample*WaveView1->StartPos], 0, WaveView1->BytesPerSample*(WaveView1->EndPos-WaveView1->StartPos)); WaveView1->ExtDataChange(NULL, HS->Channel, WaveView1->StartPos, WaveView1->EndPos); PostWaveViewData(xrec, HS->Channel, dst, den, FadeInCheck->Checked, FadeInCombo->Text.ToInt()); free8(xrec); } else if (WaveView1->OpMode<=2 && WaveView1->Selections->Count>0 && WaveView1->Selections->Focus>=0) { WaveView1->TFFilter(WaveView1->CurrentChannel, true); WaveView1->ExtDataChange(Sender, WaveView1->CurrentChannel, WaveView1->StartPos-WaveView1->SpecRes, WaveView1->EndPos+WaveView1->SpecRes); } } //--------------------------------------------------------------------------- void __fastcall TForm1::PostWaveViewData(double* data, int Channel, int StartPos, int EndPos, bool fadein, int W) { int bps=WaveView1->BytesPerSample, L=EndPos-StartPos; if (fadein) { int hW=W/2; double* leadin=new double[hW*2]; double* leadout=&leadin[hW]; IntToDouble(leadin, &WaveView1->Data8[Channel][StartPos*bps], bps, hW); IntToDouble(leadout, &WaveView1->Data8[Channel][(EndPos-hW)*bps], bps, hW); for (int i=0; i<hW; i++) { double w=0.5+0.5*cos(M_PI*i/hW); leadin[i]=leadin[i]*w+data[i]*(1-w); leadout[i]=leadout[i]*(1-w)+data[L-hW+i]*w; } if (L>hW*2) { DoubleToInt(&WaveView1->Data8[Channel][StartPos*bps], bps, leadin, hW); DoubleToInt(&WaveView1->Data8[Channel][(StartPos+hW)*bps], bps, &data[hW], L-hW*2); DoubleToInt(&WaveView1->Data8[Channel][(EndPos-hW)*bps], bps, leadout, hW); } else { DoubleToInt(&WaveView1->Data8[Channel][StartPos*bps], bps, leadin, L/2); DoubleToInt(&WaveView1->Data8[Channel][(StartPos+L/2)*bps], bps, &leadout[hW-L/2], L-L/2); } delete[] leadin; } else DoubleToInt(&WaveView1->Data8[Channel][StartPos*bps], bps, data, L); WaveView1->ExtDataChange(this, Channel, StartPos, EndPos); } void __fastcall TForm1::PostWaveViewData(__int16* data, int Channel, int StartPos, int EndPos, bool fadein, int W) { int bps=WaveView1->BytesPerSample, L=EndPos-StartPos; if (fadein) { int hW=W/2; double* leadin=new double[hW*2]; double* leadout=&leadin[hW]; IntToDouble(leadin, &WaveView1->Data8[Channel][StartPos*bps], bps, hW); IntToDouble(leadout, &WaveView1->Data8[Channel][(EndPos-hW)*bps], bps, hW); for (int i=0; i<hW; i++) { double w=0.5+0.5*cos(M_PI*i/hW); leadin[i]=leadin[i]*w+data[i]*(1-w); leadout[i]=leadout[i]*(1-w)+data[L-hW+i]*w; } if (L>hW*2) { DoubleToInt(&WaveView1->Data8[Channel][StartPos*bps], bps, leadin, hW); memcpy(&WaveView1->Data8[Channel][(StartPos+hW)*bps], &data[hW], 2*(L-hW*2)); DoubleToInt(&WaveView1->Data8[Channel][(EndPos-hW)*bps], bps, leadout, hW); } else { DoubleToInt(&WaveView1->Data8[Channel][StartPos*bps], bps, leadin, L/2); DoubleToInt(&WaveView1->Data8[Channel][(StartPos+L/2)*bps], bps, &leadout[hW-L/2], L-L/2); } delete[] leadin; } else memcpy(&WaveView1->Data8[Channel][StartPos*bps],data, 2*L); WaveView1->ExtDataChange(this, Channel, StartPos, EndPos); } void __fastcall TForm1::PostWaveViewData(__int16* data, int Channel, int StartPos, int EndPos) { memcpy(&WaveView1->Data16[Channel][StartPos], data, 2*(EndPos-StartPos)); WaveView1->ExtDataChange(this, Channel, StartPos, EndPos); } void __fastcall TForm1::FadeInCheckClick(TObject *Sender) { FadeInLabel->Enabled=FadeInCheck->Checked; FadeInCombo->Enabled=FadeInCheck->Checked; } //--------------------------------------------------------------------------- void FadeInOut(double* x, int N, int hWid) { x[0]=0; double iPI=M_PI/hWid; for (int n=1; n<hWid; n++) { double tmp=0.5-0.5*cos(n*iPI); x[n]*=tmp; x[N-n]*=tmp; } } void __fastcall TForm1::Cut1Click(TObject *Sender) { if (WaveView1->ObjectAtPointer && WaveView1->ObjectAtPointer->ShortTag[0]==stAtom || Sender==EventBox->Cut1 && HS) { int s=HS->Partials[0][0].s, hs=s/2, dst=HS->Partials[0][0].t-hs, den=HS->Partials[0][HS->Fr-1].t+hs, bps=WaveView1->BytesPerSample; double* data=new double[den-dst]; IntToDouble(data, &WaveView1->Data8[HS->Channel][dst*bps], bps, den-dst); if (GetKeyState(VK_SHIFT)<0) { int st_wid=s/2, st_offst=st_wid/2, st_len=s; int st_count=(st_len-st_wid)/st_offst+1; int st_start=st_len-st_offst*st_count-hs, Fr=HS->Fr; HS->st_start=st_start, HS->st_offst=st_offst, HS->st_count=st_count; DeAlloc2(HS->startamp); Allocate2(double, HS->M, st_count, HS->startamp); memset(HS->startamp[0], 0, sizeof(double)*st_count*HS->M); double *f1=new double[Fr*15], *fa=&f1[Fr], *fb=&fa[Fr], *fc=&fb[Fr], *fd=&fc[Fr], *xs=&fd[Fr], *p1=&xs[Fr], *a1=&p1[Fr], *aa=&a1[Fr], *ab=&aa[Fr], *ac=&ab[Fr], *ad=&ac[Fr]; int *ixs=(int*)&f1[Fr*14]; double* xrec=new double[st_len]; for (int m=0; m<HS->M; m++) { atom* part=HS->Partials[m]; bool fzero=false; for (int fr=0; fr<Fr; fr++) { if (part[fr].f<=0){fzero=true; break;} ixs[fr]=part[fr].t; xs[fr]=part[fr].t; f1[fr]=part[fr].f; p1[fr]=part[fr].p; a1[fr]=part[fr].a*2; } if (fzero) break; CubicSpline(Fr-1, fa, fb, fc, fd, xs, f1, 1, 1); CubicSpline(Fr-1, aa, ab, ac, ad, xs, a1, 1, 1); for (int l=0; l<Fr && ixs[l]-dst<st_len; l++) { int llen=(ixs[l+1]-dst<st_len)?(ixs[l+1]-ixs[l]):(st_len+dst-ixs[l]); Sinusoid(llen, &xrec[ixs[l]-dst], aa[l], ab[l], ac[l], ad[l], fa[l], fb[l], fc[l], fd[l], p1[l], p1[l+1], false); } double tmpph=p1[0]; Sinusoid(&xrec[ixs[0]-dst], -hs, 0, aa[0], ab[0], ac[0], ad[0], fa[0], fb[0], fc[0], fd[0], tmpph, false); for (int l=0; l<st_count; l++) { double *ldata=&data[st_offst*l], *lxrec=&xrec[st_offst*l]; double tmp=0, tmp2=0; for (int n=0; n<st_wid; n++) tmp+=ldata[n]*lxrec[n], tmp2+=lxrec[n]*lxrec[n]; HS->startamp[m][l]=tmp/tmp2; } } delete[] xrec; delete[] f1; } double* xrec=SynthesisHSp(HS, dst, den); FadeInOut(xrec, den-dst, s/2); for (int i=0; i<den-dst; i++) data[i]-=xrec[i]; PostWaveViewData(data, HS->Channel, dst, den, false&&FadeInCheck->Checked, FadeInCombo->Text.ToInt()); free8(xrec); delete[] data; } else if (WaveView1->OpMode<=2 && WaveView1->Selections->Count>0 && WaveView1->Selections->Focus>=0) { WaveView1->TFFilter(WaveView1->CurrentChannel, false); WaveView1->ExtDataChange(Sender, WaveView1->CurrentChannel, WaveView1->StartPos-WaveView1->SpecRes, WaveView1->EndPos+WaveView1->SpecRes); } } //--------------------------------------------------------------------------- void __fastcall TForm1::Amplify1Click(TObject *Sender) { if (!EditorPanel->Visible) { GetTargetAudio(EditorPanel->targettype, EditorPanel->Channel, EditorPanel->From, EditorPanel->To, EditorPanel->target, EditorPanel->Before); if (EditorPanel->targettype==1) {delete EditorPanel->HS; EditorPanel->HS=new THS(HS);} EditorPanel->AmpEdit1->Text="1"; EditorPanel->AmpDBEdit1->Text="0"; EditorPanel->PitchEdit1->Text="0"; EditorPanel->AMAEdit1->Text="0"; EditorPanel->AMFEdit1->Text="4"; EditorPanel->FMAEdit1->Text="0"; EditorPanel->FMFEdit1->Text="4"; EditorPanel->DeFMEdit1->Text="1"; EditorPanel->DeFMEdit2->Text="1"; } if (Sender==Amplify1) EditorPanel->PageControl1->ActivePage=EditorPanel->AmplifySheet; else if (Sender==Pitchshifting1) EditorPanel->PageControl1->ActivePage=EditorPanel->PitchSheet; else if (Sender==AM1) EditorPanel->PageControl1->ActivePage=EditorPanel->AMSheet; else if (Sender==FM1) EditorPanel->PageControl1->ActivePage=EditorPanel->FMSheet; else if (Sender==DeFM1) EditorPanel->PageControl1->ActivePage=EditorPanel->DeFMSheet; if (!EditorPanel->Visible) EditorPanel->Show(); } //--------------------------------------------------------------------------- void __fastcall TForm1::GetTargetAudio(int& targettype, int& channel, int& from, int& to, double*& target, __int16*& before) { free8(target); delete[] before; if (WaveView1->ObjectAtPointer && WaveView1->ObjectAtPointer->ShortTag[0]==stAtom) { targettype=1; channel=HS->Channel; target=SynthesisHSp(HS, from, to); before=new __int16[to-from]; memcpy(before, &WaveView1->Data16[channel][from], sizeof(__int16)*(to-from)); } else { targettype=0; channel=WaveView1->FPanes.Channel[WaveView1->StartPane]; to=WaveView1->EndPos; from=WaveView1->StartPos; target=(double*)malloc8(sizeof(double)*(to-from)); before=new __int16[to-from]; memcpy(before, &WaveView1->Data16[0][from], sizeof(__int16)*(to-from)); IntToDouble(target, before, 2, to-from); } } //--------------------------------------------------------------------------- void __fastcall TForm1::Events1Click(TObject *Sender) { if (!EventBox->Visible) { EventBox->Left=Left+Width; EventBox->Top=Top; EventBox->Height=Height; EventBox->Load(NULL); EventBox->Show(); } else { if (EventBox->Left>=Screen->Width) EventBox->Left=Left+Width; EventBox->BringToFront(); } } //--------------------------------------------------------------------------- void __fastcall TForm1::SpeedButtonSaveClick(TObject *Sender) { SaveDialog1->FileName="waveview.waveview1.wav"; SaveDialog1->FilterIndex=1; int bps=WaveView1->BytesPerSample, rfb=WaveView1->StartPos*bps, rlen=WaveView1->EndPos-WaveView1->StartPos; if (SaveDialog1->Execute()) { TWaveAudio* WA=new TWaveAudio(NULL); WA->GetWaveProperties(WaveAudio1); if (WA->Channels==1) WA->Write(&WaveView1->Data8[0][rfb], rlen*bps); else if (WA->Channels==2) WA->WriteSamplesInterleave(&WaveView1->Data8[0][rfb], &WaveView1->Data8[1][rfb], rlen); WA->SaveToFile(SaveDialog1->FileName); delete WA; } } void __fastcall TForm1::TimeZoom1Click(TObject *Sender) { WaveView1->SetStartAndEndPos(0, WaveView1->Length); } //--------------------------------------------------------------------------- void __fastcall TForm1::FrequencyZoom1Click(TObject *Sender) { WaveView1->SetStartAndEndDigiFreq(0, 0.5); } //--------------------------------------------------------------------------- void __fastcall TForm1::Vibratowizard1Click(TObject *Sender) { TVibratoDemoForm* VF=VibratoDemoForm; VF->WaveView1->StartDigiFreq=WaveView1->StartDigiFreq; VF->WaveView2->StartDigiFreq=WaveView1->StartDigiFreq; VF->WaveView1->EndDigiFreq=WaveView1->EndDigiFreq; VF->WaveView2->EndDigiFreq=WaveView1->EndDigiFreq; VF->WaveView2->SpecAmp=WaveView1->SpecAmp; int SpecRes, SpecOffst; if (Sender==EventBox->Vibratowizard1) { SpecRes=HS->Partials[0][0].s; SpecOffst=HS->Partials[0][1].t-HS->Partials[0][0].t; } else { SpecRes=WaveView1->SpecRes; SpecOffst=WaveView1->SpecOffst; } VF->WaveView1->SpecRes=SpecRes; VF->WaveView1->SpecOffst=SpecOffst; VF->WaveAudio1->Clear(NULL); VF->WaveAudio1->SamplesPerSec=WaveAudio1->SamplesPerSec; VF->WaveAudio1->BitsPerSample=WaveAudio1->BitsPerSample; int ch=WaveView1->FPanes.Channel[WaveView1->StartPane]; if (Sender==EventBox->Vibratowizard1) ch=HS->Channel; int st=(WaveView1->StartPos-SpecRes/2)/SpecOffst*SpecOffst; int en=(WaveView1->EndPos-SpecRes/2)/SpecOffst*SpecOffst+SpecRes; if (Sender==EventBox->Vibratowizard1) { st=HS->Partials[0][0].t-SpecOffst; en=HS->Partials[0][HS->Fr-1].t+SpecOffst; } if (st<0) st=0; if (en>WaveView1->Length) en=WaveView1->Length; VF->WaveAudio1->WriteSamples(&WaveView1->Data16[ch][st], en-st); VF->StartPos=st; { delete VF->HS; VF->HS=new THS(HS, st, en); } VF->StartPos=st; VF->Copydata(); VF->Synthesize(); VF->Reset(); VF->Show(); } //--------------------------------------------------------------------------- void __fastcall TForm1::Recent11Click(TObject *Sender) { TIniFile* Ini=new TIniFile(ChangeFileExt(Application->ExeName, ".ini")); AnsiString S="RecentFile"; S=S+(((TMenuItem*)Sender)->Tag+1); AnsiString FileName=Ini->ReadString(S, "FileName", ""); int start=Ini->ReadInteger(S, "Start", 0); int end=Ini->ReadInteger(S, "End", -1); double fstart=Ini->ReadFloat(S, "StartF", 0); double fend=Ini->ReadFloat(S, "EndF", 0.5); delete Ini; if (FileExists(FileName) && WaveAudio1->FileName!=FileName) { RecentFile(WaveAudio1->FileName); WaveAudio1->LoadFromFile(FileName); WaveView1->SetArea(start, end, fstart, fend); } } //--------------------------------------------------------------------------- void __fastcall TForm1::SpeedButtonRecordClick(TObject *Sender) { if (WaveAudio2 && WaveAudio2->Recording) { WaveAudio2->PauseRecording(0); double second=1.0*WaveAudio2->WaveStream->Position/(WaveAudio2->SamplesPerSec*WaveAudio2->BitsPerSample/8*WaveAudio2->Channels); int secr=(second-floor(second))*100; TDateTime dt=second/86400; RecordingForm->Label1->Caption=dt.FormatString("'Recording finished:' h:mm:ss.")+AnsiString().sprintf("%02d", secr); WaveAudio2->CloseFile(true); SpeedButtonRecord->Glyph=BitmapRecord; RecordingForm->SpeedButtonRecord->Glyph=BitmapRecord; delete WaveAudio2; WaveAudio2=0; RecordingForm->SpeedButton1->Enabled=true; RecordingForm->SpeedButton2->Enabled=true; RecordingForm->Show(); } else { WaveAudio2=new TWaveAudio(NULL); WaveAudio2->GetWaveProperties(WaveAudio1); WaveAudio2->CreateFile(ExtractFilePath(Application->ExeName)+"noname.wav"); WaveAudio2->OnInAddBuffer=WaveAudio2InAddBuffer; WaveAudio2->StartRecording(0); SpeedButtonRecord->Glyph=BitmapRecording; RecordingForm->SpeedButtonRecord->Glyph=BitmapRecording; RecordingForm->Label1->Caption="Recording in progress: 0:00:00.00"; RecordingForm->SpeedButton1->Enabled=false; RecordingForm->SpeedButton2->Enabled=false; RecordingForm->Show(); } } //--------------------------------------------------------------------------- void __fastcall TForm1::WaveAudio2InAddBuffer(TObject*) { double second=1.0*WaveAudio2->WaveStream->Position/(WaveAudio2->SamplesPerSec*WaveAudio2->BitsPerSample/8*WaveAudio2->Channels); int secr=(second-floor(second))*100; TDateTime dt=second/86400; RecordingForm->Label1->Caption=dt.FormatString("'Recording in progress:' h:mm:ss.")+AnsiString().sprintf("%02d", secr); } //--------------------------------------------------------------------------- void __fastcall TForm1::Close1Click(TObject *Sender) { RecentFile(WaveAudio1->FileName); WaveAudio1->Clear(this); Navigator1->Resize(); } //--------------------------------------------------------------------------- void __fastcall TForm1::AutoScrollCheckClick(TObject *Sender) { WaveView1->AutoScroll=AutoScrollCheck->Checked; } //--------------------------------------------------------------------------- void __fastcall TForm1::WaveView1PlaybackStartAndEndPos(TObject* Sender, int& st, int& en, bool fromsel) { TWaveView* WV=(TWaveView*)Sender; if (fromsel) { st=WV->Selections->StartPos; if (st<0) st=0; en=WV->Selections->EndPos; if (en>WV->Length) en=WV->Length; } else { st=WV->StartPos; if (PlayUntilRadio->ItemIndex==0) en=WV->Length; else if (PlayUntilRadio->ItemIndex==1) en=WV->EndPos; } } //--------------------------------------------------------------------------- void __fastcall TForm1::LoopCheckClick(TObject *Sender) { if (LoopCheck->Checked) { WaveView1->LoopPlay=true; } else { WaveView1->LoopPlay=false; PlayUntilRadioClick(Sender); } } //--------------------------------------------------------------------------- void __fastcall TForm1::PlayUntilRadioClick(TObject *Sender) { if (PlayUntilRadio->ItemIndex==0) WaveView1->SectionEndPos=WaveView1->Length; else if (WaveView1->LoopMode==2) WaveView1->SectionEndPos=WaveView1->Selections->EndPos; else WaveView1->SectionEndPos=WaveView1->EndPos; } //--------------------------------------------------------------------------- void __fastcall TForm1::MouseWheelZoomClick(TObject *Sender) { WaveView1->DisableMouseWheelZoom=!MouseWheelZoom->Checked; } //--------------------------------------------------------------------------- void __fastcall TForm1::AmpGridDblClick(TObject *Sender) { if (GridSourcePane<0 || GridSourcePane>=WaveView1->FPanes.Count || !WaveView1->FPanes.HasFreqAxis[GridSourcePane]) return; TPoint P; GetCursorPos(&P); TStringGrid* Grid=(TStringGrid*)Sender; P=Grid->ScreenToClient(P); int col, row; Grid->MouseToCell(P.x, P.y, col, row); if (col<0 || row<0) return; if (Grid->Cells[col][row].IsEmpty()) return; int CurrentFr=Grid->Cells[col][0].ToInt(), CurrentBin=Grid->Cells[0][row].ToInt(); int t=WaveView1->SpecRes/2+WaveView1->SpecOffst*CurrentFr; double f=(CurrentBin+0.5)/WaveView1->SpecRes; WaveView1->SetCursorTF(GridSourcePane, t, f); } //--------------------------------------------------------------------------- void __fastcall TForm1::Sourcefilter1Click(TObject *Sender) { TSFDemoForm* VF=SFDemoForm; VF->WaveView1->StartDigiFreq=WaveView1->StartDigiFreq; VF->WaveView2->StartDigiFreq=WaveView1->StartDigiFreq; VF->WaveView1->EndDigiFreq=WaveView1->EndDigiFreq; VF->WaveView2->EndDigiFreq=WaveView1->EndDigiFreq; VF->WaveView2->SpecAmp=WaveView1->SpecAmp; int SpecRes, SpecOffst; if (Sender==EventBox->Vibratowizard1) { SpecRes=HS->Partials[0][0].s; SpecOffst=HS->Partials[0][1].t-HS->Partials[0][0].t; } else { SpecRes=WaveView1->SpecRes; SpecOffst=WaveView1->SpecOffst; } VF->WaveView1->SpecRes=SpecRes; VF->WaveView1->SpecOffst=SpecOffst; VF->WaveAudio1->Clear(NULL); VF->WaveAudio1->SamplesPerSec=WaveAudio1->SamplesPerSec; VF->WaveAudio1->BitsPerSample=WaveAudio1->BitsPerSample; int ch=WaveView1->FPanes.Channel[WaveView1->StartPane]; if (Sender==EventBox->Vibratowizard1) ch=HS->Channel; int st=(WaveView1->StartPos-SpecRes/2)/SpecOffst*SpecOffst; int en=(WaveView1->EndPos-SpecRes/2)/SpecOffst*SpecOffst+SpecRes; if (Sender==EventBox->Vibratowizard1) { st=HS->Partials[0][0].t-SpecOffst; en=HS->Partials[0][HS->Fr-1].t+SpecOffst; } if (st<0) st=0; if (en>WaveView1->Length) en=WaveView1->Length; VF->WaveAudio1->WriteSamples(&WaveView1->Data8[ch][st*WaveAudio1->BitsPerSample/8], en-st); VF->StartPos=st; { delete VF->HS; VF->HS=new THS(HS, st, en); } VF->StartPos=st; VF->Copydata(); VF->Synthesize(); VF->Reset(); VF->Show(); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- void __fastcall TForm1::PlayFilterComboSelect(TObject *Sender) { WaveView1->PlaybackFilter=(TWaveViewPlaybackFilter)PlayFilterCombo->ItemIndex; PlaybackFilterRadio->ItemIndex=PlayFilterCombo->ItemIndex; } //--------------------------------------------------------------------------- void __fastcall TForm1::PlaybackFilterRadioClick(TObject *Sender) { PlayFilterCombo->ItemIndex=PlaybackFilterRadio->ItemIndex; } //--------------------------------------------------------------------------- void __fastcall TForm1::Retrieve1Click(TObject *Sender) { WaveView1->Retrieve(1); } //---------------------------------------------------------------------------