//--------------------------------------------------------------------------- #include #pragma hdrstop #include "GlobalUnit.h" #include "AudioTrack.h" #include "Undo.h" #include "Project.h" //--------------------------------------------------------------------------- #pragma package(smart_init) /***************************************************************************************/ // 全局变量 /***************************************************************************************/ TAudio g_Audio; TAudioTrackList& g_aAudioTracks = g_Audio.AudioTracks(); //全曲音频轨道(最大4组) int g_iSelAudio = 0; // 当前处理的音频轨 /***************************************************************************************/ // TAudio类函数 /***************************************************************************************/ void TAudio::CopyTrackList( int iStartBar, int nCopyBars, TAudioTrackList* lstAudio, bool bFx ) { int iTrkStart = 1, iTrkEnd = m_lstTracks.size(); if( g_iPreStage==0/*iTrkEnd==iTrkStart*/ ) iTrkStart = 0; for( int i=iTrkStart; ilstBars.empty() ) lstAudio->push_back( CopyTrack( i, iStartBar, nCopyBars, bFx ) ); } } TAudioTrack* TAudio::CopyTrack( int iTrack, int iStartBar, int nCopyBars, bool bFx, TAudioTrack* pDest ) { TAudioTrack* pSrcTrack = m_lstTracks[iTrack], *pDestTrack = pDest ? pDest : new TAudioTrack(); pDestTrack->state = pSrcTrack->state; pDestTrack->volume = pSrcTrack->volume; pDestTrack->pan = pSrcTrack->pan; pDestTrack->gain = pSrcTrack->gain; for( int i=0; ilstBars.push_back( new TWaveBar( pSrcTrack->lstBars[iStartBar+i] ) ); } if( bFx ){ for( int i=0; ilstFxs.size(); i++ ) pDestTrack->lstFxs.push_back( new TAudioFx( pSrcTrack->lstFxs[i]) ); } return pDestTrack; } void TAudio::ResetTracks( TAudioTrackList* lstAudio ) { //处理音频 while( m_lstTracks.size()>1 ){ delete m_lstTracks.back(); m_lstTracks.pop_back(); } for( int i=0; isize(); i++ ){ //替换AudioTrack TAudioTrack* pNewTrack = DuplicateAudioTrack( (*lstAudio)[i] ); m_lstTracks.push_back( pNewTrack ); AudioEffectsSet( i+1 ); } /* if( m_lstTracks.size()>1 ){ m_lstTracks[0]->bHide = true; } */ } void TAudio::RestoreAudio( TOpusStageList* lstStages, TAudioTrackList* lstAudio, bool bUndo ) { int iOrigStage = 0, iVarBar = 0; TOpusStageList::iterator iterDest = lstStages->begin(), iterSrc = g_lstOpusStages.begin(); int iDestBar(0), iSrcBar(0);//, iDVB(0), iSVB(0); while( iterDest!=lstStages->end() && iterSrc!=g_lstOpusStages.end() ){ TOpusStage *pSrcStage = *iterSrc, *pDestStage = *iterDest; if( pSrcStage->iSegTypeiSegTypeaBars.size(), pDestStage->aBars.size() ); if( nBar==pSrcStage->aBars.size() ){ iterSrc++; } if( nBar==pDestStage->aBars.size() ){ iterDest++; } iDestBar += nBar; iSrcBar += nBar; } else if( pSrcStage->iSegTypeiSegType>=SEGTYPE_INTRO ){ //undo情况 int nBar = pDestStage->aBars.size(); iDestBar += nBar; iSrcBar += nBar; iterDest++; } else if( pSrcStage->iSegType>=SEGTYPE_INTRO && pDestStage->iSegTypeaBars.size(); for( int i=1; iiSegType==SEGTYPE_INTRO && pDestStage->iSegType==SEGTYPE_ENDING ){//redo情况 //删掉音频 int nBar = pSrcStage->aBars.size(); for( int i=1; iiSegType==SEGTYPE_ENDING && pDestStage->iSegType==SEGTYPE_INTRO ){//undo情况 int nBar = pDestStage->aBars.size(); iDestBar += nBar; iSrcBar += nBar; iterDest++; } else{ //前尾奏类型相同 //redo比较长度并插入空白或删除 if( !bUndo ){ if( pDestStage->aBars.size() > pSrcStage->aBars.size() ){ int nBar = pDestStage->aBars.size() - pSrcStage->aBars.size(), iInsBar = iSrcBar + pSrcStage->aBars.size(); for( int i=1; iaBars.size() < pSrcStage->aBars.size() ){ int nBar = pSrcStage->aBars.size() - pDestStage->aBars.size(), iDelBar = iSrcBar + pDestStage->aBars.size(); for( int i=1; iaBars.size(); iDestBar += pDestStage->aBars.size(); iterSrc++; iterDest++; } } while( iterDest!=lstStages->end() ){ //undo情况 int nBar = (*iterDest)->aBars.size(); iDestBar += nBar; iterDest++; } //处理音频 if( lstAudio ){ for( int i=1; ilstBars.size() ); if( pSrc ){ for( int i=0; ilstBars.size(); i++ ){ TWaveBar* pWvBar = new TWaveBar; memcpy( pWvBar->aVols, pSrc->lstBars[i], sizeof(DWORD)*POINTS_PER_BAR ); pAT->lstBars.push_back( pWvBar ); } } } } } } void TAudio::WriteProj( FILE* pFile ) { int num = m_lstTracks.size(); fwrite( &num, sizeof(int), 1, pFile ); for( int i=0; ilstBars.size(); fwrite( &nBars, sizeof(int), 1, pFile ); // fwrite( &bHide, sizeof(BYTE), 1, pFile ); // fwrite( &bMute, sizeof(BYTE), 1, pFile ); fwrite( &pAT->state, sizeof(BYTE), 1, pFile ); fwrite( &pAT->volume, sizeof(BYTE), 1, pFile ); fwrite( &pAT->pan, sizeof(char), 1, pFile ); fwrite( &pAT->gain, sizeof(char), 1, pFile ); // fwrite( &iShow, sizeof(BYTE), 1, pFile ); int count = pAT->lstFxs.size(); fwrite( &count, sizeof(int), 1, pFile ); for( int j=0; jlstFxs[j]; fwrite( &pFx->iFx, sizeof(int), 1, pFile ); fwrite( &pFx->iPreset, sizeof(int), 1, pFile ); fwrite( &pFx->bBypass, sizeof(WORD), 1, pFile ); fwrite( &pFx->nParamSize, sizeof(WORD), 1, pFile ); if( pFx->nParamSize>0 ) fwrite( pFx->pParam, sizeof(float), pFx->nParamSize, pFile ); if( pFx->iFx >= FX_VST ){ VSTINFO* pVST = g_lstVSTFx[pFx->iFx-FX_VST]; DWORD uniqueID = pVST->uniqueID; fwrite( &uniqueID, sizeof(DWORD), 1, pFile ); if( pFx->iPreset>=0 ){ uniqueID = pVST->aPlugins[pFx->iPreset]->id; fwrite( &uniqueID, sizeof(DWORD), 1, pFile ); } } } } } int TAudio::ReadProj( FILE* pFile, DWORD dwVersion ) { WORD wMajVersion = HIWORD( dwVersion ), wMinVersion = LOWORD( dwVersion ); int iError = E_PROJ_NOERROR; int num; fread( &num, sizeof(int), 1, pFile ); for( int i=0; ilstBars.push_back( pWvBar ); } if( wMajVersion==5 && wMinVersion>=6 ){ fread( &pAT->state, sizeof(BYTE), 1, pFile ); fread( &pAT->volume, sizeof(BYTE), 1, pFile ); fread( &pAT->pan, sizeof(char), 1, pFile ); fread( &pAT->gain, sizeof(char), 1, pFile ); int count = 0; fread( &count, sizeof(int), 1, pFile ); for( int j=0; j0 ){ pParam = new float[nParamSize]; fread( pParam, sizeof(float), nParamSize, pFile ); } if( iFx >= FX_VST ){ DWORD uniqueID = 0, pluginID = 0; fread( &uniqueID, sizeof(DWORD), 1, pFile ); if( iPreset>=0 ) fread( &pluginID, sizeof(int), 1, pFile ); bAdd = false; for( int k=0; kuniqueID ){ iFx = FX_VST + k; if( iPreset<0 ){ bAdd = true; } else{ for( int p=0; paPlugins.size(); p++ ){ if( g_lstVSTFx[k]->aPlugins[p]->id==pluginID ){ iPreset = p; bAdd = true; break; } } } break; } } } if( bAdd ){ TAudioFx* pFx = new TAudioFx( iFx, iPreset, pParam, nParamSize, bBypass ); pAT->lstFxs.push_back( pFx ); } else{ iError |= E_PROJ_INVALIDFX; } } } else{ BYTE bHide, bMute, iShow; fread( &bHide, sizeof(BYTE), 1, pFile ); fread( &bMute, sizeof(BYTE), 1, pFile ); fread( &pAT->volume, sizeof(BYTE), 1, pFile ); fread( &iShow, sizeof(BYTE), 1, pFile ); if( bHide ) pAT->Hide(); if( bMute ) pAT->Mute(); for( int k=0; k=pAT->lstBars.size()-1 ){ int iType = g_aAudioEffectTypes[k]; if( iType!=FX_PITCH ){ int nSize = GetFxParamNum( iType ); float* pParams = new float[nSize]; int iPreset = pAE.iPreset; int nPresetCount = GetFxPresetCount( iType ); if( pAE.bOn ) memcpy( pParams, pAE.aParams, sizeof(float)*nSize ); else{ if( iPreset>=nPresetCount ) iPreset = 0; GetFxPreset( iType, iPreset, pParams ); } TAudioFx* pFx = new TAudioFx( iType, iPreset, pParams, nSize, !pAE.bOn ); pAT->lstFxs.push_back( pFx ); } } else{ iError |= E_PROJ_INVALIDFX; } } } } } return iError; } /***************************************************************************************/ // 全局函数 /***************************************************************************************/ TAudioTrack* NewAudioTrack( int nBar, bool bAddUndo ) { TAudioTrack* pTrack = NULL; if( g_aAudioTracks.size()1 ){ int iTrack = g_aAudioTracks.size()-1; for( int i=0; ilstBars.push_back( pBar ); } if( bAddUndo ){ f_MM_AudioNewTrack(); g_Undo.AddUndo( UNDO_TRKAUD_ADD, iTrack, 0, 0, NULL, NULL ); f_MM_AddUndoBefore( 0, NULL ); f_MM_AddUndoAfter( 1, &iTrack ); } g_aAudioTracks[0]->Hide(); } PostMessage( Application->MainFormHandle, UM_ENABLERECORD, 0, 0 ); } return pTrack; } void DeleteAudioTrack( int iTrack, bool bAddUndo ) { if( iTrack>0 && iTrack>=g_aAudioTracks.size() ) return; int num = 1, iDelTrk = iTrack; TAudioTrackList* aTracks = NULL; // TAudioTrack* aTracks = NULL; if( iTrack<0 ){ if( g_iPreStage==0 ){ if( g_aAudioTracks[0]->lstBars.empty() ) return; else iDelTrk = 0; } else if( g_aAudioTracks.size()<=1 ) return; } if( iDelTrk<0 ){ int nBars = g_Opus.BarCount(); num = g_aAudioTracks.size()-1; if( bAddUndo ){ aTracks = new TAudioTrackList; // aTracks = new TAudioTrack[num]; int* aTrks = new int[num]; for( int i=0; i0; i-- ){ if( bAddUndo ) // g_Audio.CopyTrack( i, 0, nBars, true, &aTracks[i-1] ); aTracks->insert( aTracks->begin(), DuplicateAudioTrack( g_aAudioTracks[i] )); f_MM_AudioDeleteTrack( i ); delete g_aAudioTracks.back(); g_aAudioTracks.pop_back(); } } else{ if( bAddUndo ){ aTracks = new TAudioTrackList; aTracks->push_back( DuplicateAudioTrack( g_aAudioTracks[iDelTrk] )); f_MM_AddUndoBefore( 1, &iDelTrk ); } f_MM_AudioDeleteTrack( iDelTrk ); delete g_aAudioTracks[iDelTrk]; if( iDelTrk==0 ) g_aAudioTracks[0] = new TAudioTrack; else g_aAudioTracks.erase( g_aAudioTracks.begin() + iDelTrk ); } if( bAddUndo ){ int iUndoType = iTrack<0 ? UNDO_TRKAUD_DELALL : UNDO_TRKAUD_DEL; g_Undo.AddUndo( iUndoType, iDelTrk, -1, -1, (void*)aTracks, NULL ); } PostMessage( Application->MainFormHandle, UM_ENABLERECORD, 0, 0 ); //Application->MainForm->Perform( UM_ENABLERECORD, 0, 0 ); } void DuplicateRawBars() { if( g_aAudioTracks.size()>1 || g_aAudioTracks[0]->lstBars.empty() ) return; TAudioTrack* pRaw = g_aAudioTracks[0]; TAudioTrack* pAT = DuplicateAudioTrack( pRaw ); g_aAudioTracks.push_back( pAT ); pRaw->Hide(); pAT->Hide(false); f_MM_AudioNewTrack(); f_MM_SetStreamVolume( 0x10+1, pAT->IsMute() ? 0.0 : ( pAT->volume / 100.0) ); MoveAudio( 0, 0, pRaw->lstBars.size(), 1, 0, MODE_INSERT | OPT_BARS ); AudioEffectsSet( g_aAudioTracks.size()-1 ); } TAudioTrack* DuplicateAudioTrack( TAudioTrack* pSrc ) { if( !pSrc ) return NULL; TAudioTrack* pNew = new TAudioTrack( pSrc ); //复制bars for( int i=0; ilstBars.size(); i++ ){ TWaveBar* pWvBar = new TWaveBar; memcpy( pWvBar->aVols, pSrc->lstBars[i]->aVols, sizeof(DWORD)*POINTS_PER_BAR ); pNew->lstBars.push_back( pWvBar ); } for( int i=0; ilstFxs.size(); i++ ){ TAudioFx* pFx = new TAudioFx( pSrc->lstFxs[i] ); pNew->lstFxs.push_back( pFx ); } return pNew; } bool MoveAudio( int iSrcTrack, double dblStart, double dblEnd, int iDestTrack, double dblInsert, int iOption ) { bool bMoveBars = iOption & OPT_BARS, bCountDown = false; int iMode = iOption & 0x0F; 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 ); TAudioTrack *pSrcTrack = iSrcTrack<0 ? NULL : g_aAudioTracks[iSrcTrack], *pDestTrack = iDestTrack<0 ? NULL : g_aAudioTracks[iDestTrack]; if( bMoveBars ){ //小节操作 int nBarCount = iEndBar - iStartBar, iDelBar = iStartBar; if( iMode==MODE_MOVE || iMode==MODE_COPY || iMode==MODE_INSERT ){ TWaveBarList lstCopyBars; for( int i=iStartBar; iaVols, pSrcTrack->lstBars[i]->aVols, sizeof(DWORD)*POINTS_PER_BAR ); lstCopyBars.push_back( pWvBar ); } InsertWaveBars( iDestTrack, iInsertBar, lstCopyBars ); if( iMode==MODE_MOVE && iInsertBariSP ){ int lenP = iEP - iSP; if( iMode==MODE_MOVE || iMode==MODE_COPY ) memcpy( aWave + iPoint, pSrcTrack->lstBars[i]->aVols + iSP, sizeof(DWORD) * lenP ); if( iMode==MODE_MOVE || iMode==MODE_ERASE ) memset( pSrcTrack->lstBars[i]->aVols + iSP, 0, sizeof(DWORD) * lenP ); iPoint += lenP; } else{ break; } } } if( iMode==MODE_MOVE || iMode==MODE_COPY ){ if( iDestTrack==0 ){ //处理增加长度 double dblMinLen = dblInsert + dblEnd - dblStart; if( dblMinLen > pDestTrack->lstBars.size() ){ int nBars = (int)dblMinLen; if( dblMinLen - nBars > 0 ) nBars++; for( int i=pDestTrack->lstBars.size(); ilstBars.push_back( pWvBar ); } } } int iPoint = 0; while( iPoint0 ){ iSP = iInsertPoint; if( iSP + nPoints - iPoint < POINTS_PER_BAR ) iEP = iSP + nPoints - iPoint; } else if( nPoints-iPoint < POINTS_PER_BAR ){ iEP = nPoints - iPoint; } if( iEP > iSP ){ int lenP = iEP - iSP; memcpy( pDestTrack->lstBars[iInsertBar]->aVols + iInsertPoint, aWave + iPoint, sizeof(DWORD) * lenP ); iInsertPoint = 0; iInsertBar++; iPoint += lenP; } else{ break; } } delete[] aWave; } f_MM_AudioMove( iDestTrack, dblInsert, iSrcTrack, dblStart, dblEnd, iMode ); if( g_iSelAudio==0 ) PostMessage( Application->MainForm->Handle, UM_AUTORECOGNITION, iMode, 0 ); } return bCountDown; } int CopyWave( int iTrack, int iStartBar, int iStartPoint, int iEndBar, int iEndPoint, DWORD** aWave ) { bool bT2A = *aWave==NULL; int nSelPoints = ( iEndBar - iStartBar - 1) * POINTS_PER_BAR + (POINTS_PER_BAR - iStartPoint) + iEndPoint; if( bT2A ){ *aWave = new DWORD[nSelPoints]; } TAudioTrack* pTrack = g_aAudioTracks[iTrack]; int iPoint = 0; for( int i=iStartBar; i<=iEndBar; i++ ){ int iSP = 0, iEP = POINTS_PER_BAR; if( i==iStartBar ) iSP = iStartPoint; if( i==iEndBar ) iEP = iEndPoint; if( iEP>iSP ){ char *pSrc = (char*)( bT2A ? pTrack->lstBars[i]->aVols+iSP : (*aWave)+iPoint ), *pDest = (char*)( bT2A ? (*aWave)+iPoint : pTrack->lstBars[i]->aVols+iSP ); memcpy( pDest, pSrc, sizeof(DWORD) * ( iEP - iSP )); iPoint += iEP - iSP; } else{ break; } } return nSelPoints; } void RemoveWaveBars( int iTrack, int iStartBar, int nDelBars ) { TAudioTrack* pTrack = g_aAudioTracks[iTrack]; for( int i=0; ilstBars[iStartBar]; pTrack->lstBars.erase( pTrack->lstBars.begin()+iStartBar ); } } void InsertWaveBars( int iTrack, int iInsertBar, TWaveBarList lstBars ) { TAudioTrack* pTrack = g_aAudioTracks[iTrack]; if( pTrack->lstBars.size()>0 && iInsertBar < pTrack->lstBars.size() ){ for( int i=lstBars.size()-1; i>=0; i-- ){ pTrack->lstBars.insert( pTrack->lstBars.begin()+iInsertBar, lstBars[i] ); } } else{ for( int i=0; ilstBars.push_back( lstBars[i] ); } } } void RestoreWaveBars( int iInsBar, int nBars, DWORD* aWave ) { int nPoints = nBars * POINTS_PER_BAR; for( int i=1; iaVols, pW + j * POINTS_PER_BAR, sizeof(DWORD)*POINTS_PER_BAR ); lstWaveBars.push_back( pWvBar ); } InsertWaveBars( i, iInsBar, lstWaveBars ); } } TAudioTrack* CopyAudioTrack( int iTrack, int iStartBar, int nCopyBars ) { TAudioTrack* pSrcTrack = g_aAudioTracks[iTrack], *pDestTrack = new TAudioTrack(pSrcTrack); for( int i=0; iaVols, pSrcTrack->lstBars[iStartBar+i], sizeof(DWORD)*POINTS_PER_BAR ); pDestTrack->lstBars.push_back( pWvBar ); } return pDestTrack; } void InsertAudioTrack( int iTrack, int iInsertBar, int nBars, TAudioTrack* pSrcTrack, int iStartBar ) { TAudioTrack* pDestTrack = g_aAudioTracks[iTrack]; if( pDestTrack->lstBars.size()>0 && iInsertBar < pDestTrack->lstBars.size() ){ for( int i=nBars-1; i>=0; i-- ){ TWaveBar* pWvBar = new TWaveBar; if( pSrcTrack ) memcpy( pWvBar->aVols, pSrcTrack->lstBars[iStartBar+i], sizeof(DWORD)*POINTS_PER_BAR ); pDestTrack->lstBars.insert( pDestTrack->lstBars.begin()+iInsertBar, pWvBar ); } } else{ for( int i=0; iaVols, pSrcTrack->lstBars[iStartBar+i], sizeof(DWORD)*POINTS_PER_BAR ); pDestTrack->lstBars.push_back( pWvBar ); } } }