00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "jdkmidi/world.h"
00035 #include "jdkmidi/smpte.h"
00036
00037 #ifndef DEBUG_MDSMPTE
00038 # define DEBUG_MDSMPTE 0
00039 #endif
00040
00041 #if DEBUG_MDSMPTE
00042 # undef DBG
00043 # define DBG(a) a
00044 #else
00045 # undef DBG
00046 # define DBG(a)
00047 #endif
00048
00049 namespace jdkmidi
00050 {
00051
00052 const uchar smpte_max_frames[] =
00053 {
00054 24, 25, 30, 30, 30, 30
00055 };
00056
00057 const double smpte_smpte_rates[] =
00058 {
00059 24.0,
00060 25.0,
00061 29.97,
00062 29.97,
00063 30.0,
00064 30.0
00065 };
00066
00067 const double smpte_smpte_rates_long[] =
00068 {
00069 2400,
00070 2500,
00071 2997,
00072 2997,
00073 3000,
00074 3000
00075 };
00076
00077
00078 const double smpte_sample_rates[] =
00079 {
00080 32000.0,
00081 44055.9,
00082 44100.0,
00083 47952.0,
00084 48000.0,
00085 48048.0
00086 };
00087
00088 const long smpte_sample_rates_long[] =
00089 {
00090 320000,
00091 440559,
00092 441000,
00093 479520,
00094 480000,
00095 480480
00096 };
00097
00098
00099
00100 SMPTE::SMPTE(
00101 SMPTE_RATE smpte_rate_,
00102 SAMPLE_RATE sample_rate_
00103 )
00104 :
00105 smpte_rate( smpte_rate_ ),
00106 sample_rate( sample_rate_ ),
00107 sample_number( 0 ),
00108 hours(0),
00109 minutes(0),
00110 seconds(0),
00111 frames(0),
00112 sub_frames(0),
00113 sample_number_dirty(false)
00114 {
00115
00116 }
00117
00118
00119
00120 SMPTE::SMPTE(
00121 const SMPTE & s
00122 )
00123 {
00124 Copy(s);
00125 }
00126
00127
00128
00129
00130
00131 void SMPTE::AddHours( char h )
00132 {
00133 AddSamples( GetSampleRateLong()
00134 * h *
00135 ( 60
00136 * 60
00137 / 10
00138 )
00139 );
00140 }
00141
00142
00143 void SMPTE::AddMinutes( char m )
00144 {
00145 AddSamples(
00146 GetSampleRateLong()
00147 * m *
00148 ( 60
00149 / 10 )
00150 );
00151 }
00152
00153
00154 void SMPTE::AddSeconds( char s )
00155 {
00156 AddSamples(
00157 GetSampleRateLong()
00158 * s
00159 / 10
00160 );
00161 }
00162
00163
00164 void SMPTE::AddFrames( char f )
00165 {
00166 AddSamples(
00167 GetSampleRateLong()
00168 * f
00169 * 10
00170 / GetSMPTERateLong()
00171 );
00172 }
00173
00174
00175 void SMPTE::AddSubFrames( char sf )
00176 {
00177 AddSamples(
00178 GetSampleRateLong()
00179 * sf
00180 / GetSMPTERateLong()
00181 / 10
00182 );
00183 }
00184
00185
00186
00187 void SMPTE::SampleToTime()
00188 {
00189
00190
00191
00192
00193 ulong tmp_sample=sample_number;
00194
00195
00196
00197
00198
00199
00200 double the_smpte_rate = smpte_smpte_rates[ smpte_rate ];
00201 double the_sample_rate = smpte_sample_rates[ sample_rate ];
00202
00203
00204
00205
00206
00207 uchar max_frame = smpte_max_frames[ smpte_rate ];
00208
00209
00210
00211
00212
00213 double samples_per_frame=smpte_sample_rates[ sample_rate ] / smpte_smpte_rates[ smpte_rate ];
00214
00215
00216
00217
00218
00219
00220 if( smpte_rate==SMPTE_RATE_30DF || smpte_rate==SMPTE_RATE_2997DF )
00221 {
00222
00223
00224
00225
00226
00227 int num_minutes = tmp_sample/(48000*60);
00228
00229 DBG( printf( "num_minutes=%d\n", (int)num_minutes ) );
00230
00231
00232
00233
00234
00235 int ten_minutes = num_minutes/10;
00236
00237 DBG( printf( "ten_minutes=%d\n", (int)ten_minutes) );
00238
00239
00240
00241
00242
00243
00244 int drops=(num_minutes - ten_minutes)*2;
00245
00246 DBG( printf( "drops=%d\n", (int)drops ) );
00247
00248
00249
00250
00251
00252 DBG( printf( "tmp_sample before drops=%ld\n", (long)tmp_sample ) );
00253
00254 tmp_sample+=(ulong)(drops*samples_per_frame);
00255
00256 DBG( printf( "tmp_sample after drops=%ld\n", (long)tmp_sample ) );
00257 }
00258
00259
00260
00261
00262
00263 ulong rounded_sub_frames= (ulong)((tmp_sample*the_smpte_rate * 100)/the_sample_rate +.5);
00264
00265 DBG( printf( "rounded_sub_frames = %ld\n", rounded_sub_frames ) );
00266
00267 sub_frames = (uchar) ((rounded_sub_frames)%100);
00268 frames = (uchar) ((rounded_sub_frames/100) % max_frame);
00269 seconds = (uchar) ((rounded_sub_frames/(100L*max_frame)) % 60 );
00270 minutes = (uchar) ((rounded_sub_frames/(100L*60L*max_frame)) % 60 );
00271 hours = (uchar) ((rounded_sub_frames/(100L*60L*24L*max_frame)) % 24 );
00272
00273 }
00274
00275
00276 void SMPTE::TimeToSample()
00277 {
00278
00279
00280
00281
00282
00283 double the_smpte_rate = smpte_smpte_rates[ smpte_rate ];
00284 double the_sample_rate = smpte_sample_rates[ sample_rate ];
00285
00286
00287
00288
00289
00290 double samples_per_frame=the_sample_rate / the_smpte_rate;
00291
00292
00293
00294
00295
00296 double tmp_sample = (double) (
00297 ( (hours * the_sample_rate * (60 * 60) )
00298 + (minutes * the_sample_rate * 60 )
00299 + (seconds * the_sample_rate )
00300 + (frames * samples_per_frame )
00301 + (sub_frames * samples_per_frame * (1.0/100.0) ) +.5)
00302 );
00303
00304
00305
00306
00307
00308 if( smpte_rate == SMPTE_RATE_30DF || smpte_rate==SMPTE_RATE_2997DF )
00309 {
00310
00311
00312
00313
00314 int num_minutes = (int)((double)tmp_sample/(smpte_sample_rates[sample_rate]*60));
00315
00316 DBG( printf( "num_minutes=%d\n", (int)num_minutes ) );
00317
00318
00319
00320
00321
00322 int ten_minutes = num_minutes/10;
00323
00324 DBG( printf( "ten_minutes=%d\n", (int)ten_minutes) );
00325
00326
00327
00328
00329
00330
00331 int drops=(num_minutes - ten_minutes)*2;
00332
00333 DBG( printf( "drops=%d\n", (int)drops ) );
00334
00335
00336
00337
00338
00339 DBG( printf( "tmp_sample before drops=%ld\n", (long)tmp_sample ) );
00340
00341 tmp_sample-=drops*samples_per_frame;
00342
00343 DBG( printf( "tmp_sample after drops=%ld\n", (long)tmp_sample ) );
00344
00345 }
00346
00347
00348
00349
00350
00351 sample_number=(ulong)tmp_sample;
00352 }
00353
00354
00355
00356 void SMPTE::Copy( const SMPTE & s )
00357 {
00358 smpte_rate=s.smpte_rate;
00359 sample_rate=s.sample_rate;
00360 sample_number=s.sample_number;
00361 hours=s.hours;
00362 minutes=s.minutes;
00363 seconds=s.seconds;
00364 frames=s.frames;
00365 sub_frames=s.sub_frames;
00366 sample_number_dirty=s.sample_number_dirty;
00367 }
00368
00369
00370 int SMPTE::Compare( SMPTE & s )
00371 {
00372 ulong a = GetSampleNumber();
00373 ulong b = s.GetSampleNumber();
00374
00375 if( a<b )
00376 return -1;
00377 if( a>b )
00378 return 1;
00379
00380 return 0;
00381 }
00382
00383
00384 void SMPTE::Add( SMPTE & s )
00385 {
00386 ulong a=GetSampleNumber();
00387 ulong b=s.GetSampleNumber();
00388
00389 SetSampleNumber( a+b );
00390 }
00391
00392 void SMPTE::Subtract( SMPTE & s )
00393 {
00394 ulong a=GetSampleNumber();
00395 ulong b=s.GetSampleNumber();
00396
00397 SetSampleNumber( a-b );
00398 }
00399
00400
00401
00402
00403
00404 }