//--------------------------------------------------------------------------- #include #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; ilstFxs.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; ilstEffects[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; ilstEffects[i]; int iFxType = g_aAudioEffectTypes[i]; if( bOn ){ while( pE ){ double dblStart = pE->iBarStart + (double)pE->iPointStart / POINTS_PER_BAR, dblEnd = -1; if( pE->iBarEndlstBars.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=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; ipNext; 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 || iEndBariBarStart > 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; } */