2527 lines
64 KiB
C++
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() );
|
|
}
|
|
}
|
|
|