/**************************************************************************** PROJECT: MusixTeX PreProcessor FILE : staff.cc AUTHOR : J. C. Nieuwenhuizen copyright (c) FlowerSoft 1995 --*/ #define max( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) ) #define min( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) #include //#incluce // exit #include "init.h" #include "key.h" #include "bar.h" #include "interval.h" #include "beam.h" #include "slur.h" #include "note.h" #include "duration.h" #include "imacro.h" #include "staff.h" #include "mpp.h" //const int STAFF_MAX = 9; /**************************************************************************** class Staff --*/ int Staff::barCount = 0; //int Staff::beamCount = - 1; int Staff::barDuration = 0; int Staff::changeContext = 0; int Staff::newBarDuration = 0; int Staff::newLine = 0; int Staff::instrumentCount = 0; //int Staff::slurCount = - 1; int Staff::count = 0; Staff* Staff::staffs[ STAFF_MAX ] = { // STAFF_MAX should be initted dynamically ZEROSTAFF, ZEROSTAFF, ZEROSTAFF, ZEROSTAFF, ZEROSTAFF, ZEROSTAFF, ZEROSTAFF, ZEROSTAFF, ZEROSTAFF }; /* Wow! talk about construction.. */ Staff::Staff( const char* name, int i ) : // filename, count of staff // should these be list ? bar( 0 ), beam( ZEROBEAM ), beamCount( 0 ), duration( 0 ), inName( name ), instrumentStaff( i ), is( 0 ), key( 0 ), lastDuration( 0 ), leftOver( 0 ), // reset each bar ? line( 0 ), // pitch of b, assume treble key midPitch( ( 'b' - 'c' + 7 ) % 7 + 4 * 7 ), newKey( 0 ), notes( 0 ), number( count++ ), octavate( 0 ), // should these be list ? slur( ZEROSLUR ), slurCount( 0 ), sourceFile( 0 ), style( 0 ), transpose( 0 ), transposedFrom( 0 ), xDuration( 4 ) { if ( ( number >= 0 ) && ( number < STAFF_MAX ) && ( Staff::staffs[ number ] == ZEROSTAFF ) ) Staff::staffs[ number ] = this; else warning( "something's wrong with Staff::staffs" ); // error() ? if ( !instrumentStaff ) instrumentNumber = ++instrumentCount - 1; else instrumentNumber = instrumentCount - 1; if ( !inName.len() || ( inName[ 0 ] == '-' ) ) { // ::error( "input from stdin not implemented", __FILE__, __LINE__ ); inName = "stdin"; sourceFile = &_cin; } else sourceFile = new ifstream( (const char*)inName ); if ( !*sourceFile ) error( quoteString( "can't open", inName ) ); cout << (const char*)inName << ':' << endl; sourceFile->flags( sourceFile->flags() & ~ios::skipws ); is = sourceFile; if ( (key = &(Key&)macroList.firstMacro( Token::compare, "C" ) ) == ZERO ) error( quoteString( "key not found", "C" ) ); key->execute( (StringList&)NOOBJECT, *this ); } Staff::~Staff() { // if ( sourceFile ) // delete sourceFile; if ( bar ) delete bar; if ( notes ) delete notes; } void Staff::calculate() { ;// monitor << "Staff::calculate" << endl; if ( bar ) bar->calculate(); } //void Staff::error( const char* s, const char* file, const int line ) const void Staff::error( const char* s ) const { // ::error( s, file, line ); ::error( s, ( inName.len() ? (const char*)inName : __FILE__ ), ( inName.len() ? line : __LINE__ ) ); } //void Staff::warning( const char* s, const char* file, const int line ) const void Staff::warning( const char* s ) const { // ::warning( s, file, line ); ::warning( s, ( inName.len() ? (const char*)inName : __FILE__ ), ( inName.len() ? line : __LINE__ ) ); } void Staff::expect( char c ) { if ( c != is->peek() ) error( String( quoteChar( "", c ) ) + "' expected" ); } /* disposes of old bar, reads a new bar */ int Staff::getBar() { if ( !line ) line = 1; if ( bar ) { delete bar; bar = 0; } if ( notes ) { delete notes; notes = 0; } noteCount = 0; bar = new Bar( *this ); // INPUT notes = new BarIterator( *bar ); lastDuration = 0; ;// monitor << "leaving Staff::getBar" << endl; return 0; } void Staff::doMacros( ostream& os ) { if ( !line ) line = 1; MacroList macroList( *this ); // INPUT os << macroList; } int Staff::getDuration() { ;// monitor << "Staff::getDuration" << endl; if ( leftOver < 0 ) // < 0, > 0 ? return leftOver; // current beat has progressed far enough, // we could output a new note Note& note = (*notes)(); if ( note != NOOBJECT ) return note.duration(); else return 0; // superfluous? } //this is longhand for Duration( 8 ).duration() static Duration duration8( 8 ); static int spacing8 = duration8.duration(); /* space needed for current note */ int Staff::getSpacing( int lastSpacing ) { ;// monitor << "Staff::getSpacing: " << number << endl; ;// monitor << lastSpacing << "," << lastDuration; ;// monitor << ":" << ( ( lastSpacing == lastDuration ) && ( lastSpacing < spacing8 ) ); Note& note = (*notes)(); if ( note != NOOBJECT ) return note.spacing( ( ( lastSpacing == lastDuration ) && ( lastSpacing < spacing8 ) ) ); else return 0; } /* INPUT: an interval of notes RETURN: width (hor) of the notes in the supplied interval. needed for spacing beams correctly */ int Staff::noteCount2NoteSkip( const Interval& note ) const // note is not a Note! { int noteSkip = 0; Interval& duration = bar->noteCount2Duration( note ); for ( int i = 0; i < count; i++ ) noteSkip = max( noteSkip, ( staffs[ i ] )->bar->duration2NoteSkip( duration ) ); delete &duration; return noteSkip; } /* INPUT os: output stream d: duration. try to print notes fitting in a duration d on os */ void Staff::printDuration( ostream& os, const int d ) { ;// monitor << "Staff::printDuration" << endl; // leftover: how much the staff can print // d: how much the score allows staff to print int duration = d + leftOver; Staff::duration += duration; // getting further in measure leftOver = 0; // superfluous if ( duration < 0 ) os << "\\sk"; while ( ( duration > 0 ) && (int)(*notes) ) // still notes, still room for more notes { Note& note = (*notes)++; lastDuration = note.duration(); // lastdur. is member duration -= lastDuration; os << note << '%' << endl; } leftOver = duration; //moved because reversed order if ( instrumentStaff ) // next staff of this instrument os << '|'; else if ( instrumentNumber ) os << '&'; Staff::duration -= leftOver; // return max( 0, duration ); } void Staff::printMacros( ostream& os ) { ;// monitor << "Staff::printMacros" << endl; Note& note = (*notes)(); if ( note != NOOBJECT ) os << note.macroList; } // superfluous void Staff::printOn( ostream& os ) const { os << "Staff"; } void Staff::printSpacing( ostream& os, const int spacing ) { for ( int i = 0; i < spacing; i++ ) os << "\\smallsk"; // smallest space we can use. } //-- class Staff //