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

216 lines
4.8 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//---------------------------------------------------------------------------
#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=全局SF2other为指定音源
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=全局SF2other为指定音源
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