//--------------------------------------------------------------------------- #include #pragma hdrstop #include "GlobalUnit.h" #include "Project.h" #include "StyleItem.h" #include "MidiTrack.h" #include "Undo.h" //--------------------------------------------------------------------------- #pragma package(smart_init) typedef struct tagTempStyleMap //临时风格映射 { UINT idTemp; UINT idLoc; UINT idStyle; } TTempStyleMap, *PTTempStyleMap; const char *g_strProjError[11] = { "全局或部分音色库失效,使用缺省音色库", "部分段落风格失效,使用全局风格替换", "部分音效失效,请重新设置", "打开工程失败!\n\n文件不存在", "打开工程失败!\n\n早期版本,请尝试用大众版打开", "打开工程失败!\n\n版本太新,请更新软件到最新版", "打开工程失败!\n\n无法识别的版本号", "打开工程失败!\n\n文件已损坏", "打开工程失败!\n\n音频数据被破环", "打开工程失败!\n\n使用的风格未下载或已失效", "打开工程失败!\n\n使用本地风格须先登录"}; const DWORD g_dwProjectVersion = MAKELONG(7, 5); //ver 5.6 //ver 2.0-2.1 3.0-3.1 4.0-4.1 5.0-5.1禁用,以判断早期版本 //ver 3.2 专业版工程 //ver 3.3 g_bPredefine读写,支持无Audio //ver 4.2 TPPRSTYLE风格结构,支持自制风格/支付记录 //ver 4.3 支持变调,新TBar/TOpusStage结构 //ver 4.4 g_bMidiMelody读写 //ver 5.2 VIP版工程, 记录工程功能费支付,旋律识别信息更新, 不保存TTrack信息,原始段落表 //ver 5.3 增加工程模式标志 iMode=0,1,2 //ver 5.4 TTrack保存iBank //ver 5.5 增加ExtendFont //ver 5.6 新BaseTrack格式 //ver 5.7 音频轨道增加到17轨 vector u_aTempStyleMap; //临时风格映射表 wstring g_strLastProjSavePath, // 上次保存工程路径 g_strProjectName, // 工程文件名 g_strAutoProjName; // 自动保存文件名 //g_strFontFile_SVD; // 音色库文件名(已保存) vectorg_lstRecentProject; // 最近的工程文件 HANDLE g_hProjectEvent; // 工程文件读写互斥变量 int g_iMelodyKey_SVD = -1, // 主旋律调号(已保存) g_nMelodyTempo_SVD = 75; // 主旋律速度(已保存) float g_fRecordVolume_SVD = -1, //录音音量(已保存) g_fSpeakerVolume_SVD = -1; //播放音量(已保存) char g_strSoundFont_SVD[80]; //全局音色库名(已保存) TUndoLite* u_pProjLite = NULL, * u_pAutoLite = NULL; void ClearProjStyleMap() { for( int i=0; ipOrigin->state!=e_Downloaded ){ if( f_CS_DownloadStyle( idStyle, NULL )!=0 ){ pStyle = NULL; } else{ pStyle->pOrigin->state = e_Downloaded; } } return pStyle; } void UpdateRecentProject(wstring wstrProj) { // 更新最近工程列表 wchar_t strTemp[MAX_PATH]; wstring strLowerProjName, strLowerCompName; wcscpy(strTemp, wstrProj.c_str()); strLowerProjName = _wcslwr(strTemp); BOOL bInList = FALSE; for (int i = 0; i < g_lstRecentProject.size(); i++) { wcscpy(strTemp, g_lstRecentProject[i].c_str()); strLowerCompName = _wcslwr(strTemp); if (strLowerProjName.compare(strLowerCompName) == 0) { if (i > 0) { vector::iterator iterStr = g_lstRecentProject.begin() + i; g_lstRecentProject.erase(iterStr); g_lstRecentProject.insert(g_lstRecentProject.begin(), wstrProj); } bInList = TRUE; break; } } if (!bInList) { g_lstRecentProject.insert(g_lstRecentProject.begin(), wstrProj); } } void CheckLocId( UINT& idLoc, UINT& idStyle ) { if( idLoc==(UINT)-1 ){ for( int k=0; kidTemp ){ idLoc = u_aTempStyleMap[k]->idLoc; idStyle = u_aTempStyleMap[k]->idStyle; break; } } } } void KeepLocSegment( LOCSEGLIST& aLocSegs, UINT& idLoc, UINT& idStyle, int iSegType, int iSegNo ) { bool bKeep = false; DWORD dwSeg = MAKELONG( iSegType, iSegNo ); for( int k=0; kidLoc && idStyle==aLocSegs[k]->idStyle ){ for( int t=0; taSegs.size(); t++ ){ if( dwSeg==aLocSegs[k]->aSegs[t] ){ bKeep = true; break; } } if( !bKeep ){ aLocSegs[k]->aSegs.push_back( dwSeg ); bKeep = true; break; } } } if( !bKeep ){ TLocSegment* pLocSeg = new TLocSegment; pLocSeg->idLoc = idLoc; pLocSeg->idStyle = idStyle; pLocSeg->aSegs.push_back( dwSeg ); aLocSegs.push_back( pLocSeg ); } CheckLocId( idLoc, idStyle ); } void SaveOpusStages( TOpusStageList& lstStages, LOCSEGLIST& lstLocSeg, FILE* pFile ) { int num = lstStages.size(); fwrite( &num, sizeof(int), 1, pFile ); for( int i=0; iiSegType, sizeof(char), 1, pFile ); fwrite( &pStage->iSegNo, sizeof(char), 1, pFile ); fwrite( &pStage->iSegKey, sizeof(char), 1, pFile ); fwrite( &pStage->nVol, sizeof(char), 1, pFile ); int count = pStage->aBars.size(); fwrite( &count, sizeof(int), 1, pFile ); for( int j=0; jaBars[j]; fwrite( &pBar->aChords, sizeof(TBarChords), 1, pFile ); fwrite( &pBar->iBarKey, sizeof(char), 1, pFile ); } count = pStage->aTracks.size(); fwrite( &count, sizeof(int), 1, pFile ); for( int j=0; jaTracks[j]; UINT idLoc = pTrack->iStyleLoc, idStyle = pTrack->iStyleId; //记录本地风格片段 if( idLoc!=0 ){ KeepLocSegment( lstLocSeg, idLoc, idStyle, pStage->iSegType, pTrack->iSegNo ); } fwrite( &idLoc, sizeof(UINT), 1, pFile ); fwrite( &idStyle, sizeof(UINT), 1, pFile ); fwrite( &pTrack->iSegNo, sizeof(BYTE), 1, pFile ); fwrite( &pTrack->iChanNo, sizeof(BYTE), 1, pFile ); fwrite( &pTrack->iChanSpec, sizeof(BYTE), 1, pFile ); fwrite( &pTrack->iProg, sizeof(BYTE), 1, pFile ); fwrite( &pTrack->iProgOrig, sizeof(BYTE), 1, pFile ); fwrite( &pTrack->nVol, sizeof(BYTE), 1, pFile ); fwrite( &pTrack->nVolOrig, sizeof(BYTE), 1, pFile ); fwrite( &pTrack->iBank, sizeof(BYTE), 1, pFile ); fwrite( &pTrack->iFile, sizeof(BYTE), 1, pFile ); } } } BOOL SaveProject( LPCSTR strProjectName, int iSaveMode, HWND hNotifyWnd ) { wstring wstrProj = str2wstr( strProjectName ); DebugPrint("Saving project: %s...", strProjectName); WaitForSingleObject(g_hProjectEvent, INFINITE); BOOL bSuccess = FALSE; FILE *pFile = NULL; if ((pFile = fopen( strProjectName, "w+b" )) != NULL) { UINT lFileSize = 0; fpos_t posFileSize = 0; // 保存版本号 fwrite(&g_dwProjectVersion, sizeof(DWORD), 1, pFile); // 预留文件长度 fgetpos(pFile, &posFileSize); fwrite(&lFileSize, sizeof(UINT), 1, pFile); // 保存模式标志 fwrite(&iSaveMode, sizeof(int), 1, pFile); // 旋律主要信息 fwrite(&g_iMelodyTimeSignature, sizeof(int), 1, pFile); // 拍号 fwrite(&g_nMelodyTempo, sizeof(int), 1, pFile); // 速度 fwrite(&g_iMelodyKey, sizeof(int), 1, pFile); // 调号 // 全局音色库 //string strFont = wstr2str( g_strFontFile ); string strFontUTF8 = GBToUTF8( g_strSoundFont );//strFont.c_str() ); int nFontNameLen = strFontUTF8.length() + 1; fwrite(&nFontNameLen, sizeof(int), 1, pFile); fwrite( strFontUTF8.c_str(), sizeof(char), nFontNameLen, pFile); fwrite( &g_bExtFont, sizeof(bool), 1, pFile ); // 各项音量设值 fwrite(&g_fRecordVolume, sizeof(float), 1, pFile); fwrite(&g_fSpeakerVolume, sizeof(float), 1, pFile); fwrite(&g_fMusicVolume, sizeof(float), 1, pFile); int iMute = g_bComposeMute ? 1 : 0; fwrite(&iMute, sizeof(int), 1, pFile); LOCSEGLIST aLocSegs; //使用的本地风格片段列表 // Theme g_Theme.WriteProj( aLocSegs, pFile ); // Opus g_Opus.WriteProj( aLocSegs, pFile ); // MidiTrack g_Midi.WriteProj( pFile ); //保存使用的音源 vector lstBank; g_Theme.GetSpecBanks( lstBank ); g_Midi.GetSpecBanks( lstBank ); //g_Opus.GetSpecBanks( lstBank ); int nCount = lstBank.size(); fwrite(&nCount, sizeof(int), 1, pFile); for( int i=0; istrFontName; BYTE len = strlen( strFontName ); fwrite(&len, sizeof(BYTE), 1, pFile); fwrite( strFontName, sizeof(char), len, pFile); } else{ /* char* name = strrchr(g_lstVSTi[iBank-0x80]->strFileName, '\\' ) + 1, *ext = strrchr( g_lstVSTi[iBank-0x80]->strFileName, '.' ); BYTE len = ext>name ? ext - name : strlen(name); */ DWORD uniqueID = g_lstVSTi[iBank-0x80]->uniqueID; fwrite( &uniqueID, sizeof(DWORD), 1, pFile ); // fwrite(&len, sizeof(BYTE), 1, pFile); // fwrite( name, sizeof(char), len, pFile); BYTE cmprMem[100000]; int lenMem = 100000; if( f_MM_HandleVSTiPreset( iBank, lenMem, cmprMem, false )==S_OK ){ fwrite( &lenMem, sizeof(int), 1, pFile ); fwrite( cmprMem, 1, lenMem, pFile ); } else{ lenMem = 0; fwrite( &lenMem, sizeof(int), 1, pFile ); } } } // Audio if( iSaveMode==PROJ_MODE_UPLOAD ){ int num = 0; fwrite( &num, sizeof(int), 1, pFile ); } else{ g_Audio.WriteProj( pFile ); } //PreStylePanel TStyleItem* pSty = g_pPreStyle; UINT idLoc = 0, idStyle = 0; if( pSty->pStyle ){ idLoc = pSty->pStyle->idLoc; idStyle = pSty->pStyle->idStyle; CheckLocId( idLoc, idStyle ); } fwrite( &idLoc, sizeof(UINT), 1, pFile ); fwrite( &idStyle, sizeof(UINT), 1, pFile ); int num = pSty->aItems->Count; fwrite( &num, sizeof(int), 1, pFile ); for( int i=0; iaItems->Items[i]; fwrite( &pSeg->iSegType, sizeof(char), 1, pFile ); fwrite( &pSeg->iSegNo, sizeof(char), 1, pFile ); fwrite( &pSeg->volume, sizeof(char), 1, pFile ); fwrite( &pSeg->nBars, sizeof(int), 1, pFile ); int count = pSeg->aItems->Count; fwrite( &count, sizeof(int), 1, pFile ); for( int j=0; jaItems->Items[j]; TTrack* pTrack = pTrk->pTrack; UINT idLoc = pTrack->iStyleLoc, idStyle = pTrack->iStyleId; CheckLocId( idLoc, idStyle ); fwrite( &idLoc, sizeof(UINT), 1, pFile ); fwrite( &idStyle, sizeof(UINT), 1, pFile ); fwrite( &pTrack->iSegNo, sizeof(char), 1, pFile ); fwrite( &pTrack->iChanNo, sizeof(char), 1, pFile ); fwrite( &pTrack->iChanSpec, sizeof(char), 1, pFile ); fwrite( &pTrack->iProg, sizeof(char), 1, pFile ); fwrite( &pTrack->iProgOrig, sizeof(char), 1, pFile ); fwrite( &pTrack->nVol, sizeof(char), 1, pFile ); fwrite( &pTrack->nVolOrig, sizeof(char), 1, pFile ); } } //段落预设 fwrite( &g_iPreStage, sizeof(int), 1, pFile ); //视图模式 int iContentView = 0; Application->MainForm->Perform( UM_GETCONTENTVIEW, (NativeInt)&iContentView, 0 ); fwrite(&iContentView, sizeof(int), 1, pFile); //预设工程 fwrite( &g_bPredefine, sizeof(bool), 1, pFile ); //MIDI输入工程 fwrite( &g_bMidiMelody, sizeof(bool), 1, pFile ); //保存本地风格数据 num = aLocSegs.size(); fwrite( &num, sizeof(int), 1, pFile ); for( int i=0; iaSegs.size(); WORD (*aSegs)[2] = new WORD[nSegNum][2]; for( int j=0; jaSegs.size(); j++ ){ aSegs[j][0] = LOWORD( pLocSeg->aSegs[j] ); aSegs[j][1] = HIWORD( pLocSeg->aSegs[j] ); } int len = 1000000; BYTE* mem = new BYTE[1000000]; UINT idLoc = pLocSeg->idLoc, idStyle = pLocSeg->idStyle; if( idLoc==(UINT)-1 ){ for( int k=0; kidTemp ){ idLoc = u_aTempStyleMap[k]->idLoc; idStyle = u_aTempStyleMap[k]->idStyle; break; } } } fwrite( &idLoc, sizeof(UINT), 1, pFile ); fwrite( &idStyle, sizeof(UINT), 1, pFile ); f_CM_ProjBackupStyle( pLocSeg->idLoc, pLocSeg->idStyle, nSegNum, aSegs, len, mem ); fwrite( &len, sizeof(int), 1, pFile ); if( len>0 ) fwrite( mem, 1, len, pFile ); delete[] mem; delete[] aSegs; delete aLocSegs[i]; } aLocSegs.clear(); // 保存文件长度 lFileSize = ftell(pFile); fclose( pFile ); int lCSSize = f_CS_SaveProject( strProjectName ); if( lCSSize>0 ){ lFileSize += lCSSize; } long lMMSize = f_MM_SaveProject( iSaveMode, hNotifyWnd, strProjectName ); if( lMMSize>0 ){ lFileSize += lMMSize; } pFile = fopen( strProjectName, "r+b" ); fsetpos(pFile, &posFileSize); fwrite(&lFileSize, sizeof(UINT), 1, pFile); fclose(pFile); bSuccess = TRUE; if( iSaveMode==PROJ_MODE_NORMAL ){ g_bProjStylePaid = false; UpdateSVDVars(); UpdateRecentProject( wstrProj ); PostMessage(hNotifyWnd, MSG_OPERATE_COMPLETE, 0, 0); u_pProjLite = g_Undo.GetLastLite(); ClearAutoProj(); } else if( iSaveMode==PROJ_MODE_AUTO ){ SetAutoSaveReg(true); } if( iSaveMode!=PROJ_MODE_UPLOAD ){ u_pAutoLite = g_Undo.GetLastLite(); } } if (SetEvent(g_hProjectEvent) == 0) { DWORD dwError = GetLastError(); DebugPrint("Set Event error! err=%d", dwError); } DebugPrint("saving done\n"); if( iSaveMode==PROJ_MODE_NORMAL ){ if (bSuccess) { g_strProjectName = wstrProj; g_strLastProjSavePath = ExtractFilePath( g_strProjectName.c_str() ).c_str(); } else{ PostMessage(hNotifyWnd, MSG_OPERATE_FAILED, E_PROJ_FILENOTEXIST, 0); } } return bSuccess; } BOOL LoadProject(LPCSTR strProjectName, HWND hNotifyWnd) { DebugPrint("Opening project...."); WaitForSingleObject(g_hProjectEvent, INFINITE); BOOL bSuccess = FALSE; int iError = E_PROJ_NOERROR; int iLoadMode = hNotifyWnd==NULL ? PROJ_MODE_AUTO : PROJ_MODE_NORMAL, // 全局变量清空 g_bPredefine = false; g_bProjStylePaid = false; g_bMidiMelody = false; g_iMelodyKey = -1; g_fMusicVolume = 1; g_bComposeMute = false; g_iViewMode = 3; ClearGlobalVars(); ClearStyleMap(); FILE *pFile = NULL; if ((pFile = fopen(strProjectName, "rb")) != NULL) { DWORD dwProjectVersion; WORD wMajVersion, wMinVersion; UINT lFileSize = 0; fpos_t posBegin = 0; int iContentView = 1; // 读取版本号 fread(&dwProjectVersion, sizeof(DWORD), 1, pFile); if( LOWORD(dwProjectVersion)<2 ){ wMajVersion = LOWORD(dwProjectVersion); wMinVersion = HIWORD(dwProjectVersion); dwProjectVersion = MAKELONG( wMinVersion, wMajVersion ); } else{ wMajVersion = HIWORD( dwProjectVersion ); wMinVersion = LOWORD( dwProjectVersion ); } // 读取文件长度 fread(&lFileSize, sizeof(UINT), 1, pFile); // 检测文件长度 fgetpos(pFile, &posBegin); fseek(pFile, 0, SEEK_END); if (lFileSize != ftell(pFile)) { iError = E_PROJ_FILECRUPT; goto STATEMENT_FALSE; } else { fsetpos(pFile, &posBegin); } if( wMajVersion<1 || wMajVersion==2 && wMinVersion>8 || wMajVersion==3 && wMinVersion>3 || wMajVersion==4 && wMinVersion>4 ){ //不可识别版本 iError = E_PROJ_INVALIDVERSION; goto STATEMENT_FALSE; } else if( wMajVersion<2 ) { //不兼容1.0老版本 iError = E_PROJ_EARLERVERSION; goto STATEMENT_FALSE; } else if( dwProjectVersion>g_dwProjectVersion ) { //后期版本 iError = E_PROJ_LATERVERSION; goto STATEMENT_FALSE; } if( wMajVersion>5 || wMajVersion==5 && wMinVersion>=3 || wMajVersion==2 && wMinVersion>=7 ) fread(&iLoadMode, sizeof(int), 1, pFile); if( wMajVersion==5 ) iError = LoadVersion5( pFile, dwProjectVersion, hNotifyWnd, &iContentView ); else if( wMajVersion==4 ) iError = LoadVersion4( pFile, dwProjectVersion, hNotifyWnd ); else if( wMajVersion==3 ) iError = LoadVersion3( pFile, dwProjectVersion, hNotifyWnd ); else if( wMajVersion==2 ) iError = LoadVersion2( pFile, dwProjectVersion, hNotifyWnd, iLoadMode ); long lPos = ftell( pFile ); fclose( pFile ); pFile = NULL; if (iError>E_PROJ_FATALERROR ) { goto STATEMENT_FALSE; } if( wMajVersion>=4 || wMajVersion==2 && wMinVersion>=6 ){ int nCSSize = f_CS_LoadProject( strProjectName, lPos, dwProjectVersion ); if( nCSSize<0 ){ iError = E_PROJ_FILECRUPT; goto STATEMENT_FALSE; } lPos += nCSSize; } lFileSize = f_MM_LoadProject( iLoadMode, hNotifyWnd, strProjectName, lPos, dwProjectVersion ); if( lFileSize<0 ){ iError = E_PROJ_CANTLOADAUDIO; goto STATEMENT_FALSE; } g_bWeakup = g_Theme.IsWeadup(); for( int i=g_aAudioTracks.size()-1; i>=0; i-- ){ if( ilstBars.size()>0 && f_MM_AudioGetLength(i)>=0 ){ if( wMajVersion>=5 ){ //获取音量信息 for( int k=0; klstBars.size(); k++ ){ TWaveBar* pBar = g_aAudioTracks[i]->lstBars[k]; for( int j=0; jaVols[j] = f_MM_GetAudioVolume( i, k + j/(double)POINTS_PER_BAR ); } } } f_MM_SetStreamVolume( 0x10+i, g_aAudioTracks[i]->IsMute() ? 0 : g_aAudioTracks[i]->volume / 100.0 ); } else{ DeleteAudioTrack( i, false ); f_MM_AudioDeleteTrack( i ); } } bSuccess = TRUE; if( hNotifyWnd ) PostMessage(hNotifyWnd, MSG_OPERATE_COMPLETE, iError, 0); PostMessage( Application->MainFormHandle, UM_SETCONTENTVIEW, iContentView, 0 ); } else { iError = E_PROJ_FILENOTEXIST; } STATEMENT_FALSE: if( pFile ){ fclose( pFile ); pFile = NULL; } if (SetEvent(g_hProjectEvent) == 0) { DWORD dwError = GetLastError(); DebugPrint("Set Event error! err=%d", dwError); } DebugPrint("opening done\n"); if( iLoadMode!=PROJ_MODE_AUTO ) { //add by tj 2013/12/31 if (!bSuccess) { PostMessage(hNotifyWnd, MSG_OPERATE_FAILED, iError, 0); } else { UpdateSVDVars(); g_strProjectName = str2wstr( strProjectName ); g_strLastProjSavePath = ExtractFilePath( g_strProjectName.c_str() ).c_str(); UpdateRecentProject(g_strProjectName); } } return bSuccess; } TPROSTYLE* GetProjStyle( UINT idLoc, UINT idStyle, STYLELIST& aUnsolvedStyles ) { TPROSTYLE* pInfo = CheckStyle( idLoc, idStyle ); if( !pInfo && idLoc!=0 && idLoc!=(UINT)-1 ){ for( int t=0; tidLoc==idLoc && aUnsolvedStyles[t]->idStyle==idStyle ){ pInfo = aUnsolvedStyles[t]; break; } } if( !pInfo ){ pInfo = new TPROSTYLE; pInfo->idLoc = idLoc; pInfo->idStyle = idStyle; aUnsolvedStyles.push_back( pInfo ); } } return pInfo; } int LoadOpusStages( TOpusStageList& lstStages, STYLELIST& aUnsolvedStyles, FILE* pFile, DWORD dwVersion ) { WORD wMajVersion = HIWORD( dwVersion ), wMinVersion = LOWORD( dwVersion ); int num, nBars = 0; fread( &num, sizeof(int), 1, pFile ); for( int i=0; iiSegType, sizeof(char), 1, pFile ); fread( &pStage->iSegNo, sizeof(char), 1, pFile ); fread( &pStage->iSegKey, sizeof(char), 1, pFile ); fread( &pStage->nVol, sizeof(char), 1, pFile ); int count; fread( &count, sizeof(int), 1, pFile ); for( int j=0; jaChords, sizeof(TBarChords), 1, pFile ); fread( &pBar->iBarKey, sizeof(char), 1, pFile ); pStage->aBars.push_back( pBar ); } nBars += count; fread( &count, sizeof(int), 1, pFile ); for( int j=0; jiStyleLoc, sizeof(UINT), 1, pFile ); fread( &pTrack->iStyleId, sizeof(UINT), 1, pFile ); fread( &pTrack->iSegNo, sizeof(BYTE), 1, pFile ); fread( &pTrack->iChanNo, sizeof(BYTE), 1, pFile ); fread( &pTrack->iChanSpec, sizeof(BYTE), 1, pFile ); fread( &pTrack->iProg, sizeof(BYTE), 1, pFile ); fread( &pTrack->iProgOrig, sizeof(BYTE), 1, pFile ); fread( &pTrack->nVol, sizeof(BYTE), 1, pFile ); fread( &pTrack->nVolOrig, sizeof(BYTE), 1, pFile ); fread( &pTrack->iBank, sizeof(BYTE), 1, pFile ); if( wMajVersion==5 && wMinVersion>=6 ) fread( &pTrack->iFile, sizeof(BYTE), 1, pFile ); TPROSTYLE* pTrackStyle = GetProjStyle( pTrack->iStyleLoc, pTrack->iStyleId, aUnsolvedStyles ); if( !pTrackStyle ){ //无效的风格ID return E_PROJ_INVALIDSTYLE; } if( wMajVersion==5 && wMinVersion<4 ){ if( pTrack->iBank!=0 ) pTrack->nVol |= 0x80; pTrack->iBank = 0xFF; } pStage->aTracks.push_back( pTrack ); } lstStages.push_back( pStage ); } return nBars; } int LoadVersion5( FILE *pFile, DWORD dwVersion, HWND hNotifyWnd, int* iContentView ) { char strFont[MAX_PATH]; string strStyleName; bool bUseful; int iError = E_PROJ_NOERROR; WORD wMinVersion = LOWORD( dwVersion ); int nSize, iMelodyKey, iMelodyTimeSignature, nMelodyTempo; // 主要参数 fread(&iMelodyTimeSignature, sizeof(int), 1, pFile); fread(&nMelodyTempo, sizeof(int), 1, pFile); fread(&iMelodyKey, sizeof(int), 1, pFile); if( g_iMelodyTimeSignature!=iMelodyTimeSignature ){ SetMelodyTS(iMelodyTimeSignature); SelectStyle(); PostMessage( Application->MainFormHandle, UM_CHANGETT, true, -1 ); } SetMelodyTempo(nMelodyTempo); g_iMelodyKey = iMelodyKey; // 读取音色库文件名 fread(&nSize, sizeof(int), 1, pFile); if (nSize > 0) { fread(strFont, sizeof(char), nSize, pFile); strcpy( g_strSoundFont, strFont ); } if( wMinVersion>=5 ) fread( &g_bExtFont, sizeof(bool), 1, pFile ); // 各项音量设值 fread(&g_fRecordVolume, sizeof(float), 1, pFile); if( g_fRecordVolume>1 ) g_fRecordVolume = 1; if( g_fRecordVolume<0 ) g_fRecordVolume = 0; fread(&g_fSpeakerVolume, sizeof(float), 1, pFile); if( g_fSpeakerVolume>1 ) g_fSpeakerVolume= 1; if( g_fSpeakerVolume<0 ) g_fSpeakerVolume= 0; fread(&g_fMusicVolume, sizeof(float), 1, pFile); if( g_fMusicVolume>1 ) g_fMusicVolume = 1; if( g_fMusicVolume<0 ) g_fMusicVolume = 0; int iMute; fread(&iMute, sizeof(int), 1, pFile); g_bComposeMute = iMute!=0; f_MM_SetStreamVolume( 0, g_fSpeakerVolume ); f_MM_SetStreamVolume( 1, g_fRecordVolume ); f_MM_SetStreamVolume( 4, g_bComposeMute ? 0 : g_fMusicVolume ); STYLELIST aUnsolvedStyles; iError = g_Theme.ReadProj( aUnsolvedStyles, pFile, dwVersion ); if( iError!=E_PROJ_NOERROR ) return iError; iError = g_Opus.ReadProj( aUnsolvedStyles, pFile, dwVersion ); if( iError!=E_PROJ_NOERROR ) return iError; if( wMinVersion>=6 ){ iError = g_Midi.ReadProj( pFile, dwVersion ); if( iError!=E_PROJ_NOERROR ) return iError; } if( wMinVersion>=4 ){ //使用的音源 bool bReset = false; BANKMAPLIST lstBank; int nCount; fread(&nCount, sizeof(int), 1, pFile); for( int i=0; iiBankOld, sizeof(BYTE), 1, pFile); if( pMap->iBankOld<0x80 ){ fread(&len, sizeof(BYTE), 1, pFile); fread(strFont, sizeof(char), len, pFile); strFont[len] = '\0'; for( int j=0; jstrFontName, strFont ) ){ iBankNew = j; break; } } } else{ DWORD uniqueID = 0; fread( &uniqueID, sizeof(DWORD), 1, pFile ); BYTE cmprMem[100000]; int lenMem = 100000; fread( &lenMem, sizeof(int), 1, pFile ); if( lenMem>0 ) fread( cmprMem, 1, lenMem, pFile ); for( int j=0; juniqueID ){ if( f_MM_LoadVSTi( j+0x80, g_lstVSTi[j]->strFileName )==S_OK ){ iBankNew = j + 0x80; f_MM_HandleVSTiPreset( iBankNew, lenMem, cmprMem, true ); } break; } } } pMap->iBankNew = iBankNew; lstBank.push_back( pMap ); if( pMap->iBankOld!=pMap->iBankNew ) bReset = true; if( iBankNew==0xFF ) iError |= E_PROJ_INVALIDFONT; } if( bReset ){ g_Theme.SetSpecBanks( lstBank ); g_Opus.SetSpecBanks( lstBank ); //g_Midi.SetSpecBanks( lstBank ); g_Midi.ClearMidiTracks(); } } g_Midi.SortMidiTracks(); iError |= g_Audio.ReadProj( pFile, dwVersion ); if( iError > E_PROJ_FATALERROR ) return iError; //PreStylePanel // bool bAuthority = g_bLogon && (g_infoUser.accountInfo.authority & 0x1000); UINT idPreLoc, idPreStyle; fread( &idPreLoc, sizeof(UINT), 1, pFile ); fread( &idPreStyle, sizeof(UINT), 1, pFile ); TPROSTYLE* info = CheckStyle( idPreLoc, idPreStyle );//GetProjStyle( idPreLoc, idPreStyle, aUnsolvedStyles ); TStyleItem* pSty = new TStyleItem( info, OPT_FONTPROG | OPT_SAVE ); int num; fread( &num, sizeof(int), 1, pFile ); for( int i=0; iAddSegment( st, sn, opts, 0, -1, vol ); pSeg->nBars = bars; int count; // TTrackItem* pTrkPrev = NULL; fread( &count, sizeof(int), 1, pFile ); for( int j=0; jiSegNo, sizeof(char), 1, pFile ); fread( &pTrk->iChanNo, sizeof(char), 1, pFile ); fread( &pTrk->iChanSpec, sizeof(char), 1, pFile ); fread( &pTrk->iProg, sizeof(char), 1, pFile ); fread( &pTrk->iProgOrig, sizeof(char), 1, pFile ); fread( &pTrk->nVol, sizeof(char), 1, pFile ); fread( &pTrk->nVolOrig, sizeof(char), 1, pFile ); if( wMinVersion<4 ){ bool bMute = false; fread( &bMute, sizeof(bool), 1, pFile ); if( bMute ) pTrk->nVol |= 0x80; } TPROSTYLE* pInfo = CheckStyle( idItemLoc, idItemStyle );//GetProjStyle( idItemLoc, idItemStyle, aUnsolvedStyles ); if( !pInfo ){ delete pTrk; continue; } DWORD dwTrkOpt = OPT_DEL|OPT_FONTPROG|OPT_VOL; if( pSeg->iSegType<=SEGTYPE_FILL ) dwTrkOpt |= OPT_TEXTURE; pTrk->iStyleLoc = idItemLoc; pTrk->iStyleId = idItemStyle; pSeg->AddTrack( pInfo, pTrk, dwTrkOpt, true ); } if( pSeg->aItems->Count==0 ){ pSty->DeleteSegment( pSeg ); } else if( !pSty->pStyle ){ pSty->pStyle = ((TTrackItem*)pSeg->aItems->Items[0])->pStyle; } } if( pSty->pStyle && pSty->aItems->Count>0 ){ g_pPreStyle = pSty; } else delete pSty; //段落预设 fread( &g_iPreStage, sizeof(int), 1, pFile ); //视图模式 fread( iContentView, sizeof(int), 1, pFile ); //预设工程 fread( &g_bPredefine, sizeof(bool), 1, pFile ); //MIDI输入工程 fread( &g_bMidiMelody, sizeof(bool), 1, pFile ); //本地风格数据 BYTE* mem = new BYTE[1000000]; fread( &num, sizeof(int), 1, pFile ); for( int i=0; i0 ){ fread( mem, 1, len, pFile ); for( int j=0; jidLoc && idStyle==pInfo->idStyle ){ int id = f_CM_ProjRestoreStyle( len, mem ); if( id>0 ){ g_Theme.SetTempStyle( idLoc, idStyle, id ); g_Opus.SetTempStyle( idLoc, idStyle, id ); TTempStyleMap* pMap = new TTempStyleMap; pMap->idTemp = id; pMap->idLoc = pInfo->idLoc; pMap->idStyle = pInfo->idStyle; u_aTempStyleMap.push_back( pMap ); pInfo->idLoc = -1; pInfo->idStyle = id; g_aTempStyles.push_back( pInfo ); aUnsolvedStyles.erase( aUnsolvedStyles.begin() + j ); } break; } } } } delete[] mem; if( !aUnsolvedStyles.empty() ){ for( int i=0; iMainFormHandle, UM_CHANGETT, true, -1 ); } SetMelodyTempo(nMelodyTempo); g_iMelodyKey = iMelodyKey; // 读取音色库文件名 fread(&nSize, sizeof(int), 1, pFile); if (nSize > 0) { fread(strFont, sizeof(char), nSize, pFile); strcpy( g_strSoundFont, strFont ); } // 各项音量设值 fread(&g_fRecordVolume, sizeof(float), 1, pFile); if( g_fRecordVolume>1 ) g_fRecordVolume = 1; if( g_fRecordVolume<0 ) g_fRecordVolume = 0; fread(&g_fSpeakerVolume, sizeof(float), 1, pFile); if( g_fSpeakerVolume>1 ) g_fSpeakerVolume= 1; if( g_fSpeakerVolume<0 ) g_fSpeakerVolume= 0; float fAudioVolume = 1; fread(&fAudioVolume, sizeof(float), 1, pFile); if( fAudioVolume>1 ) fAudioVolume = 1; if( fAudioVolume<0 ) fAudioVolume = 0; fread(&g_fMusicVolume, sizeof(float), 1, pFile); if( g_fMusicVolume>1 ) g_fMusicVolume = 1; if( g_fMusicVolume<0 ) g_fMusicVolume = 0; f_MM_SetStreamVolume( 0, g_fSpeakerVolume ); f_MM_SetStreamVolume( 1, g_fRecordVolume ); f_MM_SetStreamVolume( 4, g_fMusicVolume ); TBarList lstBars; vector lstStages; // g_lstRawBars int num; fread( &num, sizeof(int), 1, pFile ); if( num>0 ){ for( int i=0; iaVols, sizeof(DWORD), POINTS_PER_BAR, pFile ); g_aAudioTracks[0]->lstBars.push_back( pWvBar ); TBar* pBar = new TBar; fread( &pBar->aChords, sizeof(TBarChords), 1, pFile ); if( HIWORD( dwVersion )>4 || wMinVersion>=3 ) fread( &pBar->iBarKey, sizeof(char), 1, pFile ); else pBar->iBarKey = iMelodyKey; lstBars.push_back( pBar ); } AudioEffectsDefault( 0, false ); g_aAudioTracks[0]->volume = (int)(fAudioVolume * 100); } // g_lstRawStages fread( &num, sizeof(int), 1, pFile ); for( int i=0; i0 ){ pAudioTrack = new TAudioTrack; pAudioTrack->volume = (int)(fAudioVolume * 100); g_aAudioTracks.push_back( pAudioTrack ); g_aAudioTracks[0]->Hide();// = true; for( int i=0; iiSegType = iSegType; pStage->iSegNo = iSegNo; pStage->iSegKey = iMelodyKey; } else{ fread( &pStage->iSegType, sizeof(char), 1, pFile ); fread( &pStage->iSegNo, sizeof(char), 1, pFile ); fread( &pStage->iSegKey, sizeof(char), 1, pFile ); } int count; fread( &count, sizeof(int), 1, pFile ); for( int j=0; jaVols, sizeof(DWORD), POINTS_PER_BAR, pFile ); pAudioTrack->lstBars.push_back( pWvBar ); TBar* pBar = new TBar; fread( &pBar->aChords, sizeof(TBarChords), 1, pFile ); if( HIWORD( dwVersion )>4 || wMinVersion>=3 ) fread( &pBar->iBarKey, sizeof(char), 1, pFile ); else pBar->iBarKey = iMelodyKey; pStage->aBars.push_back( pBar ); } fread( &count, sizeof(int), 1, pFile ); for( int j=0; jiStyleLoc = track.iStyleLoc; pTrk->iStyleId = track.iStyleId; pTrk->iSegNo = track.iSegNo; pTrk->iChanNo = track.iChanNo; pTrk->iChanSpec = track.iChanSpec; pTrk->iProg = track.iProg; pTrk->nVol = track.nVol; pStage->aTracks.push_back( pTrk ); } g_lstOpusStages.push_back( pStage ); } g_Opus.CountBars(); } //g_aAudioEffects for( int i=0; i=pAudioTrack->lstBars.size()-1 ){ int iType = g_aAudioEffectTypes[i]; 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 ); pAudioTrack->lstFxs.push_back( pFx ); } } else{ iError |= E_PROJ_INVALIDFX; } } } //AudStylePanel信息 //PreStylePanel/UseStylePanel信息 bool bAuthority = g_bLogon && (g_infoUser.accountInfo.authority & 0x1000), bNoAuthority = false, bInvalid = false; STYLELIST aUnsolvedStyles; TStyleItem *pPreStyle = NULL, *pUseStyle = NULL; for( int n=0; n<2; n++ ){ TStyleItem*& pSty = n==0 ? pPreStyle : pUseStyle; pSty = new TStyleItem; UINT idStyItemLoc, idStyItemStyle; fread( &idStyItemLoc, sizeof(UINT), 1, pFile ); fread( &idStyItemStyle, sizeof(UINT), 1, pFile ); fread( &pSty->iType, sizeof(char), 1, pFile ); fread( &pSty->nBars, sizeof(int), 1, pFile ); int nSegNum[4]; fread( nSegNum, sizeof(int), 4, pFile ); for( int i=0; i<4; i++ ){ pSty->nSegNum[i] = nSegNum[i]; } DWORD iOpt; fread( &num, sizeof(int), 1, pFile ); for( int i=0; ibAutoSpec = n==0; fread( &pSeg->iType, sizeof(char), 1, pFile ); fread( &pSeg->iSegType, sizeof(char), 1, pFile ); fread( &pSeg->iSegNo, sizeof(char), 1, pFile ); fread( &pSeg->iInd, sizeof(char), 1, pFile ); fread( &pSeg->volume, sizeof(char), 1, pFile ); fread( &pSeg->nBars, sizeof(int), 1, pFile ); fread( pSeg->aChanUsed, sizeof(bool), 16, pFile ); int count; fread( &count, sizeof(int), 1, pFile ); for( int j=0; j0 ){ pStage = g_lstOpusStages[i]; pStage->nVol = pSeg->volume; } TTrackItem* pTrkPrev = NULL; fread( &count, sizeof(int), 1, pFile ); for( int j=0; jiType, sizeof(char), 1, pFile ); fread( &idItemLoc, sizeof(UINT), 1, pFile ); fread( &idItemStyle, sizeof(UINT), 1, pFile ); char iSegType; fread( &iSegType, sizeof(char), 1, pFile ); // fread( &pTrk->iSegType, sizeof(char), 1, pFile ); fread( &pTrack->iSegNo, sizeof(char), 1, pFile ); fread( &pTrack->iChanNo, sizeof(char), 1, pFile ); fread( &pTrack->iChanSpec, sizeof(char), 1, pFile ); fread( &pTrack->iProg, sizeof(char), 1, pFile ); fread( &pTrack->iProgOrig, sizeof(char), 1, pFile ); fread( &pTrack->nVol, sizeof(char), 1, pFile ); fread( &pTrack->nVolOrig, sizeof(char), 1, pFile ); bool bMute = false; fread( &bMute, sizeof(bool), 1, pFile ); if( bMute ) pTrack->nVol |= 0x80; int cn; fread( &cn, sizeof(int), 1, pFile ); for( int k=0; kidLoc==idItemLoc && aUnsolvedStyles[t]->idStyle==idItemStyle ){ pInfo = aUnsolvedStyles[t]; break; } } if( !pInfo ){ pInfo = new TPROSTYLE; pInfo->idLoc = idItemLoc; pInfo->idStyle = idItemStyle; aUnsolvedStyles.push_back( pInfo ); } } else{ bInvalid = true; delete pTrk; delete pTrack; delete pSeg; goto STYLE_CHECK_OVER; } } pTrk->pStyle = pInfo; pTrack->iStyleLoc = pInfo->idLoc; pTrack->iStyleId = pInfo->idStyle; pTrk->aOptions->Add( (void*)OPT_DEL ); pTrk->aOptions->Add( (void*)OPT_VOL ); if( pSeg->iSegType<=SEGTYPE_FILL ) pTrk->aOptions->Add( (void*)OPT_TEXTURE ); if( n==0 ){ pTrk->aOptions->Add( (void*)OPT_FONTPROG ); pTrk->pTrack = pTrack; pTrk->bOwnTrack = true; } else if( pStage ){ TTrack* pTrackSet = pStage->aTracks[j]; pTrackSet->iProgOrig = pTrack->iProg; pTrackSet->nVolOrig = pTrack->nVolOrig; pTrackSet->nVol = pTrack->nVol; pTrk->pTrack = pTrackSet; delete pTrack; } pTrk->up = pSeg; if( pTrkPrev ){ pTrk->prev = pTrkPrev; pTrkPrev->next = pTrk; } pTrkPrev = pTrk; pSeg->aItems->Add( pTrk ); } if( pSeg->aItems->Count>0 || n>0 ){ pSeg->aOptions->Add( (void*)OPT_DEL ); pSeg->aOptions->Add( (void*)OPT_VOL ); if( pSeg->iTypeaOptions->Add( (void*)OPT_BRUSH ); pSeg->up = pSty; if( pSegPrev ){ pSeg->prev = pSegPrev; pSegPrev->next = pSeg; } pSegPrev = pSeg; pSty->aItems->Add( pSeg ); } else{ delete pSeg; } } TPROSTYLE* info = NULL; if( bAuthority || idStyItemLoc==0 || idStyItemLoc==1 ) info = CheckStyle( idStyItemLoc, idStyItemStyle ); if( !info ){ if( n==1 && idStyItemLoc!=0 && idStyItemLoc!=1 && idStyItemLoc!=(UINT)-1 ){ for( int t=0; tidLoc==idStyItemLoc && aUnsolvedStyles[t]->idStyle==idStyItemStyle ){ info = aUnsolvedStyles[t]; break; } } if( !info ){ info = new TPROSTYLE; info->idLoc = idStyItemLoc; info->idStyle = idStyItemStyle; aUnsolvedStyles.push_back( info ); } } if( !info && pSty->aItems->Count>0 ){ for( int i=0; iaItems->Count; i++ ){ TSegmentItem* pSeg = (TSegmentItem*)pSty->aItems->Items[i]; if( pSeg->aItems->Count>0 ){ info = ((TTrackItem*)pSeg->aItems->Items[0])->pStyle; break; } } } } if( info && ( pSty->aItems->Count>0 || n>0 ) ){ pSty->pStyle = info; if( n==0 ){ pSty->aOptions->Add((void*)OPT_FONTPROG); pSty->aOptions->Add((void*)OPT_SAVE); } } else{ delete pSty; pSty = NULL; if( n>0 ){ bInvalid = true; goto STYLE_CHECK_OVER; } } } STYLE_CHECK_OVER: if( bInvalid ){ if( pPreStyle ){ delete pPreStyle; } if( pUseStyle ){ delete pUseStyle; } return E_PROJ_INVALIDSTYLE; } else{ g_pPreStyle = pPreStyle; g_pUseStyle = pUseStyle; } //段落预设 fread( &g_iPreStage, sizeof(int), 1, pFile ); //视图模式 int iViewMode; fread( &iViewMode, sizeof(int), 1, pFile ); //预设工程 fread( &g_bPredefine, sizeof(bool), 1, pFile ); //MIDI输入工程 if( HIWORD( dwVersion )>4 || wMinVersion>=4 ) fread( &g_bMidiMelody, sizeof(bool), 1, pFile ); //本地风格数据 BYTE* mem = new BYTE[1000000]; fread( &num, sizeof(int), 1, pFile ); for( int i=0; i0 ){ fread( mem, 1, len, pFile ); for( int j=0; jidLoc && idStyle==pInfo->idStyle ){ int id = f_CM_ProjRestoreStyle( len, mem ); if( id>0 ){ for( int s=0; saTracks.size(); t++ ){ TTrack* pTrack = pStage->aTracks[t]; if( pTrack->iStyleLoc==idLoc && pTrack->iStyleId==idStyle ){ pTrack->iStyleLoc = -1; pTrack->iStyleId = id; } } } TTempStyleMap* pMap = new TTempStyleMap; pMap->idTemp = id; pMap->idLoc = pInfo->idLoc; pMap->idStyle = pInfo->idStyle; u_aTempStyleMap.push_back( pMap ); pInfo->idLoc = -1; pInfo->idStyle = id; g_aTempStyles.push_back( pInfo ); aUnsolvedStyles.erase( aUnsolvedStyles.begin() + j ); } break; } } } } delete[] mem; if( !aUnsolvedStyles.empty() ){ for( int i=0; iMainFormHandle, UM_CHANGETT, true, -1 ); } TPROSTYLE* pStyle = CheckStyle( 0, idStyle ); if( !pStyle ) return E_PROJ_INVALIDSTYLE; SetMelodyTempo(nMelodyTempo); g_iMelodyKey = iMelodyKey; // 读取音色库文件名 fread(&nSize, sizeof(int), 1, pFile); if (nSize > 0) { fread(strFont, sizeof(char), nSize, pFile); strcpy( g_strSoundFont, strFont ); } // 各项音量设值 fread(&g_fRecordVolume, sizeof(float), 1, pFile); if( g_fRecordVolume>1 ) g_fRecordVolume = 1; if( g_fRecordVolume<0 ) g_fRecordVolume = 0; fread(&g_fSpeakerVolume, sizeof(float), 1, pFile); if( g_fSpeakerVolume>1 ) g_fSpeakerVolume= 1; if( g_fSpeakerVolume<0 ) g_fSpeakerVolume= 0; float fAudioVolume = 1; fread(&fAudioVolume, sizeof(float), 1, pFile); if( fAudioVolume>1 ) fAudioVolume = 1; if( fAudioVolume<0 ) fAudioVolume = 0; fread(&g_fMusicVolume, sizeof(float), 1, pFile); if( g_fMusicVolume>1 ) g_fMusicVolume = 1; if( g_fMusicVolume<0 ) g_fMusicVolume = 0; f_MM_SetStreamVolume( 0, g_fSpeakerVolume ); f_MM_SetStreamVolume( 1, g_fRecordVolume ); f_MM_SetStreamVolume( 4, g_fMusicVolume ); // g_lstRawBars TBarList lstBars; int num; fread( &num, sizeof(int), 1, pFile ); if( num>0 ){ for( int i=0; iaVols, sizeof(DWORD), POINTS_PER_BAR, pFile ); g_aAudioTracks[0]->lstBars.push_back( pWvBar ); TBar* pBar = new TBar; fread( &pBar->aChords, sizeof(TBarChords), 1, pFile ); pBar->iBarKey = iMelodyKey; lstBars.push_back( pBar ); } AudioEffectsDefault( 0, false ); g_aAudioTracks[0]->volume = (int)(fAudioVolume * 100); } // g_lstRawStages vector lstStages; fread( &num, sizeof(int), 1, pFile ); for( int i=0; i0 ){ pAudioTrack = new TAudioTrack; pAudioTrack->volume = (int)(fAudioVolume * 100); g_aAudioTracks.push_back( pAudioTrack ); g_aAudioTracks[0]->Hide();// = true; for( int i=0; iiSegType = iSegType; pStage->iSegNo = iSegNo; pStage->iSegKey = iMelodyKey; if( pStage->iSegType>=SEGTYPE_INTRO ){ if( pStage->iSegNo % 2 ) pStage->iSegNo = pStage->iSegNo/2 + 4; else pStage->iSegNo /= 2; } int count; fread( &count, sizeof(int), 1, pFile ); for( int j=0; jaVols, sizeof(DWORD), POINTS_PER_BAR, pFile ); pAudioTrack->lstBars.push_back( pWvBar ); TBar* pBar = new TBar; fread( &pBar->aChords, sizeof(TBarChords), 1, pFile ); pBar->iBarKey = iMelodyKey; pStage->aBars.push_back( pBar ); } fread( &count, sizeof(int), 1, pFile ); for( int j=0; jiStyleId = trkOld.iStyleId; pTrack->iStyleLoc = trkOld.iStyleLoc; pTrack->iSegNo = trkOld.iSegNo; if( pStage->iSegType>=SEGTYPE_INTRO ){ if( pTrack->iSegNo % 2 ) pTrack->iSegNo = pTrack->iSegNo/2 + 4; else pTrack->iSegNo /= 2; } pTrack->iChanNo = trkOld.iChanNo; pTrack->iChanSpec = trkOld.iChanSpec; pTrack->iProg = trkOld.iProg; pTrack->nVol = trkOld.nVol; pStage->aTracks.push_back( pTrack ); } g_lstOpusStages.push_back( pStage ); } g_Opus.CountBars(); } //g_aAudioEffects for( int i=0; i=pAudioTrack->lstBars.size()-1 ){ int iType = g_aAudioEffectTypes[i]; 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 ); pAudioTrack->lstFxs.push_back( pFx ); } } else{ iError |= E_PROJ_INVALIDFX; } } } //AudStylePanel信息 //PreStylePanel/UseStylePanel信息 TStyleItem *pPreStyle = NULL, *pUseStyle = NULL; bool bInvalid = false; for( int n=0; n<2; n++ ){ int idStyItemStyle; TStyleItem*& pSty = n==0 ? pPreStyle : pUseStyle; pSty = new TStyleItem; fread( &pSty->iType, sizeof(char), 1, pFile ); fread( &idStyItemStyle, sizeof(UINT), 1, pFile ); fread( &pSty->nBars, sizeof(int), 1, pFile ); int nSegNum[4]; fread( nSegNum, sizeof(int), 4, pFile ); for( int i=0; i<4; i++ ){ pSty->nSegNum[i] = nSegNum[i]; } DWORD iOpt; fread( &num, sizeof(int), 1, pFile ); for( int i=0; i0 ) pStage = g_lstOpusStages[i]; int idSegItemStyle; TSegmentItem* pSeg = new TSegmentItem; pSeg->bAutoSpec = n==0; fread( &pSeg->iType, sizeof(char), 1, pFile ); fread( &idSegItemStyle, sizeof(UINT), 1, pFile ); fread( &pSeg->iSegType, sizeof(char), 1, pFile ); fread( &pSeg->iSegNo, sizeof(char), 1, pFile ); if( pSeg->iSegType>=SEGTYPE_INTRO ){ if( pSeg->iSegNo % 2 ) pSeg->iSegNo = pSeg->iSegNo/2 + 4; else pSeg->iSegNo /= 2; } fread( &pSeg->iInd, sizeof(char), 1, pFile ); fread( &pSeg->volume, sizeof(char), 1, pFile ); fread( &pSeg->nBars, sizeof(int), 1, pFile ); fread( pSeg->aChanUsed, sizeof(bool), 16, pFile ); if( n>0 ){ pStage = g_lstOpusStages[i]; pStage->nVol = pSeg->volume; } //Options int count; fread( &count, sizeof(int), 1, pFile ); for( int j=0; jaOptions->Add( (void*)OPT_DEL ); pSeg->aOptions->Add( (void*)OPT_VOL ); if( pSeg->iTypeaOptions->Add( (void*)OPT_BRUSH ); TTrackItem* pTrkPrev = NULL; fread( &count, sizeof(int), 1, pFile ); for( int j=0; jiType, sizeof(char), 1, pFile ); fread( &idTrkItemStyle, sizeof(UINT), 1, pFile ); char iSegType; fread( &iSegType, sizeof(char), 1, pFile ); // fread( &pTrk->iSegType, sizeof(char), 1, pFile ); fread( &pTrack->iSegNo, sizeof(char), 1, pFile ); if( iSegType>=SEGTYPE_INTRO ){ if( pTrack->iSegNo % 2 ) pTrack->iSegNo = pTrack->iSegNo/2 + 4; else pTrack->iSegNo /= 2; } fread( &pTrack->iChanNo, sizeof(char), 1, pFile ); fread( &pTrack->iChanSpec, sizeof(char), 1, pFile ); fread( &pTrack->iProg, sizeof(char), 1, pFile ); fread( &pTrack->iProgOrig, sizeof(char), 1, pFile ); fread( &pTrack->nVol, sizeof(char), 1, pFile ); fread( &pTrack->nVolOrig, sizeof(char), 1, pFile ); bool bMute = false; fread( &bMute, sizeof(bool), 1, pFile ); if( bMute ) pTrack->nVol |= 0x80; int cn; fread( &cn, sizeof(int), 1, pFile ); for( int k=0; kpStyle = CheckStyle( 0, idTrkItemStyle ); if( pTrk->pStyle ){ pTrk->aOptions->Add( (void*)OPT_DEL ); pTrk->aOptions->Add( (void*)OPT_VOL ); if( pSeg->iSegType<=SEGTYPE_FILL ) pTrk->aOptions->Add( (void*)OPT_TEXTURE ); if( n==0 ){ pTrk->aOptions->Add( (void*)OPT_FONTPROG ); pTrack->iStyleLoc = 0; pTrack->iStyleId = idTrkItemStyle; pTrk->pTrack = pTrack; pTrk->bOwnTrack = true; } else if( pStage ){ TTrack* pTrackSet = pStage->aTracks[j]; pTrackSet->iProgOrig = pTrack->iProgOrig; pTrackSet->nVolOrig = pTrack->nVolOrig; pTrackSet->nVol = pTrack->nVol; pTrk->pTrack = pTrackSet; delete pTrack; } pTrk->up = pSeg; if( pTrkPrev ){ pTrk->prev = pTrkPrev; pTrkPrev->next = pTrk; } pTrkPrev = pTrk; pSeg->aItems->Add( pTrk ); } else{ delete pTrk; delete pTrack; delete pSeg; if( n>0 ){ bInvalid = true; goto STYLE_LOAD_OVER; } } } if( pSeg->nBars==0 && pSeg->iType>=SEGTYPE_INTRO ){ TPROSTYLE* info = CheckStyle( 0, idSegItemStyle ); if( !info && pSeg->aItems->Count>0 ){ info = ((TTrackItem*)pSeg->aItems->Items[0])->pStyle; } if( info ){ if( pSeg->iSegType==SEGTYPE_INTRO ) pSeg->nBars = info->pOrigin->detail.aIntroBars[pSeg->iSegNo]; else if( pSeg->iSegType==SEGTYPE_ENDING ) pSeg->nBars = info->pOrigin->detail.aEndingBars[pSeg->iSegNo]; } } if( n==0 && pSeg->aItems->Count==0 ){ delete pSeg; } else{ pSeg->up = pSty; if( pSegPrev ){ pSeg->prev = pSegPrev; pSegPrev->next = pSeg; } pSegPrev = pSeg; pSty->aItems->Add( pSeg ); } } TPROSTYLE* info = CheckStyle( 0, idStyItemStyle ); if( !info && pSty->aItems->Count>0 ){ for( int i=0; iaItems->Count; i++ ){ TSegmentItem* pSeg = (TSegmentItem*)pSty->aItems->Items[i]; if( pSeg->aItems->Count>0 ){ info = ((TTrackItem*)pSeg->aItems->Items[0])->pStyle; break; } } } if( info && ( pSty->aItems->Count>0 || n>0 ) ){ pSty->pStyle = info; if( n==0 ){ pSty->aOptions->Add((void*)OPT_FONTPROG); pSty->aOptions->Add((void*)OPT_SAVE); } } else{ delete pSty; pSty = NULL; if( n>0 ){ bInvalid = true; goto STYLE_LOAD_OVER; } } } STYLE_LOAD_OVER: if( bInvalid ){ if( pPreStyle ){ delete pPreStyle; } if( pUseStyle ){ delete pUseStyle; } return E_PROJ_INVALIDSTYLE; } else{ g_pPreStyle = pPreStyle; g_pUseStyle = pUseStyle; } g_Theme.Build( lstBars, lstStages ); //段落预设 fread( &g_iPreStage, sizeof(int), 1, pFile ); //视图模式 int iViewMode; fread( &iViewMode, sizeof(int), 1, pFile ); //预设工程 if( wMinVersion>=3 ) fread( &g_bPredefine, sizeof(bool), 1, pFile ); return iError; } int LoadVersion2( FILE *pFile, DWORD dwVersion, HWND hNotifyWnd, int iLoadMode ) { int nSize, iMelodyKey, iMelodyTimeSignature, nMelodyTempo, nMelodyBarNum, nMelodyStageNum, nComposeStageNum, nCompleteBarNum; char strFont[MAX_PATH]; string strStyleName; bool bUseful; int iError = E_PROJ_NOERROR; WORD wMinVersion = LOWORD( dwVersion ); // 主要参数 UINT idStyle = 0, iStyleType; fread(&iStyleType, sizeof(DWORD), 1, pFile); //风格类型 fread(&idStyle, sizeof(UINT), 1, pFile); if( wMinVersion!=3 ){ fread(&g_bMidiMelody, sizeof(bool), 1, pFile); } fread(&iMelodyTimeSignature, sizeof(int), 1, pFile); fread(&nMelodyTempo, sizeof(int), 1, pFile); fread(&iMelodyKey, sizeof(int), 1, pFile); if( g_iMelodyTimeSignature!=iMelodyTimeSignature ){ SetMelodyTS(iMelodyTimeSignature); SelectStyle(); PostMessage( Application->MainFormHandle, UM_CHANGETT, true, -1 ); } TPROSTYLE* pStyle = CheckStyle( 0, idStyle );//GetStyleInfo( 0, idStyle ); if( !pStyle ) return E_PROJ_INVALIDSTYLE; SetMelodyTempo(nMelodyTempo); g_iMelodyKey = iMelodyKey; // 读取音色库文件名 fread(&nSize, sizeof(int), 1, pFile); if( nSize>0 ){ fread(strFont, sizeof(char), nSize, pFile); strcpy( g_strSoundFont, strFont ); } // 各项音量设值 fread(&g_fRecordVolume, sizeof(float), 1, pFile); if( g_fRecordVolume>1 ) g_fRecordVolume = 1; if( g_fRecordVolume<0 ) g_fRecordVolume = 0; fread(&g_fSpeakerVolume, sizeof(float), 1, pFile); if( g_fSpeakerVolume>1 ) g_fSpeakerVolume= 1; if( g_fSpeakerVolume<0 ) g_fSpeakerVolume= 0; float fAudioVolume = 1; fread(&fAudioVolume, sizeof(float), 1, pFile); if( fAudioVolume>1 ) fAudioVolume = 1; if( fAudioVolume<0 ) fAudioVolume = 0; fread(&g_fMusicVolume, sizeof(float), 1, pFile); if( g_fMusicVolume>1 ) g_fMusicVolume = 1; if( g_fMusicVolume<0 ) g_fMusicVolume = 0; f_MM_SetStreamVolume( 0, g_fSpeakerVolume ); f_MM_SetStreamVolume( 1, g_fRecordVolume ); f_MM_SetStreamVolume( 4, g_fMusicVolume ); // 建立初始段落变量 TBarList lstBars; vector lstStages; // g_lstRawBars int num; fread( &num, sizeof(int), 1, pFile ); if( num>0 ){ for( int i=0; iaChords.iKey[0] = pBar->aChords.iKey[1] = (iChords[0] / 4 + iMelodyKey) % KEY_NUM; pBar->aChords.iType[0] = pBar->aChords.iType[1] = iChords[0] % 4; if( iChords[1]==-1 ){ pBar->aChords.iKey[2] = pBar->aChords.iKey[3] = pBar->aChords.iKey[0]; pBar->aChords.iType[2] = pBar->aChords.iType[3] = pBar->aChords.iType[0]; } else{ pBar->aChords.iKey[2] = pBar->aChords.iKey[3] = (iChords[1] / 4 + iMelodyKey) % KEY_NUM;; pBar->aChords.iType[2] = pBar->aChords.iType[3] = iChords[1] % 4; } pBar->iBarKey = iMelodyKey; lstBars.push_back( pBar ); fread(&iFill, sizeof(char), 1, pFile); TWaveBar* pWvBar = new TWaveBar; if( iLoadMode!=PROJ_MODE_UPLOAD || wMinVersion<8 ) fread( pWvBar->aVols, sizeof(DWORD), POINTS_PER_BAR, pFile ); if( iLoadMode==PROJ_MODE_UPLOAD ) delete pWvBar; else g_aAudioTracks[0]->lstBars.push_back( pWvBar ); } AudioEffectsDefault( 0, false ); g_aAudioTracks[0]->volume = (int)(fAudioVolume * 100); } // g_lstRawStages fread( &num, sizeof(int), 1, pFile ); for( int i=0; i0 ){ if( iLoadMode!=PROJ_MODE_UPLOAD ){ pAudioTrack = new TAudioTrack; pAudioTrack->volume = (int)(fAudioVolume * 100); g_aAudioTracks.push_back( pAudioTrack ); g_aAudioTracks[0]->Hide();// = true; } for( int i=0; i lstSegType, lstSegNo, lstSegBars; int iMelodyStage, nStageBars, iVar, idStageStyle; fread( &iMelodyStage, sizeof(int), 1, pFile ); fread( &nStageBars, sizeof(int), 1, pFile ); fread( &iVar, sizeof(int), 1, pFile ); fread( &idStageStyle, sizeof(UINT), 1, pFile ); vector lstFill; int nFillNum; fread(&nFillNum, sizeof(int), 1, pFile); for (int j = 0; j < nFillNum; j++) { DWORD dwFill; fread(&dwFill, sizeof(DWORD), 1, pFile); lstFill.push_back( dwFill ); } TPROSTYLE* pStageStyle = CheckStyle( 0, idStageStyle ); if( !pStageStyle ){ idStageStyle = idStyle; pStageStyle = pStyle; iError |= E_PROJ_INVALSTAGESTYLE; } int iBarStart = 0; if( iMelodyStage<0x100 ){ //伴奏 if( iMelodyStage>0 ) iBarStart = lstStages[iMelodyStage-1] + 1; if( nFillNum>0 ){ int iBar = 0; for( int j=0; jiBar ){ lstSegType.push_back( SEGTYPE_VAR ); lstSegNo.push_back( iVar ); lstSegBars.push_back( iPos-iBar ); } lstSegType.push_back( SEGTYPE_FILL ); lstSegNo.push_back( iNo ); lstSegBars.push_back( 1 ); iBar = iPos+1; } } else{ lstSegType.push_back( SEGTYPE_VAR ); lstSegNo.push_back( iVar ); lstSegBars.push_back( nStageBars ); } } else if( iMelodyStage<0x110 ){ //前奏 lstSegType.push_back( SEGTYPE_INTRO ); int iNo = iMelodyStage - 0x100; lstSegNo.push_back( iNo ); lstSegBars.push_back( nStageBars ); } else{ //尾奏 lstSegType.push_back( SEGTYPE_ENDING ); int iNo = iMelodyStage - 0x110; lstSegNo.push_back( iNo ); lstSegBars.push_back( nStageBars ); } for( int k=0; kiSegKey = iMelodyKey; pStage->iSegType = lstSegType[k]; pStage->iSegNo = lstSegNo[k]; pStage->nVol = 100; for( int j=0; jaBars.push_back( pBar ); TWaveBar* pWvBar = NULL; if( pAudioTrack ){ pWvBar = new TWaveBar; pAudioTrack->lstBars.push_back( pWvBar ); } pBar->iBarKey = iMelodyKey; if( pStage->iSegTypelstBars[iBarStart], sizeof(DWORD)*POINTS_PER_BAR ); iBarStart++; } } //前/间/尾奏小调修正 if( pStage->iSegTypeaBars[0]->aChords.iType[0]; if( cType==1 || cType==3 ){ for( int j=g_lstOpusStages.size()-1; j>=0; j-- ){ if( g_lstOpusStages[j]->iSegType==SEGTYPE_INTRO ){ if( g_lstOpusStages[j]->iSegNo<4 ){ g_lstOpusStages[j]->iSegNo += 4; for( int t=0; taTracks.size(); t++ ){ TTrack* pTrk = g_lstOpusStages[j]->aTracks[t]; pTrk->iSegNo += 4; } } } else{ break; } } } } else if( !g_lstOpusStages.empty() ){ if( g_lstOpusStages.back()->iSegTypeaBars[0]->aChords.iType[0]; if( cType==1 || cType==3 ){ pStage->iSegNo += 4; } } else if( g_lstOpusStages.back()->iSegNo>=4 ) pStage->iSegNo += 4; } TSTYLEDETAIL& detail = pStageStyle->pOrigin->detail; for( int j=0; detail.tracks[lstSegType[k]][lstSegNo[k]][j].no>=0; j++ ){ TTrack* pTrack = new TTrack; pTrack->iStyleId = idStageStyle; pTrack->iSegNo = pStage->iSegNo; pTrack->iChanNo = pTrack->iChanSpec = detail.tracks[lstSegType[k]][lstSegNo[k]][j].no; pTrack->iProg = pTrack->iProgOrig = detail.tracks[lstSegType[k]][lstSegNo[k]][j].prog; pTrack->nVol = pTrack->nVolOrig = detail.tracks[lstSegType[k]][lstSegNo[k]][j].vol; pStage->aTracks.push_back( pTrack ); } g_lstOpusStages.push_back( pStage ); } } g_Opus.CountBars(); } // 全曲录音信息 int iComposeKey; fread(&iComposeKey, sizeof(int), 1, pFile); // 全曲小节音量 fread(&nCompleteBarNum, sizeof(int), 1, pFile); if( nCompleteBarNum ){ for( int i=0; ilstBars[i] : &barWave; fread( pWvBar->aVols, sizeof(DWORD), POINTS_PER_BAR, pFile ); } } for( int n=0; n<2; n++ ){ TStyleItem* pSty = new TStyleItem; pSty->pStyle = pStyle; if( n==0 ){ pSty->aOptions->Add((void*)OPT_FONTPROG); pSty->aOptions->Add((void*)OPT_SAVE); g_pPreStyle = pSty; } else{ g_pUseStyle = pSty; } } g_Theme.Build( lstBars, lstStages ); // 所处页面 int iPage; fread(&iPage, sizeof(int), 1, pFile); /* if( iPage==2 ) g_iViewMode = 2; else if( iPage==1 || iPage==4 ) g_iViewMode = 1; else g_iViewMode = 3; */ g_iPreStage = 3; //音效 int nFxNum; fread( &nFxNum, sizeof(int), 1, pFile ); if( nFxNum>0 ){ int aAudioEffects[11]; fread( aAudioEffects, sizeof(int), nFxNum, pFile ); if( pAudioTrack ){ for( int i=0; i0 ){ int iType = g_aAudioEffectTypes[i]; if( iType!=FX_PITCH ){ int nSize = GetFxParamNum( iType ); float* pParams = new float[nSize]; int iPreset = aAudioEffects[i] - 1; GetFxPreset( iType, iPreset, pParams ); TAudioFx* pFx = new TAudioFx( iType, iPreset, pParams, nSize ); pAudioTrack->lstFxs.push_back( pFx ); } } } } } else if( pAudioTrack ){ AudioEffectsDefault( 1, false ); } //预设工程 if( wMinVersion>=5 ) fread( &g_bPredefine, sizeof(bool), 1, pFile ); return iError; } BOOL HasProjectModified( bool bAuto ) { if( g_Undo.GetLastLite()!=(bAuto ? u_pAutoLite : u_pProjLite)) return TRUE; if( bAuto || g_Theme.Empty() ) return FALSE; if( g_bProjStylePaid || g_fRecordVolume_SVD != g_fRecordVolume || g_fSpeakerVolume_SVD != g_fSpeakerVolume || g_iMelodyKey_SVD != g_iMelodyKey || g_nMelodyTempo_SVD != g_nMelodyTempo //|| g_strFontFile_SVD.compare(g_strFontFile) ){ || strcmp( g_strSoundFont_SVD, g_strSoundFont )){ return TRUE; } return FALSE; } void ClearSVDVars() { //g_strFontFile_SVD.clear(); g_strSoundFont_SVD[0] = 0; g_iMelodyKey_SVD = -1; g_nMelodyTempo_SVD = g_nMelodyTempo; g_fRecordVolume_SVD = g_fRecordVolume; g_fSpeakerVolume_SVD = g_fSpeakerVolume; } void UpdateSVDVars() { ClearSVDVars(); // 旋律主要信息 g_iMelodyKey_SVD = g_iMelodyKey; g_nMelodyTempo_SVD = g_nMelodyTempo; // 音色库 //g_strFontFile_SVD = g_strFontFile; strcpy( g_strSoundFont_SVD, g_strSoundFont ); // 各项音量设值 g_fRecordVolume_SVD = g_fRecordVolume; g_fSpeakerVolume_SVD = g_fSpeakerVolume; } int CanSaveProj() { // int ret = E_PROJ_NOERROR; /* bool bHasUnlocalStyle = false; for( int i=0; !bHasUnlocalStyle && iaTracks.size(); j++ ){ if( pStage->aTracks[j]->iStyleLoc==(UINT)-1 && pStage->aTracks[j]->iStyleId!=0 ){ bHasUnlocalStyle = true; break; } } } if( bHasUnlocalStyle ) return E_PROJ_NOLOCALTEMPSTYLE; */ if( g_pUseStyle && (!g_pUseStyle->pStyle || GetStyleInfo( -1, 0 )) ) return E_PROJ_UNSAVEDTEMPSTYLE; return E_PROJ_NOERROR; } void ClearAutoProj() { SetAutoSaveReg( false ); if( FileExists( g_strAutoProjName.c_str() ) ) DeleteFile( g_strAutoProjName.c_str() ); DebugPrint("delete auto Save project file...."); } void SaveAutoProj() { if( HasProjectModified(true) && CanSaveProj()==E_PROJ_NOERROR ){ DebugPrint("auto Save project...."); AnsiString strProjectName = g_strAutoProjName.c_str(); SaveProject( strProjectName.c_str() ); } }