view EventBoxUnit.cpp @ 1:f3fd4e19cec0 tip

first binary upload
author wenx <xue.wen@eecs.qmul.ac.uk>
date Wed, 10 Aug 2011 14:56:28 +0100
parents a6a46af64546
children
line wrap: on
line source
/*
    Harmonic Visualiser

    An audio file viewer and editor.
    Centre for Digital Music, Queen Mary, University of London.
    This file copyright 2011 Wen Xue.

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
    published by the Free Software Foundation; either version 2 of the
    License, or (at your option) any later version. 
*/
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "EventBoxUnit.h"
#include "WaveView.h"
#include "Unit1.h"
#include "EditorPanelUnit.h"
#include <Math.hpp>
#include <math.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TEventBox *EventBox;
//---------------------------------------------------------------------------
__fastcall TEventBox::TEventBox(TComponent* Owner)
  : TForm(Owner)
{
  HSCapacity=100;
  HSCount=0;
  HS=(THS**)malloc(sizeof(THS*)*HSCapacity);
  memset(HS, 0, sizeof(THS*)*HSCapacity);
}

__fastcall TEventBox::~TEventBox()
{
  Clear();
  free(HS);
}

void __fastcall TEventBox::Clear()
{
  ListBox1->Clear();
  for(int i=0; i<HSCount; i++) delete HS[i];
  HSCount=0;
}
//---------------------------------------------------------------------------
THS* __fastcall TEventBox::NewHS(int M, int Fr)
{
  if (HSCount>=HSCapacity)
  {
    HSCapacity+=100;
    HS=(THS**)realloc(HS, sizeof(THS*)*HSCapacity);
    memset(&HS[HSCount], 0, sizeof(THS*)*(HSCapacity-HSCount));
  }
  THS* newhs;
  if (M>0 && Fr>0) newhs=new THS(M, Fr);
  else newhs=new THS;
  HS[HSCount++]=newhs;
  if (ListBox1->Enabled)
  {
    ListBox1->Items->Add("");
    ListBox1->ItemIndex=ListBox1->Count-1;
  }
  return newhs;
}

//---------------------------------------------------------------------------
void __fastcall TEventBox::ListBox1MouseDown(TObject *Sender,
      TMouseButton Button, TShiftState Shift, int X, int Y)
{
  int c=ListBox1->ItemAtPos(TPoint(X, Y), true);
  SetItemIndex(c);
}
//---------------------------------------------------------------------------
  void ClearObjectByShortTag0(TWaveView* WV, int tag0);
void __fastcall TEventBox::SetItemIndex(int index)
{
  ListBox1->ItemIndex=index;
  ClearObjectByShortTag0(Form1->WaveView1, 1);
  if (index>=0)
  {
    Form1->HS=HS[index];
    Form1->AddHSObject(Form1->HS);
  }
  else
  {
    Form1->HS=0;
  }

  bool alreadyinvalidated=false;
  if (CheckBox1->Checked && Form1->HS)
  {
    TWaveView* WaveView1=Form1->WaveView1;
    int eventst=Form1->HS->Partials[0][0].t, eventen=Form1->HS->Partials[0][Form1->HS->Fr-1].t,
        wvlen=WaveView1->EndPos-WaveView1->StartPos;
    if (eventst>WaveView1->EndPos || eventen<WaveView1->StartPos)
    {
      int newst=(eventst+eventen)/2-wvlen/2, newen=newst+wvlen;
      if (newst<0) newst=0, newen=wvlen;
      else if (newen>WaveView1->Length) newen=WaveView1->Length, newst=WaveView1->Length-wvlen;
      WaveView1->SetStartAndEndPos(newst, newen);
      alreadyinvalidated=true;
    }
  }
  if (!alreadyinvalidated) Form1->WaveView1->Invalidate();
}
//---------------------------------------------------------------------------
void __fastcall TEventBox::Save(TObject *Sender)
{
  Sort();
  AnsiString FileName=ChangeFileExt(Form1->WaveAudio1->FileName, ".evt");
  if (FileExists(FileName))
  {
    AnsiString BakName=ChangeFileExt(FileName, ".evt.bak."+Now().FormatString("yymmddhhnnss"));
    RenameFile(FileName, BakName);
  }
  SaveToFile(FileName);
}
//---------------------------------------------------------------------------
void __fastcall TEventBox::Load(TObject *Sender)
{
  LoadFromFile(ChangeFileExt(Form1->WaveAudio1->FileName, ".evt"));
}
//---------------------------------------------------------------------------
void __fastcall TEventBox::Sort()
{
  for (int i=0; i<HSCount-1; i++)
  {
    int indmint=i;
    for (int j=i+1; j<HSCount; j++) if (HS[j]->Partials[0][0].t<HS[indmint]->Partials[0][0].t) indmint=j;

    if (indmint!=i)
    {
      THS* tmphs=HS[i];
      HS[i]=HS[indmint];
      HS[indmint]=tmphs;
      AnsiString tmpstr=ListBox1->Items->Strings[i];
      ListBox1->Items->Strings[i]=ListBox1->Items->Strings[indmint];
      ListBox1->Items->Strings[indmint]=tmpstr;
    }
  }
}

