aboutsummaryrefslogtreecommitdiff
path: root/src/adlmidi_load.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/adlmidi_load.cpp')
-rw-r--r--src/adlmidi_load.cpp127
1 files changed, 50 insertions, 77 deletions
diff --git a/src/adlmidi_load.cpp b/src/adlmidi_load.cpp
index 9ec14e7..08892a5 100644
--- a/src/adlmidi_load.cpp
+++ b/src/adlmidi_load.cpp
@@ -48,34 +48,6 @@ uint64_t MIDIplay::ReadLEint(const void *buffer, size_t nbytes)
return result;
}
-uint64_t MIDIplay::ReadVarLenEx(size_t tk, bool &ok)
-{
- uint64_t result = 0;
- ok = false;
-
- for(;;)
- {
- if(tk >= TrackData.size())
- return 1;
-
- if(tk >= CurrentPosition.track.size())
- return 2;
-
- size_t ptr = CurrentPosition.track[tk].ptr;
-
- if(ptr >= TrackData[tk].size())
- return 3;
-
- unsigned char byte = TrackData[tk][CurrentPosition.track[tk].ptr++];
- result = (result << 7) + (byte & 0x7F);
-
- if(!(byte & 0x80)) break;
- }
-
- ok = true;
- return result;
-}
-
bool MIDIplay::LoadBank(const std::string &filename)
{
fileReader file;
@@ -122,7 +94,7 @@ enum WOPL_InstrumentFlags
{
WOPL_Flags_NONE = 0,
WOPL_Flag_Enable4OP = 0x01,
- WOPL_Flag_Pseudo4OP = 0x02,
+ WOPL_Flag_Pseudo4OP = 0x02
};
struct WOPL_Inst
@@ -295,7 +267,7 @@ bool MIDIplay::LoadBank(MIDIplay::fileReader &fr)
}
}
- opl.AdlBank = opl._parent->AdlBank;
+ opl.AdlBank = m_setup.AdlBank;
opl.dynamic_metainstruments.clear();
opl.dynamic_instruments.clear();
@@ -369,6 +341,7 @@ bool MIDIplay::LoadMIDI(MIDIplay::fileReader &fr)
ADL_UNUSED(fsize);
//! Temp buffer for conversion
AdlMIDI_CPtr<uint8_t> cvt_buf;
+ errorString.clear();
#ifdef DISABLE_EMBEDDED_BANKS
if((opl.AdlBank != ~0u) || (opl.dynamic_metainstruments.size() < 256))
@@ -389,18 +362,18 @@ bool MIDIplay::LoadMIDI(MIDIplay::fileReader &fr)
/**** Set all properties BEFORE starting of actial file reading! ****/
- config->stored_samples = 0;
- config->backup_samples_size = 0;
- opl.AdlPercussionMode = (config->AdlPercussionMode != 0);
- opl.HighTremoloMode = (config->HighTremoloMode != 0);
- opl.HighVibratoMode = (config->HighVibratoMode != 0);
- opl.ScaleModulators = (config->ScaleModulators != 0);
- opl.LogarithmicVolumes = (config->LogarithmicVolumes != 0);
- opl.ChangeVolumeRangesModel(static_cast<ADLMIDI_VolumeModels>(config->VolumeModel));
+ m_setup.stored_samples = 0;
+ m_setup.backup_samples_size = 0;
+ opl.AdlPercussionMode = m_setup.AdlPercussionMode;
+ opl.HighTremoloMode = m_setup.HighTremoloMode;
+ opl.HighVibratoMode = m_setup.HighVibratoMode;
+ opl.ScaleModulators = m_setup.ScaleModulators;
+ opl.LogarithmicVolumes = m_setup.LogarithmicVolumes;
+ opl.ChangeVolumeRangesModel(static_cast<ADLMIDI_VolumeModels>(m_setup.VolumeModel));
- if(config->VolumeModel == ADLMIDI_VolumeModel_AUTO)
+ if(m_setup.VolumeModel == ADLMIDI_VolumeModel_AUTO)
{
- switch(config->AdlBank)
+ switch(m_setup.AdlBank)
{
default:
opl.m_volumeScale = OPL3::VOLUME_Generic;
@@ -429,17 +402,15 @@ bool MIDIplay::LoadMIDI(MIDIplay::fileReader &fr)
}
}
- opl.NumCards = config->NumCards;
- opl.NumFourOps = config->NumFourOps;
+ opl.NumCards = m_setup.NumCards;
+ opl.NumFourOps = m_setup.NumFourOps;
cmf_percussion_mode = false;
- opl.Reset();
+ opl.Reset(m_setup.PCM_RATE);
trackStart = true;
atEnd = false;
loopStart = true;
- loopStart_passed = false;
invalidLoop = false;
- loopStart_hit = false;
bool is_GMF = false; // GMD/MUS files (ScummVM)
//bool is_MUS = false; // MUS/DMX files (Doom)
@@ -655,8 +626,8 @@ InvFmt:
TrackData.clear();
TrackData.resize(TrackCount, std::vector<uint8_t>());
- CurrentPosition.track.clear();
- CurrentPosition.track.resize(TrackCount);
+ //CurrentPosition.track.clear();
+ //CurrentPosition.track.resize(TrackCount);
InvDeltaTicks = fraction<uint64_t>(1, 1000000l * static_cast<uint64_t>(DeltaTicks));
//Tempo = 1000000l * InvDeltaTicks;
Tempo = fraction<uint64_t>(1, static_cast<uint64_t>(DeltaTicks));
@@ -673,7 +644,8 @@ InvFmt:
//std::fprintf(stderr, "Reading IMF file...\n");
size_t end = static_cast<uint8_t>(HeaderBuf[0]) + 256 * static_cast<uint8_t>(HeaderBuf[1]);
unsigned IMF_tempo = 1428;
- static const unsigned char imf_tempo[] = {0xFF, 0x51, 0x4,
+ static const unsigned char imf_tempo[] = {0x0,//Zero delay!
+ MidiEvent::T_SPECIAL, MidiEvent::ST_TEMPOCHANGE, 0x4,
static_cast<uint8_t>(IMF_tempo >> 24),
static_cast<uint8_t>(IMF_tempo >> 16),
static_cast<uint8_t>(IMF_tempo >> 8),
@@ -686,31 +658,31 @@ InvFmt:
while(fr.tell() < end && !fr.eof())
{
uint8_t special_event_buf[5];
- special_event_buf[0] = 0xFF;
- special_event_buf[1] = 0xE3;
+ uint8_t raw[4];
+ special_event_buf[0] = MidiEvent::T_SPECIAL;
+ special_event_buf[1] = MidiEvent::ST_RAWOPL;
special_event_buf[2] = 0x02;
- special_event_buf[3] = static_cast<uint8_t>(fr.getc()); // port index
- special_event_buf[4] = static_cast<uint8_t>(fr.getc()); // port value
- uint32_t delay = static_cast<uint16_t>(fr.getc());
- delay += 256 * static_cast<uint16_t>(fr.getc());
+ if(fr.read(raw, 1, 4) != 4)
+ break;
+ special_event_buf[3] = raw[0]; // port index
+ special_event_buf[4] = raw[1]; // port value
+ uint32_t delay = static_cast<uint32_t>(raw[2]);
+ delay += 256 * static_cast<uint32_t>(raw[3]);
totalGotten += 4;
//if(special_event_buf[3] <= 8) continue;
//fprintf(stderr, "Put %02X <- %02X, plus %04X delay\n", special_event_buf[3],special_event_buf[4], delay);
TrackData[tk].insert(TrackData[tk].end(), special_event_buf, special_event_buf + 5);
-
//if(delay>>21) TrackData[tk].push_back( 0x80 | ((delay>>21) & 0x7F ) );
if(delay >> 14)
TrackData[tk].push_back(0x80 | ((delay >> 14) & 0x7F));
-
if(delay >> 7)
TrackData[tk].push_back(0x80 | ((delay >> 7) & 0x7F));
-
TrackData[tk].push_back(((delay >> 0) & 0x7F));
}
TrackData[tk].insert(TrackData[tk].end(), EndTag + 0, EndTag + 4);
- CurrentPosition.track[tk].delay = 0;
- CurrentPosition.began = true;
+ //CurrentPosition.track[tk].delay = 0;
+ //CurrentPosition.began = true;
//std::fprintf(stderr, "Done reading IMF file\n");
opl.NumFourOps = 0; //Don't use 4-operator channels for IMF playing!
}
@@ -734,10 +706,8 @@ InvFmt:
else
{
fsize = fr.read(HeaderBuf, 1, 8);
-
if(std::memcmp(HeaderBuf, "MTrk", 4) != 0)
goto InvFmt;
-
TrackLength = (size_t)ReadBEint(HeaderBuf + 4, 4);
}
@@ -749,19 +719,18 @@ InvFmt:
if(is_GMF /*|| is_MUS*/) // Note: CMF does include the track end tag.
TrackData[tk].insert(TrackData[tk].end(), EndTag + 0, EndTag + 4);
- bool ok = false;
- // Read next event time
- uint64_t tkDelay = ReadVarLenEx(tk, ok);
-
- if(ok)
- CurrentPosition.track[tk].delay = tkDelay;
- else
- {
- std::stringstream msg;
- msg << fr._fileName << ": invalid variable length in the track " << tk << "! (error code " << tkDelay << ")";
- ADLMIDI_ErrorString = msg.str();
- return false;
- }
+ //bool ok = false;
+ //// Read next event time
+ //uint64_t tkDelay = ReadVarLenEx(tk, ok);
+ //if(ok)
+ // CurrentPosition.track[tk].delay = tkDelay;
+ //else
+ //{
+ // std::stringstream msg;
+ // msg << fr._fileName << ": invalid variable length in the track " << tk << "! (error code " << tkDelay << ")";
+ // ADLMIDI_ErrorString = msg.str();
+ // return false;
+ //}
}
}
@@ -774,10 +743,14 @@ InvFmt:
return false;
}
- //Build new MIDI events table (WIP!!!)
- buildTrackData();
+ //Build new MIDI events table (ALPHA!!!)
+ if(!buildTrackData())
+ {
+ ADLMIDI_ErrorString = fr._fileName + ": MIDI data parsing error has occouped!\n" + errorString;
+ return false;
+ }
- opl.Reset(); // Reset AdLib
+ opl.Reset(m_setup.PCM_RATE); // Reset AdLib
//opl.Reset(); // ...twice (just in case someone misprogrammed OPL3 previously)
ch.clear();
ch.resize(opl.NumChannels);