Files
2026-06-13 00:05:19 +08:00

2527 lines
64 KiB
C++

//---------------------------------------------------------------------------
#include <vcl.h>
#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<TTempStyleMap*> u_aTempStyleMap; //临时风格映射表
wstring g_strLastProjSavePath, // 上次保存工程路径
g_strProjectName, // 工程文件名
g_strAutoProjName; // 自动保存文件名
//g_strFontFile_SVD; // 音色库文件名(已保存)
vector<wstring>g_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; i<u_aTempStyleMap.size(); i++ ){
delete u_aTempStyleMap[i];
}
u_aTempStyleMap.clear();
u_pAutoLite = u_pProjLite = NULL;
}
TPROSTYLE* CheckStyle( int idLoc, int idStyle )
{
TPROSTYLE* pStyle = GetStyleInfo( idLoc, idStyle );
if( pStyle && idLoc==0 && pStyle->pOrigin->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<wstring>::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; k<u_aTempStyleMap.size(); k++ ){
if( idStyle==u_aTempStyleMap[k]->idTemp ){
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; k<aLocSegs.size(); k++ ){
if( idLoc==aLocSegs[k]->idLoc
&& idStyle==aLocSegs[k]->idStyle ){
for( int t=0; t<aLocSegs[k]->aSegs.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; i<num; i++ ){
TOpusStage* pStage = lstStages[i];
fwrite( &pStage->iSegType, 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; j<count; j++ ){
TBar* pBar = pStage->aBars[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; j<count; j++ ){
TTrack* pTrack = pStage->aTracks[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<BYTE> 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; i<nCount; i++ ){
BYTE iBank = lstBank[i];
fwrite(&iBank, sizeof(BYTE), 1, pFile);
if( iBank<0x80 ){
char* strFontName = g_lstFonts[iBank]->strFontName;
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; i<num; i++ ){
TSegmentItem* pSeg = (TSegmentItem*)pSty->aItems->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; j<count; j++ ){
TTrackItem* pTrk = (TTrackItem*)pSeg->aItems->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; i<aLocSegs.size(); i++ ){
TLocSegment* pLocSeg = (TLocSegment*)aLocSegs[i];
int nSegNum = pLocSeg->aSegs.size();
WORD (*aSegs)[2] = new WORD[nSegNum][2];
for( int j=0; j<pLocSeg->aSegs.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; k<u_aTempStyleMap.size(); k++ ){
if( idStyle==u_aTempStyleMap[k]->idTemp ){
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( i<MAX_AUDIOTRACK && g_aAudioTracks[i]->lstBars.size()>0
&& f_MM_AudioGetLength(i)>=0 ){
if( wMajVersion>=5 ){ //获取音量信息
for( int k=0; k<g_aAudioTracks[i]->lstBars.size(); k++ ){
TWaveBar* pBar = g_aAudioTracks[i]->lstBars[k];
for( int j=0; j<POINTS_PER_BAR; j++ ){
pBar->aVols[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; t<aUnsolvedStyles.size(); t++ ){
if( aUnsolvedStyles[t]->idLoc==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; i<num; i++ ){
TOpusStage* pStage = new TOpusStage;
fread( &pStage->iSegType, 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; j<count; j++ ){
TBar* pBar = new TBar;
fread( &pBar->aChords, 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; j<count; j++ ){
TTrack * pTrack = new TTrack;
fread( &pTrack->iStyleLoc, 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; i<nCount; i++ ){
BYTE len;
BYTE iBankNew = 0xFF;
TBankMap* pMap = new TBankMap;
fread(&pMap->iBankOld, 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; j<g_lstFonts.size(); j++ ){
if( !strcmp( g_lstFonts[j]->strFontName, 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; j<g_lstVSTi.size(); j++ ){
if( uniqueID==g_lstVSTi[j]->uniqueID ){
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; i<num; i++ ){
char st, sn, vol;
int bars;
fread( &st, sizeof(char), 1, pFile );
fread( &sn, sizeof(char), 1, pFile );
fread( &vol, sizeof(char), 1, pFile );
fread( &bars, sizeof(int), 1, pFile );
DWORD opts = OPT_DEL | OPT_VOL | (st<SEGTYPE_INTRO ? OPT_BRUSH : 0);
TSegmentItem* pSeg = pSty->AddSegment( st, sn, opts, 0, -1, vol );
pSeg->nBars = bars;
int count;
// TTrackItem* pTrkPrev = NULL;
fread( &count, sizeof(int), 1, pFile );
for( int j=0; j<count; j++ ){
UINT idItemLoc, idItemStyle;
// TTrackItem* pTrk = new TTrackItem;
fread( &idItemLoc, sizeof(UINT), 1, pFile );
fread( &idItemStyle, sizeof(UINT), 1, pFile );
if( wMinVersion<6 ){
char iSegType;
fread( &iSegType, sizeof(char), 1, pFile );
}
TTrack* pTrk = new TTrack;
fread( &pTrk->iSegNo, 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; i<num; i++ ){
UINT idLoc, idStyle;
int len;
fread( &idLoc, sizeof(UINT), 1, pFile );
fread( &idStyle, sizeof(UINT), 1, pFile );
fread( &len, sizeof(int), 1, pFile );
if( len>0 ){
fread( mem, 1, len, pFile );
for( int j=0; j<aUnsolvedStyles.size(); j++ ){
TPROSTYLE* pInfo = aUnsolvedStyles[j];
if( idLoc==pInfo->idLoc && 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; i<aUnsolvedStyles.size(); i++ ){
delete aUnsolvedStyles[i];
}
aUnsolvedStyles.clear();
return E_PROJ_INVALIDSTYLE;
}
g_Opus.BuildStyleItem();
return iError;
}
int LoadVersion4( FILE *pFile, DWORD dwVersion, HWND hNotifyWnd )
{
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 );
}
// 各项音量设值
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<int> lstStages;
// g_lstRawBars
int num;
fread( &num, sizeof(int), 1, pFile );
if( num>0 ){
for( int i=0; i<num; i++ ){
TWaveBar* pWvBar = new TWaveBar;
fread( pWvBar->aVols, 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; i<num; i++ ){
int iRaw = 0;
fread( &iRaw, sizeof(int), 1, pFile );
lstStages.push_back( iRaw );
}
// g_lstOpusStages
TAudioTrack* pAudioTrack = NULL;
fread( &num, sizeof(int), 1, pFile );
if( num>0 ){
pAudioTrack = new TAudioTrack;
pAudioTrack->volume = (int)(fAudioVolume * 100);
g_aAudioTracks.push_back( pAudioTrack );
g_aAudioTracks[0]->Hide();// = true;
for( int i=0; i<num; i++ ){
TOpusStage* pStage = new TOpusStage;
if( HIWORD( dwVersion )==4 && wMinVersion<3 ){
int iSegType, iSegNo;
fread( &iSegType, sizeof(int), 1, pFile );
fread( &iSegNo, sizeof(int), 1, pFile );
pStage->iSegType = 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; j<count; j++ ){
TWaveBar* pWvBar = new TWaveBar;
fread( pWvBar->aVols, 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; j<count; j++ ){
TTrackOldProj track;
fread( &track, sizeof(TTrackOldProj), 1, pFile );
if( track.iStyleLoc==0 ){
TPROSTYLE* pTrackStyle = CheckStyle( track.iStyleLoc, track.iStyleId );
if( !pTrackStyle ){ //无效的风格
delete pStage;
return E_PROJ_INVALIDSTYLE;
}
}
TTrack* pTrk = new TTrack;
pTrk->iStyleLoc = 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<MAX_FX_NUM; i++ ){
int count;
fread(&count, sizeof(int), 1, pFile);
for( int j=0; j<count; j++ ){
TEffect pAE;
fread( &pAE.iBarStart, sizeof(int), 1, pFile );
fread( &pAE.iPointStart, sizeof(int), 1, pFile );
fread( &pAE.iBarEnd, sizeof(int), 1, pFile );
fread( &pAE.iPointEnd, sizeof(int), 1, pFile );
fread( &pAE.iPreset, sizeof(int), 1, pFile );
fread( &pAE.bOn, sizeof(bool), 1, pFile );
if( pAE.bOn ){
pAE.aParams = new float[6];
fread( pAE.aParams, sizeof(float), 6, pFile );
}
if( pAE.iBarStart==0 && pAE.iBarEnd>=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; i<num; i++ ){
fread( &iOpt, sizeof(DWORD), 1, pFile );
}
TOpusStage* pStage = NULL;
TSegmentItem* pSegPrev = NULL;
fread( &num, sizeof(int), 1, pFile );
for( int i=0; i<num; i++ ){
TSegmentItem* pSeg = new TSegmentItem;
pSeg->bAutoSpec = 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; j<count; j++ ){
fread( &iOpt, sizeof(DWORD), 1, pFile );
}
if( n>0 ){
pStage = g_lstOpusStages[i];
pStage->nVol = pSeg->volume;
}
TTrackItem* pTrkPrev = NULL;
fread( &count, sizeof(int), 1, pFile );
for( int j=0; j<count; j++ ){
int idItemLoc, idItemStyle;
TTrackItem* pTrk = new TTrackItem;
TTrack* pTrack = new TTrack;
fread( &pTrk->iType, 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; k<cn; k++ ){
fread( &iOpt, sizeof(DWORD), 1, pFile );
}
TPROSTYLE* pInfo = NULL;
if( bAuthority || idItemLoc==0 )
pInfo = CheckStyle( idItemLoc, idItemStyle );
if( !pInfo ){
if( n==0 ){
delete pTrk;
delete pTrack;
continue;
}
if( idItemLoc!=0 && idItemLoc!=(UINT)-1 ){
for( int t=0; t<aUnsolvedStyles.size(); t++ ){
if( aUnsolvedStyles[t]->idLoc==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->iType<SEGTYPE_INTRO )
pSeg->aOptions->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; t<aUnsolvedStyles.size(); t++ ){
if( aUnsolvedStyles[t]->idLoc==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; i<pSty->aItems->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; i<num; i++ ){
UINT idLoc, idStyle;
int len;
fread( &idLoc, sizeof(UINT), 1, pFile );
fread( &idStyle, sizeof(UINT), 1, pFile );
fread( &len, sizeof(int), 1, pFile );
if( len>0 ){
fread( mem, 1, len, pFile );
for( int j=0; j<aUnsolvedStyles.size(); j++ ){
TPROSTYLE* pInfo = aUnsolvedStyles[j];
if( idLoc==pInfo->idLoc && idStyle==pInfo->idStyle ){
int id = f_CM_ProjRestoreStyle( len, mem );
if( id>0 ){
for( int s=0; s<g_lstOpusStages.size(); s++ ){
TOpusStage* pStage = g_lstOpusStages[s];
for( int t=0; t<pStage->aTracks.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; i<aUnsolvedStyles.size(); i++ ){
delete aUnsolvedStyles[i];
}
aUnsolvedStyles.clear();
return E_PROJ_INVALIDSTYLE;
}
g_Theme.Build( lstBars, lstStages );
return iError;
}
int LoadVersion3( FILE *pFile, DWORD dwVersion, HWND hNotifyWnd )
{
char strFont[MAX_PATH];
string strStyleName;
bool bUseful;
int iError = E_PROJ_NOERROR;
WORD wMinVersion = LOWORD( dwVersion );
int nSize, iMelodyKey, iMelodyTimeSignature, nMelodyTempo;
// 主要参数
UINT idStyle = 0;
fread(&idStyle, sizeof(UINT), 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 );
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; i<num; i++ ){
TWaveBar* pWvBar = new TWaveBar;
fread( pWvBar->aVols, 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<int> lstStages;
fread( &num, sizeof(int), 1, pFile );
for( int i=0; i<num; i++ ){
int iRaw = 0;
fread( &iRaw, sizeof(int), 1, pFile );
lstStages.push_back( iRaw );
}
// g_lstOpusStages
TAudioTrack* pAudioTrack = NULL;
fread( &num, sizeof(int), 1, pFile );
if( num>0 ){
pAudioTrack = new TAudioTrack;
pAudioTrack->volume = (int)(fAudioVolume * 100);
g_aAudioTracks.push_back( pAudioTrack );
g_aAudioTracks[0]->Hide();// = true;
for( int i=0; i<num; i++ ){
TOpusStage* pStage = new TOpusStage;
int idStageStyle, iSegType, iSegNo;
fread( &idStageStyle, sizeof(UINT), 1, pFile );
fread( &iSegType, sizeof(int), 1, pFile );
fread( &iSegNo, sizeof(int), 1, pFile );
pStage->iSegType = 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; j<count; j++ ){
TWaveBar* pWvBar = new TWaveBar;
fread( pWvBar->aVols, 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; j<count; j++ ){
TTrackOld trkOld;
fread( &trkOld, sizeof(TTrackOld), 1, pFile );
TPROSTYLE* pTrackStyle = CheckStyle( 0, trkOld.iStyleId );
if( !pTrackStyle ){
delete pStage;
return E_PROJ_INVALIDSTYLE;
}
TTrack * pTrack = new TTrack;
pTrack->iStyleId = 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<MAX_FX_NUM; i++ ){
int count;
fread(&count, sizeof(int), 1, pFile);
for( int j=0; j<count; j++ ){
TEffect pAE;
fread( &pAE.iBarStart, sizeof(int), 1, pFile );
fread( &pAE.iPointStart, sizeof(int), 1, pFile );
fread( &pAE.iBarEnd, sizeof(int), 1, pFile );
fread( &pAE.iPointEnd, sizeof(int), 1, pFile );
fread( &pAE.iPreset, sizeof(int), 1, pFile );
fread( &pAE.bOn, sizeof(bool), 1, pFile );
if( pAE.bOn ){
pAE.aParams = new float[6];
fread( pAE.aParams, sizeof(float), 6, pFile );
}
if( pAE.iBarStart==0 && pAE.iBarEnd>=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; i<num; i++ ){
fread( &iOpt, sizeof(DWORD), 1, pFile );
}
TOpusStage* pStage = NULL;
TSegmentItem* pSegPrev = NULL;
fread( &num, sizeof(int), 1, pFile );
for( int i=0; i<num; i++ ){
if( n>0 )
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; j<count; j++ ){
fread( &iOpt, sizeof(DWORD), 1, pFile );
}
pSeg->aOptions->Add( (void*)OPT_DEL );
pSeg->aOptions->Add( (void*)OPT_VOL );
if( pSeg->iType<SEGTYPE_INTRO )
pSeg->aOptions->Add( (void*)OPT_BRUSH );
TTrackItem* pTrkPrev = NULL;
fread( &count, sizeof(int), 1, pFile );
for( int j=0; j<count; j++ ){
int idTrkItemStyle;
TTrackItem* pTrk = new TTrackItem;
TTrack* pTrack = new TTrack;
fread( &pTrk->iType, 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; k<cn; k++ ){
fread( &iOpt, sizeof(DWORD), 1, pFile );
}
//检查轨道风格
pTrk->pStyle = 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; i<pSty->aItems->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<int> lstStages;
// g_lstRawBars
int num;
fread( &num, sizeof(int), 1, pFile );
if( num>0 ){
for( int i=0; i<num; i++ ){
TBar* pBar = new TBar;
char iChords[2], iFill;
fread(&iChords[0], sizeof(char), 1, pFile);
fread(&iChords[1], sizeof(char), 1, pFile);
pBar->aChords.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; i<num; i++ ){
int iFirstBar, iLastBar, iVar;
fread(&iFirstBar, sizeof(int), 1, pFile);
fread(&iLastBar, sizeof(int), 1, pFile);
fread(&iVar, sizeof(int), 1, pFile);
lstStages.push_back( iLastBar );
}
// g_lstOpusStages
TAudioTrack* pAudioTrack = NULL;
fread( &num, sizeof(int), 1, pFile );
if( num>0 ){
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<num; i++ ){
vector<int> 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<int> 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; j<nFillNum; j++ ){
int iPos = LOWORD(lstFill[j]),
iNo = HIWORD(lstFill[j]);
if( iPos>iBar ){
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; k<lstSegType.size(); k++ ){
TOpusStage* pStage = new TOpusStage;
pStage->iSegKey = iMelodyKey;
pStage->iSegType = lstSegType[k];
pStage->iSegNo = lstSegNo[k];
pStage->nVol = 100;
for( int j=0; j<lstSegBars[k]; j++ ){
TBar* pBar = new TBar;
pStage->aBars.push_back( pBar );
TWaveBar* pWvBar = NULL;
if( pAudioTrack ){
pWvBar = new TWaveBar;
pAudioTrack->lstBars.push_back( pWvBar );
}
pBar->iBarKey = iMelodyKey;
if( pStage->iSegType<SEGTYPE_INTRO ){
memcpy( pBar, lstBars[iBarStart], sizeof(TBar) );
if( pWvBar )
memcpy( pWvBar, g_aAudioTracks[0]->lstBars[iBarStart],
sizeof(DWORD)*POINTS_PER_BAR );
iBarStart++;
}
}
//前/间/尾奏小调修正
if( pStage->iSegType<SEGTYPE_INTRO ){
int cType = pStage->aBars[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; t<g_lstOpusStages[j]->aTracks.size(); t++ ){
TTrack* pTrk = g_lstOpusStages[j]->aTracks[t];
pTrk->iSegNo += 4;
}
}
}
else{
break;
}
}
}
}
else if( !g_lstOpusStages.empty() ){
if( g_lstOpusStages.back()->iSegType<SEGTYPE_INTRO ){
int cType = g_lstOpusStages.back()->aBars[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; i<nCompleteBarNum; i++ ){
TWaveBar barWave;
TWaveBar* pWvBar = pAudioTrack ? pAudioTrack->lstBars[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; i<MAX_FX_NUM; i++ ){
if( aAudioEffects[i]>0 ){
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 && i<g_lstOpusStages.size(); i++ ){
TOpusStage *pStage = g_lstOpusStages[i];
for( int j=0; j<pStage->aTracks.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() );
}
}