xue@0
|
1 /*
|
xue@0
|
2 Harmonic Visualiser
|
xue@0
|
3
|
xue@0
|
4 An audio file viewer and editor.
|
xue@0
|
5 Centre for Digital Music, Queen Mary, University of London.
|
xue@0
|
6 This file copyright 2011 Wen Xue.
|
xue@0
|
7
|
xue@0
|
8 This program is free software; you can redistribute it and/or
|
xue@0
|
9 modify it under the terms of the GNU General Public License as
|
xue@0
|
10 published by the Free Software Foundation; either version 2 of the
|
xue@0
|
11 License, or (at your option) any later version.
|
xue@0
|
12 */
|
xue@0
|
13 //---------------------------------------------------------------------------
|
xue@0
|
14
|
xue@0
|
15 #pragma hdrstop
|
xue@0
|
16
|
xue@0
|
17 #include <vcl.h>
|
xue@0
|
18 #include <inifiles.hpp>
|
xue@0
|
19 #include "Unit1.h"
|
xue@0
|
20 #include "BackUpTool.h"
|
xue@0
|
21 #include <math.h>
|
xue@0
|
22 #include <Math.hpp>
|
xue@0
|
23 #include "UnitRangeEdit.h"
|
xue@0
|
24 #include "EditorPanelUnit.h"
|
xue@0
|
25 #include "VibratoDemoUnit.h"
|
xue@0
|
26 #include "RecordingUnit.h"
|
xue@0
|
27 #include "opt.h"
|
xue@0
|
28 #include "Matrix.h"
|
xue@0
|
29 #include "SFDemoUnit.h"
|
xue@0
|
30 #include "SinEst.h"
|
xue@0
|
31 #include "splines.h"
|
xue@0
|
32 #include "SinSyn.h"
|
xue@0
|
33 #include "hsedit.h"
|
xue@0
|
34 //---------------------------------------------------------------------------
|
xue@0
|
35 #pragma package(smart_init)
|
xue@0
|
36 #pragma resource "*.dfm"
|
xue@0
|
37 TForm1 *Form1;
|
xue@0
|
38 extern timestamp1;
|
xue@0
|
39 //---------------------------------------------------------------------------
|
xue@0
|
40 char ReturnKey=VK_RETURN;
|
xue@0
|
41 int BAR=2;
|
xue@0
|
42 #define ASMALLNEGATIVEVALUE -1.1e-24
|
xue@0
|
43
|
xue@0
|
44 __fastcall TForm1::TForm1(TComponent* Owner)
|
xue@0
|
45 : TForm(Owner)
|
xue@0
|
46 {
|
xue@0
|
47 Application->HintPause=0.1;
|
xue@0
|
48
|
xue@0
|
49 WaveAudio1=new TWaveAudio(NULL);
|
xue@0
|
50 WaveAudio1->AutoUseMemoryStream=true;
|
xue@0
|
51 WaveAudio1->OnLoad=WaveAudio1Load;
|
xue@0
|
52 WaveView1=new TWaveView(NULL, true, false);
|
xue@0
|
53 WaveView1->Parent=PanelWaveView;
|
xue@0
|
54 WaveView1->Align=alClient;
|
xue@0
|
55 WaveView1->ScrollBar=ScrollBar1;
|
xue@0
|
56 WaveView1->WaveAudio=WaveAudio1;
|
xue@0
|
57 WaveView1->ClickFocus=true;
|
xue@0
|
58 WaveView1->WaveBackColor=clWhite;
|
xue@0
|
59 WaveView1->WaveColor=clBlack;
|
xue@0
|
60 WaveView1->AxisColor=clGray;
|
xue@0
|
61 WaveView1->CustomInfo=WaveView1CustomInfo;
|
xue@0
|
62 WaveView1->CustomPaneInfo=WaveView1CustomPaneInfo;
|
xue@0
|
63 WaveView1->OnGetOpMode=WaveView1OpMode;
|
xue@0
|
64 WaveView1->OnGetPlaybackStartAndEndPos=WaveView1PlaybackStartAndEndPos;
|
xue@0
|
65 WaveView1->OnInfoDblClick=WaveView1InfoDblClick;
|
xue@0
|
66 WaveView1->OnPaint=WaveView1AfterPaint;
|
xue@0
|
67 WaveView1->OnPlaybackStart=WaveView1PlaybackStart;
|
xue@0
|
68 WaveView1->OnPlaybackDone=WaveView1PlaybackDone;
|
xue@0
|
69 WaveView1->OnKeyPress=WaveView1KeyPress;
|
xue@0
|
70 WaveView1->OnMouseDown=WaveView1MouseDown;
|
xue@0
|
71 WaveView1->OnMouseMove=WaveView1MouseMove;
|
xue@0
|
72 WaveView1->OnMousePointer=WaveView1MousePointer;
|
xue@0
|
73 WaveView1->OnMouseUp=WaveView1MouseUp;
|
xue@0
|
74 WaveView1->OnMouseWheel=WaveView1MouseWheel;
|
xue@0
|
75 WaveView1->SelectedFrameColorX=clGreen;
|
xue@0
|
76 WaveView1->SelectedAreaColorX=clGreen;
|
xue@0
|
77 WaveView1->BeforePlayback=WaveView1BeforePlayback;
|
xue@0
|
78 WaveView1->Hint=""; WaveView1->ShowHint=true;
|
xue@0
|
79 WaveView1->DefaultPopupMenu=false; WaveView1->PopupMenu=WaveView1PopupMenu;
|
xue@0
|
80 WaveView1->Tools<<wvtPlayNote;
|
xue@0
|
81 WaveView1->PlayNoteInSemitone=true;
|
xue@0
|
82
|
xue@0
|
83 WaveAudio2=0;
|
xue@0
|
84
|
xue@0
|
85 TWaveViewObject Obj; memset(&Obj, 0, sizeof(TWaveViewObject));
|
xue@0
|
86 Obj.DrawObject=WaveView1DrawObject; Obj.OnClick=WaveView1ObjectClick;
|
xue@0
|
87 for (int i=0; i<6; i++){Obj.Id=i; WaveView1->FObjects.Add(Obj);}
|
xue@0
|
88 WaveView1->FObjects.Items[5].OnClick=0; WaveView1->FObjects.Items[5].OnDblClick=WaveView1ObjectDblClick;
|
xue@0
|
89 WaveView1->FObjects.Items[5].OnMouseWheel=WaveView1ObjectMouseWheel;
|
xue@0
|
90
|
xue@0
|
91 Navigator1=new TNavigator(NULL);
|
xue@0
|
92 Navigator1->Parent=PanelNavigator;
|
xue@0
|
93 Navigator1->Align=alClient;
|
xue@0
|
94 Navigator1->AreaColorX=clYellow;
|
xue@0
|
95 Navigator1->OnAreaChange=Navigator1AreaChange;
|
xue@0
|
96 Navigator1->OnBackground=Navigator1Background;
|
xue@0
|
97 NavButton=new TSpeedButton(this); NavButton->Parent=Navigator1; NavButton->Left=0; NavButton->Top=0; NavButton->Width=24; NavButton->Height=16;
|
xue@0
|
98 NavButton->Transparent=true; NavButton->Font->Name="Ariel"; NavButton->Font->Height=12; NavButton->Font->Color=clBlack; NavButton->Caption="W/S";
|
xue@0
|
99 NavButton->Flat=true; NavButton->OnClick=NavButtonClick;
|
xue@0
|
100
|
xue@0
|
101 Initialize();
|
xue@0
|
102 SetWaveViewContents();
|
xue@0
|
103
|
xue@0
|
104 BitmapPlay=new Graphics::TBitmap; BitmapPlay->LoadFromResourceID((int)HInstance, 100);
|
xue@0
|
105 BitmapStop=new Graphics::TBitmap; BitmapStop->LoadFromResourceID((int)HInstance, 101);
|
xue@0
|
106 SpeedButtonPlay->Glyph=BitmapPlay;
|
xue@0
|
107 BitmapSpectrogram=new Graphics::TBitmap; BitmapSpectrogram->LoadFromResourceID((int)HInstance, 102);
|
xue@0
|
108 BitmapWaveform=new Graphics::TBitmap; BitmapWaveform->LoadFromResourceID((int)HInstance, 103);
|
xue@0
|
109 SpeedButtonS->Glyph=BitmapSpectrogram;
|
xue@0
|
110 BitmapRecord=new Graphics::TBitmap; BitmapRecord->LoadFromResourceID((int)HInstance, 104);
|
xue@0
|
111 BitmapRecording=new Graphics::TBitmap; BitmapRecording->LoadFromResourceID((int)HInstance, 105);
|
xue@0
|
112 SpeedButtonRecord->Glyph=BitmapRecord;
|
xue@0
|
113 BitmapTimeSelect=new Graphics::TBitmap; BitmapTimeSelect->LoadFromResourceID((int)HInstance, 106);
|
xue@0
|
114 SpeedButtonT->Glyph=BitmapTimeSelect;
|
xue@0
|
115 BitmapFreqSelect=new Graphics::TBitmap; BitmapFreqSelect->LoadFromResourceID((int)HInstance, 107);
|
xue@0
|
116 SpeedButtonF->Glyph=BitmapFreqSelect;
|
xue@0
|
117 BitmapMultiSelect=new Graphics::TBitmap; BitmapMultiSelect->LoadFromResourceID((int)HInstance, 108);
|
xue@0
|
118 SpeedButtonM->Glyph=BitmapMultiSelect;
|
xue@0
|
119 BitmapHSSelect=new Graphics::TBitmap; BitmapHSSelect->LoadFromResourceID((int)HInstance, 109);
|
xue@0
|
120 SpeedButtonSelect->Glyph=BitmapHSSelect;
|
xue@0
|
121 BitmapCursorText=new Graphics::TBitmap; BitmapCursorText->LoadFromResourceID((int)HInstance, 110);
|
xue@0
|
122 SpeedButtonCursorText->Glyph=BitmapCursorText;
|
xue@0
|
123 BitmapPaneInfo=new Graphics::TBitmap; BitmapPaneInfo->LoadFromResourceID((int)HInstance, 111);
|
xue@0
|
124 SpeedButtonPaneInfo->Glyph=BitmapPaneInfo;
|
xue@0
|
125
|
xue@0
|
126 SpectrogramView=false;
|
xue@0
|
127 HS=0;
|
xue@0
|
128 PartialSelectCombo->ItemIndex=0;
|
xue@0
|
129 ancps=0;
|
xue@0
|
130 ancfrs=0;
|
xue@0
|
131 ancfs=0;
|
xue@0
|
132 ancts=0;
|
xue@0
|
133 onset.f0s=0;
|
xue@0
|
134 onset.pitches=0;
|
xue@0
|
135 onset.xfr=0;
|
xue@0
|
136
|
xue@0
|
137 Application->OnIdle=ApplicationIdle;
|
xue@0
|
138
|
xue@0
|
139 for (int i=0; i<MaxRecents; i++)
|
xue@0
|
140 {
|
xue@0
|
141 int ind=File1->IndexOf(Recent00);
|
xue@0
|
142 TMenuItem* Item=new TMenuItem(this);
|
xue@0
|
143 Item->Tag=i;
|
xue@0
|
144 Item->Caption=i+1;
|
xue@0
|
145 Item->OnClick=Recent11Click;
|
xue@0
|
146 File1->Insert(ind, Item);
|
xue@0
|
147 Recents[i]=Item;
|
xue@0
|
148 }
|
xue@0
|
149
|
xue@0
|
150
|
xue@0
|
151 ExePath=ExtractFilePath(Application->ExeName);
|
xue@0
|
152 TmpInFileName=ExePath+"tvoin";
|
xue@0
|
153 TmpOutFileName=ExePath+"tvoout";
|
xue@0
|
154 IniFileName=ChangeFileExt(Application->ExeName, ".ini");
|
xue@0
|
155
|
xue@0
|
156 RecentFile("");
|
xue@0
|
157
|
xue@0
|
158 }
|
xue@0
|
159
|
xue@0
|
160 __fastcall TForm1::~TForm1()
|
xue@0
|
161 {
|
xue@0
|
162 TIniFile* Ini=0;
|
xue@0
|
163 try{
|
xue@0
|
164 Ini=new TIniFile(ChangeFileExt(Application->ExeName, ".ini"));
|
xue@0
|
165 Ini->WriteString("CurrentFile", "FileName", WaveAudio1->FileName);
|
xue@0
|
166 Ini->WriteInteger("CurrentView", "Start", WaveView1->StartPos);
|
xue@0
|
167 Ini->WriteInteger("CurrentView", "End", WaveView1->EndPos);
|
xue@0
|
168 Ini->WriteFloat("CurrentView", "StartF", WaveView1->StartDigiFreq);
|
xue@0
|
169 Ini->WriteFloat("CurrentView", "EndF", WaveView1->EndDigiFreq);
|
xue@0
|
170 Ini->WriteInteger("CurrentView", "SpecRes", WindowSizeCombo->ItemIndex);
|
xue@0
|
171 Ini->WriteInteger("CurrentView", "WindowType", WindowTypeCombo->ItemIndex);
|
xue@0
|
172 Ini->WriteString("HS", "delp", HSDelpEdit1->Text);
|
xue@0
|
173 Ini->WriteString("HS", "delm", HSDelmEdit1->Text);
|
xue@0
|
174 Ini->WriteInteger("Settings", "MouseWheelZoom", MouseWheelZoom->Checked);
|
xue@0
|
175 Ini->WriteInteger("Settings", "Mixer", false);
|
xue@0
|
176 } catch(...) {}
|
xue@0
|
177 delete Ini;
|
xue@0
|
178
|
xue@0
|
179 delete WaveAudio1;
|
xue@0
|
180 delete WaveView1;
|
xue@0
|
181 delete Navigator1;
|
xue@0
|
182 delete BitmapPlay;
|
xue@0
|
183 delete BitmapStop;
|
xue@0
|
184 delete BitmapSpectrogram;
|
xue@0
|
185 delete BitmapWaveform;
|
xue@0
|
186 delete BitmapRecord;
|
xue@0
|
187 delete BitmapRecording;
|
xue@0
|
188 delete BitmapTimeSelect;
|
xue@0
|
189 delete BitmapFreqSelect;
|
xue@0
|
190 delete BitmapMultiSelect;
|
xue@0
|
191 delete BitmapHSSelect;
|
xue@0
|
192 delete BitmapCursorText;
|
xue@0
|
193 delete BitmapPaneInfo;
|
xue@0
|
194
|
xue@0
|
195 free(ancps);
|
xue@0
|
196 free(ancfrs);
|
xue@0
|
197 free(ancfs);
|
xue@0
|
198 free(ancts);
|
xue@0
|
199 DeAlloc2(onset.f0s);
|
xue@0
|
200 DeAlloc2(onset.pitches);
|
xue@0
|
201 delete[] onset.xfr;
|
xue@0
|
202 }
|
xue@0
|
203 //---------------------------------------------------------------------------
|
xue@0
|
204 void __fastcall TForm1::ApplicationIdle(TObject* Sender, bool& Done)
|
xue@0
|
205 {
|
xue@0
|
206 if (FileExists(TmpInFileName)) VibratoDemoForm->ExternalInput();
|
xue@0
|
207 if (VibratoDemoForm->ForceUpdate) VibratoDemoForm->UpdateDisplay();
|
xue@0
|
208
|
xue@0
|
209 Done=true;
|
xue@0
|
210 }
|
xue@0
|
211
|
xue@0
|
212 //---------------------------------------------------------------------------
|
xue@0
|
213 void __fastcall TForm1::Backup1Click(TObject *Sender)
|
xue@0
|
214 {
|
xue@0
|
215 BackupForm1->ShowModal();
|
xue@0
|
216 }
|
xue@0
|
217 //---------------------------------------------------------------------------
|
xue@0
|
218
|
xue@0
|
219 void __fastcall TForm1::Exit1Click(TObject *Sender)
|
xue@0
|
220 {
|
xue@0
|
221 Close();
|
xue@0
|
222 }
|
xue@0
|
223 //---------------------------------------------------------------------------
|
xue@0
|
224 void __fastcall TForm1::ZoomToSelection1Click(TObject *Sender)
|
xue@0
|
225 {
|
xue@0
|
226 WaveView1->DoExtract(Sender);
|
xue@0
|
227 if (GetKeyState(VK_SHIFT)>=0) WaveView1->RemoveSelection(-1);
|
xue@0
|
228 }
|
xue@0
|
229 //---------------------------------------------------------------------------
|
xue@0
|
230 void TForm1::Initialize()
|
xue@0
|
231 {
|
xue@0
|
232 TIniFile* Ini=new TIniFile(ChangeFileExt(Application->ExeName, ".ini"));
|
xue@0
|
233 AnsiString FileName=Ini->ReadString("CurrentFile", "FileName", "");
|
xue@0
|
234 if (FileExists(FileName))
|
xue@0
|
235 {
|
xue@0
|
236 WaveAudio1->LoadFromFile(FileName);
|
xue@0
|
237 int Start=Ini->ReadInteger("CurrentView", "Start", 0);
|
xue@0
|
238 int End=Ini->ReadInteger("CurrentView", "End", WaveAudio1->Length);
|
xue@0
|
239 double StartDF=Ini->ReadFloat("CurrentView", "StartF", 0);
|
xue@0
|
240 double EndDF=Ini->ReadFloat("CurrentView", "EndF", 0.5);
|
xue@0
|
241 WaveView1->SetArea(Start, End, StartDF, EndDF);
|
xue@0
|
242 WindowTypeCombo->ItemIndex=Ini->ReadInteger("CurrentView", "WindowType", 2); WindowTypeComboChange(NULL);
|
xue@0
|
243 WindowSizeCombo->ItemIndex=Ini->ReadInteger("CurrentView", "SpecRes", 5); WindowSizeComboChange(NULL);
|
xue@0
|
244 HSDelpEdit1->Text=Ini->ReadString("HS", "delp", "1.0");
|
xue@0
|
245 HSDelmEdit1->Text=Ini->ReadString("HS", "delm", "1.0");
|
xue@0
|
246 MouseWheelZoom->Checked=Ini->ReadInteger("Settings", "MouseWheelZoom", true);
|
xue@0
|
247 WaveView1->DisableMouseWheelZoom=!MouseWheelZoom->Checked;
|
xue@0
|
248 }
|
xue@0
|
249 delete Ini;
|
xue@0
|
250 }
|
xue@0
|
251 //---------------------------------------------------------------------------
|
xue@0
|
252 void __fastcall TForm1::LogFreqCheckClick(TObject *Sender)
|
xue@0
|
253 {
|
xue@0
|
254 SetWaveViewContents();
|
xue@0
|
255 }
|
xue@0
|
256 //---------------------------------------------------------------------------
|
xue@0
|
257 void __fastcall TForm1::NavButtonClick(TObject*)
|
xue@0
|
258 {
|
xue@0
|
259 NavButton->Font->Color=(NavButton->Font->Color==clBlack)?clYellow:clBlack;
|
xue@0
|
260 Navigator1->Resize();
|
xue@0
|
261 }
|
xue@0
|
262 //---------------------------------------------------------------------------
|
xue@0
|
263 void __fastcall TForm1::Navigator1AreaChange(TObject*)
|
xue@0
|
264 {
|
xue@0
|
265 WaveView1->SetArea(WaveView1->Length*Navigator1->x1, WaveView1->Length*Navigator1->x2,
|
xue@0
|
266 (1-Navigator1->y2)*0.5, (1-Navigator1->y1)*0.5);
|
xue@0
|
267 }
|
xue@0
|
268 //---------------------------------------------------------------------------
|
xue@0
|
269 void __fastcall TForm1::Navigator1Background(TObject*)
|
xue@0
|
270 {
|
xue@0
|
271 if (WaveAudio1->Length<=0)
|
xue@0
|
272 Navigator1->BkgBmp->Canvas->FillRect(Navigator1->ClientRect);
|
xue@0
|
273 else if (NavButton->Font->Color==clYellow)
|
xue@0
|
274 {
|
xue@0
|
275 TWaveViewSelection Sel={0, WaveView1->Length, 0, 0.5};
|
xue@0
|
276 WaveView1->DrawSpectrogramX(0, Sel, 0, Navigator1->BkgBmp->Canvas, Navigator1->ClientRect, 10, false, false, 1);
|
xue@0
|
277 }
|
xue@0
|
278 else WaveView1->DrawWaveForm(0, Navigator1->BkgBmp->Canvas, Navigator1->ClientRect, 0, WaveView1->Length);
|
xue@0
|
279 }
|
xue@0
|
280 //---------------------------------------------------------------------------
|
xue@0
|
281 void __fastcall TForm1::Open1Click(TObject *Sender)
|
xue@0
|
282 {
|
xue@0
|
283 OpenDialog1->FilterIndex=1;
|
xue@0
|
284 if (OpenDialog1->Execute())
|
xue@0
|
285 {
|
xue@0
|
286 if (WaveAudio1->FileName!=OpenDialog1->FileName) RecentFile(WaveAudio1->FileName);
|
xue@0
|
287 WaveAudio1->LoadFromFile(OpenDialog1->FileName);
|
xue@0
|
288 }
|
xue@0
|
289 }
|
xue@0
|
290
|
xue@0
|
291 //---------------------------------------------------------------------------
|
xue@0
|
292 void __fastcall TForm1::PanelRightButtonMouseUp(TObject *Sender,
|
xue@0
|
293 TMouseButton Button, TShiftState Shift, int X, int Y)
|
xue@0
|
294 {
|
xue@0
|
295 TShape* Shape=(TShape*)Sender;
|
xue@0
|
296 if (Button==mbLeft && X>=0 && Y>=0 && X<Shape->Width && Y<Shape->Height)
|
xue@0
|
297 {
|
xue@0
|
298 TPanel* APanel; TSplitter* ASplitter;
|
xue@0
|
299 if (Shape==PanelRightButton) APanel=PanelRight, ASplitter=Splitter1;
|
xue@0
|
300 else if (Shape==PanelRightButton2) APanel=PanelGrid, ASplitter=Splitter3;
|
xue@0
|
301 ShowPanel(APanel, APanel->Visible);
|
xue@0
|
302 ASplitter->Visible=!ASplitter->Visible;
|
xue@0
|
303 }
|
xue@0
|
304 }
|
xue@0
|
305 //---------------------------------------------------------------------------
|
xue@0
|
306 void __fastcall TForm1::Play1Click(TObject *Sender)
|
xue@0
|
307 {
|
xue@0
|
308 WaveView1->StartPlayback(Sender);
|
xue@0
|
309 }
|
xue@0
|
310 //---------------------------------------------------------------------------
|
xue@0
|
311 void TForm1::PrepareNMSettings(NMSettings* settings)
|
xue@0
|
312 {
|
xue@0
|
313 memset(settings, 0, sizeof(NMSettings));
|
xue@0
|
314 int wid=WaveView1->SpecRes, sps=WaveView1->SamplesPerSec;
|
xue@0
|
315 windowspec(WaveView1->SpecWindowType, wid, &settings->M, settings->c, &settings->iH2);
|
xue@0
|
316 settings->hB=3;
|
xue@0
|
317 settings->maxp=HSMaxpEdit1->Text.ToInt();
|
xue@0
|
318 settings->maxB=HSMaxBEdit1->Text.ToDouble();
|
xue@0
|
319 settings->epf=2.0e-4;
|
xue@0
|
320 settings->epf0=2;
|
xue@0
|
321 settings->delm=HSDelmEdit1->Text.ToDouble();
|
xue@0
|
322 settings->delp=HSDelpEdit1->Text.ToDouble();
|
xue@0
|
323 settings->minf0=HSMinF0Edit1->Text.ToDouble()/sps*wid;
|
xue@0
|
324 settings->maxf0=HSMaxF0Edit1->Text.ToDouble()/sps*wid;
|
xue@0
|
325 settings->pin0=PartialSelectCombo->ItemIndex+1;
|
xue@0
|
326 settings->pcount=0;
|
xue@0
|
327 }
|
xue@0
|
328
|
xue@0
|
329 //---------------------------------------------------------------------------
|
xue@0
|
330 void TForm1::RecentFile(AnsiString FileName)
|
xue@0
|
331 {
|
xue@0
|
332 TIniFile* Ini=0;
|
xue@0
|
333 try{
|
xue@0
|
334 Ini=new TIniFile(IniFileName);
|
xue@0
|
335
|
xue@0
|
336 int newi=0, start[MaxRecents+1], end[MaxRecents+1];
|
xue@0
|
337 double fstart[MaxRecents+1], fend[MaxRecents+1];
|
xue@0
|
338 AnsiString Names[MaxRecents+1];
|
xue@0
|
339 if (FileExists(FileName))
|
xue@0
|
340 {
|
xue@0
|
341 Names[0]=FileName;
|
xue@0
|
342 start[0]=WaveView1->StartPos, end[0]=WaveView1->EndPos;
|
xue@0
|
343 fstart[0]=WaveView1->StartDigiFreq, fend[0]=WaveView1->EndDigiFreq;
|
xue@0
|
344 newi=1;
|
xue@0
|
345 }
|
xue@0
|
346
|
xue@0
|
347 AnsiString S0="RecentFile";
|
xue@0
|
348 for (int i=1; i<=MaxRecents; i++)
|
xue@0
|
349 {
|
xue@0
|
350 AnsiString S=S0+i;
|
xue@0
|
351 if (!Ini->SectionExists(S)) continue;
|
xue@0
|
352 AnsiString LName=Ini->ReadString(S, "FileName", "");
|
xue@0
|
353 if (FileExists(LName) && LName!=FileName)
|
xue@0
|
354 {
|
xue@0
|
355 Names[newi]=LName;
|
xue@0
|
356 start[newi]=Ini->ReadInteger(S, "Start", 0);
|
xue@0
|
357 end[newi]=Ini->ReadInteger(S, "End", -1);
|
xue@0
|
358 fstart[newi]=Ini->ReadFloat(S, "StartF", 0);
|
xue@0
|
359 fend[newi]=Ini->ReadFloat(S, "EndF", 0.5);
|
xue@0
|
360 newi++;
|
xue@0
|
361 }
|
xue@0
|
362 Ini->EraseSection(S);
|
xue@0
|
363 }
|
xue@0
|
364
|
xue@0
|
365 if (newi>MaxRecents) newi=MaxRecents;
|
xue@0
|
366 for (int i=0; i<newi; i++)
|
xue@0
|
367 {
|
xue@0
|
368 AnsiString S="RecentFile"; S=S+(i+1);
|
xue@0
|
369 Ini->WriteString(S, "FileName", Names[i]);
|
xue@0
|
370 Ini->WriteInteger(S, "Start", start[i]);
|
xue@0
|
371 Ini->WriteInteger(S, "End", end[i]);
|
xue@0
|
372 Ini->WriteFloat(S, "StartF", fstart[i]);
|
xue@0
|
373 Ini->WriteFloat(S, "EndF", fend[i]);
|
xue@0
|
374 }
|
xue@0
|
375
|
xue@0
|
376 for (int i=0; i<newi; i++)
|
xue@0
|
377 {
|
xue@0
|
378 Recents[i]->Caption=AnsiString(i+1)+". "+Names[i];
|
xue@0
|
379 Recents[i]->Visible=true;
|
xue@0
|
380 }
|
xue@0
|
381 for (int i=newi; i<MaxRecents; i++) Recents[i]->Visible=false;
|
xue@0
|
382 Recent00->Visible=(newi>0);
|
xue@0
|
383 }catch(...){}
|
xue@0
|
384 delete Ini;
|
xue@0
|
385 }
|
xue@0
|
386
|
xue@0
|
387 //---------------------------------------------------------------------------
|
xue@0
|
388
|
xue@0
|
389 void TForm1::SetGridContents()
|
xue@0
|
390 {
|
xue@0
|
391 if (!PanelGrid->Visible) return;
|
xue@0
|
392 if (WaveView1->CurrentPane<0) return;
|
xue@0
|
393 GridSourcePane=WaveView1->CurrentPane;
|
xue@0
|
394 int Wid=WaveView1->SpecRes, hWid=Wid/2, Offst=WaveView1->SpecOffst;
|
xue@0
|
395 double t=WaveView1->CurrentTime, f=WaveView1->CurrentDigiFreq, amp=sqrt(1.0/Wid), prange=100, i2pi=0.5*prange/M_PI;
|
xue@0
|
396 int Channel=WaveView1->FPanes.Channel[GridSourcePane];
|
xue@0
|
397 if (WaveView1->FPanes.HasFreqAxis[GridSourcePane] && (AmpTab->Visible || ArcTab->Visible))
|
xue@0
|
398 {
|
xue@0
|
399 TStringGrid* Grid;
|
xue@0
|
400 if (AmpTab->Visible) Grid=AmpGrid;
|
xue@0
|
401 else if (ArcTab->Visible) Grid=PhaseGrid;
|
xue@0
|
402 Grid->RowCount=Grid->Height/(Grid->DefaultRowHeight+1);
|
xue@0
|
403 Grid->ColCount=Grid->Width/(Grid->DefaultColWidth+1);
|
xue@0
|
404 int maxfr=(WaveView1->Length-Wid)/Offst+1;
|
xue@0
|
405 if (Grid->ColCount>maxfr+1) Grid->ColCount=maxfr+1;
|
xue@0
|
406 if (Grid->RowCount>hWid+1) Grid->ColCount=hWid+1;
|
xue@0
|
407
|
xue@0
|
408 int CurrentBin=floor(f*Wid+0.5), CurrentFr=floor((t-hWid)*1.0/Offst+0.5);
|
xue@0
|
409 if (CurrentFr<0) CurrentFr=0; else if (CurrentFr>maxfr-1) CurrentFr=maxfr-1;
|
xue@0
|
410 if (CurrentBin<0) CurrentBin=0; if (CurrentBin>hWid-1) CurrentBin=hWid-1;
|
xue@0
|
411 int frst=CurrentFr-Grid->ColCount/2; if (frst<0) frst=0;
|
xue@0
|
412 int fren=frst+Grid->ColCount-1; if (fren>maxfr) fren=maxfr, frst=maxfr-Grid->ColCount+1;
|
xue@0
|
413 int binst=CurrentBin-Grid->RowCount/2; if (binst<0) binst=0;
|
xue@0
|
414 int binen=binst+Grid->RowCount-1; if (binen>hWid) binen=hWid, binst=hWid-Grid->RowCount+1;
|
xue@0
|
415
|
xue@0
|
416 char format[128];
|
xue@0
|
417 memcpy(format, FormatEdit->Text.c_str(), FormatEdit->Text.Length()+1);
|
xue@0
|
418
|
xue@0
|
419 double *dw=0, *tw=0;
|
xue@0
|
420 cdouble *W, *X=0;
|
xue@0
|
421
|
xue@0
|
422 for (int fr=frst; fr<fren; fr++)
|
xue@0
|
423 {
|
xue@0
|
424 if (AmpTab->Visible)
|
xue@0
|
425 {
|
xue@0
|
426 QSPEC_FORMAT* data=WaveView1->A[Channel][fr];
|
xue@0
|
427 for (int bin=binst; bin<binen; bin++)
|
xue@0
|
428 Grid->Cells[fr-frst+1][binen-bin]=AnsiString().sprintf(format, data[bin]*amp);
|
xue@0
|
429 }
|
xue@0
|
430 else if (ArcTab->Visible)
|
xue@0
|
431 {
|
xue@0
|
432 cmplx<QSPEC_FORMAT>* data=WaveView1->Spec[Channel][fr];
|
xue@0
|
433 for (int bin=binst; bin<binen; bin++)
|
xue@0
|
434 {
|
xue@0
|
435 double pvalue=arg(data[bin])*i2pi;
|
xue@0
|
436 if (bin%2) pvalue+=prange/2;
|
xue@0
|
437 if (pvalue>prange/2) pvalue-=prange;
|
xue@0
|
438 Grid->Cells[fr-frst+1][binen-bin]=AnsiString().sprintf(format, pvalue);
|
xue@0
|
439 }
|
xue@0
|
440 }
|
xue@0
|
441
|
xue@0
|
442 Grid->Cells[fr-frst+1][0]=fr;
|
xue@0
|
443 for (int bin=binst; bin<binen; bin++) Grid->Cells[0][binen-bin]=bin;
|
xue@0
|
444 }
|
xue@0
|
445
|
xue@0
|
446 Grid->Row=binen-CurrentBin;
|
xue@0
|
447 Grid->Col=CurrentFr-frst+1;
|
xue@0
|
448
|
xue@0
|
449 delete[] dw;
|
xue@0
|
450 delete[] tw;
|
xue@0
|
451 delete[] X;
|
xue@0
|
452 }
|
xue@0
|
453 else if (WaveView1->FPanes.HasFreqAxis[GridSourcePane] && QPkTab->Visible)
|
xue@0
|
454 {
|
xue@0
|
455 TStringGrid* Grid=QPkGrid;
|
xue@0
|
456 Grid->RowCount=Grid->Height/(Grid->DefaultRowHeight+1);
|
xue@0
|
457 int maxfr=(WaveView1->Length-Wid)/Offst+1;
|
xue@0
|
458 if (Grid->RowCount>hWid+1) Grid->ColCount=hWid+1;
|
xue@0
|
459 TStringList* List=new TStringList;
|
xue@0
|
460 for (int c=0; c<Grid->ColCount; c++)
|
xue@0
|
461 for (int r=0; r<Grid->RowCount; r++) Grid->Cells[c][r]="";
|
xue@0
|
462 delete List;
|
xue@0
|
463
|
xue@0
|
464 int CurrentBin=floor(f*Wid+0.5), CurrentFr=floor((t-hWid)*1.0/Offst+0.5);
|
xue@0
|
465 if (CurrentFr<0) CurrentFr=0; else if (CurrentFr>maxfr-1) CurrentFr=maxfr-1;
|
xue@0
|
466 if (CurrentBin<0) CurrentBin=0; if (CurrentBin>hWid-1) CurrentBin=hWid-1;
|
xue@0
|
467 int binst=CurrentBin-Grid->RowCount/2; if (binst<0) binst=0;
|
xue@0
|
468 int binen=binst+Grid->RowCount-1; if (binen>hWid) binen=hWid, binst=hWid-Grid->RowCount+1;
|
xue@0
|
469
|
xue@0
|
470
|
xue@0
|
471 int frst=CurrentFr-Grid->ColCount/2; if (frst<0) frst=0;
|
xue@0
|
472 int fren=frst+Grid->ColCount-1; if (fren>maxfr) fren=maxfr, frst=maxfr-Grid->ColCount+1;
|
xue@0
|
473
|
xue@0
|
474 char format[128];
|
xue@0
|
475 memcpy(format, FormatEdit->Text.c_str(), FormatEdit->Text.Length()+1);
|
xue@0
|
476
|
xue@0
|
477 Grid->Cells[0][0]=AnsiString().sprintf("fr.%d", CurrentFr);
|
xue@0
|
478 for (int bin=binst; bin<binen; bin++) Grid->Cells[0][binen-bin]=bin;
|
xue@0
|
479 Grid->Cells[1][0]="f"; Grid->Cells[2][0]="a";
|
xue@0
|
480
|
xue@0
|
481 double *f=new double[(binen-binst)*3], *a=&f[binen-binst];
|
xue@0
|
482 cmplx<QSPEC_FORMAT>* spec=WaveView1->Spec[Channel][CurrentFr];
|
xue@0
|
483 cdouble *x=new cdouble[Wid/2+1]; memset(x, 0, sizeof(cdouble)*(Wid/2+1));
|
xue@0
|
484 int bnst=binst-2, bnen=binen+2; if (bnst<0) bnst=0; if (bnen>Wid/2) bnen=Wid/2;
|
xue@0
|
485 for (int i=bnst; i<bnen; i++) x[i]=spec[i];
|
xue@0
|
486 int M; double c[6], iH2;
|
xue@0
|
487 windowspec(WaveView1->SpecWindowType, Wid, &M, c, &iH2);
|
xue@0
|
488 int p=QuickPeaks(f, a, Wid, x, M, c, iH2, 0.0005, binst, binen);
|
xue@0
|
489
|
xue@0
|
490 MList* mlist=0;
|
xue@0
|
491 int M_, I, p0, q0, *p0s;
|
xue@0
|
492 double **h, *s;
|
xue@0
|
493 cdouble **u, **du;
|
xue@0
|
494 if (p>0)
|
xue@0
|
495 {
|
xue@0
|
496 mlist=new MList;
|
xue@0
|
497 s=new double[Wid]; mlist->Add(s, 1);
|
xue@0
|
498 __int16* data=&WaveView1->Data16[Channel][Offst*CurrentFr];
|
xue@0
|
499 for (int n=0; n<Wid; n++) s[n]=data[n];
|
xue@0
|
500 }
|
xue@0
|
501
|
xue@0
|
502
|
xue@0
|
503 for (int ip=0; ip<p; ip++)
|
xue@0
|
504 {
|
xue@0
|
505 int bin=floor(f[ip]+0.5);
|
xue@0
|
506 Grid->Cells[1][binen-bin]=AnsiString().sprintf(format, f[ip]);
|
xue@0
|
507 Grid->Cells[2][binen-bin]=AnsiString().sprintf(format, a[ip]);
|
xue@0
|
508 }
|
xue@0
|
509
|
xue@0
|
510 delete mlist;
|
xue@0
|
511
|
xue@0
|
512 delete[] x;
|
xue@0
|
513 delete[] f;
|
xue@0
|
514
|
xue@0
|
515 Grid->Row=binen-CurrentBin;
|
xue@0
|
516 }
|
xue@0
|
517 }
|
xue@0
|
518 //---------------------------------------------------------------------------
|
xue@0
|
519 void TForm1::SetWaveViewContents()
|
xue@0
|
520 {
|
xue@0
|
521 int rulers=(WaveView1->FPanes.Count>0)?WaveView1->FPanes.Rulers[0]:7;
|
xue@0
|
522 if (WaveView1->ShowInfo) WaveView1->FPanes.MarginOut=TRect(5, WaveView1->DefaultInfoFont->Height, 5, WaveView1->DefaultInfoFont->Height);
|
xue@0
|
523 else WaveView1->FPanes.MarginOut=TRect(5, 5, 5, WaveView1->DefaultInfoFont->Height);
|
xue@0
|
524 if (WaveView1->Channels>=2 && DisplayChannelRadio->ItemIndex==0)
|
xue@0
|
525 {
|
xue@0
|
526 int Columns=PanesRadio->ItemIndex+1;
|
xue@0
|
527 WaveView1->CreatePanes(Columns, 2);
|
xue@0
|
528 int type=SpectrogramView?(FreqLineCheck->Checked?2:1):0;
|
xue@0
|
529 WaveView1->SetContent(0, 0, 0, type);
|
xue@0
|
530 WaveView1->SetContent(0, 1, 1, type);
|
xue@0
|
531 if (Columns>1)
|
xue@0
|
532 {
|
xue@0
|
533 type=SpectrogramView?0:(FreqLineCheck->Checked?2:1);
|
xue@0
|
534 WaveView1->SetContent(1, 0, 0, type);
|
xue@0
|
535 WaveView1->SetContent(1, 1, 1, type);
|
xue@0
|
536 }
|
xue@0
|
537 }
|
xue@0
|
538 else
|
xue@0
|
539 {
|
xue@0
|
540 int Rows=PanesRadio->ItemIndex+1;
|
xue@0
|
541 WaveView1->CreatePanes(1, Rows);
|
xue@0
|
542 int type=SpectrogramView?(FreqLineCheck->Checked?2:1):0;
|
xue@0
|
543 int channel=(WaveView1->Channels>=2 && DisplayChannelRadio->ItemIndex==2)?1:0;
|
xue@0
|
544 WaveView1->SetContent(0, 0, channel, type);
|
xue@0
|
545 if (Rows>1)
|
xue@0
|
546 {
|
xue@0
|
547 type=SpectrogramView?0:(FreqLineCheck->Checked?2:1);
|
xue@0
|
548 WaveView1->SetContent(0, 1, channel, type);
|
xue@0
|
549 }
|
xue@0
|
550 }
|
xue@0
|
551
|
xue@0
|
552 int yscale=LogFreqCheck->Checked?1:0;
|
xue@0
|
553 for (int i=0; i<4; i++) WaveView1->SetYScale(i, yscale), WaveView1->SetRulers(i, rulers);
|
xue@0
|
554
|
xue@0
|
555 WaveView1->ShowCursorText=SpeedButtonCursorText->Down;
|
xue@0
|
556 WaveView1->ShowPaneInfo=SpeedButtonPaneInfo->Down;
|
xue@0
|
557 }
|
xue@0
|
558 //---------------------------------------------------------------------------
|
xue@0
|
559 void TForm1::ShowPanel(TPanel* APanel, bool Hide)
|
xue@0
|
560 {
|
xue@0
|
561 APanel->Visible=!Hide;
|
xue@0
|
562 if (APanel==PanelRight) PanelRightButton->Brush->Color=Hide?clTeal:clSilver;
|
xue@0
|
563 else if (APanel==PanelGrid) PanelRightButton2->Brush->Color=Hide?clTeal:clSilver;
|
xue@0
|
564 }
|
xue@0
|
565 //---------------------------------------------------------------------------
|
xue@0
|
566 void __fastcall TForm1::SpectrogramBrightness1Click(TObject *Sender)
|
xue@0
|
567 {
|
xue@0
|
568 WaveView1->SpecAmp=1;
|
xue@0
|
569 }
|
xue@0
|
570 //---------------------------------------------------------------------------
|
xue@0
|
571 //---------------------------------------------------------------------------
|
xue@0
|
572 void __fastcall TForm1::SpeedButtonFClick(TObject *Sender)
|
xue@0
|
573 {
|
xue@0
|
574 if (SpeedButtonF->Down)
|
xue@0
|
575 {
|
xue@0
|
576 WaveView1->SelectMode=WaveView1->SelectMode|WV2_VSELECT;
|
xue@0
|
577 if (GetKeyState(VK_SHIFT)>=0 && SpeedButtonT->Down)
|
xue@0
|
578 {
|
xue@0
|
579 SpeedButtonT->Down=false;
|
xue@0
|
580 WaveView1->SelectMode=WaveView1->SelectMode&(~WV2_HSELECT);
|
xue@0
|
581
|
xue@0
|
582 }
|
xue@0
|
583 }
|
xue@0
|
584 else WaveView1->SelectMode=WaveView1->SelectMode&(~WV2_VSELECT);
|
xue@0
|
585 }
|
xue@0
|
586 //---------------------------------------------------------------------------
|
xue@0
|
587
|
xue@0
|
588 void __fastcall TForm1::SpeedButtonMClick(TObject *Sender)
|
xue@0
|
589 {
|
xue@0
|
590 WaveView1->MultiSelect=(SpeedButtonM->Down);
|
xue@0
|
591 }
|
xue@0
|
592 //---------------------------------------------------------------------------
|
xue@0
|
593 void __fastcall TForm1::SpeedButtonTClick(TObject *Sender)
|
xue@0
|
594 {
|
xue@0
|
595 if (SpeedButtonT->Down)
|
xue@0
|
596 {
|
xue@0
|
597 WaveView1->SelectMode=WaveView1->SelectMode|WV2_HSELECT;
|
xue@0
|
598 if (GetKeyState(VK_SHIFT)>=0 && SpeedButtonF->Down)
|
xue@0
|
599 {
|
xue@0
|
600 SpeedButtonF->Down=false;
|
xue@0
|
601 WaveView1->SelectMode=WaveView1->SelectMode&(~WV2_VSELECT);
|
xue@0
|
602 }
|
xue@0
|
603 }
|
xue@0
|
604 else WaveView1->SelectMode=WaveView1->SelectMode&(~WV2_HSELECT);
|
xue@0
|
605 }
|
xue@0
|
606 //---------------------------------------------------------------------------
|
xue@0
|
607 void __fastcall TForm1::UndoZoom1Click(TObject *Sender)
|
xue@0
|
608 {
|
xue@0
|
609 WaveView1->UndoExtract(Sender);
|
xue@0
|
610 }
|
xue@0
|
611 //---------------------------------------------------------------------------
|
xue@0
|
612 void ClearObjectByShortTag0(TWaveView* WV, int tag0)
|
xue@0
|
613 {
|
xue@0
|
614 if (WV->ObjectAtPointer && WV->ObjectAtPointer->ShortTag[0]==tag0) WV->ObjectAtPointer=0;
|
xue@0
|
615 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;
|
xue@0
|
616 }
|
xue@0
|
617
|
xue@0
|
618 void __fastcall TForm1::WaveAudio1Load(TObject*)
|
xue@0
|
619 {
|
xue@0
|
620 DisplayChannelRadio->Enabled=(WaveAudio1->Channels>1);
|
xue@0
|
621 PlayChannelRadio->Enabled=(WaveAudio1->Channels>1);
|
xue@0
|
622 ClearObjectByShortTag0(WaveView1, stAtom);
|
xue@0
|
623 ClearObjectByShortTag0(WaveView1, stOnset);
|
xue@0
|
624 SetWaveViewContents();
|
xue@0
|
625 Caption="hv - "+WaveAudio1->FileName;
|
xue@0
|
626 if (EventBox) {EventBox->Load(NULL);}
|
xue@0
|
627 Navigator1->SetArea(0, 1, 1-WaveView1->EndDigiFreq*2, 1-WaveView1->StartDigiFreq*2);
|
xue@0
|
628 Navigator1->Resize();
|
xue@0
|
629 }
|
xue@0
|
630 //---------------------------------------------------------------------------
|
xue@0
|
631 void __fastcall TForm1::WaveView1AfterPaint(TObject*)
|
xue@0
|
632 {
|
xue@0
|
633 Navigator1->SetArea(WaveView1->StartPos*1.0/WaveView1->Length, WaveView1->EndPos*1.0/WaveView1->Length, 1-WaveView1->EndDigiFreq*2, 1-WaveView1->StartDigiFreq*2);
|
xue@0
|
634 fcalculatespcount=WaveView1->TimeStamp1;
|
xue@0
|
635 }
|
xue@0
|
636 //---------------------------------------------------------------------------
|
xue@0
|
637 void __fastcall TForm1::WaveView1BeforePlayback(TObject*)
|
xue@0
|
638 {
|
xue@0
|
639 if (WaveView1->Selections->Count)
|
xue@0
|
640 WaveView1->PlaybackFilter=(TWaveViewPlaybackFilter)PlayFilterCombo->ItemIndex;
|
xue@0
|
641 else
|
xue@0
|
642 WaveView1->PlaybackFilter=wvfNone;
|
xue@0
|
643 WaveView1->StereoMode=(TWaveViewStereoMode)PlayChannelRadio->ItemIndex;
|
xue@0
|
644 }
|
xue@0
|
645 //---------------------------------------------------------------------------
|
xue@0
|
646 int __fastcall TForm1::WaveView1CustomInfo(TObject* Sender)
|
xue@0
|
647 {
|
xue@0
|
648 TStringList* List=new TStringList;
|
xue@0
|
649 List->Add(AnsiString().sprintf(" %d-channel, %dhz, %dbit. ", WaveView1->Channels, WaveView1->SamplesPerSec, WaveView1->BytesPerSample*8));
|
xue@0
|
650 if (WaveView1->RulerUnitTime==0)
|
xue@0
|
651 List->Add(AnsiString().sprintf(" Time(%d): from %d to %d. ", WaveView1->EndPos-WaveView1->StartPos, WaveView1->StartPos, WaveView1->EndPos));
|
xue@0
|
652 else
|
xue@0
|
653 {
|
xue@0
|
654 double fs=WaveView1->StartPos*1.0/WaveView1->SamplesPerSec, fe=WaveView1->EndPos*1.0/WaveView1->SamplesPerSec;
|
xue@0
|
655 List->Add(AnsiString().sprintf(" Time(%.4gs): from %.4gs to %.4gs. ", fe-fs, fs, fe));
|
xue@0
|
656 }
|
xue@0
|
657 if (WaveView1->RulerUnitFreq==0)
|
xue@0
|
658 {
|
xue@0
|
659 double fs=WaveView1->StartDigiFreq*WaveView1->SamplesPerSec, fe=WaveView1->EndDigiFreq*WaveView1->SamplesPerSec;
|
xue@0
|
660 AnsiString as=SemitoneToPitch(12*Log2(WV2_LOG_FREQ(fs)/C4)), ae=SemitoneToPitch(12*Log2(WV2_LOG_FREQ(fe)/C4));
|
xue@0
|
661 List->Add(AnsiString().sprintf(" Frequency: from %.1fhz(%s) to %.1fhz(%s). ", fs, as.c_str(), fe, ae.c_str()));
|
xue@0
|
662 }
|
xue@0
|
663 else
|
xue@0
|
664 List->Add(AnsiString().sprintf(" Frequency: from %.4gbin to %.4gbin. ", WaveView1->StartDigiFreq*WaveView1->SpecRes, WaveView1->EndDigiFreq*WaveView1->SpecRes));
|
xue@0
|
665 return (int)List;
|
xue@0
|
666 }
|
xue@0
|
667
|
xue@0
|
668 int __fastcall TForm1::WaveView1CustomPaneInfo(TObject* Sender)
|
xue@0
|
669 {
|
xue@0
|
670 TStringList* List=new TStringList;
|
xue@0
|
671
|
xue@0
|
672 if (WaveView1->Channels>1) List->Add(WaveView1->FPanes.Channel[WaveView1->CurrentPane]==0?"Channel: left":"Channel: right");
|
xue@0
|
673 if (WaveView1->Selections->Count>0 && WaveView1->Selections->Focus>=0)
|
xue@0
|
674 {
|
xue@0
|
675 List->Add("Current Selection");
|
xue@0
|
676 int st=WaveView1->Selections->StartPos, en=WaveView1->Selections->EndPos;
|
xue@0
|
677 List->Add(AnsiString().sprintf("Time(%d): from %d to %d", en-st, st, en));
|
xue@0
|
678 // List->Add(AnsiString().sprintf("Frequency: from %.1fhz to %.1fhz", WaveView1->Selections->StartDigiFreq*WaveView1->SamplesPerSec, WaveView1->Selections->EndDigiFreq*WaveView1->SamplesPerSec));
|
xue@0
|
679 }
|
xue@0
|
680 if (WaveView1->ObjectAtPointer && WaveView1->ObjectAtPointer->ShortTag[0]==stAtom)
|
xue@0
|
681 {
|
xue@0
|
682 atom* part=(atom*)WaveView1->ObjectAtPointer->Buffer;
|
xue@0
|
683 List->Add("Current Atom");
|
xue@0
|
684 List->Add(AnsiString().sprintf("Partial %d", WaveView1->ObjectAtPointer->ShortTag[2]));
|
xue@0
|
685 List->Add(AnsiString().sprintf("Frame %d", WaveView1->ObjectAtPointer->Tag[2]));
|
xue@0
|
686 if (WaveView1->RulerUnitTime==0) List->Add(AnsiString().sprintf("Time %d", int(part->t)));
|
xue@0
|
687 else List->Add(AnsiString().sprintf("Time %.4fs", part->t/WaveView1->SamplesPerSec));
|
xue@0
|
688 if (WaveView1->RulerUnitFreq==0) List->Add(AnsiString().sprintf("Freq %.2fhz", part->f*WaveView1->SamplesPerSec));
|
xue@0
|
689 else List->Add(AnsiString().sprintf("Freq %.2fbin", part->f*WaveView1->SpecRes));
|
xue@0
|
690 List->Add(AnsiString().sprintf("Phase%% %.2f", part->p*50/M_PI));
|
xue@0
|
691 List->Add(AnsiString().sprintf("Amplitude %.4g", part->a));
|
xue@0
|
692 List->Add(AnsiString().sprintf("Scale %d", int(part->s)));
|
xue@0
|
693 }
|
xue@0
|
694
|
xue@0
|
695 return (int)List;
|
xue@0
|
696 }
|
xue@0
|
697 //---------------------------------------------------------------------------
|
xue@0
|
698 void __fastcall TForm1::WaveView1DrawFreqLimiter(TObject* Sender, TWaveViewObject& Obj)
|
xue@0
|
699 {
|
xue@0
|
700 TCanvas* Canv=WaveView1->Canvas; Canv->Pen->Color=clGreen; Canv->Pen->Mode=pmCopy; Canv->Pen->Style=psDot;
|
xue@0
|
701 int X=Obj.Tag[1], Y=WaveView1->FromDigiFreqToPixel(WaveView1->StartPane, f1/WaveView1->SpecRes);
|
xue@0
|
702 Canv->MoveTo(X-10, Y); Canv->LineTo(X+10, Y);
|
xue@0
|
703 Y=WaveView1->FromDigiFreqToPixel(WaveView1->StartPane, f2/WaveView1->SpecRes);
|
xue@0
|
704 Canv->MoveTo(X-10, Y); Canv->LineTo(X+10, Y);
|
xue@0
|
705 Canv->Pen->Style=psSolid;
|
xue@0
|
706 double delm=HSDelmEdit1->Text.ToDouble();
|
xue@0
|
707 Y=WaveView1->FromDigiFreqToPixel(WaveView1->StartPane, (f1-delm)/WaveView1->SpecRes);
|
xue@0
|
708 Canv->MoveTo(X-10, Y); Canv->LineTo(X+10, Y);
|
xue@0
|
709 Y=WaveView1->FromDigiFreqToPixel(WaveView1->StartPane, (f2+delm)/WaveView1->SpecRes);
|
xue@0
|
710 Canv->MoveTo(X-10, Y); Canv->LineTo(X+10, Y);
|
xue@0
|
711 }
|
xue@0
|
712 //---------------------------------------------------------------------------
|
xue@0
|
713 void __fastcall TForm1::WaveView1DrawObject(TObject* Sender, TWaveViewObject& Obj)
|
xue@0
|
714 {
|
xue@0
|
715 TCanvas* Canv=WaveView1->Canvas;
|
xue@0
|
716 int Y=WaveView1->Height;
|
xue@0
|
717
|
xue@0
|
718 if (Obj.Id>=0)
|
xue@0
|
719 {
|
xue@0
|
720 if (WaveView1->ObjectAtPointer==&Obj)
|
xue@0
|
721 {
|
xue@0
|
722 Canv->Brush->Color=clRed; Canv->Brush->Style=bsSolid;
|
xue@0
|
723 Canv->Font=WaveView1->DefaultInfoFont; Canv->Font->Color=clWhite;
|
xue@0
|
724 }
|
xue@0
|
725 else
|
xue@0
|
726 {
|
xue@0
|
727 Canv->Brush->Color=clBlack; Canv->Brush->Style=bsSolid;
|
xue@0
|
728 Canv->Font=WaveView1->DefaultInfoFont; Canv->Font->Color=clWhite;
|
xue@0
|
729 }
|
xue@0
|
730 AnsiString text; int left, top;
|
xue@0
|
731 if (Obj.Id==0)
|
xue@0
|
732 {
|
xue@0
|
733 text=(WaveView1->RulerUnitTime==1)?AnsiString(" [seconds] "):AnsiString(" [samples] ");
|
xue@0
|
734 left=WaveView1->FPanes.MarginOut.left, top=Y-WaveView1->FPanes.MarginOut.bottom;
|
xue@0
|
735 }
|
xue@0
|
736 else if (Obj.Id==1)
|
xue@0
|
737 {
|
xue@0
|
738 if (WaveView1->RulerUnitFreq==1)
|
xue@0
|
739 {
|
xue@0
|
740 if (LogFreqCheck->Checked) text=" [pitch] ";
|
xue@0
|
741 else text= " [bin] ";
|
xue@0
|
742 }
|
xue@0
|
743 else text=" [hz] ";
|
xue@0
|
744 left=WaveView1->FObjects.Items[0].Rect.right, top=WaveView1->FObjects.Items[0].Rect.top;
|
xue@0
|
745 }
|
xue@0
|
746 else if (Obj.Id==2)
|
xue@0
|
747 {
|
xue@0
|
748 text=(WaveView1->RulerUnitAmp==1)?AnsiString(" [abs. amp] "):AnsiString(" [rel. amp] ");
|
xue@0
|
749 left=WaveView1->FObjects.Items[1].Rect.right, top=WaveView1->FObjects.Items[0].Rect.top;
|
xue@0
|
750 }
|
xue@0
|
751 else if (Obj.Id==3)
|
xue@0
|
752 {
|
xue@0
|
753 if (WaveView1->FPanes.Rulers[0] & WV2_HSELECT) text=(WaveView1->RulerAlignX==alTop)?AnsiString(" [X axis: top] "):AnsiString(" [X axis: bottom] ");
|
xue@0
|
754 else text=" [X axis: off] ";
|
xue@0
|
755 left=WaveView1->FObjects.Items[2].Rect.right, top=WaveView1->FObjects.Items[0].Rect.top;
|
xue@0
|
756 }
|
xue@0
|
757 else if (Obj.Id==4)
|
xue@0
|
758 {
|
xue@0
|
759 if (WaveView1->FPanes.Rulers[0] & WV2_VSELECT) text=(WaveView1->RulerAlignY==alLeft)?AnsiString(" [Y axis: left] "):AnsiString(" [Y axis: right] ");
|
xue@0
|
760 else text=" [Y axis: off] ";
|
xue@0
|
761 left=WaveView1->FObjects.Items[3].Rect.right, top=WaveView1->FObjects.Items[0].Rect.top;
|
xue@0
|
762 }
|
xue@0
|
763 else if (Obj.Id==5)
|
xue@0
|
764 {
|
xue@0
|
765 if (WaveView1->AutoSpecAmp) text=AnsiString().sprintf(" [spec. amp (auto): %.3g] ", log(WaveView1->SpecAmp)/log(2.0));
|
xue@0
|
766 else text=AnsiString().sprintf(" [spec. amp: %.3g] ", log(WaveView1->SpecAmp)/log(2.0));
|
xue@0
|
767 left=WaveView1->FObjects.Items[4].Rect.right, top=WaveView1->FObjects.Items[0].Rect.top;
|
xue@0
|
768 }
|
xue@0
|
769 Canv->TextOut(left, top, text);
|
xue@0
|
770 Obj.Rect.left=left, Obj.Rect.top=top, Obj.Rect.right=left+Canv->TextWidth(text), Obj.Rect.bottom=top+Canv->TextHeight(text);
|
xue@0
|
771 }
|
xue@0
|
772 }
|
xue@0
|
773
|
xue@0
|
774 //---------------------------------------------------------------------------
|
xue@0
|
775 void __fastcall TForm1::WaveView1DrawAtom(TObject* Sender, TWaveViewObject& Obj)
|
xue@0
|
776 {
|
xue@0
|
777 int pane=0;
|
xue@0
|
778 while (pane<WaveView1->FPanes.Count && (!WaveView1->FPanes.HasFreqAxis[pane]
|
xue@0
|
779 ||WaveView1->FPanes.Channel[pane]!=Obj.ShortTag[1])) pane++;
|
xue@0
|
780 if (pane>=WaveView1->FPanes.Count)
|
xue@0
|
781 {Obj.Rect.left=0, Obj.Rect.right=-1, Obj.Rect.top=0, Obj.Rect.bottom=-1; return;}
|
xue@0
|
782
|
xue@0
|
783 atom* par=(atom*)Obj.Buffer;
|
xue@0
|
784 if (par->t<WaveView1->StartPos || par->t>=WaveView1->EndPos || par->f<WaveView1->StartDigiFreq || par->f>WaveView1->EndDigiFreq || par->f<=0)
|
xue@0
|
785 {Obj.Rect.left=0, Obj.Rect.right=-1, Obj.Rect.top=0, Obj.Rect.bottom=-1; return;}
|
xue@0
|
786
|
xue@0
|
787 TCanvas* Canv=WaveView1->Canvas;
|
xue@0
|
788 TRect Rect=WaveView1->FPanes.Rect[pane];
|
xue@0
|
789 HRGN Rgn=CreateRectRgn(Rect.left, Rect.top, Rect.right, Rect.bottom);
|
xue@0
|
790 SelectClipRgn(Canv->Handle, Rgn);
|
xue@0
|
791
|
xue@0
|
792 int Wid=WaveView1->SpecRes, HOffst=WaveView1->SpecOffst/2; double df=1.0/Wid;
|
xue@0
|
793 int X=WaveView1->FromSampleToPixel(pane, par->t), X1=WaveView1->FromSampleToPixel(pane, par->t-HOffst), X2=WaveView1->FromSampleToPixel(pane, par->t+HOffst);
|
xue@0
|
794 int Y=WaveView1->FromDigiFreqToPixel(pane, par->f), Y1=WaveView1->FromDigiFreqToPixel(pane, par->f+df), Y2=WaveView1->FromDigiFreqToPixel(pane, par->f-df);
|
xue@0
|
795 if (X1>X-1) X1=X-1; if (X2<X+2) X2=X+2;
|
xue@0
|
796 if (Y1>Y-1) Y1=Y-1; if (Y2<Y+2) Y2=Y+2;
|
xue@0
|
797 Canv->Pen->Mode=pmCopy; Canv->Pen->Style=psSolid;
|
xue@0
|
798 bool shiftdown=(GetKeyState(VK_SHIFT)<0), ctrldown=(GetKeyState(VK_CONTROL)<0), onobj=(WaveView1->ObjectAtPointer && WaveView1->ObjectAtPointer->ShortTag[0]==stAtom);
|
xue@0
|
799 if (!shiftdown && !ctrldown && onobj
|
xue@0
|
800 || !shiftdown && ctrldown && onobj && Obj.ShortTag[2]==WaveView1->ObjectAtPointer->ShortTag[2]
|
xue@0
|
801 || shiftdown && !ctrldown && onobj && Obj.Tag[2]==WaveView1->ObjectAtPointer->Tag[2])
|
xue@0
|
802 {
|
xue@0
|
803 switch (par->type)
|
xue@0
|
804 {
|
xue@0
|
805 case atAnchor: case atPeak: Canv->Pen->Color=clWhite; break;
|
xue@0
|
806 case atInfered: Canv->Pen->Color=clLime; break;
|
xue@0
|
807 case atMuted:
|
xue@0
|
808 case atBuried: Canv->Pen->Color=clRed; break;
|
xue@0
|
809 }
|
xue@0
|
810 }
|
xue@0
|
811 else
|
xue@0
|
812 {
|
xue@0
|
813 switch (par->type)
|
xue@0
|
814 {
|
xue@0
|
815 case atAnchor: case atPeak: Canv->Pen->Color=clGray; break;
|
xue@0
|
816 case atInfered: Canv->Pen->Color=clGreen; break;
|
xue@0
|
817 case atMuted:
|
xue@0
|
818 case atBuried: Canv->Pen->Color=TColor(RGB(128, 0, 0)); break;
|
xue@0
|
819 }
|
xue@0
|
820 }
|
xue@0
|
821 Canv->MoveTo(X-1, Y); Canv->LineTo(X+2, Y); Canv->MoveTo(X, Y-1); Canv->LineTo(X, Y+2);
|
xue@0
|
822 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
|
823 if (WaveView1->ObjectAtPointer==&Obj)
|
xue@0
|
824 {
|
xue@0
|
825 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
|
826 else {Canv->Brush->Style=bsClear; Canv->Rectangle(X1, Y1, X2, Y2);}
|
xue@0
|
827 }
|
xue@0
|
828 Obj.Rect.left=X1, Obj.Rect.right=X2;
|
xue@0
|
829 Obj.Rect.top=(Y1<Y-5)?(Y-5):Y1, Obj.Rect.bottom=(Y2>Y+6)?(Y+6):Y2;
|
xue@0
|
830 SelectClipRgn(Canv->Handle, NULL);
|
xue@0
|
831 DeleteObject(Rgn);
|
xue@0
|
832 }
|
xue@0
|
833
|
xue@0
|
834 //---------------------------------------------------------------------------
|
xue@0
|
835 void __fastcall TForm1::WaveView1InfoDblClick(TObject* Sender)
|
xue@0
|
836 {
|
xue@0
|
837 if (WaveView1->InfoRectAtPointer==1) //time range
|
xue@0
|
838 {
|
xue@0
|
839 bool timeunit=(WaveView1->RulerUnitTime==0);
|
xue@0
|
840 RangeEdit->Caption="Edit time range";
|
xue@0
|
841 if (timeunit){RangeEdit->Edit1->Text=WaveView1->StartPos; RangeEdit->Edit2->Text=WaveView1->EndPos;}
|
xue@0
|
842 else {RangeEdit->Edit1->Text=WaveView1->StartPos*1.0/WaveView1->SamplesPerSec; RangeEdit->Edit2->Text=WaveView1->EndPos*1.0/WaveView1->SamplesPerSec;}
|
xue@0
|
843 if (RangeEdit->ShowModal())
|
xue@0
|
844 {
|
xue@0
|
845 int NewStartPos, NewEndPos;
|
xue@0
|
846 if (timeunit) NewStartPos=RangeEdit->Edit1->Text.ToInt(), NewEndPos=RangeEdit->Edit2->Text.ToInt();
|
xue@0
|
847 else NewStartPos=RangeEdit->Edit1->Text.ToDouble()*WaveView1->SamplesPerSec, NewEndPos=RangeEdit->Edit2->Text.ToDouble()*WaveView1->SamplesPerSec;
|
xue@0
|
848 if (NewStartPos>NewEndPos) {int tmp=NewStartPos; NewStartPos=NewEndPos; NewEndPos=tmp;}
|
xue@0
|
849 if (NewStartPos<0) NewStartPos=0; if (NewEndPos>WaveView1->Length) NewEndPos=WaveView1->Length;
|
xue@0
|
850 WaveView1->SetStartAndEndPos(NewStartPos, NewEndPos);
|
xue@0
|
851 }
|
xue@0
|
852 }
|
xue@0
|
853 else if (WaveView1->InfoRectAtPointer==2)
|
xue@0
|
854 {
|
xue@0
|
855 bool frequnit=(WaveView1->RulerUnitFreq==0);
|
xue@0
|
856 RangeEdit->Caption="Edit frequency range";
|
xue@0
|
857 if (frequnit){RangeEdit->Edit1->Text=WaveView1->StartDigiFreq*WaveView1->SamplesPerSec; RangeEdit->Edit2->Text=WaveView1->EndDigiFreq*WaveView1->SamplesPerSec;}
|
xue@0
|
858 else {RangeEdit->Edit1->Text=WaveView1->StartDigiFreq*WaveView1->SpecRes; RangeEdit->Edit2->Text=WaveView1->EndDigiFreq*WaveView1->SpecRes;}
|
xue@0
|
859 if (RangeEdit->ShowModal())
|
xue@0
|
860 {
|
xue@0
|
861 double NewStartDigiFreq, NewEndDigiFreq;
|
xue@0
|
862 if (frequnit) NewStartDigiFreq=RangeEdit->Edit1->Text.ToDouble()/WaveView1->SamplesPerSec, NewEndDigiFreq=RangeEdit->Edit2->Text.ToDouble()/WaveView1->SamplesPerSec;
|
xue@0
|
863 else NewStartDigiFreq=RangeEdit->Edit1->Text.ToDouble()/WaveView1->SpecRes, NewEndDigiFreq=RangeEdit->Edit2->Text.ToDouble()/WaveView1->SpecRes;
|
xue@0
|
864 if (NewStartDigiFreq>NewEndDigiFreq) {double tmp=NewStartDigiFreq; NewStartDigiFreq=NewEndDigiFreq; NewEndDigiFreq=tmp;}
|
xue@0
|
865 if (NewStartDigiFreq<0) NewStartDigiFreq=0; if (NewEndDigiFreq>0.5) NewEndDigiFreq=0.5;
|
xue@0
|
866 WaveView1->SetStartAndEndDigiFreq(NewStartDigiFreq, NewEndDigiFreq);
|
xue@0
|
867 }
|
xue@0
|
868 }
|
xue@0
|
869 }
|
xue@0
|
870
|
xue@0
|
871 //---------------------------------------------------------------------------
|
xue@0
|
872
|
xue@0
|
873 void __fastcall TForm1::WaveView1KeyPress(TObject* Sender, char &Key)
|
xue@0
|
874 {
|
xue@0
|
875 if (Key=='a')
|
xue@0
|
876 {
|
xue@0
|
877 if (PanelGrid->Visible)
|
xue@0
|
878 {
|
xue@0
|
879 PageControl2->SelectNextPage(true, true);
|
xue@0
|
880 }
|
xue@0
|
881 }
|
xue@0
|
882 else if (Key=='A')
|
xue@0
|
883 {
|
xue@0
|
884 if (PanelGrid->Visible)
|
xue@0
|
885 {
|
xue@0
|
886 PageControl2->SelectNextPage(false, true);
|
xue@0
|
887 }
|
xue@0
|
888 }
|
xue@0
|
889 else if (Key=='E')
|
xue@0
|
890 {
|
xue@0
|
891 if (GetKeyState(VK_SHIFT)<0)
|
xue@0
|
892 {
|
xue@0
|
893 if (EventBox->HSCount<1) return;
|
xue@0
|
894 int idx=-1;
|
xue@0
|
895 double delf;
|
xue@0
|
896 double f=WaveView1->CurrentDigiFreq;
|
xue@0
|
897 int t=WaveView1->CurrentTime, ch=WaveView1->FPanes.Channel[WaveView1->CurrentPane];
|
xue@0
|
898 for (int ev=0; ev<EventBox->HSCount; ev++)
|
xue@0
|
899 {
|
xue@0
|
900 THS* hs=EventBox->HS[ev];
|
xue@0
|
901 if (t<hs->StartPos() || t>hs->EndPos()) continue;
|
xue@0
|
902 int offst=hs->StdOffst();
|
xue@0
|
903 int fr=(t-hs->StartPos())/offst;
|
xue@0
|
904 int m=f/hs->Partials[0][fr].f-1;
|
xue@0
|
905 if (m<0) m=0;
|
xue@0
|
906 if (m>hs->M-1) m=hs->M-1;
|
xue@0
|
907 double ldelf=fabs(f-hs->Partials[m][fr].f);
|
xue@0
|
908 while (m>0 && ldelf>fabs(f-hs->Partials[m-1][fr].f))
|
xue@0
|
909 {
|
xue@0
|
910 ldelf=ldelf>fabs(f-hs->Partials[m-1][fr].f);
|
xue@0
|
911 m--;
|
xue@0
|
912 }
|
xue@0
|
913 while (m<hs->M-1 && ldelf>fabs(f-hs->Partials[m+1][fr].f))
|
xue@0
|
914 {
|
xue@0
|
915 ldelf=fabs(f-hs->Partials[m+1][fr].f);
|
xue@0
|
916 m++;
|
xue@0
|
917 }
|
xue@0
|
918 if (idx==-1 || delf>ldelf)
|
xue@0
|
919 {
|
xue@0
|
920 delf=ldelf;
|
xue@0
|
921 idx=ev;
|
xue@0
|
922 }
|
xue@0
|
923 }
|
xue@0
|
924 if (idx>=0) EventBox->SetItemIndex(idx);
|
xue@0
|
925 }}
|
xue@0
|
926 }
|
xue@0
|
927
|
xue@0
|
928
|
xue@0
|
929 void __fastcall TForm1::AddHSObject(THS* aHS)
|
xue@0
|
930 {
|
xue@0
|
931 for (int m=0; m<aHS->M; m++) for (int fr=0; fr<aHS->Fr; fr++)
|
xue@0
|
932 {
|
xue@0
|
933 if (aHS->Partials[m][fr].f>0)
|
xue@0
|
934 {
|
xue@0
|
935 TWaveViewObject Obj; memset(&Obj, 0, sizeof(TWaveViewObject));
|
xue@0
|
936 Obj.ShortTag[0]=stAtom; Obj.ShortTag[1]=aHS->Channel; Obj.ShortTag[2]=m+1; Obj.ShortTag[3]=0;
|
xue@0
|
937 Obj.Tag[2]=fr;
|
xue@0
|
938 Obj.DrawObject=WaveView1DrawAtom; Obj.Buffer=&aHS->Partials[m][fr]; Obj.OnKeyDown=WaveView1ParKeyDown;
|
xue@0
|
939 Obj.OnMouseDown=WaveView1ParMouseDown; Obj.OnMouseMove=WaveView1ParMouseMove; Obj.OnMouseUp=WaveView1ParMouseUp;
|
xue@0
|
940 Obj.OnMouseWheel=WaveView1ParMouseWheel;
|
xue@0
|
941 WaveView1->FObjects.Add(Obj);
|
xue@0
|
942 }
|
xue@0
|
943 }
|
xue@0
|
944 }
|
xue@0
|
945
|
xue@0
|
946 void __fastcall TForm1::WaveView1MouseDown(TObject* Sender, TMouseButton Button, TShiftState Shift, int X, int Y)
|
xue@0
|
947 {
|
xue@0
|
948 if (WaveView1->OpMode!=wopCrop) WaveView1PopupMenu->AutoPopup=true;
|
xue@0
|
949 else WaveView1PopupMenu->AutoPopup=false;
|
xue@0
|
950 if (WaveView1->Playing && Shift.Contains(ssCtrl) && Button==mbRight) {WaveView1->PBPR=WaveView1->CurrentTime, WaveView1->ForceOLA=true; WaveView1PopupMenu->AutoPopup=false; return;}
|
xue@0
|
951
|
xue@0
|
952 if (WaveView1->OpMode==wopHS && WaveView1->FPanes.HasFreqAxis[WaveView1->CurrentPane] && Shift.Contains(ssLeft))
|
xue@0
|
953 {
|
xue@0
|
954 if (WaveView1->CurrentPane<0) return;
|
xue@0
|
955 if (WaveView1->ObjectAtPointer && WaveView1->ObjectAtPointer->ShortTag[0]==stAtom) PartialSelectCombo->ItemIndex=WaveView1->ObjectAtPointer->ShortTag[2]-1;
|
xue@0
|
956
|
xue@0
|
957 if (Shift.Contains(ssShift) || !(WaveView1->ObjectAtPointer && WaveView1->ObjectAtPointer->ShortTag[0]==stAtom))
|
xue@0
|
958 {
|
xue@0
|
959 double _f=WaveView1->CurrentDigiFreq;
|
xue@0
|
960 int _t=WaveView1->CurrentTime, SpecRes=WaveView1->SpecRes, SpecOffst=WaveView1->SpecOffst;
|
xue@0
|
961
|
xue@0
|
962 int frst=(WaveView1->StartPos-SpecRes/2)/SpecOffst, fren=(WaveView1->EndPos-SpecRes/2)/SpecOffst;
|
xue@0
|
963 if (frst<0) frst=0;
|
xue@0
|
964
|
xue@0
|
965 int M, Fr; atom** Partials;
|
xue@0
|
966 int Channel=WaveView1->FPanes.Channel[WaveView1->CurrentPane];
|
xue@0
|
967 NMSettings settings; PrepareNMSettings(&settings);
|
xue@0
|
968 int tag=FindNote(_t, _f, M, Fr, Partials, frst, fren, SpecRes, SpecOffst, WaveView1->Spectrogram[Channel], settings);
|
xue@0
|
969
|
xue@0
|
970 if (M>0)
|
xue@0
|
971 {
|
xue@0
|
972 if (!HS) HS=EventBox->NewHS(0, 0);
|
xue@0
|
973 else
|
xue@0
|
974 {
|
xue@0
|
975 ClearObjectByShortTag0(WaveView1, stAtom);
|
xue@0
|
976 if (HS->Partials) DeAlloc2(HS->Partials);
|
xue@0
|
977 if (HS->startamp) {DeAlloc2(HS->startamp); HS->st_count=0;}
|
xue@0
|
978 }
|
xue@0
|
979 HS->M=M, HS->Fr=Fr; HS->Partials=Partials;
|
xue@0
|
980 HS->Channel=Channel;
|
xue@0
|
981
|
xue@0
|
982 AddHSObject(HS);
|
xue@0
|
983 if (tag) HS->isconstf=1;
|
xue@0
|
984
|
xue@0
|
985 EventBox->ListBox1->Items->Strings[EventBox->ListBox1->ItemIndex]
|
xue@0
|
986 =((HS->Channel==0)?"left: ":"right: ")
|
xue@0
|
987 +AnsiString().sprintf("%.2fs, ", HS->Partials[0][0].t*1.0/WaveView1->SamplesPerSec)
|
xue@0
|
988 +SemitoneToPitch(Log2(HS->Partials[0][0].f*WaveView1->SamplesPerSec/C4)*12);
|
xue@0
|
989 if (!EventBox->Visible)
|
xue@0
|
990 {
|
xue@0
|
991 EventBox->Left=Left+Width;
|
xue@0
|
992 EventBox->Top=Top;
|
xue@0
|
993 EventBox->Height=Height;
|
xue@0
|
994 EventBox->Show();
|
xue@0
|
995 }
|
xue@0
|
996 }
|
xue@0
|
997 }
|
xue@0
|
998 }
|
xue@0
|
999 }
|
xue@0
|
1000 //---------------------------------------------------------------------------
|
xue@0
|
1001 void __fastcall TForm1::WaveView1MouseMove(TObject* Sender, TShiftState Shift, int X, int Y)
|
xue@0
|
1002 {
|
xue@0
|
1003 if (Shift.Contains(ssRight) && (X!=WaveView1->StartSelX || Y!=WaveView1->StartSelY))
|
xue@0
|
1004 if (WaveView1PopupMenu->AutoPopup) WaveView1PopupMenu->AutoPopup=false;
|
xue@0
|
1005 if (PanelGrid->Visible && (!MBCheck->Checked || Shift.Contains(ssShift))) SetGridContents();
|
xue@0
|
1006 if (Shift.Contains(ssLeft) && WaveView1->OpMode==wopSample)
|
xue@0
|
1007 {
|
xue@0
|
1008 int channel=WaveView1->FPanes.Channel[WaveView1->StartPane],
|
xue@0
|
1009 t=WaveView1->StartSel;
|
xue@0
|
1010 WaveView1->Data16[channel][t]=WaveView1->FromPixelToAmplitude(WaveView1->StartPane, Y);
|
xue@0
|
1011 WaveView1->ExtDataChange(Sender, channel, t, t);
|
xue@0
|
1012 }
|
xue@0
|
1013 }
|
xue@0
|
1014 //---------------------------------------------------------------------------
|
xue@0
|
1015 void __fastcall TForm1::WaveView1MousePointer(TObject* Sender, int Pane, int t, double f)
|
xue@0
|
1016 {
|
xue@0
|
1017 }
|
xue@0
|
1018 //---------------------------------------------------------------------------
|
xue@0
|
1019 void __fastcall TForm1::WaveView1MouseUp(TObject* Sender, TMouseButton Button, TShiftState Shift, int X, int Y)
|
xue@0
|
1020 {
|
xue@0
|
1021 }
|
xue@0
|
1022
|
xue@0
|
1023 //---------------------------------------------------------------------------
|
xue@0
|
1024 void __fastcall TForm1::WaveView1MouseWheel(TObject* Sender, TShiftState Shift, int WheelDelta, const TPoint& MousePos, bool& Handled)
|
xue@0
|
1025 {
|
xue@0
|
1026 if (Shift.Contains(ssRight))
|
xue@0
|
1027 {
|
xue@0
|
1028 if (WaveView1PopupMenu->AutoPopup) WaveView1PopupMenu->AutoPopup=false;
|
xue@0
|
1029 if (WaveView1->OpMode==wopDrag) WaveView1->StartDrag(WaveView1->LastX, WaveView1->LastY); //dragmode=false;
|
xue@0
|
1030 }
|
xue@0
|
1031 }
|
xue@0
|
1032 //---------------------------------------------------------------------------
|
xue@0
|
1033 void __fastcall TForm1::WaveView1ObjectClick(TObject*)
|
xue@0
|
1034 {
|
xue@0
|
1035 if (WaveView1->ObjectAtPointer->Id==0) WaveView1->RulerUnitTime=1-WaveView1->RulerUnitTime;
|
xue@0
|
1036 else if (WaveView1->ObjectAtPointer->Id==1) WaveView1->RulerUnitFreq=1-WaveView1->RulerUnitFreq;
|
xue@0
|
1037 else if (WaveView1->ObjectAtPointer->Id==2) WaveView1->RulerUnitAmp=1-WaveView1->RulerUnitAmp;
|
xue@0
|
1038 else if (WaveView1->ObjectAtPointer->Id==3){
|
xue@0
|
1039 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;}}
|
xue@0
|
1040 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;}}
|
xue@0
|
1041 else if (WaveView1->ObjectAtPointer->Id==4){
|
xue@0
|
1042 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;}}
|
xue@0
|
1043 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;}}
|
xue@0
|
1044 }
|
xue@0
|
1045 //---------------------------------------------------------------------------
|
xue@0
|
1046 void __fastcall TForm1::WaveView1ObjectDblClick(TObject*)
|
xue@0
|
1047 {
|
xue@0
|
1048 if (WaveView1->ObjectAtPointer->Id==5)
|
xue@0
|
1049 {
|
xue@0
|
1050 if (GetKeyState(VK_CONTROL)<0) WaveView1->AutoSpecAmp=!WaveView1->AutoSpecAmp;
|
xue@0
|
1051 else WaveView1->SpecAmp=1;
|
xue@0
|
1052 }
|
xue@0
|
1053 }
|
xue@0
|
1054 //---------------------------------------------------------------------------
|
xue@0
|
1055 void __fastcall TForm1::WaveView1ObjectMouseWheel(TObject* Sender, TShiftState Shift, int WheelDelta, const TPoint& MousePos, bool& Handled)
|
xue@0
|
1056 {
|
xue@0
|
1057 if (WaveView1->ObjectAtPointer->Id==5)
|
xue@0
|
1058 {
|
xue@0
|
1059 double amp=(WheelDelta>0)?sqrt(2.0):sqrt(0.5);
|
xue@0
|
1060 if (WaveView1->AutoSpecAmp) WaveView1->maxv_specamp*=amp;
|
xue@0
|
1061 WaveView1->SpecAmp*=amp;
|
xue@0
|
1062 }
|
xue@0
|
1063 }
|
xue@0
|
1064 //---------------------------------------------------------------------------
|
xue@0
|
1065 void __fastcall TForm1::WaveView1OpMode(TObject* Sender, TShiftState Shift, int& OpMode)
|
xue@0
|
1066 {
|
xue@0
|
1067 AnsiString S="";
|
xue@0
|
1068 if (WaveView1->Length<=0) OpMode=wopIdle;
|
xue@0
|
1069 else if (GetKeyState('X')<0) {OpMode=wopCrop; S="Crop"; WaveView1PopupMenu->AutoPopup=false;} //crop mode
|
xue@0
|
1070 else if ((SpeedButtonSelect->Down || GetKeyState('S')<0) && !EditorPanel->Visible) {OpMode=wopHS; WaveView1->Cursor=crArrow, S="Sinusoid"; WaveView1PopupMenu->AutoPopup=false;}//special select mode
|
xue@0
|
1071 else if (WaveView1->ObjectAtPointer && WaveView1->ObjectAtPointer->ShortTag[0]==stAtom) {OpMode=wopEdit; WaveView1->Cursor=crHandPoint; S="Edit";} //Edit mode
|
xue@0
|
1072 else if (Shift.Contains(ssCtrl)) OpMode=wopReselect, S="Reselect"; //re-select mode
|
xue@0
|
1073 else if (Shift.Contains(ssRight)) OpMode=wopDrag, S="Drag"; //drag mode
|
xue@0
|
1074 else if (WaveView1->CurrentPane>=0
|
xue@0
|
1075 && WaveView1->FPanes.Type[WaveView1->CurrentPane]==0
|
xue@0
|
1076 && (WaveView1->EndPos-WaveView1->StartPos)*10<WaveView1->FPanes.Rect[WaveView1->CurrentPane].Width()
|
xue@0
|
1077 && abs(WaveView1->CurrentSampleInPixel-WaveView1->CurrentY)<5)
|
xue@0
|
1078 {
|
xue@0
|
1079 OpMode=wopSample, S="Edit";
|
xue@0
|
1080 if (WaveView1->Cursor!=crHandPoint){WaveView1->Cursor=crHandPoint; ::SetCursor(Screen->Cursors[crHandPoint]);}
|
xue@0
|
1081 }
|
xue@0
|
1082 else OpMode=wopSelect, S="Select"; //select mode
|
xue@0
|
1083 StatusBar1->Panels->Items[0]->Text=S;
|
xue@0
|
1084 }
|
xue@0
|
1085 //---------------------------------------------------------------------------
|
xue@0
|
1086 void __fastcall TForm1::CropEventStart(TObject*, TShiftState Shift)
|
xue@0
|
1087 {
|
xue@0
|
1088 int dfr=WaveView1->ObjectAtPointer->Tag[2];
|
xue@0
|
1089 if (Shift.Contains(ssShift))
|
xue@0
|
1090 {
|
xue@0
|
1091 int dm=WaveView1->ObjectAtPointer->ShortTag[2];
|
xue@0
|
1092 for (int i=0; i<WaveView1->FObjects.Count; i++)
|
xue@0
|
1093 {
|
xue@0
|
1094 TWaveViewObject Obj=WaveView1->FObjects.Items[i];
|
xue@0
|
1095 if (Obj.ShortTag[0]==stAtom && Obj.ShortTag[2]==dm && Obj.Tag[2]<dfr) ((atom*)Obj.Buffer)->type=atMuted;
|
xue@0
|
1096 }
|
xue@0
|
1097 }
|
xue@0
|
1098 else
|
xue@0
|
1099 {
|
xue@0
|
1100 for (int m=0; m<HS->M; m++) for (int fr=0; fr<HS->Fr-dfr; fr++)
|
xue@0
|
1101 HS->Partials[m][fr]=HS->Partials[m][fr+dfr];
|
xue@0
|
1102 HS->Fr-=dfr;
|
xue@0
|
1103 int ind=0;
|
xue@0
|
1104 for (int i=0; i<WaveView1->FObjects.Count; i++)
|
xue@0
|
1105 {
|
xue@0
|
1106 TWaveViewObject Obj=WaveView1->FObjects.Items[i];
|
xue@0
|
1107 if (Obj.ShortTag[0]==stAtom)
|
xue@0
|
1108 {
|
xue@0
|
1109 {
|
xue@0
|
1110 if (Obj.Tag[2]>=dfr)
|
xue@0
|
1111 {
|
xue@0
|
1112 Obj.Tag[2]-=dfr;
|
xue@0
|
1113 Obj.Buffer=&HS->Partials[Obj.ShortTag[2]-1][Obj.Tag[2]];
|
xue@0
|
1114 if (WaveView1->ObjectAtPointer==&WaveView1->FObjects.Items[i]) WaveView1->ObjectAtPointer=&WaveView1->FObjects.Items[ind];
|
xue@0
|
1115 if (WaveView1->StartObject==&WaveView1->FObjects.Items[i]) WaveView1->StartObject=&WaveView1->FObjects.Items[ind];
|
xue@0
|
1116 WaveView1->FObjects.Items[ind++]=Obj;
|
xue@0
|
1117 }
|
xue@0
|
1118 else {}
|
xue@0
|
1119 }
|
xue@0
|
1120 }
|
xue@0
|
1121 else WaveView1->FObjects.Items[ind++]=Obj;
|
xue@0
|
1122 }
|
xue@0
|
1123 WaveView1->FObjects.Count=ind;
|
xue@0
|
1124 int EBLI=EventBox->ListBox1->ItemIndex;
|
xue@0
|
1125 if (HS==EventBox->HS[EBLI])
|
xue@0
|
1126 {
|
xue@0
|
1127 EventBox->ListBox1->Items->Strings[EBLI]=(HS->Channel==0?"left: ":"right: ")
|
xue@0
|
1128 +AnsiString().sprintf("%.2fs, ", HS->Partials[0][0].t*1.0/WaveView1->SamplesPerSec)
|
xue@0
|
1129 +SemitoneToPitch(Log2(HS->Partials[0][0].f*WaveView1->SamplesPerSec/C4)*12);
|
xue@0
|
1130 }
|
xue@0
|
1131 }
|
xue@0
|
1132 }
|
xue@0
|
1133 void __fastcall TForm1::CropEventEnd(TObject*, TShiftState Shift)
|
xue@0
|
1134 {
|
xue@0
|
1135 int dfr=WaveView1->ObjectAtPointer->Tag[2];
|
xue@0
|
1136 if (Shift.Contains(ssShift))
|
xue@0
|
1137 {
|
xue@0
|
1138 int dm=WaveView1->ObjectAtPointer->ShortTag[2];
|
xue@0
|
1139 for (int i=0; i<WaveView1->FObjects.Count; i++)
|
xue@0
|
1140 {
|
xue@0
|
1141 TWaveViewObject Obj=WaveView1->FObjects.Items[i];
|
xue@0
|
1142 if (Obj.ShortTag[0]==stAtom && Obj.ShortTag[2]==dm && Obj.Tag[2]>dfr) ((atom*)Obj.Buffer)->type=atMuted;
|
xue@0
|
1143 }
|
xue@0
|
1144 return;
|
xue@0
|
1145 }
|
xue@0
|
1146 HS->Fr=dfr+1;
|
xue@0
|
1147 int ind=0;
|
xue@0
|
1148 for (int i=0; i<WaveView1->FObjects.Count; i++)
|
xue@0
|
1149 {
|
xue@0
|
1150 TWaveViewObject Obj=WaveView1->FObjects.Items[i];
|
xue@0
|
1151 if (Obj.ShortTag[0]==stAtom && Obj.Tag[2]>dfr) {}
|
xue@0
|
1152 else
|
xue@0
|
1153 {
|
xue@0
|
1154 if (WaveView1->ObjectAtPointer==&WaveView1->FObjects.Items[i]) WaveView1->ObjectAtPointer=&WaveView1->FObjects.Items[ind];
|
xue@0
|
1155 if (WaveView1->StartObject==&WaveView1->FObjects.Items[i]) WaveView1->StartObject=&WaveView1->FObjects.Items[ind];
|
xue@0
|
1156 WaveView1->FObjects.Items[ind++]=Obj;
|
xue@0
|
1157 }
|
xue@0
|
1158 }
|
xue@0
|
1159 WaveView1->FObjects.Count=ind;
|
xue@0
|
1160 }
|
xue@0
|
1161 void __fastcall TForm1::WaveView1ParKeyDown(TObject*, Word& Key, TShiftState Shift)
|
xue@0
|
1162 {
|
xue@0
|
1163 if ((WaveView1->OpMode==wopHS || WaveView1->OpMode==wopEdit) && WaveView1->ObjectAtPointer->ShortTag[0]==stAtom)
|
xue@0
|
1164 {
|
xue@0
|
1165 if (Key==VK_DELETE)
|
xue@0
|
1166 {
|
xue@0
|
1167 atom* par=(atom*)WaveView1->ObjectAtPointer->Buffer;
|
xue@0
|
1168 if (par->type==atAnchor)
|
xue@0
|
1169 {
|
xue@0
|
1170 if (Shift.Contains(ssShift) && Shift.Contains(ssCtrl))
|
xue@0
|
1171 {
|
xue@0
|
1172 atom** Partials=HS->Partials;
|
xue@0
|
1173 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;
|
xue@0
|
1174 }
|
xue@0
|
1175 else if (Shift.Contains(ssShift))
|
xue@0
|
1176 {
|
xue@0
|
1177 atom** Partials=HS->Partials; int fr=WaveView1->ObjectAtPointer->Tag[2];
|
xue@0
|
1178 for (int m=0; m<HS->M; m++) if (Partials[m][fr].type==atAnchor) Partials[m][fr].type=atPeak;
|
xue@0
|
1179 }
|
xue@0
|
1180 else {par->type=atPeak;}
|
xue@0
|
1181 WaveView1->Invalidate();
|
xue@0
|
1182 }
|
xue@0
|
1183 }
|
xue@0
|
1184 }
|
xue@0
|
1185 }
|
xue@0
|
1186 //---------------------------------------------------------------------------
|
xue@0
|
1187 #define ExFpStiff ExFmStiff
|
xue@0
|
1188 void __fastcall TForm1::WaveView1ParMouseDown(TObject* Sender, TMouseButton Button, TShiftState Shift, int X, int Y)
|
xue@0
|
1189 {
|
xue@0
|
1190 if (WaveView1->OpMode==wopHS && Shift.Contains(ssShift)) return;
|
xue@0
|
1191 if (WaveView1->ObjectAtPointer->ShortTag[0]!=stAtom) return;
|
xue@0
|
1192 if (WaveView1->OpMode==wopHS)
|
xue@0
|
1193 {
|
xue@0
|
1194 if (!Shift.Contains(ssLeft)) return;
|
xue@0
|
1195 edfr=WaveView1->ObjectAtPointer->Tag[2]; int M=HS->M, Fr=HS->Fr, p=WaveView1->ObjectAtPointer->ShortTag[2];
|
xue@0
|
1196 anccount=0;
|
xue@0
|
1197 ancps=(int*)realloc(ancps, sizeof(int)*M); ancfs=(double*)realloc(ancfs, sizeof(double)*M);
|
xue@0
|
1198 ancfrs=(int*)realloc(ancfrs, sizeof(int)*M);
|
xue@0
|
1199 atom** Partials=HS->Partials;
|
xue@0
|
1200
|
xue@0
|
1201 int frst=edfr, fren=edfr+1;
|
xue@0
|
1202 if (HS->isconstf) frst=0, fren=HS->Fr;
|
xue@0
|
1203
|
xue@0
|
1204 int N=WaveView1->SpecRes;
|
xue@0
|
1205 for (int m=0; m<M; m++)
|
xue@0
|
1206 {
|
xue@0
|
1207 for (int fr=frst; fr<fren; fr++)
|
xue@0
|
1208 {
|
xue@0
|
1209 if (m+1==p) continue;
|
xue@0
|
1210 double f=Partials[m][fr].f;
|
xue@0
|
1211 if (f>0 && HS->Partials[m][fr].type==atAnchor)
|
xue@0
|
1212 {
|
xue@0
|
1213 ancps[anccount]=m+1, ancfs[anccount]=f*N;
|
xue@0
|
1214 ancfrs[anccount]=(HS->Partials[m][fr].tags&ATOM_LOCALANCHOR)?fr:(-1); //fr>=0: local anchor, used in constant-f tracking
|
xue@0
|
1215 anccount++;
|
xue@0
|
1216 break;
|
xue@0
|
1217 }
|
xue@0
|
1218 }
|
xue@0
|
1219 }
|
xue@0
|
1220 if (anccount>0)
|
xue@0
|
1221 {
|
xue@0
|
1222 double delm=HSDelmEdit1->Text.ToDouble(), maxB=HSMaxBEdit1->Text.ToDouble();
|
xue@0
|
1223 TPolygon* R=new TPolygon(4+anccount*2);
|
xue@0
|
1224 InitializeR(R, ancps[0], ancfs[0], delm, maxB);
|
xue@0
|
1225 for (int i=1; i<anccount; i++) CutR(R, ancps[i], ancfs[i], delm);
|
xue@0
|
1226 ExFpStiff(f1, f2, p, R->N, R->X, R->Y);
|
xue@0
|
1227
|
xue@0
|
1228 TWaveViewObject Obj; memset(&Obj, 0, sizeof(TWaveViewObject));
|
xue@0
|
1229 Obj.ShortTag[0]=stFreqDelimiter; Obj.Tag[1]=WaveView1->FromSampleToPixel(WaveView1->StartPane, Partials[p-1][edfr].t); Obj.DrawObject=WaveView1DrawFreqLimiter;
|
xue@0
|
1230 WaveView1->FObjects.Add(Obj);
|
xue@0
|
1231 delete R;
|
xue@0
|
1232 }
|
xue@0
|
1233 }
|
xue@0
|
1234 else if (WaveView1->OpMode==wopCrop)
|
xue@0
|
1235 {
|
xue@0
|
1236 bool refresh=false;
|
xue@0
|
1237 if (Button==mbLeft) CropEventStart(0, Shift), refresh=true;
|
xue@0
|
1238 else if (Button==mbRight) CropEventEnd(0, Shift), refresh=true;
|
xue@0
|
1239 if (refresh) WaveView1->Invalidate();
|
xue@0
|
1240 }
|
xue@0
|
1241 }
|
xue@0
|
1242
|
xue@0
|
1243 void __fastcall TForm1::WaveView1ParMouseMove(TObject* Sender, TShiftState Shift, int X, int Y)
|
xue@0
|
1244 {
|
xue@0
|
1245 if (Shift.Contains(ssLeft))
|
xue@0
|
1246 {
|
xue@0
|
1247 WaveView1->ObjectAtPointer=WaveView1->StartObject;
|
xue@0
|
1248 if (Y==WaveView1->LastY) return;
|
xue@0
|
1249 if (WaveView1->OpMode==wopHS) //harmonic sinusoid estimation mode
|
xue@0
|
1250 { //*
|
xue@0
|
1251 if (!WaveView1->StartObject) return;
|
xue@0
|
1252 atom* par=(atom*)WaveView1->StartObject->Buffer;
|
xue@0
|
1253 int t=par->t, wid=WaveView1->SpecRes, offst=WaveView1->SpecOffst;
|
xue@0
|
1254 int hwid=wid/2, fr=(t-hwid)/offst;
|
xue@0
|
1255 double f0=WaveView1->CurrentDigiFreq*wid, B;
|
xue@0
|
1256
|
xue@0
|
1257 int Channel=WaveView1->StartObject->ShortTag[1];
|
xue@0
|
1258
|
xue@0
|
1259 cdouble *x=new cdouble[hwid+1];
|
xue@0
|
1260 cmplx<QSPEC_FORMAT>* spec=WaveView1->Spec[Channel][fr];
|
xue@0
|
1261 for (int i=0; i<=hwid; i++) x[i]=spec[i];
|
xue@0
|
1262 TPolygon* R=new TPolygon(1024); R->N=0;
|
xue@0
|
1263
|
xue@0
|
1264 NMSettings settings; PrepareNMSettings(&settings);
|
xue@0
|
1265 settings.pcount=anccount; settings.pin=ancps; settings.pinf=ancfs; settings.pin0asanchor=true;
|
xue@0
|
1266 settings.pinfr=ancfrs;
|
xue@0
|
1267
|
xue@0
|
1268 if (!HS->isconstf)
|
xue@0
|
1269 {
|
xue@0
|
1270 double fpp[1024], *vfpp=&fpp[256], *pfpp=&fpp[512]; atomtype *ptype=(atomtype*)&fpp[768];
|
xue@0
|
1271 memset(fpp, 0, sizeof(double)*1024);
|
xue@0
|
1272 NMResults results={fpp, vfpp, pfpp, ptype};
|
xue@0
|
1273
|
xue@0
|
1274 NoteMatchStiff3(R, f0, B, 1, &x, wid, 0, &settings, &results, 0, 0, ds0);
|
xue@0
|
1275 atom part; part.t=par->t; part.s=par->s;
|
xue@0
|
1276 if (f0>0)
|
xue@0
|
1277 {
|
xue@0
|
1278 int Fr=WaveView1->StartObject->Tag[2];
|
xue@0
|
1279 for (int i=0; i<settings.maxp; i++)
|
xue@0
|
1280 {
|
xue@0
|
1281 if (fpp[i]>0)
|
xue@0
|
1282 {
|
xue@0
|
1283 if (i<HS->M)
|
xue@0
|
1284 {
|
xue@0
|
1285 part.f=fpp[i]/wid;
|
xue@0
|
1286 part.a=vfpp[i];
|
xue@0
|
1287 part.p=pfpp[i];
|
xue@0
|
1288 part.pin=i+1;
|
xue@0
|
1289 part.type=ptype[i];
|
xue@0
|
1290 HS->Partials[i][Fr]=part;
|
xue@0
|
1291 }
|
xue@0
|
1292 }
|
xue@0
|
1293 else
|
xue@0
|
1294 {
|
xue@0
|
1295 for (int j=i; j<HS->M; j++) HS->Partials[j][Fr].f=0;
|
xue@0
|
1296 break;
|
xue@0
|
1297 }
|
xue@0
|
1298 }
|
xue@0
|
1299 }
|
xue@0
|
1300 }
|
xue@0
|
1301 else //HS->isconstf==true
|
xue@0
|
1302 {
|
xue@0
|
1303 int Fr=HS->Fr, maxp=settings.maxp;
|
xue@0
|
1304 Alloc2(Fr*3, maxp+2, fpp); double **vfpp=&fpp[Fr], **pfpp=&fpp[Fr*2];
|
xue@0
|
1305 atomtype** Allocate2(atomtype, Fr, maxp+2, ptype);
|
xue@0
|
1306 NMResults* results=new NMResults[Fr];
|
xue@0
|
1307 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];
|
xue@0
|
1308 cdouble** Allocate2(cdouble, Fr, hwid+1, xx);
|
xue@0
|
1309 int frst=(HS->Partials[0][0].t-hwid)/offst;
|
xue@0
|
1310 for (int fr=0; fr<Fr; fr++)
|
xue@0
|
1311 {
|
xue@0
|
1312 cmplx<QSPEC_FORMAT>* spec=WaveView1->Spec[Channel][frst+fr];
|
xue@0
|
1313 for (int i=0; i<=hwid; i++) xx[fr][i]=spec[i];
|
xue@0
|
1314 }
|
xue@0
|
1315
|
xue@0
|
1316 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
|
1317 else NoteMatchStiff3(R, f0, B, Fr, xx, wid, offst, &settings, results, 0, 0, ds0, false, WaveView1->StartObject->Tag[2], 3);
|
xue@0
|
1318 if (f0>0)
|
xue@0
|
1319 {
|
xue@0
|
1320 for (int fr=0; fr<Fr; fr++)
|
xue@0
|
1321 {
|
xue@0
|
1322 double *fppfr=fpp[fr], *vfppfr=vfpp[fr], *pfppfr=pfpp[fr];
|
xue@0
|
1323 atomtype *ptypefr=ptype[fr];
|
xue@0
|
1324 for (int i=0; i<HS->M; i++)
|
xue@0
|
1325 {
|
xue@0
|
1326 atom* part=&HS->Partials[i][fr];
|
xue@0
|
1327 if (fppfr[i]>0)
|
xue@0
|
1328 {
|
xue@0
|
1329 if (i<HS->M)
|
xue@0
|
1330 {
|
xue@0
|
1331 part->f=fppfr[i]/wid;
|
xue@0
|
1332 part->a=vfppfr[i];
|
xue@0
|
1333 part->p=pfppfr[i];
|
xue@0
|
1334 part->pin=i+1;
|
xue@0
|
1335 if (ptypefr[i]) part->type=ptypefr[i];
|
xue@0
|
1336 else if (i==settings.pin0-1) part->type=atPeak;
|
xue@0
|
1337 }
|
xue@0
|
1338 }
|
xue@0
|
1339 else
|
xue@0
|
1340 {
|
xue@0
|
1341 for (int j=i; j<HS->M; j++) HS->Partials[j][fr].f=0;
|
xue@0
|
1342 break;
|
xue@0
|
1343 }
|
xue@0
|
1344 }
|
xue@0
|
1345 }
|
xue@0
|
1346 atom* atm=&HS->Partials[settings.pin0-1][WaveView1->StartObject->Tag[2]];
|
xue@0
|
1347 atm->type=atAnchor;
|
xue@0
|
1348 if (Shift.Contains(ssCtrl)) atm->tags=atm->tags|ATOM_LOCALANCHOR;
|
xue@0
|
1349 else atm->tags=atm->tags&~ATOM_LOCALANCHOR;
|
xue@0
|
1350 }
|
xue@0
|
1351 DeAlloc2(xx); delete[] results; DeAlloc2(fpp); DeAlloc2(ptype);
|
xue@0
|
1352 }
|
xue@0
|
1353 delete R;
|
xue@0
|
1354 delete[] x;
|
xue@0
|
1355 }
|
xue@0
|
1356 else if (WaveView1->OpMode==wopCrop) //crop mode
|
xue@0
|
1357 {
|
xue@0
|
1358 }
|
xue@0
|
1359 else if (WaveView1->OpMode==wopEdit) //HS edit mode
|
xue@0
|
1360 {
|
xue@0
|
1361 if (GetKeyState('F')<0)
|
xue@0
|
1362 {
|
xue@0
|
1363 Amplify1Click(FM1);
|
xue@0
|
1364 }
|
xue@0
|
1365 else
|
xue@0
|
1366 {
|
xue@0
|
1367 Amplify1Click(Pitchshifting1);
|
xue@0
|
1368 double f1=WaveView1->FromPixelToDigiFreq(WaveView1->StartPane, WaveView1->StartSelY),
|
xue@0
|
1369 f2=WaveView1->FromPixelToDigiFreq(WaveView1->StartPane, Y);
|
xue@0
|
1370 double dp=12*Log2(f2/f1);
|
xue@0
|
1371 EditorPanel->PitchEdit1->Text=dp;
|
xue@0
|
1372 EditorPanel->AmpEdit1KeyPress(EditorPanel->PitchEdit1, ReturnKey);
|
xue@0
|
1373 }
|
xue@0
|
1374 }
|
xue@0
|
1375 }
|
xue@0
|
1376 }
|
xue@0
|
1377
|
xue@0
|
1378 TPolygon* RFromAtoms(int& startp, double* vfped, double starts, int M, int fr, atom** Partials, int wid, double delm, double maxB)
|
xue@0
|
1379 {
|
xue@0
|
1380 TPolygon* R=new TPolygon(M*2+4); R->N=0;
|
xue@0
|
1381 memset(vfped, 0, sizeof(double)*M);
|
xue@0
|
1382 startp=M;
|
xue@0
|
1383 for (int m=0; m<M; m++)
|
xue@0
|
1384 {
|
xue@0
|
1385 double lf=Partials[m][fr].f*wid, la=Partials[m][fr].a;
|
xue@0
|
1386 if (lf>0)
|
xue@0
|
1387 {
|
xue@0
|
1388 if (Partials[m][fr].type<=1)
|
xue@0
|
1389 {
|
xue@0
|
1390 if (R->N==0) InitializeR(R, m+1, lf, delm, maxB);
|
xue@0
|
1391 else if (la>1) CutR(R, m+1, lf, delm, true);
|
xue@0
|
1392 }
|
xue@0
|
1393 vfped[m]=la; starts+=la*la;
|
xue@0
|
1394 }
|
xue@0
|
1395 else {startp=m; break;}
|
xue@0
|
1396 }
|
xue@0
|
1397 return R;
|
xue@0
|
1398 }
|
xue@0
|
1399
|
xue@0
|
1400 void __fastcall TForm1::WaveView1ParMouseUp(TObject* Sender, TMouseButton Button, TShiftState Shift, int X, int Y)
|
xue@0
|
1401 {
|
xue@0
|
1402 if (Button==mbRight) return;
|
xue@0
|
1403
|
xue@0
|
1404 if (WaveView1->OpMode==wopHS)
|
xue@0
|
1405 {
|
xue@0
|
1406 if (!WaveView1->StartObject) return;
|
xue@0
|
1407 ClearObjectByShortTag0(WaveView1, stFreqDelimiter); //erase the delimiter
|
xue@0
|
1408
|
xue@0
|
1409 int M=HS->M, Fr=HS->Fr; atom** Partials=HS->Partials;
|
xue@0
|
1410 //*
|
xue@0
|
1411 edfr=WaveView1->StartObject->Tag[2];
|
xue@0
|
1412 int channel=WaveView1->StartObject->ShortTag[1];
|
xue@0
|
1413 int wid=WaveView1->SpecRes, offst=WaveView1->SpecOffst, hwid=wid/2;
|
xue@0
|
1414 NMSettings settings; PrepareNMSettings(&settings);
|
xue@0
|
1415 int maxp=settings.maxp;
|
xue@0
|
1416
|
xue@0
|
1417 if (HS->isconstf)
|
xue@0
|
1418 {
|
xue@0
|
1419 double brake=0.1;
|
xue@0
|
1420 if (edfr==0 || edfr==Fr-1)
|
xue@0
|
1421 {
|
xue@0
|
1422 int frst, fren, edt=HS->Partials[0][edfr].t, startfr=(edt-hwid)/offst;
|
xue@0
|
1423 atom* part;
|
xue@0
|
1424 if (edfr==0)
|
xue@0
|
1425 {
|
xue@0
|
1426 frst=ceil((WaveView1->StartPos-hwid)*1.0/offst); if (frst<0) frst=0;
|
xue@0
|
1427 part=new atom[M*(Fr+startfr-frst+1)];
|
xue@0
|
1428 }
|
xue@0
|
1429 else //edfr==Fr-1
|
xue@0
|
1430 {
|
xue@0
|
1431 fren=floor((WaveView1->EndPos-hwid)*1.0/offst);
|
xue@0
|
1432 part=new atom[M*(Fr+fren-startfr+1)];
|
xue@0
|
1433 }
|
xue@0
|
1434 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];
|
xue@0
|
1435
|
xue@0
|
1436 double ene0=0;
|
xue@0
|
1437 for (int m=0; m<HS->M; m++)
|
xue@0
|
1438 {
|
xue@0
|
1439 if (HS->Partials[m][edfr].f>0)
|
xue@0
|
1440 {
|
xue@0
|
1441 double tmp=HS->Partials[m][edfr].a;
|
xue@0
|
1442 ene0+=tmp*tmp;
|
xue@0
|
1443 }
|
xue@0
|
1444 else break;
|
xue@0
|
1445 }
|
xue@0
|
1446
|
xue@0
|
1447 int t=edt, dt=(edfr==0)?(-offst):offst;
|
xue@0
|
1448 int channel=WaveView1->StartObject->ShortTag[1];
|
xue@0
|
1449 cdouble* x=new cdouble[hwid+1];
|
xue@0
|
1450 if (edfr==0)
|
xue@0
|
1451 {
|
xue@0
|
1452 for (int fr=startfr-1; fr>=frst; fr--)
|
xue@0
|
1453 {
|
xue@0
|
1454 t+=dt;
|
xue@0
|
1455 cmplx<QSPEC_FORMAT>* spec=WaveView1->Spec[channel][fr];
|
xue@0
|
1456 for (int i=0; i<=hwid; i++) x[i]=spec[i];
|
xue@0
|
1457 double ene=0;
|
xue@0
|
1458 for (int m=0; m<HS->M; m++)
|
xue@0
|
1459 {
|
xue@0
|
1460
|
xue@0
|
1461 double f=HS->Partials[m][edfr].f*wid;
|
xue@0
|
1462 cdouble r=IPWindowC(f, x, wid, settings.M, settings.c, settings.iH2, ceil(f-settings.hB), floor(f+settings.hB));
|
xue@0
|
1463 double la=abs(r); atomtype ltype=HS->Partials[m][edfr].type; if (!ltype) ltype=atPeak;
|
xue@0
|
1464 atom lpart={t, wid, f/wid, la, arg(r), m+1, ltype};
|
xue@0
|
1465 part[k++]=lpart;
|
xue@0
|
1466 ene+=la*la;
|
xue@0
|
1467 }
|
xue@0
|
1468 if (ene<ene0*brake) break;
|
xue@0
|
1469 if (ene>ene0) ene0=ene;
|
xue@0
|
1470 }
|
xue@0
|
1471 }
|
xue@0
|
1472 else //edfr==Fr-1
|
xue@0
|
1473 {
|
xue@0
|
1474 for (int fr=startfr+1; fr<=fren; fr++)
|
xue@0
|
1475 {
|
xue@0
|
1476 t+=dt;
|
xue@0
|
1477 cmplx<QSPEC_FORMAT>* spec=WaveView1->Spec[channel][fr];
|
xue@0
|
1478 for (int i=0; i<=hwid; i++) x[i]=spec[i];
|
xue@0
|
1479 double ene=0;
|
xue@0
|
1480 for (int m=0; m<HS->M; m++)
|
xue@0
|
1481 {
|
xue@0
|
1482
|
xue@0
|
1483 double f=HS->Partials[m][edfr].f*wid;
|
xue@0
|
1484 cdouble r=IPWindowC(f, x, wid, settings.M, settings.c, settings.iH2, ceil(f-settings.hB), floor(f+settings.hB));
|
xue@0
|
1485 double la=abs(r); atomtype ltype=HS->Partials[m][edfr].type; if (!ltype) ltype=atPeak;
|
xue@0
|
1486 atom lpart={t, wid, f/wid, la, arg(r), m+1, ltype};
|
xue@0
|
1487 part[k++]=lpart;
|
xue@0
|
1488 ene+=la*la;
|
xue@0
|
1489 }
|
xue@0
|
1490 if (ene<ene0*brake) break;
|
xue@0
|
1491 if (ene>ene0) ene0=ene;
|
xue@0
|
1492 }
|
xue@0
|
1493 }
|
xue@0
|
1494 delete[] x;
|
xue@0
|
1495
|
xue@0
|
1496 DeAlloc2(HS->Partials); AtomsToPartials(k, part, HS->M, HS->Fr, HS->Partials, offst);
|
xue@0
|
1497 ClearObjectByShortTag0(WaveView1, stAtom); AddHSObject(HS);
|
xue@0
|
1498 delete[] part;
|
xue@0
|
1499
|
xue@0
|
1500 if (edfr==0)
|
xue@0
|
1501 {
|
xue@0
|
1502 int EBLI=EventBox->ListBox1->ItemIndex;
|
xue@0
|
1503 if (HS==EventBox->HS[EBLI])
|
xue@0
|
1504 {
|
xue@0
|
1505 EventBox->ListBox1->Items->Strings[EBLI]=(HS->Channel==0?"left: ":"right: ")
|
xue@0
|
1506 +AnsiString().sprintf("%.2fs, ", HS->Partials[0][0].t*1.0/WaveView1->SamplesPerSec)
|
xue@0
|
1507 +SemitoneToPitch(Log2(HS->Partials[0][0].f*WaveView1->SamplesPerSec/C4)*12);
|
xue@0
|
1508 }
|
xue@0
|
1509 }
|
xue@0
|
1510 }
|
xue@0
|
1511 return;
|
xue@0
|
1512 }
|
xue@0
|
1513
|
xue@0
|
1514
|
xue@0
|
1515 double delm=settings.delm, maxB=settings.maxB;
|
xue@0
|
1516
|
xue@0
|
1517 double *vfped=new double[M], starts=0;
|
xue@0
|
1518
|
xue@0
|
1519 int startp;
|
xue@0
|
1520
|
xue@0
|
1521 TPolygon* R=RFromAtoms(startp, vfped, starts, M, edfr, Partials, wid, delm, maxB);
|
xue@0
|
1522 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--;}
|
xue@0
|
1523 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++;}
|
xue@0
|
1524
|
xue@0
|
1525 int fred=(Partials[0][edfr].t-wid/2)/offst, frst=(WaveView1->StartPos-wid/2)/offst, fren=(WaveView1->EndPos-wid/2)/offst;
|
xue@0
|
1526
|
xue@0
|
1527 if (fr1>=0)
|
xue@0
|
1528 {
|
xue@0
|
1529 int startpst; double startsst, *vfpst=new double[M];
|
xue@0
|
1530 TPolygon* Rst=RFromAtoms(startpst, vfpst, startsst, M, fr1, Partials, wid, delm, maxB);
|
xue@0
|
1531 FindNoteFB(fr1, Rst, vfpst, edfr, R, vfped, M, Partials, wid, offst, WaveView1->Spectrogram[channel], settings);
|
xue@0
|
1532 delete Rst; delete[] vfpst;
|
xue@0
|
1533 if (fr2<Fr)
|
xue@0
|
1534 {
|
xue@0
|
1535 int startpen; double startsen, *vfpen=new double[M];
|
xue@0
|
1536 TPolygon* Ren=RFromAtoms(startpen, vfpen, startsen, M, fr2, Partials, wid, delm, maxB);
|
xue@0
|
1537 FindNoteFB(edfr, R, vfped, fr2, Ren, vfpen, M, Partials, wid, offst, WaveView1->Spectrogram[channel], settings);
|
xue@0
|
1538 delete Ren; delete[] vfpen;
|
xue@0
|
1539 }
|
xue@0
|
1540 else
|
xue@0
|
1541 {
|
xue@0
|
1542 atom* part=new atom[M*Fr+maxp*(fren-frst)];
|
xue@0
|
1543 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];
|
xue@0
|
1544 k+=FindNoteF(&part[k], starts, R, startp, vfped, fred, fren, wid, offst, WaveView1->Spectrogram[channel], settings, 0.02);
|
xue@0
|
1545 DeAlloc2(HS->Partials); AtomsToPartials(k, part, HS->M, HS->Fr, HS->Partials, offst);
|
xue@0
|
1546 ClearObjectByShortTag0(WaveView1, stAtom); AddHSObject(HS);
|
xue@0
|
1547 delete[] part;
|
xue@0
|
1548 }
|
xue@0
|
1549 }
|
xue@0
|
1550 else //fr1<0
|
xue@0
|
1551 {
|
xue@0
|
1552 if (fr2<Fr)
|
xue@0
|
1553 {
|
xue@0
|
1554 int startpen; double startsen, *vfpen=new double[M];
|
xue@0
|
1555 TPolygon* Ren=RFromAtoms(startpen, vfpen, startsen, M, fr2, Partials, wid, delm, maxB);
|
xue@0
|
1556 FindNoteFB(edfr, R, vfped, fr2, Ren, vfpen, M, Partials, wid, offst, WaveView1->Spectrogram[channel], settings);
|
xue@0
|
1557 delete Ren; delete[] vfpen;
|
xue@0
|
1558 }
|
xue@0
|
1559 atom* part=new atom[M*Fr+maxp*(fren-frst)];
|
xue@0
|
1560 int k=0, keepst=edfr, keepen=(fr2>=Fr)?edfr:(Fr-1);
|
xue@0
|
1561 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];
|
xue@0
|
1562 k+=FindNoteF(&part[k], starts, R, startp, vfped, fred, (frst>=0)?(frst-1):-1, wid, offst, WaveView1->Spectrogram[channel], settings, 0.02);
|
xue@0
|
1563 if (fr2>=Fr) k+=FindNoteF(&part[k], starts, R, startp, vfped, fred, fren, wid, offst, WaveView1->Spectrogram[channel], settings, 0.02);
|
xue@0
|
1564 DeAlloc2(HS->Partials); AtomsToPartials(k, part, HS->M, HS->Fr, HS->Partials, offst);
|
xue@0
|
1565 ClearObjectByShortTag0(WaveView1, stAtom); AddHSObject(HS);
|
xue@0
|
1566 delete[] part;
|
xue@0
|
1567 }
|
xue@0
|
1568 delete R;
|
xue@0
|
1569 delete[] vfped;
|
xue@0
|
1570 }
|
xue@0
|
1571 }
|
xue@0
|
1572 //---------------------------------------------------------------------------
|
xue@0
|
1573 void __fastcall TForm1::WaveView1ParMouseWheel(TObject* Sender, TShiftState Shift, int WheelDelta, const TPoint& MousePos, bool& Handled)
|
xue@0
|
1574 {
|
xue@0
|
1575 if (WaveView1->OpMode==wopEdit)
|
xue@0
|
1576 {
|
xue@0
|
1577 if (GetKeyState('A')<0)
|
xue@0
|
1578 {
|
xue@0
|
1579 Amplify1Click(AM1);
|
xue@0
|
1580 EditorPanel->AMAEdit1MouseWheel(WheelDelta);
|
xue@0
|
1581 }
|
xue@0
|
1582 else if (GetKeyState('D')<0)
|
xue@0
|
1583 {
|
xue@0
|
1584 Amplify1Click(DeFM1);
|
xue@0
|
1585 EditorPanel->DeFMEdit1MouseWheel(WheelDelta);
|
xue@0
|
1586 }
|
xue@0
|
1587 else if (GetKeyState('F')<0)
|
xue@0
|
1588 {
|
xue@0
|
1589 Amplify1Click(FM1);
|
xue@0
|
1590 EditorPanel->FMAEdit1MouseWheel(WheelDelta);
|
xue@0
|
1591 }
|
xue@0
|
1592 else
|
xue@0
|
1593 {
|
xue@0
|
1594 Amplify1Click(Amplify1);
|
xue@0
|
1595 EditorPanel->AmpEdit1MouseWheel(WheelDelta);
|
xue@0
|
1596 }
|
xue@0
|
1597
|
xue@0
|
1598 }
|
xue@0
|
1599 }
|
xue@0
|
1600
|
xue@0
|
1601
|
xue@0
|
1602 //---------------------------------------------------------------------------
|
xue@0
|
1603 //---------------------------------------------------------------------------
|
xue@0
|
1604 void __fastcall TForm1::WaveView1PlaybackDone(TObject*)
|
xue@0
|
1605 {
|
xue@0
|
1606 SpeedButtonPlay->Glyph=BitmapPlay;
|
xue@0
|
1607 }
|
xue@0
|
1608 //---------------------------------------------------------------------------
|
xue@0
|
1609 void __fastcall TForm1::WaveView1PlaybackStart(TObject*)
|
xue@0
|
1610 {
|
xue@0
|
1611 SpeedButtonPlay->Glyph=BitmapStop;
|
xue@0
|
1612 }
|
xue@0
|
1613 //---------------------------------------------------------------------------
|
xue@0
|
1614 void __fastcall TForm1::WaveView1PopupMenuPopup(TObject *Sender)
|
xue@0
|
1615 {
|
xue@0
|
1616 ZoomToSelection1->Visible=(WaveView1->Selections->Count>0 && WaveView1->Selections->Focus>=0);
|
xue@0
|
1617 UndoZoom1->Visible=(WaveView1->UndoExtractSelection.EndPos>=0);
|
xue@0
|
1618 TimeZoom1->Visible=(WaveView1->StartPos!=0 || WaveView1->EndPos!=WaveView1->Length);
|
xue@0
|
1619 FrequencyZoom1->Visible=(WaveView1->StartDigiFreq!=0 || WaveView1->EndDigiFreq!=0.5);
|
xue@0
|
1620 AmplitudeZoom1->Visible=(WaveView1->YZoomRate!=1);
|
xue@0
|
1621 SpectrogramBrightness1->Visible=(WaveView1->SpecAmp!=1);
|
xue@0
|
1622 Restore1->Visible=TimeZoom1->Visible || FrequencyZoom1->Visible || AmplitudeZoom1->Visible || SpectrogramBrightness1->Visible;
|
xue@0
|
1623
|
xue@0
|
1624 Play1->Visible=(WaveView1->Length>0);
|
xue@0
|
1625 Play1->Caption=WaveView1->Playing?"Stop":"Play";
|
xue@0
|
1626
|
xue@0
|
1627 Cut1->Visible=(WaveView1->OpMode<=2 && WaveView1->Selections->Count>0 &&
|
xue@0
|
1628 WaveView1->FPanes.HasFreqAxis[WaveView1->CurrentPane]) ||
|
xue@0
|
1629 (WaveView1->ObjectAtPointer && WaveView1->ObjectAtPointer->ShortTag[0]==stAtom);
|
xue@0
|
1630 Extract1->Visible=Cut1->Visible;
|
xue@0
|
1631 Editorpanel1->Visible=(WaveView1->ObjectAtPointer && WaveView1->ObjectAtPointer->ShortTag[0]==stAtom);
|
xue@0
|
1632 }
|
xue@0
|
1633 //---------------------------------------------------------------------------
|
xue@0
|
1634 void __fastcall TForm1::WindowSizeComboChange(TObject *Sender)
|
xue@0
|
1635 {
|
xue@0
|
1636 WaveView1->SpecRes=WindowSizeCombo->Text.ToInt();
|
xue@0
|
1637 }
|
xue@0
|
1638 //---------------------------------------------------------------------------
|
xue@0
|
1639 void __fastcall TForm1::WindowTypeComboChange(TObject *Sender)
|
xue@0
|
1640 {
|
xue@0
|
1641 WindowType types[]={wtRectangle, wtHamming, wtHann, wtBlackman, wtGaussian};
|
xue@0
|
1642 WaveView1->SpecWindowType=types[WindowTypeCombo->ItemIndex];
|
xue@0
|
1643 }
|
xue@0
|
1644
|
xue@0
|
1645 //---------------------------------------------------------------------------
|
xue@0
|
1646
|
xue@0
|
1647 void __fastcall TForm1::SpeedButtonSClick(TObject *Sender)
|
xue@0
|
1648 {
|
xue@0
|
1649 SpectrogramView=!SpectrogramView;
|
xue@0
|
1650 SpeedButtonS->Glyph=SpectrogramView?BitmapWaveform:BitmapSpectrogram;
|
xue@0
|
1651 Spectrogram2->Caption=SpectrogramView?"Waveform":"Spectrogram";
|
xue@0
|
1652 SetWaveViewContents();
|
xue@0
|
1653 }
|
xue@0
|
1654 //---------------------------------------------------------------------------
|
xue@0
|
1655
|
xue@0
|
1656 void __fastcall TForm1::AmplitudeZoom1Click(TObject *Sender)
|
xue@0
|
1657 {
|
xue@0
|
1658 WaveView1->YZoomRate=1;
|
xue@0
|
1659 }
|
xue@0
|
1660 //---------------------------------------------------------------------------
|
xue@0
|
1661
|
xue@0
|
1662
|
xue@0
|
1663
|
xue@0
|
1664
|
xue@0
|
1665
|
xue@0
|
1666 void __fastcall TForm1::Extract1Click(TObject *Sender)
|
xue@0
|
1667 {
|
xue@0
|
1668 if (WaveView1->ObjectAtPointer && WaveView1->ObjectAtPointer->ShortTag[0]==stAtom
|
xue@0
|
1669 || Sender==EventBox->Extract1 && HS)
|
xue@0
|
1670 {
|
xue@0
|
1671 int dst, den;
|
xue@0
|
1672 double* xrec=SynthesisHSp(HS, dst, den);
|
xue@0
|
1673 memset(&WaveView1->Data8[HS->Channel][WaveView1->BytesPerSample*WaveView1->StartPos], 0, WaveView1->BytesPerSample*(WaveView1->EndPos-WaveView1->StartPos));
|
xue@0
|
1674 WaveView1->ExtDataChange(NULL, HS->Channel, WaveView1->StartPos, WaveView1->EndPos);
|
xue@0
|
1675 PostWaveViewData(xrec, HS->Channel, dst, den, FadeInCheck->Checked, FadeInCombo->Text.ToInt());
|
xue@0
|
1676 free8(xrec);
|
xue@0
|
1677 }
|
xue@0
|
1678 else if (WaveView1->OpMode<=2 && WaveView1->Selections->Count>0 && WaveView1->Selections->Focus>=0)
|
xue@0
|
1679 {
|
xue@0
|
1680 WaveView1->TFFilter(WaveView1->CurrentChannel, true);
|
xue@0
|
1681 WaveView1->ExtDataChange(Sender, WaveView1->CurrentChannel, WaveView1->StartPos-WaveView1->SpecRes, WaveView1->EndPos+WaveView1->SpecRes);
|
xue@0
|
1682 }
|
xue@0
|
1683 }
|
xue@0
|
1684 //---------------------------------------------------------------------------
|
xue@0
|
1685 void __fastcall TForm1::PostWaveViewData(double* data, int Channel, int StartPos, int EndPos, bool fadein, int W)
|
xue@0
|
1686 {
|
xue@0
|
1687 int bps=WaveView1->BytesPerSample, L=EndPos-StartPos;
|
xue@0
|
1688 if (fadein)
|
xue@0
|
1689 {
|
xue@0
|
1690 int hW=W/2;
|
xue@0
|
1691 double* leadin=new double[hW*2]; double* leadout=&leadin[hW];
|
xue@0
|
1692 IntToDouble(leadin, &WaveView1->Data8[Channel][StartPos*bps], bps, hW);
|
xue@0
|
1693 IntToDouble(leadout, &WaveView1->Data8[Channel][(EndPos-hW)*bps], bps, hW);
|
xue@0
|
1694 for (int i=0; i<hW; i++)
|
xue@0
|
1695 {
|
xue@0
|
1696 double w=0.5+0.5*cos(M_PI*i/hW);
|
xue@0
|
1697 leadin[i]=leadin[i]*w+data[i]*(1-w);
|
xue@0
|
1698 leadout[i]=leadout[i]*(1-w)+data[L-hW+i]*w;
|
xue@0
|
1699 }
|
xue@0
|
1700 if (L>hW*2)
|
xue@0
|
1701 {
|
xue@0
|
1702 DoubleToInt(&WaveView1->Data8[Channel][StartPos*bps], bps, leadin, hW);
|
xue@0
|
1703 DoubleToInt(&WaveView1->Data8[Channel][(StartPos+hW)*bps], bps, &data[hW], L-hW*2);
|
xue@0
|
1704 DoubleToInt(&WaveView1->Data8[Channel][(EndPos-hW)*bps], bps, leadout, hW);
|
xue@0
|
1705 }
|
xue@0
|
1706 else
|
xue@0
|
1707 {
|
xue@0
|
1708 DoubleToInt(&WaveView1->Data8[Channel][StartPos*bps], bps, leadin, L/2);
|
xue@0
|
1709 DoubleToInt(&WaveView1->Data8[Channel][(StartPos+L/2)*bps], bps, &leadout[hW-L/2], L-L/2);
|
xue@0
|
1710 }
|
xue@0
|
1711 delete[] leadin;
|
xue@0
|
1712 }
|
xue@0
|
1713 else
|
xue@0
|
1714 DoubleToInt(&WaveView1->Data8[Channel][StartPos*bps], bps, data, L);
|
xue@0
|
1715 WaveView1->ExtDataChange(this, Channel, StartPos, EndPos);
|
xue@0
|
1716 }
|
xue@0
|
1717
|
xue@0
|
1718 void __fastcall TForm1::PostWaveViewData(__int16* data, int Channel, int StartPos, int EndPos, bool fadein, int W)
|
xue@0
|
1719 {
|
xue@0
|
1720 int bps=WaveView1->BytesPerSample, L=EndPos-StartPos;
|
xue@0
|
1721 if (fadein)
|
xue@0
|
1722 {
|
xue@0
|
1723 int hW=W/2;
|
xue@0
|
1724 double* leadin=new double[hW*2]; double* leadout=&leadin[hW];
|
xue@0
|
1725 IntToDouble(leadin, &WaveView1->Data8[Channel][StartPos*bps], bps, hW);
|
xue@0
|
1726 IntToDouble(leadout, &WaveView1->Data8[Channel][(EndPos-hW)*bps], bps, hW);
|
xue@0
|
1727 for (int i=0; i<hW; i++)
|
xue@0
|
1728 {
|
xue@0
|
1729 double w=0.5+0.5*cos(M_PI*i/hW);
|
xue@0
|
1730 leadin[i]=leadin[i]*w+data[i]*(1-w);
|
xue@0
|
1731 leadout[i]=leadout[i]*(1-w)+data[L-hW+i]*w;
|
xue@0
|
1732 }
|
xue@0
|
1733 if (L>hW*2)
|
xue@0
|
1734 {
|
xue@0
|
1735 DoubleToInt(&WaveView1->Data8[Channel][StartPos*bps], bps, leadin, hW);
|
xue@0
|
1736 memcpy(&WaveView1->Data8[Channel][(StartPos+hW)*bps], &data[hW], 2*(L-hW*2));
|
xue@0
|
1737 DoubleToInt(&WaveView1->Data8[Channel][(EndPos-hW)*bps], bps, leadout, hW);
|
xue@0
|
1738 }
|
xue@0
|
1739 else
|
xue@0
|
1740 {
|
xue@0
|
1741 DoubleToInt(&WaveView1->Data8[Channel][StartPos*bps], bps, leadin, L/2);
|
xue@0
|
1742 DoubleToInt(&WaveView1->Data8[Channel][(StartPos+L/2)*bps], bps, &leadout[hW-L/2], L-L/2);
|
xue@0
|
1743 }
|
xue@0
|
1744 delete[] leadin;
|
xue@0
|
1745 }
|
xue@0
|
1746 else
|
xue@0
|
1747 memcpy(&WaveView1->Data8[Channel][StartPos*bps],data, 2*L);
|
xue@0
|
1748 WaveView1->ExtDataChange(this, Channel, StartPos, EndPos);
|
xue@0
|
1749 }
|
xue@0
|
1750
|
xue@0
|
1751 void __fastcall TForm1::PostWaveViewData(__int16* data, int Channel, int StartPos, int EndPos)
|
xue@0
|
1752 {
|
xue@0
|
1753 memcpy(&WaveView1->Data16[Channel][StartPos], data, 2*(EndPos-StartPos));
|
xue@0
|
1754 WaveView1->ExtDataChange(this, Channel, StartPos, EndPos);
|
xue@0
|
1755 }
|
xue@0
|
1756
|
xue@0
|
1757
|
xue@0
|
1758 void __fastcall TForm1::FadeInCheckClick(TObject *Sender)
|
xue@0
|
1759 {
|
xue@0
|
1760 FadeInLabel->Enabled=FadeInCheck->Checked;
|
xue@0
|
1761 FadeInCombo->Enabled=FadeInCheck->Checked;
|
xue@0
|
1762 }
|
xue@0
|
1763 //---------------------------------------------------------------------------
|
xue@0
|
1764
|
xue@0
|
1765 void FadeInOut(double* x, int N, int hWid)
|
xue@0
|
1766 {
|
xue@0
|
1767 x[0]=0; double iPI=M_PI/hWid;
|
xue@0
|
1768 for (int n=1; n<hWid; n++)
|
xue@0
|
1769 {
|
xue@0
|
1770 double tmp=0.5-0.5*cos(n*iPI);
|
xue@0
|
1771 x[n]*=tmp;
|
xue@0
|
1772 x[N-n]*=tmp;
|
xue@0
|
1773 }
|
xue@0
|
1774 }
|
xue@0
|
1775
|
xue@0
|
1776 void __fastcall TForm1::Cut1Click(TObject *Sender)
|
xue@0
|
1777 {
|
xue@0
|
1778 if (WaveView1->ObjectAtPointer && WaveView1->ObjectAtPointer->ShortTag[0]==stAtom
|
xue@0
|
1779 || Sender==EventBox->Cut1 && HS)
|
xue@0
|
1780 {
|
xue@0
|
1781 int s=HS->Partials[0][0].s, hs=s/2, dst=HS->Partials[0][0].t-hs,
|
xue@0
|
1782 den=HS->Partials[0][HS->Fr-1].t+hs, bps=WaveView1->BytesPerSample;
|
xue@0
|
1783
|
xue@0
|
1784 double* data=new double[den-dst];
|
xue@0
|
1785 IntToDouble(data, &WaveView1->Data8[HS->Channel][dst*bps], bps, den-dst);
|
xue@0
|
1786
|
xue@0
|
1787 if (GetKeyState(VK_SHIFT)<0)
|
xue@0
|
1788 {
|
xue@0
|
1789 int st_wid=s/2, st_offst=st_wid/2, st_len=s;
|
xue@0
|
1790 int st_count=(st_len-st_wid)/st_offst+1;
|
xue@0
|
1791 int st_start=st_len-st_offst*st_count-hs, Fr=HS->Fr;
|
xue@0
|
1792 HS->st_start=st_start, HS->st_offst=st_offst, HS->st_count=st_count;
|
xue@0
|
1793 DeAlloc2(HS->startamp); Allocate2(double, HS->M, st_count, HS->startamp); memset(HS->startamp[0], 0, sizeof(double)*st_count*HS->M);
|
xue@0
|
1794 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
|
1795 *aa=&a1[Fr], *ab=&aa[Fr], *ac=&ab[Fr], *ad=&ac[Fr];
|
xue@0
|
1796 int *ixs=(int*)&f1[Fr*14];
|
xue@0
|
1797 double* xrec=new double[st_len];
|
xue@0
|
1798 for (int m=0; m<HS->M; m++)
|
xue@0
|
1799 {
|
xue@0
|
1800 atom* part=HS->Partials[m];
|
xue@0
|
1801 bool fzero=false;
|
xue@0
|
1802 for (int fr=0; fr<Fr; fr++)
|
xue@0
|
1803 {
|
xue@0
|
1804 if (part[fr].f<=0){fzero=true; break;}
|
xue@0
|
1805 ixs[fr]=part[fr].t;
|
xue@0
|
1806 xs[fr]=part[fr].t;
|
xue@0
|
1807 f1[fr]=part[fr].f;
|
xue@0
|
1808 p1[fr]=part[fr].p;
|
xue@0
|
1809 a1[fr]=part[fr].a*2;
|
xue@0
|
1810 }
|
xue@0
|
1811 if (fzero) break;
|
xue@0
|
1812
|
xue@0
|
1813 CubicSpline(Fr-1, fa, fb, fc, fd, xs, f1, 1, 1);
|
xue@0
|
1814 CubicSpline(Fr-1, aa, ab, ac, ad, xs, a1, 1, 1);
|
xue@0
|
1815 for (int l=0; l<Fr && ixs[l]-dst<st_len; l++)
|
xue@0
|
1816 {
|
xue@0
|
1817 int llen=(ixs[l+1]-dst<st_len)?(ixs[l+1]-ixs[l]):(st_len+dst-ixs[l]);
|
xue@0
|
1818 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);
|
xue@0
|
1819 }
|
xue@0
|
1820 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);
|
xue@0
|
1821
|
xue@0
|
1822 for (int l=0; l<st_count; l++)
|
xue@0
|
1823 {
|
xue@0
|
1824 double *ldata=&data[st_offst*l], *lxrec=&xrec[st_offst*l];
|
xue@0
|
1825 double tmp=0, tmp2=0; for (int n=0; n<st_wid; n++) tmp+=ldata[n]*lxrec[n], tmp2+=lxrec[n]*lxrec[n];
|
xue@0
|
1826 HS->startamp[m][l]=tmp/tmp2;
|
xue@0
|
1827 }
|
xue@0
|
1828 }
|
xue@0
|
1829 delete[] xrec;
|
xue@0
|
1830 delete[] f1;
|
xue@0
|
1831 }
|
xue@0
|
1832
|
xue@0
|
1833 double* xrec=SynthesisHSp(HS, dst, den);
|
xue@0
|
1834 FadeInOut(xrec, den-dst, s/2);
|
xue@0
|
1835
|
xue@0
|
1836 for (int i=0; i<den-dst; i++) data[i]-=xrec[i];
|
xue@0
|
1837 PostWaveViewData(data, HS->Channel, dst, den, false&&FadeInCheck->Checked, FadeInCombo->Text.ToInt());
|
xue@0
|
1838 free8(xrec);
|
xue@0
|
1839 delete[] data;
|
xue@0
|
1840 }
|
xue@0
|
1841 else if (WaveView1->OpMode<=2 && WaveView1->Selections->Count>0 && WaveView1->Selections->Focus>=0)
|
xue@0
|
1842 {
|
xue@0
|
1843 WaveView1->TFFilter(WaveView1->CurrentChannel, false);
|
xue@0
|
1844 WaveView1->ExtDataChange(Sender, WaveView1->CurrentChannel, WaveView1->StartPos-WaveView1->SpecRes, WaveView1->EndPos+WaveView1->SpecRes);
|
xue@0
|
1845 }
|
xue@0
|
1846 }
|
xue@0
|
1847 //---------------------------------------------------------------------------
|
xue@0
|
1848 void __fastcall TForm1::Amplify1Click(TObject *Sender)
|
xue@0
|
1849 {
|
xue@0
|
1850 if (!EditorPanel->Visible)
|
xue@0
|
1851 {
|
xue@0
|
1852 GetTargetAudio(EditorPanel->targettype, EditorPanel->Channel, EditorPanel->From, EditorPanel->To, EditorPanel->target, EditorPanel->Before);
|
xue@0
|
1853 if (EditorPanel->targettype==1) {delete EditorPanel->HS; EditorPanel->HS=new THS(HS);}
|
xue@0
|
1854
|
xue@0
|
1855 EditorPanel->AmpEdit1->Text="1";
|
xue@0
|
1856 EditorPanel->AmpDBEdit1->Text="0";
|
xue@0
|
1857 EditorPanel->PitchEdit1->Text="0";
|
xue@0
|
1858 EditorPanel->AMAEdit1->Text="0";
|
xue@0
|
1859 EditorPanel->AMFEdit1->Text="4";
|
xue@0
|
1860 EditorPanel->FMAEdit1->Text="0";
|
xue@0
|
1861 EditorPanel->FMFEdit1->Text="4";
|
xue@0
|
1862 EditorPanel->DeFMEdit1->Text="1";
|
xue@0
|
1863 EditorPanel->DeFMEdit2->Text="1";
|
xue@0
|
1864 }
|
xue@0
|
1865
|
xue@0
|
1866 if (Sender==Amplify1) EditorPanel->PageControl1->ActivePage=EditorPanel->AmplifySheet;
|
xue@0
|
1867 else if (Sender==Pitchshifting1) EditorPanel->PageControl1->ActivePage=EditorPanel->PitchSheet;
|
xue@0
|
1868 else if (Sender==AM1) EditorPanel->PageControl1->ActivePage=EditorPanel->AMSheet;
|
xue@0
|
1869 else if (Sender==FM1) EditorPanel->PageControl1->ActivePage=EditorPanel->FMSheet;
|
xue@0
|
1870 else if (Sender==DeFM1) EditorPanel->PageControl1->ActivePage=EditorPanel->DeFMSheet;
|
xue@0
|
1871
|
xue@0
|
1872 if (!EditorPanel->Visible) EditorPanel->Show();
|
xue@0
|
1873 }
|
xue@0
|
1874 //---------------------------------------------------------------------------
|
xue@0
|
1875 void __fastcall TForm1::GetTargetAudio(int& targettype, int& channel, int& from, int& to, double*& target, __int16*& before)
|
xue@0
|
1876 {
|
xue@0
|
1877 free8(target);
|
xue@0
|
1878 delete[] before;
|
xue@0
|
1879 if (WaveView1->ObjectAtPointer && WaveView1->ObjectAtPointer->ShortTag[0]==stAtom)
|
xue@0
|
1880 {
|
xue@0
|
1881 targettype=1;
|
xue@0
|
1882 channel=HS->Channel;
|
xue@0
|
1883 target=SynthesisHSp(HS, from, to);
|
xue@0
|
1884 before=new __int16[to-from];
|
xue@0
|
1885 memcpy(before, &WaveView1->Data16[channel][from], sizeof(__int16)*(to-from));
|
xue@0
|
1886 }
|
xue@0
|
1887 else
|
xue@0
|
1888 {
|
xue@0
|
1889 targettype=0;
|
xue@0
|
1890 channel=WaveView1->FPanes.Channel[WaveView1->StartPane];
|
xue@0
|
1891 to=WaveView1->EndPos;
|
xue@0
|
1892 from=WaveView1->StartPos;
|
xue@0
|
1893 target=(double*)malloc8(sizeof(double)*(to-from));
|
xue@0
|
1894 before=new __int16[to-from];
|
xue@0
|
1895 memcpy(before, &WaveView1->Data16[0][from], sizeof(__int16)*(to-from));
|
xue@0
|
1896 IntToDouble(target, before, 2, to-from);
|
xue@0
|
1897 }
|
xue@0
|
1898 }
|
xue@0
|
1899
|
xue@0
|
1900 //---------------------------------------------------------------------------
|
xue@0
|
1901 void __fastcall TForm1::Events1Click(TObject *Sender)
|
xue@0
|
1902 {
|
xue@0
|
1903 if (!EventBox->Visible)
|
xue@0
|
1904 {
|
xue@0
|
1905 EventBox->Left=Left+Width;
|
xue@0
|
1906 EventBox->Top=Top;
|
xue@0
|
1907 EventBox->Height=Height;
|
xue@0
|
1908 EventBox->Load(NULL);
|
xue@0
|
1909 EventBox->Show();
|
xue@0
|
1910 }
|
xue@0
|
1911 else
|
xue@0
|
1912 {
|
xue@0
|
1913 if (EventBox->Left>=Screen->Width) EventBox->Left=Left+Width;
|
xue@0
|
1914 EventBox->BringToFront();
|
xue@0
|
1915 }
|
xue@0
|
1916 }
|
xue@0
|
1917 //---------------------------------------------------------------------------
|
xue@0
|
1918
|
xue@0
|
1919 void __fastcall TForm1::SpeedButtonSaveClick(TObject *Sender)
|
xue@0
|
1920 {
|
xue@0
|
1921 SaveDialog1->FileName="waveview.waveview1.wav";
|
xue@0
|
1922 SaveDialog1->FilterIndex=1;
|
xue@0
|
1923 int bps=WaveView1->BytesPerSample, rfb=WaveView1->StartPos*bps, rlen=WaveView1->EndPos-WaveView1->StartPos;
|
xue@0
|
1924 if (SaveDialog1->Execute())
|
xue@0
|
1925 {
|
xue@0
|
1926 TWaveAudio* WA=new TWaveAudio(NULL);
|
xue@0
|
1927 WA->GetWaveProperties(WaveAudio1);
|
xue@0
|
1928 if (WA->Channels==1)
|
xue@0
|
1929 WA->Write(&WaveView1->Data8[0][rfb], rlen*bps);
|
xue@0
|
1930 else if (WA->Channels==2)
|
xue@0
|
1931 WA->WriteSamplesInterleave(&WaveView1->Data8[0][rfb], &WaveView1->Data8[1][rfb], rlen);
|
xue@0
|
1932 WA->SaveToFile(SaveDialog1->FileName);
|
xue@0
|
1933 delete WA;
|
xue@0
|
1934 }
|
xue@0
|
1935 }
|
xue@0
|
1936
|
xue@0
|
1937 void __fastcall TForm1::TimeZoom1Click(TObject *Sender)
|
xue@0
|
1938 {
|
xue@0
|
1939 WaveView1->SetStartAndEndPos(0, WaveView1->Length);
|
xue@0
|
1940 }
|
xue@0
|
1941 //---------------------------------------------------------------------------
|
xue@0
|
1942
|
xue@0
|
1943
|
xue@0
|
1944 void __fastcall TForm1::FrequencyZoom1Click(TObject *Sender)
|
xue@0
|
1945 {
|
xue@0
|
1946 WaveView1->SetStartAndEndDigiFreq(0, 0.5);
|
xue@0
|
1947 }
|
xue@0
|
1948 //---------------------------------------------------------------------------
|
xue@0
|
1949
|
xue@0
|
1950
|
xue@0
|
1951 void __fastcall TForm1::Vibratowizard1Click(TObject *Sender)
|
xue@0
|
1952 {
|
xue@0
|
1953 TVibratoDemoForm* VF=VibratoDemoForm;
|
xue@0
|
1954 VF->WaveView1->StartDigiFreq=WaveView1->StartDigiFreq;
|
xue@0
|
1955 VF->WaveView2->StartDigiFreq=WaveView1->StartDigiFreq;
|
xue@0
|
1956 VF->WaveView1->EndDigiFreq=WaveView1->EndDigiFreq;
|
xue@0
|
1957 VF->WaveView2->EndDigiFreq=WaveView1->EndDigiFreq;
|
xue@0
|
1958 VF->WaveView2->SpecAmp=WaveView1->SpecAmp;
|
xue@0
|
1959
|
xue@0
|
1960 int SpecRes, SpecOffst;
|
xue@0
|
1961 if (Sender==EventBox->Vibratowizard1)
|
xue@0
|
1962 {
|
xue@0
|
1963 SpecRes=HS->Partials[0][0].s;
|
xue@0
|
1964 SpecOffst=HS->Partials[0][1].t-HS->Partials[0][0].t;
|
xue@0
|
1965 }
|
xue@0
|
1966 else
|
xue@0
|
1967 {
|
xue@0
|
1968 SpecRes=WaveView1->SpecRes;
|
xue@0
|
1969 SpecOffst=WaveView1->SpecOffst;
|
xue@0
|
1970 }
|
xue@0
|
1971 VF->WaveView1->SpecRes=SpecRes;
|
xue@0
|
1972 VF->WaveView1->SpecOffst=SpecOffst;
|
xue@0
|
1973
|
xue@0
|
1974 VF->WaveAudio1->Clear(NULL);
|
xue@0
|
1975 VF->WaveAudio1->SamplesPerSec=WaveAudio1->SamplesPerSec;
|
xue@0
|
1976 VF->WaveAudio1->BitsPerSample=WaveAudio1->BitsPerSample;
|
xue@0
|
1977 int ch=WaveView1->FPanes.Channel[WaveView1->StartPane];
|
xue@0
|
1978 if (Sender==EventBox->Vibratowizard1) ch=HS->Channel;
|
xue@0
|
1979 int st=(WaveView1->StartPos-SpecRes/2)/SpecOffst*SpecOffst;
|
xue@0
|
1980 int en=(WaveView1->EndPos-SpecRes/2)/SpecOffst*SpecOffst+SpecRes;
|
xue@0
|
1981
|
xue@0
|
1982 if (Sender==EventBox->Vibratowizard1)
|
xue@0
|
1983 {
|
xue@0
|
1984 st=HS->Partials[0][0].t-SpecOffst;
|
xue@0
|
1985 en=HS->Partials[0][HS->Fr-1].t+SpecOffst;
|
xue@0
|
1986 }
|
xue@0
|
1987
|
xue@0
|
1988 if (st<0) st=0;
|
xue@0
|
1989 if (en>WaveView1->Length) en=WaveView1->Length;
|
xue@0
|
1990
|
xue@0
|
1991 VF->WaveAudio1->WriteSamples(&WaveView1->Data16[ch][st], en-st);
|
xue@0
|
1992 VF->StartPos=st;
|
xue@0
|
1993
|
xue@0
|
1994 {
|
xue@0
|
1995 delete VF->HS;
|
xue@0
|
1996 VF->HS=new THS(HS, st, en);
|
xue@0
|
1997 }
|
xue@0
|
1998
|
xue@0
|
1999 VF->StartPos=st;
|
xue@0
|
2000 VF->Copydata();
|
xue@0
|
2001 VF->Synthesize();
|
xue@0
|
2002 VF->Reset();
|
xue@0
|
2003 VF->Show();
|
xue@0
|
2004 }
|
xue@0
|
2005
|
xue@0
|
2006 //---------------------------------------------------------------------------
|
xue@0
|
2007
|
xue@0
|
2008 void __fastcall TForm1::Recent11Click(TObject *Sender)
|
xue@0
|
2009 {
|
xue@0
|
2010 TIniFile* Ini=new TIniFile(ChangeFileExt(Application->ExeName, ".ini"));
|
xue@0
|
2011 AnsiString S="RecentFile"; S=S+(((TMenuItem*)Sender)->Tag+1);
|
xue@0
|
2012 AnsiString FileName=Ini->ReadString(S, "FileName", "");
|
xue@0
|
2013 int start=Ini->ReadInteger(S, "Start", 0);
|
xue@0
|
2014 int end=Ini->ReadInteger(S, "End", -1);
|
xue@0
|
2015 double fstart=Ini->ReadFloat(S, "StartF", 0);
|
xue@0
|
2016 double fend=Ini->ReadFloat(S, "EndF", 0.5);
|
xue@0
|
2017 delete Ini;
|
xue@0
|
2018
|
xue@0
|
2019 if (FileExists(FileName) && WaveAudio1->FileName!=FileName)
|
xue@0
|
2020 {
|
xue@0
|
2021 RecentFile(WaveAudio1->FileName);
|
xue@0
|
2022 WaveAudio1->LoadFromFile(FileName);
|
xue@0
|
2023 WaveView1->SetArea(start, end, fstart, fend);
|
xue@0
|
2024 }
|
xue@0
|
2025 }
|
xue@0
|
2026 //---------------------------------------------------------------------------
|
xue@0
|
2027
|
xue@0
|
2028 void __fastcall TForm1::SpeedButtonRecordClick(TObject *Sender)
|
xue@0
|
2029 {
|
xue@0
|
2030 if (WaveAudio2 && WaveAudio2->Recording)
|
xue@0
|
2031 {
|
xue@0
|
2032 WaveAudio2->PauseRecording(0);
|
xue@0
|
2033
|
xue@0
|
2034 double second=1.0*WaveAudio2->WaveStream->Position/(WaveAudio2->SamplesPerSec*WaveAudio2->BitsPerSample/8*WaveAudio2->Channels);
|
xue@0
|
2035 int secr=(second-floor(second))*100; TDateTime dt=second/86400;
|
xue@0
|
2036 RecordingForm->Label1->Caption=dt.FormatString("'Recording finished:' h:mm:ss.")+AnsiString().sprintf("%02d", secr);
|
xue@0
|
2037
|
xue@0
|
2038 WaveAudio2->CloseFile(true);
|
xue@0
|
2039 SpeedButtonRecord->Glyph=BitmapRecord;
|
xue@0
|
2040 RecordingForm->SpeedButtonRecord->Glyph=BitmapRecord;
|
xue@0
|
2041 delete WaveAudio2;
|
xue@0
|
2042 WaveAudio2=0;
|
xue@0
|
2043
|
xue@0
|
2044 RecordingForm->SpeedButton1->Enabled=true; RecordingForm->SpeedButton2->Enabled=true;
|
xue@0
|
2045 RecordingForm->Show();
|
xue@0
|
2046 }
|
xue@0
|
2047 else
|
xue@0
|
2048 {
|
xue@0
|
2049 WaveAudio2=new TWaveAudio(NULL);
|
xue@0
|
2050 WaveAudio2->GetWaveProperties(WaveAudio1);
|
xue@0
|
2051 WaveAudio2->CreateFile(ExtractFilePath(Application->ExeName)+"noname.wav");
|
xue@0
|
2052 WaveAudio2->OnInAddBuffer=WaveAudio2InAddBuffer;
|
xue@0
|
2053 WaveAudio2->StartRecording(0);
|
xue@0
|
2054 SpeedButtonRecord->Glyph=BitmapRecording;
|
xue@0
|
2055 RecordingForm->SpeedButtonRecord->Glyph=BitmapRecording;
|
xue@0
|
2056 RecordingForm->Label1->Caption="Recording in progress: 0:00:00.00";
|
xue@0
|
2057 RecordingForm->SpeedButton1->Enabled=false; RecordingForm->SpeedButton2->Enabled=false;
|
xue@0
|
2058 RecordingForm->Show();
|
xue@0
|
2059 }
|
xue@0
|
2060 }
|
xue@0
|
2061 //---------------------------------------------------------------------------
|
xue@0
|
2062
|
xue@0
|
2063 void __fastcall TForm1::WaveAudio2InAddBuffer(TObject*)
|
xue@0
|
2064 {
|
xue@0
|
2065 double second=1.0*WaveAudio2->WaveStream->Position/(WaveAudio2->SamplesPerSec*WaveAudio2->BitsPerSample/8*WaveAudio2->Channels);
|
xue@0
|
2066 int secr=(second-floor(second))*100; TDateTime dt=second/86400;
|
xue@0
|
2067 RecordingForm->Label1->Caption=dt.FormatString("'Recording in progress:' h:mm:ss.")+AnsiString().sprintf("%02d", secr);
|
xue@0
|
2068 }
|
xue@0
|
2069
|
xue@0
|
2070 //---------------------------------------------------------------------------
|
xue@0
|
2071 void __fastcall TForm1::Close1Click(TObject *Sender)
|
xue@0
|
2072 {
|
xue@0
|
2073 RecentFile(WaveAudio1->FileName);
|
xue@0
|
2074 WaveAudio1->Clear(this);
|
xue@0
|
2075 Navigator1->Resize();
|
xue@0
|
2076 }
|
xue@0
|
2077 //---------------------------------------------------------------------------
|
xue@0
|
2078
|
xue@0
|
2079
|
xue@0
|
2080 void __fastcall TForm1::AutoScrollCheckClick(TObject *Sender)
|
xue@0
|
2081 {
|
xue@0
|
2082 WaveView1->AutoScroll=AutoScrollCheck->Checked;
|
xue@0
|
2083 }
|
xue@0
|
2084
|
xue@0
|
2085 //---------------------------------------------------------------------------
|
xue@0
|
2086 void __fastcall TForm1::WaveView1PlaybackStartAndEndPos(TObject* Sender, int& st, int& en, bool fromsel)
|
xue@0
|
2087 {
|
xue@0
|
2088 TWaveView* WV=(TWaveView*)Sender;
|
xue@0
|
2089 if (fromsel)
|
xue@0
|
2090 {
|
xue@0
|
2091 st=WV->Selections->StartPos; if (st<0) st=0;
|
xue@0
|
2092 en=WV->Selections->EndPos; if (en>WV->Length) en=WV->Length;
|
xue@0
|
2093 }
|
xue@0
|
2094 else
|
xue@0
|
2095 {
|
xue@0
|
2096 st=WV->StartPos;
|
xue@0
|
2097 if (PlayUntilRadio->ItemIndex==0) en=WV->Length;
|
xue@0
|
2098 else if (PlayUntilRadio->ItemIndex==1) en=WV->EndPos;
|
xue@0
|
2099 }
|
xue@0
|
2100 }
|
xue@0
|
2101
|
xue@0
|
2102 //---------------------------------------------------------------------------
|
xue@0
|
2103
|
xue@0
|
2104 void __fastcall TForm1::LoopCheckClick(TObject *Sender)
|
xue@0
|
2105 {
|
xue@0
|
2106 if (LoopCheck->Checked)
|
xue@0
|
2107 {
|
xue@0
|
2108 WaveView1->LoopPlay=true;
|
xue@0
|
2109 }
|
xue@0
|
2110 else
|
xue@0
|
2111 {
|
xue@0
|
2112 WaveView1->LoopPlay=false;
|
xue@0
|
2113 PlayUntilRadioClick(Sender);
|
xue@0
|
2114 }
|
xue@0
|
2115 }
|
xue@0
|
2116 //---------------------------------------------------------------------------
|
xue@0
|
2117
|
xue@0
|
2118 void __fastcall TForm1::PlayUntilRadioClick(TObject *Sender)
|
xue@0
|
2119 {
|
xue@0
|
2120 if (PlayUntilRadio->ItemIndex==0)
|
xue@0
|
2121 WaveView1->SectionEndPos=WaveView1->Length;
|
xue@0
|
2122 else if (WaveView1->LoopMode==2)
|
xue@0
|
2123 WaveView1->SectionEndPos=WaveView1->Selections->EndPos;
|
xue@0
|
2124 else
|
xue@0
|
2125 WaveView1->SectionEndPos=WaveView1->EndPos;
|
xue@0
|
2126 }
|
xue@0
|
2127 //---------------------------------------------------------------------------
|
xue@0
|
2128
|
xue@0
|
2129 void __fastcall TForm1::MouseWheelZoomClick(TObject *Sender)
|
xue@0
|
2130 {
|
xue@0
|
2131 WaveView1->DisableMouseWheelZoom=!MouseWheelZoom->Checked;
|
xue@0
|
2132 }
|
xue@0
|
2133 //---------------------------------------------------------------------------
|
xue@0
|
2134
|
xue@0
|
2135 void __fastcall TForm1::AmpGridDblClick(TObject *Sender)
|
xue@0
|
2136 {
|
xue@0
|
2137 if (GridSourcePane<0 || GridSourcePane>=WaveView1->FPanes.Count
|
xue@0
|
2138 || !WaveView1->FPanes.HasFreqAxis[GridSourcePane]) return;
|
xue@0
|
2139
|
xue@0
|
2140 TPoint P;
|
xue@0
|
2141 GetCursorPos(&P);
|
xue@0
|
2142 TStringGrid* Grid=(TStringGrid*)Sender;
|
xue@0
|
2143 P=Grid->ScreenToClient(P);
|
xue@0
|
2144 int col, row;
|
xue@0
|
2145 Grid->MouseToCell(P.x, P.y, col, row);
|
xue@0
|
2146
|
xue@0
|
2147 if (col<0 || row<0) return;
|
xue@0
|
2148 if (Grid->Cells[col][row].IsEmpty()) return;
|
xue@0
|
2149 int CurrentFr=Grid->Cells[col][0].ToInt(), CurrentBin=Grid->Cells[0][row].ToInt();
|
xue@0
|
2150 int t=WaveView1->SpecRes/2+WaveView1->SpecOffst*CurrentFr;
|
xue@0
|
2151 double f=(CurrentBin+0.5)/WaveView1->SpecRes;
|
xue@0
|
2152 WaveView1->SetCursorTF(GridSourcePane, t, f);
|
xue@0
|
2153 }
|
xue@0
|
2154 //---------------------------------------------------------------------------
|
xue@0
|
2155
|
xue@0
|
2156
|
xue@0
|
2157 void __fastcall TForm1::Sourcefilter1Click(TObject *Sender)
|
xue@0
|
2158 {
|
xue@0
|
2159 TSFDemoForm* VF=SFDemoForm;
|
xue@0
|
2160 VF->WaveView1->StartDigiFreq=WaveView1->StartDigiFreq;
|
xue@0
|
2161 VF->WaveView2->StartDigiFreq=WaveView1->StartDigiFreq;
|
xue@0
|
2162 VF->WaveView1->EndDigiFreq=WaveView1->EndDigiFreq;
|
xue@0
|
2163 VF->WaveView2->EndDigiFreq=WaveView1->EndDigiFreq;
|
xue@0
|
2164 VF->WaveView2->SpecAmp=WaveView1->SpecAmp;
|
xue@0
|
2165
|
xue@0
|
2166 int SpecRes, SpecOffst;
|
xue@0
|
2167 if (Sender==EventBox->Vibratowizard1)
|
xue@0
|
2168 {
|
xue@0
|
2169 SpecRes=HS->Partials[0][0].s;
|
xue@0
|
2170 SpecOffst=HS->Partials[0][1].t-HS->Partials[0][0].t;
|
xue@0
|
2171 }
|
xue@0
|
2172 else
|
xue@0
|
2173 {
|
xue@0
|
2174 SpecRes=WaveView1->SpecRes;
|
xue@0
|
2175 SpecOffst=WaveView1->SpecOffst;
|
xue@0
|
2176 }
|
xue@0
|
2177 VF->WaveView1->SpecRes=SpecRes;
|
xue@0
|
2178 VF->WaveView1->SpecOffst=SpecOffst;
|
xue@0
|
2179
|
xue@0
|
2180 VF->WaveAudio1->Clear(NULL);
|
xue@0
|
2181 VF->WaveAudio1->SamplesPerSec=WaveAudio1->SamplesPerSec;
|
xue@0
|
2182 VF->WaveAudio1->BitsPerSample=WaveAudio1->BitsPerSample;
|
xue@0
|
2183 int ch=WaveView1->FPanes.Channel[WaveView1->StartPane];
|
xue@0
|
2184 if (Sender==EventBox->Vibratowizard1) ch=HS->Channel;
|
xue@0
|
2185 int st=(WaveView1->StartPos-SpecRes/2)/SpecOffst*SpecOffst;
|
xue@0
|
2186 int en=(WaveView1->EndPos-SpecRes/2)/SpecOffst*SpecOffst+SpecRes;
|
xue@0
|
2187
|
xue@0
|
2188 if (Sender==EventBox->Vibratowizard1)
|
xue@0
|
2189 {
|
xue@0
|
2190 st=HS->Partials[0][0].t-SpecOffst;
|
xue@0
|
2191 en=HS->Partials[0][HS->Fr-1].t+SpecOffst;
|
xue@0
|
2192 }
|
xue@0
|
2193
|
xue@0
|
2194 if (st<0) st=0;
|
xue@0
|
2195 if (en>WaveView1->Length) en=WaveView1->Length;
|
xue@0
|
2196
|
xue@0
|
2197 VF->WaveAudio1->WriteSamples(&WaveView1->Data8[ch][st*WaveAudio1->BitsPerSample/8], en-st);
|
xue@0
|
2198 VF->StartPos=st;
|
xue@0
|
2199
|
xue@0
|
2200 {
|
xue@0
|
2201 delete VF->HS;
|
xue@0
|
2202 VF->HS=new THS(HS, st, en);
|
xue@0
|
2203 }
|
xue@0
|
2204
|
xue@0
|
2205 VF->StartPos=st;
|
xue@0
|
2206 VF->Copydata();
|
xue@0
|
2207 VF->Synthesize();
|
xue@0
|
2208 VF->Reset();
|
xue@0
|
2209 VF->Show();
|
xue@0
|
2210 }
|
xue@0
|
2211 //---------------------------------------------------------------------------
|
xue@0
|
2212
|
xue@0
|
2213
|
xue@0
|
2214
|
xue@0
|
2215
|
xue@0
|
2216 //---------------------------------------------------------------------------
|
xue@0
|
2217
|
xue@0
|
2218 void __fastcall TForm1::PlayFilterComboSelect(TObject *Sender)
|
xue@0
|
2219 {
|
xue@0
|
2220 WaveView1->PlaybackFilter=(TWaveViewPlaybackFilter)PlayFilterCombo->ItemIndex;
|
xue@0
|
2221 PlaybackFilterRadio->ItemIndex=PlayFilterCombo->ItemIndex;
|
xue@0
|
2222 }
|
xue@0
|
2223 //---------------------------------------------------------------------------
|
xue@0
|
2224
|
xue@0
|
2225 void __fastcall TForm1::PlaybackFilterRadioClick(TObject *Sender)
|
xue@0
|
2226 {
|
xue@0
|
2227 PlayFilterCombo->ItemIndex=PlaybackFilterRadio->ItemIndex;
|
xue@0
|
2228 }
|
xue@0
|
2229 //---------------------------------------------------------------------------
|
xue@0
|
2230
|
xue@0
|
2231
|
xue@0
|
2232
|
xue@0
|
2233
|
xue@0
|
2234 void __fastcall TForm1::Retrieve1Click(TObject *Sender)
|
xue@0
|
2235 {
|
xue@0
|
2236 WaveView1->Retrieve(1);
|
xue@0
|
2237 }
|
xue@0
|
2238 //---------------------------------------------------------------------------
|
xue@0
|
2239
|
xue@0
|
2240
|