diff options
Diffstat (limited to 'portmidi/pm_win/README_WIN.txt')
| -rwxr-xr-x | portmidi/pm_win/README_WIN.txt | 174 |
1 files changed, 0 insertions, 174 deletions
diff --git a/portmidi/pm_win/README_WIN.txt b/portmidi/pm_win/README_WIN.txt deleted file mode 100755 index 8bfb467..0000000 --- a/portmidi/pm_win/README_WIN.txt +++ /dev/null @@ -1,174 +0,0 @@ -File: PortMidi Win32 Readme
-Author: Belinda Thom, June 16 2002
-Revised by: Roger Dannenberg, June 2002, May 2004, June 2007,
- Umpei Kurokawa, June 2007
- Roger Dannenberg Sep 2009, May 2022
-
-Contents:
- Using Portmidi
- To Install Portmidi
- To Compile Portmidi
- About Cmake
- Using other versions of Visual C++
- To Create Your Own Portmidi Client Application
-
-
-
-=============================================================================
-USING PORTMIDI:
-=============================================================================
-
-I recommend building a static library and linking with your
-application. PortMidi is not large. See ../README.md for
-basic compiling instructions.
-
-The Windows version has a couple of extra switches: You can define
-DEBUG and MMDEBUG for a few extra messages (see the code).
-
-If PM_CHECK_ERRORS is defined, PortMidi reports and exits on any
-error. This requires terminal output to see, and aborts your
-application, so it's only intended for quick command line programs
-where you do not care to check return values and handle errors
-more robustly.
-
-PortMidi is designed to run without a console and should work perfectly
-well within a graphical user interface application.
-
-Read the portmidi.h file for PortMidi API details on using the PortMidi API.
-See <...>\pm_test\testio.c and other files in pm_test for usage examples.
-
-There are many other programs in pm_test, including a MIDI monitor.
-
-
-============================================================================
-DESIGN NOTES
-============================================================================
-
-Orderly cleanup after errors are encountered is based on a fixed order of
-steps and state changes to reflect each step. Here's the order:
-
-To open input:
- initialize return value to NULL
- - allocate the PmInternal strucure (representation of PortMidiStream)
- return value is (non-null) PmInternal structure
- - allocate midi buffer
- set buffer field of PmInternal structure
- - call system-dependent open code
- - allocate midiwinmm_type for winmm dependent data
- set descriptor field of PmInternal structure
- - open device
- set handle field of midiwinmm_type structure
- - allocate buffers
- - start device
- - return
- - return
-
-SYSEX HANDLING
-
-There are three cases: simple output, stream output, input
-Each must deal with:
- 1. Buffer Initialization (creating buffers)
- 2. Buffer Allocation (finding a free buffer)
- 3. Buffer Fill (putting bytes in the buffer)
- 4. Buffer Preparation (midiOutPrepare, etc.)
- 5. Buffer Send (to Midi device)
- 6. Buffer Receive (in callback)
- 7. Buffer Empty (removing bytes from buffer)
- 8. Buffer Free (returning to the buffer pool)
- 9. Buffer Finalization (returning to heap)
-
-Here's how simple output handles sysex:
- 1. Buffer Initialization (creating buffers)
- allocated when code tries to write first byte to a buffer
- the test is "if (!m->sysex_buffers[0]) { ... }"
- this field is initialized to NULL when device is opened
- the size is SYSEX_BYTES_PER_BUFFER
- allocate_sysex_buffers() does the initialization
- note that the actual size of the allocation includes
- additional space for a MIDIEVENT (3 longs) which are
- not used in this case
- 2. Buffer Allocation (finding a free buffer)
- see get_free_sysex_buffer()
- cycle through m->sysex_buffers[] using m->next_sysex_buffer
- to determine where to look next
- if nothing is found, wait by blocking on m->sysex_buffer_signal
- this is signaled by the callback every time a message is
- received
- 3. Buffer Fill (putting bytes in the buffer)
- essentially a state machine approach
- hdr->dwBytesRecorded is a position in message pointed to by m->hdr
- keep appending bytes until dwBytesRecorded >= SYSEX_BYTES_PER_BUFFER
- then send the message, reseting the state to initial values
- 4. Buffer Preparation (midiOutPrepare, etc.)
- just before sending in winmm_end_sysex()
- 5. Buffer Send (to Midi device)
- message is padded with zero at end (since extra space was allocated
- this is ok) -- the zero works around a bug in (an old version of)
- MIDI YOKE drivers
- dwBufferLength gets dwBytesRecorded, and dwBytesRecorded gets 0
- uses midiOutLongMsg()
- 6. Buffer Receive (in callback)
- 7. Buffer Empty (removing bytes from buffer)
- not applicable for output
- 8. Buffer Free (returning to the buffer pool)
- unprepare message to indicate that it is free
- SetEvent on m->buffer_signal in case client is waiting
- 9. Buffer Finalization (returning to heap)
- when device is closed, winmm_out_delete frees all sysex buffers
-
-Here's how stream output handles sysex:
- 1. Buffer Initialization (creating buffers)
- same code as simple output (see above)
- 2. Buffer Allocation (finding a free buffer)
- same code as simple output (see above)
- 3. Buffer Fill (putting bytes in the buffer)
- essentially a state machine approach
- m->dwBytesRecorded is a position in message
- keep appending bytes until buffer is full (one byte to spare)
- 4. Buffer Preparation (midiOutPrepare, etc.)
- done before sending message
- dwBytesRecorded and dwBufferLength are set in winmm_end_sysex
- 5. Buffer Send (to Midi device)
- uses midiStreamOutMsg()
- 6. Buffer Receive (in callback)
- 7. Buffer Empty (removing bytes from buffer)
- not applicable for output
- 8. Buffer Free (returning to the buffer pool)
- unprepare message to indicate that it is free
- SetEvent on m->buffer_signal in case client is waiting
- 9. Buffer Finalization (returning to heap)
- when device is closed, winmm_out_delete frees all sysex buffers
-
-
-Here's how input handles sysex:
- 1. Buffer Initialization (creating buffers)
- two buffers are allocated in winmm_in_open
- 2. Buffer Allocation (finding a free buffer)
- same code as simple output (see above)
- 3. Buffer Fill (putting bytes in the buffer)
- not applicable for input
- 4. Buffer Preparation (midiOutPrepare, etc.)
- done before sending message -- in winmm_in_open and in callback
- 5. Buffer Send (to Midi device)
- uses midiInAddbuffer in allocate_sysex_input_buffer (called from
- winmm_in_open) and callback
- 6. Buffer Receive (in callback)
- 7. Buffer Empty (removing bytes from buffer)
- done without pause in loop in callback
- 8. Buffer Free (returning to the buffer pool)
- done by midiInAddBuffer in callback, no pointer to buffers
- is retained except by device
- 9. Buffer Finalization (returning to heap)
- when device is closed, empty buffers are delivered to callback,
- which frees them
-
-IMPORTANT: In addition to the above, PortMidi now has
-"shortcuts" to optimize the transfer of sysex data. To enable
-the optimization for sysex output, the system-dependent code
-sets fields in the pmInternal structure: fill_base, fill_offset_ptr,
-and fill_length. When fill_base is non-null, the system-independent
-part of PortMidi is allowed to directly copy sysex bytes to
-"fill_base[*fill_offset_ptr++]" until *fill_offset_ptr reaches
-fill_length. See the code for details.
-
-
|
