00001 00017 #include "CoreMidiSource.h" 00018 00019 /* 00020 * Obtains the current system time in microseconds. 00021 * 00022 * Class: uk_co_xfactorylibrarians_coremidi4j_CoreMidiSource 00023 * Method: getMicroSecondTime 00024 * Signature: ()J 00025 * 00026 * @return The current system time in microseconds. 00027 * 00028 */ 00029 00030 JNIEXPORT jlong JNICALL Java_uk_co_xfactorylibrarians_coremidi4j_CoreMidiSource_getMicroSecondTime(JNIEnv *, jobject) { 00031 00032 static mach_timebase_info_data_t sTimebaseInfo; // Will hold conversion factor for timestamps 00033 00034 // If this is the first time we've run, get the timebase. 00035 // We can use denom == 0 to indicate that sTimebaseInfo is 00036 // uninitialised because it makes no sense to have a zero 00037 // denominator in a fraction. 00038 if ( sTimebaseInfo.denom == 0 ) { 00039 00040 (void) mach_timebase_info(&sTimebaseInfo); 00041 00042 } 00043 00044 uint64_t currentMachTime = mach_absolute_time(); 00045 00046 // Convert the timestamp from Mach Absolute Time Units to microseconds, 00047 // as expected by Java MIDI. The first step is based on Apple Tech Q&A 1398, 00048 // https://developer.apple.com/library/mac/qa/qa1398/_index.html 00049 // 00050 // Because we are converting to microseconds rather than nanoseconds, we can start 00051 // by dividing by 1000, which should eliminate the risk of overflow described in the 00052 // comment below (copied in from the Q&A), which evidently should not have been an issue 00053 // until 584.9 years after the most recent system boot anyway, according to 00054 // http://lists.apple.com/archives/darwin-kernel/2012/Sep/msg00008.html 00055 // 00056 // Do the maths. We hope that the multiplication doesn't 00057 // overflow; the price you pay for working in fixed point. 00058 uint64_t timestamp = (currentMachTime / 1000) * sTimebaseInfo.numer / sTimebaseInfo.denom; 00059 00060 return timestamp; 00061 00062 } 00063