diff options
Diffstat (limited to 'src/adlmidi_load.cpp')
-rw-r--r-- | src/adlmidi_load.cpp | 127 |
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); |