From 44e68e4348f7ca86f4209f3f86ac7b6cb49acd52 Mon Sep 17 00:00:00 2001 From: Miller Puckette Date: Fri, 28 Dec 2007 03:28:31 +0000 Subject: 0.41-10 test 10 - many patches, plus work on callback scheduling svn path=/trunk/; revision=9107 --- pd/portmidi/pm_test/latency.c | 278 ---------------------- pd/portmidi/pm_test/latency.dsp | 102 -------- pd/portmidi/pm_test/midithread.c | 327 -------------------------- pd/portmidi/pm_test/midithread.dsp | 102 -------- pd/portmidi/pm_test/midithru.c | 364 ---------------------------- pd/portmidi/pm_test/midithru.dsp | 102 -------- pd/portmidi/pm_test/midithru.dsw | 29 --- pd/portmidi/pm_test/sysex.c | 319 ------------------------- pd/portmidi/pm_test/sysex.dsp | 102 -------- pd/portmidi/pm_test/test.c | 469 ------------------------------------- pd/portmidi/pm_test/test.dsp | 102 -------- pd/portmidi/pm_test/txdata.syx | 257 -------------------- 12 files changed, 2553 deletions(-) delete mode 100644 pd/portmidi/pm_test/latency.c delete mode 100644 pd/portmidi/pm_test/latency.dsp delete mode 100644 pd/portmidi/pm_test/midithread.c delete mode 100644 pd/portmidi/pm_test/midithread.dsp delete mode 100644 pd/portmidi/pm_test/midithru.c delete mode 100644 pd/portmidi/pm_test/midithru.dsp delete mode 100644 pd/portmidi/pm_test/midithru.dsw delete mode 100644 pd/portmidi/pm_test/sysex.c delete mode 100644 pd/portmidi/pm_test/sysex.dsp delete mode 100644 pd/portmidi/pm_test/test.c delete mode 100644 pd/portmidi/pm_test/test.dsp delete mode 100644 pd/portmidi/pm_test/txdata.syx (limited to 'pd/portmidi') diff --git a/pd/portmidi/pm_test/latency.c b/pd/portmidi/pm_test/latency.c deleted file mode 100644 index 87b1965b..00000000 --- a/pd/portmidi/pm_test/latency.c +++ /dev/null @@ -1,278 +0,0 @@ -/* latency.c -- measure latency of OS */ - -#include "porttime.h" -#include "portmidi.h" -#include "stdlib.h" -#include "stdio.h" -#include "string.h" -#include "assert.h" - -/* Latency is defined here to mean the time starting when a - process becomes ready to run, and ending when the process - actually runs. Latency is due to contention for the - processor, usually due to other processes, OS activity - including device drivers handling interrupts, and - waiting for the scheduler to suspend the currently running - process and activate the one that is waiting. - - Latency can affect PortMidi applications: if a process fails - to wake up promptly, MIDI input may sit in the input buffer - waiting to be handled, and MIDI output may not be generated - with accurate timing. Using the latency parameter when - opening a MIDI output port allows the caller to defer timing - to PortMidi, which in most implementations will pass the - data on to the OS. By passing timestamps and data to the - OS kernel, device driver, or even hardware, there are fewer - sources of latency that can affect the ultimate timing of - the data. On the other hand, the application must generate - and deliver the data ahead of the timestamp. The amount by - which data is computed early must be at least as large as - the worst-case latency to avoid timing problems. - - Latency is even more important in audio applications. If an - application lets an audio output buffer underflow, an audible - pop or click is produced. Audio input buffers can overflow, - causing data to be lost. In general the audio buffers must - be large enough to buffer the worst-case latency that the - application will encounter. - - This program measures latency by recording the difference - between the scheduled callback time and the current real time. - We do not really know the scheduled callback time, so we will - record the differences between the real time of each callback - and the real time of the previous callback. Differences that - are larger than the scheduled difference are recorded. Smaller - differences indicate the system is recovering from an earlier - latency, so these are ignored. - Since printing by the callback process can cause all sorts of - delays, this program records latency observations in a - histogram. When the program is stopped, the histogram is - printed to the console. - - Optionally the system can be tested under a load of MIDI input, - MIDI output, or both. If MIDI input is selected, the callback - thread will read any waiting MIDI events each iteration. You - must generate events on this interface for the test to actually - put any appreciable load on PortMidi. If MIDI output is - selected, alternating note on and note off events are sent each - X iterations, where you specify X. For example, with a timer - callback period of 2ms and X=1, a MIDI event is sent every 2ms. - - - INTERPRETING RESULTS: Time is quantized to 1ms, so there is - some uncertainty due to rounding. A microsecond latency that - spans the time when the clock is incremented will be reported - as a latency of 1. On the other hand, a latency of almost - 1ms that falls between two clock ticks will be reported as - zero. In general, if the highest nonzero bin is numbered N, - then the maximum latency is N+1. - -CHANGE LOG - -18-Jul-03 Mark Nelson -- Added code to generate MIDI or receive - MIDI during test, and made period user-settable. - */ - -#define HIST_LEN 21 /* how many 1ms bins in the histogram */ - -#define STRING_MAX 80 /* used for console input */ - -#define INPUT_BUFFER_SIZE 100 -#define OUTPUT_BUFFER_SIZE 0 - -#ifndef max -#define max(a, b) ((a) > (b) ? (a) : (b)) -#endif -#ifndef min -#define min(a, b) ((a) <= (b) ? (a) : (b)) -#endif - -int get_number(char *prompt); - -PtTimestamp previous_callback_time = 0; - -int period; /* milliseconds per callback */ - -long histogram[HIST_LEN]; -long max_latency = 0; /* worst latency observed */ -long out_of_range = 0; /* how many points outside of HIST_LEN? */ - -int test_in, test_out; /* test MIDI in and/or out? */ -int output_period; /* output MIDI every __ iterations if test_out true */ -int iteration = 0; -PmStream *in, *out; -int note_on = 0; /* is the note currently on? */ - -/* 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; -} - - -int main() -{ - char line[STRING_MAX]; - int i; - int len; - int choice; - PtTimestamp stop; - printf("Latency histogram.\n"); - period = get_number("Choose timer period (in ms): "); - assert(period >= 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); - return 0; -} - - -/* read a number from console */ -int get_number(char *prompt) -{ - char line[STRING_MAX]; - int n = 0, i; - printf(prompt); - while (n != 1) { - n = scanf("%d", &i); - fgets(line, STRING_MAX, stdin); - - } - return i; -} diff --git a/pd/portmidi/pm_test/latency.dsp b/pd/portmidi/pm_test/latency.dsp deleted file mode 100644 index ff6bbbd7..00000000 --- a/pd/portmidi/pm_test/latency.dsp +++ /dev/null @@ -1,102 +0,0 @@ -# Microsoft Developer Studio Project File - Name="latency" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=latency - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "latency.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "latency.mak" CFG="latency - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "latency - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "latency - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "latency - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "latency___Win32_Release" -# PROP BASE Intermediate_Dir "latency___Win32_Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "latencyRelease" -# PROP Intermediate_Dir "latencyRelease" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "../porttime" /I "../pm_common" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 ..\Release\portmidi.lib ..\porttime\Release\porttime.lib winmm.lib /nologo /subsystem:console /machine:I386 - -!ELSEIF "$(CFG)" == "latency - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "latency___Win32_Debug" -# PROP BASE Intermediate_Dir "latency___Win32_Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "latencyDebug" -# PROP Intermediate_Dir "latencyDebug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../porttime" /I "../pm_common" /D "_CONSOLE" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "USE_DLL_FOR_CLEANUP" /YX /FD /GZ /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 ..\pm_win\Debug\portmidi.lib ..\porttime\Debug\porttime.lib ..\pm_win\Debug\pm_dll.lib winmm.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "latency - Win32 Release" -# Name "latency - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\latency.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/pd/portmidi/pm_test/midithread.c b/pd/portmidi/pm_test/midithread.c deleted file mode 100644 index 861b347c..00000000 --- a/pd/portmidi/pm_test/midithread.c +++ /dev/null @@ -1,327 +0,0 @@ -/* midithread.c -- example program showing how to do midi processing - in a preemptive thread - - Notes: if you handle midi I/O from your main program, there will be - some delay before handling midi messages whenever the program is - doing something like file I/O, graphical interface updates, etc. - - To handle midi with minimal delay, you should do all midi processing - in a separate, high priority thread. A convenient way to get a high - priority thread in windows is to use the timer callback provided by - the PortTime library. That is what we show here. - - If the high priority thread writes to a file, prints to the console, - or does just about anything other than midi processing, this may - create delays, so all this processing should be off-loaded to the - "main" process or thread. Communication between threads can be tricky. - If one thread is writing at the same time the other is reading, very - tricky race conditions can arise, causing programs to behave - incorrectly, but only under certain timing conditions -- a terrible - thing to debug. Advanced programmers know this as a synchronization - problem. See any operating systems textbook for the complete story. - - To avoid synchronization problems, a simple, reliable approach is - to communicate via messages. PortMidi offers a message queue as a - datatype, and operations to insert and remove messages. Use two - queues as follows: midi_to_main transfers messages from the midi - thread to the main thread, and main_to_midi transfers messages from - the main thread to the midi thread. Queues are safe for use between - threads as long as ONE thread writes and ONE thread reads. You must - NEVER allow two threads to write to the same queue. - - This program transposes incoming midi data by an amount controlled - by the main program. To change the transposition, type an integer - followed by return. The main program sends this via a message queue - to the midi thread. To quit, type 'q' followed by return. - - The midi thread can also send a pitch to the main program on request. - Type 'm' followed by return to wait for the next midi message and - print the pitch. - - This program illustrates: - Midi processing in a high-priority thread. - Communication with a main process via message queues. - - */ - -#include "stdio.h" -#include "stdlib.h" -#include "string.h" -#include "assert.h" -#include "portmidi.h" -#include "pmutil.h" -#include "porttime.h" - -/* if INPUT_BUFFER_SIZE is 0, PortMidi uses a default value */ -#define INPUT_BUFFER_SIZE 0 - -#define OUTPUT_BUFFER_SIZE 100 -#define DRIVER_INFO NULL -#define TIME_PROC NULL -#define TIME_INFO NULL -/* use zero latency because we want output to be immediate */ -#define LATENCY 0 - -#define STRING_MAX 80 - -/**********************************/ -/* DATA USED ONLY BY process_midi */ -/* (except during initialization) */ -/**********************************/ - -int active = FALSE; -int monitor = FALSE; -int midi_thru = TRUE; - -long transpose; -PmStream *midi_in; -PmStream *midi_out; - -/****************************/ -/* END OF process_midi DATA */ -/****************************/ - -/* shared queues */ -PmQueue *midi_to_main; -PmQueue *main_to_midi; - -#define QUIT_MSG 1000 -#define MONITOR_MSG 1001 -#define THRU_MSG 1002 - -/* timer interrupt for processing midi data */ -void process_midi(PtTimestamp timestamp, void *userData) -{ - PmError result; - PmEvent buffer; /* just one message at a time */ - long msg; - - /* do nothing until initialization completes */ - if (!active) - return; - - /* check for messages */ - do { - result = Pm_Dequeue(main_to_midi, &msg); - if (result) { - if (msg >= -127 && msg <= 127) - transpose = msg; - else if (msg == QUIT_MSG) { - /* acknowledge receipt of quit message */ - Pm_Enqueue(midi_to_main, &msg); - active = FALSE; - return; - } else if (msg == MONITOR_MSG) { - /* main has requested a pitch. monitor is a flag that - * records the request: - */ - monitor = TRUE; - } else if (msg == THRU_MSG) { - /* toggle Thru on or off */ - midi_thru = !midi_thru; - } - } - } while (result); - - /* see if there is any midi input to process */ - do { - result = Pm_Poll(midi_in); - if (result) { - long status, data1, data2; - if (Pm_Read(midi_in, &buffer, 1) == pmBufferOverflow) - continue; - if (midi_thru) - Pm_Write(midi_out, &buffer, 1); - /* unless there was overflow, we should have a message now */ - status = Pm_MessageStatus(buffer.message); - data1 = Pm_MessageData1(buffer.message); - data2 = Pm_MessageData2(buffer.message); - if ((status & 0xF0) == 0x90 || - (status & 0xF0) == 0x80) { - - /* this is a note-on or note-off, so transpose and send */ - data1 += transpose; - - /* keep within midi pitch range, keep proper pitch class */ - while (data1 > 127) - data1 -= 12; - while (data1 < 0) - data1 += 12; - - /* send the message */ - buffer.message = Pm_Message(status, data1, data2); - Pm_Write(midi_out, &buffer, 1); - - /* if monitor is set, send the pitch to the main thread */ - if (monitor) { - Pm_Enqueue(midi_to_main, &data1); - monitor = FALSE; /* only send one pitch per request */ - } - } - } - } while (result); -} - -void exit_with_message(char *msg) -{ - char line[STRING_MAX]; - printf("%s\n", msg); - fgets(line, STRING_MAX, stdin); - exit(1); -} - -int main() -{ - int id; - long n; - const PmDeviceInfo *info; - char line[STRING_MAX]; - int spin; - int done = FALSE; - - /* determine what type of test to run */ - printf("begin PortMidi multithread test...\n"); - - /* note that it is safe to call PortMidi from the main thread for - initialization and opening devices. You should not make any - calls to PortMidi from this thread once the midi thread begins. - to make PortMidi calls. - */ - - /* make the message queues */ - /* messages can be of any size and any type, but all messages in - * a given queue must have the same size. We'll just use long's - * for our messages in this simple example - */ - midi_to_main = Pm_QueueCreate(32, sizeof(long)); - assert(midi_to_main != NULL); - main_to_midi = Pm_QueueCreate(32, sizeof(long)); - assert(main_to_midi != NULL); - - /* a little test of enqueue and dequeue operations. Ordinarily, - * you would call Pm_Enqueue from one thread and Pm_Dequeue from - * the other. Since the midi thread is not running, this is safe. - */ - n = 1234567890; - Pm_Enqueue(midi_to_main, &n); - n = 987654321; - Pm_Enqueue(midi_to_main, &n); - Pm_Dequeue(midi_to_main, &n); - if (n != 1234567890) { - exit_with_message("Pm_Dequeue produced unexpected result."); - } - Pm_Dequeue(midi_to_main, &n); - if(n != 987654321) { - exit_with_message("Pm_Dequeue produced unexpected result."); - } - - /* always start the timer before you start midi */ - Pt_Start(1, &process_midi, 0); /* start a timer with millisecond accuracy */ - /* the timer will call our function, process_midi() every millisecond */ - - Pm_Initialize(); - - id = Pm_GetDefaultOutputDeviceID(); - info = Pm_GetDeviceInfo(id); - if (info == NULL) { - printf("Could not open default output device (%d).", id); - exit_with_message(""); - } - printf("Opening output device %s %s\n", info->interf, info->name); - - /* use zero latency because we want output to be immediate */ - Pm_OpenOutput(&midi_out, - id, - DRIVER_INFO, - OUTPUT_BUFFER_SIZE, - TIME_PROC, - TIME_INFO, - LATENCY); - - id = Pm_GetDefaultInputDeviceID(); - info = Pm_GetDeviceInfo(id); - if (info == NULL) { - printf("Could not open default input device (%d).", id); - exit_with_message(""); - } - printf("Opening input device %s %s\n", info->interf, info->name); - Pm_OpenInput(&midi_in, - id, - DRIVER_INFO, - INPUT_BUFFER_SIZE, - TIME_PROC, - TIME_INFO); - - active = TRUE; /* enable processing in the midi thread -- yes, this - is a shared variable without synchronization, but - this simple assignment is safe */ - - printf("Enter midi input; it will be transformed as specified by...\n"); - printf("%s\n%s\n%s\n", - "Type 'q' to quit, 'm' to monitor next pitch, t to toggle thru or", - "type a number to specify transposition.", - "Must terminate with [ENTER]"); - - while (!done) { - long msg; - int len; - fgets(line, STRING_MAX, stdin); - /* remove the newline: */ - len = strlen(line); - if (len > 0) line[len - 1] = 0; /* overwrite the newline char */ - if (strcmp(line, "q") == 0) { - msg = QUIT_MSG; - Pm_Enqueue(main_to_midi, &msg); - /* wait for acknowlegement */ - do { - spin = Pm_Dequeue(midi_to_main, &msg); - } while (spin == 0); /* spin */ ; - done = TRUE; /* leave the command loop and wrap up */ - } else if (strcmp(line, "m") == 0) { - msg = MONITOR_MSG; - Pm_Enqueue(main_to_midi, &msg); - printf("Waiting for note...\n"); - do { - spin = Pm_Dequeue(midi_to_main, &msg); - } while (spin == 0); /* spin */ ; - printf("... pitch is %ld\n", msg); - } else if (strcmp(line, "t") == 0) { - /* reading midi_thru asynchronously could give incorrect results, - e.g. if you type "t" twice before the midi thread responds to - the first one, but we'll do it this way anyway. Perhaps a more - correct way would be to wait for an acknowledgement message - containing the new state. */ - printf("Setting THRU %s\n", (midi_thru ? "off" : "on")); - msg = THRU_MSG; - Pm_Enqueue(main_to_midi, &msg); - } else if (sscanf(line, "%ld", &msg) == 1) { - if (msg >= -127 && msg <= 127) { - /* send transposition value */ - printf("Transposing by %ld\n", msg); - Pm_Enqueue(main_to_midi, &msg); - } else { - printf("Transposition must be within -127...127\n"); - } - } else { - printf("%s\n%s\n%s\n", - "Type 'q' to quit, 'm' to monitor next pitch, or", - "type a number to specify transposition.", - "Must terminate with [ENTER]"); - } - } - - /* at this point, midi thread is inactive and we need to shut down - * the midi input and output - */ - Pt_Stop(); /* stop the timer */ - Pm_QueueDestroy(midi_to_main); - Pm_QueueDestroy(main_to_midi); - - /* Belinda! if close fails here, some memory is deleted, right??? */ - Pm_Close(midi_in); - Pm_Close(midi_out); - - printf("finished portMidi multithread test...enter any character to quit [RETURN]..."); - fgets(line, STRING_MAX, stdin); - return 0; -} diff --git a/pd/portmidi/pm_test/midithread.dsp b/pd/portmidi/pm_test/midithread.dsp deleted file mode 100644 index 7dc0a16f..00000000 --- a/pd/portmidi/pm_test/midithread.dsp +++ /dev/null @@ -1,102 +0,0 @@ -# Microsoft Developer Studio Project File - Name="midithread" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=midithread - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "midithread.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "midithread.mak" CFG="midithread - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "midithread - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "midithread - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "midithread - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "midithreadRelease" -# PROP Intermediate_Dir "midithreadRelease" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "../pm_common" /I "../porttime" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 ..\Release\portmidi.lib ..\porttime\Release\porttime.lib winmm.lib /nologo /subsystem:console /machine:I386 - -!ELSEIF "$(CFG)" == "midithread - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "midithreadDebug" -# PROP BASE Intermediate_Dir "midithreadDebug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "midithreadDebug" -# PROP Intermediate_Dir "midithreadDebug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../pm_common" /I "../porttime" /D "_CONSOLE" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "USE_DLL_FOR_CLEANUP" /YX /FD /GZ /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 ..\pm_win\Debug\portmidi.lib ..\porttime\Debug\porttime.lib ..\pm_win\Debug\pm_dll.lib winmm.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "midithread - Win32 Release" -# Name "midithread - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\midithread.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/pd/portmidi/pm_test/midithru.c b/pd/portmidi/pm_test/midithru.c deleted file mode 100644 index 270246fb..00000000 --- a/pd/portmidi/pm_test/midithru.c +++ /dev/null @@ -1,364 +0,0 @@ -/* midithru.c -- example program implementing background thru processing */ - -/* suppose you want low-latency midi-thru processing, but your application - wants to take advantage of the input buffer and timestamped data so that - it does not have to operate with very low latency. - - This program illustrates how to use a timer callback from PortTime to - implement a low-latency process that handles midi thru, including correctly - merging midi data from the application with midi data from the input port. - - The main application, which runs in the main program thread, will use an - interface similar to that of PortMidi, but since PortMidi does not allow - concurrent threads to share access to a stream, the application will - call private methods that transfer MIDI messages to and from the timer - thread. All PortMidi API calls are made from the timer thread. - */ - -/* DESIGN - -All setup will be done by the main thread. Then, all direct access to -PortMidi will be handed off to the timer callback thread. - -After this hand-off, the main thread will get/send messages via a queue. - -The goal is to send incoming messages to the midi output while merging -any midi data generated by the application. Sysex is a problem here -because you cannot insert (merge) a midi message while a sysex is in -progress. There are at least three ways to implement midi thru with -sysex messages: - -1) Turn them off. If your application does not need them, turn them off - with Pm_SetFilter(midi_in, PM_FILT_ACTIVE | PM_FILT_SYSEX). You will - not receive sysex (or active sensing messages), so you will not have - to handle them. - -2) Make them atomic. As you receive sysex messages, copy the data into - a (big) buffer. Ideally, expand the buffer as needed -- sysex messages - do not have any maximum length. Even more ideally, use a list structure - and real-time memory allocation to avoid latency in the timer thread. - When a full sysex message is received, send it to the midi output all - at once. - -3) Process sysex incrementally. Send sysex data to midi output as it - arrives. Block any non-real-time messages from the application until - the sysex message completes. There is the risk that an incomplete - sysex message will block messages forever, so implement a 5-second - timeout: if no sysex data is seen for 5 seconds, release the block, - possibly losing the rest of the sysex message. - - Application messages must be processed similarly: once started, a - sysex message will block MIDI THRU processing. We will assume that - the application will not abort a sysex message, so timeouts are not - necessary here. - -This code implements (3). - -Latency is also an issue. PortMidi requires timestamps to be in -non-decreasing order. Since we'll be operating with a low-latency -timer thread, we can just set the latency to zero meaning timestamps -are ignored by PortMidi. This will allow thru to go through with -minimal latency. The application, however, needs to use timestamps -because we assume it is high latency (the whole purpose of this -example is to illustrate how to get low-latency thru with a high-latency -application.) So the callback thread will implement midi timing by -observing timestamps. The current timestamp will be available in the -global variable current_timestamp. - -*/ - - -#include "stdio.h" -#include "stdlib.h" -#include "string.h" -#include "assert.h" -#include "portmidi.h" -#include "pmutil.h" -#include "porttime.h" - -#define MIDI_SYSEX 0xf0 -#define MIDI_EOX 0xf7 - -/* active is set true when midi processing should start */ -int active = FALSE; -/* process_midi_exit_flag is set when the timer thread shuts down */ -int process_midi_exit_flag; - -PmStream *midi_in; -PmStream *midi_out; - -/* shared queues */ -#define IN_QUEUE_SIZE 1024 -#define OUT_QUEUE_SIZE 1024 -PmQueue *in_queue; -PmQueue *out_queue; -PmTimestamp current_timestamp = 0; -int thru_sysex_in_progress = FALSE; -int app_sysex_in_progress = FALSE; -PmTimestamp last_timestamp = 0; - - -/* time proc parameter for Pm_MidiOpen */ -long midithru_time_proc(void *info) -{ - return current_timestamp; -} - - -/* timer interrupt for processing midi data. - Incoming data is delivered to main program via in_queue. - Outgoing data from main program is delivered via out_queue. - Incoming data from midi_in is copied with low latency to midi_out. - Sysex messages from either source block messages from the other. - */ -void process_midi(PtTimestamp timestamp, void *userData) -{ - PmError result; - PmEvent buffer; /* just one message at a time */ - - current_timestamp++; /* update every millisecond */ - /* if (current_timestamp % 1000 == 0) - printf("time %d\n", current_timestamp); */ - - /* do nothing until initialization completes */ - if (!active) { - /* this flag signals that no more midi processing will be done */ - process_midi_exit_flag = TRUE; - return; - } - - /* see if there is any midi input to process */ - if (!app_sysex_in_progress) { - do { - result = Pm_Poll(midi_in); - if (result) { - long status; - if (Pm_Read(midi_in, &buffer, 1) == pmBufferOverflow) - continue; - - /* record timestamp of most recent data */ - last_timestamp = current_timestamp; - - /* the data might be the end of a sysex message that - has timed out, in which case we must ignore it. - It's a continuation of a sysex message if status - is actually a data byte (high-order bit is zero). */ - status = Pm_MessageStatus(buffer.message); - if (((status & 0x80) == 0) && !thru_sysex_in_progress) { - continue; /* ignore this data */ - } - - /* implement midi thru */ - /* note that you could output to multiple ports or do other - processing here if you wanted - */ - /* printf("thru: %x\n", buffer.message); */ - Pm_Write(midi_out, &buffer, 1); - - /* send the message to the application */ - /* you might want to filter clock or active sense messages here - to avoid sending a bunch of junk to the application even if - you want to send it to MIDI THRU - */ - Pm_Enqueue(in_queue, &buffer); - - /* sysex processing */ - if (status == MIDI_SYSEX) thru_sysex_in_progress = TRUE; - else if ((status & 0xF8) != 0xF8) { - /* not MIDI_SYSEX and not real-time, so */ - thru_sysex_in_progress = FALSE; - } - if (thru_sysex_in_progress && /* look for EOX */ - (((buffer.message & 0xFF) == MIDI_EOX) || - (((buffer.message >> 8) & 0xFF) == MIDI_EOX) || - (((buffer.message >> 16) & 0xFF) == MIDI_EOX) || - (((buffer.message >> 24) & 0xFF) == MIDI_EOX))) { - thru_sysex_in_progress = FALSE; - } - } - } while (result); - } - - - /* see if there is application midi data to process */ - while (!Pm_QueueEmpty(out_queue)) { - /* see if it is time to output the next message */ - PmEvent *next = (PmEvent *) Pm_QueuePeek(out_queue); - assert(next); /* must be non-null because queue is not empty */ - if (next->timestamp <= current_timestamp) { - /* time to send a message, first make sure it's not blocked */ - long status = Pm_MessageStatus(buffer.message); - if ((status & 0xF8) == 0xF8) { - ; /* real-time messages are not blocked */ - } else if (thru_sysex_in_progress) { - /* maybe sysex has timed out (output becomes unblocked) */ - if (last_timestamp + 5000 < current_timestamp) { - thru_sysex_in_progress = FALSE; - } else break; /* output is blocked, so exit loop */ - } - Pm_Dequeue(out_queue, &buffer); - Pm_Write(midi_out, &buffer, 1); - - /* inspect message to update app_sysex_in_progress */ - if (status == MIDI_SYSEX) app_sysex_in_progress = TRUE; - else if ((status & 0xF8) != 0xF8) { - /* not MIDI_SYSEX and not real-time, so */ - app_sysex_in_progress = FALSE; - } - if (app_sysex_in_progress && /* look for EOX */ - (((buffer.message & 0xFF) == MIDI_EOX) || - (((buffer.message >> 8) & 0xFF) == MIDI_EOX) || - (((buffer.message >> 16) & 0xFF) == MIDI_EOX) || - (((buffer.message >> 24) & 0xFF) == MIDI_EOX))) { - app_sysex_in_progress = FALSE; - } - } else break; /* wait until indicated timestamp */ - } -} - - -void exit_with_message(char *msg) -{ -#define STRING_MAX 80 - char line[STRING_MAX]; - printf("%s\nType ENTER...", msg); - fgets(line, STRING_MAX, stdin); - exit(1); -} - - -void initialize() -/* set up midi processing thread and open midi streams */ -{ - /* note that it is safe to call PortMidi from the main thread for - initialization and opening devices. You should not make any - calls to PortMidi from this thread once the midi thread begins. - to make PortMidi calls. - */ - - /* note that this routine provides minimal error checking. If - you use the PortMidi library compiled with PM_CHECK_ERRORS, - then error messages will be printed and the program will exit - if an error is encountered. Otherwise, you should add some - error checking to this code. - */ - - const PmDeviceInfo *info; - int id; - - /* make the message queues */ - in_queue = Pm_QueueCreate(IN_QUEUE_SIZE, sizeof(PmEvent)); - assert(in_queue != NULL); - out_queue = Pm_QueueCreate(OUT_QUEUE_SIZE, sizeof(PmEvent)); - assert(out_queue != NULL); - - /* always start the timer before you start midi */ - Pt_Start(1, &process_midi, 0); /* start a timer with millisecond accuracy */ - /* the timer will call our function, process_midi() every millisecond */ - - Pm_Initialize(); - - id = Pm_GetDefaultOutputDeviceID(); - info = Pm_GetDeviceInfo(id); - if (info == NULL) { - printf("Could not open default output device (%d).", id); - exit_with_message(""); - } - printf("Opening output device %s %s\n", info->interf, info->name); - - /* use zero latency because we want output to be immediate */ - Pm_OpenOutput(&midi_out, - id, - NULL /* driver info */, - OUT_QUEUE_SIZE, - &midithru_time_proc, - NULL /* time info */, - 0 /* Latency */); - - id = Pm_GetDefaultInputDeviceID(); - info = Pm_GetDeviceInfo(id); - if (info == NULL) { - printf("Could not open default input device (%d).", id); - exit_with_message(""); - } - printf("Opening input device %s %s\n", info->interf, info->name); - Pm_OpenInput(&midi_in, - id, - NULL /* driver info */, - 0 /* use default input size */, - &midithru_time_proc, - NULL /* time info */); - /* Note: if you set a filter here, then this will filter what goes - to the MIDI THRU port. You may not want to do this. - */ - Pm_SetFilter(midi_in, PM_FILT_ACTIVE | PM_FILT_CLOCK); - - active = TRUE; /* enable processing in the midi thread -- yes, this - is a shared variable without synchronization, but - this simple assignment is safe */ - -} - - -void finalize() -{ - /* the timer thread could be in the middle of accessing PortMidi stuff */ - /* to detect that it is done, we first clear process_midi_exit_flag and - then wait for the timer thread to set it - */ - process_midi_exit_flag = FALSE; - active = FALSE; - /* busy wait for flag from timer thread that it is done */ - while (!process_midi_exit_flag) ; - /* at this point, midi thread is inactive and we need to shut down - * the midi input and output - */ - Pt_Stop(); /* stop the timer */ - Pm_QueueDestroy(in_queue); - Pm_QueueDestroy(out_queue); - - Pm_Close(midi_in); - Pm_Close(midi_out); - - Pm_Terminate(); -} - - -int main(int argc, char *argv[]) -{ - PmTimestamp last_time = 0; - PmEvent buffer; - - /* determine what type of test to run */ - printf("begin PortMidi midithru program...\n"); - - initialize(); /* set up and start midi processing */ - - printf("%s\n%s\n", - "This program will run for 60 seconds, or until you play middle C,", - "echoing all input with a 2 second delay."); - - while (current_timestamp < 60000) { - /* just to make the point that this is not a low-latency process, - spin until half a second has elapsed */ - last_time = last_time + 500; - while (last_time > current_timestamp) ; - - /* now read data and send it after changing timestamps */ - while (Pm_Dequeue(in_queue, &buffer) == 1) { - /* printf("timestamp %d\n", buffer.timestamp); */ - /* printf("message %x\n", buffer.message); */ - buffer.timestamp = buffer.timestamp + 2000; /* delay */ - Pm_Enqueue(out_queue, &buffer); - /* play middle C to break out of loop */ - if (Pm_MessageStatus(buffer.message) == 0x90 && - Pm_MessageData1(buffer.message) == 60) { - goto quit_now; - } - } - } -quit_now: - finalize(); - exit_with_message("finished PortMidi midithru program."); - return 0; /* never executed, but keeps the compiler happy */ -} diff --git a/pd/portmidi/pm_test/midithru.dsp b/pd/portmidi/pm_test/midithru.dsp deleted file mode 100644 index 83f28cfc..00000000 --- a/pd/portmidi/pm_test/midithru.dsp +++ /dev/null @@ -1,102 +0,0 @@ -# Microsoft Developer Studio Project File - Name="midithru" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=midithru - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "midithru.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "midithru.mak" CFG="midithru - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "midithru - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "midithru - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "midithru - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "midithruRelease" -# PROP Intermediate_Dir "midithruRelease" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "../pm_common" /I "../porttime" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 ..\Release\portmidi.lib ..\porttime\Release\porttime.lib winmm.lib /nologo /subsystem:console /machine:I386 - -!ELSEIF "$(CFG)" == "midithru - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "midithruDebug" -# PROP BASE Intermediate_Dir "midithruDebug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "midithruDebug" -# PROP Intermediate_Dir "midithruDebug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../pm_common" /I "../porttime" /D "_CONSOLE" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "USE_DLL_FOR_CLEANUP" /YX /FD /GZ /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 ..\pm_win\Debug\portmidi.lib ..\porttime\Debug\porttime.lib ..\pm_win\Debug\pm_dll.lib winmm.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "midithru - Win32 Release" -# Name "midithru - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\midithru.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/pd/portmidi/pm_test/midithru.dsw b/pd/portmidi/pm_test/midithru.dsw deleted file mode 100644 index b244a104..00000000 --- a/pd/portmidi/pm_test/midithru.dsw +++ /dev/null @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "midithread"=.\midithru.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/pd/portmidi/pm_test/sysex.c b/pd/portmidi/pm_test/sysex.c deleted file mode 100644 index f49bf962..00000000 --- a/pd/portmidi/pm_test/sysex.c +++ /dev/null @@ -1,319 +0,0 @@ -/* sysex.c -- example program showing how to send and receive sysex - messages - - Messages are stored in a file using 2-digit hexadecimal numbers, - one per byte, separated by blanks, with up to 32 numbers per line: - F0 14 A7 4B ... - - */ - -#include "stdio.h" -#include "stdlib.h" -#include "assert.h" -#include "portmidi.h" -#include "porttime.h" -#include "string.h" - -#define MIDI_SYSEX 0xf0 -#define MIDI_EOX 0xf7 - -#define STRING_MAX 80 - -int latency = 0; - -/* read a number from console */ -/**/ -int get_number(char *prompt) -{ - char line[STRING_MAX]; - int n = 0, i; - printf(prompt); - while (n != 1) { - n = scanf("%d", &i); - fgets(line, STRING_MAX, stdin); - - } - return i; -} - - -/* loopback test -- send/rcv from 2 to 1000 bytes of random midi data */ -/**/ -void loopback_test() -{ - int outp; - int inp; - PmStream *midi_in; - PmStream *midi_out; - unsigned char msg[1024]; - char line[80]; - long len; - int i; - int data; - PmEvent event; - int shift; - - Pt_Start(1, 0, 0); - - printf("Connect a midi cable from an output port to an input port.\n"); - printf("This test will send random data via sysex message from output\n"); - printf("to input and check that the correct data was received.\n"); - outp = get_number("Type output device number: "); - /* Open output with 1ms latency -- when latency is non-zero, the Win32 - implementation supports sending sysex messages incrementally in a - series of buffers. This is nicer than allocating a big buffer for the - message, and it also seems to work better. Either way works. - */ - Pm_OpenOutput(&midi_out, outp, NULL, 0, NULL, NULL, latency); - inp = get_number("Type input device number: "); - /* since we are going to send and then receive, make sure the input buffer - is large enough for the entire message */ - Pm_OpenInput(&midi_in, inp, NULL, 512, NULL, NULL); - - srand((unsigned int) Pt_Time()); /* seed for random numbers */ - - while (1) { - PmError count; - long start_time; - long error_position; - long expected = 0; - long actual = 0; - printf("Type return to send message, q to quit: "); - fgets(line, STRING_MAX, stdin); - if (line[0] == 'q') goto cleanup; - - /* compose the message */ - len = rand() % 998 + 2; /* len only counts data bytes */ - msg[0] = (char) MIDI_SYSEX; /* start of SYSEX message */ - /* data bytes go from 1 to len */ - for (i = 0; i < len; i++) { - msg[i + 1] = rand() & 0x7f; /* MIDI data */ - } - /* final EOX goes in len+1, total of len+2 bytes in msg */ - msg[len + 1] = (char) MIDI_EOX; - - /* sanity check: before we send, there should be no queued data */ - count = Pm_Read(midi_in, &event, 1); - - if (count != 0) { - printf("Before sending anything, a MIDI message was found in\n"); - printf("the input buffer. Please try again.\n"); - break; - } - - /* send the message */ - printf("Sending %ld byte sysex message.\n", len + 2); - Pm_WriteSysEx(midi_out, 0, msg); - - /* receive the message and compare to msg[] */ - data = 0; - shift = 0; - i = 0; - start_time = Pt_Time(); - error_position = -1; - /* allow up to 2 seconds for transmission */ - while (data != MIDI_EOX && start_time + 2000 > Pt_Time()) { - count = Pm_Read(midi_in, &event, 1); - /* CAUTION: this causes busy waiting. It would be better to - be in a polling loop to avoid being compute bound. PortMidi - does not support a blocking read since this is so seldom - useful. There is no timeout, so if we don't receive a sysex - message, or at least an EOX, the program will hang here. - */ - if (count == 0) continue; - - /* printf("read %lx ", event.message); - fflush(stdout); */ - - /* compare 4 bytes of data until you reach an eox */ - for (shift = 0; shift < 32 && (data != MIDI_EOX); shift += 8) { - data = (event.message >> shift) & 0xFF; - if (data != msg[i] && error_position < 0) { - error_position = i; - expected = msg[i]; - actual = data; - } - i++; - } - } - if (error_position >= 0) { - printf("Error at byte %ld: sent %lx recd %lx\n", error_position, expected, actual); - } else if (i != len + 2) { - printf("Error: byte %d not received\n", i); - } else { - printf("Correctly "); - } - printf("received %d byte sysex message.\n", i); - } -cleanup: - Pm_Close(midi_out); - Pm_Close(midi_in); - return; -} - - -#define is_real_time_msg(msg) ((0xF0 & Pm_MessageStatus(msg)) == 0xF8) - - -void receive_sysex() -{ - char line[80]; - FILE *f; - PmStream *midi; - int shift = 0; - int data = 0; - int bytes_on_line = 0; - PmEvent msg; - - /* determine which output device to use */ - int i = get_number("Type input device number: "); - - /* open input device */ - Pm_OpenInput(&midi, i, NULL, 512, NULL, NULL); - printf("Midi Input opened, type file for sysex data: "); - - /* open file */ - fgets(line, STRING_MAX, stdin); - /* remove the newline character */ - if (strlen(line) > 0) line[strlen(line) - 1] = 0; - f = fopen(line, "w"); - if (!f) { - printf("Could not open %s\n", line); - Pm_Close(midi); - return; - } - - printf("Ready to receive a sysex message\n"); - - /* read data and write to file */ - while (data != MIDI_EOX) { - PmError count; - count = Pm_Read(midi, &msg, 1); - /* CAUTION: this causes busy waiting. It would be better to - be in a polling loop to avoid being compute bound. PortMidi - does not support a blocking read since this is so seldom - useful. - */ - if (count == 0) continue; - /* ignore real-time messages */ - if (is_real_time_msg(Pm_MessageStatus(msg.message))) continue; - - /* write 4 bytes of data until you reach an eox */ - for (shift = 0; shift < 32 && (data != MIDI_EOX); shift += 8) { - data = (msg.message >> shift) & 0xFF; - /* if this is a status byte that's not MIDI_EOX, the sysex - message is incomplete and there is no more sysex data */ - if (data & 0x80 && data != MIDI_EOX) break; - fprintf(f, "%2x ", data); - if (++bytes_on_line >= 16) { - fprintf(f, "\n"); - bytes_on_line = 0; - } - } - } - fclose(f); - Pm_Close(midi); -} - - -void send_sysex() -{ - char line[80]; - FILE *f; - PmStream *midi; - int data; - int shift = 0; - PmEvent msg; - - /* determine which output device to use */ - int i = get_number("Type output device number: "); - - msg.timestamp = 0; /* no need for timestamp */ - - /* open output device */ - Pm_OpenOutput(&midi, i, NULL, 0, NULL, NULL, latency); - printf("Midi Output opened, type file with sysex data: "); - - /* open file */ - fgets(line, STRING_MAX, stdin); - /* remove the newline character */ - if (strlen(line) > 0) line[strlen(line) - 1] = 0; - f = fopen(line, "r"); - if (!f) { - printf("Could not open %s\n", line); - Pm_Close(midi); - return; - } - - /* read file and send data */ - msg.message = 0; - while (1) { - /* get next byte from file */ - - if (fscanf(f, "%x", &data) == 1) { - /* printf("read %x, ", data); */ - /* OR byte into message at proper offset */ - msg.message |= (data << shift); - shift += 8; - } - /* send the message if it's full (shift == 32) or if we are at end */ - if (shift == 32 || data == MIDI_EOX) { - /* this will send sysex data 4 bytes at a time -- it would - be much more efficient to send multiple PmEvents at once - but this method is simpler. See Pm_WriteSysex for a more - efficient code example. - */ - Pm_Write(midi, &msg, 1); - msg.message = 0; - shift = 0; - } - if (data == MIDI_EOX) { /* end of message */ - fclose(f); - Pm_Close(midi); - return; - } - } -} - - -int main() -{ - int i; - char line[80]; - - /* list device information */ - for (i = 0; i < Pm_CountDevices(); i++) { - const PmDeviceInfo *info = Pm_GetDeviceInfo(i); - printf("%d: %s, %s", i, info->interf, info->name); - if (info->input) printf(" (input)"); - if (info->output) printf(" (output)"); - printf("\n"); - } - latency = get_number("Latency in milliseconds (0 to send data immediatedly,\n" - " >0 to send timestamped messages): "); - while (1) { - printf("Type r to receive sysex, s to send," - " l for loopback test, q to quit: "); - fgets(line, STRING_MAX, stdin); - switch (line[0]) { - case 'r': - receive_sysex(); - break; - case 's': - send_sysex(); - break; - case 'l': - loopback_test(); - case 'q': - exit(0); - default: - break; - } - } - return 0; -} - - - - - diff --git a/pd/portmidi/pm_test/sysex.dsp b/pd/portmidi/pm_test/sysex.dsp deleted file mode 100644 index 329d3ef9..00000000 --- a/pd/portmidi/pm_test/sysex.dsp +++ /dev/null @@ -1,102 +0,0 @@ -# Microsoft Developer Studio Project File - Name="sysex" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=sysex - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "sysex.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "sysex.mak" CFG="sysex - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "sysex - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "sysex - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "sysex - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "sysexRelease" -# PROP Intermediate_Dir "sysexRelease" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\pm_common" /I "..\porttime" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib ..\Release\portmidi.lib ..\porttime\Release\porttime.lib ..\pm_win\Release\pm_dll.lib /nologo /subsystem:console /machine:I386 - -!ELSEIF "$(CFG)" == "sysex - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "sysexDebug" -# PROP Intermediate_Dir "sysexDebug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "..\pm_common" /I "..\porttime" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib ..\pm_win\Debug\portmidi.lib ..\porttime\Debug\porttime.lib ..\pm_win\Debug\pm_dll.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "sysex - Win32 Release" -# Name "sysex - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\sysex.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/pd/portmidi/pm_test/test.c b/pd/portmidi/pm_test/test.c deleted file mode 100644 index ade8564d..00000000 --- a/pd/portmidi/pm_test/test.c +++ /dev/null @@ -1,469 +0,0 @@ -#include "portmidi.h" -#include "porttime.h" -#include "stdlib.h" -#include "stdio.h" -#include "string.h" -#include "assert.h" - -#define INPUT_BUFFER_SIZE 100 -#define OUTPUT_BUFFER_SIZE 0 -#define DRIVER_INFO NULL -#define TIME_PROC ((long (*)(void *)) Pt_Time) -#define TIME_INFO NULL -#define TIME_START Pt_Start(1, 0, 0) /* timer started w/millisecond accuracy */ - -#define STRING_MAX 80 /* used for console input */ - -long latency = 0; - -/* crash the program to test whether midi ports are closed */ -/**/ -void doSomethingReallyStupid() { - int * tmp = NULL; - *tmp = 5; -} - - -/* exit the program without any explicit cleanup */ -/**/ -void doSomethingStupid() { - assert(0); -} - - -/* read a number from console */ -/**/ -int get_number(char *prompt) -{ - char line[STRING_MAX]; - int n = 0, i; - printf(prompt); - while (n != 1) { - n = scanf("%d", &i); - fgets(line, STRING_MAX, stdin); - - } - return i; -} - - -/* - * the somethingStupid parameter can be set to simulate a program crash. - * We want PortMidi to close Midi ports automatically in the event of a - * crash because Windows does not (and this may cause an OS crash) - */ -void main_test_input(unsigned int somethingStupid) { - PmStream * midi; - PmError status, length; - PmEvent buffer[1]; - int num = 10; - int i = get_number("Type input number: "); - /* It is recommended to start timer before Midi; otherwise, PortMidi may - start the timer with its (default) parameters - */ - TIME_START; - - /* open input device */ - Pm_OpenInput(&midi, - i, - DRIVER_INFO, - INPUT_BUFFER_SIZE, - TIME_PROC, - TIME_INFO); - - printf("Midi Input opened. Reading %d Midi messages...\n",num); - Pm_SetFilter(midi, PM_FILT_ACTIVE | PM_FILT_CLOCK); - /* empty the buffer after setting filter, just in case anything - got through */ - while (Pm_Poll(midi)) { - Pm_Read(midi, buffer, 1); - } - /* now start paying attention to messages */ - i = 0; /* count messages as they arrive */ - while (i < num) { - status = Pm_Poll(midi); - if (status == TRUE) { - length = Pm_Read(midi,buffer, 1); - if (length > 0) { - printf("Got message %d: time %ld, %2lx %2lx %2lx\n", - i, - buffer[0].timestamp, - Pm_MessageStatus(buffer[0].message), - Pm_MessageData1(buffer[0].message), - Pm_MessageData2(buffer[0].message)); - i++; - } else { - assert(0); - } - } - /* simulate crash if somethingStupid is 1 or 2 */ - if ((i > (num/2)) && (somethingStupid == 1)) { - doSomethingStupid(); - } else if ((i > (num/2)) && (somethingStupid == 2)) { - doSomethingReallyStupid(); - } - } - - /* close device (this not explicitly needed in most implementations) */ - printf("ready to close..."); - - Pm_Close(midi); - printf("done closing..."); -} - - - -void main_test_output() { - PmStream * midi; - char line[80]; - long off_time; - int chord[] = { 60, 67, 76, 83, 90 }; - #define chord_size 5 - PmEvent buffer[chord_size]; - PmTimestamp timestamp; - - /* determine which output device to use */ - int i = get_number("Type output number: "); - - /* It is recommended to start timer before PortMidi */ - TIME_START; - - /* open output device -- since PortMidi avoids opening a timer - when latency is zero, we will pass in a NULL timer pointer - for that case. If PortMidi tries to access the time_proc, - we will crash, so this test will tell us something. */ - Pm_OpenOutput(&midi, - i, - DRIVER_INFO, - OUTPUT_BUFFER_SIZE, - (latency == 0 ? NULL : TIME_PROC), - (latency == 0 ? NULL : TIME_INFO), - latency); - printf("Midi Output opened with %ld ms latency.\n", latency); - - /* output note on/off w/latency offset; hold until user prompts */ - printf("ready to send program 1 change... (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); - Pm_Write(midi, buffer, 1); - - printf("ready to note-on... (type RETURN):"); - fgets(line, STRING_MAX, stdin); - buffer[0].timestamp = TIME_PROC(TIME_INFO); - buffer[0].message = Pm_Message(0x90, 60, 100); - Pm_Write(midi, buffer, 1); - printf("ready to note-off... (type RETURN):"); - fgets(line, STRING_MAX, stdin); - buffer[0].timestamp = TIME_PROC(TIME_INFO); - buffer[0].message = Pm_Message(0x90, 60, 0); - Pm_Write(midi, buffer, 1); - - /* output short note on/off w/latency offset; hold until user prompts */ - printf("ready to note-on (short form)... (type RETURN):"); - fgets(line, STRING_MAX, stdin); - Pm_WriteShort(midi, TIME_PROC(TIME_INFO), - Pm_Message(0x90, 60, 100)); - printf("ready to note-off (short form)... (type RETURN):"); - fgets(line, STRING_MAX, stdin); - Pm_WriteShort(midi, TIME_PROC(TIME_INFO), - Pm_Message(0x90, 60, 0)); - - /* output several note on/offs to test timing. - Should be 1s between notes */ - printf("chord will arpeggiate if latency > 0\n"); - printf("ready to chord-on/chord-off... (type RETURN):"); - fgets(line, STRING_MAX, stdin); - timestamp = TIME_PROC(TIME_INFO); - for (i = 0; i < chord_size; i++) { - buffer[i].timestamp = timestamp + 1000 * i; - buffer[i].message = Pm_Message(0x90, chord[i], 100); - } - Pm_Write(midi, buffer, chord_size); - - off_time = timestamp + 1000 + chord_size * 1000; - while (TIME_PROC(TIME_INFO) < off_time) - /* busy wait */; - for (i = 0; i < chord_size; i++) { - buffer[i].timestamp = timestamp + 1000 * i; - buffer[i].message = Pm_Message(0x90, chord[i], 0); - } - Pm_Write(midi, buffer, chord_size); - - /* 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"); -} - - -void main_test_both() -{ - int i = 0; - int in, out; - PmStream * midi, * midiOut; - PmEvent buffer[1]; - PmError status, length; - int num = 10; - - in = get_number("Type input number: "); - out = get_number("Type output number: "); - - /* In is recommended to start timer before PortMidi */ - TIME_START; - - Pm_OpenOutput(&midiOut, - out, - DRIVER_INFO, - OUTPUT_BUFFER_SIZE, - TIME_PROC, - TIME_INFO, - latency); - printf("Midi Output opened with %ld ms latency.\n", latency); - /* open input device */ - Pm_OpenInput(&midi, - in, - DRIVER_INFO, - INPUT_BUFFER_SIZE, - TIME_PROC, - TIME_INFO); - printf("Midi Input opened. Reading %d Midi messages...\n",num); - Pm_SetFilter(midi, PM_FILT_ACTIVE | PM_FILT_CLOCK); - /* empty the buffer after setting filter, just in case anything - got through */ - while (Pm_Poll(midi)) { - Pm_Read(midi, buffer, 1); - } - i = 0; - while (i < num) { - status = Pm_Poll(midi); - if (status == TRUE) { - length = Pm_Read(midi,buffer,1); - if (length > 0) { - Pm_Write(midiOut, buffer, 1); - printf("Got message %d: time %ld, %2lx %2lx %2lx\n", - i, - buffer[0].timestamp, - Pm_MessageStatus(buffer[0].message), - Pm_MessageData1(buffer[0].message), - Pm_MessageData2(buffer[0].message)); - i++; - } else { - assert(0); - } - } - } - - /* since close device should not needed, lets get - rid of it just to make sure program exit closes MIDI devices */ - /* Pm_Close(midi); - Pm_Close(midiOut); - Pm_Terminate(); */ -} - - -/* main_test_stream exercises windows winmm API's stream mode */ -/* 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", 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"); -} - - -void show_usage() -{ - printf("Usage: test [-h] [-l latency-in-ms]\n"); - exit(0); -} - -int main(int argc, char *argv[]) -{ - int i = 0, n = 0; - char line[STRING_MAX]; - int test_input = 0, test_output = 0, test_both = 0, somethingStupid = 0; - int stream_test = 0; - int latency_valid = FALSE; - - for (i = 1; i < argc; i++) { - if (strcmp(argv[i], "-h") == 0) { - show_usage(); - } else if (strcmp(argv[i], "-l") == 0 && (i + 1 < argc)) { - i = i + 1; - latency = atoi(argv[i]); - printf("Latency will be %ld\n", latency); - latency_valid = TRUE; - } else { - show_usage(); - } - } - - while (!latency_valid) { - printf("Latency in ms: "); - if (scanf("%ld", &latency) == 1) { - latency_valid = TRUE; - } - } - - /* determine what type of test to run */ - printf("begin portMidi test...\n"); - printf("%s%s%s%s%s", - "enter your choice...\n 1: test input\n", - " 2: test input (fail w/assert)\n", - " 3: test input (fail w/NULL assign)\n", - " 4: test output\n 5: test both\n", - " 6: stream test\n"); - while (n != 1) { - n = scanf("%d", &i); - fgets(line, STRING_MAX, stdin); - switch(i) { - case 1: - test_input = 1; - break; - case 2: - test_input = 1; - somethingStupid = 1; - break; - case 3: - test_input = 1; - somethingStupid = 2; - break; - case 4: - test_output = 1; - break; - case 5: - test_both = 1; - break; - case 6: - stream_test = 1; - break; - default: - printf("got %d (invalid input)\n", n); - break; - } - } - - /* list device information */ - for (i = 0; i < Pm_CountDevices(); i++) { - const PmDeviceInfo *info = Pm_GetDeviceInfo(i); - if (((test_input | test_both) & info->input) | - ((test_output | test_both | stream_test) & info->output)) { - printf("%d: %s, %s", i, info->interf, info->name); - if (info->input) printf(" (input)"); - if (info->output) printf(" (output)"); - printf("\n"); - } - } - - /* run test */ - if (stream_test) { - main_test_stream(); - } else if (test_input) { - main_test_input(somethingStupid); - } else if (test_output) { - main_test_output(); - } else if (test_both) { - main_test_both(); - } - - printf("finished portMidi test...type ENTER to quit..."); - fgets(line, STRING_MAX, stdin); - return 0; -} diff --git a/pd/portmidi/pm_test/test.dsp b/pd/portmidi/pm_test/test.dsp deleted file mode 100644 index 66ba3e91..00000000 --- a/pd/portmidi/pm_test/test.dsp +++ /dev/null @@ -1,102 +0,0 @@ -# Microsoft Developer Studio Project File - Name="test" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=test - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "test.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "test.mak" CFG="test - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "test - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "test - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "test - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "testRelease" -# PROP Intermediate_Dir "testRelease" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "../pm_common" /I "../porttime" /D "WIN32" /D "DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib ..\Release\portmidi.lib ..\porttime\Release\porttime.lib ..\pm_win\Release\pm_dll.lib /nologo /subsystem:console /machine:I386 - -!ELSEIF "$(CFG)" == "test - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "testDebug" -# PROP Intermediate_Dir "testDebug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../pm_common" /I "../porttime" /D "_CONSOLE" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "USE_DLL_FOR_CLEANUP" /FR /YX /FD /GZ /c -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib ..\pm_win\Debug\portmidi.lib ..\porttime\Debug\porttime.lib ..\pm_win\Debug\pm_dll.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "test - Win32 Release" -# Name "test - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\test.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/pd/portmidi/pm_test/txdata.syx b/pd/portmidi/pm_test/txdata.syx deleted file mode 100644 index 1e06e5a6..00000000 --- a/pd/portmidi/pm_test/txdata.syx +++ /dev/null @@ -1,257 +0,0 @@ -20 0 1d 4 c 6 0 34 1 4d 4 d 1f 7 3 6 - c 5e 4 4d d b 18 5 3 6 0 3d 1 4a 16 18 -1f 8 3 6 d 0 1 63 4 13 3a 23 0 0 0 2 - c 2 4 0 63 32 0 0 0 32 0 47 72 61 6e 64 -50 69 61 6e 6f 63 63 63 32 32 32 0 0 0 0 0 -10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1f 9 9 f c 27 2 35 37 10 1f 4 3 4 - d 19 4 56 5 16 1f f 8 d c 0 43 60 4 e -1f c 3 7 e 0 43 63 5 10 3c 14 8 2 1b 56 - 5 2 4 0 63 32 0 0 0 32 0 4c 6f 54 69 6e -65 38 31 5a 20 63 63 63 32 32 32 0 7f 0 1 0 -18 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1f e f e 9 0 3 43 2d e 1f f 5 7 - f 16 43 5a 0 0 1f 12 6 8 d 0 3 63 4 0 -1f 12 6 8 f 0 2 63 4 6 34 14 0 1 2 4e -18 2 4 0 63 32 0 32 0 32 0 44 79 6e 6f 6d -69 74 65 45 50 63 63 63 32 32 32 0 70 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1f b 1 b 8 18 40 5f a e 1f 1f 0 a - f 0 40 5f 4 0 1f 1f 0 a f 0 40 63 5 6 -1f 1f 0 a f 0 40 5f 0 8 1f 20 0 3 0 5a -18 4 4 0 63 32 32 0 0 32 0 50 65 72 63 4f -72 67 61 6e 20 63 63 63 32 32 32 0 0 0 0 0 - 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1f b 7 f 9 0 4 49 13 13 1f 8 7 5 - e 0 2 58 0 c 1f 6 4 6 f 23 3 46 10 a -1f 7 8 c d 0 2 63 8 b 2 1c 0 0 0 52 -18 4 4 0 63 32 0 32 0 32 0 54 68 69 6e 20 -43 6c 61 76 20 63 63 63 32 32 32 0 70 0 20 0 -10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1f c 0 6 1 a 4 50 20 e 1f c 0 6 - 1 a 4 50 1f 8 1f b 9 5 e 0 2 63 5 e -1f b 9 5 e 0 3 63 4 8 4 1a 0 0 0 52 -1d 2 4 0 63 32 0 32 0 32 0 42 72 69 74 65 -43 65 6c 73 74 63 63 63 32 32 32 0 20 0 26 0 - 1 0 8 4 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 f 1f 4 8 f 0 3a 51 4 b e 1f 0 8 - f 0 22 4b 4 3 f 1a b 8 d 0 3b 36 9 3 -12 1f 0 8 f 0 22 5d 4 b 3a 1e 19 5 0 52 -18 4 4 0 63 32 0 0 0 32 0 54 72 75 6d 70 -65 74 38 31 5a 63 63 63 32 32 32 0 0 0 50 0 -51 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 c 5 0 8 0 0 2 4a 4 b f 1f 0 8 - f 0 2 3f 4 3 1f f 0 8 0 23 3 44 b 3 -10 1f 0 9 f 0 2 5e 4 c 3a 1f 19 7 0 52 -18 4 4 0 63 32 0 0 0 32 0 46 6c 75 67 65 -6c 68 6f 72 6e 63 63 63 32 32 32 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 10 1f 0 8 f 0 42 4a 0 3 11 1f 0 8 - f a 43 51 0 3 11 9 0 8 d 0 42 2b 16 6 -10 1f 0 9 f 0 42 63 4 b 3a 1e 9 9 0 5a -24 4 4 0 63 32 31 0 0 32 0 52 61 73 70 41 -6c 74 6f 20 20 63 63 63 32 32 32 0 10 0 20 0 -54 0 20 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 10 9 2 6 d 0 41 3e 4 15 c b 2 3 - e 0 41 4f 4 12 c e 2 8 d 0 42 4b a 1c - d b 1 9 e 0 3 63 a 14 0 23 f 2 1b 5e -18 4 5 0 63 28 50 32 0 32 0 48 61 72 6d 6f -6e 69 63 61 20 63 63 63 32 32 32 0 50 10 50 0 -50 0 10 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1c 2 0 4 e 63 0 4e 4 3 d 5 0 6 - e 63 1 56 a 8 12 7 0 6 9 63 2 47 1b e - a a 0 5 f 0 1 63 4 b 32 1a 8 d 0 52 - c 4 4 0 63 32 0 0 0 32 0 44 6f 75 62 6c -65 42 61 73 73 63 63 63 32 32 32 0 10 0 0 0 - 3 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 b 4 0 4 f 14 2 49 9 6 a 7 0 4 - f 14 2 51 a 0 8 1f 0 5 f 0 1 63 9 6 - a 1f 0 5 f 0 1 63 a 0 3c 1f 6 9 0 52 - 5 4 4 0 63 32 0 0 0 32 0 48 69 53 74 72 -69 6e 67 20 31 63 63 63 32 32 32 0 2 0 30 0 -32 0 10 5 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 10 13 f 4 a 0 3 3b 14 14 1f e 8 7 - 9 0 2 42 5 e 18 13 d 9 c 0 2 3c 13 8 -1f 11 7 4 f 0 42 63 4 10 3a 1b 0 0 0 52 -1d 4 4 0 63 32 0 0 0 32 0 48 61 72 70 20 -20 20 20 20 20 63 63 63 32 32 32 8 0 0 21 0 - 0 0 8 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1f 6 6 4 f 0 40 48 5 0 c 8 7 5 - f 5 0 52 4 0 f 7 3 7 e 8 3 63 4 6 - f 8 4 5 f 0 3 63 4 6 7c 1f 0 6 0 4a -11 2 4 0 63 32 0 0 0 32 0 46 61 6e 66 61 -72 54 70 74 73 63 63 63 32 32 32 6 1 0 38 0 - 8 0 48 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 d b 0 1 c 0 2 2c 3d 3 d 7 0 1 - c 0 2 1f 3c 3 d 1f 0 5 f 0 2 63 5 6 - d 1f 0 5 f 0 2 63 4 0 3c 63 0 2f 0 53 -11 4 4 0 63 32 0 0 0 32 0 42 72 65 61 74 -68 4f 72 67 6e 63 63 63 32 32 32 4 30 5 50 0 -11 0 18 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1f 9 0 6 0 27 2 51 19 b 1c 6 0 8 - 0 37 2 47 a 3 1f a 0 9 0 3d 2 4d a e -1f 12 8 8 f 0 3 61 4 b 28 1f 0 3 0 52 - c 3 4 0 63 32 1 32 0 32 0 4e 79 6c 6f 6e -47 75 69 74 20 63 63 63 32 32 32 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1f e e f f 0 3 48 2d 6 1f f 4 f - f 25 3 5b 0 0 1f 12 6 c e 1c 3 55 0 10 -1f 13 7 8 e 6 4 62 4 e 3b 14 0 0 0 42 -18 2 4 0 63 32 0 32 0 32 0 47 75 69 74 61 -72 20 23 31 20 63 63 63 32 32 32 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1f 19 8 a 3 0 3 63 10 18 1f c 5 b - 5 0 3 52 0 b 1f 19 6 b 5 0 3 63 a 16 -1f f 11 9 7 0 4 63 4 3 3a 14 0 0 0 42 -18 2 4 0 63 32 0 32 0 32 0 46 75 6e 6b 79 -20 50 69 63 6b 63 63 63 32 32 32 0 30 0 0 0 - 0 0 0 7 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1f 1 0 8 4 0 3 3d a 1e 1f 1 0 8 - 0 0 0 43 0 10 1f 9 6 8 c 1b 7 46 1c 1e -1f 9 0 9 9 0 1 63 4 3 3a 1c 0 0 0 52 - c 4 5 0 63 4b 0 0 0 32 0 45 6c 65 63 42 -61 73 73 20 31 63 63 63 32 32 32 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1f f f e 9 0 3 46 1d 16 1f f 5 e - e d 3 63 0 b 1f 13 6 5 d 1c 3 63 0 0 -1f 13 6 8 f 0 4 63 4 6 3b 1f 0 0 0 42 - c 4 4 0 63 32 0 32 0 32 0 53 79 6e 46 75 -6e 6b 42 61 73 63 63 63 32 32 32 d 6c 0 0 0 -70 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1f 10 7 8 3 0 3 4f 4 3 1f 9 0 8 - 0 0 1 4a 0 b 1f 11 0 8 0 0 1 47 4 8 -1f 9 0 8 0 0 0 63 0 b 39 19 0 7 0 52 - c 2 4 0 63 32 0 32 0 32 0 4c 61 74 65 6c -79 42 61 73 73 63 63 63 32 32 32 2 0 0 0 0 -40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 13 12 0 9 d 22 0 51 0 b 1f 14 0 5 - 8 24 40 5c 0 3 1f 11 0 6 c 2c 0 53 9 0 -10 1f 0 b f 0 0 5c a e 3a 22 11 e 1e 5e -18 7 4 0 63 32 0 32 0 32 0 53 79 6e 63 20 -4c 65 61 64 20 63 63 63 32 32 32 0 70 0 40 0 - 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 13 1e 0 9 e 0 0 63 3f b 1f 14 0 5 - e 24 1 51 4 3 1f 14 0 f 1 0 41 4d 8 3 - f 1f 0 b f 0 2 63 4 b 3b 20 11 12 33 56 -18 4 4 0 63 37 e 0 0 32 0 4a 61 7a 7a 20 -46 6c 75 74 65 63 63 63 32 32 32 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 15 13 d 3 d 1e 2 50 18 e 15 14 9 4 - c 1e 2 56 11 8 1b 1f f 7 f 0 1 63 4 6 -1a 1f e 6 f 0 2 63 4 0 7c b 0 8 0 62 -18 4 4 0 63 32 0 0 0 32 0 4a 61 76 61 20 -4a 69 76 65 20 63 63 63 32 32 32 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1f 0 0 4 f 0 40 63 3c 0 b 8 7 7 - f 5 0 63 4 6 f 5 3 7 f 8 0 3b 5 6 - e 8 4 5 f 0 3 63 3 0 7e 1d 6 f 0 4a -11 0 4 0 63 32 0 0 0 32 0 42 61 61 64 42 -72 65 61 74 68 63 63 63 32 32 32 6 30 0 38 0 - 1 0 46 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1f 0 0 4 f 0 40 47 2f 0 e 8 7 7 - f 5 0 4c 0 6 13 1c d c 6 8 0 63 5 6 -14 11 d b 0 0 3 63 4 0 7a 10 0 51 0 68 -17 0 4 0 63 32 0 0 0 32 0 56 6f 63 61 6c -4e 75 74 73 20 63 63 63 32 32 32 6 30 0 30 0 - 1 0 10 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1f 1f 0 5 f 0 0 41 32 3 1f 14 10 5 - 5 1 2 63 7 3 1f b 12 8 f 0 1 63 c 3 -1f 1f f 8 f 0 1 63 4 3 39 23 0 0 0 62 -18 7 4 0 63 32 0 0 0 32 0 57 61 74 65 72 -47 6c 61 73 73 63 63 63 32 32 32 0 0 0 0 0 - 0 0 0 7 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 16 2 0 4 6 9 1 4f 8 0 19 e 1 4 - 0 20 1 43 19 0 1f 12 10 6 7 0 0 54 3d 3 -16 d 6 6 2 1e 3 61 8 e 3a 20 1 14 0 42 - c 2 4 2 63 63 63 0 0 32 0 46 75 7a 7a 79 -20 4b 6f 74 6f 63 63 63 32 32 32 0 0 0 0 b -50 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1c 8 0 3 e 0 1 55 12 3 1c 7 0 1 - e 2e 1 58 27 b e 4 0 2 a 0 2 63 4 a - d 9 0 2 c 1 2 63 10 b 4 54 0 47 0 53 -18 7 4 0 63 32 0 0 0 32 0 42 72 74 68 62 -65 6c 6c 73 20 63 63 63 32 32 32 0 4 0 40 0 -40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1a 4 1 1 b 16 0 47 5 3 15 e 0 1 - d 0 0 4c 5 16 1c 6 4 2 7 0 0 63 4 16 -18 18 3 1 e 0 0 5e 4 10 24 7 0 4 0 62 -24 4 4 0 63 32 0 0 0 32 0 54 75 62 65 20 -42 65 6c 6c 73 63 63 63 32 32 32 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1f 1f 13 3 0 0 0 5f 3d 6 1f 12 13 2 - 0 0 1 52 5 2 1f 14 13 3 0 0 1 56 28 5 -1e b 13 f 9 0 0 63 6 3 3b 63 0 63 0 73 -23 7 4 0 63 32 0 0 0 32 0 4e 6f 69 73 65 -20 53 68 6f 74 63 63 63 32 32 32 8 0 0 0 8 - 0 0 0 6 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1f 16 0 3 7 0 1 50 0 3 1f 18 3 3 - 3 22 0 63 0 14 1d 7 6 3 6 0 1 3c 8 3 -1f 5 7 3 0 0 1 63 4 1b 39 23 0 8 0 42 -18 4 4 0 63 32 0 0 0 32 0 48 61 6e 64 20 -44 72 75 6d 20 63 63 63 32 32 32 0 1 0 3 0 - 1 0 1 3 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 7d f7 \ No newline at end of file -- cgit v1.2.1