void pause(int time_in_milliseconds)
{
    long time;

    time = Pt_Time(NULL);
    while(Pt_Time(NULL) - time < time_in_milliseconds);
}
示例#2
0
文件: scheduler.c 项目: mrdg/flim
void schedule_task(struct scheduler *sched, struct task *t)
{
    PtTimestamp now = Pt_Time();
    if (t->start <= now) {
        exec_task(sched, t);
    } else {
        enqueue(sched->queue, t);
    }
}
示例#3
0
int Mf_StreamRead(MfStream *stream, MfEvent **into, int *ptrack, int32_t length)
{
    uint32_t curTick;

    /* calculate the current tick */
    curTick = Mf_StreamGetTick(stream, Pt_Time());

    return Mf_StreamReadUntil(stream, into, ptrack, length, curTick);
}
示例#4
0
static void *Pt_CallbackProc(void *p)
{
    pt_callback_parameters *parameters = (pt_callback_parameters *) p;
    int mytime = 1;

    kern_return_t error;
    thread_extended_policy_data_t extendedPolicy;
    thread_precedence_policy_data_t precedencePolicy;

    extendedPolicy.timeshare = 0;
    error = thread_policy_set(mach_thread_self(), THREAD_EXTENDED_POLICY,
                              (thread_policy_t)&extendedPolicy,
                              THREAD_EXTENDED_POLICY_COUNT);
    if (error != KERN_SUCCESS) {
        mach_error("Couldn't set thread timeshare policy", error);
    }

    precedencePolicy.importance = THREAD_IMPORTANCE;
    error = thread_policy_set(mach_thread_self(), THREAD_PRECEDENCE_POLICY,
                              (thread_policy_t)&precedencePolicy,
                              THREAD_PRECEDENCE_POLICY_COUNT);
    if (error != KERN_SUCCESS) {
        mach_error("Couldn't set thread precedence policy", error);
    }
    
    
    /* to kill a process, just increment the pt_callback_proc_id */
    /* printf("pt_callback_proc_id %d, id %d\n", pt_callback_proc_id, parameters->id); */
    while (pt_callback_proc_id == parameters->id) {
        /* wait for a multiple of resolution ms */
        UInt64 wait_time;
        int delay = mytime++ * parameters->resolution - Pt_Time();
	PtTimestamp timestamp;
        if (delay < 0) delay = 0;
        wait_time = AudioConvertNanosToHostTime((UInt64)delay * NSEC_PER_MSEC);
        wait_time += AudioGetCurrentHostTime();
        error = mach_wait_until(wait_time);
	timestamp = Pt_Time();
        (*(parameters->callback))(timestamp, parameters->userData);
    }
    free(parameters);
    return NULL;
}
示例#5
0
void CALLBACK winmm_time_callback(UINT uID, UINT uMsg, DWORD dwUser, 
                                  DWORD dw1, DWORD dw2)
{
#if (defined (_MSCVER) || defined (_MSC_VER))
   UNREFERENCED_PARAMETER(uID);
   UNREFERENCED_PARAMETER(uMsg);
   UNREFERENCED_PARAMETER(dw1);
   UNREFERENCED_PARAMETER(dw2);
#endif
   (*time_callback)(Pt_Time(), (void *) dwUser);
}
示例#6
0
static void *Pt_CallbackProc(void *p)
{
    pt_callback_parameters *parameters = (pt_callback_parameters *) p;
    int mytime = 1;
    /* to kill a process, just increment the pt_callback_proc_id */
    /* printf("pt_callback_proc_id %d, id %d\n", pt_callback_proc_id,
           parameters->id); */
    if (geteuid() == 0) setpriority(PRIO_PROCESS, 0, -20);
    while (pt_callback_proc_id == parameters->id) {
        /* wait for a multiple of resolution ms */
        struct timeval timeout;
        int delay = mytime++ * parameters->resolution - Pt_Time();
        if (delay < 0) delay = 0;
        timeout.tv_sec = 0;
        timeout.tv_usec = delay * 1000;
        select(0, NULL, NULL, NULL, &timeout);
        (*(parameters->callback))(Pt_Time(), parameters->userData);
    }
    /* printf("Pt_CallbackProc exiting\n"); */
    // free(parameters);
    return NULL;
}
示例#7
0
/* callback function for PortTime -- computes histogram */
void pt_callback(PtTimestamp timestamp, void *userData)
{
    PtTimestamp difference = timestamp - previous_callback_time - period;
    previous_callback_time = timestamp;

    /* allow 5 seconds for the system to settle down */
    if (timestamp < 5000) return;

    iteration++;
    /* send a note on/off if user requested it */
    if (test_out && (iteration % output_period == 0)) {
        PmEvent buffer[1];
        buffer[0].timestamp = Pt_Time(NULL);
        if (note_on) {
            /* note off */
            buffer[0].message = Pm_Message(0x90, 60, 0);
            note_on = 0;
        } else {
            /* note on */
            buffer[0].message = Pm_Message(0x90, 60, 100);
            note_on = 1;
        }
        Pm_Write(out, buffer, 1);
        iteration = 0;
    }

    /* read all waiting events (if user requested) */
    if (test_in) {
       PmError status;
       PmEvent buffer[1];
       do {
          status = Pm_Poll(in);
          if (status == TRUE) {
              Pm_Read(in,buffer,1);
          }
       } while (status == TRUE);
    }

    if (difference < 0) return; /* ignore when system is "catching up" */

    /* update the histogram */
    if (difference < HIST_LEN) {
        histogram[difference]++;
    } else {
        out_of_range++;
    }

    if (max_latency < difference) max_latency = difference;
}
示例#8
0
void
pm_pressout(Server *self, int value, int chan, long timestamp)
{
    int i, curtime;
    PmEvent buffer[1];

    PyoPmBackendData *be_data = (PyoPmBackendData *) self->midi_be_data;

    curtime = Pt_Time();
    buffer[0].timestamp = curtime + timestamp;
    if (chan == 0)
        buffer[0].message = Pm_Message(0xD0, value, 0);
    else
        buffer[0].message = Pm_Message(0xD0 | (chan - 1), value, 0);
    for (i=0; i<self->midiout_count; i++) {
        Pm_Write(be_data->midiout[i], buffer, 1);
    }
}
示例#9
0
/* poll for events from the stream */
PmError Mf_StreamPoll(MfStream *stream)
{
    int i;
    MfFile *file;
    MfTrack *track;
    uint32_t curTick;

    /* calculate the current tick */
    curTick = Mf_StreamGetTick(stream, Pt_Time());

    file = stream->file;
    for (i = 0; i < file->trackCt; i++) {
        track = file->tracks[i];
        if (track->head && track->head->absoluteTm <= curTick) return TRUE;
    }

    return FALSE;
}
示例#10
0
void
pm_bendout(Server *self, int value, int chan, long timestamp)
{
    int i, lsb, msb, curtime;
    PmEvent buffer[1];

    PyoPmBackendData *be_data = (PyoPmBackendData *) self->midi_be_data;

    curtime = Pt_Time();
    buffer[0].timestamp = curtime + timestamp;
    lsb = value & 0x007F;
    msb = (value & (0x007F << 7)) >> 7;
    if (chan == 0)
        buffer[0].message = Pm_Message(0xE0, lsb, msb);
    else
        buffer[0].message = Pm_Message(0xE0 | (chan - 1), lsb, msb);
    for (i=0; i<self->midiout_count; i++) {
        Pm_Write(be_data->midiout[i], buffer, 1);
    }
}
示例#11
0
文件: flim.c 项目: mrdg/flim
static JSBool now(JSContext *cx, uintN argc, jsval *vp)
{
    JS_SET_RVAL(cx, vp, INT_TO_JSVAL(Pt_Time()));
    return JS_TRUE;
}
示例#12
0
void CALLBACK winmm_time_callback(UINT uID, UINT uMsg, DWORD_PTR dwUser, 
                                  DWORD_PTR dw1, DWORD_PTR dw2)
{
    (*time_callback)(Pt_Time(), (void *) dwUser);
}
示例#13
0
void Pt_CFTimerCallback(CFRunLoopTimerRef timer, void *info)
{
    PtThreadParams *params = (PtThreadParams*)info;
    (*params->callback)(Pt_Time(), params->userData);
}
示例#14
0
/*    The winmm stream mode is used for latency>0, and sends
   timestamped messages. The timestamps are relative (delta) 
   times, whereas PortMidi times are absolute. Since peculiar
   things happen when messages are not always sent in advance,
   this function allows us to exercise the system and test it.
 */
