1312 lines
30 KiB
C++
1312 lines
30 KiB
C++
//---------------------------------------------------------------------------
|
|
#include <vcl.h>
|
|
#pragma hdrstop
|
|
|
|
#include "GlobalUnit.h"
|
|
#include "FxDef.h"
|
|
#include "AudioTrack.h"
|
|
#include "Compose.h"
|
|
#include "ContentPanelUnit.h"
|
|
//---------------------------------------------------------------------------
|
|
#pragma package(smart_init)
|
|
/***************************************************************************************/
|
|
// 全局常量
|
|
/***************************************************************************************/
|
|
const char *g_strEffect[MAX_FX_NUM] = {
|
|
"回声", "失真", "旋转", "混响", "压缩",
|
|
"哇音", "合唱", "均衡", "移相", "变调" },
|
|
*g_strEffectPreset[MAX_FX_NUM][3] = {
|
|
{ "小", "中", "大" }, { "默认", "", "" },
|
|
{ "慢", "中", "快" }, { "小", "中", "大" },
|
|
{ "小", "中", "大" }, { "小", "中", "大" },
|
|
{ "小", "中", "大" }, { "喇叭", "电话", "听筒" },
|
|
{ "小", "中", "大" }, { "默认", "低八度", "高八度" } },
|
|
*g_strEffectParamName[MAX_FX_NUM][6] = {
|
|
/* { "WetDryMix", "Feedback", "LeftDelay", "RightDelay", "", "" },
|
|
{ "Gain", "Frequency", "Bandwidth", "Edge", "CutOff", "" },
|
|
{ "Rate", "", "", "", "", "" },
|
|
{ "InGain", "ReverbMix", "ReverbTime", "RTRatio", "", "" },
|
|
{ "Gain", "Threshold", "Ratio", "Attack", "Release", "" },
|
|
{ "DryMix", "WetMix", "Feedback", "Rate", "Range", "Frequency" },
|
|
//{ "DryMix", "WetMix", "Feedback", "Rate", "MinDelay", "MaxDelay" },
|
|
{ "WetDryMix", "Depth", "Feedback", "Frequency", "Delay", "" },
|
|
{ "Center", "Bandwidth", "Gain", "", "", "" },
|
|
{ "DryMix", "WetMix", "Feedback", "Rate", "Range", "Frequency" },
|
|
*/
|
|
{ "干湿比", "反馈", "左延迟", "右延迟", "", "" },
|
|
{ "增益", "频率", "波段", "边界", "临界值", "" },
|
|
{ "速率", "", "", "", "", "" },
|
|
{ "输入增益", "混响比", "混响时间", "混响速率", "", "" },
|
|
{ "增益", "阀值", "速率", "启动", "释放", "" },
|
|
{ "干声比", "湿声比", "反馈", "速率", "范围", "频率" },
|
|
{ "干湿比", "深度", "反馈", "频率", "延迟", "" },
|
|
{ "中心点", "波段", "增益", "", "", "" },
|
|
{ "干声比", "湿声比", "反馈", "速率", "范围", "频率" },
|
|
{ "半音阶", "", "", "", "", "" } };
|
|
|
|
const DWORD g_aAudioEffectTypes[MAX_FX_NUM] ={
|
|
FX_ECHO, FX_DISTORTION, FX_ROTATE, FX_REVERB, FX_COMPRESSOR,
|
|
FX_WAH, FX_CHORUS, FX_PARAMEQ, FX_PHASER, FX_PITCH }; //音效类型
|
|
|
|
const float g_aEffectParamLimit[MAX_FX_NUM][6][2] = {
|
|
{ {0,100}, {0,100}, {1,2000}, {1,2000}, {0,0}, {0,0} },
|
|
{ {-60,0}, {0,100}, {100,8000}, {100,8000}, {100,8000}, {0,0} },
|
|
{ {0,5}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0} },
|
|
{ {-96,0}, {-96,0}, {0.001,3000}, {0.001,0.999}, {0,0}, {0,0} },
|
|
{ {-60,60}, {-60,0}, {1,20}, {0.01,1000}, {0.01,5000}, {0,0} },
|
|
{ {-2,2}, {-2,2}, {-1,1}, {0.001,9.999}, {0.001,9.999}, {1,999} },
|
|
//{ {-2,2}, {-2,2}, {-1,1}, {1,6000}, {1,6000}, {1,1000} },
|
|
{ {0,100}, {0,100}, {-99,99}, {0,10}, {0,20}, {0,0} },
|
|
{ {80,16000}, {1,36}, {-15,15}, {0,0}, {0,0}, {0,0} },
|
|
{ {-2,2}, {-2,2}, {-1,1}, {0.001,9.999}, {0.001,9.999}, {1,999} },
|
|
{ {-36,36}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0} } };
|
|
|
|
/***************************************************************************************/
|
|
// 全局变量
|
|
/***************************************************************************************/
|
|
/*PTEffect //g_aAudioEffects[MAX_FX_NUM],
|
|
//g_aAudioEffects_SVD[MAX_FX_NUM],
|
|
g_aAudioEffects_Clipboard[MAX_FX_NUM];
|
|
*/
|
|
/***************************************************************************************/
|
|
// 全局函数
|
|
/***************************************************************************************/
|
|
int GetFxPresetCount( int iFxType )
|
|
{
|
|
if( iFxType==FX_DISTORTION )
|
|
return 1;
|
|
|
|
return 3;
|
|
}
|
|
|
|
void GetFxPreset( int iFxType, int iPreset, float fParams[] )
|
|
{
|
|
if( iFxType==FX_ROTATE ){
|
|
if( iPreset==0 ){
|
|
fParams[0] = 0.2;
|
|
}
|
|
else if( iPreset==1 ){
|
|
fParams[0] = 1.0;
|
|
}
|
|
else if( iPreset==2 ){
|
|
fParams[0] = 2.28;
|
|
}
|
|
}
|
|
else if( iFxType==FX_WAH ){
|
|
fParams[0] = 0.5;
|
|
fParams[1] = 1.5;
|
|
fParams[2] = 0.5;
|
|
|
|
if( iPreset==0 ){
|
|
fParams[3] = 2;
|
|
fParams[4] = 4.3;
|
|
fParams[5] = 50;
|
|
}
|
|
else if( iPreset==1 ){
|
|
|
|
fParams[3] = 5;
|
|
fParams[4] = 5.3;
|
|
fParams[5] = 50;
|
|
}
|
|
else if( iPreset==2 ){
|
|
fParams[3] = 5;
|
|
fParams[4] = 4.3;
|
|
fParams[5] = 500;
|
|
}
|
|
}
|
|
else if( iFxType==FX_PHASER ){
|
|
fParams[0] = 0.999;
|
|
fParams[1] = 0.999;
|
|
fParams[3] = 1;
|
|
|
|
if( iPreset==0 ){
|
|
fParams[2] = 0.0;
|
|
fParams[4] = 4.0;
|
|
fParams[5] = 100;
|
|
}
|
|
else if( iPreset==1 ){
|
|
fParams[2] = 0.6;
|
|
fParams[4] = 4.0;
|
|
fParams[5] = 40;
|
|
}
|
|
else if( iPreset==2 ){
|
|
fParams[2] = 0.6;
|
|
fParams[4] = 4.0;
|
|
fParams[5] = 60;
|
|
}
|
|
}
|
|
else if( iFxType==FX_CHORUS ){
|
|
/*
|
|
fParams[2] = 0.5;
|
|
fParams[3] = 1;
|
|
|
|
if( iPreset==0 ){
|
|
fParams[0] = 1;
|
|
fParams[1] = 0.3;
|
|
fParams[4] = 5;
|
|
fParams[5] = 1;
|
|
}
|
|
else if( iPreset==1 ){
|
|
fParams[0] = 0.9;
|
|
fParams[1] = -0.4;
|
|
fParams[4] = 2;
|
|
fParams[5] = 1;
|
|
}
|
|
else if( iPreset==2 ){
|
|
fParams[0] = 0.3;
|
|
fParams[1] = 0.4;
|
|
fParams[4] = 10;
|
|
fParams[5] = 5;
|
|
}
|
|
*/
|
|
if( iPreset==0 ){
|
|
fParams[0] = 25;
|
|
fParams[1] = 10;
|
|
fParams[2] = 10;
|
|
fParams[3] = 1.1;
|
|
fParams[4] = 10;
|
|
}
|
|
else if( iPreset==1 ){
|
|
fParams[0] = 50;
|
|
fParams[1] = 10;
|
|
fParams[2] = 25;
|
|
fParams[3] = 1.1;
|
|
fParams[4] = 16;
|
|
}
|
|
else if( iPreset==2 ){
|
|
fParams[0] = 65;
|
|
fParams[1] = 20;
|
|
fParams[2] = 45;
|
|
fParams[3] = 5;
|
|
fParams[4] = 16;
|
|
}
|
|
}
|
|
else if( iFxType==FX_DISTORTION ){
|
|
fParams[0] = -60;
|
|
fParams[1] = 60;
|
|
fParams[2] = 6466;
|
|
fParams[3] = 1327;
|
|
fParams[4] = 7080;
|
|
}
|
|
else if( iFxType==FX_REVERB ){
|
|
fParams[0] = 0;
|
|
fParams[3] = 0.001;
|
|
|
|
if( iPreset==0 ){
|
|
fParams[1] = -44;
|
|
fParams[2] = 1428;
|
|
}
|
|
else if( iPreset==1 ){
|
|
fParams[1] = -21;
|
|
fParams[2] = 1573;
|
|
}
|
|
else if( iPreset==2 ){
|
|
fParams[1] = -9;
|
|
fParams[2] = 1573;
|
|
}
|
|
}
|
|
else if( iFxType==FX_COMPRESSOR ){
|
|
if( iPreset==0 ){
|
|
fParams[0] = 0;
|
|
fParams[1] = -12;
|
|
fParams[2] = 6;
|
|
}
|
|
else if( iPreset==1 ){
|
|
fParams[0] = 8;
|
|
fParams[1] = -13;
|
|
fParams[2] = 4;
|
|
}
|
|
else if( iPreset==2 ){
|
|
fParams[0] = 15;
|
|
fParams[1] = -15;
|
|
fParams[2] = 2;
|
|
}
|
|
|
|
fParams[3] = 10;
|
|
fParams[4] = 200;
|
|
}
|
|
else if( iFxType==FX_ECHO ){
|
|
fParams[0] = 20;
|
|
fParams[1] = 6;
|
|
|
|
if( iPreset==0 ){
|
|
if( g_iMelodyTimeSignature==3 )
|
|
fParams[2] = fParams[3] = g_dblTimePerBar / g_nChordNumPerBar / 3;
|
|
else
|
|
fParams[2] = fParams[3] = g_dblTimePerBar / g_nChordNumPerBar / 2;
|
|
}
|
|
else if( iPreset==1 ){
|
|
if( g_iMelodyTimeSignature==3 )
|
|
fParams[2] = g_dblTimePerBar / g_nChordNumPerBar / 3;
|
|
else
|
|
fParams[2] = g_dblTimePerBar / g_nChordNumPerBar / 2;
|
|
|
|
fParams[3] = g_dblTimePerBar / g_nChordNumPerBar;
|
|
}
|
|
else if( iPreset==2 ){
|
|
fParams[2] = g_dblTimePerBar / g_nChordNumPerBar;
|
|
fParams[3] = g_dblTimePerBar / g_nChordNumPerBar * 2;
|
|
}
|
|
|
|
if( fParams[2]>2000 )
|
|
fParams[2] = 2000;
|
|
// fParams[3] = 500;
|
|
}
|
|
else if( iFxType==FX_PARAMEQ ){
|
|
if( iPreset==0 ){
|
|
fParams[0] = 2220;
|
|
fParams[1] = 14;
|
|
fParams[2] = 10;
|
|
}
|
|
else if( iPreset==1 ){
|
|
fParams[0] = 932;
|
|
fParams[1] = 20;
|
|
fParams[2] = 6;
|
|
}
|
|
else if( iPreset==2 ){
|
|
fParams[0] = 1110;
|
|
fParams[1] = 11;
|
|
fParams[2] = 6;
|
|
}
|
|
}
|
|
else if( iFxType==FX_PITCH ){
|
|
if( iPreset==1 )
|
|
fParams[0] = -12;
|
|
else if( iPreset==2 )
|
|
fParams[0] = 12;
|
|
else
|
|
fParams[0] = 0;
|
|
}
|
|
}
|
|
|
|
int GetFxParamNum( int iFxType )
|
|
{
|
|
int num = 0;
|
|
|
|
switch( iFxType ){
|
|
case FX_ROTATE:
|
|
case FX_PITCH:
|
|
num = 1;
|
|
break;
|
|
/*
|
|
case FX_VOLUME:
|
|
num = 2;
|
|
break;
|
|
*/
|
|
case FX_PARAMEQ:
|
|
num = 3;
|
|
break;
|
|
|
|
case FX_REVERB:
|
|
case FX_ECHO:
|
|
num = 4;
|
|
break;
|
|
|
|
case FX_DISTORTION:
|
|
case FX_COMPRESSOR:
|
|
case FX_CHORUS:
|
|
num = 5;
|
|
break;
|
|
|
|
case FX_WAH:
|
|
case FX_PHASER:
|
|
num = 6;
|
|
break;
|
|
}
|
|
|
|
return num;
|
|
}
|
|
|
|
float Pos2Param( int iFx, int iParam, int Pos )
|
|
{
|
|
float fMin = g_aEffectParamLimit[iFx][iParam][0],
|
|
fMax = g_aEffectParamLimit[iFx][iParam][1];
|
|
|
|
return fMin + ( fMax - fMin ) * ( Pos / 100.0 );
|
|
}
|
|
|
|
int Param2Pos( int iFx, int iParam, float fParam )
|
|
{
|
|
float fMin = g_aEffectParamLimit[iFx][iParam][0],
|
|
fMax = g_aEffectParamLimit[iFx][iParam][1];
|
|
|
|
return (int)( (fParam-fMin) / ( fMax-fMin ) * 100);
|
|
}
|
|
|
|
void AudioEffectsClear( int iWave, bool bApply )
|
|
{
|
|
TAudioTrack* pAT = g_aAudioTracks[iWave];
|
|
|
|
while( !pAT->lstFxs.empty() ){
|
|
TAudioFx* pFx = pAT->lstFxs.back();
|
|
|
|
if( bApply )
|
|
f_MM_AudioMoveFx( iWave, pAT->lstFxs.size()-1, -1 );
|
|
|
|
delete pFx;
|
|
pAT->lstFxs.pop_back();
|
|
}
|
|
}
|
|
|
|
HRESULT AudioApplyEffect( int iWave, int ind, TAudioFx* pFx )
|
|
{
|
|
UINT pluginID = 0;
|
|
char* strVSTFile = NULL;
|
|
|
|
if( pFx->iFx>=FX_VST ){
|
|
VSTINFO* pVST = g_lstVSTFx[pFx->iFx-FX_VST];
|
|
strVSTFile = pVST->strFileName;
|
|
|
|
if( pFx->iPreset>=0 && !pVST->aPlugins.empty() ){
|
|
pluginID = pVST->aPlugins[pFx->iPreset]->id;
|
|
}
|
|
}
|
|
|
|
Screen->Cursor = crHourGlass;
|
|
|
|
HRESULT hr = f_MM_AudioAddFx( iWave, pFx->iFx, strVSTFile, pluginID, false );
|
|
if( hr==S_OK ){
|
|
if( !pFx->bBypass || pFx->iFx>=FX_VST )
|
|
f_MM_AudioSetFxParam( iWave, ind, pFx->pParam, pFx->nParamSize );
|
|
|
|
if( pFx->bBypass )
|
|
f_MM_AudioSetFxParam( iWave, ind, NULL, 0 );
|
|
}
|
|
|
|
Screen->Cursor = crDefault;
|
|
|
|
return hr;
|
|
}
|
|
|
|
void AudioEffectsDefault( int iWave, bool bApply )
|
|
{
|
|
AudioEffectsClear( iWave, bApply );
|
|
|
|
TAudioTrack* pTrack = g_aAudioTracks[iWave];
|
|
|
|
int nBarCount = pTrack->lstBars.size();
|
|
|
|
if( nBarCount>0 ){
|
|
int nSize = GetFxParamNum( FX_REVERB );
|
|
float* pParams = new float[nSize];
|
|
|
|
GetFxPreset( FX_REVERB, 1, pParams );
|
|
|
|
TAudioFx* pFx = new TAudioFx( FX_REVERB, 1, pParams, nSize );
|
|
pTrack->lstFxs.push_back( pFx );
|
|
|
|
if( bApply )
|
|
AudioEffectsSet( iWave );
|
|
}
|
|
}
|
|
|
|
void AudioEffectsSet( int iWave )
|
|
{
|
|
TAudioTrack* pAT = g_aAudioTracks[iWave];
|
|
|
|
for( int i=0; i<pAT->lstFxs.size(); i++ ){
|
|
TAudioFx* pFx = pAT->lstFxs[i];
|
|
|
|
if( S_OK!=AudioApplyEffect( iWave, i, pFx ) ){
|
|
delete pFx;
|
|
pAT->lstFxs.erase( pAT->lstFxs.begin()+i );
|
|
i--;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
void AudioEffectsDefault( int iWave, bool bApply )
|
|
{
|
|
AudioEffectsClear( iWave, bApply );
|
|
|
|
TAudioTrack* pTrack = g_aAudioTracks[iWave];
|
|
|
|
int nBarCount = pTrack->lstBars.size();
|
|
|
|
if( nBarCount>0 ){
|
|
TEffect* pAE = new TEffect;
|
|
pAE->iBarStart = 0;
|
|
pAE->iPointStart = 0;
|
|
pAE->iBarEnd = nBarCount;
|
|
pAE->iPointEnd = 0;
|
|
pAE->bOn = true;
|
|
pAE->iPreset = 1; //中等
|
|
pAE->aParams = new float[6];
|
|
GetFxPreset( g_aAudioEffectTypes[3], 1, pAE->aParams );
|
|
|
|
pTrack->lstEffects[3] = pAE;
|
|
|
|
if( bApply ){
|
|
f_MM_AudioFx( iWave, 0, -1, g_aAudioEffectTypes[3], pAE->aParams );
|
|
}
|
|
}
|
|
}
|
|
|
|
void AudioEffectsClear( int iWave, bool bApply )
|
|
{
|
|
TAudioTrack* pTrack = g_aAudioTracks[iWave];
|
|
|
|
//清空音效
|
|
for( int i=0; i<MAX_FX_NUM; i++ ){
|
|
TEffect * pE = pTrack->lstEffects[i];
|
|
|
|
if( pE ){
|
|
if( bApply )
|
|
f_MM_AudioFx( iWave, 0, -1, g_aAudioEffectTypes[i], NULL );
|
|
|
|
while( pE ){
|
|
TEffect *pTemp = pE->pNext;
|
|
delete pE;
|
|
pE = pTemp;
|
|
}
|
|
|
|
pTrack->lstEffects[i] = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool AudioEffectsSort( int iWave, int iFx )
|
|
{
|
|
TAudioTrack* pTrack = g_aAudioTracks[iWave];
|
|
|
|
int nBarCount = pTrack->lstBars.size();
|
|
int iFxStart = iFx, iFxEnd = iFx;
|
|
if( iFx<0 ){
|
|
iFxStart = 0;
|
|
iFxEnd = MAX_FX_NUM-1;
|
|
}
|
|
|
|
bool bCountDown = false;
|
|
for( int i=iFxStart; i<=iFxEnd; i++ ){
|
|
TEffect *pAE = pTrack->lstEffects[i],
|
|
*pHead = pAE,
|
|
*pPrev = NULL;
|
|
|
|
bool bHead = pHead!=NULL;
|
|
while( pAE ){
|
|
DWORD dwStart = pAE->iBarStart * POINTS_PER_BAR + pAE->iPointStart,
|
|
dwEnd = pAE->iBarEnd * POINTS_PER_BAR + pAE->iPointEnd;
|
|
|
|
//清除关闭或短时效果
|
|
if( !pAE->bOn || dwStart+4 >= dwEnd ){
|
|
TEffect* pNext = pAE->pNext;
|
|
|
|
if( pPrev ) pPrev->pNext = pNext;
|
|
if( pHead==pAE ) pHead = pNext;
|
|
|
|
delete pAE;
|
|
pAE = pNext;
|
|
|
|
continue;
|
|
}
|
|
|
|
if( pAE->pNext ){
|
|
DWORD dwNextStart = pAE->pNext->iBarStart * POINTS_PER_BAR
|
|
+ pAE->pNext->iPointStart,
|
|
dwNextEnd = pAE->pNext->iBarEnd * POINTS_PER_BAR
|
|
+ pAE->pNext->iPointEnd;
|
|
|
|
//清除关闭或短时效果
|
|
if( !pAE->pNext->bOn || dwNextStart+4 >= dwNextEnd ){
|
|
TEffect *pTemp = pAE->pNext;
|
|
pAE->pNext = pTemp->pNext;
|
|
delete pTemp;
|
|
|
|
continue;
|
|
}
|
|
else{
|
|
if( dwNextStart - dwEnd <= 4 ){
|
|
if( !memcmp( pAE->aParams, pAE->pNext->aParams, 6*sizeof(float) )){
|
|
pAE->iBarEnd = pAE->pNext->iBarEnd;
|
|
pAE->iPointEnd = pAE->pNext->iPointEnd;
|
|
|
|
TEffect *pTemp = pAE->pNext;
|
|
pAE->pNext = pTemp->pNext;
|
|
delete pTemp;
|
|
|
|
continue;
|
|
}
|
|
else{
|
|
pAE->iBarEnd = (dwNextStart - 1) / POINTS_PER_BAR;
|
|
pAE->iPointEnd = (dwNextStart - 1) % POINTS_PER_BAR;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if( pAE->iBarEnd==nBarCount-1 && pAE->iPointEnd==POINTS_PER_BAR-1 ){
|
|
pAE->iBarEnd = nBarCount;
|
|
pAE->iPointEnd = 0;
|
|
}
|
|
|
|
pPrev = pAE;
|
|
pAE = pAE->pNext;
|
|
}
|
|
|
|
pTrack->lstEffects[i] = pHead;
|
|
|
|
if( bHead && !pHead )
|
|
bCountDown = true;
|
|
}
|
|
|
|
return bCountDown;
|
|
}
|
|
|
|
void AudioEffectsSet( int iWave, bool bOn )
|
|
{
|
|
TAudioTrack* pTrack = g_aAudioTracks[iWave];
|
|
|
|
for( int i=0; i<MAX_FX_NUM; i++ ){
|
|
TEffect * pE = pTrack->lstEffects[i];
|
|
int iFxType = g_aAudioEffectTypes[i];
|
|
|
|
if( bOn ){
|
|
while( pE ){
|
|
double dblStart = pE->iBarStart + (double)pE->iPointStart / POINTS_PER_BAR,
|
|
dblEnd = -1;
|
|
|
|
if( pE->iBarEnd<g_aAudioTracks[iWave]->lstBars.size() )
|
|
dblEnd = pE->iBarEnd + (double)pE->iPointEnd / POINTS_PER_BAR;
|
|
|
|
f_MM_AudioFx( iWave, dblStart, dblEnd, iFxType, pE->aParams );
|
|
|
|
pE = pE->pNext;
|
|
}
|
|
}
|
|
else{
|
|
f_MM_AudioFx( iWave, 0, -1, iFxType, NULL );
|
|
}
|
|
}
|
|
}
|
|
|
|
bool AudioEffectsMove( int iSrc, double dblStart, double dblEnd, int iDest, double dblInsert, int iMode )
|
|
{
|
|
int iStartBar = (int)dblStart,
|
|
iEndBar = (int)dblEnd,
|
|
iInsertBar = (int)dblInsert,
|
|
iStartPoint = (int)( (dblStart-iStartBar) * POINTS_PER_BAR + 0.5 ),
|
|
iEndPoint = (int)( (dblEnd-iEndBar) * POINTS_PER_BAR + 0.5 ),
|
|
iInsertPoint = (int)( (dblInsert-iInsertBar) * POINTS_PER_BAR + 0.5 );
|
|
|
|
int iDelStartBar = iStartBar,
|
|
iDelStartPoint = iStartPoint,
|
|
iDelEndBar = iEndBar,
|
|
iDelEndPoint = iEndPoint,
|
|
iDelStart = iStartBar * POINTS_PER_BAR + iStartPoint,
|
|
iDelEnd = iEndBar * POINTS_PER_BAR + iEndPoint;
|
|
|
|
if( iMode==MODE_MOVE && ( iInsertBar<iStartBar || iInsertBar==iStartBar
|
|
&& iInsertPoint<=iStartPoint )){
|
|
int nLen = ( iEndBar-iStartBar ) * POINTS_PER_BAR + iEndPoint - iStartPoint;
|
|
|
|
iDelStart += nLen;
|
|
iDelEnd += nLen;
|
|
|
|
iDelStartBar = iDelStart / POINTS_PER_BAR;
|
|
iDelStartPoint = iDelStart % POINTS_PER_BAR;
|
|
iDelEndBar = iDelEnd / POINTS_PER_BAR;
|
|
iDelEndPoint = iDelEnd % POINTS_PER_BAR;
|
|
}
|
|
|
|
TAudioTrack *pSrcTrack = iSrc<0 ? NULL : g_aAudioTracks[iSrc],
|
|
*pDestTrack = g_aAudioTracks[iDest];
|
|
|
|
if( iDest>=0 )
|
|
AudioEffectsSet( iDest, false );
|
|
if( iSrc>=0 && iSrc!=iDest )
|
|
AudioEffectsSet( iSrc, false );
|
|
|
|
bool bCountDown = false;
|
|
for(int i = 0; i < MAX_FX_NUM; i++){
|
|
PTEffect pBackupHead = NULL, // 记录备份链表头地址
|
|
pBackupLast = NULL; // 记录备份链表尾地址
|
|
|
|
if( iMode==MODE_MOVE || iMode==MODE_COPY || iMode==MODE_INSERT ){
|
|
if( pSrcTrack ){
|
|
PTEffect pAE = pSrcTrack->lstEffects[i];
|
|
//备份
|
|
while( pAE ) {
|
|
if(pAE->iBarStart > iEndBar || pAE->iBarStart==iEndBar
|
|
&& pAE->iPointStart>=iEndPoint ){
|
|
break;
|
|
}
|
|
else if(pAE->iBarEnd > iStartBar || pAE->iBarEnd==iStartBar
|
|
&& pAE->iPointEnd > iStartPoint ) {
|
|
TEffect *pNewLast = new TEffect( pAE );
|
|
|
|
if(pBackupHead == NULL) {
|
|
pBackupHead = pNewLast;
|
|
pBackupLast = pNewLast;
|
|
}
|
|
else {
|
|
pBackupLast->pNext = pNewLast;
|
|
pBackupLast = pNewLast;
|
|
}
|
|
|
|
if(pAE->iBarStart < iStartBar || pAE->iBarStart==iStartBar
|
|
&& pAE->iPointStart < iStartPoint ) {
|
|
// 相对位置
|
|
pNewLast->iBarStart = iInsertBar;
|
|
pNewLast->iPointStart = iInsertPoint;
|
|
}
|
|
else {
|
|
pNewLast->iBarStart = pAE->iBarStart - iStartBar + iInsertBar;
|
|
pNewLast->iPointStart = pAE->iPointStart - iStartPoint + iInsertPoint;
|
|
|
|
if( pNewLast->iPointStart<0 ){
|
|
pNewLast->iPointStart += POINTS_PER_BAR;
|
|
pNewLast->iBarStart--;
|
|
}
|
|
else if( pNewLast->iPointStart>=POINTS_PER_BAR ){
|
|
pNewLast->iPointStart -= POINTS_PER_BAR;
|
|
pNewLast->iBarStart++;
|
|
}
|
|
}
|
|
|
|
int iEB = iInsertBar - iStartBar,
|
|
iEP = iInsertPoint - iStartPoint;
|
|
|
|
if( pAE->iBarEnd < iEndBar || pAE->iBarEnd==iEndBar
|
|
&& pAE->iPointEnd < iEndPoint ){
|
|
iEB += pAE->iBarEnd;
|
|
iEP += pAE->iPointEnd;
|
|
}
|
|
else{
|
|
iEB += iEndBar;
|
|
iEP += iEndPoint;
|
|
}
|
|
|
|
pNewLast->iBarEnd = iEB;
|
|
pNewLast->iPointEnd = iEP;
|
|
|
|
if( pNewLast->iPointEnd < 0 ){
|
|
pNewLast->iPointEnd += POINTS_PER_BAR;
|
|
pNewLast->iBarEnd--;
|
|
}
|
|
else if( pNewLast->iPointEnd >= POINTS_PER_BAR ){
|
|
pNewLast->iPointEnd -= POINTS_PER_BAR;
|
|
pNewLast->iBarEnd++;
|
|
}
|
|
}
|
|
|
|
pAE = pAE->pNext;
|
|
}
|
|
}
|
|
|
|
// 插入并记录插入点
|
|
PTEffect pAE = pDestTrack->lstEffects[i],
|
|
pPrev = NULL,
|
|
pNext = NULL;
|
|
|
|
while(pAE) {
|
|
if( iInsertBar < pAE->iBarStart || iInsertBar==pAE->iBarStart
|
|
&& iInsertPoint<=pAE->iPointStart ){
|
|
pNext = pAE;
|
|
break;
|
|
}
|
|
else if( iInsertBar > pAE->iBarEnd || iInsertBar==pAE->iBarEnd
|
|
&& iInsertPoint > pAE->iPointEnd ){
|
|
pPrev = pAE;
|
|
}
|
|
else{
|
|
// 拆分
|
|
TEffect *pNewEffect = new TEffect( pAE );
|
|
pNewEffect->iBarStart = iInsertBar;
|
|
pNewEffect->iPointStart = iInsertPoint;
|
|
pNewEffect->pNext = pAE->pNext;
|
|
|
|
pAE->iBarEnd = iInsertBar;
|
|
pAE->iPointEnd = iInsertPoint - 1;
|
|
pAE->pNext = pNewEffect;
|
|
|
|
if( pAE->iPointEnd<0 ){
|
|
pAE->iPointEnd += POINTS_PER_BAR;
|
|
pAE->iBarEnd--;
|
|
}
|
|
|
|
pPrev = pAE;
|
|
pNext = pNewEffect;
|
|
|
|
break;
|
|
}
|
|
|
|
pAE = pAE->pNext;
|
|
}
|
|
|
|
if( pBackupHead ){
|
|
if( pPrev ){
|
|
pPrev->pNext = pBackupHead;
|
|
}
|
|
else{
|
|
pDestTrack->lstEffects[i] = pBackupHead;
|
|
}
|
|
|
|
pBackupLast->pNext = pNext;
|
|
}
|
|
|
|
// 修正
|
|
int nBar = iEndBar - iStartBar,
|
|
nPoint = iEndPoint - iStartPoint;
|
|
pAE = pNext;
|
|
while(pAE) {
|
|
if( !(iMode==MODE_INSERT && pAE==pNext && !pBackupHead && pAE->iBarStart==iInsertBar
|
|
&& pAE->iPointStart==iInsertPoint )){
|
|
pAE->iBarStart += nBar;
|
|
pAE->iPointStart += nPoint;
|
|
|
|
if( pAE->iPointStart<0 ){
|
|
pAE->iPointStart += POINTS_PER_BAR;
|
|
pAE->iBarStart--;
|
|
}
|
|
else if( pAE->iPointStart>=POINTS_PER_BAR ){
|
|
pAE->iPointStart -= POINTS_PER_BAR;
|
|
pAE->iBarStart++;
|
|
}
|
|
}
|
|
|
|
pAE->iBarEnd += nBar;
|
|
pAE->iPointEnd += nPoint;
|
|
|
|
if( pAE->iPointEnd < 0 ){
|
|
pAE->iPointEnd += POINTS_PER_BAR;
|
|
pAE->iBarEnd--;
|
|
}
|
|
else if( pAE->iPointEnd >= POINTS_PER_BAR ){
|
|
pAE->iPointEnd -= POINTS_PER_BAR;
|
|
pAE->iBarEnd++;
|
|
}
|
|
|
|
pAE = pAE->pNext;
|
|
}
|
|
}
|
|
|
|
// 删除
|
|
if( iMode==MODE_DELETE || iMode==MODE_MOVE ){
|
|
PTEffect pAE = pSrcTrack->lstEffects[i],
|
|
pPrev = NULL,
|
|
pNext = NULL;
|
|
|
|
while( pAE ) {
|
|
int iAEStart = pAE->iBarStart * POINTS_PER_BAR + pAE->iPointStart,
|
|
iAEEnd = pAE->iBarEnd * POINTS_PER_BAR + pAE->iPointEnd;
|
|
|
|
if( iAEStart>=iDelStart && iAEEnd<=iDelEnd ){
|
|
if( pPrev )
|
|
pPrev->pNext = pAE->pNext;
|
|
else
|
|
pSrcTrack->lstEffects[i] = pAE->pNext;
|
|
|
|
PTEffect pTemp = pAE;
|
|
pAE = pAE->pNext;
|
|
delete pTemp;
|
|
|
|
continue;
|
|
}
|
|
else if( iAEStart < iDelStart ){
|
|
pPrev = pAE;
|
|
|
|
if( iAEEnd > iDelStart ){
|
|
if( iAEEnd > iDelEnd ){ //拆分
|
|
TEffect* pBreak = new TEffect( pAE );
|
|
pBreak->iBarStart = iDelEndBar;
|
|
pBreak->iPointStart = iDelEndPoint;
|
|
|
|
pBreak->pNext = pAE->pNext;
|
|
pAE->pNext = pBreak;
|
|
}
|
|
|
|
pAE->iBarEnd = iDelStartBar;
|
|
pAE->iPointEnd = iDelStartPoint;
|
|
}
|
|
}
|
|
else if( iAEEnd > iDelStart ){
|
|
if( iAEStart < iDelEnd ){
|
|
pAE->iBarStart = iDelEndBar;
|
|
pAE->iPointStart = iDelEndPoint;
|
|
}
|
|
|
|
pNext = pAE;
|
|
break;
|
|
}
|
|
|
|
pAE = pAE->pNext;
|
|
}
|
|
|
|
if( pNext ){
|
|
// 修正
|
|
int nBar = iEndBar - iStartBar,
|
|
nPoint = iEndPoint - iStartPoint;
|
|
pAE = pNext;
|
|
while(pAE) {
|
|
pAE->iBarStart -= nBar;
|
|
pAE->iPointStart -= nPoint;
|
|
|
|
if( pAE->iPointStart<0 ){
|
|
pAE->iPointStart += POINTS_PER_BAR;
|
|
pAE->iBarStart--;
|
|
}
|
|
else if( pAE->iPointStart>=POINTS_PER_BAR ){
|
|
pAE->iPointStart -= POINTS_PER_BAR;
|
|
pAE->iBarStart++;
|
|
}
|
|
|
|
pAE->iBarEnd -= nBar;
|
|
pAE->iPointEnd -= nPoint;
|
|
|
|
if( pAE->iPointEnd < 0 ){
|
|
pAE->iPointEnd += POINTS_PER_BAR;
|
|
pAE->iBarEnd--;
|
|
}
|
|
else if( pAE->iPointEnd >= POINTS_PER_BAR ){
|
|
pAE->iPointEnd -= POINTS_PER_BAR;
|
|
pAE->iBarEnd++;
|
|
}
|
|
|
|
pAE = pAE->pNext;
|
|
}
|
|
}
|
|
else if( !pPrev ){
|
|
pSrcTrack->lstEffects[i] = NULL;
|
|
}
|
|
}
|
|
|
|
if( iDest>=0 )
|
|
bCountDown |= AudioEffectsSort( iDest, i );
|
|
if( iSrc>=0 && iSrc!=iDest )
|
|
bCountDown |= AudioEffectsSort( iSrc, i );
|
|
}
|
|
|
|
if( iDest>=0 )
|
|
AudioEffectsSet( iDest, true );
|
|
if( iSrc>=0 && iSrc!=iDest )
|
|
AudioEffectsSet( iSrc, true );
|
|
|
|
return bCountDown;
|
|
}
|
|
|
|
void ClearAudioEffects( TEffect* lstEffects[] )
|
|
{
|
|
//清空音效
|
|
for( int i=0; i<MAX_FX_NUM; i++ ){
|
|
TEffect * pE = lstEffects[i];
|
|
|
|
if( pE ){
|
|
while( pE ){
|
|
TEffect *pTemp = pE->pNext;
|
|
delete pE;
|
|
pE = pTemp;
|
|
}
|
|
|
|
lstEffects[i] = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CopyAudioEffects( TEffect* lstDest[], TEffect* lstSrc[], double dblStart, double dblEnd )
|
|
{
|
|
int iStartBar = (int)dblStart,
|
|
iEndBar = (int)dblEnd,
|
|
iStartPoint = (int)( (dblStart-iStartBar) * POINTS_PER_BAR + 0.5 ),
|
|
iEndPoint = (int)( (dblEnd-iEndBar) * POINTS_PER_BAR + 0.5 );
|
|
|
|
if( !lstDest || !lstSrc || iEndBar<iStartBar
|
|
|| iEndBar==iStartBar && iEndPoint<=iStartPoint )
|
|
return;
|
|
|
|
for(int i = 0; i < MAX_FX_NUM; i++){
|
|
PTEffect pBackupHead = NULL, // 记录备份链表头地址
|
|
pBackupLast = NULL; // 记录备份链表尾地址
|
|
PTEffect pAE = lstSrc[i];
|
|
|
|
//备份
|
|
while( pAE ) {
|
|
if( pAE->iBarStart > iEndBar || pAE->iBarStart==iEndBar
|
|
&& pAE->iPointStart>=iEndPoint ){
|
|
break;
|
|
}
|
|
else if(pAE->iBarEnd > iStartBar || pAE->iBarEnd==iStartBar
|
|
&& pAE->iPointEnd > iStartPoint ) {
|
|
TEffect *pNewLast = new TEffect( pAE );
|
|
|
|
if( pBackupHead == NULL ){
|
|
pBackupHead = pNewLast;
|
|
pBackupLast = pNewLast;
|
|
}
|
|
else{
|
|
pBackupLast->pNext = pNewLast;
|
|
pBackupLast = pNewLast;
|
|
}
|
|
|
|
if( pAE->iBarStart < iStartBar || pAE->iBarStart==iStartBar
|
|
&& pAE->iPointStart < iStartPoint ){
|
|
// 相对位置
|
|
pNewLast->iBarStart = 0;
|
|
pNewLast->iPointStart = 0;
|
|
}
|
|
else {
|
|
pNewLast->iBarStart = pAE->iBarStart - iStartBar;
|
|
pNewLast->iPointStart = pAE->iPointStart - iStartPoint;
|
|
|
|
if( pNewLast->iPointStart<0 ){
|
|
pNewLast->iPointStart += POINTS_PER_BAR;
|
|
pNewLast->iBarStart--;
|
|
}
|
|
else if( pNewLast->iPointStart>=POINTS_PER_BAR ){
|
|
pNewLast->iPointStart -= POINTS_PER_BAR;
|
|
pNewLast->iBarStart++;
|
|
}
|
|
}
|
|
|
|
if( pAE->iBarEnd < iEndBar || pAE->iBarEnd==iEndBar
|
|
&& pAE->iPointEnd < iEndPoint ){
|
|
pNewLast->iBarEnd = pAE->iBarEnd - iStartBar;
|
|
pNewLast->iPointEnd = pAE->iPointEnd - iStartPoint;
|
|
}
|
|
else{
|
|
pNewLast->iBarEnd = iEndBar - iStartBar;
|
|
pNewLast->iPointEnd = iEndPoint - iStartPoint;
|
|
}
|
|
|
|
if( pNewLast->iPointEnd < 0 ){
|
|
pNewLast->iPointEnd += POINTS_PER_BAR;
|
|
pNewLast->iBarEnd--;
|
|
}
|
|
else if( pNewLast->iPointEnd >= POINTS_PER_BAR ){
|
|
pNewLast->iPointEnd -= POINTS_PER_BAR;
|
|
pNewLast->iBarEnd++;
|
|
}
|
|
}
|
|
|
|
pAE = pAE->pNext;
|
|
}
|
|
|
|
lstDest[i] = pBackupHead;
|
|
}
|
|
}
|
|
|
|
void InsertAudioEffetcts( TEffect* lstDest[], TEffect* lstSrc[], double dblInsert, double dblLen )
|
|
{
|
|
if( !lstDest )
|
|
return;
|
|
|
|
int iInsertBar = (int)dblInsert,
|
|
iInsertPoint = (int)( (dblInsert-iInsertBar) * POINTS_PER_BAR + 0.5 ),
|
|
nLenBar = (int)dblLen,
|
|
nLenPoint = (int)( (dblLen-nLenBar) * POINTS_PER_BAR + 0.5 );
|
|
|
|
for(int i = 0; i < MAX_FX_NUM; i++){
|
|
PTEffect pSetHead = NULL, // 记录备份链表头地址
|
|
pSetTail = NULL; // 记录备份链表尾地址
|
|
|
|
if( lstSrc && lstSrc[i] ){
|
|
PTEffect pTemp = lstSrc[i];
|
|
while( pTemp ){
|
|
TEffect *pAE = new TEffect( pTemp );
|
|
|
|
pAE->iBarStart += iInsertBar;
|
|
pAE->iPointStart += iInsertPoint;
|
|
|
|
if( pAE->iPointStart<0 ){
|
|
pAE->iPointStart += POINTS_PER_BAR;
|
|
pAE->iBarStart--;
|
|
}
|
|
else if( pAE->iPointStart>=POINTS_PER_BAR ){
|
|
pAE->iPointStart -= POINTS_PER_BAR;
|
|
pAE->iBarStart++;
|
|
}
|
|
|
|
pAE->iBarEnd += iInsertBar;
|
|
pAE->iPointEnd += iInsertPoint;
|
|
|
|
if( pAE->iPointEnd < 0 ){
|
|
pAE->iPointEnd += POINTS_PER_BAR;
|
|
pAE->iBarEnd--;
|
|
}
|
|
else if( pAE->iPointEnd >= POINTS_PER_BAR ){
|
|
pAE->iPointEnd -= POINTS_PER_BAR;
|
|
pAE->iBarEnd++;
|
|
}
|
|
|
|
if( pSetHead == NULL ){
|
|
pSetHead = pAE;
|
|
pSetTail = pAE;
|
|
}
|
|
else{
|
|
pSetTail->pNext = pAE;
|
|
pSetTail = pSetTail->pNext;
|
|
}
|
|
|
|
pTemp = pTemp->pNext;
|
|
}
|
|
}
|
|
|
|
// 插入并记录插入点
|
|
PTEffect pAE = lstDest[i],
|
|
pPrev = NULL,
|
|
pNext = NULL;
|
|
|
|
while(pAE) {
|
|
if( iInsertBar < pAE->iBarStart || iInsertBar==pAE->iBarStart
|
|
&& iInsertPoint<=pAE->iPointStart ){
|
|
pNext = pAE;
|
|
break;
|
|
}
|
|
else if( iInsertBar > pAE->iBarEnd || iInsertBar==pAE->iBarEnd
|
|
&& iInsertPoint > pAE->iPointEnd ){
|
|
pPrev = pAE;
|
|
}
|
|
else{
|
|
// 拆分
|
|
TEffect *pNewEffect = new TEffect( pAE );
|
|
pNewEffect->iBarStart = iInsertBar;
|
|
pNewEffect->iPointStart = iInsertPoint;
|
|
pNewEffect->pNext = pAE->pNext;
|
|
|
|
pAE->iBarEnd = iInsertBar;
|
|
pAE->iPointEnd = iInsertPoint;
|
|
pAE->pNext = pNewEffect;
|
|
|
|
if( pAE->iPointEnd<0 ){
|
|
pAE->iPointEnd += POINTS_PER_BAR;
|
|
pAE->iBarEnd--;
|
|
}
|
|
|
|
pPrev = pAE;
|
|
pNext = pNewEffect;
|
|
|
|
break;
|
|
}
|
|
|
|
pAE = pAE->pNext;
|
|
}
|
|
|
|
if( pSetHead ){
|
|
if( pPrev )
|
|
pPrev->pNext = pSetHead;
|
|
else
|
|
lstDest[i] = pSetHead;
|
|
|
|
pSetTail->pNext = pNext;
|
|
}
|
|
|
|
// 修正
|
|
pAE = pNext;
|
|
while(pAE) {
|
|
pAE->iBarStart += nLenBar;
|
|
pAE->iPointStart += nLenPoint;
|
|
|
|
if( pAE->iPointStart<0 ){
|
|
pAE->iPointStart += POINTS_PER_BAR;
|
|
pAE->iBarStart--;
|
|
}
|
|
else if( pAE->iPointStart>=POINTS_PER_BAR ){
|
|
pAE->iPointStart -= POINTS_PER_BAR;
|
|
pAE->iBarStart++;
|
|
}
|
|
|
|
pAE->iBarEnd += nLenBar;
|
|
pAE->iPointEnd += nLenPoint;
|
|
|
|
if( pAE->iPointEnd < 0 ){
|
|
pAE->iPointEnd += POINTS_PER_BAR;
|
|
pAE->iBarEnd--;
|
|
}
|
|
else if( pAE->iPointEnd >= POINTS_PER_BAR ){
|
|
pAE->iPointEnd -= POINTS_PER_BAR;
|
|
pAE->iBarEnd++;
|
|
}
|
|
|
|
pAE = pAE->pNext;
|
|
}
|
|
|
|
SortAudioEffects( &lstDest[i] );
|
|
}
|
|
}
|
|
|
|
void SortAudioEffects( TEffect** lstEffect )
|
|
{
|
|
TEffect *pAE = *lstEffect,
|
|
*pHead = pAE,
|
|
*pPrev = NULL;
|
|
|
|
while( pAE ){
|
|
DWORD dwStart = pAE->iBarStart * POINTS_PER_BAR + pAE->iPointStart,
|
|
dwEnd = pAE->iBarEnd * POINTS_PER_BAR + pAE->iPointEnd;
|
|
|
|
//清除关闭或短时效果
|
|
if( !pAE->bOn || dwStart+4 >= dwEnd ){
|
|
TEffect* pNext = pAE->pNext;
|
|
|
|
if( pPrev ) pPrev->pNext = pNext;
|
|
if( pHead==pAE ) pHead = pNext;
|
|
|
|
delete pAE;
|
|
pAE = pNext;
|
|
|
|
continue;
|
|
}
|
|
|
|
if( pAE->pNext ){
|
|
DWORD dwNextStart = pAE->pNext->iBarStart * POINTS_PER_BAR
|
|
+ pAE->pNext->iPointStart,
|
|
dwNextEnd = pAE->pNext->iBarEnd * POINTS_PER_BAR
|
|
+ pAE->pNext->iPointEnd;
|
|
|
|
//清除关闭或短时效果
|
|
if( !pAE->pNext->bOn || dwNextStart+4 >= dwNextEnd ){
|
|
TEffect *pTemp = pAE->pNext;
|
|
pAE->pNext = pTemp->pNext;
|
|
delete pTemp;
|
|
|
|
continue;
|
|
}
|
|
else{
|
|
if( dwNextStart - dwEnd <= 4 ){
|
|
if( !memcmp( pAE->aParams, pAE->pNext->aParams, 6*sizeof(float) )){
|
|
pAE->iBarEnd = pAE->pNext->iBarEnd;
|
|
pAE->iPointEnd = pAE->pNext->iPointEnd;
|
|
|
|
TEffect *pTemp = pAE->pNext;
|
|
pAE->pNext = pTemp->pNext;
|
|
delete pTemp;
|
|
|
|
continue;
|
|
}
|
|
else{
|
|
pAE->iBarEnd = (dwNextStart - 1) / POINTS_PER_BAR;
|
|
pAE->iPointEnd = (dwNextStart - 1) % POINTS_PER_BAR;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pPrev = pAE;
|
|
pAE = pAE->pNext;
|
|
}
|
|
|
|
*lstEffect = pHead;
|
|
}
|
|
|
|
void RemoveAudioEffects( TEffect* lstEffects[], double dblStart, double dblEnd )
|
|
{
|
|
int iStartBar = (int)dblStart,
|
|
iEndBar = (int)dblEnd,
|
|
iStartPoint = (int)( (dblStart-iStartBar) * POINTS_PER_BAR + 0.5 ),
|
|
iEndPoint = (int)( (dblEnd-iEndBar) * POINTS_PER_BAR + 0.5 ),
|
|
iDelStart = iStartBar * POINTS_PER_BAR + iStartPoint,
|
|
iDelEnd = iEndBar * POINTS_PER_BAR + iEndPoint;
|
|
|
|
for(int i = 0; i < MAX_FX_NUM; i++){
|
|
PTEffect pAE = lstEffects[i],
|
|
pPrev = NULL,
|
|
pNext = NULL;
|
|
|
|
while( pAE ) {
|
|
int iAEStart = pAE->iBarStart * POINTS_PER_BAR + pAE->iPointStart,
|
|
iAEEnd = pAE->iBarEnd * POINTS_PER_BAR + pAE->iPointEnd;
|
|
|
|
if( iAEStart>=iDelStart && iAEEnd<=iDelEnd ){
|
|
if( pPrev )
|
|
pPrev->pNext = pAE->pNext;
|
|
else
|
|
lstEffects[i] = pAE->pNext;
|
|
|
|
PTEffect pTemp = pAE;
|
|
pAE = pAE->pNext;
|
|
delete pTemp;
|
|
|
|
continue;
|
|
}
|
|
else if( iAEStart < iDelStart ){
|
|
pPrev = pAE;
|
|
|
|
if( iAEEnd > iDelStart ){
|
|
if( iAEEnd > iDelEnd ){ //拆分
|
|
TEffect* pBreak = new TEffect( pAE );
|
|
pBreak->iBarStart = iEndBar;
|
|
pBreak->iPointStart = iEndPoint;
|
|
|
|
pBreak->pNext = pAE->pNext;
|
|
pAE->pNext = pBreak;
|
|
}
|
|
|
|
pAE->iBarEnd = iStartBar;
|
|
pAE->iPointEnd = iStartPoint;
|
|
}
|
|
}
|
|
else if( iAEEnd > iDelStart ){
|
|
if( iAEStart < iDelEnd ){
|
|
pAE->iBarStart = iEndBar;
|
|
pAE->iPointStart = iEndPoint;
|
|
}
|
|
|
|
pNext = pAE;
|
|
break;
|
|
}
|
|
|
|
pAE = pAE->pNext;
|
|
}
|
|
|
|
if( pNext ){
|
|
// 修正
|
|
int nBar = iEndBar - iStartBar,
|
|
nPoint = iEndPoint - iStartPoint;
|
|
pAE = pNext;
|
|
while(pAE) {
|
|
pAE->iBarStart -= nBar;
|
|
pAE->iPointStart -= nPoint;
|
|
|
|
if( pAE->iPointStart<0 ){
|
|
pAE->iPointStart += POINTS_PER_BAR;
|
|
pAE->iBarStart--;
|
|
}
|
|
else if( pAE->iPointStart>=POINTS_PER_BAR ){
|
|
pAE->iPointStart -= POINTS_PER_BAR;
|
|
pAE->iBarStart++;
|
|
}
|
|
|
|
pAE->iBarEnd -= nBar;
|
|
pAE->iPointEnd -= nPoint;
|
|
|
|
if( pAE->iPointEnd < 0 ){
|
|
pAE->iPointEnd += POINTS_PER_BAR;
|
|
pAE->iBarEnd--;
|
|
}
|
|
else if( pAE->iPointEnd >= POINTS_PER_BAR ){
|
|
pAE->iPointEnd -= POINTS_PER_BAR;
|
|
pAE->iBarEnd++;
|
|
}
|
|
|
|
pAE = pAE->pNext;
|
|
}
|
|
}
|
|
else if( !pPrev ){
|
|
lstEffects[i] = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
TEffect* DuplicateEffects( TEffect* pSrcHead )
|
|
{
|
|
TEffect *pDestHead = NULL,
|
|
*pAE = pSrcHead,
|
|
*pPrev = NULL;
|
|
|
|
while( pAE ){
|
|
TEffect* pNew = new TEffect( pAE );
|
|
if( !pPrev ){
|
|
pDestHead = pPrev = pNew;
|
|
}
|
|
else{
|
|
pPrev->pNext = pNew;
|
|
pPrev = pNew;
|
|
}
|
|
|
|
pAE = pAE->pNext;
|
|
}
|
|
|
|
return pDestHead;
|
|
}
|
|
*/
|