2 // midi-event.cc -- implement Midi_event
4 // copyright 1997 Jan Nieuwenhuizen <jan@digicash.com>
9 #include "plist.hh" // all for midi-main.hh
12 #include "sourcefile.hh"
13 #include "midi-main.hh" // *tors
16 #include "midi-event.hh"
18 Midi_event::Midi_event()
22 Midi_event::~Midi_event()
27 Midi_event::mudela_str()
32 Midi_key::Midi_key( int accidentals_i, int minor_i )
34 accidentals_i_ = accidentals_i;
37 key_i_ = ( ( accidentals_i % 7 )[ "cgdaebf" ] - 'a' + 2 ) % 7;
39 key_i_ = ( ( -accidentals_i % 7 )[ "fbeadg" ] - 'a' + 2 ) % 7;
40 mudela_str_ = String( "\\key\\" );
42 mudela_str_ += String( (char)( key_i_ - 2 + 'A' ) );
44 mudela_str_ += String( (char)( key_i_ - 2 + 'a' ) );
48 Midi_key::notename_str( int pitch_i )
50 // this may seem very smart,
51 // but it-s only an excuse not to read a notename table
54 // minor scale: la-la ( = + 5 )
55 static int notename_i_a[ 12 ] = { 0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6 };
56 int notename_i = notename_i_a[ ( minor_i_ * 5 + pitch_i ) % 12 ];
58 static int accidentals_i_a[ 12 ] = { 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0 };
59 int accidental_i = accidentals_i_a[ minor_i_ * 5 + pitch_i % 12 ];
60 if ( accidentals_i_ < 0 ) {
61 accidental_i = - accidental_i;
62 notename_i = ( notename_i + 1 ) % 7;
65 String notename_str = (char)( ( ( notename_i + key_i_ - 2 ) % 7 ) + 'a' );
66 while ( accidental_i-- > 0 )
69 while ( accidental_i++ < 0 )
70 if ( ( notename_str == "a" ) || ( notename_str == "e" ) )
82 Midi_note::Midi_note( Midi_key* midi_key_l, Midi_time* midi_time_l, int clocks_per_whole_i, int pitch_i, Real delta_time_f )
84 mudela_str_ = midi_key_l->notename_str( pitch_i );
85 mudela_str_ += midi_time_l->duration_str( clocks_per_whole_i, delta_time_f );
88 Midi_note::~Midi_note()
92 Midi_tempo::Midi_tempo( int useconds_per_4_i )
94 useconds_per_4_i_ = useconds_per_4_i;
95 seconds_per_1_f_ = (Real)useconds_per_4_i_ * 4 / 1e6;
96 mudela_str_ = "\\Tempo: ";
97 mudela_str_ += String( useconds_per_4_i_ );
98 mudela_str_ += String( ": " )
99 + String( get_tempo_i( Moment( 1, 4 ) ) )
100 + String( " 4 per minute" );
103 Midi_tempo::~Midi_tempo()
108 Midi_tempo::get_tempo_i( Moment moment )
110 return Moment( 60 ) / moment / Moment( seconds_per_1_f_ );
113 Midi_time::Midi_time( int num_i, int den_i, int clocks_i, int count_32_i )
115 // we should warn, at least!
116 // assert( count_32_i == 8 );
117 if ( count_32_i != 8 )
118 warning( String( "#32 in quarter: " ) + String( count_32_i ), 0 );
121 // huh?, see midiitem.cc; reasonably for fugue1.midi
122 // whole_clocks_i_ = clocks_i * 4 * 10;
123 whole_clocks_i_ = clocks_i * 4;
124 // whole_clocks_i_ = clocks_i;
125 mudela_str_ = "\\Time: ";
126 mudela_str_ += String( num_i_ ) + "/" + String( den_i_ )
127 + ", " + String( whole_clocks_i_ )
128 + ": " + String( count_32_i );
131 Midi_time::~Midi_time()
136 Midi_time::duration_str( int clocks_per_whole_i, Real delta_time_f )
138 dtor << "(" << delta_time_f;
141 Moment delta_time_moment = 1.0;
142 if ( delta_time_f ) {
145 // 24/96*.25 = 0.0625
146 // delta_time_moment = Moment( delta_time_f ) / Moment( whole_clocks_i() );
147 if ( clocks_per_whole_i > 0 )
148 delta_time_moment = Moment( delta_time_f ) / Moment( clocks_per_whole_i );
150 delta_time_moment = Moment( -clocks_per_whole_i ) / Moment( delta_time_f );
153 dtor << ", " << (Real)delta_time_moment << "): ";
155 static Real sync_f = 1;
156 delta_time_moment = delta_time_moment / sync_f;
160 && ( abs( modf( (Real)delta_time_moment / ( (Real)1 / 64 / 3 ), &dummy_f ) ) ) > 1e-6 ) {
161 sync_f = (Real)delta_time_moment / 0.125;
162 delta_time_moment = (Real)delta_time_moment / sync_f;
163 mtor << "\nsyncing: " << sync_f << ", "
164 // << (Real)sync_f / usecond24th_per_clock_i << endl;
165 << (Real)whole_clocks_i() << endl;
168 static bool must_resync_bo = false;
169 if ( ( (Real)delta_time_moment / 0.125 > 16 )
170 || ( (Real)delta_time_moment / 0.125 < ( (Real)1 / 16 ) ) )
171 must_resync_bo = true;
173 if ( must_resync_bo ) {
174 must_resync_bo = false;
175 delta_time_moment = delta_time_moment * sync_f;
176 sync_f = (Real)delta_time_moment / 0.125;
177 delta_time_moment = (Real)delta_time_moment / sync_f;
178 mtor << "\nresyncing: " << sync_f << ", "
179 // << (Real)sync_f / usecond24th_per_clock_i << endl;
180 << (Real)whole_clocks_i() << endl;
183 if ( !delta_time_moment )
186 // output of modf: double
187 double duration_f = 0;
188 Real rest_f = modf( ( Moment( 1 ) / delta_time_moment ), &duration_f );
192 // output of modf: double
194 Real dots_rest_f = modf( rest_f * 3, &dots_f );
196 dots_i = (int)rint( dots_f );
197 else if ( abs( dots_rest_f - rint( dots_rest_f ) ) < 1e-8 )
198 dots_i = (int)rint( dots_rest_f );
200 else if ( !modf( (Real)3 * delta_time_moment / 2, &duration_f ) )
203 else if ( !modf( (Real)6 * delta_time_moment / 2, &duration_f ) )
206 // str += String( "\n*" ) + String( (int)( 1 / rest_f ) );
207 str += String( "\n*" ) + String( rest_f );
208 must_resync_bo = true;
213 for ( int i = dots_i; i ; i-- )
214 delta_time_moment *= (Real)2 / 3;
215 modf( ( Moment( 1 ) / delta_time_moment ), &duration_f );
218 str += String( (int)( duration_f ) );
220 str += String( '.', dots_i );
222 str += String( "/" ) + String( plet_type_i );
228 Midi_time::whole_clocks_i()
230 return whole_clocks_i_;