2 * Adplug - Replayer for many OPL2/OPL3 audio file formats.
3 * Copyright (C) 1999 - 2006 Simon Peter, <dn.tlp@gmx.net>, et al.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 * rol.h - ROL Player by OPLx <oplx@yahoo.com>
21 * Visit: http://tenacity.hispeed.com/aomit/oplx/
29 int const CrolPlayer::kSizeofDataRecord = 30;
30 int const CrolPlayer::kMaxTickBeat = 60;
31 int const CrolPlayer::kSilenceNote = -12;
32 int const CrolPlayer::kNumMelodicVoices = 9;
33 int const CrolPlayer::kNumPercussiveVoices = 11;
34 int const CrolPlayer::kBassDrumChannel = 6;
35 int const CrolPlayer::kSnareDrumChannel = 7;
36 int const CrolPlayer::kTomtomChannel = 8;
37 int const CrolPlayer::kTomtomFreq = 2;//4;
38 int const CrolPlayer::kSnareDrumFreq = 2;//kTomtomFreq + 7;
39 float const CrolPlayer::kDefaultUpdateTme = 18.2f;
40 float const CrolPlayer::kPitchFactor = 400.0f;
42 static const unsigned char drum_table[4] = {0x14, 0x12, 0x15, 0x11};
44 CrolPlayer::uint16 const CrolPlayer::kNoteTable[12] =
60 /*** public methods **************************************/
62 CPlayer *CrolPlayer::factory(Copl *newopl)
64 return new CrolPlayer(newopl);
66 //---------------------------------------------------------
67 CrolPlayer::CrolPlayer(Copl *newopl)
70 ,mNextTempoEvent ( 0 )
72 ,mTimeOfLastNote ( 0 )
73 ,mRefresh ( kDefaultUpdateTme )
78 memset(bxRegister, 0, sizeof(bxRegister) );
79 memset(volumeCache, 0, sizeof(volumeCache) );
80 memset(freqCache, 0, sizeof(freqCache) );
85 //---------------------------------------------------------
86 CrolPlayer::~CrolPlayer()
88 if( rol_header != NULL )
94 //---------------------------------------------------------
95 bool CrolPlayer::load(const std::string &filename, const CFileProvider &fp)
97 binistream *f = fp.open(filename); if(!f) return false;
99 char *fn = new char[filename.length()+12];
101 std::string bnk_filename;
103 AdPlug_LogWrite("*** CrolPlayer::load(f, \"%s\") ***\n", filename.c_str());
104 strcpy(fn,filename.data());
105 for (i=strlen(fn)-1; i>=0; i--)
106 if (fn[i] == '/' || fn[i] == '\\')
108 strcpy(fn+i+1,"standard.bnk");
111 AdPlug_LogWrite("bnk_filename = \"%s\"\n",bnk_filename.c_str());
113 rol_header = new SRolHeader;
114 memset( rol_header, 0, sizeof(SRolHeader) );
116 rol_header->version_major = f->readInt( 2 );
117 rol_header->version_minor = f->readInt( 2 );
120 if(rol_header->version_major != 0 || rol_header->version_minor != 4) {
121 AdPlug_LogWrite("Unsupported file version %d.%d or not a ROL file!\n",
122 rol_header->version_major, rol_header->version_minor);
123 AdPlug_LogWrite("--- CrolPlayer::load ---\n");
128 f->seek( 40, binio::Add );
130 rol_header->ticks_per_beat = f->readInt( 2 );
131 rol_header->beats_per_measure = f->readInt( 2 );
132 rol_header->edit_scale_y = f->readInt( 2 );
133 rol_header->edit_scale_x = f->readInt( 2 );
135 f->seek( 1, binio::Add );
137 rol_header->mode = f->readInt(1);
139 f->seek( 90+38+15, binio::Add );
141 rol_header->basic_tempo = f->readFloat( binio::Single );
143 load_tempo_events( f );
147 if( load_voice_data( f, bnk_filename, fp ) != true )
149 AdPlug_LogWrite("CrolPlayer::load_voice_data(f) failed!\n");
150 AdPlug_LogWrite("--- CrolPlayer::load ---\n");
159 AdPlug_LogWrite("--- CrolPlayer::load ---\n");
162 //---------------------------------------------------------
163 bool CrolPlayer::update()
165 if( mNextTempoEvent < mTempoEvents.size() &&
166 mTempoEvents[mNextTempoEvent].time == mCurrTick )
168 SetRefresh( mTempoEvents[mNextTempoEvent].multiplier );
172 TVoiceData::iterator curr = voice_data.begin();
173 TVoiceData::iterator end = voice_data.end();
178 UpdateVoice( voice, *curr );
185 if( mCurrTick > mTimeOfLastNote )
191 //return ( mCurrTick > mTimeOfLastNote ) ? false : true;
193 //---------------------------------------------------------
194 void CrolPlayer::rewind( int subsong )
196 TVoiceData::iterator curr = voice_data.begin();
197 TVoiceData::iterator end = voice_data.end();
201 CVoiceData &voice = *curr;
207 memset(bxRegister, 0, sizeof(bxRegister) );
208 memset(volumeCache, 0, sizeof(volumeCache) );
212 opl->init(); // initialize to melodic by default
213 opl->write(1,0x20); // Enable waveform select (bit 5)
215 if( rol_header->mode == 0 )
217 opl->write( 0xbd, 0x20 ); // select rhythm mode (bit 5)
220 SetFreq( kTomtomChannel, 24 );
221 SetFreq( kSnareDrumChannel, 31 );
229 //---------------------------------------------------------
230 inline float fmin( int const a, int const b )
232 return static_cast<float>( a < b ? a : b );
234 //---------------------------------------------------------
235 void CrolPlayer::SetRefresh( float const multiplier )
237 float const tickBeat = fmin(kMaxTickBeat, rol_header->ticks_per_beat);
239 mRefresh = (tickBeat*rol_header->basic_tempo*multiplier) / 60.0f;
241 //---------------------------------------------------------
242 float CrolPlayer::getrefresh()
246 //---------------------------------------------------------
247 void CrolPlayer::UpdateVoice( int const voice, CVoiceData &voiceData )
249 TNoteEvents const &nEvents = voiceData.note_events;
251 if( nEvents.empty() || voiceData.mEventStatus & CVoiceData::kES_NoteEnd )
253 return; // no note data to process, don't bother doing anything.
256 TInstrumentEvents &iEvents = voiceData.instrument_events;
257 TVolumeEvents &vEvents = voiceData.volume_events;
258 TPitchEvents &pEvents = voiceData.pitch_events;
260 if( !(voiceData.mEventStatus & CVoiceData::kES_InstrEnd ) &&
261 iEvents[voiceData.next_instrument_event].time == mCurrTick )
263 if( voiceData.next_instrument_event < iEvents.size() )
265 send_ins_data_to_chip( voice, iEvents[voiceData.next_instrument_event].ins_index );
266 ++voiceData.next_instrument_event;
270 voiceData.mEventStatus |= CVoiceData::kES_InstrEnd;
274 if( !(voiceData.mEventStatus & CVoiceData::kES_VolumeEnd ) &&
275 vEvents[voiceData.next_volume_event].time == mCurrTick )
277 SVolumeEvent const &volumeEvent = vEvents[voiceData.next_volume_event];
279 if( voiceData.next_volume_event < vEvents.size() )
281 int const volume = (int)(63.0f*(1.0f - volumeEvent.multiplier));
283 SetVolume( voice, volume );
285 ++voiceData.next_volume_event; // move to next volume event
289 voiceData.mEventStatus |= CVoiceData::kES_VolumeEnd;
293 if( voiceData.mForceNote || voiceData.current_note_duration > voiceData.mNoteDuration-1 )
297 ++voiceData.current_note;
300 if( voiceData.current_note < nEvents.size() )
302 SNoteEvent const ¬eEvent = nEvents[voiceData.current_note];
304 SetNote( voice, noteEvent.number );
305 voiceData.current_note_duration = 0;
306 voiceData.mNoteDuration = noteEvent.duration;
307 voiceData.mForceNote = false;
311 SetNote( voice, kSilenceNote );
312 voiceData.mEventStatus |= CVoiceData::kES_NoteEnd;
317 if( !(voiceData.mEventStatus & CVoiceData::kES_PitchEnd ) &&
318 pEvents[voiceData.next_pitch_event].time == mCurrTick )
320 if( voiceData.next_pitch_event < pEvents.size() )
322 SetPitch(voice,pEvents[voiceData.next_pitch_event].variation);
323 ++voiceData.next_pitch_event;
327 voiceData.mEventStatus |= CVoiceData::kES_PitchEnd;
331 ++voiceData.current_note_duration;
333 //---------------------------------------------------------
334 void CrolPlayer::SetNote( int const voice, int const note )
336 if( voice < kBassDrumChannel || rol_header->mode )
338 SetNoteMelodic( voice, note );
342 SetNotePercussive( voice, note );
345 //---------------------------------------------------------
346 void CrolPlayer::SetNotePercussive( int const voice, int const note )
348 int const bit_pos = 4-voice+kBassDrumChannel;
350 bdRegister &= ~( 1<<bit_pos );
351 opl->write( 0xbd, bdRegister );
353 if( note != kSilenceNote )
358 SetFreq( kSnareDrumChannel, note+7 );
359 case kBassDrumChannel:
360 SetFreq( voice, note );
364 bdRegister |= 1<<bit_pos;
365 opl->write( 0xbd, bdRegister );
368 //---------------------------------------------------------
369 void CrolPlayer::SetNoteMelodic( int const voice, int const note )
371 opl->write( 0xb0+voice, bxRegister[voice] & ~0x20 );
373 if( note != kSilenceNote )
375 SetFreq( voice, note, true );
378 //---------------------------------------------------------
379 void CrolPlayer::SetPitch(int const voice, real32 const variation)
381 pitchCache[voice] = variation;
382 freqCache[voice] += (uint16)((((float)freqCache[voice])*(variation-1.0f)) / kPitchFactor);
384 opl->write(0xa0+voice,freqCache[voice] & 0xff);
386 //---------------------------------------------------------
387 void CrolPlayer::SetFreq( int const voice, int const note, bool const keyOn )
389 uint16 freq = kNoteTable[note%12] + ((note/12) << 10);
390 freq += (uint16)((((float)freq)*(pitchCache[voice]-1.0f))/kPitchFactor);
392 freqCache[voice] = freq;
393 bxRegister[voice] = ((freq >> 8) & 0x1f);
395 opl->write( 0xa0+voice, freq & 0xff );
396 opl->write( 0xb0+voice, bxRegister[voice] | (keyOn ? 0x20 : 0x0) );
398 //---------------------------------------------------------
399 void CrolPlayer::SetVolume( int const voice, int const volume )
401 volumeCache[voice] = (volumeCache[voice] &0xc0) | volume;
403 int const op_offset = ( voice < kSnareDrumChannel || rol_header->mode ) ?
404 op_table[voice]+3 : drum_table[voice-kSnareDrumChannel];
406 opl->write( 0x40+op_offset, volumeCache[voice] );
408 //---------------------------------------------------------
409 void CrolPlayer::send_ins_data_to_chip( int const voice, int const ins_index )
411 SRolInstrument &instrument = ins_list[ins_index].instrument;
413 send_operator( voice, instrument.modulator, instrument.carrier );
415 //---------------------------------------------------------
416 void CrolPlayer::send_operator( int const voice, SOPL2Op const &modulator, SOPL2Op const &carrier )
418 if( voice < kSnareDrumChannel || rol_header->mode )
420 int const op_offset = op_table[voice];
422 opl->write( 0x20+op_offset, modulator.ammulti );
423 opl->write( 0x40+op_offset, modulator.ksltl );
424 opl->write( 0x60+op_offset, modulator.ardr );
425 opl->write( 0x80+op_offset, modulator.slrr );
426 opl->write( 0xc0+voice , modulator.fbc );
427 opl->write( 0xe0+op_offset, modulator.waveform );
429 volumeCache[voice] = (carrier.ksltl & 0xc0) | volumeCache[voice] & 0x3f;
431 opl->write( 0x23+op_offset, carrier.ammulti );
432 opl->write( 0x43+op_offset, volumeCache[voice] );
433 opl->write( 0x63+op_offset, carrier.ardr );
434 opl->write( 0x83+op_offset, carrier.slrr );
435 // opl->write( 0xc3+voice , carrier.fbc ); <- don't bother writing this.
436 opl->write( 0xe3+op_offset, carrier.waveform );
440 int const op_offset = drum_table[voice-kSnareDrumChannel];
442 volumeCache[voice] = (modulator.ksltl & 0xc0) | volumeCache[voice] & 0x3f;
444 opl->write( 0x20+op_offset, modulator.ammulti );
445 opl->write( 0x40+op_offset, volumeCache[voice] );
446 opl->write( 0x60+op_offset, modulator.ardr );
447 opl->write( 0x80+op_offset, modulator.slrr );
448 opl->write( 0xc0+voice , modulator.fbc );
449 opl->write( 0xe0+op_offset, modulator.waveform );
452 //---------------------------------------------------------
453 void CrolPlayer::load_tempo_events( binistream *f )
455 int16 const num_tempo_events = f->readInt( 2 );
457 mTempoEvents.reserve( num_tempo_events );
459 for(int i=0; i<num_tempo_events; ++i)
463 event.time = f->readInt( 2 );
464 event.multiplier = f->readFloat( binio::Single );
465 mTempoEvents.push_back( event );
468 //---------------------------------------------------------
469 bool CrolPlayer::load_voice_data( binistream *f, std::string const &bnk_filename, const CFileProvider &fp )
471 SBnkHeader bnk_header;
472 binistream *bnk_file = fp.open( bnk_filename.c_str() );
476 load_bnk_info( bnk_file, bnk_header );
478 int const numVoices = rol_header->mode ? kNumMelodicVoices : kNumPercussiveVoices;
480 voice_data.reserve( numVoices );
481 for(int i=0; i<numVoices; ++i)
485 load_note_events( f, voice );
486 load_instrument_events( f, voice, bnk_file, bnk_header );
487 load_volume_events( f, voice );
488 load_pitch_events( f, voice );
490 voice_data.push_back( voice );
500 //---------------------------------------------------------
501 void CrolPlayer::load_note_events( binistream *f, CVoiceData &voice )
503 f->seek( 15, binio::Add );
505 int16 const time_of_last_note = f->readInt( 2 );
507 if( time_of_last_note != 0 )
509 TNoteEvents ¬e_events = voice.note_events;
510 int16 total_duration = 0;
516 event.number = f->readInt( 2 );
517 event.duration = f->readInt( 2 );
519 event.number += kSilenceNote; // adding -12
521 note_events.push_back( event );
523 total_duration += event.duration;
524 } while( total_duration < time_of_last_note );
526 if( time_of_last_note > mTimeOfLastNote )
528 mTimeOfLastNote = time_of_last_note;
532 f->seek( 15, binio::Add );
534 //---------------------------------------------------------
535 void CrolPlayer::load_instrument_events( binistream *f, CVoiceData &voice,
536 binistream *bnk_file, SBnkHeader const &bnk_header )
538 int16 const number_of_instrument_events = f->readInt( 2 );
540 TInstrumentEvents &instrument_events = voice.instrument_events;
542 instrument_events.reserve( number_of_instrument_events );
544 for(int i=0; i<number_of_instrument_events; ++i)
546 SInstrumentEvent event;
547 event.time = f->readInt( 2 );
548 f->readString( event.name, 9 );
550 std::string event_name = event.name;
551 event.ins_index = load_rol_instrument( bnk_file, bnk_header, event_name );
553 instrument_events.push_back( event );
555 f->seek( 1+2, binio::Add );
558 f->seek( 15, binio::Add );
560 //---------------------------------------------------------
561 void CrolPlayer::load_volume_events( binistream *f, CVoiceData &voice )
563 int16 const number_of_volume_events = f->readInt( 2 );
565 TVolumeEvents &volume_events = voice.volume_events;
567 volume_events.reserve( number_of_volume_events );
569 for(int i=0; i<number_of_volume_events; ++i)
572 event.time = f->readInt( 2 );
573 event.multiplier = f->readFloat( binio::Single );
575 volume_events.push_back( event );
578 f->seek( 15, binio::Add );
580 //---------------------------------------------------------
581 void CrolPlayer::load_pitch_events( binistream *f, CVoiceData &voice )
583 int16 const number_of_pitch_events = f->readInt( 2 );
585 TPitchEvents &pitch_events = voice.pitch_events;
587 pitch_events.reserve( number_of_pitch_events );
589 for(int i=0; i<number_of_pitch_events; ++i)
592 event.time = f->readInt( 2 );
593 event.variation = f->readFloat( binio::Single );
595 pitch_events.push_back( event );
598 //---------------------------------------------------------
599 bool CrolPlayer::load_bnk_info( binistream *f, SBnkHeader &header )
601 header.version_major = f->readInt(1);
602 header.version_minor = f->readInt(1);
603 f->readString( header.signature, 6 );
605 header.number_of_list_entries_used = f->readInt( 2 );
606 header.total_number_of_list_entries = f->readInt( 2 );
608 header.abs_offset_of_name_list = f->readInt( 4 );
609 header.abs_offset_of_data = f->readInt( 4 );
611 f->seek( header.abs_offset_of_name_list, binio::Set );
613 TInstrumentNames &ins_name_list = header.ins_name_list;
614 ins_name_list.reserve( header.number_of_list_entries_used );
616 for(int i=0; i<header.number_of_list_entries_used; ++i)
618 SInstrumentName instrument;
620 instrument.index = f->readInt( 2 );
621 instrument.record_used = f->readInt(1);
622 f->readString( instrument.name, 9 );
624 // printf("%s = #%d\n", instrument.name, i );
626 ins_name_list.push_back( instrument );
629 //std::sort( ins_name_list.begin(), ins_name_list.end(), StringCompare() );
633 //---------------------------------------------------------
634 int CrolPlayer::load_rol_instrument( binistream *f, SBnkHeader const &header, std::string &name )
636 TInstrumentNames const &ins_name_list = header.ins_name_list;
638 int const ins_index = get_ins_index( name );
640 if( ins_index != -1 )
645 typedef TInstrumentNames::const_iterator TInsIter;
646 typedef std::pair<TInsIter, TInsIter> TInsIterPair;
648 TInsIterPair range = std::equal_range( ins_name_list.begin(),
653 if( range.first != range.second )
655 int const seekOffs = header.abs_offset_of_data + (range.first->index*kSizeofDataRecord);
656 f->seek( seekOffs, binio::Set );
662 if( range.first != range.second )
664 read_rol_instrument( f, usedIns.instrument );
668 // set up default instrument data here
669 memset( &usedIns.instrument, 0, sizeof(SRolInstrument) );
671 ins_list.push_back( usedIns );
673 return ins_list.size()-1;
675 //---------------------------------------------------------
676 int CrolPlayer::get_ins_index( std::string const &name ) const
678 for(unsigned int i=0; i<ins_list.size(); ++i)
680 if( stricmp(ins_list[i].name.c_str(), name.c_str()) == 0 )
688 //---------------------------------------------------------
689 void CrolPlayer::read_rol_instrument( binistream *f, SRolInstrument &ins )
691 ins.mode = f->readInt(1);
692 ins.voice_number = f->readInt(1);
694 read_fm_operator( f, ins.modulator );
695 read_fm_operator( f, ins.carrier );
697 ins.modulator.waveform = f->readInt(1);
698 ins.carrier.waveform = f->readInt(1);
700 //---------------------------------------------------------
701 void CrolPlayer::read_fm_operator( binistream *f, SOPL2Op &opl2_op )
705 fm_op.key_scale_level = f->readInt(1);
706 fm_op.freq_multiplier = f->readInt(1);
707 fm_op.feed_back = f->readInt(1);
708 fm_op.attack_rate = f->readInt(1);
709 fm_op.sustain_level = f->readInt(1);
710 fm_op.sustaining_sound = f->readInt(1);
711 fm_op.decay_rate = f->readInt(1);
712 fm_op.release_rate = f->readInt(1);
713 fm_op.output_level = f->readInt(1);
714 fm_op.amplitude_vibrato = f->readInt(1);
715 fm_op.frequency_vibrato = f->readInt(1);
716 fm_op.envelope_scaling = f->readInt(1);
717 fm_op.fm_type = f->readInt(1);
719 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;
720 opl2_op.ksltl = fm_op.key_scale_level << 6 | fm_op.output_level;
721 opl2_op.ardr = fm_op.attack_rate << 4 | fm_op.decay_rate;
722 opl2_op.slrr = fm_op.sustain_level << 4 | fm_op.release_rate;
723 opl2_op.fbc = fm_op.feed_back << 1 | (fm_op.fm_type ^ 1);