Explorar o código

Version 1.0.3

Gary Scavone %!s(int64=11) %!d(string=hai) anos
pai
achega
71b723e4cb
Modificáronse 5 ficheiros con 83 adicións e 30 borrados
  1. 1 1
      RtMidi.cpp
  2. 18 4
      RtMidi.h
  3. 3 3
      doc/doxygen/tutorial.txt
  4. 3 0
      doc/release.txt
  5. 58 22
      tests/midiout.cpp

+ 1 - 1
RtMidi.cpp

@@ -35,7 +35,7 @@
 */
 /**********************************************************************/
 
-// RtMidi: Version 1.0.2, 21 September 2004
+// RtMidi: Version 1.0.3, 22 November 2004
 
 #include "RtMidi.h"
 #include <sstream>

+ 18 - 4
RtMidi.h

@@ -35,7 +35,7 @@
 */
 /**********************************************************************/
 
-// RtMidi: Version 1.0.2, 21 September 2004
+// RtMidi: Version 1.0.3, 22 November 2004
 
 #ifndef RTMIDI_H
 #define RTMIDI_H
@@ -45,10 +45,26 @@
 
 class RtMidi
 {
+ public:
+
+  //! Pure virtual openPort() function.
+  virtual void openPort( unsigned int portNumber = 0 ) = 0;
+
+  //! Pure virtual openVirtualPort() function.
+  virtual void openVirtualPort() = 0;
+
+  //! Pure virtual getPortCount() function.
+  virtual unsigned int getPortCount() = 0;
+
+  //! Pure virtual getPortName() function.
+  virtual std::string getPortName( unsigned int portNumber = 0 ) = 0;
+
+  //! Pure virtual closePort() function.
+  virtual void closePort( void ) = 0;
+
  protected:
 
   RtMidi();
-
   virtual ~RtMidi() {};
 
   // A basic error reporting function for internal use in the RtMidi
@@ -56,8 +72,6 @@ class RtMidi
   // suit specific needs.
   void error( RtError::Type type );
 
-  virtual void openPort( unsigned int portNumber = 0 ) = 0;
-
   void *apiData_;
   bool connected_;
   std::string errorString_;

+ 3 - 3
doc/doxygen/tutorial.txt

@@ -19,11 +19,11 @@ MIDI input and output functionality are separated into two classes, RtMidiIn and
 
 \section download Download
 
-Latest Release (21 September 2004): <A href="http://music.mcgill.ca/~gary/rtmidi/release/rtmidi-1.0.2.tar.gz">Version 1.0.2 (111 kB tar/gzipped)</A>
+Latest Release (22 November 2004): <A href="http://music.mcgill.ca/~gary/rtmidi/release/rtmidi-1.0.3.tar.gz">Version 1.0.3</A>
 
 \section start Getting Started
 
-The first thing that must be done when using RtMidi is to create an instance of the RtMidiIn or RtMidiOut subclasses.  RtMidi is an abstract base class, which itself cannot be instantiated.  Each default constructor attempts to establish any necessary "connections" with the underlying MIDI system.  RtMidi uses C++ exceptions to report errors, necessitating try/catch blocks around many member functions.  An RtError can be thrown during instantiation in some circumstances.  A warning message may also be reported if no MIDI devices are found during instantiation.  The RtMidi classes have been designed to work with "hot pluggable" or virtual (software) MIDI devices, making it is possible to connect or start MIDI devices after the classes have been instantiated.  The following code example demonstrates default object construction and destruction:
+The first thing that must be done when using RtMidi is to create an instance of the RtMidiIn or RtMidiOut subclasses.  RtMidi is an abstract base class, which itself cannot be instantiated.  Each default constructor attempts to establish any necessary "connections" with the underlying MIDI system.  RtMidi uses C++ exceptions to report errors, necessitating try/catch blocks around many member functions.  An RtError can be thrown during instantiation in some circumstances.  A warning message may also be reported if no MIDI devices are found during instantiation.  The RtMidi classes have been designed to work with "hot pluggable" or virtual (software) MIDI devices, making it possible to connect to MIDI devices that may not have been present when the classes were instantiated.  The following code example demonstrates default object construction and destruction:
 
 \code
 
@@ -198,7 +198,7 @@ The RtMidiIn class provides the RtMidiIn::ignoreTypes() function to specify that
 
 \subsection qmidiin Queued MIDI Input
 
-The RtMidiIn::getMessage() function does not block.  If a MIDI message is available in the queue, it is copied to the user-provided \c std::vector<unsigned char> container.  When no MIDI message is available, the function returns an empty container.  The default maximum MIDI queue size is 1024 messages.  This value may be modified with the RtMidiIn::setQueueSizeLimit() function.  If the maximum queue size limit is reached, subsequent MIDI messages are discarded until the queue size is reduced.
+The RtMidiIn::getMessage() function does not block.  If a MIDI message is available in the queue, it is copied to the user-provided \c std::vector<unsigned char> container.  When no MIDI message is available, the function returns an empty container.  The default maximum MIDI queue size is 1024 messages.  This value may be modified with the RtMidiIn::setQueueSizeLimit() function.  If the maximum queue size limit is reached, subsequent incoming MIDI messages are discarded until the queue size is reduced.
 
 In the following example, we omit some necessary error checking and details regarding OS-dependent sleep functions.  For a more complete example, see the \c qmidiin.cpp program in the \c tests directory.
 

+ 3 - 0
doc/release.txt

@@ -2,6 +2,9 @@ RtMidi - a set of C++ classes which provide a common API for realtime MIDI input
 
 By Gary P. Scavone, 2003-2004.
 
+v1.0.3: (22 November 2004)
+- added common pure virtual functions to RtMidi abstract base class
+
 v1.0.2: (21 September 2004)
 - added warning messages to openVirtualPort() functions in Windows and Irix (where it can't be implemented)
 

+ 58 - 22
tests/midiout.cpp

@@ -18,22 +18,16 @@
   #define SLEEP( milliseconds ) usleep( (unsigned long) (milliseconds * 1000.0) )
 #endif
 
-void usage(void) {
-  // Error function in case of incorrect command-line
-  // argument specifications.
-  std::cout << "\nuseage: midiout <port>\n";
-  std::cout << "    where port = the device to use (default = 0).\n\n";
-  exit(0);
-}
+// This function should be embedded in a try/catch block in case of
+// an exception.  It offers the user a choice of MIDI ports to open.
+// It returns false if there are no ports available.
+bool chooseMidiPort( RtMidi *rtmidi );
 
 int main(int argc, char *argv[])
 {
   RtMidiOut *midiout = 0;
   std::vector<unsigned char> message;
 
-  // Minimal command-line check.
-  if ( argc > 2 ) usage();
-
   // RtMidiOut constructor
   try {
     midiout = new RtMidiOut();
@@ -43,19 +37,9 @@ int main(int argc, char *argv[])
     exit(EXIT_FAILURE);
   }
 
-  // Check available ports vs. specified.
-  unsigned int port = 0;
-  unsigned int nPorts = midiout->getPortCount();
-  if ( argc == 2 ) port = (unsigned int) atoi( argv[1] );
-  if ( port >= nPorts ) {
-    delete midiout;
-    std::cout << "Invalid port specifier!\n";
-    usage();
-  }
-
+  // Call function to select port.
   try {
-    midiout->openPort( port );
-    //midiout->openVirtualPort();
+    if ( chooseMidiPort( midiout ) == false ) goto cleanup;
   }
   catch (RtError &error) {
     error.printMessage();
@@ -104,3 +88,55 @@ int main(int argc, char *argv[])
 
   return 0;
 }
+
+bool chooseMidiPort( RtMidi *rtmidi )
+{
+  bool isInput = false;
+  if ( typeid( *rtmidi ) == typeid( RtMidiIn ) )
+    isInput = true;
+
+  if ( isInput )
+    std::cout << "\nWould you like to open a virtual input port? [y/N] ";
+  else
+    std::cout << "\nWould you like to open a virtual output port? [y/N] ";
+
+  std::string keyHit;
+  std::getline( std::cin, keyHit );
+  if ( keyHit == "y" ) {
+    rtmidi->openVirtualPort();
+    return true;
+  }
+
+  std::string portName;
+  unsigned int i = 0, nPorts = rtmidi->getPortCount();
+  if ( nPorts == 0 ) {
+    if ( isInput )
+      std::cout << "No input ports available!" << std::endl;
+    else
+      std::cout << "No output ports available!" << std::endl;
+    return false;
+  }
+
+  if ( nPorts == 1 ) {
+    std::cout << "\nOpening " << rtmidi->getPortName() << std::endl;
+  }
+  else {
+    for ( i=0; i<nPorts; i++ ) {
+      portName = rtmidi->getPortName(i);
+      if ( isInput )
+        std::cout << "  Input port #" << i << ": " << portName << '\n';
+      else
+        std::cout << "  Output port #" << i << ": " << portName << '\n';
+    }
+
+    do {
+      std::cout << "\nChoose a port number: ";
+      std::cin >> i;
+    } while ( i >= nPorts );
+  }
+
+  std::cout << "\n";
+  rtmidi->openPort( i );
+
+  return true;
+}