void main_test_stream() {
    PmStream * midi;
	char line[80];
    PmEvent buffer[16];

	/* determine which output device to use */
    int i = get_number("Type output number: ");

	latency = 500; /* ignore LATENCY for this test and
				      fix the latency at 500ms */

    /* It is recommended to start timer before PortMidi */
    TIME_START;

	/* open output device */
    Pm_OpenOutput(&midi, 
                  i, 
                  DRIVER_INFO,
                  OUTPUT_BUFFER_SIZE, 
                  TIME_PROC,
                  TIME_INFO, 
                  latency);
    printf("Midi Output opened with %ld ms latency.\n", (long) latency);

    /* output note on/off w/latency offset; hold until user prompts */
    printf("ready to send output... (type RETURN):");
    fgets(line, STRING_MAX, stdin);

    /* if we were writing midi for immediate output, we could always use
       timestamps of zero, but since we may be writing with latency, we
       will explicitly set the timestamp to "now" by getting the time.
       The source of timestamps should always correspond to the TIME_PROC
       and TIME_INFO parameters used in Pm_OpenOutput(). */
    buffer[0].timestamp = TIME_PROC(TIME_INFO);
    buffer[0].message = Pm_Message(0xC0, 0, 0);
	buffer[1].timestamp = buffer[0].timestamp;
	buffer[1].message = Pm_Message(0x90, 60, 100);
	buffer[2].timestamp = buffer[0].timestamp + 1000;
	buffer[2].message = Pm_Message(0x90, 62, 100);
	buffer[3].timestamp = buffer[0].timestamp + 2000;
	buffer[3].message = Pm_Message(0x90, 64, 100);
	buffer[4].timestamp = buffer[0].timestamp + 3000;
	buffer[4].message = Pm_Message(0x90, 66, 100);
	buffer[5].timestamp = buffer[0].timestamp + 4000;
	buffer[5].message = Pm_Message(0x90, 60, 0);
	buffer[6].timestamp = buffer[0].timestamp + 4000;
	buffer[6].message = Pm_Message(0x90, 62, 0);
	buffer[7].timestamp = buffer[0].timestamp + 4000;
	buffer[7].message = Pm_Message(0x90, 64, 0);
	buffer[8].timestamp = buffer[0].timestamp + 4000;
	buffer[8].message = Pm_Message(0x90, 66, 0);

    Pm_Write(midi, buffer, 9);
#ifdef SEND8
	/* Now, we're ready for the real test.
	   Play 4 notes at now, now+500, now+1000, and now+1500
	   Then wait until now+2000.
	   Play 4 more notes as before.
	   We should hear 8 evenly spaced notes. */
	now = TIME_PROC(TIME_INFO);
	for (i = 0; i < 4; i++) {
		buffer[i * 2].timestamp = now + (i * 500);
		buffer[i * 2].message = Pm_Message(0x90, 60, 100);
		buffer[i * 2 + 1].timestamp = now + 250 + (i * 500);
		buffer[i * 2 + 1].message = Pm_Message(0x90, 60, 0);
	}
    Pm_Write(midi, buffer, 8);

    while (Pt_Time() < now + 2500) 
		/* busy wait */;
	/* now we are 500 ms behind schedule, but since the latency
	   is 500, the delay should not be audible */
	now += 2000;
	for (i = 0; i < 4; i++) {
		buffer[i * 2].timestamp = now + (i * 500);
		buffer[i * 2].message = Pm_Message(0x90, 60, 100);
		buffer[i * 2 + 1].timestamp = now + 250 + (i * 500);
		buffer[i * 2 + 1].message = Pm_Message(0x90, 60, 0);
	}
    Pm_Write(midi, buffer, 8);
#endif
    /* close device (this not explicitly needed in most implementations) */
    printf("ready to close and terminate... (type RETURN):");
    fgets(line, STRING_MAX, stdin);
	
    Pm_Close(midi);
    Pm_Terminate();
    printf("done closing and terminating...\n");
}
示例#15
0
void midiWrite(struct Note *note)
{
        outBuffer[0].timestamp = Pt_Time(NULL);
        outBuffer[0].message = Pm_Message(note->status, note->note, note->vol);
        Pm_Write(out, outBuffer, 1);
}
示例#16
0
void midiNoteOn(int note, int vol)
{
        outBuffer[0].timestamp = Pt_Time(NULL);
        outBuffer[0].message = Pm_Message(0x90, note, vol); /* program change */
        Pm_Write(out, outBuffer, 1);
}
示例#17
0
int main()
{
    char line[STRING_MAX];
    int i;
    int len;
    int choice;
    PtTimestamp stop;
    printf("Latency histogram.\n");
    period = 0;
    while (period < 1) {
        period = get_number("Choose timer period (in ms, >= 1): ");
    }
    printf("Benchmark with:\n\t%s\n\t%s\n\t%s\n\t%s\n",
           "1. No MIDI traffic",
           "2. MIDI input",
           "3. MIDI output",
           "4. MIDI input and output");
    choice = get_number("? ");
    switch (choice) {
      case 1: test_in = 0; test_out = 0; break;
      case 2: test_in = 1; test_out = 0; break;
      case 3: test_in = 0; test_out = 1; break;
      case 4: test_in = 1; test_out = 1; break;
      default: assert(0);
    }
    if (test_in || test_out) {
        /* list device information */
        for (i = 0; i < Pm_CountDevices(); i++) {
            const PmDeviceInfo *info = Pm_GetDeviceInfo(i);
            if ((test_in && info->input) ||
                (test_out && info->output)) {
                printf("%d: %s, %s", i, info->interf, info->name);
                if (info->input) printf(" (input)");
                if (info->output) printf(" (output)");
                printf("\n");
            }
        }
        /* open stream(s) */
        if (test_in) {
            int i = get_number("MIDI input device number: ");
            Pm_OpenInput(&in, 
                  i,
                  NULL, 
                  INPUT_BUFFER_SIZE, 
                  (long (*)(void *)) Pt_Time, 
                  NULL);
            /* turn on filtering; otherwise, input might overflow in the 
               5-second period before timer callback starts reading midi */
            Pm_SetFilter(in, PM_FILT_ACTIVE | PM_FILT_CLOCK);
        }
        if (test_out) {
            int i = get_number("MIDI output device number: ");
            PmEvent buffer[1];
            Pm_OpenOutput(&out, 
                  i,
                  NULL,
                  OUTPUT_BUFFER_SIZE,
                  (long (*)(void *)) Pt_Time,
                  NULL, 
                  0); /* no latency scheduling */

            /* send a program change to force a status byte -- this fixes
               a problem with a buggy linux MidiSport driver, and shouldn't
               hurt anything else
             */
            buffer[0].timestamp = 0;
            buffer[0].message = Pm_Message(0xC0, 0, 0); /* program change */
            Pm_Write(out, buffer, 1);

            output_period = get_number(
                "MIDI out should be sent every __ callback iterations: ");

            assert(output_period >= 1);
        }
    }

    printf("%s%s", "Latency measurements will start in 5 seconds. ",
                   "Type return to stop: ");
    Pt_Start(period, &pt_callback, 0);
    fgets(line, STRING_MAX, stdin);
    stop = Pt_Time();
    Pt_Stop();

    /* courteously turn off the last note, if necessary */
    if (note_on) {
       PmEvent buffer[1];
       buffer[0].timestamp = Pt_Time(NULL);
       buffer[0].message = Pm_Message(0x90, 60, 0);
       Pm_Write(out, buffer, 1);
    }

    /* print the histogram */
    printf("Duration of test: %g seconds\n\n", max(0, stop - 5000) * 0.001);
    printf("Latency(ms)  Number of occurrences\n");
    /* avoid printing beyond last non-zero histogram entry */
    len = min(HIST_LEN, max_latency + 1);
    for (i = 0; i < len; i++) {
        printf("%2d      %10ld\n", i, histogram[i]);
    }
    printf("Number of points greater than %dms: %ld\n", 
           HIST_LEN - 1, out_of_range);
    printf("Maximum latency: %ld milliseconds\n", max_latency);
    printf("\nNote that due to rounding, actual latency can be 1ms higher\n");
    printf("than the numbers reported here.\n");
    printf("Type return to exit...");
    fgets(line, STRING_MAX, stdin);

	if(choice == 2)
		Pm_Close(in);
	else if(choice == 3)
		Pm_Close(out);
	else if(choice == 4)
	{
		Pm_Close(in);
		Pm_Close(out);
	}
    return 0;
}
示例#18
0
int main(int argc, char **argv)
{
    FILE *f;
    PmError perr;
    PtError pterr;
    MfFile *pf;
    int argi, i;
    char *arg, *nextarg, *file;

    PmDeviceID dev = -1;
    int list = 0;
    file = NULL;

    for (argi = 1; argi < argc; argi++) {
        arg = argv[argi];
        nextarg = argv[argi+1];
        if (arg[0] == '-') {
            if (!strcmp(arg, "-l")) {
                list = 1;
            } else if (!strcmp(arg, "-o") && nextarg) {
                dev = atoi(nextarg);
                argi++;
            } else {
                fprintf(stderr, "Invalid invocation.\n");
                exit(1);
            }
        } else {
            file = arg;
        }
    }

    PSF(perr, Pm_Initialize, ());
    PSF(perr, Mf_Initialize, ());
    PTSF(pterr, Pt_Start, (1, play, NULL));

    /* list devices */
    if (list) {
        int ct = Pm_CountDevices();
        PmDeviceID def = Pm_GetDefaultInputDeviceID();
        const PmDeviceInfo *devinf;

        for (i = 0; i < ct; i++) {
            devinf = Pm_GetDeviceInfo(i);
            printf("%d%s: %s%s %s\n", i, (def == i) ? "*" : "",
                (devinf->input) ? "I" : "",
                (devinf->output) ? "O" : "",
                devinf->name);
        }
    }

    /* choose device */
    if (dev == -1) {
        fprintf(stderr, "No device selected.\n");
        exit(1);
    }

    /* open it for input */
    PSF(perr, Pm_OpenOutput, (&ostream, dev, NULL, 1024, NULL, NULL, 0));

    /* open it for input */
    f = fopen(file, "rb");
    if (f == NULL) {
        perror(file);
        exit(1);
    }

    /* and read it */
    PSF(perr, Mf_ReadMidiFile, (&pf, f));
    fclose(f);

    /* now start running */
    stream = Mf_OpenStream(pf);
    Mf_StartStream(stream, Pt_Time());

    /* FIXME: I sure hope this doesn't get reordered >_> */
    ready = 1;

    while (1) Pt_Sleep(1<<30);

    return 0;
}
示例#19
0
/*
 * Method:    Pt_Time
 */
JNIEXPORT jint JNICALL Java_jportmidi_JPortMidiApi_Pt_1Time
        (JNIEnv *env, jclass c)
 {
     return Pt_Time();
 }