📄 midifile.cpp
字号:
// ------ read and process a track
// +-------------------------------------------------------------
// |
// | Function : MIDIFile::ReadTrack
// | Description :
// |
// +-------------------------------------------------------------
void MIDIFile::ReadTrack() throw (std::runtime_error)
{
char buff[5]; // Buffer for signature "MThd"
// ------ read signature
for (int i = 0; i < 4; i++)
buff[i] = GetMIDIChar();
buff[i] = '\0';
// ------ validate signature
if (std::string(buff) != "MTrk")
throw MFBadTrkSig();
// ---- initialize time variable for the track
m_nDeltaTime = 0;
m_bEot = false; // Indicate that EOT event hasn't been sensed
// ---- notify user that new track is found
StartTrack(++m_nTrackNo);
// -------- Read the length of the track
if ((m_nTrackLength = Read32()) < 0)
throw MFBadTrkLen();
// --------- Read the data in the track
while (m_nTrackLength > 0)
ReadEvent();
if (!m_bEot) // Has EOT been sensed?
throw MFNoEot();
}
// ------- read and process a Standard MIDI Format (SMF) file
// +-------------------------------------------------------------
// |
// | Function : MIDIFile::ReadMIDIFile
// | Description :
// |
// +-------------------------------------------------------------
void MIDIFile::ReadMIDIFile()
{
assert(m_pIfile != 0);
ReadHeader(); // read the header
for (int i = 0; i < m_nTracks; i++)
ReadTrack(); // read the tracks
}
// ------- write a Standard MIDI Format (SMF) file
// +-------------------------------------------------------------
// |
// | Function : MIDIFile::WriteMIDIFile
// | Description :
// |
// +-------------------------------------------------------------
void MIDIFile::WriteMIDIFile()
{
assert(m_pOfile != 0);
// ---- write the header
m_pOfile->write("MThd",4);
// --- header length
Write32(6);
// --- format
Write16(m_nFormat);
// --- tracks
Write16(m_nTracks);
// --- ticks/quarter note
Write16(m_nDivision);
m_bWritingTrack = true;
for (m_nTrackNo = 1; m_nTrackNo <= m_nTracks; m_nTrackNo++) {
// --- write the track header
m_nTrackLength = 0;
m_pOfile->write("MTrk",4);
long position = m_pOfile->tellp(); // where length is written at end of track
Write32(0); // to be overwritten at end of track
m_bOverride = true;
StartTrack(m_nTrackNo);
assert(m_bOverride == true); // ensure that application overrides StartTrack
// ---- write end of track
WriteMetaEvent(0,META_EOT,0);
long here = m_pOfile->tellp();
// --- seek back and write track length
m_pOfile->seekp(position);
Write32(m_nTrackLength);
// --- seek to write next track
m_pOfile->seekp(here);
}
}
// +-------------------------------------------------------------
// |
// | Function : MIDIFile::WriteMetaEvent
// | Description :
// |
// | delta :
// | event :
// | length :
// |
// +-------------------------------------------------------------
void MIDIFile::WriteMetaEvent(Long delta,Short event,Short length)
{
m_nTrackLength += WriteVarLength(delta);
m_pOfile->put('\xff');
m_pOfile->put(static_cast<char>(event));
m_nTrackLength += 2;
m_nTrackLength += WriteVarLength(length);
m_nTrackLength += length;
}
// +-------------------------------------------------------------
// |
// | Function : MIDIFile::SequenceNum
// | Description :
// |
// | delta :
// | seqno :
// |
// +-------------------------------------------------------------
void MIDIFile::SequenceNum(Long delta,Short seqno)
{
if (m_pOfile != 0) {
// --- writing an SMF file
assert(m_bWritingTrack);
WriteMetaEvent(delta,META_SEQNUM,2);
Write16(seqno);
}
else
m_bOverride = false;
}
// +-------------------------------------------------------------
// |
// | Function : MIDIFile::TextEvent
// | Description :
// |
// | delta :
// | event :
// | length :
// | text :
// |
// +-------------------------------------------------------------
void MIDIFile::TextEvent(Long delta,Short event,Long length,const char* text)
{
if (m_pOfile != 0) {
// --- writing an SMF file
assert(m_bWritingTrack);
assert(event >= META_COPYRIGHT && event <= META_CUEPT);
WriteMetaEvent(delta,event,length);
m_pOfile->write(text,length);
}
else
m_bOverride = false;
}
// +-------------------------------------------------------------
// |
// | Function : MIDIFile::Tempo
// | Description :
// |
// | delta :
// | tempo :
// |
// +-------------------------------------------------------------
void MIDIFile::Tempo(Long delta,Long tempo)
{
if (m_pOfile != 0) {
// --- writing an SMF file
assert(m_bWritingTrack);
WriteMetaEvent(delta,META_TEMPO,3);
Write24(tempo);
}
else
m_bOverride = false;
}
// +-------------------------------------------------------------
// |
// | Function : MIDIFile::SMPTE
// | Description :
// |
// | delta :
// | hr :
// | min :
// | sec :
// | frame :
// | fraction :
// |
// +-------------------------------------------------------------
void MIDIFile::SMPTE(Long delta,Short hr,Short min,Short sec,Short frame,Short fraction)
{
if (m_pOfile != 0) {
// --- writing an SMF file
assert(m_bWritingTrack);
WriteMetaEvent(delta,META_SMPTE,5);
m_pOfile->put(static_cast<char>(hr));
m_pOfile->put(static_cast<char>(min));
m_pOfile->put(static_cast<char>(sec));
m_pOfile->put(static_cast<char>(frame));
m_pOfile->put(static_cast<char>(fraction));
}
else
m_bOverride = false;
}
// +-------------------------------------------------------------
// |
// | Function : MIDIFile::TimeSignature
// | Description :
// |
// | delta :
// | numer :
// | denom :
// | clocks :
// | qnote :
// |
// +-------------------------------------------------------------
void MIDIFile::TimeSignature(Long delta,Short numer,Short denom,Short clocks,Short qnote)
{
if (m_pOfile != 0) {
// --- writing an SMF file
assert(m_bWritingTrack);
WriteMetaEvent(delta,META_TIMESIG,4);
m_pOfile->put(static_cast<char>(numer));
m_pOfile->put(static_cast<char>(denom));
m_pOfile->put(static_cast<char>(clocks));
m_pOfile->put(static_cast<char>(qnote));
}
else
m_bOverride = false;
}
// +-------------------------------------------------------------
// |
// | Function : MIDIFile::KeySignature
// | Description :
// |
// | delta :
// | sharpsflats :
// | isminor :
// |
// +-------------------------------------------------------------
void MIDIFile::KeySignature(Long delta,Short sharpsflats,bool isminor)
{
if (m_pOfile != 0) {
// --- writing an SMF file
assert(m_bWritingTrack);
WriteMetaEvent(delta,META_KEYSIG,2);
m_pOfile->put(static_cast<char>(sharpsflats));
m_pOfile->put(isminor ? '\x01' : '\x00');
}
else
m_bOverride = false;
}
// +-------------------------------------------------------------
// |
// | Function : MIDIFile::SequencerSpecific
// | Description :
// |
// | delta :
// | length :
// | text :
// |
// +-------------------------------------------------------------
void MIDIFile::SequencerSpecific(Long delta,Short length,const char* text)
{
if (m_pOfile != 0) {
// --- writing an SMF file
assert(m_bWritingTrack);
WriteMetaEvent(delta,META_SEQSPEC,length);
m_pOfile->write(text,length);
}
else
m_bOverride = false;
}
// +-------------------------------------------------------------
// |
// | Function : MIDIFile::ChannelPrefix
// | Description :
// |
// | delta :
// | channel :
// |
// +-------------------------------------------------------------
void MIDIFile::ChannelPrefix(Long delta,Short channel)
{
if (m_pOfile != 0) {
// --- writing an SMF file
assert(m_bWritingTrack);
WriteMetaEvent(delta,META_CHANPFX,1);
m_pOfile->put(static_cast<char>(channel));
}
else
m_bOverride = false;
}
// +-------------------------------------------------------------
// |
// | Function : MIDIFile::WriteMIDIEvent
// | Description :
// |
// | delta :
// | event :
// | length :
// |
// +-------------------------------------------------------------
void MIDIFile::WriteMIDIEvent(Long delta,Short event,Short length)
{
m_nTrackLength += WriteVarLength(delta);
m_pOfile->put(static_cast<char>(event));
m_nTrackLength++;
m_nTrackLength += length;
}
// +-------------------------------------------------------------
// |
// | Function : MIDIFile::NoteOn
// | Description :
// |
// | delta :
// | channel :
// | note :
// | velocity :
// |
// +-------------------------------------------------------------
void MIDIFile::NoteOn(Long delta,Short channel,Short note,Short velocity)
{
if (m_pOfile != 0) {
// --- writing an SMF file
assert(m_bWritingTrack);
WriteMIDIEvent(delta,MIDI_NOTEON | channel,2);
m_pOfile->put(static_cast<char>(note & 0x7f));
m_pOfile->put(static_cast<char>(velocity & 0x7f));
}
else
m_bOverride = false;
}
// +-------------------------------------------------------------
// |
// | Function : MIDIFile::NoteOff
// | Description :
// |
// | delta :
// | channel :
// | note :
// | velocity :
// |
// +-------------------------------------------------------------
void MIDIFile::NoteOff(Long delta,Short channel,Short note,Short velocity)
{
if (m_pOfile != 0) {
// --- writing an SMF file
assert(m_bWritingTrack);
WriteMIDIEvent(delta,MIDI_NOTEOFF | channel,2);
m_pOfile->put(static_cast<char>(note & 0x7f));
m_pOfile->put(static_cast<char>(velocity & 0x7f));
}
else
m_bOverride = false;
}
// +-------------------------------------------------------------
// |
// | Function : MIDIFile::Pressure
// | Description :
// |
// | delta :
// | channel :
// | note :
// | aftertouch :
// |
// +-------------------------------------------------------------
void MIDIFile::Pressure(Long delta,Short channel,Short note,Short aftertouch)
{
if (m_pOfile != 0) {
// --- writing an SMF file
assert(m_bWritingTrack);
WriteMIDIEvent(delta,MIDI_PRESSURE | channel,2);
m_pOfile->put(static_cast<char>(note & 0x7f));
m_pOfile->put(static_cast<char>(aftertouch & 0x7f));
}
else
m_bOverride = false;
}
// +-------------------------------------------------------------
// |
// | Function : MIDIFile::Controller
// | Description :
// |
// | delta :
// | channel :
// | controller :
// | value :
// |
// +-------------------------------------------------------------
void MIDIFile::Controller(Long delta,Short channel,Short controller,Short value)
{
if (m_pOfile != 0) {
// --- writing an SMF file
assert(m_bWritingTrack);
WriteMIDIEvent(delta,MIDI_CONTROL | channel,2);
m_pOfile->put(static_cast<char>(controller & 0x7f));
m_pOfile->put(static_cast<char>(value & 0x7f));
}
else
m_bOverride = false;
}
// +-------------------------------------------------------------
// |
// | Function : MIDIFile::ProgramChange
// | Description :
// |
// | delta :
// | channel :
// | program :
// |
// +-------------------------------------------------------------
void MIDIFile::ProgramChange(Long delta,Short channel,Short program)
{
if (m_pOfile != 0) {
// --- writing an SMF file
assert(m_bWritingTrack);
WriteMIDIEvent(delta,MIDI_PROGRAM | channel,1);
m_pOfile->put(static_cast<char>(program & 0x7f));
}
else
m_bOverride = false;
}
// +-------------------------------------------------------------
// |
// | Function : MIDIFile::ChannelPressure
// | Description :
// |
// | delta :
// | channel :
// | aftertouch :
// |
// +-------------------------------------------------------------
void MIDIFile::ChannelPressure(Long delta,Short channel,Short aftertouch)
{
if (m_pOfile != 0) {
// --- writing an SMF file
assert(m_bWritingTrack);
WriteMIDIEvent(delta,MIDI_CHANPRES | channel,1);
m_pOfile->put(static_cast<char>(aftertouch & 0x7f));
}
else
m_bOverride = false;
}
// +-------------------------------------------------------------
// |
// | Function : MIDIFile::PitchBend
// | Description :
// |
// | delta :
// | channel :
// | pitch :
// |
// +-------------------------------------------------------------
void MIDIFile::PitchBend(Long delta,Short channel,Short pitch)
{
if (m_pOfile != 0) {
// --- writing an SMF file
assert(m_bWritingTrack);
WriteMIDIEvent(delta,MIDI_PITCHBEND | channel,1);
m_pOfile->put(static_cast<char>(pitch & 0x7f));
}
else
m_bOverride = false;
}
// +-------------------------------------------------------------
// |
// | Function : MIDIFile::SystemExclusive
// | Description :
// |
// | delta :
// | length :
// | data :
// |
// +-------------------------------------------------------------
void MIDIFile::SystemExclusive(Long delta,Long length,const char* data)
{
if (m_pOfile != 0) {
// --- writing an SMF file
assert(m_bWritingTrack);
m_nTrackLength += WriteVarLength(delta);
m_pOfile->put('\xf0');
m_nTrackLength++;
m_nTrackLength += WriteVarLength(length);
m_pOfile->write(data,length);
}
else
m_bOverride = false;
}
// +-------------------------------------------------------------
// |
// | Function : MIDIFile::SystemExclusivePacket
// | Description :
// |
// | delta :
// | length :
// | data :
// |
// +-------------------------------------------------------------
void MIDIFile::SystemExclusivePacket(Long delta,Long length,const char* data)
{
if (m_pOfile != 0) {
// --- writing an SMF file
assert(m_bWritingTrack);
m_nTrackLength += WriteVarLength(delta);
m_pOfile->put('\xf7');
m_nTrackLength++;
m_nTrackLength += WriteVarLength(length);
m_pOfile->write(data,length);
}
else
m_bOverride = false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -