Initial commit
This commit is contained in:
+215
@@ -0,0 +1,215 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#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
|
||||
Reference in New Issue
Block a user