216 lines
4.8 KiB
C++
216 lines
4.8 KiB
C++
//---------------------------------------------------------------------------
|
||
|
||
#ifndef MidiTrackH
|
||
#define MidiTrackH
|
||
//---------------------------------------------------------------------------
|
||
#include <vector>
|
||
#include "ProCommon.h"
|
||
using namespace std;
|
||
#include "StyleItem.h"
|
||
#include "BaseTrack.h"
|
||
|
||
/***************************************************************************************/
|
||
// TMidi
|
||
typedef struct tagMidiNote{
|
||
BYTE pitch, //音高
|
||
velocity, //力度
|
||
volume, //音量
|
||
rsvd;
|
||
int tkOn, tkOff;
|
||
|
||
tagMidiNote( BYTE pt, BYTE vel, BYTE vol, DWORD on )
|
||
{
|
||
pitch = pt;
|
||
velocity = vel;
|
||
volume = vol;
|
||
tkOn = on;
|
||
tkOff = -1;
|
||
|
||
};
|
||
} TMidiNote;
|
||
|
||
class TMidiTrack : public TBaseTrack
|
||
{
|
||
public:
|
||
BYTE bank; //音源号 0xFF=全局SF2,other为指定音源
|
||
BYTE chno; //通道号
|
||
BYTE prog; //乐器号
|
||
BYTE file; //文件号 处理乐器多于16种的情况
|
||
|
||
BYTE ptMin, ptMax; //音符范围
|
||
|
||
vector<int> aStages;
|
||
vector<TMidiNote*> aNotes;
|
||
|
||
TMidiTrack() : TBaseTrack()
|
||
{
|
||
bank = chno = prog = file = 0xFF;
|
||
};
|
||
|
||
TMidiTrack( BYTE bk, BYTE ch, BYTE pr, BYTE fi=0 ) : TBaseTrack()
|
||
{
|
||
bank = bk;
|
||
chno = ch;
|
||
prog = pr;
|
||
file = fi;
|
||
|
||
ptMin = 0xFF;
|
||
ptMax = 0;
|
||
};
|
||
|
||
TMidiTrack( TMidiTrack* pSrc ) : TBaseTrack( pSrc->state, pSrc->volume, pSrc->pan, pSrc->gain )
|
||
{
|
||
bank = pSrc->bank;
|
||
chno = pSrc->chno;
|
||
prog = pSrc->prog;
|
||
file = pSrc->file;
|
||
|
||
ptMin = 0xFF;
|
||
ptMax = 0;
|
||
}
|
||
|
||
void AddStage( int iStage )
|
||
{
|
||
if( aStages.empty() )
|
||
aStages.push_back( iStage );
|
||
else{
|
||
for( int i=aStages.size()-1; i>=0; i-- ){
|
||
if( aStages[i]<iStage ){
|
||
if( i+1>=aStages.size() )
|
||
aStages.push_back( iStage );
|
||
else
|
||
aStages.insert( aStages.begin()+i+1, iStage );
|
||
|
||
break;
|
||
}
|
||
|
||
if( aStages[i]==iStage )
|
||
break;
|
||
|
||
if( i==0 ){
|
||
aStages.insert( aStages.begin(), iStage );
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
void DelStage( int iStage )
|
||
{
|
||
for( int i=0; i<aStages.size(); i++ ){
|
||
if( aStages[i]>iStage )
|
||
break;
|
||
|
||
if( aStages[i]==iStage ){
|
||
aStages.erase( aStages.begin() + i );
|
||
break;
|
||
}
|
||
}
|
||
};
|
||
|
||
bool ValidStages( vector<int>& lstStages ) //段落可用
|
||
{
|
||
bool bValid = true;
|
||
vector<int>::iterator iter1 = aStages.begin(),
|
||
iter2 = lstStages.begin();
|
||
while( iter1!=aStages.end() && iter2!=lstStages.end() ){
|
||
if( *iter1 < *iter2 )
|
||
iter1++;
|
||
else if( *iter1 > *iter2 )
|
||
iter2++;
|
||
else{
|
||
bValid = false;
|
||
break;
|
||
}
|
||
}
|
||
|
||
return bValid;
|
||
};
|
||
|
||
bool IsDrum()
|
||
{
|
||
if( !aStages.empty() ){
|
||
TOpusStage* pStage = g_lstOpusStages[aStages[0]];
|
||
for( int i=0; i<pStage->aTracks.size(); i++ ){
|
||
TTrack* pTrack = pStage->aTracks[i];
|
||
if( pTrack->iFile==file && pTrack->iChanSpec==chno && pTrack->iChanNo==9 )
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
};
|
||
|
||
typedef struct tagChnoUsed
|
||
{
|
||
WORD chno; //通道号按位占用
|
||
BYTE file; //文件号 处理乐器多于16种的情况
|
||
BYTE bank; //音源号 0xFF=全局SF2,other为指定音源
|
||
|
||
tagChnoUsed( BYTE bk, BYTE fi=0 )
|
||
{
|
||
bank = bk;
|
||
file = fi;
|
||
chno = 0;
|
||
}
|
||
} TChnoUsed, *PTChnoUsed;
|
||
|
||
typedef vector<TMidiTrack*> TMidiTrackList;
|
||
|
||
class TMidi
|
||
{
|
||
private:
|
||
TMidiTrackList m_lstMidiTracks; //MIDI轨道列表
|
||
vector<PTChnoUsed> m_aChnoUsed;
|
||
int m_nMidiFile;
|
||
|
||
|
||
public:
|
||
TMidi(){m_nMidiFile = 0;};
|
||
~TMidi(){ClearMidiTracks();};
|
||
|
||
TMidiTrackList& MidiTrackList() { return m_lstMidiTracks; };
|
||
bool IsEmpty() { return m_lstMidiTracks.empty(); };
|
||
void ClearMidiTracks();
|
||
void ClearMidiTrackNotes();
|
||
int ClearEmptyTrack();
|
||
|
||
void SortMidiTracks(); //整理channel号
|
||
|
||
int GetMidiTrackIndex( BYTE file, BYTE chno );
|
||
TMidiTrack* FindMidiTrack( BYTE file, BYTE chno );
|
||
TMidiTrack* GetValidMidiTrack( vector<int>& lstStages, BYTE file, BYTE chno, BYTE bank, BYTE prog );
|
||
TMidiTrack* GetValidMidiTrack( int iStage, BYTE file, BYTE chno, BYTE bank, BYTE prog );
|
||
|
||
void CutStage( int iStage ); //分割段
|
||
void InsertStage( int iStage ); //插入空段
|
||
void RemoveStage( int iStage, bool bSort ); //删除段 bSort=不留空
|
||
|
||
TChnoUsed* GetChnoUsed( BYTE file, BYTE bank );
|
||
void AddMidiTrack( TMidiTrack* pCh, int iInd=-1 );
|
||
void AddChnoUsed( TChnoUsed* pCU );
|
||
void DeleteMidiTrack( TMidiTrack* pCh );
|
||
void DeleteChnoUsed( TChnoUsed* pCU );
|
||
BYTE GetValidFile( BYTE bank, BYTE chno );
|
||
void ChangMidiChno( int iMT, BYTE fiNew, BYTE chNew );
|
||
|
||
void InitNoteColor();
|
||
TColor GetNoteColor( int vol );
|
||
void ChangeNotesVolume( int iMT, int iSBar, int iEBar, BYTE volume );
|
||
|
||
void GetSpecBanks( vector<BYTE>& lstBank );
|
||
void SetSpecBanks( BANKMAPLIST& lstMap );
|
||
void WriteProj( FILE* pFile );
|
||
int ReadProj( FILE* pFile, DWORD dwVersion );
|
||
};
|
||
|
||
/***************************************************************************************/
|
||
// 全局变量
|
||
/***************************************************************************************/
|
||
extern TMidi g_Midi; //MIDI轨道对象
|
||
extern TMidiTrackList& g_aMidiTracks; //MIDI轨道列表
|
||
extern int g_iSelMidiTrack; //当前处理的MIDI轨道
|
||
|
||
#endif
|