Porting notes (07/07/97) ----------------------------------------------------------------------- Introduction: Starting with maplay 1.2+ 1.81, I will try to make the source as portable as possible. If you succeed in doing a port, please e-mail the changes to me so everyone can benefit. You will be credited accordingly, and you may distribute your port freely. I have included output classes for a few other operating systems, but I modified them slightly, and haven't tested the modified versions. These came either from Tobias Bading's maplay 1.2, maplay 1.3, or John Fehr. Thanks go out to Tobias Bading for his original, portable maplay with lots of Obuffer implementations, John Fehr for the new command-line source and his BeOS Obuffer and the HP-UX buffer that uses the audio server, and Timo Jantunen for his OS/2 buffer. ----------------------------------------------------------------------- General guidelines: You shouldn't have to delete anything, just add stuff. Try not to mess around with too much stuff because you think it's bad style, or whatever. The less you change, the easier it will be for me to include your source in later releases of maplay, and the harder it will be for you to use later releases of maplay. Try to keep track of your changes so you can tell me what you did. If you can, please support Borland compilers. They gave me a free copy of BC++ 5.01, which is the reason for maplay 1.2+ getting as far as it has. Not to mention that Borland compilers are probably the best on the market. I highly discourage using my code with ActiveX. I hate Microsoft's internet strategy, which is basically the use of its vast resources to replace anything well-written out there, like Java and Netscape, with its own proprietary crap. (For example, integrating the operating system shell with a WWW browser -- totally ridiculous and a transparent move to make Netscape obsolete that must violate some anti-trust law). Perhaps my mind has been warped by the disgusting "smooth scrolling" of Internet Explorer, but I don't want any part in what Microsoft is trying to accomplish with ActiveX. ----------------------------------------------------------------------- How maplay works: The general idea is that you have a main() that passes : 1. a newly created input bitstream 2. a newly created header, with get_header() called already using the input bitstream of (1) 3. a mutex if you want your port to be seekable or stoppable once it has begun playing 4. various decoding options such as which channels to decode, whether to use stdout for output, whether to use the headphone output, etc. These parameters are passed through the MPEG_Args class to maplay(), which will continue to decode the stream until it is finished, or, if your port is stoppable, until the "stop" member of the MPEG_Args class is set to TRUE. maplay() will create an operating system dependent output buffer by calling create_obuffer(), and begin decoding. ----------------------------------------------------------------------- Here is a rough procedure of what you need to do: 1. First you must decide what #define's to have. Here is a list of of meanings if the following #defines are on: __WIN32__ : Port is for Win32, like Windows 95, Windows NT, or Win32s AIX : Port is for IBM AIX BEOS : Port is for BeOS HPUX : Port is for HP-UX IRIX : Port is for SGI Indigo 4.0 (ELF version of libaudio needed for 5.*, which is not distributed with 5.2) LINUX : Port is for Linux __FreeBSD__ : Port is for FreeBSD NeXT : Port is for NeXTStep SPARC : Port is for Sun SPARC, running Solaris or SunOS OS2 : Port is for OS/2 (The previous operating systems already have output buffers written for them; the output buffer for FreeBSD is the same as the one for Linux. You may add your own defines for your operating system, i.e. DOS, SYSTEM7, etc.) If SPARC is defined, the following may be defined: Solaris : Solaris machine SunOS : Any SunOS (must be defined if any of the last 3 are) SunOS4_1_1 : SunOS version 4.1.1 or 4.1B SunOS4_1_3 : SunOS version 4.1.3 or 4.1C SunOS5+ : SunOS version 5.* ULAW : For SPARC, BEOS, or the file output buffer, use 8 kHz, ulaw output (may not work correctly) VERBOSE : For non-GUI versions, enable printing of stream information. GUI : Port is going to run in a window, so errors are reported to dialog boxes instead of using cerr. This must be defined if you are going to use any of the below xxxGUI defines. WIN32GUI : Port is going to run in Win32 as a GUI version (You may add your own defines for your windowing system, i.e. X11R6GUI, TCLTKGUI, OS2GUI, etc.) SIXTEEN_BIT_COMPILER : "int" on your compiler is a 16 bit integer, used for older compilers, like for DOS or Windows 3.1 NObool : The "bool" type is not defined in your compiler. I think this is for older, non-ANSI C++ compilers. DAMN_INTEL_BYTE_ORDER : Platform you want to port to is little endian, like Intel x86's or Motorola 68k's. Also the Windows NT platform is little endian. SEEK_STOP : The decoding of the stream will be seekable or stoppable by the user once decoding has begun. This requires the use of threads and mutexes. PENTIUM : Optional define that is used to mark the version as optimized for the Pentium processor. It is only used when printing the version information. If you have one of the supported operating systems, you may be able to do a port just by changing defines and recompiling (and probably making a Makefile)! 2. Copy all of the files you need into one directory. For example, if you are porting to an Indigo machine, copy the files "/Indigo/indigo_obuffer.cc", "/Indigo/indigo_obuffer.h", and "/Indigo/Makefile" into the same directory as the rest of the source files. This is so that the Makefiles and shell scripts will work. 3. If you are not porting for a UNIX system or Win32, you will probably need to modify "ibitstr.cpp" so you can read from files. 4. If you are porting to an operating system not mentioned in the above #define's, you also need to implement a output buffer to write to the audio device. Use the virtual Obuffer class as the parent of your new Obuffer class, and implement the functions declared in the Obuffer class. If you want or need to have more information passed to your new Obuffer, you can add members to the MPEG_Args class (in "all.h"). Finally write a function to return a pointer to a new instance of _your_ Obuffer, with the prototype : Obuffer *create_obuffer(MPEG_Args *maplay_args); Include the header for your new obuffer class in "obuffer.h", and include the implementation file (*.cc) in "obuffer.cpp". 5. If you have decided to make your port seekable or stoppable, you will have to fill in the missing functions in the OBuffer subclasses (except in mci_obuf.cpp). Also you will have to fill in the type for the mutex in "all.h" and implement locking and unlocking in "mutx_imp.h". After initializing the MPEG_Args, create a new thread running maplay(). Your interface will communicate with maplay() through the members of the MPEG_Args class. When seeking or stopping, remember to lock the mutex before accessing or changing the volatile variables that tell maplay to stop, seek, where to seek, etc. After you have read or written the appropriate variables, unlock the mutex. Communication with the parent process in maplay() should be also be filled in. 6. If you want a command-line interface, make any necessary changes to "cmdline.cpp". These changes will probably be setting different members of the MPEG_Args class. If you planning on doing a GUI version, you're pretty much on your own for that. 7. If you are doing a GUI version, fill in the parts where an error message would have been sent to cerr, and instead pop open a message box with the error message. Errors are reported in "maplay.cpp", "header.cpp", and "ibitstr.cpp". 8. Create a Makefile if necessary. I have no idea how to make Makefiles but I have included the Makefile from maplay 1.3b, "Makefile.old", which should help. You can get most of the compiler flags for your operating system in the file "config.sh.old"; just add the necessary defines from above. Also there is a working Makefile for the Indigo you can look at "/Indigo/Makefile". An alternative to making a Makefile is to make a shell script that will compile all the files and link them. For an example, see "/FreeBSD/freebsd.sh" When creating the Makefile or shell script, please assume all the necessary source files and the Makefile or script itself are in the same directory. 9. Once you are done, add yourself to the "credits.txt" file! Congratulations! Please send me your changes as well as your Makefile. Then you can distribute your port and be as famous as me (Jeffy Tee-Say ???who???)!! ----------------------------------------------------------------------- Here is a list of successful ports, the porters, and the necessary defines: Platform Porter #define's @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ BeOS Thomas Philippe BEOS, VERBOSE tphilippe@sdv.fr FreeBSD Jeff Tsay __FREEBSD__, VERBOSE, DAMN_INTEL_BYTE_ORDER PENTIUM (on Pentium version) HP-UX Earle Philhower HPUX, VERBOSE earle@geocities.com SGI Indigo Andres Meyer IRIX, VERBOSE ameyer@desun1.epfl.ch Win32 GUI for x86 Jeff Tsay __WIN32__, SEEK_STOP, DAMN_INTEL_BYTE_ORDER, GUI, WIN32GUI, PENTIUM (on Pentium version) WinNT GUI for Thomas Krantz __WIN32__, SEEK_STOP, DEC Alpha aga@krantz.pp.se DAMN_INTEL_BYTE_ORDER, GUI, WIN32GUI Win32 commandline Jeff Tsay __WIN32__, VERBOSE, for x86 DAMN_INTEL_BYTE_ORDER, PENTIUM (on Pentium version) @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Links to the binaries of these ports are on my maplay homepage at: http://www-inst.eecs.berkeley.edu/~ctsay/mp2win32.html The above ports are "straight ports", meaning that no extra functionality was added. Ports with additional features include versions for Linux and OS/2 by Timo Jantunen (jeti@niksula.hut.fi) and SoundApp for the Macintosh, a player with support for multiple sound formats by Norme Franke (franke@xenon.stanford.edu). ----------------------------------------------------------------------- Jeff Tsay (ctsay@pasteur.eecs.berkeley.edu)