gearmulator

Emulation of classic VA synths of the late 90s/2000s that are based on Motorola 56300 family DSPs
Log | Files | Refs | Submodules | README | LICENSE

README_WIN.txt (15978B)


      1 File: PortMidi Win32 Readme
      2 Author: Belinda Thom, June 16 2002
      3 Revised by: Roger Dannenberg, June 2002, May 2004, June 2007, 
      4             Umpei Kurokawa, June 2007
      5             Roger Dannenberg Sep 2009
      6 
      7 Contents:
      8         Using Portmidi
      9         To Install Portmidi
     10         To Compile Portmidi
     11         About Cmake
     12         Using other versions of Visual C++
     13         To Create Your Own Portmidi Client Application
     14         
     15 
     16 
     17 =============================================================================
     18 USING PORTMIDI:
     19 =============================================================================
     20 
     21 Using Microsoft Visual C++ project files (provided with PortMidi), there
     22 are two configurations of the PortMidi library. The Debug version is 
     23 intended for debugging, especially in a console application. The Debug
     24 version enables some extra error checking and outputs some text as well
     25 as a prompt to type ENTER so that you don't lose any debugging text when
     26 the program exits. You can turn off this extra debugging info by taking
     27 out the compile-time definition for DEBUG. (But leave _DEBUG, which I
     28 think is important for compiling in Debug mode.) This debugging version also
     29 defines PM_CHECK_ERRORS, which forces a check for error return codes from
     30 every call to PortMidi. You can disable this checking (especially if you
     31 want to handle error codes in your own way) by removing PM_CHECK_ERRORS
     32 from the predefined symbols list in the Settings dialog box.
     33 
     34 PortMidi is designed to run without a console and should work perfectly 
     35 well within a graphical user interface application. The Release version
     36 is both optimized and lacking the debugging printout code of the Debug
     37 version.
     38 
     39 Read the portmidi.h file for PortMidi API details on using the PortMidi API.
     40 See <...>\pm_test\test.c and other files in pm_test for usage examples.
     41 
     42 =============================================================================
     43 TO INSTALL PORTMIDI:
     44 =============================================================================
     45 1)  get current source from the portmedia project at SourceForge.net
     46 
     47 2)  copy source into directory: <...>\portmidi
     48 
     49 =============================================================================
     50 TO COMPILE PORTMIDI:
     51 =============================================================================
     52 
     53 3)  cd to or open the portmidi directory
     54 
     55 4)  start or click on the portmidi.sln workspace (note, all Visual Studio
     56     files are built by CMake. If you need a different version or have
     57     problems with paths, try rebuilding the Visual Studio project files
     58     using CMake -- See "Using other versions of visual C++" below.)
     59 	
     60 5)  the following projects exist within this workspace:
     61     - portmidi-static, portmidi-dynamic (versions of the PortMidi library)
     62     - test (simple midi I/O testing)
     63     - midithread (an example illustrating low-latency MIDI processing
     64         using a dedicated low-latency thread)
     65     - sysex (simple sysex message I/O testing)
     66     - latency (uses porttime to measure system latency)
     67     - midithru (an example illustrating software MIDI THRU)
     68     - qtest (a test of the new multicore-safe queue implementation)
     69     - mm  (allows monitoring of midi messages)
     70     - pmjni (a dll to provide an interface to PortMidi for Java)
     71 
     72 6)  set the Java SDK path using one of two methods:
     73     Method 1: open portmidi/CMakeLists.txt with CMake, configure, and 
     74         generate -- this should find the Java SDK path and update your
     75             solution and project files
     76     Method 2: (does not require CMake):
     77         - open the pmjni project properties
     78         - visit Configuration Properties, C/C++, General
     79         - find Additional Include Directories property and open the editor (...)
     80         - at the end of the list, you will find two paths mentioning Java
     81         - these are absolute paths to the Java SDK; you'll need to install the
     82           Java SDK (from Sun) and update these directories in order to build
     83           this project.
     84         - similarly, the Linker->Input->Additional Dependencies list has a
     85           path to the jvm.lib file, which needs to be correct(ed).
     86 
     87 6)  use Build->Batch Build ... to build everything in the project. If a 
     88     build fails, try building again. There seem to be some missing 
     89     dependencies, so you may have to "ALL_BUILD" several times before
     90     everything builds successfully.
     91 	
     92 7)  The settings for these projects were distributed in the zip file, so
     93     compile should just work.
     94 
     95 8)  run test project; use the menu that shows up from the command prompt to
     96     test that portMidi works on your system. tests include: 
     97 		- verify midi output works
     98 		- verify midi input works
     99 
    100 9) run other projects if you wish: sysex, latency, midithread, mm, 
    101     qtest, midithru
    102 
    103 10) compile the java code:
    104     - cd pm_java
    105     - make.bat
    106         + If there is a problem running javac, note that you must have
    107           a path to javac.exe on your PATH environment variable. Edit
    108           your path (in Vista) using Control Panel > User Accounts > 
    109           User Accounts > Change my environment variables; then select
    110           Path and click Edit... After changing, you will have to 
    111           restart the command window to see any effect.
    112         + In Vista, you may get a warning about running 
    113           UpdateRsrcJavaExe.exe. This is called by make.bat, and you
    114           should allow the program to run.
    115         + Note that make.bat does not build pmjni\jportmidi_JPortMidiApi.h
    116           because it is included in the distribution. You can rebuild it 
    117           from sources as follows:
    118               cd pm_java
    119               javah jportmidi.JPortMidiApi
    120               move jportmidi_JPortMidiApi pmjni\jportmidi_JPortMidiApi.h
    121        
    122 11) you might wish to move pm_java/win32 to another location; run the
    123     pmdefaults.exe program from the (entire) win32 directory to use 
    124     PmDefaults. This program let's you select default input/output 
    125     midi devices for PortMidi applications.
    126 
    127 ============================================================================
    128 ABOUT CMAKE
    129 ============================================================================
    130 
    131 cmake was used to generate .vcproj files. cmake embeds absolute paths
    132 into .vcproj files, which makes the files non-portable to other systems.
    133 To work around this problem, pm_win\clean_up_vcproj.bat can be used to 
    134 replace absolute paths with relative paths. To use it, you will need to
    135 install gawk and set your search path to allow you to execute gawk, e.g. 
    136 my path includes "C:\Program Files\GnuWin32\bin;". You will also need to
    137 edit pm_win\clean_up_vcproj.awk, replacing C:\Users\rbd\portmidi with
    138 whatever absolute path cmake uses in your vcproj files.
    139 
    140 This is not a general or robust fix, but it seems to work with the 
    141 vcproj files currently created by CMake.
    142 
    143 ============================================================================
    144 USING OTHER VERSIONS OF VISUAL C++
    145 ============================================================================
    146 
    147 You can use cmake to make Visual Studio solution and project files.
    148 If you do not want to use the provided Version 9 project files, install
    149 cmake, run it, set the "Where is the source code" box to your portmidi
    150 directory, and click on Configure. A menu will allow you to choose the
    151 Visual Studio project version you want. Click Configure once again, then
    152 Generate, and you should be all set to open portmidi.sln.
    153 
    154 ============================================================================
    155 TO CREATE YOUR OWN PORTMIDI CLIENT APPLICATION:
    156 ============================================================================
    157 
    158 NOTE: this section needs to be reviewed and tested. My suggestion would
    159 be to copy the test project file (test.dsp) and modify it. -RBD
    160 
    161 The easiest way is to start a new project w/in the portMidi workspace:
    162 
    163 1) To open new project: 
    164 	- File->New->Projects
    165 	- Location: <...>\portmidi\<yourProjectName>
    166 	- check Add to current workspace
    167 	- select Win32 Console Application (recommended for now)
    168 	- do *NOT* select the "make dependency" box (you will explicitly do this
    169       in the next step)
    170 	- Click OK
    171 	- Select "An Empty Project" and click Finish
    172 	
    173 	In Visual C++ 2005 Express Edition, 
    174 	- File->New->Projects
    175 	- Location: <...>\portmidi\<yourProjectName>
    176 	- select Add to solution
    177 	- select CLR Empty project in CLR
    178 	- select Win32 Console Application in Win32
    179 	- select Empty project in General
    180 	
    181 2) Now this project will be the active project. Make it explicitly depend
    182    on PortMidi dll:
    183 	- Project->Dependencies
    184 	- Click pm_dll
    185 
    186 3) add whatever files you wish to add to your new project, using portMidi
    187    calls as desired (see USING PORTMIDI at top of this readme)
    188 
    189 4) when you include portMidi files, do so like this:
    190 	- #include "..\pm_common\portmidi.h"
    191 	- etc.
    192 
    193 5) build and run your project
    194 
    195 ============================================================================
    196 DESIGN NOTES
    197 ============================================================================
    198 
    199 PortMidi for Win32 exists as a simple static library,
    200 with Win32-specific code in pmwin.c and MM-specific code in pmwinmm.c.
    201 
    202 Orderly cleanup after errors are encountered is based on a fixed order of
    203 steps and state changes to reflect each step. Here's the order:
    204 
    205 To open input:
    206     initialize return value to NULL
    207     - allocate the PmInternal strucure (representation of PortMidiStream)
    208     return value is (non-null) PmInternal structure
    209     - allocate midi buffer
    210     set buffer field of PmInternal structure
    211     - call system-dependent open code
    212         - allocate midiwinmm_type for winmm dependent data
    213         set descriptor field of PmInternal structure
    214         - open device
    215         set handle field of midiwinmm_type structure
    216         - allocate buffers
    217         - start device
    218         - return
    219     - return
    220 
    221 SYSEX HANDLING -- the most complex, least exercised, and therefore most
    222       buggy part of PortMidi (but maybe bugs are finally gone)
    223 
    224 There are three cases: simple output, stream output, input
    225 Each must deal with:
    226  1. Buffer Initialization (creating buffers)
    227  2. Buffer Allocation (finding a free buffer)
    228  3. Buffer Fill (putting bytes in the buffer)
    229  4. Buffer Preparation (midiOutPrepare, etc.)
    230  5. Buffer Send (to Midi device)
    231  6. Buffer Receive (in callback)
    232  7. Buffer Empty (removing bytes from buffer)
    233  8. Buffer Free (returning to the buffer pool)
    234  9. Buffer Finalization (returning to heap)
    235 
    236 Here's how simple output handles sysex:
    237  1. Buffer Initialization (creating buffers)
    238   allocated when code tries to write first byte to a buffer
    239   the test is "if (!m->sysex_buffers[0]) { ... }"
    240   this field is initialized to NULL when device is opened
    241   the size is SYSEX_BYTES_PER_BUFFER
    242   allocate_sysex_buffers() does the initialization
    243   note that the actual size of the allocation includes
    244       additional space for a MIDIEVENT (3 longs) which are
    245       not used in this case
    246  2. Buffer Allocation (finding a free buffer)
    247   see get_free_sysex_buffer()
    248   cycle through m->sysex_buffers[] using m->next_sysex_buffer
    249       to determine where to look next
    250   if nothing is found, wait by blocking on m->sysex_buffer_signal
    251   this is signaled by the callback every time a message is
    252       received
    253  3. Buffer Fill (putting bytes in the buffer)
    254   essentially a state machine approach
    255   hdr->dwBytesRecorded is a position in message pointed to by m->hdr
    256   keep appending bytes until dwBytesRecorded >= SYSEX_BYTES_PER_BUFFER
    257   then send the message, reseting the state to initial values
    258  4. Buffer Preparation (midiOutPrepare, etc.)
    259   just before sending in winmm_end_sysex()
    260  5. Buffer Send (to Midi device)
    261   message is padded with zero at end (since extra space was allocated
    262       this is ok) -- the zero works around a bug in (an old version of)
    263       MIDI YOKE drivers
    264   dwBufferLength gets dwBytesRecorded, and dwBytesRecorded gets 0
    265   uses midiOutLongMsg()
    266  6. Buffer Receive (in callback)
    267  7. Buffer Empty (removing bytes from buffer)
    268   not applicable for output
    269  8. Buffer Free (returning to the buffer pool)
    270   unprepare message to indicate that it is free
    271   SetEvent on m->buffer_signal in case client is waiting
    272  9. Buffer Finalization (returning to heap)
    273   when device is closed, winmm_out_delete frees all sysex buffers
    274 
    275 Here's how stream output handles sysex:
    276  1. Buffer Initialization (creating buffers)
    277   same code as simple output (see above)
    278  2. Buffer Allocation (finding a free buffer)
    279   same code as simple output (see above)
    280  3. Buffer Fill (putting bytes in the buffer)
    281   essentially a state machine approach
    282   m->dwBytesRecorded is a position in message
    283   keep appending bytes until buffer is full (one byte to spare)
    284  4. Buffer Preparation (midiOutPrepare, etc.)
    285   done before sending message
    286   dwBytesRecorded and dwBufferLength are set in winmm_end_sysex
    287  5. Buffer Send (to Midi device)
    288   uses midiStreamOutMsg()
    289  6. Buffer Receive (in callback)
    290  7. Buffer Empty (removing bytes from buffer)
    291   not applicable for output
    292  8. Buffer Free (returning to the buffer pool)
    293   unprepare message to indicate that it is free
    294   SetEvent on m->buffer_signal in case client is waiting
    295  9. Buffer Finalization (returning to heap)
    296   when device is closed, winmm_out_delete frees all sysex buffers
    297 
    298 
    299 Here's how input handles sysex:
    300  1. Buffer Initialization (creating buffers)
    301   two buffers are allocated in winmm_in_open
    302  2. Buffer Allocation (finding a free buffer)
    303   same code as simple output (see above)
    304  3. Buffer Fill (putting bytes in the buffer)
    305   not applicable for input
    306  4. Buffer Preparation (midiOutPrepare, etc.)
    307   done before sending message -- in winmm_in_open and in callback
    308  5. Buffer Send (to Midi device)
    309   uses midiInAddbuffer in allocate_sysex_input_buffer (called from
    310       winmm_in_open) and callback
    311  6. Buffer Receive (in callback)
    312  7. Buffer Empty (removing bytes from buffer)
    313       done without pause in loop in callback
    314  8. Buffer Free (returning to the buffer pool)
    315   done by midiInAddBuffer in callback, no pointer to buffers
    316       is retained except by device
    317  9. Buffer Finalization (returning to heap)
    318   when device is closed, empty buffers are delivered to callback,
    319       which frees them
    320 
    321 IMPORTANT: In addition to the above, PortMidi now has
    322 "shortcuts" to optimize the transfer of sysex data. To enable
    323 the optimization for sysex output, the system-dependent code
    324 sets fields in the pmInternal structure: fill_base, fill_offset_ptr,
    325 and fill_length. When fill_base is non-null, the system-independent
    326 part of PortMidi is allowed to directly copy sysex bytes to
    327 "fill_base[*fill_offset_ptr++]" until *fill_offset_ptr reaches
    328 fill_length. See the code for details.
    329 
    330 -----------
    331 
    332 Additional notes on using VS 2005 (maybe this is obsolete now?):
    333 
    334 1) Make sure "Configuration: All Configurations" is selected in all of the following Properties modifications!
    335 
    336 2) In my case the project defaulted to compiling all .c files with the C++ compiler, which was disastrous. I had to go to set Properties for each file, to wit: Expand Configuration Properties, Expand C/C++, Select Advanced, set the Compile As popup to Compile as C Code (/TC). (For better or worse, the project I inherited has a bunch of .c files that rely on C++ features, so I couldn't reliably set this the project properties level.)
    337 
    338 3) While you're there, make sure that the C/C++ -> General -> "Compile with Common Language Runtime support" is set to "No Common Language Runtime support" (the C compiler *can't* support CLR, but VS won't do anything useful like automatically set the two options to match)-.
    339 
    340 4) I never got VS precompiled header thing to work sensibly, so I took the path of least resistance and turned PCH's off for all my files. Properties -> Configuration Properties -> C/C++ -> Precompiled Headers -> Create/Use Precompiled Header popup set to "Not Using Precompiled Headers". The compiler is reasonably fast even if it has to parse all the header files, so unless someone wants to explain VS's PCHs to me, the hell with it, I say.
    341