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