void __fastcall TEventBox::SaveToFile(AnsiString FileName)
{
  TFileStream* File=new TFileStream(FileName, fmCreate);
  File->Write(&HSCount, sizeof(int));
  for (int i=0; i<HSCount; i++) HS[i]->WriteToStream(File);
  delete File;
}

void __fastcall TEventBox::LoadFromFile(AnsiString FileName)
{
  Clear(); SetItemIndex(-1);
  if (!FileExists(FileName)) return;
  TFileStream* File=new TFileStream(FileName, fmOpenRead);
  __int32 hsc; File->Read(&hsc, sizeof(__int32));
  bool counted=memcmp(&hsc, "EVT", 4);
  if (!counted) File->Seek(-4, soFromCurrent);
  ListBox1->Enabled=false;

  int i=0;
  while (!counted || i<hsc)
  {
    THS* hs=NewHS(0, 0);
    if (!hs->ReadFromStream(File))
    {
      if (!counted)
      {
        delete HS[i];
        HSCount--;
        break;
      }
      else
      { //load old format file
        char c[5]; c[4]=0;
        int Channel, M, Fr;
        File->Read(c, 4);
        File->Read(&Channel, sizeof(int));
        File->Read(&M, sizeof(int));
        File->Read(&Fr, sizeof(int));
        hs->Resize(M, Fr);
        hs->Channel=Channel;
        File->Read(hs->Partials[0], sizeof(atom)*M*Fr);
        File->Read(c, 4);
        if (strcmp(c, "EVT ")) hs->isconstf=*(int*)c;
        else File->Seek(-4, soFromCurrent);
      }
    }
    i++;
  }
  delete File;
  TStringList* List=new TStringList;

  for (int i=0; i<HSCount; i++)
  {
    List->Add(AnsiString(i)+" "+
    (HS[i]->Channel==0?"left: ":"right: ")
      +AnsiString().sprintf("%.2fs, ", HS[i]->Partials[0][0].t*1.0/Form1->WaveView1->SamplesPerSec)
      +SemitoneToPitch(Log2(HS[i]->Partials[0][0].f*Form1->WaveView1->SamplesPerSec/C4)*12)
    );
  }
    ListBox1->Items=List;
    delete List;
  ListBox1->Enabled=true;
  SetItemIndex(-1);
}
//---------------------------------------------------------------------------


void __fastcall TEventBox::ListBox1KeyUp(TObject *Sender, WORD &Key,
      TShiftState Shift)
{
  int LII=ListBox1->ItemIndex;
  if (Key==VK_DELETE)
  {
    if (LII>=0)
    {
      delete HS[LII];
      HSCount-=1;
      memcpy(&HS[LII], &HS[LII+1], sizeof(THS*)*(HSCount-LII));
      ListBox1->Items->Delete(LII);
      ClearObjectByShortTag0(Form1->WaveView1, 1);
      Form1->HS=0;
      Form1->WaveView1->Invalidate();
    }
  }
  else if (Key=='L') Load(NULL);
  else if (Key=='S') Save(NULL);
  else
  {
  }
  LII=ListBox1->ItemIndex;
  if (LII>=0 && Form1->HS!=HS[LII]) SetItemIndex(LII);
  else if (LII<0 && Form1->HS!=0) SetItemIndex(LII);
}
//---------------------------------------------------------------------------


void __fastcall TEventBox::Vibratowizard1Click(TObject *Sender)
{
  if (Form1->Vibratowizard1->Enabled) Form1->Vibratowizard1Click(Sender);
}
//---------------------------------------------------------------------------

void __fastcall TEventBox::ListBox1DblClick(TObject *Sender)
{
	if (Form1->Vibratowizard1->Enabled)
	{
		if (GetKeyState(VK_SHIFT)>=0)
			Form1->Sourcefilter1Click(Vibratowizard1);
		else
			Form1->Vibratowizard1Click(Vibratowizard1);
	}
}
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------

void __fastcall TEventBox::FormClick(TObject *Sender)
{
  SetItemIndex(-1);  
}
//---------------------------------------------------------------------------


void __fastcall TEventBox::Cut1Click(TObject *Sender)
{
  if (Form1->Cut1->Enabled) Form1->Cut1Click(Sender);
}
//---------------------------------------------------------------------------


void __fastcall TEventBox::PopupMenu1Popup(TObject *Sender)
{
  bool hasselection=ListBox1->ItemIndex>=0;
  Vibratowizard1->Visible=hasselection;
  Sourcefilter1->Visible=hasselection;
  Extract1->Visible=hasselection;
  Cut1->Visible=hasselection;;
}
//---------------------------------------------------------------------------

void __fastcall TEventBox::Extract1Click(TObject *Sender)
{
  if (Form1->Extract1->Enabled) Form1->Extract1Click(Sender);
}
//---------------------------------------------------------------------------


void __fastcall TEventBox::Sourcefilter1Click(TObject *Sender)
{
	if (Form1->Vibratowizard1->Enabled)
  	Form1->Sourcefilter1Click(Vibratowizard1);
}
//---------------------------------------------------------------------------