Mercurial > audlegacy-plugins
diff src/adplug/core/rol.cxx @ 956:88ba14f18587 trunk
[svn] I said to indent it, not to break it, hmmkay?
author | chainsaw |
---|---|
date | Sat, 14 Apr 2007 16:09:21 -0700 |
parents | 4709ce4e209e |
children | fa9f85cebade |
line wrap: on
line diff
--- a/src/adplug/core/rol.cxx Sat Apr 14 15:23:50 2007 -0700 +++ b/src/adplug/core/rol.cxx Sat Apr 14 16:09:21 2007 -0700 @@ -25,786 +25,702 @@ #include "rol.h" #include "debug.h" -int const - CrolPlayer::kSizeofDataRecord = 30; -int const - CrolPlayer::kMaxTickBeat = 60; -int const - CrolPlayer::kSilenceNote = -12; -int const - CrolPlayer::kNumMelodicVoices = 9; -int const - CrolPlayer::kNumPercussiveVoices = 11; -int const - CrolPlayer::kBassDrumChannel = 6; -int const - CrolPlayer::kSnareDrumChannel = 7; -int const - CrolPlayer::kTomtomChannel = 8; -int const - CrolPlayer::kTomtomFreq = 2; //4; -int const - CrolPlayer::kSnareDrumFreq = 2; //kTomtomFreq + 7; -float const - CrolPlayer::kDefaultUpdateTme = 18.2f; -float const - CrolPlayer::kPitchFactor = 400.0f; +int const CrolPlayer::kSizeofDataRecord = 30; +int const CrolPlayer::kMaxTickBeat = 60; +int const CrolPlayer::kSilenceNote = -12; +int const CrolPlayer::kNumMelodicVoices = 9; +int const CrolPlayer::kNumPercussiveVoices = 11; +int const CrolPlayer::kBassDrumChannel = 6; +int const CrolPlayer::kSnareDrumChannel = 7; +int const CrolPlayer::kTomtomChannel = 8; +int const CrolPlayer::kTomtomFreq = 2;//4; +int const CrolPlayer::kSnareDrumFreq = 2;//kTomtomFreq + 7; +float const CrolPlayer::kDefaultUpdateTme = 18.2f; +float const CrolPlayer::kPitchFactor = 400.0f; + +static const unsigned char drum_table[4] = {0x14, 0x12, 0x15, 0x11}; -static const unsigned char -drum_table[4] = { 0x14, 0x12, 0x15, 0x11 }; - -CrolPlayer::uint16 const - CrolPlayer::kNoteTable[12] = { - 340, // C - 363, // C# - 385, // D - 408, // D# - 432, // E - 458, // F - 485, // F# - 514, // G - 544, // G# - 577, // A - 611, // A# - 647 // B +CrolPlayer::uint16 const CrolPlayer::kNoteTable[12] = +{ + 340, // C + 363, // C# + 385, // D + 408, // D# + 432, // E + 458, // F + 485, // F# + 514, // G + 544, // G# + 577, // A + 611, // A# + 647 // B }; /*** public methods **************************************/ -CPlayer * -CrolPlayer::factory (Copl * newopl) -{ - return new CrolPlayer (newopl); -} - -//--------------------------------------------------------- -CrolPlayer::CrolPlayer (Copl * newopl):CPlayer (newopl), rol_header (NULL), mNextTempoEvent (0), mCurrTick (0), -mTimeOfLastNote (0), mRefresh (kDefaultUpdateTme), -bdRegister (0) -{ - int - n; - - memset (bxRegister, 0, sizeof (bxRegister)); - memset (volumeCache, 0, sizeof (volumeCache)); - memset (freqCache, 0, sizeof (freqCache)); - - for (n = 0; n < 11; n++) - pitchCache[n] = 1.0f; -} - -//--------------------------------------------------------- -CrolPlayer::~CrolPlayer () +CPlayer *CrolPlayer::factory(Copl *newopl) { - if (rol_header) - { - delete rol_header; - rol_header = 0; - } + return new CrolPlayer(newopl); } - //--------------------------------------------------------- -bool -CrolPlayer::load (VFSFile * fd, const CFileProvider & fp) +CrolPlayer::CrolPlayer(Copl *newopl) +: CPlayer ( newopl ) + ,rol_header ( NULL ) + ,mNextTempoEvent ( 0 ) + ,mCurrTick ( 0 ) + ,mTimeOfLastNote ( 0 ) + ,mRefresh ( kDefaultUpdateTme ) + ,bdRegister ( 0 ) { - binistream *f = fp.open (fd); - if (!f) - return false; - std::string filename (fd->uri); + int n; - char *fn = new char[filename.length () + 12]; - int i; - std::string bnk_filename; - - AdPlug_LogWrite ("*** CrolPlayer::load(f, \"%s\") ***\n", - filename.c_str ()); - strcpy (fn, filename.data ()); - for (i = strlen (fn) - 1; i >= 0; i--) - if (fn[i] == '/' || fn[i] == '\\') - break; - strcpy (fn + i + 1, "standard.bnk"); - bnk_filename = fn; - delete[]fn; - fn = 0; - AdPlug_LogWrite ("bnk_filename = \"%s\"\n", bnk_filename.c_str ()); - - rol_header = new SRolHeader; - memset (rol_header, 0, sizeof (SRolHeader)); + memset(bxRegister, 0, sizeof(bxRegister) ); + memset(volumeCache, 0, sizeof(volumeCache) ); + memset(freqCache, 0, sizeof(freqCache) ); - rol_header->version_major = f->readInt (2); - rol_header->version_minor = f->readInt (2); - - // Version check - if (rol_header->version_major != 0 || rol_header->version_minor != 4) - { - AdPlug_LogWrite ("Unsupported file version %d.%d or not a ROL file!\n", - rol_header->version_major, rol_header->version_minor); - AdPlug_LogWrite ("--- CrolPlayer::load ---\n"); - fp.close (f); - return false; - } - - f->seek (40, binio::Add); - - rol_header->ticks_per_beat = f->readInt (2); - rol_header->beats_per_measure = f->readInt (2); - rol_header->edit_scale_y = f->readInt (2); - rol_header->edit_scale_x = f->readInt (2); - - f->seek (1, binio::Add); - - rol_header->mode = f->readInt (1); - - f->seek (90 + 38 + 15, binio::Add); - - rol_header->basic_tempo = f->readFloat (binio::Single); - - load_tempo_events (f); + for(n=0; n<11; n++) + pitchCache[n]=1.0f; +} +//--------------------------------------------------------- +CrolPlayer::~CrolPlayer() +{ + if(rol_header) + { + delete rol_header; + rol_header = 0; + } +} +//--------------------------------------------------------- +bool CrolPlayer::load(VFSFile *fd, const CFileProvider &fp) +{ + binistream *f = fp.open(fd); if(!f) return false; + std::string filename(fd->uri); - mTimeOfLastNote = 0; - - if (load_voice_data (f, bnk_filename, fp) != true) - { - AdPlug_LogWrite ("CrolPlayer::load_voice_data(f) failed!\n"); - AdPlug_LogWrite ("--- CrolPlayer::load ---\n"); - - fp.close (f); - return false; - } - - fp.close (f); + char *fn = new char[filename.length()+12]; + int i; + std::string bnk_filename; - rewind (0); - AdPlug_LogWrite ("--- CrolPlayer::load ---\n"); - return true; -} + AdPlug_LogWrite("*** CrolPlayer::load(f, \"%s\") ***\n", filename.c_str()); + strcpy(fn,filename.data()); + for (i=strlen(fn)-1; i>=0; i--) + if (fn[i] == '/' || fn[i] == '\\') + break; + strcpy(fn+i+1,"standard.bnk"); + bnk_filename = fn; + delete [] fn; fn = 0; + AdPlug_LogWrite("bnk_filename = \"%s\"\n",bnk_filename.c_str()); -//--------------------------------------------------------- -bool -CrolPlayer::update () -{ - if (mNextTempoEvent < mTempoEvents.size () && - mTempoEvents[mNextTempoEvent].time == mCurrTick) - { - SetRefresh (mTempoEvents[mNextTempoEvent].multiplier); - ++mNextTempoEvent; - } + rol_header = new SRolHeader; + memset( rol_header, 0, sizeof(SRolHeader) ); - TVoiceData::iterator curr = voice_data.begin (); - TVoiceData::iterator end = voice_data.end (); - int voice = 0; + rol_header->version_major = f->readInt( 2 ); + rol_header->version_minor = f->readInt( 2 ); - while (curr != end) - { - UpdateVoice (voice, *curr); - ++curr; - ++voice; - } + // Version check + if(rol_header->version_major != 0 || rol_header->version_minor != 4) { + AdPlug_LogWrite("Unsupported file version %d.%d or not a ROL file!\n", + rol_header->version_major, rol_header->version_minor); + AdPlug_LogWrite("--- CrolPlayer::load ---\n"); + fp.close(f); + return false; + } - ++mCurrTick; - - if (mCurrTick > mTimeOfLastNote) - { - return false; - } + f->seek( 40, binio::Add ); - return true; - //return ( mCurrTick > mTimeOfLastNote ) ? false : true; -} + rol_header->ticks_per_beat = f->readInt( 2 ); + rol_header->beats_per_measure = f->readInt( 2 ); + rol_header->edit_scale_y = f->readInt( 2 ); + rol_header->edit_scale_x = f->readInt( 2 ); -//--------------------------------------------------------- -void -CrolPlayer::rewind (int subsong) -{ - TVoiceData::iterator curr = voice_data.begin (); - TVoiceData::iterator end = voice_data.end (); + f->seek( 1, binio::Add ); - while (curr != end) - { - CVoiceData & voice = *curr; + rol_header->mode = f->readInt(1); - voice.Reset (); - ++curr; - } + f->seek( 90+38+15, binio::Add ); - memset (bxRegister, 0, sizeof (bxRegister)); - memset (volumeCache, 0, sizeof (volumeCache)); + rol_header->basic_tempo = f->readFloat( binio::Single ); - bdRegister = 0; - - opl->init (); // initialize to melodic by default - opl->write (1, 0x20); // Enable waveform select (bit 5) + load_tempo_events( f ); - if (rol_header->mode == 0) - { - opl->write (0xbd, 0x20); // select rhythm mode (bit 5) - bdRegister = 0x20; + mTimeOfLastNote = 0; - SetFreq (kTomtomChannel, 24); - SetFreq (kSnareDrumChannel, 31); - } + if( load_voice_data( f, bnk_filename, fp ) != true ) + { + AdPlug_LogWrite("CrolPlayer::load_voice_data(f) failed!\n"); + AdPlug_LogWrite("--- CrolPlayer::load ---\n"); - mNextTempoEvent = 0; - mCurrTick = 0; + fp.close( f ); + return false; + } - SetRefresh (1.0f); + fp.close( f ); + + rewind( 0 ); + AdPlug_LogWrite("--- CrolPlayer::load ---\n"); + return true; } - //--------------------------------------------------------- -inline float -fmin (int const a, int const b) -{ - return static_cast < float >(a < b ? a : b); -} - -//--------------------------------------------------------- -void -CrolPlayer::SetRefresh (float const multiplier) +bool CrolPlayer::update() { - float const tickBeat = fmin (kMaxTickBeat, rol_header->ticks_per_beat); - - mRefresh = (tickBeat * rol_header->basic_tempo * multiplier) / 60.0f; -} - -//--------------------------------------------------------- -float -CrolPlayer::getrefresh () -{ - return mRefresh; -} - -//--------------------------------------------------------- -void -CrolPlayer::UpdateVoice (int const voice, CVoiceData & voiceData) -{ - TNoteEvents const &nEvents = voiceData.note_events; - - if (nEvents.empty () || voiceData.mEventStatus & CVoiceData::kES_NoteEnd) - { - return; // no note data to process, don't bother doing anything. - } - - TInstrumentEvents & iEvents = voiceData.instrument_events; - TVolumeEvents & vEvents = voiceData.volume_events; - TPitchEvents & pEvents = voiceData.pitch_events; - - if (!(voiceData.mEventStatus & CVoiceData::kES_InstrEnd) && - iEvents[voiceData.next_instrument_event].time == mCurrTick) - { - if (voiceData.next_instrument_event < iEvents.size ()) + if( mNextTempoEvent < mTempoEvents.size() && + mTempoEvents[mNextTempoEvent].time == mCurrTick ) { - send_ins_data_to_chip (voice, - iEvents[voiceData.next_instrument_event]. - ins_index); - ++voiceData.next_instrument_event; - } - else - { - voiceData.mEventStatus |= CVoiceData::kES_InstrEnd; + SetRefresh( mTempoEvents[mNextTempoEvent].multiplier ); + ++mNextTempoEvent; } - } - if (!(voiceData.mEventStatus & CVoiceData::kES_VolumeEnd) && - vEvents[voiceData.next_volume_event].time == mCurrTick) - { - SVolumeEvent const &volumeEvent = vEvents[voiceData.next_volume_event]; + TVoiceData::iterator curr = voice_data.begin(); + TVoiceData::iterator end = voice_data.end(); + int voice = 0; - if (voiceData.next_volume_event < vEvents.size ()) + while( curr != end ) { - int const volume = (int) (63.0f * (1.0f - volumeEvent.multiplier)); - - SetVolume (voice, volume); + UpdateVoice( voice, *curr ); + ++curr; + ++voice; + } - ++voiceData.next_volume_event; // move to next volume event - } - else + ++mCurrTick; + + if( mCurrTick > mTimeOfLastNote ) { - voiceData.mEventStatus |= CVoiceData::kES_VolumeEnd; - } - } - - if (voiceData.mForceNote - || voiceData.current_note_duration > voiceData.mNoteDuration - 1) - { - if (mCurrTick != 0) - { - ++voiceData.current_note; + return false; } - if (voiceData.current_note < nEvents.size ()) + return true; + //return ( mCurrTick > mTimeOfLastNote ) ? false : true; +} +//--------------------------------------------------------- +void CrolPlayer::rewind( int subsong ) +{ + TVoiceData::iterator curr = voice_data.begin(); + TVoiceData::iterator end = voice_data.end(); + + while( curr != end ) { - SNoteEvent const ¬eEvent = nEvents[voiceData.current_note]; + CVoiceData &voice = *curr; + + voice.Reset(); + ++curr; + } + + memset(bxRegister, 0, sizeof(bxRegister) ); + memset(volumeCache, 0, sizeof(volumeCache) ); + + bdRegister = 0; + + opl->init(); // initialize to melodic by default + opl->write(1,0x20); // Enable waveform select (bit 5) + + if( rol_header->mode == 0 ) + { + opl->write( 0xbd, 0x20 ); // select rhythm mode (bit 5) + bdRegister = 0x20; + + SetFreq( kTomtomChannel, 24 ); + SetFreq( kSnareDrumChannel, 31 ); + } - SetNote (voice, noteEvent.number); - voiceData.current_note_duration = 0; - voiceData.mNoteDuration = noteEvent.duration; - voiceData.mForceNote = false; + mNextTempoEvent = 0; + mCurrTick = 0; + + SetRefresh(1.0f); +} +//--------------------------------------------------------- +inline float fmin( int const a, int const b ) +{ + return static_cast<float>( a < b ? a : b ); +} +//--------------------------------------------------------- +void CrolPlayer::SetRefresh( float const multiplier ) +{ + float const tickBeat = fmin(kMaxTickBeat, rol_header->ticks_per_beat); + + mRefresh = (tickBeat*rol_header->basic_tempo*multiplier) / 60.0f; +} +//--------------------------------------------------------- +float CrolPlayer::getrefresh() +{ + return mRefresh; +} +//--------------------------------------------------------- +void CrolPlayer::UpdateVoice( int const voice, CVoiceData &voiceData ) +{ + TNoteEvents const &nEvents = voiceData.note_events; + + if( nEvents.empty() || voiceData.mEventStatus & CVoiceData::kES_NoteEnd ) + { + return; // no note data to process, don't bother doing anything. } - else + + TInstrumentEvents &iEvents = voiceData.instrument_events; + TVolumeEvents &vEvents = voiceData.volume_events; + TPitchEvents &pEvents = voiceData.pitch_events; + + if( !(voiceData.mEventStatus & CVoiceData::kES_InstrEnd ) && + iEvents[voiceData.next_instrument_event].time == mCurrTick ) { - SetNote (voice, kSilenceNote); - voiceData.mEventStatus |= CVoiceData::kES_NoteEnd; - return; + if( voiceData.next_instrument_event < iEvents.size() ) + { + send_ins_data_to_chip( voice, iEvents[voiceData.next_instrument_event].ins_index ); + ++voiceData.next_instrument_event; + } + else + { + voiceData.mEventStatus |= CVoiceData::kES_InstrEnd; + } } - } + + if( !(voiceData.mEventStatus & CVoiceData::kES_VolumeEnd ) && + vEvents[voiceData.next_volume_event].time == mCurrTick ) + { + SVolumeEvent const &volumeEvent = vEvents[voiceData.next_volume_event]; + + if( voiceData.next_volume_event < vEvents.size() ) + { + int const volume = (int)(63.0f*(1.0f - volumeEvent.multiplier)); + + SetVolume( voice, volume ); + + ++voiceData.next_volume_event; // move to next volume event + } + else + { + voiceData.mEventStatus |= CVoiceData::kES_VolumeEnd; + } + } + + if( voiceData.mForceNote || voiceData.current_note_duration > voiceData.mNoteDuration-1 ) + { + if( mCurrTick != 0 ) + { + ++voiceData.current_note; + } - if (!(voiceData.mEventStatus & CVoiceData::kES_PitchEnd) && - pEvents[voiceData.next_pitch_event].time == mCurrTick) - { - if (voiceData.next_pitch_event < pEvents.size ()) + if( voiceData.current_note < nEvents.size() ) + { + SNoteEvent const ¬eEvent = nEvents[voiceData.current_note]; + + SetNote( voice, noteEvent.number ); + voiceData.current_note_duration = 0; + voiceData.mNoteDuration = noteEvent.duration; + voiceData.mForceNote = false; + } + else + { + SetNote( voice, kSilenceNote ); + voiceData.mEventStatus |= CVoiceData::kES_NoteEnd; + return; + } + } + + if( !(voiceData.mEventStatus & CVoiceData::kES_PitchEnd ) && + pEvents[voiceData.next_pitch_event].time == mCurrTick ) { - SetPitch (voice, pEvents[voiceData.next_pitch_event].variation); - ++voiceData.next_pitch_event; + if( voiceData.next_pitch_event < pEvents.size() ) + { + SetPitch(voice,pEvents[voiceData.next_pitch_event].variation); + ++voiceData.next_pitch_event; + } + else + { + voiceData.mEventStatus |= CVoiceData::kES_PitchEnd; + } + } + + ++voiceData.current_note_duration; +} +//--------------------------------------------------------- +void CrolPlayer::SetNote( int const voice, int const note ) +{ + if( voice < kBassDrumChannel || rol_header->mode ) + { + SetNoteMelodic( voice, note ); } else { - voiceData.mEventStatus |= CVoiceData::kES_PitchEnd; + SetNotePercussive( voice, note ); } - } - - ++voiceData.current_note_duration; } - //--------------------------------------------------------- -void -CrolPlayer::SetNote (int const voice, int const note) +void CrolPlayer::SetNotePercussive( int const voice, int const note ) { - if (voice < kBassDrumChannel || rol_header->mode) - { - SetNoteMelodic (voice, note); - } - else - { - SetNotePercussive (voice, note); - } -} + int const bit_pos = 4-voice+kBassDrumChannel; -//--------------------------------------------------------- -void -CrolPlayer::SetNotePercussive (int const voice, int const note) -{ - int const bit_pos = 4 - voice + kBassDrumChannel; - - bdRegister &= ~(1 << bit_pos); - opl->write (0xbd, bdRegister); + bdRegister &= ~( 1<<bit_pos ); + opl->write( 0xbd, bdRegister ); - if (note != kSilenceNote) - { - switch (voice) + if( note != kSilenceNote ) { - case kTomtomChannel: - SetFreq (kSnareDrumChannel, note + 7); - case kBassDrumChannel: - SetFreq (voice, note); - break; - } - - bdRegister |= 1 << bit_pos; - opl->write (0xbd, bdRegister); - } -} + switch( voice ) + { + case kTomtomChannel: + SetFreq( kSnareDrumChannel, note+7 ); + case kBassDrumChannel: + SetFreq( voice, note ); + break; + } + bdRegister |= 1<<bit_pos; + opl->write( 0xbd, bdRegister ); + } +} //--------------------------------------------------------- -void -CrolPlayer::SetNoteMelodic (int const voice, int const note) +void CrolPlayer::SetNoteMelodic( int const voice, int const note ) { - opl->write (0xb0 + voice, bxRegister[voice] & ~0x20); + opl->write( 0xb0+voice, bxRegister[voice] & ~0x20 ); - if (note != kSilenceNote) - { - SetFreq (voice, note, true); - } + if( note != kSilenceNote ) + { + SetFreq( voice, note, true ); + } } - //--------------------------------------------------------- -void -CrolPlayer::SetPitch (int const voice, real32 const variation) +void CrolPlayer::SetPitch(int const voice, real32 const variation) { pitchCache[voice] = variation; - freqCache[voice] += - (uint16) ((((float) freqCache[voice]) * (variation - 1.0f)) / - kPitchFactor); + freqCache[voice] += (uint16)((((float)freqCache[voice])*(variation-1.0f)) / kPitchFactor); - opl->write (0xa0 + voice, freqCache[voice] & 0xff); + opl->write(0xa0+voice,freqCache[voice] & 0xff); } - //--------------------------------------------------------- -void -CrolPlayer::SetFreq (int const voice, int const note, bool const keyOn) +void CrolPlayer::SetFreq( int const voice, int const note, bool const keyOn ) { - uint16 freq = kNoteTable[note % 12] + ((note / 12) << 10); - freq += - (uint16) ((((float) freq) * (pitchCache[voice] - 1.0f)) / kPitchFactor); + uint16 freq = kNoteTable[note%12] + ((note/12) << 10); + freq += (uint16)((((float)freq)*(pitchCache[voice]-1.0f))/kPitchFactor); - freqCache[voice] = freq; - bxRegister[voice] = ((freq >> 8) & 0x1f); + freqCache[voice] = freq; + bxRegister[voice] = ((freq >> 8) & 0x1f); - opl->write (0xa0 + voice, freq & 0xff); - opl->write (0xb0 + voice, bxRegister[voice] | (keyOn ? 0x20 : 0x0)); + opl->write( 0xa0+voice, freq & 0xff ); + opl->write( 0xb0+voice, bxRegister[voice] | (keyOn ? 0x20 : 0x0) ); } - //--------------------------------------------------------- -void -CrolPlayer::SetVolume (int const voice, int const volume) +void CrolPlayer::SetVolume( int const voice, int const volume ) { - volumeCache[voice] = (volumeCache[voice] & 0xc0) | volume; + volumeCache[voice] = (volumeCache[voice] &0xc0) | volume; + + int const op_offset = ( voice < kSnareDrumChannel || rol_header->mode ) ? + op_table[voice]+3 : drum_table[voice-kSnareDrumChannel]; - int const op_offset = (voice < kSnareDrumChannel || rol_header->mode) ? - op_table[voice] + 3 : drum_table[voice - kSnareDrumChannel]; - - opl->write (0x40 + op_offset, volumeCache[voice]); + opl->write( 0x40+op_offset, volumeCache[voice] ); } - //--------------------------------------------------------- -void -CrolPlayer::send_ins_data_to_chip (int const voice, int const ins_index) +void CrolPlayer::send_ins_data_to_chip( int const voice, int const ins_index ) { - SRolInstrument & instrument = ins_list[ins_index].instrument; + SRolInstrument &instrument = ins_list[ins_index].instrument; - send_operator (voice, instrument.modulator, instrument.carrier); + send_operator( voice, instrument.modulator, instrument.carrier ); } - //--------------------------------------------------------- -void -CrolPlayer::send_operator (int const voice, SOPL2Op const &modulator, - SOPL2Op const &carrier) +void CrolPlayer::send_operator( int const voice, SOPL2Op const &modulator, SOPL2Op const &carrier ) { - if (voice < kSnareDrumChannel || rol_header->mode) - { - int const op_offset = op_table[voice]; + if( voice < kSnareDrumChannel || rol_header->mode ) + { + int const op_offset = op_table[voice]; - opl->write (0x20 + op_offset, modulator.ammulti); - opl->write (0x40 + op_offset, modulator.ksltl); - opl->write (0x60 + op_offset, modulator.ardr); - opl->write (0x80 + op_offset, modulator.slrr); - opl->write (0xc0 + voice, modulator.fbc); - opl->write (0xe0 + op_offset, modulator.waveform); + opl->write( 0x20+op_offset, modulator.ammulti ); + opl->write( 0x40+op_offset, modulator.ksltl ); + opl->write( 0x60+op_offset, modulator.ardr ); + opl->write( 0x80+op_offset, modulator.slrr ); + opl->write( 0xc0+voice , modulator.fbc ); + opl->write( 0xe0+op_offset, modulator.waveform ); - volumeCache[voice] = (carrier.ksltl & 0xc0) | volumeCache[voice] & 0x3f; + volumeCache[voice] = (carrier.ksltl & 0xc0) | volumeCache[voice] & 0x3f; - opl->write (0x23 + op_offset, carrier.ammulti); - opl->write (0x43 + op_offset, volumeCache[voice]); - opl->write (0x63 + op_offset, carrier.ardr); - opl->write (0x83 + op_offset, carrier.slrr); + opl->write( 0x23+op_offset, carrier.ammulti ); + opl->write( 0x43+op_offset, volumeCache[voice] ); + opl->write( 0x63+op_offset, carrier.ardr ); + opl->write( 0x83+op_offset, carrier.slrr ); // opl->write( 0xc3+voice , carrier.fbc ); <- don't bother writing this. - opl->write (0xe3 + op_offset, carrier.waveform); - } - else - { - int const op_offset = drum_table[voice - kSnareDrumChannel]; + opl->write( 0xe3+op_offset, carrier.waveform ); + } + else + { + int const op_offset = drum_table[voice-kSnareDrumChannel]; - volumeCache[voice] = (modulator.ksltl & 0xc0) | volumeCache[voice] & 0x3f; + volumeCache[voice] = (modulator.ksltl & 0xc0) | volumeCache[voice] & 0x3f; - opl->write (0x20 + op_offset, modulator.ammulti); - opl->write (0x40 + op_offset, volumeCache[voice]); - opl->write (0x60 + op_offset, modulator.ardr); - opl->write (0x80 + op_offset, modulator.slrr); - opl->write (0xc0 + voice, modulator.fbc); - opl->write (0xe0 + op_offset, modulator.waveform); - } + opl->write( 0x20+op_offset, modulator.ammulti ); + opl->write( 0x40+op_offset, volumeCache[voice] ); + opl->write( 0x60+op_offset, modulator.ardr ); + opl->write( 0x80+op_offset, modulator.slrr ); + opl->write( 0xc0+voice , modulator.fbc ); + opl->write( 0xe0+op_offset, modulator.waveform ); + } } - //--------------------------------------------------------- -void -CrolPlayer::load_tempo_events (binistream * f) +void CrolPlayer::load_tempo_events( binistream *f ) { - int16 const num_tempo_events = f->readInt (2); + int16 const num_tempo_events = f->readInt( 2 ); - mTempoEvents.reserve (num_tempo_events); + mTempoEvents.reserve( num_tempo_events ); - for (int i = 0; i < num_tempo_events; ++i) - { - STempoEvent event; + for(int i=0; i<num_tempo_events; ++i) + { + STempoEvent event; - event.time = f->readInt (2); - event.multiplier = f->readFloat (binio::Single); - mTempoEvents.push_back (event); - } + event.time = f->readInt( 2 ); + event.multiplier = f->readFloat( binio::Single ); + mTempoEvents.push_back( event ); + } } - //--------------------------------------------------------- -bool -CrolPlayer::load_voice_data (binistream * f, std::string const &bnk_filename, - const CFileProvider & fp) +bool CrolPlayer::load_voice_data( binistream *f, std::string const &bnk_filename, const CFileProvider &fp ) { - SBnkHeader bnk_header; - VFSFile *fd = vfs_fopen (bnk_filename.c_str (), "rb"); - binistream *bnk_file = fp.open (fd); + SBnkHeader bnk_header; + VFSFile *fd = vfs_fopen(bnk_filename.c_str(), "rb"); + binistream *bnk_file = fp.open(fd); + + if( bnk_file ) + { + load_bnk_info( bnk_file, bnk_header ); + + int const numVoices = rol_header->mode ? kNumMelodicVoices : kNumPercussiveVoices; - if (bnk_file) - { - load_bnk_info (bnk_file, bnk_header); - - int const numVoices = - rol_header->mode ? kNumMelodicVoices : kNumPercussiveVoices; + voice_data.reserve( numVoices ); + for(int i=0; i<numVoices; ++i) + { + CVoiceData voice; - voice_data.reserve (numVoices); - for (int i = 0; i < numVoices; ++i) - { - CVoiceData voice; + load_note_events( f, voice ); + load_instrument_events( f, voice, bnk_file, bnk_header ); + load_volume_events( f, voice ); + load_pitch_events( f, voice ); - load_note_events (f, voice); - load_instrument_events (f, voice, bnk_file, bnk_header); - load_volume_events (f, voice); - load_pitch_events (f, voice); + voice_data.push_back( voice ); + } - voice_data.push_back (voice); + fp.close(bnk_file); + vfs_fclose(fd); + + return true; } - fp.close (bnk_file); - vfs_fclose (fd); - - return true; - } - - return false; + return false; } +//--------------------------------------------------------- +void CrolPlayer::load_note_events( binistream *f, CVoiceData &voice ) +{ + f->seek( 15, binio::Add ); -//--------------------------------------------------------- -void -CrolPlayer::load_note_events (binistream * f, CVoiceData & voice) -{ - f->seek (15, binio::Add); + int16 const time_of_last_note = f->readInt( 2 ); - int16 const time_of_last_note = f->readInt (2); + if( time_of_last_note != 0 ) + { + TNoteEvents ¬e_events = voice.note_events; + int16 total_duration = 0; - if (time_of_last_note != 0) - { - TNoteEvents & note_events = voice.note_events; - int16 total_duration = 0; + do + { + SNoteEvent event; - do - { - SNoteEvent event; + event.number = f->readInt( 2 ); + event.duration = f->readInt( 2 ); - event.number = f->readInt (2); - event.duration = f->readInt (2); - - event.number += kSilenceNote; // adding -12 + event.number += kSilenceNote; // adding -12 - note_events.push_back (event); + note_events.push_back( event ); - total_duration += event.duration; - } while (total_duration < time_of_last_note); + total_duration += event.duration; + } while( total_duration < time_of_last_note ); - if (time_of_last_note > mTimeOfLastNote) - { - mTimeOfLastNote = time_of_last_note; + if( time_of_last_note > mTimeOfLastNote ) + { + mTimeOfLastNote = time_of_last_note; + } } - } - - f->seek (15, binio::Add); -} + f->seek( 15, binio::Add ); +} //--------------------------------------------------------- -void -CrolPlayer::load_instrument_events (binistream * f, CVoiceData & voice, - binistream * bnk_file, - SBnkHeader const &bnk_header) +void CrolPlayer::load_instrument_events( binistream *f, CVoiceData &voice, + binistream *bnk_file, SBnkHeader const &bnk_header ) { - int16 const number_of_instrument_events = f->readInt (2); + int16 const number_of_instrument_events = f->readInt( 2 ); - TInstrumentEvents & instrument_events = voice.instrument_events; + TInstrumentEvents &instrument_events = voice.instrument_events; - instrument_events.reserve (number_of_instrument_events); + instrument_events.reserve( number_of_instrument_events ); - for (int i = 0; i < number_of_instrument_events; ++i) - { - SInstrumentEvent event; - event.time = f->readInt (2); - f->readString (event.name, 9); + for(int i=0; i<number_of_instrument_events; ++i) + { + SInstrumentEvent event; + event.time = f->readInt( 2 ); + f->readString( event.name, 9 ); - std::string event_name = event.name; - event.ins_index = load_rol_instrument (bnk_file, bnk_header, event_name); - - instrument_events.push_back (event); + std::string event_name = event.name; + event.ins_index = load_rol_instrument( bnk_file, bnk_header, event_name ); - f->seek (1 + 2, binio::Add); - } + instrument_events.push_back( event ); - f->seek (15, binio::Add); -} + f->seek( 1+2, binio::Add ); + } + f->seek( 15, binio::Add ); +} //--------------------------------------------------------- -void -CrolPlayer::load_volume_events (binistream * f, CVoiceData & voice) +void CrolPlayer::load_volume_events( binistream *f, CVoiceData &voice ) { - int16 const number_of_volume_events = f->readInt (2); - - TVolumeEvents & volume_events = voice.volume_events; + int16 const number_of_volume_events = f->readInt( 2 ); - volume_events.reserve (number_of_volume_events); + TVolumeEvents &volume_events = voice.volume_events; - for (int i = 0; i < number_of_volume_events; ++i) - { - SVolumeEvent event; - event.time = f->readInt (2); - event.multiplier = f->readFloat (binio::Single); + volume_events.reserve( number_of_volume_events ); - volume_events.push_back (event); - } + for(int i=0; i<number_of_volume_events; ++i) + { + SVolumeEvent event; + event.time = f->readInt( 2 ); + event.multiplier = f->readFloat( binio::Single ); - f->seek (15, binio::Add); + volume_events.push_back( event ); + } + + f->seek( 15, binio::Add ); } - //--------------------------------------------------------- -void -CrolPlayer::load_pitch_events (binistream * f, CVoiceData & voice) +void CrolPlayer::load_pitch_events( binistream *f, CVoiceData &voice ) { - int16 const number_of_pitch_events = f->readInt (2); + int16 const number_of_pitch_events = f->readInt( 2 ); - TPitchEvents & pitch_events = voice.pitch_events; + TPitchEvents &pitch_events = voice.pitch_events; - pitch_events.reserve (number_of_pitch_events); + pitch_events.reserve( number_of_pitch_events ); - for (int i = 0; i < number_of_pitch_events; ++i) - { - SPitchEvent event; - event.time = f->readInt (2); - event.variation = f->readFloat (binio::Single); - - pitch_events.push_back (event); - } -} + for(int i=0; i<number_of_pitch_events; ++i) + { + SPitchEvent event; + event.time = f->readInt( 2 ); + event.variation = f->readFloat( binio::Single ); + pitch_events.push_back( event ); + } +} //--------------------------------------------------------- -bool -CrolPlayer::load_bnk_info (binistream * f, SBnkHeader & header) +bool CrolPlayer::load_bnk_info( binistream *f, SBnkHeader &header ) { - header.version_major = f->readInt (1); - header.version_minor = f->readInt (1); - f->readString (header.signature, 6); + header.version_major = f->readInt(1); + header.version_minor = f->readInt(1); + f->readString( header.signature, 6 ); - header.number_of_list_entries_used = f->readInt (2); - header.total_number_of_list_entries = f->readInt (2); + header.number_of_list_entries_used = f->readInt( 2 ); + header.total_number_of_list_entries = f->readInt( 2 ); - header.abs_offset_of_name_list = f->readInt (4); - header.abs_offset_of_data = f->readInt (4); + header.abs_offset_of_name_list = f->readInt( 4 ); + header.abs_offset_of_data = f->readInt( 4 ); - f->seek (header.abs_offset_of_name_list, binio::Set); + f->seek( header.abs_offset_of_name_list, binio::Set ); - TInstrumentNames & ins_name_list = header.ins_name_list; - ins_name_list.reserve (header.number_of_list_entries_used); + TInstrumentNames &ins_name_list = header.ins_name_list; + ins_name_list.reserve( header.number_of_list_entries_used ); - for (int i = 0; i < header.number_of_list_entries_used; ++i) - { - SInstrumentName instrument; + for(int i=0; i<header.number_of_list_entries_used; ++i) + { + SInstrumentName instrument; - instrument.index = f->readInt (2); - instrument.record_used = f->readInt (1); - f->readString (instrument.name, 9); + instrument.index = f->readInt( 2 ); + instrument.record_used = f->readInt(1); + f->readString( instrument.name, 9 ); - // printf("%s = #%d\n", instrument.name, i ); + // printf("%s = #%d\n", instrument.name, i ); - ins_name_list.push_back (instrument); - } + ins_name_list.push_back( instrument ); + } //std::sort( ins_name_list.begin(), ins_name_list.end(), StringCompare() ); return true; } - //--------------------------------------------------------- -int -CrolPlayer::load_rol_instrument (binistream * f, SBnkHeader const &header, - std::string & name) +int CrolPlayer::load_rol_instrument( binistream *f, SBnkHeader const &header, std::string &name ) { - TInstrumentNames const &ins_name_list = header.ins_name_list; + TInstrumentNames const &ins_name_list = header.ins_name_list; - int const ins_index = get_ins_index (name); + int const ins_index = get_ins_index( name ); - if (ins_index != -1) - { - return ins_index; - } + if( ins_index != -1 ) + { + return ins_index; + } - typedef TInstrumentNames::const_iterator TInsIter; - typedef std::pair < TInsIter, TInsIter > TInsIterPair; + typedef TInstrumentNames::const_iterator TInsIter; + typedef std::pair<TInsIter, TInsIter> TInsIterPair; - TInsIterPair range = std::equal_range (ins_name_list.begin (), - ins_name_list.end (), - name, - StringCompare ()); + TInsIterPair range = std::equal_range( ins_name_list.begin(), + ins_name_list.end(), + name, + StringCompare() ); - if (range.first != range.second) - { - int const seekOffs = - header.abs_offset_of_data + (range.first->index * kSizeofDataRecord); - f->seek (seekOffs, binio::Set); - } + if( range.first != range.second ) + { + int const seekOffs = header.abs_offset_of_data + (range.first->index*kSizeofDataRecord); + f->seek( seekOffs, binio::Set ); + } - SUsedList usedIns; - usedIns.name = name; + SUsedList usedIns; + usedIns.name = name; - if (range.first != range.second) - { - read_rol_instrument (f, usedIns.instrument); - } - else - { - // set up default instrument data here - memset (&usedIns.instrument, 0, kSizeofDataRecord); - } - ins_list.push_back (usedIns); + if( range.first != range.second ) + { + read_rol_instrument( f, usedIns.instrument ); + } + else + { + // set up default instrument data here + memset( &usedIns.instrument, 0, kSizeofDataRecord ); + } + ins_list.push_back( usedIns ); - return ins_list.size () - 1; + return ins_list.size()-1; } - //--------------------------------------------------------- -int -CrolPlayer::get_ins_index (std::string const &name) const const +int CrolPlayer::get_ins_index( std::string const &name ) const { - for (unsigned int i = 0; i < ins_list.size (); ++i) - { - if (stricmp (ins_list[i].name.c_str (), name.c_str ()) == 0) + for(unsigned int i=0; i<ins_list.size(); ++i) { - return i; + if( stricmp(ins_list[i].name.c_str(), name.c_str()) == 0 ) + { + return i; + } } - } - return -1; + return -1; } - //--------------------------------------------------------- -void -CrolPlayer::read_rol_instrument (binistream * f, SRolInstrument & ins) +void CrolPlayer::read_rol_instrument( binistream *f, SRolInstrument &ins ) { - ins.mode = f->readInt (1); - ins.voice_number = f->readInt (1); + ins.mode = f->readInt(1); + ins.voice_number = f->readInt(1); - read_fm_operator (f, ins.modulator); - read_fm_operator (f, ins.carrier); + read_fm_operator( f, ins.modulator ); + read_fm_operator( f, ins.carrier ); - ins.modulator.waveform = f->readInt (1); - ins.carrier.waveform = f->readInt (1); + ins.modulator.waveform = f->readInt(1); + ins.carrier.waveform = f->readInt(1); } - //--------------------------------------------------------- -void -CrolPlayer::read_fm_operator (binistream * f, SOPL2Op & opl2_op) +void CrolPlayer::read_fm_operator( binistream *f, SOPL2Op &opl2_op ) { SFMOperator fm_op; - fm_op.key_scale_level = f->readInt (1); - fm_op.freq_multiplier = f->readInt (1); - fm_op.feed_back = f->readInt (1); - fm_op.attack_rate = f->readInt (1); - fm_op.sustain_level = f->readInt (1); - fm_op.sustaining_sound = f->readInt (1); - fm_op.decay_rate = f->readInt (1); - fm_op.release_rate = f->readInt (1); - fm_op.output_level = f->readInt (1); - fm_op.amplitude_vibrato = f->readInt (1); - fm_op.frequency_vibrato = f->readInt (1); - fm_op.envelope_scaling = f->readInt (1); - fm_op.fm_type = f->readInt (1); + fm_op.key_scale_level = f->readInt(1); + fm_op.freq_multiplier = f->readInt(1); + fm_op.feed_back = f->readInt(1); + fm_op.attack_rate = f->readInt(1); + fm_op.sustain_level = f->readInt(1); + fm_op.sustaining_sound = f->readInt(1); + fm_op.decay_rate = f->readInt(1); + fm_op.release_rate = f->readInt(1); + fm_op.output_level = f->readInt(1); + fm_op.amplitude_vibrato = f->readInt(1); + fm_op.frequency_vibrato = f->readInt(1); + fm_op.envelope_scaling = f->readInt(1); + fm_op.fm_type = f->readInt(1); - opl2_op.ammulti = - fm_op.amplitude_vibrato << 7 | fm_op.frequency_vibrato << 6 | fm_op. - sustaining_sound << 5 | fm_op.envelope_scaling << 4 | fm_op. - freq_multiplier; - opl2_op.ksltl = fm_op.key_scale_level << 6 | fm_op.output_level; - opl2_op.ardr = fm_op.attack_rate << 4 | fm_op.decay_rate; - opl2_op.slrr = fm_op.sustain_level << 4 | fm_op.release_rate; - opl2_op.fbc = fm_op.feed_back << 1 | (fm_op.fm_type ^ 1); + opl2_op.ammulti = fm_op.amplitude_vibrato << 7 | fm_op.frequency_vibrato << 6 | fm_op.sustaining_sound << 5 | fm_op.envelope_scaling << 4 | fm_op.freq_multiplier; + opl2_op.ksltl = fm_op.key_scale_level << 6 | fm_op.output_level; + opl2_op.ardr = fm_op.attack_rate << 4 | fm_op.decay_rate; + opl2_op.slrr = fm_op.sustain_level << 4 | fm_op.release_rate; + opl2_op.fbc = fm_op.feed_back << 1 | (fm_op.fm_type ^ 1); }