xue@0: /* xue@0: Harmonic Visualiser xue@0: xue@0: An audio file viewer and editor. xue@0: Centre for Digital Music, Queen Mary, University of London. xue@0: This file copyright 2011 Wen Xue. xue@0: xue@0: This program is free software; you can redistribute it and/or xue@0: modify it under the terms of the GNU General Public License as xue@0: published by the Free Software Foundation; either version 2 of the xue@0: License, or (at your option) any later version. xue@0: */ xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: #include xue@0: #pragma hdrstop xue@0: xue@0: #include "EventBoxUnit.h" xue@0: #include "WaveView.h" xue@0: #include "Unit1.h" xue@0: #include "EditorPanelUnit.h" xue@0: #include xue@0: #include xue@0: //--------------------------------------------------------------------------- xue@0: #pragma package(smart_init) xue@0: #pragma resource "*.dfm" xue@0: TEventBox *EventBox; xue@0: //--------------------------------------------------------------------------- xue@0: __fastcall TEventBox::TEventBox(TComponent* Owner) xue@0: : TForm(Owner) xue@0: { xue@0: HSCapacity=100; xue@0: HSCount=0; xue@0: HS=(THS**)malloc(sizeof(THS*)*HSCapacity); xue@0: memset(HS, 0, sizeof(THS*)*HSCapacity); xue@0: } xue@0: xue@0: __fastcall TEventBox::~TEventBox() xue@0: { xue@0: Clear(); xue@0: free(HS); xue@0: } xue@0: xue@0: void __fastcall TEventBox::Clear() xue@0: { xue@0: ListBox1->Clear(); xue@0: for(int i=0; i=HSCapacity) xue@0: { xue@0: HSCapacity+=100; xue@0: HS=(THS**)realloc(HS, sizeof(THS*)*HSCapacity); xue@0: memset(&HS[HSCount], 0, sizeof(THS*)*(HSCapacity-HSCount)); xue@0: } xue@0: THS* newhs; xue@0: if (M>0 && Fr>0) newhs=new THS(M, Fr); xue@0: else newhs=new THS; xue@0: HS[HSCount++]=newhs; xue@0: if (ListBox1->Enabled) xue@0: { xue@0: ListBox1->Items->Add(""); xue@0: ListBox1->ItemIndex=ListBox1->Count-1; xue@0: } xue@0: return newhs; xue@0: } xue@0: xue@0: //--------------------------------------------------------------------------- xue@0: void __fastcall TEventBox::ListBox1MouseDown(TObject *Sender, xue@0: TMouseButton Button, TShiftState Shift, int X, int Y) xue@0: { xue@0: int c=ListBox1->ItemAtPos(TPoint(X, Y), true); xue@0: SetItemIndex(c); xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: void ClearObjectByShortTag0(TWaveView* WV, int tag0); xue@0: void __fastcall TEventBox::SetItemIndex(int index) xue@0: { xue@0: ListBox1->ItemIndex=index; xue@0: ClearObjectByShortTag0(Form1->WaveView1, 1); xue@0: if (index>=0) xue@0: { xue@0: Form1->HS=HS[index]; xue@0: Form1->AddHSObject(Form1->HS); xue@0: } xue@0: else xue@0: { xue@0: Form1->HS=0; xue@0: } xue@0: xue@0: bool alreadyinvalidated=false; xue@0: if (CheckBox1->Checked && Form1->HS) xue@0: { xue@0: TWaveView* WaveView1=Form1->WaveView1; xue@0: int eventst=Form1->HS->Partials[0][0].t, eventen=Form1->HS->Partials[0][Form1->HS->Fr-1].t, xue@0: wvlen=WaveView1->EndPos-WaveView1->StartPos; xue@0: if (eventst>WaveView1->EndPos || eventenStartPos) xue@0: { xue@0: int newst=(eventst+eventen)/2-wvlen/2, newen=newst+wvlen; xue@0: if (newst<0) newst=0, newen=wvlen; xue@0: else if (newen>WaveView1->Length) newen=WaveView1->Length, newst=WaveView1->Length-wvlen; xue@0: WaveView1->SetStartAndEndPos(newst, newen); xue@0: alreadyinvalidated=true; xue@0: } xue@0: } xue@0: if (!alreadyinvalidated) Form1->WaveView1->Invalidate(); xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: void __fastcall TEventBox::Save(TObject *Sender) xue@0: { xue@0: Sort(); xue@0: AnsiString FileName=ChangeFileExt(Form1->WaveAudio1->FileName, ".evt"); xue@0: if (FileExists(FileName)) xue@0: { xue@0: AnsiString BakName=ChangeFileExt(FileName, ".evt.bak."+Now().FormatString("yymmddhhnnss")); xue@0: RenameFile(FileName, BakName); xue@0: } xue@0: SaveToFile(FileName); xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: void __fastcall TEventBox::Load(TObject *Sender) xue@0: { xue@0: LoadFromFile(ChangeFileExt(Form1->WaveAudio1->FileName, ".evt")); xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: void __fastcall TEventBox::Sort() xue@0: { xue@0: for (int i=0; iPartials[0][0].tPartials[0][0].t) indmint=j; xue@0: xue@0: if (indmint!=i) xue@0: { xue@0: THS* tmphs=HS[i]; xue@0: HS[i]=HS[indmint]; xue@0: HS[indmint]=tmphs; xue@0: AnsiString tmpstr=ListBox1->Items->Strings[i]; xue@0: ListBox1->Items->Strings[i]=ListBox1->Items->Strings[indmint]; xue@0: ListBox1->Items->Strings[indmint]=tmpstr; xue@0: } xue@0: } xue@0: } xue@0: xue@0: void __fastcall TEventBox::SaveToFile(AnsiString FileName) xue@0: { xue@0: TFileStream* File=new TFileStream(FileName, fmCreate); xue@0: File->Write(&HSCount, sizeof(int)); xue@0: for (int i=0; iWriteToStream(File); xue@0: delete File; xue@0: } xue@0: xue@0: void __fastcall TEventBox::LoadFromFile(AnsiString FileName) xue@0: { xue@0: Clear(); SetItemIndex(-1); xue@0: if (!FileExists(FileName)) return; xue@0: TFileStream* File=new TFileStream(FileName, fmOpenRead); xue@0: __int32 hsc; File->Read(&hsc, sizeof(__int32)); xue@0: bool counted=memcmp(&hsc, "EVT", 4); xue@0: if (!counted) File->Seek(-4, soFromCurrent); xue@0: ListBox1->Enabled=false; xue@0: xue@0: int i=0; xue@0: while (!counted || iReadFromStream(File)) xue@0: { xue@0: if (!counted) xue@0: { xue@0: delete HS[i]; xue@0: HSCount--; xue@0: break; xue@0: } xue@0: else xue@0: { //load old format file xue@0: char c[5]; c[4]=0; xue@0: int Channel, M, Fr; xue@0: File->Read(c, 4); xue@0: File->Read(&Channel, sizeof(int)); xue@0: File->Read(&M, sizeof(int)); xue@0: File->Read(&Fr, sizeof(int)); xue@0: hs->Resize(M, Fr); xue@0: hs->Channel=Channel; xue@0: File->Read(hs->Partials[0], sizeof(atom)*M*Fr); xue@0: File->Read(c, 4); xue@0: if (strcmp(c, "EVT ")) hs->isconstf=*(int*)c; xue@0: else File->Seek(-4, soFromCurrent); xue@0: } xue@0: } xue@0: i++; xue@0: } xue@0: delete File; xue@0: TStringList* List=new TStringList; xue@0: xue@0: for (int i=0; iAdd(AnsiString(i)+" "+ xue@0: (HS[i]->Channel==0?"left: ":"right: ") xue@0: +AnsiString().sprintf("%.2fs, ", HS[i]->Partials[0][0].t*1.0/Form1->WaveView1->SamplesPerSec) xue@0: +SemitoneToPitch(Log2(HS[i]->Partials[0][0].f*Form1->WaveView1->SamplesPerSec/C4)*12) xue@0: ); xue@0: } xue@0: ListBox1->Items=List; xue@0: delete List; xue@0: ListBox1->Enabled=true; xue@0: SetItemIndex(-1); xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: xue@0: void __fastcall TEventBox::ListBox1KeyUp(TObject *Sender, WORD &Key, xue@0: TShiftState Shift) xue@0: { xue@0: int LII=ListBox1->ItemIndex; xue@0: if (Key==VK_DELETE) xue@0: { xue@0: if (LII>=0) xue@0: { xue@0: delete HS[LII]; xue@0: HSCount-=1; xue@0: memcpy(&HS[LII], &HS[LII+1], sizeof(THS*)*(HSCount-LII)); xue@0: ListBox1->Items->Delete(LII); xue@0: ClearObjectByShortTag0(Form1->WaveView1, 1); xue@0: Form1->HS=0; xue@0: Form1->WaveView1->Invalidate(); xue@0: } xue@0: } xue@0: else if (Key=='L') Load(NULL); xue@0: else if (Key=='S') Save(NULL); xue@0: else xue@0: { xue@0: } xue@0: LII=ListBox1->ItemIndex; xue@0: if (LII>=0 && Form1->HS!=HS[LII]) SetItemIndex(LII); xue@0: else if (LII<0 && Form1->HS!=0) SetItemIndex(LII); xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: xue@0: void __fastcall TEventBox::Vibratowizard1Click(TObject *Sender) xue@0: { xue@0: if (Form1->Vibratowizard1->Enabled) Form1->Vibratowizard1Click(Sender); xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: void __fastcall TEventBox::ListBox1DblClick(TObject *Sender) xue@0: { xue@0: if (Form1->Vibratowizard1->Enabled) xue@0: { xue@0: if (GetKeyState(VK_SHIFT)>=0) xue@0: Form1->Sourcefilter1Click(Vibratowizard1); xue@0: else xue@0: Form1->Vibratowizard1Click(Vibratowizard1); xue@0: } xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: void __fastcall TEventBox::FormClick(TObject *Sender) xue@0: { xue@0: SetItemIndex(-1); xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: xue@0: void __fastcall TEventBox::Cut1Click(TObject *Sender) xue@0: { xue@0: if (Form1->Cut1->Enabled) Form1->Cut1Click(Sender); xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: xue@0: void __fastcall TEventBox::PopupMenu1Popup(TObject *Sender) xue@0: { xue@0: bool hasselection=ListBox1->ItemIndex>=0; xue@0: Vibratowizard1->Visible=hasselection; xue@0: Sourcefilter1->Visible=hasselection; xue@0: Extract1->Visible=hasselection; xue@0: Cut1->Visible=hasselection;; xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: void __fastcall TEventBox::Extract1Click(TObject *Sender) xue@0: { xue@0: if (Form1->Extract1->Enabled) Form1->Extract1Click(Sender); xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: xue@0: xue@0: void __fastcall TEventBox::Sourcefilter1Click(TObject *Sender) xue@0: { xue@0: if (Form1->Vibratowizard1->Enabled) xue@0: Form1->Sourcefilter1Click(Vibratowizard1); xue@0: } xue@0: //--------------------------------------------------------------------------- xue@0: