//--------------------------------------------------------------------------- #include #include #pragma hdrstop #include "GlobalUnit.h" #include "UseStylePanel.h" #include "MidiTrack.h" #include "Undo.h" #include "SwitchProgFormUnit.h" #include "SwitchTextureForm.h" //--------------------------------------------------------------------------- #pragma package(smart_init) extern int w_xOffDrag, //图片左上角与鼠标距离 w_yOffDrag; __fastcall TUseStylePanel::TUseStylePanel(TComponent* AOwner) : TStylePanel(AOwner) { m_pContentPanel = NULL; m_pPlayTimer = NULL; m_bAddWeakupBar = true; m_strTitle = "使用风格"; } //--------------------------------------------------------------------------- void TUseStylePanel::ClearAllItems() { TStylePanel::ClearAllItems(); } //--------------------------------------------------------------------------- void TUseStylePanel::CountTotalLine() { m_nTotalLine = 0; if( m_pTopItem ){ //计算总行数 TCommonItem* pItem = m_pTopItem; while( pItem ){ //所有显示的子孙项 m_nTotalLine++; pItem = GetNextItem( pItem ); } } } //--------------------------------------------------------------------------- bool __fastcall TUseStylePanel::Charge4Fonts() { for( int i=g_aMidiTracks.size()-1; i>=0; i-- ){ if( g_aMidiTracks[i]->bank!=0xFF ){ return true; } } return false; } //--------------------------------------------------------------------------- void __fastcall TUseStylePanel::DoChangeFontProg(TObject* Sender) { Stop( STOP_ALL ); if( Sender ) SetSelect( m_pFocItem, m_iFocLine ); TTrackItem *pItem = (TTrackItem *)m_pSelItem ; TTrack* pTrack = pItem->pTrack; TSwitchProgForm *sPf = new TSwitchProgForm( NULL, pTrack->iBank, pTrack->iProg, pTrack->iChanNo ); BYTE data[100000]; int len = 100000; GetDemoData( pItem, len, data, sPf->m_iStartBar, sPf->m_lenBar ); f_MM_LoadDemo( data, len ); if( sPf->ShowModal() == mrOk ){ bool bChanged = false; int iStage = FindItemStage( pItem ); BYTE iBank = pTrack->iBank, iBankSet = sPf->m_iFont==g_idFont ? 0xFF : sPf->m_iFont; char iProg = sPf->m_iProg, iChno = sPf->m_iChno; if( iBank!=iBankSet || iProg!=pTrack->iProg || iChno!=pTrack->iChanNo ){ int range = g_Opus.StageRange(iStage), iMT = g_Midi.GetMidiTrackIndex( pTrack->iFile, pTrack->iChanSpec ); ChangeFont( LOWORD(range), HIWORD(range), iMT, iBankSet, iProg, iChno, pItem->iType ); } } delete sPf; f_MM_LoadDemo( NULL, 0 ); } //--------------------------------------------------------------------------- TTrackItem* TUseStylePanel::FindTrackItem( int iStage, TTrack* pTrk ) { TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First(); TSegmentItem* pSeg = (TSegmentItem*)pStyleItem->aItems->Items[iStage]; for( int i=0; iaItems->Count; i++ ){ TTrackItem* pTrkItem = (TTrackItem*)pSeg->aItems->Items[i]; if( pTrkItem->pTrack==pTrk ) return pTrkItem; } return NULL; } //--------------------------------------------------------------------------- void __fastcall TUseStylePanel::ChangeFont( int iSBar, int iEBar, int iMT, int iBank, int iProg, int iChno, int op ) { int iBStage = iSBar<0 ? 0 : GetInsertStage( iSBar ), iEStage = iEBar<0 ? g_Opus.StageCount() : GetInsertStage( iEBar+1 ); int iDelMT = iMT, iAddMT = -1; TMidiTrack *pDelMT = g_aMidiTracks[iMT], *pAddMT = NULL; vector* aStagesBefore = new vector, * aStagesAfter = new vector; vector aTracksBefore, aTracksAfter; bool bInit = false; vector aAddStages; TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First(); vector::iterator itDelStage = pDelMT->aStages.begin(); while( itDelStage!=pDelMT->aStages.end() ){ int iStage = *itDelStage;//pDelMT->aStages[i]; if( iStage=iEStage ) break; else{ TOpusStage* pStage = g_lstOpusStages[iStage]; TSegmentItem* pSeg = (TSegmentItem*)pStyleItem->aItems->Items[iStage]; for( int j=0; jaTracks.size(); j++ ){ TTrack* pTrack = pStage->aTracks[j]; if( pTrack->iFile==pDelMT->file && pTrack->iChanSpec==pDelMT->chno ){ int iFBar = g_Opus.StageFirstBar(iStage), iLBar = g_Opus.StageLastBar(iStage); aTracksBefore.push_back( new TTrack(pTrack) ); // aStagesBefore->push_back( MAKELONG(iStage, j) ); DWORD dwFLT = iFBar + (iLBar<<12) + (j<<24); aStagesBefore->push_back( dwFLT ); pTrack->iBank = iBank; pTrack->iProg = iProg; pTrack->iChanSpec = iChno; aTracksAfter.push_back( pTrack ); // aStagesAfter->push_back( MAKELONG(iStage, j) ); aStagesAfter->push_back( dwFLT ); aAddStages.push_back( iStage ); break; } } itDelStage = pDelMT->aStages.erase( itDelStage ); } } TTrack *pBefore = NULL, *pAfter = NULL; int count = aAddStages.size(); if( count==0 ){ delete aStagesBefore; delete aStagesAfter; return; } int stateDel = pDelMT->state, volumeDel = pDelMT->volume, panDel = pDelMT->pan, iErase = g_Midi.ClearEmptyTrack(); int nMTOri = g_aMidiTracks.size(); pAddMT = g_Midi.GetValidMidiTrack( aAddStages, 0xFF, iChno, iBank, iProg ); if( nMTOri=0 ){ pAddMT->state = stateDel; pAddMT->volume = volumeDel; pAddMT->pan = panDel; } } if( iErase>=0 ){ if( bInit && iErase==iMT ){ g_aMidiTracks.pop_back(); g_aMidiTracks.insert( g_aMidiTracks.begin()+iMT, pAddMT ); iAddMT = iMT; bInit = false; } else bInit = true; } pBefore = new TTrack[count]; pAfter = new TTrack[count]; for( int i=0; iiFile = pAddMT->file; aTracksAfter[i]->iChanSpec = pAddMT->chno; memcpy( &pAfter[i], aTracksAfter[i], sizeof(TTrack) ); } if( iAddMT<0 ) iAddMT = g_Midi.GetMidiTrackIndex( pAddMT->file, pAddMT->chno ); int iCode = op, iExt1 = iDelMT>=0 ? iDelMT + (stateDel<<8) + (volumeDel<<16) + (panDel<<24) : -1, iExt2 = iAddMT>=0 ? iAddMT + (pAddMT->state<<8) + (pAddMT->volume<<16) + (pAddMT->pan<<24) : -1; g_Undo.AddUndo( UNDO_MIDI_FONT, op, iSBar, iEBar, (void*)pBefore, (void*)pAfter ); g_Undo.SetUndoExtra( iExt1, iExt2, -1, aStagesBefore, aStagesAfter ); int iShowTrack = -1; if( !m_pContentPanel->IsVertical() ){ if( bInit ){ m_pContentPanel->InitialVars(); } else{ if( iDelMT>=0 ){ int iST = m_pContentPanel->GetShowTrackId( ST_MIDI, iDelMT ); if( iST>0 ) m_pContentPanel->InvalidateBars( iSBar, iEBar, BAR_TRACK | iST ); } } } IntegrateStages( iBStage ); Paint(); if( !m_pContentPanel->IsVertical() ){ if( iAddMT>=0 ){ if( iAddMT==iDelMT ) m_pContentPanel->SelectTrack( -1, -1, -1, false ); if( iShowTrack<0 ) iShowTrack = m_pContentPanel->GetShowTrackId( ST_MIDI, iAddMT ) - 1; if( iShowTrack>=0 ){ m_pContentPanel->SelectTrack( iShowTrack, -1, -1, false ); m_pContentPanel->SetSelectRange( iSBar, 0, iEBar, POINTS_PER_BAR-1 ); } } GenerateCompose(); } if( g_iPreStage==0 ){ g_Theme.Set( g_pUseStyle->pStyle->idLoc, g_pUseStyle->pStyle->idStyle, g_lstOpusStages ); } } //--------------------------------------------------------------------------- void __fastcall TUseStylePanel::ChangeTexture( int iSBar, int iEBar, char sType, int iMT, TTrack* pSubTrack, int op ) { int iBStage = iSBar<0 ? 0 : GetInsertStage( iSBar ), iEStage = iEBar<0 ? g_Opus.StageCount() : GetInsertStage( iEBar+1 ); vector* aStagesBefore = new vector, * aStagesAfter = new vector; vector aTracksBefore, aTracksAfter; int iUndoType = iMT<0 ? UNDO_MIDI_ADD : ( pSubTrack ? UNDO_MIDI_SUB : UNDO_MIDI_DEL ); if( iSBar<0 && iEBar<0 ) { if( iMT<0 ) iUndoType = UNDO_TRKMID_ADD; else if( !pSubTrack ) iUndoType = UNDO_TRKMID_DEL; } int iDelMT = iMT, iAddMT = -1; if( pSubTrack && pSubTrack->iFile!=0xFF ) iAddMT = g_Midi.GetMidiTrackIndex( pSubTrack->iFile, pSubTrack->iChanSpec ); TMidiTrack* pDelMT = iDelMT<0 ? NULL : g_aMidiTracks[iDelMT], * pAddMT = iAddMT<0 ? NULL : g_aMidiTracks[iAddMT]; BYTE iDelFile = pDelMT ? pDelMT->file : 0xFF, iDelChan = pDelMT ? pDelMT->chno : 0xFF, iAddFile = pAddMT ? pAddMT->file : 0xFF, iAddChan = pAddMT ? pAddMT->chno : 0xFF; bool bDrum = false; if( pSubTrack ){ if( pSubTrack->iChanNo==9 ) bDrum = true; } vector aAddStages; TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First(); for( int i=iBStage; iaItems->Items[i]; int iFBar = g_Opus.StageFirstBar(i), iLBar = g_Opus.StageLastBar(i); TTrack *pDelTrack = NULL, *pAddTrack = NULL; int iDelTrack = -1, iAddTrack = -1; if( iDelChan!=0xFF && ( sType<0 || pStage->iSegType==sType ) ){ for( int j=0; jaTracks.size(); j++ ){ TTrack* pTmpTrack = pStage->aTracks[j]; if( iDelFile!=0xFF && pTmpTrack->iFile==iDelFile && pTmpTrack->iChanSpec==iDelChan ){ pDelTrack = pTmpTrack; iDelTrack = j; break; } } } if( pDelTrack ){ if( !pDelMT || pDelMT->file!=pDelTrack->iFile ) pDelMT = g_Midi.FindMidiTrack( pDelTrack->iFile, pDelTrack->iChanSpec ); pDelMT->DelStage( i ); // aStagesBefore->push_back( MAKELONG( i, iDelTrack ) ); DWORD dwFLT = iFBar + (iLBar<<12) + (iDelTrack<<24); aStagesBefore->push_back( dwFLT ); if( pSubTrack ){ aTracksBefore.push_back( new TTrack(pDelTrack) ); if( pDelTrack->iStyleLoc!=pSubTrack->iStyleLoc || pDelTrack->iStyleId!=pSubTrack->iStyleId ){ TTrackItem* pTrkItem = (TTrackItem*)pSeg->aItems->Items[iDelTrack]; pTrkItem->pStyle = GetStyleInfo( pSubTrack->iStyleLoc, pSubTrack->iStyleId ); } memcpy( pDelTrack, pSubTrack, sizeof(TTrack) ); aTracksAfter.push_back( pDelTrack ); // aStagesAfter->push_back( MAKELONG(i, iDelTrack) ); aStagesAfter->push_back( dwFLT ); if( pAddMT ) pAddMT->AddStage( i ); else aAddStages.push_back( i ); if( iUndoType!=UNDO_MIDI_SUB ) iUndoType==UNDO_MIDI_SUB; } else{ TTrackItem* pDelItem = (TTrackItem*)pSeg->aItems->Items[iDelTrack];//FindTrackItem( i, pDelTrack ); TStylePanel::DeleteItem( pDelItem, -1 ); aTracksBefore.push_back( pDelTrack ); pStage->aTracks.erase( pStage->aTracks.begin()+iDelTrack ); } } else if( pSubTrack && pStage->iSegType==sType && ( !bDrum || iMT<0 || iDelChan==9 ) ){ TTrack* pTrk = new TTrack( pSubTrack ); if( pAddMT ) pAddMT->AddStage( i ); else aAddStages.push_back( i ); int iTrk = 0; if( bDrum ){ pStage->aTracks.insert( pStage->aTracks.begin(), pTrk ); } else{ iTrk = pStage->aTracks.size(); pStage->aTracks.push_back( pTrk ); } AddTrack( pSeg, pTrk ); aTracksAfter.push_back( pTrk ); // aStagesAfter->push_back( MAKELONG(i, iTrk) ); DWORD dwFLT = iFBar + (iLBar<<12) + (iTrk<<24); aStagesAfter->push_back( dwFLT ); } } TTrack *pBefore = NULL, *pAfter = NULL; int iExt1 = iDelMT>=0 ? iDelMT + (pDelMT->state<<8) + (pDelMT->volume<<16) + (pDelMT->pan<<24) : -1, iErase = g_Midi.ClearEmptyTrack(); if( !aStagesBefore->empty() ){ int count = aStagesBefore->size(); pBefore = new TTrack[count]; for( int i=0; iempty() ){ if( !pAddMT && !aAddStages.empty() ){ int nMTOri = g_aMidiTracks.size(); pAddMT = g_Midi.GetValidMidiTrack( aAddStages, pSubTrack->iFile, pSubTrack->iChanNo, pSubTrack->iBank, pSubTrack->iProg ); if( nMTOrisize(); pAfter = new TTrack[count]; for( int i=0; iiFile = pAddMT->file; aTracksAfter[i]->iChanSpec = pAddMT->chno; } memcpy( &pAfter[i], aTracksAfter[i], sizeof(TTrack) ); } } if( iErase>=0 ){ if( bInit && iErase==iMT && pAddMT ){ g_aMidiTracks.pop_back(); g_aMidiTracks.insert( g_aMidiTracks.begin()+iMT, pAddMT ); iAddMT = iMT; bInit = false; } else bInit = true; } if( pAddMT && iAddMT<0 ) iAddMT = g_Midi.GetMidiTrackIndex( pAddMT->file, pAddMT->chno ); int iCode = op, iExt2 = iAddMT>=0 ? iAddMT + (pAddMT->state<<8) + (pAddMT->volume<<16) + (pAddMT->pan<<24) : -1; g_Undo.AddUndo( iUndoType, iCode, iSBar, iEBar, (void*)pBefore, (void*)pAfter ); g_Undo.SetUndoExtra( iExt1, iExt2, -1, aStagesBefore, aStagesAfter ); int iShowTrack = -1; if( !m_pContentPanel->IsVertical() ){ if( bInit ){ m_pContentPanel->InitialVars(); } else{ if( iDelMT>=0 ){ int iST = m_pContentPanel->GetShowTrackId( ST_MIDI, iDelMT ); if( iST>0 ) m_pContentPanel->InvalidateBars( iSBar, iEBar, BAR_TRACK | iST ); } } } IntegrateStages( iBStage ); Paint(); if( g_iSegColorMode==1 ) m_pContentPanel->InvalidateBars( iSBar, iEBar, BAR_DATA ); if( !m_pContentPanel->IsVertical() ){ if( iAddMT>=0 ){ if( VIEW_TRACK!=g_iViewMode ){ Application->MainForm->Perform( UM_SETVIEWMODE, VIEW_TRACK, 0 ); } else if( iAddMT==iDelMT ) m_pContentPanel->SelectTrack( -1, -1, -1, false ); if( iShowTrack<0 ) iShowTrack = m_pContentPanel->GetShowTrackId( ST_MIDI, iAddMT ) - 1; if( iShowTrack>=0 ){ m_pContentPanel->SelectTrack( iShowTrack, -1, -1, false ); m_pContentPanel->SetSelectRange( iSBar, 0, iEBar, POINTS_PER_BAR-1 ); } } GenerateCompose(); } if( g_iPreStage==0 ){ g_Theme.Set( g_pUseStyle->pStyle->idLoc, g_pUseStyle->pStyle->idStyle, g_lstOpusStages ); } } //--------------------------------------------------------------------------- void __fastcall TUseStylePanel::DoChangeTexture(TObject* Sender) { Stop( STOP_ALL ); if( Sender ) SetSelect( m_pFocItem, m_iFocLine ); TTrackItem *pItem = (TTrackItem *)m_pSelItem ; TTrack* pTrack = pItem->pTrack; int stype = pItem->GetSegType(); char progOri = pTrack->iProgOrig; int iStage = FindItemStage( pItem ); TOpusStage* pStage = g_lstOpusStages[iStage]; int iSBar = g_Opus.StageFirstBar( iStage ), lenBar = pStage->aBars.size(); TStageList m_lstStage; TStage *stage = new TStage; TStageList lstStages; stage->iSegType = stype; stage->iSegKey = pStage->iSegKey; stage->nBarNum = lenBar; stage->nTrkNum = 0; lstStages.push_back( stage ); if( stype<=SEGTYPE_FILL ){ stage->aChords = new TBarChords[lenBar]; for( int j=0; jaChords[j], &pStage->aBars[j]->aChords, sizeof(TBarChords) ); } } TSwitchTextureForm *pProgPar = new TSwitchTextureForm(NULL, (1<iBank, pTrack->iProg, pItem->pStyle, pTrack->iChanNo, pTrack->iSegNo, &lstStages, 0); if(pProgPar->ShowModal() == mrOk){ TTrack subTrk; subTrk.iStyleLoc = pProgPar->m_pSetStyle->idLoc; subTrk.iStyleId = pProgPar->m_pSetStyle->idStyle; subTrk.iSegNo = pProgPar->m_cSetSegNo; subTrk.iChanNo = pProgPar->m_cSetchan; subTrk.iProgOrig = pProgPar->m_cSetProgOri; subTrk.nVol = pProgPar->m_cSetVol; subTrk.nVolOrig = pProgPar->m_cSetVolOri; if( pProgPar->m_bSetCur ){ subTrk.iProg = pProgPar->m_cSetProg; subTrk.iChanSpec = subTrk.iChanNo; subTrk.iBank = 0xFF; subTrk.iFile = 0xFF; } else{ subTrk.iProg = pTrack->iProg; subTrk.iChanSpec = pTrack->iChanSpec; subTrk.iBank = pTrack->iBank; subTrk.iFile = pTrack->iFile; } int iMT = g_Midi.GetMidiTrackIndex( pTrack->iFile, pTrack->iChanSpec ); ChangeTexture( iSBar, iSBar+lenBar-1, stype, iMT, &subTrk, SEGTYPE_TRACK ); } delete pProgPar; delete stage; } //--------------------------------------------------------------------------- void __fastcall TUseStylePanel::DeleteAllTexture( bool bAddUndo ) { if( g_Midi.IsEmpty() || g_Opus.BarCount()==0 ) return; TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First(); TOpusStageList *lstStageBefore = NULL, *lstStageAfter = NULL; UINT idLocBefore(-1), idStyleBefore(-1), idLocAfter(-1), idStyleAfter(-1); int nTrks = g_aMidiTracks.size(); TMidiTrackList *lstTracksBefore = NULL; if( bAddUndo ){ lstStageBefore = new TOpusStageList; g_Opus.CopyStages( 0, g_Opus.BarCount()-1, lstStageBefore ); if( pStyleItem->pStyle ){ idLocBefore = pStyleItem->pStyle->idLoc; idStyleBefore = pStyleItem->pStyle->idStyle; } lstTracksBefore = new TMidiTrackList; for( int i=0; ipush_back( new TMidiTrack(g_aMidiTracks[i]) ); } for( int i=0; iaItems->Items[i]; while( !pStage->aTracks.empty() ){ TTrackItem* pDelItem = (TTrackItem*)pSeg->aItems->Last(); TStylePanel::DeleteItem( pDelItem, -1 ); TTrack* pTrack = pStage->aTracks.back(); pStage->aTracks.pop_back(); } } g_Midi.ClearMidiTracks(); IntegrateStages( 0 ); Paint(); if( bAddUndo ){ lstStageAfter = new TOpusStageList; g_Opus.CopyStages( 0, g_Opus.BarCount()-1, lstStageAfter ); if( pStyleItem->pStyle ){ idLocAfter = pStyleItem->pStyle->idLoc; idStyleAfter = pStyleItem->pStyle->idStyle; } g_Undo.AddUndo( UNDO_TRKMID_DELALL, ST_MIDI, idStyleBefore, idStyleAfter, (void*)lstStageBefore, (void*)lstStageAfter ); g_Undo.SetUndoExtra( idLocBefore, idLocAfter, 0, (void*)lstTracksBefore, NULL ); } if( !m_pContentPanel->IsVertical() ){ m_pContentPanel->InitialVars(); GenerateCompose(); } else if( g_iSegColorMode==1 ){ m_pContentPanel->InvalidateBars( 0, g_Opus.BarCount()-1, BAR_DATA ); } if( g_iPreStage==0 ){ g_Theme.Set( g_pUseStyle->pStyle->idLoc, g_pUseStyle->pStyle->idStyle, g_lstOpusStages ); } } //--------------------------------------------------------------------------- TSegmentItem* TUseStylePanel::AddStage( TOpusStage* pStage ) { TStyleItem* pStyItem = (TStyleItem*)m_aItems->First(); int ind = 0; DWORD opts = OPT_DEL|OPT_VOL; if( pStage->iSegType<=SEGTYPE_FILL ){ ind = pStyItem->nSegNum[0] + pStyItem->nSegNum[1]; opts |= OPT_BRUSH; } else ind = pStyItem->nSegNum[pStage->iSegType]; TSegmentItem* pSegItem = pStyItem->AddSegment( pStage->iSegType, pStage->iSegNo, opts, pStage->aBars.size(), ind, pStage->nVol, false ); opts = OPT_DEL|OPT_FONTPROG|OPT_VOL; if( pStage->iSegTypeaTracks.size(); j++ ){ TTrack* pTrack = pStage->aTracks[j]; pSegItem->AddTrack( NULL, pTrack, opts, false ); } return pSegItem; } //--------------------------------------------------------------------------- int TUseStylePanel::GetDemoData( TCommonItem* pItem, int &nLen, BYTE* pData, int& iStartBar, int& lenBar ) { int ret = 0; if( pItem->iType==SEGTYPE_TRACK ){ //播放单一轨道{ int iStage = FindItemStage( pItem ); TOpusStage* pStage = g_lstOpusStages[iStage]; TSegmentItem* pSeg = (TSegmentItem*)pItem->up; int stype = pItem->GetSegType(); TTrack* pTrk = ((TTrackItem*)pItem)->pTrack; TStage stage; stage.aTracks = new TComposeTrack[1]; int nStageNum = 1; stage.iSegType = stype; stage.iSegKey = pStage->iSegKey; stage.nBarNum = lenBar; stage.nTrkNum = 1; stage.aTracks->iStyleId = pTrk->iStyleId;// >pStyle->idStyle; stage.aTracks->iStyleLoc = pTrk->iStyleLoc;// >pStyle->idLoc; if( stype>=SEGTYPE_INTRO ){ char cType = (pTrk->iSegNo / 4 + 1) << 4; char sno = pTrk->iSegNo % 4; stage.aTracks->iSegNo = sno + cType; } else stage.aTracks->iSegNo = pTrk->iSegNo; stage.aTracks->iChanNo = pTrk->iChanNo; stage.aTracks->iChanSpec = pTrk->iChanSpec; stage.aTracks->iProg = pTrk->iProg; stage.aTracks->nVol = pTrk->nVol<0 ? 0 : pTrk->nVol * pSeg->volume / 100.0; if( stype<=SEGTYPE_FILL ){ stage.aChords = new TBarChords[lenBar]; for( int j=0; jaBars[j]->aChords, sizeof(TBarChords) ); } } ret = f_CM_Compose( &nLen, pData, g_iMelodyTimeSignature, g_nMelodyTempo, nStageNum, &stage, false, NULL, NULL ); } return ret; } //--------------------------------------------------------------------------- void TUseStylePanel::PlayDemo( TCommonItem *pItem, int tempo ) { if( !pItem || g_lstOpusStages.size()==0 ) return; Stop( STOP_ALL ); if( pItem->iType!=SEGTYPE_TRACK ){ GenerateCompose(); SetTrackParams( false ); } int iStartBar(0), lenBar(0); if( pItem->iType==SEGTYPE_STYLE ){ //播放完整全曲 f_MM_Play( Handle, 0, TYPE_COMPOSE ); //仅播放编曲 m_bPlaying = true; } else{ int iStage = FindItemStage( pItem ); TOpusStage* pStage = g_lstOpusStages[iStage]; for( int i=0; iaBars.size(); } lenBar = pStage->aBars.size(); if( pItem->iType==SEGTYPE_TRACK ){ //播放单一轨道 BYTE data[100000]; int len = 100000; int ret = GetDemoData( pItem, len, data, iStartBar, lenBar ); if( ret==0 ){ BYTE iBank = ((TTrackItem*)pItem)->pTrack->iBank; char* strFile = iBank==0xFF ? NULL : iBank<0x80 ? g_lstFonts[iBank]->strFileName : g_lstVSTi[iBank-0x80]->strFileName; f_MM_LoadDemo( data, len ); f_MM_PlayDemo( Handle, 0, -1, -1, iBank, strFile ); m_bPlaying = true; } else{ DebugPrint( "Compose error: %d", ret ); } } else{ f_MM_Play( Handle, iStartBar, TYPE_COMPOSE ); //仅播放编曲 m_bPlaying = true; } if( m_bPlaying ){ if( !m_pPlayTimer ){ m_pPlayTimer = new TTimer(this); } m_pPlayTimer->Interval = lenBar * g_dblTimePerBar - 100; m_pPlayTimer->OnTimer = PlayEndProc; m_pPlayTimer->Enabled = true; } } if( m_bPlaying ) m_pPlayItem = pItem; } //--------------------------------------------------------------------------- void __fastcall TUseStylePanel::PlayEndProc(TObject* Sender) { Stop(STOP_SELF); } //--------------------------------------------------------------------------- void __fastcall TUseStylePanel::OnPlayEnd(TMessage &msg) { Stop(STOP_SELF); } //--------------------------------------------------------------------------- void TUseStylePanel::SetSelect( TCommonItem *pItem, int iLine ) { TCommonItem * pOldSeg = NULL; if( m_pSelItem && m_pSelItem->iType>=SEGTYPE_VAR && m_pSelItem->iType<=SEGTYPE_ENDING ){ pOldSeg = m_pSelItem; } if( !pItem || pItem->iType==SEGTYPE_STYLE ){ m_pContentPanel->SelectStage( -1 ); } TStylePanel::SetSelect( pItem, iLine ); if( pOldSeg!=m_pSelItem && m_pSelItem && m_pSelItem->iType>=SEGTYPE_VAR && m_pSelItem->iType<=SEGTYPE_ENDING ){ TStyleItem* pStyle = (TStyleItem*)m_aItems->Items[0]; for( int i=0; iaItems->Count; i++ ){ if( m_pSelItem==pStyle->aItems->Items[i] ){ m_pContentPanel->SelectStage( i ); break; } } } } //--------------------------------------------------------------------------- void TUseStylePanel::Stop( DWORD dwSpec ) { if( m_pPlayTimer ){ delete m_pPlayTimer; m_pPlayTimer = NULL; } if( m_bPlaying ){ dwSpec = STOP_SELF; if( m_pPlayItem && m_pPlayItem->iType!=SEGTYPE_TRACK ) SetTrackParams(); } TStylePanel::Stop( dwSpec ); } //--------------------------------------------------------------------------- bool TUseStylePanel::HandleHoverEvent(TPoint ptMouse) { int X = ptMouse.X, Y = ptMouse.Y; TCommonItem* pHoverItem = NULL; int iHoverLine = -1; TCommonItem* pItem = HitTest( X, Y-m_nTitleHeight, NULL ); if( pItem && m_pDropItem ){ if( m_pDropItem->iType==SEGTYPE_TRACK ){ iHoverLine = (Y - m_nTitleHeight)/m_nItemHeight; pHoverItem = GetTrackHoverItem( pItem, iHoverLine ); } else if( m_pDropItem->iType==SEGTYPE_STYLE ){ //查看风格是否缺少片段 if( ((TStyleItem*)m_pDropItem)->nSegNum[0]>0 ){ pHoverItem = (TCommonItem*)m_aItems->Items[0]; iHoverLine = -m_iTopLine; } } else{ int iDropType = m_pDropItem->GetSegType(), iHoverType = pItem->GetSegType(); if( iDropType==iHoverType //类型相同可替换 || ( iHoverType==SEGTYPE_FILL || iHoverType==SEGTYPE_VAR) && (iDropType==SEGTYPE_FILL || iDropType==SEGTYPE_VAR )){ //伴奏与加花可替换 iHoverLine = (Y - m_nTitleHeight)/m_nItemHeight; pHoverItem = pItem; } } } SetUnfoldTimer( pItem, pHoverItem ); SetHover( pHoverItem, iHoverLine ); return pHoverItem!=NULL; } //--------------------------------------------------------------------------- void TUseStylePanel::HandleDropEvent( int iState ) { if( m_pDropItem && m_pHoverItem ){ Stop(); if( m_pDropItem->iType==SEGTYPE_STYLE ){ //应用风格 PostMessage( Parent->Handle, UM_APPLYSTYLE, 1, LPARAM(m_pDropItem) ); } else{ //应用片段 int iStage = FindItemStage( m_pHoverItem ); if( m_pDropItem->iType==SEGTYPE_TRACK ){ //添加track TSegmentItem* pSeg = (TSegmentItem*)m_pHoverItem; if( m_pHoverItem->iType==SEGTYPE_TRACK ) pSeg = (TSegmentItem*)m_pHoverItem->up; TTrack *pSrcTrack = new TTrack( ((TTrackItem*)m_pDropItem)->pTrack ), *pDstTrack = NULL; if( pSrcTrack->iChanNo==9 ){ for( int i=0; iaItems->Count; i++ ){ TTrackItem* pTmpItem = (TTrackItem*)pSeg->aItems->Items[i]; if( pTmpItem->pTrack->iChanNo==9 ){ pDstTrack = pTmpItem->pTrack; break; } } } int iMT = -1; if( pDstTrack ){ iMT = g_Midi.GetMidiTrackIndex( pDstTrack->iFile, pDstTrack->iChanSpec ); } else{ pSrcTrack->iFile = 0xFF; pSrcTrack->iChanSpec = pSrcTrack->iChanNo; } TOpusStage* pStage = g_lstOpusStages[iStage]; int iSBar = FirstBar( iStage ), iEBar = iSBar + pStage->aBars.size() - 1; ChangeTexture( iSBar, iEBar, pStage->iSegType, iMT, pSrcTrack, SEGTYPE_TRACK ); } else{ ReformStage( iStage, (TSegmentItem*)m_pDropItem ); } } } } //--------------------------------------------------------------------------- String TUseStylePanel::ChargeTip( TStyleItem* pItem ) { String strTip = " 风格支付预估\n\n 风格 唱作音符\n"; strTip += "------------------------\n"; char buf[512]; int nFee = 0; for( int i=0; iidLoc==0 && m_aStyles[i]->pOrigin->cost>0 ){ TPROSTYLE* pStyle = m_aStyles[i]; sprintf( buf, "[%4d] %d\n", pStyle->idStyle, pStyle->pOrigin->cost ); strTip += buf; nFee += pStyle->pOrigin->cost; } } strTip += "------------------------\n"; strTip += " 合计 " + IntToStr( nFee ); return strTip; } //--------------------------------------------------------------------------- void TUseStylePanel::ApplyStyle( TStyleItem* pSrcStyle ) { g_Midi.ClearMidiTracks(); TStyleItem* pDestStyle = (TStyleItem*)m_aItems->Items[0]; //Set Undo bool bMMUndo = false; int nBars = pDestStyle->nBars, idLoc = (pDestStyle && pDestStyle->pStyle) ? pDestStyle->pStyle->idLoc : 0, idStyle = (pDestStyle && pDestStyle->pStyle) ? pDestStyle->pStyle->idStyle : 0; TAudioTrackList* lstAudio = NULL; TOpusStageList* lstStageBefore = new TOpusStageList; g_Opus.CopyStages( 0, nBars-1, lstStageBefore ); //替换风格 pDestStyle->pStyle = pSrcStyle->pStyle; int nSegNum[4]; vector aSegments[4]; memset( nSegNum, 0, sizeof(int)*4 ); for( int i=0; iaItems->Count; i++ ){ TSegmentItem* pSegment = (TSegmentItem*)pSrcStyle->aItems->Items[i]; int stype = pSegment->GetSegType(); aSegments[stype].push_back( pSegment ); nSegNum[stype]++; } m_pFocItem = NULL; m_iFocLine = -1; m_pSelItem = NULL; m_iSelLine = -1; for( int i=pDestStyle->aItems->Count-1; i>=0; i-- ){ TSegmentItem* pDestSeg = (TSegmentItem*)pDestStyle->aItems->Items[i]; TSegmentItem* pSrcSeg = NULL; int stype = pDestSeg->iSegType; int sno = pDestSeg->iSegNo; if( stype>=SEGTYPE_INTRO ){ if( nSegNum[stype]>0 ){ TSegmentItem* pBackup = NULL; int t = sno / 2, c = sno % 2; for( int j=0; jiSegNo % 2 == c ){ if( aSegments[stype][j]->iSegNo / 2 == t ){ pSrcSeg = aSegments[stype][j]; break; } else{ pBackup = aSegments[stype][j]; } } } if( !pSrcSeg ){ if( pBackup ) pSrcSeg = pBackup; else pSrcSeg = aSegments[stype][0]; //大小调不分 } } if( !bMMUndo && ( !pSrcSeg || pSrcSeg->nBars!=pDestSeg->nBars ) ){ f_MM_AddUndoBefore( -1, NULL ); lstAudio = new TAudioTrackList; g_Audio.CopyTrackList( 0, nBars, lstAudio ); bMMUndo = true; } } else{ if( stype==SEGTYPE_FILL && nSegNum[SEGTYPE_FILL]==0 ){ stype = SEGTYPE_VAR; } else if( stype==SEGTYPE_VAR && nSegNum[SEGTYPE_VAR]==0 ){ stype = SEGTYPE_FILL; } sno = min( sno, nSegNum[stype]-1 ); pSrcSeg = aSegments[stype][sno]; } if( pSrcSeg ){ ReplaceSegment( pDestSeg, pSrcSeg ); } else{ //删除段落 RemoveSegment( pDestSeg ); } } IntegrateStages( 0 ); if( bMMUndo ){ f_MM_AddUndoAfter( -1, NULL ); } TOpusStageList* lstStageAfter = new TOpusStageList; g_Opus.CopyStages( 0, pDestStyle->nBars-1, lstStageAfter ); g_Undo.AddUndo( UNDO_OPUS_STYLE, 0, idLoc, idStyle, (void*)lstStageBefore, (void*)lstStageAfter ); if( bMMUndo ) g_Undo.SetUndoExtra( 0, 0, 0, (void*)lstAudio, NULL ); if( !pDestStyle->IsUnfold() ) SetFold( pDestStyle, 0 ); else if( m_pTopItem!=pDestStyle ) ScrollView( 0, true ); else InvalidateRgn( Handle, NULL, false ); m_pContentPanel->OnStageChanged( 0, MODE_INIT ); } //--------------------------------------------------------------------------- void TUseStylePanel::ReplaceSegment( TSegmentItem* pDestSeg, TSegmentItem* pSrcSeg ) { int iStage = FindItemStage( pDestSeg ); TOpusStage* pStage = g_lstOpusStages[iStage]; TStyleItem *pStyItem = (TStyleItem*)m_aItems->Items[0]; int nBar = pStage->aBars.size(); if( pSrcSeg->iSegType>=SEGTYPE_INTRO ) nBar = pSrcSeg->nBars; bool bPreChange = g_iPreStage==0; if( pStage->aBars.size()!=nBar ){ //段落长度调整 int offset = nBar - pStage->aBars.size(); int iOrigEnd = FirstBar(iStage) + pStage->aBars.size(); if( bPreChange ){ DuplicateRawBars(); SendMessage( Parent->Handle, UM_STAGECHANGED, 3, 0 ); } if( offset!=0 && pStage->iSegType==SEGTYPE_INTRO ){ if( g_Theme.IsWeadup() && !memcmp( g_aAudioTracks[1]->lstBars[iOrigEnd-1]->aVols, g_aAudioTracks[0]->lstBars[0]->aVols, POINTS_PER_BAR * sizeof(DWORD) )){ iOrigEnd--; } } if( offset>0 ){ //添加小节 for( int i=0; iaBars.push_back(pBar); for( int j=1; jlstBars.insert( g_aAudioTracks[j]->lstBars.begin() + iOrigEnd, pWvBar ); } } for( int j=1; joffset; i-- ){ delete pStage->aBars.back(); pStage->aBars.pop_back(); for( int j=1; jlstBars[iOrigEnd+i]; g_aAudioTracks[j]->lstBars.erase( g_aAudioTracks[j]->lstBars.begin() + iOrigEnd+i ); } } for( int j=1; jnBars += offset; pStyItem->nBars += offset; g_Opus.CountBars(); } if( pDestSeg->iType != pSrcSeg->iType ){ pStyItem->nSegNum[pDestSeg->iType]--; pStyItem->nSegNum[pSrcSeg->iType]++; } pDestSeg->iType = pSrcSeg->iType; pStage->nVol = pDestSeg->volume = pSrcSeg->volume; pStage->iSegType = pDestSeg->iSegType = pSrcSeg->iSegType; pStage->iSegNo = pDestSeg->iSegNo = pSrcSeg->iSegNo; g_Midi.RemoveStage( iStage, false ); //清空tracks while( pStage->aTracks.size()>0 ){ delete pStage->aTracks.back(); pStage->aTracks.pop_back(); } int iSegLine = 0, nTrkBefore = 0, nTrkAfter = 0; if( pStyItem->IsUnfold() ){ TCommonItem *pItem = pStyItem; while( pItem && pItem!=pDestSeg ){ iSegLine++; pItem = GetNextItem( pItem ); } if( pDestSeg->IsUnfold() ){ if( m_pSelItem && m_pSelItem->up==pDestSeg ){ m_pSelItem = NULL; m_iSelLine = -1; } nTrkBefore = pDestSeg->aItems->Count; nTrkAfter = pSrcSeg->aItems->Count; if( m_pTopItem && m_pTopItem->up==pDestSeg ){ TCommonItem * pItem = m_pTopItem; int iTopLine = m_iTopLine; while( pItem!=pDestSeg ){ iTopLine--; pItem = GetPrevItem( pItem ); } ScrollView( iTopLine, true ); } } } pDestSeg->ClearSubItems(); DWORD opts = OPT_DEL|OPT_VOL; if( pDestSeg->iSegTypeaItems->Count; i++ ){ TTrackItem* pTrkItem = (TTrackItem*)pSrcSeg->aItems->Items[i]; TTrack * pTrack = new TTrack( pTrkItem->pTrack ); pDestSeg->AddTrack( pTrkItem->pStyle, pTrack, opts, false ); pStage->aTracks.push_back( pTrack ); TMidiTrack* pMT = g_Midi.GetValidMidiTrack( iStage, pTrack->iFile, pTrack->iChanNo, pTrack->iBank, pTrack->iProg ); pTrack->iFile = pMT->file; pTrack->iChanSpec = pMT->chno; } bool bDeletedMT = g_Midi.ClearEmptyTrack()>=0; if( bPreChange || !m_pContentPanel->IsVertical() && ( bDeletedMT || nMTCount!=g_aMidiTracks.size() )) m_pContentPanel->InitialVars(); m_nTotalLine += nTrkAfter - nTrkBefore; if( m_iTopLine>iSegLine ){ m_iTopLine += nTrkAfter - nTrkBefore; } ResetScrollBar(); Paint(); } //--------------------------------------------------------------------------- void TUseStylePanel::DeleteItem( TCommonItem *pItem, int iLine ) { Stop(); TStyleItem *pStyItem = (TStyleItem*)m_aItems->Items[0]; int iStage = FindItemStage( pItem ); if( pItem->iType==SEGTYPE_TRACK ){ DeleteTrack( iStage, (TTrackItem*)pItem, iLine ); } else{ RemoveStage( iStage ); if( pStyItem->aItems->Count==0 ){ // g_Midi.ClearMidiTracks(); ClearAllItems(); g_pUseStyle = NULL; Paint(); } } } //--------------------------------------------------------------------------- void TUseStylePanel::DeleteTrack( int iStage, TTrackItem* pTrkItem, int iLine ) { TOpusStage* pStage = g_lstOpusStages[iStage]; for( int i=0; iaTracks.size(); i++ ){ TTrack* pTrack = pStage->aTracks[i]; if( pTrkItem->pTrack==pTrack ){ int iFirstBar = FirstBar( iStage ), iEndBar = iFirstBar + pStage->aBars.size() - 1; int iMT= g_Midi.GetMidiTrackIndex( pTrack->iFile, pTrack->iChanSpec ); ChangeTexture( iFirstBar, iEndBar, pStage->iSegType, iMT, NULL, SEGTYPE_TRACK ); break; } } } //--------------------------------------------------------------------------- TSegmentItem* TUseStylePanel::InsertSegment( int iStage, TSegmentItem* pSrcSeg, int nBars ) { if( m_aItems->Count==0 ){ g_pUseStyle = AddStyle( ((TTrackItem*)pSrcSeg->aItems->Items[0])->pStyle ); } TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First(); int ind = 0; DWORD opts = OPT_DEL|OPT_VOL; int stype = pSrcSeg->iSegType; if( pSrcSeg->iSegType<=SEGTYPE_FILL ){ stype = SEGTYPE_VAR; opts |= OPT_BRUSH; } if( iStage<0 || iStage>=pStyleItem->aItems->Count ){ iStage = pStyleItem->aItems->Count; if( pSrcSeg->iSegType<=SEGTYPE_FILL ){ ind = pStyleItem->nSegNum[SEGTYPE_VAR] + pStyleItem->nSegNum[SEGTYPE_FILL]; } else ind = pStyleItem->nSegNum[pSrcSeg->iSegType]; } else{ for( int i=0; iaItems->Count; i++ ){ TSegmentItem* pTmpSeg = (TSegmentItem*)pStyleItem->aItems->Items[i]; if( pTmpSeg->iSegType<=SEGTYPE_FILL && stype==SEGTYPE_VAR ){ if( iiInd++; } else if( pTmpSeg->iSegType==stype ){ if( iiInd++; } } } TSegmentItem* pDestSeg = new TSegmentItem( pStyleItem, pSrcSeg->iSegType, pSrcSeg->iSegNo, opts, nBars, ind, pSrcSeg->volume, false ); opts = OPT_DEL|OPT_VOL; if( pSrcSeg->iSegTypeaTracks.size(); i++ ){ TTrack* pTrack = pStage->aTracks[i]; pDestSeg->AddTrack( NULL, pTrack, opts, false ); } if( pStyleItem->IsUnfold() ){ m_nTotalLine++; int iTopStage = FindItemStage( m_pTopItem ); if( iTopStage>=iStage ){ m_iTopLine++; } } pStyleItem->InsertSegment( iStage, pDestSeg, nBars ); return pDestSeg; } //--------------------------------------------------------------------------- void TUseStylePanel::RemoveSegment( TSegmentItem* pItem, bool bSetMM ) { int iStage = FindItemStage( pItem ); TOpusStage* pStage = g_lstOpusStages[iStage]; int iFirstBar = FirstBar(iStage); int iEndBar = iFirstBar + pStage->aBars.size(); if( bSetMM && iEndBar>iFirstBar ){ if( g_iPreStage==0 ) DuplicateRawBars(); for( int i=1; iFirst(); if( m_pTopItem ){ int iTopStage = FindItemStage( m_pTopItem ); if( pStyItem->IsUnfold() ){ if( iTopStage>iStage ){ m_iTopLine--; if( pItem->IsUnfold() ){ m_iTopLine -= pItem->aItems->Count; } } else if( iTopStage==iStage && m_pTopItem!=pItem ){ //展开且TopItem是Track TCommonItem* pTmpItem = m_pTopItem; m_pTopItem = GetPrevItem( pItem ); while( pTmpItem!=m_pTopItem ){ m_iTopLine--; pTmpItem = GetPrevItem( pTmpItem ); } } } } TStylePanel::DeleteItem( pItem, -1 ); pStyItem->nBars -= iEndBar - iFirstBar; } //--------------------------------------------------------------------------- int TUseStylePanel::FindItemStage( TCommonItem* pItem ) { int iStage = -1; TStyleItem* pStyle = (TStyleItem*)m_aItems->First(); TSegmentItem* pSeg = NULL; if( pItem->iType!=SEGTYPE_STYLE ){ if( pItem->iType==SEGTYPE_TRACK ) pSeg = (TSegmentItem*)pItem->up; else pSeg = (TSegmentItem*)pItem; for( int i=0; iaItems->Count; i++ ){ if( pSeg==pStyle->aItems->Items[i] ){ iStage = i; break; } } } return iStage; } // --------------------------------------------------------------------------- /* TCommonItem* TUseStylePanel::DrawDragStageItem( int iStage ) { TStyleItem* pStyle= (TStyleItem*)m_aItems->First(); TSegmentItem* pSeg = (TSegmentItem*)pStyle->aItems->Items[iStage]; DrawDragImg( pSeg ); return pSeg; } // --------------------------------------------------------------------------- */ void TUseStylePanel::SetSelectStage( int iStage ) { if( m_aItems->Count==0 ) return; TStyleItem* pStyle = (TStyleItem*)m_aItems->Items[0]; if( iStage>=0 && iStageaItems->Count ){ TSegmentItem* pSeg = (TSegmentItem*)pStyle->aItems->Items[iStage]; if( !pStyle->IsUnfold() ){ SetFold( pStyle, 0 ); } TCommonItem* pItem = GetNextItem( pStyle ); int iLine = 1; while( pItem!=pSeg ){ pItem = GetNextItem( pItem ); iLine++; } SetSelect( pSeg, iLine - m_iTopLine ); ShowSelItem(); } else{ SetSelect( NULL, -1 ); } } // --------------------------------------------------------------------------- void TUseStylePanel::VolumeChanged( TCommonItem *pItem, char volNew ) { char volOld = pItem->iType==SEGTYPE_TRACK ? ((TTrackItem*)pItem)->pTrack->nVol : ((TSegmentItem*)pItem)->volume; if( volNew==(char)0x80 ){ if( pItem->IsMute() ) volNew = volOld & ~0x80; else volNew = volOld | 0x80; } else if( volOld<0 ){ volNew |= 0x80; } int iStage = FindItemStage( pItem ); if( iStage<0 ) return; ChangeVolume( iStage, pItem, volNew ); } // --------------------------------------------------------------------------- void TUseStylePanel::ChangeVolume( int iStage, TCommonItem* pItem, char newVol, bool bAddUndo ) { bool bSetUndo = false; int volBefore, volAfter = newVol, iUndoType = -1, iUndoCode = -1; TTrack* pUndoExt = NULL; int iStartBar = FirstBar( iStage ), iEndBar = iStartBar + g_lstOpusStages[iStage]->aBars.size(); TOpusStage* pStage = g_lstOpusStages[iStage]; TSegmentItem* pSeg = NULL; TTrackItem* pTrkItem = NULL; if( pItem->iType==SEGTYPE_TRACK ){ pSeg = (TSegmentItem*)pItem->up; pTrkItem = (TTrackItem*)pItem; } else{ pSeg = (TSegmentItem*)pItem; if( bAddUndo ){ bSetUndo = true; iUndoType = UNDO_STAGE_VOL; iUndoCode = MAKELONG( iStage, -1 ); volBefore = pStage->nVol; } pStage->nVol = pSeg->volume = newVol; } float fSegVol = pSeg->volume / 100.0; for( int i=0; iaTracks.size(); i++ ){ TTrack* pTrk = pStage->aTracks[i]; if( pTrkItem ){ if( pTrk==pTrkItem->pTrack ){ if( bAddUndo ){ bSetUndo = true; iUndoType = UNDO_PROG_VOL; iUndoCode = MAKELONG( iStage, (pTrk->iFile<<8) + pTrk->iChanSpec ); volBefore = (char)pTrk->nVol; pUndoExt = new TTrack( pTrk ); } pTrk->nVol = newVol; int vol = pTrk->nVol<0 ? 0 : pTrk->nVol * fSegVol; f_MM_SetTrackEvent( MIDI_EVENT_VOLUME, iStartBar, iEndBar, pTrk->iChanSpec, vol, pTrk->iFile ); if( m_bPlaying && ( pTrkItem==m_pSelItem )){ f_MM_SetTrackEvent( MIDI_EVENT_VOLUME, 0, iEndBar-iStartBar, pTrk->iChanSpec, vol, -1 ); } int iMT = g_Midi.GetMidiTrackIndex( pTrk->iFile, pTrk->iChanSpec ); g_Midi.ChangeNotesVolume( iMT, iStartBar, iEndBar, vol ); if( !m_pContentPanel->IsVertical() ){ int iShowTrack = m_pContentPanel->GetShowTrackId( ST_MIDI, iMT ); m_pContentPanel->InvalidateBars( iStartBar, iEndBar-1, BAR_TRACK | iShowTrack ); } break; } } else if( pTrk->nVol>0 ){ int vol = pTrk->nVol * fSegVol; f_MM_SetTrackEvent( MIDI_EVENT_VOLUME, iStartBar, iEndBar, pTrk->iChanSpec, vol, pTrk->iFile ); if( m_bPlaying && pSeg==m_pSelItem->up ){ f_MM_SetTrackEvent( MIDI_EVENT_VOLUME, 0, iEndBar-iStartBar, pTrk->iChanSpec, vol, -1 ); } int iMT = g_Midi.GetMidiTrackIndex( pTrk->iFile, pTrk->iChanSpec ); g_Midi.ChangeNotesVolume( iMT, iStartBar, iEndBar, vol ); if( !m_pContentPanel->IsVertical() ){ int iShowTrack = m_pContentPanel->GetShowTrackId( ST_MIDI, iMT ); m_pContentPanel->InvalidateBars( iStartBar, iEndBar-1, BAR_TRACK | iShowTrack ); } } } if( bSetUndo ){ TUndoLite* pLite = g_Undo.GetLastLite(); if( pLite && pLite->iType==iUndoType && pLite->iCode==iUndoCode ){ bool bMuteCurr = volBefore>=0 && volAfter<0 || volBefore<0 && volAfter>=0, bMuteLast = ( (int)pLite->pBefore >= 0 && (int)pLite->pAfter < 0 || (int)pLite->pBefore < 0 && (int)pLite->pAfter >= 0 ); if( bMuteCurr==bMuteLast ){ bSetUndo = false; if( (char)pLite->pBefore==volAfter ) g_Undo.CancelUndo(); else pLite->pAfter = (void*)volAfter; if( pUndoExt ) delete pUndoExt; } } if( bSetUndo ){ g_Undo.AddUndo( iUndoType, iUndoCode, iStartBar, iEndBar, (void*)volBefore, (void*)volAfter ); if( pUndoExt ) g_Undo.SetUndoExtra( 0, 0, 0, pUndoExt, NULL ); } } if( g_iPreStage==0 ){ g_Theme.Set( g_pUseStyle->pStyle->idLoc, g_pUseStyle->pStyle->idStyle, g_lstOpusStages ); } } // --------------------------------------------------------------------------- bool TUseStylePanel::IntegrateStages( int iStageBegin, bool bSetMM ) { iStageBegin--; if( iStageBegin<0 ) iStageBegin = 0; if( g_lstOpusStages.size()==0 ){ ClearAllItems(); g_pUseStyle = NULL; } if( g_lstOpusStages.size()<=iStageBegin ){ return false; } bool bIntegrated = false; TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First(); TSegmentItem* pSegItem1 = (TSegmentItem*)pStyleItem->aItems->Items[iStageBegin]; TOpusStageList::iterator iterFirst, iterSecond; iterFirst = iterSecond = g_lstOpusStages.begin() + iStageBegin; while( (++iterSecond)!=g_lstOpusStages.end() ){ TOpusStage *pStage1 = *iterFirst, *pStage2 = *iterSecond; TSegmentItem* pSegItem2 = (TSegmentItem*)pSegItem1->next; if( pStage1->iSegType<=SEGTYPE_FILL && pStage2->iSegType==pStage1->iSegType && !DiffStages( pStage1, pStage2 ) ){ if( !pStage1->aTracks.empty() ){ int num = pStage1->aTracks.size(); bool* aMatch = new bool[num]; memset( aMatch, false, sizeof(bool)*num ); for( int i=0; iaTracks[i]; for( int j=0; jaTracks[j]; if( !aMatch[j] && pTrk1->iStyleId==pTrk2->iStyleId && pTrk1->iStyleLoc==pTrk2->iStyleLoc && pTrk1->iSegNo==pTrk2->iSegNo && pTrk1->iChanNo==pTrk2->iChanNo && pTrk1->iBank==pTrk2->iBank && pTrk1->iProg==pTrk2->iProg && pTrk1->nVol==pTrk2->nVol ){ if( pTrk1->iFile==0xFF && pTrk2->iFile!=0xFF ){ pTrk1->iFile = pTrk2->iFile; pTrk1->iChanSpec = pTrk2->iChanSpec; } aMatch[j] = true; break; } } } delete[] aMatch; } pSegItem1->nBars += pSegItem2->nBars; for( int i=0; iaBars.size(); i++ ){ pStage1->aBars.push_back( pStage2->aBars[i] ); } pStage2->aBars.clear(); g_Opus.ChangeStageBar( iterFirst - g_lstOpusStages.begin(), pSegItem2->nBars, false ); RemoveSegment( pSegItem2, bSetMM ); bIntegrated = true; iterSecond = iterFirst; } else{ iterFirst++; pSegItem1 = (TSegmentItem*)pSegItem1->next; } } CountStyles(); HandleWeakup( iStageBegin, bSetMM ); return bIntegrated; } //--------------------------------------------------------------------------- void TUseStylePanel::HandleWeakup( int iStageBegin, bool bSetMM ) { if( !g_Theme.IsWeadup() || g_aAudioTracks.size()<2 || g_aAudioTracks[0]->lstBars.empty() || g_aAudioTracks[1]->lstBars.empty() ) return; TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First(); TSegmentItem* pSegItem1 = (TSegmentItem*)pStyleItem->aItems->Items[iStageBegin]; TOpusStageList::iterator iterFirst, iterSecond; iterFirst = iterSecond = g_lstOpusStages.begin() + iStageBegin; int iFirstBar = FirstBar( iStageBegin ); if( iFirstBar==0 ){ if( pSegItem1->iSegType<=SEGTYPE_FILL ){ if( m_bAddWeakupBar ){ TOpusStage *pStage0 = *iterFirst; if( !memcmp( g_aAudioTracks[1]->lstBars[0]->aVols, g_aAudioTracks[0]->lstBars[1]->aVols, POINTS_PER_BAR * sizeof(DWORD) )){ TBar * pBar0 = new TBar( g_Theme.GetFirstBar() ); pStage0->aBars.insert( pStage0->aBars.begin(), pBar0 ); pSegItem1->nBars++; pStyleItem->nBars++; for( int i=1; ilstBars[0] ); if( bSetMM ) f_MM_AudioMove( 1, 0, 0, 0, 1, MODE_INSERT ); } else{//其它音轨添加空白小节 pWvBar = new TWaveBar; if( bSetMM ) f_MM_AudioMove( i, 0, -1, 0, 1, MODE_INSERT ); } g_aAudioTracks[i]->lstBars.insert( g_aAudioTracks[i]->lstBars.begin(), pWvBar ); } } iFirstBar += pSegItem1->nBars; iterFirst++; iterSecond++; } } else{ m_bAddWeakupBar = true; } } while( pSegItem1->next && (++iterSecond)!=g_lstOpusStages.end() ){ TOpusStage *pStage1 = *iterFirst, *pStage2 = *iterSecond; TSegmentItem* pSegItem2 = (TSegmentItem*)pSegItem1->next; if( pStage1->iSegType==SEGTYPE_INTRO ){ int iFirstBar2 = iFirstBar + pSegItem2->nBars; if( pStage2->iSegType<=SEGTYPE_FILL && !memcmp( g_aAudioTracks[1]->lstBars[iFirstBar2]->aVols, g_aAudioTracks[0]->lstBars[1]->aVols, POINTS_PER_BAR * sizeof(DWORD) )){ bool bCopy = true; for( int i=0; ilstBars[iFirstBar2-1]->aVols[i]!=0 ){ bCopy = false; break; } } if( bCopy ){ memcpy( g_aAudioTracks[1]->lstBars[iFirstBar2-1]->aVols, g_aAudioTracks[0]->lstBars[0]->aVols, POINTS_PER_BAR * sizeof(DWORD) ); if( bSetMM ) f_MM_AudioMove( 1, iFirstBar2-1, 0, 0, 1, MODE_COPY ); } } else{ if( !memcmp( g_aAudioTracks[1]->lstBars[iFirstBar2-1]->aVols, g_aAudioTracks[0]->lstBars[0]->aVols, POINTS_PER_BAR * sizeof(DWORD) )){ memset( g_aAudioTracks[1]->lstBars[iFirstBar2-1]->aVols, 0, POINTS_PER_BAR * sizeof(DWORD) ); if( bSetMM ) f_MM_AudioMove( -1, 0, 1, iFirstBar2-1, iFirstBar2, MODE_ERASE ); } } } iFirstBar += pSegItem1->nBars; iterFirst++; pSegItem1 = (TSegmentItem*)pSegItem1->next; } } int TUseStylePanel::GetInsertStage( int iInsertBar ) { int iFirstBar, iDestStage = FindStage( iInsertBar, &iFirstBar ); if( iDestStage>=0 ){ TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First(); TSegmentItem* pSrcSeg = (TSegmentItem*)pStyleItem->aItems->Items[iDestStage]; if( iInsertBar!=iFirstBar ){//分段插入 int nBarNum = pSrcSeg->nBars - ( iInsertBar - iFirstBar ); g_Opus.CutStage( iDestStage, iInsertBar ); g_Midi.CutStage( iDestStage ); InsertSegment( iDestStage+1, pSrcSeg, nBarNum ); pSrcSeg->nBars -= nBarNum; pStyleItem->nBars -= nBarNum; iDestStage++; } } else if( iInsertBar>0 ){ iDestStage = g_lstOpusStages.size(); } return iDestStage; } //----------------------------------------------------------------------------- TTrackItem* TUseStylePanel::AddTrack( TSegmentItem* pSeg, TTrack* pSrcTrk, int iInd ) { TTrackItem* pDestTrk = NULL; if( pSeg && pSrcTrk ){ int nTrksBefore = pSeg->aItems->Count; TPROSTYLE* info = GetStyleInfo( pSrcTrk->iStyleLoc, pSrcTrk->iStyleId ); if( info ){ DWORD opts = OPT_DEL|OPT_VOL; if( pSeg->iSegTypeAddTrack( info, pSrcTrk, opts, false, iInd ); int nTrksAfter = pSeg->aItems->Count; if( pSeg->IsUnfold() && nTrksAfter!=nTrksBefore ){ m_nTotalLine += nTrksAfter-nTrksBefore; } } } return pDestTrk; } void __fastcall TUseStylePanel::InsertStage( int iInsertBar, TSegmentItem* pSrcSeg ) { Stop(); int iDestStage = GetInsertStage( iInsertBar ); TOpusStage* pNewStage = new TOpusStage; pNewStage->iSegKey = g_iMelodyKey; pNewStage->iSegNo = pSrcSeg->iSegNo; pNewStage->iSegType = pSrcSeg->iSegType; pNewStage->nVol = pSrcSeg->volume; int nBarNum = 0; if( pSrcSeg->iSegType>=SEGTYPE_INTRO ) nBarNum = pSrcSeg->nBars; bool bPreChange = g_iPreStage==0; if( bPreChange ){ DuplicateRawBars(); } for( int j=0; jaBars.push_back(pBar); } bool bCountDown = false; for( int i=1; iaTracks.size(); i++ ){ TTrack* pTrack = pNewStage->aTracks[i]; TMidiTrack* pMT = g_Midi.GetValidMidiTrack( iDestStage, pTrack->iFile, pTrack->iChanNo, pTrack->iBank, pTrack->iProg ); pTrack->iFile = pMT->file; pTrack->iChanSpec = pMT->chno; } if( bPreChange || nMTCountOld!=g_aMidiTracks.size() ) m_pContentPanel->InitialVars(); InsertSegment( iDestStage, pSrcSeg, nBarNum ); IntegrateStages( iDestStage ); ResetScrollBar(); Paint(); m_pContentPanel->OnStageChanged( iDestStage, MODE_INSERT ); } //----------------------------------------------------------------------------- void __fastcall TUseStylePanel::RemoveStage( int iStage ) { TStyleItem* pStyle = (TStyleItem*)m_aItems->First(); TSegmentItem* pSegItem = (TSegmentItem*)pStyle->aItems->Items[iStage]; bool bPreChange = g_iPreStage==0; if( bPreChange ) DuplicateRawBars(); f_MM_AddUndoBefore( -1, NULL ); SetBarsUndo( UNDO_BAR_DELETE, FirstBar(iStage), pSegItem->nBars ); RemoveSegment( pSegItem ); f_MM_AddUndoAfter( -1, NULL ); IntegrateStages( iStage ); ResetScrollBar(); Paint(); // InvalidateRgn( Handle, NULL, false ); if( bPreChange ) m_pContentPanel->InitialVars(); m_pContentPanel->OnStageChanged( iStage, MODE_DELETE ); } //----------------------------------------------------------------------------- void __fastcall TUseStylePanel::MoveBars( int iStartBar, int iEndBar, int iInsertBar, int iMode ) { if( iMode==MODE_MOVE && ( iInsertBar>=iStartBar && iInsertBar<=iEndBar+1 ) )//无须移动 return; Stop(); bool bPreChange = g_iPreStage==0; if( bPreChange ) DuplicateRawBars(); int nBars = iEndBar - iStartBar + 1, nOrigBars = g_Opus.BarCount(); if( iMode==MODE_DELETE ){ SetBarsUndo( UNDO_BAR_DELETE, iStartBar, nBars ); } else if( iMode==MODE_MOVE ){ SetBarsUndo( UNDO_BAR_MOVE, iStartBar, nBars, iInsertBar ); } f_MM_AddUndoBefore( -1, NULL ); int iDestStage = GetInsertStage( iInsertBar ), iSrcStage = FindStage( iStartBar, NULL ), iFirstChangeStage = (iMode==MODE_MOVE) ? min(iSrcStage, iDestStage) : (iMode==MODE_DELETE) ? iSrcStage : iDestStage; TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First(); if( g_Theme.IsWeadup() && iStartBar==0 && iEndBar==0 && ( iMode==MODE_MOVE || iMode==MODE_DELETE )){ TOpusStage* pFirstStage = g_lstOpusStages[iSrcStage]; if( pFirstStage->iSegType<=SEGTYPE_FILL ){ if( !memcmp( g_aAudioTracks[1]->lstBars[0]->aVols, g_aAudioTracks[0]->lstBars[0]->aVols, POINTS_PER_BAR * sizeof(DWORD) )){ m_bAddWeakupBar = false; } } } // 音频操作 bool bCountDown = false; for( int i=1; iaItems->Items[iSrcStage]; TOpusStage* pOriStage = g_lstOpusStages[iSrcStage]; TOpusStage* pNewStage = (iMode==MODE_DELETE) ? NULL : new TOpusStage; int nCopyBar = pOriStage->aBars.size() - nOffsetBar; if( nCopyBar>iEndBar-iBar+1 ) nCopyBar = iEndBar-iBar+1; if( pNewStage ){ pNewStage->iSegKey = pOriStage->iSegKey; pNewStage->iSegNo = pOriStage->iSegNo; pNewStage->iSegType = pOriStage->iSegType; pNewStage->nVol = pOriStage->nVol; for( int i=0; iaTracks.size(); i++ ){ TTrack * pTrack = new TTrack( pOriStage->aTracks[i] ); pNewStage->aTracks.push_back( pTrack ); } } int iCopyBar = nOffsetBar; for( int i=0; iaBars[iCopyBar] ); else pBar = pOriStage->aBars[iCopyBar]; pNewStage->aBars.push_back( pBar ); } if( iMode==MODE_MOVE || iMode==MODE_DELETE ) pOriStage->aBars.erase( pOriStage->aBars.begin() + iCopyBar ); else iCopyBar++; } if( iMode!=MODE_DELETE ){ g_lstOpusStages.insert( g_lstOpusStages.begin()+iDestStage, pNewStage ); g_Midi.CutStage( iDestStage ); InsertSegment( iDestStage, pSrcSeg, nCopyBar ); } if( iMode==MODE_MOVE || iMode==MODE_DELETE ){ if( iMode==MODE_MOVE && iDestStage<=iSrcStage ) iSrcStage++; else{ iBar -= nCopyBar; iEndBar -= nCopyBar; } if( pOriStage->aBars.size()==0 ){ //删除原段落 RemoveSegment( pSrcSeg ); if( iMode!=MODE_DELETE && iDestStage>=iSrcStage ) iDestStage--; } else{ pSrcSeg->nBars -= nCopyBar; } pStyleItem->nBars -= nCopyBar; } else if( iDestStage<=iSrcStage ){ iBar += nCopyBar; iEndBar += nCopyBar; } g_Opus.CountBars(); iBar += nCopyBar; if( iMode!=MODE_DELETE ){ nBarCount += nCopyBar; iDestStage++; } } if( iMode!=MODE_MOVE ) g_Opus.CountBars(); IntegrateStages( iFirstChangeStage ); f_MM_AddUndoAfter( -1, NULL ); if( iMode==MODE_COPY ){ SetBarsUndo( UNDO_BAR_INSERT, iInsertBar, nBars ); } else{ //计算是否AddWeakupBar bool bAddWeakupBar = false; int nCurrBars = g_Opus.BarCount(); if( iMode==MODE_MOVE && nCurrBars>nOrigBars || iMode==MODE_DELETE && nCurrBars>nOrigBars-nBars ) bAddWeakupBar = true; if( bAddWeakupBar ) g_Undo.SetUndoCode( bAddWeakupBar ); } if( iMode==MODE_DELETE ){ m_pContentPanel->SelectBars( -1, - 1 ); /* if( pStyleItem->aItems->Count==0 ){ // g_Midi.ClearMidiTracks(); ClearAllItems(); g_pUseStyle = NULL; } */ } else if( iMode==MODE_COPY || iInsertBarSelectBars( iInsertBar, iInsertBar + nBars - 1 ); } else if( iInsertBar>iEndBar ){ m_pContentPanel->SelectBars( iInsertBar - nBars, iInsertBar - 1 ); } ResetScrollBar(); Paint(); bool bDeletedMT = g_Midi.ClearEmptyTrack()>=0; if( bPreChange || (bDeletedMT || nMTCount!=g_aMidiTracks.size() ) && !m_pContentPanel->IsVertical() ) m_pContentPanel->InitialVars(); m_pContentPanel->OnStageChanged( bCountDown ? 0 : iFirstChangeStage, iMode ); } //----------------------------------------------------------------------------- void __fastcall TUseStylePanel::ReformBars( int iStartBarP, int iEndBarP, TSegmentItem* pSrcSeg, bool bAddUndo ) { Stop(); int iStartBar = iStartBarP; int iChangeStage = -1; TOpusStageList* lstStageBefore = NULL; if( bAddUndo ){ lstStageBefore = new TOpusStageList; g_Opus.CopyStages( iStartBarP, iEndBarP, lstStageBefore ); } while( iStartBar<=iEndBarP ){ int iFirstBar, iStage = FindStage( iStartBar, &iFirstBar ); TOpusStage* pOriStage = g_lstOpusStages[iStage]; if( pOriStage->iSegType>=SEGTYPE_INTRO ){ iStartBar = iFirstBar + pOriStage->aBars.size(); } else{ bool bChange = false; TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First(); TSegmentItem* pOriSegItem = (TSegmentItem*)pStyleItem->aItems->Items[iStage]; TSegmentItem* pDestSegItem = NULL; if( pOriStage->iSegType==pSrcSeg->iSegType && pOriStage->iSegNo==pSrcSeg->iSegNo && pOriStage->nVol==pSrcSeg->volume && pOriStage->aTracks.size()==pSrcSeg->aItems->Count ){ if( pOriStage->aTracks.size()>0 ){ int num = pOriStage->aTracks.size(); bool* aMatch = new bool[num]; memset( aMatch, false, sizeof(bool)*num ); for( int i=0; iaTracks[i]; bool bFound = false; for( int j=0; jaItems->Items[j])->pTrack; if( !aMatch[j] && pTrk1->iStyleId==pTrk2->iStyleId && pTrk1->iStyleLoc==pTrk2->iStyleLoc && pTrk1->iSegNo==pTrk2->iSegNo && pTrk1->iChanNo==pTrk2->iChanNo && pTrk1->iBank==pTrk2->iBank && pTrk1->iProg==pTrk2->iProg && pTrk1->nVol==pTrk2->nVol ){ bFound = true; aMatch[j] = true; break; } } if( !bFound ){ bChange = true; break; } } delete[] aMatch; } } else bChange = true; if( !bChange ) iStartBar = iFirstBar + pOriStage->aBars.size(); else{ TOpusStage* pBrushStage = NULL; int iEndBar = iFirstBar + pOriStage->aBars.size()-1; if( iEndBar>iEndBarP ){ g_Opus.CutStage( iStage, iEndBarP+1 ); g_Midi.CutStage( iStage ); InsertSegment( iStage+1, pOriSegItem, iEndBar - iEndBarP ); pOriSegItem->nBars -= iEndBar - iEndBarP; pStyleItem->nBars -= iEndBar - iEndBarP; iEndBar = iEndBarP; } if( iStartBar>iFirstBar ){ g_Opus.CutStage( iStage, iStartBar ); g_Midi.CutStage( iStage ); pDestSegItem = InsertSegment( iStage+1, pOriSegItem, iEndBar-iStartBar+1 ); pOriSegItem->nBars -= iEndBar-iStartBar+1; pStyleItem->nBars -= iEndBar-iStartBar+1; iStage++; } else{ pBrushStage = pOriStage; pDestSegItem = pOriSegItem; } ReplaceSegment( pDestSegItem, pSrcSeg ); //g_Opus.CountBars(); iStartBar = iEndBar + 1; if( iChangeStage<0 ) iChangeStage = iStage; } } } if( iChangeStage>=0 ){ IntegrateStages( iChangeStage ); if( bAddUndo ){ TOpusStageList* lstStageAfter = new TOpusStageList; g_Opus.CopyStages( iStartBarP, iEndBarP, lstStageAfter ); g_Undo.AddUndo( UNDO_BAR_CHANGE, 0, iStartBarP, iEndBarP, (void*)lstStageBefore, (void*)lstStageAfter ); } ResetScrollBar(); Paint(); m_pContentPanel->OnStageChanged( iChangeStage, MODE_CHANGE ); } else if( lstStageBefore ){ for( int i=0; isize(); i++ ){ delete (*lstStageBefore)[i]; } delete lstStageBefore; } } void __fastcall TUseStylePanel::ReformStage( int iDestStage, TSegmentItem* pSrcSeg ) { Stop(); TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First(); TSegmentItem* pDestSeg = (TSegmentItem*)pStyleItem->aItems->Items[iDestStage]; int iStartBar = FirstBar( iDestStage ), iEndBar = iStartBar + pDestSeg->nBars -1, nOffset = 0; bool bMMUndo = false; TAudioTrackList* lstAudio = NULL; TOpusStageList* lstStageBefore = new TOpusStageList; g_Opus.CopyStages( iStartBar, iEndBar, lstStageBefore ); if( pSrcSeg->iSegType>=SEGTYPE_INTRO && pSrcSeg->nBars!=pDestSeg->nBars ){ nOffset = pSrcSeg->nBars - pDestSeg->nBars; if( nOffset<0 ){ //小节减少,复制将删除部分波形 int nWaveBars = -nOffset; lstAudio = new TAudioTrackList; g_Audio.CopyTrackList( iEndBar+nOffset+1, nWaveBars, lstAudio ); } bMMUndo = true; } if( bMMUndo ){ f_MM_AddUndoBefore( -1, NULL ); } ReplaceSegment( pDestSeg, pSrcSeg ); IntegrateStages( iDestStage ); // if( bMMUndo ){ // f_MM_AddUndoAfter( -1, NULL ); // } TOpusStageList* lstStageAfter = new TOpusStageList; g_Opus.CopyStages( iStartBar, iEndBar+nOffset, lstStageAfter ); g_Undo.AddUndo( UNDO_BAR_CHANGE, 0, iStartBar, iEndBar, (void*)lstStageBefore, (void*)lstStageAfter ); if( bMMUndo ){ f_MM_AddUndoAfter( -1, NULL ); g_Undo.SetUndoExtra( nOffset, 0, 0, (void*)lstAudio, NULL ); } ResetScrollBar(); Paint(); m_pContentPanel->OnStageChanged( iDestStage, MODE_CHANGE ); } //----------------------------------------------------------------------------- void __fastcall TUseStylePanel::InitOpus( TStyleItem* pPreStyle, int iMode ) { //清空内容 ClearGlobalVars( LIST_OPUSSTAGES | LIST_OPUSAUDIOS ); ClearAllItems(); g_pUseStyle = NULL; m_bAddWeakupBar = true; if( iMode<0 || !pPreStyle ){ ClearGlobalVars( LIST_RAWAUDIO ); m_pContentPanel->InitialVars(); Paint(); return; } if( iMode==0 ){ UINT idLoc, idStyle; g_Theme.Get( idLoc, idStyle, g_lstOpusStages ); g_pUseStyle = AddStyle( GetStyleInfo( idLoc, idStyle ) ); for( int i=0; iHide(false); ((TStyleItem*)m_aItems->First())->SetCharge( g_pUseStyle->pStyle->idLoc==0 && g_pUseStyle->pStyle->pOrigin->cost>0 ); } else{ g_pUseStyle = AddStyle( pPreStyle->pStyle ); int iFirstStage = g_Theme.IsWeadup() ? 1 : 0; int nRepeat = iMode>=2 ? 2 : 1; int nSegNum[4]; vector aSegments[4]; memset( nSegNum, 0, sizeof(int)*4 ); for( int i=0; iaItems->Count; i++ ){ TSegmentItem* pSegment = (TSegmentItem*)pPreStyle->aItems->Items[i]; int stype = pSegment->GetSegType(); aSegments[stype].push_back( pSegment ); nSegNum[stype]++; } if( g_aAudioTracks[0]->lstBars.size()>0 ){ DuplicateRawBars(); if( iMode==2 ) MoveAudio( 1, 0, g_aAudioTracks[0]->lstBars.size(), 1, 0, MODE_COPY | OPT_BARS ); } int iSegNo; int nBarCount = 0; int nThemeStages = g_Theme.StageCount(); while( nRepeat>0 ){ if( iMode>0 && iMode<=3 && nSegNum[SEGTYPE_INTRO]>0 ){ //添加前奏 int iM = iMode>=2 ? 2 : 1; iSegNo = (iM - nRepeat) % nSegNum[SEGTYPE_INTRO]; int iChord = g_Theme.GetFirstChord(); int ctype = LOWORD( iChord ), key = HIWORD( iChord ); if( ctype==3 ) ctype = 1; else if( ctype>1 ) ctype = 0; if( ctype==1 ) key = ( key + 3 ) % 12; TSegmentItem *pSegment = NULL; TSegmentItem* pBackup = NULL; for( int j=0; jiSegNo / 4 == ctype ){ if( aSegments[SEGTYPE_INTRO][j]->iSegNo % 4 == iSegNo ){ pSegment = aSegments[SEGTYPE_INTRO][j]; break; } else{ pBackup = aSegments[SEGTYPE_INTRO][j]; } } } if( !pSegment ){ if( pBackup ) pSegment = pBackup; else pSegment = aSegments[SEGTYPE_INTRO][0]; //大小调不分 } TOpusStage* pNewStage = new TOpusStage; pNewStage->iSegNo = pSegment->iSegNo; pNewStage->iSegType = SEGTYPE_INTRO; pNewStage->iSegKey = key; pNewStage->nVol = pSegment->volume; int nBarNum = pSegment->nBars; for( int i=0; iaBars.push_back(pBar); } ProduceTracks( pNewStage, pSegment ); g_lstOpusStages.push_back( pNewStage ); int nWaveBars = nBarNum; if( iFirstStage>0 ) nWaveBars--; if( g_aAudioTracks.size()>1 ) MoveAudio( -1, 0, nWaveBars, 1, nBarCount, MODE_INSERT | OPT_BARS ); InsertSegment( -1, pSegment, nBarNum ); nBarCount += nBarNum; } //添加主旋律部分 iSegNo = 0; int iStartStage = iFirstStage; if( iMode>2 && nRepeat==1 && nThemeStages>iFirstStage + 2 ){ iStartStage++; if( nSegNum[SEGTYPE_VAR]>1 ) iSegNo = 1; } for( int i=iStartStage; iaBars.size(); if( i==nThemeStages-1 && nSegNum[SEGTYPE_FILL]>0 && pStage->aBars.size()>1 && iMode>0 && iMode<=3 && ( nRepeat>0 && nSegNum[SEGTYPE_INTRO]>0 || nRepeat==0 && nSegNum[SEGTYPE_ENDING]>0 )){ int iFill = 1 % nSegNum[SEGTYPE_FILL]; TSegmentItem *pSegFill = aSegments[SEGTYPE_FILL][iFill]; TOpusStage * pFillStage = new TOpusStage; pFillStage->iSegType = SEGTYPE_FILL; pFillStage->iSegNo = pSegFill->iSegNo; pFillStage->iSegKey = pStage->iSegKey; pFillStage->nVol = pStage->nVol; pFillStage->aBars.push_back( pStage->aBars.back() ); pStage->aBars.pop_back(); pSegItem->nBars--; g_pUseStyle->nBars--; ProduceTracks( pFillStage, pSegFill ); g_lstOpusStages.push_back( pFillStage ); AddStage( pFillStage ); } } nRepeat--; } if( iMode<=3 && nSegNum[SEGTYPE_ENDING]>0 ){ //添加尾奏 int iChord = g_Theme.GetLastChord(); int ctype = LOWORD( iChord ), key = HIWORD( iChord ); if( ctype==3 ) ctype = 1; else if( ctype>1 ) ctype = 0; if( ctype==1 ) key = ( key + 3 ) % 12; TSegmentItem *pSegment = NULL; for( int j=0; jiSegNo / 4 == ctype ){ pSegment = aSegments[SEGTYPE_ENDING][j]; break; } } if( !pSegment ){ pSegment = aSegments[SEGTYPE_ENDING][0]; //大小调不分 } TOpusStage* pNewStage = new TOpusStage; pNewStage->iSegType = SEGTYPE_ENDING; pNewStage->iSegNo = pSegment->iSegNo; pNewStage->iSegKey = key; pNewStage->nVol = pSegment->volume; int nBarNum = pSegment->nBars; for( int i=0; iaBars.push_back(pBar); } ProduceTracks( pNewStage, pSegment ); g_lstOpusStages.push_back( pNewStage ); if( g_aAudioTracks.size()>1 ) MoveAudio( -1, 0, nBarNum, 1, nBarCount, MODE_INSERT | OPT_BARS ); InsertSegment( -1, pSegment, nBarNum ); nBarCount += nBarNum; } } g_Opus.CountBars(); IntegrateStages( 0 ); g_Midi.SortMidiTracks(); SetFold( (TCommonItem*)m_aItems->First(), 0 ); ResetScrollBar(); Paint(); // InvalidateRgn( Handle, NULL, false ); m_pContentPanel->OnStageChanged( 0, MODE_INIT ); } // --------------------------------------------------------------------------- void __fastcall TUseStylePanel::SetStyleItem( TStyleItem* pStyItem ) { TStylePanel::SetStyleItem( pStyItem ); if( pStyItem ){ IntegrateStages( 0, false ); if( g_Midi.IsEmpty() ) g_Midi.SortMidiTracks(); } } // --------------------------------------------------------------------------- void TUseStylePanel::RestoreItems() { for( int i=0; iaBars.push_back( pNewBar ); //添加一个小节 int iBarT1 = iInsertBar; // 处理弱起 if( g_bWeakup ){ if( iInsertBar>0 ){ int iFirstBar, iLastStage = FindStage( iInsertBar-1, &iFirstBar ); TOpusStage *pLastStage = g_lstOpusStages[iLastStage]; if( pLastStage->iSegType>SEGTYPE_FILL && !memcmp( g_aAudioTracks[1]->lstBars[iInsertBar-1]->aVols, g_aAudioTracks[0]->lstBars[0]->aVols, POINTS_PER_BAR * sizeof(DWORD) )){ iBarT1--; } } } bool bCountDown = false; for( int i=1; iFirst(); //根据前后小节位置确定和弦与伴奏型 TSegmentItem *pSrcSeg = NULL; int iFirstBar1, iFirstBar2, iLastStage = FindStage( iInsertBar-1, &iFirstBar1 ), iNextStage = FindStage( iInsertBar, &iFirstBar2 ); TOpusStage *pLastStage = iLastStage>=0 ? g_lstOpusStages[iLastStage] : NULL, *pNextStage = g_lstOpusStages[iNextStage]; //是否前一小节可用 if( pLastStage && pLastStage->iSegType<=SEGTYPE_FILL ){ pNewStage->iSegKey = pLastStage->iSegKey; TBar *pLastBar = pLastStage->aBars[iInsertBar-iFirstBar1-1]; pNewBar->iBarKey = pLastBar->iBarKey; for( int i=0; iaChords.iKey[i] = pLastBar->aChords.iKey[g_nChordNumPerBar-1]; pNewBar->aChords.iType[i] = pLastBar->aChords.iType[g_nChordNumPerBar-1]; } pSrcSeg = (TSegmentItem*)pStyleItem->aItems->Items[iLastStage]; } else if( pNextStage->iSegType<=SEGTYPE_FILL ){ //是否后一小节可用 pNewStage->iSegKey = pNextStage->iSegKey; TBar *pNextBar = pNextStage->aBars[iInsertBar-iFirstBar2]; pNewBar->iBarKey = pNextBar->iBarKey; for( int i=0; iaChords.iKey[i] = pNextBar->aChords.iKey[0]; pNewBar->aChords.iType[i] = pNextBar->aChords.iType[0]; } pSrcSeg = (TSegmentItem*)pStyleItem->aItems->Items[iNextStage]; } else{ //前后小节皆不可用 int iSegKey, iKey, iType = 0; if( pLastStage ){ iKey = pNewBar->iBarKey = pNewStage->iSegKey = pLastStage->iSegKey; if( pLastStage->iSegNo % 2 > 0 ){ iKey = ( iKey + 9 ) % 12; iType = 1; } } else{ iKey = pNewBar->iBarKey = pNewStage->iSegKey = pNextStage->iSegKey; if( pNextStage->iSegNo % 2 > 0 ){ //小调 iKey = ( iKey + 9 ) % 12; iType = 1; } } for( int i=0; iaChords.iKey[i] = iKey; pNewBar->aChords.iType[i] = iType; } for( int i=0; iaItems->Count; i++ ){ TSegmentItem* pSegment = (TSegmentItem*)g_pPreStyle->aItems->Items[i]; int stype = pSegment->GetSegType(); if( stype==SEGTYPE_VAR || stype==SEGTYPE_FILL ){ pSrcSeg = pSegment; break; } } } pNewStage->iSegType = pSrcSeg->iSegType; pNewStage->iSegNo = pSrcSeg->iSegNo; // ProduceTracks( pNewStage, pSrcSeg ); g_Opus.InsertStage( iDestStage, pNewStage ); g_Midi.InsertStage( iDestStage ); InsertSegment( iDestStage, pSrcSeg, 1 ); IntegrateStages( iDestStage ); ResetScrollBar(); Paint(); m_pContentPanel->OnStageChanged( iDestStage, MODE_INSERT ); } // --------------------------------------------------------------------------- void TUseStylePanel::CountStyles() { m_aStyles.clear(); if( m_aItems->Count==0 ) return; TStyleItem* pStyItem = (TStyleItem*)m_aItems->First(); TPROSTYLE* pStyle = pStyItem->pStyle, *pMainStyle = NULL; vector lstCount; for( int i=0; iaItems->Count; i++ ){ TSegmentItem* pSeg = (TSegmentItem*)pStyItem->aItems->Items[i]; for( int j=0; jaItems->Count; j++ ){ TTrackItem* pTrk = (TTrackItem*)pSeg->aItems->Items[j]; bool bMatch = false; for( int k=0; kpStyle->idLoc==m_aStyles[k]->idLoc // && pTrk->pStyle->idStyle==m_aStyles[k]->idStyle ){ if( pTrk->pStyle==m_aStyles[k] ){ bMatch = true; lstCount[k]++; break; } } if( !bMatch ){ m_aStyles.push_back( pTrk->pStyle ); lstCount.push_back( 1 ); } } } bool bKeep = false; bool bCharge = false; int maxCount = 0; for( int i=0; imaxCount ){ maxCount = lstCount[i]; pMainStyle = m_aStyles[i]; } if( pStyle && pStyle->idLoc==m_aStyles[i]->idLoc && pStyle->idStyle==m_aStyles[i]->idStyle ){ bKeep = true; } if( !bCharge && m_aStyles[i]->idLoc==0 && m_aStyles[i]->pOrigin->cost>0 ){ bCharge = true; } } if( !pStyle || !bKeep ){ pStyItem->pStyle = pMainStyle; if( m_pTopItem==pStyItem ) DrawItem( pStyItem, 0, -1 ); } pStyItem->SetCharge( bCharge ); } // --------------------------------------------------------------------------- void TUseStylePanel::CopyUndoBars( int iStartBar, int iEndBar, TOpusStageList* lstStages, TAudioTrackList* lstAudio, bool bFx ) { if( lstStages ) g_Opus.CopyStages( iStartBar, iEndBar, lstStages ); if( lstAudio ) g_Audio.CopyTrackList( iStartBar, iEndBar-iStartBar+1, lstAudio, bFx ); } void TUseStylePanel::CopyBars( int iStartBar, int iEndBar, TOpusStageList* lstStages, TSegmentList* lstSegments, TAudioTrackList* lstAudio ) { int iBar = iStartBar; while( iBar<=iEndBar ){ int iFirstBar, iSrcStage = FindStage( iBar, &iFirstBar ), nOffsetBar = iBar-iFirstBar; TOpusStage* pOriStage = g_lstOpusStages[iSrcStage]; int nCopyBar = pOriStage->aBars.size() - nOffsetBar; if( nCopyBar>iEndBar-iBar+1 ) nCopyBar = iEndBar-iBar+1; if( lstStages ){ TOpusStage* pNewStage = new TOpusStage( pOriStage ); for( int i=nOffsetBar; iaBars.push_back( new TBar( pOriStage->aBars[i] ) ); } for( int j=0; jaTracks.size(); j++ ){ pNewStage->aTracks.push_back( new TTrack( pOriStage->aTracks[j] )); } lstStages->push_back( pNewStage ); } iBar += nCopyBar; } if( lstAudio ){ for( int i=1; ipush_back( pAudio ); } } } // --------------------------------------------------------------------------- /* void TUseStylePanel::InsertStages( int iInsertBar, TOpusStageList lstStages ) { int iDestStage = GetInsertStage( iInsertBar ); for( int i=lstStages.size()-1; i>=0; i-- ){ TOpusStage* pStage = lstStages[i]; g_lstOpusStages.insert( g_lstOpusStages.begin()+iDestStage, pStage ); } } // --------------------------------------------------------------------------- */ void TUseStylePanel::DeleteBars( int iStartBarP, int iEndBarP, bool bDelWave ) { TStyleItem* pStyItem = (TStyleItem*)m_aItems->First(); int iBar = iStartBarP, iEndBar = iEndBarP; while( iBar<=iEndBar ){ int iFirstBar, iSrcStage = FindStage( iBar, &iFirstBar ), nOffsetBar = iBar-iFirstBar; TSegmentItem* pSrcSeg = (TSegmentItem*)pStyItem->aItems->Items[iSrcStage]; TOpusStage* pOriStage = g_lstOpusStages[iSrcStage]; int nDelBar = pOriStage->aBars.size() - nOffsetBar; if( nDelBar>iEndBar-iBar+1 ) nDelBar = iEndBar-iBar+1; pOriStage->aBars.erase( pOriStage->aBars.begin() + nOffsetBar, pOriStage->aBars.begin() + nOffsetBar + nDelBar ); iEndBar -= nDelBar; g_Opus.ChangeStageBar( iSrcStage, -nDelBar, true ); if( pOriStage->aBars.empty() ){ //删除原段落 RemoveSegment( pSrcSeg, false ); } else{ pSrcSeg->nBars -= nDelBar; } pStyItem->nBars -= nDelBar; } // g_Opus.CountBars(); if( bDelWave ){ for( int i=1; ilstEffects, iStartBarP, iEndBarP+1 ); } } m_pContentPanel->SelectBars( -1, -1 ); } // --------------------------------------------------------------------------- void TUseStylePanel::Undo( bool bUndo ) { if( m_VolTrackBar ){ delete m_VolTrackBar; m_VolTrackBar = NULL; } int iMode=-1, iChangeStage = 0; TUndoLite* pLite = bUndo ? g_Undo.Undo() : g_Undo.Redo(); int iType = pLite->iType; if( ( iTypeUNDO_MIDI_FONT ) && ( iTypeUNDO_TRKMID_DELALL ) && VIEW_STYLE!=g_iViewMode ) Application->MainForm->Perform( UM_SETVIEWMODE, VIEW_STYLE, 0 ); if( iType!=UNDO_STAGE_VOL ) Stop(); if( iType>=UNDO_BAR_INSERT && iType<=UNDO_BAR_CHANGE ){ if( bUndo && pLite->iCode>0 ){ //处理AddWeakupBar m_bAddWeakupBar = true; //删除第一小节 for( int i=1; ilstBars[0]; pAT->lstBars.erase( pAT->lstBars.begin() ); } TOpusStage* pStage = g_lstOpusStages[0]; delete pStage->aBars[0]; pStage->aBars.erase( pStage->aBars.begin() ); g_Opus.CountBars(); TStyleItem* pStyItem = (TStyleItem*)m_aItems->First(); TSegmentItem* pSegment = (TSegmentItem*)pStyItem->aItems->Items[0]; pSegment->nBars--; pStyItem->nBars--; } int iDelStart = pLite->iBegin, iDelEnd = pLite->iEnd, iInsStart = pLite->iBegin, iInsEnd = pLite->iEnd, nBars = pLite->iEnd - pLite->iBegin + 1; TOpusStageList* lstStages = ( iType>=UNDO_BAR_CHANGE && !bUndo || iType==UNDO_BAR_INSERT ) ? (TOpusStageList*)pLite->pAfter : (TOpusStageList*)pLite->pBefore; if( iTypeiExt1 ) f_MM_Undo( bUndo ); if( iType==UNDO_BAR_INSERT && bUndo || iType==UNDO_BAR_DELETE && !bUndo ){ iMode = MODE_DELETE; } else if( iType==UNDO_BAR_INSERT && !bUndo || iType==UNDO_BAR_DELETE && bUndo ){ iMode = MODE_INSERT; } else if( iType==UNDO_BAR_MOVE ){ iMode = MODE_MOVE; if( bUndo ){ iDelStart = pLite->iExt1; iDelEnd = iDelStart + nBars - 1; } else{ iInsStart = pLite->iExt1; iInsEnd = iInsStart + nBars - 1; } } else{ iMode = MODE_CHANGE; if( bUndo ) iDelEnd += pLite->iExt1; else iInsEnd += pLite->iExt1; } iChangeStage = FindStage( min( iDelStart, iInsStart ), NULL ); int nMTCount = g_aMidiTracks.size(); if( iMode==MODE_DELETE || iMode==MODE_MOVE || iMode==MODE_CHANGE ){ DeleteBars( iDelStart, iDelEnd, iMode==MODE_CHANGE ? false : true ); } if( iMode==MODE_INSERT || iMode==MODE_MOVE || iMode==MODE_CHANGE ){ //还原波形 if( iMode==MODE_INSERT || iMode==MODE_MOVE ){ TAudioTrackList* lstAudio = (TAudioTrackList*)pLite->pExt1; for( int i=1; i iDelEnd ){ TAudioTrackList* lstAudio = (TAudioTrackList*)pLite->pExt1; for( int i=1; iiSegType = pStage->iSegType; pSegment->iSegNo = pStage->iSegNo; pSegment->volume = pStage->nVol; pSegment->nBars = pStage->aBars.size(); DWORD opts = OPT_DEL|OPT_VOL; if( pStage->iSegTypeaTracks.size(); i++ ){ TTrack* pTrack = pStage->aTracks[i]; TPROSTYLE* pStyle = GetStyleInfo( pTrack->iStyleLoc, pTrack->iStyleId ); if( pStyle ){ pSegment->AddTrack( pStyle, pTrack, opts, false ); TMidiTrack* pMT = g_Midi.GetValidMidiTrack( iStage, pTrack->iFile, pTrack->iChanSpec, pTrack->iBank, pTrack->iProg ); pTrack->iFile = pMT->file; pTrack->iChanSpec = pMT->chno; } else{ DebugPrint( "风格文件已失效!\n" ); delete pTrack; pStage->aTracks.erase( pStage->aTracks.begin() + i ); i--; } } InsertSegment( iStage, pSegment, pStage->aBars.size() ); delete pSegment; iStage++; } m_pContentPanel->SelectBars( iInsStart, iInsEnd ); } IntegrateStages( iChangeStage, false ); ResetScrollBar(); Paint(); bool bDeletedMT = g_Midi.ClearEmptyTrack()>=0; if( m_pContentPanel->IsVertical() && nBars==g_Opus.BarCount() || !m_pContentPanel->IsVertical() && ( bDeletedMT || nMTCount!=g_aMidiTracks.size()) ){ m_pContentPanel->InitialVars(); } // if( !m_pContentPanel->IsVertical() ) // GenerateCompose(); } else if( iType==UNDO_TRKMID_DELALL ){ if( m_pContentPanel->IsVertical() ){ if( pLite->iCode==ST_MIDI ) m_pContentPanel->SetScrollMode( false ); } TOpusStageList* lstStages = bUndo ? (TOpusStageList*)pLite->pBefore : (TOpusStageList*)pLite->pAfter; TMidiTrackList *lstTracks = bUndo ? (TMidiTrackList*)pLite->pExt1 : NULL; UINT idLoc = bUndo ? pLite->iExt1 : pLite->iExt2, idStyle = bUndo ? pLite->iBegin : pLite->iEnd; ClearAllItems(); g_Midi.ClearMidiTracks(); if( lstTracks ){ for( int i=0; isize(); i++ ){ TMidiTrack* pMT = new TMidiTrack((*lstTracks)[i]); g_Midi.AddMidiTrack( pMT ); } } g_Opus.Set( idLoc, idStyle, *lstStages ); g_Midi.SortMidiTracks(); g_Opus.BuildStyleItem(); TStylePanel::SetStyleItem( g_pUseStyle ); ResetScrollBar(); Paint(); if( !m_pContentPanel->IsVertical() ){ m_pContentPanel->InitialVars(); GenerateCompose(); } else if( g_iSegColorMode==1 ){ m_pContentPanel->InvalidateBars( 0, g_Opus.BarCount()-1, BAR_DATA ); } if( g_iPreStage==0 ){ g_Theme.Set( g_pUseStyle->pStyle->idLoc, g_pUseStyle->pStyle->idStyle, g_lstOpusStages ); } } else if( iType>=UNDO_MIDI_ADD && iType<=UNDO_MIDI_FONT || iType==UNDO_TRKMID_ADD || iType==UNDO_TRKMID_DEL ){ if( m_pContentPanel->IsVertical() ){ if( pLite->iCode==ST_MIDI ) m_pContentPanel->SetScrollMode( false ); else if( VIEW_STYLE!=g_iViewMode ) Application->MainForm->Perform( UM_SETVIEWMODE, VIEW_STYLE, 0 ); } vector *aAddStage = (vector*)( bUndo ? pLite->pExt1 : pLite->pExt2 ), *aDelStage = (vector*)( bUndo ? pLite->pExt2 : pLite->pExt1 ); TTrack *aAddTrks = bUndo ? (TTrack*)pLite->pBefore : (TTrack*)pLite->pAfter; int iSBar = pLite->iBegin, iEBar = pLite->iEnd, iBStage = iSBar<0 ? 0 : GetInsertStage( iSBar ), infoAdd = bUndo ? pLite->iExt1 : pLite->iExt2, infoDel = bUndo ? pLite->iExt2 : pLite->iExt1, iAddMT = infoAdd==-1 ? -1 : (infoAdd & 0xFF), iDelMT = infoDel==-1 ? -1 : (infoDel & 0xFF); BYTE iAddMTState = infoAdd==-1 ? 0 : (infoAdd & 0xFF00)>>8, iAddMTVol = infoAdd==-1 ? 0 : (infoAdd & 0xFF0000)>>16; char iAddMTPan = infoAdd==-1 ? 0 : (infoAdd & 0xFF000000)>>24; if( iEBar>=0 ) GetInsertStage( iEBar+1 ); TMidiTrack *pDelMT = NULL, *pAddMT = NULL; if( iDelMT>=0 && iDelMT=0 && iAddMT::iterator itAdd = aAddStage->begin(), itDel = aDelStage->begin(); int iAddStage(-1), iAddTrack(-1), iDelStage(-1), iDelTrack(-1); if( itAdd!=aAddStage->end() ){ int iFBar = (*itAdd) & 0xFFF, iLBar = ((*itAdd) & 0xFFF000)>>12; iAddTrack = ((*itAdd) & 0xFF000000)>>24; iAddStage = GetInsertStage( iFBar ); GetInsertStage( iLBar+1 ); } if( itDel!=aDelStage->end() ){ int iFBar = (*itDel) & 0xFFF, iLBar = ((*itDel) & 0xFFF000)>>12; iDelTrack = ((*itDel) & 0xFF000000)>>24; iDelStage = GetInsertStage( iFBar ); GetInsertStage( iLBar+1 ); } bool bAddedMT = false; TStyleItem* pStyItem = (TStyleItem*)m_aItems->First(); while( itAdd!=aAddStage->end() || itDel!=aDelStage->end() ){ if( iDelStage>=0 && (iAddStage<0 || iDelStageaTracks[iDelTrack]; if( !pDelMT || pDelMT->file!=pTrack->iFile || pDelMT->chno!=pTrack->iChanSpec ){ pDelMT = g_Midi.FindMidiTrack( pTrack->iFile, pTrack->iChanSpec ); } delete pTrack; pStage->aTracks.erase( pStage->aTracks.begin()+iDelTrack ); TSegmentItem* pSegment = (TSegmentItem*)pStyItem->aItems->Items[iDelStage]; TTrackItem* pTrkItem = (TTrackItem*)pSegment->aItems->Items[iDelTrack]; TStylePanel::DeleteItem( pTrkItem, -1 ); pDelMT->DelStage( iDelStage ); if( ++itDel!=aDelStage->end() ){ int iFBar = (*itDel) & 0xFFF, iLBar = ((*itDel) & 0xFFF000)>>12; iDelTrack = ((*itDel) & 0xFF000000)>>24; iDelStage = GetInsertStage( iFBar ); GetInsertStage( iLBar+1 ); } else{ iDelStage = -1; iDelTrack = -1; } } else if( iDelStage>=0 && iDelStage==iAddStage ){ TOpusStage* pStage = g_lstOpusStages[iDelStage]; TTrack *pTrack = pStage->aTracks[iDelTrack], *pSubTrack = &aAddTrks[itAdd - aAddStage->begin()]; if( !pDelMT || pDelMT->file!=pTrack->iFile || pDelMT->chno!=pTrack->iChanSpec ){ pDelMT = g_Midi.FindMidiTrack( pTrack->iFile, pTrack->iChanSpec ); } if( pSubTrack->iFile!=pDelMT->file || pSubTrack->iChanSpec!=pDelMT->chno ){ if( !pAddMT || pAddMT->file!=pSubTrack->iFile || pAddMT->chno!=pSubTrack->iChanSpec || pAddMT->prog!=pSubTrack->iProg || !( pAddMT=g_Midi.FindMidiTrack( pSubTrack->iFile, pSubTrack->iChanSpec )) ){ pAddMT = new TMidiTrack( pSubTrack->iBank, pSubTrack->iChanSpec, pSubTrack->iProg, pSubTrack->iFile ); pAddMT->state = iAddMTState; pAddMT->volume = iAddMTVol; pAddMT->pan = iAddMTPan; g_Midi.AddMidiTrack( pAddMT, iAddMT ); bAddedMT = true; } pDelMT->DelStage( iDelStage ); pAddMT->AddStage( iAddStage ); } else if( pAddMT==pDelMT && pSubTrack->iProg!=pAddMT->prog ){ pAddMT->prog = pSubTrack->iProg; } if( pTrack->iStyleLoc!=pSubTrack->iStyleLoc || pTrack->iStyleId!=pSubTrack->iStyleId ){ TSegmentItem* pSeg = (TSegmentItem*)pStyItem->aItems->Items[iDelStage]; TTrackItem* pTrkItem = (TTrackItem*)pSeg->aItems->Items[iDelTrack]; pTrkItem->pStyle = GetStyleInfo( pSubTrack->iStyleLoc, pSubTrack->iStyleId ); } memcpy( pTrack, pSubTrack, sizeof(TTrack) ); if( ++itAdd!=aAddStage->end() ){ int iFBar = (*itAdd) & 0xFFF, iLBar = ((*itAdd) & 0xFFF000)>>12; iAddTrack = ((*itAdd) & 0xFF000000)>>24; iAddStage = GetInsertStage( iFBar ); GetInsertStage( iLBar+1 ); } else{ iAddStage = -1, iAddTrack = -1; } if( ++itDel!=aDelStage->end() ){ int iFBar = (*itDel) & 0xFFF, iLBar = ((*itDel) & 0xFFF000)>>12; iDelTrack = ((*itDel) & 0xFF000000)>>24; iDelStage = GetInsertStage( iFBar ); GetInsertStage( iLBar+1 ); } else{ iDelStage = -1; iDelTrack = -1; } } else if( iAddStage>=0 && ( iDelStage<0 || iDelStage>iAddStage ) ){ TTrack* pTrack = new TTrack( &aAddTrks[itAdd - aAddStage->begin()] ); if( !pAddMT || pAddMT->file!=pTrack->iFile || pAddMT->chno!=pTrack->iChanSpec || !( pAddMT=g_Midi.FindMidiTrack( pTrack->iFile, pTrack->iChanSpec )) ){ pAddMT = new TMidiTrack( pTrack->iBank, pTrack->iChanSpec, pTrack->iProg, pTrack->iFile ); pAddMT->state = iAddMTState; pAddMT->volume = iAddMTVol; pAddMT->pan = iAddMTPan; g_Midi.AddMidiTrack( pAddMT, iAddMT ); bAddedMT = true; } TOpusStage* pStage = g_lstOpusStages[iAddStage]; TSegmentItem* pSeg = (TSegmentItem*)pStyItem->aItems->Items[iAddStage]; pStage->aTracks.insert( pStage->aTracks.begin()+iAddTrack, pTrack ); AddTrack( pSeg, pTrack, iAddTrack ); pAddMT->AddStage( iAddStage ); if( ++itAdd!=aAddStage->end() ){ int iFBar = (*itAdd) & 0xFFF, iLBar = ((*itAdd) & 0xFFF000)>>12; iAddTrack = ((*itAdd) & 0xFF000000)>>24; iAddStage = GetInsertStage( iFBar ); GetInsertStage( iLBar+1 ); } else{ iAddStage = -1, iAddTrack = -1; } } } IntegrateStages( iBStage, false ); ResetScrollBar(); Paint(); bool bDeletedMT = g_Midi.ClearEmptyTrack()>=0; if( !m_pContentPanel->IsVertical() ){ if( bDeletedMT || bAddedMT ){ m_pContentPanel->InitialVars(); } else{ if( iDelMT>=0 ){ int iST = m_pContentPanel->GetShowTrackId( ST_MIDI, iDelMT ); if( iST>0 ) m_pContentPanel->InvalidateBars( iSBar, iEBar, BAR_TRACK | iST ); } } if( iAddMT>=0 && !aAddStage->empty() || iDelMT>=0 && !bDeletedMT ){ if( VIEW_TRACK!=g_iViewMode ) Application->MainForm->Perform( UM_SETVIEWMODE, VIEW_TRACK, 0 ); if( iAddMT==iDelMT ) m_pContentPanel->SelectTrack( -1, -1, -1, false ); int iMT = iAddMT>=0 && !aAddStage->empty() ? iAddMT : iDelMT, iST = m_pContentPanel->GetShowTrackId( ST_MIDI, iMT ); if( iST>0 ){ m_pContentPanel->SelectTrack( iST-1, -1, -1, false ); m_pContentPanel->SetSelectRange( iSBar, 0, iEBar, POINTS_PER_BAR-1, true ); } } GenerateCompose(); } if( g_iSegColorMode==1 && iType!=UNDO_MIDI_FONT ) m_pContentPanel->InvalidateBars( iSBar, iEBar, BAR_DATA ); } else if( iType==UNDO_OPUS_STYLE ){ //全曲风格替换 iMode = MODE_INIT; TAudioTrackList* lstAudio = (TAudioTrackList*)pLite->pExt1; TOpusStageList* lstStages = (TOpusStageList*)( bUndo ? pLite->pBefore : pLite->pAfter ); if( lstAudio ){ f_MM_Undo( bUndo ); } g_Audio.RestoreAudio( lstStages, lstAudio, bUndo ); g_Opus.Set( pLite->iBegin, pLite->iEnd, *lstStages ); g_Opus.BuildStyleItem(); g_Midi.ClearMidiTracks(); SetStyleItem( g_pUseStyle ); if( g_iPreStage==0 ){ g_Theme.Set( g_pUseStyle->pStyle->idLoc, g_pUseStyle->pStyle->idStyle, g_lstOpusStages ); } } else if( iType==UNDO_STAGE_VOL || iType==UNDO_PROG_VOL ){ int iStage = GetInsertStage( pLite->iBegin ), nStageLen = pLite->iEnd - pLite->iBegin; TStyleItem* pStyItem = (TStyleItem*)m_aItems->First(); TSegmentItem* pTempSeg = (TSegmentItem*)pStyItem->aItems->Items[iStage]; if( pTempSeg->iSegTypenBars>nStageLen ) GetInsertStage( pLite->iEnd ); TSegmentItem* pSegItem = (TSegmentItem*)pStyItem->aItems->Items[iStage]; int iSet = (int)(bUndo ? pLite->pBefore : pLite->pAfter ), iOther = (int)(!bUndo ? pLite->pBefore : pLite->pAfter ); TCommonItem* pSetItem = NULL; if( iType==UNDO_STAGE_VOL ){ SetSelectStage( iStage ); pSetItem = pSegItem; } else{ TTrack* pExt = (TTrack*)pLite->pExt1; for( int i=0; iaItems->Count; i++ ){ TTrackItem* pTrkItem = (TTrackItem*)pSegItem->aItems->Items[i]; TTrack* pTrack = pTrkItem->pTrack; if( pTrack->iStyleLoc==pExt->iStyleLoc && pTrack->iStyleId==pExt->iStyleId && pTrack->iSegNo==pExt->iSegNo && pTrack->iBank==pExt->iBank && pTrack->iProg==pExt->iProg && pTrack->nVol==iOther ){ pSetItem = pTrkItem; SetSelectTrack( pTrkItem ); break; } } } ChangeVolume( iStage, pSetItem, iSet, false ); if( iSet>=0 && iOther<0 || iSet<0 && iOther>=0 ){ //静音操作 DrawItem( m_pSelItem, m_iSelLine, COL_FOLD ); } else{ DrawItem( m_pSelItem, m_iSelLine, COL_TEXT ); DoAdjustVolume( NULL ); } } if( iMode>=0 ) m_pContentPanel->OnStageChanged( iChangeStage, iMode ); } // --------------------------------------------------------------------------- void TUseStylePanel::SetSelectTrack( TTrackItem* pTrack ) { TStyleItem* pStyle = (TStyleItem*)m_aItems->Items[0]; TSegmentItem* pSeg = (TSegmentItem*)pTrack->up; if( !pStyle->IsUnfold() ){ SetFold( pStyle, 0 ); } TCommonItem* pItem = GetNextItem( pStyle ); int iLine = 1; while( pItem!=pSeg ){ pItem = GetNextItem( pItem ); iLine++; } if( !pSeg->IsUnfold() ){ SetFold( pSeg, iLine ); } while( pItem!=pTrack ){ pItem = GetNextItem( pItem ); iLine++; } SetSelect( pTrack, iLine - m_iTopLine ); ShowSelItem(); } // --------------------------------------------------------------------------- bool __fastcall TUseStylePanel::GetPrebeat( BYTE* pData, int& nSize ) { if( m_aItems->Count==0 ) return false; TStyleItem* pStyItem = (TStyleItem*)m_aItems->Items[0]; TTrack* pDrumTrk = NULL; for( int i=pStyItem->aItems->Count-1; !pDrumTrk && i>=0; i-- ){ TSegmentItem* pSeg = (TSegmentItem*)pStyItem->aItems->Items[i]; int stype = pSeg->GetSegType(); if( stype!=SEGTYPE_ENDING ){ for( int j=0; jaItems->Count; j++ ){ TTrack* pTrk = ((TTrackItem*)pSeg->aItems->Items[j])->pTrack; if( pTrk->iChanNo==9 ){ pDrumTrk = pTrk; break; } } } } if( pDrumTrk ){ int nStageNum = 1; TStage* aStages = new TStage[nStageNum]; aStages[0].iSegType = SEGTYPE_VAR; aStages[0].iSegKey = 0; aStages[0].nBarNum = 4; aStages[0].aChords = new TBarChords[aStages[0].nBarNum]; for( int j=0; j<4; j++ ){ aStages[0].aChords[j].iKey[0] = aStages[0].aChords[j].iKey[1] = aStages[0].aChords[j].iKey[2] = aStages[0].aChords[j].iKey[3] = 0; aStages[0].aChords[j].iType[0] = aStages[0].aChords[j].iType[1] = aStages[0].aChords[j].iType[2] = aStages[0].aChords[j].iType[3] = 0; } //tracks aStages[0].nTrkNum = 1; aStages[0].aTracks = new TComposeTrack[aStages[0].nTrkNum]; aStages[0].aTracks[0].iStyleLoc = pDrumTrk->iStyleLoc; aStages[0].aTracks[0].iStyleId = pDrumTrk->iStyleId; aStages[0].aTracks[0].iSegNo = pDrumTrk->iSegNo; aStages[0].aTracks[0].iChanNo = pDrumTrk->iChanNo; aStages[0].aTracks[0].iChanSpec = pDrumTrk->iChanSpec; aStages[0].aTracks[0].iProg = pDrumTrk->iProg; aStages[0].aTracks[0].nVol = 110; int ret = f_CM_Compose( &nSize, pData, g_iMelodyTimeSignature, g_nMelodyTempo, nStageNum, aStages, false, NULL, NULL ); if( ret==0 ){ return true; } } return false; } // --------------------------------------------------------------------------- void TUseStylePanel::SetBarsUndo( int iMode, int iStartBar, int nBars, int iMoveTo ) { int iEndBar = iStartBar + nBars - 1; TOpusStageList* lstStages = new TOpusStageList; TAudioTrackList* lstAudio = new TAudioTrackList; CopyUndoBars( iStartBar, iEndBar, lstStages, lstAudio ); void *pBefore = iMode==UNDO_BAR_INSERT ? NULL : (void*)lstStages, *pAfter = iMode==UNDO_BAR_INSERT ? (void*)lstStages : NULL; g_Undo.AddUndo( iMode, 0, iStartBar, iEndBar, pBefore, pAfter ); if( iMode==UNDO_BAR_MOVE && iMoveTo > iStartBar ) iMoveTo -= nBars; g_Undo.SetUndoExtra( iMoveTo, 0, 0, (void*)lstAudio, NULL ); } //---------------------------------------------------------------------------