rplay-3.3.2/ 40755 153 62 0 6727650101 11224 5ustar boynsstaffrplay-3.3.2/doc/ 40755 153 62 0 6727650076 12004 5ustar boynsstaffrplay-3.3.2/doc/Makefile.in100644 153 62 3637 6552756453 14161 0ustar boynsstaffinclude @RPLAY_TOP@/Makefile.config srcdir = @srcdir@ VPATH = @srcdir@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ MKINSTALLDIRS= @srcdir@/../mkinstalldirs .SUFFIXES: .SUFFIXES: .texi .info .dvi .ps .html .texi.info: $(MAKEINFO) $(MAKEINFO_FLAGS) $< .texi.dvi: $(TEXI2DVI) $(TEXI2DVI_FLAGS) $< .dvi.ps: $(DVIPS) $< -o .texi.html: $(TEXI2HTML) $(TEXI2HTML_FLAGS) $< all: info: RPLAY.info RPTP.info librplay.info rplay.info dvi: RPLAY.dvi RPTP.dvi librplay.dvi rplay.dvi ps: RPLAY.ps RPTP.ps librplay.ps rplay.ps html: RPLAY.html RPTP.html librplay.html rplay.html man: ./genman rplay.1.in ./genman rptp.1.in ./genman rplayd.8.in install: all -$(MKINSTALLDIRS) $(mandir)/man1 $(mandir)/man5 $(mandir)/man8 $(infodir) -$(INSTALL_DATA) rplay.1 $(mandir)/man1 -$(INSTALL_DATA) rplayd.8 $(mandir)/man8 -$(INSTALL_DATA) rptp.1 $(mandir)/man1 -$(INSTALL_DATA) rplay.conf.5 $(mandir)/man5 -$(INSTALL_DATA) rplay.helpers.5 $(mandir)/man5 -$(INSTALL_DATA) rplay.hosts.5 $(mandir)/man5 -$(INSTALL_DATA) rplay.servers.5 $(mandir)/man5 -$(INSTALL_DATA) RPLAY.info $(infodir)/RPLAY.info -$(INSTALL_DATA) RPTP.info $(infodir)/RPTP.info -$(INSTALL_DATA) librplay.info $(infodir)/librplay.info -$(INSTALL_DATA) rplay.info $(infodir)/rplay.info uninstall: -$(RM) $(mandir)/man1/rplay.1 -$(RM) $(mandir)/man8/rplayd.8 -$(RM) $(mandir)/man1/rptp.1 -$(RM) $(mandir)/man5/rplay.conf.5 -$(RM) $(mandir)/man5/rplay.helpers.5 -$(RM) $(mandir)/man5/rplay.hosts.5 -$(RM) $(mandir)/man5/rplay.servers.5 -$(RM) $(infodir)/RPLAY.info -$(RM) $(infodir)/RPTP.info -$(RM) $(infodir)/librplay.info -$(RM) $(infodir)/rplay.info clean: $(RM) *~ *.bak *.orig $(RM) *.aux *.cp *.cps *.fn *.fns *.ky *.kys *.log $(RM) *.pg *.pgs *.toc *.tp *.tps *.vr *.vrs $(RM) *.ev *.evs *.ov *.ovs *.cv *.cvs *.ma *.mas distclean: clean $(RM) Makefile $(RM) *.html *.dvi *.ps tags: TAGS: etags: depend: rplay-3.3.2/doc/RPLAY.info100644 153 62 12051 6552756453 13666 0ustar boynsstaffThis is Info file RPLAY.info, produced by Makeinfo-1.63 from the input file RPLAY.texi. This file documents RPLAY protocol. Copyright (C) 1995 Mark Boyns Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions.  File: RPLAY.info, Node: Top, Next: Overview, Prev: (dir), Up: (dir) RPLAY ***** This file documents the RPLAY protocol. * Menu: * Overview:: Prelimary information * Commands:: List of supported commands. * Attributes:: List of supported command attributes. * Packet description:: What a RPLAY packet looks like.  File: RPLAY.info, Node: Overview, Next: Commands, Prev: Top, Up: Top Overview ******** The `RPLAY' protocol uses simple binary UDP packets to control the audio server. Communication between the client and server is one-way - packets are sent to the server and the server *never* replies.  File: RPLAY.info, Node: Commands, Next: Attributes, Prev: Overview, Up: Top Commands ******** `RPLAY' is based on a small set of commands which are used to control the audio server. These commands are: `RPLAY_PLAY' Play a sound. `RPLAY_STOP' Stop a sound. `RPLAY_PAUSE' Pause a sound. `RPLAY_CONTINUE' Continue a sound. `RPLAY_PING' Wakeup the server. This command was introduced to solve a problem with TCP clients that are trying to connect to a server that's started by inetd using a UDP port. `RPLAY_RESET' Force the server to reset itself. A reset normally involves re-reading all database files, closing all connections, and stops all playing sounds. `RPLAY_DONE' Force a sound to be done. In most cases this is the same as `RPLAY_STOP'.  File: RPLAY.info, Node: Attributes, Next: Packet description, Prev: Commands, Up: Top Attributes ********** Most `RPLAY' commands use attributes to modify their behaviour. These attributes are: `RPLAY_COUNT' The number of times to play a sound. The value should be between 0 and 255 inclusive. A value of 0 will play the sound forever. The default is RPLAY_DEFAULT_COUNT. `RPLAY_LIST_COUNT' The number of times to play a sound list. The value should be between 0 and 255 inclusive. A value of 0 will play the sound forever. The default is RPLAY_DEFAULT_LIST_COUNT. `RPLAY_PRIORITY' The priority of a sound. The value should be between RPLAY_MIN_PRIORITY (0) and RPLAY_MAX_PRIORITY (255). The default is RPLAY_DEFAULT_PRIORITY (0). `RPLAY_RPTP_FROM_SENDER' Tell the rplay server that it should try to contact the sender's RPTP server to obtain RPLAY_SOUND. This is only used if the rplay server does not already have the sound. `RPLAY_RPTP_SERVER' Tell the rplay server which RPTP server should be used to try and obtain RPLAY_SOUND. This is only used if the rplay server does not already have the sound and RPLAY_RPTP_SEARCH is true. `RPLAY_RPTP_SEARCH' Tell the rplay server whether or not it should search for RPLAY_SOUND. `RPLAY_RPTP_SERVER_PORT' Tell the rplay server which port should be used to contact the RPTP server when using RPLAY_RPTP_SEARCH. `RPLAY_SAMPLE_RATE' Play a sound at a specified sample rate. A value of 0 will use the sound's default sample rate. The default value is RPLAY_DEFAULT_SAMPLE_RATE (0). `RPLAY_SOUND' The name of a sound. `RPLAY_VOLUME' The volume of a sound. The value should be between RPLAY_MIN_VOLUME (0) and RPLAY_MAX_VOLUME (255). The default is RPLAY_DEFAULT_VOLUME (127).  File: RPLAY.info, Node: Packet description, Prev: Attributes, Up: Top Packet description ****************** RPLAY packets always begin with a RPLAY_ID byte followed by a RPLAY command. (*note Commands::.) The remaining contents is a list of attributes (*note Attributes::.) and their corresponding values. The packet is terminated with the RPLAY_NULL attribute. A packet will never contain an attribute that is set to a default value. This feature allows new attributes to be added without breaking old servers and it also makes packets very small. Here's an example packet: RPLAY_ID RPLAY_PLAY RPLAY_SOUND RPLAY_NULL 30 1 5 bogus.au 0 Note that numbers in RPLAY packets are stored in one byte and strings are always null-terminated. The above example in hexadecimal would be: 1E 01 05 62 6f 67 75 73 2E 61 75 00 00  Tag Table: Node: Top734 Node: Overview1124 Node: Commands1425 Node: Attributes2252 Node: Packet description4129  End Tag Table rplay-3.3.2/doc/RPLAY.texi100644 153 62 13503 6552756453 13707 0ustar boynsstaff\input texinfo @c -*-texinfo-*- @c %**start of header @setfilename RPLAY.info @settitle The RPLAY Protocol @iftex @finalout @end iftex @setchapternewpage odd @c %**end of header @ifinfo This file documents RPLAY protocol. Copyright (C) 1995 Mark Boyns Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. @ignore Permission is granted to process this file through Tex and print the results, provided the printed document carries copying permission notice identical to this one except for the removal of this paragraph (this paragraph not being relevant to the printed manual). @end ignore Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions. @end ifinfo @titlepage @title The RPLAY Protocol @author by Mark Boyns @page @vskip 0pt plus 1filll Copyright @copyright{} 1995 Mark Boyns Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions. @end titlepage @page @node Top, Overview, (dir), (dir) @top RPLAY @ifinfo This file documents the RPLAY protocol. @end ifinfo @menu * Overview:: Prelimary information * Commands:: List of supported commands. * Attributes:: List of supported command attributes. * Packet description:: What a RPLAY packet looks like. @end menu @node Overview, Commands, Top, Top @chapter Overview The @code{RPLAY} protocol uses simple binary UDP packets to control the audio server. Communication between the client and server is one-way - packets are sent to the server and the server @emph{never} replies. @node Commands, Attributes, Overview, Top @chapter Commands @code{RPLAY} is based on a small set of commands which are used to control the audio server. These commands are: @table @code @item RPLAY_PLAY Play a sound. @item RPLAY_STOP Stop a sound. @item RPLAY_PAUSE Pause a sound. @item RPLAY_CONTINUE Continue a sound. @item RPLAY_PING Wakeup the server. This command was introduced to solve a problem with TCP clients that are trying to connect to a server that's started by inetd using a UDP port. @item RPLAY_RESET Force the server to reset itself. A reset normally involves re-reading all database files, closing all connections, and stops all playing sounds. @item RPLAY_DONE Force a sound to be done. In most cases this is the same as @samp{RPLAY_STOP}. @end table @node Attributes, Packet description, Commands, Top @chapter Attributes Most @code{RPLAY} commands use attributes to modify their behaviour. These attributes are: @table @code @item RPLAY_COUNT The number of times to play a sound. The value should be between 0 and 255 inclusive. A value of 0 will play the sound forever. The default is RPLAY_DEFAULT_COUNT. @item RPLAY_LIST_COUNT The number of times to play a sound list. The value should be between 0 and 255 inclusive. A value of 0 will play the sound forever. The default is RPLAY_DEFAULT_LIST_COUNT. @item RPLAY_PRIORITY The priority of a sound. The value should be between RPLAY_MIN_PRIORITY (0) and RPLAY_MAX_PRIORITY (255). The default is RPLAY_DEFAULT_PRIORITY (0). @item RPLAY_RPTP_FROM_SENDER Tell the rplay server that it should try to contact the sender's RPTP server to obtain RPLAY_SOUND. This is only used if the rplay server does not already have the sound. @item RPLAY_RPTP_SERVER Tell the rplay server which RPTP server should be used to try and obtain RPLAY_SOUND. This is only used if the rplay server does not already have the sound and RPLAY_RPTP_SEARCH is true. @item RPLAY_RPTP_SEARCH Tell the rplay server whether or not it should search for RPLAY_SOUND. @item RPLAY_RPTP_SERVER_PORT Tell the rplay server which port should be used to contact the RPTP server when using RPLAY_RPTP_SEARCH. @item RPLAY_SAMPLE_RATE Play a sound at a specified sample rate. A value of 0 will use the sound's default sample rate. The default value is RPLAY_DEFAULT_SAMPLE_RATE (0). @item RPLAY_SOUND The name of a sound. @item RPLAY_VOLUME The volume of a sound. The value should be between RPLAY_MIN_VOLUME (0) and RPLAY_MAX_VOLUME (255). The default is RPLAY_DEFAULT_VOLUME (127). @end table @node Packet description, , Attributes, Top @chapter Packet description RPLAY packets always begin with a RPLAY_ID byte followed by a RPLAY command. (@pxref{Commands}) The remaining contents is a list of attributes (@pxref{Attributes}) and their corresponding values. The packet is terminated with the RPLAY_NULL attribute. A packet will never contain an attribute that is set to a default value. This feature allows new attributes to be added without breaking old servers and it also makes packets very small. @noindent Here's an example packet: @example RPLAY_ID RPLAY_PLAY RPLAY_SOUND RPLAY_NULL 30 1 5 bogus.au 0 @end example @noindent Note that numbers in RPLAY packets are stored in one byte and strings are always null-terminated. The above example in hexadecimal would be: @example 1E 01 05 62 6f 67 75 73 2E 61 75 00 00 @end example @summarycontents @contents @bye rplay-3.3.2/doc/RPTP.info100644 153 62 65434 6552756453 13601 0ustar boynsstaffThis is Info file RPTP.info, produced by Makeinfo-1.63 from the input file RPTP.texi. This file documents RPTP protocol. Copyright (C) 1995 Mark Boyns Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions.  File: RPTP.info, Node: Top, Next: Overview, Prev: (dir), Up: (dir) RPTP **** This document describes the Remote Play Transfer Protocol, otherwise known as RPTP. * Menu: * Overview:: * Attributes:: * Events:: * Event Notification:: * Commands:: * Connecting:: * Timeouts:: * Attribute Index:: Attribute Index. * Event Index:: Event Index. * Command Index:: Command Index.  File: RPTP.info, Node: Overview, Next: Attributes, Prev: Top, Up: Top Overview ******** RPTP is a command-based TCP interface to control the rplay audio server. The protocol is simple, the client sends a command and the server sends back a result. Name-value pairs are used in both commands and results. A name-value pair is of the form `name=value' where `name' is an attribute name and `value' is the value of the attribute. Multiple name-value pairs on a line are separated by a spaces and/or tabs. When `value' contains spaces or tabs it must be quoted as `name="value"'. Commands consist of a command name followed by command attributes. An example would be `play volume=50 sound=bogus.au'. In this case, the command is `play' and its attributes are `volume=50' and `sound=bogus.au'. The server responds to each command with a result line. Each result line begins with a special character which is used to determine command success or failure. The following characaters are defined: `+' Successful command execution (RPTP_OK) `-' Error (RPTP_ERROR) `!' Connection timeout (RPTP_TIMEOUT) `@' Event notification (RPTP_NOTIFY) After this first character, the result line contains name-value pairs. For example, if the server wanted to report an error to the client, the result line could be: `-error="sorry, you can't do that"'. There is one RPTP command that returns more than one line. This is the list command which returns a normal result line followed by zero or more lines terminated by a line containing only a `.'. These additional lines do not begin with any special characters. Future versions may include an attribute that clients can use to determine the number of lines that will be returned. All RPTP lines are terminated using a carriage return `\r' (ASCII 13) followed by a newline `\n' (ASCII 10).  File: RPTP.info, Node: Attributes, Next: Events, Prev: Overview, Up: Top Attributes ********** The following is a list of attributes that can be found within the name-value lists. - Attribute: access A set of characters defining access permissions. These characters can include `r' - read access, `w' - write access, and `x' - execute access. Example: access=rwx - Attribute: application The name of an rplay application. Example: application="rptp 3.2.0a7" - Attribute: audio-bits The number of bits in an audio sample or audio device. The value can be 8, 16, and maybe 24 and 32 in the future. Example: audio-bits=16 - Attribute: audio-bufsize The size in bytes of the audio buffer. Example: audio-bufsize=1600 - Attribute: audio-byte-order The byte order of the audio data. The value can be either big-endian or little-endian. Example: audio-byte-order=big-endian - Attribute: audio-channels The number of channels in an audio sample or audio device. The value can be 1 or 2. Example: audio-channels=2 - Attribute: audio-device The name of an audio device. The value can be any audio device name. Example: audio-device=/dev/audio - Attribute: audio-format The format of an audio sample or audio device. The value can be ulaw, linear-8, ulinear-8, linear-16, or ulinear-16. (linear = signed, ulinear = unsigned) Example: audio-format=ulaw - Attribute: audio-offset Number of bytes to skip from the current position in the audio data. Example: audio-offset=32. - Attribute: audio-port Audio output ports. The value can be speaker, headphone, and lineout. Multiple ports should be separated using a comma. Example: audio-port=headphone,speaker - Attribute: audio-rate The rate at which audio buffers are being written. Example: audio-rate=10 - Attribute: audio-sample-rate The sample rate of an audio sample or audio device. Example: audio-sample-rate=11025 - Attribute: audio-volume The volume of an audio sample or audio device. The value can be an integer between 0 and 255. Example: audio-volume=120 - Attribute: bits See audio-bits. - Attribute: channels See audio-channels. - Attribute: count The number of times a sound will be played or a generic number of items. Example: count=5 - Attribute: event The name of an RPTP event. Example: event=play - Attribute: error An error message. Example: error="access denied" - Attribute: format See audio-format. - Attribute: host A hostname. Example: host=mojo - Attribute: id A spool id. The value can be an integer between 0 and 999. A value of 0 refers to all ids. An id always begins with the `#' character since ids can be intermixed with sound names. Therefore, sounds can never begin with `#'. Example: id=#219 - Attribute: idle The amount of time a RPTP connection has been idle. Example: idle=1+01:37:05 - Attribute: input Where audio is coming from. Example: input=flow - Attribute: input-bits See audio-bits. - Attribute: input-byte-order See audio-byte-order. - Attribute: input-channels See audio-channels. - Attribute: input-format See audio-format. - Attribute: input-offset See audio-offset. - Attribute: input-sample-rate See audio-sample-rate. - Attribute: left The output level of the left speaker. Valid levels range from 0 to 255. - Attribute: list-count The number of times a list of sounds will be played. Example: list-count=5 - Attribute: message A generic message. Example: message="stop successful" - Attribute: notify A list of RPTP events. Multiple events should be separated using a comma. Example: notify=play,pause,done - Attribute: pause The number of sounds paused. Example: pause=1 - Attribute: play The number of sounds playing. Example: play=3 - Attribute: position The current second offset in a sound. - Attribute: priority The priority of a sound. The value should be an integer between 0 and 255 where 0 is the lowest priority and 255 is the highest. Example: priority=0 - Attribute: random Play a random sound from a list of sounds. Example: random=true - Attribute: remain Number of seconds remaining in a sound. - Attribute: right The output level of the right speaker. Valid levels range from 0 to 255. - Attribute: sample The current sample offset in a sound. - Attribute: samples The total number of samples in a sound. - Attribute: sample-rate See audio-sample-rate. - Attribute: seconds Number of seconds in a sound. Example: seconds=247.54 - Attribute: size The number of bytes in an audio file. Example: size=1868508 - Attribute: sound The name of a sound. Example: sound=petergun.au - Attribute: uptime The amount of time an RPTP server has been running. Example: uptime=27+09:19:10 - Attribute: version The version of rplay. Example: version=3.2.0a8 - Attribute: volume See audio-volume.  File: RPTP.info, Node: Events, Next: Event Notification, Prev: Attributes, Up: Top Events ****** RPTP supports both synchronous and asynchronous event notification. Events can be use to monitor the status of the server or wait for something special to happen. These events are: `all' All events. `any' See all. `continue' A sound has been continued. `done' A sound is finished. `level' Used to obtain the output level of the left and right speakers. Level values range from 0 to 255. `none' No events. `pause' A sound has been paused. `play' A sound has been played. `position' Used to obtain the current sample position of a sound that's being played. `skip' A sound has been skipped. `state' A server state change. `stop' A sound has been stopped. `volume' The volume has changed.  File: RPTP.info, Node: Event Notification, Next: Commands, Prev: Events, Up: Top Event Notification ****************** RPTP clients can receive event notification messages from the server. The event notification messages sent by the server always begin with the `@' character followed by a list of attributes. This character is used to help RPTP clients distinguish notification messages from other RPTP responses. Using a special character is especially useful for clients that deal with server messages asychronously. Each message will always contain an event attribute to inform the client which event occurred. The message can also contain several other attributes to provide the client with more event information. The following is a list of sample event messages: `continue' Example: @event=continue id=#160 sound=bogus.au `done' Example: @event=done id=#23 sound=bogus.au `level' Example: @event=level volume=46 left=23 right=23 `pause' Example: @event=pause id=#160 sound=bogus.au `play' Example: @event=play id=#160 sound=bogus.au volume=127 sample-rate=8000 seconds=1.19 count=1 `position' Example: @event=position id=#24 position=0.50 remain=0.69 seconds=1.19 sample=4000 samples=9542 `skip' Example: @event=skip id=#160 sound=bogus.au `state' Example: @event=state play=1 pause=1 volume=120 `stop' Example: @event=stop id=#160 sound=bogus.au `volume' Example: @event=volume volume=200 Notification messages can be enabled and disabled using the `set' command. For example, `set notify=play,pause' tells the server to send notification messages when sounds are played or paused. For fun you might try connecting to your rplay server with telnet and monitor its events in real-time. This can be done using the following: $ telnet somehost.sdsu.edu 5556 Once connected, type `set notify=all' and you will receive notification for all server events.  File: RPTP.info, Node: Commands, Next: Connecting, Prev: Event Notification, Up: Top Commands ******** Clients use commands to interact with the server. All commands will return errors using a result line beginning with `-'. This line will always contain the `error' attribute which contains a text error message. An example error response would be: `-error="access denied"'. The follow is a list of all the RPTP commands. Almost all commands accept attributes which can be specified in any order. More commands and command attributes can and probably will be added in the future. - Command: access Obtain client access permissions. This command returns one line containing the `access' attribute. - Command: application NAME Set the name of the client application. This command returns one line containing the `name' of the application. Example: application Xrplay 2.0 +Xrplay 2.0 *Caution:* This command is considered obsolete and may be removed in the future. Please use the `set' command instead. - Command: continue ID|SOUND ... Continue playing a paused sound. This command returns one line containing the `message' attribute. Example: continue sound=bogus.au +message="continue successful" - Command: done ID|SOUND ... Force a playing or paused sound to be done. In most cases this is the same as stop. This command returns one line containing the `message' attribute. Example: done sound=bogus.au message="done successful" - Command: find SOUND Search for a sound. This command returns one line containing the `sound' and `size' attributes. Example: find sound=bogus.au +sound=bogus.au size=9574 - Command: get SOUND Retrieve a sound. This command returns one line containing the `sound' and `size' attributes followed by `size' bytes of audio data. Example: get sound=bogus.au +sound=bogus.au size=9574 ... 9574 bytes of audio data ... - Command: help Obtain a list of server-supported commands. - Command: info SOUND Obtain information about a sound. This command returns one line containing information about the sound. The following attributes may be included: `sound', `size', `bits', `sample-rate', and `channels'. Example: info sound=bogus.au +sound=bogus.au size=9574 bits=8 sample-rate=8000 channels=1 - Command: list [CONNECTIONS|HOSTS|SERVERS|SPOOL|SOUNDS] List the specified server information. `connections' the server's RPTP connections `hosts' the server's rplay.hosts. `servers' the server's rplay.servers. `spool' the server's audio spool. `sounds' the server's rplay.conf and rplay.cache. This command returns one line containing the `message' attribute followed by zero or more lines terminated by a line containing only a `.'. Example: list connections +message="connections" host=130.191.225.64 type=client what=idle host=127.0.0.1 type=client what="notify 00000080" idle=.06 application="Xrplay 2.0" . list hosts +message="hosts" host=mojo access=rwx host=127.0.0.1 access=rwx . list servers +message="servers" host=hercules.sdsu.edu port=5556 host=pandora.sdsu.edu port=5556 . list spool +message="spool" id=#437 state=play sound=petergun host=130.191.225.64 volume=127 \backslash priority=0 count=1 seconds=227.75 sample_rate=8000 . list sounds +message="sounds" sound=monster2.au sound=monster1.au sound=monkey-3.au sound=monkey-2.au sound=monkey-1.au . *Caution:* This command does not use name-value pairs as arguments. - Command: pause ID|SOUND Pause a playing sound. This command returns one line containing the `message' attribute. Example: pause sound=bogus.au +message="pause successful" - Command: play Play a sound. This command accepts several attribute arguments, but only the `sound' attribute is required and it may be repeated to play a list of sounds sequentially. The `sound' attribute can be preceded by any of the following attributes: `count' `list-count' `priority' `random' `sample-rate' `volume' `input' `input-bits' `input-byte-order' `input-channels' `input-format' `input-offset' `input-sample-rate' This command returns one line containing the `id' attribute. Example: play sample-rate=4000 priority=255 sound=Debbie +id=#84 - Command: put ID|SIZE Give the server an entire sound or send flow data to a particular spool id. This command returns one line containing the `sound' or `id' and `size' attributes. After this line is received by the client, the server assumes the client will then send `size' bytes of audio data. If the specified spool id doesn't exist, the server will return an error. Example: put sound=bogus.au size=9574 +sound=bogus.au size=9574 or put id=#200 size=8000 +id=#200 size=8000 - Command: quit Terminate the RPTP session. This command returns nothing, the server simply closes the connection. - Command: reset Tell the server to reset itself. A reset usually includes re-reading all configuration files, closing all connections, and removing all sounds from the spool. If possible, the server will return one line containing the `message' attribute. The server will probably close the connect so the line may not be sent. - Command: set NAME[=VALUE] ... Get and set server attributes. The current set of supported server attributes is: `application' `level-notify-rate' `notify' `notify-rate' `position-notify-rate' `priority-threshold' `volume' This command returns one line containing the server's values for the specified attributes. If an attribute cannot be set, the server will return a value of `-1' for that attribute. Example: set application="Xrplay 2.0" notify=state volume=127 +application="Xrplay 2.0" notify=state volume=127 or set volume +volume=127 *Caution:* This command does not use name-value pairs to "get" the value of attributes. - Command: skip ID|COUNT Skip around to sounds in a sound list. The sound list must be referenced by ID. The number of sounds to skip (COUNT) can be negative (skip backwards), zero (skip to the beginning of the current sound), or positive (skip forward). Skipping before the beginning of the sound list will cause the first sound to be played. Skipping after the last sound will terminate the spool entry. Skipping a paused sound will cause the next sound (the skipee?) to also be paused. This command returns one line containing the `message' attribute. Example: skip id=#0 count=1 +message="skipped" - Command: status Obtain a server's current status. This command returns one line containing several attributes. Example: status +host=mojo version=3.2.0a8 uptime=01:32 audio-bits=8 audio-bufsize=800 \ audio-channels=1 audio-device=/dev/audio audio-format=ulaw \ audio-port=speaker audio-rate=10 audio-sample-rate=8000 volume=127 \ curr-bufsize=800 curr-rate=10 - Command: stop ID|SOUND ... Stop a paused or playing sound. This command returns one line containing the `message' attribute. Example: stop sound=bogus.au +message="stop successful" - Command: version Obtain the version number of the server. This command returns one line containing the `version' attribute. Example: version +version=3.2.0a8 - Command: volume [NEW-VOLUME] Get and set the volume of the audio device. This command returns one line containing the volume of the audio device. - Command: wait ID|EVENT|COMMAND Wait for a spool id, an event, or wait for the completion of a RPTP command. This comand returns one line that always contains the event attribute. Other attributes may also be included to provide more event information. Example: wait play sound=bogus +event=done id=#267 sound=bogus.au or wait event=volume +event=volume volume=135 or wait id=#300 +event=done id=#300 sound=tap2.au or wait event=any +event=play id=#360 sound=tap2.au volume=127 sample-rate=8000 seconds=0.21 count=1 *Caution:* This command is considered obsolete and may be removed in the future. Please use the `set' command instead.  File: RPTP.info, Node: Connecting, Next: Timeouts, Prev: Commands, Up: Top Connecting ********** An initial connection to a RPTP server is considered to be a RPTP command. This means that the server will always send a response to every client connection. The response sent is one line that begins with `+' for a successful connection and `-' for errors. The rest of the line consists of server attributes that can be used to find out more information about the server. An example would be: +host=hercules version=3.2.0b3 uptime=00:47:20 audio-bits=16 \ audio-bufsize=2450 audio-byte-order=big-endian audio-channels=1 \ audio-device=/dev/audio audio-format=linear-16 \ audio-port=speaker,headphone,lineout audio-rate=10 \ audio-sample-rate=11025 volume=120 curr-bufsize=2450 curr-rate=9 \ priority-threshold=0 Note that a `\' was used in the above example to split up the long attribute line.  File: RPTP.info, Node: Timeouts, Next: Attribute Index, Prev: Connecting, Up: Top Timeouts ******** RPTP servers can be configured to close connections on idle clients. Before the connection is closed, the server will send a timeout notification to the client. The notification is one line that begins with `!'. The reset of the line will contain attributes which should contain information about the timeout. For example: !message="Connection timed out after 300 idle seconds."  File: RPTP.info, Node: Attribute Index, Next: Event Index, Prev: Timeouts, Up: Top Attribute Index *************** * Menu: * access: Attributes. * application: Attributes. * audio-bits: Attributes. * audio-bufsize: Attributes. * audio-byte-order: Attributes. * audio-channels: Attributes. * audio-device: Attributes. * audio-format: Attributes. * audio-offset: Attributes. * audio-port: Attributes. * audio-rate: Attributes. * audio-sample-rate: Attributes. * audio-volume: Attributes. * bits: Attributes. * channels: Attributes. * count: Attributes. * error: Attributes. * event: Attributes. * format: Attributes. * host: Attributes. * id: Attributes. * idle: Attributes. * input: Attributes. * input-bits: Attributes. * input-byte-order: Attributes. * input-channels: Attributes. * input-format: Attributes. * input-offset: Attributes. * input-sample-rate: Attributes. * left: Attributes. * list-count: Attributes. * message: Attributes. * notify: Attributes. * pause: Attributes. * play: Attributes. * position: Attributes. * priority: Attributes. * random: Attributes. * remain: Attributes. * right: Attributes. * sample: Attributes. * sample-rate: Attributes. * samples: Attributes. * seconds: Attributes. * size: Attributes. * sound: Attributes. * uptime: Attributes. * version: Attributes. * volume: Attributes.  File: RPTP.info, Node: Event Index, Next: Command Index, Prev: Attribute Index, Up: Top Event Index *********** * Menu: * all: Events. * any: Events. * continue: Events. * done: Events. * level: Events. * none: Events. * pause: Events. * play: Events. * position: Events. * skip: Events. * state: Events. * stop: Events. * volume: Events.  File: RPTP.info, Node: Command Index, Prev: Event Index, Up: Top Command Index ************* * Menu: * access: Commands. * application: Commands. * continue: Commands. * done: Commands. * find: Commands. * get: Commands. * help: Commands. * info: Commands. * list: Commands. * pause: Commands. * play: Commands. * put: Commands. * quit: Commands. * reset: Commands. * set: Commands. * skip: Commands. * status: Commands. * stop: Commands. * version: Commands. * volume: Commands. * wait: Commands.  Tag Table: Node: Top731 Node: Overview1170 Node: Attributes3059 Node: Events8728 Node: Event Notification9612 Node: Commands11672 Node: Connecting21105 Node: Timeouts22048 Node: Attribute Index22548 Node: Event Index25229 Node: Command Index25983  End Tag Table rplay-3.3.2/doc/RPTP.texi100644 153 62 57302 6552756453 13612 0ustar boynsstaff\input texinfo @c -*-texinfo-*- @c %**start of header @setfilename RPTP.info @settitle The RPTP Protocol @defindex ev @iftex @finalout @end iftex @setchapternewpage odd @c %**end of header @ifinfo This file documents RPTP protocol. Copyright (C) 1995 Mark Boyns Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. @ignore Permission is granted to process this file through Tex and print the results, provided the printed document carries copying permission notice identical to this one except for the removal of this paragraph (this paragraph not being relevant to the printed manual). @end ignore Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions. @end ifinfo @titlepage @title The RPTP Protocol @author by Mark Boyns @page @vskip 0pt plus 1filll Copyright @copyright{} 1995 Mark Boyns Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions. @end titlepage @page @node Top, Overview, (dir), (dir) @top RPTP This document describes the Remote Play Transfer Protocol, otherwise known as RPTP. @menu * Overview:: * Attributes:: * Events:: * Event Notification:: * Commands:: * Connecting:: * Timeouts:: * Attribute Index:: Attribute Index. * Event Index:: Event Index. * Command Index:: Command Index. @end menu @node Overview, Attributes, Top, Top @chapter Overview RPTP is a command-based TCP interface to control the rplay audio server. The protocol is simple, the client sends a command and the server sends back a result. Name-value pairs are used in both commands and results. A name-value pair is of the form @samp{name=value} where @samp{name} is an attribute name and @samp{value} is the value of the attribute. Multiple name-value pairs on a line are separated by a spaces and/or tabs. When @samp{value} contains spaces or tabs it must be quoted as @samp{name="value"}. Commands consist of a command name followed by command attributes. An example would be @samp{play volume=50 sound=bogus.au}. In this case, the command is @samp{play} and its attributes are @samp{volume=50} and @samp{sound=bogus.au}. The server responds to each command with a result line. Each result line begins with a special character which is used to determine command success or failure. The following characaters are defined: @table @samp @item + Successful command execution (RPTP_OK) @item - Error (RPTP_ERROR) @item ! Connection timeout (RPTP_TIMEOUT) @item @@ Event notification (RPTP_NOTIFY) @end table After this first character, the result line contains name-value pairs. For example, if the server wanted to report an error to the client, the result line could be: @samp{-error="sorry, you can't do that"}. There is one RPTP command that returns more than one line. This is the list command which returns a normal result line followed by zero or more lines terminated by a line containing only a @samp{.}. These additional lines do not begin with any special characters. Future versions may include an attribute that clients can use to determine the number of lines that will be returned. All RPTP lines are terminated using a carriage return @samp{\r} (ASCII 13) followed by a newline @samp{\n} (ASCII 10). @node Attributes, Events, Overview, Top @chapter Attributes The following is a list of attributes that can be found within the name-value lists. @defvr Attribute access A set of characters defining access permissions. These characters can include @samp{r} - read access, @samp{w} - write access, and @samp{x} - execute access. Example: @example access=rwx @end example @end defvr @defvr Attribute application The name of an rplay application. Example: @example application="rptp 3.2.0a7" @end example @end defvr @defvr Attribute audio-bits The number of bits in an audio sample or audio device. The value can be 8, 16, and maybe 24 and 32 in the future. Example: @example audio-bits=16 @end example @end defvr @defvr Attribute audio-bufsize The size in bytes of the audio buffer. Example: @example audio-bufsize=1600 @end example @end defvr @defvr Attribute audio-byte-order The byte order of the audio data. The value can be either big-endian or little-endian. Example: @example audio-byte-order=big-endian @end example @end defvr @defvr Attribute audio-channels The number of channels in an audio sample or audio device. The value can be 1 or 2. Example: @example audio-channels=2 @end example @end defvr @defvr Attribute audio-device The name of an audio device. The value can be any audio device name. Example: @example audio-device=/dev/audio @end example @end defvr @defvr Attribute audio-format The format of an audio sample or audio device. The value can be ulaw, linear-8, ulinear-8, linear-16, or ulinear-16. (linear = signed, ulinear = unsigned) Example: @example audio-format=ulaw @end example @end defvr @defvr Attribute audio-offset Number of bytes to skip from the current position in the audio data. Example: @example audio-offset=32. @end example @end defvr @defvr Attribute audio-port Audio output ports. The value can be speaker, headphone, and lineout. Multiple ports should be separated using a comma. Example: @example audio-port=headphone,speaker @end example @end defvr @defvr Attribute audio-rate The rate at which audio buffers are being written. Example: @example audio-rate=10 @end example @end defvr @defvr Attribute audio-sample-rate The sample rate of an audio sample or audio device. Example: @example audio-sample-rate=11025 @end example @end defvr @defvr Attribute audio-volume The volume of an audio sample or audio device. The value can be an integer between 0 and 255. Example: @example audio-volume=120 @end example @end defvr @defvr Attribute bits See audio-bits. @end defvr @defvr Attribute channels See audio-channels. @end defvr @defvr Attribute count The number of times a sound will be played or a generic number of items. Example: @example count=5 @end example @end defvr @defvr Attribute event The name of an RPTP event. Example: @example event=play @end example @end defvr @defvr Attribute error An error message. Example: @example error="access denied" @end example @end defvr @defvr Attribute format See audio-format. @end defvr @defvr Attribute host A hostname. Example: @example host=mojo @end example @end defvr @defvr Attribute id A spool id. The value can be an integer between 0 and 999. A value of 0 refers to all ids. An id always begins with the @samp{#} character since ids can be intermixed with sound names. Therefore, sounds can never begin with @samp{#}. Example: @example id=#219 @end example @end defvr @defvr Attribute idle The amount of time a RPTP connection has been idle. Example: @example idle=1+01:37:05 @end example @end defvr @defvr Attribute input Where audio is coming from. Example: @example input=flow @end example @end defvr @defvr Attribute input-bits See audio-bits. @end defvr @defvr Attribute input-byte-order See audio-byte-order. @end defvr @defvr Attribute input-channels See audio-channels. @end defvr @defvr Attribute input-format See audio-format. @end defvr @defvr Attribute input-offset See audio-offset. @end defvr @defvr Attribute input-sample-rate See audio-sample-rate. @end defvr @defvr Attribute left The output level of the left speaker. Valid levels range from 0 to 255. @end defvr @defvr Attribute list-count The number of times a list of sounds will be played. Example: @example list-count=5 @end example @end defvr @defvr Attribute message A generic message. Example: @example message="stop successful" @end example @end defvr @defvr Attribute notify A list of RPTP events. Multiple events should be separated using a comma. Example: @example notify=play,pause,done @end example @end defvr @defvr Attribute pause The number of sounds paused. Example: @example pause=1 @end example @end defvr @defvr Attribute play The number of sounds playing. Example: @example play=3 @end example @end defvr @defvr Attribute position The current second offset in a sound. @end defvr @defvr Attribute priority The priority of a sound. The value should be an integer between 0 and 255 where 0 is the lowest priority and 255 is the highest. Example: @example priority=0 @end example @end defvr @defvr Attribute random Play a random sound from a list of sounds. Example: @example random=true @end example @end defvr @defvr Attribute remain Number of seconds remaining in a sound. @end defvr @defvr Attribute right The output level of the right speaker. Valid levels range from 0 to 255. @end defvr @defvr Attribute sample The current sample offset in a sound. @end defvr @defvr Attribute samples The total number of samples in a sound. @end defvr @defvr Attribute sample-rate See audio-sample-rate. @end defvr @defvr Attribute seconds Number of seconds in a sound. Example: @example seconds=247.54 @end example @end defvr @defvr Attribute size The number of bytes in an audio file. Example: @example size=1868508 @end example @end defvr @defvr Attribute sound The name of a sound. Example: @example sound=petergun.au @end example @end defvr @defvr Attribute uptime The amount of time an RPTP server has been running. Example: @example uptime=27+09:19:10 @end example @end defvr @defvr Attribute version The version of rplay. Example: @example version=3.2.0a8 @end example @end defvr @defvr Attribute volume See audio-volume. @end defvr @node Events, Event Notification, Attributes, Top @chapter Events RPTP supports both synchronous and asynchronous event notification. Events can be use to monitor the status of the server or wait for something special to happen. These events are: @table @code @item all @evindex all All events. @item any @evindex any See all. @item continue @evindex continue A sound has been continued. @item done @evindex done A sound is finished. @item level @evindex level Used to obtain the output level of the left and right speakers. Level values range from 0 to 255. @item none @evindex none No events. @item pause @evindex pause A sound has been paused. @item play @evindex play A sound has been played. @item position @evindex position Used to obtain the current sample position of a sound that's being played. @item skip @evindex skip A sound has been skipped. @item state @evindex state A server state change. @item stop @evindex stop A sound has been stopped. @item volume @evindex volume The volume has changed. @end table @node Event Notification, Commands, Events, Top @chapter Event Notification RPTP clients can receive event notification messages from the server. The event notification messages sent by the server always begin with the @samp{@@} character followed by a list of attributes. This character is used to help RPTP clients distinguish notification messages from other RPTP responses. Using a special character is especially useful for clients that deal with server messages asychronously. Each message will always contain an event attribute to inform the client which event occurred. The message can also contain several other attributes to provide the client with more event information. The following is a list of sample event messages: @table @code @item continue Example: @example @@event=continue id=#160 sound=bogus.au @end example @item done Example: @example @@event=done id=#23 sound=bogus.au @end example @item level Example: @example @@event=level volume=46 left=23 right=23 @end example @item pause Example: @example @@event=pause id=#160 sound=bogus.au @end example @item play Example: @example @@event=play id=#160 sound=bogus.au volume=127 sample-rate=8000 seconds=1.19 count=1 @end example @item position Example: @example @@event=position id=#24 position=0.50 remain=0.69 seconds=1.19 sample=4000 samples=9542 @end example @item skip Example: @example @@event=skip id=#160 sound=bogus.au @end example @item state Example: @example @@event=state play=1 pause=1 volume=120 @end example @item stop Example: @example @@event=stop id=#160 sound=bogus.au @end example @item volume Example: @example @@event=volume volume=200 @end example @end table Notification messages can be enabled and disabled using the @code{set} command. For example, @samp{set notify=play,pause} tells the server to send notification messages when sounds are played or paused. For fun you might try connecting to your rplay server with telnet and monitor its events in real-time. This can be done using the following: @noindent @example $ telnet somehost.sdsu.edu 5556 @end example Once connected, type @samp{set notify=all} and you will receive notification for all server events. @node Commands, Connecting, Event Notification, Top @chapter Commands Clients use commands to interact with the server. All commands will return errors using a result line beginning with @samp{-}. This line will always contain the @code{error} attribute which contains a text error message. An example error response would be: @samp{-error="access denied"}. The follow is a list of all the RPTP commands. Almost all commands accept attributes which can be specified in any order. More commands and command attributes can and probably will be added in the future. @deffn Command access Obtain client access permissions. This command returns one line containing the @code{access} attribute. @end deffn @deffn Command application @var{name} Set the name of the client application. This command returns one line containing the @code{name} of the application. Example: @example application Xrplay 2.0 +Xrplay 2.0 @end example @strong{Caution:} This command is considered obsolete and may be removed in the future. Please use the @code{set} command instead. @end deffn @deffn Command continue @var{id}|@var{sound} ... Continue playing a paused sound. This command returns one line containing the @code{message} attribute. Example: @example continue sound=bogus.au +message="continue successful" @end example @end deffn @deffn Command done @var{id}|@var{sound} ... Force a playing or paused sound to be done. In most cases this is the same as stop. This command returns one line containing the @code{message} attribute. Example: @example done sound=bogus.au message="done successful" @end example @end deffn @deffn Command find @var{sound} Search for a sound. This command returns one line containing the @code{sound} and @code{size} attributes. Example: @example find sound=bogus.au +sound=bogus.au size=9574 @end example @end deffn @deffn Command get @var{sound} Retrieve a sound. This command returns one line containing the @code{sound} and @code{size} attributes followed by @code{size} bytes of audio data. Example: @example get sound=bogus.au +sound=bogus.au size=9574 ... 9574 bytes of audio data ... @end example @end deffn @deffn Command help Obtain a list of server-supported commands. @end deffn @deffn Command info @var{sound} Obtain information about a sound. This command returns one line containing information about the sound. The following attributes may be included: @code{sound}, @code{size}, @code{bits}, @code{sample-rate}, and @code{channels}. Example: @example info sound=bogus.au +sound=bogus.au size=9574 bits=8 sample-rate=8000 channels=1 @end example @end deffn @deffn Command list [connections|hosts|servers|spool|sounds] List the specified server information. @table @code @item connections the server's RPTP connections @item hosts the server's rplay.hosts. @item servers the server's rplay.servers. @item spool the server's audio spool. @item sounds the server's rplay.conf and rplay.cache. @end table This command returns one line containing the @code{message} attribute followed by zero or more lines terminated by a line containing only a @samp{.}. Example: @example list connections +message="connections" host=130.191.225.64 type=client what=idle host=127.0.0.1 type=client what="notify 00000080" idle=.06 application="Xrplay 2.0" . list hosts +message="hosts" host=mojo access=rwx host=127.0.0.1 access=rwx . list servers +message="servers" host=hercules.sdsu.edu port=5556 host=pandora.sdsu.edu port=5556 . list spool +message="spool" id=#437 state=play sound=petergun host=130.191.225.64 volume=127 \backslash priority=0 count=1 seconds=227.75 sample_rate=8000 . list sounds +message="sounds" sound=monster2.au sound=monster1.au sound=monkey-3.au sound=monkey-2.au sound=monkey-1.au . @end example @strong{Caution:} This command does not use name-value pairs as arguments. @end deffn @deffn Command pause @var{id}|@var{sound} Pause a playing sound. This command returns one line containing the @code{message} attribute. Example: @example pause sound=bogus.au +message="pause successful" @end example @end deffn @deffn Command play Play a sound. This command accepts several attribute arguments, but only the @code{sound} attribute is required and it may be repeated to play a list of sounds sequentially. The @code{sound} attribute can be preceded by any of the following attributes: @table @code @item count @item list-count @item priority @item random @item sample-rate @item volume @item input @item input-bits @item input-byte-order @item input-channels @item input-format @item input-offset @item input-sample-rate @end table This command returns one line containing the @code{id} attribute. Example: @example play sample-rate=4000 priority=255 sound=Debbie +id=#84 @end example @end deffn @deffn Command put @var{id}|@var{size} Give the server an entire sound or send flow data to a particular spool id. This command returns one line containing the @code{sound} or @code{id} and @code{size} attributes. After this line is received by the client, the server assumes the client will then send @code{size} bytes of audio data. If the specified spool id doesn't exist, the server will return an error. Example: @example put sound=bogus.au size=9574 +sound=bogus.au size=9574 or put id=#200 size=8000 +id=#200 size=8000 @end example @end deffn @deffn Command quit Terminate the RPTP session. This command returns nothing, the server simply closes the connection. @end deffn @deffn Command reset Tell the server to reset itself. A reset usually includes re-reading all configuration files, closing all connections, and removing all sounds from the spool. If possible, the server will return one line containing the @code{message} attribute. The server will probably close the connect so the line may not be sent. @end deffn @deffn Command set name[=value] ... Get and set server attributes. The current set of supported server attributes is: @table @code @item application @item level-notify-rate @item notify @item notify-rate @item position-notify-rate @item priority-threshold @item volume @end table This command returns one line containing the server's values for the specified attributes. If an attribute cannot be set, the server will return a value of @code{-1} for that attribute. Example: @example set application="Xrplay 2.0" notify=state volume=127 +application="Xrplay 2.0" notify=state volume=127 or set volume +volume=127 @end example @strong{Caution:} This command does not use name-value pairs to "get" the value of attributes. @end deffn @deffn Command skip @var{id}|@var{count} Skip around to sounds in a sound list. The sound list must be referenced by @var{id}. The number of sounds to skip (@var{count}) can be negative (skip backwards), zero (skip to the beginning of the current sound), or positive (skip forward). Skipping before the beginning of the sound list will cause the first sound to be played. Skipping after the last sound will terminate the spool entry. Skipping a paused sound will cause the next sound (the skipee?) to also be paused. This command returns one line containing the @code{message} attribute. Example: @example skip id=#0 count=1 +message="skipped" @end example @end deffn @deffn Command status Obtain a server's current status. This command returns one line containing several attributes. Example: @example status +host=mojo version=3.2.0a8 uptime=01:32 audio-bits=8 audio-bufsize=800 \ audio-channels=1 audio-device=/dev/audio audio-format=ulaw \ audio-port=speaker audio-rate=10 audio-sample-rate=8000 volume=127 \ curr-bufsize=800 curr-rate=10 @end example @end deffn @deffn Command stop @var{id}|@var{sound} ... Stop a paused or playing sound. This command returns one line containing the @code{message} attribute. Example: @example stop sound=bogus.au +message="stop successful" @end example @end deffn @deffn Command version Obtain the version number of the server. This command returns one line containing the @code{version} attribute. Example: @example version +version=3.2.0a8 @end example @end deffn @deffn Command volume [@var{new-volume}] Get and set the volume of the audio device. This command returns one line containing the volume of the audio device. @end deffn @deffn Command wait @var{id}|@var{event}|@var{command} Wait for a spool id, an event, or wait for the completion of a RPTP command. This comand returns one line that always contains the event attribute. Other attributes may also be included to provide more event information. Example: @example wait play sound=bogus +event=done id=#267 sound=bogus.au or wait event=volume +event=volume volume=135 or wait id=#300 +event=done id=#300 sound=tap2.au or wait event=any +event=play id=#360 sound=tap2.au volume=127 sample-rate=8000 seconds=0.21 count=1 @end example @strong{Caution:} This command is considered obsolete and may be removed in the future. Please use the @code{set} command instead. @end deffn @node Connecting, Timeouts, Commands, Top @chapter Connecting An initial connection to a RPTP server is considered to be a RPTP command. This means that the server will always send a response to every client connection. The response sent is one line that begins with @samp{+} for a successful connection and @samp{-} for errors. The rest of the line consists of server attributes that can be used to find out more information about the server. An example would be: @example +host=hercules version=3.2.0b3 uptime=00:47:20 audio-bits=16 \ audio-bufsize=2450 audio-byte-order=big-endian audio-channels=1 \ audio-device=/dev/audio audio-format=linear-16 \ audio-port=speaker,headphone,lineout audio-rate=10 \ audio-sample-rate=11025 volume=120 curr-bufsize=2450 curr-rate=9 \ priority-threshold=0 @end example Note that a @samp{\} was used in the above example to split up the long attribute line. @node Timeouts, Attribute Index, Connecting, Top @chapter Timeouts RPTP servers can be configured to close connections on idle clients. Before the connection is closed, the server will send a timeout notification to the client. The notification is one line that begins with @samp{!}. The reset of the line will contain attributes which should contain information about the timeout. For example: @example !message="Connection timed out after 300 idle seconds." @end example @node Attribute Index, Event Index, Timeouts, Top @appendix Attribute Index @printindex vr @node Event Index, Command Index, Attribute Index, Top @appendix Event Index @printindex ev @node Command Index, , Event Index, Top @appendix Command Index @printindex fn @summarycontents @contents @bye rplay-3.3.2/doc/genman100755 153 62 1451 6552756453 13277 0ustar boynsstaff#!/usr/bin/perl $options = 0; $in = $ARGV[0]; ($progname, $section, $junk) = split ('\.', $in); $out = "$progname.$section"; open (IN, "$in") || die "$in: $!"; open (OUT, ">$out") || die "$out: $!"; local ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime (time); $mon++; print OUT ".TH " . uc ($progname) . " $section" . " $mon/$mday/$year\n"; print STDERR "Generating $out..."; while () { print OUT; if (/^\.SH OPTIONS$/) { open (PROG, "$progname --help|") || die "$progname: $!"; while () { chop; next if /^$/; if (/^-/) { s/-/\\-/g; print OUT ".TP\n.I \"$_\"\n"; $options++; } elsif ($options) { s/^\t//g; print OUT "$_\n"; } } close PROG; } } close OUT; close IN; print STDERR "done\n"; exit 0; rplay-3.3.2/doc/librplay.info100644 153 62 54273 6552756453 14631 0ustar boynsstaffThis is Info file librplay.info, produced by Makeinfo-1.63 from the input file librplay.texi. This file documents librplay. Copyright (C) 1995 Mark Boyns Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions.  File: librplay.info, Node: Top, Next: RPLAY Core Functions, Prev: (dir), Up: (dir) librplay ******** This file documents `librplay', the C library interface to the RPLAY and RPTP protocols. Programs that wish to use `librplay' must include `rplay.h' and link with `librplay'. rplay is based on two protocols and therefore this library has two distinct sets of routines. The routines can be distinguished by either a `rplay_' or `rptp_' prefix. To avoid conflicts, user programs are encouraged not to use variables or functions that begin with either of these prefixes. In most cases, each function description includes one or more examples to help illustrate how the function can be used. * Menu: * RPLAY Core Functions:: Low-level routines. * RPLAY Helper Functions:: * RPLAY Miscellaneous Functions:: Routines that may not be very useful. * RPLAY Error Reporting:: How to deal with RPLAY errors. * RPTP Core Functions:: Low-level routines. * RPTP Helper Functions:: * RPTP Error Reporting:: How to deal with RPTP errors. * Function Index:: Function Index.  File: librplay.info, Node: RPLAY Core Functions, Next: RPLAY Helper Functions, Prev: Top, Up: Top RPLAY Core Functions ******************** - Function: int rplay_open (char *HOST) Open a UDP socket connection to send RPLAY packets to host. The HOST argument is the name or IP address of the host where packets will be sent. The IP address can be a subnet mask which is used to broadcast packets to multiple hosts. The return value is a socket descriptor on success and `-1' on failure. Example: int rplay_fd; rplay_fd = rplay_open ("130.191.255.255"); if (rplay_fd < 0) { rplay_perror ("rplay_open"); exit (1); } - Function: int rplay_close (int RPLAY_FD) This function closes a rplay connection. The RPLAY_FD argument should be a socket descriptor opened by `rplay_open'. The return value is `0' on success and `-1' on failure. - Function: RPLAY * rplay_create (int COMMAND) Create a RPLAY object to perform a specific command. The COMMAND argument should be one of the following: `RPLAY_PLAY', `RPLAY_STOP', `RPLAY_PAUSE', `RPLAY_CONTINUE', `RPLAY_PING', or `RPLAY_RESET'. The return value is a pointer to a new RPLAY object on success and `NULL' on failure. Example: RPLAY *rp; rp = rplay_create (RPLAY_PLAY); if (rp == NULL) { rplay_perror ("rplay_create"); exit (1); } - Function: int rplay_set (RPLAY *RP, ...) Modify attributes of a RPLAY object. The RP argument should be a pointer to a RPLAY object created by `rplay_create'. The remaining arguments will be: `RPLAY_APPEND' Append a sound and its attributes. `RPLAY_DELETE' Delete a sound and its attributes. `RPLAY_INSERT' Insert a sound and its attributes. `RPLAY_RANDOM_SOUND' Choose a sound at random from the sound list. Only the chosen sound will be played, not entire sound list. The attribute list must be terminated with `NULL'. The return value is `0' on success and `-1' on failure. Example: /* Add a sound named `bogus.au' with volume 200. */ rplay_set (rp, RPLAY_APPEND, RPLAY_SOUND, "bogus.au", RPLAY_VOLUME, 200, NULL); /* Insert a sound named `bogus.au' with volume 200. */ rplay_set (rp, RPLAY_INSERT, 0, RPLAY_SOUND, "bogus.au", RPLAY_VOLUME, 200, NULL); /* Prepare to stop a sound named `excellent.au'. */ rp = rplay_create(RPLAY_STOP); rplay_set (rp, RPLAY_APPEND, RPLAY_SOUND, "excellent.au", NULL); /* Delete the sound at position 1. */ rplay_set (rp, RPLAY_DELETE, 1, NULL); /* * count and list count example * * result = gong.au gong.au drip.au drip.au * gong.au gong.au drip.au drip.au * */ rplay_set (rp, RPLAY_LIST_COUNT, 2, NULL); rplay_set (rp, RPLAY_APPEND, RPLAY_SOUND, "gong.au", RPLAY_COUNT, 2, NULL); rplay_set (rp, RPLAY_APPEND, RPLAY_SOUND, "drip.au", RPLAY_COUNT, 2, NULL); /* * random example (assume there is already a sound list) */ rplay_set (rp, RPLAY_RANDOM_SOUND, NULL); /* pick a sound randomly */ rplay_set (rp, RPLAY_RANDOM_SOUND, NULL); /* pick another sound */ rplay (rplay_fd, rp); /* play the random sound */ - Function: int rplay_get (RPLAY *RP, ...) Retrieve attributes from a RPLAY object. The RP argument should be a pointer to a RPLAY object created by `rplay_create' and modified using `rplay_set'. This argument is followed by a rplay attribute and its optional attribute argument. The return value will be either `int' or `char *' depending on the attribute. The caller will need to cast the return value to `char *' when necessary. Example: RPLAY *rp; int n; char *p; /* Get the number of sounds. */ n = rplay_get (rp, RPLAY_NSOUNDS); /* Get the name of sound 0. */ p = (char *) rplay_get (rp, RPLAY_SOUND, 0); /* Get the volume of sound 1. */ n = rplay_get (rp, RPLAY_VOLUME, 1); /* Get the rplay command. */ n = rplay_get (rp, RPLAY_COMMAND); - Function: int rplay (int RPLAY_FD, RPLAY *RP) This function uses a RPLAY packet to send RP to the host connected to RPLAY_FD. The RPLAY_FD argument should be a socket descriptor opened by `rplay_open'. RP should be a pointer to a `RPLAY' object created by `rplay_create' and modified using `rplay_set'. The return value is `0' on success and `-1' on failure. Example: if (rplay (rplay_fd, rp) < 0) { rplay_perror ("rplay"); exit (1); } - Function: void rplay_destroy (RPLAY *RP) Release all memory used by a RPLAY object. The RP argument should be a pointer to a RPLAY object created by `rplay_create'.  File: librplay.info, Node: RPLAY Helper Functions, Next: RPLAY Miscellaneous Functions, Prev: RPLAY Core Functions, Up: Top RPLAY Helper Functions ********************** - Function: int rplay_default (char *SOUND) Play SOUND on the default rplay host which is obtained using `rplay_default_host'. The SOUND argument is the name of the sound to play. The return value is `0' on success and `-1' on failure. Example: if (rplay_default ("bogus.au") < 0) { rplay_perror ("rplay_default"); exit (1); } - Function: char * rplay_default_host (void) Obtain the name of the default rplay host. A default rplay host can be specified by the user with the `RPLAY_HOST' environment variable. If this variable is not defined, `localhost' will be used instead. Example: char *hostname; hostname = rplay_default_host (); - Function: int rplay_display (char *SOUND) Play a sound on the host returned by rplay_open_display. The SOUND argument is the name of the sound to play. The return value is `0' on success and `-1' on failure. Example: if (rplay_display ("bogus.au") < 0) { rplay_perror ("rplay_display"); exit (1); } - Function: int rplay_host (char *HOST, char *SOUND) Play a sound on a host. The HOST is the name or IP address of the host where SOUND will be played. The return value is `0' on success and `-1' on failure. Example: if (rplay_host ("bozo.sdsu.edu", "bogus.au") < 0) { rplay_perror ("rplay_host"); exit (1); } - Function: int rplay_host_volume (char *HOST, char *SOUND, int VOLUME) Play a sound at specific volume on a host. The HOST is the name or IP address of the host where SOUND will be played using VOLUME. The return value is `0' on success and `-1' on failure. Example: if (rplay_host_volume ("bozo.sdsu.edu", "bogus.au", 200) < 0) { rplay_perror ("rplay_host_volume"); exit (1); } - Function: int rplay_local (char *SOUND) Play a sound on the localhost. The SOUND argument is the name of the sound to play. The return value is `0' on success and `-1' on failure. Example: if (rplay_local ("bogus.au") < 0) { rplay_perror ("rplay_local"); exit (1); } - Function: int rplay_open_default (void) Open a UDP socket connection to send RPLAY packets to the user's default rplay host. The default rplay host is obtained using `rplay_default_host'. The return value is a socket descriptor on success and `-1' on failure. Example: int rplay_fd; rplay_fd = rplay_open_default (); if (rplay_fd < 0) { rplay_perror ("rplay_open_default"); exit (1); } - Function: int rplay_open_display (void) Open a UDP socket connection to the host associated with the current X Windows display. The `DISPLAY' environment variable is used obtain the name of the X Windows display host. If this variable is not defined, `localhost' is used. The return value is a socket descriptor on success and `-1' on failure. Example: int rplay_fd; rplay_fd = rplay_open_display (); if (rplay_fd < 0) { rplay_perror ("rplay_open_display"); exit (1); } - Function: int rplay_open_port (char *HOST, int PORT) Open a UDP socket connection to send RPLAY packets to host at a specific port. The HOST argument is the same as `rplay_open' and the PORT argument should be the port number desired. The default port is defined in rplay.h as `RPLAY_PORT'. The return value is a socket descriptor on success and `-1' on failure. Example: int rplay_fd; rplay_fd = rplay_open_port ("130.191.224.3", 5555); if (rplay_fd < 0) { rplay_perror ("rplay_open_port"); exit (1); } - Function: int rplay_open_sockaddr_in (struct sockaddr_in *ADDR) Open a UDP socket connection to send RPLAY packets to the address specified in a `struct sockaddr_in'. The return value is a socket descriptor on success and `-1' on failure. Example: struct sockaddr_in *saddr; int rplay_fd; rplay_fd = rplay_open_sockaddr_in (saddr); if (rplay_fd < 0) { rplay_perror ("rplay_open_sockaddr_in"); exit (1); } - Function: int rplay_ping (char *HOST) Send a `RPLAY_PING' package to a host. This funcion is used to wake-up rplay servers that are started by inetd. The HOST argument is the name or IP address of the host that will receive the ping. The return value is `0' on success and `-1' on failure. Example: if (rplay_ping ("bozo.sdsu.edu") < 0) { rplay_perror ("rplay_ping"); exit (1); } - Function: int rplay_ping_sockaddr_in (struct sockaddr_in *ADDR) The same as `rplay_ping' except the ping is sent to the host addressed by ADDR. - Function: int rplay_ping_sockfd (int SOCKFD) The same as `rplay_ping' except the ping is sent to the host associated with UDP socket descriptor SOCKFD. - Function: int rplay_sound (int RPLAY_FD, char *SOUND) Play a sound on a host associated with a UDP socket descriptor. The RPLAY_FD argument is a UDP socket descriptor returned by any of the rplay_open routines and the SOUND argument is the name of the sound to be played. The return value is `0' on success and `-1' on failure. Example: rplay_sound (rplay_fd, "bogus.au");  File: librplay.info, Node: RPLAY Miscellaneous Functions, Next: RPLAY Error Reporting, Prev: RPLAY Helper Functions, Up: Top RPLAY Miscellaneous Functions ***************************** - Function: char * rplay_convert (char *PTR) Convert a RPLAY 2.0 packet to a RPLAY 3.0 packet. The PTR argument should be a pointer to the data contained in a RPLAY 2.0. The return value is the data pointed to by PTR converted to a RPLAY 3.0 packet. - Function: int rplay_pack (RPLAY *RP) Pack-up the attributes of the RPLAY object into the packet buffer associated with the object. This routine is called automatically by all routines that modify attributes. The RP argument should be a pointer to a RPLAY object created by `rplay_create'. The return value is `0' on success and `-1' on failure. - Function: RPLAY * rplay_unpack (char *RAW_PTR) Unpack a raw rplay 3.0 packet into a new RPLAY object. The RAW_PTR argument should be a pointer to a rplay 3.0 packet sent by a rplay client. The return value is a pointer to a new RPLAY object that is created using `rplay_create'.  File: librplay.info, Node: RPLAY Error Reporting, Next: RPTP Core Functions, Prev: RPLAY Miscellaneous Functions, Up: Top RPLAY Error Reporting ********************* - Function: void rplay_perror (char *MESSAGE) Report errors return by rplay library routines to standard error. Errors are obtained using `rplay_errno' and `rplay_errlist'. This should be called when routines return -1 or NULL. The MESSAGE argument followed by `: ' will prefix the rplay error message.  File: librplay.info, Node: RPTP Core Functions, Next: RPTP Helper Functions, Prev: RPLAY Error Reporting, Up: Top RPTP Core Functions ******************* - Function: int rptp_open (char *HOST, int PORT, char *RESPONSE, int RESPONSE_SIZE) Open a TCP socket connection for a RPTP session. The HOST argument is the name or IP address of a RPTP server, PORT is the TCP port at HOST to connect to, and up-to RESPONSE_SIZE bytes of the server's initial reponse are stored in RESPONSE. The return value is a TCP socket descriptor and `-1' on failure. Example: int rptp_fd; char buf[RPTP_MAX_LINE]; /* defined in rplay.h */ rptp_fd = rptp_open ("bozo.sdsu.edu", RPTP_PORT, buf, sizeof(buf)); if (rptp_fd < 0) { rptp_perror ("bozo.sdsu.edu"); exit(1); } - Function: int rptp_close (int RPTP_FD) Close a TCP socket descriptor created by `rptp_open'. The return value is `0' on success and `-1' on failure. - Function: int rptp_read (int RPTP_FD, char *BUF, int NBYTES) Read data from a RPTP server. The RPTP_FD argument should be a TCP socket descriptor returned by RPTP_OPEN. At most NBYTES will be read into the BUF. The return value is the number of bytes read and `-1' on failure. Example: if (rptp_read (rptp_fd, buf, sizeof(buf)) < 0) { rptp_perror ("rptp_read"); exit (1); } - Function: int rptp_write (int RPTP_FD, char *BUF, int NBYTES) Write data to a RPTP server. The RPTP_FD argument should be a TCP socket descriptor returned by RPTP_OPEN. NBYTES of data will be written from BUF. The return value is the number of bytes written and `-1' on failure. Example: if (rptp_write (rptp_fd, buf, sizeof(buf)) != sizeof(buf)) { rptp_perror ("rptp_write"); exit (1); }  File: librplay.info, Node: RPTP Helper Functions, Next: RPTP Error Reporting, Prev: RPTP Core Functions, Up: Top RPTP Helper Functions ********************* - Function: int rptp_command (int RPTP_FD, char *COMMAND, char *RESPONSE, int RESPONSE_SIZE) Send a RPTP command a RPTP server, storing the server's response in a buffer. The RPTP_FD argument should be a TCP socket descriptor returned by RPTP_OPEN. COMMAND is the command that will be sent and RESPONSE is where up-to RESPONSE_SIZE bytes of the command response will be stored. The return value is `0' if the response begins with `RPTP_OK' or or `RPTP_NOTIFY', `1' if the response beings with `RPTP_ERROR', and `-1' if the response beings with `RPTP_TIMEOUT' or there's an error. Example: char *error; switch (rptp_command (rptp_fd, command, response, sizeof(response))) { case -1: rptp_perror (command); break; case 1: error = rptp_parse (response, "error"); printf ("%s\n", error); break; case 0: /* Success! Now do something useful. */ break; } - Function: int rptp_getline (int RPTP_FD, char *BUF, int NBYTES) Read a line from a RPTP connection. `\r\n' will be removed from the line. The RPTP_FD argument should be a TCP socket descriptor returned by RPTP_OPEN. BUF is the buffer where up-to NBYTES of the line will be stored. The return value is the number of bytes read and `-1' on failure. Example: if (rptp_getline (rptp_fd, buf, sizeof(buf)) < 0) { rptp_perror ("rptp_getline"); exit (1); } - Function: char * rptp_parse (char *RESPONSE, char *NAME) Parse name-value pairs contained in RPTP responses. The RESPONSE argument can be a list of name-value pairs or `NULL'. The NAME can be the name of specific name-value pair or `NULL'. The example below gives more details. Note that any leading dashes in any name-value pair will be ignored. The return value can be name or value of a name-value pair depending on the arguments. Example: /* Return the value of `name' where `name=value' is in the response string. */ value = rptp_parse (response, "name") /* Same as above but return the value of `name' in the previously specified response. */ value = rptp_parse (NULL, "name") /* Return the first `name' in the response `name=value' list. */ name = rptp_parse (response, NULL) /* Same as above but return the next `name' is the previously specified response. name = rptp_parse (NULL, NULL) - Function: int rptp_putline (int RPTP_FD, char *FMT, ...) Send a line to a RPTP server. This routine will always append `\r\n' to the line sent. The RPTP_FD argument should be a TCP socket descriptor returned by RPTP_OPEN. FMT is any `printf' format string and the rest of the arguments are the values for the format specified. The return value is `0' on success and `-1' on failure. Example: if (rptp_putline (rptp_fd, "find sound=%s", "bogus.au") < 0) { rptp_perror ("rptp_putline"); exit (1); }  File: librplay.info, Node: RPTP Error Reporting, Next: Function Index, Prev: RPTP Helper Functions, Up: Top RPTP Error Reporting ******************** - Function: void rptp_perror (char *MESSAGE) Report errors return by rptp library routines to standard error. Errors are obtained using `rptp_errno' and `rptp_errlist'. This should be called when routines return -1 or NULL. The MESSAGE argument followed by `: ' will prefix the rptp error message.  File: librplay.info, Node: Function Index, Prev: RPTP Error Reporting, Up: Top Function Index ************** * Menu: * rplay: RPLAY Core Functions. * rplay_close: RPLAY Core Functions. * rplay_convert: RPLAY Miscellaneous Functions. * rplay_create: RPLAY Core Functions. * rplay_default: RPLAY Helper Functions. * rplay_default_host: RPLAY Helper Functions. * rplay_destroy: RPLAY Core Functions. * rplay_display: RPLAY Helper Functions. * rplay_get: RPLAY Core Functions. * rplay_host: RPLAY Helper Functions. * rplay_host_volume: RPLAY Helper Functions. * rplay_local: RPLAY Helper Functions. * rplay_open: RPLAY Core Functions. * rplay_open_default: RPLAY Helper Functions. * rplay_open_display: RPLAY Helper Functions. * rplay_open_port: RPLAY Helper Functions. * rplay_open_sockaddr_in: RPLAY Helper Functions. * rplay_pack: RPLAY Miscellaneous Functions. * rplay_perror: RPLAY Error Reporting. * rplay_ping: RPLAY Helper Functions. * rplay_ping_sockaddr_in: RPLAY Helper Functions. * rplay_ping_sockfd: RPLAY Helper Functions. * rplay_set: RPLAY Core Functions. * rplay_sound: RPLAY Helper Functions. * rplay_unpack: RPLAY Miscellaneous Functions. * rptp_close: RPTP Core Functions. * rptp_command: RPTP Helper Functions. * rptp_getline: RPTP Helper Functions. * rptp_open: RPTP Core Functions. * rptp_parse: RPTP Helper Functions. * rptp_perror: RPTP Error Reporting. * rptp_putline: RPTP Helper Functions. * rptp_read: RPTP Core Functions. * rptp_write: RPTP Core Functions.  Tag Table: Node: Top734 Node: RPLAY Core Functions1886 Node: RPLAY Helper Functions7013 Node: RPLAY Miscellaneous Functions12728 Node: RPLAY Error Reporting13892 Node: RPTP Core Functions14398 Node: RPTP Helper Functions16308 Node: RPTP Error Reporting19628 Node: Function Index20113  End Tag Table rplay-3.3.2/doc/librplay.texi100644 153 62 52665 6552756453 14652 0ustar boynsstaff\input texinfo @c -*-texinfo-*- @c %**start of header @setfilename librplay.info @settitle The rplay Programmer's Manual @iftex @finalout @end iftex @setchapternewpage odd @c %**end of header @ifinfo This file documents librplay. Copyright (C) 1995 Mark Boyns Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. @ignore Permission is granted to process this file through Tex and print the results, provided the printed document carries copying permission notice identical to this one except for the removal of this paragraph (this paragraph not being relevant to the printed manual). @end ignore Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions. @end ifinfo @titlepage @title The rplay Programmer's Manual @author by Mark Boyns @page @vskip 0pt plus 1filll Copyright @copyright{} 1995 Mark Boyns Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions. @end titlepage @page @node Top, RPLAY Core Functions, (dir), (dir) @top librplay This file documents @samp{librplay}, the C library interface to the RPLAY and RPTP protocols. Programs that wish to use @samp{librplay} must include @file{rplay.h} and link with @file{librplay}. rplay is based on two protocols and therefore this library has two distinct sets of routines. The routines can be distinguished by either a @samp{rplay_} or @samp{rptp_} prefix. To avoid conflicts, user programs are encouraged not to use variables or functions that begin with either of these prefixes. In most cases, each function description includes one or more examples to help illustrate how the function can be used. @menu * RPLAY Core Functions:: Low-level routines. * RPLAY Helper Functions:: * RPLAY Miscellaneous Functions:: Routines that may not be very useful. * RPLAY Error Reporting:: How to deal with RPLAY errors. * RPTP Core Functions:: Low-level routines. * RPTP Helper Functions:: * RPTP Error Reporting:: How to deal with RPTP errors. * Function Index:: Function Index. @end menu @node RPLAY Core Functions, RPLAY Helper Functions, Top, Top @chapter RPLAY Core Functions @c @c rplay_open @c @deftypefun int rplay_open (char *@var{host}) Open a UDP socket connection to send RPLAY packets to host. The @var{host} argument is the name or IP address of the host where packets will be sent. The IP address can be a subnet mask which is used to broadcast packets to multiple hosts. The return value is a socket descriptor on success and @code{-1} on failure. @end deftypefun Example: @example int rplay_fd; rplay_fd = rplay_open ("130.191.255.255"); if (rplay_fd < 0) @{ rplay_perror ("rplay_open"); exit (1); @} @end example @c @c rplay_close @c @deftypefun int rplay_close (int @var{rplay_fd}) This function closes a rplay connection. The @var{rplay_fd} argument should be a socket descriptor opened by @code{rplay_open}. The return value is @code{0} on success and @code{-1} on failure. @end deftypefun @c @c rplay_create @c @deftypefun {RPLAY *} rplay_create (int @var{command}) Create a RPLAY object to perform a specific command. The @var{command} argument should be one of the following: @code{RPLAY_PLAY}, @code{RPLAY_STOP}, @code{RPLAY_PAUSE}, @code{RPLAY_CONTINUE}, @code{RPLAY_PING}, or @code{RPLAY_RESET}. The return value is a pointer to a new RPLAY object on success and @code{NULL} on failure. @end deftypefun Example: @example RPLAY *rp; rp = rplay_create (RPLAY_PLAY); if (rp == NULL) @{ rplay_perror ("rplay_create"); exit (1); @} @end example @c @c rplay_set @c @deftypefun int rplay_set (RPLAY *@var{rp}, ...) Modify attributes of a RPLAY object. The @var{rp} argument should be a pointer to a RPLAY object created by @code{rplay_create}. The remaining arguments will be: @table @code @item RPLAY_APPEND Append a sound and its attributes. @item RPLAY_DELETE Delete a sound and its attributes. @item RPLAY_INSERT Insert a sound and its attributes. @item RPLAY_RANDOM_SOUND Choose a sound at random from the sound list. Only the chosen sound will be played, not entire sound list. @end table The attribute list must be terminated with @code{NULL}. The return value is @code{0} on success and @code{-1} on failure. @end deftypefun Example: @example /* Add a sound named `bogus.au' with volume 200. */ rplay_set (rp, RPLAY_APPEND, RPLAY_SOUND, "bogus.au", RPLAY_VOLUME, 200, NULL); /* Insert a sound named `bogus.au' with volume 200. */ rplay_set (rp, RPLAY_INSERT, 0, RPLAY_SOUND, "bogus.au", RPLAY_VOLUME, 200, NULL); /* Prepare to stop a sound named `excellent.au'. */ rp = rplay_create(RPLAY_STOP); rplay_set (rp, RPLAY_APPEND, RPLAY_SOUND, "excellent.au", NULL); /* Delete the sound at position 1. */ rplay_set (rp, RPLAY_DELETE, 1, NULL); /* * count and list count example * * result = gong.au gong.au drip.au drip.au * gong.au gong.au drip.au drip.au * */ rplay_set (rp, RPLAY_LIST_COUNT, 2, NULL); rplay_set (rp, RPLAY_APPEND, RPLAY_SOUND, "gong.au", RPLAY_COUNT, 2, NULL); rplay_set (rp, RPLAY_APPEND, RPLAY_SOUND, "drip.au", RPLAY_COUNT, 2, NULL); /* * random example (assume there is already a sound list) */ rplay_set (rp, RPLAY_RANDOM_SOUND, NULL); /* pick a sound randomly */ rplay_set (rp, RPLAY_RANDOM_SOUND, NULL); /* pick another sound */ rplay (rplay_fd, rp); /* play the random sound */ @end example @c @c rplay_get @c @deftypefun int rplay_get (RPLAY *@var{rp}, ...) Retrieve attributes from a RPLAY object. The @var{rp} argument should be a pointer to a RPLAY object created by @code{rplay_create} and modified using @code{rplay_set}. This argument is followed by a rplay attribute and its optional attribute argument. The return value will be either @code{int} or @code{char *} depending on the attribute. The caller will need to cast the return value to @code{char *} when necessary. @end deftypefun Example: @example RPLAY *rp; int n; char *p; /* Get the number of sounds. */ n = rplay_get (rp, RPLAY_NSOUNDS); /* Get the name of sound 0. */ p = (char *) rplay_get (rp, RPLAY_SOUND, 0); /* Get the volume of sound 1. */ n = rplay_get (rp, RPLAY_VOLUME, 1); /* Get the rplay command. */ n = rplay_get (rp, RPLAY_COMMAND); @end example @c @c rplay @c @deftypefun int rplay (int @var{rplay_fd}, RPLAY *@var{rp}) This function uses a RPLAY packet to send @var{rp} to the host connected to @var{rplay_fd}. The @var{rplay_fd} argument should be a socket descriptor opened by @code{rplay_open}. @var{rp} should be a pointer to a @code{RPLAY} object created by @code{rplay_create} and modified using @code{rplay_set}. The return value is @code{0} on success and @code{-1} on failure. @end deftypefun Example: @example if (rplay (rplay_fd, rp) < 0) @{ rplay_perror ("rplay"); exit (1); @} @end example @c @c rplay_destroy @c @deftypefun void rplay_destroy (RPLAY *@var{rp}) Release all memory used by a RPLAY object. The @var{rp} argument should be a pointer to a RPLAY object created by @code{rplay_create}. @end deftypefun @node RPLAY Helper Functions, RPLAY Miscellaneous Functions, RPLAY Core Functions, Top @chapter RPLAY Helper Functions @c @c rplay_default @c @deftypefun int rplay_default (char *@var{sound}) Play @var{sound} on the default rplay host which is obtained using @code{rplay_default_host}. The @var{sound} argument is the name of the sound to play. The return value is @code{0} on success and @code{-1} on failure. @end deftypefun Example: @example if (rplay_default ("bogus.au") < 0) @{ rplay_perror ("rplay_default"); exit (1); @} @end example @c @c rplay_default_host @c @deftypefun {char *} rplay_default_host (void) Obtain the name of the default rplay host. A default rplay host can be specified by the user with the @code{RPLAY_HOST} environment variable. If this variable is not defined, @code{localhost} will be used instead. @end deftypefun Example: @example char *hostname; hostname = rplay_default_host (); @end example @c @c rplay_display @c @deftypefun int rplay_display (char *@var{sound}) Play a sound on the host returned by rplay_open_display. The @var{sound} argument is the name of the sound to play. The return value is @code{0} on success and @code{-1} on failure. @end deftypefun Example: @example if (rplay_display ("bogus.au") < 0) @{ rplay_perror ("rplay_display"); exit (1); @} @end example @c @c rplay_host @c @deftypefun int rplay_host (char *@var{host}, char *@var{sound}) Play a sound on a host. The @var{host} is the name or IP address of the host where @var{sound} will be played. The return value is @code{0} on success and @code{-1} on failure. @end deftypefun Example: @example if (rplay_host ("bozo.sdsu.edu", "bogus.au") < 0) @{ rplay_perror ("rplay_host"); exit (1); @} @end example @c @c rplay_host_volume @c @deftypefun int rplay_host_volume (char *@var{host}, char *@var{sound}, int @var{volume}) Play a sound at specific volume on a host. The @var{host} is the name or IP address of the host where @var{sound} will be played using @var{volume}. The return value is @code{0} on success and @code{-1} on failure. @end deftypefun Example: @example if (rplay_host_volume ("bozo.sdsu.edu", "bogus.au", 200) < 0) @{ rplay_perror ("rplay_host_volume"); exit (1); @} @end example @c @c rplay_local @c @deftypefun int rplay_local (char *@var{sound}) Play a sound on the localhost. The @var{sound} argument is the name of the sound to play. The return value is @code{0} on success and @code{-1} on failure. @end deftypefun Example: @example if (rplay_local ("bogus.au") < 0) @{ rplay_perror ("rplay_local"); exit (1); @} @end example @c @c rplay_open_default @c @deftypefun int rplay_open_default (void) Open a UDP socket connection to send RPLAY packets to the user's default rplay host. The default rplay host is obtained using @code{rplay_default_host}. The return value is a socket descriptor on success and @code{-1} on failure. @end deftypefun Example: @example int rplay_fd; rplay_fd = rplay_open_default (); if (rplay_fd < 0) @{ rplay_perror ("rplay_open_default"); exit (1); @} @end example @c @c rplay_open_display @c @deftypefun int rplay_open_display (void) Open a UDP socket connection to the host associated with the current X Windows display. The @code{DISPLAY} environment variable is used obtain the name of the X Windows display host. If this variable is not defined, @code{localhost} is used. The return value is a socket descriptor on success and @code{-1} on failure. @end deftypefun Example: @example int rplay_fd; rplay_fd = rplay_open_display (); if (rplay_fd < 0) @{ rplay_perror ("rplay_open_display"); exit (1); @} @end example @c @c rplay_open_port @c @deftypefun int rplay_open_port (char *@var{host}, int @var{port}) Open a UDP socket connection to send RPLAY packets to host at a specific port. The @var{host} argument is the same as @code{rplay_open} and the @var{port} argument should be the port number desired. The default port is defined in rplay.h as @code{RPLAY_PORT}. The return value is a socket descriptor on success and @code{-1} on failure. @end deftypefun Example: @example int rplay_fd; rplay_fd = rplay_open_port ("130.191.224.3", 5555); if (rplay_fd < 0) @{ rplay_perror ("rplay_open_port"); exit (1); @} @end example @c @c rplay_open_sockaddr_in @c @deftypefun int rplay_open_sockaddr_in (struct sockaddr_in *@var{addr}) Open a UDP socket connection to send RPLAY packets to the address specified in a @code{struct sockaddr_in}. The return value is a socket descriptor on success and @code{-1} on failure. @end deftypefun Example: @example struct sockaddr_in *saddr; int rplay_fd; rplay_fd = rplay_open_sockaddr_in (saddr); if (rplay_fd < 0) @{ rplay_perror ("rplay_open_sockaddr_in"); exit (1); @} @end example @c @c rplay_ping @c @deftypefun int rplay_ping (char *@var{host}) Send a @code{RPLAY_PING} package to a host. This funcion is used to wake-up rplay servers that are started by inetd. The @var{host} argument is the name or IP address of the host that will receive the ping. The return value is @code{0} on success and @code{-1} on failure. @end deftypefun Example: @example if (rplay_ping ("bozo.sdsu.edu") < 0) @{ rplay_perror ("rplay_ping"); exit (1); @} @end example @c @c rplay_ping_sockaddr_in @c @deftypefun int rplay_ping_sockaddr_in (struct sockaddr_in *@var{addr}) The same as @code{rplay_ping} except the ping is sent to the host addressed by @var{addr}. @end deftypefun @c @c rplay_ping_sockfd @c @deftypefun int rplay_ping_sockfd (int @var{sockfd}) The same as @code{rplay_ping} except the ping is sent to the host associated with UDP socket descriptor @var{sockfd}. @end deftypefun @c @c rplay_sound @c @deftypefun int rplay_sound (int @var{rplay_fd}, char *@var{sound}) Play a sound on a host associated with a UDP socket descriptor. The @var{rplay_fd} argument is a UDP socket descriptor returned by any of the rplay_open routines and the @var{sound} argument is the name of the sound to be played. The return value is @code{0} on success and @code{-1} on failure. @end deftypefun Example: @example rplay_sound (rplay_fd, "bogus.au"); @end example @node RPLAY Miscellaneous Functions, RPLAY Error Reporting, RPLAY Helper Functions, Top @chapter RPLAY Miscellaneous Functions @c @c rplay_convert @c @deftypefun {char *} rplay_convert (char *@var{ptr}) Convert a RPLAY 2.0 packet to a RPLAY 3.0 packet. The @var{ptr} argument should be a pointer to the data contained in a RPLAY 2.0. The return value is the data pointed to by @var{ptr} converted to a RPLAY 3.0 packet. @end deftypefun @c @c rplay_pack @c @deftypefun int rplay_pack (RPLAY *@var{rp}) Pack-up the attributes of the RPLAY object into the packet buffer associated with the object. This routine is called automatically by all routines that modify attributes. The @var{rp} argument should be a pointer to a RPLAY object created by @code{rplay_create}. The return value is @code{0} on success and @code{-1} on failure. @end deftypefun @c @c rplay_unpack @c @deftypefun {RPLAY *} rplay_unpack (char *@var{raw_ptr}) Unpack a raw rplay 3.0 packet into a new RPLAY object. The @var{raw_ptr} argument should be a pointer to a rplay 3.0 packet sent by a rplay client. The return value is a pointer to a new RPLAY object that is created using @code{rplay_create}. @end deftypefun @node RPLAY Error Reporting, RPTP Core Functions, RPLAY Miscellaneous Functions, Top @chapter RPLAY Error Reporting @c @c rplay_perror @c @deftypefun void rplay_perror (char *@var{message}) Report errors return by rplay library routines to standard error. Errors are obtained using @code{rplay_errno} and @code{rplay_errlist}. This should be called when routines return -1 or NULL. The @var{message} argument followed by @code{: } will prefix the rplay error message. @end deftypefun @node RPTP Core Functions, RPTP Helper Functions, RPLAY Error Reporting, Top @chapter RPTP Core Functions @c @c rptp_open @c @deftypefun int rptp_open (char *@var{host}, int @var{port}, char *@var{response}, int @var{response_size}) Open a TCP socket connection for a RPTP session. The @var{host} argument is the name or IP address of a RPTP server, @var{port} is the TCP port at @var{host} to connect to, and up-to @var{response_size} bytes of the server's initial reponse are stored in @var{response}. The return value is a TCP socket descriptor and @code{-1} on failure. @end deftypefun Example: @example int rptp_fd; char buf[RPTP_MAX_LINE]; /* defined in rplay.h */ rptp_fd = rptp_open ("bozo.sdsu.edu", RPTP_PORT, buf, sizeof(buf)); if (rptp_fd < 0) @{ rptp_perror ("bozo.sdsu.edu"); exit(1); @} @end example @c @c rptp_close @c @deftypefun int rptp_close (int @var{rptp_fd}) Close a TCP socket descriptor created by @code{rptp_open}. The return value is @code{0} on success and @code{-1} on failure. @end deftypefun @c @c rptp_read @c @deftypefun int rptp_read (int @var{rptp_fd}, char *@var{buf}, int @var{nbytes}) Read data from a RPTP server. The @var{rptp_fd} argument should be a TCP socket descriptor returned by @var{rptp_open}. At most @var{nbytes} will be read into the @var{buf}. The return value is the number of bytes read and @code{-1} on failure. @end deftypefun Example: @example if (rptp_read (rptp_fd, buf, sizeof(buf)) < 0) @{ rptp_perror ("rptp_read"); exit (1); @} @end example @c @c rptp_write @c @deftypefun int rptp_write (int @var{rptp_fd}, char *@var{buf}, int @var{nbytes}) Write data to a RPTP server. The @var{rptp_fd} argument should be a TCP socket descriptor returned by @var{rptp_open}. @var{nbytes} of data will be written from @var{buf}. The return value is the number of bytes written and @code{-1} on failure. @end deftypefun Example: @example if (rptp_write (rptp_fd, buf, sizeof(buf)) != sizeof(buf)) @{ rptp_perror ("rptp_write"); exit (1); @} @end example @node RPTP Helper Functions, RPTP Error Reporting, RPTP Core Functions, Top @chapter RPTP Helper Functions @c @c rptp_command @c @deftypefun int rptp_command (int @var{rptp_fd}, char *@var{command}, char *@var{response}, int @var{response_size}) Send a RPTP command a RPTP server, storing the server's response in a buffer. The @var{rptp_fd} argument should be a TCP socket descriptor returned by @var{rptp_open}. @var{command} is the command that will be sent and @var{response} is where up-to @var{response_size} bytes of the command response will be stored. The return value is @code{0} if the response begins with @code{RPTP_OK} or or @code{RPTP_NOTIFY}, @code{1} if the response beings with @code{RPTP_ERROR}, and @code{-1} if the response beings with @code{RPTP_TIMEOUT} or there's an error. @end deftypefun Example: @example char *error; switch (rptp_command (rptp_fd, command, response, sizeof(response))) @{ case -1: rptp_perror (command); break; case 1: error = rptp_parse (response, "error"); printf ("%s\n", error); break; case 0: /* Success! Now do something useful. */ break; @} @end example @c @c rptp_getline @c @deftypefun int rptp_getline (int @var{rptp_fd}, char *@var{buf}, int @var{nbytes}) Read a line from a RPTP connection. @code{\r\n} will be removed from the line. The @var{rptp_fd} argument should be a TCP socket descriptor returned by @var{rptp_open}. @var{buf} is the buffer where up-to @var{nbytes} of the line will be stored. The return value is the number of bytes read and @code{-1} on failure. @end deftypefun Example: @example if (rptp_getline (rptp_fd, buf, sizeof(buf)) < 0) @{ rptp_perror ("rptp_getline"); exit (1); @} @end example @c @c rptp_parse @c @deftypefun {char *} rptp_parse (char *@var{response}, char *@var{name}) Parse name-value pairs contained in RPTP responses. The @var{response} argument can be a list of name-value pairs or @code{NULL}. The @var{name} can be the name of specific name-value pair or @code{NULL}. The example below gives more details. Note that any leading dashes in any name-value pair will be ignored. The return value can be name or value of a name-value pair depending on the arguments. @end deftypefun Example: @example /* Return the value of `name' where `name=value' is in the response string. */ value = rptp_parse (response, "name") /* Same as above but return the value of `name' in the previously specified response. */ value = rptp_parse (NULL, "name") /* Return the first `name' in the response `name=value' list. */ name = rptp_parse (response, NULL) /* Same as above but return the next `name' is the previously specified response. name = rptp_parse (NULL, NULL) @end example @c @c rptp_putline @c @deftypefun int rptp_putline (int @var{rptp_fd}, char *@var{fmt}, ...) Send a line to a RPTP server. This routine will always append @samp{\r\n} to the line sent. The @var{rptp_fd} argument should be a TCP socket descriptor returned by @var{rptp_open}. @var{fmt} is any @code{printf} format string and the rest of the arguments are the values for the format specified. The return value is @code{0} on success and @code{-1} on failure. @end deftypefun Example: @example if (rptp_putline (rptp_fd, "find sound=%s", "bogus.au") < 0) @{ rptp_perror ("rptp_putline"); exit (1); @} @end example @node RPTP Error Reporting, Function Index, RPTP Helper Functions, Top @chapter RPTP Error Reporting @c @c rptp_perror @c @deftypefun void rptp_perror (char *@var{message}) Report errors return by rptp library routines to standard error. Errors are obtained using @code{rptp_errno} and @code{rptp_errlist}. This should be called when routines return -1 or NULL. The @var{message} argument followed by @code{: } will prefix the rptp error message. @end deftypefun @node Function Index, , RPTP Error Reporting, Top @appendix Function Index @printindex fn @summarycontents @contents @bye rplay-3.3.2/doc/rplay.1100644 153 62 5167 6552756453 13325 0ustar boynsstaff.TH RPLAY 1 6/29/98 .SH NAME rplay \- play, pause, continue, and stop sounds .SH SYNOPSIS .B rplay [options] [sound ...] .SH DESCRIPTION rplay is client that communicates with rplayd to play, pause, continue, and stop sounds using both the RPLAY and RPTP protocols. Sound files can be played by rplayd directly if available on the local system or sounds can be sent over the network using UDP or TCP/IP. rplay will attempt to determine whether or not the server has the sound before using the network. .SH OPTIONS .TP .I "\-b BYTES, \-\-buffer\-size=BYTES" Use of a buffer size of BYTES when playing sounds using RPTP flows. The default is 8K. .TP .I "\-c, \-\-continue" Continue sounds. .TP .I "\-n N, \-\-count=N" Number of times to play the sound, default = 1. .TP .I "\-N N, \-\-list\-count=N" Number of times to play all the sounds, default = 1. .TP .I "\-\-list\-name=NAME" Name this list NAME. rplayd appends sounds with the same NAME into the same sound list -- it plays them sequentially. .TP .I "\-\-help" Display helpful information. .TP .I "\-h HOST, \-\-host=HOST, \-\-hosts=HOST" Specify the rplay host, default = localhost. .TP .I "\-i INFO, \-\-info=INFO" Audio information for a sound file. This option is intended to be used when sounds are read from standard input. INFO must be of the form: `format,sample-rate,bits,channels,byte-order,offset' Examples: ulaw,8000,8,1,big-endian,0 gsm,8000 Shorthand info is provided for Sun's audio devices using the following options: --info-amd, --info-dbri, --info-cs4231. There's also: --info-ulaw and --info-gsm. .TP .I "\-p, \-\-pause" Pause sounds. .TP .I "\-\-port=PORT" Use PORT instead of the default RPLAY/UDP or RPTP/TCP port. .TP .I "\-P N, \-\-priority=N" Play sounds at priority N (0 <= N <= 255), default = 0. .TP .I "\-r, \-\-random" Randomly choose one of the given sounds. .TP .I "\-\-reset" Tell the server to reset itself. .TP .I "\-\-rplay, \-\-RPLAY" Force the use of the RPLAY protocol. The default protocol to be used is determined by checking whether or not the server has local access to the specified sounds. RPLAY is used when sounds are accessible, otherwise RPTP and possibly flows are used. RPLAY will also be used when sound accessibility cannot be determined. .TP .I "\-\-rptp, \-\-RPTP" Force the use of the RPTP protocol. See `--rplay' for more information about protocols. .TP .I "\-R N, \-\-sample\-rate=N" Play sounds at sample rate N, default = 0. .TP .I "\-s, \-\-stop" Stop sounds. .TP .I "\-\-version" Print the rplay version and exit. .TP .I "\-v N, \-\-volume=N" Play sounds at volume N (0 <= N <= 255), default = 127. .SH SEE ALSO .IR rplayd (8), .IR rptp (1) rplay-3.3.2/doc/rplay.1.in100644 153 62 1032 6552756453 13715 0ustar boynsstaff.SH NAME rplay \- play, pause, continue, and stop sounds .SH SYNOPSIS .B rplay [options] [sound ...] .SH DESCRIPTION rplay is client that communicates with rplayd to play, pause, continue, and stop sounds using both the RPLAY and RPTP protocols. Sound files can be played by rplayd directly if available on the local system or sounds can be sent over the network using UDP or TCP/IP. rplay will attempt to determine whether or not the server has the sound before using the network. .SH OPTIONS .SH SEE ALSO .IR rplayd (8), .IR rptp (1) rplay-3.3.2/doc/rplay.conf.5100644 153 62 1176 6552756453 14251 0ustar boynsstaff.TH RPLAY.CONF 5 12/21/97 .SH NAME rplay.conf \- rplay sound database .SH SYNOPSIS .B /usr/local/etc/rplay.conf .SH DESCRIPTION The .I rplay.conf file contains a list of sound files that are available locally to .I rplayd. Each line must contain the complete pathname of one sound file. rplayd can be forced to re-read this file using the .I "rplay --reset" command. .SH EXAMPLE /usr/local/lib/sounds/bark.au .br /usr/local/lib/sounds/bogus.au .br /usr/local/lib/sounds/Puke.au .SH FILES .B /usr/local/etc/rplay.conf .SH "SEE ALSO" .BR rplayd (8) .BR rplay (1) .SH BUGS The name of this file should really be rplay.sounds, but it's not. rplay-3.3.2/doc/rplay.helpers.5100644 153 62 1170 6552756453 14760 0ustar boynsstaff.TH RPLAY.HELPERS 5 06/22/98 .SH NAME rplay.helpers \- rplay helper applications .SH SYNOPSIS .B /usr/local/etc/rplay.helpers .SH DESCRIPTION The .I rplay.helpers file contains a list of regex and application pairs used by .I rplayd to convert unknown file formats. The application must be configured to accept input from stdin and output data to stdout in the given audio format. Each line of this file is of the form: .IP .SH EXAMPLE .*mp3$ linear16,44100,16,2,little-endian /usr/bin/mpg123 -s -q -r 44100 --stereo - .SH FILES .B /usr/local/etc/rplay.helpers .SH "SEE ALSO" .BR rplayd (8) rplay-3.3.2/doc/rplay.hosts.5100644 153 62 2704 6552756453 14462 0ustar boynsstaff.TH RPLAY.HOSTS 5 12/21/97 .SH NAME rplay.hosts \- rplay host authentication database .SH SYNOPSIS .B /usr/local/etc/rplay.hosts .SH DESCRIPTION The .I rplay.hosts file contains a list of hosts and access permissions which .I rplayd uses to validate incoming connections. Each line is of the form: .IP hostname[:permission] .PP where .TP 15 .B hostname is the name of a remote host or a host's IP address. Wildcards can be used within IP addresses to match multiple hosts. The wildcard character is "*". .TP 15 .B permission is an optional field containing any combination of the following characters: .RS .TP 3 .B r the host can read sounds. .TP 3 .B w the host can write sounds. .TP 3 .B x the host can play, stop, pause, and continue sounds. This is normally called execute permission. .RE .TP "rx" permissions are used when no permissions are specified. .SH EXAMPLE .LP .ft B .nf # # All hosts have read access: # *:r # # Trusted hosts: # nice-guy.sdsu.edu:rwx friend.sdsu.edu:rwx amigo.sdsu.edu:rwx 130.191.224.224:rwx # # Hosts which can read and execute: # foo.bar.com:rx 130.190.*:rx 146.244.234.*:rx using.default.perms.edu .fi .ft R .LP .SH FILES .B /usr/local/etc/rplay.hosts .SH "SEE ALSO" .BR rplayd (1) .SH BUGS The permissions for an "*" entry apply to .B all matching hosts. The order of this file does not matter. Specific hosts can have access disabled with entries like: .LP .nf bad.guy.edu: .fi .LP however, any matching "*" entries will still apply. rplay-3.3.2/doc/rplay.info100644 153 62 13653 6552756453 14137 0ustar boynsstaffThis is Info file rplay.info, produced by Makeinfo version 1.67 from the input file rplay.texi. This file documents the rplay Network Audio System. Copyright (C) 1993-97 Mark Boyns Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions.  File: rplay.info, Node: Top, Next: Overview, Prev: (dir), Up: (dir) rplay Network Audio System ************************** This file documents the rplay Network Audio System. * Menu: * Overview:: Prelimary information * rplayd:: The rplay audio server. * rplay:: A sample RPLAY client. * rptp:: A sample RPTP client. * xrplay:: A X Windows rplay audio control panel.  File: rplay.info, Node: Overview, Next: rplayd, Prev: Top, Up: Top Overview ******** rplay is a flexible network audio system that allows sounds to be played to and from local and remote Unix systems. Sounds can be played with or without sending audio data over the network using either UDP or TCP/IP. rplay audio servers can be configured to share sound files with each other. Support for rplay is included in several applications. These include xpilot, xlockmore, xboing, fvwm, and ctwm. The rplay audio server is known to work well on Linux, SunOS 4.1.x, and Solaris 2.x. FreeBSD, Irix, and HPUX are known to work but the current status of these drivers is unknown. Linux support is based on the Open Sound System (OSS) driver so other systems using this driver might work with a few modifications. rplay supports two network protocols: `RPLAY' The Remote Play protocol which is connection-less and based on UDP (User Datagram Protocol). This protocol uses one-way communication with the audio server using single UDP packets. RPLAY was designed to be used by games which attempt to play hundreds of sounds a second, but it is also ideal for low-bandwidth applications. If you want simplicity, speed, and no error reporting, you should use RPLAY. `RPTP' The Remote Play Transfer Protocol which is connection-oriented and based on TCP (Transmission Control Protocol). This protocol uses two-way communication with the audio server using an interactive command language. RPTP is intended to be used by applications that require complete control of the audio server. Both protocols allow sounds to be played, paused, continued, and stopped.  File: rplay.info, Node: rplayd, Next: rplay, Prev: Overview, Up: Top rplayd ****** rplayd is the sound server for the rplay audio system. The server listens for requests to play, pause, continue, and stop sounds using both the RPLAY and RPTP protocols. Normally RPLAY requests are received on port 5555/udp and RPTP on 5556/tcp. (Older ports 55555/udp and 55556/tcp are also supported) Access to the server is restricted using the rplay.hosts file. rplayd can be started during the system boot process, via inetd, or by individual users. root access may be required depending on audio device permissions. In most causes rplayd will play sounds that are available on the local disk. However, rplayd can be sent sounds via the network and rplayd can also contact other rplayds to share sound files. The index of all the local sound files is stored in rplay.conf and remote rplayds are specified in rplay.servers. Sounds received from other rplayds will be stored in a cache directory normally located in /tmp/.rplay-cache. Cache entries are expired on an LRU basis. Many sound file formats are supported by rplayd. These include: AU AIFF WAV VOC UB UL G.721 4-bit, G.723 3-bit, G.723 5-bit GSM Several sounds can be played at once and sounds can be played at any sample rate. rplayd can be configured to output many different formats using the various -audio options. On some systems, namely Solaris and Linux, rplayd can read sounds directly from CDROM using CDDA. The special sound name cdrom: will play the entire CDROM. cdrom:3-5 will play tracks 3 through 5.  File: rplay.info, Node: rplay, Next: rptp, Prev: rplayd, Up: Top rplay ***** rplay is client that communicates with rplayd to play, pause, continue, and stop sounds using both the RPLAY and RPTP protocols. Sound files can be played by rplayd directly if available on the local system or sounds can be sent over the network using UDP or TCP/IP. rplay will attempt to determine whether or not the server has the sound before using the network.  File: rplay.info, Node: rptp, Next: xrplay, Prev: rplay, Up: Top rptp **** rptp is a simple RPTP client that communicates with rplayd using the RPTP protocol. Several commands can be issued to control rplayd and report its status. See the output of the rptp help command for a list of available commands.  File: rplay.info, Node: xrplay, Prev: rptp, Up: Top xrplay ****** rplay control panel which includes CD player-like buttons, volume control, a simple vu meter, and a sound progess bar. Sounds can be played, paused, continued, and stopped using the appropriate buttons. xrplay is also useful as a sound file player and can be used with web browsers and other applications that use external programs to play sounds. xrplay communicates with the local (or remote) rplayd using the RPTP protocol.  Tag Table: Node: Top761 Node: Overview1247 Node: rplayd2983 Node: rplay4640 Node: rptp5094 Node: xrplay5413  End Tag Table rplay-3.3.2/doc/rplay.servers.5100644 153 62 1370 6552756453 15011 0ustar boynsstaff.TH RPLAY.SERVERS 5 12/21/97 .SH NAME rplay.servers \- rplay servers database .SH SYNOPSIS .B /usr/local/etc/rplay.servers .SH DESCRIPTION The .I rplay.servers file contains a list of hosts that .I rplayd will contact to obtain sound files that are not available locally. Servers are contacted sequentially; best servers should be listed first. Each line is of the form: .IP hostname[:port] .LP where .TP 15 .B hostname is the name of a remote host or a host's IP address. .TP 15 .B port is an optional field containing the port to connect to. Port 5556 is used when the port is not specified. .SH EXAMPLE bozo.sdsu.edu .br 130.191.224.88 .br bozo.nowhere.com .br soundhost.foo.com:9999 .SH FILES .B /usr/local/etc/rplay.servers .SH "SEE ALSO" .BR rplayd (8) rplay-3.3.2/doc/rplay.texi100644 153 62 15115 6552756453 14150 0ustar boynsstaff\input texinfo @c -*-texinfo-*- @c %**start of header @setfilename rplay.info @settitle rplay @iftex @finalout @end iftex @setchapternewpage odd @c %**end of header @ifinfo This file documents the rplay Network Audio System. Copyright (C) 1993-97 Mark Boyns Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. @ignore Permission is granted to process this file through Tex and print the results, provided the printed document carries copying permission notice identical to this one except for the removal of this paragraph (this paragraph not being relevant to the printed manual). @end ignore Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided also that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions. @end ifinfo @titlepage @title The rplay Network Audio System @author by Mark Boyns @page @vskip 0pt plus 1filll Copyright @copyright{} 1993-97 Mark Boyns Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions. @end titlepage @page @node Top, Overview, (dir), (dir) @top rplay Network Audio System @ifinfo This file documents the rplay Network Audio System. @end ifinfo @menu * Overview:: Prelimary information * rplayd:: The rplay audio server. * rplay:: A sample RPLAY client. * rptp:: A sample RPTP client. * xrplay:: A X Windows rplay audio control panel. @end menu @node Overview, rplayd, Top, Top @chapter Overview rplay is a flexible network audio system that allows sounds to be played to and from local and remote Unix systems. Sounds can be played with or without sending audio data over the network using either UDP or TCP/IP. rplay audio servers can be configured to share sound files with each other. Support for rplay is included in several applications. These include xpilot, xlockmore, xboing, fvwm, and ctwm. The rplay audio server is known to work well on Linux, SunOS 4.1.x, and Solaris 2.x. FreeBSD, Irix, and HPUX are known to work but the current status of these drivers is unknown. Linux support is based on the Open Sound System (OSS) driver so other systems using this driver might work with a few modifications. @noindent rplay supports two network protocols: @table @code @item RPLAY The Remote Play protocol which is connection-less and based on UDP (User Datagram Protocol). This protocol uses one-way communication with the audio server using single UDP packets. RPLAY was designed to be used by games which attempt to play hundreds of sounds a second, but it is also ideal for low-bandwidth applications. If you want simplicity, speed, and no error reporting, you should use RPLAY. @item RPTP The Remote Play Transfer Protocol which is connection-oriented and based on TCP (Transmission Control Protocol). This protocol uses two-way communication with the audio server using an interactive command language. RPTP is intended to be used by applications that require complete control of the audio server. @end table Both protocols allow sounds to be played, paused, continued, and stopped. @node rplayd, rplay, Overview, Top @chapter rplayd rplayd is the sound server for the rplay audio system. The server listens for requests to play, pause, continue, and stop sounds using both the RPLAY and RPTP protocols. Normally RPLAY requests are received on port 5555/udp and RPTP on 5556/tcp. (Older ports 55555/udp and 55556/tcp are also supported) Access to the server is restricted using the rplay.hosts file. rplayd can be started during the system boot process, via inetd, or by individual users. root access may be required depending on audio device permissions. In most causes rplayd will play sounds that are available on the local disk. However, rplayd can be sent sounds via the network and rplayd can also contact other rplayds to share sound files. The index of all the local sound files is stored in rplay.conf and remote rplayds are specified in rplay.servers. Sounds received from other rplayds will be stored in a cache directory normally located in /tmp/.rplay-cache. Cache entries are expired on an LRU basis. Many sound file formats are supported by rplayd. These include: AU AIFF WAV VOC UB UL G.721 4-bit, G.723 3-bit, G.723 5-bit GSM Several sounds can be played at once and sounds can be played at any sample rate. rplayd can be configured to output many different formats using the various --audio options. On some systems, namely Solaris and Linux, rplayd can read sounds directly from CDROM using CDDA. The special sound name cdrom: will play the entire CDROM. cdrom:3-5 will play tracks 3 through 5. @node rplay, rptp, rplayd, Top @chapter rplay rplay is client that communicates with rplayd to play, pause, continue, and stop sounds using both the RPLAY and RPTP protocols. Sound files can be played by rplayd directly if available on the local system or sounds can be sent over the network using UDP or TCP/IP. rplay will attempt to determine whether or not the server has the sound before using the network. @node rptp, xrplay, rplay, Top @chapter rptp rptp is a simple RPTP client that communicates with rplayd using the RPTP protocol. Several commands can be issued to control rplayd and report its status. See the output of the rptp help command for a list of available commands. @node xrplay, , rptp, Top @chapter xrplay rplay control panel which includes CD player-like buttons, volume control, a simple vu meter, and a sound progess bar. Sounds can be played, paused, continued, and stopped using the appropriate buttons. xrplay is also useful as a sound file player and can be used with web browsers and other applications that use external programs to play sounds. xrplay communicates with the local (or remote) rplayd using the RPTP protocol. @bye rplay-3.3.2/doc/rplayd.8100644 153 62 14637 6552756453 13522 0ustar boynsstaff.TH RPLAYD 8 6/29/98 .SH NAME rplayd \- rplay sound server .SH SYNOPSIS .B rplayd [options] .SH DESCRIPTION .B rplayd is the sound server for the rplay audio system. The server listens for requests to play, pause, continue, and stop sounds using both the RPLAY and RPTP protocols. Normally RPLAY requests are received on port 5555/udp and RPTP on 5556/tcp. (Older ports 55555/udp and 55556/tcp are also supported) Access to the server is restricted using the .I rplay.hosts file. .P rplayd can be started during the system boot process, via inetd, or by individual users. root access may be required depending on audio device permissions. .P In most causes rplayd will play sounds that are available on the local disk. However, rplayd can be sent sounds via the network and rplayd can also contact other rplayds to share sound files. The index of all the local sound files is stored in .I rplay.conf and remote rplayds are specified in .I rplay.servers. Sounds received from other rplayds will be stored in a cache directory normally located in .I /tmp/.rplay-cache. Cache entries are expired on an LRU basis. .P Many sound file formats are supported by rplayd. These include: .nf AU AIFF WAV VOC UB UL G.721 4-bit, G.723 3-bit, G.723 5-bit GSM .fi .P Other formats can be played using external helper applications which convert unknown file formats to CD quality data which can then be played by rplayd. See rplay.helpers(5) .P Several sounds can be played at once and sounds can be played at any sample rate. rplayd can be configured to output many different formats using the various \-\-audio options. .P On some systems, namely Solaris and Linux, rplayd can read sounds directly from CDROM using CDDA. The special sound name .I cdrom: will play the entire CDROM. .I cdrom:3-5 will play tracks 3 through 5. .SH OPTIONS .TP .I "\-A DEVICE, \-\-audio\-device=DEVICE" Use DEVICE for the audio device (/dev/dsp). .TP .I "\-B N, \-\-audio\-bits=N" Audio device bits per sample, 8 or 16. .TP .I "\-\-audio\-channels=N" Number of audio channels to use, 1 == mono, 2 == stereo. .TP .I "\-c N, \-\-audio\-close=N" Close /dev/dsp after N idle seconds, disabled with 0 (5). .TP .I "\-F N, \-\-audio_flush=N" Flush /dev/dsp after N idle seconds, disabled with 0 (-1). N = -1 : flush when spool is empty. N = -2 : flush after each audio write. (not recommended) N should be <= to the audio close timeout. .TP .I "\-\-audio\-format=FORMAT" Tell rplayd to write audio data using FORMAT, where FORMAT can be ulaw, linear-8, ulinear-8, linear-16, or ulinear-16. (linear = signed, ulinear = unsigned) .TP .I "\-\-audio\-fragsize=N" Audio fragment size (0). The default size is zero which lets the audio driver pick the "best" size. The size specified must be a power of 2 greater than 16. Example: 256, 1024, 4096. .TP .I "\-\-audio\-info=INFO, \-\-info=INFO, \-i INFO" Specify complete audio device information with one option. INFO is of the form: format,sample-rate,bits,channels Examples: `ulaw,8000,8,1' and `linear-16,44100,16,2' Also provided are: --audio-info-ulaw, --info-ulaw -> ulaw,8000,8,1 .TP .I "\-\-audio\-match" Attempt to match the sample rate of the audio device with the sample rate of the current sound when no other sounds are playing. If the match fails, --audio-sample-rate is used. This option overrides --audio-bufsize. .TP .I "\-\-audio\-port=PORT[,PORT...]" Output audio to the specified audio port(s). Valid ports are `speaker', `headphone', and `lineout'. Multiple ports can be specified using `speaker,headphone,lineout' .TP .I "\-r N, \-\-audio\-rate=N" Write the audio buffer N times per second (0). .TP .I "\-R N, \-\-audio\-sample\-rate=N" Sample rate of the audio device. .TP .I "\-\-auth" Enable host access authentication. .TP .I "\-D DIR, \-\-cache\-directory=DIR" Use DIR for rplay.cache (/tmp/.rplay-cache). .TP .I "\-\-cache\-remove" Remove the cache directory and all its contents when rplayd exists. .TP .I "\-s N, \-\-cache\-size=N" Maximum size in bytes of the rplay cache, disabled with 0 (8388608). .TP .I "\-\-cdrom0=DEVICE, \-\-cdrom1=DEVICE, \-\-cdrom2=DEVICE, \-\-cdrom3=DEVICE" Specify the cdrom[0-3] to DEVICE mapping. For Solaris 2.x the default mapping is cdrom[0-3] -> /vol/dev/aliases/cdrom[0-3]. Linux uses cdrom[0-3] -> /dev/cdrom[0-3]. .TP .I "\-C FILE, \-\-conf=FILE" Use FILE for rplay.conf (/etc/rplay/rplay.conf). .TP .I "\-T N, \-\-connection\-timeout=N" Close idle RPTP connections after N seconds, disabled with 0 (300). .TP .I "\-d, \-\-debug" Enable debug mode. .TP .I "\-f HOST, \-\-forward=HOST" Forward all RPLAY packets to HOST. .TP .I "\-\-fork" Enable backgrounding rplayd at startup. (enabled) .TP .I "\-\-group=GROUP" Run with GROUP privs. (audio) .TP .I "\-\-help" Display helpful information. .TP .I "\-\-helpers=FILE" Use FILE for rplay.helpers (/etc/rplay/rplay.helpers). .TP .I "\-H FILE, \-\-hosts=FILE" Use FILE for rplay.hosts (/etc/rplay/rplay.hosts). .TP .I "\-\-inetd" Enable inetd mode. (disabled) .TP .I "\-L FILE, \-\-log\-file=FILE" Use file for rplay.log (/tmp/rplay.log). .TP .I "\-l N, \-\-log\-level=N" Use logging level N where 0 <= n <= 4. .TP .I "\-\-memory\-cache\-size=N" Maximum size in bytes of the memory cache, disable caching with 0 (4194304). .TP .I "\-\-memory\-cache\-sound\-size=N" Maximum size in bytes of a sound that can be cached in memory. A value of 0 means to try and cache all sounds. (2097152) .TP .I "\-N, \-\-no\-audio" Disable audio, RPTP file server mode. .TP .I "\-\-no\-auth" Disable host access authentication. .TP .I "\-n, \-\-no\-inetd" Disable inetd mode. (disabled) .TP .I "\-\-no\-fork" Disable backgrounding rplayd at startup. (enabled) .TP .I "\-\-options\-file=FILE" Read rplayd options from FILE. .TP .I "\-\-port=PORT, \-\-rplay\-port=PORT" Use PORT as the RPLAY/UDP port. (5555) (--other-rplay-port may also be available) .TP .I "\-\-rptp\-port=PORT" Use PORT as the RPTP/TCP port. (5556) (--other-rptp-port may also be available) .TP .I "\-S FILE, \-\-servers=FILE" Use FILE for rplay.servers (/etc/rplay/rplay.servers). .TP .I "\-t N, \-\-timeout=N" Exit after N idle seconds, disabled with 0 (0). .TP .I "\-\-user=USER" Run with USER privs. (nobody) .TP .I "\-v, \-\-version" Print the rplay version and exit. .SH FILES .nf ~/.rplaydrc /tmp/.rplay-cache /usr/local/etc/rplay.conf /usr/local/etc/rplay.helpers /usr/local/etc/rplay.hosts /usr/local/etc/rplay.servers .fi .SH SEE ALSO .IR rplay.conf (5), .IR rplay.helpers (5), .IR rplay.hosts (5), .IR rplay.servers (5), .IR rplay (1), .IR rptp (1) rplay-3.3.2/doc/rplayd.8.in100644 153 62 4102 6552756453 14071 0ustar boynsstaff.SH NAME rplayd \- rplay sound server .SH SYNOPSIS .B rplayd [options] .SH DESCRIPTION .B rplayd is the sound server for the rplay audio system. The server listens for requests to play, pause, continue, and stop sounds using both the RPLAY and RPTP protocols. Normally RPLAY requests are received on port 5555/udp and RPTP on 5556/tcp. (Older ports 55555/udp and 55556/tcp are also supported) Access to the server is restricted using the .I rplay.hosts file. .P rplayd can be started during the system boot process, via inetd, or by individual users. root access may be required depending on audio device permissions. .P In most causes rplayd will play sounds that are available on the local disk. However, rplayd can be sent sounds via the network and rplayd can also contact other rplayds to share sound files. The index of all the local sound files is stored in .I rplay.conf and remote rplayds are specified in .I rplay.servers. Sounds received from other rplayds will be stored in a cache directory normally located in .I /tmp/.rplay-cache. Cache entries are expired on an LRU basis. .P Many sound file formats are supported by rplayd. These include: .nf AU AIFF WAV VOC UB UL G.721 4-bit, G.723 3-bit, G.723 5-bit GSM .fi .P Other formats can be played using external helper applications which convert unknown file formats to CD quality data which can then be played by rplayd. See rplay.helpers(5) .P Several sounds can be played at once and sounds can be played at any sample rate. rplayd can be configured to output many different formats using the various \-\-audio options. .P On some systems, namely Solaris and Linux, rplayd can read sounds directly from CDROM using CDDA. The special sound name .I cdrom: will play the entire CDROM. .I cdrom:3-5 will play tracks 3 through 5. .SH OPTIONS .SH FILES .nf ~/.rplaydrc /tmp/.rplay-cache /usr/local/etc/rplay.conf /usr/local/etc/rplay.helpers /usr/local/etc/rplay.hosts /usr/local/etc/rplay.servers .fi .SH SEE ALSO .IR rplay.conf (5), .IR rplay.helpers (5), .IR rplay.hosts (5), .IR rplay.servers (5), .IR rplay (1), .IR rptp (1) rplay-3.3.2/doc/rptp.1100644 153 62 640 6552756453 13132 0ustar boynsstaff.TH RPTP 1 6/29/98 .SH NAME rptp \- communicate with rplayd using RPTP .SH SYNOPSIS .B rptp [options] [command] .SH DESCRIPTION rptp is a simple RPTP client that communicates with rplayd using the RPTP protocol. Several commands can be issued to control rplayd and report its status. See the output of the .B rptp help command for a list of available commands. .OPTIONS .SH SEE ALSO .IR rplayd (8), .IR rplay (1) rplay-3.3.2/doc/rptp.1.in100644 153 62 615 6552756453 13541 0ustar boynsstaff.SH NAME rptp \- communicate with rplayd using RPTP .SH SYNOPSIS .B rptp [options] [command] .SH DESCRIPTION rptp is a simple RPTP client that communicates with rplayd using the RPTP protocol. Several commands can be issued to control rplayd and report its status. See the output of the .B rptp help command for a list of available commands. .OPTIONS .SH SEE ALSO .IR rplayd (8), .IR rplay (1) rplay-3.3.2/COPYING100644 153 62 43070 6552756452 12414 0ustar boynsstaff GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. rplay-3.3.2/ChangeLog100644 153 62 204257 6727376730 13162 0ustar boynsstaff1999-03-21 Mark R. Boyns * fixed Makefile dependencies and shared library builds. 1999-03-09 Mark R. Boyns * rptp/rptp.c: added monitor support support for GNU readline display progress info for get, put, and monitor * rplayd/connection.c: monitor support * rplayd/rplayd.c: added audio monitor support * rplayd/command: added rptp monitor command * rplayd/host.c: added "m" monitor access 1999-03-02 Mark R. Boyns * devrplay/devrplay.c: new fake /dev/dsp hack based on esddsp. 1998-11-10 Mark R. Boyns * rptp/rptp.c: added set command. 1998-11-06 Mark R. Boyns * rplayd: fixed SNPRINTF code and other potential buffer overflow problems. 1998-10-15 Mark R. Boyns * Version 3.3.1 released. 1998-09-05 Mark R. Boyns * rplayd/connection.c (connection_update): fixed bus error when connections close other connections at the wrong time. 1998-09-02 Mark R. Boyns * rplayd/audio/audio_*.c (rplay_audio_open): enabled close-on-exec on rplay_audio_fd to fix mp3 helper bug. 1998-07-14 Mark R. Boyns * rplayd/sound.c: improved header parsing. 1998-06-29 Mark R. Boyns * Version 3.3.0 released. 1998-06-18 Mark R. Boyns * etc: include sample config files. * configure.in: add --enable-rplayd-user=USER and --enable-rplayd-group=GROUP. 1998-06-17 Mark R. Boyns * removed xrplay. * include/config.h.in: define AUTO_REREAD by default. * use rx. 1998-06-16 Mark R. Boyns * rplayd/rplayd.c: added --user and --group options and RPLAYD_USER and RPLAYD_GROUP config.h options. 1998-06-11 Mark R. Boyns * doc/rplay.helpers.5: new man page. * rplay/rplay.c: handle broken pipe better. * rplayd/command.c: added helper support. * rplayd/spool.c: added helper support. * rplayd/rplayd.c: added helper support. * rplayd/sound.c: added helper support. * rplayd/helper.c: new file to maintain helper application information. New config file rplay.helpers. 1998-06-03 Mark R. Boyns * rplayd/rplayd.c (doit): make sure the timer starts. (doit): keep trying to open the audio device. * rplayd/timer.c (timer_update): approximate getospace to keep things going. 1998-03-08 Mark Boyns * rplayd/sound.c (sound_read): allow directories in rplay.conf. When found, all files in a directory are made available to rplayd. 1997-12-24 Mark Boyns * rplayd/sound.c (sound_open): ditto * rplayd/cache.c (cache_create): ditto * rplayd/rplayd.c (doit): ditto * rplayd/connection.c: use EAGAIN with EINTR. 1997-12-23 Mark Boyns * contrib/xjukebox-0.9/rptpstuff.c: fixed enough to work with recent versions of rplay. * doc/xrplay.1.in: updated * doc/rptp.1.in: updated * doc/rplayd.8.in: updated * doc/rplay.1.in: updated * doc/rplay.texi: updated 1997-12-22 Mark Boyns * adpcm: build encode and decode as g72xencode and g72xdecode. Also include simple man pages. * perl/Mailsound.1: new file * Applied 64-bit Linux/Alpha patches from Martin Ostermann. 1997-12-21 Mark Boyns * doc/Makefile.in (man): use rplayd.8 instead of rplayd.1. * rplayd/command.c (command_quit): close later 1997-12-16 Mark Boyns * rplayd/rplayd.c (usage): added --inetd option which must be specified when rplayd is run via inetd. 1997-12-13 Mark Boyns * include/config.h.in (SNPRINTF): use snprintf and vsnprintf in rplayd if available. * rplayd/Makefile.in (install): install rplayd in $prefix/sbin. * rplayd/rplayd.c (usage): --fork and --no-fork options. When not in debug or inetd mode, rplayd will fork to put itself in the background. 1997-12-07 Mark Boyns * rplayd/rplayd.c: tilde expand RPLAY_* config files from config.h. 1997-12-06 Mark Boyns * rplayd/rplayd.c (usage): New --audio-fragsize option. * rplayd/timer.c (timer_update): Linux/OSS fixes. * rplayd/cdrom.c: Linux cdrom support. * rplayd/audio/audio_oss.c: New driver for Linux/OSS. Thu Nov 7 17:29:12 1996 Mark Boyns * Version 3.2.0 beta6 released. * rplayd/audio/audio_linux.c: Applied Linux audio patches from sinster@scintilla.darkwater.com (Darren Senn). He says this patch greatly improves audio under Linux. * xrplay: Updated for XForms 0.81. * include/config.h.in (RPLAY_CACHE): Change from "/tmp/rplay.cache" to "/tmp/.rplay-cache". Tue Nov 5 14:51:44 1996 Mark Boyns * rplayd/sound.c (sound_map): Fixed .wav file parsing from Mark Rawling . Mon Jun 3 16:08:35 1996 Mark Boyns * rplayd/sound.c (sound_map): Support 16-bit .voc files, I think. Mon Apr 22 09:53:32 1996 Mark Boyns * rplayd/native.c (x_to_native): Added oversampling patches from Andrew Scherpbier. Sun Apr 21 09:35:18 1996 Mark Boyns * rplay/rplay.c (doit): Pretend rplayd can get unknown sounds from another rplayd. * rplayd/sound.c (sound_fill): don't uncompress/decode sounds when sending to another rplayd or RPTP client. Thu Feb 29 13:54:09 1996 Mark Boyns * rplayd/spool.c (spool_remove): use spool_done to report RPTP events. Thu Feb 8 14:53:04 1996 Mark Boyns * rplayd/sound.c (sound_map): Didn't play the first few samples of flows. Thu Feb 1 15:38:48 1996 Mark Boyns * Version 3.2.0 beta5 released. * rplayd/rplayd.c (handle_sigchld): Use waitpid instead of wait3. Use wait if waitpid doesn't exist. * rplayd/sound.c (sound_map): Fixed problem with wav files that have weird sound_chunk_sizes. Tue Jan 30 14:31:36 1996 Mark Boyns * Version 3.2.0 beta4 released. * doc: Updated some of the man pages with new options. * contrib/Mailsound: New "mailsound" program called `Mailsound' which uses the new RPlay.pm perl 5 module. See the contrib/Mailsound directory for more information. Mon Jan 29 14:50:22 1996 Mark Boyns * rplayd/rplayd.c (usage): New options --cdrom0=DEVICE, --cdrom1=DEVICE, --cdrom2=DEVICE, and --cdrom3=DEVICE. These change the default cdrom devices specified in rplayd/cdrom.c. Currently `/vol/dev/aliases/cdrom0' is used for cdrom0, etc. * rplayd/cdrom.c: The new CDROM support requires no modifications to RPLAY/RPTP clients. CD tracks can be played using the special `cdrom:' prefix followed by a range of tracks or none for all tracks. `rplay cdrom:1-5' will play tracks 1 through 5, `rplay cdrom:4' will play track 4, and `rplay cdrom:' will play the entire CD. Other CDROM devices will be known as `cdrom1:', `cdrom2:', etc. `cdrom:' is the same as `cdrom0:'. Tue Jan 23 15:42:24 1996 Mark Boyns * rplayd/cdrom.c: rplayd can now read audio directly from a CDROM using the Solaris 2.x CDDA interface. This work was inspired by the read_cdda program written by Jim Mintha (mintha@geog.ubc.ca). rplayd uses a child process to read from the CDROM and uses a pipe to read the data (similar to a flow). Support for other CDROM devices only requires modifications to the file `cdrom.c'. If you've got Solaris 2.x, put your favorite CD in the CDROM and execute `rplay cdrom:'. Don't forget to crank up the volume. Fri Jan 19 11:45:32 1996 Mark Boyns * rplayd/rplayd.c: Use `sigset' instead of `signal'. (Solaris fix) Fri Dec 22 17:58:07 1995 Mark Boyns * rplayd/sound.c (sound_cleanup): Don't free memory used by sounds that are (paused) in the spool. * rplay/rplay.c: `rplay' now always uses single-put flows to send audio data. Removed asynchronous code. Thu Aug 31 15:09:50 1995 Mark Boyns * xrplay/xrplay_main.c (main): Ignore SIGPIPE. * xrplay: Added headphone, speaker, and lineout buttons to XRPlay. Wed Aug 30 14:50:23 1995 Mark Boyns * rplayd/command.c (command_set): `audio-port' can now be specified with the RPTP set command. This allows applications to easily change between speaker, headphone, etc., ports. (command_set): `audio-info' can now be set with the RPTP set command. This allows applications to change the audio parameters of the audio device. * Removed the `site' and `samples' directories. * rplayd/sound.c (sound_map): Fixed clicks at the end of .wav files and possibly .aiff files. Thu Aug 10 15:36:48 1995 Mark Boyns * The rplay source tree has been modified to support compiling for multiple architectures. See the INSTALL.generic file for more details. * gsm: The GSM source tree has been transformed into something that easier for rplay to use. See gsm/README.rplay for more details. * librplay/rplay.c: RPLAY packets can now send audio data to rplayd. Here's an example: rp = rplay_create (RPLAY_PUT); rplay_set (rp, RPLAY_ID, id); rplay_set (rp, RPLAY_SEQUENCE, sequence++); rplay_set (rp, RPLAY_DATA, buffer, nbytes); rplay (rplay_fd, rp); This example assumes that a single-put flow has been started using the RPTP play and put commands with the spool id saved in id. * include/rplay.h: New RPLAY command RPLAY_PUT. New attributes for this command are RPLAY_ID, RPLAY_SEQUENCE, RPLAY_DATA, RPLAY_DATA_SIZE. Tue Jul 25 15:38:16 1995 Mark Boyns * xrplay/gui.c (set_object_gray_state): Updated xrplay to work with the latest version of XForms. Sun Jul 23 23:35:33 1995 Mark Boyns * INSTALL: Support Emacs' outline-mode. Sat Jul 22 12:18:02 1995 Mark Boyns * rplayd/rplayd.c: New --audio-info (--info, -i) option to specify the audio configuration easily. Also available is --audio-info-ulaw (--info-ulaw). Thu Jul 13 16:14:46 1995 Mark Boyns * rplayd/rplayd.c: New `~/.rplaydrc' which can contain a default set of rplayd command line options. rplayd reads this file before parsing any command line options. The file can contain any option specified in `rplayd --help'. For example: ## ## Sample .rplaydrc ## --audio-match --audio-close=0 --options-file=/tmp/rplayd.options --servers=/usr/local/etc/rplay.servers --hosts=/usr/local/etc/rplay.hosts --conf=/usr/local/etc/rplay.conf The default rc file can be changed in include/config.h. Sun Jul 9 23:07:23 1995 Mark Boyns * xrplay/io.c (read_proc): Fixed bug which caused xrplay to abort when the server connection was lost. Sat Jul 8 11:01:58 1995 Mark Boyns * rplayd/host.c (host_read): Automatically add access for the local host when AUTH is defined in config.h and a rplay.hosts file doesn't exist. * rplayd/rplayd.c (handle_sigint): rplayd now catches SIGINT and exits normally when it's received. Thu Jul 6 10:05:15 1995 Mark Boyns * rplay/rplay.c: New RPTP flow code which is completely asynchronous and improves stdin performance. `rplay' will use the new single-put flow method when using stdin. * rplayd: RPTP flows now support a single-put protocol to avoid extra network traffic. A single-put flow is started by using `size=0' with the RPTP put command. After a receiving a successful put response, the RPTP client can then send a continuous stream of audio data which is terminated by closing the RPTP connection. * rplay/rplay.c: Changed the --info format from 8000,ulaw,8,1,big-endian,offset to ulaw,8000,8,1,big-endian,offset. Now the format is listed first instead of sample-rate. GSM --info should be specified as `--info=gsm,8000'; the remaining arguments are not required and really don't make much sense for GSM. Thu Jun 29 09:13:33 1995 Mark Boyns * adpcm: Also build `encode' and `decode' to help users create their own G.72x files. * gsm: New directory containing the sources for GSM version 1.0.7. Support for GSM compressed audio files has been added to rplay. GSM is a lossy sound compression algorithm that effectively compresses 16 bit audio to 1.65 bit -- very impressive. GSM is ideal for low bandwidth links since it only needs 1650 bytes/sec for 8000hz audio, and half that for 4000hz. Use the `toast' program in gsm/bin to create your own .gsm files. Thanks to Jutta Degener (jutta@cs.tu-berlin.de) and Carsten Bormann (cabo@cs.tu-berlin.de) for GSM and to Germano Caronni for telling me about GSM. * rplayd/audio/audio_FreeBSD.c: New FreeBSD audio code contributed by Andreas S. Wetzel . Mon Jun 26 15:08:03 1995 Mark Boyns * rplay/rplay.c: Removed option `--no-flows'. Changed the way `rplay' determines which protocol to use. The default protocol to be used is determined by checking whether or not the server has local access to the specified sounds. RPLAY is used when sounds are accessible, otherwise RPTP and possibly flows are used. RPLAY will also be used when sound accessibility cannot be determined. New options `--rplay' and `--rptp' can be used to force the use of a specific protocol. * rplayd/rplayd.c (do_option): New option `--remove-cache' which forces rplayd to remove the rplay.cache and its contents when it exits. The rplay.cache directory will always be removed if it's empty. * rplayd/cache.c (cache_init): Changed default rplay.cache directory permissions from 0755 to 0777. (cache_cleanup): New function to remove the cache directory and all its contents. Suggested by Johan Ramestam (pt93jr@pt.hk-r.se). (cache_create): Changed default rplay.cache file permissions from 0644 to 0666. Wed May 31 16:27:52 1995 Mark Boyns * xrplay/xrplay.c: Added a position slider which uses the RPTP position notify event. Also changed some colors. * rplay/rplay.c: Removed --flow. `rplay' now uses the RPTP find command to determine whether or not a flow is really necessary. Thu May 25 10:15:44 1995 Mark Boyns * Version 3.2.0 beta3 released. * examples/vu.c: New example program that uses XForms and the new level notification event. Compile this example with vu.Makefile. * examples/pos.c: New example program that uses XForms and the new position notification event. Compile this example with pos.Makefile. * xrplay: Added a new version of XRPlay written by Andrew Scherpbier using XForms. Sun May 7 12:51:48 1995 Mark Boyns * rplayd/connection.c (connection_notify): Added audio file/flow position notification. This new `position' event can be used to monitor/display the current sample position of a sound that's being played. Sat May 6 12:14:29 1995 Mark Boyns * rplayd/native.c (level): Added left and right output level notification. The new `level' notification event is used to obtain the values of the left and right speakers using the `left' and `right' attributes. Levels range from 0 to 255, with 255 being the highest/loudest level. Fri Apr 28 11:42:46 1995 Mark Boyns * rplayd/native.c: Fixed bug with unsigned 16-bit audio. Tue Apr 25 10:45:13 1995 Mark Boyns * include/config.h.in: Changed RPLAYD_TIMEOUT to 0 which means that rplayd will no longer timeout by default. inetd users will probably want to add `-t 360' if the old behavior is desired. * rplayd/sound.c (sound_clean): New function which is used to fixes problems with flows been deleted at the wrong time. Thu Apr 13 11:02:32 1995 Mark Boyns * rplayd/connection.c (connection_notify): Added priority-threshold to state notification events. * xrplay: New `--priority' option which tells xrplay to display priority-threshold information and allow the user to modify it. * rplayd/command.c (command_set): Added the `priority-threshold' attribute to the RPTP set command. The value of priority-threshold is the minimum priority of a sound that will be played by rplayd. Sounds with priorities below the threshold are ignored. The default value is 0. * rplay/rplay.c (usage): Added the --no-flow option to `rplay'. Wed Apr 12 15:25:52 1995 Mark Boyns * rplay/rplay.c: Added the --buffer-size (-b) option to `rplay' so the audio buffer size that's flowed to the server can be easily configured. Sometimes this is necessary when the default of 8k isn't enough or may even be too much. * librplay/rptp.c (rptp): Removed this new routine since I decided that RPLAY and RPTP should not be inter-mixed. (rptp_parse): Fixed bug which freed internal list objects at an inconvenient time. Now the current/previous list of name-value pairs is always kept in memory. * Now `rplay' can be used to talk to your friends on the internet. For example, if you and a friend are running rplayd on a Sun with an amd audio device and a microphone, you can use the following: hostA$ rplay --host=hostB --info-amd - < /dev/audio hostB$ rplay --host=hostA --info-amd - < /dev/audio (see `rplay --help' for more information) * rplay/rplay.c: Added RPTP flow support to `rplay'. Flows are now used whenever `rplay' can access any of the specified sounds. This means that `rplay' can _finally_ do `rplay sound.au' where sound.au is some sound in the current directory. Previously `rplay ./sound.au' was required and a flow was not used. If a sound named `-' is used, `rplay' will read audio data from standard input and flow it to rplayd. New options --info, --info-dbri, and --info-cs4231 can be used to describe the audio data. Fri Mar 24 11:05:57 1995 Mark Boyns * rplayd/connection.c (connection_notify): Added `priority-threshold' to `state' notify events and added it to the server status attributes. * rplayd/command.c (command_set): Changed the new `priority' attribute to `priority-threshold' since that makes more sense. Tue Mar 21 17:44:00 1995 Mark Boyns * rplayd/command.c (command_set): Added `set priority=value' RPTP command. This priority value is used to set the sound priorities that will be accepted by rplayd. Sounds with priorities less than VALUE will be ignore. The default priority is 0. Mon Mar 13 09:54:04 1995 Mark Boyns * SGI patches from Rob Kooper which fix errno problems in rplayd/audio/audio_sgi.c and change configure.in to fail if the multimedia development kit isn't installed. Thu Mar 9 09:52:07 1995 Mark Boyns * rplayd/connection.c (connection_update): Fixed bug reported by stevejg@wni.com (Steve J. Green). Thu Mar 2 22:51:29 1995 Mark Boyns * librplay/rptp.c (rptp_parse): Skip leading dashes so name-value parse can look like: name=value, -name=value, or even --name=value. Tue Feb 21 21:44:32 1995 Mark Boyns * Added RPLAY_LIST_NAME / `--list-name' attribute. The value of this attribute is used to append sounds with the same `list-name' into the same sound list. For example: $ rplay --list-name=test raiders $ rplay --list-name=test jedi $ rplay --list-name=test Debbie rplayd will first play `raiders', append `jedi', and then append `Debbie'. This is the same as: $ rplay raiders jedi Debbie * rplay/rplay.c: Added `--rptp' which sends commands using RPTP instead of RPLAY. * librplay/rptp.c (rptp): New RPTP library routine `int rptp (int rptp_fd, RPLAY *rp)' which converts a RPLAY object into a RPTP command and then sends the command to the rptp_fd using `rptp_command'. This routine gives RPTP clients the flexibility of `rplay_get' and `rplay_set'. Sun Feb 19 10:06:03 1995 Mark Boyns * rplayd/sound.c (sound_delete): Fixed a nasty bug. Sat Feb 18 10:56:47 1995 Mark Boyns * rplayd/rplayd.c (rplayd_play): Added spool_destroy to fix a "spool full" problem and a possible memory leak. Thu Feb 16 09:51:59 1995 Mark Boyns * xrplay/connect.c: Ultrix fix. * rplayd/audio/audio_generic.c: Utlrix fix. * site/Makefile.in (install): Fixed `make install' problem for Ultrix. Thanks nissen@montefiore.ulg.ac.be (Alain Nissen). * Define MAXHOSTNAMELEN in librplay/rplay.c and rplayd/rplayd.c if it's not defined in system headers. Wed Feb 15 17:14:32 1995 Mark Boyns * rplayd/audio/audio_sun.c (rplay_audio_init): Allow audio port to really be set to `none'. This fixes problems with 4/4xx and 4/6xx systems running SunOS 4.1.x. Thanks nissen@montefiore.ulg.ac.be (Alain Nissen). Fri Feb 10 14:00:02 1995 Mark Boyns * rplayd/audio/audio_sun.c (rplay_audio_init): Fixed typo where `rplayd_audio_port' was used instead of `rplay_audio_port'. Reported by nissen@montefiore.ulg.ac.be (Alain Nissen). Tue Feb 7 17:27:17 1995 Mark Boyns * contrib/tkrplay: Fixed `Configure' problem with tkrplay. Reported by stevejg@wni.com (Steve J. Green). Mon Feb 6 16:34:43 1995 Mark Boyns * Version 3.2.0 beta2 released. * xrplay: Added a newer version of xrplay. This version has several bug fixes and it can use flows to play sounds specified on its command line. There's still a few known bugs in xrplay that will be fixed later. Thanks Andrew Scherpbier . Sun Feb 5 10:09:32 1995 Mark Boyns * librplay/async.c: Added the RPTP asynchronous I/O system written by Andrew Scherpbier . These library routines make adding rplay support to asynchronous programs *much* easier. xrplay and rplaytool have been updated to use these routines. The examples directory has some async examples. * examples: Created the `examples' directory. This directory contains example source code to help demonstrate how to do various things using librplay. Fri Feb 3 15:49:58 1995 Mark Boyns * rplayd/command.c (do_events): RPTP event masks can now be manipulated using + and - binary operators. For example: set notify="play,pause,done" set notify="+continue" notify would then be "play,pause,done,continue". set notify="-pause" notify would then be "play,done,continue". The default binary operator is `+' which means that events are always added to the mask. The mask can be reset using: set notify="none,play,done" This sets notify to "none" and then assigns "play,done". * rplayd/audio/audio_solaris.c (dbri_table): New match table. * rplayd/audio/audio_sun.c (dbri_table): New match table. * Added `rplaytool' to the contrib directory. See contrib/rplaytool/README for more information. Tue Jan 31 15:39:24 1995 Mark Boyns * rplayd/native.c: Fixed yet another byte-order problem. The adpcm_decode routines already generate 16-bit audio in the native format so no byte swapping is necessary. Fri Jan 27 16:07:26 1995 Mark Boyns * librplay/rplay.[ch]: Added the RPLAY_CLIENT_DATA attribute. This attribute can be used to associate a null-terminated string with a sound. The RPTP `client-data' attribute will also be added so clients can associate data with RPTP commands and the command responses. Tue Jan 24 21:38:57 1995 Mark Boyns * rplayd/audio/audio_hpux.c (rplay_audio_init): a few minor modifications and changed the default output port to the speaker and headphone. (The original default of headphone was confusing some people since they couldn't hear anything :) * Finished adding support for real-time audio flows. The `play' and `put' RPTP commands have been extended to send audio data to rplayd. `play' now accepts the following attributes: input, input-offset, input-format, input-byte-order, input-sample-rate, input-bits, input-channels, and input-storage. (Thanks to Hendrik for input-storage). input=flow begins a flow and the rest of the attributes default to what's contained in the audio header. input-storage defaults to "none" which tells rplayd to discard flow data. Setting input-storage to "disk" tells rplayd to eventually save the flow data to `rplay.cache'. Flows saved to disk may have unique file names generated by rplayd. `put' now accepts the id attribute which tells rplayd where to store/play the audio data. Note that multiple clients can "put" data into the same spool entry. (spool sharing?) The new `done' command is used to terminate a flow. `done' is the same as `stop' for local audio files. Tue Jan 17 22:43:14 1995 Mark Boyns * rplayd/connection.c: `+' responses for RPTP commands are now guaranteed to *always* come before any `@' responses (events) that the commands may generate. This helps clients to reliably keep track of events. Mon Jan 16 13:22:34 1995 Mark Boyns * rplayd/connection.c (connection_notify): New RPTP `modify' event. This event provides notification when spool entries are modified with the `modify' command. * rplayd/command.c (command_modify): New RPTP `modify' command which can be used to modify spool attributes. Currently count, list-count, priority, sample-rate, and volume can be modified. Sample rate modification was suggested by Richard Stallman . * rplayd/native.c (native_table): Fixed byte-order problems. (check_buffers): Fixed a memory leak. Sun Jan 15 11:02:47 1995 Mark Boyns * rplayd/sound.c: Added support for G.721 4-bit, G.723 3-bit, and G.723 5-bit compressed audio files. Public domain G.72x encoding and decoding routines written by Sun Microsystems are located in the new adpcm directory. Suggested by Germano Caronni Tue Jan 10 13:29:17 1995 Mark Boyns * rplayd/audio/audio_sun.c (rplay_audio_init): Now recognize the SS5 CS4231 audio chip correctly on SunOS 4.1.X. Thanks John Denune . Sun Jan 8 22:47:04 1995 Mark Boyns * rplay/rplay.c: Disabled GNU getopt permutation of arguments since order is important. Sat Jan 7 10:41:30 1995 Mark Boyns * rplayd/{rplayd.c,spool.c}: Fixed audio matching bug reported by Germano Caronni . Tue Jan 3 10:54:35 1995 Mark Boyns * rplayd/sound.c (sound_open): now does a lot of what sound_map used to do. * rplayd/audio/audio_solaris.c (rplay_audio_init): Added support for the SUNW,CS4231 device. (rplay_audio_init): Use AUDIO_INITINFO instead of AUDIO_GETINFO. Thanks jhempe@broadvision.com (John Hempe). * rplayd/audio/{audio_sun.c,audio_solaris.c}: Updated `dbri_table' with more supported audio configurations. Optional settings are checked in a more consistent manner. * rplayd/audio/audio_sun.c (rplay_audio_init): Use AUDIO_INITINFO to initialize audio_info_t instead of AUDIO_GETINFO. * include/config.h.in: Added `/devices' to BAD_DIRS. Suggested by Germano Caronni . Mon Dec 26 11:06:51 1994 Mark Boyns * GNU indent'ed rplay, rptp, librplay, and rplayd. * rplayd/rplayd.c (audio_test): Test supported audio configurations. Enabled with the new `--audio-test' option. Sat Dec 24 09:02:34 1994 Mark Boyns * rplayd/spool.c (spool_update): Fixed event `done' bug. * Added new version of xrplay from Andrew Scherpbier . This version fixes the refresh problems and adds lots of new options. See `xrplay --help' for more details. Tue Dec 13 17:04:59 1994 Mark Boyns * rplayd/connection.c (connection_notify): Fixed non-ANSI C bug reported by kooper@cc.gatech.edu (Rob Kooper). Mon Dec 5 14:09:28 1994 Mark Boyns * Version 3.2.0 beta released. * rplayd/rplayd.c: Added `--options-file=FILE' option to rplayd. This option allows rplayd options to be read from the specified filename. Sun Dec 4 01:25:55 1994 Mark Boyns * Merged several typos and grammar errors reported by Andrew Scherpbier . * doc: Updated RPLAY.html, RPTP.html, and librplay.html. Automatically create index.html which is a HTML index of all the HTML documentation. HTML browsers should startup with index.html. * include/config.in: Changed the following defaults: RPLAY_CACHE_SIZE - 8MB MEMORY_CACHE_SOUND_SIZE - 2MB MEMORY_CACHE_SIZE - 4MB * rplayd/audio: Added audio tables to audio_sun.c audio_solaris.c, and audio_generic.c. * rplayd/spool.c (spool_play): Improved --audio-match to use an audio table of supported audio device configurations. This table is used to choose the closest supported match. Sat Dec 3 14:57:02 1994 Mark Boyns * doc: created the librplay.html document which is a replacement for README.LIBRPLAY. * doc: created the RPLAY.html document which describes the RPLAY protocol and finally explains what's in those mysterious RPLAY packets. * doc: man pages and HTML documents are now created automatically for rplayd, rplay, rptp, and xrplay. These new man pages do not contain as much information as the previous versions, but they are now up-to date. * configure.in: `configure' now accepts the --target option. This option can be used to force a specific configuration to be used. Example: `configure --target=sun' Fri Dec 2 09:50:07 1994 Mark Boyns * configure.in: Add `-laudio' automatically for SGI systems. Sun Nov 27 00:09:37 1994 Mark Boyns * Started to re-organize the contrib directory. xvolume and volume have been removed since they have been replaced by xrplay and `rptp volume'. There's now a contrib/patches directory which contains all the window manager patches. * Hopefully fixed the `install' bug. * rplayd/sound.c (sound_map): Added MAP_FILE to the mmap flags. Suggested by Ben Jackson . * rplayd/spool.c (spool_ready): Fixed bug reported by Germano Caronni . The symptoms were "Play a long song. While it is playing, load two short samples from somewhere else. Crash for free." * rptp/rptp.c: Changed `rptp' to support the new RPTP protocol. * Changed the initial RPTP connection line to contain name-value pairs. * Changed the RPTP status command to return one line name-value pairs. * librplay/rptp.c (rptp_parse): New rplay library function which is used to parse the RPTP name-value pairs. This function is used as follows: /* Return the value of `name' where `name=value' is in the response string. */ value = rptp_parse (response, "name") /* Same as above but return the value of `name' in the previously specified response. */ value = rptp_parse (NULL, "name") /* Return the first `name' in the response `name=value' list. */ name = rptp_parse (response, NULL) /* Same as above but return the next `name' is the previously specified response. name = rptp_parse (NULL, NULL) * Changed all RPTP commands to support name-value pairs. Some commands still support the old-style RPTP so older rplayds can still communicate. * Added xrplay to the top level rplay source tree. xrplay was written by Andrew Scherpbier and is a new and improved version xvolume. New features include bitmap buttons for previous sound, play/pause, stop, and next sound. xrplay takes full advantage of the new event notification and the `set' and `skip' commands. Thanks Andrew! * Added the RPTP skip command which is used to skip to sounds in a sound list. * Added the RPTP set command which is used to set server attributes. The current attributes that can be set are application, notify, and volume. The application and volume commands are now implemented using set. Please avoid using these commands since they are considered obsolete and may be removed. * Added RPTP event notification. All events are reported using a line beginning with `@', followed by name-value pairs. Event notification can be enabled and disabled using the RPTP set command. See doc/RPTP.html for more details. * Changed the RPTP protocol to use name-value pairs for command arguments and command results. This new and improved RPTP is documented in doc/RPTP.html and the old README.RPTP is now obsolete. Wed Nov 16 11:20:15 1994 Mark Boyns * rplayd/audio/audio_*.c (rplay_audio_set_volume): Always set `rplay_audio_volume' to the volume of the audio device. Tue Nov 15 20:57:17 1994 Mark Boyns * Added BAD_DIRS option to config.h. The value of BAD_DIRS is a colon separated list of directories that cannot be accessed by rplayd. The default is "/dev:/etc". Thu Nov 10 10:35:31 1994 Mark Boyns * Added more SGI patches from Rob Kooper. These patches include fixes for 16-bit audio and an SGI select/timer bug. Wed Nov 9 17:20:51 1994 Mark Boyns * librplay/rplay.c (rplay_ping): Now ping both the port listed in /etc/services and either RPLAY_PORT or OLD_RPLAY_PORT depending on which one isn't in /etc/services. This should fix some problems with inetd that people have been experiencing. Tue Nov 8 14:15:15 1994 Mark Boyns * Version 3.2.0 alpha7 released. * rplayd/rplayd.c: New option `--audio-match' which attempts to match the sample rate of the audio device with the sample rate of the current sound when no other sounds are playing. If the match fails, --audio-sample-rate is used. This option overrides --audio-bufsize. This option is currently not enabled by default, but it may be in the future. Suggested by Germano Caronni and Raphael Quinet . * rplayd/rplayd.c (rplayd_audio_init): New function used to (re)initialize the audio device. Mon Nov 7 11:32:22 1994 Mark Boyns * rplayd/sound.c (sound_map): added support for .ub files which are Macintosh unsigned byte files. .ub files may also be incorrectly named with a .snd extension. * rplayd/sound.c (sound_map): added support for .voc files which is really simple so far. All the .voc files that I've found seem to work. * rplayd/command.c (command_status): display audio-port info. * Added real --audio-port support to audio_sun and audio_solaris. audio_linux, audio_generic, and audio_sgi simply set the port to `speaker'. audio_hp already has port support. * rplayd/rplayd.c: New --audio-port option which can be used to specify rplayd audio output ports. Valid ports are `speaker', `headphone', and `lineout'. Suggested by Hendrik (J.C.Harrison@ncl.ac.uk) * rplayd/audio/audio_hpux.c: Added new version of audio_hpux.[ch] from Hendrik (J.C.Harrison@ncl.ac.uk). Fri Nov 4 15:47:00 1994 Mark Boyns * Added audio_sgi.[ch] to the rplayd/audio directory. These files contain the new SGI audio support written by kooper@dcs.qmw.ac.uk (Rob Kooper). Rob's patches also included bug fixes for the .wav and .aiff parsing. * Removed the [-PNnv] entries from the help messages for the connection, pause and stop RPTP commands. Those options are ignored by rplayd. Suggested by Germano Caronni Sun Oct 30 21:55:32 1994 Mark Boyns * configure.in: Updated to use autoconf 2.0 features. Wed Oct 12 23:28:56 1994 Mark Boyns * rplayd/audio/audio_solaris.c (rplay_audio_init): Added check for dbri device on Solaris 2.x systems. Tue Oct 11 10:14:26 1994 Mark Boyns * include/config.h.in: Changed OLD_RPLAY_PORTS to OTHER_RPLAY_PORTS since `OTHER' makes more sense. Sun Oct 9 00:22:33 1994 Mark Boyns * rplayd/rplayd.c (main): Audio click detection/prevention. * Added RPLAY_RESET packet and RPTP reset command which tell the server to reset itself. Support has been added to librplay, rplay, rptp, and rplayd. Suggested by Raphael Quinet. * librplay/rplay.c (rplay_open_port): Create an RPLAY/UDP socket with a specific port. (rplay_open): Use rplay_open_port with the port in /etc/services or RPLAY_PORT. * rplayd/rplayd.c (usage): Added --rplay-port (--port), --rptp-port, --other-rplay-port, and --other-rptp-port options to rplayd. Sat Oct 8 23:57:14 1994 Mark Boyns * rplayd/native.c: Created native.c and native.h which implement a new audio processing scheme. (fake_volume): Fake volume support is now handled by this routine. Sat Sep 24 10:24:29 1994 Mark Boyns * rplayd/spool.c: A critical section now blocks the timer to hopefully prevent a race condition. * rplayd/timer.c: Added timer_block () and timer_unblock () which block and unblock SIGALRM. Sun Sep 18 22:46:25 1994 Mark Boyns * Makefiles now allow CFLAGS to be changed on the `make' command line. (i.e. `make CFLAGS="-O2 -g"') * rplayd/spool.c: Changed the spool from an array to an linked list. * Fixed all known memory leaks except for the leaks in GNU GAS' hash.[ch]. * audio.c & rplayd.c: Added fake hardware volume support which is enabled when `FAKE_VOLUME' is #defined. Wed Aug 31 22:39:21 1994 Mark Boyns (boyns@mojo.sdsu.edu) * Changed all of rplayd's hash_ routines to xhash_. This change makes it very simple to move from one hashing library to another. * rplayd now uses hash.[ch] from GAS, the GNU Assembler. hash.[ch] are now included in the lib directory. * rptp/rptp.c: Added --raw (-r) option to the rptp client. This option forces the client to display all of the RPTP data received from the server. Sun Aug 28 00:48:07 1994 Mark Boyns (boyns@mojo.sdsu.edu) * rplay/rplay.c (usage): Added GNU getopt support to the RPLAY client. * rptp/rptp.c (usage): Added GNU getopt support to the RPTP client. * Replaced support with the lib directory which now contains a library that includes getopt, regex, strdup, etc. Wed Aug 24 09:38:59 1994 Mark Boyns (boyns@hercules.sdsu.edu) * rplayd/audio/audio_hpux.c: Added audio_hpux module provided by J.C.Harrison@newcastle.ac.uk. This code was developed on a HP9000/710. Tue Aug 23 20:36:37 1994 Mark Boyns (boyns@mojo.sdsu.edu) * rplayd/rplayd.c (usage): Replaced the --sound-cache-size option with --memory-cache-size and --memory-cache-sound-size. Thu Aug 18 15:55:47 1994 Mark Boyns (boyns@hercules.sdsu.edu) * librplay/rplay.c (rplay_unpack): changed ntohs to ntohl for the unpacking of the sample rate. * Finally got console access to a Linux system! Wed Aug 17 10:36:36 1994 Mark Boyns (boyns@hercules.sdsu.edu) * Fixed lots of autoconf files/parameters to fix problems with Solaris and possibly other systems. * rplayd/server.c (server_read): unknown hosts in rplay.servers no longer cause rplayd to exit. Tue Aug 9 17:14:44 1994 Mark Boyns (boyns@hercules.sdsu.edu) * Version 3.2.0 alpha4 released. Mon Aug 8 23:39:55 1994 Mark Boyns (boyns@mojo.sdsu.edu) * rplayd/rplayd.c (usage): Added the --sound-cache-size option to rplayd. The default value is RPLAY_SOUND_CACHE_SIZE. * include/config.h.in: Added RPLAY_SOUND_CACHE_SIZE configuration option. * rplayd: Finished implementing sound caching scheme. Sounds <= sound_max_cache_size are cached in memory using mmap or malloc. All of the sound io routines have been changed to use SINDEX (sound index). A SINDEX can be used to reference a cached or a non-cached sound. * Added HAVE_MMAP check. Sat Aug 6 10:32:20 1994 Mark Boyns (boyns@mojo.sdsu.edu) * rplayd/rplayd.c: Changed the default buffer-scheme from "load" to "none". * Added checks for HAVE_CONFIG_H, HAVE_STRING_H, and HAVE_MEMORY_H. * rplayd/cache.c (cache_create): changed "return NULL" to "return -1". (oops) Tue Jul 12 16:12:44 1994 Mark Boyns (boyns@hercules.sdsu.edu) * Added FreeBSD patches from Brian Childs (brian@claremont.com). Thanks Brian! Fri Jun 24 22:58:25 1994 Mark Boyns (boyns@mojo.sdsu.edu) * Version 3.2.0 alpha3 released. Wed Jun 22 20:45:39 1994 Mark Boyns (boyns@mojo.sdsu.edu) * Added HP patches that Richard Lloyd sent me about a month ago. Thanks. Tue Jun 21 23:32:28 1994 Mark Boyns (boyns@mojo.sdsu.edu) * rplayd/rplayd.c (rplayd_write): Fixed problems with new audio buffer code. BTW, the new code will make fast- forwarding and rewinding possible someday. Sun Jun 19 21:25:52 1994 Mark Boyns (boyns@mojo.sdsu.edu) * rplayd/rplayd.c (rplayd_write): Re-wrote audio buffer management routines. Wed Jun 15 14:09:15 1994 Mark Boyns (boyns@hercules.sdsu.edu) * rplayd: added optional_format to all the system audio stubs. * rplayd: added --audio-format, --buffer-scheme, and --help options. Tue Jun 14 23:23:39 1994 Mark Boyns (boyns@mojo.sdsu.edu) * doc/man1/rplayd.1: updated the man page with all of the new long-named options. * rplayd: added --auth and --no-auth options which enable and disable host access authentication when rplayd is compiled with AUTH defined. * rplayd: use GNU getopt to parse rplayd's options. All previous options now have long-named options. getopt.[ch] and getopt1.c have been added to the rplayd directory. Tue Jun 14 08:39:03 1994 Mark Boyns (boyns@hercules.sdsu.edu) * rplayd/audio/audio_linux.c (rplay_audio_flush): use rplay_audio_fd instead of audio_fd. Mon Jun 13 22:37:33 1994 Mark Boyns (boyns@mojo.sdsu.edu) * rplayd/misc.c: Added the sys_err_str routine which is used to obtain system error messages. This routine replaces the need for using sys_errlist all over the place. All occurrances of sys_errlist have been replaced with a call to sys_err_str. This routine tries to use strerror if autoconf can find it. Otherwise, sys_errlist[errno] is used. * rplayd/host.c: rplayd doesn't exit anymore when a hostname cannot be resolved. The invalid rplay.hosts entry is ingored. Sun Jun 12 21:39:33 1994 Mark Boyns (boyns@mojo.sdsu.edu) * Added rplay_audio_flush_timeout to rplayd. The timeout value is used to determine when the audio device should flushed. Valid values are: n > 0 : flush after n idle seconds n == 0 : never flush n == -1 : flush when the spool is empty (this is the default) n == -2 : flush after each audio write rplayd has a new -F option which used to specify the flush timeout value. * Added RPLAY_AUDIO_FLUSH_TIMEOUT to all the rplayd/audio/audio_*.h files with a default value of -1. * Use AC_HAVE_FUNCS instead of AC_REPLACE_FUNCS in configure.in. * Created the rplay mailing list - rplay@sdsu.edu. This is a Majordomo list so send a message that contains "subscribe your_username@your.hostname" to rplay-request@sdsu.edu to be added to the list. (the subject of the message will be ignored) See README for more details. * Renamed the CHANGES file to ChangeLog. * Started using Emacs' add-change-log-entry to document changes. Previous ChangeLog entries in the old CHANGES format: * Version 3.2.0 alpha2 released. * New version of XVolume that has pause, continue, and stop buttons. Thanks Andrew. * Added references to XSession and XMailbox++ to the README file. * rplayd timeout works again. * Fixed bug in rplayd/timer.c - sa_flags was never initialized. oops :) Thanks Rob Mallory. * Added automatic detection of changes made to the rplay.conf, rplay.servers, and rplay.hosts files. Changed files are only automatically re-read when rplayd is ready to do so. SIGHUP still forces rplayd to re-read all files. * Fixed audio_sun.c so it will compile on pre-SunOS 4.1.3 systems. * Added tkrplay to the contrib directory. This is my first Tcl/Tk program. :) * Sound lists no longer have one second delays between sounds. * Changed the default log level to 0 - no logging. * Added support for a few new features of GNU autoconf 1.8 and higher. * I'm going to phase out the use of ports 55555 and 55556 since they don't work on HP's. The new ports will be 5555 and 5556 respectively. rplayd has been modified to support both pairs of RPLAY/RPTP ports. This support is enabled with the OLD_RPLAY_PORTS #define in config.h. * Added the wait RPTP command which can be used to have clients block until the desired event has occurred. For example: wait play petergun.au - client will block until petergun is done playing wait volume - client will block until the volume has changed wait #34 - client will block until spool id #34 is done playing wait can prefix any RPTP command but it is only effective with the play and volume commands. Generic wait events may be added later. * Added RPTP wait support to xvolume. Now the xvolume slider is automagically updated when any client changes the volume with the RPTP volume command. * Added RPTP wait support to the rptp client. * Added RPTP status command which is used to obtain RPTP server statistics. * Added RPTP status support to the rptp client. * Added RPTP application command which is used to notify rplayd what application is talking to it. Now "list connections" can display things like this: list connections +connections HOST TYPE IDLE APPLICATION WHAT 130.191.225.64 client 1 rptp (idle) 127.0.0.1 client .47 XVolume 1.3 wait volume 127.0.0.1 client 2 wait volume . The idea of using a command like application was suggested by Raphael Quinet a long time ago. I recommend that all RPTP applications use the application command to tell rplay who they are. Older rplayds will not understand this command so applications can ignore any '-' error received. * Added RPTP application support to the rptp client and XVolume. * Created the support directory which contains library routines that configure couldn't find. Now rplay.h doesn't have a prototype for strdup since rplay sources include support.h now. * Fixed a memory leak in the re-reading of rplay.conf. * Added linux patches from Mark Skouson (skouson@gecko.ee.byu.edu). The patches include fixes for audio flushing. * Created the patches directory and put HP patches and Linux audio module that contains GUS support. * rplayd used to read sounds in one second chunks. The second that was read was one second of data according to the sample rate of the file, not the sample rate that rplayd was writing. Now rplayd reads curr_bufsize * curr_rate bytes at a time. This helps a lot. -------------------------------------------------------------------------------- rplay 3.2.0alpha major improvements and changes from rplay 3.1.1beta (there never was a non-beta release of 3.1.1) * GNU Autoconf is now used to configure rplay. * Added tvtwm, twm, and ctwm patches to the contrib directory. Thanks J.E. Sacco (jsacco@ssl.com). * rplayd can now be reset by sending it a SIGHUP. When the signal is received, all playing sounds are stopped, connections are closed, and the sounds, hosts and servers files are reread. * Added XJukebox 0.9 to the contrib directory. * Added a new version of XVolume to the contrib directory. * Added mailnoise to the contrib directory. * RPTP volume now supports +value and -value. * Added info and load RPTP commands. * Support for 8-bit and 16-bit audio input and output. * Support for Sun's speaker box. * Support for all sample rates. * Added -R option to rplay. This is LOTS of fun! * Support for .aiff and lots of .au files. * rplay now accepts relative pathnames. Thanks Raphael. * rplay can now do things like this: rplay -n3 -v30 bogus -n2 -v200 excellent * The rptp client now accepts RPTP commands on the command line. Example: rptp -h sounds.sdsu.edu list sounds This feature makes the contrib/volume program unnecessary since the same thing can be accomplished with "rptp volume ". * Fixed a serious bug for systems that have an IP address of 127.0.0.1. * Added the FvwmSound module to the contrib directory. * Re-designed rplayd's audio writing scheme. This has no user-visible changes but it was a lot of work. The -r and -b options are still valid. * Added byte info to the "list connections" RPTP command. It now looks like this: HOST TYPE IDLE WHAT 127.0.0.1 client (idle) 130.191.224.8 server get 2lust.au (2017372/2195456) * Added the version RPTP command. * Support for .wav files. * Support for stereo input and output. * Removed the remote-install Makefile target. * Fixed problems with previous rplay command line options and added the following: rplay -s, rplay -p, and rplay -c will stop, pause, and continue ALL sounds when no sounds are specified. This is easier than having to type rplay -s #0. * Added the -N option to rplayd. This disables audio and is only useful for RPTP servers without an audio device. rplayd will also disable audio if it cannot open the audio device when it starts. * Fixed the audio close timeout code. * Removed the load RPTP command. * The RPTP volume command now supports + and - which are used as volume offsets. * Re-designed rplayd's audio reading & writing scheme. Now audio files are read piece by piece. Normally only one second of audio data is used at a time so rplayd does not have to use lots of memory when playing large audio files. As a result, all the mmap code has been removed from rplayd. * Added fingergoodies to the contrib directory. Thanks Raphael. * Fixed rplayd's idle mode. * Disabled the sound_cleanup_timeout in rplayd since it's not necessary anymore. * Fixed serious bug in spool_init/spool_clear. -------------------------------------------------------------------------------- rplay 3.1.1beta major improvements and changes from rplay 3.1.1 (BETA): * Added the RPTP volume command. (Only works on Suns so far) * Added XVolume to the contrib directory. Thanks for all the Xlib code Andrew. * Added volume to the contrib directory. * Added the remote-install Makefile target. * Added the samples and site directory to simplify installation. * Added the -A option to rplayd which specifies an alternate audio device. * Added more checks for interrupted systems calls in rplayd. * Added RPLAY packet forwarding to rplayd. When the -f option is used, all RPLAY packets will be forwarded to . Note that RPTP traffic is not forwarded. * Added support for hosts with multiple IP addresses. * Now localhost (127.0.0.1) is automatically added to the host access list if the local host's address is found. * rplayd now has a better "idle mode". * Changed the range of spool ids from 1..SPOOL_SIZE to 1..999. * Changed the RPTP play protocol to return the spool id. For example: play bogus.au when successful will return: +218 where 218 is the spool id associated with the sound. Thanks for the suggestion Raphael. * Added some xpilot sound configuration files to the contrib/xpilot directory. * Added XJukebox 0.8 to the contrib directory. This program is still under development so there might still be a few bugs. Thanks Raphael. * Added olvwm rplay 3 patches to the contrib directory. Thanks Joseph E. Sacco . * Released 11/4/93. -------------------------------------------------------------------------------- rplay 3.1.1 (BETA) major improvements and changes from rplay 3.1.0: * Added audio timer code. Now audio data is written at a configurable rate to the audio device. The default audio write rate is 20 times per second. The size of the audio data written is also configurable, with the default size being the sample rate of the audio device divided by the audio write rate. For Sun's, which have a sample rate of 8000, 400 bytes of audio data is written to the audio device 20 times per second. The end result of all this is that sounds are now played/paused/continued/ stopped immediately, when before there were delays. * Added the -r option to rplayd to control the audio write rate. * Added the -b option to rplayd to control the size of the audio buffer size. * Changed rplayd to accept RPLAY_COUNT and RPLAY_LIST_COUNT with values of zero. Now when the values are zero the sound or sound list will be repeated forever. * Removed the use of usleep(). * Added the RPLAY_RPTP_SEARCH attribute which specifies whether or not rplayd should search for the given sound. * Added the RPLAY_RPTP_SERVER and RPLAY_RPTP_PORT attributes which specify the RPTP server to use if the given sound is not found. This server overrides the default servers listed in the rplay.servers file. * Added Raphael's jukebox 1.3 to the contrib directory. * Added the RPLAY_RPTP_FROM_SENDER attribute which tells rplayd to try and obtain sounds from the sender when they are not found locally. * Added "COUNT" to the "list spool" output. * Added rplayd logging facilities which were inspired by Raphael Quinet's logging patches. Default logging parameters are specified in include/conf.h and can be specified using -l and -L rplayd options. * Implemented spool ids. Each spool entry is assigned a unique spool id when it is inserted in the spool. Valid spool ids range from 1 to the maximum spool size (defined in include/conf.h). Spool id 0 can be used to reference all sounds in the spool. Now all sounds can be stopped using: rplay -s #0 or rptp> stop #0 Specific spool entries can be stopped/paused/continued using the following: rplay -p #1 #5 #6 /* pause spool entries #1 #5 & #6 */ rplay -c #1 /* continue spool entry #1 */ Note that the spool id extension assumes that no sounds begin with the '#' character. The "list spool" output now looks like: SID HOST STATE VOL PRI COUNT SECONDS REMAIN SOUND 1 127.0.0.1 play 10 0 0 6 2 spacemusic.au * Made spool matching less specific. Now only sound names are compared where before all the attributes were compared. When a sound is played with: rplay -v200 -P255 petergun it can be stopped using only: rplay -s petergun * All spool entries are now checked for a match. For example, if there are 10 spool entries playing "petergun", all of them can be stopped using a single "rplay -s petergun". -------------------------------------------------------------------------------- rplay 3.1.0 major improvements and changes from rplay 3.1 (BETA3): * Added SGI Indigo patches from Mike.Hoffmann@mch.sni.de. * Added a newer version of Raphael's jukebox 1.2 which includes a man page. * Added patches from Raphael to support DEC 3100's running Ultrix 4.2, with cc or gcc-2.4.5. These patches do not include audio support, however, a DEC can be used as a sound server. * Added more idle information to the "list connections" display. * Released 9/1/93. -------------------------------------------------------------------------------- rplay 3.1 (BETA3) major improvements and changes from rplay 3.1 (BETA2): * RPTP commands "play", "pause", "continue", and "stop" now accept the following options (similar to the rplay client): -P Sound priority. -N Number of times to play the sound list. -n Number of times to play each sound. -v Volume. * Fixed bug which caused sounds to get stuck in the spool when the first RPTP server was unavailable. (mgyger@itr.ch) * Fixed bug which caused sounds to get stuck in the spool when the TCP connection was lost during a sound transfer. (quinet@montefiore.ulg.ac.be) * The volume of low priority sounds is lowered when higher priority sounds are in the sound spool. Each sound's volume is lowered depending on it's priority relative to the highest priority. * sound_delete now deletes sound files. * Sounds that are transferred by rplayd are stored in the cache using the name that the remote rplayd sends. (quinet@montefiore.ulg.ac.be) * Sound cleanup will no longer cleanup sounds that have events associated with them. It took a long time to find this one! Thanks for your slow network connection Raphael. * Added SOUND_CLEANUP_TIMEOUT to include/conf.h so the cleanup timeout can be configured. * Added a newer version of mailsound to the contrib directory. The new version has a lot of new options. Thanks Andrew. * Changed PORTABLE_LONG macro to use (unsigned char *). (mrh@io.nosc.mil) * Added more Solaris 2.x suggestions from Kjetil Wiekhorst J{\o}rgensen . * Added 386bsd patches to audio.c from Mike Halderman (mrh@io.nosc.mil). The 386bsd patches require the soundblaster driver version 1.5 written by Steve Haehnichen (shaehnic@ucsd.edu). -------------------------------------------------------------------------------- rplay 3.1 (BETA2) major improvements and changes from rplay 3.1 (BETA): * Fixed bug in rplayd's "put" implementation. (quinet@montefiore.ulg.ac.be) * Fixed segmentation violation when rplayd had no rplay.servers. (quinet@montefiore.ulg.ac.be) * The rptp client now handles IP addresses correctly and deals with connections being closed and timed out much better. * Corrected many mistakes in the documentation. (quinet@montefiore.ulg.ac.be) (mgyger@itr.ch) * Added '!' (RPTP_TIMEOUT) as an RPTP response type. * Added RPTP_ERROR_TIMEOUT to the possible rptp_errno values. * Fixed server timeout handling in rplayd. * Fixed a nasty bug in rptp_getline. * Added the use of the RPLAY_HOST environment variable. The host defined by RPLAY_HOST specifies a default rplay host. When RPLAY_HOST is not defined localhost will be used. The new rplay library routine char *rplay_default_host(void) can be used to obtain the default rplay host. * Changed the -h option in the rplay client. -h is now used to specify an rplay host. Now a hostname does not have to be specified. For example: "rplay bogus.au" uses RPLAY_HOST or localhost. "rplay -h bozo bogus.au" uses bozo. * Changed the -h option in the rptp client. -h is now used to specify an rptp host. Now a hostname does not have to be specified. For example: "rptp" uses RPLAY_HOST or localhost port 55556. "rptp -h bozo" uses bozo port 55556. * Removed the -h option from rplayd to be consistent with the other programs. -h will still display the usage information in all the programs since either an option is required or the option is not valid. * Added int rplay_default(char *sound) to the rplay library. * Cleaned up rplayd's memory usage. Sounds are now unmapped when the audio device is closed. * Fixed a bug in rplayd's event handling routines. Now sounds that are being transferred don't get stuck in the spool. * Comments were moved in Makefile.config to avoid bugs in some versions of make. (sinster@scintilla.santa-clara.ca.us) * The mail command used by "make mail" is now defined in Makefile.conf. * Added more fixes for HP-UX. (mgyger@itr.ch) * Added int rplay_open_default(void) to the rplay library. * Added jukebox version 1.2 to the contrib directory. Thanks again Raphael. -------------------------------------------------------------------------------- rplay 3.1 (BETA) major improvements and changes from rplay 3.0 PL2: (This release has many changes so I probably have forgotten some of them.) * Completely re-organized the rplay source tree. * Designed and implemented RPTP. This includes writing the RPTP client and adding RPTP support to rplayd. Please read doc/README.RPTP if you want to learn more about RPTP. * Added the following routines to librplay: int rplay_host_volume(char *host, char *sound, int volume) int rplay_open_sockaddr_in(struct sockaddr_in *saddr) int rplay_ping(char *host) int rplay_ping_sockfd(int rplay_fd) int rplay_ping_sockaddr_in(struct sockaddr_in *saddr) int rptp_open(char *host, int port, char *response, int response_size) int rptp_read(int rptp_fd, char *ptr, int nbytes) int rptp_write(int rptp_fd, char *ptr, int nbytes) int rptp_putline(int rptp_fd, char *fmt, ...) int rptp_getline(int rptp_fd, char *buf, int nbytes) int rptp_command(int rptp_fd, char *command, char *response,int response_size) int rptp_close(int rptp_fd) void rptp_perror(char *message) * Added the RPLAY_PING attribute to the RPLAY protocol. This attribute is used by RPTP to wakeup rplayd since inetd can't invoke one program using two ports. * Now using the GNU General Public License Version 2. * Add the rplay.servers file which lists the rplay servers that rplayd should contact to obtain sound files. * Implemented the sound cache where rplayd will store sound files it obtains. * Changed the format of the rplay.hosts file to accept wildcards and access permissions. * Fixed a bug that caused some rplay packets to incorrectly have permission denied. * Changed rplayd to accept sounds which are not in the rplay.conf and are available locally. For example, is /tmp/foo.au is not in the rplay.conf it can still be played using 'rplay hostname /tmp/foo.au". * Changed include/conf.h to '#define AUTH' by default. * Switched to Darren Senn's hsearch implementation. * Included Darren Senn's PORTABLE_LONG macro which is useful when examining ulaw file headers on multiple architectures. * Wrote some manual pages which are in the doc directory. * Updated doc/README.LIBRPLAY to included the new RPTP extensions. * Added a NEW version of mailsound to the contrib directory. The new version has a lot of new options. Thanks Andrew. * Added crossfire to the contrib directory. * Added HP-UX patches from rkl@csc.liv.ac.uk (Richard Lloyd) and Markus Gyger . * Conversion tables are now used for both ulaw->linear and linear->ulaw. The tables were contributed by Markus Gyger . * Headerless ulaw files can still be played if their filename extension is either .au, .u, or .ul as suggested by Markus Gyger . * Added Solaris 2.x patches from Kjetil Wiekhorst J{\o}rgensen . -------------------------------------------------------------------------------- rplay 3.0 PL2 major improvements and changes from rplay 3.0 PL1: * Use strchr and strrchr instead of index and rindex. * Added -r (random pick) option to the rplay client. * Added RPLAY_RANDOM_SOUND attribute which will pick a sound randomly from a sound list. See README.LIBRPLAY for an example. * Added jukebox to the contrib directory. See contrib/jukebox1.1/README for more details. (Thanks quinet@montefiore.ulg.ac.be) * Changed rplayd to handle filenames with spaces correctly. * Fixed librplay.c and rplayd.c prototypes to support non ANSI C compilers. (Thanks infmx!cheetah!dranney@uunet.UU.NET) * Added the following to the rplay library to make playing sounds even easier: (See README.LIBRPLAY for more information) int rplay_open_display(void); int rplay_display(char *sound); int rplay_local(char *sound); int rplay_host(char *host, char *sound); int rplay_sound(int rplay_fd, char *sound); -------------------------------------------------------------------------------- rplay 3.0 PL1 major improvements and changes from rplay 3.0: * Changed conf.h to '#undef AUTH' (host authentication). * Changed rplay_set to strdup() sound filenames. * Added -n (count), -N (list count), and -P (priority) options to the rplay client. * Added RPLAY_PRIORITY attribute. Priorities range from 0 to 255 (0 being the lowest priority). Sounds with higher priorities will replace lower priority sounds when the sound spool is full. * Sounds can be referenced using complete pathnames. This helps to avoid problems when different sound files have the same name. * Sound filename extensions are now optional. If extensions are used they are enforced. * Added RPLAY_LIST_COUNT attribute. The sound list will be played count number of times. * Added RPLAY_COUNT attribute. Each sound in a sound list will be played count number of times. * Fixed select's usage of timeval struct. (sinster@scintilla.santa-clara.ca.us) * Cleaned up the code a little. Added better ANSI C support and put in a little more documentation. * Fixed some spelling mistakes. * Removed -V option from the rplay client. -------------------------------------------------------------------------------- rplay 3.0 major improvements and changes from rplay 2.0: * rplayd is no longer based on Sun's lwp library. This will make rplay portable to machines other than SPARCstations. Hopefully soon rplay will work with BSDI, Linux, and maybe 386bsd. Only 8 bit ulaw audio files are currently supported. * The rplay library has been rewritten and is now much more flexible for rplay additions. This new library is not compatible with the rplay2.0 library, what I mean is that old rplay programs will not compile. See WARNING and README.LIBRPLAY for conversion help. * A more flexible rplay protocol is used. The rplay2.0 protocol can still be supported. See conf.h. * Host authentication can be used to allow only certain machines access to play sounds. See conf.h and INSTALL. * Compile time option to use mmap or malloc and read to load sound files. See conf.h. * inetd support can be disabled with a command line option * rplayd timeouts can be changed or disabled with command line options * rplayd has many other options, run rplay -h to see them. * rplayd speed enhancements -------------------------------------------------------------------------------- rplay 2.0 major improvements and changes from rplay 1.2: * Sounds are no longer indexed by id, the sound names are now used. * Sounds can be played, paused, continued, and stopped. * Each sound can have a volume associated with it. A volume is a number between 0 and 255 and it is relative to the actual volume of the audio device. * Sequences of sounds are supported. This is useful for playing sentences or sounds that need to be played sequentially. * mmap is now used to read sounds. This increases performance and saves a lot of memory. Thanks to stripes@pix.com for this suggestion. * Broadcasting sounds. To use this just use a broadcast address instead of a hostname. For example, I use: rplay 130.191.255.255 burp.au to play burp.au on all our machines running rplayd on our subnet. * The Sun audio stuff is no longer used. Thanks to libst.c and libst.h from Sound Tools. See these files for more information. * Released 11/12/92. -------------------------------------------------------------------------------- * rplay 1.2 released 7/20/92 * rplay 1.1 released 7/13/92 * Original rplay released sometime in May or June of 92, I have forgotten. rplay-3.3.2/INSTALL100644 153 62 13761 6564501752 12410 0ustar boynsstaffrplay INSTALL - Installation instructions -*-outline-*- * Overview This file contains a list of installation instructions for rplay. Please read this file very carefully and don't skip any steps unless you think you know what you are doing. If you get confused at any time during the installation please read the documents in the `doc' directory. * Configuration ** Execute `./configure' rplay is configured using GNU autoconf. Execute `./configure' in the rplay source directory to create rplay configuration files for your system. If you want to install rplay in a directory tree other than `/usr/local' use `./configure --prefix=/installation/path'. The file `INSTALL.generic' contains generic GNU autoconf installation instructions. Please read this file if you're having problems using configure. If the configuration script cannot determine your system type it will try to use a generic configuration. Note that the system type is used to enable system specific audio routines. The generic configuration assumes an 8000 Hz audio device that accepts ulaw encoded audio data. System specific audio routines are located in the rplayd/audio directory. See the PORTING file for more information on porting rplay to another system. ** Edit `Makefile.config' You may need to edit `Makefile.config' to choose the correct C compiler, CC_OPTIONS, and LD_OPTIONS. Note that configure will try to use the gcc compiler with the -O flag by default. HP users should uncomment all the lines specified. ** Edit `include/config.h' rplay configuration parameters can be changed in `include/config.h'. This is where you can change the location of rplay.conf, rplay.hosts, rplay.servers, rplay.cache, and rplay.log, if necessary. (These file names are automatically modified by configure's --prefix option) There's several other parameters that you may want to enable or disable or change. ** Special HP modifications HP users need to edit `librplay/Makefile' to comment/uncomment a few lines. See the directions in `librplay/Makefile' for more information. -- I've got to add this to the configure script. * Build Makefile dependencies (optional) Execute `make depend' to create dependencies in the Makefiles. The `makedepend' program is used to create the dependencies (see `Makefile.config'). * Compile rplay Execute `make' to compile rplay. Compiler flags can be changed by specifying CFLAGS on the make command line. (i.e. `make CFLAGS="-O4 -g"') The C compiler can be changed in the same manner as CFLAGS by using the CC make parameter. If rplay does not compile successfully you might need to change either the `Makefile.config' or `include/config.h'. * Create configuration files Create your rplay.servers, rplay.hosts, and rplay.conf files. Manual pages for each of these files are included in the `doc' directory. Note that the rplay.hosts file is only required if AUTH was defined in include/config.h. (AUTH is defined by default) * Install rplay When rplay successfully compiles, execute `make install'. This will verify that rplay has been compiled successfully and install rplay. * rplayd installation options ** Is rplayd secure enough to run as root? Well, that's entirely up to you. The BAD_DIRS option in `include/config.h' restricts the directories that can be accessed by rplayd. (By default BAD_DIRS includes /etc, /dev, /devices, and /proc) Remember to read the NO WARRANTY section in the COPYING file. ** Running rplayd from inetd Option --inetd *must* be used. Sample inetd.conf entry: rplay dgram udp wait root /usr/sbin/rplayd rplayd --inetd Sample /etc/services entry: rplay 5555/udp ** Running rplayd as a standalone daemon When rplayd is not started by inetd it must be started manually by individual users or at system startup. Users may wish to start rplayd whenever they use the system console. See `rplayd --help' for option information. ** Audio device permissions Check your systems audio device permissions. SunOS 4.1.x can automatically set the permissions of /dev/audio using /etc/fbtab. (`man 5 fbtab') Solaris 2.X uses /etc/logindevperm. When these device permission files include the audio device, only the person logged in on the system console will have access to the audio device. Linux users should check /dev/dsp and /dev/mixer. * Now see if rplay works Start rplayd (using inetd or standalone) and execute `rplay sound', where `sound' is the name of a sound file in rplay.conf, a sound file in the current directory, or a complete pathname to a sound file. * It doesn't work! ** Try debug mode If a `sound' is not played then I recommend you run rplayd in debug mode to see exactly what is wrong. When using rplayd in debug mode all inetd.conf entries (if any) must be removed and inetd restarted. Try running `rplayd -d' and `rplay sound'. You should see output like: rplayd: loading local file /home/mrb/sounds/bogus.au rplayd: bogus.au input=file bits=8 sample-rate=8000 channels=1 samples=9542 format=ulaw byte-order=big-endian ** Other possible problems *** Is the volume of the audio device very low or zero? Use xrplay, audiotool, xmix, xmixer, etc., to change the volume. *** Is another program using the audio device? There are several programs around that hog the audio device. These programs include web browsers, soundtool, audiotool, play, x_soundtool, any many other sound players. Note that rplay is audio device friendly and will close the audio device when it is not being used (see --audio-close). *** Are you running another audio server like Aserver? rplay does not work with Aserver and probably won't work with other servers. If you want to use rplay make sure other audio servers are not running. When you see errors like `/dev/audio open: Device busy', another program is using the audio device. Read the audio device permissions section above. ** Ask for help If you are still having problems send email to rplay@doit.org and I will do my best to help you out. The rplay mailing list is discussed in the README file. $Id: INSTALL,v 1.2 1998/08/13 06:12:58 boyns Exp $ rplay-3.3.2/INSTALL.generic100644 153 62 16446 6552756452 14034 0ustar boynsstaffBasic Installation ================== These are generic installation instructions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, a file `config.cache' that saves the results of its tests to speed up reconfiguring, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.in' is used to create `configure' by a program called `autoconf'. You only need `configure.in' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes awhile. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. You can give `configure' initial values for variables by setting them in the environment. Using a Bourne-compatible shell, you can do that on the command line like this: CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure Or on systems that have the `env' program, you can do it like this: env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. If you have to use a `make' that does not supports the `VPATH' variable, you have to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. Installation Names ================== By default, `make install' will install the package's files in `/usr/local/bin', `/usr/local/man', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PATH'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec-prefix=PATH', the package will use PATH as the prefix for installing programs and libraries. Documentation and other data files will still use the regular prefix. If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Specifying the System Type ========================== There may be some features `configure' can not figure out automatically, but needs to determine by the type of host the package will run on. Usually `configure' can figure that out, but if it prints a message saying it can not guess the host type, give it the `--host=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name with three fields: CPU-COMPANY-SYSTEM See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the host type. If you are building compiler tools for cross-compiling, you can also use the `--target=TYPE' option to select the type of system they will produce code for and the `--build=TYPE' option to select the type of system on which you are compiling the package. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Operation Controls ================== `configure' recognizes the following options to control how it operates. `--cache-file=FILE' Use and save the results of the tests in FILE instead of `./config.cache'. Set FILE to `/dev/null' to disable caching, for debugging `configure'. `--help' Print a summary of the options to `configure', and exit. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `--version' Print the version of Autoconf used to generate the `configure' script, and exit. `configure' also accepts some other, not widely useful, options. rplay-3.3.2/Makefile.config.in100644 153 62 2722 6564501753 14644 0ustar boynsstaff## $Id: Makefile.config.in,v 1.2 1998/08/13 06:12:59 boyns Exp $ ## ## rplay Makefile configuration ## SHELL= /bin/sh srcdir= @srcdir@ VPATH= @srcdir@ prefix= @prefix@ exec_prefix= @exec_prefix@ bindir= $(exec_prefix)/bin sbindir= $(exec_prefix)/sbin libdir= $(exec_prefix)/lib mandir= $(prefix)/man etcdir= $(prefix)/etc includedir= $(prefix)/include infodir= $(prefix)/info tmpdir= /tmp debiandir= @srcdir@/../debian ## ## C compiler ## CC= @CC@ #CC= gcc #CC= acc #CC= cc ## ## Default CFLAGS ## CFLAGS= @CFLAGS@ ## ## Other compiler options. ## #CC_OPTIONS= -O4 #CC_OPTIONS= -O2 -fstrength-reduce -g #CC_OPTIONS= -fast # acc #CC_OPTIONS= -O -DSVR4 # Solaris 2.x using SunPro C #CC_OPTIONS= -Aa -D_HPUX_SOURCE +O3 -J +ESlit +Obb850 +FPD # HP A.09.34 cc #CC_OPTIONS= -Ae +O2 +Oall # HP A.09.61 or greater cc #CC_OPTIONS= -O -cckr # SGI #CC_OPTIONS= -O # generic #CC_OPTIONS= -g # debug ## ## Extra linker options. ## #LD_OPTIONS= #LD_OPTIONS= -s -L$(libdir) # HP-UX ## ## Name of the rplay library to build. ## LIBRPLAY_NAME= librplay.a #LIBRPLAY_NAME= librplay.sl # HP-UX ## ## System utilities. ## RM= rm -f CHMOD= chmod TAGS= @ETAGS@ MAKEDEPEND= @MAKEDEPEND@ LN_S= @LN_S@ AR= ar RANLIB= @RANLIB@ MAKEINFO= @MAKEINFO@ MAKEINFO_FLAGS= TEXI2DVI= @TEXI2DVI@ TEXI2DVI_FLAGS= TEXI2HTML= @TEXI2HTML@ TEXI2HTML_FLAGS= -menu -split_chapter DVIPS= @DVIPS@ ## ## rplay version - don't change this! ## RPLAY_VERSION= "@RPLAY_VERSION@" rplay-3.3.2/Makefile.in100644 153 62 2233 6552756452 13402 0ustar boynsstaffinclude @RPLAY_TOP@/Makefile.config INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ MKINSTALLDIRS = @srcdir@/mkinstalldirs TARGET= @BUILD_TARGETS@ all: @for i in $(TARGET); \ do \ (echo make all in $$i...; cd $$i; $(MAKE) $(MFLAGS) all); \ done; world: all install install: @for i in $(TARGET); \ do \ (echo make install in $$i...; cd $$i; $(MAKE) $(MFLAGS) install); \ done; uninstall: @for i in $(TARGET); \ do \ (echo make uninstall in $$i...; cd $$i; $(MAKE) $(MFLAGS) uninstall); \ done; clean: @for i in $(TARGET); \ do \ (echo make clean in $$i...; cd $$i; $(MAKE) $(MFLAGS) clean); \ done; distclean: @for i in $(TARGET); \ do \ (echo make distclean in $$i...; cd $$i; $(MAKE) $(MFLAGS) distclean); \ done; $(RM) Makefile Makefile.config config.status config.cache config.log *~ *.bak *.orig stamp-configure stamp-build tags: @for i in $(TARGET); \ do \ (echo make tags in $$i...; cd $$i; $(MAKE) $(MFLAGS) tags); \ done; TAGS: tags etags: tags depend: @for i in $(TARGET); \ do \ (echo make depend in $$i...; cd $$i; $(MAKE) $(MFLAGS) depend); \ done; rplay-3.3.2/NEWS100644 153 62 5375 6671560540 12037 0ustar boynsstaffrplay NEWS - User-visible changes. Copyright (C) 1993-99 Mark R. Boyns Changes since rplay 3.3.1: * Added devrplay.so which can be used with LD_PRELOAD to add rplay support to audio applications use /dev/dsp. devrplay is known to work with rvplayer, xmp, mpg123, freeamp, s3mod, esd (Enlightenment Sound Daemon) and even rplayd itself. devrplay.so should be installed in your LD_LIBRARY_PATH. Example usage: bash$ LD_PRELOAD=devrplay.so rvplayer bash$ LD_PRELOAD=devrplay.so /usr/X11R6/lib/X11/rvplayer/rvplayer bash$ LD_PRELOAD=devrplay.so dd if=/foo/bar/sound.wav of=/dev/dsp bash$ LD_PRELOAD=devrplay.so xxmp sound.mod bash$ LD_PRELOAD=devrplay.so mpg123 sound.mp3 tcsh users will probably need to `setenv LD_PRELOAD devrplay.so; command' instead of using the `LD_PRELOAD=devrplay.so command' syntax. devrplay has only been tested on Linux, but it should be possible to get it working on other systems. * Added rptp "set" command. This can be used to set rplayd variables. One important use of this is to set the audio-close variable. Examples: Tell rplayd to close the audio device: $ rptp set audio-close 1 Tell rplayd *not* to close the audio device: $ rptp set audio-close 0 * Added rplayd monitor support which allows rptp clients to monitor audio data that is written to the audio device. rptp clients can now issue the "monitor" command to start receiving audio data. One use of this feature is to pipe the audio data to a program for visual display. * rptp includes support for GNU readline and also displays progress information when doing get, put, and monitor. * Fixed several potential rplayd buffer overflows. Changes since rplay 3.2: * Improved Linux support, including playing sounds directly from ATAPI CDROM. Tested with the following: Linux 2.0.34 Debian 2.0 ESS ES1688 AudioDrive (rev 6) (3.1) TOSHIBA CD-ROM XM-1502B, ATAPI CDROM drive This also includes a new --audio-fragsize rplayd option. See README.linux for more information. * Support for external helper applications used to convert unsupported audio formats. Helpers can be configured to support formats such as MPEG (using mpg123), modules (using xmp), and any other format that can be converted using a stdin -> stdout filter. * --fork and --no-fork rplayd options. When not in debug or inetd mode, rplayd will fork to put itself in the background. * rplayd is now installed in $prefix/sbin/rplayd instead of $prefix/bin/rplayd. * Running rplayd from inetd now requires the --inetd option. * --enable-rplayd-user=USER and --enable-rplayd-group=GROUP configure options. * --user=USER and --group=GROUP rplayd options. * Lots of bug fixes. $Id: NEWS,v 1.4 1999/03/10 21:17:20 boyns Exp $ rplay-3.3.2/PORTING100644 153 62 11103 6564501755 12413 0ustar boynsstaffrplay PORTING - How to port rplay to other systems. Last updated: Mon Nov 7 13:13:50 PST 1994 0. PORTING OVERVIEW -------------------- This file describes the following rplay porting topics: AUTO CONFIGURATION(1), AUDIO CONFIGURATION(2) Please email new audio configurations to boyns@sdsu.edu. 1. AUTO CONFIGURATION --------------------- Starting with 3.2.0, all system audio specific code is located in separate files in the rplayd/audio directory. GNU autoconf is used to determine what type of system you have and therefore what audio code to use. Currently the following systems are automatically determined: sun, solaris, hpux, sgi, linux, 386bsd, Free_BSD New systems should be added to configure.in using the following linux example: dnl dnl Check for Linux dnl if test -z "$RPLAY_TARGET"; then AC_MSG_CHECKING(for linux) AC_EGREP_CPP(yes, [ #ifdef linux yes #endif ], is_linux=yes, is_linux=no) AC_MSG_RESULT($is_linux) if test $is_linux = "yes"; then RPLAY_TARGET="linux" fi fi You will see the above in configure.in. The important line is "#ifdef linux" which references a unique preprocessor symbol for the system. You will have to find a unique symbol that your preprocessor defines so your system type can be automatically determined. If you have gcc you can probably find your system's preprocessor defines in the specs file. Assume you have a foobar system and it defines __foobar__. You would then have to add the following to configure.in: dnl dnl Check for foobar dnl if test -z "$RPLAY_TARGET"; then AC_MSG_CHECKING(for foobar) AC_EGREP_CPP(yes, [ #ifdef __foobar__ yes #endif ], is_foobar=yes, is_foobar=no) AC_MSG_RESULT($is_foobar) if test $is_foobar = "yes"; then RPLAY_TARGET="foobar" fi fi This assumes that the foobar audio files will be called audio_foobar.c and audio_foobar.h in the rplayd/audio directory. Now that you have a new configure.in, you will have to create a new configure script. For this, you will need to get the GNU autoconf package from your favorite GNU archive site (prep.ai.mit.edu:/pub/gnu). After installing autoconf, execute `autoconf' and a new `configure' script will be created. If you do not want to deal with installing autoconf, email me the unique preprocessor symbol for your system and I'll create a configure script for you. You can also experiment with the generic audio configuration files. 2. AUDIO CONFIGURATION ----------------------- The audio configuration files are located in the rplayd/audio directory. Each system should have its own audio configuration. The system type is determined using GNU autoconf (see section 1). audio_generic.c and audio_generic.h should be used as a template. audio_.h must define the following: RPLAY_AUDIO_DEVICE - the name of the audio device. RPLAY_AUDIO_TIMEOUT - close the audio device when it hasn't been used for seconds. RPLAY_AUDIO_RATE - number of times per second that the audio data should be written to the audio device. RPLAY_AUDIO_BYTE_ORDER - should be RPLAY_BIG_ENDIAN or RPLAY_LITTLE_ENDIAN. RPLAY_AUDIO_FLUSH_TIMEOUT - flush audio device when it hasn't been used for seconds. There are the following exceptions: == 0 : flushing is disabled == -1 : flush when spool is empty (this should be the default) == -2 : flush after each audio write audio_.c has the following routines: int rplay_audio_init() int rplay_audio_open() int rplay_audio_isopen() int rplay_audio_flush() int rplay_audio_write(char *buf, int nbytes) int rplay_audio_close() int rplay_audio_get_volume() int rplay_audio_set_volume(int volume) One of the most important routines is rplay_audio_init(). This routine sets the sample rate, precision, channels, audio port(s), and the format of the audio device. Generic defaults are 8000, 8, 1, speaker, and RPLAY_FORMAT_ULAW (see rplay.h) respectively. The audio_sun rplay_audio_init detects an external speakerbox which supports 16-bit audio and high sample rates so it could be a good example for other configurations. Systems that don't have hardware volume control should enable software volume control by defining `FAKE_VOLUME'. Look at rplay_get_volume and rplay_set_volume in audio_linux.c to see how FAKE_VOLUME should be used. $Id: PORTING,v 1.2 1998/08/13 06:13:01 boyns Exp $ rplay-3.3.2/README100644 153 62 4236 6671422144 12210 0ustar boynsstaffrplay 3.3 README Copyright (C) 1993-99 Mark R. Boyns rplay is a flexible network audio system that allows sounds to be played to and from local and remote Unix systems. Sounds can be played with or without sending audio data over the network using either UDP or TCP. rplay audio servers can be configured to share sound files with each other. Support for rplay is included in several applications. These include xpilot, xlockmore, xboing, fvwm, and ctwm. The rplay audio server is known to work well on Linux, SunOS 4.1.x, and Solaris 2.x. FreeBSD, Irix, and HPUX are known to work but the current status of these drivers is unknown. Linux support is based on the Open Sound System (OSS) driver so other systems using this driver might work with a few modifications. See the COPYING file for license information. See the INSTALL file for compilation and installation instructions. See the NEWS file for a list of user-visible changes. See the PORTING file for help with porting rplay to other systems. See the TODO file to find out what may be fixed/changed/implemented. This distribution includes: * rplayd - The rplay audio server. Support for playing the following sound formats: AU, AIFF, WAV, VOC, UB, UL, G.721 4-bit, G.723 3-bit, G.723 5-bit, GSM. Other formats such as MPEG 1.0/2.0 and Modules can also be played using helper conversion applications. Sounds can also be played directly from CDROM. * rplay - Sound player which communicates with rplayd to play sounds. * rptp - Simple RPTP client. * librplay - A library used by rplay clients to communicate with rplay servers.Supports both RPLAY and RPTP protocols. * doc - rplay documentation. * contrib - More rplay applications, pointers to programs that support rplay, and patches which add rplay support to several programs. The rplay mailing list is located at . To subscribe, mail to with the word "subscribe". The latest version of rplay is available at the following locations: http://rplay.doit.org/ ftp://rplay.doit.org/pub/rplay/ Send suggestions and bug reports to $Id: README,v 1.4 1999/03/10 07:51:00 boyns Exp $ rplay-3.3.2/README.linux100644 153 62 3154 6564501757 13355 0ustar boynsstaffrplay README.linux - notes for Linux users. Linux support is based on the Open Sound System driver included with most Linux kernels. /dev/dsp is used by default with CD quality output -- 44100 Hz, 16-bit, 2 channels. These parameters can be changed using the --audio-* command line options and/or ~/.rplaydrc. When /dev/audio is used, rplayd uses 8000 Hz, 8-bit, 1 channel, and ulaw output. /dev/mixer is used to control the volume and configure output ports. rplay supports headphone, lineout, and speaker. Ports that aren't enabled have their volume set to zero. The --audio-fragsize rplayd option can be used to control audio device buffering. Fragment sizes must be a power of 2 greater than 16. By default, rplayd lets the audio driver pick an appropriate fragment size which has about a 0.5 second delay. Example sizes: 256, 512, 1024, 2048, 4096, 8192 DSP_BUFFSIZE in the kernel sound driver may need to setup with a different value to improve audio performance. 65536 is known to work well with rplay. If you hear gaps, clicks, pops, etc., try increasing this value. Reading audio from CDROM uses /dev/cdrom by default. Make this a symbolic link to your real CDROM device. For example: lrwxrwxrwx 1 root root 8 Oct 1 12:46 /dev/cdrom -> /dev/hdc /dev/cdrom1, /dev/cdrom2, and /dev/cdrom3 can also be created if available. Tracks can be played using: $ rplay cdrom: # play entire CD $ rplay cdrom:5 # play track 5 $ rplay cdrom:1-3 # play tracks 1, 2, 3 CDROM support only works on ATAPI CDROM devices, I think. $Id: README.linux,v 1.2 1998/08/13 06:13:03 boyns Exp $ rplay-3.3.2/README.sgi100644 153 62 1145 6564501760 12770 0ustar boynsstaffrplay README.sgi - Notes for SGI users. * REQUIREMENTS The SGI support has been tested on IRIX 4.0.5 and IRIX 5.2. IRIX 5.2 does not include the multimedia development kit that came with 4.0.5 -- it is an extra option (SC4-DMDEV-2.0). There has been a lot of outcry about this and SGI decided to put the multimedia development kit back in 5.3, meaning full audio and video and QT/MPEG/SGI-MOV file support. If you do not have the multimedia development kit, you can call SGI and ask for it. The phone number of SGI is 1-800-800-SGI1 (1-800-800-7441). $Id: README.sgi,v 1.2 1998/08/13 06:13:04 boyns Exp $ rplay-3.3.2/README.sun100644 153 62 2242 6564501761 13013 0ustar boynsstaffrplay README.sun - Notes for SunOS 4.1.x and Solaris 2.x users. * audioamd SPARCstation 1, 2, IPC, IPX, SLC, ELC, LC (classic), and SPARCserver 6xx systems have a "audioamd - telephone quality audio device". This device supports 8-bit u-law encoded audio data sampled at 8000Hz. See `man audioamd' for more details. * dbri SPARCstation 10, 10SX, 20, LX have a "dbri - Dual Basic Rate ISDN Interface and audio interface". This device supports configrations which range from 8-bit u-law 8000Hz to stereo 16-bit linear 48000Hz. See `man dbri' for more details. * clicks The dbri audio device may "click" when it's opened using the open system call. These clicks can be avoided by forcing rplayd to always keep the audio device open. Use either `-c0' or `--audio-close=0'. * SS5 The SPARCstation 5 running SunOS 4.1.x requires the `ms2' patch to get audio working properly. * SPARCserver 4/6xx and probably 4/4xx using SunOS 4.1.x. The device driver on these systems does not accept *any* audio port value in the audio_info_t structure when using AUDIO_SETINFO. To fix this, rplayd must be run with `--audio-port=none'. $Id: README.sun,v 1.2 1998/08/13 06:13:05 boyns Exp $ rplay-3.3.2/TODO100644 153 62 2135 6671422144 12014 0ustar boynsstaffrplay TODO - A random list of things that may (not) be fixed/changed/implemented. * rplayd tends to peg the cpu when it is trying to connect to another rplayd. This needs to be fixed. * Support more than one audio device in rplayd. A client should be able to specify which device to use. Should there be more than one audio spool? * Add RPLAY_VOLUME_LEFT and RPLAY_VOLUME_RIGHT attributes. RPLAY_VOLUME should still apply to both left & right. * rplayd needs to be updated to use the RPTP `set application=rplayd' command when connecting to other rplay servers. * Improve rplayd's RPTP error messages. * Fix memory leak in lib/hash.c! * Have rplayd play certain sounds at startup, shutdown, when a sound isn't found, etc. * When clients tell rplayd to play a sound that's actually a directory, rplayd will of course not play the directory, but it keeps the directory in its sound list. rplayd should remove the directories from its list. * Stereo G.72x files don't work and I don't know how to fix 'em. * Don't modify audio-port by default $Id: TODO,v 1.3 1999/03/10 07:51:00 boyns Exp $ rplay-3.3.2/configure100755 153 62 264560 6727404413 13310 0ustar boynsstaff#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated automatically using autoconf version 2.13 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # Defaults: ac_help= ac_default_prefix=/usr/local # Any additions from configure.in: ac_help="$ac_help --enable-rplayd-user=USER" ac_help="$ac_help --enable-rplayd-group=GROUP" # Initialize some variables set by options. # The variables have the same names as the options, with # dashes changed to underlines. build=NONE cache_file=./config.cache exec_prefix=NONE host=NONE no_create= nonopt=NONE no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= target=NONE verbose= x_includes=NONE x_libraries=NONE bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. ac_max_here_lines=12 ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi case "$ac_option" in -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) ac_optarg= ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case "$ac_option" in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir="$ac_optarg" ;; -build | --build | --buil | --bui | --bu) ac_prev=build ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build="$ac_optarg" ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file="$ac_optarg" ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir="$ac_optarg" ;; -disable-* | --disable-*) ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` eval "enable_${ac_feature}=no" ;; -enable-* | --enable-*) ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "enable_${ac_feature}='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix="$ac_optarg" ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he) # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat << EOF Usage: configure [options] [host] Options: [defaults in brackets after descriptions] Configuration: --cache-file=FILE cache test results in FILE --help print this message --no-create do not create output files --quiet, --silent do not print \`checking...' messages --version print the version of autoconf that created configure Directory and file names: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [same as prefix] --bindir=DIR user executables in DIR [EPREFIX/bin] --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] --libexecdir=DIR program executables in DIR [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data in DIR [PREFIX/share] --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data in DIR [PREFIX/com] --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] --libdir=DIR object code libraries in DIR [EPREFIX/lib] --includedir=DIR C header files in DIR [PREFIX/include] --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] --infodir=DIR info documentation in DIR [PREFIX/info] --mandir=DIR man documentation in DIR [PREFIX/man] --srcdir=DIR find the sources in DIR [configure dir or ..] --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names EOF cat << EOF Host type: --build=BUILD configure for building on BUILD [BUILD=HOST] --host=HOST configure for HOST [guessed] --target=TARGET configure for TARGET [TARGET=HOST] Features and packages: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR EOF if test -n "$ac_help"; then echo "--enable and --with options recognized:$ac_help" fi exit 0 ;; -host | --host | --hos | --ho) ac_prev=host ;; -host=* | --host=* | --hos=* | --ho=*) host="$ac_optarg" ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir="$ac_optarg" ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir="$ac_optarg" ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir="$ac_optarg" ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir="$ac_optarg" ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir="$ac_optarg" ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir="$ac_optarg" ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir="$ac_optarg" ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix="$ac_optarg" ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix="$ac_optarg" ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix="$ac_optarg" ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name="$ac_optarg" ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir="$ac_optarg" ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir="$ac_optarg" ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site="$ac_optarg" ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir="$ac_optarg" ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir="$ac_optarg" ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target="$ac_optarg" ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers) echo "configure generated by autoconf version 2.13" exit 0 ;; -with-* | --with-*) ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "with_${ac_package}='$ac_optarg'" ;; -without-* | --without-*) ac_package=`echo $ac_option|sed -e 's/-*without-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` eval "with_${ac_package}=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes="$ac_optarg" ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries="$ac_optarg" ;; -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } ;; *) if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then echo "configure: warning: $ac_option: invalid host type" 1>&2 fi if test "x$nonopt" != xNONE; then { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } fi nonopt="$ac_option" ;; esac done if test -n "$ac_prev"; then { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } fi trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 # File descriptor usage: # 0 standard input # 1 file creation # 2 errors and warnings # 3 some systems may open it to /dev/tty # 4 used on the Kubota Titan # 6 checking for... messages and results # 5 compiler messages saved in config.log if test "$silent" = yes; then exec 6>/dev/null else exec 6>&1 fi exec 5>./config.log echo "\ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. " 1>&5 # Strip out --no-create and --no-recursion so they do not pile up. # Also quote any args containing shell metacharacters. ac_configure_args= for ac_arg do case "$ac_arg" in -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) ac_configure_args="$ac_configure_args '$ac_arg'" ;; *) ac_configure_args="$ac_configure_args $ac_arg" ;; esac done # NLS nuisances. # Only set these to C if already set. These must not be set unconditionally # because not all systems understand e.g. LANG=C (notably SCO). # Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! # Non-C LC_CTYPE values break the ctype check. if test "${LANG+set}" = set; then LANG=C; export LANG; fi if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo > confdefs.h # A filename unique to this package, relative to the directory that # configure is in, which we can look for to find out if srcdir is correct. ac_unique_file=rplayd/rplayd.c # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_prog=$0 ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } else { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } fi fi srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then echo "loading site script $ac_site_file" . "$ac_site_file" fi done if test -r "$cache_file"; then echo "loading cache $cache_file" . $cache_file else echo "creating cache $cache_file" > $cache_file fi ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross ac_exeext= ac_objext=o if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then ac_n= ac_c=' ' ac_t=' ' else ac_n=-n ac_c= ac_t= fi else ac_n= ac_c='\c' ac_t= fi export srcdir RPLAY_VERSION=`$srcdir/version` echo configuring rplay version $RPLAY_VERSION cat >> confdefs.h <&6 echo "configure:548: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="gcc" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:578: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_prog_rejected=no ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" break fi done IFS="$ac_save_ifs" if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# -gt 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift set dummy "$ac_dir/$ac_word" "$@" shift ac_cv_prog_CC="$@" fi fi fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then case "`uname -s`" in *win32* | *WIN32*) # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:629: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="cl" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi ;; esac fi test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 echo "configure:661: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF #line 672 "configure" #include "confdefs.h" main(){return(0);} EOF if { (eval echo configure:677: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then ac_cv_prog_cc_cross=no else ac_cv_prog_cc_cross=yes fi else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 ac_cv_prog_cc_works=no fi rm -fr conftest* ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 echo "configure:703: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 echo "configure:708: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no fi fi echo "$ac_t""$ac_cv_prog_gcc" 1>&6 if test $ac_cv_prog_gcc = yes; then GCC=yes else GCC= fi ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 echo "configure:736: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo 'void f(){}' > conftest.c if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then ac_cv_prog_cc_g=yes else ac_cv_prog_cc_g=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 if test "$ac_test_CFLAGS" = set; then CFLAGS="$ac_save_CFLAGS" elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi # If we're using gcc and the user hasn't specified CFLAGS, add -O to CFLAGS. test -n "$GCC" && test -n "$auto_cflags" && CFLAGS="$CFLAGS -O" # Check whether --enable-rplayd-user or --disable-rplayd-user was given. if test "${enable_rplayd_user+set}" = set; then enableval="$enable_rplayd_user" RPLAYD_USER=$enableval fi # Check whether --enable-rplayd-group or --disable-rplayd-group was given. if test "${enable_rplayd_group+set}" = set; then enableval="$enable_rplayd_group" RPLAYD_GROUP=$enableval fi if test -n "$RPLAYD_USER" then cat >> confdefs.h <> confdefs.h <&6 echo "configure:801: checking for POSIXized ISC" >&5 if test -d /etc/conf/kconfig.d && grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1 then echo "$ac_t""yes" 1>&6 ISC=yes # If later tests want to check for ISC. cat >> confdefs.h <<\EOF #define _POSIX_SOURCE 1 EOF if test "$GCC" = yes; then CC="$CC -posix" else CC="$CC -Xp" fi else echo "$ac_t""no" 1>&6 ISC= fi echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 echo "configure:822: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # This must be in double quotes, not single quotes, because CPP may get # substituted into the Makefile and "${CC-cc}" will confuse make. CPP="${CC-cc} -E" # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:843: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:860: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:877: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP=/lib/cpp fi rm -f conftest* fi rm -f conftest* fi rm -f conftest* ac_cv_prog_CPP="$CPP" fi CPP="$ac_cv_prog_CPP" else ac_cv_prog_CPP="$CPP" fi echo "$ac_t""$CPP" 1>&6 ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do if test -f $ac_dir/install-sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f $ac_dir/install.sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break fi done if test -z "$ac_aux_dir"; then { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } fi ac_config_guess=$ac_aux_dir/config.guess ac_config_sub=$ac_aux_dir/config.sub ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 echo "configure:932: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" for ac_dir in $PATH; do # Account for people who put trailing slashes in PATH elements. case "$ac_dir/" in /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do if test -f $ac_dir/$ac_prog; then if test $ac_prog = install && grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : else ac_cv_path_install="$ac_dir/$ac_prog -c" break 2 fi fi done ;; esac done IFS="$ac_save_IFS" fi if test "${ac_cv_path_install+set}" = set; then INSTALL="$ac_cv_path_install" else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL="$ac_install_sh" fi fi echo "$ac_t""$INSTALL" 1>&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 echo "configure:985: checking whether ln -s works" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else rm -f conftestdata if ln -s X conftestdata 2>/dev/null then rm -f conftestdata ac_cv_prog_LN_S="ln -s" else ac_cv_prog_LN_S=ln fi fi LN_S="$ac_cv_prog_LN_S" if test "$ac_cv_prog_LN_S" = "ln -s"; then echo "$ac_t""yes" 1>&6 else echo "$ac_t""no" 1>&6 fi # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:1008: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_RANLIB="ranlib" break fi done IFS="$ac_save_ifs" test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" fi fi RANLIB="$ac_cv_prog_RANLIB" if test -n "$RANLIB"; then echo "$ac_t""$RANLIB" 1>&6 else echo "$ac_t""no" 1>&6 fi for ac_prog in etags do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:1040: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_ETAGS'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$ETAGS"; then ac_cv_prog_ETAGS="$ETAGS" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_ETAGS="$ac_prog" break fi done IFS="$ac_save_ifs" fi fi ETAGS="$ac_cv_prog_ETAGS" if test -n "$ETAGS"; then echo "$ac_t""$ETAGS" 1>&6 else echo "$ac_t""no" 1>&6 fi test -n "$ETAGS" && break done test -n "$ETAGS" || ETAGS="true" for ac_prog in makedepend do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:1075: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_MAKEDEPEND'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$MAKEDEPEND"; then ac_cv_prog_MAKEDEPEND="$MAKEDEPEND" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_MAKEDEPEND="$ac_prog" break fi done IFS="$ac_save_ifs" fi fi MAKEDEPEND="$ac_cv_prog_MAKEDEPEND" if test -n "$MAKEDEPEND"; then echo "$ac_t""$MAKEDEPEND" 1>&6 else echo "$ac_t""no" 1>&6 fi test -n "$MAKEDEPEND" && break done test -n "$MAKEDEPEND" || MAKEDEPEND="true" for ac_prog in makeinfo do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:1110: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_MAKEINFO'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$MAKEINFO"; then ac_cv_prog_MAKEINFO="$MAKEINFO" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_MAKEINFO="$ac_prog" break fi done IFS="$ac_save_ifs" fi fi MAKEINFO="$ac_cv_prog_MAKEINFO" if test -n "$MAKEINFO"; then echo "$ac_t""$MAKEINFO" 1>&6 else echo "$ac_t""no" 1>&6 fi test -n "$MAKEINFO" && break done test -n "$MAKEINFO" || MAKEINFO="true" for ac_prog in texi2dvi do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:1145: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_TEXI2DVI'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$TEXI2DVI"; then ac_cv_prog_TEXI2DVI="$TEXI2DVI" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_TEXI2DVI="$ac_prog" break fi done IFS="$ac_save_ifs" fi fi TEXI2DVI="$ac_cv_prog_TEXI2DVI" if test -n "$TEXI2DVI"; then echo "$ac_t""$TEXI2DVI" 1>&6 else echo "$ac_t""no" 1>&6 fi test -n "$TEXI2DVI" && break done test -n "$TEXI2DVI" || TEXI2DVI="true" for ac_prog in texi2html do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:1180: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_TEXI2HTML'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$TEXI2HTML"; then ac_cv_prog_TEXI2HTML="$TEXI2HTML" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_TEXI2HTML="$ac_prog" break fi done IFS="$ac_save_ifs" fi fi TEXI2HTML="$ac_cv_prog_TEXI2HTML" if test -n "$TEXI2HTML"; then echo "$ac_t""$TEXI2HTML" 1>&6 else echo "$ac_t""no" 1>&6 fi test -n "$TEXI2HTML" && break done test -n "$TEXI2HTML" || TEXI2HTML="true" for ac_prog in dvips do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:1215: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_DVIPS'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$DVIPS"; then ac_cv_prog_DVIPS="$DVIPS" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_DVIPS="$ac_prog" break fi done IFS="$ac_save_ifs" fi fi DVIPS="$ac_cv_prog_DVIPS" if test -n "$DVIPS"; then echo "$ac_t""$DVIPS" 1>&6 else echo "$ac_t""no" 1>&6 fi test -n "$DVIPS" && break done test -n "$DVIPS" || DVIPS="true" ac_header_dirent=no for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6 echo "configure:1251: checking for $ac_hdr that defines DIR" >&5 if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include <$ac_hdr> int main() { DIR *dirp = 0; ; return 0; } EOF if { (eval echo configure:1264: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* eval "ac_cv_header_dirent_$ac_safe=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_dirent_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. if test $ac_header_dirent = dirent.h; then echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6 echo "configure:1289: checking for opendir in -ldir" >&5 ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-ldir $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="$LIBS -ldir" else echo "$ac_t""no" 1>&6 fi else echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6 echo "configure:1330: checking for opendir in -lx" >&5 ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lx $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="$LIBS -lx" else echo "$ac_t""no" 1>&6 fi fi echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 echo "configure:1372: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #include #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1385: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* ac_cv_header_stdc=yes else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "memchr" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "free" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') #define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF if { (eval echo configure:1452: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_header_stdc=no fi rm -fr conftest* fi fi fi echo "$ac_t""$ac_cv_header_stdc" 1>&6 if test $ac_cv_header_stdc = yes; then cat >> confdefs.h <<\EOF #define STDC_HEADERS 1 EOF fi echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6 echo "configure:1476: checking whether time.h and sys/time.h may both be included" >&5 if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #include int main() { struct tm *tp; ; return 0; } EOF if { (eval echo configure:1490: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_time=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_time=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_header_time" 1>&6 if test $ac_cv_header_time = yes; then cat >> confdefs.h <<\EOF #define TIME_WITH_SYS_TIME 1 EOF fi for ac_hdr in fcntl.h sys/file.h sys/ioctl.h sys/time.h stdlib.h unistd.h memory.h string.h strings.h utime.h limits.h gsm.h gsm/gsm.h rxposix.h rx/rxposix.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:1514: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1524: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6 echo "configure:1551: checking for sys/wait.h that is POSIX.1 compatible" >&5 if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #ifndef WEXITSTATUS #define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) #endif #ifndef WIFEXITED #define WIFEXITED(stat_val) (((stat_val) & 255) == 0) #endif int main() { int s; wait (&s); s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; ; return 0; } EOF if { (eval echo configure:1572: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_sys_wait_h=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_sys_wait_h=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_header_sys_wait_h" 1>&6 if test $ac_cv_header_sys_wait_h = yes; then cat >> confdefs.h <<\EOF #define HAVE_SYS_WAIT_H 1 EOF fi echo $ac_n "checking for working const""... $ac_c" 1>&6 echo "configure:1594: checking for working const" >&5 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; } ; return 0; } EOF if { (eval echo configure:1648: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_c_const=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_c_const" 1>&6 if test $ac_cv_c_const = no; then cat >> confdefs.h <<\EOF #define const EOF fi echo $ac_n "checking for size_t""... $ac_c" 1>&6 echo "configure:1669: checking for size_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_size_t=yes else rm -rf conftest* ac_cv_type_size_t=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_size_t" 1>&6 if test $ac_cv_type_size_t = no; then cat >> confdefs.h <<\EOF #define size_t unsigned EOF fi for ac_hdr in unistd.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:1706: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1716: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done for ac_func in getpagesize do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:1745: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:1773: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi done echo $ac_n "checking for working mmap""... $ac_c" 1>&6 echo "configure:1798: checking for working mmap" >&5 if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then ac_cv_func_mmap_fixed_mapped=no else cat > conftest.$ac_ext < #include #include /* This mess was copied from the GNU getpagesize.h. */ #ifndef HAVE_GETPAGESIZE # ifdef HAVE_UNISTD_H # include # endif /* Assume that all systems that can run configure have sys/param.h. */ # ifndef HAVE_SYS_PARAM_H # define HAVE_SYS_PARAM_H 1 # endif # ifdef _SC_PAGESIZE # define getpagesize() sysconf(_SC_PAGESIZE) # else /* no _SC_PAGESIZE */ # ifdef HAVE_SYS_PARAM_H # include # ifdef EXEC_PAGESIZE # define getpagesize() EXEC_PAGESIZE # else /* no EXEC_PAGESIZE */ # ifdef NBPG # define getpagesize() NBPG * CLSIZE # ifndef CLSIZE # define CLSIZE 1 # endif /* no CLSIZE */ # else /* no NBPG */ # ifdef NBPC # define getpagesize() NBPC # else /* no NBPC */ # ifdef PAGESIZE # define getpagesize() PAGESIZE # endif /* PAGESIZE */ # endif /* no NBPC */ # endif /* no NBPG */ # endif /* no EXEC_PAGESIZE */ # else /* no HAVE_SYS_PARAM_H */ # define getpagesize() 8192 /* punt totally */ # endif /* no HAVE_SYS_PARAM_H */ # endif /* no _SC_PAGESIZE */ #endif /* no HAVE_GETPAGESIZE */ #ifdef __cplusplus extern "C" { void *malloc(unsigned); } #else char *malloc(); #endif int main() { char *data, *data2, *data3; int i, pagesize; int fd; pagesize = getpagesize(); /* * First, make a file with some known garbage in it. */ data = malloc(pagesize); if (!data) exit(1); for (i = 0; i < pagesize; ++i) *(data + i) = rand(); umask(0); fd = creat("conftestmmap", 0600); if (fd < 0) exit(1); if (write(fd, data, pagesize) != pagesize) exit(1); close(fd); /* * Next, try to mmap the file at a fixed address which * already has something else allocated at it. If we can, * also make sure that we see the same garbage. */ fd = open("conftestmmap", O_RDWR); if (fd < 0) exit(1); data2 = malloc(2 * pagesize); if (!data2) exit(1); data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1); if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0L)) exit(1); for (i = 0; i < pagesize; ++i) if (*(data + i) != *(data2 + i)) exit(1); /* * Finally, make sure that changes to the mapped area * do not percolate back to the file as seen by read(). * (This is a bug on some variants of i386 svr4.0.) */ for (i = 0; i < pagesize; ++i) *(data2 + i) = *(data2 + i) + 1; data3 = malloc(pagesize); if (!data3) exit(1); if (read(fd, data3, pagesize) != pagesize) exit(1); for (i = 0; i < pagesize; ++i) if (*(data + i) != *(data3 + i)) exit(1); close(fd); unlink("conftestmmap"); exit(0); } EOF if { (eval echo configure:1946: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_mmap_fixed_mapped=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_func_mmap_fixed_mapped=no fi rm -fr conftest* fi fi echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6 if test $ac_cv_func_mmap_fixed_mapped = yes; then cat >> confdefs.h <<\EOF #define HAVE_MMAP 1 EOF fi echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6 echo "configure:1969: checking for 8-bit clean memcmp" >&5 if eval "test \"`echo '$''{'ac_cv_func_memcmp_clean'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then ac_cv_func_memcmp_clean=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_memcmp_clean=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_func_memcmp_clean=no fi rm -fr conftest* fi fi echo "$ac_t""$ac_cv_func_memcmp_clean" 1>&6 test $ac_cv_func_memcmp_clean = no && LIBOBJS="$LIBOBJS memcmp.${ac_objext}" echo $ac_n "checking for vprintf""... $ac_c" 1>&6 echo "configure:2005: checking for vprintf" >&5 if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char vprintf(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_vprintf) || defined (__stub___vprintf) choke me #else vprintf(); #endif ; return 0; } EOF if { (eval echo configure:2033: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_vprintf=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_vprintf=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'vprintf`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_VPRINTF 1 EOF else echo "$ac_t""no" 1>&6 fi if test "$ac_cv_func_vprintf" != yes; then echo $ac_n "checking for _doprnt""... $ac_c" 1>&6 echo "configure:2057: checking for _doprnt" >&5 if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char _doprnt(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub__doprnt) || defined (__stub____doprnt) choke me #else _doprnt(); #endif ; return 0; } EOF if { (eval echo configure:2085: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func__doprnt=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func__doprnt=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'_doprnt`\" = yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define HAVE_DOPRNT 1 EOF else echo "$ac_t""no" 1>&6 fi fi echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 echo "configure:2110: checking return type of signal handlers" >&5 if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #ifdef signal #undef signal #endif #ifdef __cplusplus extern "C" void (*signal (int, void (*)(int)))(int); #else void (*signal ()) (); #endif int main() { int i; ; return 0; } EOF if { (eval echo configure:2132: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_type_signal=void else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_type_signal=int fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_signal" 1>&6 cat >> confdefs.h <&6 echo "configure:2153: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:2181: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi done echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6 echo "configure:2206: checking for socket in -lsocket" >&5 ac_lib_var=`echo socket'_'socket | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="$LIBS -lsocket" else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for t_accept in -lnsl""... $ac_c" 1>&6 echo "configure:2246: checking for t_accept in -lnsl" >&5 ac_lib_var=`echo nsl'_'t_accept | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="$LIBS -lnsl" else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for readline in -lreadline""... $ac_c" 1>&6 echo "configure:2287: checking for readline in -lreadline" >&5 ac_lib_var=`echo readline'_'readline | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lreadline $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 RL_LIBS="-lreadline" else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking for gsm_decode in -lgsm""... $ac_c" 1>&6 echo "configure:2329: checking for gsm_decode in -lgsm" >&5 ac_lib_var=`echo gsm'_'gsm_decode | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lgsm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 HAVE_GSM="yes" else echo "$ac_t""no" 1>&6 fi if test "$HAVE_GSM" = "yes"; then GSM_LIBS="-lgsm" GSM_INCS="" else GSM_LIBS="-L../gsm -lgsm" GSM_INCS="-I\${srcdir}/../gsm" fi echo $ac_n "checking for regncomp in -lrx""... $ac_c" 1>&6 echo "configure:2379: checking for regncomp in -lrx" >&5 ac_lib_var=`echo rx'_'regncomp | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lrx $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 HAVE_RX="yes" else echo "$ac_t""no" 1>&6 fi if test "$HAVE_RX" = "yes"; then RX_LIBS="-lrx" RX_INCS="" else RX_LIBS="-L../rx -lrx" RX_INCS="-I\${srcdir}/../rx" fi RPLAY_TOP=`pwd` if test -n "$target" -a "$target" != "NONE"; then RPLAY_TARGET=$target echo "using specified $RPLAY_TARGET configuration" fi if test -z "$RPLAY_TARGET"; then echo $ac_n "checking for sun""... $ac_c" 1>&6 echo "configure:2438: checking for sun" >&5 cat > conftest.$ac_ext <&5 | egrep "yes" >/dev/null 2>&1; then rm -rf conftest* is_sun=yes else rm -rf conftest* is_sun=no fi rm -f conftest* echo "$ac_t""$is_sun" 1>&6 if test $is_sun = "yes"; then RPLAY_TARGET="sun" fi if test "$RPLAY_TARGET"; then echo $ac_n "checking for solaris""... $ac_c" 1>&6 echo "configure:2464: checking for solaris" >&5 if test ! -f /vmunix; then is_solaris=yes RPLAY_TARGET="solaris" else is_solaris=no fi echo "$ac_t""$is_solaris" 1>&6 fi fi if test -z "$RPLAY_TARGET"; then echo $ac_n "checking for linux""... $ac_c" 1>&6 echo "configure:2477: checking for linux" >&5 cat > conftest.$ac_ext <&5 | egrep "yes" >/dev/null 2>&1; then rm -rf conftest* is_linux=yes else rm -rf conftest* is_linux=no fi rm -f conftest* echo "$ac_t""$is_linux" 1>&6 if test $is_linux = "yes"; then RPLAY_TARGET="oss" fi fi if test -z "$RPLAY_TARGET"; then echo $ac_n "checking for hpux""... $ac_c" 1>&6 echo "configure:2505: checking for hpux" >&5 cat > conftest.$ac_ext <&5 | egrep "yes" >/dev/null 2>&1; then rm -rf conftest* is_hpux=yes else rm -rf conftest* is_hpux=no fi rm -f conftest* echo "$ac_t""$is_hpux" 1>&6 if test $is_hpux = "yes"; then RPLAY_TARGET="hpux" fi fi if test -z "$RPLAY_TARGET"; then echo $ac_n "checking for sgi""... $ac_c" 1>&6 echo "configure:2533: checking for sgi" >&5 cat > conftest.$ac_ext <&5 | egrep "yes" >/dev/null 2>&1; then rm -rf conftest* is_sgi=yes else rm -rf conftest* is_sgi=no fi rm -f conftest* echo "$ac_t""$is_sgi" 1>&6 if test $is_sgi = "yes"; then RPLAY_TARGET="sgi" echo $ac_n "checking for multimedia development kit""... $ac_c" 1>&6 echo "configure:2557: checking for multimedia development kit" >&5 for ac_hdr in audio.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:2562: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:2572: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done if test $ac_cv_header_audio_h = "no"; then echo 'The multimedia development kit was not found.' echo 'Please read the README.sgi file.' exit -1 fi fi fi if test -z "$RPLAY_TARGET"; then echo $ac_n "checking for FreeBSD""... $ac_c" 1>&6 echo "configure:2608: checking for FreeBSD" >&5 cat > conftest.$ac_ext <&5 | egrep "yes" >/dev/null 2>&1; then rm -rf conftest* is_freebsd=yes else rm -rf conftest* is_freebsd=no fi rm -f conftest* echo "$ac_t""$is_freebsd" 1>&6 if test $is_freebsd = "yes"; then RPLAY_TARGET="FreeBSD" fi fi if test -z "$RPLAY_TARGET"; then echo 'Sorry, I could not figure out what type of system you have.' echo -n 'Would you like to try the generic configuration? ' read ans case "$ans" in y|Y|yes|Yes|YES|sure|ok|okay) RPLAY_TARGET="generic" ;; *) echo configuration aborted; exit 1; esac fi echo "using $RPLAY_TARGET configuration" if test $RPLAY_TARGET = "solaris"; then cat >> confdefs.h <<\EOF #define SVR4 1 EOF fi if test $RPLAY_TARGET = "sgi"; then LIBS="$LIBS -laudio" fi BUILD_TARGETS="include lib adpcm" if test "$HAVE_RX" != "yes"; then BUILD_TARGETS="$BUILD_TARGETS rx" subdirs="rx" fi if test "$HAVE_GSM" != "yes"; then BUILD_TARGETS="$BUILD_TARGETS gsm" fi BUILD_TARGETS="$BUILD_TARGETS librplay rplayd rplay rptp doc" if test $RPLAY_TARGET = "oss"; then BUILD_TARGETS="$BUILD_TARGETS devrplay" fi trap '' 1 2 15 cat > confcache <<\EOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs. It is not useful on other systems. # If it contains results you don't want to keep, you may remove or edit it. # # By default, configure uses ./config.cache as the cache file, # creating it if it does not exist already. You can give configure # the --cache-file=FILE option to use a different cache file; that is # what configure does when it calls configure scripts in # subdirectories, so they share the cache. # Giving --cache-file=/dev/null disables caching, for debugging configure. # config.status only pays attention to the cache file if you give it the # --recheck option to rerun configure. # EOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. (set) 2>&1 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote substitution # turns \\\\ into \\, and sed turns \\ into \). sed -n \ -e "s/'/'\\\\''/g" \ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' ;; esac >> confcache if cmp -s $cache_file confcache; then : else if test -w $cache_file; then echo "updating cache $cache_file" cat confcache > $cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Any assignment to VPATH causes Sun make to only execute # the first set of double-colon rules, so remove it if not needed. # If there is a colon in the path, we need to keep it. if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' fi trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 DEFS=-DHAVE_CONFIG_H # Without the "./", some shells look in PATH for config.status. : ${CONFIG_STATUS=./config.status} echo creating $CONFIG_STATUS rm -f $CONFIG_STATUS cat > $CONFIG_STATUS </dev/null | sed 1q`: # # $0 $ac_configure_args # # Compiler output produced by configure, useful for debugging # configure, is in ./config.log if it exists. ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" for ac_option do case "\$ac_option" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) echo "$CONFIG_STATUS generated by autoconf version 2.13" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; *) echo "\$ac_cs_usage"; exit 1 ;; esac done ac_given_srcdir=$srcdir ac_given_INSTALL="$INSTALL" trap 'rm -fr `echo "Makefile.config Makefile include/Makefile lib/Makefile adpcm/Makefile gsm/Makefile librplay/Makefile rplayd/Makefile rplay/Makefile rptp/Makefile doc/Makefile devrplay/Makefile include/config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF $ac_vpsub $extrasub s%@SHELL@%$SHELL%g s%@CFLAGS@%$CFLAGS%g s%@CPPFLAGS@%$CPPFLAGS%g s%@CXXFLAGS@%$CXXFLAGS%g s%@FFLAGS@%$FFLAGS%g s%@DEFS@%$DEFS%g s%@LDFLAGS@%$LDFLAGS%g s%@LIBS@%$LIBS%g s%@exec_prefix@%$exec_prefix%g s%@prefix@%$prefix%g s%@program_transform_name@%$program_transform_name%g s%@bindir@%$bindir%g s%@sbindir@%$sbindir%g s%@libexecdir@%$libexecdir%g s%@datadir@%$datadir%g s%@sysconfdir@%$sysconfdir%g s%@sharedstatedir@%$sharedstatedir%g s%@localstatedir@%$localstatedir%g s%@libdir@%$libdir%g s%@includedir@%$includedir%g s%@oldincludedir@%$oldincludedir%g s%@infodir@%$infodir%g s%@mandir@%$mandir%g s%@RPLAY_VERSION@%$RPLAY_VERSION%g s%@CC@%$CC%g s%@CPP@%$CPP%g s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g s%@INSTALL_DATA@%$INSTALL_DATA%g s%@LN_S@%$LN_S%g s%@RANLIB@%$RANLIB%g s%@ETAGS@%$ETAGS%g s%@MAKEDEPEND@%$MAKEDEPEND%g s%@MAKEINFO@%$MAKEINFO%g s%@TEXI2DVI@%$TEXI2DVI%g s%@TEXI2HTML@%$TEXI2HTML%g s%@DVIPS@%$DVIPS%g s%@LIBOBJS@%$LIBOBJS%g s%@RL_LIBS@%$RL_LIBS%g s%@GSM_LIBS@%$GSM_LIBS%g s%@GSM_INCS@%$GSM_INCS%g s%@RX_LIBS@%$RX_LIBS%g s%@RX_INCS@%$RX_INCS%g s%@RPLAY_TOP@%$RPLAY_TOP%g s%@RPLAY_TARGET@%$RPLAY_TARGET%g s%@subdirs@%$subdirs%g s%@BUILD_TARGETS@%$BUILD_TARGETS%g CEOF EOF cat >> $CONFIG_STATUS <<\EOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. ac_file=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_cmds # Line after last line for current file. ac_more_lines=: ac_sed_cmds="" while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file else sed "${ac_end}q" conftest.subs > conftest.s$ac_file fi if test ! -s conftest.s$ac_file; then ac_more_lines=false rm -f conftest.s$ac_file else if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f conftest.s$ac_file" else ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" fi ac_file=`expr $ac_file + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_cmds` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" # A "../" for each directory in $ac_dir_suffix. ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` else ac_dir_suffix= ac_dots= fi case "$ac_given_srcdir" in .) srcdir=. if test -z "$ac_dots"; then top_srcdir=. else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; *) # Relative path. srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" top_srcdir="$ac_dots$ac_given_srcdir" ;; esac case "$ac_given_INSTALL" in [/$]*) INSTALL="$ac_given_INSTALL" ;; *) INSTALL="$ac_dots$ac_given_INSTALL" ;; esac echo creating "$ac_file" rm -f "$ac_file" configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." case "$ac_file" in *Makefile*) ac_comsub="1i\\ # $configure_input" ;; *) ac_comsub= ;; esac ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` sed -e "$ac_comsub s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g s%@INSTALL@%$INSTALL%g " $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file fi; done rm -f conftest.s* # These sed commands are passed to sed as "A NAME B NAME C VALUE D", where # NAME is the cpp macro being defined and VALUE is the value it is being given. # # ac_d sets the value in "#define NAME VALUE" lines. ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' ac_dC='\3' ac_dD='%g' # ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_uB='\([ ]\)%\1#\2define\3' ac_uC=' ' ac_uD='\4%g' # ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_eB='$%\1#\2define\3' ac_eC=' ' ac_eD='%g' if test "${CONFIG_HEADERS+set}" != set; then EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF fi for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac echo creating $ac_file rm -f conftest.frag conftest.in conftest.out ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` cat $ac_file_inputs > conftest.in EOF # Transform confdefs.h into a sed script conftest.vals that substitutes # the proper values into config.h.in to produce config.h. And first: # Protect against being on the right side of a sed subst in config.status. # Protect against being in an unquoted here document in config.status. rm -f conftest.vals cat > conftest.hdr <<\EOF s/[\\&%]/\\&/g s%[\\$`]%\\&%g s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp s%ac_d%ac_u%gp s%ac_u%ac_e%gp EOF sed -n -f conftest.hdr confdefs.h > conftest.vals rm -f conftest.hdr # This sed command replaces #undef with comments. This is necessary, for # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. cat >> conftest.vals <<\EOF s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% EOF # Break up conftest.vals because some shells have a limit on # the size of here documents, and old seds have small limits too. rm -f conftest.tail while : do ac_lines=`grep -c . conftest.vals` # grep -c gives empty output for an empty file on some AIX systems. if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi # Write a limited-size here document to conftest.frag. echo ' cat > conftest.frag <> $CONFIG_STATUS sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS echo 'CEOF sed -f conftest.frag conftest.in > conftest.out rm -f conftest.in mv conftest.out conftest.in ' >> $CONFIG_STATUS sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail rm -f conftest.vals mv conftest.tail conftest.vals done rm -f conftest.vals cat >> $CONFIG_STATUS <<\EOF rm -f conftest.frag conftest.h echo "/* $ac_file. Generated automatically by configure. */" > conftest.h cat conftest.in >> conftest.h rm -f conftest.in if cmp -s $ac_file conftest.h 2>/dev/null; then echo "$ac_file is unchanged" rm -f conftest.h else # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" fi rm -f $ac_file mv conftest.h $ac_file fi fi; done EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF srcdir=$ac_given_srcdir while test -n "$ac_sources"; do set $ac_dests; ac_dest=$1; shift; ac_dests=$* set $ac_sources; ac_source=$1; shift; ac_sources=$* echo "linking $srcdir/$ac_source to $ac_dest" if test ! -r $srcdir/$ac_source; then { echo "configure: error: $srcdir/$ac_source: File not found" 1>&2; exit 1; } fi rm -f $ac_dest # Make relative symlinks. # Remove last slash and all that follows it. Not all systems have dirname. ac_dest_dir=`echo $ac_dest|sed 's%/[^/][^/]*$%%'` if test "$ac_dest_dir" != "$ac_dest" && test "$ac_dest_dir" != .; then # The dest file is in a subdirectory. test ! -d "$ac_dest_dir" && mkdir "$ac_dest_dir" ac_dest_dir_suffix="/`echo $ac_dest_dir|sed 's%^\./%%'`" # A "../" for each directory in $ac_dest_dir_suffix. ac_dots=`echo $ac_dest_dir_suffix|sed 's%/[^/]*%../%g'` else ac_dest_dir_suffix= ac_dots= fi case "$srcdir" in [/$]*) ac_rel_source="$srcdir/$ac_source" ;; *) ac_rel_source="$ac_dots$srcdir/$ac_source" ;; esac # Make a symlink if possible; otherwise try a hard link. if ln -s $ac_rel_source $ac_dest 2>/dev/null || ln $srcdir/$ac_source $ac_dest; then : else { echo "configure: error: can not link $ac_dest to $srcdir/$ac_source" 1>&2; exit 1; } fi done EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF exit 0 EOF chmod +x $CONFIG_STATUS rm -fr confdefs* $ac_clean_files test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 if test "$no_recursion" != yes; then # Remove --cache-file and --srcdir arguments so they do not pile up. ac_sub_configure_args= ac_prev= for ac_arg in $ac_configure_args; do if test -n "$ac_prev"; then ac_prev= continue fi case "$ac_arg" in -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) ;; *) ac_sub_configure_args="$ac_sub_configure_args $ac_arg" ;; esac done for ac_config_dir in rx; do # Do not complain, so a configure script can configure whichever # parts of a large source tree are present. if test ! -d $srcdir/$ac_config_dir; then continue fi echo configuring in $ac_config_dir case "$srcdir" in .) ;; *) if test -d ./$ac_config_dir || mkdir ./$ac_config_dir; then :; else { echo "configure: error: can not create `pwd`/$ac_config_dir" 1>&2; exit 1; } fi ;; esac ac_popdir=`pwd` cd $ac_config_dir # A "../" for each directory in /$ac_config_dir. ac_dots=`echo $ac_config_dir|sed -e 's%^\./%%' -e 's%[^/]$%&/%' -e 's%[^/]*/%../%g'` case "$srcdir" in .) # No --srcdir option. We are building in place. ac_sub_srcdir=$srcdir ;; /*) # Absolute path. ac_sub_srcdir=$srcdir/$ac_config_dir ;; *) # Relative path. ac_sub_srcdir=$ac_dots$srcdir/$ac_config_dir ;; esac # Check for guested configure; otherwise get Cygnus style configure. if test -f $ac_sub_srcdir/configure; then ac_sub_configure=$ac_sub_srcdir/configure elif test -f $ac_sub_srcdir/configure.in; then ac_sub_configure=$ac_configure else echo "configure: warning: no configuration information is in $ac_config_dir" 1>&2 ac_sub_configure= fi # The recursion is here. if test -n "$ac_sub_configure"; then # Make the cache file name correct relative to the subdirectory. case "$cache_file" in /*) ac_sub_cache_file=$cache_file ;; *) # Relative path. ac_sub_cache_file="$ac_dots$cache_file" ;; esac case "$ac_given_INSTALL" in [/$]*) INSTALL="$ac_given_INSTALL" ;; *) INSTALL="$ac_dots$ac_given_INSTALL" ;; esac echo "running ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir" # The eval makes quoting arguments work. if eval ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir then : else { echo "configure: error: $ac_sub_configure failed for $ac_config_dir" 1>&2; exit 1; } fi fi cd $ac_popdir done fi rplay-3.3.2/configure.in100644 153 62 13460 6727404424 13663 0ustar boynsstaffdnl $Id: configure.in,v 1.5 1999/06/09 06:26:28 boyns Exp $ dnl dnl Process this file with autoconf to produce a configure script. dnl AC_INIT(rplayd/rplayd.c) AC_CONFIG_HEADER(include/config.h) dnl dnl Figure what version of rplay this is. dnl export srcdir RPLAY_VERSION=`$srcdir/version` echo configuring rplay version $RPLAY_VERSION AC_SUBST(RPLAY_VERSION) AC_DEFINE_UNQUOTED(RPLAY_VERSION, "$RPLAY_VERSION") # We want these before the checks, so the checks can modify their values. test -z "$CFLAGS" && CFLAGS=-g auto_cflags=1 AC_PROG_CC # If we're using gcc and the user hasn't specified CFLAGS, add -O to CFLAGS. test -n "$GCC" && test -n "$auto_cflags" && CFLAGS="$CFLAGS -O" AC_SUBST(CFLAGS)dnl AC_SUBST(LDFLAGS)dnl AC_ARG_ENABLE(rplayd-user, [ --enable-rplayd-user=USER], RPLAYD_USER=$enableval) AC_ARG_ENABLE(rplayd-group, [ --enable-rplayd-group=GROUP], RPLAYD_GROUP=$enableval) if test -n "$RPLAYD_USER" then AC_DEFINE_UNQUOTED(RPLAYD_USER, "$RPLAYD_USER") fi if test -n "$RPLAYD_GROUP" then AC_DEFINE_UNQUOTED(RPLAYD_GROUP, "$RPLAYD_GROUP") fi dnl Programs AC_ISC_POSIX AC_PROG_CPP AC_PROG_INSTALL AC_PROG_LN_S AC_PROG_RANLIB AC_CHECK_PROGS(ETAGS, etags, true) AC_CHECK_PROGS(MAKEDEPEND, makedepend, true) AC_CHECK_PROGS(MAKEINFO, makeinfo, true) AC_CHECK_PROGS(TEXI2DVI, texi2dvi, true) AC_CHECK_PROGS(TEXI2HTML, texi2html, true) AC_CHECK_PROGS(DVIPS, dvips, true) dnl Check for header files. AC_HEADER_DIRENT AC_HEADER_STDC AC_HEADER_TIME dnl AC_PATH_XTRA AC_CHECK_HEADERS(fcntl.h sys/file.h sys/ioctl.h sys/time.h stdlib.h unistd.h memory.h string.h strings.h utime.h limits.h gsm.h gsm/gsm.h rxposix.h rx/rxposix.h) AC_HEADER_SYS_WAIT dnl Check for typedefs, structures, and compiler characteristics. AC_C_CONST AC_TYPE_SIZE_T dnl Check for library functions. AC_FUNC_MMAP AC_FUNC_MEMCMP AC_FUNC_VPRINTF AC_TYPE_SIGNAL AC_CHECK_FUNCS(getcwd gethostname mkdir re_comp regcomp select snprintf socket strdup strerror strstr fstat fchmod fchown utime utimes memmove sigset vsnprintf waitpid random srandom) AC_CHECK_LIB(socket, socket, [LIBS="$LIBS -lsocket"]) AC_CHECK_LIB(nsl, t_accept, [LIBS="$LIBS -lnsl"]) AC_CHECK_LIB(readline, readline, [RL_LIBS="-lreadline"]) AC_SUBST(RL_LIBS) AC_CHECK_LIB(gsm, gsm_decode, [HAVE_GSM="yes"]) if test "$HAVE_GSM" = "yes"; then GSM_LIBS="-lgsm" GSM_INCS="" else GSM_LIBS="-L../gsm -lgsm" GSM_INCS="-I\${srcdir}/../gsm" fi AC_SUBST(GSM_LIBS) AC_SUBST(GSM_INCS) AC_CHECK_LIB(rx, regncomp, [HAVE_RX="yes"]) if test "$HAVE_RX" = "yes"; then RX_LIBS="-lrx" RX_INCS="" else RX_LIBS="-L../rx -lrx" RX_INCS="-I\${srcdir}/../rx" fi AC_SUBST(RX_LIBS) AC_SUBST(RX_INCS) RPLAY_TOP=`pwd` AC_SUBST(RPLAY_TOP) dnl dnl First check if target is already defined. dnl if test -n "$target" -a "$target" != "NONE"; then RPLAY_TARGET=$target echo "using specified $RPLAY_TARGET configuration" fi dnl dnl Check for Sun dnl if test -z "$RPLAY_TARGET"; then AC_MSG_CHECKING(for sun) AC_EGREP_CPP(yes, [ #ifdef sun yes #endif ], is_sun=yes, is_sun=no) AC_MSG_RESULT($is_sun) if test $is_sun = "yes"; then RPLAY_TARGET="sun" fi if test "$RPLAY_TARGET"; then AC_MSG_CHECKING(for solaris) if test ! -f /vmunix; then is_solaris=yes RPLAY_TARGET="solaris" else is_solaris=no fi AC_MSG_RESULT($is_solaris) fi fi dnl dnl Check for Linux dnl if test -z "$RPLAY_TARGET"; then AC_MSG_CHECKING(for linux) AC_EGREP_CPP(yes, [ #ifdef linux yes #endif ], is_linux=yes, is_linux=no) AC_MSG_RESULT($is_linux) if test $is_linux = "yes"; then RPLAY_TARGET="oss" fi fi dnl dnl Check for HP-UX dnl if test -z "$RPLAY_TARGET"; then AC_MSG_CHECKING(for hpux) AC_EGREP_CPP(yes, [ #ifdef __hpux yes #endif ], is_hpux=yes, is_hpux=no) AC_MSG_RESULT($is_hpux) if test $is_hpux = "yes"; then RPLAY_TARGET="hpux" fi fi dnl dnl Check for SGI dnl if test -z "$RPLAY_TARGET"; then AC_MSG_CHECKING(for sgi) AC_EGREP_CPP(yes, [ #ifdef sgi yes #endif ], is_sgi=yes, is_sgi=no) AC_MSG_RESULT($is_sgi) if test $is_sgi = "yes"; then RPLAY_TARGET="sgi" AC_MSG_CHECKING(for multimedia development kit) AC_CHECK_HEADERS(audio.h) if test $ac_cv_header_audio_h = "no"; then echo 'The multimedia development kit was not found.' echo 'Please read the README.sgi file.' exit -1 fi fi fi dnl dnl Check for FreeBSD dnl if test -z "$RPLAY_TARGET"; then AC_MSG_CHECKING(for FreeBSD) AC_EGREP_CPP(yes, [ #ifdef __FreeBSD__ yes #endif ], is_freebsd=yes, is_freebsd=no) AC_MSG_RESULT($is_freebsd) if test $is_freebsd = "yes"; then RPLAY_TARGET="FreeBSD" fi fi dnl dnl *** Add new systems before this line *** dnl dnl dnl Now make sure the system type has been found. dnl if test -z "$RPLAY_TARGET"; then echo 'Sorry, I could not figure out what type of system you have.' echo -n 'Would you like to try the generic configuration? ' read ans case "$ans" in y|Y|yes|Yes|YES|sure|ok|okay) RPLAY_TARGET="generic" ;; *) echo configuration aborted; exit 1; esac fi echo "using $RPLAY_TARGET configuration" AC_SUBST(RPLAY_TARGET) AC_LINK_FILES(rplayd/audio/audio_${RPLAY_TARGET}.c rplayd/audio/audio_${RPLAY_TARGET}.h, rplayd/audio.c rplayd/audio.h) dnl dnl Add special things to @DEFS@. dnl if test $RPLAY_TARGET = "solaris"; then AC_DEFINE(SVR4) fi AC_SUBST(DEFS) dnl dnl Add special things to @LIBS@. dnl if test $RPLAY_TARGET = "sgi"; then LIBS="$LIBS -laudio" fi AC_SUBST(LIBS) BUILD_TARGETS="include lib adpcm" if test "$HAVE_RX" != "yes"; then BUILD_TARGETS="$BUILD_TARGETS rx" AC_CONFIG_SUBDIRS(rx) fi if test "$HAVE_GSM" != "yes"; then BUILD_TARGETS="$BUILD_TARGETS gsm" fi BUILD_TARGETS="$BUILD_TARGETS librplay rplayd rplay rptp doc" if test $RPLAY_TARGET = "oss"; then BUILD_TARGETS="$BUILD_TARGETS devrplay" fi AC_SUBST(BUILD_TARGETS) AC_OUTPUT(Makefile.config Makefile include/Makefile lib/Makefile adpcm/Makefile gsm/Makefile librplay/Makefile rplayd/Makefile rplay/Makefile rptp/Makefile doc/Makefile devrplay/Makefile) rplay-3.3.2/install-sh100755 153 62 11243 6552756452 13362 0ustar boynsstaff#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. # # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" tranformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 rplay-3.3.2/mkinstalldirs100755 153 62 1211 6552756452 14136 0ustar boynsstaff#!/bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Last modified: 1994-03-25 # Public domain errstatus=0 for file in ${1+"$@"} ; do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d in ${1+"$@"} ; do pathcomp="$pathcomp$d" case "$pathcomp" in -* ) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" 1>&2 mkdir "$pathcomp" || errstatus=$? fi pathcomp="$pathcomp/" done done exit $errstatus # mkinstalldirs ends here rplay-3.3.2/version100755 153 62 713 6552756452 12731 0ustar boynsstaff#!/bin/sh if [ "$srcdir" = "" ] then srcdir="." fi VERSION=`awk ' \ BEGIN { major = ""; minor = ""; patchlevel = ""; status = ""; } \ /RPLAY_MAJOR_VERSION/ { major = $3 } \ /RPLAY_MINOR_VERSION/ { minor = $3 } \ /RPLAY_PATCHLEVEL/ { patchlevel = $3 } \ /RPLAY_STATUS/ { status = $3 } \ END { printf("%s.%s.%s%s", major, minor, patchlevel, status) } \ ' $srcdir/include/version.h` VERSION=`echo $VERSION | sed 's/"//g'` echo $VERSION rplay-3.3.2/adpcm/ 40755 153 62 0 6727650074 12321 5ustar boynsstaffrplay-3.3.2/adpcm/Makefile.in100644 153 62 1707 6552756453 14474 0ustar boynsstaffinclude @RPLAY_TOP@/Makefile.config srcdir = @srcdir@ VPATH = @srcdir@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ CPPFLAGS= $(CC_OPTIONS) -I. -I../include -I@srcdir@ -I@srcdir@/../include -I@srcdir@/../lib @DEFS@ .c.o: $(CC) -c $(CPPFLAGS) $(CFLAGS) $< LDFLAGS= $(LD_OPTIONS) -L. -ladpcm @LDFLAGS@ TARGET= libadpcm.a SRCS= g711.c g721.c g723_24.c g723_40.c g72x.c OBJS= g711.o g721.o g723_24.o g723_40.o g72x.o all: $(TARGET) decode encode $(TARGET): $(OBJS) $(AR) rcv $@ $? $(RANLIB) $@ decode: $(TARGET) decode.o $(CC) -o g72xdecode decode.o $(LDFLAGS) encode: $(TARGET) encode.o $(CC) -o g72xencode encode.o $(LDFLAGS) install: uninstall: clean: $(RM) $(OBJS) $(TARGET) decode.o g72xdecode encode.o g72xencode a.out core *~ *.bak *.orig TAGS distclean: clean $(RM) Makefile tags: $(TAGS) *.[ch] TAGS: tags etags: tags depend: $(MAKEDEPEND) -- $(CPPFLAGS) $(CFLAGS) -- $(SRCS) rplay-3.3.2/adpcm/README100644 153 62 6221 6552756453 13303 0ustar boynsstaffThe files in this directory comprise ANSI-C language reference implementations of the CCITT (International Telegraph and Telephone Consultative Committee) G.711, G.721 and G.723 voice compressions. They have been tested on Sun SPARCstations and passed 82 out of 84 test vectors published by CCITT (Dec. 20, 1988) for G.721 and G.723. [The two remaining test vectors, which the G.721 decoder implementation for u-law samples did not pass, may be in error because they are identical to two other vectors for G.723_40.] This source code is released by Sun Microsystems, Inc. to the public domain. Please give your acknowledgement in product literature if this code is used in your product implementation. Sun Microsystems supports some CCITT audio formats in Solaris 2.0 system software. However, Sun's implementations have been optimized for higher performance on SPARCstations. The source files for CCITT conversion routines in this directory are: g72x.h header file for g721.c, g723_24.c and g723_40.c g711.c CCITT G.711 u-law and A-law compression g72x.c common denominator of G.721 and G.723 ADPCM codes g721.c CCITT G.721 32Kbps ADPCM coder (with g72x.c) g723_24.c CCITT G.723 24Kbps ADPCM coder (with g72x.c) g723_40.c CCITT G.723 40Kbps ADPCM coder (with g72x.c) Simple conversions between u-law, A-law, and 16-bit linear PCM are invoked as follows: unsigned char ucode, acode; short pcm_val; ucode = linear2ulaw(pcm_val); ucode = alaw2ulaw(acode); acode = linear2alaw(pcm_val); acode = ulaw2alaw(ucode); pcm_val = ulaw2linear(ucode); pcm_val = alaw2linear(acode); The other CCITT compression routines are invoked as follows: #include "g72x.h" struct g72x_state state; int sample, code; g72x_init_state(&state); code = {g721,g723_24,g723_40}_encoder(sample, coding, &state); sample = {g721,g723_24,g723_40}_decoder(code, coding, &state); where coding = AUDIO_ENCODING_ULAW for 8-bit u-law samples AUDIO_ENCODING_ALAW for 8-bit A-law samples AUDIO_ENCODING_LINEAR for 16-bit linear PCM samples This directory also includes the following sample programs: encode.c CCITT ADPCM encoder decode.c CCITT ADPCM decoder Makefile makefile for the sample programs The sample programs contain examples of how to call the various compression routines and pack/unpack the bits. The sample programs read byte streams from stdin and write to stdout. The input/output data is raw data (no file header or other identifying information is embedded). The sample programs are invoked as follows: encode [-3|4|5] [-a|u|l] outfile decode [-3|4|5] [-a|u|l] outfile where: -3 encode to (decode from) G.723 24kbps (3-bit) data -4 encode to (decode from) G.721 32kbps (4-bit) data [the default] -5 encode to (decode from) G.723 40kbps (5-bit) data -a encode from (decode to) A-law data -u encode from (decode to) u-law data [the default] -l encode from (decode to) 16-bit linear data Examples: # Read 16-bit linear and output G.721 encode -4 -l g721file # Read 40Kbps G.723 and output A-law decode -5 -a alawfile # Compress and then decompress u-law data using 24Kbps G.723 encode -3 ulawout rplay-3.3.2/adpcm/README.rplay100644 153 62 305 6552756453 14406 0ustar boynsstaff This directory contains Sun's original ANSI C source code converted to K&R C using `ansi2knr'. `g72x.h' was also modified for K&R C compilers. No other modifications have been made. Mark Boyns rplay-3.3.2/adpcm/decode.c100644 153 62 4771 6552756453 14022 0ustar boynsstaff/* * decode.c * * CCITT ADPCM decoder * * Usage : decode [-3|4|5] [-a|u|l] < infile > outfile */ #include #include "g72x.h" /* * Unpack input codes and pass them back as bytes. * Returns 1 if there is residual input, returns -1 if eof, else returns 0. */ int unpack_input(code, bits) unsigned char *code; int bits; { static unsigned int in_buffer = 0; static int in_bits = 0; unsigned char in_byte; if (in_bits < bits) { if (fread(&in_byte, sizeof (char), 1, stdin) != 1) { *code = 0; return (-1); } in_buffer |= (in_byte << in_bits); in_bits += 8; } *code = in_buffer & ((1 << bits) - 1); in_buffer >>= bits; in_bits -= bits; return (in_bits > 0); } main(argc, argv) int argc; char **argv; { short sample; unsigned char code; int n; struct g72x_state state; int out_coding; int out_size; int (*dec_routine)(); int dec_bits; g72x_init_state(&state); out_coding = AUDIO_ENCODING_ULAW; out_size = sizeof (char); dec_routine = g721_decoder; dec_bits = 4; /* Process encoding argument, if any */ while ((argc > 1) && (argv[1][0] == '-')) { switch (argv[1][1]) { case '3': dec_routine = g723_24_decoder; dec_bits = 3; break; case '4': dec_routine = g721_decoder; dec_bits = 4; break; case '5': dec_routine = g723_40_decoder; dec_bits = 5; break; case 'u': out_coding = AUDIO_ENCODING_ULAW; out_size = sizeof (char); break; case 'a': out_coding = AUDIO_ENCODING_ALAW; out_size = sizeof (char); break; case 'l': out_coding = AUDIO_ENCODING_LINEAR; out_size = sizeof (short); break; default: fprintf(stderr, "CCITT ADPCM Decoder -- usage:\n"); fprintf(stderr, "\tdecode [-3|4|5] [-a|u|l] < infile > outfile\n"); fprintf(stderr, "where:\n"); fprintf(stderr, "\t-3\tProcess G.723 24kbps (3-bit) input data\n"); fprintf(stderr, "\t-4\tProcess G.721 32kbps (4-bit) input data [default]\n"); fprintf(stderr, "\t-5\tProcess G.723 40kbps (5-bit) input data\n"); fprintf(stderr, "\t-a\tGenerate 8-bit A-law data\n"); fprintf(stderr, "\t-u\tGenerate 8-bit u-law data [default]\n"); fprintf(stderr, "\t-l\tGenerate 16-bit linear PCM data\n"); exit(1); } argc--; argv++; } /* Read and unpack input codes and process them */ while (unpack_input(&code, dec_bits) >= 0) { sample = (*dec_routine)(code, out_coding, &state); if (out_size == 2) { fwrite(&sample, out_size, 1, stdout); } else { code = (unsigned char)sample; fwrite(&code, out_size, 1, stdout); } } fclose(stdout); } rplay-3.3.2/adpcm/encode.c100644 153 62 5325 6552756453 14030 0ustar boynsstaff/* * encode.c * * CCITT ADPCM encoder * * Usage : encode [-3|4|5] [-a|u|l] < infile > outfile */ #include #include "g72x.h" /* * Pack output codes into bytes and write them to stdout. * Returns 1 if there is residual output, else returns 0. */ int pack_output(code, bits) unsigned code; int bits; { static unsigned int out_buffer = 0; static int out_bits = 0; unsigned char out_byte; out_buffer |= (code << out_bits); out_bits += bits; if (out_bits >= 8) { out_byte = out_buffer & 0xff; out_bits -= 8; out_buffer >>= 8; fwrite(&out_byte, sizeof (char), 1, stdout); } return (out_bits > 0); } main(argc, argv) int argc; char **argv; { struct g72x_state state; unsigned char sample_char; short sample_short; unsigned char code; int resid; int in_coding; int in_size; unsigned *in_buf; int (*enc_routine)(); int enc_bits; g72x_init_state(&state); /* Set defaults to u-law input, G.721 output */ in_coding = AUDIO_ENCODING_ULAW; in_size = sizeof (char); in_buf = (unsigned *)&sample_char; enc_routine = g721_encoder; enc_bits = 4; /* Process encoding argument, if any */ while ((argc > 1) && (argv[1][0] == '-')) { switch (argv[1][1]) { case '3': enc_routine = g723_24_encoder; enc_bits = 3; break; case '4': enc_routine = g721_encoder; enc_bits = 4; break; case '5': enc_routine = g723_40_encoder; enc_bits = 5; break; case 'u': in_coding = AUDIO_ENCODING_ULAW; in_size = sizeof (char); in_buf = (unsigned *)&sample_char; break; case 'a': in_coding = AUDIO_ENCODING_ALAW; in_size = sizeof (char); in_buf = (unsigned *)&sample_char; break; case 'l': in_coding = AUDIO_ENCODING_LINEAR; in_size = sizeof (short); in_buf = (unsigned *)&sample_short; break; default: fprintf(stderr, "CCITT ADPCM Encoder -- usage:\n"); fprintf(stderr, "\tencode [-3|4|5] [-a|u|l] < infile > outfile\n"); fprintf(stderr, "where:\n"); fprintf(stderr, "\t-3\tGenerate G.723 24kbps (3-bit) data\n"); fprintf(stderr, "\t-4\tGenerate G.721 32kbps (4-bit) data [default]\n"); fprintf(stderr, "\t-5\tGenerate G.723 40kbps (5-bit) data\n"); fprintf(stderr, "\t-a\tProcess 8-bit A-law input data\n"); fprintf(stderr, "\t-u\tProcess 8-bit u-law input data [default]\n"); fprintf(stderr, "\t-l\tProcess 16-bit linear PCM input data\n"); exit(1); } argc--; argv++; } /* Read input file and process */ while (fread(in_buf, in_size, 1, stdin) == 1) { code = (*enc_routine)(in_size == 2 ? sample_short : sample_char, in_coding, &state); resid = pack_output(code, enc_bits); } /* Write zero codes until all residual codes are written out */ while (resid) { resid = pack_output(0, enc_bits); } fclose(stdout); } rplay-3.3.2/adpcm/g711.c100644 153 62 16646 6552756453 13302 0ustar boynsstaff/* * This source code is a product of Sun Microsystems, Inc. and is provided * for unrestricted use. Users may copy or modify this source code without * charge. * * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun source code is provided with no support and without any obligation on * the part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ /* * g711.c * * u-law, A-law and linear PCM conversions. */ #define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */ #define QUANT_MASK (0xf) /* Quantization field mask. */ #define NSEGS (8) /* Number of A-law segments. */ #define SEG_SHIFT (4) /* Left shift for segment number. */ #define SEG_MASK (0x70) /* Segment field mask. */ static short seg_end[8] = {0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF}; /* copy from CCITT G.711 specifications */ unsigned char _u2a[128] = { /* u- to A-law conversions */ 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 29, 31, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128}; unsigned char _a2u[128] = { /* A- to u-law conversions */ 1, 3, 5, 7, 9, 11, 13, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 48, 49, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127}; static int search(val, table, size) int val; short *table; int size; { int i; for (i = 0; i < size; i++) { if (val <= *table++) return (i); } return (size); } /* * linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law * * linear2alaw() accepts an 16-bit integer and encodes it as A-law data. * * Linear Input Code Compressed Code * ------------------------ --------------- * 0000000wxyza 000wxyz * 0000001wxyza 001wxyz * 000001wxyzab 010wxyz * 00001wxyzabc 011wxyz * 0001wxyzabcd 100wxyz * 001wxyzabcde 101wxyz * 01wxyzabcdef 110wxyz * 1wxyzabcdefg 111wxyz * * For further information see John C. Bellamy's Digital Telephony, 1982, * John Wiley & Sons, pps 98-111 and 472-476. */ unsigned char linear2alaw(pcm_val) int pcm_val; /* 2's complement (16-bit range) */ { int mask; int seg; unsigned char aval; if (pcm_val >= 0) { mask = 0xD5; /* sign (7th) bit = 1 */ } else { mask = 0x55; /* sign bit = 0 */ pcm_val = -pcm_val - 8; } /* Convert the scaled magnitude to segment number. */ seg = search(pcm_val, seg_end, 8); /* Combine the sign, segment, and quantization bits. */ if (seg >= 8) /* out of range, return maximum value. */ return (0x7F ^ mask); else { aval = seg << SEG_SHIFT; if (seg < 2) aval |= (pcm_val >> 4) & QUANT_MASK; else aval |= (pcm_val >> (seg + 3)) & QUANT_MASK; return (aval ^ mask); } } /* * alaw2linear() - Convert an A-law value to 16-bit linear PCM * */ int alaw2linear(a_val) unsigned char a_val; { int t; int seg; a_val ^= 0x55; t = (a_val & QUANT_MASK) << 4; seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT; switch (seg) { case 0: t += 8; break; case 1: t += 0x108; break; default: t += 0x108; t <<= seg - 1; } return ((a_val & SIGN_BIT) ? t : -t); } #define BIAS (0x84) /* Bias for linear code. */ /* * linear2ulaw() - Convert a linear PCM value to u-law * * In order to simplify the encoding process, the original linear magnitude * is biased by adding 33 which shifts the encoding range from (0 - 8158) to * (33 - 8191). The result can be seen in the following encoding table: * * Biased Linear Input Code Compressed Code * ------------------------ --------------- * 00000001wxyza 000wxyz * 0000001wxyzab 001wxyz * 000001wxyzabc 010wxyz * 00001wxyzabcd 011wxyz * 0001wxyzabcde 100wxyz * 001wxyzabcdef 101wxyz * 01wxyzabcdefg 110wxyz * 1wxyzabcdefgh 111wxyz * * Each biased linear code has a leading 1 which identifies the segment * number. The value of the segment number is equal to 7 minus the number * of leading 0's. The quantization interval is directly available as the * four bits wxyz. * The trailing bits (a - h) are ignored. * * Ordinarily the complement of the resulting code word is used for * transmission, and so the code word is complemented before it is returned. * * For further information see John C. Bellamy's Digital Telephony, 1982, * John Wiley & Sons, pps 98-111 and 472-476. */ unsigned char linear2ulaw(pcm_val) int pcm_val; /* 2's complement (16-bit range) */ { int mask; int seg; unsigned char uval; /* Get the sign and the magnitude of the value. */ if (pcm_val < 0) { pcm_val = BIAS - pcm_val; mask = 0x7F; } else { pcm_val += BIAS; mask = 0xFF; } /* Convert the scaled magnitude to segment number. */ seg = search(pcm_val, seg_end, 8); /* * Combine the sign, segment, quantization bits; * and complement the code word. */ if (seg >= 8) /* out of range, return maximum value. */ return (0x7F ^ mask); else { uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF); return (uval ^ mask); } } /* * ulaw2linear() - Convert a u-law value to 16-bit linear PCM * * First, a biased linear code is derived from the code word. An unbiased * output can then be obtained by subtracting 33 from the biased code. * * Note that this function expects to be passed the complement of the * original code word. This is in keeping with ISDN conventions. */ int ulaw2linear(u_val) unsigned char u_val; { int t; /* Complement to obtain normal u-law value. */ u_val = ~u_val; /* * Extract and bias the quantization bits. Then * shift up by the segment number and subtract out the bias. */ t = ((u_val & QUANT_MASK) << 3) + BIAS; t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT; return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS)); } /* A-law to u-law conversion */ unsigned char alaw2ulaw(aval) unsigned char aval; { aval &= 0xff; return ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) : (0x7F ^ _a2u[aval ^ 0x55])); } /* u-law to A-law conversion */ unsigned char ulaw2alaw(uval) unsigned char uval; { uval &= 0xff; return ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1)) : (0x55 ^ (_u2a[0x7F ^ uval] - 1))); } rplay-3.3.2/adpcm/g721.c100644 153 62 12277 6552756453 13277 0ustar boynsstaff/* * This source code is a product of Sun Microsystems, Inc. and is provided * for unrestricted use. Users may copy or modify this source code without * charge. * * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun source code is provided with no support and without any obligation on * the part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ /* * g721.c * * Description: * * g721_encoder(), g721_decoder() * * These routines comprise an implementation of the CCITT G.721 ADPCM * coding algorithm. Essentially, this implementation is identical to * the bit level description except for a few deviations which * take advantage of work station attributes, such as hardware 2's * complement arithmetic and large memory. Specifically, certain time * consuming operations such as multiplications are replaced * with lookup tables and software 2's complement operations are * replaced with hardware 2's complement. * * The deviation from the bit level specification (lookup tables) * preserves the bit level performance specifications. * * As outlined in the G.721 Recommendation, the algorithm is broken * down into modules. Each section of code below is preceded by * the name of the module which it is implementing. * */ #include "g72x.h" static short qtab_721[7] = {-124, 80, 178, 246, 300, 349, 400}; /* * Maps G.721 code word to reconstructed scale factor normalized log * magnitude values. */ static short _dqlntab[16] = {-2048, 4, 135, 213, 273, 323, 373, 425, 425, 373, 323, 273, 213, 135, 4, -2048}; /* Maps G.721 code word to log of scale factor multiplier. */ static short _witab[16] = {-12, 18, 41, 64, 112, 198, 355, 1122, 1122, 355, 198, 112, 64, 41, 18, -12}; /* * Maps G.721 code words to a set of values whose long and short * term averages are computed and then compared to give an indication * how stationary (steady state) the signal is. */ static short _fitab[16] = {0, 0, 0, 0x200, 0x200, 0x200, 0x600, 0xE00, 0xE00, 0x600, 0x200, 0x200, 0x200, 0, 0, 0}; /* * g721_encoder() * * Encodes the input vale of linear PCM, A-law or u-law data sl and returns * the resulting code. -1 is returned for unknown input coding value. */ int g721_encoder(sl, in_coding, state_ptr) int sl; int in_coding; struct g72x_state *state_ptr; { short sezi, se, sez; /* ACCUM */ short d; /* SUBTA */ short sr; /* ADDB */ short y; /* MIX */ short dqsez; /* ADDC */ short dq, i; switch (in_coding) { /* linearize input sample to 14-bit PCM */ case AUDIO_ENCODING_ALAW: sl = alaw2linear(sl) >> 2; break; case AUDIO_ENCODING_ULAW: sl = ulaw2linear(sl) >> 2; break; case AUDIO_ENCODING_LINEAR: sl >>= 2; /* 14-bit dynamic range */ break; default: return (-1); } sezi = predictor_zero(state_ptr); sez = sezi >> 1; se = (sezi + predictor_pole(state_ptr)) >> 1; /* estimated signal */ d = sl - se; /* estimation difference */ /* quantize the prediction difference */ y = step_size(state_ptr); /* quantizer step size */ i = quantize(d, y, qtab_721, 7); /* i = ADPCM code */ dq = reconstruct(i & 8, _dqlntab[i], y); /* quantized est diff */ sr = (dq < 0) ? se - (dq & 0x3FFF) : se + dq; /* reconst. signal */ dqsez = sr + sez - se; /* pole prediction diff. */ update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state_ptr); return (i); } /* * g721_decoder() * * Description: * * Decodes a 4-bit code of G.721 encoded data of i and * returns the resulting linear PCM, A-law or u-law value. * return -1 for unknown out_coding value. */ int g721_decoder(i, out_coding, state_ptr) int i; int out_coding; struct g72x_state *state_ptr; { short sezi, sei, sez, se; /* ACCUM */ short y; /* MIX */ short sr; /* ADDB */ short dq; short dqsez; i &= 0x0f; /* mask to get proper bits */ sezi = predictor_zero(state_ptr); sez = sezi >> 1; sei = sezi + predictor_pole(state_ptr); se = sei >> 1; /* se = estimated signal */ y = step_size(state_ptr); /* dynamic quantizer step size */ dq = reconstruct(i & 0x08, _dqlntab[i], y); /* quantized diff. */ sr = (dq < 0) ? (se - (dq & 0x3FFF)) : se + dq; /* reconst. signal */ dqsez = sr - se + sez; /* pole prediction diff. */ update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state_ptr); switch (out_coding) { case AUDIO_ENCODING_ALAW: return (tandem_adjust_alaw(sr, se, y, i, 8, qtab_721)); case AUDIO_ENCODING_ULAW: return (tandem_adjust_ulaw(sr, se, y, i, 8, qtab_721)); case AUDIO_ENCODING_LINEAR: return (sr << 2); /* sr was 14-bit dynamic range */ default: return (-1); } } rplay-3.3.2/adpcm/g723_24.c100644 153 62 11123 6552756453 13573 0ustar boynsstaff/* * This source code is a product of Sun Microsystems, Inc. and is provided * for unrestricted use. Users may copy or modify this source code without * charge. * * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun source code is provided with no support and without any obligation on * the part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ /* * g723_24.c * * Description: * * g723_24_encoder(), g723_24_decoder() * * These routines comprise an implementation of the CCITT G.723 24 Kbps * ADPCM coding algorithm. Essentially, this implementation is identical to * the bit level description except for a few deviations which take advantage * of workstation attributes, such as hardware 2's complement arithmetic. * */ #include "g72x.h" /* * Maps G.723_24 code word to reconstructed scale factor normalized log * magnitude values. */ static short _dqlntab[8] = {-2048, 135, 273, 373, 373, 273, 135, -2048}; /* Maps G.723_24 code word to log of scale factor multiplier. */ static short _witab[8] = {-128, 960, 4384, 18624, 18624, 4384, 960, -128}; /* * Maps G.723_24 code words to a set of values whose long and short * term averages are computed and then compared to give an indication * how stationary (steady state) the signal is. */ static short _fitab[8] = {0, 0x200, 0x400, 0xE00, 0xE00, 0x400, 0x200, 0}; static short qtab_723_24[3] = {8, 218, 331}; /* * g723_24_encoder() * * Encodes a linear PCM, A-law or u-law input sample and returns its 3-bit code. * Returns -1 if invalid input coding value. */ int g723_24_encoder(sl, in_coding, state_ptr) int sl; int in_coding; struct g72x_state *state_ptr; { short sei, sezi, se, sez; /* ACCUM */ short d; /* SUBTA */ short y; /* MIX */ short sr; /* ADDB */ short dqsez; /* ADDC */ short dq, i; switch (in_coding) { /* linearize input sample to 14-bit PCM */ case AUDIO_ENCODING_ALAW: sl = alaw2linear(sl) >> 2; break; case AUDIO_ENCODING_ULAW: sl = ulaw2linear(sl) >> 2; break; case AUDIO_ENCODING_LINEAR: sl >>= 2; /* sl of 14-bit dynamic range */ break; default: return (-1); } sezi = predictor_zero(state_ptr); sez = sezi >> 1; sei = sezi + predictor_pole(state_ptr); se = sei >> 1; /* se = estimated signal */ d = sl - se; /* d = estimation diff. */ /* quantize prediction difference d */ y = step_size(state_ptr); /* quantizer step size */ i = quantize(d, y, qtab_723_24, 3); /* i = ADPCM code */ dq = reconstruct(i & 4, _dqlntab[i], y); /* quantized diff. */ sr = (dq < 0) ? se - (dq & 0x3FFF) : se + dq; /* reconstructed signal */ dqsez = sr + sez - se; /* pole prediction diff. */ update(3, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr); return (i); } /* * g723_24_decoder() * * Decodes a 3-bit CCITT G.723_24 ADPCM code and returns * the resulting 16-bit linear PCM, A-law or u-law sample value. * -1 is returned if the output coding is unknown. */ int g723_24_decoder(i, out_coding, state_ptr) int i; int out_coding; struct g72x_state *state_ptr; { short sezi, sei, sez, se; /* ACCUM */ short y; /* MIX */ short sr; /* ADDB */ short dq; short dqsez; i &= 0x07; /* mask to get proper bits */ sezi = predictor_zero(state_ptr); sez = sezi >> 1; sei = sezi + predictor_pole(state_ptr); se = sei >> 1; /* se = estimated signal */ y = step_size(state_ptr); /* adaptive quantizer step size */ dq = reconstruct(i & 0x04, _dqlntab[i], y); /* unquantize pred diff */ sr = (dq < 0) ? (se - (dq & 0x3FFF)) : (se + dq); /* reconst. signal */ dqsez = sr - se + sez; /* pole prediction diff. */ update(3, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr); switch (out_coding) { case AUDIO_ENCODING_ALAW: return (tandem_adjust_alaw(sr, se, y, i, 4, qtab_723_24)); case AUDIO_ENCODING_ULAW: return (tandem_adjust_ulaw(sr, se, y, i, 4, qtab_723_24)); case AUDIO_ENCODING_LINEAR: return (sr << 2); /* sr was of 14-bit dynamic range */ default: return (-1); } } rplay-3.3.2/adpcm/g723_40.c100644 153 62 12717 6552756453 13603 0ustar boynsstaff/* * This source code is a product of Sun Microsystems, Inc. and is provided * for unrestricted use. Users may copy or modify this source code without * charge. * * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun source code is provided with no support and without any obligation on * the part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ /* * g723_40.c * * Description: * * g723_40_encoder(), g723_40_decoder() * * These routines comprise an implementation of the CCITT G.723 40Kbps * ADPCM coding algorithm. Essentially, this implementation is identical to * the bit level description except for a few deviations which * take advantage of workstation attributes, such as hardware 2's * complement arithmetic. * * The deviation from the bit level specification (lookup tables), * preserves the bit level performance specifications. * * As outlined in the G.723 Recommendation, the algorithm is broken * down into modules. Each section of code below is preceded by * the name of the module which it is implementing. * */ #include "g72x.h" /* * Maps G.723_40 code word to ructeconstructed scale factor normalized log * magnitude values. */ static short _dqlntab[32] = {-2048, -66, 28, 104, 169, 224, 274, 318, 358, 395, 429, 459, 488, 514, 539, 566, 566, 539, 514, 488, 459, 429, 395, 358, 318, 274, 224, 169, 104, 28, -66, -2048}; /* Maps G.723_40 code word to log of scale factor multiplier. */ static short _witab[32] = {448, 448, 768, 1248, 1280, 1312, 1856, 3200, 4512, 5728, 7008, 8960, 11456, 14080, 16928, 22272, 22272, 16928, 14080, 11456, 8960, 7008, 5728, 4512, 3200, 1856, 1312, 1280, 1248, 768, 448, 448}; /* * Maps G.723_40 code words to a set of values whose long and short * term averages are computed and then compared to give an indication * how stationary (steady state) the signal is. */ static short _fitab[32] = {0, 0, 0, 0, 0, 0x200, 0x200, 0x200, 0x200, 0x200, 0x400, 0x600, 0x800, 0xA00, 0xC00, 0xC00, 0xC00, 0xC00, 0xA00, 0x800, 0x600, 0x400, 0x200, 0x200, 0x200, 0x200, 0x200, 0, 0, 0, 0, 0}; static short qtab_723_40[15] = {-122, -16, 68, 139, 198, 250, 298, 339, 378, 413, 445, 475, 502, 528, 553}; /* * g723_40_encoder() * * Encodes a 16-bit linear PCM, A-law or u-law input sample and retuens * the resulting 5-bit CCITT G.723 40Kbps code. * Returns -1 if the input coding value is invalid. */ int g723_40_encoder(sl, in_coding, state_ptr) int sl; int in_coding; struct g72x_state *state_ptr; { short sei, sezi, se, sez; /* ACCUM */ short d; /* SUBTA */ short y; /* MIX */ short sr; /* ADDB */ short dqsez; /* ADDC */ short dq, i; switch (in_coding) { /* linearize input sample to 14-bit PCM */ case AUDIO_ENCODING_ALAW: sl = alaw2linear(sl) >> 2; break; case AUDIO_ENCODING_ULAW: sl = ulaw2linear(sl) >> 2; break; case AUDIO_ENCODING_LINEAR: sl >>= 2; /* sl of 14-bit dynamic range */ break; default: return (-1); } sezi = predictor_zero(state_ptr); sez = sezi >> 1; sei = sezi + predictor_pole(state_ptr); se = sei >> 1; /* se = estimated signal */ d = sl - se; /* d = estimation difference */ /* quantize prediction difference */ y = step_size(state_ptr); /* adaptive quantizer step size */ i = quantize(d, y, qtab_723_40, 15); /* i = ADPCM code */ dq = reconstruct(i & 0x10, _dqlntab[i], y); /* quantized diff */ sr = (dq < 0) ? se - (dq & 0x7FFF) : se + dq; /* reconstructed signal */ dqsez = sr + sez - se; /* dqsez = pole prediction diff. */ update(5, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr); return (i); } /* * g723_40_decoder() * * Decodes a 5-bit CCITT G.723 40Kbps code and returns * the resulting 16-bit linear PCM, A-law or u-law sample value. * -1 is returned if the output coding is unknown. */ int g723_40_decoder(i, out_coding, state_ptr) int i; int out_coding; struct g72x_state *state_ptr; { short sezi, sei, sez, se; /* ACCUM */ short y, dif; /* MIX */ short sr; /* ADDB */ short dq; short dqsez; i &= 0x1f; /* mask to get proper bits */ sezi = predictor_zero(state_ptr); sez = sezi >> 1; sei = sezi + predictor_pole(state_ptr); se = sei >> 1; /* se = estimated signal */ y = step_size(state_ptr); /* adaptive quantizer step size */ dq = reconstruct(i & 0x10, _dqlntab[i], y); /* estimation diff. */ sr = (dq < 0) ? (se - (dq & 0x7FFF)) : (se + dq); /* reconst. signal */ dqsez = sr - se + sez; /* pole prediction diff. */ update(5, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr); switch (out_coding) { case AUDIO_ENCODING_ALAW: return (tandem_adjust_alaw(sr, se, y, i, 0x10, qtab_723_40)); case AUDIO_ENCODING_ULAW: return (tandem_adjust_ulaw(sr, se, y, i, 0x10, qtab_723_40)); case AUDIO_ENCODING_LINEAR: return (sr << 2); /* sr was of 14-bit dynamic range */ default: return (-1); } } rplay-3.3.2/adpcm/g72x.c100644 153 62 34410 6552756453 13377 0ustar boynsstaff/* * This source code is a product of Sun Microsystems, Inc. and is provided * for unrestricted use. Users may copy or modify this source code without * charge. * * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun source code is provided with no support and without any obligation on * the part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ /* * g72x.c * * Common routines for G.721 and G.723 conversions. */ #include "g72x.h" static short power2[15] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000}; /* * quan() * * quantizes the input val against the table of size short integers. * It returns i if table[i - 1] <= val < table[i]. * * Using linear search for simple coding. */ static int quan(val, table, size) int val; short *table; int size; { int i; for (i = 0; i < size; i++) if (val < *table++) break; return (i); } /* * fmult() * * returns the integer product of the 14-bit integer "an" and * "floating point" representation (4-bit exponent, 6-bit mantessa) "srn". */ static int fmult(an, srn) int an; int srn; { short anmag, anexp, anmant; short wanexp, wanmag, wanmant; short retval; anmag = (an > 0) ? an : ((-an) & 0x1FFF); anexp = quan(anmag, power2, 15) - 6; anmant = (anmag == 0) ? 32 : (anexp >= 0) ? anmag >> anexp : anmag << -anexp; wanexp = anexp + ((srn >> 6) & 0xF) - 13; wanmant = (anmant * (srn & 077) + 0x30) >> 4; retval = (wanexp >= 0) ? ((wanmant << wanexp) & 0x7FFF) : (wanmant >> -wanexp); return (((an ^ srn) < 0) ? -retval : retval); } /* * g72x_init_state() * * This routine initializes and/or resets the g72x_state structure * pointed to by 'state_ptr'. * All the initial state values are specified in the CCITT G.721 document. */ void g72x_init_state(state_ptr) struct g72x_state *state_ptr; { int cnta; state_ptr->yl = 34816; state_ptr->yu = 544; state_ptr->dms = 0; state_ptr->dml = 0; state_ptr->ap = 0; for (cnta = 0; cnta < 2; cnta++) { state_ptr->a[cnta] = 0; state_ptr->pk[cnta] = 0; state_ptr->sr[cnta] = 32; } for (cnta = 0; cnta < 6; cnta++) { state_ptr->b[cnta] = 0; state_ptr->dq[cnta] = 32; } state_ptr->td = 0; } /* * predictor_zero() * * computes the estimated signal from 6-zero predictor. * */ int predictor_zero(state_ptr) struct g72x_state *state_ptr; { int i; int sezi; sezi = fmult(state_ptr->b[0] >> 2, state_ptr->dq[0]); for (i = 1; i < 6; i++) /* ACCUM */ sezi += fmult(state_ptr->b[i] >> 2, state_ptr->dq[i]); return (sezi); } /* * predictor_pole() * * computes the estimated signal from 2-pole predictor. * */ int predictor_pole(state_ptr) struct g72x_state *state_ptr; { return (fmult(state_ptr->a[1] >> 2, state_ptr->sr[1]) + fmult(state_ptr->a[0] >> 2, state_ptr->sr[0])); } /* * step_size() * * computes the quantization step size of the adaptive quantizer. * */ int step_size(state_ptr) struct g72x_state *state_ptr; { int y; int dif; int al; if (state_ptr->ap >= 256) return (state_ptr->yu); else { y = state_ptr->yl >> 6; dif = state_ptr->yu - y; al = state_ptr->ap >> 2; if (dif > 0) y += (dif * al) >> 6; else if (dif < 0) y += (dif * al + 0x3F) >> 6; return (y); } } /* * quantize() * * Given a raw sample, 'd', of the difference signal and a * quantization step size scale factor, 'y', this routine returns the * ADPCM codeword to which that sample gets quantized. The step * size scale factor division operation is done in the log base 2 domain * as a subtraction. */ int quantize(d, y, table, size) int d; /* Raw difference signal sample */ int y; /* Step size multiplier */ short *table; /* quantization table */ int size; /* table size of short integers */ { short dqm; /* Magnitude of 'd' */ short exp; /* Integer part of base 2 log of 'd' */ short mant; /* Fractional part of base 2 log */ short dl; /* Log of magnitude of 'd' */ short dln; /* Step size scale factor normalized log */ int i; /* * LOG * * Compute base 2 log of 'd', and store in 'dl'. */ dqm = abs(d); exp = quan(dqm >> 1, power2, 15); mant = ((dqm << 7) >> exp) & 0x7F; /* Fractional portion. */ dl = (exp << 7) + mant; /* * SUBTB * * "Divide" by step size multiplier. */ dln = dl - (y >> 2); /* * QUAN * * Obtain codword i for 'd'. */ i = quan(dln, table, size); if (d < 0) /* take 1's complement of i */ return ((size << 1) + 1 - i); else if (i == 0) /* take 1's complement of 0 */ return ((size << 1) + 1); /* new in 1988 */ else return (i); } /* * reconstruct() * * Returns reconstructed difference signal 'dq' obtained from * codeword 'i' and quantization step size scale factor 'y'. * Multiplication is performed in log base 2 domain as addition. */ int reconstruct(sign, dqln, y) int sign; /* 0 for non-negative value */ int dqln; /* G.72x codeword */ int y; /* Step size multiplier */ { short dql; /* Log of 'dq' magnitude */ short dex; /* Integer part of log */ short dqt; short dq; /* Reconstructed difference signal sample */ dql = dqln + (y >> 2); /* ADDA */ if (dql < 0) { return ((sign) ? -0x8000 : 0); } else { /* ANTILOG */ dex = (dql >> 7) & 15; dqt = 128 + (dql & 127); dq = (dqt << 7) >> (14 - dex); return ((sign) ? (dq - 0x8000) : dq); } } /* * update() * * updates the state variables for each output code */ void update(code_size, y, wi, fi, dq, sr, dqsez, state_ptr) int code_size; /* distinguish 723_40 with others */ int y; /* quantizer step size */ int wi; /* scale factor multiplier */ int fi; /* for long/short term energies */ int dq; /* quantized prediction difference */ int sr; /* reconstructed signal */ int dqsez; /* difference from 2-pole predictor */ struct g72x_state *state_ptr; /* coder state pointer */ { int cnt; short mag, exp, mant; /* Adaptive predictor, FLOAT A */ short a2p; /* LIMC */ short a1ul; /* UPA1 */ short ua2, pks1; /* UPA2 */ short uga2a, fa1; short uga2b; char tr; /* tone/transition detector */ short ylint, thr2, dqthr; short ylfrac, thr1; short pk0; pk0 = (dqsez < 0) ? 1 : 0; /* needed in updating predictor poles */ mag = dq & 0x7FFF; /* prediction difference magnitude */ /* TRANS */ ylint = state_ptr->yl >> 15; /* exponent part of yl */ ylfrac = (state_ptr->yl >> 10) & 0x1F; /* fractional part of yl */ thr1 = (32 + ylfrac) << ylint; /* threshold */ thr2 = (ylint > 9) ? 31 << 10 : thr1; /* limit thr2 to 31 << 10 */ dqthr = (thr2 + (thr2 >> 1)) >> 1; /* dqthr = 0.75 * thr2 */ if (state_ptr->td == 0) /* signal supposed voice */ tr = 0; else if (mag <= dqthr) /* supposed data, but small mag */ tr = 0; /* treated as voice */ else /* signal is data (modem) */ tr = 1; /* * Quantizer scale factor adaptation. */ /* FUNCTW & FILTD & DELAY */ /* update non-steady state step size multiplier */ state_ptr->yu = y + ((wi - y) >> 5); /* LIMB */ if (state_ptr->yu < 544) /* 544 <= yu <= 5120 */ state_ptr->yu = 544; else if (state_ptr->yu > 5120) state_ptr->yu = 5120; /* FILTE & DELAY */ /* update steady state step size multiplier */ state_ptr->yl += state_ptr->yu + ((-state_ptr->yl) >> 6); /* * Adaptive predictor coefficients. */ if (tr == 1) { /* reset a's and b's for modem signal */ state_ptr->a[0] = 0; state_ptr->a[1] = 0; state_ptr->b[0] = 0; state_ptr->b[1] = 0; state_ptr->b[2] = 0; state_ptr->b[3] = 0; state_ptr->b[4] = 0; state_ptr->b[5] = 0; } else { /* update a's and b's */ pks1 = pk0 ^ state_ptr->pk[0]; /* UPA2 */ /* update predictor pole a[1] */ a2p = state_ptr->a[1] - (state_ptr->a[1] >> 7); if (dqsez != 0) { fa1 = (pks1) ? state_ptr->a[0] : -state_ptr->a[0]; if (fa1 < -8191) /* a2p = function of fa1 */ a2p -= 0x100; else if (fa1 > 8191) a2p += 0xFF; else a2p += fa1 >> 5; if (pk0 ^ state_ptr->pk[1]) /* LIMC */ if (a2p <= -12160) a2p = -12288; else if (a2p >= 12416) a2p = 12288; else a2p -= 0x80; else if (a2p <= -12416) a2p = -12288; else if (a2p >= 12160) a2p = 12288; else a2p += 0x80; } /* TRIGB & DELAY */ state_ptr->a[1] = a2p; /* UPA1 */ /* update predictor pole a[0] */ state_ptr->a[0] -= state_ptr->a[0] >> 8; if (dqsez != 0) if (pks1 == 0) state_ptr->a[0] += 192; else state_ptr->a[0] -= 192; /* LIMD */ a1ul = 15360 - a2p; if (state_ptr->a[0] < -a1ul) state_ptr->a[0] = -a1ul; else if (state_ptr->a[0] > a1ul) state_ptr->a[0] = a1ul; /* UPB : update predictor zeros b[6] */ for (cnt = 0; cnt < 6; cnt++) { if (code_size == 5) /* for 40Kbps G.723 */ state_ptr->b[cnt] -= state_ptr->b[cnt] >> 9; else /* for G.721 and 24Kbps G.723 */ state_ptr->b[cnt] -= state_ptr->b[cnt] >> 8; if (dq & 0x7FFF) { /* XOR */ if ((dq ^ state_ptr->dq[cnt]) >= 0) state_ptr->b[cnt] += 128; else state_ptr->b[cnt] -= 128; } } } for (cnt = 5; cnt > 0; cnt--) state_ptr->dq[cnt] = state_ptr->dq[cnt-1]; /* FLOAT A : convert dq[0] to 4-bit exp, 6-bit mantissa f.p. */ if (mag == 0) { state_ptr->dq[0] = (dq >= 0) ? 0x20 : 0xFC20; } else { exp = quan(mag, power2, 15); state_ptr->dq[0] = (dq >= 0) ? (exp << 6) + ((mag << 6) >> exp) : (exp << 6) + ((mag << 6) >> exp) - 0x400; } state_ptr->sr[1] = state_ptr->sr[0]; /* FLOAT B : convert sr to 4-bit exp., 6-bit mantissa f.p. */ if (sr == 0) { state_ptr->sr[0] = 0x20; } else if (sr > 0) { exp = quan(sr, power2, 15); state_ptr->sr[0] = (exp << 6) + ((sr << 6) >> exp); } else if (sr > -32768) { mag = -sr; exp = quan(mag, power2, 15); state_ptr->sr[0] = (exp << 6) + ((mag << 6) >> exp) - 0x400; } else state_ptr->sr[0] = 0xFC20; /* DELAY A */ state_ptr->pk[1] = state_ptr->pk[0]; state_ptr->pk[0] = pk0; /* TONE */ if (tr == 1) /* this sample has been treated as data */ state_ptr->td = 0; /* next one will be treated as voice */ else if (a2p < -11776) /* small sample-to-sample correlation */ state_ptr->td = 1; /* signal may be data */ else /* signal is voice */ state_ptr->td = 0; /* * Adaptation speed control. */ state_ptr->dms += (fi - state_ptr->dms) >> 5; /* FILTA */ state_ptr->dml += (((fi << 2) - state_ptr->dml) >> 7); /* FILTB */ if (tr == 1) state_ptr->ap = 256; else if (y < 1536) /* SUBTC */ state_ptr->ap += (0x200 - state_ptr->ap) >> 4; else if (state_ptr->td == 1) state_ptr->ap += (0x200 - state_ptr->ap) >> 4; else if (abs((state_ptr->dms << 2) - state_ptr->dml) >= (state_ptr->dml >> 3)) state_ptr->ap += (0x200 - state_ptr->ap) >> 4; else state_ptr->ap += (-state_ptr->ap) >> 4; } /* * tandem_adjust(sr, se, y, i, sign) * * At the end of ADPCM decoding, it simulates an encoder which may be receiving * the output of this decoder as a tandem process. If the output of the * simulated encoder differs from the input to this decoder, the decoder output * is adjusted by one level of A-law or u-law codes. * * Input: * sr decoder output linear PCM sample, * se predictor estimate sample, * y quantizer step size, * i decoder input code, * sign sign bit of code i * * Return: * adjusted A-law or u-law compressed sample. */ int tandem_adjust_alaw(sr, se, y, i, sign, qtab) int sr; /* decoder output linear PCM sample */ int se; /* predictor estimate sample */ int y; /* quantizer step size */ int i; /* decoder input code */ int sign; short *qtab; { unsigned char sp; /* A-law compressed 8-bit code */ short dx; /* prediction error */ char id; /* quantized prediction error */ int sd; /* adjusted A-law decoded sample value */ int im; /* biased magnitude of i */ int imx; /* biased magnitude of id */ if (sr <= -32768) sr = -1; sp = linear2alaw((sr >> 1) << 3); /* short to A-law compression */ dx = (alaw2linear(sp) >> 2) - se; /* 16-bit prediction error */ id = quantize(dx, y, qtab, sign - 1); if (id == i) { /* no adjustment on sp */ return (sp); } else { /* sp adjustment needed */ /* ADPCM codes : 8, 9, ... F, 0, 1, ... , 6, 7 */ im = i ^ sign; /* 2's complement to biased unsigned */ imx = id ^ sign; if (imx > im) { /* sp adjusted to next lower value */ if (sp & 0x80) { sd = (sp == 0xD5) ? 0x55 : ((sp ^ 0x55) - 1) ^ 0x55; } else { sd = (sp == 0x2A) ? 0x2A : ((sp ^ 0x55) + 1) ^ 0x55; } } else { /* sp adjusted to next higher value */ if (sp & 0x80) sd = (sp == 0xAA) ? 0xAA : ((sp ^ 0x55) + 1) ^ 0x55; else sd = (sp == 0x55) ? 0xD5 : ((sp ^ 0x55) - 1) ^ 0x55; } return (sd); } } int tandem_adjust_ulaw(sr, se, y, i, sign, qtab) int sr; /* decoder output linear PCM sample */ int se; /* predictor estimate sample */ int y; /* quantizer step size */ int i; /* decoder input code */ int sign; short *qtab; { unsigned char sp; /* u-law compressed 8-bit code */ short dx; /* prediction error */ char id; /* quantized prediction error */ int sd; /* adjusted u-law decoded sample value */ int im; /* biased magnitude of i */ int imx; /* biased magnitude of id */ if (sr <= -32768) sr = 0; sp = linear2ulaw(sr << 2); /* short to u-law compression */ dx = (ulaw2linear(sp) >> 2) - se; /* 16-bit prediction error */ id = quantize(dx, y, qtab, sign - 1); if (id == i) { return (sp); } else { /* ADPCM codes : 8, 9, ... F, 0, 1, ... , 6, 7 */ im = i ^ sign; /* 2's complement to biased unsigned */ imx = id ^ sign; if (imx > im) { /* sp adjusted to next lower value */ if (sp & 0x80) sd = (sp == 0xFF) ? 0x7E : sp + 1; else sd = (sp == 0) ? 0 : sp - 1; } else { /* sp adjusted to next higher value */ if (sp & 0x80) sd = (sp == 0x80) ? 0x80 : sp - 1; else sd = (sp == 0x7F) ? 0xFE : sp + 1; } return (sd); } } rplay-3.3.2/adpcm/g72x.h100644 153 62 6760 6552756453 13373 0ustar boynsstaff/* * This source code is a product of Sun Microsystems, Inc. and is provided * for unrestricted use. Users may copy or modify this source code without * charge. * * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun source code is provided with no support and without any obligation on * the part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ /* * g72x.h * * Header file for CCITT conversion routines. * */ #ifndef _G72X_H #define _G72X_H #define AUDIO_ENCODING_ULAW (1) /* ISDN u-law */ #define AUDIO_ENCODING_ALAW (2) /* ISDN A-law */ #define AUDIO_ENCODING_LINEAR (3) /* PCM 2's-complement (0-center) */ /* * The following is the definition of the state structure * used by the G.721/G.723 encoder and decoder to preserve their internal * state between successive calls. The meanings of the majority * of the state structure fields are explained in detail in the * CCITT Recommendation G.721. The field names are essentially indentical * to variable names in the bit level description of the coding algorithm * included in this Recommendation. */ struct g72x_state { long yl; /* Locked or steady state step size multiplier. */ short yu; /* Unlocked or non-steady state step size multiplier. */ short dms; /* Short term energy estimate. */ short dml; /* Long term energy estimate. */ short ap; /* Linear weighting coefficient of 'yl' and 'yu'. */ short a[2]; /* Coefficients of pole portion of prediction filter. */ short b[6]; /* Coefficients of zero portion of prediction filter. */ short pk[2]; /* * Signs of previous two samples of a partially * reconstructed signal. */ short dq[6]; /* * Previous 6 samples of the quantized difference * signal represented in an internal floating point * format. */ short sr[2]; /* * Previous 2 samples of the quantized difference * signal represented in an internal floating point * format. */ char td; /* delayed tone detect, new in 1988 version */ }; /* External function definitions. */ #ifdef __STDC__ extern void g72x_init_stat(struct g72x_state *); extern int g721_encoder( int sample, int in_coding, struct g72x_state *state_ptr); extern int g721_decoder( int code, int out_coding, struct g72x_state *state_ptr); extern int g723_24_encoder( int sample, int in_coding, struct g72x_state *state_ptr); extern int g723_24_decoder( int code, int out_coding, struct g72x_state *state_ptr); extern int g723_40_encoder( int sample, int in_coding, struct g72x_state *state_ptr); extern int g723_40_decoder( int code, int out_coding, struct g72x_state *state_ptr); #else extern void g72x_init_stat(); extern int g721_encoder(); extern int g721_decoder(); extern int g723_24_encoder(); extern int g723_24_decoder(); extern int g723_40_encoder(); extern int g723_40_decoder(); #endif #endif /* !_G72X_H */ rplay-3.3.2/adpcm/g72xdecode.1100644 153 62 740 6552756453 14420 0ustar boynsstaff.TH G72XDECODE 1 .SH NAME g72xdecode \- CCITT ADPCM decoder .SH SYNOPSIS .B g72xdecode [-3|4|5] [-a|u|l] < infile > outfile .SH DESCRIPTION CCITT ADPCM decoder .SH OPTIONS .nf -3 Process G.723 24kbps (3-bit) input data -4 Process G.721 32kbps (4-bit) input data [default] -5 Process G.723 40kbps (5-bit) input data -a Generate 8-bit A-law data -u Generate 8-bit u-law data [default] -l Generate 16-bit linear PCM data .SH SEE ALSO .IR g72xencode (1) rplay-3.3.2/adpcm/g72xencode.1100644 153 62 740 6552756453 14432 0ustar boynsstaff.TH G72XENCODE 1 .SH NAME g72xencode \- CCITT ADPCM encoder .SH SYNOPSIS .B g72xencode [-3|4|5] [-a|u|l] < infile > outfile .SH DESCRIPTION CCITT ADPCM encoder .SH OPTIONS .nf -3 Generate G.723 24kbps (3-bit) data -4 Generate G.721 32kbps (4-bit) data [default] -5 Generate G.723 40kbps (5-bit) data -a Process 8-bit A-law input data -u Process 8-bit u-law input data [default] -l Process 16-bit linear PCM input data .SH SEE ALSO .IR g72xdecode (1) rplay-3.3.2/contrib/ 40755 153 62 0 6727650075 12676 5ustar boynsstaffrplay-3.3.2/contrib/pos/ 40755 153 62 0 6727650074 13476 5ustar boynsstaffrplay-3.3.2/contrib/pos/Makefile100644 153 62 437 6552756453 15223 0ustar boynsstaffinclude ../../Makefile.config CPPFLAGS= $(CC_OPTIONS) -I../../include -I/usr/X11R6/include .c.o: $(CC) -c $(CPPFLAGS) $(CFLAGS) $< LDFLAGS= $(LD_OPTIONS) -L../../librplay -L/usr/X11R6/lib -lrplay -lforms -lXpm -lX11 -lm OBJS= pos.o pos: $(OBJS) $(CC) -o $@ $(OBJS) $(LDFLAGS) rplay-3.3.2/contrib/pos/pos.c100644 153 62 11252 6552756453 14565 0ustar boynsstaff/* * Copyright (C) 1995 Mark Boyns * * This file is part of rplay. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #define TITLE "" FL_FORM *form; FL_OBJECT *window, *slider; typedef struct { int id; char name[1024]; double position; double seconds; } SOUND; #define MAX_SOUNDS 12 SOUND sounds[MAX_SOUNDS]; #define SOUND_INIT(i)\ sounds[i].id = 0; \ sounds[i].name[0] = '\0'; \ sounds[i].position = 0; \ sounds[i].seconds = 0; double max_seconds = 0.0; void do_form (); void do_rptp (); void event_callback (int fd, int event, char *line); void set_title (char *title); main (int argc, char **argv) { #if 1 fl_flip_yorigin (); fl_initialize (&argc, argv, "POS", 0, 0); #else fl_initialize (argv[0], "??", 0, 0, &argc, argv); #endif do_form (); do_rptp (); rptp_main_loop (); } void do_form () { int i; #define W 300 #define H 50 form = fl_bgn_form (FL_NO_BOX, W, H); window = fl_add_box (FL_UP_BOX, 0, 0, W, H, ""); slider = fl_add_valslider (FL_HOR_FILL_SLIDER, 0, 0, W, H, ""); /* fl_set_object_align (slider, FL_ALIGN_LEFT); */ fl_set_object_color (slider, FL_COL1, FL_GREEN); fl_set_slider_bounds (slider, 0.0, 1.0); fl_set_slider_value (slider, 0.0); for (i = 0; i < MAX_SOUNDS; i++) { SOUND_INIT(i); } fl_end_form (); fl_show_form (form, FL_FREE_SIZE, FL_FULLBORDER, TITLE); fl_check_forms (); } void do_rptp () { char buf[RPTP_MAX_LINE]; int fd; fd = rptp_open (rplay_default_host (), RPTP_PORT, buf, sizeof (buf)); rptp_async_notify (fd, RPTP_EVENT_POSITION|RPTP_EVENT_PLAY|RPTP_EVENT_DONE|RPTP_EVENT_CLOSE, event_callback); rptp_async_putline (fd, NULL, "set notify-rate=1.0"); } void event_callback (int fd, int event, char *line) { FL_OBJECT *obj; double position, seconds; char *sec; char buf[RPTP_MAX_LINE]; int i, j, id, max_index; rptp_parse (line, 0); id = atoi (1 + rptp_parse (0, "id")); switch (event) { case RPTP_EVENT_PLAY: for (i = 0; i < MAX_SOUNDS; i++) { if (sounds[i].id == 0) { sscanf (rptp_parse (0, "seconds"), "%lf", &seconds); sounds[i].id = id; sounds[i].seconds = seconds; strcpy (sounds[i].name, rptp_parse (0, "sound")); if (seconds > max_seconds) { max_seconds = seconds; fl_set_slider_bounds (slider, 0.0, max_seconds); fl_set_slider_value (slider, 0.0); set_title (sounds[i].name); } break; } } break; case RPTP_EVENT_DONE: for (i = 0; i < MAX_SOUNDS; i++) { if (sounds[i].id == id && sounds[i].seconds == max_seconds) { max_seconds = 0.0; max_index = -1; for (j = 0; j < MAX_SOUNDS; j++) { if (j == i) { continue; } if (sounds[j].seconds > max_seconds) { max_seconds = sounds[j].seconds; max_index = j; } } if (max_index == -1) { fl_set_slider_bounds (slider, 0.0, 1.0); fl_set_slider_value (slider, 0.0); set_title (TITLE); } else { fl_set_slider_bounds (slider, 0.0, sounds[max_index].seconds); fl_set_slider_value (slider, sounds[max_index].position); set_title (sounds[max_index].name); } SOUND_INIT(i); break; } } break; case RPTP_EVENT_POSITION: for (i = 0; i < MAX_SOUNDS; i++) { if (sounds[i].id == id && sounds[i].seconds == max_seconds) { sscanf (rptp_parse (0, "position"), "%lf", &position); fl_set_slider_value (slider, position); break; } } break; case RPTP_EVENT_CLOSE: exit (1); } obj = fl_check_forms (); } void set_title (char *title) { XTextProperty windowName; XStringListToTextProperty(&title, 1, &windowName); XSetWMName(fl_display, form->window, &windowName); XFlush (fl_display); } rplay-3.3.2/contrib/README.crossfire100644 153 62 324 6552756452 15632 0ustar boynsstaff crossfire can be obtained via anonymous ftp a ifi.uio.no, look for the crossfire directory. You might also need to get the crossfire-0.89.2-sound-diffs.Z and the sound files until version 0.89.3 is released. rplay-3.3.2/contrib/mailnoise100755 153 62 6365 6552756452 14715 0ustar boynsstaff#!/usr/local/bin/perl # sub Usage { print <" where username is your username. USAGE exit 1; } # ---------------------------------------- # # uses the rptp command-line interface # Justin Mason 20/12/93. $RPTP_PATH = "/usr/local/bin"; # Where rptp(1) can be found # default values (in rplay(1) terms) $vol = 40; $pri = 0; # if someone has a display on these hosts, map it to somewhere # else that has an rplayd daemon. %mappings = ( "operation", "class", "stream", "class", "exception", "class" ); # you probably won't need to change this. $ENV{'PATH'} = "$RPTP_PATH:/usr/ucb:/usr/local/bin" . $ENV{'PATH'}; # end of config section ---------------------------- require 'newgetopt.pl'; &NGetOpt("user:s") || &Usage; &main; while (<>) { ; } # eat the input exit 0; sub gethost { $host = $DEFAULTHOST; $smallest = 9999; if ($opt_user eq '') { $home = $ENV{'HOME'} || $ENV{'LOGDIR'} || (getpwuid($<))[7] || die "You have no \$HOME!\n"; $user = $ENV{'USER'} || getlogin || (getpwuid($<))[0] || "someone"; } else { $user = $opt_user; $home = (getpwnam ($user))[7] || die "$user has no password entry!"; } if (-r "$home/.display") { open (H, "< $home/.display"); chop ($host = ); close H; } else { # assume that the least idle is on the user's display (er ;) open (RWHO, "rwho |"); while () { next unless /^${user}\s/; # username next unless ($' =~ /^\s+([^:]+):/); # hostname $h = $1; next unless /[A-Z][a-z][a-z] [ \d]\d \d\d:\d\d/; # date $_ = $'; # get the idle, if it exists if ($_ =~ /:/) { ($host = $h) if (($`*60 + $') < $smallest); } else { # not idle $host = $h; } } close RWHO; } $host; } sub main { $host = &gethost; if (-r "$home/.mailnoise") { open (N, "< $home/.mailnoise"); while () { tr/A-Z/a-z/; chop; s/^\s+//g; /^priority: / && ($pri = $'); /^host: / && ($host = $'); /^volume: / && ($vol = $'); /^noise: / && ($noise .= " $'"); } close N; } $noise =~ s/^ //; open (RPTP, "echo find \"$noise\" \| rptp 2>&1 |"); while () { /^$noise/ && $valid++; } close RPTP; if ($valid) { if ($host eq '') { # print STDERR "rplay -v $vol -P $pri ", $noise; system ("/usr/local/bin/rplay", "-v", $vol, "-P", $pri, $noise); } else { # print STDERR "rplay -h $host -v $vol -P $pri ", $noise; system ("/usr/local/bin/rplay", "-h", $host, "-v", $vol, "-P", $pri, $noise); } } } rplay-3.3.2/contrib/cdrplay/ 40755 153 62 0 6727650074 14333 5ustar boynsstaffrplay-3.3.2/contrib/cdrplay/cdrplay.c100644 153 62 21574 6671422216 16254 0ustar boynsstaff/* $Id: cdrplay.c,v 1.3 1999/03/10 07:51:42 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /* A lot of the CDDA code is based on read_cdda 1.01 by Jim Mintha (mintha@geog.ubc.ca) which seems to have borrowed code from Workman sources written by Steven Grimm (koreth@hyperion.com). */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_CDROM #include #include #include "rplayd.h" #include "cdrom.h" CDROM_TABLE cdrom_table[MAX_CDROMS] = { { "cdrom:", "/vol/dev/aliases/cdrom0", 0, 0 }, { "cdrom0:", "/vol/dev/aliases/cdrom0", 0, 0 }, { "cdrom1:", "/vol/dev/aliases/cdrom1", 0, 0 }, { "cdrom2:", "/vol/dev/aliases/cdrom2", 0, 0 }, { "cdrom3:", "/vol/dev/aliases/cdrom3", 0, 0 }, }; /* Internal prototypes. */ #ifdef HAVE_CDDA #ifdef __STDC__ static void cdda_cdrom_reader (CDROM_TABLE *cdt, int starting_track, int ending_track, int output_fd); #else static void cdda_cdrom_reader (/* CDROM_TABLE *cdt, int starting_track, int ending_track, int output_fd */); #endif #endif /* HAVE_CDDA */ /* starting_track and ending_track can be 0 which means first and last */ #ifdef __STDC__ void cdrom_reader (int index, int starting_track, int ending_track, int output_fd) #else void cdrom_reader (index, starting_track, ending_track, output_fd) int index; int starting_track; int ending_track; int output_fd; #endif { CDROM_TABLE *cdt; cdt = &cdrom_table[index]; report (REPORT_DEBUG, "cdrom_reader: %s%s tracks %d..%d\n", cdt->name, cdt->device, starting_track, ending_track); #ifdef HAVE_CDDA rplay_audio_close (); /* prevent device busy problems */ cdda_cdrom_reader (cdt, starting_track, ending_track, output_fd); #endif /* HAVE_CDDA */ /* Add more cdrom readers here. */ exit (0); } /******************************************************************************/ #ifdef HAVE_CDDA /* A nicer interface to reading from the CDDA interface using the CDDA_INFO structure and the cdda_open, cdda_read, and cdda_close routines. */ typedef struct { char *device; int starting_track; int ending_track; int num_blocks; int fd; char *buffer; int buffer_length; int starting_block; int current_block; int ending_block; } CDDA_INFO; #define CDDA_BLOCK_SIZE 2368 #define CDDA_BLOCK_IGNORE 16 static int cdda_open (CDDA_INFO *info); static int cdda_read (CDDA_INFO *info); static int cdda_close (CDDA_INFO *info); static int internal_cdda_init (CDDA_INFO *info); static int internal_cdda_read (CDDA_INFO *info); static int internal_cdda_toc (CDDA_INFO *info); #ifdef __STDC__ static void cdda_cdrom_reader (CDROM_TABLE *cdt, int starting_track, int ending_track, int output_fd) #else static void cdda_cdrom_reader (cdt, starting_track, ending_track, output_fd) CDROM_TABLE *cdt; int starting_track; int ending_track; int output_fd; #endif { CDDA_INFO info; int n, i; char *p; info.device = cdt->device; info.starting_track = starting_track; info.ending_track = ending_track; info.num_blocks = 30; info.fd = -1; info.buffer = NULL; if (cdda_open (&info) < 0) { return; } for (;;) { n = cdda_read (&info); if (n <= 0) { break; } p = info.buffer; for (i = 0; i < info.num_blocks; i++) { write (output_fd, p, CDDA_BLOCK_SIZE - CDDA_BLOCK_IGNORE); p += CDDA_BLOCK_SIZE; } } cdda_close (&info); } #ifdef __STDC__ static int cdda_open (CDDA_INFO *info) #else static int cdda_open (info) CDDA_INFO *info; #endif { if (info->fd < 0) { if (internal_cdda_init (info) < 0) { return -1; } } return internal_cdda_toc (info); } #ifdef __STDC__ static int cdda_read (CDDA_INFO *info) #else static int cdda_read (info) CDDA_INFO *info; #endif { int n; n = internal_cdda_read (info); if (n < 0) { return -1; } return n; } #ifdef __STDC__ static int cdda_close (CDDA_INFO *info) #else static int cdda_close (info) CDDA_INFO *info; #endif { close (info->fd); info->fd = -1; if (info->buffer) { free ((char *) info->buffer); } info->buffer = NULL; return 0; } /* End of nicer CDDA interface. */ #include #include #include #include #include #include #include #define CDDABLKSIZE 2368 #define SAMPLES_PER_BLK 588 #ifdef __STDC__ static int internal_cdda_init (CDDA_INFO *info) #else static int internal_cdda_init (info) CDDA_INFO *info; #endif { struct cdrom_cdda cdda; info->fd = open (info->device, 0); if (info->fd < 0) { perror (info->device); return -1; } info->buffer = (char *) malloc (info->num_blocks * CDDABLKSIZE + CDDABLKSIZE); if (info->buffer == NULL) { fprintf (stderr, "malloc: out of memory\n"); return -1; } info->buffer_length = info->num_blocks * CDDABLKSIZE; cdda.cdda_addr = 200; cdda.cdda_length = 1; cdda.cdda_data = info->buffer; cdda.cdda_subcode = CDROM_DA_SUBQ; if (ioctl (info->fd, CDROMCDDA, &cdda) < 0) { perror ("ioctl: CDROMCDDA"); free ((char *) info->buffer); info->buffer = NULL; close (info->fd); return -1; } return 0; } #ifdef __STDC__ static int internal_cdda_read (CDDA_INFO *info) #else static int internal_cdda_read (info) CDDA_INFO *info; #endif { struct cdrom_cdda cdda; int blk; unsigned char *q; if (info->current_block >= info->ending_block) { return 0; } cdda.cdda_addr = info->current_block; if (info->current_block + info->num_blocks > info->ending_block) { cdda.cdda_length = info->ending_block - info->current_block; } else { cdda.cdda_length = info->num_blocks; } cdda.cdda_data = info->buffer; cdda.cdda_subcode = CDROM_DA_SUBQ; if (ioctl (info->fd, CDROMCDDA, &cdda) < 0) { if (errno == ENXIO) { perror ("ioctl: CDROMCDDA: CD ejected"); return -1; } if (info->current_block + info->num_blocks > info->ending_block) { return 0; } if (ioctl (info->fd, CDROMCDDA, &cdda) < 0) { if (ioctl (info->fd, CDROMCDDA, &cdda) < 0) { if (ioctl (info->fd, CDROMCDDA, &cdda) < 0) { perror ("ioctl: CDROMCDDA"); return -1; } } } } info->current_block += cdda.cdda_length; return cdda.cdda_length * CDDABLKSIZE; } #ifdef __STDC__ static int internal_cdda_toc (CDDA_INFO *info) #else static int internal_cdda_toc (info) CDDA_INFO *info; #endif { struct cdrom_tochdr hdr; struct cdrom_tocentry entry; int i; if (ioctl (info->fd, CDROMREADTOCHDR, &hdr) < 0) { perror ("ioctl: CDROMREADTOCHDR"); return -1; } info->starting_block = 0; info->ending_block = 0; if (info->starting_track == 0) { info->starting_track = hdr.cdth_trk0; } if (info->ending_track == 0) { info->ending_track = hdr.cdth_trk1; } for (i = 1; i <= hdr.cdth_trk1; i++) { entry.cdte_track = i; entry.cdte_format = CDROM_MSF; if (ioctl (info->fd, CDROMREADTOCENTRY, &entry) < 0) { perror ("ioctl: CDROMREADTOCENTRY"); return -1; } if (i == info->starting_track) { info->starting_block = entry.cdte_addr.msf.minute * 60 * 75 + entry.cdte_addr.msf.second * 75 + entry.cdte_addr.msf.frame; } if (i == info->ending_track + 1) { info->ending_block = entry.cdte_addr.msf.minute * 60 * 75 + entry.cdte_addr.msf.second * 75 + entry.cdte_addr.msf.frame; } } entry.cdte_track = CDROM_LEADOUT; entry.cdte_format = CDROM_MSF; if (ioctl (info->fd, CDROMREADTOCENTRY, &entry) < 0) { perror ("ioctl: CDROMREADTOCENTRY"); return -1; } if (info->ending_block == 0) { info->ending_block = entry.cdte_addr.msf.minute * 60 * 75 + entry.cdte_addr.msf.second * 75 + entry.cdte_addr.msf.frame; } /* Move back two seconds - don't know why but works */ info->starting_block -= 150; info->ending_block -= 150; info->current_block = info->starting_block; return 0; } #endif /* HAVE_CDDA */ /******************************************************************************/ #endif /* HAVE_CDROM */ rplay-3.3.2/contrib/fingergoodies/ 40755 153 62 0 6727650074 15521 5ustar boynsstaffrplay-3.3.2/contrib/fingergoodies/.fingerrc100644 153 62 2670 6552756453 17427 0ustar boynsstaff#/bin/csh -f echo "Hack-O-Matic Consulting Services, Inc." echo "Please wait... Scanning database bogus1194-91..." if [ "`/usr/ucb/whoami`" = "quinet" ] then /bin/sed -e "s/Plan:/Address:/g" | grep -v "GNU Finger" echo "Local time: `date`" echo "Local weather: `/usr/local/ulg/bin/random 'ask Meteosat ..' 'nice for Belgium' 'cloudy' 'better than yesterday' 'better than tomorrow' 'it cannot be worse'`." echo "Current location: `/usr/local/ulg/bin/random 'guess ..' 'far away from home' 'lost in my programs' 'trapped somewhere in a CrossFire map' 'here'`." echo "Most useless host: `/usr/local/ulg/bin/getcalleraddr -stderr`." echo "Best finger: `/usr/local/ulg/bin/random 'thumb' 'index finger' 'middle finger' 'ring finger' 'little finger' 'GNU finger (lots of nice features)'`." echo " " echo "I have received a lot of mail lately. (I will reply later... Be patient.)" echo "Current size of my mailbox: `ls -l /usr/spool/mail/quinet | cut -c 23-`" echo " " echo "Zippy the Pinhead says:" /usr/local/bin/yow echo "`/bin/date` - Finger from `/usr/local/ulg/bin/getcalleraddr -stderr` to `hostname`" >> .fingerlog /usr/local/bin/rplay -h verif1 police.au /usr/local/bin/rplay -h "`/usr/local/ulg/bin/getcalleraddr -stderr`" ohyeah.au else echo "Warning: cryptographic integrity check failed!" /bin/mv -f .fingerrc .fingerrc.quinet /bin/mv -f .plan .plan.quinet /bin/mv -f .project .project.quinet echo "Try again..." fi rplay-3.3.2/contrib/fingergoodies/getcalleraddr.c100644 153 62 3124 6552756453 20563 0ustar boynsstaff/* getcalleraddr.c Prints the address of the host that is using this program through a socket. Useful in a remote shell or in a ".fingerrc" file... [Raphael Quinet, 09 Feb 94] */ #include #include #include #include #include #include #include #include char *getcallername(s) int s; { struct sockaddr_in addr; int addrlen; struct hostent *hp; addrlen = sizeof(struct sockaddr); if (getpeername(s, (struct sockaddr *)&addr, &addrlen) > -1) { hp = gethostbyaddr(addr.sin_addr, addrlen, AF_INET); if (hp != NULL) return hp->h_name; else return inet_ntoa(addr.sin_addr); } return NULL; } void main(argc, argv) int argc; char *argv[]; { char *prog_name; int socket_num; char *caller_name; prog_name = *argv++; socket_num = fileno(stdout); for (argc--; argc; argv++, argc--) if (!strcmp(*argv, "-stdin")) socket_num = fileno(stdin); else if (!strcmp(*argv, "-stdout")) socket_num = fileno(stdout); else if (!strcmp(*argv, "-stderr")) socket_num = fileno(stderr); else { if (strcmp(*argv, "-help") && strcmp(*argv, "-h")) printf("Error: invalid option %s\n", *argv); printf("Usage: rsh %s [-stdin | -stdout | -stderr]\n", prog_name); exit(-1); } caller_name = getcallername(socket_num); if (caller_name) { printf("%s\n", caller_name); exit(0); } else { printf("Error: no socket\n"); exit(1); } } rplay-3.3.2/contrib/fingergoodies/random.c100644 153 62 354 6552756453 17230 0ustar boynsstaff/* random.c This program randomly picks one of its command line arguments and prints it. [Raphael Quinet, 07 Feb 92, 13 May 93] */ main(v,c)char**c;{srandom((int)time(!++c)*getpid());v-->1?printf("%s\n",c[random()%v]):(int)v;} rplay-3.3.2/contrib/jukebox-1.3/ 40755 153 62 0 6727650074 14643 5ustar boynsstaffrplay-3.3.2/contrib/jukebox-1.3/man1/ 40755 153 62 0 6727650074 15477 5ustar boynsstaffrplay-3.3.2/contrib/jukebox-1.3/man1/jukebox.1100644 153 62 10365 6552756453 17356 0ustar boynsstaff.TH JUKEBOX 1 "27 August 1993" .SH NAME jukebox \- play a list of sounds (songs) .SH SYNOPSIS .B jukebox [-afhlqrsv] [directory\.\.\.] .SH DESCRIPTION Jukebox is a small program that plays a list of songs on the host of your choice, using Mark Boyns' .B rplay library. This allows you to listen to some background music while you are working or doing anything else. There are two ways to build a list of songs : you may use the .B \-f option followed by a file name which contains a list of song names (like rplay.conf), or you may simply give the name of a directory. All the \.au files in this directory will be added to the list. While the jukebox is playing, you may skip a song with .I Ctrl\-C. This will stop the current song and play the next one. You may also use .I Ctrl\-Z, which will stop both the current song and the jukebox. Once the jukebox has been stopped with a .I Ctrl\-Z, you may continue with the next song : use .B fg or whatever your shell needs to restart a stopped process. If you want to terminate the process, use .B kill XXX or .B kill \-HUP XXX, where XXX is the process number of the jukebox. .SH OPTIONS .TP .B \-h hostname[:hostname\.\.\.] Play sounds on this or all of these hosts. This option will override the default host defined by the .B RPLAY_HOST environment variable. .TP .B \-f Take a list of sounds from the file .B . This file should contain one sound name per line. You may supply several lists of songs, each one preceded by the \-f flag. .TP .B \-l Loop mode. The jukebox will keep on playing until stopped with a Ctrl-Z or another signal. .TP .B \-a Play the songs in alphabetical order (file names). This might be useful if the file names begin with the name of the artist or group, for example. .TP .B \-r Play the songs in a random order. If the jukebox is in loop mode, a new list (in a different order) will be created each time the jukebox reaches the last song. .TP .B \-q Quiet mode. Suppresses output except for error messages. .TP .B \-s Sleep between songs ( .B is in milliseconds and may be negative). If you give a negative number, the two songs will be superimposed. You may use this option to create a "fade in / fade out" effect (see examples below). .TP .B \-v Change the default play volume. .SH EXAMPLES .LP Suppose you have several directories named "songs/XXX", where "XXX" is the name of some artist or group. If you want to play some music on "verif1" (replace this with the name of your host), you might type something like this : .IP .B "jukebox -h verif1 -r -s -4000 songs/*" .PP This will play all the songs from these directories, taken in a random order. There is also a "negative delay" of 4 seconds. If all the songs begin with a "fade in" and end with a "fade out", you will get a pretty good effect. If you want to play your favourite songs over and over on the default host, you could type : .IP .B "jukebox -l -q songs/kate_bush songs/queen songs/rem ..." .PP (By the way, it is simpler to go in the "songs" directory to type these commands as the paths would be shorter, but this is only an example). Here, the .B \-q option is used to suppress all normal output. You can then use the jukebox as a background job if you are short of terminals. You may also put the names of your favorite songs in a file, and use this file with the .B \-f option. You may even create several files and use them in any order, like this : .IP .B "jukebox -f rock_n_roll -f pop_music songs/rap ..." .PP In this example, the songs are taken from the files "rock_n_roll" and "pop_music", but also from the directory "songs/rap". .SH "SEE ALSO" .BR rplay (1), .BR rplayd (1), .BR rplay.conf (5) .SH AUTHOR This program was written by Raphael Quinet (University of Liege, Belgium) He can be reached by E-mail as follows: .RS .B quinet@montefiore.ULg.ac.Be .RE The .B jukebox program makes use of Mark Boyns' .B rplay package which can play multiple sounds on remote machines. .br He can be reached by E-mail as follows: .RS .B boyns@SDSU.edu .RE .SH BUGS You have to supply the full pathnames in the sound lists. The program's timer doesn't expect the sounds to be delayed in any way while they are playing. This leads to disastrous effects if the song has to be fetched from another server or if someone pauses the audio device. rplay-3.3.2/contrib/jukebox-1.3/Makefile100644 153 62 2027 6552756453 16405 0ustar boynsstaff# # Makefile for JUKEBOX 1.3 # (C) 1993 Raphael Quinet (quinet@montefiore.ulg.ac.be) # # NOTE : you should "make" this program *before* you "make clean" in the # main rplay directory ("../.."). #include include ../../Makefile.config LIBRPLAY_DIR= ../../librplay INCLUDE_DIR= ../../include TARGET= jukebox SRCS = jukebox.c OBJS = jukebox.o all: $(TARGET) $(TARGET): $(OBJS) $(CC) $(CFLAGS) -o $@ $(OBJS) $(LDFLAGS) install: $(TARGET) @echo Installing $(TARGET) in $(INSTALL_BIN_DIR) $(BIN_INSTALL) $(TARGET) $(INSTALL_BIN_DIR) install.man: @echo Installing the man page in $(INSTALL_BIN_DIR) $(INSTALL) man1/$(TARGET).1 $(INSTALL_MAN_DIR)/man1 chmod a+r $(INSTALL_MAN_DIR)/man1/$(TARGET).1 world: all install install.man clean: $(RM) $(TARGET) $(OBJS) core a.out *~ *.bak man1/*.bak man1/*~ depend: $(MAKEDEPEND) -- $(CFLAGS) -- $(SRCS) tar: clean (cd .. ; tar -cvf $(TARGET).tar $(TARGET) ; gzip -9 $(TARGET).tar ) zip: clean (cd .. ; zip -9 -o -y -r $(TARGET).zip $(TARGET) ) rplay-3.3.2/contrib/jukebox-1.3/jukebox.c100644 153 62 35602 6552756453 16605 0ustar boynsstaff/* * Copyright (c) 1993 by Raphael Quinet (quinet@montefiore.ulg.ac.be) * Bits of code from "rplay.c" : Copyright (c) 1992-93 by Mark Boyns * (boyns@sdsu.edu) * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation. This software is provided "as is" without express or * implied warranty. */ /* * Thanks to Mark Boyns and R.K.Lloyd@csc.liv.ac.uk for their comments and * bug fixes. * * If you make any useful changes/improvements/bug fixes to this program, * please send them to me (quinet@montefiore.ulg.ac.be) and they will be * included in the next version of this program. */ static char *jukebox_version = "JUKEBOX 1.3"; #include #include #include #include #include #include #include #include #include #include extern char *optarg; extern int optind; /* Structure used in the "songs" table. */ typedef struct { int idx; char *name; int length; } song; /* Global variables. */ song *songs; int nsongs = 0; char *progname; int stop_song = 0; unsigned long total_time = 0; int opt_quiet; /***************************************************************************** * usage() * *---------------------------------------------------------------------------* * Displays a help message. * *****************************************************************************/ usage() { printf("\n%s - Copyright (c) 1993 by Raphael Quinet (quinet@montefiore.ulg.ac.be)\n\n", jukebox_version); printf("usage: %s [options] [directory ...]\n", progname); printf("\t-a\tplay songs in alphabetical order (file names)\n"); printf("\t-f name\tload the list of songs from a file\n"); printf("\t-h host\tuse this instead of the default host (%s)\n", rplay_default_host()); printf("\t-l\tloop mode - no exit\n"); printf("\t-q\tquiet - only error messages\n"); printf("\t-r\tplay songs in a random order\n"); printf("\t-s n\tsleep n milliseconds between songs (n may be negative)\n"); printf("\t-v n\tvolume n (%d <= n <= %d), default = %d\n", RPLAY_MIN_VOLUME, RPLAY_MAX_VOLUME, RPLAY_DEFAULT_VOLUME); printf("No options will play all songs (*.au) from the current\n"); printf("directory at the default volume\n\n"); exit(1); } /***************************************************************************** * set_timer() * *---------------------------------------------------------------------------* * Sets the real-time timer to "msec" milliseconds. A SIGALRM signal is * * delivered when this timer expires. * *****************************************************************************/ #ifdef __STDC__ set_timer(int msec) #else set_timer(msec) int msec; #endif { struct itimerval it; it.it_value.tv_sec = msec / 1000; it.it_value.tv_usec = (msec % 1000) * 1000; it.it_interval.tv_sec = 0; it.it_interval.tv_usec = 0; setitimer(ITIMER_REAL, &it, (struct itimerval *)0); } /***************************************************************************** * catch_sigtstp() * *---------------------------------------------------------------------------* * SIGTSTP handler : If the user wants to stop the jukebox (Ctrl-Z). * *****************************************************************************/ catch_sigtstp() { signal(SIGTSTP, catch_sigtstp); stop_song = 2; /* Stop current song and call the default SIGTSTP handler. */ } /***************************************************************************** * catch_sigint() * *---------------------------------------------------------------------------* * SIGINT handler : If the user wants another song (Ctrl-C). * *****************************************************************************/ catch_sigint() { signal(SIGINT, catch_sigint); stop_song = 1; /* Stop current song and play the next one. */ } /***************************************************************************** * catch_sigalrm() * *---------------------------------------------------------------------------* * SIGALRM handler : It's time to play the next song... * *****************************************************************************/ catch_sigalrm() { signal(SIGALRM, catch_sigalrm); stop_song = 0; /* Play the next song. */ } /***************************************************************************** * readsongs(char *dirname) * *---------------------------------------------------------------------------* * Looks for "*.au" files in the "dirname" directory and stores the names * * and lengths of the files in the "songs" table. * *****************************************************************************/ #ifdef __STDC__ readsongs(char *dirname) #else readsongs(dirname) char *dirname; #endif { DIR *dirp; struct dirent *dp; struct stat statbuf; char filename[MAXPATHLEN]; strcpy(filename, dirname); strcat(filename, "/"); dirp = opendir(dirname); if (dirp == NULL) { fprintf(stderr, "%s: can't open directory %s\n", progname, dirname); exit(1); } for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) if ((strlen(dp->d_name) > 3) && !strcmp(dp->d_name + strlen(dp->d_name) - 3, ".au")) { /* "stat()" needs the full path to the files, so it is built in * the "filename" buffer. As "rplayd" doesn't need the paths, only * the file name is stored in the "songs" table. */ strcat(filename, dp->d_name); if (stat(filename, &statbuf) == -1) { if (!opt_quiet) fprintf(stderr, "%s warning: can't stat %s\n", progname, filename); continue; } filename[strlen(filename) - dp->d_namlen] = '\0'; if (nsongs == 0) songs = (song *)malloc(sizeof(song) * ++nsongs); else songs = (song *)realloc(songs, sizeof(song) * ++nsongs); if (songs == NULL) { fprintf(stderr, "%s: out of memory\n", progname); exit(1); } songs[nsongs - 1].name = (char *)malloc(dp->d_namlen + 1); if (songs[nsongs - 1].name == NULL) { fprintf(stderr, "%s: out of memory\n", progname); exit(1); } strcpy(songs[nsongs - 1].name, dp->d_name); songs[nsongs - 1].length = statbuf.st_size / 8 - 10; total_time += songs[nsongs - 1].length; } closedir (dirp); } /***************************************************************************** * readlist(char *listname) * *---------------------------------------------------------------------------* * Reads a list of songs from the file "listname". * *****************************************************************************/ #ifdef __STDC__ readlist(char *listname) #else readlist(listname) char *listname; #endif { FILE *fp; struct stat statbuf; char buf[MAXPATHLEN], filename[MAXPATHLEN], *s; fp = fopen(listname, "r"); if (fp == NULL) { fprintf(stderr, "%s: cannot open %s\n", progname, listname); exit(1); } while (fgets(buf, sizeof(buf), fp) != NULL) { switch (buf[0]) { case '#': case ' ': case '\t': case '\n': continue; } sscanf(buf, "%[^\n]", filename); if (stat(filename, &statbuf) == -1) { if (!opt_quiet) fprintf(stderr, "%s warning: can't stat %s\n", progname, filename); continue; } if (nsongs == 0) songs = (song *)malloc(sizeof(song) * ++nsongs); else songs = (song *)realloc(songs, sizeof(song) * ++nsongs); if (songs == NULL) { fprintf(stderr, "%s: out of memory\n", progname); exit(1); } if (s = (char *)strrchr(filename, '/')) s++; else s = filename; songs[nsongs - 1].name = (char *)malloc(strlen(s) + 1); if (songs[nsongs - 1].name == NULL) { fprintf(stderr, "%s: out of memory\n", progname); exit(1); } strcpy(songs[nsongs - 1].name, s); songs[nsongs - 1].length = statbuf.st_size / 8 - 10; total_time += songs[nsongs - 1].length; } fclose(fp); } /***************************************************************************** * idxcompare(song *i, song *j) * *---------------------------------------------------------------------------* * Compares two song's indexes (used by "qsort()" - random order). * *****************************************************************************/ #ifdef __STDC__ idxcompare(song *i, song *j) #else idxcompare(i,j) song *i, *j; #endif { return (i->idx - j->idx); } /***************************************************************************** * alphacompare(song *i, song *j) * *---------------------------------------------------------------------------* * Compares two song's names (used by "qsort()" - alphabetical order). * *****************************************************************************/ #ifdef __STDC__ alphacompare(song *i, song *j) #else alphacompare(i,j) song *i, *j; #endif { return strcmp(i->name, j->name); } /***************************************************************************** * main(int argc, char **argv) * *---------------------------------------------------------------------------* * Come on, don't tell me that you don't know why I wrote a function named * * "main()" ! My compiler told me it was really useful... * *****************************************************************************/ #ifdef __STDC__ main(int argc, char **argv) #else main(argc, argv) int argc; char **argv; #endif { int rplay_fd, c, i; int opt_volume, opt_sleep, opt_loop, opt_random, opt_sort; char *host; RPLAY *rpp, *rps; if (progname = (char *)strrchr(*argv, '/')) progname++; else progname = *argv; host = rplay_default_host(); opt_loop = 0; opt_quiet = 0; opt_random = 0; opt_sort = 0; opt_sleep = 0; opt_volume = RPLAY_DEFAULT_VOLUME; while ((c = getopt(argc, argv, "af:h:lqrs:v:")) != -1) { switch(c) { case 'a': if (opt_random && !opt_quiet) fprintf(stderr, "%s warning: option -a overrides previous option -r\n", progname); opt_sort = 1; break; case 'f': readlist(optarg); break; case 'h': host = optarg; if (host[0] == '-') usage(); break; case 'l': opt_loop = 1; break; case 'q': opt_quiet = 1; break; case 'r': if (opt_sort && !opt_quiet) fprintf(stderr, "%s warning: option -r overrides previous option -a\n", progname); opt_random = 1; srandom(getpid()); break; case 's': opt_sleep = atoi(optarg); break; case 'v': opt_volume = atoi(optarg); default: usage(); exit(1); } } if (argc == optind) readsongs("."); else while (optind < argc) readsongs(argv[optind++]); if (nsongs == 0) { fprintf(stderr, "%s: no songs (*.au) to play\n", progname); exit(1); } rplay_fd = rplay_open(host); if (rplay_fd < 0) { rplay_perror(host); exit(1); } rpp = rplay_create(RPLAY_PLAY); if (rpp == NULL) { rplay_perror("rplay_create"); exit(1); } c = rplay_set(rpp, RPLAY_APPEND, RPLAY_SOUND, "", RPLAY_VOLUME, opt_volume, NULL); if (c < 0) { rplay_perror("rplay_set"); exit(1); } rps = rplay_create(RPLAY_STOP); if (rps == NULL) { rplay_perror("rplay_create"); exit(1); } c = rplay_set(rps, RPLAY_APPEND, RPLAY_SOUND, "", NULL); if (c < 0) { rplay_perror("rplay_set"); exit(1); } /* Use Ctrl-Z (SIGTSTP) if you want to stop the program then send a SIGTERM * or SIGHUP if you want to kill it. Ctrl-C (SIGINT) will only stop the * current song and play the next one. */ signal(SIGINT, catch_sigint); signal(SIGTSTP, catch_sigtstp); signal(SIGALRM, catch_sigalrm); if (!opt_quiet) { printf("\n%s - Welcome !\n\n", jukebox_version); printf("I will play %d songs just for you.\n", nsongs); if (opt_sleep) printf("(Estimated total time : %lu%+ld seconds).\n\n", total_time / 1000L, ((long)opt_sleep * (long)nsongs) / 1000L); else printf("(Estimated total time : %lu seconds).\n\n", total_time / 1000L); } if (opt_sort) qsort((char *)songs, nsongs, sizeof(song), alphacompare); do { if (opt_random) { if (!opt_quiet && opt_loop) printf("Building random list ...\n\n"); for (i = 0; i < nsongs; i++) songs[i].idx = (int)random(); qsort((char *)songs, nsongs, sizeof(song), idxcompare); } for (i = 0; i < nsongs; i++) { if (!opt_quiet) { if (opt_sleep) printf("Playing %s ... (%d%+d seconds)\n", songs[i].name, songs[i].length / 1000, opt_sleep / 1000); else printf("Playing %s ... (%d seconds)\n", songs[i].name, songs[i].length / 1000); } c = rplay_set(rpp, RPLAY_CHANGE, 0, RPLAY_SOUND, songs[i].name, NULL); if (c < 0) { rplay_perror("rplay_set"); exit(1); } if (rplay(rplay_fd, rpp) < 0) { rplay_perror(host); exit(1); } if (songs[i].length + opt_sleep > 100) set_timer(songs[i].length + opt_sleep); else set_timer(100); /* Wait until the next signal. This may be a SIGALRM delivered * by the timer (just play the next song) or another signal from * the user (stop the current song). */ pause(); if (stop_song != 0) /* Stop the current song. */ { if (!opt_quiet) printf(" Ouch !\n"); c = rplay_set(rps, RPLAY_CHANGE, 0, RPLAY_SOUND, songs[i].name, NULL); if (c < 0) { rplay_perror("rplay_set"); exit(1); } if (rplay(rplay_fd, rps) < 0) { rplay_perror(host); exit(1); } if (stop_song == 2) /* And stop the jukebox too. */ { signal(SIGTSTP, SIG_DFL); kill(getpid(), SIGTSTP); /* Stop now ! */ if (!opt_quiet) printf("\nI still have %d songs to play.\n", nsongs - i - 1); signal(SIGTSTP, catch_sigtstp); } } } } while (opt_loop > 0); if (!opt_quiet) printf("\nPlease insert coins to play another song.\n"); rplay_close(rplay_fd); exit(0); } rplay-3.3.2/contrib/mailsound/ 40755 153 62 0 6727650074 14670 5ustar boynsstaffrplay-3.3.2/contrib/mailsound/Makefile100644 153 62 355 6552756452 16413 0ustar boynsstaffinclude ../../Makefile.config CPPFLAGS= $(CC_OPTIONS) -I../../include .c.o: $(CC) -c $(CPPFLAGS) $(CFLAGS) $< LDFLAGS= $(LD_OPTIONS) -L../../librplay -lrplay OBJS= mailsound.o mailsound: $(OBJS) $(CC) -o $@ $(OBJS) $(LDFLAGS) rplay-3.3.2/contrib/mailsound/mailsound.1100644 153 62 6705 6552756453 17056 0ustar boynsstaff.TH MAILSOUND 1 "11 August 1993" .SH NAME mailsound \- play sounds when mail is received .SH SYNOPSIS .B mailsound [-hszZvrd] soundname \.\.\. .SH DESCRIPTION mailsound allows a user to play sounds when new mail arrives. It reads a mail message from stdin and uses Mark Boyns' .B rplay library to play sounds. The sound that is played is determined by a configuration file in the user's home directory called .B .mailsounds. Each line in this file has two parts. The first part is a regular expression which will be used to match the from address from a mail message. The second part describes what to do when a match is found. The options in the second part are identical to the options on the command line. The command line options will set defaults which will be used if they are not specified in the configuration file. .br If not specified, the .B mailsound program will use the following defaults: .IP default sound: youvegotmail.au .br default volume: 127 (50%) .RE If the mail address does not match any of the regular expressions in the .B .mailsounds file, no sound will be played. .SH OPTIONS .TP .B \-h hostname:[hostname\.\.\.] Play sounds on all of these hosts. .TP .B \-z :,: The volume the sound will be played at will be determined by the size of the mail message. The sound for a message with a size smaller than .B will be played at volume .B . The sound for a message with a size larger than .B will be played at volume .B . The sound for a message with a size between .B and .B will be played at a volume which is a linear interpolation between .B and .B . .TP .B \-Z , The sound to be played is determined by the size of the mail message. If the message is smaller than .B , the first listed sound is played. If the message is larger than .B , the last listed sound is played. If the message size is between those two values, the appropriate sound from the list is played. .TP .B \-s The regular expression supplied will have to match the subject of the message. If this option is not there, the subject of the message is completely ignored. Be careful that the regular expression does not contain spaces. Due to laziness of the author of this program, this will hopelessly confuse the program. .TP .B \-v Set the volume at which the sound should be played. The range is 0-255. .TP .B \-r Pick a sound at random from the list of sounds provided. .TP .B \-d Turn on debugging. This will produce diagnostic output to stdout. .SH EXAMPLE .LP The following could appear in the .forward file in your home directory: (This assumes that your username is pickard) .IP \\pickard, |"/usr/local/bin/mailsound" .LP Here is a sample $HOME/.mailsounds file: .IP .nf Andrew.* -r Passing_Train riot arrp flinstones root.* out! daemon.* -v 220 sci_fi_fun MAILER.* -S 1000,10000 cuckoo pig Oomph *. pigs .fi .SH FILES $HOME/.mailsounds .SH "SEE ALSO" .BR rplay.conf (5), .BR rplayd (1) .SH AUTHOR This program was written by Andrew Scherpbier at San Diego State University. He can be reached by E-mail as follows: .RS .B Andrew@SDSU.Edu .RE The .B mailsound program makes use of Mark Boyns' .B rplay package which can play multiple sounds on remote machines. .br He can be reached by E-mail as follows: .RS .B boyns@sdsu.edu .RE .SH BUGS The code does very little error checking. No range checking on any of the values is done. rplay-3.3.2/contrib/mailsound/mailsound.c100644 153 62 15713 6552756453 17157 0ustar boynsstaff/* * Copyright (C) 1993 Andrew Scherpbier * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #define PUBLIC #define PRIVATE static #undef TRUE #define TRUE (1) #undef FALSE #define FALSE (0) #define OK (0) #define NOTOK (-1) /* Private routines * ================ */ PRIVATE void dump_state(); PRIVATE void parse_args(int ac, char **av, int size); PRIVATE compare(char *buffer, char *from, long size); PRIVATE play_sound(char *sound, long size); /* Private variables * ================= */ PRIVATE char hostname[200] = "localhost"; PRIVATE int volume = 127; PRIVATE int use_random = FALSE; PRIVATE int use_size_volume = FALSE; PRIVATE int use_size_sound = FALSE; PRIVATE int min_size = 0; PRIVATE int max_size = 10000; PRIVATE int min_volume = 10; PRIVATE int max_volume = 200; PRIVATE char *sound = "youvegotmail"; PRIVATE char *subject_re = NULL; PRIVATE char subject[200]; PRIVATE int debug = FALSE; /* Public routines * =============== */ /* Public variables * ================ */ /************************************************************************** * PUBLIC main(int ac, char **av) * PURPOSE: * None */ PUBLIC main(int ac, char **av) { char buffer[1000]; char path[200]; char address[1000]; char *p; FILE *fl; int size = 0; struct passwd *pw; /* * Read the first line of the message. This is what we will use * to find out what sound to play. */ gets(buffer); size = strlen(buffer) + 1; if (!strtok(buffer, " ")) exit(1); p = strtok(NULL, " \t\n"); strcpy(address, p); subject[0] = '\0'; /* * We now need to read the rest of the message to determine its * size. */ while (gets(buffer)) { if (strncmp(buffer, "Subject: ", 9) == 0) { strcpy(subject, buffer + 9); } size += strlen(buffer) + 1; } /* * Deal with the command line arguments to be used as defaults. */ parse_args(ac, av, size); if (debug) dump_state(); /* * Find the configuration file in the home directory */ pw = getpwuid(getuid()); sprintf(path, "%s/.mailsounds", pw->pw_dir); fl = fopen(path, "r"); if (fl == NULL) exit(0); /* * Search through this file to find a line which will match the * address */ while (fgets(buffer, 1000, fl) != NULL) { compare(buffer, address, size); } play_sound(av[1], 0); fclose(fl); exit(0); } /************************************************************************** * PRIVATE compare(char *buffer, char *from, long size) * PURPOSE: * None * PARAMETERS: * None */ PRIVATE compare(char *buffer, char *from, long size) { char *pattern, *sound_args; char *p; pattern = strtok(buffer, " \t"); sound_args = strtok(NULL, "\t\n"); if ((char *)re_comp(pattern) != NULL) return; if (re_exec(from)) { if (debug) printf("Normal sound is played\n"); if (play_sound(sound_args, size) == OK) exit(0); } } /************************************************************************** * PRIVATE play_sound(char *sound_args, long size) * PURPOSE: * None * PARAMETERS: * None */ PRIVATE play_sound(char *sound_args, long size) { int ac; char *av[50]; char *token; /* * We need to build an argument list from the sound_args string. */ ac = 1; av[0] = "xxxx"; token = strtok(sound_args, " \t"); while (token && ac < 50) { av[ac++] = token; token = strtok(NULL, " \t"); } subject_re = NULL; parse_args(ac, av, size); if (subject_re) { if ((char *)re_comp(subject_re) != NULL) return NOTOK; if (!re_exec(subject)) return NOTOK; } if (debug) dump_state(); /* * Play the sound on each of the hosts listed in the hostname. */ token = strtok(hostname, ":"); while (token) { rplay_host_volume(token, sound, volume); token = strtok(NULL, ":"); } return OK; } /************************************************************************** * PRIVATE void parse_args(int ac, char **av, int size) * PURPOSE: * Take arguments and extract data from them. The arguments are * assumed to be in the same format as what is passed to the * main() program. */ PRIVATE void parse_args(int ac, char **av, int size) { int c; int i, count; extern char *optarg; extern int optind; char *sounds[50]; optind = 1; subject_re = NULL; while ((c = getopt(ac, av, "s:h:rz:Z:v:d")) != NOTOK) { switch (c) { case 'h': strcpy(hostname, optarg); break; case 'r': use_random = TRUE; break; case 's': subject_re = strdup(optarg); break; case 'z': sscanf(optarg, "%d:%d,%d:%d", &min_size, &min_volume, &max_size, &max_volume); use_size_volume = TRUE; break; case 'Z': sscanf(optarg, "%d,%d", &min_size, &max_size); use_size_sound = TRUE; break; case 'v': volume = atoi(optarg); break; case 'd': debug = TRUE; break; } } /* * The rest of the arguments are assumed to be sounds. */ count = 0; for (i = optind; i < ac && count < 50; i++) { sounds[count++] = av[i]; } /* * By default we will pick the first sound in the list */ sound = sounds[0]; /* * Now pick the sound and the volume. */ if (use_random) { srandom(time(NULL)); sound = sounds[random() % count]; } else if (use_size_sound) { if (size < min_size) sound = sounds[0]; if (size > max_size) sound = sounds[count - 1]; else { sound = sounds[(size - min_size) * count / (max_size - min_size)]; } } if (use_size_volume) { if (size < min_size) volume = min_volume; else if (size > max_size) volume = max_volume; else volume = (size - min_size) * (max_volume - min_volume) / (max_size - min_size) + min_volume; } } /************************************************************************** * PRIVATE void dump_state() * PURPOSE: * Produce debug output of all the global variables which make * up the state of the program */ PRIVATE void dump_state() { printf("host: '%s', volume: %d, random: %d, size_volume: %d, size_sound: %d\n", hostname, volume, use_random, use_size_volume, use_size_sound); printf("range data: v: (%d, %d), s: (%d, %d)\n", min_volume, max_volume, min_size, max_size); printf("sound: '%s'\n", sound); if (subject_re) printf("Subject regular expression: '%s'\n", subject_re); printf("Subject: '%s'\n", subject); } rplay-3.3.2/contrib/rplaytool-1.1/ 40755 153 62 0 6727650074 15217 5ustar boynsstaffrplay-3.3.2/contrib/rplaytool-1.1/COPYING100644 153 62 43070 6552756453 16377 0ustar boynsstaff GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. rplay-3.3.2/contrib/rplaytool-1.1/ChangeLog100644 153 62 1603 6552756453 17072 0ustar boynsstaffMon Feb 27 23:27:48 1995 Mark Boyns * Added and removed some buttons in the Sounds window. Now there's Play, Next, Prev, and Stop buttons as well as a Move button/menu. Fri Feb 17 10:44:28 1995 Mark Boyns * Added the following options: --dir, --disk-sounds, --server-sounds, and --sounds. See `rplaytool --help' for more information. Mon Feb 13 15:02:07 1995 Mark Boyns * rplaytool_stubs.c (longopts): Added GNU long-named options --help, --host, --playlist1, --playlist2, --playlist3, --playlist4, --version. * Complete pathnames are never displayed in playlists. Sun Feb 12 12:09:26 1995 Mark Boyns * rplaytool_stubs.c (do_soundlist): Fixed double-click problem. (do_disklist): Fixed double-click problem. (process_input): Don't display full pathnames in the spool list. rplay-3.3.2/contrib/rplaytool-1.1/Makefile100644 153 62 4406 6552756453 16764 0ustar boynsstaff## -- Begin Makefile configuration -- ## Your favorite K&R C compiler. CC = gcc ## rplaytool requires XView. OPENWINHOME should be set to the ## directory that contains the XView include files and the ## XView libraries. OPENWINHOME = /usr/openwin ## Where is `rplay.h' and `librplay.a' installed? RPLAY_INCLUDE = /usr/local/include RPLAY_LIB = /usr/local/lib ## Libraries you'll need for Solaris and maybe others. #EXTRA_LIBS = -lsocket -lnsl ## The OpenWindows Developer's Guide is only required if you're ## going to modify this program. GUIDEHOME = /usr/guide ## -- End Makefile configuration -- PROGRAM = rplaytool SOURCES.c = rptp.c misc.c getopt.c getopt1.c SOURCES.h = SOURCES.G = rplaytool.G STUBS.G = rplaytool.G # Derived parameters. SOURCES = \ $(SOURCES.G) \ $(SOURCES.h) \ $(SOURCES.l) \ $(SOURCES.y) \ $(SOURCES.cps) \ $(SOURCES.c) TARGETS.c = \ $(SOURCES.G:%.G=%_ui.c) \ $(STUBS.G:%.G=%_stubs.c) TARGETS.h = \ $(SOURCES.G:%.G=%_ui.h) \ $(SOURCES.l:%.l=%.h) \ $(SOURCES.y:%.y=%.h) \ $(SOURCES.cps:%.cps=%.h) TARGETS.other = \ $(SOURCES.G:%.G=%.info) TARGETS = \ $(TARGETS.other) \ $(TARGETS.h) \ $(TARGETS.c) OBJECTS = \ $(SOURCES.c:%.c=%.o) \ $(TARGETS.c:%.c=%.o) # Compiler flags. CFLAGS += -g CPPFLAGS += -I$(RPLAY_INCLUDE) -I$(GUIDEHOME)/include -I$(OPENWINHOME)/include -DMAIN LDFLAGS += -L$(RPLAY_LIB) -L$(GUIDEHOME)/lib -L$(OPENWINHOME)/lib ##LDLIBS += -lrplay -lguidexv -lguide -lxview -lolgx -lX11 LDLIBS += -lrplay -lxview -lolgx -lX11 $(EXTRA_LIBS) # Standard targets. all: $(TARGETS.other) $(PROGRAM) objects: $(SOURCES.c) $(TARGETS.c) $(TARGETS.h) $(OBJECTS) sources: $(SOURCES) targets: $(SOURCES) $(TARGETS) $(PROGRAM): $(SOURCES.c) $(TARGETS.c) $(TARGETS.h) $(OBJECTS) $(LINK.c) -o $@ $(OBJECTS) $(LDLIBS) # Targets to be used by Saber-C. saber_src: #load $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) \ $(SOURCES.c) $(TARGETS.c) $(LDLIBS) saber_obj: #load $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $(OBJECTS) $(LDLIBS) clean: $(RM) $(OBJECTS) *.BAK *.delta core $(PROGRAM) *~ guideclean: $(RM) $(SOURCES.G:%.G=%_ui.c) $(TARGETS.other) $(TARGETS.h) $(OBJECTS) *.BAK *.delta core $(PROGRAM) *~ %_ui.c: %.G $(GUIDEHOME)/bin/gxv $* %_ui.h: %_ui.c @touch $@ %_stubs.c: %_ui.c @touch $@ %.info: %_ui.c @touch $@ rplay-3.3.2/contrib/rplaytool-1.1/README100644 153 62 2602 6552756453 16200 0ustar boynsstaffrplaytool README This is version 1.1 of rplaytool. Many features of rplaytool were inspired by XJukebox 0.9 written by Raphael Quinet . FEATURES: * Show sounds that are currently playing or paused. * Allows sounds to be played, paused, continued, and stopped. * Server volume control. * Server sound browser/player (play with a double-click). * Disk sound browser/player (play with a double-click). * Maintain up-to 4 lists of sounds to be played sequentially. These lists are called playlists. * Playlists can be saved and loaded using files. * Uses RPTP asynchronous event notification and client-data to keep state. REQUIREMENTS: * rplay 3.2 available at ftp://ftp.sdsu.edu/pub/rplay/ ftp://ftp.x.org/contrib/audio/rplay/ * XView 3.x. If you have Open Windows, you have XView. XView (X window-system-based Visual/Integrated Environment for Workstations) is a X Window System toolkit that is publicly available at ftp.x.org. * SunOS or GNU `make'. TODO: * Support the RPTP `modify' command. * Allow the user to specify sample-rate, count, volume, etc. * Support flows. * Implement shuffle. The GUI interface to rplaytool was developed using the Open Windows Developer's Guide (devguide). Devguide is only required if you plan on modifying *any* of the source code. Send suggestions and bug reports to Mark Boyns . rplay-3.3.2/contrib/rplaytool-1.1/getopt.c100644 153 62 52421 6552756453 17012 0ustar boynsstaff/* Getopt for GNU. NOTE: getopt is now part of the C library, so if you don't know what "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu before changing it! Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* This tells Alpha OSF/1 not to define a getopt prototype in . Ditto for AIX 3.2 and . */ #ifndef _NO_PROTO #define _NO_PROTO #endif #ifdef HAVE_CONFIG_H #if defined (emacs) || defined (CONFIG_BROKETS) /* We use instead of "config.h" so that a compilation using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h (which it would do because it found this file in $srcdir). */ #include #else #include "config.h" #endif #endif #ifndef __STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ #ifndef const #define const #endif #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #if defined (_LIBC) || !defined (__GNU_LIBRARY__) /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ /* Don't include stdlib.h for non-GNU C libraries because some of them contain conflicting prototypes for getopt. */ #include #endif /* GNU C library. */ /* This version of `getopt' appears to the caller like standard Unix `getopt' but it behaves differently for the user, since it allows the user to intersperse the options with the other arguments. As `getopt' works, it permutes the elements of ARGV so that, when it is done, all the options precede everything else. Thus all application programs are extended to handle flexible argument order. Setting the environment variable POSIXLY_CORRECT disables permutation. Then the behavior is completely standard. GNU application programs can use a third alternative mode in which they can distinguish the relative order of options and other arguments. */ #include "getopt.h" /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ char *optarg = NULL; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns EOF, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ /* XXX 1003.2 says this must be 1 before any call. */ int optind = 0; /* The next char to be scanned in the option-element in which the last option character we returned was found. This allows us to pick up the scan where we left off. If this is zero, or a null string, it means resume the scan by advancing to the next ARGV-element. */ static char *nextchar; /* Callers store zero here to inhibit the error message for unrecognized options. */ int opterr = 1; /* Set to an option character which was unrecognized. This must be initialized on some systems to avoid linking in the system's own getopt implementation. */ int optopt = '?'; /* Describe how to deal with options that follow non-option ARGV-elements. If the caller did not specify anything, the default is REQUIRE_ORDER if the environment variable POSIXLY_CORRECT is defined, PERMUTE otherwise. REQUIRE_ORDER means don't recognize them as options; stop option processing when the first non-option is seen. This is what Unix does. This mode of operation is selected by either setting the environment variable POSIXLY_CORRECT, or using `+' as the first character of the list of option characters. PERMUTE is the default. We permute the contents of ARGV as we scan, so that eventually all the non-options are at the end. This allows options to be given in any order, even with programs that were not written to expect this. RETURN_IN_ORDER is an option available to programs that were written to expect options and other ARGV-elements in any order and that care about the ordering of the two. We describe each non-option ARGV-element as if it were the argument of an option with character code 1. Using `-' as the first character of the list of option characters selects this mode of operation. The special argument `--' forces an end of option-scanning regardless of the value of `ordering'. In the case of RETURN_IN_ORDER, only `--' can cause `getopt' to return EOF with `optind' != ARGC. */ static enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering; #ifdef __GNU_LIBRARY__ /* We want to avoid inclusion of string.h with non-GNU libraries because there are many ways it can cause trouble. On some systems, it contains special magic macros that don't work in GCC. */ #include #define my_index strchr #else /* Avoid depending on library functions or files whose names are inconsistent. */ char *getenv (); static char * my_index (str, chr) const char *str; int chr; { while (*str) { if (*str == chr) return (char *) str; str++; } return 0; } /* If using GCC, we can safely declare strlen this way. If not using GCC, it is ok not to declare it. */ #ifdef __GNUC__ /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. That was relevant to code that was here before. */ #ifndef __STDC__ /* gcc with -traditional declares the built-in strlen to return int, and has done so at least since version 2.4.5. -- rms. */ extern int strlen (const char *); #endif /* not __STDC__ */ #endif /* __GNUC__ */ #endif /* not __GNU_LIBRARY__ */ /* Handle permutation of arguments. */ /* Describe the part of ARGV that contains non-options that have been skipped. `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is the index after the last of them. */ static int first_nonopt; static int last_nonopt; /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) which contains all the non-options that have been skipped so far. The other is elements [last_nonopt,optind), which contains all the options processed since those non-options were skipped. `first_nonopt' and `last_nonopt' are relocated so that they describe the new indices of the non-options in ARGV after they are moved. */ static void exchange (argv) char **argv; { int bottom = first_nonopt; int middle = last_nonopt; int top = optind; char *tem; /* Exchange the shorter segment with the far end of the longer segment. That puts the shorter segment into the right place. It leaves the longer segment in the right place overall, but it consists of two parts that need to be swapped next. */ while (top > middle && middle > bottom) { if (top - middle > middle - bottom) { /* Bottom segment is the short one. */ int len = middle - bottom; register int i; /* Swap it with the top part of the top segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[top - (middle - bottom) + i]; argv[top - (middle - bottom) + i] = tem; } /* Exclude the moved bottom segment from further swapping. */ top -= len; } else { /* Top segment is the short one. */ int len = top - middle; register int i; /* Swap it with the bottom part of the bottom segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[middle + i]; argv[middle + i] = tem; } /* Exclude the moved top segment from further swapping. */ bottom += len; } } /* Update records for the slots the non-options now occupy. */ first_nonopt += (optind - last_nonopt); last_nonopt = optind; } /* Initialize the internal data when the first call is made. */ static const char * _getopt_initialize (optstring) const char *optstring; { /* Start processing options with ARGV-element 1 (since ARGV-element 0 is the program name); the sequence of previously skipped non-option ARGV-elements is empty. */ first_nonopt = last_nonopt = optind = 1; nextchar = NULL; /* Determine how to handle the ordering of options and nonoptions. */ if (optstring[0] == '-') { ordering = RETURN_IN_ORDER; ++optstring; } else if (optstring[0] == '+') { ordering = REQUIRE_ORDER; ++optstring; } else if (getenv ("POSIXLY_CORRECT") != NULL) ordering = REQUIRE_ORDER; else ordering = PERMUTE; return optstring; } /* Scan elements of ARGV (whose length is ARGC) for option characters given in OPTSTRING. If an element of ARGV starts with '-', and is not exactly "-" or "--", then it is an option element. The characters of this element (aside from the initial '-') are option characters. If `getopt' is called repeatedly, it returns successively each of the option characters from each of the option elements. If `getopt' finds another option character, it returns that character, updating `optind' and `nextchar' so that the next call to `getopt' can resume the scan with the following option character or ARGV-element. If there are no more option characters, `getopt' returns `EOF'. Then `optind' is the index in ARGV of the first ARGV-element that is not an option. (The ARGV-elements have been permuted so that those that are not options now come last.) OPTSTRING is a string containing the legitimate option characters. If an option character is seen that is not listed in OPTSTRING, return '?' after printing an error message. If you set `opterr' to zero, the error message is suppressed but we still return '?'. If a char in OPTSTRING is followed by a colon, that means it wants an arg, so the following text in the same ARGV-element, or the text of the following ARGV-element, is returned in `optarg'. Two colons mean an option that wants an optional arg; if there is text in the current ARGV-element, it is returned in `optarg', otherwise `optarg' is set to zero. If OPTSTRING starts with `-' or `+', it requests different methods of handling the non-option ARGV-elements. See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. Long-named options begin with `--' instead of `-'. Their names may be abbreviated as long as the abbreviation is unique or is an exact match for some defined option. If they have an argument, it follows the option name in the same ARGV-element, separated from the option name by a `=', or else the in next ARGV-element. When `getopt' finds a long-named option, it returns 0 if that option's `flag' field is nonzero, the value of the option's `val' field if the `flag' field is zero. The elements of ARGV aren't really const, because we permute them. But we pretend they're const in the prototype to be compatible with other systems. LONGOPTS is a vector of `struct option' terminated by an element containing a name which is zero. LONGIND returns the index in LONGOPT of the long-named option found. It is only valid when a long-named option has been found by the most recent call. If LONG_ONLY is nonzero, '-' as well as '--' can introduce long-named options. */ int _getopt_internal (argc, argv, optstring, longopts, longind, long_only) int argc; char *const *argv; const char *optstring; const struct option *longopts; int *longind; int long_only; { optarg = NULL; if (optind == 0) optstring = _getopt_initialize (optstring); if (nextchar == NULL || *nextchar == '\0') { /* Advance to the next ARGV-element. */ if (ordering == PERMUTE) { /* If we have just processed some options following some non-options, exchange them so that the options come first. */ if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (last_nonopt != optind) first_nonopt = optind; /* Skip any additional non-options and extend the range of non-options previously skipped. */ while (optind < argc && (argv[optind][0] != '-' || argv[optind][1] == '\0')) optind++; last_nonopt = optind; } /* The special ARGV-element `--' means premature end of options. Skip it like a null option, then exchange with previous non-options as if it were an option, then skip everything else like a non-option. */ if (optind != argc && !strcmp (argv[optind], "--")) { optind++; if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (first_nonopt == last_nonopt) first_nonopt = optind; last_nonopt = argc; optind = argc; } /* If we have done all the ARGV-elements, stop the scan and back over any non-options that we skipped and permuted. */ if (optind == argc) { /* Set the next-arg-index to point at the non-options that we previously skipped, so the caller will digest them. */ if (first_nonopt != last_nonopt) optind = first_nonopt; return EOF; } /* If we have come to a non-option and did not permute it, either stop the scan or describe it to the caller and pass it by. */ if ((argv[optind][0] != '-' || argv[optind][1] == '\0')) { if (ordering == REQUIRE_ORDER) return EOF; optarg = argv[optind++]; return 1; } /* We have found another option-ARGV-element. Skip the initial punctuation. */ nextchar = (argv[optind] + 1 + (longopts != NULL && argv[optind][1] == '-')); } /* Decode the current option-ARGV-element. */ /* Check whether the ARGV-element is a long option. If long_only and the ARGV-element has the form "-f", where f is a valid short option, don't consider it an abbreviated form of a long option that starts with f. Otherwise there would be no way to give the -f short option. On the other hand, if there's a long option "fubar" and the ARGV-element is "-fu", do consider that an abbreviation of the long option, just like "--fu", and not "-f" with arg "u". This distinction seems to be the most useful approach. */ if (longopts != NULL && (argv[optind][1] == '-' || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) { char *nameend; const struct option *p; const struct option *pfound = NULL; int exact = 0; int ambig = 0; int indfound; int option_index; for (nameend = nextchar; *nameend && *nameend != '='; nameend++) /* Do nothing. */ ; /* Test all long options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp (p->name, nextchar, nameend - nextchar)) { if (nameend - nextchar == strlen (p->name)) { /* Exact match found. */ pfound = p; indfound = option_index; exact = 1; break; } else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else /* Second or later nonexact match found. */ ambig = 1; } if (ambig && !exact) { if (opterr) fprintf (stderr, "%s: option `%s' is ambiguous\n", argv[0], argv[optind]); nextchar += strlen (nextchar); optind++; return '?'; } if (pfound != NULL) { option_index = indfound; optind++; if (*nameend) { /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */ if (pfound->has_arg) optarg = nameend + 1; else { if (opterr) { if (argv[optind - 1][1] == '-') /* --option */ fprintf (stderr, "%s: option `--%s' doesn't allow an argument\n", argv[0], pfound->name); else /* +option or -option */ fprintf (stderr, "%s: option `%c%s' doesn't allow an argument\n", argv[0], argv[optind - 1][0], pfound->name); } nextchar += strlen (nextchar); return '?'; } } else if (pfound->has_arg == 1) { if (optind < argc) optarg = argv[optind++]; else { if (opterr) fprintf (stderr, "%s: option `%s' requires an argument\n", argv[0], argv[optind - 1]); nextchar += strlen (nextchar); return optstring[0] == ':' ? ':' : '?'; } } nextchar += strlen (nextchar); if (longind != NULL) *longind = option_index; if (pfound->flag) { *(pfound->flag) = pfound->val; return 0; } return pfound->val; } /* Can't find it as a long option. If this is not getopt_long_only, or the option starts with '--' or is not a valid short option, then it's an error. Otherwise interpret it as a short option. */ if (!long_only || argv[optind][1] == '-' || my_index (optstring, *nextchar) == NULL) { if (opterr) { if (argv[optind][1] == '-') /* --option */ fprintf (stderr, "%s: unrecognized option `--%s'\n", argv[0], nextchar); else /* +option or -option */ fprintf (stderr, "%s: unrecognized option `%c%s'\n", argv[0], argv[optind][0], nextchar); } nextchar = (char *) ""; optind++; return '?'; } } /* Look at and handle the next short option-character. */ { char c = *nextchar++; char *temp = my_index (optstring, c); /* Increment `optind' when we start to process its last character. */ if (*nextchar == '\0') ++optind; if (temp == NULL || c == ':') { if (opterr) { /* 1003.2 specifies the format of this message. */ fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c); } optopt = c; return '?'; } if (temp[1] == ':') { if (temp[2] == ':') { /* This is an option that accepts an argument optionally. */ if (*nextchar != '\0') { optarg = nextchar; optind++; } else optarg = NULL; nextchar = NULL; } else { /* This is an option that requires an argument. */ if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ optind++; } else if (optind == argc) { if (opterr) { /* 1003.2 specifies the format of this message. */ fprintf (stderr, "%s: option requires an argument -- %c\n", argv[0], c); } optopt = c; if (optstring[0] == ':') c = ':'; else c = '?'; } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ optarg = argv[optind++]; nextchar = NULL; } } return c; } } int getopt (argc, argv, optstring) int argc; char *const *argv; const char *optstring; { return _getopt_internal (argc, argv, optstring, (const struct option *) 0, (int *) 0, 0); } #endif /* _LIBC or not __GNU_LIBRARY__. */ #ifdef TEST /* Compile with -DTEST to make an executable for use in testing the above definition of `getopt'. */ int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; c = getopt (argc, argv, "abc:d:0123456789"); if (c == EOF) break; switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ rplay-3.3.2/contrib/rplaytool-1.1/getopt.h100644 153 62 10474 6552756453 17021 0ustar boynsstaff/* Declarations for getopt. Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _GETOPT_H #define _GETOPT_H 1 #ifdef __cplusplus extern "C" { #endif /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ extern char *optarg; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns EOF, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ extern int optind; /* Callers store zero here to inhibit the error message `getopt' prints for unrecognized options. */ extern int opterr; /* Set to an option character which was unrecognized. */ extern int optopt; /* Describe the long-named options requested by the application. The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector of `struct option' terminated by an element containing a name which is zero. The field `has_arg' is: no_argument (or 0) if the option does not take an argument, required_argument (or 1) if the option requires an argument, optional_argument (or 2) if the option takes an optional argument. If the field `flag' is not NULL, it points to a variable that is set to the value given in the field `val' when the option is found, but left unchanged if the option is not found. To have a long-named option do something other than set an `int' to a compiled-in constant, such as set a value from `optarg', set the option's `flag' field to zero and its `val' field to a nonzero value (the equivalent single-letter option character, if there is one). For long options that have a zero `flag' field, `getopt' returns the contents of the `val' field. */ struct option { #if __STDC__ const char *name; #else char *name; #endif /* has_arg can't be an enum because some compilers complain about type mismatches in all the code that assumes it is an int. */ int has_arg; int *flag; int val; }; /* Names for the values of the `has_arg' field of `struct option'. */ #define no_argument 0 #define required_argument 1 #define optional_argument 2 #if __STDC__ #if defined(__GNU_LIBRARY__) /* Many other libraries have conflicting prototypes for getopt, with differences in the consts, in stdlib.h. To avoid compilation errors, only prototype getopt for the GNU C library. */ extern int getopt (int argc, char *const *argv, const char *shortopts); #else /* not __GNU_LIBRARY__ */ extern int getopt (); #endif /* not __GNU_LIBRARY__ */ extern int getopt_long (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); extern int getopt_long_only (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); /* Internal only. Users should not call this directly. */ extern int _getopt_internal (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind, int long_only); #else /* not __STDC__ */ extern int getopt (); extern int getopt_long (); extern int getopt_long_only (); extern int _getopt_internal (); #endif /* not __STDC__ */ #ifdef __cplusplus } #endif #endif /* _GETOPT_H */ rplay-3.3.2/contrib/rplaytool-1.1/getopt1.c100644 153 62 10640 6552756453 17070 0ustar boynsstaff/* getopt_long and getopt_long_only entry points for GNU getopt. Copyright (C) 1987, 88, 89, 90, 91, 92, 1993 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef HAVE_CONFIG_H #if defined (emacs) || defined (CONFIG_BROKETS) /* We use instead of "config.h" so that a compilation using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h (which it would do because it found this file in $srcdir). */ #include #else #include "config.h" #endif #endif #include "getopt.h" #ifndef __STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ #ifndef const #define const #endif #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #if defined (_LIBC) || !defined (__GNU_LIBRARY__) /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ #include #else char *getenv (); #endif #ifndef NULL #define NULL 0 #endif int getopt_long (argc, argv, options, long_options, opt_index) int argc; char *const *argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal (argc, argv, options, long_options, opt_index, 0); } /* Like getopt_long, but '-' as well as '--' can indicate a long option. If an option that starts with '-' (not '--') doesn't match a long option, but does match a short option, it is parsed as a short option instead. */ int getopt_long_only (argc, argv, options, long_options, opt_index) int argc; char *const *argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal (argc, argv, options, long_options, opt_index, 1); } #endif /* _LIBC or not __GNU_LIBRARY__. */ #ifdef TEST #include int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; int option_index = 0; static struct option long_options[] = { {"add", 1, 0, 0}, {"append", 0, 0, 0}, {"delete", 1, 0, 0}, {"verbose", 0, 0, 0}, {"create", 0, 0, 0}, {"file", 1, 0, 0}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "abc:d:0123456789", long_options, &option_index); if (c == EOF) break; switch (c) { case 0: printf ("option %s", long_options[option_index].name); if (optarg) printf (" with arg %s", optarg); printf ("\n"); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case 'd': printf ("option d with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ rplay-3.3.2/contrib/rplaytool-1.1/list100644 153 62 232 6552756453 16173 0ustar boynsstaffbeep.au --sample-rate=4000 --volume=200 excellent.au --delay=4 jedi.au --delay=3 oh_my_god.au --delay=3 duck.au --name="A Duck" --delay=10 rplay-3.3.2/contrib/rplaytool-1.1/misc.c100644 153 62 40125 6564501777 16441 0ustar boynsstaff/* $Id: misc.c,v 1.2 1998/08/13 06:13:19 boyns Exp $ */ /* * Copyright (C) 1995 Mark Boyns * * This file is part of rplaytool. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "misc.h" #include #include #include #include #ifdef __STDC__ #include #else #include #endif #include "rplaytool_ui.h" #include "rptp.h" #undef MIN #undef MAX #define MIN(a,b) ((a)<(b)?(a):(b)) #define MAX(a,b) ((a)>(b)?(a):(b)) /* Windows */ extern rplaytool_w_objects *Rplaytool_w; extern rplaytool_s_objects *Rplaytool_s; extern rplaytool_f_objects *Rplaytool_f; PLAYLIST playlist[NUMBER_OF_PLAYLISTS]; int curr_playlist = 0; int client_id = 0; extern int initial_delay; static unsigned short directory_bits[] = { #include "icons/directory.icon" }; static unsigned short sound_bits[] = { #include "icons/sound.icon" }; static unsigned short play_bits[] = { #include "icons/play.icon" }; static unsigned short play1_bits[] = { #include "icons/play1.icon" }; static unsigned short play2_bits[] = { #include "icons/play2.icon" }; static unsigned short play3_bits[] = { #include "icons/play3.icon" }; static unsigned short play4_bits[] = { #include "icons/play4.icon" }; static unsigned short pause_bits[] = { #include "icons/pause.icon" }; static unsigned short pause1_bits[] = { #include "icons/pause1.icon" }; static unsigned short pause2_bits[] = { #include "icons/pause2.icon" }; static unsigned short pause3_bits[] = { #include "icons/pause3.icon" }; static unsigned short pause4_bits[] = { #include "icons/pause4.icon" }; static unsigned short arrow_bits[] = { #include "icons/arrow.icon" }; static unsigned short none_bits[] = { #include "icons/none.icon" }; static unsigned short file_bits[] = { #include "icons/file.icon" }; static unsigned short watch_bits[] = { #include "icons/watch.icon" }; SOME_ICON icons[NUMBER_OF_ICONS] = { { NULL, play_bits }, { NULL, play1_bits }, { NULL, play2_bits }, { NULL, play3_bits }, { NULL, play4_bits }, { NULL, pause_bits }, { NULL, pause1_bits }, { NULL, pause2_bits }, { NULL, pause3_bits }, { NULL, pause4_bits }, { NULL, directory_bits }, { NULL, sound_bits }, { NULL, arrow_bits }, { NULL, none_bits }, { NULL, file_bits }, { NULL, watch_bits }, }; #ifdef __STDC__ int notice (Xv_opaque panel, char *button1, char *button2, char *fmt, ...) #else int notice (va_alist) va_dcl #endif { char message[1024]; Xv_notice nw; int choice = 0; va_list args; #ifdef __STDC__ va_start (args, fmt); #else char *fmt, *button1, *button2; Xv_opaque panel; va_start (args); panel = va_arg (args, Xv_opaque); button1 = va_arg (args, char *); button2 = va_arg (args, char *); fmt = va_arg (args, char *); #endif vsprintf (message, fmt, args); if (button1 && button2) { nw = xv_create (panel, NOTICE, NOTICE_MESSAGE_STRINGS, message, NULL, NOTICE_BUTTON, button1, 1, NOTICE_BUTTON, button2, 2, NOTICE_STATUS, &choice, XV_SHOW, TRUE, NULL); } else if (button1) { nw = xv_create (panel, NOTICE, NOTICE_MESSAGE_STRINGS, message, NULL, NOTICE_BUTTON, button1, 1, NOTICE_STATUS, &choice, XV_SHOW, TRUE, NULL); } else { nw = xv_create (panel, NOTICE, NOTICE_MESSAGE_STRINGS, message, NULL, XV_SHOW, TRUE, NULL); } xv_destroy_safe (nw); return choice; } void sort_list (list) Xv_opaque list; { xv_set(list, PANEL_INACTIVE, TRUE, NULL); xv_set(list, PANEL_LIST_SORT, PANEL_FORWARD, NULL); xv_set(list, PANEL_INACTIVE, FALSE, NULL); } void busy (frame, flag) Xv_opaque frame; int flag; { xv_set (frame, FRAME_BUSY, flag, NULL); } static INFO * new_info () { INFO *info = (INFO *) malloc (sizeof (INFO)); info->filename[0] = '\0'; info->name[0] = '\0'; info->volume = RPLAY_DEFAULT_VOLUME; info->sample_rate = RPLAY_DEFAULT_SAMPLE_RATE; info->delay = initial_delay; /* -1 or seconds */ return info; } /* Initialize a playlist. */ void do_playlist_init (list) int list; { playlist[list].id = -1; playlist[list].size = 0; playlist[list].curr = -1; playlist[list].auto_play = 1; playlist[list].filename[0] = '\0'; playlist[list].mtime = 0; playlist[list].delay = -1; } /* Reset a playlist. */ void do_playlist_reset (list) int list; { playlist[list].id = -1; playlist[list].size = 0; playlist[list].curr = -1; playlist[list].auto_play = 1; /* playlist[list].filename[0] = '\0'; */ /* playlist[list].mtime = 0; */ /* playlist[list].delay = -1; */ } void playlist_update_icons (list) int list; { int i; xv_set (playlist[list].list, XV_SHOW, FALSE, NULL); for (i = 0; i < playlist[list].size; i++) { xv_set (playlist[list].list, PANEL_LIST_GLYPH, i, icons[ICON_NONE].image, NULL); } /* Delaying */ if (playlist[list].delay > 0) { xv_set (playlist[list].list, PANEL_LIST_GLYPH, playlist[list].curr, icons[ICON_WATCH].image, NULL); } /* Playing */ else if (playlist[list].curr >= 0 && playlist[list].id > 0) { xv_set (playlist[list].list, PANEL_LIST_GLYPH, playlist[list].curr, icons[ICON_SOUND].image, NULL); } /* Not playing */ else if (playlist[list].curr >= 0 && playlist[list].curr < playlist[list].size) { xv_set (playlist[list].list, PANEL_LIST_GLYPH, playlist[list].curr, icons[ICON_ARROW].image, NULL); } else { xv_set (playlist[list].list, PANEL_LIST_GLYPH, 0, icons[ICON_ARROW].image, NULL); } xv_set (playlist[list].list, XV_SHOW, TRUE, NULL); } /* Add a sound to list at index. */ void do_playlist_add (list, index, filename) int list; int index; char *filename; { INFO *info; char *p; info = new_info (); strcpy (info->filename, filename); p = strrchr (info->filename, '/'); if (p) { strcpy (info->name, p+1); } else { strcpy (info->name, info->filename); } xv_set (playlist[list].list, PANEL_LIST_INSERT, index, PANEL_LIST_STRING, index, info->name, PANEL_LIST_CLIENT_DATA, index, info, NULL); playlist[list].size++; } /* Append a sound to list .*/ void do_playlist_append (list, filename) int list; char *filename; { do_playlist_add (list, playlist[list].size, filename); playlist_update_icons (list); } void do_playlist_move (list, from, to) int list; int from; int to; { char from_name[RPTP_MAX_LINE], *from_data; char to_name[RPTP_MAX_LINE], *to_data; xv_set (playlist[list].list, XV_SHOW, FALSE, NULL); strcpy (from_name, (char *) xv_get (playlist[list].list, PANEL_LIST_STRING, from)); from_data = (char *) xv_get (playlist[list].list, PANEL_LIST_CLIENT_DATA, from); strcpy (to_name, (char *) xv_get (playlist[list].list, PANEL_LIST_STRING, to)); to_data = (char *) xv_get (playlist[list].list, PANEL_LIST_CLIENT_DATA, to); xv_set (playlist[list].list, PANEL_LIST_STRING, from, to_name, PANEL_LIST_CLIENT_DATA, from, to_data, NULL); xv_set (playlist[list].list, PANEL_LIST_STRING, to, from_name, PANEL_LIST_CLIENT_DATA, to, from_data, NULL); playlist_update_icons (list); xv_set (playlist[list].list, XV_SHOW, TRUE, NULL); } /* Delete all entries from a playlist. */ void do_playlist_delete_all (list) int list; { int i, n; n = (int) xv_get (playlist[list].list, PANEL_LIST_NROWS); for (i = 0; i < n; i++) { do_playlist_delete (list, 0); } do_playlist_reset (list); } /* Delete a single entry from a playlist. */ void do_playlist_delete (list, index) int list; int index; { char *p; p = (char *) xv_get (playlist[list].list, PANEL_LIST_CLIENT_DATA, index); if (p) { free ((char *) p); } xv_set (playlist[list].list, PANEL_LIST_DELETE, index, NULL); /* Update the size. */ playlist[curr_playlist].size--; /* Stop it if it's playing. */ if (playlist[list].curr != -1 && index == playlist[list].curr) { do_playlist_stop (list); playlist[list].curr--; } /* Update curr. */ else if (playlist[list].curr != -1 && index < playlist[list].curr) { playlist[list].curr--; } } /* Stop the sound a playlist is playing. */ void do_playlist_stop (list) int list; { if (playlist[list].curr != -1 && playlist[list].id > 0) { char client_data[RPTP_MAX_LINE]; sprintf (client_data, "%d %d", client_id, list); do_rptp_stop (playlist[list].id, client_data); playlist[curr_playlist].id = -1; } if (playlist[curr_playlist].delay > 0) { playlist[curr_playlist].delay = -1; } playlist_update_icons (list); } void do_playlist_load (list, fp) int list; FILE *fp; { char buf[BUFSIZ]; char *value; INFO *info; struct stat st; while (fgets (buf, sizeof (buf), fp)) { value = rptp_parse (buf, 0); do_playlist_append (list, value); info = (INFO *) xv_get (playlist[list].list, PANEL_LIST_CLIENT_DATA, playlist[list].size - 1); value = rptp_parse (0, "volume"); if (value && *value) { info->volume = atoi (value); } value = rptp_parse (0, "sample-rate"); if (value && *value) { info->sample_rate = atoi (value); } value = rptp_parse (0, "name"); if (value && *value) { strcpy (info->name, value); xv_set (playlist[list].list, PANEL_LIST_STRING, playlist[list].size - 1, info->name, NULL); } value = rptp_parse (0, "delay"); if (value && *value) { info->delay = atoi (value); } } if (fstat (fileno (fp), &st) > 0) { playlist[list].mtime = st.st_mtime; } playlist_update_icons (list); } void do_playlist_save (list, fp) int list; FILE *fp; { INFO *info; int i; for (i = 0; i < playlist[list].size; i++) { info = (INFO *) xv_get (playlist[list].list, PANEL_LIST_CLIENT_DATA, i); fprintf (fp, "%s --name=\"%s\"", info->filename, info->name); if (info->volume != RPLAY_DEFAULT_VOLUME) { fprintf (fp, " --volume=%d", info->volume); } if (info->sample_rate != RPLAY_DEFAULT_SAMPLE_RATE) { fprintf (fp, " --sample-rate=%d", info->sample_rate); } if (info->delay > 0) { fprintf (fp, " --delay=%d", info->delay); } fprintf (fp, "\n"); } } /* Scan all the playlist filenames to see if they have been modified. If so, update the playlist with the new file contents. */ void playlist_scan () { int i, n; struct stat st; FILE *fp; char buf[BUFSIZ]; char message[1024]; char filename[MAXPATHLEN]; INFO *info; char was_playing[MAXPATHLEN]; int was_playing_id; int was_playing_index; for (i = 0; i < NUMBER_OF_PLAYLISTS; i++) { if (playlist[i].filename[0] != '\0') { stat (playlist[i].filename, &st); if (st.st_mtime > playlist[i].mtime) { busy (Rplaytool_s->s, TRUE); fp = fopen (playlist[i].filename, "r"); if (!fp) { fprintf (stderr, "Can't open `%s'\n", playlist[i].filename); busy (Rplaytool_s->s, FALSE); continue; } /* Save the sound that was playing. */ if (playlist[i].curr != -1) { info = (INFO *) xv_get (playlist[i].list, PANEL_LIST_CLIENT_DATA, playlist[i].curr); strcpy (was_playing, info->filename); was_playing_id = playlist[i].id; was_playing_index = playlist[i].curr; } else { was_playing[0] = '\0'; was_playing_id = 0; was_playing_index = 0; } /* Delete all sounds from this list. */ playlist[i].curr = -1; /* hack to prevent the stopping of the playing sound */ playlist[i].id = -1; do_playlist_delete_all (i); /* Load the new list. */ do_playlist_load (i, fp); fclose (fp); if (was_playing[0]) { int new_position = -1; /* Try to find the sound that was playing in the new list. */ /* First try the original position. */ n = (int) xv_get (playlist[i].list, PANEL_LIST_NROWS); if (was_playing_index < n) { info = (INFO *) xv_get (playlist[i].list, PANEL_LIST_CLIENT_DATA, was_playing_index); } else { info = NULL; } if (info && strcmp (was_playing, info->filename) == 0) { new_position = was_playing_index; } /* Find closest match. */ else { int closest_before = -1; int closest_after = -1; int match_found = 0; for (n = 0; n < playlist[i].size; n++) { info = (INFO *) xv_get (playlist[i].list, PANEL_LIST_CLIENT_DATA, n); if (strcmp (was_playing, info->filename) == 0) { match_found++; if (n < was_playing_index) { closest_before = n; } else if (n > was_playing_index) { closest_after = n; break; } } } #if 0 printf ("match_found=%d prev=%d next=%d was=%d\n", match_found, closest_before, closest_after, was_playing_index); #endif if (match_found) { if (closest_before >= 0 && closest_after >= 0) { int distance_before; int distance_after; distance_before = was_playing_index - closest_before; distance_after = closest_after - was_playing_index; /* If matches are equally distance, use the previous one. Otherwise, use the closest one. */ new_position = distance_before <= distance_after ? closest_before : closest_after; } else if (closest_before >= 0) { new_position = closest_before; } else { new_position = closest_after; } } } if (new_position == -1) { do_rptp_stop (was_playing_id, ""); playlist[i].curr = 0; play_playlist (i, TRUE); } else { playlist[i].curr = new_position; playlist[i].id = was_playing_id; } } playlist[i].mtime = st.st_mtime; playlist_update_icons (i); busy (Rplaytool_s->s, FALSE); } } } } void play_playlist (list, use_delay) int list; int use_delay; { char client_data[32]; Scrollbar scrollbar; INFO *info; if ((int) xv_get (playlist[list].list, PANEL_LIST_NROWS) > 0 && playlist[list].curr >= 0 && playlist[list].curr < playlist[list].size) { int rows, view; info = (INFO *) xv_get (playlist[list].list, PANEL_LIST_CLIENT_DATA, playlist[list].curr); /* See if the play should be delayed a while. */ if (use_delay && info->delay > 0) { /* It's already being delayed, interrupt it. */ if (playlist[list].delay > 0) { playlist[list].delay = -1; } else { playlist[list].delay = info->delay; playlist_update_icons (list); return; } } /* Set `client-data' to the client_id and soundlist number. */ sprintf (client_data, "%d %d", client_id, list); /* Play the sound */ do_rptp_play_info (info, client_data); busy (Rplaytool_s->s, TRUE); /* Auto-scroll */ rows = (int) xv_get (playlist[list].list, PANEL_LIST_DISPLAY_ROWS); scrollbar = (Scrollbar) xv_get (playlist[list].list, PANEL_LIST_SCROLLBAR); view = (int) xv_get (scrollbar, SCROLLBAR_VIEW_START); if (playlist[list].curr >= view + rows) { xv_set (scrollbar, SCROLLBAR_VIEW_START, playlist[list].curr, NULL); } else if (playlist[list].curr < view) { view = playlist[list].curr - rows; if (view < 0) { view = 0; } xv_set (scrollbar, SCROLLBAR_VIEW_START, view, NULL); } } else if (playlist[list].curr >= playlist[list].size || playlist[list].curr < 0) { playlist[list].curr = 0; /* rewind */ } playlist_update_icons (list); } rplay-3.3.2/contrib/rplaytool-1.1/misc.h100644 153 62 6056 6564502000 16407 0ustar boynsstaff/* $Id: misc.h,v 1.2 1998/08/13 06:13:20 boyns Exp $ */ /* * Copyright (C) 1995 Mark Boyns * * This file is part of rplaytool. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _misc_h #define _misc_h #include #include #include #include #define STATE_NONE 0 #define STATE_PLAY 1 #define STATE_STOP 2 #define STATE_PAUSE 3 #define STATE_CONTINUE 4 /* Icons */ typedef struct { Server_image image; unsigned short *bits; } SOME_ICON; #define ICON_PLAY 0 #define ICON_PLAY1 1 #define ICON_PLAY2 2 #define ICON_PLAY3 3 #define ICON_PLAY4 4 #define ICON_PAUSE 5 #define ICON_PAUSE1 6 #define ICON_PAUSE2 7 #define ICON_PAUSE3 8 #define ICON_PAUSE4 9 #define ICON_DIRECTORY 10 #define ICON_SOUND 11 #define ICON_ARROW 12 #define ICON_NONE 13 #define ICON_FILE 14 #define ICON_WATCH 15 #define NUMBER_OF_ICONS 16 typedef struct { char filename[MAXPATHLEN]; char name[MAXPATHLEN]; int volume; int sample_rate; int delay; } INFO; typedef struct { int id; int size; int curr; Xv_opaque list; int auto_play; time_t mtime; char filename[MAXPATHLEN]; int delay; } PLAYLIST; #define NUMBER_OF_PLAYLISTS 4 extern PLAYLIST playlist[NUMBER_OF_PLAYLISTS]; extern int curr_playlist; extern SOME_ICON icons[NUMBER_OF_ICONS]; extern int client_id; #ifdef __STDC__ extern int notice (Xv_opaque panel, char *button1, char *button2, char *fmt, ...); #else extern int notice (/* Xv_opaque frame, char *button1, char *button2, char *fmt, ... */ ); #endif extern void sort_list (/* Xv_opaque list */); extern void busy (/* Xv_opaque frame, int flag */); extern void do_playlist_init (/* int list */); extern void do_playlist_reset (/* int list */); extern void do_playlist_add (/* list, index, sound_dir, sound_name */); extern void do_playlist_append (/* list, sound_dir, sound_name */); extern void do_playlist_move (/* list, from, to */); extern void do_playlist_delete_all (/* int list */); extern void do_playlist_delete (/* int list, int index */); extern void do_playlist_stop (/* int list */); extern void playlist_scan (); extern void do_playlist_load (/* int list, FILE *fp */); extern void do_playlist_save (/* int list, FILE *fp */); extern void play_playlist (/* int list */); extern void playlist_update_icons (/* int list */); #endif /* _misc_h */ rplay-3.3.2/contrib/rplaytool-1.1/rplaytool.G100644 153 62 136022 6552756453 17521 0ustar boynsstaff;GIL-3 ( ( :type :menu :name file_menu :help "" :columns 1 :menu-type :command :menu-handler nil :menu-title "" :menu-item-labels ("Sounds..." "Quit" ) :menu-item-label-types (:string :string ) :menu-item-states (:active :active ) :menu-item-defaults (nil nil ) :initial-selections (nil nil ) :menu-item-handlers (nil do_quit ) :menu-item-menus (nil nil ) :menu-item-colors ("" "" ) :pinnable nil :user-data () :actions ( ( :from (file_menu "Quit") :when (Notify ) :to (file_menu "Quit") :function_type CallFunction :arg_type () :action (do_quit) ) ( :from (file_menu "Sounds...") :when (Notify ) :to (s) :function_type :user_defined :arg_type () :action (Show) ) ) ) ( :type :menu :name cont_menu :help "" :columns 1 :menu-type :command :menu-handler nil :menu-title "" :menu-item-labels ("Selected sounds" "All sounds" ) :menu-item-label-types (:string :string ) :menu-item-states (:active :active ) :menu-item-defaults (t nil ) :initial-selections (nil nil ) :menu-item-handlers (do_cont_selected do_cont_all ) :menu-item-menus (nil nil ) :menu-item-colors ("" "" ) :pinnable nil :user-data () :actions ( ( :from (cont_menu "Selected sounds") :when (Notify ) :to (cont_menu "Selected sounds") :function_type CallFunction :arg_type () :action (do_cont_selected) ) ( :from (cont_menu "All sounds") :when (Notify ) :to (cont_menu "All sounds") :function_type CallFunction :arg_type () :action (do_cont_all) ) ) ) ( :type :menu :name pause_menu :help "" :columns 1 :menu-type :command :menu-handler nil :menu-title "" :menu-item-labels ("Selected sounds" "All sounds" ) :menu-item-label-types (:string :string ) :menu-item-states (:active :active ) :menu-item-defaults (t nil ) :initial-selections (nil nil ) :menu-item-handlers (do_pause_selected do_pause_all ) :menu-item-menus (nil nil ) :menu-item-colors ("" "" ) :pinnable nil :user-data () :actions ( ( :from (pause_menu "Selected sounds") :when (Notify ) :to (pause_menu "Selected sounds") :function_type CallFunction :arg_type () :action (do_pause_selected) ) ( :from (pause_menu "All sounds") :when (Notify ) :to (pause_menu "All sounds") :function_type CallFunction :arg_type () :action (do_pause_all) ) ) ) ( :type :menu :name stop_menu :help "" :columns 1 :menu-type :command :menu-handler nil :menu-title "" :menu-item-labels ("Selected sounds" "All sounds" ) :menu-item-label-types (:string :string ) :menu-item-states (:active :active ) :menu-item-defaults (t nil ) :initial-selections (nil nil ) :menu-item-handlers (do_stop_selected do_stop_all ) :menu-item-menus (nil nil ) :menu-item-colors ("" "" ) :pinnable nil :user-data () :actions ( ( :from (stop_menu "Selected sounds") :when (Notify ) :to (stop_menu "Selected sounds") :function_type CallFunction :arg_type () :action (do_stop_selected) ) ( :from (stop_menu "All sounds") :when (Notify ) :to (stop_menu "All sounds") :function_type CallFunction :arg_type () :action (do_stop_all) ) ) ) ( :type :menu :name delete_menu :help "" :columns 1 :menu-type :command :menu-handler nil :menu-title "" :menu-item-labels ("Selected sounds" "All sounds" ) :menu-item-label-types (:string :string ) :menu-item-states (:active :active ) :menu-item-defaults (nil nil ) :initial-selections (nil nil ) :menu-item-handlers (playlist_delete playlist_delete_all ) :menu-item-menus (nil nil ) :menu-item-colors ("" "" ) :pinnable nil :user-data () :actions ( ( :from (delete_menu "Selected sounds") :when (Notify ) :to (delete_menu "Selected sounds") :function_type CallFunction :arg_type () :action (playlist_delete) ) ( :from (delete_menu "All sounds") :when (Notify ) :to (delete_menu "All sounds") :function_type CallFunction :arg_type () :action (playlist_delete_all) ) ) ) ( :type :menu :name add_menu :help "" :columns 1 :menu-type :command :menu-handler nil :menu-title "" :menu-item-labels ("Select sound" "All sounds" ) :menu-item-label-types (:string :string ) :menu-item-states (:active :active ) :menu-item-defaults (nil nil ) :initial-selections (nil nil ) :menu-item-handlers (add_sounds add_all_sounds ) :menu-item-menus (nil nil ) :menu-item-colors ("" "" ) :pinnable nil :user-data () :actions ( ( :from (add_menu "Select sound") :when (Notify ) :to (add_menu "Select sound") :function_type CallFunction :arg_type () :action (add_sounds) ) ( :from (add_menu "All sounds") :when (Notify ) :to (add_menu "All sounds") :function_type CallFunction :arg_type () :action (add_all_sounds) ) ) ) ( :type :menu :name playlistfile_menu :help "" :columns 1 :menu-type :command :menu-handler nil :menu-title "" :menu-item-labels ("Load..." "Save..." ) :menu-item-label-types (:string :string ) :menu-item-states (:active :active ) :menu-item-defaults (nil nil ) :initial-selections (nil nil ) :menu-item-handlers (playlistfile_load playlistfile_save ) :menu-item-menus (nil nil ) :menu-item-colors ("" "" ) :pinnable nil :user-data () :actions ( ( :from (playlistfile_menu "Load...") :when (Notify ) :to (playlistfile_menu "Load...") :function_type CallFunction :arg_type () :action (playlistfile_load) ) ( :from (playlistfile_menu "Save...") :when (Notify ) :to (playlistfile_menu "Save...") :function_type CallFunction :arg_type () :action (playlistfile_save) ) ( :from (playlistfile_menu "Load...") :when (Notify ) :to (f) :function_type :user_defined :arg_type () :action (Show) ) ( :from (playlistfile_menu "Save...") :when (Notify ) :to (f) :function_type :user_defined :arg_type () :action (Show) ) ( :from (playlistfile_menu "Load...") :when (Notify ) :to (f) :function_type :user_defined :arg_type (:string) :action (SetLabel "Load a Play List") ) ( :from (playlistfile_menu "Save...") :when (Notify ) :to (f) :function_type :user_defined :arg_type (:string) :action (SetLabel "Save a Play List") ) ( :from (playlistfile_menu "Load...") :when (Notify ) :to (f filedoit) :function_type :user_defined :arg_type (:string) :action (SetLabel "Load") ) ( :from (playlistfile_menu "Save...") :when (Notify ) :to (f filedoit) :function_type :user_defined :arg_type (:string) :action (SetLabel "Save") ) ) ) ( :type :menu :name move_menu :help "" :columns 1 :menu-type :command :menu-handler nil :menu-title "" :menu-item-labels ("Up" "Down" "Top" "Bottom" ) :menu-item-label-types (:string :string :string :string ) :menu-item-states (:active :active :active :active ) :menu-item-defaults (nil nil nil nil ) :initial-selections (nil nil nil nil ) :menu-item-handlers (move_up move_down move_top move_bottom ) :menu-item-menus (nil nil nil nil ) :menu-item-colors ("" "" "" "" ) :pinnable nil :user-data () :actions ( ( :from (move_menu "Bottom") :when (Notify ) :to (move_menu "Bottom") :function_type CallFunction :arg_type () :action (move_bottom) ) ( :from (move_menu "Top") :when (Notify ) :to (move_menu "Top") :function_type CallFunction :arg_type () :action (move_top) ) ( :from (move_menu "Up") :when (Notify ) :to (move_menu "Up") :function_type CallFunction :arg_type () :action (move_up) ) ( :from (move_menu "Down") :when (Notify ) :to (move_menu "Down") :function_type CallFunction :arg_type () :action (move_down) ) ) ) ( :type :base-window :name w :owner nil :width 358 :height 341 :background-color "" :foreground-color "" :label "rplaytool" :label-type :string :initial-state :open :show-footer t :resizable nil :icon-file "icons/rplaytool.icon" :icon-label "" :icon-mask-file "icons/rplaytool_mask.icon" :event-handler nil :user-data () :actions () ) ( :type :control-area :name c :owner w :help "" :x 0 :y 0 :width 358 :height 341 :background-color "" :foreground-color "" :initial-state :visible :show-border nil :menu nil :event-handler nil :user-data () :actions () ) ( :type :button :name file :owner c :help "" :x 16 :y 8 :width 54 :height 19 :constant-width nil :button-type :normal :foreground-color "" :label "File" :label-type :string :initial-state :active :menu file_menu :notify-handler nil :event-handler nil :user-data () :actions () ) ( :type :text-field :name host :owner c :help "" :x 136 :y 16 :width 212 :height 15 :value-x 220 :value-y 16 :value-length 16 :stored-length 80 :rows 3 :foreground-color "" :text-type :alphanumeric :label "Hostname: " :label-type :string :layout-type :horizontal :value-underlined t :initial-value "" :initial-state :active :read-only nil :notify-handler do_host :event-handler nil :user-data () :actions ( ( :from (w host) :when (Notify ) :to (w host) :function_type CallFunction :arg_type () :action (do_host) ) ) ) ( :type :slider :name volume :owner c :help "" :x 152 :y 48 :width 197 :height 39 :value-x 207 :value-y 48 :slider-width 100 :ticks 7 :foreground-color "" :label "Volume:" :label-type :string :layout-type :horizontal :orientation :horizontal :show-endboxes t :show-range nil :show-value nil :min-value 0 :max-value 255 :min-value-string "" :max-value-string "" :min-tick-string "0%" :max-tick-string "100%" :initial-value 0 :initial-state :active :notify-handler do_volume :event-handler nil :user-data () :actions ( ( :from (w volume) :when (Notify ) :to (w volume) :function_type CallFunction :arg_type () :action (do_volume) ) ) ) ( :type :scrolling-list :name spool :owner c :help "" :x 16 :y 96 :width 300 :height 188 :value-x 16 :value-y 113 :rows 8 :foreground-color "" :label "" :title "Spool" :label-type :string :layout-type :vertical :read-only t :multiple-selections t :selection-required nil :initial-state :active :droppable nil :default-drop-site nil :menu nil :notify-handler nil :event-handler nil :initial-list-values () :initial-list-glyphs () :initial-selections () :user-data () :actions () ) ( :type :button :name cont :owner c :help "" :x 70 :y 296 :width 88 :height 19 :constant-width nil :button-type :normal :foreground-color "" :label "Continue" :label-type :string :initial-state :active :menu cont_menu :notify-handler nil :event-handler nil :user-data () :actions () ) ( :type :button :name pause :owner c :help "" :x 160 :y 296 :width 68 :height 19 :constant-width nil :button-type :normal :foreground-color "" :label "Pause" :label-type :string :initial-state :active :menu pause_menu :notify-handler nil :event-handler nil :user-data () :actions () ) ( :type :button :name stop :owner c :help "" :x 230 :y 296 :width 59 :height 19 :constant-width nil :button-type :normal :foreground-color "" :label "Stop" :label-type :string :initial-state :active :menu stop_menu :notify-handler nil :event-handler nil :user-data () :actions () ) ( :type :popup-window :name s :owner w :width 580 :height 391 :background-color "" :foreground-color "" :label "Sounds" :label-type :string :initial-state :invisible :show-footer t :resizable nil :pinned t :done-handler nil :event-handler nil :user-data () :actions () ) ( :type :control-area :name controls7 :owner s :help "" :x 0 :y 0 :width 247 :height 281 :background-color "" :foreground-color "" :initial-state :invisible :show-border nil :menu nil :event-handler nil :user-data () :actions () ) ( :type :text-field :name directory :owner controls7 :help "" :x 8 :y 24 :width 234 :height 15 :value-x 82 :value-y 24 :value-length 20 :stored-length 80 :rows 3 :foreground-color "" :text-type :alphanumeric :label "Directory:" :label-type :string :layout-type :horizontal :value-underlined t :initial-value "" :initial-state :active :read-only nil :notify-handler do_cd :event-handler nil :user-data () :actions ( ( :from (s directory) :when (Notify ) :to (s directory) :function_type CallFunction :arg_type () :action (do_cd) ) ) ) ( :type :scrolling-list :name disklist :owner controls7 :help "" :x 16 :y 48 :width 200 :height 224 :value-x 16 :value-y 48 :rows 10 :foreground-color "" :label "" :title "Disk Sounds" :label-type :string :layout-type :horizontal :read-only t :multiple-selections nil :selection-required nil :initial-state :active :droppable nil :default-drop-site nil :menu nil :notify-handler do_disklist :event-handler nil :initial-list-values () :initial-list-glyphs () :initial-selections () :user-data () :actions ( ( :from (s disklist) :when (Notify ) :to (s disklist) :function_type CallFunction :arg_type () :action (do_disklist) ) ) ) ( :type :control-area :name controls9 :owner s :help "" :x 0 :y 0 :width 247 :height 281 :background-color "" :foreground-color "" :initial-state :visible :show-border nil :menu nil :event-handler nil :user-data () :actions () ) ( :type :scrolling-list :name soundlist :owner controls9 :help "" :x 14 :y 24 :width 200 :height 224 :value-x 14 :value-y 24 :rows 10 :foreground-color "" :label "" :title "Server Sounds" :label-type :string :layout-type :horizontal :read-only t :multiple-selections nil :selection-required nil :initial-state :active :droppable nil :default-drop-site nil :menu nil :notify-handler do_soundlist :event-handler nil :initial-list-values () :initial-list-glyphs () :initial-selections () :user-data () :actions ( ( :from (s soundlist) :when (Notify ) :to (s soundlist) :function_type CallFunction :arg_type () :action (do_soundlist) ) ) ) ( :type :control-area :name controls1 :owner s :help "" :x 247 :y 0 :width 62 :height 391 :background-color "" :foreground-color "" :initial-state :visible :show-border nil :menu nil :event-handler nil :user-data () :actions () ) ( :type :button :name add :owner controls1 :help "" :x 3 :y 112 :width 56 :height 19 :constant-width nil :button-type :normal :foreground-color "" :label "Add" :label-type :string :initial-state :inactive :menu add_menu :notify-handler nil :event-handler nil :user-data () :actions () ) ( :type :button :name close :owner controls1 :help "" :x 4 :y 368 :width 51 :height 19 :constant-width nil :button-type :normal :foreground-color "" :label "Close" :label-type :string :initial-state :active :menu nil :notify-handler nil :event-handler nil :user-data () :actions ( ( :from (s close) :when (Notify ) :to (s) :function_type :user_defined :arg_type () :action (Hide) ) ) ) ( :type :control-area :name controls4 :owner s :help "" :x 309 :y 0 :width 271 :height 257 :background-color "" :foreground-color "" :initial-state :invisible :show-border nil :menu nil :event-handler nil :user-data () :actions () ) ( :type :scrolling-list :name playlist3 :owner controls4 :help "" :x 18 :y 24 :width 200 :height 224 :value-x 18 :value-y 24 :rows 10 :foreground-color "" :label "" :title "User Play List 3" :label-type :string :layout-type :horizontal :read-only t :multiple-selections nil :selection-required nil :initial-state :active :droppable nil :default-drop-site nil :menu nil :notify-handler do_playlist3 :event-handler nil :initial-list-values () :initial-list-glyphs () :initial-selections () :user-data () :actions ( ( :from (s playlist3) :when (Notify ) :to (s playlist3) :function_type CallFunction :arg_type () :action (do_playlist3) ) ) ) ( :type :control-area :name controls5 :owner s :help "" :x 309 :y 0 :width 271 :height 257 :background-color "" :foreground-color "" :initial-state :invisible :show-border nil :menu nil :event-handler nil :user-data () :actions () ) ( :type :scrolling-list :name playlist4 :owner controls5 :help "" :x 18 :y 24 :width 200 :height 224 :value-x 18 :value-y 24 :rows 10 :foreground-color "" :label "" :title "User Play List 4" :label-type :string :layout-type :horizontal :read-only t :multiple-selections nil :selection-required nil :initial-state :active :droppable nil :default-drop-site nil :menu nil :notify-handler do_playlist4 :event-handler nil :initial-list-values () :initial-list-glyphs () :initial-selections () :user-data () :actions ( ( :from (s playlist4) :when (Notify ) :to (s playlist4) :function_type CallFunction :arg_type () :action (do_playlist4) ) ) ) ( :type :control-area :name controls2 :owner s :help "" :x 309 :y 0 :width 271 :height 257 :background-color "" :foreground-color "" :initial-state :visible :show-border nil :menu nil :event-handler nil :user-data () :actions () ) ( :type :scrolling-list :name playlist1 :owner controls2 :help "" :x 18 :y 24 :width 200 :height 224 :value-x 18 :value-y 24 :rows 10 :foreground-color "" :label "" :title "User Play List 1" :label-type :string :layout-type :horizontal :read-only t :multiple-selections nil :selection-required nil :initial-state :active :droppable nil :default-drop-site nil :menu nil :notify-handler do_playlist1 :event-handler nil :initial-list-values () :initial-list-glyphs () :initial-selections () :user-data () :actions ( ( :from (s playlist1) :when (Notify ) :to (s playlist1) :function_type CallFunction :arg_type () :action (do_playlist1) ) ) ) ( :type :control-area :name controls3 :owner s :help "" :x 309 :y 0 :width 271 :height 257 :background-color "" :foreground-color "" :initial-state :invisible :show-border nil :menu nil :event-handler nil :user-data () :actions () ) ( :type :scrolling-list :name playlist2 :owner controls3 :help "" :x 18 :y 24 :width 200 :height 224 :value-x 18 :value-y 24 :rows 10 :foreground-color "" :label "" :title "User Play List 2" :label-type :string :layout-type :horizontal :read-only t :multiple-selections nil :selection-required nil :initial-state :active :droppable nil :default-drop-site nil :menu nil :notify-handler do_playlist2 :event-handler nil :initial-list-values () :initial-list-glyphs () :initial-selections () :user-data () :actions ( ( :from (s playlist2) :when (Notify ) :to (s playlist2) :function_type CallFunction :arg_type () :action (do_playlist2) ) ) ) ( :type :control-area :name controls6 :owner s :help "" :x 309 :y 257 :width 271 :height 134 :background-color "" :foreground-color "" :initial-state :visible :show-border nil :menu nil :event-handler nil :user-data () :actions () ) ( :type :button :name move :owner controls6 :help "" :x 31 :y 16 :width 64 :height 19 :constant-width nil :button-type :normal :foreground-color "" :label "Move" :label-type :string :initial-state :inactive :menu move_menu :notify-handler nil :event-handler nil :user-data () :actions () ) ( :type :button :name delete :owner controls6 :help "" :x 107 :y 16 :width 71 :height 19 :constant-width nil :button-type :normal :foreground-color "" :label "Delete" :label-type :string :initial-state :inactive :menu delete_menu :notify-handler nil :event-handler nil :user-data () :actions () ) ( :type :button :name file :owner controls6 :help "" :x 186 :y 16 :width 54 :height 19 :constant-width nil :button-type :normal :foreground-color "" :label "File" :label-type :string :initial-state :active :menu playlistfile_menu :notify-handler nil :event-handler nil :user-data () :actions () ) ( :type :button :name playit :owner controls6 :help "" :x 32 :y 48 :width 44 :height 19 :constant-width nil :button-type :normal :foreground-color "" :label "Play" :label-type :string :initial-state :active :menu nil :notify-handler do_playit :event-handler nil :user-data () :actions ( ( :from (s playit) :when (Notify ) :to (s playit) :function_type CallFunction :arg_type () :action (do_playit) ) ) ) ( :type :button :name next :owner controls6 :help "" :x 87 :y 48 :width 46 :height 19 :constant-width nil :button-type :normal :foreground-color "" :label "Next" :label-type :string :initial-state :active :menu nil :notify-handler do_next :event-handler nil :user-data () :actions ( ( :from (s next) :when (Notify ) :to (s next) :function_type CallFunction :arg_type () :action (do_next) ) ) ) ( :type :button :name prev :owner controls6 :help "" :x 141 :y 48 :width 45 :height 19 :constant-width nil :button-type :normal :foreground-color "" :label "Prev" :label-type :string :initial-state :active :menu nil :notify-handler do_prev :event-handler nil :user-data () :actions ( ( :from (s prev) :when (Notify ) :to (s prev) :function_type CallFunction :arg_type () :action (do_prev) ) ) ) ( :type :button :name stopit :owner controls6 :help "" :x 194 :y 48 :width 45 :height 19 :constant-width nil :button-type :normal :foreground-color "" :label "Stop" :label-type :string :initial-state :active :menu nil :notify-handler do_stopit :event-handler nil :user-data () :actions ( ( :from (s stopit) :when (Notify ) :to (s stopit) :function_type CallFunction :arg_type () :action (do_stopit) ) ) ) ( :type :setting :name whichlist :owner controls6 :help "" :x 25 :y 80 :width 209 :height 23 :value-x 138 :value-y 80 :rows 1 :columns 0 :layout-type :horizontal :foreground-color "" :setting-type :exclusive :selection-required t :label "Select play list:" :label-type :string :notify-handler switch_playlist :event-handler nil :choices ("1" "2" "3" "4" ) :choice-label-types (:string :string :string :string ) :choice-colors ("" "" "" "" ) :initial-selections (nil nil nil nil ) :initial-state :active :user-data () :actions ( ( :from (s whichlist) :when (Notify ) :to (s whichlist) :function_type CallFunction :arg_type () :action (switch_playlist) ) ( :from (s whichlist "1") :when (Notify ) :to (s controls2) :function_type :user_defined :arg_type () :action (Show) ) ( :from (s whichlist "2") :when (Notify ) :to (s controls3) :function_type :user_defined :arg_type () :action (Show) ) ( :from (s whichlist "3") :when (Notify ) :to (s controls4) :function_type :user_defined :arg_type () :action (Show) ) ( :from (s whichlist "4") :when (Notify ) :to (s controls5) :function_type :user_defined :arg_type () :action (Show) ) ) ) ( :type :control-area :name controls8 :owner s :help "" :x 0 :y 281 :width 247 :height 110 :background-color "" :foreground-color "" :initial-state :visible :show-border nil :menu nil :event-handler nil :user-data () :actions () ) ( :type :button :name sort :owner controls8 :help "" :x 69 :y 16 :width 42 :height 19 :constant-width nil :button-type :normal :foreground-color "" :label "Sort" :label-type :string :initial-state :active :menu nil :notify-handler do_soundsort :event-handler nil :user-data () :actions ( ( :from (s sort) :when (Notify ) :to (s sort) :function_type CallFunction :arg_type () :action (do_soundsort) ) ) ) ( :type :button :name reload :owner controls8 :help "" :x 119 :y 16 :width 59 :height 19 :constant-width nil :button-type :normal :foreground-color "" :label "Reload" :label-type :string :initial-state :active :menu nil :notify-handler do_reload :event-handler nil :user-data () :actions ( ( :from (s reload) :when (Notify ) :to (s reload) :function_type CallFunction :arg_type () :action (do_reload) ) ) ) ( :type :setting :name soundsource :owner controls8 :help "" :x 8 :y 48 :width 224 :height 23 :value-x 136 :value-y 48 :rows 1 :columns 0 :layout-type :horizontal :foreground-color "" :setting-type :exclusive :selection-required t :label "List sounds from:" :label-type :string :notify-handler nil :event-handler nil :choices ("Server" "Disk" ) :choice-label-types (:string :string ) :choice-colors ("" "" ) :initial-selections (t nil ) :initial-state :active :user-data () :actions ( ( :from (s soundsource "Server") :when (Notify ) :to (s controls9) :function_type :user_defined :arg_type () :action (Show) ) ( :from (s soundsource "Disk") :when (Notify ) :to (s controls7) :function_type :user_defined :arg_type () :action (Show) ) ) ) ( :type :stack :name layered_pane1 :owner s :members (controls2 controls4 controls5 controls3 ) :user-data () ) ( :type :stack :name layered_pane2 :owner s :members (controls7 controls9 ) :user-data () ) ( :type :popup-window :name f :owner w :width 344 :height 351 :background-color "" :foreground-color "" :label "" :label-type :string :initial-state :invisible :show-footer nil :resizable nil :pinned t :done-handler nil :event-handler nil :user-data () :actions () ) ( :type :control-area :name controls10 :owner f :help "" :x 0 :y 0 :width 344 :height 351 :background-color "" :foreground-color "" :initial-state :visible :show-border nil :menu nil :event-handler nil :user-data () :actions () ) ( :type :text-field :name filedir :owner controls10 :help "" :x 7 :y 16 :width 330 :height 15 :value-x 81 :value-y 16 :value-length 32 :stored-length 80 :rows 3 :foreground-color "" :text-type :alphanumeric :label "Directory:" :label-type :string :layout-type :horizontal :value-underlined t :initial-value "" :initial-state :active :read-only nil :notify-handler filedir_notify :event-handler nil :user-data () :actions ( ( :from (f filedir) :when (Notify ) :to (f filedir) :function_type CallFunction :arg_type () :action (filedir_notify) ) ) ) ( :type :scrolling-list :name filelist :owner controls10 :help "" :x 13 :y 48 :width 300 :height 200 :value-x 13 :value-y 48 :rows 10 :foreground-color "" :label "" :title "" :label-type :string :layout-type :horizontal :read-only t :multiple-selections nil :selection-required nil :initial-state :active :droppable nil :default-drop-site nil :menu nil :notify-handler filelist_notify :event-handler nil :initial-list-values () :initial-list-glyphs () :initial-selections () :user-data () :actions ( ( :from (f filelist) :when (Notify ) :to (f filelist) :function_type CallFunction :arg_type () :action (filelist_notify) ) ) ) ( :type :text-field :name filename :owner controls10 :help "" :x 26 :y 264 :width 292 :height 15 :value-x 62 :value-y 264 :value-length 32 :stored-length 80 :rows 3 :foreground-color "" :text-type :alphanumeric :label "File:" :label-type :string :layout-type :horizontal :value-underlined t :initial-value "" :initial-state :active :read-only nil :notify-handler filename_notify :event-handler nil :user-data () :actions ( ( :from (f filename) :when (Notify ) :to (f filename) :function_type CallFunction :arg_type () :action (filename_notify) ) ) ) ( :type :button :name filedoit :owner controls10 :help "" :x 147 :y 296 :width 46 :height 19 :constant-width nil :button-type :normal :foreground-color "" :label "Load" :label-type :string :initial-state :active :menu nil :notify-handler filedoit_notify :event-handler nil :user-data () :actions ( ( :from (f filedoit) :when (Notify ) :to (f filedoit) :function_type CallFunction :arg_type () :action (filedoit_notify) ) ) ) ( :type :button :name fileclose :owner controls10 :help "" :x 145 :y 323 :width 51 :height 19 :constant-width nil :button-type :normal :foreground-color "" :label "Close" :label-type :string :initial-state :active :menu nil :notify-handler nil :event-handler nil :user-data () :actions ( ( :from (f fileclose) :when (Notify ) :to (f) :function_type :user_defined :arg_type () :action (Hide) ) ) ) ) rplay-3.3.2/contrib/rplaytool-1.1/rplaytool.P100644 153 62 154 6552756453 17446 0ustar boynsstaff;GIL-3 ( :interfaces (rplaytool.G ) :actions () :root_window nil ) rplay-3.3.2/contrib/rplaytool-1.1/rplaytool.info100644 153 62 205 6552756453 20177 0ustar boynsstaff# # rplaytool.info - User interface object help text. # This file was generated by `gxv' from `rplaytool.G'. # DO NOT EDIT BY HAND. rplay-3.3.2/contrib/rplaytool-1.1/rplaytool.make100644 153 62 264 6552756453 20166 0ustar boynsstaff# This file is generated by `guide' for project `rplaytool.P'. # It is to be included by the Makefile for project `rplaytool.P'. SOURCES.G += rplaytool.G STUBS.G += rplaytool.G rplay-3.3.2/contrib/rplaytool-1.1/rplaytool_stubs.c100644 153 62 147527 6552756453 21011 0ustar boynsstaff/* * rplaytool_stubs.c - Notify and event callback function stubs. * This file was generated by `gxv' from `rplaytool.G'. */ /* * Copyright (C) 1995 Mark Boyns * * This file is part of rplaytool. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #include #include "rplaytool_ui.h" #include #include #include #include #include #include #include "rptp.h" #include "misc.h" #include "getopt.h" static char *rplaytool_version = "1.1"; #define SOUNDLIST_MESSAGE "Retrieving sound list..." void talk (); Notify_value process (); static Notify_value timer_update (/* client, which */); /* * Global object definitions. */ rplaytool_w_objects *Rplaytool_w; rplaytool_s_objects *Rplaytool_s; rplaytool_f_objects *Rplaytool_f; typedef struct { int id; int playlist; } SPOOL; static int spool_size = 0; static int soundlist_size = 0; static int disklist_size = 0; static Xv_opaque curr_soundlist; static char *rptp_host = NULL; static char *playlist1_file = NULL; static char *playlist2_file = NULL; static char *playlist3_file = NULL; static char *playlist4_file = NULL; static int show_sounds = 0; static int use_disk_sounds = 0; static int use_server_sounds = 1; static int scan_playlist_files = 1; static int scan_playlist_interval = 5; /* seconds */ static int countdown = 0; int initial_delay = -1; static struct option longopts[] = { {"delay", required_argument, NULL, 4}, {"disk-sounds", no_argument, NULL, 3}, {"dir", required_argument, NULL, 'd'}, {"help", no_argument, NULL, 1}, {"host", required_argument, NULL, 'h'}, {"playlist1", required_argument, NULL, '1'}, {"playlist2", required_argument, NULL, '2'}, {"playlist3", required_argument, NULL, '3'}, {"playlist4", required_argument, NULL, '4'}, {"server-sounds", no_argument, NULL, 2}, {"sounds", no_argument, &show_sounds, 1}, {"version", no_argument, NULL, 'v'}, {NULL, 0, NULL, 0} }; #ifdef MAIN /* * Instance XV_KEY_DATA key. An instance is a set of related * user interface objects. A pointer to an object's instance * is stored under this key in every object. This must be a * global variable. */ Attr_attribute INSTANCE; main(argc, argv) int argc; char **argv; { int i, c; char title[32]; char *disk_dir = NULL; struct itimerval timer; extern char *optarg; extern int optind, opterr; /* * Initialize XView. */ xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL); INSTANCE = xv_unique_key(); rptp_host = rplay_default_host (); while ((c = getopt_long (argc, argv, "h:1:2:3:4:", longopts, 0)) != -1) { switch (c) { case 0: /* getopt has processed a long-named option -- do nothing */ break; case 1: /* --help */ usage (); case 2: /* --server-sounds */ use_server_sounds++; use_disk_sounds = 0; break; case 3: /* --disk-sounds */ use_server_sounds = 0; use_disk_sounds++; break; case 4: /* --delay */ initial_delay = atoi (optarg); break; case 'd': disk_dir = optarg; use_server_sounds = 0; use_disk_sounds++; show_sounds++; break; case 'h': rptp_host = optarg; break; case '1': playlist1_file = optarg; break; case '2': playlist2_file = optarg; break; case '3': playlist3_file = optarg; break; case '4': playlist4_file = optarg; break; case 'v': printf ("rplaytool %s\n", rplaytool_version); exit (0); default: fprintf (stderr, "Try `rplaytool --help' for more information.\n"); exit (1); } } /* * Initialize user interface components. * Do NOT edit the object initializations by hand. */ Rplaytool_w = rplaytool_w_objects_initialize(NULL, NULL); Rplaytool_s = rplaytool_s_objects_initialize(NULL, Rplaytool_w->w); Rplaytool_f = rplaytool_f_objects_initialize(NULL, Rplaytool_w->w); /* Initialize the playlists. */ for (i = 0; i < NUMBER_OF_PLAYLISTS; i++) { do_playlist_init (i); } playlist[0].list = Rplaytool_s->playlist1; playlist[1].list = Rplaytool_s->playlist2; playlist[2].list = Rplaytool_s->playlist3; playlist[3].list = Rplaytool_s->playlist4; if (playlist1_file) { curr_playlist = 0; file_load_file (playlist1_file); } if (playlist2_file) { curr_playlist = 1; file_load_file (playlist2_file); } if (playlist3_file) { curr_playlist = 2; file_load_file (playlist3_file); } if (playlist4_file) { curr_playlist = 3; file_load_file (playlist4_file); } curr_playlist = 0; curr_soundlist = Rplaytool_s->soundlist; /* Create the icons. */ for (i = 0; i < NUMBER_OF_ICONS; i++) { icons[i].image = (Server_image) xv_create (NULL, SERVER_IMAGE, XV_WIDTH, 16, XV_HEIGHT, 16, SERVER_IMAGE_BITS, icons[i].bits, NULL); } /* Update the frame title. */ sprintf (title, "rplaytool %s", rplaytool_version); xv_set (Rplaytool_w->w, XV_LABEL, title, NULL); /* Connect to the default RPTP server. */ client_id = getpid (); talk (rptp_host); /* Automatically show the "Sounds" popup. */ if (show_sounds) { if (use_server_sounds) { load_soundlist (); } else if (use_disk_sounds) { load_disklist (disk_dir ? disk_dir : 0); } xv_set(Rplaytool_s->s, FRAME_CMD_PUSHPIN_IN, TRUE, NULL); xv_set(Rplaytool_s->s, XV_SHOW, TRUE, NULL); xv_set(Rplaytool_s->soundsource, PANEL_VALUE, use_server_sounds ? 0 : 1, NULL); } /* */ timer.it_value.tv_sec = 1; timer.it_value.tv_usec = 0; timer.it_interval.tv_sec = 1; timer.it_interval.tv_usec = 0; notify_set_itimer_func (Rplaytool_w->w, timer_update, ITIMER_REAL, &timer, NULL); /* * Turn control over to XView. */ xv_main_loop(Rplaytool_w->w); exit(0); } #endif static Notify_value timer_update (client, which) Notify_client client; int which; { static int count; int i; count++; if (scan_playlist_files) { if ((count % scan_playlist_interval) == 0) { playlist_scan (); } } for (i = 0; i < NUMBER_OF_PLAYLISTS; i++) { if (playlist[i].delay >= 0) { if (playlist[i].delay == 0) { play_playlist (i, FALSE); } else { if (countdown) { char line[RPTP_MAX_LINE]; sprintf (line, "%d.au", playlist[i].delay); do_rptp_play (line, NULL); } } playlist[i].delay--; } } } usage () { printf ("\nrplaytool %s\n\n", rplaytool_version); printf ("usage: rplaytool [options]\n"); printf ("--delay=N\n"); printf ("\tDelay N seconds before playing each sound in a playlist.\n"); printf ("\n"); printf ("--dir=DIR\n"); printf ("\tUse DIR as the default disk sounds directory.\n"); printf ("\tThis option implies `--disk-sounds' and `--sounds'.\n"); printf ("\n"); printf ("--disk-sounds\n"); printf ("\tDisplay disk sounds by default in the `Sounds' popup.\n"); printf ("\tThe default is server sounds.\n"); printf ("\n"); printf ("--help\n"); printf ("\tDisplay helpful information.\n"); printf ("\n"); printf ("--host=HOST, -h HOST\n"); printf ("\tSpecify the rplay host, default = %s.\n", rptp_host); printf ("\n"); printf ("--playlist1=FILE, -1 FILE\n"); printf ("\tFILE used for playlist1.\n"); printf ("\n"); printf ("--playlist2=FILE, -2 FILE\n"); printf ("\tFILE used for playlist2.\n"); printf ("\n"); printf ("--playlist3=FILE, -3 FILE\n"); printf ("\tFILE used for playlist3.\n"); printf ("\n"); printf ("--playlist4=FILE, -4 FILE\n"); printf ("\tFILE used for playlist4.\n"); printf ("\n"); printf ("--server-sounds\n"); printf ("\tDisplay server sounds by default in the `Sounds' popup.\n"); printf ("\tThe is the default.\n"); printf ("\n"); printf ("--sounds\n"); printf ("\tAutomatically show the `Sounds' popup.\n"); printf ("\n"); printf ("--version\n"); printf ("\tPrint the rplaytool version and exit.\n"); printf ("\n"); exit (0); } Notify_value process_write (client, fd) Notify_client client; int fd; { rptp_async_process (fd, RPTP_ASYNC_WRITE); return NOTIFY_DONE; } Notify_value process_read (client, fd) Notify_client client; int fd; { rptp_async_process (fd, RPTP_ASYNC_READ); return NOTIFY_DONE; } Notify_client input_client = (Notify_client) 10101; Notify_client output_client = (Notify_client) 20202; void enable_notify_write (fd) int fd; { notify_set_output_func(output_client, process_write, fd); } void disable_notify_write (fd) int fd; { notify_set_output_func(output_client, NOTIFY_FUNC_NULL, fd); } void talk (host) char *host; { static int talking; char buf[1024]; if (talking) { talking = 0; notify_set_input_func(input_client, NOTIFY_FUNC_NULL, rptp_fd); notify_set_output_func(output_client, NOTIFY_FUNC_NULL, rptp_fd); rptp_close (rptp_fd); rptp_fd = -1; } if (!host) { host = rplay_default_host (); } xv_set (Rplaytool_w->host, PANEL_VALUE, host, NULL); sprintf (buf, "Connecting to %s...", host); xv_set (Rplaytool_w->w, FRAME_LEFT_FOOTER, buf, NULL); busy (Rplaytool_w->w, TRUE); do_rptp_open (host); busy (Rplaytool_w->w, FALSE); if (rptp_fd < 0) { rptp_fd = -1; notice (Rplaytool_w->w, NULL, NULL, "Connection to %s failed", host); xv_set (Rplaytool_w->w, FRAME_LEFT_FOOTER, "Not Connected", NULL); } else { notify_set_input_func(input_client, process_read, rptp_fd); talking++; sprintf (buf, "Connected to %s", host); xv_set (Rplaytool_w->w, FRAME_LEFT_FOOTER, buf, NULL); } } void process_input (fd, event, line) int fd; int event; char *line; { int i, n, id, data_index = -1, data_id = -1, state = -1; char buf[RPTP_MAX_LINE], *p, *client_data; SPOOL *sp; rptp_parse (line, 0); p = rptp_parse (0, "id"); if (p) { id = atoi (p+1); } client_data = rptp_parse (0, "client-data"); if (client_data && *client_data) { n = sscanf (client_data, "%d %d %d", &state, &data_id, &data_index); if (n != 3) { state = -1; data_id = -1; data_index = -1; } } switch (event) { case RPTP_EVENT_CLOSE: rptp_async_register (rptp_fd, RPTP_ASYNC_READ, NULL); talk (NULL); break; case RPTP_EVENT_OK: /* A playlist-play OK response. */ if (state == STATE_PLAY && data_index >= 0) { playlist[data_index].id = id; busy (Rplaytool_s->s, FALSE); } break; case RPTP_EVENT_ERROR: /* A playlist-play ERROR response. */ if (state == STATE_PLAY && data_index >= 0) { busy (Rplaytool_s->s, FALSE); } switch (state) { case STATE_PLAY: case STATE_PAUSE: case STATE_CONTINUE: notice (Rplaytool_w->w, NULL, NULL, rptp_parse (0, "error")); break; case STATE_STOP: /* Stops may fail since the sound may finish before the command arrives. Therefore, stop errors are ignored. */ break; } break; case RPTP_EVENT_PLAY: case RPTP_EVENT_PAUSE: case RPTP_EVENT_CONTINUE: { char *sound_name; int found = 0; int use_icon; sound_name = rptp_parse (0, "sound"); p = strrchr (sound_name, '/'); sound_name = p ? p+1 : sound_name; if (event == RPTP_EVENT_CONTINUE || event == RPTP_EVENT_PLAY) { use_icon = ICON_PLAY + ((data_index >= 0) ? data_index+1 : 0); } else { use_icon = ICON_PAUSE + ((data_index >= 0) ? data_index+1 : 0); } sprintf (buf, "%s", sound_name); n = (int) xv_get (Rplaytool_w->spool, PANEL_LIST_NROWS); for (i = 0; i < n; i++) { sp = (SPOOL *) xv_get(Rplaytool_w->spool, PANEL_LIST_CLIENT_DATA, i); if (sp->id == id) { xv_set (Rplaytool_w->spool, PANEL_LIST_STRING, i, buf, PANEL_LIST_GLYPH, i, icons[use_icon].image, NULL); found++; break; } } /* Insert a new sound. */ if (!found) { sp = (SPOOL *) malloc (sizeof (SPOOL)); sp->id = id; sp->playlist = data_index; xv_set (Rplaytool_w->spool, PANEL_LIST_INSERT, spool_size, PANEL_LIST_STRING, spool_size, buf, PANEL_LIST_CLIENT_DATA, spool_size, sp, PANEL_LIST_GLYPH, spool_size, icons[use_icon].image, NULL); spool_size++; } if (data_index >= 0) { playlist_update_icons (data_index); } } break; case RPTP_EVENT_DONE: n = (int) xv_get (Rplaytool_w->spool, PANEL_LIST_NROWS); for (i = 0; i < n; i++) { sp = (SPOOL *) xv_get(Rplaytool_w->spool, PANEL_LIST_CLIENT_DATA, i); if (sp->id == id) { xv_set (Rplaytool_w->spool, PANEL_LIST_DELETE, i, NULL); spool_size--; if (data_id == client_id && sp->playlist >= 0 && playlist[sp->playlist].id == id) { playlist[sp->playlist].id = -1; if (playlist[sp->playlist].auto_play) { playlist[sp->playlist].curr++; play_playlist (sp->playlist, TRUE); } } free ((char *) sp); break; } } break; case RPTP_EVENT_STATE: { int curr_volume, new_volume; int nplaying, npaused; curr_volume = (int) xv_get (Rplaytool_w->volume, PANEL_VALUE); new_volume = atoi (rptp_parse (0, "volume")); if (curr_volume != new_volume) { xv_set (Rplaytool_w->volume, PANEL_VALUE, new_volume, NULL); } nplaying = atoi (rptp_parse (0, "play")); npaused = atoi (rptp_parse (0, "pause")); if (nplaying && !npaused) { xv_set (Rplaytool_w->pause, PANEL_INACTIVE, FALSE, NULL); xv_set (Rplaytool_w->cont, PANEL_INACTIVE, TRUE, NULL); xv_set (Rplaytool_w->stop, PANEL_INACTIVE, FALSE, NULL); } else if (!nplaying && npaused) { xv_set (Rplaytool_w->pause, PANEL_INACTIVE, TRUE, NULL); xv_set (Rplaytool_w->cont, PANEL_INACTIVE, FALSE, NULL); xv_set (Rplaytool_w->stop, PANEL_INACTIVE, FALSE, NULL); } else if (nplaying && npaused) { xv_set (Rplaytool_w->pause, PANEL_INACTIVE, FALSE, NULL); xv_set (Rplaytool_w->cont, PANEL_INACTIVE, FALSE, NULL); xv_set (Rplaytool_w->stop, PANEL_INACTIVE, FALSE, NULL); } else { xv_set (Rplaytool_w->pause, PANEL_INACTIVE, TRUE, NULL); xv_set (Rplaytool_w->cont, PANEL_INACTIVE, TRUE, NULL); xv_set (Rplaytool_w->stop, PANEL_INACTIVE, TRUE, NULL); } } break; case RPTP_EVENT_OTHER: if (strcmp (line, ".") == 0) { xv_set (Rplaytool_s->soundlist, XV_SHOW, TRUE, NULL); xv_set (Rplaytool_s->s, FRAME_LEFT_FOOTER, "", NULL); busy (Rplaytool_s->s, FALSE); } else { xv_set (Rplaytool_s->soundlist, PANEL_LIST_INSERT, soundlist_size, PANEL_LIST_STRING, soundlist_size, rptp_parse (0, "sound"), PANEL_LIST_GLYPH, soundlist_size, icons[ICON_SOUND].image, NULL); soundlist_size++; if ((soundlist_size % 50) == 0) { sprintf (buf, "%s%d", SOUNDLIST_MESSAGE, soundlist_size); xv_set (Rplaytool_s->s, FRAME_LEFT_FOOTER, buf, NULL); } } break; } } load_soundlist () { busy (Rplaytool_s->s, TRUE); xv_set (Rplaytool_s->s, FRAME_LEFT_FOOTER, SOUNDLIST_MESSAGE, NULL); xv_set (Rplaytool_s->soundlist, PANEL_LIST_DELETE_ROWS, 0, (int) xv_get (Rplaytool_s->soundlist, PANEL_LIST_NROWS), NULL); xv_set (Rplaytool_s->soundlist, XV_SHOW, FALSE, NULL); soundlist_size = 0; do_rptp_sounds (); xv_set(Rplaytool_s->controls9, XV_SHOW, TRUE, NULL); /* hack */ curr_soundlist = Rplaytool_s->soundlist; } load_disklist (newdir) char *newdir; { char cwd[MAXPATHLEN]; char *p; DIR *dir; struct dirent *dp; struct stat st; int n; Scrollbar scrollbar; busy (Rplaytool_s->s, TRUE); if (newdir) { chdir (newdir); } getcwd (cwd, sizeof (cwd)); dir = opendir ("."); if (dir == NULL) { exit (1); } xv_set (Rplaytool_s->disklist, PANEL_LIST_DELETE_ROWS, 0, (int) xv_get (Rplaytool_s->disklist, PANEL_LIST_NROWS), NULL); xv_set (Rplaytool_s->disklist, XV_SHOW, FALSE, NULL); disklist_size = 0; /* Put `..' first. */ xv_set (Rplaytool_s->disklist, PANEL_LIST_INSERT, disklist_size, PANEL_LIST_STRING, disklist_size, "..", PANEL_LIST_CLIENT_DATA, disklist_size, 1, /* a directory */ PANEL_LIST_GLYPH, disklist_size, icons[ICON_DIRECTORY].image, NULL); disklist_size++; for (;;) { dp = readdir (dir); if (dp == NULL) { closedir (dir); break; } else if (strcmp (dp->d_name, ".") == 0 || strcmp (dp->d_name, "..") == 0) { continue; } else { p = strrchr (dp->d_name, '.'); stat (dp->d_name, &st); if (S_ISDIR (st.st_mode)) { xv_set (Rplaytool_s->disklist, PANEL_LIST_INSERT, disklist_size, PANEL_LIST_STRING, disklist_size, dp->d_name, PANEL_LIST_CLIENT_DATA, disklist_size, 1, /* a directory */ PANEL_LIST_GLYPH, disklist_size, icons[ICON_DIRECTORY].image, NULL); disklist_size++; } else if (p && (strcmp (p, ".au") == 0 || strcmp (p, ".snd") == 0 || strcmp (p, ".wav") == 0 || strcmp (p, ".aiff") == 0 || strcmp (p, ".voc") == 0 || strcmp (p, ".ub") == 0 || strcmp (p, ".ul") == 0 || strcmp (p, ".g721") == 0 || strcmp (p, ".g723_3") == 0 || strcmp (p, ".g723_5") == 0)) { xv_set (Rplaytool_s->disklist, PANEL_LIST_INSERT, disklist_size, PANEL_LIST_STRING, disklist_size, dp->d_name, PANEL_LIST_CLIENT_DATA, disklist_size, 0, /* a file */ PANEL_LIST_GLYPH, disklist_size, icons[ICON_SOUND].image, NULL); disklist_size++; } } } scrollbar = (Scrollbar) xv_get (Rplaytool_s->disklist, PANEL_LIST_SCROLLBAR); xv_set (scrollbar, SCROLLBAR_VIEW_START, 0, NULL); xv_set (Rplaytool_s->disklist, XV_SHOW, TRUE, NULL); xv_set (Rplaytool_s->directory, PANEL_VALUE, cwd, NULL); xv_set(Rplaytool_s->controls7, XV_SHOW, TRUE, NULL); /* hack */ curr_soundlist = Rplaytool_s->disklist; busy (Rplaytool_s->s, FALSE); } /* * Notify callback function for `volume'. */ void do_volume(item, value, event) Panel_item item; int value; Event *event; { rplaytool_w_objects *ip = (rplaytool_w_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); do_rptp_volume ((int) xv_get (ip->volume, PANEL_VALUE)); /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ } /* * Menu handler for `file_menu (Quit)'. */ Menu_item do_quit(item, op) Menu_item item; Menu_generate op; { rplaytool_w_objects * ip = (rplaytool_w_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); switch (op) { case MENU_DISPLAY: break; case MENU_DISPLAY_DONE: break; case MENU_NOTIFY: if (notice (ip->w, "Yes", "No", "Really Quit?") == 1) { xv_destroy_safe (ip->w); exit (0); } /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ break; case MENU_NOTIFY_DONE: break; } return item; } /* * Notify callback function for `host'. */ Panel_setting do_host(item, event) Panel_item item; Event *event; { rplaytool_w_objects *ip = (rplaytool_w_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); char * value = (char *) xv_get(item, PANEL_VALUE); xv_set (ip->spool, PANEL_LIST_DELETE_ROWS, 0, (int) xv_get (ip->spool, PANEL_LIST_NROWS) - 1, NULL); talk (value); /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ return panel_text_notify(item, event); } /* * Menu handler for `file_menu (Sounds...)'. */ Menu_item rplaytool_file_menu_item0_callback(item, op) Menu_item item; Menu_generate op; { rplaytool_w_objects * ip = (rplaytool_w_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); switch (op) { case MENU_DISPLAY: break; case MENU_DISPLAY_DONE: break; case MENU_NOTIFY: if (use_server_sounds) { load_soundlist (); } else if (use_disk_sounds) { load_disklist (0); } /* gxv_start_connections DO NOT EDIT THIS SECTION */ xv_set(Rplaytool_s->s, FRAME_CMD_PUSHPIN_IN, TRUE, NULL); xv_set(Rplaytool_s->s, XV_SHOW, TRUE, NULL); /* gxv_end_connections */ break; case MENU_NOTIFY_DONE: break; } return item; } /* * Notify callback function for `soundlist'. */ int do_soundlist(item, string, client_data, op, event, row) Panel_item item; char *string; Xv_opaque client_data; Panel_list_op op; Event *event; int row; { rplaytool_s_objects *ip = (rplaytool_s_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); static long prev_click_time = 0; static int prev_row = -1; struct timeval tv; long click_time; if (op == PANEL_LIST_OP_DESELECT || op == PANEL_LIST_OP_SELECT) { gettimeofday (&tv, 0); click_time = tv.tv_sec * 1000 + tv.tv_usec / 1000; if (prev_row == row && (click_time - prev_click_time < 400)) { do_rptp_play (string, NULL); prev_click_time = 0; prev_row = -1; } else { prev_click_time = click_time; prev_row = row; } } switch(op) { case PANEL_LIST_OP_DESELECT: xv_set (ip->add, PANEL_INACTIVE, TRUE, NULL); break; case PANEL_LIST_OP_SELECT: xv_set (ip->add, PANEL_INACTIVE, FALSE, NULL); break; case PANEL_LIST_OP_VALIDATE: break; case PANEL_LIST_OP_DELETE: break; } /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ return XV_OK; } /* * Notify callback function for `close'. */ void rplaytool_s_close_notify_callback(item, event) Panel_item item; Event *event; { rplaytool_s_objects *ip = (rplaytool_s_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); /* gxv_start_connections DO NOT EDIT THIS SECTION */ xv_set(Rplaytool_s->s, FRAME_CMD_PUSHPIN_IN, FALSE, NULL); xv_set(Rplaytool_s->s, XV_SHOW, FALSE, NULL); /* gxv_end_connections */ } /* * Menu handler for `cont_menu (Selected sounds)'. */ Menu_item do_cont_selected(item, op) Menu_item item; Menu_generate op; { rplaytool_w_objects * ip = (rplaytool_w_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); int i; SPOOL *sp; switch (op) { case MENU_DISPLAY: break; case MENU_DISPLAY_DONE: break; case MENU_NOTIFY: for (i = (int) xv_get (ip->spool, PANEL_LIST_FIRST_SELECTED); i != -1; i = (int) xv_get (ip->spool, PANEL_LIST_NEXT_SELECTED, i)) { sp = (SPOOL *) xv_get(ip->spool, PANEL_LIST_CLIENT_DATA, i); do_rptp_cont (sp->id, ""); } /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ break; case MENU_NOTIFY_DONE: break; } return item; } /* * Menu handler for `cont_menu (All sounds)'. */ Menu_item do_cont_all(item, op) Menu_item item; Menu_generate op; { rplaytool_w_objects * ip = (rplaytool_w_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); switch (op) { case MENU_DISPLAY: break; case MENU_DISPLAY_DONE: break; case MENU_NOTIFY: do_rptp_cont (0, ""); /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ break; case MENU_NOTIFY_DONE: break; } return item; } /* * Menu handler for `pause_menu (Selected sounds)'. */ Menu_item do_pause_selected(item, op) Menu_item item; Menu_generate op; { rplaytool_w_objects * ip = (rplaytool_w_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); int i; SPOOL *sp; switch (op) { case MENU_DISPLAY: break; case MENU_DISPLAY_DONE: break; case MENU_NOTIFY: for (i = (int) xv_get (ip->spool, PANEL_LIST_FIRST_SELECTED); i != -1; i = (int) xv_get (ip->spool, PANEL_LIST_NEXT_SELECTED, i)) { sp = (SPOOL *) xv_get(ip->spool, PANEL_LIST_CLIENT_DATA, i); do_rptp_pause (sp->id, ""); } /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ break; case MENU_NOTIFY_DONE: break; } return item; } /* * Menu handler for `pause_menu (All sounds)'. */ Menu_item do_pause_all(item, op) Menu_item item; Menu_generate op; { rplaytool_w_objects * ip = (rplaytool_w_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); switch (op) { case MENU_DISPLAY: break; case MENU_DISPLAY_DONE: break; case MENU_NOTIFY: do_rptp_pause (0, ""); /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ break; case MENU_NOTIFY_DONE: break; } return item; } /* * Menu handler for `stop_menu (Selected sounds)'. */ Menu_item do_stop_selected(item, op) Menu_item item; Menu_generate op; { rplaytool_w_objects * ip = (rplaytool_w_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); int i; SPOOL *sp; switch (op) { case MENU_DISPLAY: break; case MENU_DISPLAY_DONE: break; case MENU_NOTIFY: for (i = (int) xv_get (ip->spool, PANEL_LIST_FIRST_SELECTED); i != -1; i = (int) xv_get (ip->spool, PANEL_LIST_NEXT_SELECTED, i)) { sp = (SPOOL *) xv_get(ip->spool, PANEL_LIST_CLIENT_DATA, i); do_rptp_stop (sp->id, ""); } /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ break; case MENU_NOTIFY_DONE: break; } return item; } /* * Menu handler for `stop_menu (All sounds)'. */ Menu_item do_stop_all(item, op) Menu_item item; Menu_generate op; { rplaytool_w_objects * ip = (rplaytool_w_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); switch (op) { case MENU_DISPLAY: break; case MENU_DISPLAY_DONE: break; case MENU_NOTIFY: do_rptp_stop (0, ""); /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ break; case MENU_NOTIFY_DONE: break; } return item; } /* * Notify callback function for `whichlist'. */ void switch_playlist(item, value, event) Panel_item item; int value; Event *event; { rplaytool_s_objects *ip = (rplaytool_s_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); curr_playlist = value; /* gxv_start_connections DO NOT EDIT THIS SECTION */ if (value == 0) { xv_set(Rplaytool_s->controls2, XV_SHOW, TRUE, NULL); } if (value == 1) { xv_set(Rplaytool_s->controls3, XV_SHOW, TRUE, NULL); } if (value == 2) { xv_set(Rplaytool_s->controls4, XV_SHOW, TRUE, NULL); } if (value == 3) { xv_set(Rplaytool_s->controls5, XV_SHOW, TRUE, NULL); } /* gxv_end_connections */ } /* * Notify callback function for `playit'. */ void do_playit(item, event) Panel_item item; Event *event; { rplaytool_s_objects *ip = (rplaytool_s_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); playlist[curr_playlist].auto_play = 1; if (playlist[curr_playlist].curr == -1) { playlist[curr_playlist].curr = 0; } play_playlist (curr_playlist, TRUE); /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ } /* * Notify callback function for `disklist'. */ int do_disklist(item, string, client_data, op, event, row) Panel_item item; char *string; Xv_opaque client_data; Panel_list_op op; Event *event; int row; { rplaytool_s_objects *ip = (rplaytool_s_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); static long prev_click_time = 0; static int prev_row = -1; struct timeval tv; long click_time; if (op == PANEL_LIST_OP_DESELECT || op == PANEL_LIST_OP_SELECT) { gettimeofday (&tv, 0); click_time = tv.tv_sec * 1000 + tv.tv_usec / 1000; if (prev_row == row && (click_time - prev_click_time < 400)) { /* See if it's a directory */ if ((int) xv_get(ip->disklist, PANEL_LIST_CLIENT_DATA, row)) { load_disklist (string); } else { /* Play the sound */ char buf[RPTP_MAX_LINE]; char *cwd = (char *) xv_get (ip->directory, PANEL_VALUE); sprintf (buf, "%s/%s", cwd, string); do_rptp_play (buf, NULL); } prev_click_time = 0; prev_row = -1; } else { prev_click_time = click_time; prev_row = row; } } switch(op) { case PANEL_LIST_OP_DESELECT: xv_set (ip->add, PANEL_INACTIVE, TRUE, NULL); break; case PANEL_LIST_OP_SELECT: xv_set (ip->add, PANEL_INACTIVE, FALSE, NULL); break; case PANEL_LIST_OP_VALIDATE: break; case PANEL_LIST_OP_DELETE: break; } /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ return XV_OK; } /* * Notify callback function for `playlist3'. */ int do_playlist3(item, string, client_data, op, event, row) Panel_item item; char *string; Xv_opaque client_data; Panel_list_op op; Event *event; int row; { rplaytool_s_objects *ip = (rplaytool_s_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); switch(op) { case PANEL_LIST_OP_DESELECT: xv_set (ip->delete, PANEL_INACTIVE, TRUE, NULL); xv_set (ip->move, PANEL_INACTIVE, TRUE, NULL); break; case PANEL_LIST_OP_SELECT: xv_set (ip->delete, PANEL_INACTIVE, FALSE, NULL); xv_set (ip->move, PANEL_INACTIVE, FALSE, NULL); break; case PANEL_LIST_OP_VALIDATE: break; case PANEL_LIST_OP_DELETE: break; } /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ return XV_OK; } /* * Notify callback function for `playlist4'. */ int do_playlist4(item, string, client_data, op, event, row) Panel_item item; char *string; Xv_opaque client_data; Panel_list_op op; Event *event; int row; { rplaytool_s_objects *ip = (rplaytool_s_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); switch(op) { case PANEL_LIST_OP_DESELECT: xv_set (ip->delete, PANEL_INACTIVE, TRUE, NULL); xv_set (ip->move, PANEL_INACTIVE, TRUE, NULL); break; case PANEL_LIST_OP_SELECT: xv_set (ip->delete, PANEL_INACTIVE, FALSE, NULL); xv_set (ip->move, PANEL_INACTIVE, FALSE, NULL); break; case PANEL_LIST_OP_VALIDATE: break; case PANEL_LIST_OP_DELETE: break; } /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ return XV_OK; } /* * Notify callback function for `playlist1'. */ int do_playlist1(item, string, client_data, op, event, row) Panel_item item; char *string; Xv_opaque client_data; Panel_list_op op; Event *event; int row; { rplaytool_s_objects *ip = (rplaytool_s_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); switch(op) { case PANEL_LIST_OP_DESELECT: xv_set (ip->delete, PANEL_INACTIVE, TRUE, NULL); xv_set (ip->move, PANEL_INACTIVE, TRUE, NULL); break; case PANEL_LIST_OP_SELECT: xv_set (ip->delete, PANEL_INACTIVE, FALSE, NULL); xv_set (ip->move, PANEL_INACTIVE, FALSE, NULL); break; case PANEL_LIST_OP_VALIDATE: break; case PANEL_LIST_OP_DELETE: break; } /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ return XV_OK; } /* * Notify callback function for `playlist2'. */ int do_playlist2(item, string, client_data, op, event, row) Panel_item item; char *string; Xv_opaque client_data; Panel_list_op op; Event *event; int row; { rplaytool_s_objects *ip = (rplaytool_s_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); switch(op) { case PANEL_LIST_OP_DESELECT: xv_set (ip->delete, PANEL_INACTIVE, TRUE, NULL); xv_set (ip->move, PANEL_INACTIVE, TRUE, NULL); break; case PANEL_LIST_OP_SELECT: xv_set (ip->delete, PANEL_INACTIVE, FALSE, NULL); xv_set (ip->move, PANEL_INACTIVE, FALSE, NULL); break; case PANEL_LIST_OP_VALIDATE: break; case PANEL_LIST_OP_DELETE: break; } /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ return XV_OK; } /* * Notify callback function for `soundsource'. */ void rplaytool_s_soundsource_notify_callback(item, value, event) Panel_item item; int value; Event *event; { rplaytool_s_objects *ip = (rplaytool_s_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); if (value == 0) { curr_soundlist = Rplaytool_s->soundlist; load_soundlist (); } else if (value == 1) { curr_soundlist = Rplaytool_s->disklist; load_disklist (0); } /* gxv_start_connections DO NOT EDIT THIS SECTION */ if (value == 0) { xv_set(Rplaytool_s->controls9, XV_SHOW, TRUE, NULL); } if (value == 1) { xv_set(Rplaytool_s->controls7, XV_SHOW, TRUE, NULL); } /* gxv_end_connections */ } /* * Notify callback function for `directory'. */ Panel_setting do_cd(item, event) Panel_item item; Event *event; { rplaytool_s_objects *ip = (rplaytool_s_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); char * value = (char *) xv_get(item, PANEL_VALUE); if (value && *value) { load_disklist (value); } /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ return panel_text_notify(item, event); } /* * Menu handler for `delete_menu (Selected sounds)'. */ Menu_item playlist_delete(item, op) Menu_item item; Menu_generate op; { rplaytool_s_objects * ip = (rplaytool_s_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); int i; char *p; switch (op) { case MENU_DISPLAY: break; case MENU_DISPLAY_DONE: break; case MENU_NOTIFY: for (i = (int) xv_get (playlist[curr_playlist].list, PANEL_LIST_FIRST_SELECTED); i != -1; i = (int) xv_get (playlist[curr_playlist].list, PANEL_LIST_NEXT_SELECTED, i)) { do_playlist_delete (curr_playlist, i); } xv_set (ip->delete, PANEL_INACTIVE, TRUE, NULL); /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ break; case MENU_NOTIFY_DONE: break; } return item; } /* * Menu handler for `delete_menu (All sounds)'. */ Menu_item playlist_delete_all(item, op) Menu_item item; Menu_generate op; { rplaytool_s_objects * ip = (rplaytool_s_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); int i; char *p; switch (op) { case MENU_DISPLAY: break; case MENU_DISPLAY_DONE: break; case MENU_NOTIFY: xv_set (playlist[curr_playlist].list, XV_SHOW, FALSE, NULL); do_playlist_delete_all (curr_playlist); xv_set (ip->delete, PANEL_INACTIVE, TRUE, NULL); xv_set (playlist[curr_playlist].list, XV_SHOW, TRUE, NULL); /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ break; case MENU_NOTIFY_DONE: break; } return item; } /* * Menu handler for `add_menu (Select sound)'. */ Menu_item add_sounds(item, op) Menu_item item; Menu_generate op; { rplaytool_s_objects * ip = (rplaytool_s_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); int i; char *sound, *cwd, *p; char buf[RPTP_MAX_LINE]; switch (op) { case MENU_DISPLAY: break; case MENU_DISPLAY_DONE: break; case MENU_NOTIFY: i = (int) xv_get (curr_soundlist, PANEL_LIST_FIRST_SELECTED); sound = (char *) xv_get (curr_soundlist, PANEL_LIST_STRING, i); if (curr_soundlist == Rplaytool_s->disklist) { if ((int) xv_get(curr_soundlist, PANEL_LIST_CLIENT_DATA, i) == 0) /* a file */ { cwd = (char *) xv_get (ip->directory, PANEL_VALUE); sprintf (buf, "%s", sound); } else { /* ignore directories */ return item; } } else { cwd = ""; sprintf (buf, "%s", sound); } do_playlist_append (curr_playlist, cwd, buf); /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ break; case MENU_NOTIFY_DONE: break; } return item; } /* * Menu handler for `add_menu (All sounds)'. */ Menu_item add_all_sounds(item, op) Menu_item item; Menu_generate op; { rplaytool_s_objects * ip = (rplaytool_s_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); int i, n; char *sound, *cwd, *p; char buf[RPTP_MAX_LINE]; switch (op) { case MENU_DISPLAY: break; case MENU_DISPLAY_DONE: break; case MENU_NOTIFY: busy (Rplaytool_s->s, TRUE); xv_set (playlist[curr_playlist].list, XV_SHOW, FALSE, NULL); n = (int) xv_get (curr_soundlist, PANEL_LIST_NROWS); for (i = 0; i < n; i++) { sound = (char *) xv_get (curr_soundlist, PANEL_LIST_STRING, i); if (curr_soundlist == Rplaytool_s->disklist) { if ((int) xv_get(curr_soundlist, PANEL_LIST_CLIENT_DATA, i) == 0) /* a file */ { cwd = (char *) xv_get (ip->directory, PANEL_VALUE); sprintf (buf, "%s", sound); } else { /* ignore directories */ continue; } } else { cwd = ""; sprintf (buf, "%s", sound); } do_playlist_append (curr_playlist, cwd, buf); } xv_set (playlist[curr_playlist].list, XV_SHOW, TRUE, NULL); busy (Rplaytool_s->s, FALSE); /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ break; case MENU_NOTIFY_DONE: break; } return item; } /* * Notify callback function for `stopit'. */ void do_stopit(item, event) Panel_item item; Event *event; { rplaytool_s_objects *ip = (rplaytool_s_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); if (playlist[curr_playlist].id > 0) { do_playlist_stop (curr_playlist); playlist[curr_playlist].id = -1; playlist[curr_playlist].auto_play = 0; playlist[curr_playlist].curr++; if (playlist[curr_playlist].curr >= playlist[curr_playlist].size) { playlist[curr_playlist].curr = 0; } playlist_update_icons (curr_playlist); } else if (playlist[curr_playlist].delay > 0) { playlist[curr_playlist].delay = -1; playlist[curr_playlist].id = -1; playlist[curr_playlist].auto_play = 0; playlist[curr_playlist].curr++; if (playlist[curr_playlist].curr >= playlist[curr_playlist].size) { playlist[curr_playlist].curr = 0; } playlist_update_icons (curr_playlist); } /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ } /* * Notify callback function for `sort'. */ void do_soundsort(item, event) Panel_item item; Event *event; { rplaytool_s_objects *ip = (rplaytool_s_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); busy (ip->s, TRUE); sort_list (curr_soundlist); busy (ip->s, FALSE); /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ } /* * Notify callback function for `reload'. */ void do_reload(item, event) Panel_item item; Event *event; { rplaytool_s_objects *ip = (rplaytool_s_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); if (curr_soundlist == Rplaytool_s->disklist) { load_disklist (0); } else { load_soundlist (); } /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ } /* Load a file into curr_playlist. */ int file_load_file (file) char *file; { FILE *fp; fp = fopen (file, "r"); if (fp == NULL) { notice (Rplaytool_f->f, NULL, NULL, "Can't read %s", file); return -1; } /* Make sure playlist files are stored with complete pathnames. */ if (file[0] != '/') { char cwd[MAXPATHLEN]; getcwd (cwd, sizeof (cwd)); sprintf (playlist[curr_playlist].filename, "%s/%s", cwd, file); } else { strcpy (playlist[curr_playlist].filename, file); } busy (Rplaytool_f->f, TRUE); xv_set (playlist[curr_playlist].list, XV_SHOW, FALSE, NULL); do_playlist_delete_all (curr_playlist); do_playlist_load (curr_playlist, fp); fclose (fp); xv_set (playlist[curr_playlist].list, XV_SHOW, TRUE, NULL); busy (Rplaytool_f->f, FALSE); return 0; } /* Save curr_playlist in a file. */ file_save_file (file) char *file; { FILE *fp; INFO *info; int i; if (access (file, R_OK) == 0) { if (notice (Rplaytool_f->f, "Yes", "No", "Overwrite %s?", file) == 2) { return; } } fp = fopen (file, "w"); if (fp == NULL) { notice (Rplaytool_f->f, NULL, NULL, "Can't create %s", file); return; } busy (Rplaytool_f->f, TRUE); do_playlist_save (curr_playlist, fp); fclose (fp); busy (Rplaytool_f->f, FALSE); } /* Load a directory into the filelist popup. */ file_load_dir (new_dir) char *new_dir; { char cwd[MAXPATHLEN]; DIR *dir; struct dirent *dp; struct stat st; int row; Scrollbar scrollbar; busy (Rplaytool_f->f, TRUE); if (new_dir) { chdir (new_dir); } getcwd (cwd, sizeof (cwd)); dir = opendir ("."); if (dir == NULL) { exit (1); } xv_set (Rplaytool_f->filelist, PANEL_LIST_DELETE_ROWS, 0, (int) xv_get (Rplaytool_f->filelist, PANEL_LIST_NROWS), NULL); xv_set (Rplaytool_f->filelist, XV_SHOW, FALSE, NULL); row = 0; xv_set (Rplaytool_f->filelist, PANEL_LIST_INSERT, row, PANEL_LIST_STRING, row, "..", PANEL_LIST_CLIENT_DATA, row, 1, /* a directory */ PANEL_LIST_GLYPH, row, icons[ICON_DIRECTORY].image, NULL); row++; for (;;) { dp = readdir (dir); if (dp == NULL) { closedir (dir); break; } else if (strcmp (dp->d_name, ".") == 0 || strcmp (dp->d_name, "..") == 0) { continue; } else { stat (dp->d_name, &st); if (S_ISDIR (st.st_mode)) { xv_set (Rplaytool_f->filelist, PANEL_LIST_INSERT, row, PANEL_LIST_STRING, row, dp->d_name, PANEL_LIST_CLIENT_DATA, row, 1, /* a directory */ PANEL_LIST_GLYPH, row, icons[ICON_DIRECTORY].image, NULL); } else { xv_set (Rplaytool_f->filelist, PANEL_LIST_INSERT, row, PANEL_LIST_STRING, row, dp->d_name, PANEL_LIST_CLIENT_DATA, row, 0, /* a file */ PANEL_LIST_GLYPH, row, icons[ICON_FILE].image, NULL); } row++; } } scrollbar = (Scrollbar) xv_get (Rplaytool_f->filelist, PANEL_LIST_SCROLLBAR); xv_set (scrollbar, SCROLLBAR_VIEW_START, 0, NULL); xv_set (Rplaytool_f->filelist, XV_SHOW, TRUE, NULL); xv_set (Rplaytool_f->filedir, PANEL_VALUE, cwd, NULL); busy (Rplaytool_f->f, FALSE); } /* * Notify callback function for `filedir'. */ Panel_setting filedir_notify(item, event) Panel_item item; Event *event; { rplaytool_f_objects *ip = (rplaytool_f_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); char * value = (char *) xv_get(item, PANEL_VALUE); file_load_dir (value); /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ return panel_text_notify(item, event); } /* * Notify callback function for `filelist'. */ int filelist_notify(item, string, client_data, op, event, row) Panel_item item; char *string; Xv_opaque client_data; Panel_list_op op; Event *event; int row; { rplaytool_f_objects *ip = (rplaytool_f_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); static long prev_click_time; struct timeval tv; long click_time; gettimeofday (&tv, 0); click_time = tv.tv_sec * 1000 + tv.tv_usec / 1000; switch(op) { case PANEL_LIST_OP_DESELECT: if (click_time - prev_click_time < 400) { /* See if it's a directory */ if ((int) xv_get(ip->filelist, PANEL_LIST_CLIENT_DATA, row)) { file_load_dir (string); } prev_click_time = 0; } break; case PANEL_LIST_OP_SELECT: if ((int) xv_get(ip->filelist, PANEL_LIST_CLIENT_DATA, row) == 0) /* a file */ { xv_set (ip->filename, PANEL_VALUE, string, NULL); } prev_click_time = click_time; break; case PANEL_LIST_OP_VALIDATE: break; case PANEL_LIST_OP_DELETE: break; } /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ return XV_OK; } /* * Notify callback function for `filename'. */ Panel_setting filename_notify(item, event) Panel_item item; Event *event; { rplaytool_f_objects *ip = (rplaytool_f_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); char *value = (char *) xv_get(item, PANEL_VALUE); char *dir = (char *) xv_get (ip->filedir, PANEL_VALUE); char *label; char filename[MAXPATHLEN]; sprintf (filename, "%s/%s", dir, value); label = (char *) xv_get (ip->filedoit, PANEL_LABEL_STRING, NULL); if (strcmp (label, "Load") == 0) { file_load_file (filename); } else if (strcmp (label, "Save") == 0) { file_save_file (filename); } /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ return panel_text_notify(item, event); } /* * Notify callback function for `filedoit'. */ void filedoit_notify(item, event) Panel_item item; Event *event; { rplaytool_f_objects *ip = (rplaytool_f_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); char *value = (char *) xv_get (ip->filename, PANEL_VALUE); char *dir = (char *) xv_get (ip->filedir, PANEL_VALUE); char *label; char filename[MAXPATHLEN]; sprintf (filename, "%s/%s", dir, value); label = (char *) xv_get (ip->filedoit, PANEL_LABEL_STRING, NULL); if (strcmp (label, "Load") == 0) { file_load_file (filename); } else if (strcmp (label, "Save") == 0) { file_save_file (filename); } /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ } /* * Notify callback function for `fileclose'. */ void rplaytool_f_fileclose_notify_callback(item, event) Panel_item item; Event *event; { rplaytool_f_objects *ip = (rplaytool_f_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); /* gxv_start_connections DO NOT EDIT THIS SECTION */ xv_set(Rplaytool_f->f, FRAME_CMD_PUSHPIN_IN, FALSE, NULL); xv_set(Rplaytool_f->f, XV_SHOW, FALSE, NULL); /* gxv_end_connections */ } /* * Menu handler for `playlistfile_menu (Load...)'. */ Menu_item playlistfile_load(item, op) Menu_item item; Menu_generate op; { rplaytool_s_objects * ip = (rplaytool_s_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); switch (op) { case MENU_DISPLAY: break; case MENU_DISPLAY_DONE: break; case MENU_NOTIFY: if (playlist[curr_playlist].filename[0] == '\0') { file_load_dir (NULL); } else { char *p, filename[MAXPATHLEN]; strcpy (filename, playlist[curr_playlist].filename); p = strrchr (filename, '/'); if (p && p[1]) { *p++ = '\0'; xv_set (Rplaytool_f->filename, PANEL_VALUE, p); file_load_dir (filename); } else { file_load_dir (NULL); } } /* gxv_start_connections DO NOT EDIT THIS SECTION */ xv_set(Rplaytool_f->f, FRAME_CMD_PUSHPIN_IN, TRUE, NULL); xv_set(Rplaytool_f->f, XV_SHOW, TRUE, NULL); xv_set(Rplaytool_f->f, XV_LABEL, "Load a Play List", NULL); xv_set(Rplaytool_f->filedoit, PANEL_LABEL_STRING, "Load", NULL); /* gxv_end_connections */ break; case MENU_NOTIFY_DONE: break; } return item; } /* * Menu handler for `playlistfile_menu (Save...)'. */ Menu_item playlistfile_save(item, op) Menu_item item; Menu_generate op; { rplaytool_s_objects * ip = (rplaytool_s_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); switch (op) { case MENU_DISPLAY: break; case MENU_DISPLAY_DONE: break; case MENU_NOTIFY: if (playlist[curr_playlist].filename[0] == '\0') { file_load_dir (NULL); } else { char *p, filename[MAXPATHLEN]; strcpy (filename, playlist[curr_playlist].filename); p = strrchr (filename, '/'); if (p && p[1]) { *p++ = '\0'; xv_set (Rplaytool_f->filename, PANEL_VALUE, p); file_load_dir (filename); } else { file_load_dir (NULL); } } /* gxv_start_connections DO NOT EDIT THIS SECTION */ xv_set(Rplaytool_f->f, FRAME_CMD_PUSHPIN_IN, TRUE, NULL); xv_set(Rplaytool_f->f, XV_SHOW, TRUE, NULL); xv_set(Rplaytool_f->f, XV_LABEL, "Save a Play List", NULL); xv_set(Rplaytool_f->filedoit, PANEL_LABEL_STRING, "Save", NULL); /* gxv_end_connections */ break; case MENU_NOTIFY_DONE: break; } return item; } /* * Menu handler for `move_menu (Up)'. */ Menu_item move_up(item, op) Menu_item item; Menu_generate op; { rplaytool_s_objects * ip = (rplaytool_s_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); int i; switch (op) { case MENU_DISPLAY: break; case MENU_DISPLAY_DONE: break; case MENU_NOTIFY: i = (int) xv_get (playlist[curr_playlist].list, PANEL_LIST_FIRST_SELECTED); if (i > 0) { do_playlist_move (curr_playlist, i, i-1); xv_set (playlist[curr_playlist].list, PANEL_LIST_SELECT, i-1, TRUE, NULL); } /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ break; case MENU_NOTIFY_DONE: break; } return item; } /* * Menu handler for `move_menu (Down)'. */ Menu_item move_down(item, op) Menu_item item; Menu_generate op; { rplaytool_s_objects * ip = (rplaytool_s_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); int i; switch (op) { case MENU_DISPLAY: break; case MENU_DISPLAY_DONE: break; case MENU_NOTIFY: i = (int) xv_get (playlist[curr_playlist].list, PANEL_LIST_FIRST_SELECTED); if (i < playlist[curr_playlist].size - 1) { do_playlist_move (curr_playlist, i, i+1); xv_set (playlist[curr_playlist].list, PANEL_LIST_SELECT, i+1, TRUE, NULL); } /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ break; case MENU_NOTIFY_DONE: break; } return item; } /* * Menu handler for `move_menu (Top)'. */ Menu_item move_top(item, op) Menu_item item; Menu_generate op; { rplaytool_s_objects * ip = (rplaytool_s_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); int i; switch (op) { case MENU_DISPLAY: break; case MENU_DISPLAY_DONE: break; case MENU_NOTIFY: xv_set (playlist[curr_playlist].list, XV_SHOW, FALSE, NULL); i = (int) xv_get (playlist[curr_playlist].list, PANEL_LIST_FIRST_SELECTED); while (i > 0) { do_playlist_move (curr_playlist, i, i-1); i--; } xv_set (playlist[curr_playlist].list, PANEL_LIST_SELECT, 0, TRUE, NULL); xv_set (playlist[curr_playlist].list, XV_SHOW, TRUE, NULL); /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ break; case MENU_NOTIFY_DONE: break; } return item; } /* * Menu handler for `move_menu (Bottom)'. */ Menu_item move_bottom(item, op) Menu_item item; Menu_generate op; { rplaytool_s_objects * ip = (rplaytool_s_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); int i; switch (op) { case MENU_DISPLAY: break; case MENU_DISPLAY_DONE: break; case MENU_NOTIFY: xv_set (playlist[curr_playlist].list, XV_SHOW, FALSE, NULL); i = (int) xv_get (playlist[curr_playlist].list, PANEL_LIST_FIRST_SELECTED); while (i < playlist[curr_playlist].size-1) { do_playlist_move (curr_playlist, i, i+1); i++; } xv_set (playlist[curr_playlist].list, PANEL_LIST_SELECT, playlist[curr_playlist].size-1, TRUE, NULL); xv_set (playlist[curr_playlist].list, XV_SHOW, TRUE, NULL); /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ break; case MENU_NOTIFY_DONE: break; } return item; } /* * Notify callback function for `next'. */ void do_next(item, event) Panel_item item; Event *event; { rplaytool_s_objects *ip = (rplaytool_s_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); if (playlist[curr_playlist].id > 0 || playlist[curr_playlist].delay > 0) { do_playlist_stop (curr_playlist); playlist[curr_playlist].auto_play = 1; playlist[curr_playlist].curr++; if (playlist[curr_playlist].curr >= playlist[curr_playlist].size) { playlist[curr_playlist].curr = 0; } play_playlist (curr_playlist, TRUE); } else { if (playlist[curr_playlist].curr == -1) { playlist[curr_playlist].curr = 0; } playlist[curr_playlist].curr++; if (playlist[curr_playlist].curr >= playlist[curr_playlist].size) { playlist[curr_playlist].curr = 0; } playlist_update_icons (curr_playlist); } /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ } /* * Notify callback function for `prev'. */ void do_prev(item, event) Panel_item item; Event *event; { rplaytool_s_objects *ip = (rplaytool_s_objects *) xv_get(item, XV_KEY_DATA, INSTANCE); if (playlist[curr_playlist].id > 0 || playlist[curr_playlist].delay > 0) { do_playlist_stop (curr_playlist); playlist[curr_playlist].auto_play = 1; playlist[curr_playlist].curr--; if (playlist[curr_playlist].curr < 0) { playlist[curr_playlist].curr = playlist[curr_playlist].size - 1; } play_playlist (curr_playlist, TRUE); } else { playlist[curr_playlist].curr--; if (playlist[curr_playlist].curr < 0) { playlist[curr_playlist].curr = playlist[curr_playlist].size - 1; } playlist_update_icons (curr_playlist); } /* gxv_start_connections DO NOT EDIT THIS SECTION */ /* gxv_end_connections */ } rplay-3.3.2/contrib/rplaytool-1.1/rplaytool_ui.c100644 153 62 75042 6552756453 20236 0ustar boynsstaff/* * rplaytool_ui.c - User interface object initialization functions. * This file was generated by `gxv' from `rplaytool.G'. * DO NOT EDIT BY HAND. */ #include #include #include #include #include #include #include #include #include #include #include #include #include "rplaytool_ui.h" /* * Create object `file_menu' in the specified instance. */ Xv_opaque rplaytool_file_menu_create(ip, owner) caddr_t ip; Xv_opaque owner; { extern Menu_item rplaytool_file_menu_item0_callback(); extern Menu_item do_quit(); Xv_opaque obj; obj = xv_create(XV_NULL, MENU_COMMAND_MENU, XV_KEY_DATA, INSTANCE, ip, MENU_ITEM, XV_KEY_DATA, INSTANCE, ip, MENU_STRING, "Sounds...", MENU_GEN_PROC, rplaytool_file_menu_item0_callback, NULL, MENU_ITEM, XV_KEY_DATA, INSTANCE, ip, MENU_STRING, "Quit", MENU_GEN_PROC, do_quit, NULL, NULL); return obj; } /* * Create object `cont_menu' in the specified instance. */ Xv_opaque rplaytool_cont_menu_create(ip, owner) caddr_t ip; Xv_opaque owner; { extern Menu_item do_cont_selected(); extern Menu_item do_cont_all(); Xv_opaque obj; obj = xv_create(XV_NULL, MENU_COMMAND_MENU, XV_KEY_DATA, INSTANCE, ip, MENU_ITEM, XV_KEY_DATA, INSTANCE, ip, MENU_STRING, "Selected sounds", MENU_GEN_PROC, do_cont_selected, NULL, MENU_ITEM, XV_KEY_DATA, INSTANCE, ip, MENU_STRING, "All sounds", MENU_GEN_PROC, do_cont_all, NULL, MENU_DEFAULT, 1, NULL); return obj; } /* * Create object `pause_menu' in the specified instance. */ Xv_opaque rplaytool_pause_menu_create(ip, owner) caddr_t ip; Xv_opaque owner; { extern Menu_item do_pause_selected(); extern Menu_item do_pause_all(); Xv_opaque obj; obj = xv_create(XV_NULL, MENU_COMMAND_MENU, XV_KEY_DATA, INSTANCE, ip, MENU_ITEM, XV_KEY_DATA, INSTANCE, ip, MENU_STRING, "Selected sounds", MENU_GEN_PROC, do_pause_selected, NULL, MENU_ITEM, XV_KEY_DATA, INSTANCE, ip, MENU_STRING, "All sounds", MENU_GEN_PROC, do_pause_all, NULL, MENU_DEFAULT, 1, NULL); return obj; } /* * Create object `stop_menu' in the specified instance. */ Xv_opaque rplaytool_stop_menu_create(ip, owner) caddr_t ip; Xv_opaque owner; { extern Menu_item do_stop_selected(); extern Menu_item do_stop_all(); Xv_opaque obj; obj = xv_create(XV_NULL, MENU_COMMAND_MENU, XV_KEY_DATA, INSTANCE, ip, MENU_ITEM, XV_KEY_DATA, INSTANCE, ip, MENU_STRING, "Selected sounds", MENU_GEN_PROC, do_stop_selected, NULL, MENU_ITEM, XV_KEY_DATA, INSTANCE, ip, MENU_STRING, "All sounds", MENU_GEN_PROC, do_stop_all, NULL, MENU_DEFAULT, 1, NULL); return obj; } /* * Create object `delete_menu' in the specified instance. */ Xv_opaque rplaytool_delete_menu_create(ip, owner) caddr_t ip; Xv_opaque owner; { extern Menu_item playlist_delete(); extern Menu_item playlist_delete_all(); Xv_opaque obj; obj = xv_create(XV_NULL, MENU_COMMAND_MENU, XV_KEY_DATA, INSTANCE, ip, MENU_ITEM, XV_KEY_DATA, INSTANCE, ip, MENU_STRING, "Selected sounds", MENU_GEN_PROC, playlist_delete, NULL, MENU_ITEM, XV_KEY_DATA, INSTANCE, ip, MENU_STRING, "All sounds", MENU_GEN_PROC, playlist_delete_all, NULL, NULL); return obj; } /* * Create object `add_menu' in the specified instance. */ Xv_opaque rplaytool_add_menu_create(ip, owner) caddr_t ip; Xv_opaque owner; { extern Menu_item add_sounds(); extern Menu_item add_all_sounds(); Xv_opaque obj; obj = xv_create(XV_NULL, MENU_COMMAND_MENU, XV_KEY_DATA, INSTANCE, ip, MENU_ITEM, XV_KEY_DATA, INSTANCE, ip, MENU_STRING, "Select sound", MENU_GEN_PROC, add_sounds, NULL, MENU_ITEM, XV_KEY_DATA, INSTANCE, ip, MENU_STRING, "All sounds", MENU_GEN_PROC, add_all_sounds, NULL, NULL); return obj; } /* * Create object `playlistfile_menu' in the specified instance. */ Xv_opaque rplaytool_playlistfile_menu_create(ip, owner) caddr_t ip; Xv_opaque owner; { extern Menu_item playlistfile_load(); extern Menu_item playlistfile_save(); Xv_opaque obj; obj = xv_create(XV_NULL, MENU_COMMAND_MENU, XV_KEY_DATA, INSTANCE, ip, MENU_ITEM, XV_KEY_DATA, INSTANCE, ip, MENU_STRING, "Load...", MENU_GEN_PROC, playlistfile_load, NULL, MENU_ITEM, XV_KEY_DATA, INSTANCE, ip, MENU_STRING, "Save...", MENU_GEN_PROC, playlistfile_save, NULL, NULL); return obj; } /* * Create object `move_menu' in the specified instance. */ Xv_opaque rplaytool_move_menu_create(ip, owner) caddr_t ip; Xv_opaque owner; { extern Menu_item move_up(); extern Menu_item move_down(); extern Menu_item move_top(); extern Menu_item move_bottom(); Xv_opaque obj; obj = xv_create(XV_NULL, MENU_COMMAND_MENU, XV_KEY_DATA, INSTANCE, ip, MENU_ITEM, XV_KEY_DATA, INSTANCE, ip, MENU_STRING, "Up", MENU_GEN_PROC, move_up, NULL, MENU_ITEM, XV_KEY_DATA, INSTANCE, ip, MENU_STRING, "Down", MENU_GEN_PROC, move_down, NULL, MENU_ITEM, XV_KEY_DATA, INSTANCE, ip, MENU_STRING, "Top", MENU_GEN_PROC, move_top, NULL, MENU_ITEM, XV_KEY_DATA, INSTANCE, ip, MENU_STRING, "Bottom", MENU_GEN_PROC, move_bottom, NULL, NULL); return obj; } /* * Initialize an instance of object `w'. */ rplaytool_w_objects * rplaytool_w_objects_initialize(ip, owner) rplaytool_w_objects *ip; Xv_opaque owner; { if (!ip && !(ip = (rplaytool_w_objects *) calloc(1, sizeof (rplaytool_w_objects)))) return (rplaytool_w_objects *) NULL; if (!ip->w) ip->w = rplaytool_w_w_create(ip, owner); if (!ip->c) ip->c = rplaytool_w_c_create(ip, ip->w); if (!ip->file) ip->file = rplaytool_w_file_create(ip, ip->c); if (!ip->host) ip->host = rplaytool_w_host_create(ip, ip->c); if (!ip->volume) ip->volume = rplaytool_w_volume_create(ip, ip->c); if (!ip->spool) ip->spool = rplaytool_w_spool_create(ip, ip->c); if (!ip->cont) ip->cont = rplaytool_w_cont_create(ip, ip->c); if (!ip->pause) ip->pause = rplaytool_w_pause_create(ip, ip->c); if (!ip->stop) ip->stop = rplaytool_w_stop_create(ip, ip->c); return ip; } /* * Create object `w' in the specified instance. */ Xv_opaque rplaytool_w_w_create(ip, owner) rplaytool_w_objects *ip; Xv_opaque owner; { Xv_opaque obj; Xv_opaque w_image; static unsigned short w_bits[] = { #include "icons/rplaytool.icon" }; Xv_opaque w_image_mask; static unsigned short w_mask_bits[] = { #include "icons/rplaytool_mask.icon" }; w_image = xv_create(XV_NULL, SERVER_IMAGE, SERVER_IMAGE_DEPTH, 1, SERVER_IMAGE_BITS, w_bits, XV_WIDTH, 64, XV_HEIGHT, 64, NULL); w_image_mask = xv_create(XV_NULL, SERVER_IMAGE, SERVER_IMAGE_DEPTH, 1, SERVER_IMAGE_BITS, w_mask_bits, XV_WIDTH, 64, XV_HEIGHT, 64, NULL); obj = xv_create(owner, FRAME, XV_KEY_DATA, INSTANCE, ip, XV_WIDTH, 358, XV_HEIGHT, 341, XV_LABEL, "rplaytool", FRAME_SHOW_FOOTER, TRUE, FRAME_SHOW_RESIZE_CORNER, FALSE, FRAME_ICON, xv_create(XV_NULL, ICON, ICON_IMAGE, w_image, ICON_MASK_IMAGE, w_image_mask, NULL), NULL); return obj; } /* * Create object `c' in the specified instance. */ Xv_opaque rplaytool_w_c_create(ip, owner) rplaytool_w_objects *ip; Xv_opaque owner; { Xv_opaque obj; obj = xv_create(owner, PANEL, XV_KEY_DATA, INSTANCE, ip, XV_X, 0, XV_Y, 0, XV_WIDTH, WIN_EXTEND_TO_EDGE, XV_HEIGHT, WIN_EXTEND_TO_EDGE, WIN_BORDER, FALSE, NULL); return obj; } /* * Create object `file' in the specified instance. */ Xv_opaque rplaytool_w_file_create(ip, owner) rplaytool_w_objects *ip; Xv_opaque owner; { Xv_opaque obj; obj = xv_create(owner, PANEL_BUTTON, XV_KEY_DATA, INSTANCE, ip, XV_X, 16, XV_Y, 8, PANEL_LABEL_STRING, "File", PANEL_ITEM_MENU, rplaytool_file_menu_create((caddr_t) ip, ip->w), NULL); return obj; } /* * Create object `host' in the specified instance. */ Xv_opaque rplaytool_w_host_create(ip, owner) rplaytool_w_objects *ip; Xv_opaque owner; { extern Panel_setting do_host(); Xv_opaque obj; obj = xv_create(owner, PANEL_TEXT, XV_KEY_DATA, INSTANCE, ip, XV_X, 136, XV_Y, 16, PANEL_VALUE_DISPLAY_LENGTH, 16, PANEL_VALUE_STORED_LENGTH, 80, PANEL_LABEL_STRING, "Hostname: ", PANEL_LAYOUT, PANEL_HORIZONTAL, PANEL_READ_ONLY, FALSE, PANEL_NOTIFY_PROC, do_host, NULL); return obj; } /* * Create object `volume' in the specified instance. */ Xv_opaque rplaytool_w_volume_create(ip, owner) rplaytool_w_objects *ip; Xv_opaque owner; { extern void do_volume(); Xv_opaque obj; obj = xv_create(owner, PANEL_SLIDER, XV_KEY_DATA, INSTANCE, ip, XV_X, 152, XV_Y, 48, PANEL_SLIDER_WIDTH, 100, PANEL_TICKS, 7, PANEL_LABEL_STRING, "Volume:", PANEL_DIRECTION, PANEL_HORIZONTAL, PANEL_SLIDER_END_BOXES, TRUE, PANEL_SHOW_RANGE, FALSE, PANEL_SHOW_VALUE, FALSE, PANEL_MIN_VALUE, 0, PANEL_MAX_VALUE, 255, PANEL_MIN_TICK_STRING, "0%", PANEL_MAX_TICK_STRING, "100%", PANEL_VALUE, 0, PANEL_NOTIFY_PROC, do_volume, NULL); return obj; } /* * Create object `spool' in the specified instance. */ Xv_opaque rplaytool_w_spool_create(ip, owner) rplaytool_w_objects *ip; Xv_opaque owner; { Xv_opaque obj; obj = xv_create(owner, PANEL_LIST, XV_KEY_DATA, INSTANCE, ip, XV_X, 16, XV_Y, 96, PANEL_LIST_WIDTH, 300, PANEL_LIST_DISPLAY_ROWS, 8, PANEL_LIST_TITLE, "Spool", PANEL_LAYOUT, PANEL_VERTICAL, PANEL_READ_ONLY, TRUE, PANEL_CHOOSE_ONE, FALSE, PANEL_CHOOSE_NONE, TRUE, NULL); return obj; } /* * Create object `cont' in the specified instance. */ Xv_opaque rplaytool_w_cont_create(ip, owner) rplaytool_w_objects *ip; Xv_opaque owner; { Xv_opaque obj; obj = xv_create(owner, PANEL_BUTTON, XV_KEY_DATA, INSTANCE, ip, XV_X, 70, XV_Y, 296, PANEL_LABEL_STRING, "Continue", PANEL_ITEM_MENU, rplaytool_cont_menu_create((caddr_t) ip, ip->w), NULL); return obj; } /* * Create object `pause' in the specified instance. */ Xv_opaque rplaytool_w_pause_create(ip, owner) rplaytool_w_objects *ip; Xv_opaque owner; { Xv_opaque obj; obj = xv_create(owner, PANEL_BUTTON, XV_KEY_DATA, INSTANCE, ip, XV_X, 160, XV_Y, 296, PANEL_LABEL_STRING, "Pause", PANEL_ITEM_MENU, rplaytool_pause_menu_create((caddr_t) ip, ip->w), NULL); return obj; } /* * Create object `stop' in the specified instance. */ Xv_opaque rplaytool_w_stop_create(ip, owner) rplaytool_w_objects *ip; Xv_opaque owner; { Xv_opaque obj; obj = xv_create(owner, PANEL_BUTTON, XV_KEY_DATA, INSTANCE, ip, XV_X, 230, XV_Y, 296, PANEL_LABEL_STRING, "Stop", PANEL_ITEM_MENU, rplaytool_stop_menu_create((caddr_t) ip, ip->w), NULL); return obj; } /* * Initialize an instance of object `s'. */ rplaytool_s_objects * rplaytool_s_objects_initialize(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { if (!ip && !(ip = (rplaytool_s_objects *) calloc(1, sizeof (rplaytool_s_objects)))) return (rplaytool_s_objects *) NULL; if (!ip->s) ip->s = rplaytool_s_s_create(ip, owner); if (!ip->controls7) ip->controls7 = rplaytool_s_controls7_create(ip, ip->s); if (!ip->directory) ip->directory = rplaytool_s_directory_create(ip, ip->controls7); if (!ip->disklist) ip->disklist = rplaytool_s_disklist_create(ip, ip->controls7); if (!ip->controls9) ip->controls9 = rplaytool_s_controls9_create(ip, ip->s); if (!ip->soundlist) ip->soundlist = rplaytool_s_soundlist_create(ip, ip->controls9); if (!ip->controls1) ip->controls1 = rplaytool_s_controls1_create(ip, ip->s); if (!ip->add) ip->add = rplaytool_s_add_create(ip, ip->controls1); if (!ip->close) ip->close = rplaytool_s_close_create(ip, ip->controls1); if (!ip->controls4) ip->controls4 = rplaytool_s_controls4_create(ip, ip->s); if (!ip->playlist3) ip->playlist3 = rplaytool_s_playlist3_create(ip, ip->controls4); if (!ip->controls5) ip->controls5 = rplaytool_s_controls5_create(ip, ip->s); if (!ip->playlist4) ip->playlist4 = rplaytool_s_playlist4_create(ip, ip->controls5); if (!ip->controls2) ip->controls2 = rplaytool_s_controls2_create(ip, ip->s); if (!ip->playlist1) ip->playlist1 = rplaytool_s_playlist1_create(ip, ip->controls2); if (!ip->controls3) ip->controls3 = rplaytool_s_controls3_create(ip, ip->s); if (!ip->playlist2) ip->playlist2 = rplaytool_s_playlist2_create(ip, ip->controls3); if (!ip->controls6) ip->controls6 = rplaytool_s_controls6_create(ip, ip->s); if (!ip->move) ip->move = rplaytool_s_move_create(ip, ip->controls6); if (!ip->delete) ip->delete = rplaytool_s_delete_create(ip, ip->controls6); if (!ip->file) ip->file = rplaytool_s_file_create(ip, ip->controls6); if (!ip->playit) ip->playit = rplaytool_s_playit_create(ip, ip->controls6); if (!ip->next) ip->next = rplaytool_s_next_create(ip, ip->controls6); if (!ip->prev) ip->prev = rplaytool_s_prev_create(ip, ip->controls6); if (!ip->stopit) ip->stopit = rplaytool_s_stopit_create(ip, ip->controls6); if (!ip->whichlist) ip->whichlist = rplaytool_s_whichlist_create(ip, ip->controls6); if (!ip->controls8) ip->controls8 = rplaytool_s_controls8_create(ip, ip->s); if (!ip->sort) ip->sort = rplaytool_s_sort_create(ip, ip->controls8); if (!ip->reload) ip->reload = rplaytool_s_reload_create(ip, ip->controls8); if (!ip->soundsource) ip->soundsource = rplaytool_s_soundsource_create(ip, ip->controls8); return ip; } /* * Create object `s' in the specified instance. */ Xv_opaque rplaytool_s_s_create(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { Xv_opaque obj; obj = xv_create(owner, FRAME_CMD, XV_KEY_DATA, INSTANCE, ip, XV_WIDTH, 580, XV_HEIGHT, 391, XV_LABEL, "Sounds", XV_SHOW, FALSE, FRAME_SHOW_FOOTER, TRUE, FRAME_SHOW_RESIZE_CORNER, FALSE, FRAME_CMD_PUSHPIN_IN, TRUE, NULL); xv_set(xv_get(obj, FRAME_CMD_PANEL), WIN_SHOW, FALSE, NULL); return obj; } /* * Create object `controls7' in the specified instance. */ Xv_opaque rplaytool_s_controls7_create(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { Xv_opaque obj; obj = xv_create(owner, PANEL, XV_KEY_DATA, INSTANCE, ip, XV_X, 0, XV_Y, 0, XV_WIDTH, 247, XV_HEIGHT, 281, XV_SHOW, FALSE, WIN_BORDER, FALSE, NULL); return obj; } /* * Create object `directory' in the specified instance. */ Xv_opaque rplaytool_s_directory_create(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { extern Panel_setting do_cd(); Xv_opaque obj; obj = xv_create(owner, PANEL_TEXT, XV_KEY_DATA, INSTANCE, ip, XV_X, 8, XV_Y, 24, PANEL_VALUE_DISPLAY_LENGTH, 20, PANEL_VALUE_STORED_LENGTH, 80, PANEL_LABEL_STRING, "Directory:", PANEL_LAYOUT, PANEL_HORIZONTAL, PANEL_READ_ONLY, FALSE, PANEL_NOTIFY_PROC, do_cd, NULL); return obj; } /* * Create object `disklist' in the specified instance. */ Xv_opaque rplaytool_s_disklist_create(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { extern int do_disklist(); Xv_opaque obj; obj = xv_create(owner, PANEL_LIST, XV_KEY_DATA, INSTANCE, ip, XV_X, 16, XV_Y, 48, PANEL_LIST_WIDTH, 200, PANEL_LIST_DISPLAY_ROWS, 10, PANEL_LIST_TITLE, "Disk Sounds", PANEL_LAYOUT, PANEL_HORIZONTAL, PANEL_READ_ONLY, TRUE, PANEL_CHOOSE_ONE, TRUE, PANEL_CHOOSE_NONE, TRUE, PANEL_NOTIFY_PROC, do_disklist, NULL); return obj; } /* * Create object `controls9' in the specified instance. */ Xv_opaque rplaytool_s_controls9_create(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { Xv_opaque obj; obj = xv_create(owner, PANEL, XV_KEY_DATA, INSTANCE, ip, XV_X, 0, XV_Y, 0, XV_WIDTH, 247, XV_HEIGHT, 281, WIN_BORDER, FALSE, NULL); return obj; } /* * Create object `soundlist' in the specified instance. */ Xv_opaque rplaytool_s_soundlist_create(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { extern int do_soundlist(); Xv_opaque obj; obj = xv_create(owner, PANEL_LIST, XV_KEY_DATA, INSTANCE, ip, XV_X, 14, XV_Y, 24, PANEL_LIST_WIDTH, 200, PANEL_LIST_DISPLAY_ROWS, 10, PANEL_LIST_TITLE, "Server Sounds", PANEL_LAYOUT, PANEL_HORIZONTAL, PANEL_READ_ONLY, TRUE, PANEL_CHOOSE_ONE, TRUE, PANEL_CHOOSE_NONE, TRUE, PANEL_NOTIFY_PROC, do_soundlist, NULL); return obj; } /* * Create object `controls1' in the specified instance. */ Xv_opaque rplaytool_s_controls1_create(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { Xv_opaque obj; obj = xv_create(owner, PANEL, XV_KEY_DATA, INSTANCE, ip, XV_X, (int)xv_get(ip->controls7, XV_X) + (int)xv_get(ip->controls7, XV_WIDTH), XV_Y, 0, XV_WIDTH, 62, XV_HEIGHT, WIN_EXTEND_TO_EDGE, WIN_BORDER, FALSE, NULL); return obj; } /* * Create object `add' in the specified instance. */ Xv_opaque rplaytool_s_add_create(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { Xv_opaque obj; obj = xv_create(owner, PANEL_BUTTON, XV_KEY_DATA, INSTANCE, ip, XV_X, 3, XV_Y, 112, PANEL_LABEL_STRING, "Add", PANEL_INACTIVE, TRUE, PANEL_ITEM_MENU, rplaytool_add_menu_create((caddr_t) ip, ip->s), NULL); return obj; } /* * Create object `close' in the specified instance. */ Xv_opaque rplaytool_s_close_create(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { extern void rplaytool_s_close_notify_callback(); Xv_opaque obj; obj = xv_create(owner, PANEL_BUTTON, XV_KEY_DATA, INSTANCE, ip, XV_X, 4, XV_Y, 368, PANEL_LABEL_STRING, "Close", PANEL_NOTIFY_PROC, rplaytool_s_close_notify_callback, NULL); return obj; } /* * Create object `controls4' in the specified instance. */ Xv_opaque rplaytool_s_controls4_create(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { Xv_opaque obj; obj = xv_create(owner, PANEL, XV_KEY_DATA, INSTANCE, ip, XV_X, (int)xv_get(ip->controls1, XV_X) + (int)xv_get(ip->controls1, XV_WIDTH), XV_Y, 0, XV_WIDTH, WIN_EXTEND_TO_EDGE, XV_HEIGHT, 257, XV_SHOW, FALSE, WIN_BORDER, FALSE, NULL); return obj; } /* * Create object `playlist3' in the specified instance. */ Xv_opaque rplaytool_s_playlist3_create(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { extern int do_playlist3(); Xv_opaque obj; obj = xv_create(owner, PANEL_LIST, XV_KEY_DATA, INSTANCE, ip, XV_X, 18, XV_Y, 24, PANEL_LIST_WIDTH, 200, PANEL_LIST_DISPLAY_ROWS, 10, PANEL_LIST_TITLE, "User Play List 3", PANEL_LAYOUT, PANEL_HORIZONTAL, PANEL_READ_ONLY, TRUE, PANEL_CHOOSE_ONE, TRUE, PANEL_CHOOSE_NONE, TRUE, PANEL_NOTIFY_PROC, do_playlist3, NULL); return obj; } /* * Create object `controls5' in the specified instance. */ Xv_opaque rplaytool_s_controls5_create(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { Xv_opaque obj; obj = xv_create(owner, PANEL, XV_KEY_DATA, INSTANCE, ip, XV_X, (int)xv_get(ip->controls1, XV_X) + (int)xv_get(ip->controls1, XV_WIDTH), XV_Y, 0, XV_WIDTH, WIN_EXTEND_TO_EDGE, XV_HEIGHT, 257, XV_SHOW, FALSE, WIN_BORDER, FALSE, NULL); return obj; } /* * Create object `playlist4' in the specified instance. */ Xv_opaque rplaytool_s_playlist4_create(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { extern int do_playlist4(); Xv_opaque obj; obj = xv_create(owner, PANEL_LIST, XV_KEY_DATA, INSTANCE, ip, XV_X, 18, XV_Y, 24, PANEL_LIST_WIDTH, 200, PANEL_LIST_DISPLAY_ROWS, 10, PANEL_LIST_TITLE, "User Play List 4", PANEL_LAYOUT, PANEL_HORIZONTAL, PANEL_READ_ONLY, TRUE, PANEL_CHOOSE_ONE, TRUE, PANEL_CHOOSE_NONE, TRUE, PANEL_NOTIFY_PROC, do_playlist4, NULL); return obj; } /* * Create object `controls2' in the specified instance. */ Xv_opaque rplaytool_s_controls2_create(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { Xv_opaque obj; obj = xv_create(owner, PANEL, XV_KEY_DATA, INSTANCE, ip, XV_X, (int)xv_get(ip->controls1, XV_X) + (int)xv_get(ip->controls1, XV_WIDTH), XV_Y, 0, XV_WIDTH, WIN_EXTEND_TO_EDGE, XV_HEIGHT, 257, WIN_BORDER, FALSE, NULL); return obj; } /* * Create object `playlist1' in the specified instance. */ Xv_opaque rplaytool_s_playlist1_create(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { extern int do_playlist1(); Xv_opaque obj; obj = xv_create(owner, PANEL_LIST, XV_KEY_DATA, INSTANCE, ip, XV_X, 18, XV_Y, 24, PANEL_LIST_WIDTH, 200, PANEL_LIST_DISPLAY_ROWS, 10, PANEL_LIST_TITLE, "User Play List 1", PANEL_LAYOUT, PANEL_HORIZONTAL, PANEL_READ_ONLY, TRUE, PANEL_CHOOSE_ONE, TRUE, PANEL_CHOOSE_NONE, TRUE, PANEL_NOTIFY_PROC, do_playlist1, NULL); return obj; } /* * Create object `controls3' in the specified instance. */ Xv_opaque rplaytool_s_controls3_create(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { Xv_opaque obj; obj = xv_create(owner, PANEL, XV_KEY_DATA, INSTANCE, ip, XV_X, (int)xv_get(ip->controls1, XV_X) + (int)xv_get(ip->controls1, XV_WIDTH), XV_Y, 0, XV_WIDTH, WIN_EXTEND_TO_EDGE, XV_HEIGHT, 257, XV_SHOW, FALSE, WIN_BORDER, FALSE, NULL); return obj; } /* * Create object `playlist2' in the specified instance. */ Xv_opaque rplaytool_s_playlist2_create(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { extern int do_playlist2(); Xv_opaque obj; obj = xv_create(owner, PANEL_LIST, XV_KEY_DATA, INSTANCE, ip, XV_X, 18, XV_Y, 24, PANEL_LIST_WIDTH, 200, PANEL_LIST_DISPLAY_ROWS, 10, PANEL_LIST_TITLE, "User Play List 2", PANEL_LAYOUT, PANEL_HORIZONTAL, PANEL_READ_ONLY, TRUE, PANEL_CHOOSE_ONE, TRUE, PANEL_CHOOSE_NONE, TRUE, PANEL_NOTIFY_PROC, do_playlist2, NULL); return obj; } /* * Create object `controls6' in the specified instance. */ Xv_opaque rplaytool_s_controls6_create(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { Xv_opaque obj; obj = xv_create(owner, PANEL, XV_KEY_DATA, INSTANCE, ip, XV_X, (int)xv_get(ip->controls1, XV_X) + (int)xv_get(ip->controls1, XV_WIDTH), XV_Y, (int)xv_get(ip->controls4, XV_Y) + (int)xv_get(ip->controls4, XV_HEIGHT), XV_WIDTH, WIN_EXTEND_TO_EDGE, XV_HEIGHT, WIN_EXTEND_TO_EDGE, WIN_BORDER, FALSE, NULL); return obj; } /* * Create object `move' in the specified instance. */ Xv_opaque rplaytool_s_move_create(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { Xv_opaque obj; obj = xv_create(owner, PANEL_BUTTON, XV_KEY_DATA, INSTANCE, ip, XV_X, 31, XV_Y, 16, PANEL_LABEL_STRING, "Move", PANEL_INACTIVE, TRUE, PANEL_ITEM_MENU, rplaytool_move_menu_create((caddr_t) ip, ip->s), NULL); return obj; } /* * Create object `delete' in the specified instance. */ Xv_opaque rplaytool_s_delete_create(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { Xv_opaque obj; obj = xv_create(owner, PANEL_BUTTON, XV_KEY_DATA, INSTANCE, ip, XV_X, 107, XV_Y, 16, PANEL_LABEL_STRING, "Delete", PANEL_INACTIVE, TRUE, PANEL_ITEM_MENU, rplaytool_delete_menu_create((caddr_t) ip, ip->s), NULL); return obj; } /* * Create object `file' in the specified instance. */ Xv_opaque rplaytool_s_file_create(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { Xv_opaque obj; obj = xv_create(owner, PANEL_BUTTON, XV_KEY_DATA, INSTANCE, ip, XV_X, 186, XV_Y, 16, PANEL_LABEL_STRING, "File", PANEL_ITEM_MENU, rplaytool_playlistfile_menu_create((caddr_t) ip, ip->s), NULL); return obj; } /* * Create object `playit' in the specified instance. */ Xv_opaque rplaytool_s_playit_create(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { extern void do_playit(); Xv_opaque obj; obj = xv_create(owner, PANEL_BUTTON, XV_KEY_DATA, INSTANCE, ip, XV_X, 32, XV_Y, 48, PANEL_LABEL_STRING, "Play", PANEL_NOTIFY_PROC, do_playit, NULL); return obj; } /* * Create object `next' in the specified instance. */ Xv_opaque rplaytool_s_next_create(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { extern void do_next(); Xv_opaque obj; obj = xv_create(owner, PANEL_BUTTON, XV_KEY_DATA, INSTANCE, ip, XV_X, 87, XV_Y, 48, PANEL_LABEL_STRING, "Next", PANEL_NOTIFY_PROC, do_next, NULL); return obj; } /* * Create object `prev' in the specified instance. */ Xv_opaque rplaytool_s_prev_create(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { extern void do_prev(); Xv_opaque obj; obj = xv_create(owner, PANEL_BUTTON, XV_KEY_DATA, INSTANCE, ip, XV_X, 141, XV_Y, 48, PANEL_LABEL_STRING, "Prev", PANEL_NOTIFY_PROC, do_prev, NULL); return obj; } /* * Create object `stopit' in the specified instance. */ Xv_opaque rplaytool_s_stopit_create(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { extern void do_stopit(); Xv_opaque obj; obj = xv_create(owner, PANEL_BUTTON, XV_KEY_DATA, INSTANCE, ip, XV_X, 194, XV_Y, 48, PANEL_LABEL_STRING, "Stop", PANEL_NOTIFY_PROC, do_stopit, NULL); return obj; } /* * Create object `whichlist' in the specified instance. */ Xv_opaque rplaytool_s_whichlist_create(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { extern void switch_playlist(); Xv_opaque obj; obj = xv_create(owner, PANEL_CHOICE, XV_KEY_DATA, INSTANCE, ip, XV_X, 25, XV_Y, 80, PANEL_CHOICE_NROWS, 1, PANEL_LAYOUT, PANEL_HORIZONTAL, PANEL_CHOOSE_NONE, FALSE, PANEL_LABEL_STRING, "Select play list:", PANEL_NOTIFY_PROC, switch_playlist, PANEL_CHOICE_STRINGS, "1", "2", "3", "4", NULL, NULL); return obj; } /* * Create object `controls8' in the specified instance. */ Xv_opaque rplaytool_s_controls8_create(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { Xv_opaque obj; obj = xv_create(owner, PANEL, XV_KEY_DATA, INSTANCE, ip, XV_X, 0, XV_Y, (int)xv_get(ip->controls7, XV_Y) + (int)xv_get(ip->controls7, XV_HEIGHT), XV_WIDTH, 247, XV_HEIGHT, WIN_EXTEND_TO_EDGE, WIN_BORDER, FALSE, NULL); return obj; } /* * Create object `sort' in the specified instance. */ Xv_opaque rplaytool_s_sort_create(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { extern void do_soundsort(); Xv_opaque obj; obj = xv_create(owner, PANEL_BUTTON, XV_KEY_DATA, INSTANCE, ip, XV_X, 69, XV_Y, 16, PANEL_LABEL_STRING, "Sort", PANEL_NOTIFY_PROC, do_soundsort, NULL); return obj; } /* * Create object `reload' in the specified instance. */ Xv_opaque rplaytool_s_reload_create(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { extern void do_reload(); Xv_opaque obj; obj = xv_create(owner, PANEL_BUTTON, XV_KEY_DATA, INSTANCE, ip, XV_X, 119, XV_Y, 16, PANEL_LABEL_STRING, "Reload", PANEL_NOTIFY_PROC, do_reload, NULL); return obj; } /* * Create object `soundsource' in the specified instance. */ Xv_opaque rplaytool_s_soundsource_create(ip, owner) rplaytool_s_objects *ip; Xv_opaque owner; { extern void rplaytool_s_soundsource_notify_callback(); Xv_opaque obj; obj = xv_create(owner, PANEL_CHOICE, XV_KEY_DATA, INSTANCE, ip, XV_X, 8, XV_Y, 48, PANEL_CHOICE_NROWS, 1, PANEL_LAYOUT, PANEL_HORIZONTAL, PANEL_CHOOSE_NONE, FALSE, PANEL_LABEL_STRING, "List sounds from:", PANEL_NOTIFY_PROC, rplaytool_s_soundsource_notify_callback, PANEL_CHOICE_STRINGS, "Server", "Disk", NULL, PANEL_VALUE, 0, NULL); return obj; } /* * Initialize an instance of object `f'. */ rplaytool_f_objects * rplaytool_f_objects_initialize(ip, owner) rplaytool_f_objects *ip; Xv_opaque owner; { if (!ip && !(ip = (rplaytool_f_objects *) calloc(1, sizeof (rplaytool_f_objects)))) return (rplaytool_f_objects *) NULL; if (!ip->f) ip->f = rplaytool_f_f_create(ip, owner); if (!ip->controls10) ip->controls10 = rplaytool_f_controls10_create(ip, ip->f); if (!ip->filedir) ip->filedir = rplaytool_f_filedir_create(ip, ip->controls10); if (!ip->filelist) ip->filelist = rplaytool_f_filelist_create(ip, ip->controls10); if (!ip->filename) ip->filename = rplaytool_f_filename_create(ip, ip->controls10); if (!ip->filedoit) ip->filedoit = rplaytool_f_filedoit_create(ip, ip->controls10); if (!ip->fileclose) ip->fileclose = rplaytool_f_fileclose_create(ip, ip->controls10); return ip; } /* * Create object `f' in the specified instance. */ Xv_opaque rplaytool_f_f_create(ip, owner) rplaytool_f_objects *ip; Xv_opaque owner; { Xv_opaque obj; obj = xv_create(owner, FRAME_CMD, XV_KEY_DATA, INSTANCE, ip, XV_WIDTH, 344, XV_HEIGHT, 351, XV_SHOW, FALSE, FRAME_SHOW_FOOTER, FALSE, FRAME_SHOW_RESIZE_CORNER, FALSE, FRAME_CMD_PUSHPIN_IN, TRUE, NULL); xv_set(xv_get(obj, FRAME_CMD_PANEL), WIN_SHOW, FALSE, NULL); return obj; } /* * Create object `controls10' in the specified instance. */ Xv_opaque rplaytool_f_controls10_create(ip, owner) rplaytool_f_objects *ip; Xv_opaque owner; { Xv_opaque obj; obj = xv_create(owner, PANEL, XV_KEY_DATA, INSTANCE, ip, XV_X, 0, XV_Y, 0, XV_WIDTH, WIN_EXTEND_TO_EDGE, XV_HEIGHT, WIN_EXTEND_TO_EDGE, WIN_BORDER, FALSE, NULL); return obj; } /* * Create object `filedir' in the specified instance. */ Xv_opaque rplaytool_f_filedir_create(ip, owner) rplaytool_f_objects *ip; Xv_opaque owner; { extern Panel_setting filedir_notify(); Xv_opaque obj; obj = xv_create(owner, PANEL_TEXT, XV_KEY_DATA, INSTANCE, ip, XV_X, 7, XV_Y, 16, PANEL_VALUE_DISPLAY_LENGTH, 32, PANEL_VALUE_STORED_LENGTH, 80, PANEL_LABEL_STRING, "Directory:", PANEL_LAYOUT, PANEL_HORIZONTAL, PANEL_READ_ONLY, FALSE, PANEL_NOTIFY_PROC, filedir_notify, NULL); return obj; } /* * Create object `filelist' in the specified instance. */ Xv_opaque rplaytool_f_filelist_create(ip, owner) rplaytool_f_objects *ip; Xv_opaque owner; { extern int filelist_notify(); Xv_opaque obj; obj = xv_create(owner, PANEL_LIST, XV_KEY_DATA, INSTANCE, ip, XV_X, 13, XV_Y, 48, PANEL_LIST_WIDTH, 300, PANEL_LIST_DISPLAY_ROWS, 10, PANEL_LAYOUT, PANEL_HORIZONTAL, PANEL_READ_ONLY, TRUE, PANEL_CHOOSE_ONE, TRUE, PANEL_CHOOSE_NONE, TRUE, PANEL_NOTIFY_PROC, filelist_notify, NULL); return obj; } /* * Create object `filename' in the specified instance. */ Xv_opaque rplaytool_f_filename_create(ip, owner) rplaytool_f_objects *ip; Xv_opaque owner; { extern Panel_setting filename_notify(); Xv_opaque obj; obj = xv_create(owner, PANEL_TEXT, XV_KEY_DATA, INSTANCE, ip, XV_X, 26, XV_Y, 264, PANEL_VALUE_DISPLAY_LENGTH, 32, PANEL_VALUE_STORED_LENGTH, 80, PANEL_LABEL_STRING, "File:", PANEL_LAYOUT, PANEL_HORIZONTAL, PANEL_READ_ONLY, FALSE, PANEL_NOTIFY_PROC, filename_notify, NULL); return obj; } /* * Create object `filedoit' in the specified instance. */ Xv_opaque rplaytool_f_filedoit_create(ip, owner) rplaytool_f_objects *ip; Xv_opaque owner; { extern void filedoit_notify(); Xv_opaque obj; obj = xv_create(owner, PANEL_BUTTON, XV_KEY_DATA, INSTANCE, ip, XV_X, 147, XV_Y, 296, PANEL_LABEL_STRING, "Load", PANEL_NOTIFY_PROC, filedoit_notify, NULL); return obj; } /* * Create object `fileclose' in the specified instance. */ Xv_opaque rplaytool_f_fileclose_create(ip, owner) rplaytool_f_objects *ip; Xv_opaque owner; { extern void rplaytool_f_fileclose_notify_callback(); Xv_opaque obj; obj = xv_create(owner, PANEL_BUTTON, XV_KEY_DATA, INSTANCE, ip, XV_X, 145, XV_Y, 323, PANEL_LABEL_STRING, "Close", PANEL_NOTIFY_PROC, rplaytool_f_fileclose_notify_callback, NULL); return obj; } rplay-3.3.2/contrib/rplaytool-1.1/rplaytool_ui.h100644 153 62 7625 6552756453 20225 0ustar boynsstaff#ifndef rplaytool_HEADER #define rplaytool_HEADER /* * rplaytool_ui.h - User interface object and function declarations. * This file was generated by `gxv' from `rplaytool.G'. * DO NOT EDIT BY HAND. */ extern Attr_attribute INSTANCE; extern Xv_opaque rplaytool_file_menu_create(); extern Xv_opaque rplaytool_cont_menu_create(); extern Xv_opaque rplaytool_pause_menu_create(); extern Xv_opaque rplaytool_stop_menu_create(); extern Xv_opaque rplaytool_delete_menu_create(); extern Xv_opaque rplaytool_add_menu_create(); extern Xv_opaque rplaytool_playlistfile_menu_create(); extern Xv_opaque rplaytool_move_menu_create(); typedef struct { Xv_opaque w; Xv_opaque c; Xv_opaque file; Xv_opaque host; Xv_opaque volume; Xv_opaque spool; Xv_opaque cont; Xv_opaque pause; Xv_opaque stop; } rplaytool_w_objects; extern rplaytool_w_objects *rplaytool_w_objects_initialize(); extern Xv_opaque rplaytool_w_w_create(); extern Xv_opaque rplaytool_w_c_create(); extern Xv_opaque rplaytool_w_file_create(); extern Xv_opaque rplaytool_w_host_create(); extern Xv_opaque rplaytool_w_volume_create(); extern Xv_opaque rplaytool_w_spool_create(); extern Xv_opaque rplaytool_w_cont_create(); extern Xv_opaque rplaytool_w_pause_create(); extern Xv_opaque rplaytool_w_stop_create(); typedef struct { Xv_opaque s; Xv_opaque controls7; Xv_opaque directory; Xv_opaque disklist; Xv_opaque controls9; Xv_opaque soundlist; Xv_opaque controls1; Xv_opaque add; Xv_opaque close; Xv_opaque controls4; Xv_opaque playlist3; Xv_opaque controls5; Xv_opaque playlist4; Xv_opaque controls2; Xv_opaque playlist1; Xv_opaque controls3; Xv_opaque playlist2; Xv_opaque controls6; Xv_opaque move; Xv_opaque delete; Xv_opaque file; Xv_opaque playit; Xv_opaque next; Xv_opaque prev; Xv_opaque stopit; Xv_opaque whichlist; Xv_opaque controls8; Xv_opaque sort; Xv_opaque reload; Xv_opaque soundsource; } rplaytool_s_objects; extern rplaytool_s_objects *rplaytool_s_objects_initialize(); extern Xv_opaque rplaytool_s_s_create(); extern Xv_opaque rplaytool_s_controls7_create(); extern Xv_opaque rplaytool_s_directory_create(); extern Xv_opaque rplaytool_s_disklist_create(); extern Xv_opaque rplaytool_s_controls9_create(); extern Xv_opaque rplaytool_s_soundlist_create(); extern Xv_opaque rplaytool_s_controls1_create(); extern Xv_opaque rplaytool_s_add_create(); extern Xv_opaque rplaytool_s_close_create(); extern Xv_opaque rplaytool_s_controls4_create(); extern Xv_opaque rplaytool_s_playlist3_create(); extern Xv_opaque rplaytool_s_controls5_create(); extern Xv_opaque rplaytool_s_playlist4_create(); extern Xv_opaque rplaytool_s_controls2_create(); extern Xv_opaque rplaytool_s_playlist1_create(); extern Xv_opaque rplaytool_s_controls3_create(); extern Xv_opaque rplaytool_s_playlist2_create(); extern Xv_opaque rplaytool_s_controls6_create(); extern Xv_opaque rplaytool_s_move_create(); extern Xv_opaque rplaytool_s_delete_create(); extern Xv_opaque rplaytool_s_file_create(); extern Xv_opaque rplaytool_s_playit_create(); extern Xv_opaque rplaytool_s_next_create(); extern Xv_opaque rplaytool_s_prev_create(); extern Xv_opaque rplaytool_s_stopit_create(); extern Xv_opaque rplaytool_s_whichlist_create(); extern Xv_opaque rplaytool_s_controls8_create(); extern Xv_opaque rplaytool_s_sort_create(); extern Xv_opaque rplaytool_s_reload_create(); extern Xv_opaque rplaytool_s_soundsource_create(); typedef struct { Xv_opaque f; Xv_opaque controls10; Xv_opaque filedir; Xv_opaque filelist; Xv_opaque filename; Xv_opaque filedoit; Xv_opaque fileclose; } rplaytool_f_objects; extern rplaytool_f_objects *rplaytool_f_objects_initialize(); extern Xv_opaque rplaytool_f_f_create(); extern Xv_opaque rplaytool_f_controls10_create(); extern Xv_opaque rplaytool_f_filedir_create(); extern Xv_opaque rplaytool_f_filelist_create(); extern Xv_opaque rplaytool_f_filename_create(); extern Xv_opaque rplaytool_f_filedoit_create(); extern Xv_opaque rplaytool_f_fileclose_create(); #endif rplay-3.3.2/contrib/rplaytool-1.1/rptp.c100644 153 62 7115 6564502001 16432 0ustar boynsstaff/* $Id: rptp.c,v 1.2 1998/08/13 06:13:21 boyns Exp $ */ /* * Copyright (C) 1995 Mark Boyns * * This file is part of rplaytool. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "rptp.h" #include "misc.h" int rptp_fd = -1; char *rptp_host = 0; static void callback (fd, action) int fd; int action; { switch (action) { case RPTP_ASYNC_ENABLE: enable_notify_write (fd); break; case RPTP_ASYNC_DISABLE: disable_notify_write (fd); break; } } int do_rptp_open (host) char *host; { char rptp_buf[RPTP_MAX_LINE]; extern void process_input (); if (rptp_fd != -1) { rptp_close (rptp_fd); } rptp_fd = rptp_open (host, RPTP_PORT, rptp_buf, sizeof (rptp_buf)); rptp_async_register (rptp_fd, RPTP_ASYNC_WRITE, callback); #if 0 rptp_async_notify (rptp_fd, RPTP_EVENT_PLAY|RPTP_EVENT_PAUSE|RPTP_EVENT_CONTINUE|RPTP_EVENT_DONE |RPTP_EVENT_STATE|RPTP_EVENT_OK|RPTP_EVENT_ERROR|RPTP_EVENT_CLOSE |RPTP_EVENT_OTHER, process_input); #else rptp_async_notify (rptp_fd, RPTP_EVENT_ALL, process_input); #endif if (rptp_host) { free (rptp_host); } rptp_host = (char *) strdup (host); return 0; } int do_rptp_pause (id, client_data) int id; char *client_data; { rptp_async_putline (rptp_fd, NULL, "pause id=#%d client-data=\"%d %s\"", id, STATE_PAUSE, client_data); return 0; } int do_rptp_cont (id, client_data) int id; char *client_data; { rptp_async_putline (rptp_fd, NULL, "continue id=#%d client-data=\"%d %s\"", id, STATE_CONTINUE, client_data); return 0; } int do_rptp_stop (id, client_data) int id; char *client_data; { rptp_async_putline (rptp_fd, NULL, "stop id=#%d client-data=\"%d %s\"", id, STATE_STOP, client_data); return 0; } int do_rptp_volume (volume) int volume; { rptp_async_putline (rptp_fd, NULL, "set volume=%d", volume); return 0; } int do_rptp_sounds () { rptp_async_putline (rptp_fd, NULL, "list sounds"); return 0; } int do_rptp_play (sound, client_data, args) char *sound; char *client_data; char *args; { if (client_data) { rptp_async_putline (rptp_fd, NULL, "play client-data=\"%d %s\" %s sound=\"%s\"", STATE_PLAY, client_data, args ? args : "", sound); } else { rptp_async_putline (rptp_fd, NULL, "play %s sound=%s", args ? args : "", sound); } return 0; } int do_rptp_play_info (info, client_data) INFO *info; char *client_data; { char buf[RPTP_MAX_LINE]; buf[0] = '\0'; if (info->sample_rate != RPLAY_DEFAULT_SAMPLE_RATE) { sprintf (buf + strlen (buf), "sample-rate=%d ", info->sample_rate); } if (info->volume != RPLAY_DEFAULT_VOLUME) { sprintf (buf + strlen (buf), "volume=%d ", info->volume); } return do_rptp_play (info->filename, client_data, buf); } rplay-3.3.2/contrib/rplaytool-1.1/rptp.h100644 153 62 2271 6564502002 16436 0ustar boynsstaff/* $Id: rptp.h,v 1.2 1998/08/13 06:13:22 boyns Exp $ */ /* * Copyright (C) 1995 Mark Boyns * * This file is part of rplaytool. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _rptp_h #define _rptp_h #include extern int rptp_fd; extern char *rptp_host; extern int do_rptp_open (); extern int do_rptp_pause (); extern int do_rptp_cont (); extern int do_rptp_stop (); extern int do_rptp_volume (); extern int do_rptp_sounds (); extern int do_rptp_play (); extern int do_rptp_play_info (); #endif /* _rptp_h */ rplay-3.3.2/contrib/rplaytool-1.1/icons/ 40755 153 62 0 6727650075 16333 5ustar boynsstaffrplay-3.3.2/contrib/rplaytool-1.1/icons/arrow.icon100644 153 62 336 6552756453 20421 0ustar boynsstaff/* Format_version=1, Width=16, Height=16, Depth=1, Valid_bits_per_item=16 */ 0x0000, 0x0000, 0x0020, 0x0030, 0x0038, 0x003C, 0x1FFE, 0x1FFF, 0x1FFF, 0x1FFE, 0x003C, 0x0038, 0x0030, 0x0020, 0x0000, 0x0000, rplay-3.3.2/contrib/rplaytool-1.1/icons/directory.icon100644 153 62 336 6552756453 21273 0ustar boynsstaff/* Format_version=1, Width=16, Height=16, Depth=1, Valid_bits_per_item=16 */ 0x0000, 0x0000, 0x003C, 0x0042, 0xFF81, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0xFFFF, rplay-3.3.2/contrib/rplaytool-1.1/icons/file.icon100644 153 62 336 6552756453 20206 0ustar boynsstaff/* Format_version=1, Width=16, Height=16, Depth=1, Valid_bits_per_item=16 */ 0xFFE0, 0x8030, 0x8028, 0xBFA4, 0x8022, 0xBFBF, 0x8001, 0xBFFD, 0x8001, 0xBFFD, 0x8001, 0xBFFD, 0x8001, 0xBFFD, 0x8001, 0xFFFF, rplay-3.3.2/contrib/rplaytool-1.1/icons/none.icon100644 153 62 336 6552756453 20226 0ustar boynsstaff/* Format_version=1, Width=16, Height=16, Depth=1, Valid_bits_per_item=16 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, rplay-3.3.2/contrib/rplaytool-1.1/icons/pause.icon100644 153 62 336 6552756453 20404 0ustar boynsstaff/* Format_version=1, Width=16, Height=16, Depth=1, Valid_bits_per_item=16 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0066, 0x0066, 0x0066, 0x0066, 0x0066, 0x0066, 0x0066, 0x0066, 0x0000, 0x0000, 0x0000, 0x0000, rplay-3.3.2/contrib/rplaytool-1.1/icons/pause1.icon100644 153 62 336 6552756453 20465 0ustar boynsstaff/* Format_version=1, Width=16, Height=16, Depth=1, Valid_bits_per_item=16 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0066, 0x3066, 0x7066, 0x1066, 0x1066, 0x1066, 0x1066, 0x7C66, 0x0000, 0x0000, 0x0000, 0x0000, rplay-3.3.2/contrib/rplaytool-1.1/icons/pause2.icon100644 153 62 336 6552756453 20466 0ustar boynsstaff/* Format_version=1, Width=16, Height=16, Depth=1, Valid_bits_per_item=16 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0066, 0x3866, 0x6466, 0x0466, 0x0866, 0x1866, 0x3466, 0x7C66, 0x0000, 0x0000, 0x0000, 0x0000, rplay-3.3.2/contrib/rplaytool-1.1/icons/pause3.icon100644 153 62 336 6552756453 20467 0ustar boynsstaff/* Format_version=1, Width=16, Height=16, Depth=1, Valid_bits_per_item=16 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0066, 0x7866, 0x0466, 0x0466, 0x1866, 0x0466, 0x0466, 0x7866, 0x0000, 0x0000, 0x0000, 0x0000, rplay-3.3.2/contrib/rplaytool-1.1/icons/pause4.icon100644 153 62 336 6552756453 20470 0ustar boynsstaff/* Format_version=1, Width=16, Height=16, Depth=1, Valid_bits_per_item=16 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0066, 0x0866, 0x1866, 0x2866, 0x6866, 0x7C66, 0x0866, 0x1C66, 0x0000, 0x0000, 0x0000, 0x0000, rplay-3.3.2/contrib/rplaytool-1.1/icons/play.icon100644 153 62 336 6552756453 20234 0ustar boynsstaff/* Format_version=1, Width=16, Height=16, Depth=1, Valid_bits_per_item=16 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x00C0, 0x00F0, 0x00FC, 0x00FF, 0x00FF, 0x00FC, 0x00F0, 0x00C0, 0x0000, 0x0000, 0x0000, 0x0000, rplay-3.3.2/contrib/rplaytool-1.1/icons/play1.icon100644 153 62 336 6552756453 20315 0ustar boynsstaff/* Format_version=1, Width=16, Height=16, Depth=1, Valid_bits_per_item=16 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x00C0, 0x30F0, 0x70FC, 0x10FF, 0x10FF, 0x10FC, 0x10F0, 0x7CC0, 0x0000, 0x0000, 0x0000, 0x0000, rplay-3.3.2/contrib/rplaytool-1.1/icons/play2.icon100644 153 62 336 6552756453 20316 0ustar boynsstaff/* Format_version=1, Width=16, Height=16, Depth=1, Valid_bits_per_item=16 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x00C0, 0x38F0, 0x64FC, 0x04FF, 0x08FF, 0x18FC, 0x34F0, 0x7CC0, 0x0000, 0x0000, 0x0000, 0x0000, rplay-3.3.2/contrib/rplaytool-1.1/icons/play3.icon100644 153 62 336 6552756453 20317 0ustar boynsstaff/* Format_version=1, Width=16, Height=16, Depth=1, Valid_bits_per_item=16 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x00C0, 0x78F0, 0x04FC, 0x04FF, 0x18FF, 0x04FC, 0x04F0, 0x78C0, 0x0000, 0x0000, 0x0000, 0x0000, rplay-3.3.2/contrib/rplaytool-1.1/icons/play4.icon100644 153 62 336 6552756453 20320 0ustar boynsstaff/* Format_version=1, Width=16, Height=16, Depth=1, Valid_bits_per_item=16 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x00C0, 0x08F0, 0x18FC, 0x28FF, 0x68FF, 0x7CFC, 0x08F0, 0x1CC0, 0x0000, 0x0000, 0x0000, 0x0000, rplay-3.3.2/contrib/rplaytool-1.1/icons/rplaytool.icon100644 153 62 4216 6552756453 21335 0ustar boynsstaff/* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03FC, 0x3FC7, 0x8018, 0x78E0, 0x0186, 0x1863, 0x0018, 0x3040, 0x0186, 0x1863, 0x0038, 0x1880, 0x0186, 0x1863, 0x002C, 0x1900, 0x018C, 0x18C3, 0x004C, 0x0E00, 0x01F0, 0x1F86, 0x004C, 0x0C00, 0x0318, 0x3006, 0x008C, 0x0C00, 0x0318, 0x3006, 0x00FE, 0x1800, 0x030C, 0x3006, 0x0906, 0x1800, 0x030D, 0x3006, 0x0B06, 0x1800, 0x078E, 0x780F, 0xFF8F, 0x3C00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x000C, 0xA000, 0x6000, 0x0000, 0x0002, 0xA000, 0x8000, 0x0000, 0x000E, 0xA001, 0x2800, 0x0FC0, 0x000A, 0xA002, 0x4C00, 0x00C0, 0x002D, 0x6004, 0x8E00, 0x0180, 0xC000, 0x0189, 0x2F00, 0x0300, 0xE000, 0x0389, 0x2FE0, 0x0780, 0xF000, 0x058A, 0x4FE0, 0x00C0, 0xF800, 0x0189, 0x2FE0, 0x00C0, 0xFC00, 0x0189, 0x2F00, 0x0CC0, 0xF800, 0x0184, 0x8E00, 0x0780, 0xF000, 0x0182, 0x4C00, 0x0000, 0xE000, 0x0181, 0x2800, 0x0000, 0xC000, 0x07E0, 0x8000, 0x0000, 0x0000, 0x0000, 0x6000, 0x0000, 0x0156, 0x4800, 0x0000, 0x0080, 0x0151, 0x4800, 0x0030, 0x00C0, 0x0157, 0x4800, 0x0070, 0x00E0, 0x00A5, 0x5000, 0x00F0, 0x0FF0, 0x04A6, 0xA000, 0x01B0, 0x0FF0, 0x0000, 0x0198, 0x0330, 0x00E0, 0x03C0, 0x0198, 0x0330, 0x00C0, 0x0660, 0x0198, 0x03F0, 0x0080, 0x0660, 0x0198, 0x0030, 0x0000, 0x0060, 0x0198, 0x0030, 0x0044, 0x81C0, 0x0198, 0x0000, 0x0009, 0x0300, 0x0198, 0x24C6, 0x065F, 0x8600, 0x0198, 0x2528, 0x0149, 0x0600, 0x0000, 0x2528, 0x0749, 0x07E0, 0x0000, 0x2928, 0x0549, 0x0000, 0x0000, 0x90C6, 0x16C9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x003F, 0xF07C, 0x07C3, 0xC000, 0x0023, 0x1186, 0x1861, 0x8000, 0x0023, 0x1303, 0x3031, 0x8000, 0x0003, 0x0303, 0x3031, 0x8000, 0x0003, 0x0603, 0x6031, 0x8000, 0x0006, 0x0603, 0x6033, 0x0000, 0x0006, 0x0603, 0x6033, 0x0000, 0x0006, 0x0606, 0x6063, 0x0000, 0x0006, 0x0606, 0x6063, 0x0400, 0x0006, 0x030C, 0x30C3, 0x0400, 0x000F, 0x01F0, 0x1F07, 0xFC00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, rplay-3.3.2/contrib/rplaytool-1.1/icons/rplaytool_mask.icon100644 153 62 4216 6552756453 22350 0ustar boynsstaff/* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03FC, 0x3FC7, 0x8018, 0x78E0, 0x0186, 0x1863, 0x0018, 0x3040, 0x0186, 0x1863, 0x0038, 0x1880, 0x0186, 0x1863, 0x002C, 0x1900, 0x018C, 0x18C3, 0x004C, 0x0E00, 0x01F0, 0x1F86, 0x004C, 0x0C00, 0x0318, 0x3006, 0x008C, 0x0C00, 0x0318, 0x3006, 0x00FE, 0x1800, 0x030C, 0x3006, 0x0906, 0x1800, 0x030D, 0x3006, 0x0B06, 0x1800, 0x078E, 0x780F, 0xFF8F, 0x3C00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x000C, 0xA000, 0x6000, 0x0000, 0x0002, 0xA000, 0x8000, 0x0000, 0x000E, 0xA001, 0x2800, 0x0FC0, 0x000A, 0xA002, 0x4C00, 0x00C0, 0x002D, 0x6004, 0x8E00, 0x0180, 0xC000, 0x0189, 0x2F00, 0x0300, 0xE000, 0x0389, 0x2FE0, 0x0780, 0xF000, 0x058A, 0x4FE0, 0x00C0, 0xF800, 0x0189, 0x2FE0, 0x00C0, 0xFC00, 0x0189, 0x2F00, 0x0CC0, 0xF800, 0x0184, 0x8E00, 0x0780, 0xF000, 0x0182, 0x4C00, 0x0000, 0xE000, 0x0181, 0x2800, 0x0000, 0xC000, 0x07E0, 0x8000, 0x0000, 0x0000, 0x0000, 0x6000, 0x0000, 0x0156, 0x4800, 0x0000, 0x0080, 0x0151, 0x4800, 0x0030, 0x00C0, 0x0157, 0x4800, 0x0070, 0x00E0, 0x00A5, 0x5000, 0x00F0, 0x0FF0, 0x04A6, 0xA000, 0x01B0, 0x0FF0, 0x0000, 0x0198, 0x0330, 0x00E0, 0x03C0, 0x0198, 0x0330, 0x00C0, 0x0660, 0x0198, 0x03F0, 0x0080, 0x0660, 0x0198, 0x0030, 0x0000, 0x0060, 0x0198, 0x0030, 0x0044, 0x81C0, 0x0198, 0x0000, 0x0009, 0x0300, 0x0198, 0x24C6, 0x065F, 0x8600, 0x0198, 0x2528, 0x0149, 0x0600, 0x0000, 0x2528, 0x0749, 0x07E0, 0x0000, 0x2928, 0x0549, 0x0000, 0x0000, 0x90C6, 0x16C9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x003F, 0xF07C, 0x07C3, 0xC000, 0x0023, 0x1186, 0x1861, 0x8000, 0x0023, 0x1303, 0x3031, 0x8000, 0x0003, 0x0303, 0x3031, 0x8000, 0x0003, 0x0603, 0x6031, 0x8000, 0x0006, 0x0603, 0x6033, 0x0000, 0x0006, 0x0603, 0x6033, 0x0000, 0x0006, 0x0606, 0x6063, 0x0000, 0x0006, 0x0606, 0x6063, 0x0400, 0x0006, 0x030C, 0x30C3, 0x0400, 0x000F, 0x01F0, 0x1F07, 0xFC00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, rplay-3.3.2/contrib/rplaytool-1.1/icons/sound.icon100644 153 62 336 6552756453 20417 0ustar boynsstaff/* Format_version=1, Width=16, Height=16, Depth=1, Valid_bits_per_item=16 */ 0x0000, 0x0000, 0x0088, 0x0184, 0x0392, 0x0789, 0x3FA5, 0x3F95, 0x3F95, 0x3FA5, 0x0789, 0x0392, 0x0184, 0x0088, 0x0000, 0x0000, rplay-3.3.2/contrib/rplaytool-1.1/icons/watch.icon100644 153 62 336 6552756453 20375 0ustar boynsstaff/* Format_version=1, Width=16, Height=16, Depth=1, Valid_bits_per_item=16 */ 0x07E0, 0x07E0, 0x07E0, 0x0FF0, 0x1C38, 0x1918, 0x310C, 0x310C, 0x31CC, 0x300C, 0x1818, 0x1C38, 0x0FF0, 0x07E0, 0x07E0, 0x07E0, rplay-3.3.2/contrib/tkrplay/ 40755 153 62 0 6727650075 14364 5ustar boynsstaffrplay-3.3.2/contrib/tkrplay/README100644 153 62 1001 6552756453 15334 0ustar boynsstaff tkrplay is a Tcl/Tk sound directory browser. Sounds are played, paused, stopped, and continued using the rplay command. Host volume setting is done using the rptp command. Both the rplay and rptp programs must be installed somewhere in your PATH. The RotateLeft button in the bottom left corner of the window will move back to the previous directory. The ! button in the botton right corner will stop all sounds that are currently playing. Tcl and Tk are available at ftp.x.org in the /contrib directory. rplay-3.3.2/contrib/tkrplay/foo100755 153 62 15751 6552756453 15226 0ustar boynsstaff#!/usr/local/bin/wish -f # # Copyright (C) 1994-95 Mark Boyns # # tkrplay # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # # # Usage: tkrplay # # -- Begin configuration options --- set default_host "localhost" set default_volume 127 set default_priority 0 set sound_dir "/opt/sounds" # --- End configuration options --- set host $default_host set volume $default_volume set priority $default_priority set hvolume [lindex [split [exec rptp -h $host volume] =] 1] set version "1.1" # # Set window manager parameters. # wm title . "tkrplay $version" wm iconname . "tkrplay $version" wm minsize . 1 1 # # Create the Quit and Configure buttons. # frame .menu -relief raise -borderwidth 2 pack .menu -side top -fill x menubutton .menu.file -text "File" -menu .menu.file.m -underline 0 -relief raise menu .menu.file.m .menu.file.m add command -label "Quit" -command "destroy ." -underline 0 button .menu.config -text "Configure" -command "config" -relief raised pack .menu.file -side left pack .menu.config -side right # # Create the current directory entry. # frame .pwd entry .pwd.entry -relief sunken -width 40 label .pwd.label pack .pwd.entry -side right pack .pwd.label -side left bind .pwd.entry { if [file isdirectory [.pwd.entry get]] { cd [.pwd.entry get] load } } .pwd.label config -text Directory: pack .pwd # # Create the sounds list. # frame .sounds scrollbar .sounds.scroll -command ".sounds.list yview" pack .sounds.scroll -side right -fill y listbox .sounds.list -yscroll ".sounds.scroll set" -relief sunken -setgrid yes bind .sounds.list {destroy .} bind .sounds.list {destroy .} bind .sounds.list {foreach i [selection get] {doit "play" $i}} pack .sounds.list -side top -fill both -expand yes pack .sounds -side top -fill both # # Create the sound action buttons. # frame .buttons button .buttons.play -text "Play" -command \ { foreach i [.sounds.list curselection] { doit "play" [.sounds.list get $i] } } button .buttons.stop -text "Stop" -command \ { foreach i [.sounds.list curselection] { doit "stop" [.sounds.list get $i] } } button .buttons.pause -text "Pause" -command \ { foreach i [.sounds.list curselection] { doit "pause" [.sounds.list get $i] } } button .buttons.continue -text "Continue" -command \ { foreach i [.sounds.list curselection] { doit "continue" [.sounds.list get $i] } } button .buttons.prev -bitmap @/opt/X11R6/include/X11/bitmaps/RotateLeft -command { cd ..; load } button .buttons.next -bitmap @/opt/X11R6/include/X11/bitmaps/Excl -command { stop "#0" } pack .buttons.prev .buttons.play .buttons.stop .buttons.pause \ .buttons.continue .buttons.next -side left -expand yes pack .buttons -side bottom -fill both # # Create the "Configure" window. # proc config {} { global host global volume global hvolume global priority catch {destroy .config} toplevel .config wm title .config "tkrplay configure" frame .config.host entry .config.host.e -relief sunken -width 40 pack .config.host.e -side right .config.host.e insert 0 $host label .config.host.l pack .config.host.l -side left .config.host.l config -text "Sound Host:" pack .config.host -fill x frame .config.hvolume -relief raised -borderwidth 2 label .config.hvolume.l -text "Host Volume" scale .config.hvolume.s -from 0 -to 255 -length 10c -orient horizontal -tickinterval 50 .config.hvolume.s set $hvolume pack .config.hvolume.l .config.hvolume.s pack .config.hvolume frame .config.volume -relief raised -borderwidth 2 label .config.volume.l -text "Sound Volume" scale .config.volume.s -from 0 -to 255 -length 10c -orient horizontal -tickinterval 50 .config.volume.s set $volume pack .config.volume.l .config.volume.s pack .config.volume frame .config.priority -relief raised -borderwidth 2 label .config.priority.l -text "Sound Priority" scale .config.priority.s -from 0 -to 255 -length 10c -orient horizontal -tickinterval 50 .config.priority.s set $priority pack .config.priority.l .config.priority.s pack .config.priority button .config.apply -text "Apply" -command { set host [.config.host.e get] set hvolume [.config.hvolume.s get] set volume [.config.volume.s get] set priority [.config.priority.s get] set hvolume [lindex [split [exec rptp -h $host volume $hvolume] =] 1] .config.hvolume.s set $hvolume } button .config.reset -text "Reset" -command { set volume $default_volume .config.volume.s set $default_volume set priority $default_priority .config.priority.s set $default_priority set host $default_host .config.host.e delete 0 end .config.host.e insert 0 $default_host set hvolume [lindex [split [exec rptp -h $host volume] =] 1] .config.hvolume.s set $hvolume } button .config.cancel -text "Cancel" -command "destroy .config" pack .config.apply .config.reset .config.cancel -side left -expand yes } # # Play a sound. # proc play args { global host global priority global volume exec rplay -h $host -P $priority -v $volume $args } # # Pause a sound. # proc pause args { global host global priority global volume exec rplay -h $host -P $priority -v $volume -p $args } # # Continue a sound. # proc continue args { global host global priority global volume exec rplay -h $host -P $priority -v $volume -c $args } # # Stop a sound. # proc stop args { global host global priority global volume exec rplay -h $host -P $priority -v $volume -s $args } # # Load a list of the current directories' sounds. Only .au, .wav, .aiff, and # directories are displayed. # proc load {} { global dir set dir [pwd] .pwd.entry delete 0 end .pwd.entry insert 0 $dir .sounds.list delete 0 [.sounds.list size] foreach i [exec ls -a] { if [file isdirectory $i] { if {[string compare $i "."] != 0 && [string compare $i ".."] != 0} { .sounds.list insert end $i } } else { if {[string match *.au $i] || [string match *.wav $i] || [string match *.aiff $i]} { .sounds.list insert end $i } } } } # # Change working directory or perform a sound action. # proc doit {action file} { global dir if [file isdirectory $file] { cd $file load } else { case $action in { { play } { play $dir/$file } { stop } { stop $dir/$file } { pause } { pause $dir/$file } { continue } { continue $dir/$file } } } } # # Here's where everything starts. # focus .sounds.list if $argc>0 {set dir [lindex $argv 0]} else {set dir $sound_dir} cd $dir load rplay-3.3.2/contrib/tkrplay/tkrplay100755 153 62 15772 6552756453 16134 0ustar boynsstaff#!/usr/local/bin/wish -f # # Copyright (C) 1994-95 Mark Boyns # # tkrplay # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # # # Usage: tkrplay # # -- Begin configuration options --- set default_host "localhost" set default_volume 127 set default_priority 0 set sound_dir "/usr/local/lib/sounds" # --- End configuration options --- set host $default_host set volume $default_volume set priority $default_priority set hvolume [lindex [split [exec rptp -h $host volume] =] 1] set version "1.1" # # Set window manager parameters. # wm title . "tkrplay $version" wm iconname . "tkrplay $version" wm minsize . 1 1 # # Create the Quit and Configure buttons. # frame .menu -relief raise -borderwidth 2 pack .menu -side top -fill x menubutton .menu.file -text "File" -menu .menu.file.m -underline 0 -relief raise menu .menu.file.m .menu.file.m add command -label "Quit" -command "destroy ." -underline 0 button .menu.config -text "Configure" -command "config" -relief raised pack .menu.file -side left pack .menu.config -side right # # Create the current directory entry. # frame .pwd entry .pwd.entry -relief sunken -width 40 label .pwd.label pack .pwd.entry -side right pack .pwd.label -side left bind .pwd.entry { if [file isdirectory [.pwd.entry get]] { cd [.pwd.entry get] load } } .pwd.label config -text Directory: pack .pwd # # Create the sounds list. # frame .sounds scrollbar .sounds.scroll -command ".sounds.list yview" pack .sounds.scroll -side right -fill y listbox .sounds.list -yscroll ".sounds.scroll set" -relief sunken -geometry 20x20 \ -setgrid yes bind .sounds.list {destroy .} bind .sounds.list {destroy .} bind .sounds.list {foreach i [selection get] {doit "play" $i}} pack .sounds.list -side top -fill both -expand yes pack .sounds -side top -fill both # # Create the sound action buttons. # frame .buttons button .buttons.play -text "Play" -command \ { foreach i [.sounds.list curselection] { doit "play" [.sounds.list get $i] } } button .buttons.stop -text "Stop" -command \ { foreach i [.sounds.list curselection] { doit "stop" [.sounds.list get $i] } } button .buttons.pause -text "Pause" -command \ { foreach i [.sounds.list curselection] { doit "pause" [.sounds.list get $i] } } button .buttons.continue -text "Continue" -command \ { foreach i [.sounds.list curselection] { doit "continue" [.sounds.list get $i] } } button .buttons.prev -bitmap @/usr/include/X11/bitmaps/RotateLeft -command { cd ..; load } button .buttons.next -bitmap @/usr/include/X11/bitmaps/Excl -command { stop "#0" } pack .buttons.prev .buttons.play .buttons.stop .buttons.pause \ .buttons.continue .buttons.next -side left -expand yes pack .buttons -side bottom -fill both # # Create the "Configure" window. # proc config {} { global host global volume global hvolume global priority catch {destroy .config} toplevel .config wm title .config "tkrplay configure" frame .config.host entry .config.host.e -relief sunken -width 40 pack .config.host.e -side right .config.host.e insert 0 $host label .config.host.l pack .config.host.l -side left .config.host.l config -text "Sound Host:" pack .config.host -fill x frame .config.hvolume -relief raised -borderwidth 2 label .config.hvolume.l -text "Host Volume" scale .config.hvolume.s -from 0 -to 255 -length 10c -orient horizontal -tickinterval 50 .config.hvolume.s set $hvolume pack .config.hvolume.l .config.hvolume.s pack .config.hvolume frame .config.volume -relief raised -borderwidth 2 label .config.volume.l -text "Sound Volume" scale .config.volume.s -from 0 -to 255 -length 10c -orient horizontal -tickinterval 50 .config.volume.s set $volume pack .config.volume.l .config.volume.s pack .config.volume frame .config.priority -relief raised -borderwidth 2 label .config.priority.l -text "Sound Priority" scale .config.priority.s -from 0 -to 255 -length 10c -orient horizontal -tickinterval 50 .config.priority.s set $priority pack .config.priority.l .config.priority.s pack .config.priority button .config.apply -text "Apply" -command { set host [.config.host.e get] set hvolume [.config.hvolume.s get] set volume [.config.volume.s get] set priority [.config.priority.s get] set hvolume [lindex [split [exec rptp -h $host volume $hvolume] =] 1] .config.hvolume.s set $hvolume } button .config.reset -text "Reset" -command { set volume $default_volume .config.volume.s set $default_volume set priority $default_priority .config.priority.s set $default_priority set host $default_host .config.host.e delete 0 end .config.host.e insert 0 $default_host set hvolume [lindex [split [exec rptp -h $host volume] =] 1] .config.hvolume.s set $hvolume } button .config.cancel -text "Cancel" -command "destroy .config" pack .config.apply .config.reset .config.cancel -side left -expand yes } # # Play a sound. # proc play args { global host global priority global volume exec rplay -h $host -P $priority -v $volume $args } # # Pause a sound. # proc pause args { global host global priority global volume exec rplay -h $host -P $priority -v $volume -p $args } # # Continue a sound. # proc continue args { global host global priority global volume exec rplay -h $host -P $priority -v $volume -c $args } # # Stop a sound. # proc stop args { global host global priority global volume exec rplay -h $host -P $priority -v $volume -s $args } # # Load a list of the current directories' sounds. Only .au, .wav, .aiff, and # directories are displayed. # proc load {} { global dir set dir [pwd] .pwd.entry delete 0 end .pwd.entry insert 0 $dir .sounds.list delete 0 [.sounds.list size] foreach i [exec ls -a] { if [file isdirectory $i] { if {[string compare $i "."] != 0 && [string compare $i ".."] != 0} { .sounds.list insert end $i } } else { if {[string match *.au $i] || [string match *.wav $i] || [string match *.aiff $i]} { .sounds.list insert end $i } } } } # # Change working directory or perform a sound action. # proc doit {action file} { global dir if [file isdirectory $file] { cd $file load } else { case $action in { { play } { play $dir/$file } { stop } { stop $dir/$file } { pause } { pause $dir/$file } { continue } { continue $dir/$file } } } } # # Here's where everything starts. # focus .sounds.list if $argc>0 {set dir [lindex $argv 0]} else {set dir $sound_dir} cd $dir load rplay-3.3.2/contrib/vu/ 40755 153 62 0 6727650075 13330 5ustar boynsstaffrplay-3.3.2/contrib/vu/Makefile100644 153 62 427 6552756453 15053 0ustar boynsstaffinclude ../../Makefile.config CPPFLAGS= $(CC_OPTIONS) -I../../include -I/usr/X11R6/include .c.o: $(CC) -c $(CPPFLAGS) $(CFLAGS) $< LDFLAGS= $(LD_OPTIONS) -L../../librplay -L/usr/X11R6/lib -lrplay -lforms -lX11 -lm OBJS= vu.o vu: $(OBJS) $(CC) -o $@ $(OBJS) $(LDFLAGS) rplay-3.3.2/contrib/vu/vu.1100644 153 62 1116 6552756453 14143 0ustar boynsstaff.TH VU 1 12/21/97 .SH NAME vu \- rplay vu meter .SH SYNOPSIS .B vu [options] .SH DESCRIPTION Simple vu meter for rplay. While sounds are playing this meter will display the volume of the left and right channels using three colors: green, yellow, and red. .SH OPTIONS .TP .I "\-bw WIDTH" Change the border width. The default is 3. .TP .I "\-display HOST:DPY" X Windows display. The default is $DISPLAY. .TP .I "\-visual CLASS, \-depth DEPTH, \-private, \-shared, \-stdcmap," .TP .I "\-double, \-sync, \-name, etc." .SH SEE ALSO .IR rplay (1), .IR rplayd (8), .IR rptp (1), .IR xrplay (1) rplay-3.3.2/contrib/vu/vu.c100644 153 62 7364 6552756453 14240 0ustar boynsstaff/* * Copyright (C) 1995 Mark Boyns * * This file is part of rplay. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #define NBOXES 8 typedef struct { FL_OBJECT *obj; int level; FL_PD_COL color; } BOX; FL_FORM *form; FL_OBJECT *w, *input; BOX left[] = { { 0, 0, FL_GREEN }, { 0, 32, FL_GREEN }, { 0, 64, FL_GREEN }, { 0, 96, FL_GREEN }, { 0, 128, FL_YELLOW }, { 0, 160, FL_YELLOW }, { 0, 192, FL_RED }, { 0, 224, FL_RED } }; BOX right[] = { { 0, 0, FL_GREEN }, { 0, 32, FL_GREEN }, { 0, 64, FL_GREEN }, { 0, 96, FL_GREEN }, { 0, 128, FL_YELLOW }, { 0, 160, FL_YELLOW }, { 0, 192, FL_RED }, { 0, 224, FL_RED } }; int stereo = 1; float scale = 1.0; void do_form (); void do_rptp (); void event_callback (int fd, int event, char *line); main (int argc, char **argv) { #if 1 fl_flip_yorigin (); fl_initialize (&argc, argv, "VU", 0, 0); #else fl_initialize (argv[0], "VU", 0, 0, &argc, argv); #endif do_form (); do_rptp (); rptp_main_loop (); } void do_form () { int i, width, x, y; if (stereo) { width = 200; } else { width = 100; } form = fl_bgn_form (FL_NO_BOX, width, 260); w = fl_add_box (FL_UP_BOX, 0, 0, width, 260, ""); input = fl_add_input (FL_HIDDEN_INPUT, 0, 0, width, 260, ""); fl_set_input_return (input, FL_RETURN_ALWAYS); fl_set_input (input, ""); x = 10; y = 10; for (i = 0; i < NBOXES; i++, y += 30) { left[i].obj = fl_add_box (FL_DOWN_BOX, x, y, 80, 30, ""); if (stereo) { right[i].obj = fl_add_box (FL_DOWN_BOX, 100+x, y, 80, 30, ""); } } fl_end_form (); fl_show_form (form, FL_FREE_SIZE, FL_FULLBORDER, "VU"); fl_check_forms (); } void do_rptp () { char buf[RPTP_MAX_LINE]; int fd; fd = rptp_open (rplay_default_host (), RPTP_PORT, buf, sizeof (buf)); rptp_async_notify (fd, RPTP_EVENT_LEVEL|RPTP_EVENT_CLOSE, event_callback); } void event_callback (int fd, int event, char *line) { FL_OBJECT *obj; int left_level, right_level, i; switch (event) { case RPTP_EVENT_LEVEL: left_level = atoi (rptp_parse (line, "left")); right_level = atoi (rptp_parse (0, "right")); for (i = 0; i < NBOXES; i++) { if (left_level > left[i].level) { fl_set_object_color (left[i].obj, left[i].color, FL_COL1); } else { fl_set_object_color (left[i].obj, FL_COL1, FL_COL1); } if (stereo) { if (right_level > right[i].level) { fl_set_object_color (right[i].obj, right[i].color, FL_COL1); } else { fl_set_object_color (right[i].obj, FL_COL1, FL_COL1); } } } break; case RPTP_EVENT_CLOSE: exit (1); } obj = fl_check_forms (); if (obj == input) { float new_scale = scale; char *key = fl_get_input (obj); if (*key == '<') { new_scale *= 0.8; } else if (*key == '>') { new_scale *= (1/0.8); } if (new_scale != scale) { fl_scale_form (form, new_scale/scale, new_scale/scale); scale = new_scale; } fl_set_input (input, ""); } } rplay-3.3.2/contrib/window_managers/ 40755 153 62 0 6727650075 16062 5ustar boynsstaffrplay-3.3.2/contrib/window_managers/ctwm100644 153 62 30074 6552756453 17103 0ustar boynsstaff These routines were extracted from the sound hack for olvwm3.3 by Andrew "Ender" Scherpbier (turtle@sciences.sdsu.edu) and modified by J.E. Sacco (jsacco@ssl.com) and then slightly modified by Mark Boyns (boyns@sdsu.edu) for ctwm-3.0. Sound events are stored the .ctwm-sounds file located in your home directory. Here a list of all the supported sound events: KeyPress KeyRelease ButtonPress ButtonRelease MotionNotify EnterNotify LeaveNotify FocusIn FocusOut KeymapNotify Expose GraphicsExpose NoExpose VisibilityNotify CreateNotify DestroyNotify UnmapNotify MapNotify MapRequest ReparentNotify ConfigureNotify ConfigureRequest GravityNotify ResizeRequest CirculateNotify CirculateRequest PropertyNotify SelectionClear SelectionRequest SelectionNotify ColormapNotify ClientMessage MappingNotify And here is a sample sounds file: KeyPress: Cork.au MapNotify: turbbeep.au ResizeRequest: failure.au Startup: 2lust.au Shutdown: 1sadeness.au *** Imakefile.orig Fri Nov 5 11:09:11 1993 --- Imakefile Wed Nov 10 09:03:05 1993 *************** *** 9,14 **** --- 9,15 ---- #define XPM #undef IMCONV #define USEM4 + #define USE_SOUND YFLAGS = -d DEPLIBS = $(DEPXMULIB) $(DEPEXTENSIONLIB) $(DEPXLIB) *************** *** 51,67 **** M4LIB = #endif ! LOCAL_LIBRARIES = $(M4LIB) $(IMCONVLIB) $(XPMLIB) $(XMULIB) $(XTOOLLIB) $(XLIB) ! DEFINES = $(SIGNAL_DEFINES) $(M4DEFINES) $(IMCONVDEFINES) $(XPMDEFINES) ! EXTRA_INCLUDES = $(M4INCDIR) $(IMCONVINCDIR) $(XPMINCDIR) SRCS = gram.c lex.c deftwmrc.c add_window.c gc.c list.c ctwm.c \ parse.c menus.c events.c resize.c util.c version.c iconmgr.c \ ! cursor.c icons.c workmgr.c OBJS = gram.o lex.o deftwmrc.o add_window.o gc.o list.o ctwm.o \ parse.o menus.o events.o resize.o util.o version.o iconmgr.o \ ! cursor.o icons.o workmgr.o PIXMAPFILES = xpm/IslandD.xpm xpm/mail1.xpm xpm/xgopher.xpm \ xpm/IslandW.xpm xpm/nothing.xpm xpm/xgrab.xpm \ --- 52,78 ---- M4LIB = #endif ! #ifdef USE_SOUND ! SOUND_LIBS = -lrplay ! SOUND_INCLUDES = -I/usr/local/include ! SOUND_DEFS = -DSOUNDS ! #else ! SOUND_LIBS = ! SOUND_INCLUDES = ! SOUND_DEFS = ! #endif ! ! LOCAL_LIBRARIES = $(M4LIB) $(IMCONVLIB) $(XPMLIB) $(XMULIB) $(XTOOLLIB) $(XLIB) $(SOUND_LIBS) ! DEFINES = $(SIGNAL_DEFINES) $(M4DEFINES) $(IMCONVDEFINES) $(XPMDEFINES) $(SOUND_DEFS) ! EXTRA_INCLUDES = $(M4INCDIR) $(IMCONVINCDIR) $(XPMINCDIR) $(SOUND_INCLUDES) SRCS = gram.c lex.c deftwmrc.c add_window.c gc.c list.c ctwm.c \ parse.c menus.c events.c resize.c util.c version.c iconmgr.c \ ! cursor.c icons.c workmgr.c sound.c OBJS = gram.o lex.o deftwmrc.o add_window.o gc.o list.o ctwm.o \ parse.o menus.o events.o resize.o util.o version.o iconmgr.o \ ! cursor.o icons.o workmgr.o sound.o PIXMAPFILES = xpm/IslandD.xpm xpm/mail1.xpm xpm/xgopher.xpm \ xpm/IslandW.xpm xpm/nothing.xpm xpm/xgrab.xpm \ *** ctwm.c.orig Tue Jul 20 03:29:19 1993 --- ctwm.c Tue Nov 9 22:14:21 1993 *************** *** 574,579 **** --- 574,583 ---- exit (1); } + #ifdef SOUNDS + play_startup_sound(); + #endif + RestartPreviousState = True; HandlingEvents = TRUE; InitEvents(); *************** *** 856,861 **** --- 860,868 ---- SIGNAL_T Done() { + #ifdef SOUNDS + play_exit_sound(); + #endif Reborder (CurrentTime); XDeleteProperty (dpy, Scr->Root, _XA_WM_WORKSPACESLIST); XCloseDisplay(dpy); *** events.c.orig Tue Jul 20 03:29:20 1993 --- events.c Tue Nov 9 22:15:17 1993 *************** *** 61,66 **** --- 61,70 ---- extern unsigned int mods_used; extern int menuFromFrameOrWindowOrTitlebar; + #ifdef SOUNDS + extern play_sounds(); + #endif + #define MAX_X_EVENT 256 event_proc EventHandler[MAX_X_EVENT]; /* event handler jump table */ char *Action; *************** *** 272,278 **** * Procedure: * DispatchEvent2 - * handle a single X event stored in global var Event ! * this rouitine for is for a call during an f.move * *********************************************************************** */ --- 276,282 ---- * Procedure: * DispatchEvent2 - * handle a single X event stored in global var Event ! * this routine for is for a call during an f.move * *********************************************************************** */ *************** *** 290,295 **** --- 294,303 ---- if (!Scr) return False; + #ifdef SOUNDS + play_sound(Event.type); + #endif + if (menuFromFrameOrWindowOrTitlebar && Event.type == Expose) HandleExpose(); *************** *** 322,327 **** --- 330,338 ---- if (!Scr) return False; if (Event.type>= 0 && Event.type < MAX_X_EVENT) { + #ifdef SOUNDS + play_sound(Event.type); + #endif (*EventHandler[Event.type])(); } *** menus.c.orig Tue Jul 20 03:29:20 1993 --- menus.c Wed Nov 10 10:16:48 1993 *************** *** 58,63 **** --- 58,68 ---- #include #include "version.h" + #ifdef SOUNDS + extern int toggle_sound(); + extern int reread_sounds(); + #endif + extern XEvent Event; int RootFunction = 0; *************** *** 1549,1554 **** --- 1554,1567 ---- switch (func) { + #ifdef SOUNDS + case F_TOGGLESOUND: + toggle_sound(); + break; + case F_REREADSOUNDS: + reread_sounds(); + break; + #endif case F_NOP: case F_TITLE: break; *************** *** 3014,3019 **** --- 3027,3035 ---- #endif #ifdef USEM4 (void) strcat (Info[n], ", USEM4"); + #endif + #ifdef SOUNDS + (void) strcat (Info[n], ", SOUNDS"); #endif n++; Info[n++][0] = '\0'; *** parse.c.orig Tue Jul 20 03:29:20 1993 --- parse.c Wed Nov 10 09:56:35 1993 *************** *** 95,100 **** --- 95,103 ---- extern char *defTwmrc[]; /* default bindings */ + #ifdef SOUNDS + extern int set_sound_host(); + #endif /*********************************************************************** * *************** *** 472,477 **** --- 475,484 ---- #define kws_IconDirectory 8 #define kws_MaxWindowSize 9 #define kws_PixmapDirectory 10 + #ifdef SOUNDS + #define kws_SoundHost 11 + #endif + #define kwn_ConstrainedMoveTime 1 #define kwn_MoveDelta 2 *************** *** 513,519 **** #define kwc_MenuTitleBackground 6 #define kwc_MenuShadowColor 7 - /* * The following is sorted alphabetically according to name (which must be * in lowercase and only contain the letters a-z). It is fed to a binary --- 520,525 ---- *************** *** 599,604 **** --- 605,613 ---- { "f.raise", FKEYWORD, F_RAISE }, { "f.raiselower", FKEYWORD, F_RAISELOWER }, { "f.refresh", FKEYWORD, F_REFRESH }, + #ifdef SOUNDS + { "f.rereadsounds", FKEYWORD, F_REREADSOUNDS }, + #endif { "f.resize", FKEYWORD, F_RESIZE }, { "f.restart", FKEYWORD, F_RESTART }, { "f.righticonmgr", FKEYWORD, F_RIGHTICONMGR }, *************** *** 612,617 **** --- 621,629 ---- { "f.sorticonmgr", FKEYWORD, F_SORTICONMGR }, { "f.source", FSKEYWORD, F_BEEP }, /* XXX - don't work */ { "f.title", FKEYWORD, F_TITLE }, + #ifdef SOUNDS + { "f.togglesound", FKEYWORD, F_TOGGLESOUND }, + #endif { "f.togglestate", FKEYWORD, F_TOGGLESTATE }, { "f.topzoom", FKEYWORD, F_TOPZOOM }, { "f.twmrc", FKEYWORD, F_RESTART }, *************** *** 722,727 **** --- 734,742 ---- { "showiconmanager", KEYWORD, kw0_ShowIconManager }, { "showworkspacemanager", KEYWORD, kw0_ShowWorkspaceManager }, { "sorticonmanager", KEYWORD, kw0_SortIconManager }, + #ifdef SOUNDS + { "soundhost", SKEYWORD, kws_SoundHost }, + #endif { "south", DKEYWORD, D_SOUTH }, { "squeezetitle", SQUEEZE_TITLE, 0 }, { "starticonified", START_ICONIFIED, 0 }, *************** *** 1007,1012 **** --- 1022,1034 ---- Scr->MaxWindowWidth = JunkWidth; Scr->MaxWindowHeight = JunkHeight; return 1; + + #ifdef SOUNDS + case kws_SoundHost: + if (Scr->FirstTime) set_sound_host(s); + return 1; + #endif + } return 0; *** parse.h.orig Tue Jul 20 03:29:19 1993 --- parse.h Wed Nov 10 08:53:25 1993 *************** *** 103,108 **** --- 103,112 ---- #define F_NEXTWORKSPACE 56 #define F_PREVWORKSPACE 57 #define F_SEPARATOR 58 + #ifdef SOUNDS + #define F_TOGGLESOUND 59 + #define F_REREADSOUNDS 60 + #endif #define F_MENU 101 /* string */ #define F_WARPTO 102 /* string */ *** sound.c.orig Tue Nov 9 22:12:27 1993 --- sound.c Wed Nov 10 09:22:45 1993 *************** *** 0 **** --- 1,181 ---- + /* + * These routines were extracted from the sound hack for olvwm3.3 by + * Andrew "Ender" Scherpbier (turtle@sciences.sdsu.edu) + * and modified by J.E. Sacco (jsacco @ssl.com) + */ + + #include + #include + #include + + char *eventNames[] = + { + "", + "", + "KeyPress", + "KeyRelease", + "ButtonPress", + "ButtonRelease", + "MotionNotify", + "EnterNotify", + "LeaveNotify", + "FocusIn", + "FocusOut", + "KeymapNotify", + "Expose", + "GraphicsExpose", + "NoExpose", + "VisibilityNotify", + "CreateNotify", + "DestroyNotify", + "UnmapNotify", + "MapNotify", + "MapRequest", + "ReparentNotify", + "ConfigureNotify", + "ConfigureRequest", + "GravityNotify", + "ResizeRequest", + "CirculateNotify", + "CirculateRequest", + "PropertyNotify", + "SelectionClear", + "SelectionRequest", + "SelectionNotify", + "ColormapNotify", + "ClientMessage", + "MappingNotify", + "Startup", + "Shutdown" + }; + + #define NEVENTS (sizeof(eventNames) / sizeof(char *)) + + RPLAY *rp[NEVENTS]; + + static int need_sound_init = 1; + static int sound_fd = 0; + static int sound_state = 1; + static int startup_sound = NEVENTS -2; + static int exit_sound = NEVENTS -1; + static char hostname[200]; + + /* + * initialize + */ + static + sound_init () + { + int i; + FILE *fl; + char buffer[100]; + char *token; + + need_sound_init = 0; + if (sound_fd == 0) { + if (hostname[0] == '\0') { + strcpy(hostname, rplay_default_host()); + } + + if ((sound_fd = rplay_open (hostname)) < 0) + rplay_perror ("create"); + } + + /* + * Destroy any old sounds + */ + for (i = 0; i < NEVENTS; i++) { + if (rp[i] != NULL) + rplay_destroy (rp[i]); + rp[i] = NULL; + } + + /* + * Now read the file which contains the sounds + */ + fl = fopen (".ctwm-sounds", "r"); + if (fl == NULL) + return; + while (fgets (buffer, 100, fl) != NULL) { + token = strtok (buffer, ": \t"); + if (token == NULL) + continue; + for (i = 0; i < NEVENTS; i++) { + if (strcmp (token, eventNames[i]) == 0) { + token = strtok (NULL, " \t\r\n"); + if (token == NULL || *token == '#' || isspace (*token)) + continue; + rp[i] = rplay_create (RPLAY_PLAY); + if (rp[i] == NULL) { + rplay_perror ("create"); + continue; + } + if (rplay_set(rp[i], RPLAY_INSERT, 0, RPLAY_SOUND, token, NULL) + < 0) + rplay_perror ("rplay"); + } + } + } + fclose (fl); + } + + + /* + * Play sound + */ + play_sound (snd) + int snd; + { + if (sound_state == 0) + return; + + if (need_sound_init) + sound_init (); + + if (rp[snd] == NULL) + return; + if (rplay (sound_fd, rp[snd]) < 0) + rplay_perror ("create"); + } + + play_startup_sound() + { + play_sound(startup_sound); + } + + play_exit_sound() + { + play_sound(exit_sound); + } + + /* + * Toggle the sound on/off + */ + toggle_sound () + { + sound_state ^= 1; + } + + + /* + * Re-read the sounds mapping file + */ + reread_sounds () + { + sound_init (); + } + + /* + * Set the SoundHost and force the sound_fd to be re-opened. + */ + set_sound_host(host) + char *host; + { + strcpy(hostname, host); + if (sound_fd != 0) + { + rplay_close(sound_fd); + } + sound_fd = 0; + } + rplay-3.3.2/contrib/window_managers/fvwm100644 153 62 332 6552756453 17042 0ustar boynsstaff fvwm is shipped with a audio module called FvwmAudio. This module has builtin rplay support. fvwm is the *greatest* window manager. Sources can be obtained via anonymous ftp a spcot.sanders.com in /pub/fvwm. Mark rplay-3.3.2/contrib/window_managers/tvtwm100644 153 62 25714 6552756453 17317 0ustar boynsstaff These routines were extracted from the sound hack for olvwm3.3 by Andrew "Ender" Scherpbier (turtle@sciences.sdsu.edu) and modified by J.E. Sacco (jsacco@ssl.com) for tvtwm. Sound events are stored the .tvtwm-sounds file located in your home directory. Here a list of all the supported sound events: KeyPress KeyRelease ButtonPress ButtonRelease MotionNotify EnterNotify LeaveNotify FocusIn FocusOut KeymapNotify Expose GraphicsExpose NoExpose VisibilityNotify CreateNotify DestroyNotify UnmapNotify MapNotify MapRequest ReparentNotify ConfigureNotify ConfigureRequest GravityNotify ResizeRequest CirculateNotify CirculateRequest PropertyNotify SelectionClear SelectionRequest SelectionNotify ColormapNotify ClientMessage MappingNotify And here is a sample sounds file: KeyPress: Cork.au MapNotify: turbbeep.au ResizeRequest: failure.au Startup: 2lust.au Shutdown: 1sadeness.au found the following files to diff ./sound.c.dist ./events.c.dist ./parse.c.dist ./parse.h.dist ./menus.c.dist ./twm.c.dist ./Imakefile.dist *** ./sound.c.dist Tue Nov 9 21:41:54 1993 --- ./sound.c Tue Nov 9 20:37:17 1993 *************** *** 0 **** --- 1,164 ---- + /* + * These routines were extracted from the sound hack for olvwm3.3 by + * Andrew "Ender" Scherpbier (turtle@sciences.sdsu.edu) + * and modified by J.E. Sacco (jsacco @ssl.com) + */ + + #include + #include + #include + + char *eventNames[] = + { + "", + "", + "KeyPress", + "KeyRelease", + "ButtonPress", + "ButtonRelease", + "MotionNotify", + "EnterNotify", + "LeaveNotify", + "FocusIn", + "FocusOut", + "KeymapNotify", + "Expose", + "GraphicsExpose", + "NoExpose", + "VisibilityNotify", + "CreateNotify", + "DestroyNotify", + "UnmapNotify", + "MapNotify", + "MapRequest", + "ReparentNotify", + "ConfigureNotify", + "ConfigureRequest", + "GravityNotify", + "ResizeRequest", + "CirculateNotify", + "CirculateRequest", + "PropertyNotify", + "SelectionClear", + "SelectionRequest", + "SelectionNotify", + "ColormapNotify", + "ClientMessage", + "MappingNotify", + "Startup", + "Shutdown" + }; + + #define NEVENTS (sizeof(eventNames) / sizeof(char *)) + + RPLAY *rp[NEVENTS]; + + static int need_sound_init = 1; + static int sound_fd = 0; + static int sound_state = 1; + static int startup_sound = NEVENTS -2; + static int exit_sound = NEVENTS -1; + + /* + * initialize + */ + static + sound_init () + { + int i; + FILE *fl; + char buffer[100]; + char *token; + char hostname[200]; + + need_sound_init = 0; + if (sound_fd == 0) { + gethostname (hostname, 200); + + if ((sound_fd = rplay_open (hostname)) < 0) + rplay_perror ("create"); + } + + /* + * Destroy any old sounds + */ + for (i = 0; i < NEVENTS; i++) { + if (rp[i] != NULL) + rplay_destroy (rp[i]); + rp[i] = NULL; + } + + /* + * Now read the file which contains the sounds + */ + fl = fopen (".tvtwm-sounds", "r"); + if (fl == NULL) + return; + while (fgets (buffer, 100, fl) != NULL) { + token = strtok (buffer, ": \t"); + if (token == NULL) + continue; + for (i = 0; i < NEVENTS; i++) { + if (strcmp (token, eventNames[i]) == 0) { + token = strtok (NULL, " \t\r\n"); + if (token == NULL || *token == '#' || isspace (*token)) + continue; + rp[i] = rplay_create (RPLAY_PLAY); + if (rp[i] == NULL) { + rplay_perror ("create"); + continue; + } + if (rplay_set(rp[i], RPLAY_INSERT, 0, RPLAY_SOUND, token, NULL) + < 0) + rplay_perror ("rplay"); + } + } + } + fclose (fl); + } + + + /* + * Play sound + */ + play_sound (snd) + int snd; + { + if (sound_state == 0) + return; + + if (need_sound_init) + sound_init (); + + if (rp[snd] == NULL) + return; + if (rplay (sound_fd, rp[snd]) < 0) + rplay_perror ("create"); + } + + play_startup_sound() + { + play_sound(startup_sound); + } + + play_exit_sound() + { + play_sound(exit_sound); + } + + /* + * Toggle the sound on/off + */ + toggle_sound () + { + sound_state ^= 1; + } + + + /* + * Re-read the sounds mapping file + */ + reread_sounds () + { + sound_init (); + } *** ./events.c.dist Fri Nov 5 11:11:04 1993 --- ./events.c Tue Nov 9 18:18:00 1993 *************** *** 134,139 **** --- 134,143 ---- #include "version.h" #include "vdt.h" + #ifdef SOUNDS + extern play_sounds(); + #endif + extern unsigned int mods_used; extern int menuFromFrameOrWindowOrTitlebar; *************** *** 351,357 **** * Procedure: * DispatchEvent2 - * handle a single X event stored in global var Event ! * this rouitine for is for a call during an f.move * *********************************************************************** */ --- 355,361 ---- * Procedure: * DispatchEvent2 - * handle a single X event stored in global var Event ! * this routine for is for a call during an f.move * *********************************************************************** */ *************** *** 373,378 **** --- 377,386 ---- if (!Scr) return False; + #ifdef SOUNDS + play_sound(Event.type); + #endif + if (menuFromFrameOrWindowOrTitlebar && Event.type == Expose) HandleExpose(); *************** *** 407,412 **** --- 415,423 ---- if (!Scr) return False; if (Event.type>= 0 && Event.type < MAX_X_EVENT) { + #ifdef SOUNDS + play_sound(Event.type); + #endif (*EventHandler[Event.type])(); } *** ./parse.c.dist Tue Nov 9 18:27:11 1993 --- ./parse.c Tue Nov 9 19:23:46 1993 *************** *** 56,62 **** #include #ifndef SYSTEM_INIT_FILE ! #define SYSTEM_INIT_FILE "/usr/local/X11R4/lib/twm/system.twmrc" #endif #define BUF_LEN 300 --- 56,62 ---- #include #ifndef SYSTEM_INIT_FILE ! #define SYSTEM_INIT_FILE "/usr/local/X11R5/lib/twm/system.twmrc" #endif #define BUF_LEN 300 *************** *** 652,657 **** --- 652,660 ---- { "f.raiselower", FKEYWORD, F_RAISELOWER }, { "f.refresh", FKEYWORD, F_REFRESH }, { "f.relativeresize", FKEYWORD, F_RELATIVERESIZE }, + #ifdef SOUNDS + { "f.rereadsounds", FKEYWORD, F_REREADSOUNDS }, + #endif { "f.resize", FKEYWORD, F_RESIZE }, { "f.restart", FKEYWORD, F_RESTART }, { "f.righticonmgr", FKEYWORD, F_RIGHTICONMGR }, *************** *** 670,675 **** --- 673,681 ---- { "f.stick", FKEYWORD, F_STICK }, { "f.test", FKEYWORD, F_TESTEXEC }, { "f.title", FKEYWORD, F_TITLE }, + #ifdef SOUNDS + { "f.togglesound", FKEYWORD, F_TOGGLESOUND }, + #endif { "f.topzoom", FKEYWORD, F_TOPZOOM }, { "f.twmrc", FKEYWORD, F_RESTART }, { "f.unfocus", FKEYWORD, F_UNFOCUS }, *** ./parse.h.dist Tue Nov 9 18:35:53 1993 --- ./parse.h Tue Nov 9 18:37:02 1993 *************** *** 102,107 **** --- 102,112 ---- #define F_CONSTRAINEDMOVE 55 #define F_OPAQUEMOVE 56 #define F_DELETEORDESTROY 57 + #ifdef SOUNDS + #define F_TOGGLESOUND 58 + #define F_REREADSOUNDS 59 + #endif + #define F_MENU 101 /* string */ #define F_WARPTO 102 /* string */ *** ./menus.c.dist Tue Nov 9 18:42:53 1993 --- ./menus.c Tue Nov 9 18:49:00 1993 *************** *** 172,177 **** --- 172,182 ---- #include "add_window.h" #include "patchlevel.h" + #ifdef SOUNDS + extern int toggle_sound(); + extern int reread_sounds(); + #endif + extern XEvent Event; int RootFunction = 0; *************** *** 1959,1964 **** --- 1964,1977 ---- switch (func) { + #ifdef SOUNDS + case F_TOGGLESOUND: + toggle_sound(); + break; + case F_REREADSOUNDS: + reread_sounds(); + break; + #endif case F_NOP: case F_TITLE: break; *** ./twm.c.dist Tue Nov 9 18:50:08 1993 --- ./twm.c Tue Nov 9 21:35:26 1993 *************** *** 717,722 **** --- 717,726 ---- } } + #ifdef SOUNDS + play_startup_sound(); + #endif + HandleEvents(); } *************** *** 1161,1166 **** --- 1165,1173 ---- SIGNAL_T Done() { + #ifdef SOUNDS + play_exit_sound(); + #endif Reborder (CurrentTime); RemoveProperties(); XCloseDisplay(dpy); *** ./Imakefile.dist Tue Nov 9 18:58:26 1993 --- ./Imakefile Tue Nov 9 20:24:29 1993 *************** *** 46,58 **** XPM_DEF = -DXPM XLOADIM_DEF = -DXLOADIMAGE=\"$(BINDIR)/xloadimage\" XCOMM Ultrix doesn't have a mkstemp in libc... XCOMM SysV R4 doesn't seem to either... #if SystemV || defined(UltrixArchitecture) ! LOCAL_DEFINES = $(XPM_DEF) -DNOSTEMP #else ! LOCAL_DEFINES = $(XPM_DEF) #endif XCOMM Various defines to pass into twm.c --- 46,63 ---- XPM_DEF = -DXPM XLOADIM_DEF = -DXLOADIMAGE=\"$(BINDIR)/xloadimage\" + XCOMM Specify rplay library + RPLAY = -lrplay + RPLAY_INC = -I/usr/local/include + EXTRA_INCLUDES = $(RPLAY_INC) + XCOMM Ultrix doesn't have a mkstemp in libc... XCOMM SysV R4 doesn't seem to either... #if SystemV || defined(UltrixArchitecture) ! LOCAL_DEFINES = $(XPM_DEF) -DNOSTEMP -SOUNDS #else ! LOCAL_DEFINES = $(XPM_DEF) -DSOUNDS #endif XCOMM Various defines to pass into twm.c *************** *** 65,83 **** #endif TWM_DEFS = $(XLOADIM_DEF) $(M4_DEF) $(WAITPID_DEF) ! LOCAL_LIBRARIES = $(XMULIB) $(EXTENSIONLIB) $(XPMLIB) $(XLIB) LINTLIBS = $(LINTXMU) $(LINTEXTENSIONLIB) $(LINTXLIB) DEFINES = -DSHAPE $(RELEASE_DEFINES) $(LOCAL_DEFINES) $(SIGNAL_DEFINES) SRCS = gram.c lex.c deftwmrc.c add_window.c gc.c list.c twm.c \ parse.c menus.c events.c resize.c util.c version.c \ iconmgr.c cursor.c icons.c vdt.c move.c LocPixmap.c \ ! regexp.c OBJS = gram.o lex.o deftwmrc.o add_window.o gc.o list.o twm.o \ parse.o menus.o events.o resize.o util.o version.o \ iconmgr.o cursor.o icons.o vdt.o move.o LocPixmap.o \ ! regexp.o AllTarget(tvtwm ssetroot) --- 70,88 ---- #endif TWM_DEFS = $(XLOADIM_DEF) $(M4_DEF) $(WAITPID_DEF) ! LOCAL_LIBRARIES = $(XMULIB) $(EXTENSIONLIB) $(XPMLIB) $(XLIB) $(RPLAY) LINTLIBS = $(LINTXMU) $(LINTEXTENSIONLIB) $(LINTXLIB) DEFINES = -DSHAPE $(RELEASE_DEFINES) $(LOCAL_DEFINES) $(SIGNAL_DEFINES) SRCS = gram.c lex.c deftwmrc.c add_window.c gc.c list.c twm.c \ parse.c menus.c events.c resize.c util.c version.c \ iconmgr.c cursor.c icons.c vdt.c move.c LocPixmap.c \ ! regexp.c sound.c OBJS = gram.o lex.o deftwmrc.o add_window.o gc.o list.o twm.o \ parse.o menus.o events.o resize.o util.o version.o \ iconmgr.o cursor.o icons.o vdt.o move.o LocPixmap.o \ ! regexp.o sound.o AllTarget(tvtwm ssetroot) rplay-3.3.2/contrib/window_managers/twm100644 153 62 22757 6552756453 16751 0ustar boynsstaff These routines were extracted from the sound hack for olvwm3.3 by Andrew "Ender" Scherpbier (turtle@sciences.sdsu.edu) and modified by J.E. Sacco (jsacco@ssl.com) for twm. Sound events are stored the .twm-sounds file located in your home directory. Here a list of all the supported sound events: KeyPress KeyRelease ButtonPress ButtonRelease MotionNotify EnterNotify LeaveNotify FocusIn FocusOut KeymapNotify Expose GraphicsExpose NoExpose VisibilityNotify CreateNotify DestroyNotify UnmapNotify MapNotify MapRequest ReparentNotify ConfigureNotify ConfigureRequest GravityNotify ResizeRequest CirculateNotify CirculateRequest PropertyNotify SelectionClear SelectionRequest SelectionNotify ColormapNotify ClientMessage MappingNotify And here is a sample sounds file: KeyPress: Cork.au MapNotify: turbbeep.au ResizeRequest: failure.au Startup: 2lust.au Shutdown: 1sadeness.au ----------------------twm patches ----------------------------------------- found the following files to diff ./events.c.dist ./parse.h.dist ./sound.c.dist ./parse.c.dist ./menus.c.dist ./twm.c.dist ./Imakefile.dist *** ./events.c.dist Tue Nov 9 22:36:17 1993 --- ./events.c Tue Nov 9 22:37:59 1993 *************** *** 50,55 **** --- 50,59 ---- #include "iconmgr.h" #include "version.h" + #ifdef SOUNDS + extern play_sounds(); + #endif + extern int iconifybox_width, iconifybox_height; extern unsigned int mods_used; extern int menuFromFrameOrWindowOrTitlebar; *************** *** 277,282 **** --- 281,290 ---- if (!Scr) return False; + #ifdef SOUNDS + play_sound(Event.type); + #endif + if (menuFromFrameOrWindowOrTitlebar && Event.type == Expose) HandleExpose(); *************** *** 309,314 **** --- 317,325 ---- if (!Scr) return False; if (Event.type>= 0 && Event.type < MAX_X_EVENT) { + #ifdef SOUNDS + play_sound(Event.type); + #endif (*EventHandler[Event.type])(); } *** ./parse.h.dist Tue Nov 9 22:38:04 1993 --- ./parse.h Tue Nov 9 22:38:49 1993 *************** *** 90,95 **** --- 90,100 ---- #define F_CUTFILE 43 #define F_SHOWLIST 44 #define F_HIDELIST 45 + #ifdef SOUNDS + #define F_TOGGLESOUND 46 + #define F_REREADSOUNDS 47 + #endif + #define F_MENU 101 /* string */ #define F_WARPTO 102 /* string */ *** ./sound.c.dist Wed Nov 10 10:07:02 1993 --- ./sound.c Wed Nov 10 09:31:52 1993 *************** *** 0 **** --- 1,164 ---- + /* + * These routines were extracted from the sound hack for olvwm3.3 by + * Andrew "Ender" Scherpbier (turtle@sciences.sdsu.edu) + * and modified by J.E. Sacco (jsacco @ssl.com) + */ + + #include + #include + #include + + char *eventNames[] = + { + "", + "", + "KeyPress", + "KeyRelease", + "ButtonPress", + "ButtonRelease", + "MotionNotify", + "EnterNotify", + "LeaveNotify", + "FocusIn", + "FocusOut", + "KeymapNotify", + "Expose", + "GraphicsExpose", + "NoExpose", + "VisibilityNotify", + "CreateNotify", + "DestroyNotify", + "UnmapNotify", + "MapNotify", + "MapRequest", + "ReparentNotify", + "ConfigureNotify", + "ConfigureRequest", + "GravityNotify", + "ResizeRequest", + "CirculateNotify", + "CirculateRequest", + "PropertyNotify", + "SelectionClear", + "SelectionRequest", + "SelectionNotify", + "ColormapNotify", + "ClientMessage", + "MappingNotify", + "Startup", + "Shutdown" + }; + + #define NEVENTS (sizeof(eventNames) / sizeof(char *)) + + RPLAY *rp[NEVENTS]; + + static int need_sound_init = 1; + static int sound_fd = 0; + static int sound_state = 1; + static int startup_sound = NEVENTS -2; + static int exit_sound = NEVENTS -1; + + /* + * initialize + */ + static + sound_init () + { + int i; + FILE *fl; + char buffer[100]; + char *token; + char hostname[200]; + + need_sound_init = 0; + if (sound_fd == 0) { + gethostname (hostname, 200); + + if ((sound_fd = rplay_open (hostname)) < 0) + rplay_perror ("create"); + } + + /* + * Destroy any old sounds + */ + for (i = 0; i < NEVENTS; i++) { + if (rp[i] != NULL) + rplay_destroy (rp[i]); + rp[i] = NULL; + } + + /* + * Now read the file which contains the sounds + */ + fl = fopen (".twm-sounds", "r"); + if (fl == NULL) + return; + while (fgets (buffer, 100, fl) != NULL) { + token = strtok (buffer, ": \t"); + if (token == NULL) + continue; + for (i = 0; i < NEVENTS; i++) { + if (strcmp (token, eventNames[i]) == 0) { + token = strtok (NULL, " \t\r\n"); + if (token == NULL || *token == '#' || isspace (*token)) + continue; + rp[i] = rplay_create (RPLAY_PLAY); + if (rp[i] == NULL) { + rplay_perror ("create"); + continue; + } + if (rplay_set(rp[i], RPLAY_INSERT, 0, RPLAY_SOUND, token, NULL) + < 0) + rplay_perror ("rplay"); + } + } + } + fclose (fl); + } + + + /* + * Play sound + */ + play_sound (snd) + int snd; + { + if (sound_state == 0) + return; + + if (need_sound_init) + sound_init (); + + if (rp[snd] == NULL) + return; + if (rplay (sound_fd, rp[snd]) < 0) + rplay_perror ("create"); + } + + play_startup_sound() + { + play_sound(startup_sound); + } + + play_exit_sound() + { + play_sound(exit_sound); + } + + /* + * Toggle the sound on/off + */ + toggle_sound () + { + sound_state ^= 1; + } + + + /* + * Re-read the sounds mapping file + */ + reread_sounds () + { + sound_init (); + } *** ./parse.c.dist Tue Nov 9 22:38:58 1993 --- ./parse.c Wed Nov 10 10:00:55 1993 *************** *** 424,429 **** --- 424,432 ---- { "f.raise", FKEYWORD, F_RAISE }, { "f.raiselower", FKEYWORD, F_RAISELOWER }, { "f.refresh", FKEYWORD, F_REFRESH }, + #ifdef SOUNDS + { "f.rereadsounds", FKEYWORD, F_REREADSOUNDS }, + #endif { "f.resize", FKEYWORD, F_RESIZE }, { "f.restart", FKEYWORD, F_RESTART }, { "f.righticonmgr", FKEYWORD, F_RIGHTICONMGR }, *************** *** 433,438 **** --- 436,444 ---- { "f.sorticonmgr", FKEYWORD, F_SORTICONMGR }, { "f.source", FSKEYWORD, F_BEEP }, /* XXX - don't work */ { "f.title", FKEYWORD, F_TITLE }, + #ifdef SOUNDS + { "f.togglesound", FKEYWORD, F_TOGGLESOUND }, + #endif { "f.topzoom", FKEYWORD, F_TOPZOOM }, { "f.twmrc", FKEYWORD, F_RESTART }, { "f.unfocus", FKEYWORD, F_UNFOCUS }, *** ./menus.c.dist Tue Nov 9 22:40:32 1993 --- ./menus.c Wed Nov 10 09:43:29 1993 *************** *** 52,57 **** --- 52,62 ---- #include #include "version.h" + #ifdef SOUNDS + extern int toggle_sound(); + extern int reread_sounds(); + #endif + extern XEvent Event; int RootFunction = NULL; *************** *** 1347,1352 **** --- 1352,1365 ---- switch (func) { + #ifdef SOUNDS + case F_TOGGLESOUND: + toggle_sound(); + break; + case F_REREADSOUNDS: + reread_sounds(); + break; + #endif case F_UPICONMGR: case F_LEFTICONMGR: case F_RIGHTICONMGR: *** ./twm.c.dist Tue Nov 9 22:42:59 1993 --- ./twm.c Tue Nov 9 22:46:34 1993 *************** *** 110,115 **** --- 110,120 ---- extern void assign_var_savecolor(); + #ifdef SOUNDS + extern int play_startup_sound(); + extern int play_exit_sound(); + #endif + /*********************************************************************** * * Procedure: *************** *** 511,516 **** --- 516,524 ---- RestartPreviousState = False; HandlingEvents = TRUE; + #ifdef SOUNDS + play_startup_sound(); + #endif InitEvents(); HandleEvents(); } *************** *** 766,771 **** --- 774,782 ---- SIGNAL_T Done() { + #ifdef SOUNDS + play_exit_sound(); + #endif Reborder (CurrentTime); XCloseDisplay(dpy); exit(0); *** ./Imakefile.dist Tue Nov 9 22:46:46 1993 --- ./Imakefile Wed Nov 10 09:48:40 1993 *************** *** 6,24 **** XCOMM distribute this one. XCOMM YFLAGS = -d DEPLIBS = $(DEPXMULIB) $(DEPEXTENSIONLIB) $(DEPXLIB) ! LOCAL_LIBRARIES = $(XMULIB) $(EXTENSIONLIB) $(XLIB) LINTLIBS = $(LINTXMU) $(LINTEXTENSIONLIB) $(LINTXLIB) ! DEFINES = $(SIGNAL_DEFINES) SRCS = gram.c lex.c deftwmrc.c add_window.c gc.c list.c twm.c \ parse.c menus.c events.c resize.c util.c version.c iconmgr.c \ ! cursor.c icons.c OBJS = gram.o lex.o deftwmrc.o add_window.o gc.o list.o twm.o \ parse.o menus.o events.o resize.o util.o version.o iconmgr.o \ ! cursor.o icons.o AllTarget(twm) --- 6,30 ---- XCOMM distribute this one. XCOMM + XCOMM Specify rplay library + RPLAY = -lrplay + RPLAY_INC = -I/usr/local/include + EXTRA_INCLUDES = $(RPLAY_INC) + LOCAL_DEFINES = -DSOUNDS + YFLAGS = -d DEPLIBS = $(DEPXMULIB) $(DEPEXTENSIONLIB) $(DEPXLIB) ! LOCAL_LIBRARIES = $(XMULIB) $(EXTENSIONLIB) $(XLIB) $(RPLAY) LINTLIBS = $(LINTXMU) $(LINTEXTENSIONLIB) $(LINTXLIB) ! DEFINES = $(SIGNAL_DEFINES) $(LOCAL_DEFINES) SRCS = gram.c lex.c deftwmrc.c add_window.c gc.c list.c twm.c \ parse.c menus.c events.c resize.c util.c version.c iconmgr.c \ ! cursor.c icons.c sound.c OBJS = gram.o lex.o deftwmrc.o add_window.o gc.o list.o twm.o \ parse.o menus.o events.o resize.o util.o version.o iconmgr.o \ ! cursor.o icons.o sound.o AllTarget(twm) rplay-3.3.2/contrib/window_managers/olvwm/ 40755 153 62 0 6727650075 17226 5ustar boynsstaffrplay-3.3.2/contrib/window_managers/olvwm/.olvwm-sounds100644 153 62 154 6552756453 21764 0ustar boynsstaffKeyPress: Cork.au MapNotify: turbbeep.au ResizeRequest: failure.au Startup: 2lust.au Shutdown: 1sadeness.au rplay-3.3.2/contrib/window_managers/olvwm/README100644 153 62 455 6552756453 20172 0ustar boynsstaff This directory contains rplay 3 sound patches to olvwm 3.3 which were originally done my Andrew Scherpbier and modified to support rplay 3 by Joseph E. Sacco . olvwm-3.3-patch The patch. olvwm.events A list of olvwm events. .olvwm-sounds A sample olvwm sound configuration file. rplay-3.3.2/contrib/window_managers/olvwm/olvwm-3.3-patch100644 153 62 12151 6552756453 22033 0ustar boynsstaffdiff -r -c /tmp/olvwm3.3/Debug.c ./Debug.c *** /tmp/olvwm3.3/Debug.c Sat Dec 12 09:27:01 1992 --- ./Debug.c Fri Dec 11 22:19:10 1992 *************** *** 60,65 **** --- 60,69 ---- "ColormapNotify", "ClientMessage", "MappingNotify", + #ifdef SOUNDS + "Startup", + "Shutdown", + #endif }; void *************** *** 99,101 **** --- 103,209 ---- typeNames[win->core.kind]); (void) fflush(stderr); } + + #ifdef SOUNDS + #include + #include + #include + + #define NEVENTS (sizeof(eventNames) / sizeof(char *)) + + RPLAY *rp[NEVENTS]; + + static int need_sound_init = 1; + static int sound_fd = 0; + static int sound_state = 1; + + static sound_init() + { + int i; + FILE *fl; + char buffer[100]; + char *token; + char hostname[200]; + + need_sound_init = 0; + if (sound_fd == 0) + { + gethostname(hostname, 200); + if ((sound_fd = rplay_open(hostname)) < 0) + rplay_perror("create"); + } + + /* + * Destroy any old sounds + */ + for (i = 0; i < NEVENTS; i++) + { + if (rp[i] != NULL) + rplay_destroy(rp[i]); + rp[i] = NULL; + } + + /* + * Now read the file which contains the sounds + */ + fl = fopen(".olvwm-sounds", "r"); + if (fl == NULL) + return; + while (fgets(buffer, 100, fl) != NULL) + { + token = strtok(buffer, ": \t"); + if (token == NULL) + continue; + for (i = 0; i < NEVENTS; i++) + { + if (strcmp(token, eventNames[i]) == 0) + { + token = strtok(NULL, " \t\r\n"); + if (token == NULL || *token == '#' || isspace(*token)) + continue; + rp[i] = rplay_create(RPLAY_PLAY); + if (rp[i] == NULL) + { + rplay_perror("create"); + continue; + } + if (rplay_set(rp[i], RPLAY_INSERT, 0, + RPLAY_SOUND, token, + NULL) < 0) + { + rplay_perror("rplay"); + } + } + } + } + fclose(fl); + } + + + play_sound(snd) + int snd; + { + if (sound_state == 0) + return; + + if (need_sound_init) + sound_init(); + + if (rp[snd] == NULL) + return; + if (rplay(sound_fd, rp[snd]) < 0) + rplay_perror("create"); + } + + + toggle_sound() + { + sound_state ^= 1; + } + + + reread_sounds() + { + sound_init(); + } + #endif diff -r -c /tmp/olvwm3.3/Makefile.sunpro ./Makefile.sunpro *** /tmp/olvwm3.3/Makefile.sunpro Sat Dec 12 09:27:02 1992 --- ./Makefile.sunpro Sat Dec 12 08:20:29 1992 *************** *** 33,40 **** # # You shouldn't need to change anything below this line ! INC = -I${OPENWINHOME}/include ! CFLAGS = ${INC} ${DEBUG} -DOW_I18N_L3 -DSUNDAE -DSHAPE HEADERS = cmdstream.h cursors.h defaults.h environ.h events.h gettext.h \ globals.h group.h helpcmd.h i18n.h iconimage.h iconmask.h \ --- 33,40 ---- # # You shouldn't need to change anything below this line ! INC = -I${OPENWINHOME}/include -I/usr/local/include ! CFLAGS = ${INC} ${DEBUG} -DOW_I18N_L3 -DSUNDAE -DSHAPE -DSOUNDS HEADERS = cmdstream.h cursors.h defaults.h environ.h events.h gettext.h \ globals.h group.h helpcmd.h i18n.h iconimage.h iconmask.h \ *************** *** 53,59 **** ol_button.c LDFLAGS = -L${OPENWINHOME}/lib ! LIBS = ${LDFLAGS} -lolgx -lX11 -lXext -ll -lm OBJS = ${SRCS:.c=.o} ${VERSION} --- 53,59 ---- ol_button.c LDFLAGS = -L${OPENWINHOME}/lib ! LIBS = ${LDFLAGS} -lolgx -lX11 -lXext -ll -lm -lrplay OBJS = ${SRCS:.c=.o} ${VERSION} diff -r -c /tmp/olvwm3.3/events.c ./events.c *** /tmp/olvwm3.3/events.c Sat Dec 12 09:27:05 1992 --- ./events.c Fri Dec 11 22:21:34 1992 *************** *** 160,165 **** --- 160,168 ---- if (GRV.PrintAll) DebugEvent(event, "Dispatch - debug"); + #ifdef SOUNDS + play_sound(event->type); + #endif saveTimestamp( event ); if (winInfo == NULL) diff -r -c /tmp/olvwm3.3/olwm.c ./olwm.c *** /tmp/olvwm3.3/olwm.c Sat Dec 12 09:27:13 1992 --- ./olwm.c Fri Dec 11 22:23:02 1992 *************** *** 369,374 **** --- 369,377 ---- sendSyncSignal(); + #ifdef SOUNDS + play_sound(35); + #endif EventLoop( DefDpy ); /*NOTREACHED*/ *************** *** 569,574 **** --- 572,580 ---- SlaveStop(); ListApply(ActiveClientList, ClientShutdown, (void *)0); + #ifdef SOUNDS + play_sound(36); + #endif XSync(dpy, True); exit(0); /*NOTREACHED*/ diff -r -c /tmp/olvwm3.3/usermenu.c ./usermenu.c *** /tmp/olvwm3.3/usermenu.c Sat Dec 12 09:27:18 1992 --- ./usermenu.c Fri Dec 11 22:25:28 1992 *************** *** 190,195 **** --- 190,199 ---- extern int GenDirMenuFunc(); extern int StickSelnFunc(); extern int MoveDesktopFunc(); + #ifdef SOUNDS + extern int toggle_sound(); + extern int reread_sounds(); + #endif /* --------------------------------------------------------------------- * local forward declarations *************** *** 1334,1340 **** }, { "MOVE_DESKTOP", MoveDesktopFunc, ServiceToken ! } }; #define NSERVICES COUNT(svctokenlookup) --- 1338,1352 ---- }, { "MOVE_DESKTOP", MoveDesktopFunc, ServiceToken ! }, ! #ifdef SOUNDS ! { ! "FLIPSOUND", toggle_sound, ServiceToken ! }, ! { ! "REREADSOUNDS", reread_sounds, ServiceToken ! }, ! #endif }; #define NSERVICES COUNT(svctokenlookup) rplay-3.3.2/contrib/window_managers/olvwm/olvwm.events100644 153 62 1620 6552756453 21717 0ustar boynsstaff KeyPress # A key was pressed while on the root KeyRelease # A key was released while on the root ButtonPress # A button was pressed (anywhere) ButtonRelease # A button was released (anywhere) MotionNotify # A mouse drag was started EnterNotify # The mouse entered a window LeaveNotify # The mouse left a window FocusIn # A window gained focus FocusOut # A window lost focus KeymapNotify Expose # Some rectangle on the screen was redrawn GraphicsExpose # Some rectangle on the screen was redrawn NoExpose VisibilityNotify CreateNotify DestroyNotify UnmapNotify # A window was unmapped from the screen MapNotify # A window was mapped onto the screen MapRequest ReparentNotify ConfigureNotify ConfigureRequest GravityNotify ResizeRequest CirculateNotify CirculateRequest PropertyNotify SelectionClear SelectionRequest SelectionNotify ColormapNotify ClientMessage MappingNotify rplay-3.3.2/contrib/xjukebox-0.9/ 40755 153 62 0 6727650075 15041 5ustar boynsstaffrplay-3.3.2/contrib/xjukebox-0.9/INSTALL100644 153 62 273 6552756453 16154 0ustar boynsstaffTo install, edit "Imakefile" (check the lines with RPLAY_LIB and RPLAY_INCLUDE), then do the following : xmkmf -a make make install Please read the README file for more information. rplay-3.3.2/contrib/xjukebox-0.9/Imakefile100644 153 62 5160 6552756453 16754 0ustar boynsstaffXCOMM Imakefile -- Imakefile for XJukebox XCOMM Copyright (C) 1993 Raphael Quinet XCOMM XCOMM This program is free software; you can redistribute it and/or modify XCOMM it under the terms of the GNU General Public License as published by XCOMM the Free Software Foundation; either version 2 of the License, or XCOMM (at your option) any later version. XCOMM XCOMM This program is distributed in the hope that it will be useful, XCOMM but WITHOUT ANY WARRANTY; without even the implied warranty of XCOMM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the XCOMM GNU General Public License for more details. XCOMM XCOMM You should have received a copy of the GNU General Public License XCOMM along with this program; if not, write to the Free Software XCOMM Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. XCOMM XCOMM Author : Raphael Quinet XCOMM E-Mail : quinet@montefiore.ulg.ac.be XCOMM quinet@server.montefiore.ulg.ac.be XCOMM S-Mail : 9, Rue des Martyrs 4550 Nandrin (Belgium, Europe) XCOMM These are the directories where the rplay files can be found : RPLAY_LIB = /usr/local/lib RPLAY_INCLUDE = /usr/local/include XCOMM Uncomment and adjust these to change the destinations of "make install" XCOMM and "make install.man" if the defaults are not satisfactory. XCOMM BINDIR = /usr/local/bin XCOMM MANDIR = /usr/local/man/man1 XCOMM MANSUFFIX = 1 XCOMM It's not a good idea to change the default "app-default" directory. XCOMM Chances are that "XJukebox.ad" and "XJukebox-color.ad" will simply be XCOMM ignored if you uncomment and change the following line. But you may XCOMM change it if you can't install the files in their default directory. XCOMM XAPPLOADDIR = /usr/lib/X11/app-defaults XCOMM How excited are you about debugging ? This can be -g, -O, or nothing. XCOMM CDEBUGFLAGS = -g XCOMM ------------------------------------------------------------------------- XCOMM Please don't change anything below this point - no need really - I hope. SRCS = xjukebox.c rptpstuff.c widgets.c OBJS = xjukebox.o rptpstuff.o widgets.o DEPLIBS = XawClientDepLibs LOCAL_LIBRARIES = XawClientLibs -L$(RPLAY_LIB) -lrplay DEFINES = -I$(RPLAY_INCLUDE) ComplexProgramTarget(xjukebox) InstallAppDefaults(XJukebox) InstallAppDefaults(XJukebox-color) XCOMM You will only need the following lines if you change Xjukebox.ad and XCOMM you want to hard-code the changes into xjukebox. This is not needed if XCOMM Xjukebox.ad is installed in the ".../lib/X11/app-defaults" directory. XJukebox.ad.h: XJukebox.ad ad2c XJukebox.ad > XJukebox.ad.h rplay-3.3.2/contrib/xjukebox-0.9/Makefile100644 153 62 62226 6552756453 16631 0ustar boynsstaff# Makefile generated by imake - do not edit! # $XConsortium: imake.c /main/90 1996/11/13 14:43:23 lehors $ # ---------------------------------------------------------------------- # Makefile generated from "Imake.tmpl" and # $TOG: Imake.tmpl /main/245 1997/05/20 10:05:47 kaleb $ # # # # # $XFree86: xc/config/cf/Imake.tmpl,v 3.32.2.4 1997/05/21 15:49:24 dawes Exp $ # all:: .SUFFIXES: .i # $XConsortium: Imake.cf /main/26 1996/09/28 16:05:09 rws $ # $XFree86: xc/config/cf/Imake.cf,v 3.34 1997/01/05 11:49:28 dawes Exp $ # ----------------------------------------------------------------------- # site-specific configuration parameters that need to come before # the platform-specific parameters - edit site.def to change # site: $XConsortium: site.def /main/revisionist/4 1996/12/31 08:02:07 kaleb $ # site: $XFree86: xc/config/cf/site.def,v 3.17 1997/01/14 22:12:40 dawes Exp $ # $XFree86: xc/config/cf/xf86site.def,v 3.101.2.10 1997/05/24 13:38:10 dawes Exp $ # ---------------------------------------------------------------------- # platform-specific configuration parameters - edit linux.cf to change # platform: $XConsortium: linux.cf /main/27 1996/12/26 08:52:44 kaleb $ # platform: $XFree86: xc/config/cf/linux.cf,v 3.57.2.6 1997/05/27 06:22:10 dawes Exp $ # operating system: Linux 2.0.33 i586 [ELF] (2.0.33) # $XConsortium: lnxLib.rules /main/13 1996/09/28 16:11:01 rws $ # $XFree86: xc/config/cf/lnxLib.rules,v 3.28.2.2 1997/05/24 08:35:53 dawes Exp $ # $XFree86: xc/config/cf/xfree86.cf,v 3.129.2.13 1997/06/02 01:44:09 dawes Exp $ # $XConsortium: xfree86.cf /main/34 1996/12/06 11:45:18 rws $ LINKKITDIR = $(USRLIBDIR)/Server XF98LINKKITDIR = $(USRLIBDIR)/Server XF86SRC = $(SERVERSRC)/hw/xfree86 XF86ACCELSRC = $(XF86SRC)/accel XF86COMSRC = $(XF86SRC)/common XF86CONFIGSRC = $(XF86COMSRC) XF86HWSRC = $(XF86SRC)/common_hw XF86OSSRC = $(XF86SRC)/os-support VGADRIVERSRC = $(XF86SRC)/vga256/drivers VGA16DRIVERSRC = $(XF86SRC)/vga16/drivers VGA2DRIVERSRC = $(XF86SRC)/vga2/drivers MONODRIVERSRC = $(XF86SRC)/mono/drivers S3DRIVERSRC = $(XF86SRC)/accel/s3/drivers S3VDRIVERSRC = $(XF86SRC)/accel/s3_virge/drivers XF68SRC = $(SERVERSRC)/hw/xfree68 XF68COMSRC = $(XF68SRC)/common XF68CONFIGSRC = $(XF68COMSRC) XF68OSSRC = $(XF68SRC)/os-support XF98SRC = $(SERVERSRC)/hw/xfree98 XF98ACCELSRC = $(XF98SRC)/accel XF98COMSRC = $(XF98SRC)/common XF98CONFIGSRC = $(XF98COMSRC) XF98HWSRC = $(XF98SRC)/common_hw/generic XF98HWNECSRC = $(XF98SRC)/common_hw/nec XF98HWPWSKBSRC = $(XF98SRC)/common_hw/pwskb XF98HWPWLBSRC = $(XF98SRC)/common_hw/pwlb XF98HWGA968SRC = $(XF98SRC)/common_hw/ga968 XF98OSSRC = $(XF98SRC)/os-support XF98VGADRIVERSRC = $(XF98SRC)/vga256/drivers XF98VGA16DRIVERSRC = $(XF98SRC)/vga16/drivers XF98VGA2DRIVERSRC = $(XF98SRC)/vga2/drivers XF98MONODRIVERSRC = $(XF98SRC)/mono/drivers XF98NECS3DRIVERSRC = $(XF98SRC)/accel/s3nec/drivers XF98PWSKBDRIVERSRC = $(XF98SRC)/accel/s3pwskb/drivers XF98PWLBDRIVERSRC = $(XF98SRC)/accel/s3pwlb/drivers XF98GA968DRIVERSRC = $(XF98SRC)/accel/s3ga968/drivers XFREE86DOCDIR = $(LIBDIR)/doc XFREE86PSDOCDIR = $(XFREE86DOCDIR)/PostScript XFREE86HTMLDOCDIR = $(XFREE86DOCDIR)/html XFREE86JAPANESEDOCDIR = $(XFREE86DOCDIR)/Japanese # $XConsortium: xf86.rules /main/9 1996/10/31 14:54:26 kaleb $ # $XFree86: xc/config/cf/xf86.rules,v 3.16.2.1 1997/05/18 12:00:01 dawes Exp $ # ---------------------------------------------------------------------- # site-specific configuration parameters that go after # the platform-specific parameters - edit site.def to change # site: $XConsortium: site.def /main/revisionist/4 1996/12/31 08:02:07 kaleb $ # site: $XFree86: xc/config/cf/site.def,v 3.17 1997/01/14 22:12:40 dawes Exp $ # --------------------------------------------------------------------- # Imake rules for building libraries, programs, scripts, and data files # rules: $TOG: Imake.rules /main/218 1997/02/13 13:54:11 kaleb $ # rules: $XFree86: xc/config/cf/Imake.rules,v 3.33.2.2 1997/05/11 05:04:02 dawes Exp $ _NULLCMD_ = @ echo -n TKLIBNAME = tk4.2 TKLIBDIR = /usr/lib TCLLIBNAME = tcl7.6 TCLIBDIR = /usr/lib PATHSEP = / SHELL = /bin/sh TOP = . CURRENT_DIR = . IMAKE = imake DEPEND = gccmakedep MKDIRHIER = mkdir -p EXPORTLISTGEN = CONFIGSRC = $(TOP)/config IMAKESRC = $(CONFIGSRC)/imake DEPENDSRC = $(CONFIGSRC)/util INCROOT = /usr/X11R6/include USRLIBDIR = /usr/X11R6/lib VARLIBDIR = /var/lib SHLIBDIR = /usr/X11R6/lib LINTLIBDIR = $(USRLIBDIR)/lint MANPATH = /usr/X11R6/man MANSOURCEPATH = $(MANPATH)/man MANDIR = $(MANSOURCEPATH)1 LIBMANDIR = $(MANSOURCEPATH)3 FILEMANDIR = $(MANSOURCEPATH)5 AR = ar clq BOOTSTRAPCFLAGS = CC = gcc AS = as .SUFFIXES: .cc CXX = c++ CXXFILT = c++filt CXXLIB = CXXDEBUGFLAGS = -O2 -fno-strength-reduce CXXDEPENDINCLUDES = CXXEXTRA_DEFINES = CXXEXTRA_INCLUDES = CXXSTD_DEFINES = -D_POSIX_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE -Dlinux -D__i386__ -DX_LOCALE $(CXXPROJECT_DEFINES) CXXOPTIONS = CXXINCLUDES = $(INCLUDES) $(TOP_INCLUDES) $(CXXEXTRA_INCLUDES) CXXDEFINES = $(CXXINCLUDES) $(CXXSTD_DEFINES) $(THREADS_CXXDEFINES) $(CXXEXTRA_DEFINES) $(DEFINES) CXXFLAGS = $(CXXDEBUGFLAGS) $(CXXOPTIONS) $(THREADS_CXXFLAGS) $(CXXDEFINES) COMPRESS = compress GZIPCMD = gzip CPP = /lib/cpp $(STD_CPP_DEFINES) PREPROCESSCMD = gcc -E $(STD_CPP_DEFINES) INSTALL = install INSTALLFLAGS = -c LD = ld LEX = flex -l LEXLIB = -lfl YACC = bison -y CCYACC = bison -y LINT = lint LINTLIBFLAG = -C LINTOPTS = -axz LN = ln -s MAKE = make MV = mv -f CP = cp RANLIB = ranlib RANLIBINSTFLAGS = RM = rm -f MANSUFFIX = 1x LIBMANSUFFIX = 3x FILEMANSUFFIX = 5x TROFF = psroff NROFF = nroff MSMACROS = -ms MANMACROS = -man TBL = tbl EQN = eqn NEQN = neqn COL = col DVIPS = dvips LATEX = latex STD_INCLUDES = STD_CPP_DEFINES = -traditional -D_POSIX_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE -Dlinux -D__i386__ -DX_LOCALE $(PROJECT_DEFINES) STD_DEFINES = -D_POSIX_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE -Dlinux -D__i386__ -DX_LOCALE $(PROJECT_DEFINES) EXTRA_LOAD_FLAGS = EXTRA_LDOPTIONS = EXTRA_LIBRARIES = TAGS = ctags PARALLELMFLAGS = SHAREDCODEDEF = SHLIBDEF = SHLIBLDFLAGS = -shared PICFLAGS = -fPIC CXXPICFLAGS = -fPIC PROTO_DEFINES = -DFUNCPROTO=15 -DNARROWPROTO INSTPGMFLAGS = -s INSTBINFLAGS = -m 0755 INSTUIDFLAGS = -m 4711 INSTLIBFLAGS = -m 0644 INSTINCFLAGS = -m 0444 INSTMANFLAGS = -m 0444 INSTDATFLAGS = -m 0444 INSTKMEMFLAGS = -m 4711 PROJECTROOT = /usr/X11R6 CDEBUGFLAGS = -O2 -fno-strength-reduce CCOPTIONS = ALLINCLUDES = $(INCLUDES) $(EXTRA_INCLUDES) $(TOP_INCLUDES) $(STD_INCLUDES) ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(EXTRA_DEFINES) $(PROTO_DEFINES) $(THREADS_DEFINES) $(DEFINES) CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(THREADS_CFLAGS) $(ALLDEFINES) LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES) $(DEPEND_DEFINES) LDPRELIB = -L$(USRLIBDIR) LDPOSTLIB = LDOPTIONS = $(CDEBUGFLAGS) $(CCOPTIONS) $(EXTRA_LDOPTIONS) $(THREADS_LDFLAGS) $(LOCAL_LDFLAGS) $(LDPRELIBS) CXXLDOPTIONS = $(CXXDEBUGFLAGS) $(CXXOPTIONS) $(EXTRA_LDOPTIONS) $(THREADS_CXXLDFLAGS) $(LOCAL_LDFLAGS) $(LDPRELIBS) LDLIBS = $(LDPOSTLIBS) $(THREADS_LIBS) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES) CCLINK = $(CC) CXXLINK = $(CXX) LDSTRIPFLAGS = -x LDCOMBINEFLAGS = -r DEPENDFLAGS = # Not sure this belongs here TKLIBDIR = /usr/lib TKINCDIR = /usr/include/tk TKLIBNAME = tk4.2 TKLIBRARY = -L$(TKLIBDIR) -l$(TKLIBNAME) TCLLIBDIR = /usr/lib TCLINCDIR = /usr/include/tcl TCLLIBNAME = tcl7.6 TCLLIBRARY = -L$(TCLLIBDIR) -l$(TCLLIBNAME) MACROFILE = linux.cf RM_CMD = $(RM) IMAKE_DEFINES = IRULESRC = $(CONFIGDIR) IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES) ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/X11.tmpl $(IRULESRC)/site.def $(IRULESRC)/$(MACROFILE) $(IRULESRC)/xfree86.cf $(IRULESRC)/xf86.rules $(IRULESRC)/xf86site.def $(IRULESRC)/host.def $(EXTRA_ICONFIGFILES) # $XConsortium: X11.rules /main/2 1996/12/04 10:13:00 swick $ # ---------------------------------------------------------------------- # X Window System Build Parameters and Rules # $TOG: X11.tmpl /main/292 1997/05/20 10:05:59 kaleb $ # # # # # $XFree86: xc/config/cf/X11.tmpl,v 1.8.2.3 1997/05/21 15:02:13 dawes Exp $ # ----------------------------------------------------------------------- # X Window System make variables; these need to be coordinated with rules XTOP = $(TOP) BINDIR = /usr/X11R6/bin BUILDINCROOT = $(TOP)/exports BUILDINCDIR = $(BUILDINCROOT)/include BUILDINCTOP = ../.. BUILDLIBDIR = $(TOP)/exports/lib BUILDLIBTOP = ../.. BUILDBINDIR = $(TOP)/exports/bin BUILDBINTOP = ../.. XBUILDINCROOT = $(XTOP)/exports XBUILDINCDIR = $(XBUILDINCROOT)/include/X11 XBUILDINCTOP = ../../.. XBUILDBINDIR = $(XBUILDINCROOT)/bin INCDIR = $(INCROOT) ADMDIR = /usr/adm LIBDIR = $(USRLIBDIR)/X11 TOP_X_INCLUDES = FONTDIR = $(LIBDIR)/fonts XINITDIR = $(LIBDIR)/xinit XDMDIR = $(LIBDIR)/xdm XDMVARDIR = $(VARLIBDIR)/xdm TWMDIR = $(LIBDIR)/twm XSMDIR = $(LIBDIR)/xsm NLSDIR = $(LIBDIR)/nls XLOCALEDIR = $(LIBDIR)/locale PEXAPIDIR = $(LIBDIR)/PEX LBXPROXYDIR = $(LIBDIR)/lbxproxy PROXYMANAGERDIR = $(LIBDIR)/proxymngr XPRINTDIR = $(LIBDIR) XAPPLOADDIR = $(LIBDIR)/app-defaults FONTCFLAGS = -t INSTAPPFLAGS = $(INSTDATFLAGS) RGB = rgb FONTC = bdftopcf MKFONTDIR = mkfontdir DOCUTILSRC = $(XTOP)/doc/util CLIENTSRC = $(TOP)/clients DEMOSRC = $(TOP)/demos XDOCMACROS = $(DOCUTILSRC)/macros.t XIDXMACROS = $(DOCUTILSRC)/indexmacros.t PROGRAMSRC = $(TOP)/programs LIBSRC = $(XTOP)/lib FONTSRC = $(XTOP)/fonts INCLUDESRC = $(BUILDINCROOT)/include XINCLUDESRC = $(INCLUDESRC)/X11 SERVERSRC = $(XTOP)/programs/Xserver CONTRIBSRC = $(XTOP)/../contrib UNSUPPORTEDSRC = $(XTOP)/unsupported DOCSRC = $(XTOP)/doc RGBSRC = $(XTOP)/programs/rgb BDFTOPCFSRC = $(PROGRAMSRC)/bdftopcf MKFONTDIRSRC = $(PROGRAMSRC)/mkfontdir FONTSERVERSRC = $(PROGRAMSRC)/xfs FONTINCSRC = $(XTOP)/include/fonts EXTINCSRC = $(XTOP)/include/extensions TRANSCOMMSRC = $(LIBSRC)/xtrans TRANS_INCLUDES = -I$(TRANSCOMMSRC) XENVLIBDIR = $(USRLIBDIR) CLIENTENVSETUP = LD_LIBRARY_PATH=$(XENVLIBDIR) # $XConsortium: lnxLib.tmpl,v 1.5 95/01/11 21:44:44 kaleb Exp $ # $XFree86: xc/config/cf/lnxLib.tmpl,v 3.9 1996/02/24 04:32:52 dawes Exp $ XLIBSRC = $(LIBSRC)/X11 SOXLIBREV = 6.1 DEPXONLYLIB = XONLYLIB = -lX11 LINTXONLY = $(LINTLIBDIR)/llib-lX11.ln XLIBONLY = $(XONLYLIB) XEXTLIBSRC = $(LIBSRC)/Xext SOXEXTREV = 6.3 DEPEXTENSIONLIB = EXTENSIONLIB = -lXext LINTEXTENSION = $(LINTLIBDIR)/llib-lXext.ln LINTEXTENSIONLIB = $(LINTEXTENSION) DEPXLIB = $(DEPEXTENSIONLIB) $(DEPXONLYLIB) XLIB = $(EXTENSIONLIB) $(XONLYLIB) LINTXLIB = $(LINTXONLYLIB) XSSLIBSRC = $(LIBSRC)/Xss DEPXSSLIB = $(USRLIBDIR)/libXss.a XSSLIB = -lXss LINTXSS = $(LINTLIBDIR)/llib-lXss.ln XXF86MISCLIBSRC = $(LIBSRC)/Xxf86misc DEPXXF86MISCLIB = $(USRLIBDIR)/libXxf86misc.a XXF86MISCLIB = -lXxf86misc LINTXXF86MISC = $(LINTLIBDIR)/llib-lXxf86misc.ln XXF86VMLIBSRC = $(LIBSRC)/Xxf86vm DEPXXF86VMLIB = $(USRLIBDIR)/libXxf86vm.a XXF86VMLIB = -lXxf86vm LINTXXF86VM = $(LINTLIBDIR)/llib-lXxf86vm.ln XXF86DGALIBSRC = $(LIBSRC)/Xxf86dga DEPXXF86DGALIB = $(USRLIBDIR)/libXxf86dga.a XXF86DGALIB = -lXxf86dga LINTXXF86DGA = $(LINTLIBDIR)/llib-lXxf86dga.ln XDPMSLIBSRC = $(LIBSRC)/Xdpms DEPXDPMSLIB = $(USRLIBDIR)/libXdpms.a XDPMSLIB = -lXdpms LINTXDPMS = $(LINTLIBDIR)/llib-lXdpms.ln XAUTHSRC = $(LIBSRC)/Xau DEPXAUTHLIB = $(USRLIBDIR)/libXau.a XAUTHLIB = -lXau LINTXAUTH = $(LINTLIBDIR)/llib-lXau.ln XDMCPLIBSRC = $(LIBSRC)/Xdmcp DEPXDMCPLIB = $(USRLIBDIR)/libXdmcp.a XDMCPLIB = -lXdmcp LINTXDMCP = $(LINTLIBDIR)/llib-lXdmcp.ln XMUSRC = $(LIBSRC)/Xmu SOXMUREV = 6.0 DEPXMULIB = XMULIB = -lXmu LINTXMU = $(LINTLIBDIR)/llib-lXmu.ln OLDXLIBSRC = $(LIBSRC)/oldX DEPOLDXLIB = $(USRLIBDIR)/liboldX.a OLDXLIB = -loldX LINTOLDX = $(LINTLIBDIR)/llib-loldX.ln XPLIBSRC = $(LIBSRC)/Xp SOXPREV = 6.2 DEPXPLIB = XPLIB = -lXp LINTXP = $(LINTLIBDIR)/llib-lXp.ln TOOLKITSRC = $(LIBSRC)/Xt SOXTREV = 6.0 DEPXTOOLONLYLIB = XTOOLONLYLIB = -lXt LINTXTOOLONLY = $(LINTLIBDIR)/llib-lXt.ln DEPXTOOLLIB = $(DEPXTOOLONLYLIB) $(DEPSMLIB) $(DEPICELIB) XTOOLLIB = $(XTOOLONLYLIB) $(SMLIB) $(ICELIB) LINTXTOOLLIB = $(LINTXTOOLONLYLIB) XALIBSRC = $(LIBSRC)/Xa SOXAREV = 1.0 DEPXALIB = XALIB = -lXa LINTXA = $(LINTLIBDIR)/llib-lXa.ln AWIDGETSRC = $(LIBSRC)/Xaw SOXAWREV = 6.1 DEPXAWLIB = XAWLIB = -lXaw LINTXAW = $(LINTLIBDIR)/llib-lXaw.ln XILIBSRC = $(LIBSRC)/Xi SOXINPUTREV = 6.0 DEPXILIB = XILIB = -lXi LINTXI = $(LINTLIBDIR)/llib-lXi.ln XTESTLIBSRC = $(LIBSRC)/Xtst SOXTESTREV = 6.1 DEPXTESTLIB = XTESTLIB = -lXtst LINTXTEST = $(LINTLIBDIR)/llib-lXtst.ln PEXLIBSRC = $(LIBSRC)/PEX5 SOPEXREV = 6.0 DEPPEXLIB = PEXLIB = -lPEX5 LINTPEX = $(LINTLIBDIR)/llib-lPEX5.ln XIELIBSRC = $(LIBSRC)/XIE SOXIEREV = 6.0 DEPXIELIB = XIELIB = -lXIE LINTXIE = $(LINTLIBDIR)/llib-lXIE.ln PHIGSLIBSRC = $(LIBSRC)/PHIGS DEPPHIGSLIB = $(USRLIBDIR)/libphigs.a PHIGSLIB = -lphigs LINTPHIGS = $(LINTLIBDIR)/llib-lphigs.ln DEPXBSDLIB = $(USRLIBDIR)/libXbsd.a XBSDLIB = -lXbsd LINTXBSD = $(LINTLIBDIR)/llib-lXbsd.ln ICESRC = $(LIBSRC)/ICE SOICEREV = 6.3 DEPICELIB = ICELIB = -lICE LINTICE = $(LINTLIBDIR)/llib-lICE.ln SMSRC = $(LIBSRC)/SM SOSMREV = 6.0 DEPSMLIB = SMLIB = -lSM LINTSM = $(LINTLIBDIR)/llib-lSM.ln XKEYSRC = $(LIBSRC)/Xkey SOXKEYREV = 6.0 DEPXKEYLIB = XKEYLIB = -lXkey LINTXKEY = $(LINTLIBDIR)/llib-lXkey.ln FSLIBSRC = $(LIBSRC)/FS DEPFSLIB = $(USRLIBDIR)/libFS.a FSLIB = -lFS LINTFS = $(LINTLIBDIR)/llib-lFS.ln FONTLIBSRC = $(LIBSRC)/font DEPFONTLIB = $(USRLIBDIR)/libfont.a FONTLIB = -lfont LINTFONT = $(LINTLIBDIR)/llib-lfont.ln XPMLIBSRC = $(LIBSRC)/Xpm DEPXPMLIB = $(USRLIBDIR)/libXpm.a XPMLIB = -lXpm LINTXPM = $(LINTLIBDIR)/llib-lXpm.ln XKBFILELIBSRC = $(LIBSRC)/xkbfile DEPXKBFILELIB = $(USRLIBDIR)/libxkbfile.a XKBFILELIB = -lxkbfile LINTXKBFILE = $(LINTLIBDIR)/llib-lxkbfile.ln XKBCOMPCMD = xkbcomp XKBUILIBSRC = $(LIBSRC)/xkbui DEPXKBUILIB = $(USRLIBDIR)/libxkbui.a XKBUILIB = -lxkbui LINTXKBUI = $(LINTLIBDIR)/llib-lxkbui.ln DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB) DEPLIBS1 = $(DEPLIBS) DEPLIBS2 = $(DEPLIBS) DEPLIBS3 = $(DEPLIBS) DEPLIBS4 = $(DEPLIBS) DEPLIBS5 = $(DEPLIBS) DEPLIBS6 = $(DEPLIBS) DEPLIBS7 = $(DEPLIBS) DEPLIBS8 = $(DEPLIBS) DEPLIBS9 = $(DEPLIBS) DEPLIBS10 = $(DEPLIBS) XMULIBONLY = -lXmu XMULIB = $(XMULIBONLY) $(XTOOLLIB) $(XLIB) CONFIGDIR = $(LIBDIR)/config USRLIBDIRPATH = $(USRLIBDIR) LDPRELIBS = -L$(USRLIBDIR) LDPOSTLIBS = TOP_INCLUDES = -I$(INCROOT) $(TOP_X_INCLUDES) PROJECT_DEFINES = CXXPROJECT_DEFINES = # ---------------------------------------------------------------------- # start of Imakefile # Imakefile -- Imakefile for XJukebox # Copyright (C) 1993 Raphael Quinet # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # # Author : Raphael Quinet # E-Mail : quinet@montefiore.ulg.ac.be # quinet@server.montefiore.ulg.ac.be # S-Mail : 9, Rue des Martyrs 4550 Nandrin (Belgium, Europe) # These are the directories where the rplay files can be found : RPLAY_LIB = /usr/local/lib RPLAY_INCLUDE = /usr/local/include # Uncomment and adjust these to change the destinations of "make install" # and "make install.man" if the defaults are not satisfactory. # BINDIR = /usr/local/bin # MANDIR = /usr/local/man/man1 # MANSUFFIX = 1 # It's not a good idea to change the default "app-default" directory. # Chances are that "XJukebox.ad" and "XJukebox-color.ad" will simply be # ignored if you uncomment and change the following line. But you may # change it if you can't install the files in their default directory. # XAPPLOADDIR = /usr/lib/X11/app-defaults # How excited are you about debugging ? This can be -g, -O, or nothing. # CDEBUGFLAGS = -g # ------------------------------------------------------------------------- # Please don't change anything below this point - no need really - I hope. SRCS = xjukebox.c rptpstuff.c widgets.c OBJS = xjukebox.o rptpstuff.o widgets.o DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB) LOCAL_LIBRARIES = $(XAWLIB) $(XMULIBONLY) $(XTOOLLIB) $(XLIB) -L$(RPLAY_LIB) -lrplay DEFINES = -I$(RPLAY_INCLUDE) PROGRAM = xjukebox all:: xjukebox xjukebox: $(OBJS) $(DEPLIBS) $(RM) $@ $(CCLINK) -o $@ $(LDOPTIONS) $(OBJS) $(LOCAL_LIBRARIES) $(LDLIBS) $(EXTRA_LOAD_FLAGS) install:: xjukebox @if [ -d $(DESTDIR)$(BINDIR) ]; then set +x; \ else (set -x; $(MKDIRHIER) $(DESTDIR)$(BINDIR)); fi $(INSTALL) $(INSTALLFLAGS) $(INSTPGMFLAGS) xjukebox $(DESTDIR)$(BINDIR)/xjukebox install.man:: xjukebox.man @if [ -d $(DESTDIR)$(MANDIR) ]; then set +x; \ else (set -x; $(MKDIRHIER) $(DESTDIR)$(MANDIR)); fi $(INSTALL) $(INSTALLFLAGS) $(INSTMANFLAGS) xjukebox.man $(DESTDIR)$(MANDIR)/xjukebox.$(MANSUFFIX) depend:: $(DEPEND) $(DEPENDFLAGS) -- $(ALLDEFINES) $(DEPEND_DEFINES) -- $(SRCS) lint: $(LINT) $(LINTFLAGS) $(SRCS) $(LINTLIBS) lint1: $(LINT) $(LINTFLAGS) $(FILE) $(LINTLIBS) clean:: $(RM) xjukebox install:: XJukebox.ad @if [ -d $(DESTDIR)$(XAPPLOADDIR) ]; then set +x; \ else (set -x; $(MKDIRHIER) $(DESTDIR)$(XAPPLOADDIR)); fi $(INSTALL) $(INSTALLFLAGS) $(INSTAPPFLAGS) XJukebox.ad $(DESTDIR)$(XAPPLOADDIR)/XJukebox install:: XJukebox-color.ad @if [ -d $(DESTDIR)$(XAPPLOADDIR) ]; then set +x; \ else (set -x; $(MKDIRHIER) $(DESTDIR)$(XAPPLOADDIR)); fi $(INSTALL) $(INSTALLFLAGS) $(INSTAPPFLAGS) XJukebox-color.ad $(DESTDIR)$(XAPPLOADDIR)/XJukebox-color # You will only need the following lines if you change Xjukebox.ad and # you want to hard-code the changes into xjukebox. This is not needed if # Xjukebox.ad is installed in the ".../lib/X11/app-defaults" directory. XJukebox.ad.h: XJukebox.ad ad2c XJukebox.ad > XJukebox.ad.h # ---------------------------------------------------------------------- # common rules for all Makefiles - do not edit .c.i: $(RM) $@ $(CC) -E $(CFLAGS) $(_NOOP_) $*.c > $@ emptyrule:: clean:: $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut "#"* Makefile:: -@if [ -f Makefile ]; then set -x; \ $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \ else exit 0; fi $(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR) tags:: $(TAGS) -w *.[ch] $(TAGS) -xw *.[ch] > TAGS man_keywords:: # ---------------------------------------------------------------------- # empty rules for directories that do not have SUBDIRS - do not edit install:: @echo "install in $(CURRENT_DIR) done" install.man:: @echo "install.man in $(CURRENT_DIR) done" install.linkkit:: @echo "install.linkkit in $(CURRENT_DIR) done" Makefiles:: includes:: depend:: # ---------------------------------------------------------------------- # dependencies generated by makedepend # DO NOT DELETE xjukebox.o: xjukebox.c xjukebox.h /usr/include/stdio.h \ /usr/include/features.h /usr/include/sys/cdefs.h /usr/include/libio.h \ /usr/include/_G_config.h /usr/include/string.h \ /usr/lib/gcc-lib/i486-linux/2.7.2.1/include/stddef.h \ /usr/local/include/rplay.h /usr/include/sys/types.h \ /usr/include/linux/types.h /usr/include/linux/posix_types.h \ /usr/include/asm/posix_types.h /usr/include/asm/types.h \ /usr/include/sys/bitypes.h /usr/include/sys/socket.h \ /usr/include/linux/socket.h /usr/include/asm/socket.h \ /usr/include/asm/sockios.h /usr/include/linux/sockios.h \ /usr/include/linux/uio.h /usr/include/netinet/in.h \ /usr/include/linux/in.h /usr/include/asm/byteorder.h \ /usr/X11R6/include/X11/Xlib.h /usr/X11R6/include/X11/X.h \ /usr/X11R6/include/X11/Xfuncproto.h /usr/X11R6/include/X11/Xosdefs.h \ /usr/X11R6/include/X11/Xutil.h /usr/X11R6/include/X11/Intrinsic.h \ /usr/X11R6/include/X11/Xresource.h /usr/X11R6/include/X11/Core.h \ /usr/X11R6/include/X11/Composite.h \ /usr/X11R6/include/X11/Constraint.h /usr/X11R6/include/X11/Object.h \ /usr/X11R6/include/X11/RectObj.h /usr/X11R6/include/X11/StringDefs.h rptpstuff.o: rptpstuff.c xjukebox.h /usr/include/stdio.h \ /usr/include/features.h /usr/include/sys/cdefs.h /usr/include/libio.h \ /usr/include/_G_config.h /usr/include/string.h \ /usr/lib/gcc-lib/i486-linux/2.7.2.1/include/stddef.h \ /usr/local/include/rplay.h /usr/include/sys/types.h \ /usr/include/linux/types.h /usr/include/linux/posix_types.h \ /usr/include/asm/posix_types.h /usr/include/asm/types.h \ /usr/include/sys/bitypes.h /usr/include/sys/socket.h \ /usr/include/linux/socket.h /usr/include/asm/socket.h \ /usr/include/asm/sockios.h /usr/include/linux/sockios.h \ /usr/include/linux/uio.h /usr/include/netinet/in.h \ /usr/include/linux/in.h /usr/include/asm/byteorder.h \ /usr/X11R6/include/X11/Xlib.h /usr/X11R6/include/X11/X.h \ /usr/X11R6/include/X11/Xfuncproto.h /usr/X11R6/include/X11/Xosdefs.h \ /usr/X11R6/include/X11/Xutil.h /usr/X11R6/include/X11/Intrinsic.h \ /usr/X11R6/include/X11/Xresource.h /usr/X11R6/include/X11/Core.h \ /usr/X11R6/include/X11/Composite.h \ /usr/X11R6/include/X11/Constraint.h /usr/X11R6/include/X11/Object.h \ /usr/X11R6/include/X11/RectObj.h /usr/X11R6/include/X11/StringDefs.h \ /usr/X11R6/include/X11/Xaw/Cardinals.h \ /usr/X11R6/include/X11/Xaw/List.h /usr/X11R6/include/X11/Xaw/Simple.h \ /usr/X11R6/include/X11/Xmu/Converters.h widgets.o: widgets.c xjukebox.h /usr/include/stdio.h \ /usr/include/features.h /usr/include/sys/cdefs.h /usr/include/libio.h \ /usr/include/_G_config.h /usr/include/string.h \ /usr/lib/gcc-lib/i486-linux/2.7.2.1/include/stddef.h \ /usr/local/include/rplay.h /usr/include/sys/types.h \ /usr/include/linux/types.h /usr/include/linux/posix_types.h \ /usr/include/asm/posix_types.h /usr/include/asm/types.h \ /usr/include/sys/bitypes.h /usr/include/sys/socket.h \ /usr/include/linux/socket.h /usr/include/asm/socket.h \ /usr/include/asm/sockios.h /usr/include/linux/sockios.h \ /usr/include/linux/uio.h /usr/include/netinet/in.h \ /usr/include/linux/in.h /usr/include/asm/byteorder.h \ /usr/X11R6/include/X11/Xlib.h /usr/X11R6/include/X11/X.h \ /usr/X11R6/include/X11/Xfuncproto.h /usr/X11R6/include/X11/Xosdefs.h \ /usr/X11R6/include/X11/Xutil.h /usr/X11R6/include/X11/Intrinsic.h \ /usr/X11R6/include/X11/Xresource.h /usr/X11R6/include/X11/Core.h \ /usr/X11R6/include/X11/Composite.h \ /usr/X11R6/include/X11/Constraint.h /usr/X11R6/include/X11/Object.h \ /usr/X11R6/include/X11/RectObj.h /usr/X11R6/include/X11/StringDefs.h \ /usr/X11R6/include/X11/cursorfont.h /usr/X11R6/include/X11/Shell.h \ /usr/X11R6/include/X11/SM/SMlib.h /usr/X11R6/include/X11/SM/SM.h \ /usr/X11R6/include/X11/ICE/ICElib.h /usr/X11R6/include/X11/ICE/ICE.h \ /usr/X11R6/include/X11/Xaw/Cardinals.h \ /usr/X11R6/include/X11/Xaw/List.h /usr/X11R6/include/X11/Xaw/Simple.h \ /usr/X11R6/include/X11/Xmu/Converters.h \ /usr/X11R6/include/X11/Xaw/Form.h /usr/X11R6/include/X11/Xaw/Paned.h \ /usr/X11R6/include/X11/Xaw/Viewport.h \ /usr/X11R6/include/X11/Xaw/Reports.h \ /usr/X11R6/include/X11/Xaw/Label.h \ /usr/X11R6/include/X11/Xaw/Command.h \ /usr/X11R6/include/X11/Xaw/MenuButton.h \ /usr/X11R6/include/X11/Xaw/SimpleMenu.h \ /usr/X11R6/include/X11/Xaw/SmeBSB.h /usr/X11R6/include/X11/Xaw/Sme.h \ /usr/X11R6/include/X11/Xaw/Dialog.h XJukebox.ad.h rplay-3.3.2/contrib/xjukebox-0.9/README100644 153 62 3062 6552756453 16022 0ustar boynsstaffREADME file for XJukebox 0.9 ---------------------------- *----------------------------------------------------------------* | This program is currently under development, so please send | | any questions, suggestions or bug reports concerning this | | application to : Raphael Quinet . | *----------------------------------------------------------------* Please read the "TODO" file for known bugs and missing features. Sorry, I didn't have the time to write a man page. In the next release, maybe... To install, edit "Imakefile" (check the lines with RPLAY_LIB and RPLAY_INCLUDE), then do the following : xmkmf -a make make install I you notice some unusual problems, drop me a note and I'll fix them as soon as possible. Changes since last version (0.8) : ---------------------------------- - Rewrote all function declarations. You should be able to use most C compilers with this version. In 0.8, you had to use "gcc". If you still have some problems with your C compiler (even unusual warnings), please report them to me. - Added the "-jukeboxShown" command-line option, and the corresponding resource. Not really useful, but at least your compiler won't complain about empty structs in "widgets.c". - Added some lines in the TODO file, but nothing else in the source files :-). Credits : --------- Thanks to Mark Boyns for nearly everything. ;-) Thanks to Patrick Atoon for his help about "cc" compatibility. I made a lot of silly mistakes in the function declarations ! rplay-3.3.2/contrib/xjukebox-0.9/TODO100644 153 62 3563 6552756453 15640 0ustar boynsstaff* Delay all other rptp commands when the spool is being updated. Currently, the jukebox will crash if, for example, you choose "Get server list" when the spool is being updated. A new RPTP command should only be sent if "rptp_mode" is equal to "MODE_IDLE". This is the most annoying known bug. * Keep the current selection in the spool list. Each time the spool is updated, the current selection is lost. This is a real nuisance, as the spool is updated every second... * Fix the bug that smashes the default file name in the "Load list ..." and "Save list ..." menus entries. * Implement "Sort by size", "Shuffle" and "Build list from directory". These options have been temporarily removed from the menus. * Use the "Multilist" widget (from the Free Widget Foundation) instead of the normal "List" widget. Do something with double-clicks in the lists. * Add some comments in the source files. * Remove the debug messages. Use popups for fatal error messages. * Add a status bar, where all useful messages will be displayed. * Add an "options" menu in the jukebox panel, with the following entries : "Set volume", "Set priority", "Set delay betweens sounds" ... * Add a "repeat" or "loop" option. (Keep the names of the files that are played and rebuild the list after the last one, or move the files to the bottom of the list as soon as they are played.) * Add an "options" menu in the spool panel, with the following entries : "Toggle spool auto-update", "Set refresh rate", "Toggle host display", "Show access permissions". * Add more comments in the source files. * Add some command-line options (and the corresponding X resources). * Change the colors. * Add nice bitmaps for the buttons ("play", "stop", ... like on a CD-player). I you have any suggestions, please send them to me. (quinet@montefiore.ulg.ac.be or quinet@server.montefiore.ulg.ac.be) rplay-3.3.2/contrib/xjukebox-0.9/XJukebox-color.ad100644 153 62 514 6552756453 20302 0ustar boynsstaff! If you want to use this file, insert this in your ~/.Xdefaults file: ! ! #ifdef COLOR ! XJukebox.customization: -color ! #endif ! #include "XJukebox" *background: Grey *Command.background: RoyalBlue4 *Command.foreground: Gold *MenuButton.background: RoyalBlue4 *MenuButton.foreground: Gold *List.background: Azure rplay-3.3.2/contrib/xjukebox-0.9/XJukebox.ad100644 153 62 13412 6552756453 17227 0ustar boynsstaff! If you have X11R5, put this in your ~/.Xdefaults file: ! ! #ifdef COLOR ! *customization: -color ! #endif ! ! This will allow you to see XJukebox (and other applications) in full colors. ! Global resources (button shapes, keyboard shortcuts, ...) : *Command.ShapeStyle: Oval *MenuButton.ShapeStyle: Oval *MenuButton.leftBitmap: menu12 *translations: #override \n\ WM_PROTOCOLS: WMProtocols() \n *Dialog*value.translations: #override \n\ Return: Ok() \n *xjukebox.label: Jukebox Controls *jukebox.label: Jukebox ! Resources for the "spool" panel : *spoolViewport.width: 300 *spoolViewport.height: 100 *quitButton.label: Quit *quitButton.cursorName: pirate *jukeboxButton.label: Jukebox *hostButton.label: Host *aboutButton.label: About *spoolLabel.label: Rplay spool *spoolLabel.borderWidth: 0 *spoolList*font: fixed *stopButton.label: Stop *pauseButton.label: Pause *continueButton.label: Continue ! Resources for the "sounds" panel : *soundViewport.width: 200 *soundViewport.height: 300 *soundLabel.label: Sounds *soundLabel.borderWidth: 0 *soundList*font: fixed *addButton.label: Add *addAllButton.label: Add all *sfileMenuButton.label: File *serverList.label: Get list from server *loadList.label: Load list ... *saveList.label: Save List ... ! Resources for the "jukebox" (queue) panel : *queueViewport.width: 200 *queueViewport.height: 100 *queueLabel.label: Jukebox *queueLabel.borderWidth: 0 *queueList*font: fixed *playButton.label: Play *deleteButton.label: Delete *sortMenuButton.label: Sort *qfileMenuButton.label: File *moveToTop.label: Move to top *moveToBottom.label: Move to Bottom *sortByName.label: Sort by name *sortBySize.label: Sort by size *shuffle.label: Shuffle *directoryList.label: Get list from directory ... ! You might get unexpected results if you change the following resources... ! My advice : don't touch this ! *spoolViewport.top: ChainTop *spoolViewport.bottom: ChainBottom *spoolViewport.left: ChainLeft *spoolViewport.right: ChainRight *soundViewport.top: ChainTop *soundViewport.bottom: ChainBottom *soundViewport.left: ChainLeft *soundViewport.right: ChainRight *queueViewport.top: ChainTop *queueViewport.bottom: ChainBottom *queueViewport.left: ChainLeft *queueViewport.right: ChainRight *quitButton.top: ChainTop *quitButton.bottom: ChainTop *quitButton.left: ChainLeft *quitButton.right: ChainLeft *jukeboxButton.fromHoriz: quitButton *jukeboxButton.top: ChainTop *jukeboxButton.bottom: ChainTop *jukeboxButton.left: ChainLeft *jukeboxButton.right: ChainLeft *hostButton.fromHoriz: jukeboxButton *hostButton.top: ChainTop *hostButton.bottom: ChainTop *hostButton.left: ChainLeft *hostButton.right: ChainLeft *aboutButton.fromHoriz: hostButton *aboutButton.top: ChainTop *aboutButton.bottom: ChainTop *aboutButton.left: ChainLeft *aboutButton.right: ChainLeft *spoolLabel.fromVert: quitButton *spoolLabel.top: ChainTop *spoolLabel.bottom: ChainTop *spoolLabel.left: ChainLeft *spoolLabel.right: ChainLeft *spoolViewport.fromVert: spoolLabel *spoolViewport.allowVert: True *spoolList.forceColumns: True *spoolList.defaultColumns: 1 *spoolList.horizDistance: 0 *stopButton.fromVert: spoolViewport *stopButton.top: ChainBottom *stopButton.bottom: ChainBottom *stopButton.left: ChainLeft *stopButton.right: ChainLeft *pauseButton.fromVert: spoolViewport *pauseButton.fromHoriz: stopButton *pauseButton.top: ChainBottom *pauseButton.bottom: ChainBottom *pauseButton.left: ChainLeft *pauseButton.right: ChainLeft *continueButton.fromVert: spoolViewport *continueButton.fromHoriz: pauseButton *continueButton.top: ChainBottom *continueButton.bottom: ChainBottom *continueButton.left: ChainLeft *continueButton.right: ChainLeft *soundLabel.top: ChainTop *soundLabel.bottom: ChainTop *soundLabel.left: ChainLeft *soundLabel.right: ChainLeft *soundViewport.fromVert: soundLabel *soundViewport.allowVert: True *soundList.forceColumns: True *soundList.defaultColumns: 1 *soundList.horizDistance: 0 *addButton.fromVert: soundViewport *addButton.top: ChainBottom *addButton.bottom: ChainBottom *addButton.left: ChainLeft *addButton.right: ChainLeft *addAllButton.fromVert: soundViewport *addAllButton.fromHoriz: addButton *addAllButton.top: ChainBottom *addAllButton.bottom: ChainBottom *addAllButton.left: ChainLeft *addAllButton.right: ChainLeft *sfileMenuButton.fromVert: soundViewport *sfileMenuButton.fromHoriz: addAllButton *sfileMenuButton.top: ChainBottom *sfileMenuButton.bottom: ChainBottom *sfileMenuButton.left: ChainLeft *sfileMenuButton.right: ChainLeft *queueLabel.top: ChainTop *queueLabel.bottom: ChainTop *queueLabel.left: ChainLeft *queueLabel.right: ChainLeft *queueViewport.fromVert: queueLabel *queueViewport.allowVert: True *queueList.forceColumns: True *queueList.defaultColumns: 1 *queueList.horizDistance: 0 *playButton.fromVert: queueViewport *playButton.top: ChainBottom *playButton.bottom: ChainBottom *playButton.left: ChainLeft *playButton.right: ChainLeft *deleteButton.fromVert: queueViewport *deleteButton.fromHoriz: playButton *deleteButton.top: ChainBottom *deleteButton.bottom: ChainBottom *deleteButton.left: ChainLeft *deleteButton.right: ChainLeft *sortMenuButton.fromVert: queueViewport *sortMenuButton.fromHoriz: deleteButton *sortMenuButton.top: ChainBottom *sortMenuButton.bottom: ChainBottom *sortMenuButton.left: ChainLeft *sortMenuButton.right: ChainLeft *qfileMenuButton.fromVert: queueViewport *qfileMenuButton.fromHoriz: sortMenuButton *qfileMenuButton.top: ChainBottom *qfileMenuButton.bottom: ChainBottom *qfileMenuButton.left: ChainLeft *qfileMenuButton.right: ChainLeft rplay-3.3.2/contrib/xjukebox-0.9/XJukebox.ad.h100644 153 62 13365 6552756453 17464 0ustar boynsstaff"*Command.ShapeStyle: Oval", "*MenuButton.ShapeStyle: Oval", "*MenuButton.leftBitmap: menu12", "*translations: #override \\n\ WM_PROTOCOLS: WMProtocols() \\n", "*Dialog*value.translations: #override \\n\ Return: Ok() \\n", "*xjukebox.label: Jukebox Controls", "*jukebox.label: Jukebox", "*spoolViewport.width: 300", "*spoolViewport.height: 100", "*quitButton.label: Quit", "*quitButton.cursorName: pirate", "*jukeboxButton.label: Jukebox", "*hostButton.label: Host", "*aboutButton.label: About", "*spoolLabel.label: Rplay spool", "*spoolLabel.borderWidth: 0", "*spoolList*font: fixed", "*stopButton.label: Stop", "*pauseButton.label: Pause", "*continueButton.label: Continue", "*soundViewport.width: 200", "*soundViewport.height: 300", "*soundLabel.label: Sounds", "*soundLabel.borderWidth: 0", "*soundList*font: fixed", "*addButton.label: Add", "*addAllButton.label: Add all", "*sfileMenuButton.label: File", "*serverList.label: Get list from server", "*loadList.label: Load list ...", "*saveList.label: Save List ...", "*queueViewport.width: 200", "*queueViewport.height: 100", "*queueLabel.label: Jukebox", "*queueLabel.borderWidth: 0", "*queueList*font: fixed", "*playButton.label: Play", "*deleteButton.label: Delete", "*sortMenuButton.label: Sort", "*qfileMenuButton.label: File", "*moveToTop.label: Move to top", "*moveToBottom.label: Move to Bottom", "*sortByName.label: Sort by name", "*sortBySize.label: Sort by size", "*shuffle.label: Shuffle", "*directoryList.label: Get list from directory ...", "*spoolViewport.top: ChainTop", "*spoolViewport.bottom: ChainBottom", "*spoolViewport.left: ChainLeft", "*spoolViewport.right: ChainRight", "*soundViewport.top: ChainTop", "*soundViewport.bottom: ChainBottom", "*soundViewport.left: ChainLeft", "*soundViewport.right: ChainRight", "*queueViewport.top: ChainTop", "*queueViewport.bottom: ChainBottom", "*queueViewport.left: ChainLeft", "*queueViewport.right: ChainRight", "*quitButton.top: ChainTop", "*quitButton.bottom: ChainTop", "*quitButton.left: ChainLeft", "*quitButton.right: ChainLeft", "*jukeboxButton.fromHoriz: quitButton", "*jukeboxButton.top: ChainTop", "*jukeboxButton.bottom: ChainTop", "*jukeboxButton.left: ChainLeft", "*jukeboxButton.right: ChainLeft", "*hostButton.fromHoriz: jukeboxButton", "*hostButton.top: ChainTop", "*hostButton.bottom: ChainTop", "*hostButton.left: ChainLeft", "*hostButton.right: ChainLeft", "*aboutButton.fromHoriz: hostButton", "*aboutButton.top: ChainTop", "*aboutButton.bottom: ChainTop", "*aboutButton.left: ChainLeft", "*aboutButton.right: ChainLeft", "*spoolLabel.fromVert: quitButton", "*spoolLabel.top: ChainTop", "*spoolLabel.bottom: ChainTop", "*spoolLabel.left: ChainLeft", "*spoolLabel.right: ChainLeft", "*spoolViewport.fromVert: spoolLabel", "*spoolViewport.allowVert: True", "*spoolList.forceColumns: True", "*spoolList.defaultColumns: 1", "*spoolList.horizDistance: 0", "*stopButton.fromVert: spoolViewport", "*stopButton.top: ChainBottom", "*stopButton.bottom: ChainBottom", "*stopButton.left: ChainLeft", "*stopButton.right: ChainLeft", "*pauseButton.fromVert: spoolViewport", "*pauseButton.fromHoriz: stopButton", "*pauseButton.top: ChainBottom", "*pauseButton.bottom: ChainBottom", "*pauseButton.left: ChainLeft", "*pauseButton.right: ChainLeft", "*continueButton.fromVert: spoolViewport", "*continueButton.fromHoriz: pauseButton", "*continueButton.top: ChainBottom", "*continueButton.bottom: ChainBottom", "*continueButton.left: ChainLeft", "*continueButton.right: ChainLeft", "*soundLabel.top: ChainTop", "*soundLabel.bottom: ChainTop", "*soundLabel.left: ChainLeft", "*soundLabel.right: ChainLeft", "*soundViewport.fromVert: soundLabel", "*soundViewport.allowVert: True", "*soundList.forceColumns: True", "*soundList.defaultColumns: 1", "*soundList.horizDistance: 0", "*addButton.fromVert: soundViewport", "*addButton.top: ChainBottom", "*addButton.bottom: ChainBottom", "*addButton.left: ChainLeft", "*addButton.right: ChainLeft", "*addAllButton.fromVert: soundViewport", "*addAllButton.fromHoriz: addButton", "*addAllButton.top: ChainBottom", "*addAllButton.bottom: ChainBottom", "*addAllButton.left: ChainLeft", "*addAllButton.right: ChainLeft", "*sfileMenuButton.fromVert: soundViewport", "*sfileMenuButton.fromHoriz: addAllButton", "*sfileMenuButton.top: ChainBottom", "*sfileMenuButton.bottom: ChainBottom", "*sfileMenuButton.left: ChainLeft", "*sfileMenuButton.right: ChainLeft", "*queueLabel.top: ChainTop", "*queueLabel.bottom: ChainTop", "*queueLabel.left: ChainLeft", "*queueLabel.right: ChainLeft", "*queueViewport.fromVert: queueLabel", "*queueViewport.allowVert: True", "*queueList.forceColumns: True", "*queueList.defaultColumns: 1", "*queueList.horizDistance: 0", "*playButton.fromVert: queueViewport", "*playButton.top: ChainBottom", "*playButton.bottom: ChainBottom", "*playButton.left: ChainLeft", "*playButton.right: ChainLeft", "*deleteButton.fromVert: queueViewport", "*deleteButton.fromHoriz: playButton", "*deleteButton.top: ChainBottom", "*deleteButton.bottom: ChainBottom", "*deleteButton.left: ChainLeft", "*deleteButton.right: ChainLeft", "*sortMenuButton.fromVert: queueViewport", "*sortMenuButton.fromHoriz: deleteButton", "*sortMenuButton.top: ChainBottom", "*sortMenuButton.bottom: ChainBottom", "*sortMenuButton.left: ChainLeft", "*sortMenuButton.right: ChainLeft", "*qfileMenuButton.fromVert: queueViewport", "*qfileMenuButton.fromHoriz: sortMenuButton", "*qfileMenuButton.top: ChainBottom", "*qfileMenuButton.bottom: ChainBottom", "*qfileMenuButton.left: ChainLeft", "*qfileMenuButton.right: ChainLeft", rplay-3.3.2/contrib/xjukebox-0.9/ad2c100755 153 62 3151 6552756453 15700 0ustar boynsstaff#!/bin/sh # # ad2c : Convert app-defaults file to C strings decls. # # George Ferguson, ferguson@cs.rcohester.edu, 12 Nov 1990. # 19 Mar 1991: gf # Made it self-contained. # 6 Jan 1992: mycroft@gnu.ai.mit.edu (Charles Hannum) # Removed use of "-n" and ":read" label since Gnu and # IBM sed print pattern space on "n" command. Still works # with Sun sed, of course. # 7 Jan 1992: matthew@sunpix.East.Sun.COM (Matthew Stier) # Escape quotes after escaping backslashes. # 8 Jul 1992: Version 1.6 # Manpage fixes. # 19 Apr 1993: Version 1.7 # Remove comments that were inside the sed command since # some versions of sed don't like them. The comments are # now given here in the header. # # Comments on the script by line: # /^!/d Remove comments # /^$/d Remove blanks # s/\\/\\\\/g Escape backslashes... # s/\\$//g ...except the line continuation ones # s/"/\\"/g Escape quotes # s/^/"/ Add leading quote # : test Establish label for later branch # /\\$/b slash Branch to label "slash" if line ends in backslash # s/$/",/ Otherwise add closing quote and comma... # p ...output the line... # d ...and clear the pattern space so it's not printed again # : slash Branch comes here if line ends in backslash # n Read next line, append to pattern space # [...] The "d" and "s" commands that follow just delete # comments and blank lines and escape control sequences # b test Branch up to see if the line ends in backslash or not # sed ' /^!/d /^$/d s/\\/\\\\/g s/\\$//g s/"/\\"/g s/^/"/ : test /\\$/b slash s/$/",/ p d : slash n /^!/d /^$/d s/"/\\"/g s/\\\\/\\/g s/\\n/\\\\n/g s/\\t/\\\\t/g s/\\f/\\\\f/g s/\\b/\\\\b/g b test' "$@" rplay-3.3.2/contrib/xjukebox-0.9/rptpstuff.c100644 153 62 25031 6552756453 17363 0ustar boynsstaff/* * Copyright (C) 1993 Raphael Quinet (quinet@montefiore.ulg.ac.be) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "xjukebox.h" #include #include #ifdef __STDC__ extern void setBusy(Boolean busy); extern void add_spool_item(String new_info, spool_info ***list, String **nlist, int *items_count); extern void free_spool_items(spool_info ***list, String **nlist, int *items_count); #else extern void setBusy(); extern void add_spool_item(); extern void free_spool_items(); #endif extern String *sound_names; extern int sound_count; extern String *queue_names; extern int queue_count; extern String *spool_names; extern int spool_count; extern Widget sound_list; extern Widget queue_list; extern Widget spool_list; extern int return_code; extern XtAppContext app_context; XtInputId input_id; XtIntervalId interval_id = NO_INTERVAL; int rptp_port = RPTP_PORT; char *rptp_host = NULL; int rptp_fd = -1; char rptp_buf[4096]; char rptp_resp[RPTP_MAX_LINE]; int rptp_mode = MODE_IDLE; int old_spool_count = -1; spool_info **spool_info_list; static String empty_spool[] = { "", NULL }; int playing_sid = -1; #ifdef __STDC__ void rptp_callback(XtPointer client_data, int *input, XtInputId *input_id); void rptp_get_spool_list(XtPointer client_data, XtIntervalId *id); #else void rptp_callback(); void rptp_get_spool_list(); #endif /*****************************************************************************/ #ifdef __STDC__ void setSpoolUpdate(Boolean update) #else void setSpoolUpdate(update) Boolean update; #endif { if (update) { if (interval_id == NO_INTERVAL) interval_id = XtAppAddTimeOut(app_context, 1000, rptp_get_spool_list, NULL); } else { if (interval_id != NO_INTERVAL) XtRemoveTimeOut(interval_id); interval_id = NO_INTERVAL; } } /*****************************************************************************/ void rptp_disconnect() { setSpoolUpdate(False); if (rptp_fd != -1) { XtRemoveInput(input_id); rptp_close(rptp_fd); rptp_fd = -1; } } /*****************************************************************************/ #ifdef __STDC__ void rptp_connect(char *hostname) #else void rptp_connect(hostname) char *hostname; #endif { rptp_disconnect(); if ((hostname == NULL) || (hostname[0] == '\0')) rptp_host = rplay_default_host(); else rptp_host = hostname; rptp_fd = rptp_open(rptp_host, rptp_port, rptp_resp, sizeof(rptp_resp)); if (rptp_fd < 0) { rptp_perror("*** open"); return; /* !!!! */ } printf("Connected to %s port %d.\n", rptp_host, rptp_port); printf("%s\n", rptp_resp + 1); input_id = XtAppAddInput(app_context, rptp_fd, (XtPointer) XtInputReadMask, rptp_callback, NULL); old_spool_count = -1; /* setSpoolUpdate(True); Loose, loose ! */ } /*****************************************************************************/ int rptp_reconnect() { printf("*** Error in connection with %s. Trying to reconnect...\n", rptp_host); rptp_disconnect(); if (rptp_host == NULL) printf("BANG ! A bug... (rptp_host = NULL)\n"); rptp_fd = rptp_open(rptp_host, rptp_port, rptp_resp, sizeof(rptp_resp)); if (rptp_fd < 0) { rptp_perror("*** reopen"); return -1; } printf("Reconnected to %s port %d.\n", rptp_host, rptp_port); printf("%s\n", rptp_resp + 1); input_id = XtAppAddInput(app_context, rptp_fd, (XtPointer) XtInputReadMask, rptp_callback, NULL); old_spool_count = -1; setSpoolUpdate(True); return 1; } /*****************************************************************************/ #ifdef __STDC__ void rptp_play_sound(char *name) #else void rptp_play_sound(name) char *name; #endif { sprintf(rptp_buf, "play sound=%s", name); /* printf("%s\n", rptp_buf); */ switch (rptp_command(rptp_fd, rptp_buf, rptp_resp, sizeof(rptp_resp))) { case -1: /* !!!!!!!!!! */ rptp_perror("play"); if (rptp_reconnect() > 0) rptp_play_sound(name); break; case 1: printf("?? %s\n", rptp_resp + 1); break; case 0: playing_sid = atoi (rptp_parse (rptp_resp, "id") + 1); break; } } /*****************************************************************************/ #ifdef __STDC__ void rptp_stop_sound(int spool_index) #else void rptp_stop_sound(spool_index) int spool_index; #endif { sprintf(rptp_buf, "stop id=#%d", spool_info_list[spool_index]->sid); /* printf("%s\n", rptp_buf); */ switch (rptp_command(rptp_fd, rptp_buf, rptp_resp, sizeof(rptp_resp))) { case -1: /* !!!!!!!!!! */ rptp_perror("stop"); if (rptp_reconnect() > 0) rptp_stop_sound(spool_index); break; case 1: printf("!! %s\n", rptp_resp + 1); break; case 0: break; } } /*****************************************************************************/ #ifdef __STDC__ void rptp_pause_sound(int spool_index) #else void rptp_pause_sound(spool_index) int spool_index; #endif { sprintf(rptp_buf, "pause id=#%d", spool_info_list[spool_index]->sid); /* printf("%s\n", rptp_buf); */ switch (rptp_command(rptp_fd, rptp_buf, rptp_resp, sizeof(rptp_resp))) { case -1: /* !!!!!!!!!! */ rptp_perror("pause"); if (rptp_reconnect() > 0) rptp_pause_sound(spool_index); break; case 1: printf("*!! %s\n", rptp_resp + 1); break; case 0: break; } } /*****************************************************************************/ #ifdef __STDC__ void rptp_continue_sound(int spool_index) #else void rptp_continue_sound(spool_index) int spool_index; #endif { sprintf(rptp_buf, "continue id=#%d", spool_info_list[spool_index]->sid); /* printf("%s\n", rptp_buf); */ switch (rptp_command(rptp_fd, rptp_buf, rptp_resp, sizeof(rptp_resp))) { case -1: /* !!!!!!!!!! */ rptp_perror("continue"); if (rptp_reconnect() > 0) rptp_continue_sound(spool_index); break; case 1: printf("*!! %s\n", rptp_resp + 1); break; case 0: break; } } /*****************************************************************************/ void rptp_get_sound_list() { if (rptp_fd == -1) { printf("Aaaargh !\n"); /* !!!!!!! */ return; } switch (rptp_command(rptp_fd, "list sounds", rptp_resp, sizeof(rptp_resp))) { case -1: /* !!!!!!!!!! */ rptp_perror("get_sound_list"); rptp_disconnect(); return; case 1: printf("get_sound_list : %s\n---\n", rptp_resp + 1); /* rptp_mode = MODE_READING_SOUNDS; */ break; case 0: rptp_mode = MODE_READING_SOUNDS; break; } sound_names = NULL; setSpoolUpdate(False); /* Quick hack... */ } /*****************************************************************************/ #ifdef __STDC__ void rptp_get_spool_list(XtPointer client_data, XtIntervalId *id) #else void rptp_get_spool_list(client_data, id) XtPointer client_data; XtIntervalId *id; #endif { interval_id = NO_INTERVAL; if (rptp_fd == -1) { printf("Aaaargh !\n"); /* !!!!!!! */ return; } switch (rptp_command(rptp_fd, "list spool", rptp_resp, sizeof(rptp_resp))) { case -1: /* !!!!!!!!!! */ rptp_perror("get_spool_list"); rptp_disconnect(); return; case 1: printf("get_spool_list : %s\n---\n", rptp_resp + 1); /* rptp_mode = MODE_READING_SPOOL; */ break; case 0: rptp_mode = MODE_READING_SPOOL; break; } free_spool_items(&spool_info_list, &spool_names, &spool_count); } /*****************************************************************************/ #ifdef __STDC__ void rptp_callback(XtPointer client_data, int *input, XtInputId *id) #else void rptp_callback(client_data, input, id) XtPointer client_data; int *input; XtInputId *id; #endif { int n, i; switch (rptp_mode) { case MODE_IDLE : printf("*** Unexpected event ! Connection timed out ?\n"); sleep(1); /* !!!!!!!!!! */ /* n = rptp_getline(rptp_fd, rptp_buf, sizeof(rptp_buf)); printf(" n = %d, rptp_buf = \"%s\"\n", n, rptp_buf); */ break; case MODE_READING_SOUNDS : n = rptp_getline(rptp_fd, rptp_buf, sizeof(rptp_buf)); if (n < 0) { /* !!!!!!!!!! */ rptp_perror("list sounds"); return; } if (! strcmp(rptp_buf, ".")) { rptp_mode = MODE_IDLE; XawListChange(sound_list, sound_names, sound_count, 0, True); setBusy(False); setSpoolUpdate(True); return; } add_item(rptp_parse (rptp_buf, "sound"), &sound_names, &sound_count); break; case MODE_READING_SPOOL : n = rptp_getline(rptp_fd, rptp_buf, sizeof(rptp_buf)); if (n < 0) { /* !!!!!!!!!! */ rptp_perror("list spool"); return; } if (! strcmp(rptp_buf, ".")) { rptp_mode = MODE_IDLE; if ((spool_count > 0) || (old_spool_count != 0)) { if (spool_count > 0) XawListChange(spool_list, spool_names, spool_count, 0, True); else XawListChange(spool_list, empty_spool, 1, 0, True); old_spool_count = spool_count; } if (playing_sid > 0) { for (i = 0; i < spool_count; i++) if (spool_info_list[i]->sid == playing_sid) break; if (i >= spool_count) /* Sound not found, play next one */ { playing_sid = -1; if (queue_count > 0) { rptp_play_sound(queue_names[0]); delete_item(0, &queue_names, &queue_count); XawListChange(queue_list, queue_names, queue_count, 0, True); } } } setSpoolUpdate(True); return; } add_spool_item(rptp_buf, &spool_info_list, &spool_names, &spool_count); break; default : printf("*** Unknown mode : BUG !\n"); break; } } rplay-3.3.2/contrib/xjukebox-0.9/widgets.c100644 153 62 73562 6552756453 17010 0ustar boynsstaff/* * Copyright (C) 1993 Raphael Quinet (quinet@montefiore.ulg.ac.be) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "xjukebox.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef __STDC__ extern char *rplay_default_host(); extern void setSpoolUpdate(Boolean update); extern void rptp_connect(char *hostname); extern void rptp_get_sound_list(); extern void rptp_get_spool_list(); extern int alphacompare(char **i, char **j); #else extern char *rplay_default_host(); extern void setSpoolUpdate(); extern void rptp_connect(); extern void rptp_get_sound_list(); extern void rptp_get_spool_list(); extern int alphacompare(); #endif extern String *sound_names; extern int sound_count; extern String *queue_names; extern int queue_count; extern String *spool_names; extern int spool_count; extern int return_code; #ifdef __STDC__ void wmProtocolsProc(Widget w, XEvent *event, String params[], Cardinal *num_params); void okProc(Widget w, XEvent *event, String params[], Cardinal *num_params); void cancelProc(Widget w, XEvent *event, String params[], Cardinal *num_params); #else void wmProtocolsProc(); void okProc(); void cancelProc(); #endif Widget top_shell, jukebox_shell, sound_list, queue_list, spool_list; Atom XA_WM_DELETE_WINDOW; XtAppContext app_context; static Boolean closing_top_shell = False; static int current_dialog = DIALOG_NONE; static String default_file = ""; static String fallback_resources[] = { #include "XJukebox.ad.h" NULL }; #define Offset(field) XtOffsetOf(struct _resources_rec, field) static XtResource resources_desc[] = { { "jukeboxShown", "JukeboxShown", XtRBoolean, sizeof(Boolean), Offset(jukebox_shown), XtRImmediate, (XtPointer)FALSE } }; #undef Offset static XrmOptionDescRec options[] = { { "-jukeboxShown", ".jukeboxShown", XrmoptionNoArg, "TRUE" } }; static XtActionsRec actions[] = { { "WMProtocols", wmProtocolsProc }, { "Ok", okProc }, { "Cancel", cancelProc } }; /*****************************************************************************/ void ringBell() { XBell(XtDisplay(top_shell), 50); } /*****************************************************************************/ #ifdef __STDC__ void setBusy(Boolean busy) #else void setBusy(busy) Boolean busy; #endif { static Window win1 = (Window) 0; static Window win2 = (Window) 0; Display *disp; XSetWindowAttributes xswa; disp = XtDisplay(top_shell); if (! win1) { xswa.do_not_propagate_mask = (KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask); xswa.cursor = XCreateFontCursor(disp, XC_watch); win1 = XCreateWindow(disp, XtWindow(top_shell), 0, 0, (unsigned int) 8192, /* Should be large enough */ (unsigned int) 8192, (unsigned int) 0, CopyFromParent, InputOnly, CopyFromParent, CWDontPropagate | CWCursor, &xswa); win2 = XCreateWindow(disp, XtWindow(jukebox_shell), 0, 0, (unsigned int) 8192, (unsigned int) 8192, (unsigned int) 0, CopyFromParent, InputOnly, CopyFromParent, CWDontPropagate | CWCursor, &xswa); } if (busy) { XMapRaised(disp, win1); XMapRaised(disp, win2); } else { XUnmapWindow(disp, win1); XUnmapWindow(disp, win2); } } /*****************************************************************************/ #ifdef __STDC__ void selectOkProc(Widget w, XtPointer client_data, XtPointer call_data) #else void selectOkProc(w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; #endif { Widget dialog; String value; dialog = (Widget) client_data; value = (String) XawDialogGetValueString(dialog); XtDestroyWidget(XtParent(dialog)); switch (current_dialog) { case DIALOG_SET_NEW_HOST : rptp_connect(value); setSpoolUpdate(True); break; case DIALOG_LOAD_SOUND_FILE : load_list(value, &sound_names, &sound_count); XawListChange(sound_list, sound_names, sound_count, 0, True); default_file = value; break; case DIALOG_SAVE_SOUND_FILE : save_list(value, sound_names, sound_count); default_file = value; break; case DIALOG_GET_SOUND_DIR : printf("*** Not implemented : GET_SOUND_DIR : %s\n", value); break; case DIALOG_LOAD_QUEUE_FILE : load_list(value, &queue_names, &queue_count); XawListChange(queue_list, queue_names, queue_count, 0, True); default_file = value; break; case DIALOG_SAVE_QUEUE_FILE : save_list(value, queue_names, queue_count); default_file = value; break; default : printf("*** Congratulations ! You found a bug ! ***\n"); } current_dialog = DIALOG_NONE; setBusy(False); } /*****************************************************************************/ #ifdef __STDC__ void selectCancelProc(Widget w, XtPointer client_data, XtPointer call_data) #else void selectCancelProc(w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; #endif { Widget dialog; dialog = (Widget) client_data; XtDestroyWidget(XtParent(dialog)); current_dialog = DIALOG_NONE; setBusy(False); } /*****************************************************************************/ #ifdef __STDC__ void popupDialog(Widget button, String message, String default_value, int id) #else void popupDialog(button, message, default_value, id) Widget button; String message; String default_value; int id; #endif { Arg args[2]; Widget popup, dialog; Position x, y; Dimension width, height; XtSetArg(args[0], XtNwidth, &width); XtSetArg(args[1], XtNheight, &height); XtGetValues(button, args, TWO); XtTranslateCoords(button, (Position)(width / 2 - 64), (Position)(height / 2 - 32), &x, &y); XtSetArg(args[0], XtNx, x); XtSetArg(args[1], XtNy, y); popup = XtCreatePopupShell((String) "popup", transientShellWidgetClass, button, args, TWO); XtSetArg(args[0], XtNlabel, message); XtSetArg(args[1], XtNvalue, default_value); dialog = XtCreateManagedWidget((String) "dialog", dialogWidgetClass, popup, args, TWO); XawDialogAddButton(dialog, "ok", selectOkProc, (XtPointer) dialog); XawDialogAddButton(dialog, "cancel", selectCancelProc, (XtPointer) dialog); current_dialog = id; XtPopup(popup, XtGrabExclusive); setBusy(True); } /*****************************************************************************/ #ifdef __STDC__ void select_soundProc(Widget w, XtPointer client_data, XtPointer call_data) #else void select_soundProc(w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; #endif { /* Should check double click... (= Add) */ } /*****************************************************************************/ #ifdef __STDC__ void select_queueProc(Widget w, XtPointer client_data, XtPointer call_data) #else void select_queueProc(w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; #endif { /* Should check double click... (= Play this sound) */ } /*****************************************************************************/ #ifdef __STDC__ void select_spoolProc(Widget w, XtPointer client_data, XtPointer call_data) #else void select_spoolProc(w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; #endif { /* ... */ } /*****************************************************************************/ #ifdef __STDC__ void quitProc(Widget w, XtPointer client_data, XtPointer call_data) #else void quitProc(w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; #endif { XtDestroyWidget(top_shell); exit(return_code); } /*****************************************************************************/ #ifdef __STDC__ void jukeboxProc(Widget w, XtPointer client_data, XtPointer call_data) #else void jukeboxProc(w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; #endif { if (resources.jukebox_shown) { resources.jukebox_shown = False; XtPopdown(jukebox_shell); } else { XtPopup(jukebox_shell, XtGrabNone); resources.jukebox_shown = True; } } /*****************************************************************************/ #ifdef __STDC__ void hostProc(Widget w, XtPointer client_data, XtPointer call_data) #else void hostProc(w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; #endif { popupDialog(w, (String) "New rplay host :", (String) rplay_default_host(), DIALOG_SET_NEW_HOST); setSpoolUpdate(False); } /*****************************************************************************/ #ifdef __STDC__ void aboutProc(Widget w, XtPointer client_data, XtPointer call_data) #else void aboutProc(w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; #endif { Arg args[5]; XtCallbackRec callback[2]; Widget popup, about, label, button; Position x, y; Dimension width, height; char buffer[100]; XtSetArg(args[0], XtNwidth, &width); XtSetArg(args[1], XtNheight, &height); XtGetValues(w, args, TWO); XtTranslateCoords(w, (Position)(width / 2 - 64), (Position)(height / 2 - 32), &x, &y); XtSetArg(args[0], XtNx, x); XtSetArg(args[1], XtNy, y); popup = XtCreatePopupShell((String) "popup", transientShellWidgetClass, w, args, TWO); about = XtCreateManagedWidget((String) "aboutForm", formWidgetClass, popup, NULL, ZERO); sprintf(buffer, "XJukebox %s (C) 1993, Raphael Quinet\n", XJUKEBOX_VERSION); XtSetArg(args[0], XtNlabel, buffer); XtSetArg(args[1], XtNborderWidth, NULL); XtSetArg(args[2], XtNfromHoriz, NULL); XtSetArg(args[3], XtNfromVert, NULL); label = XtCreateManagedWidget((String) "aboutLabel1", labelWidgetClass, about, args, FOUR); XtSetArg(args[0], XtNlabel, " "); XtSetArg(args[3], XtNfromVert, label); XtSetArg(args[4], XtNvertDistance, 0); label = XtCreateManagedWidget((String) "aboutLabel2", labelWidgetClass, about, args, FIVE); XtSetArg(args[0], XtNlabel, "Special thanks to :"); XtSetArg(args[3], XtNfromVert, label); XtSetArg(args[4], XtNvertDistance, 10); label = XtCreateManagedWidget((String) "aboutLabel3", labelWidgetClass, about, args, FIVE); XtSetArg(args[0], XtNlabel, "Mark Boyns "); XtSetArg(args[3], XtNfromVert, label); XtSetArg(args[4], XtNvertDistance, 0); label = XtCreateManagedWidget((String) "aboutLabel4", labelWidgetClass, about, args, FIVE); XtSetArg(args[0], XtNlabel, " for his rplay library"); XtSetArg(args[3], XtNfromVert, label); label = XtCreateManagedWidget((String) "aboutLabel5", labelWidgetClass, about, args, FIVE); XtSetArg(args[0], XtNlabel, "Alain Nissen "); XtSetArg(args[3], XtNfromVert, label); label = XtCreateManagedWidget((String) "aboutLabel6", labelWidgetClass, about, args, FIVE); XtSetArg(args[0], XtNlabel, " for his help and encouragements"); XtSetArg(args[3], XtNfromVert, label); label = XtCreateManagedWidget((String) "aboutLabel7", labelWidgetClass, about, args, FIVE); callback[0].callback = selectCancelProc; callback[0].closure = (XtPointer) about; callback[1].callback = NULL; callback[1].closure = NULL; XtSetArg(args[0], XtNcallback, callback); XtSetArg(args[1], XtNlabel, "Done"); XtSetArg(args[2], XtNfromHoriz, NULL); XtSetArg(args[3], XtNfromVert, label); button = XtCreateManagedWidget((String) "doneButton", commandWidgetClass, about, args, FOUR); XtPopup(popup, XtGrabExclusive); setBusy(True); } /*****************************************************************************/ #ifdef __STDC__ void stopProc(Widget w, XtPointer client_data, XtPointer call_data) #else void stopProc(w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; #endif { XawListReturnStruct *item; item = XawListShowCurrent(spool_list); if (spool_count > 0) { if (item->list_index != XAW_LIST_NONE) rptp_stop_sound(item->list_index); else rptp_stop_sound(0); } else ringBell(); } /*****************************************************************************/ #ifdef __STDC__ void pauseProc(Widget w, XtPointer client_data, XtPointer call_data) #else void pauseProc(w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; #endif { XawListReturnStruct *item; item = XawListShowCurrent(spool_list); if (spool_count > 0) { if (item->list_index != XAW_LIST_NONE) rptp_pause_sound(item->list_index); else rptp_pause_sound(0); } else ringBell(); } /*****************************************************************************/ #ifdef __STDC__ void continueProc(Widget w, XtPointer client_data, XtPointer call_data) #else void continueProc(w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; #endif { XawListReturnStruct *item; item = XawListShowCurrent(spool_list); if (spool_count > 0) { if (item->list_index != XAW_LIST_NONE) rptp_continue_sound(item->list_index); else rptp_continue_sound(0); } else ringBell(); } /*****************************************************************************/ #ifdef __STDC__ void addProc(Widget w, XtPointer client_data, XtPointer call_data) #else void addProc(w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; #endif { XawListReturnStruct *item; item = XawListShowCurrent(sound_list); if ((item->list_index != XAW_LIST_NONE) && (sound_count > 0)) add_item(item->string, &queue_names, &queue_count); else ringBell(); XawListChange(queue_list, queue_names, queue_count, 0, True); } /*****************************************************************************/ #ifdef __STDC__ void addallProc(Widget w, XtPointer client_data, XtPointer call_data) #else void addallProc(w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; #endif { int i; for (i = 0; i < sound_count; i++) add_item(sound_names[i], &queue_names, &queue_count); XawListChange(queue_list, queue_names, queue_count, 0, True); } /*****************************************************************************/ #ifdef __STDC__ void sfileMenuSelectProc(Widget w, XtPointer client_data, XtPointer call_data) #else void sfileMenuSelectProc(w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; #endif { if (!strcmp(XtName(w), "serverList")) { setBusy(True); rptp_get_sound_list(); } if (!strcmp(XtName(w), "loadList")) popupDialog(XtParent(XtParent(w)), (String) "Load list from file :", default_file, DIALOG_LOAD_SOUND_FILE); if (!strcmp(XtName(w), "saveList")) popupDialog(XtParent(XtParent(w)), (String) "Save list into file :", default_file, DIALOG_SAVE_SOUND_FILE); } /*****************************************************************************/ #ifdef __STDC__ void playProc(Widget w, XtPointer client_data, XtPointer call_data) #else void playProc(w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; #endif { if (queue_count >= 1) { rptp_play_sound(queue_names[0]); delete_item(0, &queue_names, &queue_count); XawListChange(queue_list, queue_names, queue_count, 0, True); } else XBell(XtDisplay(w), 50); } /*****************************************************************************/ #ifdef __STDC__ void deleteProc(Widget w, XtPointer client_data, XtPointer call_data) #else void deleteProc(w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; #endif { XawListReturnStruct *item; item = XawListShowCurrent(queue_list); if (item->list_index != XAW_LIST_NONE) delete_item(item->list_index, &queue_names, &queue_count); else if (queue_count >= 1) delete_item(queue_count - 1, &queue_names, &queue_count); else XBell(XtDisplay(w), 50); XawListChange(queue_list, queue_names, queue_count, 0, True); } /*****************************************************************************/ #ifdef __STDC__ void sortMenuSelectProc(Widget w, XtPointer client_data, XtPointer call_data) #else void sortMenuSelectProc(w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; #endif { XawListReturnStruct *item; item = XawListShowCurrent(queue_list); if (!strcmp(XtName(w), "moveToTop")) { if (item->list_index != XAW_LIST_NONE) move_item(item->list_index, 0, &queue_names); else move_item(queue_count - 1, 0, &queue_names); } if (!strcmp(XtName(w), "moveToBottom")) { if (item->list_index != XAW_LIST_NONE) move_item(item->list_index, queue_count - 1, &queue_names); else move_item(0, queue_count - 1, &queue_names); } if (!strcmp(XtName(w), "sortByName")) { qsort((char *)queue_names, queue_count, sizeof(String), alphacompare); } if (!strcmp(XtName(w), "sortBySize")) { printf("*** Not implemented : Sort by size...\n"); } if (!strcmp(XtName(w), "shuffle")) { printf("*** Not implemented : Shuffle...\n"); } XawListChange(queue_list, queue_names, queue_count, 0, True); } /*****************************************************************************/ #ifdef __STDC__ void qfileMenuSelectProc(Widget w, XtPointer client_data, XtPointer call_data) #else void qfileMenuSelectProc(w, client_data, call_data) Widget w; XtPointer client_data; XtPointer call_data; #endif { if (!strcmp(XtName(w), "directoryList")) popupDialog(XtParent(XtParent(w)), (String) "Build list from directory :", "", DIALOG_GET_SOUND_DIR); if (!strcmp(XtName(w), "loadList")) popupDialog(XtParent(XtParent(w)), (String) "Load list from file :", default_file, DIALOG_LOAD_QUEUE_FILE); if (!strcmp(XtName(w), "saveList")) popupDialog(XtParent(XtParent(w)), (String) "Save list into file :", default_file, DIALOG_SAVE_QUEUE_FILE); } /*****************************************************************************/ #ifdef __STDC__ void wmProtocolsProc(Widget w, XEvent *event, String params[], Cardinal *num_params) #else void wmProtocolsProc(w, event, params, num_params) Widget w; XEvent *event; String params[]; Cardinal *num_params; #endif { if (event -> xclient.data.l[0] == XA_WM_DELETE_WINDOW) { if ((w == top_shell) && ! closing_top_shell) { closing_top_shell = True; quitProc(w, (XtPointer) NULL, (XtPointer) NULL); closing_top_shell = False; } if (w == jukebox_shell) { resources.jukebox_shown = False; XtPopdown(jukebox_shell); } } } /*****************************************************************************/ #ifdef __STDC__ void okProc(Widget w, XEvent *event, String params[], Cardinal *num_params) #else void okProc(w, event, params, num_params) Widget w; XEvent *event; String params[]; Cardinal *num_params; #endif { Widget dialog; dialog = XtParent(w); selectOkProc(w, (XtPointer) dialog, (XtPointer) NULL); } /*****************************************************************************/ #ifdef __STDC__ void cancelProc(Widget w, XEvent *event, String params[], Cardinal *num_params) #else void cancelProc(w, event, params, num_params) Widget w; XEvent *event; String params[]; Cardinal *num_params; #endif { Widget dialog; dialog = XtParent(w); selectCancelProc(w, (XtPointer) dialog, (XtPointer) NULL); } /*****************************************************************************/ #ifdef __STDC__ void create_widgets(Widget top_shell) #else void create_widgets(top_shell) Widget top_shell; #endif { Widget sound_viewport, queue_viewport, spool_viewport; Widget sound_label, queue_label, spool_label; Widget spool_form, jukebox_paned, sound_form, queue_form; Widget quit_button, jukebox_button, host_button, about_button; Widget stop_button, pause_button, continue_button; Widget add_button, addall_button, sfile_button; Widget play_button, delete_button, sort_button, qfile_button; Widget menu, menu_item; /* --- Main panel (rplay spool) ------------------------------------------ */ spool_form = XtCreateManagedWidget((String) "spoolForm", formWidgetClass, top_shell, NULL, ZERO); quit_button = XtCreateManagedWidget((String) "quitButton", commandWidgetClass, spool_form, NULL, ZERO); XtAddCallback(quit_button, XtNcallback, quitProc, NULL); jukebox_button = XtCreateManagedWidget((String) "jukeboxButton", commandWidgetClass, spool_form, NULL, ZERO); XtAddCallback(jukebox_button, XtNcallback, jukeboxProc, NULL); host_button = XtCreateManagedWidget((String) "hostButton", commandWidgetClass, spool_form, NULL, ZERO); XtAddCallback(host_button, XtNcallback, hostProc, NULL); about_button = XtCreateManagedWidget((String) "aboutButton", commandWidgetClass, spool_form, NULL, ZERO); XtAddCallback(about_button, XtNcallback, aboutProc, NULL); spool_label = XtCreateManagedWidget((String) "spoolLabel", labelWidgetClass, spool_form, NULL, ZERO); spool_viewport = XtCreateManagedWidget((String) "spoolViewport", viewportWidgetClass, spool_form, NULL, ZERO); spool_list = XtCreateManagedWidget((String) "spoolList", listWidgetClass, spool_viewport, NULL, ZERO); XtAddCallback(spool_list, XtNcallback, select_spoolProc, NULL); XawListChange(spool_list, spool_names, spool_count, 0, True); stop_button = XtCreateManagedWidget((String) "stopButton", commandWidgetClass, spool_form, NULL, ZERO); XtAddCallback(stop_button, XtNcallback, stopProc, NULL); pause_button = XtCreateManagedWidget((String) "pauseButton", commandWidgetClass, spool_form, NULL, ZERO); XtAddCallback(pause_button, XtNcallback, pauseProc, NULL); continue_button = XtCreateManagedWidget((String) "continueButton", commandWidgetClass, spool_form, NULL, ZERO); XtAddCallback(continue_button, XtNcallback, continueProc, NULL); /* --- Jukebox panel ----------------------------------------------------- */ jukebox_shell = XtCreatePopupShell((String) "jukebox", topLevelShellWidgetClass, top_shell, NULL, ZERO); jukebox_paned = XtCreateManagedWidget((String) "jukeboxPaned", panedWidgetClass, jukebox_shell, NULL, ZERO); sound_form = XtCreateManagedWidget((String) "soundForm", formWidgetClass, jukebox_paned, NULL, ZERO); sound_label = XtCreateManagedWidget((String) "soundLabel", labelWidgetClass, sound_form, NULL, ZERO); sound_viewport = XtCreateManagedWidget((String) "soundViewport", viewportWidgetClass, sound_form, NULL, ZERO); sound_list = XtCreateManagedWidget((String) "soundList", listWidgetClass, sound_viewport, NULL, ZERO); XtAddCallback(sound_list, XtNcallback, select_soundProc, NULL); XawListChange(sound_list, sound_names, sound_count, 0, True); add_button = XtCreateManagedWidget((String) "addButton", commandWidgetClass, sound_form, NULL, ZERO); XtAddCallback(add_button, XtNcallback, addProc, NULL); addall_button = XtCreateManagedWidget((String) "addAllButton", commandWidgetClass, sound_form, NULL, ZERO); XtAddCallback(addall_button, XtNcallback, addallProc, NULL); sfile_button = XtCreateManagedWidget((String) "sfileMenuButton", menuButtonWidgetClass, sound_form, NULL, ZERO); queue_form = XtCreateManagedWidget((String) "queueForm", formWidgetClass, jukebox_paned, NULL, ZERO); queue_label = XtCreateManagedWidget((String) "queueLabel", labelWidgetClass, queue_form, NULL, ZERO); queue_viewport = XtCreateManagedWidget((String) "queueViewport", viewportWidgetClass, queue_form, NULL, ZERO); queue_list = XtCreateManagedWidget((String) "queueList", listWidgetClass, queue_viewport, NULL, ZERO); XtAddCallback(queue_list, XtNcallback, select_queueProc, NULL); XawListChange(queue_list, queue_names, queue_count, 0, True); play_button = XtCreateManagedWidget((String) "playButton", commandWidgetClass, queue_form, NULL, ZERO); XtAddCallback(play_button, XtNcallback, playProc, NULL); delete_button = XtCreateManagedWidget((String) "deleteButton", commandWidgetClass, queue_form, NULL, ZERO); XtAddCallback(delete_button, XtNcallback, deleteProc, NULL); sort_button = XtCreateManagedWidget((String) "sortMenuButton", menuButtonWidgetClass, queue_form, NULL, ZERO); qfile_button = XtCreateManagedWidget((String) "qfileMenuButton", menuButtonWidgetClass, queue_form, NULL, ZERO); /* --- Menus ------------------------------------------------------------- */ menu = XtCreatePopupShell((String) "menu", simpleMenuWidgetClass, sfile_button, NULL, ZERO); menu_item = XtCreateManagedWidget((String) "serverList", smeBSBObjectClass, menu, NULL, ZERO); XtAddCallback(menu_item, XtNcallback, sfileMenuSelectProc, NULL); menu_item = XtCreateManagedWidget((String) "loadList", smeBSBObjectClass, menu, NULL, ZERO); XtAddCallback(menu_item, XtNcallback, sfileMenuSelectProc, NULL); menu_item = XtCreateManagedWidget((String) "saveList", smeBSBObjectClass, menu, NULL, ZERO); XtAddCallback(menu_item, XtNcallback, sfileMenuSelectProc, NULL); menu = XtCreatePopupShell((String) "menu", simpleMenuWidgetClass, sort_button, NULL, ZERO); menu_item = XtCreateManagedWidget((String) "moveToTop", smeBSBObjectClass, menu, NULL, ZERO); XtAddCallback(menu_item, XtNcallback, sortMenuSelectProc, NULL); menu_item = XtCreateManagedWidget((String) "moveToBottom", smeBSBObjectClass, menu, NULL, ZERO); XtAddCallback(menu_item, XtNcallback, sortMenuSelectProc, NULL); menu_item = XtCreateManagedWidget((String) "sortByName", smeBSBObjectClass, menu, NULL, ZERO); XtAddCallback(menu_item, XtNcallback, sortMenuSelectProc, NULL); /* menu_item = XtCreateManagedWidget((String) "sortBySize", smeBSBObjectClass, menu, NULL, ZERO); XtAddCallback(menu_item, XtNcallback, sortMenuSelectProc, NULL); menu_item = XtCreateManagedWidget((String) "shuffle", smeBSBObjectClass, menu, NULL, ZERO); XtAddCallback(menu_item, XtNcallback, sortMenuSelectProc, NULL); */ menu = XtCreatePopupShell((String) "menu", simpleMenuWidgetClass, qfile_button, NULL, ZERO); /* menu_item = XtCreateManagedWidget((String) "directoryList", smeBSBObjectClass, menu, NULL, ZERO); XtAddCallback(menu_item, XtNcallback, qfileMenuSelectProc, NULL); */ menu_item = XtCreateManagedWidget((String) "loadList", smeBSBObjectClass, menu, NULL, ZERO); XtAddCallback(menu_item, XtNcallback, qfileMenuSelectProc, NULL); menu_item = XtCreateManagedWidget((String) "saveList", smeBSBObjectClass, menu, NULL, ZERO); XtAddCallback(menu_item, XtNcallback, qfileMenuSelectProc, NULL); } /*****************************************************************************/ #ifdef __STDC__ void init_application(char *app_name, int argc, char *argv[]) #else void init_application(app_name, argc, argv) char *app_name; int argc; char *argv[]; #endif { Display *disp; top_shell = XtAppInitialize(&app_context, app_name, options, XtNumber(options), &argc, argv, fallback_resources, NULL, ZERO); disp = XtDisplay(top_shell); XA_WM_DELETE_WINDOW = XInternAtom(disp, "WM_DELETE_WINDOW", False); XtGetApplicationResources(top_shell, (XtPointer) &resources, resources_desc, XtNumber(resources_desc), NULL, ZERO); XtAppAddActions(app_context, actions, XtNumber(actions)); /* if (argc != 1) error(SYNTAX_ERROR); */ create_widgets(top_shell); XtRealizeWidget(top_shell); XSetWMProtocols(disp, XtWindow(top_shell), &XA_WM_DELETE_WINDOW, 1); XtRealizeWidget(jukebox_shell); XSetWMProtocols(disp, XtWindow(jukebox_shell), &XA_WM_DELETE_WINDOW, 1); if (resources.jukebox_shown) XtPopup(jukebox_shell, XtGrabNone); } rplay-3.3.2/contrib/xjukebox-0.9/xjukebox.c100644 153 62 17231 6552756453 17170 0ustar boynsstaff/* * Copyright (C) 1993 Raphael Quinet (quinet@montefiore.ulg.ac.be) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "xjukebox.h" extern XtAppContext app_context; #ifdef __STDC__ extern void rptp_connect(char *hostname); extern void rptp_get_sound_list(); extern void init_application(char *app_name, int argc, char *argv[]); #else extern void rptp_connect(); extern void rptp_get_sound_list(); extern void init_application(); #endif String *sound_names; int sound_count; String *queue_names; int queue_count; String *spool_names; int spool_count; static String empty_list[] = { "< No sounds >", NULL }; char *program_name; int return_code; /*****************************************************************************/ #ifdef __STDC__ void add_item(String new_item, String **list, int *items_count) #else void add_item(new_item, list, items_count) String new_item; String **list; int *items_count; #endif { if ((*list != NULL) && (*list != empty_list)) *list = (String *)realloc(*list, (*items_count + 1) * sizeof(String)); else { *items_count = 0; *list = (String *)malloc(sizeof(String)); } (*list)[*items_count] = (String)malloc((strlen(new_item) + 1) * sizeof(char)); strcpy((*list)[*items_count], new_item); (*items_count)++; } /*****************************************************************************/ #ifdef __STDC__ void delete_item(int list_index, String **list, int *items_count) #else void delete_item(list_index, list, items_count) int list_index; String **list; int *items_count; #endif { int i; free((*list)[list_index]); if (*items_count > 1) { for (i = list_index; i < *items_count - 1; i++) (*list)[i] = (*list)[i + 1]; *list = (String *)realloc(*list, (*items_count - 1) * sizeof(String)); } else { free(*list); *list = empty_list; *items_count = 0; } (*items_count)--; } /*****************************************************************************/ #ifdef __STDC__ void move_item(int old_index, int new_index, String **list) #else void move_item(old_index, new_index, list) int old_index; int new_index; String **list; #endif { int i; String tmp_s; tmp_s = (*list)[old_index]; if (new_index < old_index) { for (i = old_index; i > new_index; i--) (*list)[i] = (*list)[i - 1]; } else { for (i = old_index; i < new_index; i++) (*list)[i] = (*list)[i + 1]; } (*list)[new_index] = tmp_s; } /*****************************************************************************/ #ifdef __STDC__ void load_list(String file_name, String **list, int *items_count) #else void load_list(file_name, list, items_count) String file_name; String **list; int *items_count; #endif { FILE *list_file; char buffer[1024]; list_file = fopen(file_name, "r"); if (list_file == NULL) { /* !!! */ return; } *list = empty_list; while (fscanf(list_file, "%1023s", buffer) > 0) add_item(buffer, list, items_count); fclose(list_file); } /*****************************************************************************/ #ifdef __STDC__ void save_list(String file_name, String *list, int items_count) #else void save_list(file_name, list, items_count) String file_name; String *list; int items_count; #endif { FILE *list_file; int i; list_file = fopen(file_name, "w"); if (list_file == NULL) { /* !!! */ return; } for (i = 0; i < items_count; i++) fprintf(list_file, "%s\n", list[i]); fclose(list_file); } /*****************************************************************************/ #ifdef __STDC__ int alphacompare(char **i, char **j) #else int alphacompare(i, j) char **i; char **j; #endif { return strcmp(*i, *j); } /*****************************************************************************/ #ifdef __STDC__ void add_spool_item(String new_info, spool_info ***list, String **nlist, int *items_count) #else void add_spool_item(new_info, list, nlist, items_count) String new_info; spool_info ***list; String **nlist; int *items_count; #endif { spool_info *new_item; char state_buf[10]; char name_buf[1024]; int n; new_item = (spool_info *)malloc(sizeof(spool_info)); new_item->sid = atoi (1 + rptp_parse (new_info, "id")); new_item->vol = atoi (rptp_parse (NULL, "volume")); new_item->pri = atoi (rptp_parse (NULL, "priority")); new_item->count = atoi (rptp_parse (NULL, "count")); new_item->seconds = atoi (rptp_parse (NULL, "seconds")); new_item->remain = atoi (rptp_parse (NULL, "remain")); strcpy (new_item->host, rptp_parse (NULL, "host")); strcpy (state_buf, rptp_parse (NULL, "state")); strcpy (name_buf, rptp_parse (NULL, "sound")); if (!strcmp(state_buf, "play")) new_item->state = SPOOL_PLAY; else if (!strcmp(state_buf, "pause")) new_item->state = SPOOL_PAUSE; else if (!strcmp(state_buf, "(wait)")) new_item->state = SPOOL_WAIT; else new_item->state = SPOOL_UNKNOWN; new_item->sound = (char *)malloc((20 + strlen(name_buf)) * sizeof(char)); if ((new_item->seconds > 0) && (new_item->remain > 0)) sprintf(new_item->sound, "%6s %3d%% %s", state_buf, 100 - ((new_item->remain * 100) / new_item->seconds), name_buf); else sprintf(new_item->sound, "%6s 100%% %s", state_buf, name_buf); if (*list != NULL) *list = (spool_info **)realloc(*list, (*items_count + 1) * sizeof(spool_info *)); else { *items_count = 0; *list = (spool_info **)malloc(sizeof(spool_info *)); } (*list)[*items_count] = new_item; if ((*nlist != NULL) && (*nlist != empty_list)) *nlist = (String *)realloc(*nlist, (*items_count + 1) * sizeof(String)); else *nlist = (String *)malloc(sizeof(String)); (*nlist)[*items_count] = new_item->sound; (*items_count)++; } /*****************************************************************************/ #ifdef __STDC__ void free_spool_items(spool_info ***list, String **nlist, int *items_count) #else void free_spool_items(list, nlist, items_count) spool_info ***list; String **nlist; int *items_count; #endif { int i; for (i = 0; i < *items_count; i++) { free((*nlist)[i]); free((*list)[i]); } *list = NULL; *nlist = NULL; *items_count = 0; } /*****************************************************************************/ #ifdef __STDC__ void main(int argc, char *argv[]) #else void main(argc, argv) int argc; char *argv[]; #endif { if ((program_name = strrchr(argv[0], (int) '/')) == NULL) program_name = argv[0]; else program_name++; return_code = 0; sound_names = empty_list; spool_names = empty_list; queue_names = empty_list; init_application("XJukebox", argc, argv); rptp_connect(NULL); /* Connect to default rplay server */ rptp_get_sound_list(); XtAppMainLoop(app_context); } rplay-3.3.2/contrib/xjukebox-0.9/xjukebox.h100644 153 62 3225 6552756453 17153 0ustar boynsstaff#include #include #include #include #include #include #include #define XJUKEBOX_VERSION "0.9" #define MODE_IDLE 0 #define MODE_READING_SOUNDS 1 #define MODE_READING_SPOOL 2 #define MODE_DISCONNECTED 3 #define DIALOG_NONE 0 #define DIALOG_SET_NEW_HOST 1 #define DIALOG_LOAD_SOUND_FILE 2 #define DIALOG_SAVE_SOUND_FILE 3 #define DIALOG_GET_SOUND_DIR 4 #define DIALOG_LOAD_QUEUE_FILE 5 #define DIALOG_SAVE_QUEUE_FILE 6 #define NO_INTERVAL ((XtIntervalId) -1) #define SPOOL_UNKNOWN 0 #define SPOOL_PLAY 1 #define SPOOL_PAUSE 2 #define SPOOL_WAIT 3 typedef struct { int sid; /* Sound id (given by rplayd) */ char host[16]; /* Where did the play command come from ? */ int state; /* SPOOL_PLAY, SPOOL_PAUSE, SPOOL_WAIT, ... */ int vol; /* Volume */ int pri; /* Priority */ int count; /* Number of sounds */ int seconds; /* Duration */ int remain; /* Remaining time */ char *sound; /* File name */ } spool_info; typedef struct { char *sound; /* File name */ int size; /* Size (given by "find ...") */ int idx; /* Used for shuffling the sounds */ } queue_info; struct _resources_rec /* Most of these are not used yet. :-) */ { Boolean jukebox_shown; Boolean update_spool; int refresh_rate; Boolean show_hostname; Boolean show_volume; } resources; rplay-3.3.2/contrib/xjukebox-0.9/xjukebox.xpm100644 153 62 7043 6552756453 17532 0ustar boynsstaff/* XPM */ /* XJukebox icon by Raphael Quinet */ static char * xjukebox_xpm[] = { "48 64 8 1", " s mask c none", ". c #FFFFFFFF7F7F", "X c #0000FFFF0000", "o c #FFFF0000FFFF", "O c #0000FFFFFFFF", "+ c #FFFFFFFFFFFF", "@ c #7F7F7F7F7F7F", "# c #B3B3B3B3B3B3", " .......... ", " .................. ", " ...................... ", " ........XXXXXXXXXX........ ", " .......XXXXXXXXXXXXXXXX....... ", " .....XXXXXXooooooooooXXXXXX..... ", " ....XXXXXooooooooooooooooXXXXX.... ", " ....XXXXooooooOOOOOOOOooooooXXXX.... ", " ....XXXoooooOOOOOOOOOOOOOOoooooXXX.... ", " ....XXXooooOOOOOOOOOOOOOOOOOOooooXXX.... ", " ....XXooooOOOOOOOOOOOOOOOOOOOOOOooooXX.... ", " ...XXXoooOOOOOOOOOOOOOOOOOO+OOOOOoooXXX... ", " ...XXXoooOOOOOOOOOOOOOOOOOOOOO+OOOOoooXXX... ", " ...XXoooOOOOOOOOOOOOOOOOOOOOOOO+OOOOoooXX... ", " ...XXXooOOOOOOOOOOOOOOOOOOOOOO+OOOOOOOooXXX... ", " ...XXoooOOOOOOOOOOOOOOOOOOOOOOOOOO+OOOoooXX... ", " ...XXooOOOOOOOOOOOOOOOOOOOOOOOOO+OO+OOOooXX... ", "...XXoooOOOOOOOOOOOOOOOOOOOOOOOOOO+OOOOOoooXX...", "...XXoooOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOoooXX...", "...XXooOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOooXX...", "...XXooOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOooXX...", "...XXooOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOooXX...", "...XXooOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOooXX...", "...XXoo@@@############################@@@ooXX...", "...XXoo@@@############################@@@ooXX...", "...XXoo@@###+#+++#+#+++#+#+++#+#+++####@@ooXX...", "...XXoo@@##############################@@ooXX...", "...XXoo@@###+#+++#+#+++#+#+++#+#+++####@@ooXX...", "...XXoo@@##############################@@ooXX...", "...XXoo@####+#+++#+#+++#+#+++#+#+++#####@ooXX...", "...XXoo@################################@ooXX...", "...XXoo@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ooXX...", "...XXoo##################################ooXX...", "...XXoo##################################ooXX...", "...XXoo##################################ooXX...", "...XXoo##################################ooXX...", "...XXoo####@@@@@@@@@@@@@@@@@@@@@@@@@@####ooXX...", "...XXoo####@########################@####ooXX...", "...XXoo####@#@##################@#@#@####ooXX...", "...XXoo####@####################@###@####ooXX...", "...XXoo####@#################@#@@@##@####ooXX...", "...XXoo####@############@#@###@@####@####ooXX...", "...XXoo####@#############@@##@@@####@####ooXX...", "...XXoo####@#########@@###@@@@@#####@####ooXX...", "...XXoo####@##########@@###@@##@####@####ooXX...", "...XXoo####@###########@##@@###@####@####ooXX...", "...XXoo####@############@@@@########@####ooXX...", "...XXoo####@###########@@@##########@####ooXX...", "...XXoo####@##########@@#@##########@####ooXX...", "...XXoo####@####@####@@#############@####ooXX...", "...XXoo####@#####@##@@@#############@####ooXX...", "...XXoo####@#####@#@@@##############@####ooXX...", "...XXoo####@###@##@@@###############@####ooXX...", "...XXoo####@###@@#@@################@####ooXX...", "...XXoo####@@@@#@@@@################@####ooXX...", "...XXoo####@###@@@################@#@####ooXX...", "...XXoo####@#@###@################@#@####ooXX...", "...XXoo####@########################@####ooXX...", "...XXoo####@@@@@@@@@@@@@@@@@@@@@@@@@@####ooXX...", "...XXoo##################################ooXX...", "...XXoo##################################ooXX...", "...XXoo##################################ooXX...", "...XXoo##################################ooXX...", "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"}; rplay-3.3.2/contrib/xpilot/ 40755 153 62 0 6727650075 14215 5ustar boynsstaffrplay-3.3.2/contrib/xpilot/README100644 153 62 510 6552756453 15151 0ustar boynsstaff XPilot versions 2.0betaPL2 and up include rplay sound support and are available at ftp.cs.uit.no in the /pub/games/xpilot directory. You can also use ftp.x.org /contrib/games/multiplayer. Included in this directory are a few sample xpilot sound configuration files. sounds-3.1.0 contains new sound events for xpilot 3.1.0. rplay-3.3.2/contrib/xpilot/arnold_sounds100644 153 62 2523 6552756453 17114 0ustar boynsstaffstart destroy_yourselves.au fire_shot tap3.au fire_torpedo go.au fire_heat_shot go.au fire_smart_shot go.au player_explosion beback.au player_hit_player chilloutdickwad.au player_hit_cannon are_you_crazy.au player_hit_mine dontbullshitme.au player_eat_torpedo_shot trust.au player_eat_heat_shot bullshit2.au player_eat_smart_shot shit.au drop_mine no_shit.au player_hit_wall dickhead.au worm_hole arnold_laugh.au wideangle_shot_pickup uglymf.au sensor_pack_pickup howdy_stranger.au back_shot_pickup dontberidiculous.au smart_shot_pickup big_surprize.au cloaking_device_pickup whathellareyou.au energy_pack_pickup arnold_excellent.au mine_pack_pickup no_problemo.au refuel arnold_excellent.au thrust thrust.au cloak who_is_it_my_mother.au change_home get_out.au ecm_pickup mindfuck.au afterburner_pickup shove_real_hard.au tank_pickup amazing.au drop_moving_mine knock_knock.au mine_explosion adios_amigo.au ecm fuck_you_asshole.au tank_detach here_comes_hard_part.au cannon_fire tap3.au player_shot_themself i_need_vacation.au declare_war youbastards.au player_hit_cannonfire i_need_vacation.au object_explosion great.au player_eat_shot arrp.au transporter_pickup trust_me.au transporter_success give_to_me.au transporter_fail no_deal.au nuke_launch niceknowingyou.au nuke_explosion hasta_la_vista.au player_ran_over_player igiveup.au rplay-3.3.2/contrib/xpilot/ren+stimpy_sounds100644 153 62 2652 6552756453 17745 0ustar boynsstaffstart hurtle.au fire_shot tap3.au fire_torpedo danger.au fire_heat_shot alarm.au fire_smart_shot bling.au player_explosion bus_vaporize2.au player_hit_player boink.au player_hit_cannon you_broke_it2.au player_hit_mine yeeeeeee.au player_eat_torpedo_shot helmet_buzzer.au player_eat_heat_shot whats_the_idea.au player_eat_smart_shot yeowch2.au drop_mine ploop.au player_hit_wall ren-scream.au worm_hole evil_laugh.au wideangle_shot_pickup prize2.au sensor_pack_pickup im_sohappy.au back_shot_pickup whatsthis_stupid_thing.au smart_shot_pickup always_wanted.au cloaking_device_pickup what_are_you_up_to.au energy_pack_pickup ice_cream.au mine_pack_pickup poopie_time.au refuel ice_cream.au thrust thrust.au cloak foghorn.au change_home hey_what_are_you_doing.au ecm_pickup ohjoy.au afterburner_pickup speed.au tank_pickup feeling_any_better2.au drop_moving_mine spin.au mine_explosion bzzzt.au ecm buzzer.au tank_detach areyou_nuts.au cannon_fire tap3.au player_shot_themself ive_been_bad_ren.au declare_war gonna_do_to_you2.au player_hit_cannonfire idiot-2.au object_explosion bzzzt.au player_eat_shot small_bing.au transporter_pickup here_ren.au transporter_success givethat.au transporter_fail ohno_you_dont.au nuke_launch boathorn.au nuke_explosion pain_stop.au player_ran_over_player aargh.au laser molfart.au laser_pickup magic.au player_roasted ayaah.au player_eat_laser bats.au rplay-3.3.2/contrib/xpilot/sounds100644 153 62 2431 6552756453 15553 0ustar boynsstaffstart F_Troop.au fire_shot tap3.au fire_torpedo Missle1.au fire_heat_shot Missle1.au fire_smart_shot Missle1.au player_explosion Explosion.au player_hit_player boink2.au player_hit_cannon Explosion.au player_hit_mine Explosion.au player_eat_torpedo_shot ouch.au player_eat_heat_shot ouch.au player_eat_smart_shot ouch.au drop_mine ploop.au player_hit_wall Explosion.au worm_hole beep_laughing_warning.au wideangle_shot_pickup swish.au sensor_pack_pickup drum.au back_shot_pickup Teeswing.au smart_shot_pickup Whoosh.au cloaking_device_pickup dadan.au energy_pack_pickup JFS.au mine_pack_pickup beep_metal.au thrust thrust.au cloak squish.au change_home hey_what_are_you_doing.au ecm_pickup beep_arcade.au afterburner_pickup beep_pure_saw.au tank_pickup beep_multi.au drop_moving_mine spin.au mine_explosion Oomph.au ecm beep_bassoon_and_bone.au tank_detach beep_space_code.au cannon_fire tap3.au player_shot_themself MORON.au declare_war this_means_war.au player_hit_cannonfire MORON.au object_explosion drip.au player_eat_shot arrp.au transporter_pickup Missed.au transporter_success givethat.au transporter_fail ohno_you_dont.au nuke_launch boathorn.au nuke_explosion pain_stop.au fire_laser molfart.au laser_pickup magic.au player_roasted ayaah.au player_eat_laser bats.au rplay-3.3.2/contrib/xpilot/sounds-3.1.0100644 153 62 4223 6552756453 16211 0ustar boynsstaffstart F_Troop.au|destroy_yourselves.au|Barts_Paradox_Example.au|hurtle.au|shields-up.au fire_shot tap3.au fire_torpedo ST_torpedo.au fire_heat_shot ST_phaser.au fire_smart_shot Missle1.au player_explosion Explosion.au|bus_vaporize2.au|ren-scream.au player_hit_player boink2.au player_hit_cannon Explosion.au|ren-scream.au player_hit_mine Explosion.au|yeeeeeee.au player_eat_torpedo_shot ouch.au|Barney-Awww.au|Why_You_Little.au|yeowch2.au player_eat_heat_shot ouch.au|Barney-Awww.au|Why_You_Little.au|yeowch2.au player_eat_smart_shot ouch.au|Barney-Awww.au|Why_You_Little.au|yeowch2.au drop_mine ploop.au player_hit_wall Explosion.au|bus_vaporize2.au worm_hole beep_laughing_warning.au|evil_laugh.au wideangle_shot_pickup swish.au sensor_pack_pickup drum.au back_shot_pickup Teeswing.au smart_shot_pickup Whoosh.au cloaking_device_pickup dadan.au energy_pack_pickup JFS.au mine_pack_pickup beep_metal.au thrust thrust.au cloak squish.au change_home hey_what_are_you_doing.au ecm_pickup beep_arcade.au afterburner_pickup beep_pure_saw.au tank_pickup beep_multi.au drop_moving_mine spin.au mine_explosion Oomph.au ecm beep_bassoon_and_bone.au tank_detach beep_space_code.au cannon_fire tap3.au player_shot_themself Burns_Morons.au declare_war this_means_war.au|You_Sicken_Me.au|gonna_do_to_you2.au player_hit_cannonfire MORON.au|idiot-2.au object_explosion drip.au|bzzzt.au|blast1.au player_eat_shot arrp.au transporter_pickup Missed.au transporter_success givethat.au|sugar.au|give_to_me.au|Bring_Him_to_Me.au transporter_fail ohno_you_dont.au|no_deal.au|Greasy_Mitts.au nuke_launch boathorn.au|Time_of_Purification.au nuke_explosion pain_stop.au|hasta_la_vista.au fire_laser ST_laser.au laser_pickup magic.au player_roasted ayaah.au player_eat_laser bats.au|HandPhaser.au|ST_scream.au emergency_thrust_pickup st_energize.au autopilot_pickup beep_fm.au tractor_beam_pickup beep_kind_warning.au player_bounced oh_my_god.au autopilot_on oh_my_god.au autopilot_off oh_my_god.au tractor_beam beep_robotic.au connect_ball oh_my_god.au drop_ball oh_my_god.au destroy_target boom.au team_win whistle.au team_draw gong.au player_win whistle.au player_draw gong.au rplay-3.3.2/contrib/xpilot/sounds-simpsons100644 153 62 2437 6552756453 17432 0ustar boynsstaffstart Barts_Paradox_Example.au fire_shot tap3.au fire_torpedo Nelson_Laugh.au fire_heat_shot Maggie_Sucks.au fire_smart_shot Homer-He_Hee.au player_explosion homer_scream.au player_hit_player boink2.au player_hit_cannon Shock_Therapy_Screams.au player_hit_mine Abe-Ill_Be_Good.au player_eat_torpedo_shot Barney-Awww.au player_eat_heat_shot Call_My_Lawyers.au player_eat_smart_shot Why_You_Little.au drop_mine Bart_Snicker.au player_hit_wall dont_want_pity.au worm_hole krusty_laugh.au wideangle_shot_pickup ill_cheer.au sensor_pack_pickup Barney-Wow.au back_shot_pickup Bart-Cooool.au smart_shot_pickup Time_of_Purification.au cloaking_device_pickup Absitively_Posolutely.au energy_pack_pickup Homer-Wohoo.au mine_pack_pickup Barney_Belch.au thrust thrust.au cloak Who_the_Hell_are_You.au change_home USA_USA.au ecm_pickup Homer_Laugh.au afterburner_pickup Mmmm_Burger.au tank_pickup Selma-Oh_Yeah.au drop_moving_mine Youre_Funny.au mine_explosion oh_yeah.au ecm Go_to_Hell.au tank_detach ive_coughed_up.au cannon_fire tap3.au player_shot_themself Burns_Morons.au declare_war You_Sicken_Me.au player_hit_cannonfire Aye_Carumba.au object_explosion drip.au player_eat_shot Doh1.au transporter_pickup Otto-Allright.au transporter_fail Greasy_Mitts.au transporter_success Bring_Him_to_Me.au rplay-3.3.2/contrib/xpilot/st_sounds100644 153 62 2634 6552756453 16266 0ustar boynsstaffstart ST_prepare_to_attack.au fire_shot tap3.au fire_torpedo ST_torpedo.au fire_heat_shot ST_phaser.au fire_smart_shot ST_phaser.au player_explosion dead.au player_hit_player vulcan_mind.au player_hit_cannon ST_explosion.au player_hit_mine ST_explosion.au player_eat_torpedo_shot ST_deflector_shields.au player_eat_heat_shot ST_deflector_shields.au player_eat_smart_shot ST_deflector_shields.au drop_mine the_ping.au player_hit_wall ST_explosion.au worm_hole ST_molecules.au wideangle_shot_pickup fascinating.au sensor_pack_pickup ST_there_he_is.au back_shot_pickup ST_main_screen.au smart_shot_pickup ST_mercy.au cloaking_device_pickup ST_tribble.au energy_pack_pickup st_energize.au mine_pack_pickup communicator.au thrust ST_move.au cloak kirk1.au change_home ST_alert.au ecm_pickup kirk_damn.au afterburner_pickup intercom.au tank_pickup kirk4.au drop_moving_mine ST_klaxon.au mine_explosion ST_explosion.au ecm ST_buttons.au tank_detach enterprise.au cannon_fire tap3.au #player_shot_themself MORON.au declare_war ST_up_your_shaft.au player_hit_cannonfire sickbay_2_kirk.au object_explosion ST_explosion.au player_eat_shot ST_comm.au transporter_pickup ST_warp.au transporter_fail kirk2.au transporter_success kirk_nowin.au nuke_launch ST_khan.au nuke_explosion dying.au fire_laser ST_laser.au player_eat_laser ST_scream.au player_roasted sickbay_2_kirk.au laser_pickup ST_food_syth.au rplay-3.3.2/contrib/xpilot/sttng_sounds100644 153 62 3417 6552756453 16777 0ustar boynsstaffplayer_ran_over_player bustedup.au|not-a-merry-man.au player_roasted mayday.au afterburner_pickup hfreqsnd.au back_shot_pickup get-lucky.au cannon_fire tap3.au change_home under-control.au cloak classified-matter.au|no-signs.au cloaking_device_pickup pwrup.au declare_war everyone-dies.au drop_mine activate.au drop_moving_mine bluealrt.au ecm comp2.au|freeze_program.au|telling_me_what_courseto_set.au ecm_pickup comp10.au energy_pack_pickup comp11.au fire_heat_shot fire.au fire_laser jlpfire.au fire_shot button.au fire_smart_shot danger.au|danger_tone3.au|hurt-a-bit.au|photons1.au fire_torpedo comp12.au|kill-him.au|rapid_fire_allweapons.au laser_pickup chanopen.au mine_explosion ST_explosion.au mine_pack_pickup iconia1.au nuke_explosion resistance_is_futile.au nuke_launch fire-phasers.au|iconia1.au object_explosion phasers1.au player_eat_heat_shot funny.au player_eat_laser HandPhaser.au player_eat_shot ST_comm.au player_eat_smart_shot ST_deflector_shields.au player_eat_torpedo_shot impossible.au player_explosion blast1.au player_hit_cannon feltlike.au player_hit_cannonfire turblift.au player_hit_mine wes-happen.au player_hit_player launsnd.au player_hit_wall halt.au player_shot_themself intelligence_at_workhere.au|nobodys-perfect.au sensor_pack_pickup identify.au|remove-my-ears.au|see-so-much-more.au smart_shot_pickup engage.au|well-done.au start Worf_Vessle.au|peace-and-long-life.au|shields-up.au|welcome-to-24.au|welcome-to-romulus.au tank_detach idontpla.au|relhim.au tank_pickup comp2-7.au|lockcomp.au thrust stb_short.au transporter_fail comp3.au|request-denied.au|trickus.au transporter_pickup comp15.au|shutbay2.au transporter_success beamin2.au|compthng.au|xptr3 wideangle_shot_pickup got-something.au worm_hole flyby.au|universe.au rplay-3.3.2/devrplay/ 40755 153 62 0 6727650076 13065 5ustar boynsstaffrplay-3.3.2/devrplay/Makefile.in100644 153 62 2070 6675577056 15236 0ustar boynsstaffinclude @RPLAY_TOP@/Makefile.config srcdir = @srcdir@ VPATH = @srcdir@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ MKINSTALLDIRS= @srcdir@/../mkinstalldirs CPPFLAGS= $(CC_OPTIONS) -fPIC -I. -I../include -I@srcdir@/../include @DEFS@ .c.o: $(CC) -c $(CPPFLAGS) $(CFLAGS) $< LDFLAGS= $(LD_OPTIONS) -shared @LDFLAGS@ @LIBS@ -L../librplay -lrplay -ldl TARGET= devrplay.so SRCS= devrplay.c OBJS= devrplay.o all: $(TARGET) #$(TARGET): $(OBJS) ../librplay/librplay.so # $(CC) -o $@ $(OBJS) ../librplay/rplay.lo ../librplay/rptp.lo $(LDFLAGS) $(TARGET): $(OBJS) ../librplay/librplay.so $(CC) -o $@ $(OBJS) $(LDFLAGS) ../librplay/librplay.so: (cd ../librplay; $(MAKE) $(MFLAGS) librplay.so) install: all $(MKINSTALLDIRS) $(libdir) $(INSTALL_DATA) $(TARGET) $(libdir) uninstall: $(RM) $(libdir)/$(TARGET) clean: $(RM) $(OBJS) $(TARGET) a.out core *~ *.bak *.orig TAGS distclean: clean $(RM) Makefile tags: $(TAGS) *.[ch] TAGS: tags etags: tags depend: $(MAKEDEPEND) -- $(CPPFLAGS) $(CFLAGS) -- $(SRCS) rplay-3.3.2/devrplay/devrplay.c100644 153 62 13271 6675040400 15162 0ustar boynsstaff/* $Id: devrplay.c,v 1.4 1999/03/21 00:44:48 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /* * based on esddsp.c * Copyright (C) 1998, 1999 Manish Singh */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include "rplay.h" #define DEVRPLAY_SOUND "devrplay" #ifdef linux #include #include #define REAL_LIBC RTLD_NEXT static int rplay_fd = -1; static int spool_id = -1; static int dsp_fmt; static int dsp_speed; static int dsp_channels; static int dsp_speed; static int dsp_blksize; static int streaming; static char * getsound() { char *p = getenv("DEVRPLAY_SOUND"); return p ? p : DEVRPLAY_SOUND; } static char * getinfo() { char *p = getenv("DEVRPLAY_INFO"); return p ? p : 0; } static char * getopts() { char *p = getenv("DEVRPLAY_OPTS"); return p ? p : 0; } int open(const char *pathname, int flags,...) { static int (*func)(const char *, int, mode_t) = NULL; va_list args; mode_t mode; char response[RPTP_MAX_LINE]; if (!func) func = (int (*)(const char *, int, mode_t)) dlsym(REAL_LIBC, "open"); va_start(args, flags); mode = va_arg(args, mode_t); va_end(args); if (strcmp(pathname, "/dev/dsp") == 0) { rplay_fd = rptp_open(rplay_default_host(), RPTP_PORT, response, sizeof(response)); if (rplay_fd < 0) { rptp_perror(rplay_default_host()); } return rplay_fd; } else { return (*func)(pathname, flags, mode); } } static int dspctl(int fd, int request, void *argp) { int *arg = (int *) argp; switch (request) { case SNDCTL_DSP_SETFMT: dsp_fmt = *arg; break; case SNDCTL_DSP_SPEED: dsp_speed = *arg; break; case SNDCTL_DSP_STEREO: dsp_channels = *arg ? 2 : 1; break; case SNDCTL_DSP_CHANNELS: dsp_channels = *arg; break; case SNDCTL_DSP_GETBLKSIZE: *arg = 65535; break; case SNDCTL_DSP_GETFMTS: *arg = 0x38; break; case SNDCTL_DSP_GETCAPS: *arg = 0; break; case SNDCTL_DSP_GETOSPACE: { audio_buf_info *info = (audio_buf_info *) argp; info->fragments = 16; info->fragstotal = 16; info->fragsize = 4096; info->bytes = 44100; } break; default: break; } if (spool_id == -1 && dsp_fmt && dsp_speed && dsp_channels) { char response[RPTP_MAX_LINE]; streaming = 1; rptp_putline(rplay_fd, "play input=flow input-info=%s,%d,%d,%d,%s %s sound=\"%s\"", dsp_fmt == 16 ? "linear16" : "ulinear8", dsp_speed, dsp_fmt, dsp_channels, "little-endian", getopts(), getsound()); rptp_getline(rplay_fd, response, sizeof(response)); spool_id = atoi(1 + rptp_parse(response, "id")); rptp_putline(rplay_fd, "put id=#%d size=0", spool_id); rptp_getline(rplay_fd, response, sizeof(response)); } return 0; } int ioctl(int fd, int request,...) { static int (*func)(int, int, void *) = NULL; va_list args; void *argp; if (!func) func = (int (*)(int, int, void *)) dlsym(REAL_LIBC, "ioctl"); va_start(args, request); argp = va_arg(args, void *); va_end(args); if (fd != rplay_fd) { return (*func)(fd, request, argp); } else if (fd == rplay_fd) { return dspctl(fd, request, argp); } } ssize_t write(int fd, const void *buf, size_t count) { static int (*func)(int, const void *, size_t) = NULL; if (!func) func = (int (*)(int, const void *, size_t)) dlsym(REAL_LIBC, "write"); if (fd == rplay_fd && !streaming) { char info[64]; char response[RPTP_MAX_LINE]; info[0] = '\0'; /* use dsp defaults if something was specified */ if (dsp_speed || dsp_fmt || dsp_channels) { if (!dsp_speed) dsp_speed = 8000; if (!dsp_fmt) dsp_fmt = 8; if (!dsp_channels) dsp_channels = 1; sprintf(info, "input-info=%s,%d,%d,%d,%s", dsp_fmt == 16 ? "linear16" : "ulinear8", dsp_speed, dsp_fmt, dsp_channels, "little-endian"); } /* try user specified sound info */ else if (getinfo()) { strncpy(info, getinfo(), sizeof(info)-1); } /* otherwise let rplayd figure out the format using the sound header and/or name. */ streaming = 1; rptp_putline(rplay_fd, "play input=flow %s sound=\"%s\"", info, getsound()); rptp_getline(rplay_fd, response, sizeof(response)); spool_id = atoi(1 + rptp_parse(response, "id")); rptp_putline(rplay_fd, "put id=#%d size=0", spool_id); rptp_getline(rplay_fd, response, sizeof(response)); } return (*func)(fd, buf, count); } int close(int fd) { static int (*func)(int) = NULL; if (!func) func = (int (*)(int)) dlsym(REAL_LIBC, "close"); if (fd == rplay_fd) { rplay_fd = -1; spool_id = -1; streaming = 0; dsp_fmt = dsp_speed = dsp_channels = dsp_speed = dsp_blksize = 0; } return (*func)(fd); } #endif /* linux */ rplay-3.3.2/etc/ 40755 153 62 0 6727650076 12012 5ustar boynsstaffrplay-3.3.2/etc/rplay.conf100644 153 62 120 6552756453 14060 0ustar boynsstaff# Sample rplay.conf # # put pointers to sounds files here # /opt/sounds/doh.wav rplay-3.3.2/etc/rplay.helpers100644 153 62 570 6610424105 14563 0ustar boynsstaff# Sample rplay.helpers # # # ## MPEG \.mp[1-3]$ linear16,44100,16,2,little-endian /usr/bin/mpg123 --stdout --quiet --rate 44100 --stereo - ## MODS #\.\(669\|alm\|amd\|far\|mod\|mtm\|okt\|ptm\|rad\|s3m\|stm\|wow\|xm\)$ linear16,44100,16,2,little-endian /usr/local/bin/xmp --stereo --little-endian -b 16 -f 44100 --stdout --nocmd /dev/fd/0 rplay-3.3.2/etc/rplay.hosts100644 153 62 237 6552756453 14304 0ustar boynsstaff# Sample rplay.hosts # # this file describes what machines can read from or write to this server # *:rwx # would allow anyone to read or write to this server. rplay-3.3.2/etc/rplay.servers100644 153 62 244 6552756453 14633 0ustar boynsstaff# Sounds rplay.servers # # you can use this file to have rplayd retrieve sounds from a remote # server simply list the hostnames here. # soundserver.some_where.com rplay-3.3.2/examples/ 40755 153 62 0 6727650076 13055 5ustar boynsstaffrplay-3.3.2/examples/async1.c100644 153 62 1615 6621134137 14503 0ustar boynsstaff/* $Id: async1.c,v 1.3 1998/11/07 21:15:11 boyns Exp $ */ #include static void event_callback(int fd, int event, char *line); main(int argc, char **argv) { char buf[RPTP_MAX_LINE]; int fd; fd = rptp_open(rplay_default_host(), RPTP_PORT, buf, sizeof(buf)); rptp_async_notify(fd, RPTP_EVENT_PLAY | RPTP_EVENT_PAUSE | RPTP_EVENT_DONE | RPTP_EVENT_CONTINUE, event_callback); rptp_main_loop(); exit(0); } static void event_callback(int fd, int event, char *line) { switch (event) { case RPTP_EVENT_PLAY: printf("%s is playing\n", rptp_parse(line, "sound")); break; case RPTP_EVENT_PAUSE: printf("%s is paused\n", rptp_parse(line, "sound")); break; case RPTP_EVENT_DONE: printf("%s is done\n", rptp_parse(line, "sound")); break; case RPTP_EVENT_CONTINUE: printf("%s continue\n", rptp_parse(line, "sound")); break; } } rplay-3.3.2/examples/async2.c100644 153 62 2547 6621134140 14503 0ustar boynsstaff/* $Id: async2.c,v 1.3 1998/11/07 21:15:12 boyns Exp $ */ #include #include static void process_input(int fd); static void event_callback(int fd, int event, char *line); static int rptp_fd; main(int argc, char **argv) { char buf[RPTP_MAX_LINE]; rptp_fd = rptp_open(rplay_default_host(), RPTP_PORT, buf, sizeof(buf)); rptp_async_register(0, RPTP_ASYNC_READ, process_input); rptp_async_notify(rptp_fd, RPTP_EVENT_ALL, event_callback); rptp_main_loop(); exit(0); } static void process_input(int fd) { char buf[BUFSIZ]; fgets(buf, sizeof(buf), stdin); buf[strlen(buf) - 1] = '\0'; rptp_async_putline(rptp_fd, NULL, buf); } static void event_callback(int fd, int event, char *line) { rptp_parse(line, 0); switch (event) { case RPTP_EVENT_OK: break; case RPTP_EVENT_ERROR: printf("Error: %s\n", rptp_parse(0, "error")); break; case RPTP_EVENT_PLAY: printf("[%s] Play %s\n", rptp_parse(0, "id"), rptp_parse(0, "sound")); break; case RPTP_EVENT_PAUSE: printf("[%s] Pause %s\n", rptp_parse(0, "id"), rptp_parse(0, "sound")); break; case RPTP_EVENT_DONE: printf("[%s] Done %s\n", rptp_parse(0, "id"), rptp_parse(0, "sound")); break; case RPTP_EVENT_CONTINUE: printf("[%s] Continue %s\n", rptp_parse(0, "id"), rptp_parse(0, "sound")); break; } } rplay-3.3.2/examples/flow1.c100644 153 62 4301 6621134140 14322 0ustar boynsstaff/* $Id: flow1.c,v 1.3 1998/11/07 21:15:12 boyns Exp $ */ /* usage: flow1 soundfile */ #include #include #include #include main(int argc, char **argv) { FILE *fp; int rptp_fd, size, n, nwritten; struct stat st; char *id; char line[RPTP_MAX_LINE]; char response[RPTP_MAX_LINE]; char buf[8000]; /* First determine how big the audio file is. */ if (stat(argv[1], &st) < 0) { perror(argv[1]); exit(1); } size = st.st_size; fp = fopen(argv[1], "r"); if (fp == NULL) { perror(argv[1]); exit(1); } /* Connect to the audio server. */ rptp_fd = rptp_open(rplay_default_host(), RPTP_PORT, response, sizeof(response)); if (rptp_fd < 0) { rptp_perror(rplay_default_host()); exit(1); } /* Start the flow using `input-storage=none'. */ sprintf(line, "play input=flow input-storage=none sound=%s", argv[1]); switch (rptp_command(rptp_fd, line, response, sizeof(response))) { case -1: rptp_perror(argv[0]); exit(1); case 1: fprintf(stderr, "%s\n", rptp_parse(response, "error")); exit(1); case 0: break; } /* Save the spool id so `put' can use it later. */ id = rptp_parse(response, "id"); /* Read chunks of audio from the file and send them to rplayd. rplayd will deal with flow-control. */ while (size > 0) { n = fread(buf, 1, sizeof(buf), fp); /* Use `put' to send the audio data. */ sprintf(line, "put id=%s size=%d", id, n); switch (rptp_command(rptp_fd, line, response, sizeof(response))) { case -1: rptp_perror(argv[0]); exit(1); case 1: fprintf(stderr, "%s\n", rptp_parse(response, "error")); exit(1); case 0: break; } nwritten = rptp_write(rptp_fd, buf, n); if (nwritten != n) { rptp_perror("flow"); break; } size -= nwritten; } fclose(fp); /* Always send `done' when the flow is over. */ sprintf(line, "done id=%s", id); switch (rptp_command(rptp_fd, line, response, sizeof(response))) { case -1: rptp_perror(argv[0]); exit(1); case 1: fprintf(stderr, "%s\n", rptp_parse(response, "error")); exit(1); case 0: break; } exit(0); } rplay-3.3.2/examples/level.c100644 153 62 1226 6621134140 14404 0ustar boynsstaff#include static void event_callback(int fd, int event, char *line); main(int argc, char **argv) { char buf[RPTP_MAX_LINE]; int fd; fd = rptp_open(rplay_default_host(), RPTP_PORT, buf, sizeof(buf)); rptp_async_notify(fd, RPTP_EVENT_LEVEL | RPTP_EVENT_CLOSE, event_callback); rptp_main_loop(); exit(0); } static void event_callback(int fd, int event, char *line) { static int i; int left, right; switch (event) { case RPTP_EVENT_LEVEL: left = atoi(rptp_parse(line, "left")); right = atoi(rptp_parse(0, "right")); printf("%3d %3d\n", left, right); break; case RPTP_EVENT_CLOSE: exit(0); } } rplay-3.3.2/gsm/ 40755 153 62 0 6727650077 12026 5ustar boynsstaffrplay-3.3.2/gsm/COPYRIGHT100644 153 62 1262 6552756454 13421 0ustar boynsstaffCopyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, Technische Universitaet Berlin Any use of this software is permitted provided that this notice is not removed and that neither the authors nor the Technische Universitaet Berlin are deemed to have made any representations as to the suitability of this software for any purpose nor are held responsible for any defects of this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. As a matter of courtesy, the authors request to be informed about uses this software has found, about bugs in this software, and about any improvements that may be of general interest. Berlin, 28.11.1994 Jutta Degener Carsten Bormann rplay-3.3.2/gsm/INSTALL100644 153 62 6107 6552756454 13162 0ustar boynsstaffHow to get started: Edit the Makefile. You should configure a few machine-dependencies and what compiler you want to use. The code works both with ANSI and K&R-C. Use -DNeedFunctionPrototypes to compile with, or -UNeedFunctionPrototypes to compile without, function prototypes in the header files. Make addtst The "add" program that will be compiled and run checks whether the basic math functions of the gsm library work with your compiler. If it prints anything to stderr, complain (to us). Edit inc/config.h. Make Local versions of the gsm library and the "compress"-like filters toast, untoast and tcat will be generated. If the compilation aborts because of a missing function, declaration, or header file, see if there's something in inc/config.h to work around it. If not, complain. Try it Grab an audio file from somewhere (raw u-law or Sun .au is fine, linear 16-bit in host byte order will do), copy it, toast it, untoast it, and listen to the result. The GSM-encoded and -decoded audio should have the quality of a good phone line. If the resulting audio is noisier than your original, or if you hear compression artifacts, complain; that's a bug in our software, not a bug in the GSM encoding standard itself. Installation You can install the gsm library interface, or the toast binaries, or both. Edit the Makefile Fill in the directories where you want to install the library, header files, manual pages, and binaries. Turn off the installation of one half of the distribution (i.e., gsm library or toast binaries) by not setting the corresponding directory root Makefile macro. make install will install the programs "toast" with two links named "tcat" and "untoast", and the gsm library "libgsm.a" with a "gsm.h" header file, and their respective manual pages. Optimizing This code was developed on a machine without an integer multiplication instruction, where we obtained the fastest result by replacing some of the integer multiplications with floating point multiplications. If your machine does multiply integers fast enough, leave USE_FLOAT_MUL undefined. The results should be the same in both cases. On machines with fast floating point arithmetic, defining both USE_FLOAT_MUL and FAST makes a run-time library option available that will (in a few crucial places) use ``native'' floating point operations rather than the bit-by-bit defined ones of the GSM standard. If you use this fast option, the outcome will not be bitwise identical to the results prescribed by the standard, but it is compatible with the standard encoding, and a user is unlikely to notice a difference. Bug Reports Please direct bug reports, questions, and comments to jutta@cs.tu-berlin.de and cabo@informatik.uni-bremen.de. Good luck, Jutta Degener, Carsten Bormann -- Copyright 1992, 1993, 1994, by Jutta Degener and Carsten Bormann, Technische Universitaet Berlin. See the accompanying file "COPYRIGHT" for details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. rplay-3.3.2/gsm/MACHINES100644 153 62 670 6552756454 13222 0ustar boynsstaffThe gsm library has been tested successfully on the following platforms: - Various Sun4's running SunOS 4.1.2 - SPARC1 (SunOS 4.1.1) - Integrated Solutions 68k Optimum running 4.3BSD UNIX with a Green Hills cc - NeXTstation running NeXT-OS/Mach 3.0 - No-name AT/386 with Xenix 2.3.2 (using -DSTUPID_COMPILER) - RS/6000-350 running AIX 3.2.0 - RS/6000-320 running AIX 3.1.5 - Alliant FX80 (Concentrix 5.7) - SGI Indigo XS4000 (IRIX 4.0.5F) rplay-3.3.2/gsm/Makefile.in100644 153 62 2724 6552756453 14176 0ustar boynsstaffinclude @RPLAY_TOP@/Makefile.config srcdir = @srcdir@ VPATH = @srcdir@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ SASR = -DSASR MULHACK = -DUSE_FLOAT_MUL FAST = -DFAST #LTP_CUT = -DLTP_CUT LTP_CUT = CPPFLAGS= $(CC_OPTIONS) -I. -I../include -I@srcdir@ -I@srcdir@/../include -I@srcdir@/../lib @DEFS@ .c.o: $(CC) -c $(CPPFLAGS) $(SASR) $(DEBUG) $(MULHACK) $(FAST) $(LTP_CUT) $(CFLAGS) $< LDFLAGS= $(LD_OPTIONS) -L. -lgsm @LDFLAGS@ TARGET= libgsm.a SRCS= add.c code.c debug.c decode.c gsm_create.c gsm_decode.c \ gsm_destroy.c gsm_encode.c gsm_explode.c gsm_implode.c gsm_option.c \ gsm_print.c long_term.c lpc.c preprocess.c rpe.c short_term.c table.c OBJS= add.o code.o debug.o decode.o gsm_create.o gsm_decode.o \ gsm_destroy.o gsm_encode.o gsm_explode.o gsm_implode.o gsm_option.o \ gsm_print.o long_term.o lpc.o preprocess.o rpe.o short_term.o table.o TOAST= toast TOAST_SRCS= toast.c toast_alaw.c toast_audio.c toast_lin.c toast_ulaw.c TOAST_OBJS= toast.o toast_alaw.o toast_audio.o toast_lin.o toast_ulaw.o all: $(TARGET) $(TOAST) $(TARGET): $(OBJS) $(AR) rcv $@ $? $(RANLIB) $@ $(TOAST): $(TARGET) $(TOAST_OBJS) $(CC) -o $@ $(TOAST_OBJS) $(LDFLAGS) install: uninstall: clean: $(RM) $(OBJS) $(TARGET) $(TOAST_OBJS) $(TOAST) a.out core *~ *.bak *.orig TAGS distclean: clean $(RM) Makefile tags: $(TAGS) *.[ch] TAGS: tags etags: tags depend: $(MAKEDEPEND) -- $(CPPFLAGS) $(CFLAGS) -- $(SRCS) rplay-3.3.2/gsm/README100644 153 62 3207 6552756454 13007 0ustar boynsstaff GSM 06.10 13 kbit/s RPE/LTP speech compression available -------------------------------------------------------- The Communications and Operating Systems Research Group (KBS) at the Technische Universitaet Berlin is currently working on a set of UNIX-based tools for computer-mediated telecooperation that will be made freely available. As part of this effort we are publishing an implementation of the European GSM 06.10 provisional standard for full-rate speech transcoding, prI-ETS 300 036, which uses RPE/LTP (residual pulse excitation/long term prediction) coding at 13 kbit/s. GSM 06.10 compresses frames of 160 13-bit samples (8 kHz sampling rate, i.e. a frame rate of 50 Hz) into 260 bits; for compatibility with typical UNIX applications, our implementation turns frames of 160 16-bit linear samples into 33-byte frames (1650 Bytes/s). The quality of the algorithm is good enough for reliable speaker recognition; even music often survives transcoding in recognizable form (given the bandwidth limitations of 8 kHz sampling rate). The interfaces offered are a front end modelled after compress(1), and a library API. Compression and decompression run faster than realtime on most SPARCstations. The implementation has been verified against the ETSI standard test patterns. Jutta Degener (jutta@cs.tu-berlin.de) Carsten Bormann (cabo@cs.tu-berlin.de) Communications and Operating Systems Research Group, TU Berlin Fax: +49.30.31425156, Phone: +49.30.31424315 -- Copyright 1992 by Jutta Degener and Carsten Bormann, Technische Universitaet Berlin. See the accompanying file "COPYRIGHT" for details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. rplay-3.3.2/gsm/README.rplay100644 153 62 1115 6552756454 14131 0ustar boynsstaff WARNING: This directory contains a *partial* GSM 1.0.7 distribution. Several files and directories have been (re)moved to save space and make compilation easier. The Makefile has been re-written to suit the needs of RPlay. The original config.h as been replaced by ../include/config.h. GSM is Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, Technische Universitaet Berlin. Please see the COPYRIGHT file for more details. The complete GSM distribution is available at: host ftp.cs.tu-berlin.de directory /pub/local/kbs/tubmik/gsm/ file gsm-1.0.7.tar.gz rplay-3.3.2/gsm/add.c100644 153 62 12644 6552756453 13047 0ustar boynsstaff/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /usr/local/cvsroot/rplay/gsm/add.c,v 1.1.1.1 1998/07/14 22:35:23 mrb Exp $ */ /* * See private.h for the more commonly used macro versions. */ #include #include #include "private.h" #include "gsm.h" #include "proto.h" #define saturate(x) \ ((x) < MIN_WORD ? MIN_WORD : (x) > MAX_WORD ? MAX_WORD: (x)) word gsm_add P2((a,b), word a, word b) { longword sum = (longword)a + (longword)b; return saturate(sum); } word gsm_sub P2((a,b), word a, word b) { longword diff = (longword)a - (longword)b; return saturate(diff); } word gsm_mult P2((a,b), word a, word b) { if (a == MIN_WORD && b == MIN_WORD) return MAX_WORD; else return SASR( (longword)a * (longword)b, 15 ); } word gsm_mult_r P2((a,b), word a, word b) { if (b == MIN_WORD && a == MIN_WORD) return MAX_WORD; else { longword prod = (longword)a * (longword)b + 16384; prod >>= 15; return prod & 0xFFFF; } } word gsm_abs P1((a), word a) { return a < 0 ? (a == MIN_WORD ? MAX_WORD : -a) : a; } longword gsm_L_mult P2((a,b),word a, word b) { assert( a != MIN_WORD || b != MIN_WORD ); return ((longword)a * (longword)b) << 1; } longword gsm_L_add P2((a,b), longword a, longword b) { if (a < 0) { if (b >= 0) return a + b; else { ulongword A = (ulongword)-(a + 1) + (ulongword)-(b + 1); return A >= MAX_LONGWORD ? MIN_LONGWORD :-(longword)A-2; } } else if (b <= 0) return a + b; else { ulongword A = (ulongword)a + (ulongword)b; return A > MAX_LONGWORD ? MAX_LONGWORD : A; } } longword gsm_L_sub P2((a,b), longword a, longword b) { if (a >= 0) { if (b >= 0) return a - b; else { /* a>=0, b<0 */ ulongword A = (ulongword)a + -(b + 1); return A >= MAX_LONGWORD ? MAX_LONGWORD : (A + 1); } } else if (b <= 0) return a - b; else { /* a<0, b>0 */ ulongword A = (ulongword)-(a + 1) + b; return A >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)A - 1; } } static unsigned char bitoff[ 256 ] = { 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; word gsm_norm P1((a), longword a ) /* * the number of left shifts needed to normalize the 32 bit * variable L_var1 for positive values on the interval * * with minimum of * minimum of 1073741824 (01000000000000000000000000000000) and * maximum of 2147483647 (01111111111111111111111111111111) * * * and for negative values on the interval with * minimum of -2147483648 (-10000000000000000000000000000000) and * maximum of -1073741824 ( -1000000000000000000000000000000). * * in order to normalize the result, the following * operation must be done: L_norm_var1 = L_var1 << norm( L_var1 ); * * (That's 'ffs', only from the left, not the right..) */ { assert(a != 0); if (a < 0) { if (a <= -1073741824) return 0; a = ~a; } return a & 0xffff0000 ? ( a & 0xff000000 ? -1 + bitoff[ 0xFF & (a >> 24) ] : 7 + bitoff[ 0xFF & (a >> 16) ] ) : ( a & 0xff00 ? 15 + bitoff[ 0xFF & (a >> 8) ] : 23 + bitoff[ 0xFF & a ] ); } longword gsm_L_asl P2((a,n), longword a, int n) { if (n >= 32) return 0; if (n <= -32) return -(a < 0); if (n < 0) return gsm_L_asr(a, -n); return a << n; } word gsm_asl P2((a,n), word a, int n) { if (n >= 16) return 0; if (n <= -16) return -(a < 0); if (n < 0) return gsm_asr(a, -n); return a << n; } longword gsm_L_asr P2((a,n), longword a, int n) { if (n >= 32) return -(a < 0); if (n <= -32) return 0; if (n < 0) return a << -n; # ifdef SASR return a >> n; # else if (a >= 0) return a >> n; else return -(longword)( -(ulongword)a >> n ); # endif } word gsm_asr P2((a,n), word a, int n) { if (n >= 16) return -(a < 0); if (n <= -16) return 0; if (n < 0) return a << -n; # ifdef SASR return a >> n; # else if (a >= 0) return a >> n; else return -(word)( -(uword)a >> n ); # endif } /* * (From p. 46, end of section 4.2.5) * * NOTE: The following lines gives [sic] one correct implementation * of the div(num, denum) arithmetic operation. Compute div * which is the integer division of num by denum: with denum * >= num > 0 */ word gsm_div P2((num,denum), word num, word denum) { longword L_num = num; longword L_denum = denum; word div = 0; int k = 15; /* The parameter num sometimes becomes zero. * Although this is explicitly guarded against in 4.2.5, * we assume that the result should then be zero as well. */ /* assert(num != 0); */ assert(num >= 0 && denum >= num); if (num == 0) return 0; while (k--) { div <<= 1; L_num <<= 1; if (L_num >= L_denum) { L_num -= L_denum; div++; } } return div; } rplay-3.3.2/gsm/code.c100644 153 62 4761 6552756453 13212 0ustar boynsstaff/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /usr/local/cvsroot/rplay/gsm/code.c,v 1.1.1.1 1998/07/14 22:35:23 mrb Exp $ */ #include "config.h" #ifdef HAS_STDLIB_H #include #else # include "proto.h" extern char * memcpy P((char *, char *, int)); #endif #include "private.h" #include "gsm.h" #include "proto.h" /* * 4.2 FIXED POINT IMPLEMENTATION OF THE RPE-LTP CODER */ void Gsm_Coder P8((S,s,LARc,Nc,bc,Mc,xmaxc,xMc), struct gsm_state * S, word * s, /* [0..159] samples IN */ /* * The RPE-LTD coder works on a frame by frame basis. The length of * the frame is equal to 160 samples. Some computations are done * once per frame to produce at the output of the coder the * LARc[1..8] parameters which are the coded LAR coefficients and * also to realize the inverse filtering operation for the entire * frame (160 samples of signal d[0..159]). These parts produce at * the output of the coder: */ word * LARc, /* [0..7] LAR coefficients OUT */ /* * Procedure 4.2.11 to 4.2.18 are to be executed four times per * frame. That means once for each sub-segment RPE-LTP analysis of * 40 samples. These parts produce at the output of the coder: */ word * Nc, /* [0..3] LTP lag OUT */ word * bc, /* [0..3] coded LTP gain OUT */ word * Mc, /* [0..3] RPE grid selection OUT */ word * xmaxc,/* [0..3] Coded maximum amplitude OUT */ word * xMc /* [13*4] normalized RPE samples OUT */ ) { int k; word * dp = S->dp0 + 120; /* [ -120...-1 ] */ word * dpp = dp; /* [ 0...39 ] */ static word e [50] = {0}; word so[160]; Gsm_Preprocess (S, s, so); Gsm_LPC_Analysis (S, so, LARc); Gsm_Short_Term_Analysis_Filter (S, LARc, so); for (k = 0; k <= 3; k++, xMc += 13) { Gsm_Long_Term_Predictor ( S, so+k*40, /* d [0..39] IN */ dp, /* dp [-120..-1] IN */ e + 5, /* e [0..39] OUT */ dpp, /* dpp [0..39] OUT */ Nc++, bc++); Gsm_RPE_Encoding ( S, e + 5, /* e ][0..39][ IN/OUT */ xmaxc++, Mc++, xMc ); /* * Gsm_Update_of_reconstructed_short_time_residual_signal * ( dpp, e + 5, dp ); */ { register int i; register longword ltmp; for (i = 0; i <= 39; i++) dp[ i ] = GSM_ADD( e[5 + i], dpp[i] ); } dp += 40; dpp += 40; } (void)memcpy( (char *)S->dp0, (char *)(S->dp0 + 160), 120 * sizeof(*S->dp0) ); } rplay-3.3.2/gsm/debug.c100644 153 62 2776 6552756454 13373 0ustar boynsstaff/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /usr/local/cvsroot/rplay/gsm/debug.c,v 1.1.1.1 1998/07/14 22:35:24 mrb Exp $ */ #include "private.h" #ifndef NDEBUG /* If NDEBUG _is_ defined and no debugging should be performed, * calls to functions in this module are #defined to nothing * in private.h. */ #include #include "proto.h" void gsm_debug_words P4( (name, from, to, ptr), char * name, int from, int to, word * ptr) { int nprinted = 0; fprintf( stderr, "%s [%d .. %d]: ", name, from, to ); while (from <= to) { fprintf(stderr, "%d ", ptr[ from ] ); from++; if (nprinted++ >= 7) { nprinted = 0; if (from < to) putc('\n', stderr); } } putc('\n', stderr); } void gsm_debug_longwords P4( (name, from, to, ptr), char * name, int from, int to, longword * ptr) { int nprinted = 0; fprintf( stderr, "%s [%d .. %d]: ", name, from, to ); while (from <= to) { fprintf(stderr, "%d ", ptr[ from ] ); from++; if (nprinted++ >= 7) { nprinted = 0; if (from < to) putc('\n', stderr); } } putc('\n', stderr); } void gsm_debug_longword P2( (name, value), char * name, longword value ) { fprintf(stderr, "%s: %d\n", name, (long)value ); } void gsm_debug_word P2( (name, value), char * name, word value ) { fprintf(stderr, "%s: %d\n", name, (long)value); } #endif rplay-3.3.2/gsm/decode.c100644 153 62 3030 6552756454 13510 0ustar boynsstaff/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /usr/local/cvsroot/rplay/gsm/decode.c,v 1.1.1.1 1998/07/14 22:35:24 mrb Exp $ */ #include #include "private.h" #include "gsm.h" #include "proto.h" /* * 4.3 FIXED POINT IMPLEMENTATION OF THE RPE-LTP DECODER */ static void Postprocessing P2((S,s), struct gsm_state * S, register word * s) { register int k; register word msr = S->msr; register longword ltmp; /* for GSM_ADD */ register word tmp; for (k = 160; k--; s++) { tmp = GSM_MULT_R( msr, 28180 ); msr = GSM_ADD(*s, tmp); /* Deemphasis */ *s = GSM_ADD(msr, msr) & 0xFFF8; /* Truncation & Upscaling */ } S->msr = msr; } void Gsm_Decoder P8((S,LARcr, Ncr,bcr,Mcr,xmaxcr,xMcr,s), struct gsm_state * S, word * LARcr, /* [0..7] IN */ word * Ncr, /* [0..3] IN */ word * bcr, /* [0..3] IN */ word * Mcr, /* [0..3] IN */ word * xmaxcr, /* [0..3] IN */ word * xMcr, /* [0..13*4] IN */ word * s) /* [0..159] OUT */ { int j, k; word erp[40], wt[160]; word * drp = S->dp0 + 120; for (j=0; j <= 3; j++, xmaxcr++, bcr++, Ncr++, Mcr++, xMcr += 13) { Gsm_RPE_Decoding( S, *xmaxcr, *Mcr, xMcr, erp ); Gsm_Long_Term_Synthesis_Filtering( S, *Ncr, *bcr, erp, drp ); for (k = 0; k <= 39; k++) wt[ j * 40 + k ] = drp[ k ]; } Gsm_Short_Term_Synthesis_Filter( S, LARcr, wt, s ); Postprocessing(S, s); } rplay-3.3.2/gsm/gsm.3100644 153 62 5401 6552756454 12777 0ustar boynsstaff.\" .\" Copyright 1992 by Jutta Degener and Carsten Bormann, Technische .\" Universitaet Berlin. See the accompanying file "COPYRIGHT" for .\" details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. .\" .PU .TH GSM 3 .SH NAME gsm_create, gsm_destroy, gsm_encode, gsm_decode \(em GSM\ 06.10 lossy sound compression .SH SYNOPSIS .PP #include "gsm.h" .PP gsm gsm_create(); .PP void gsm_encode(handle, src, dst) .br gsm handle; .br gsm_signal src[160]; .br gsm_frame dst; .PP int gsm_decode(handle, src, dst) .br gsm handle; .br gsm_frame src; .br gsm_signal dst[160]; .PP void gsm_destroy(handle) .br gsm handle; .br .SH "DESCRIPTION" Gsm is an implementation of the final draft GSM 06.10 standard for full-rate speech transcoding. .PP gsm_create() initializes a gsm pass and returns a 'gsm' object which can be used as a handle in subsequent calls to gsm_decode(), gsm_encode() or gsm_destroy(). .PP gsm_encode() encodes an array of 160 13-bit samples (given as gsm_signal's, signed integral values of at least 16 bits) into a gsm_frame of 33 bytes. (gsm_frame is a type defined as an array of 33 gsm_bytes in gsm.h.) .PP gsm_decode() decodes a gsm_frame into an array of 160 13-bit samples (given as gsm_signals), which sound rather like what you handed to gsm_encode() on the other side of the wire. .PP gsm_destroy() finishes a gsm pass and frees all storage associated with it. .SS "Sample format" The following scaling is assumed for input to the algorithm: .br .nf 0 1 11 12 S..v..v..v..v..v..v..v..v..v..v..v..v..*..*..* .nf .br Only the top 13 bits are used as a signed input value. The output of gsm_decode() has the three lower bits set to zero. .\" .SH OPTIONS .SH "RETURN VALUE" gsm_create() returns an opaque handle object of type gsm, or 0 on error. gsm_decode() returns -1 if the passed frame is invalid, else 0. .SH EXAMPLE .nf #include "gsm.h" gsm handle; gsm_frame buf; gsm_signal sample[160]; int cc, soundfd; play() { /* read compressed data from standard input, write to soundfd */ if (!(handle = gsm_create())) error... while (cc = read(0, (char *)buf, sizeof buf)) { if (cc != sizeof buf) error... if (gsm_decode(handle, buf, sample) < 0) error... if (write(soundfd, sample, sizeof sample) != sizeof sample) error... } gsm_destroy(handle); } record() { /* read from soundfd, write compressed to standard output */ if (!(handle = gsm_create())) error... while (cc = read(soundfd, sample, sizeof sample)) { if (cc != sizeof sample) error... gsm_encode(handle, sample, buf); if (write(1, (char *)buf, sizeof buf) != sizeof sample) error... } gsm_destroy(handle); } .nf .SH BUGS Please direct bug reports to jutta@cs.tu-berlin.de and cabo@cs.tu-berlin.de. .SH "SEE ALSO" toast(1), gsm_print(3), gsm_explode(3), gsm_option(3) rplay-3.3.2/gsm/gsm.h100644 153 62 3053 6552756454 13065 0ustar boynsstaff/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /*$Header: /usr/local/cvsroot/rplay/gsm/gsm.h,v 1.1.1.1 1998/07/14 22:35:24 mrb Exp $*/ #ifndef GSM_H #define GSM_H #ifdef __cplusplus # define NeedFunctionPrototypes 1 #endif #if __STDC__ # define NeedFunctionPrototypes 1 #endif #ifdef _NO_PROTO # undef NeedFunctionPrototypes #endif #ifdef NeedFunctionPrototypes # include /* for FILE * */ #endif #undef GSM_P #if NeedFunctionPrototypes # define GSM_P( protos ) protos #else # define GSM_P( protos ) ( /* protos */ ) #endif /* * Interface */ typedef struct gsm_state * gsm; typedef short gsm_signal; /* signed 16 bit */ typedef unsigned char gsm_byte; typedef gsm_byte gsm_frame[33]; /* 33 * 8 bits */ #define GSM_MAGIC 0xD /* 13 kbit/s RPE-LTP */ #define GSM_PATCHLEVEL 7 #define GSM_MINOR 0 #define GSM_MAJOR 1 #define GSM_OPT_VERBOSE 1 #define GSM_OPT_FAST 2 #define GSM_OPT_LTP_CUT 3 extern gsm gsm_create GSM_P((void)); extern void gsm_destroy GSM_P((gsm)); extern int gsm_print GSM_P((FILE *, gsm, gsm_byte *)); extern int gsm_option GSM_P((gsm, int, int *)); extern void gsm_encode GSM_P((gsm, gsm_signal *, gsm_byte *)); extern int gsm_decode GSM_P((gsm, gsm_byte *, gsm_signal *)); extern int gsm_explode GSM_P((gsm, gsm_byte *, gsm_signal *)); extern void gsm_implode GSM_P((gsm, gsm_signal *, gsm_byte *)); #undef GSM_P #endif /* GSM_H */ rplay-3.3.2/gsm/gsm_create.c100644 153 62 1510 6552756454 14377 0ustar boynsstaff/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ static char ident[] = "$Header: /usr/local/cvsroot/rplay/gsm/gsm_create.c,v 1.1.1.1 1998/07/14 22:35:24 mrb Exp $"; #include "config.h" #ifdef HAS_STRING_H #include #else # include "proto.h" extern char * memset P((char *, int, int)); #endif #ifdef HAS_STDLIB_H # include #else # ifdef HAS_MALLOC_H # include # else extern char * malloc(); # endif #endif #include #include "gsm.h" #include "private.h" #include "proto.h" gsm gsm_create P0() { gsm r; r = (gsm)malloc(sizeof(struct gsm_state)); if (!r) return r; memset((char *)r, 0, sizeof(*r)); r->nrp = 40; return r; } rplay-3.3.2/gsm/gsm_decode.c100644 153 62 6736 6552756454 14376 0ustar boynsstaff/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /usr/local/cvsroot/rplay/gsm/gsm_decode.c,v 1.1.1.1 1998/07/14 22:35:24 mrb Exp $ */ #include "private.h" #include "gsm.h" #include "proto.h" int gsm_decode P3((s, c, target), gsm s, gsm_byte * c, gsm_signal * target) { word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4]; /* GSM_MAGIC = (*c >> 4) & 0xF; */ if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1; LARc[0] = (*c++ & 0xF) << 2; /* 1 */ LARc[0] |= (*c >> 6) & 0x3; LARc[1] = *c++ & 0x3F; LARc[2] = (*c >> 3) & 0x1F; LARc[3] = (*c++ & 0x7) << 2; LARc[3] |= (*c >> 6) & 0x3; LARc[4] = (*c >> 2) & 0xF; LARc[5] = (*c++ & 0x3) << 2; LARc[5] |= (*c >> 6) & 0x3; LARc[6] = (*c >> 3) & 0x7; LARc[7] = *c++ & 0x7; Nc[0] = (*c >> 1) & 0x7F; bc[0] = (*c++ & 0x1) << 1; bc[0] |= (*c >> 7) & 0x1; Mc[0] = (*c >> 5) & 0x3; xmaxc[0] = (*c++ & 0x1F) << 1; xmaxc[0] |= (*c >> 7) & 0x1; xmc[0] = (*c >> 4) & 0x7; xmc[1] = (*c >> 1) & 0x7; xmc[2] = (*c++ & 0x1) << 2; xmc[2] |= (*c >> 6) & 0x3; xmc[3] = (*c >> 3) & 0x7; xmc[4] = *c++ & 0x7; xmc[5] = (*c >> 5) & 0x7; xmc[6] = (*c >> 2) & 0x7; xmc[7] = (*c++ & 0x3) << 1; /* 10 */ xmc[7] |= (*c >> 7) & 0x1; xmc[8] = (*c >> 4) & 0x7; xmc[9] = (*c >> 1) & 0x7; xmc[10] = (*c++ & 0x1) << 2; xmc[10] |= (*c >> 6) & 0x3; xmc[11] = (*c >> 3) & 0x7; xmc[12] = *c++ & 0x7; Nc[1] = (*c >> 1) & 0x7F; bc[1] = (*c++ & 0x1) << 1; bc[1] |= (*c >> 7) & 0x1; Mc[1] = (*c >> 5) & 0x3; xmaxc[1] = (*c++ & 0x1F) << 1; xmaxc[1] |= (*c >> 7) & 0x1; xmc[13] = (*c >> 4) & 0x7; xmc[14] = (*c >> 1) & 0x7; xmc[15] = (*c++ & 0x1) << 2; xmc[15] |= (*c >> 6) & 0x3; xmc[16] = (*c >> 3) & 0x7; xmc[17] = *c++ & 0x7; xmc[18] = (*c >> 5) & 0x7; xmc[19] = (*c >> 2) & 0x7; xmc[20] = (*c++ & 0x3) << 1; xmc[20] |= (*c >> 7) & 0x1; xmc[21] = (*c >> 4) & 0x7; xmc[22] = (*c >> 1) & 0x7; xmc[23] = (*c++ & 0x1) << 2; xmc[23] |= (*c >> 6) & 0x3; xmc[24] = (*c >> 3) & 0x7; xmc[25] = *c++ & 0x7; Nc[2] = (*c >> 1) & 0x7F; bc[2] = (*c++ & 0x1) << 1; /* 20 */ bc[2] |= (*c >> 7) & 0x1; Mc[2] = (*c >> 5) & 0x3; xmaxc[2] = (*c++ & 0x1F) << 1; xmaxc[2] |= (*c >> 7) & 0x1; xmc[26] = (*c >> 4) & 0x7; xmc[27] = (*c >> 1) & 0x7; xmc[28] = (*c++ & 0x1) << 2; xmc[28] |= (*c >> 6) & 0x3; xmc[29] = (*c >> 3) & 0x7; xmc[30] = *c++ & 0x7; xmc[31] = (*c >> 5) & 0x7; xmc[32] = (*c >> 2) & 0x7; xmc[33] = (*c++ & 0x3) << 1; xmc[33] |= (*c >> 7) & 0x1; xmc[34] = (*c >> 4) & 0x7; xmc[35] = (*c >> 1) & 0x7; xmc[36] = (*c++ & 0x1) << 2; xmc[36] |= (*c >> 6) & 0x3; xmc[37] = (*c >> 3) & 0x7; xmc[38] = *c++ & 0x7; Nc[3] = (*c >> 1) & 0x7F; bc[3] = (*c++ & 0x1) << 1; bc[3] |= (*c >> 7) & 0x1; Mc[3] = (*c >> 5) & 0x3; xmaxc[3] = (*c++ & 0x1F) << 1; xmaxc[3] |= (*c >> 7) & 0x1; xmc[39] = (*c >> 4) & 0x7; xmc[40] = (*c >> 1) & 0x7; xmc[41] = (*c++ & 0x1) << 2; xmc[41] |= (*c >> 6) & 0x3; xmc[42] = (*c >> 3) & 0x7; xmc[43] = *c++ & 0x7; /* 30 */ xmc[44] = (*c >> 5) & 0x7; xmc[45] = (*c >> 2) & 0x7; xmc[46] = (*c++ & 0x3) << 1; xmc[46] |= (*c >> 7) & 0x1; xmc[47] = (*c >> 4) & 0x7; xmc[48] = (*c >> 1) & 0x7; xmc[49] = (*c++ & 0x1) << 2; xmc[49] |= (*c >> 6) & 0x3; xmc[50] = (*c >> 3) & 0x7; xmc[51] = *c & 0x7; /* 33 */ Gsm_Decoder(s, LARc, Nc, bc, Mc, xmaxc, xmc, target); return 0; } rplay-3.3.2/gsm/gsm_destroy.c100644 153 62 1057 6552756454 14633 0ustar boynsstaff/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /usr/local/cvsroot/rplay/gsm/gsm_destroy.c,v 1.1.1.1 1998/07/14 22:35:24 mrb Exp $ */ #include "gsm.h" #include "config.h" #include "proto.h" #ifdef HAS_STDLIB_H # include #else # ifdef HAS_MALLOC_H # include # else extern void free(); # endif #endif void gsm_destroy P1((S), gsm S) { if (S) free((char *)S); } rplay-3.3.2/gsm/gsm_encode.c100644 153 62 11345 6552756454 14420 0ustar boynsstaff/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /usr/local/cvsroot/rplay/gsm/gsm_encode.c,v 1.1.1.1 1998/07/14 22:35:24 mrb Exp $ */ #include "private.h" #include "gsm.h" #include "proto.h" void gsm_encode P3((s, source, c), gsm s, gsm_signal * source, gsm_byte * c) { word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4]; Gsm_Coder(s, source, LARc, Nc, bc, Mc, xmaxc, xmc); /* variable size GSM_MAGIC 4 LARc[0] 6 LARc[1] 6 LARc[2] 5 LARc[3] 5 LARc[4] 4 LARc[5] 4 LARc[6] 3 LARc[7] 3 Nc[0] 7 bc[0] 2 Mc[0] 2 xmaxc[0] 6 xmc[0] 3 xmc[1] 3 xmc[2] 3 xmc[3] 3 xmc[4] 3 xmc[5] 3 xmc[6] 3 xmc[7] 3 xmc[8] 3 xmc[9] 3 xmc[10] 3 xmc[11] 3 xmc[12] 3 Nc[1] 7 bc[1] 2 Mc[1] 2 xmaxc[1] 6 xmc[13] 3 xmc[14] 3 xmc[15] 3 xmc[16] 3 xmc[17] 3 xmc[18] 3 xmc[19] 3 xmc[20] 3 xmc[21] 3 xmc[22] 3 xmc[23] 3 xmc[24] 3 xmc[25] 3 Nc[2] 7 bc[2] 2 Mc[2] 2 xmaxc[2] 6 xmc[26] 3 xmc[27] 3 xmc[28] 3 xmc[29] 3 xmc[30] 3 xmc[31] 3 xmc[32] 3 xmc[33] 3 xmc[34] 3 xmc[35] 3 xmc[36] 3 xmc[37] 3 xmc[38] 3 Nc[3] 7 bc[3] 2 Mc[3] 2 xmaxc[3] 6 xmc[39] 3 xmc[40] 3 xmc[41] 3 xmc[42] 3 xmc[43] 3 xmc[44] 3 xmc[45] 3 xmc[46] 3 xmc[47] 3 xmc[48] 3 xmc[49] 3 xmc[50] 3 xmc[51] 3 */ *c++ = ((GSM_MAGIC & 0xF) << 4) /* 1 */ | ((LARc[0] >> 2) & 0xF); *c++ = ((LARc[0] & 0x3) << 6) | (LARc[1] & 0x3F); *c++ = ((LARc[2] & 0x1F) << 3) | ((LARc[3] >> 2) & 0x7); *c++ = ((LARc[3] & 0x3) << 6) | ((LARc[4] & 0xF) << 2) | ((LARc[5] >> 2) & 0x3); *c++ = ((LARc[5] & 0x3) << 6) | ((LARc[6] & 0x7) << 3) | (LARc[7] & 0x7); *c++ = ((Nc[0] & 0x7F) << 1) | ((bc[0] >> 1) & 0x1); *c++ = ((bc[0] & 0x1) << 7) | ((Mc[0] & 0x3) << 5) | ((xmaxc[0] >> 1) & 0x1F); *c++ = ((xmaxc[0] & 0x1) << 7) | ((xmc[0] & 0x7) << 4) | ((xmc[1] & 0x7) << 1) | ((xmc[2] >> 2) & 0x1); *c++ = ((xmc[2] & 0x3) << 6) | ((xmc[3] & 0x7) << 3) | (xmc[4] & 0x7); *c++ = ((xmc[5] & 0x7) << 5) /* 10 */ | ((xmc[6] & 0x7) << 2) | ((xmc[7] >> 1) & 0x3); *c++ = ((xmc[7] & 0x1) << 7) | ((xmc[8] & 0x7) << 4) | ((xmc[9] & 0x7) << 1) | ((xmc[10] >> 2) & 0x1); *c++ = ((xmc[10] & 0x3) << 6) | ((xmc[11] & 0x7) << 3) | (xmc[12] & 0x7); *c++ = ((Nc[1] & 0x7F) << 1) | ((bc[1] >> 1) & 0x1); *c++ = ((bc[1] & 0x1) << 7) | ((Mc[1] & 0x3) << 5) | ((xmaxc[1] >> 1) & 0x1F); *c++ = ((xmaxc[1] & 0x1) << 7) | ((xmc[13] & 0x7) << 4) | ((xmc[14] & 0x7) << 1) | ((xmc[15] >> 2) & 0x1); *c++ = ((xmc[15] & 0x3) << 6) | ((xmc[16] & 0x7) << 3) | (xmc[17] & 0x7); *c++ = ((xmc[18] & 0x7) << 5) | ((xmc[19] & 0x7) << 2) | ((xmc[20] >> 1) & 0x3); *c++ = ((xmc[20] & 0x1) << 7) | ((xmc[21] & 0x7) << 4) | ((xmc[22] & 0x7) << 1) | ((xmc[23] >> 2) & 0x1); *c++ = ((xmc[23] & 0x3) << 6) | ((xmc[24] & 0x7) << 3) | (xmc[25] & 0x7); *c++ = ((Nc[2] & 0x7F) << 1) /* 20 */ | ((bc[2] >> 1) & 0x1); *c++ = ((bc[2] & 0x1) << 7) | ((Mc[2] & 0x3) << 5) | ((xmaxc[2] >> 1) & 0x1F); *c++ = ((xmaxc[2] & 0x1) << 7) | ((xmc[26] & 0x7) << 4) | ((xmc[27] & 0x7) << 1) | ((xmc[28] >> 2) & 0x1); *c++ = ((xmc[28] & 0x3) << 6) | ((xmc[29] & 0x7) << 3) | (xmc[30] & 0x7); *c++ = ((xmc[31] & 0x7) << 5) | ((xmc[32] & 0x7) << 2) | ((xmc[33] >> 1) & 0x3); *c++ = ((xmc[33] & 0x1) << 7) | ((xmc[34] & 0x7) << 4) | ((xmc[35] & 0x7) << 1) | ((xmc[36] >> 2) & 0x1); *c++ = ((xmc[36] & 0x3) << 6) | ((xmc[37] & 0x7) << 3) | (xmc[38] & 0x7); *c++ = ((Nc[3] & 0x7F) << 1) | ((bc[3] >> 1) & 0x1); *c++ = ((bc[3] & 0x1) << 7) | ((Mc[3] & 0x3) << 5) | ((xmaxc[3] >> 1) & 0x1F); *c++ = ((xmaxc[3] & 0x1) << 7) | ((xmc[39] & 0x7) << 4) | ((xmc[40] & 0x7) << 1) | ((xmc[41] >> 2) & 0x1); *c++ = ((xmc[41] & 0x3) << 6) /* 30 */ | ((xmc[42] & 0x7) << 3) | (xmc[43] & 0x7); *c++ = ((xmc[44] & 0x7) << 5) | ((xmc[45] & 0x7) << 2) | ((xmc[46] >> 1) & 0x3); *c++ = ((xmc[46] & 0x1) << 7) | ((xmc[47] & 0x7) << 4) | ((xmc[48] & 0x7) << 1) | ((xmc[49] >> 2) & 0x1); *c++ = ((xmc[49] & 0x3) << 6) | ((xmc[50] & 0x7) << 3) | (xmc[51] & 0x7); } rplay-3.3.2/gsm/gsm_explode.3100644 153 62 2327 6552756454 14523 0ustar boynsstaff.\" .\" Copyright 1992 by Jutta Degener and Carsten Bormann, Technische .\" Universitaet Berlin. See the accompanying file "COPYRIGHT" for .\" details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. .\" .PU .TH GSM_EXPLODE 3 .SH NAME gsm_explode, gsm_implode \(em GSM\ 06.10 supplementary functions for testing .SH SYNOPSIS #include "gsm.h" .PP void gsm_explode(g, frame, xframe) .br gsm g; .br gsm_frame frame; .br gsm_signal xframe[ 76 ]; .PP void gsm_implode(g, xframe, frame) .br gsm g; .br gsm_signal xframe[ 76 ]; .br gsm_frame frame; .SH "DESCRIPTION" Gsm is an implementation of the final draft GSM 06.10 standard for full-rate speech transcoding. Test data for implementations of this particular document can be bought and used to verify an implementation. .PP The encoded test data uses a format different from what one would use to transmit frames with the least number of bits. Gsm_explode() and gsm_implode() convert between the internal, small, 33-byte format and the 76-word format used by the test data. .PP .SH "RETURN VALUE" gsm_explode() returns -1 if the passed frame is invalid, else 0. .SH BUGS Please direct bug reports to jutta@cs.tu-berlin.de and cabo@cs.tu-berlin.de. .SH "SEE ALSO" gsm(3) rplay-3.3.2/gsm/gsm_explode.c100644 153 62 10215 6552756454 14616 0ustar boynsstaff/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /usr/local/cvsroot/rplay/gsm/gsm_explode.c,v 1.1.1.1 1998/07/14 22:35:24 mrb Exp $ */ #include "private.h" #include "gsm.h" #include "proto.h" int gsm_explode P3((s, c, target), gsm s, gsm_byte * c, gsm_signal * target) { /* GSM_MAGIC = (*c >> 4) & 0xF; */ if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1; #define LARc target LARc[0] = (*c++ & 0xF) << 2; /* 1 */ LARc[0] |= (*c >> 6) & 0x3; LARc[1] = *c++ & 0x3F; LARc[2] = (*c >> 3) & 0x1F; LARc[3] = (*c++ & 0x7) << 2; LARc[3] |= (*c >> 6) & 0x3; LARc[4] = (*c >> 2) & 0xF; LARc[5] = (*c++ & 0x3) << 2; LARc[5] |= (*c >> 6) & 0x3; LARc[6] = (*c >> 3) & 0x7; LARc[7] = *c++ & 0x7; #define Nc (target + 8) Nc[0] = (*c >> 1) & 0x7F; #define bc (target + 9) bc[0] = (*c++ & 0x1) << 1; bc[0] |= (*c >> 7) & 0x1; #define Mc (target + 10) Mc[0] = (*c >> 5) & 0x3; #define xmaxc (target + 11) xmaxc[0] = (*c++ & 0x1F) << 1; xmaxc[0] |= (*c >> 7) & 0x1; #define xmc (target + 12) xmc[0] = (*c >> 4) & 0x7; xmc[1] = (*c >> 1) & 0x7; xmc[2] = (*c++ & 0x1) << 2; xmc[2] |= (*c >> 6) & 0x3; xmc[3] = (*c >> 3) & 0x7; xmc[4] = *c++ & 0x7; xmc[5] = (*c >> 5) & 0x7; xmc[6] = (*c >> 2) & 0x7; xmc[7] = (*c++ & 0x3) << 1; /* 10 */ xmc[7] |= (*c >> 7) & 0x1; xmc[8] = (*c >> 4) & 0x7; xmc[9] = (*c >> 1) & 0x7; xmc[10] = (*c++ & 0x1) << 2; xmc[10] |= (*c >> 6) & 0x3; xmc[11] = (*c >> 3) & 0x7; xmc[12] = *c++ & 0x7; #undef Nc #define Nc (target + 25 - 1) Nc[1] = (*c >> 1) & 0x7F; #undef bc #define bc (target + 26 - 1) bc[1] = (*c++ & 0x1) << 1; bc[1] |= (*c >> 7) & 0x1; #undef Mc #define Mc (target + 27 - 1) Mc[1] = (*c >> 5) & 0x3; #undef xmaxc #define xmaxc (target + 28 - 1) xmaxc[1] = (*c++ & 0x1F) << 1; xmaxc[1] |= (*c >> 7) & 0x1; #undef xmc #define xmc (target + 29 - 13) xmc[13] = (*c >> 4) & 0x7; xmc[14] = (*c >> 1) & 0x7; xmc[15] = (*c++ & 0x1) << 2; xmc[15] |= (*c >> 6) & 0x3; xmc[16] = (*c >> 3) & 0x7; xmc[17] = *c++ & 0x7; xmc[18] = (*c >> 5) & 0x7; xmc[19] = (*c >> 2) & 0x7; xmc[20] = (*c++ & 0x3) << 1; xmc[20] |= (*c >> 7) & 0x1; xmc[21] = (*c >> 4) & 0x7; xmc[22] = (*c >> 1) & 0x7; xmc[23] = (*c++ & 0x1) << 2; xmc[23] |= (*c >> 6) & 0x3; xmc[24] = (*c >> 3) & 0x7; xmc[25] = *c++ & 0x7; #undef Nc #define Nc (target + 42 - 2) Nc[2] = (*c >> 1) & 0x7F; #undef bc #define bc (target + 43 - 2) bc[2] = (*c++ & 0x1) << 1; /* 20 */ bc[2] |= (*c >> 7) & 0x1; #undef Mc #define Mc (target + 44 - 2) Mc[2] = (*c >> 5) & 0x3; #undef xmaxc #define xmaxc (target + 45 - 2) xmaxc[2] = (*c++ & 0x1F) << 1; xmaxc[2] |= (*c >> 7) & 0x1; #undef xmc #define xmc (target + 46 - 26) xmc[26] = (*c >> 4) & 0x7; xmc[27] = (*c >> 1) & 0x7; xmc[28] = (*c++ & 0x1) << 2; xmc[28] |= (*c >> 6) & 0x3; xmc[29] = (*c >> 3) & 0x7; xmc[30] = *c++ & 0x7; xmc[31] = (*c >> 5) & 0x7; xmc[32] = (*c >> 2) & 0x7; xmc[33] = (*c++ & 0x3) << 1; xmc[33] |= (*c >> 7) & 0x1; xmc[34] = (*c >> 4) & 0x7; xmc[35] = (*c >> 1) & 0x7; xmc[36] = (*c++ & 0x1) << 2; xmc[36] |= (*c >> 6) & 0x3; xmc[37] = (*c >> 3) & 0x7; xmc[38] = *c++ & 0x7; #undef Nc #define Nc (target + 59 - 3) Nc[3] = (*c >> 1) & 0x7F; #undef bc #define bc (target + 60 - 3) bc[3] = (*c++ & 0x1) << 1; bc[3] |= (*c >> 7) & 0x1; #undef Mc #define Mc (target + 61 - 3) Mc[3] = (*c >> 5) & 0x3; #undef xmaxc #define xmaxc (target + 62 - 3) xmaxc[3] = (*c++ & 0x1F) << 1; xmaxc[3] |= (*c >> 7) & 0x1; #undef xmc #define xmc (target + 63 - 39) xmc[39] = (*c >> 4) & 0x7; xmc[40] = (*c >> 1) & 0x7; xmc[41] = (*c++ & 0x1) << 2; xmc[41] |= (*c >> 6) & 0x3; xmc[42] = (*c >> 3) & 0x7; xmc[43] = *c++ & 0x7; /* 30 */ xmc[44] = (*c >> 5) & 0x7; xmc[45] = (*c >> 2) & 0x7; xmc[46] = (*c++ & 0x3) << 1; xmc[46] |= (*c >> 7) & 0x1; xmc[47] = (*c >> 4) & 0x7; xmc[48] = (*c >> 1) & 0x7; xmc[49] = (*c++ & 0x1) << 2; xmc[49] |= (*c >> 6) & 0x3; xmc[50] = (*c >> 3) & 0x7; xmc[51] = *c & 0x7; /* 33 */ return 0; } rplay-3.3.2/gsm/gsm_implode.c100644 153 62 13171 6552756454 14613 0ustar boynsstaff/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /usr/local/cvsroot/rplay/gsm/gsm_implode.c,v 1.1.1.1 1998/07/14 22:35:24 mrb Exp $ */ #include "private.h" #include "gsm.h" #include "proto.h" void gsm_implode P3((s, source, c), gsm s, gsm_signal * source, gsm_byte * c) { /* variable size index GSM_MAGIC 4 - LARc[0] 6 0 LARc[1] 6 1 LARc[2] 5 2 LARc[3] 5 3 LARc[4] 4 4 LARc[5] 4 5 LARc[6] 3 6 LARc[7] 3 7 Nc[0] 7 8 bc[0] 2 9 Mc[0] 2 10 xmaxc[0] 6 11 xmc[0] 3 12 xmc[1] 3 13 xmc[2] 3 14 xmc[3] 3 15 xmc[4] 3 16 xmc[5] 3 17 xmc[6] 3 18 xmc[7] 3 19 xmc[8] 3 20 xmc[9] 3 21 xmc[10] 3 22 xmc[11] 3 23 xmc[12] 3 24 Nc[1] 7 25 bc[1] 2 26 Mc[1] 2 27 xmaxc[1] 6 28 xmc[13] 3 29 xmc[14] 3 30 xmc[15] 3 31 xmc[16] 3 32 xmc[17] 3 33 xmc[18] 3 34 xmc[19] 3 35 xmc[20] 3 36 xmc[21] 3 37 xmc[22] 3 38 xmc[23] 3 39 xmc[24] 3 40 xmc[25] 3 41 Nc[2] 7 42 bc[2] 2 43 Mc[2] 2 44 xmaxc[2] 6 45 xmc[26] 3 46 xmc[27] 3 47 xmc[28] 3 48 xmc[29] 3 49 xmc[30] 3 50 xmc[31] 3 51 xmc[32] 3 52 xmc[33] 3 53 xmc[34] 3 54 xmc[35] 3 55 xmc[36] 3 56 xmc[37] 3 57 xmc[38] 3 58 Nc[3] 7 59 bc[3] 2 60 Mc[3] 2 61 xmaxc[3] 6 62 xmc[39] 3 63 xmc[40] 3 64 xmc[41] 3 65 xmc[42] 3 66 xmc[43] 3 67 xmc[44] 3 68 xmc[45] 3 69 xmc[46] 3 70 xmc[47] 3 71 xmc[48] 3 72 xmc[49] 3 73 xmc[50] 3 74 xmc[51] 3 75 */ #define LARc source *c++ = ((GSM_MAGIC & 0xF) << 4) /* 1 */ | ((LARc[0] >> 2) & 0xF); *c++ = ((LARc[0] & 0x3) << 6) | (LARc[1] & 0x3F); *c++ = ((LARc[2] & 0x1F) << 3) | ((LARc[3] >> 2) & 0x7); *c++ = ((LARc[3] & 0x3) << 6) | ((LARc[4] & 0xF) << 2) | ((LARc[5] >> 2) & 0x3); *c++ = ((LARc[5] & 0x3) << 6) | ((LARc[6] & 0x7) << 3) | (LARc[7] & 0x7); #define Nc (source + 8) *c++ = ((Nc[0] & 0x7F) << 1) #define bc (source + 9) | ((bc[0] >> 1) & 0x1); *c++ = ((bc[0] & 0x1) << 7) #define Mc (source + 10) | ((Mc[0] & 0x3) << 5) #define xmaxc (source + 11) | ((xmaxc[0] >> 1) & 0x1F); *c++ = ((xmaxc[0] & 0x1) << 7) #define xmc (source + 12) | ((xmc[0] & 0x7) << 4) | ((xmc[1] & 0x7) << 1) | ((xmc[2] >> 2) & 0x1); *c++ = ((xmc[2] & 0x3) << 6) | ((xmc[3] & 0x7) << 3) | (xmc[4] & 0x7); *c++ = ((xmc[5] & 0x7) << 5) /* 10 */ | ((xmc[6] & 0x7) << 2) | ((xmc[7] >> 1) & 0x3); *c++ = ((xmc[7] & 0x1) << 7) | ((xmc[8] & 0x7) << 4) | ((xmc[9] & 0x7) << 1) | ((xmc[10] >> 2) & 0x1); *c++ = ((xmc[10] & 0x3) << 6) | ((xmc[11] & 0x7) << 3) | (xmc[12] & 0x7); #undef Nc #define Nc (source + 25 - 1) *c++ = ((Nc[1] & 0x7F) << 1) #undef bc #define bc (source + 26 - 1) | ((bc[1] >> 1) & 0x1); *c++ = ((bc[1] & 0x1) << 7) #undef Mc #define Mc (source + 27 - 1) | ((Mc[1] & 0x3) << 5) #undef xmaxc #define xmaxc (source + 28 - 1) | ((xmaxc[1] >> 1) & 0x1F); *c++ = ((xmaxc[1] & 0x1) << 7) #undef xmc #define xmc (source + 29 - 13) | ((xmc[13] & 0x7) << 4) | ((xmc[14] & 0x7) << 1) | ((xmc[15] >> 2) & 0x1); *c++ = ((xmc[15] & 0x3) << 6) | ((xmc[16] & 0x7) << 3) | (xmc[17] & 0x7); *c++ = ((xmc[18] & 0x7) << 5) | ((xmc[19] & 0x7) << 2) | ((xmc[20] >> 1) & 0x3); *c++ = ((xmc[20] & 0x1) << 7) | ((xmc[21] & 0x7) << 4) | ((xmc[22] & 0x7) << 1) | ((xmc[23] >> 2) & 0x1); *c++ = ((xmc[23] & 0x3) << 6) | ((xmc[24] & 0x7) << 3) | (xmc[25] & 0x7); #undef Nc #define Nc (source + 42 - 2) *c++ = ((Nc[2] & 0x7F) << 1) /* 20 */ #undef bc #define bc (source + 43 - 2) | ((bc[2] >> 1) & 0x1); *c++ = ((bc[2] & 0x1) << 7) #undef Mc #define Mc (source + 44 - 2) | ((Mc[2] & 0x3) << 5) #undef xmaxc #define xmaxc (source + 45 - 2) | ((xmaxc[2] >> 1) & 0x1F); *c++ = ((xmaxc[2] & 0x1) << 7) #undef xmc #define xmc (source + 46 - 26) | ((xmc[26] & 0x7) << 4) | ((xmc[27] & 0x7) << 1) | ((xmc[28] >> 2) & 0x1); *c++ = ((xmc[28] & 0x3) << 6) | ((xmc[29] & 0x7) << 3) | (xmc[30] & 0x7); *c++ = ((xmc[31] & 0x7) << 5) | ((xmc[32] & 0x7) << 2) | ((xmc[33] >> 1) & 0x3); *c++ = ((xmc[33] & 0x1) << 7) | ((xmc[34] & 0x7) << 4) | ((xmc[35] & 0x7) << 1) | ((xmc[36] >> 2) & 0x1); *c++ = ((xmc[36] & 0x3) << 6) | ((xmc[37] & 0x7) << 3) | (xmc[38] & 0x7); #undef Nc #define Nc (source + 59 - 3) *c++ = ((Nc[3] & 0x7F) << 1) #undef bc #define bc (source + 60 - 3) | ((bc[3] >> 1) & 0x1); *c++ = ((bc[3] & 0x1) << 7) #undef Mc #define Mc (source + 61 - 3) | ((Mc[3] & 0x3) << 5) #undef xmaxc #define xmaxc (source + 62 - 3) | ((xmaxc[3] >> 1) & 0x1F); *c++ = ((xmaxc[3] & 0x1) << 7) #undef xmc #define xmc (source + 63 - 39) | ((xmc[39] & 0x7) << 4) | ((xmc[40] & 0x7) << 1) | ((xmc[41] >> 2) & 0x1); *c++ = ((xmc[41] & 0x3) << 6) /* 30 */ | ((xmc[42] & 0x7) << 3) | (xmc[43] & 0x7); *c++ = ((xmc[44] & 0x7) << 5) | ((xmc[45] & 0x7) << 2) | ((xmc[46] >> 1) & 0x3); *c++ = ((xmc[46] & 0x1) << 7) | ((xmc[47] & 0x7) << 4) | ((xmc[48] & 0x7) << 1) | ((xmc[49] >> 2) & 0x1); *c++ = ((xmc[49] & 0x3) << 6) | ((xmc[50] & 0x7) << 3) | (xmc[51] & 0x7); } rplay-3.3.2/gsm/gsm_option.3100644 153 62 5736 6552756454 14402 0ustar boynsstaff.\" .\" Copyright 1992-1995 by Jutta Degener and Carsten Bormann, Technische .\" Universitaet Berlin. See the accompanying file "COPYRIGHT" for .\" details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. .\" .PU .TH GSM_OPTION 3 .SH NAME gsm_option \(em customizing the GSM 06.10 implementation .SH SYNOPSIS #include "gsm.h" .PP int gsm_option(handle, option, valueP); .br gsm handle; .br int option; .br int * valueP; .SH "DESCRIPTION" The gsm library is an implementation of the final draft GSM 06.10 standard for full-rate speech transcoding, a lossy speech compression algorithm. .PP The gsm_option() function can be used to set and query various options or flags that are not needed for regular GSM 06.10 encoding or decoding, but might be of interest in special cases. .PP The second argument to gsm_option specifies what parameter should be changed or queried. The third argument is either a null pointer, in which case the current value of that parameter is returned; or it is a pointer to an integer containing the value you want to set, in which case the previous value will be returned. .PP The following options are currently defined: .PP .I GSM_OPT_VERBOSE Verbosity level. .br .in+5 This option is only supported if the library was compiled with debugging turned on, and may be used by developers of compression algorithms to aid debugging. .br The verbosity level can be changed at any time during encoding or decoding. .in-5 .sp .I GSM_OPT_FAST Faster compression algorithm. .br .in+5 This implementation offers a not strictly standard-compliant, but faster compression algorithm that is compatible with the regular method and does not noticably degrade audio quality. .br The value passed to .br .nf gsm_option(handle, GSM_OPT_FAST, & value) .fi .br functions as a boolean flag; if it is zero, the regular algorithm will be used, if not, the faster version will be used. .br The availability of this option depends on the hardware used; if it is not available, gsm_option will return -1 on an attempt to set or query it. .br This option can be set any time during encoding or decoding. .in-5 .ne 5 .sp .PP .I GSM_OPT_LTP_CUT Enable, disable, or query the LTP cut-off optimization. .br .in+5 During encoding, the search for the long-term correlation lag forms the bottleneck of the algorithm. The ltp-cut option enables an approximation that disregards most of the samples for purposes of finding that correlation, and hence speeds up the encoding at a noticable loss in quality. .br The value passed to .br .nf gsm_option(handle, GSM_OPT_LTP_CUT, & value) .fi .br turns the optimization on if nonzero, and off if zero. .br This option can be set any time during encoding or decoding; it will only affect the encoding pass, not the decoding. .SH "RETURN VALUE" gsm_option() returns -1 if an option is not supported, the previous value of the option otherwise. .SH BUGS Please direct bug reports to jutta@cs.tu-berlin.de and cabo@cs.tu-berlin.de. .SH "SEE ALSO" toast(1), gsm(3), gsm_explode(3), gsm_print(3) rplay-3.3.2/gsm/gsm_option.c100644 153 62 1521 6552756454 14446 0ustar boynsstaff/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /usr/local/cvsroot/rplay/gsm/gsm_option.c,v 1.1.1.1 1998/07/14 22:35:24 mrb Exp $ */ #include "private.h" #include "gsm.h" #include "proto.h" int gsm_option P3((r, opt, val), gsm r, int opt, int * val) { int result = -1; switch (opt) { case GSM_OPT_LTP_CUT: #ifdef LTP_CUT result = r->ltp_cut; if (val) r->ltp_cut = *val; #endif break; case GSM_OPT_VERBOSE: #ifndef NDEBUG result = r->verbose; if (val) r->verbose = *val; #endif break; case GSM_OPT_FAST: #if defined(FAST) && defined(USE_FLOAT_MUL) result = r->fast; if (val) r->fast = !!*val; #endif break; default: break; } return result; } rplay-3.3.2/gsm/gsm_print.3100644 153 62 3013 6552756454 14210 0ustar boynsstaff.\" .\" Copyright 1992 by Jutta Degener and Carsten Bormann, Technische .\" Universitaet Berlin. See the accompanying file "COPYRIGHT" for .\" details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. .\" .PU .TH GSM_PRINT 3 .SH NAME gsm_print \(em GSM\ 06.10 supplementary function for debugging .SH SYNOPSIS #include "gsm.h" #include int gsm_print(f, g, frame); .br FILE * f; .br gsm g; .br gsm_frame frame; .SH "DESCRIPTION" Gsm is an implementation of the final draft GSM 06.10 standard for full-rate speech transcoding, a lossy speech compression algorithm. The compressed form involves 76 variables with different numbers of significant bits packed into 33 bytes. .PP If you are interested in investigating the details of this coding scheme, gsm_print() can be used to dump the contents of individual gsm_frames to a file pointer provided by the application. .PP .SH "RETURN VALUE" gsm_print() returns -1 if the frame is invalid, else 0. .SH EXAMPLE A single frame looks like this: .br .nf LARc: 29 32 20 11 08 05 06 07 #1: Nc 0040 bc 0 Mc 1 xmaxc 60 06 04 00 03 03 06 04 02 02 04 05 04 01 #2: Nc 0045 bc 1 Mc 1 xmaxc 48 03 07 01 03 04 04 07 01 03 02 04 05 03 #3: Nc 0091 bc 1 Mc 1 xmaxc 46 00 03 03 07 01 06 02 04 05 03 03 02 04 #4: Nc 0120 bc 0 Mc 1 xmaxc 47 07 03 06 00 03 03 06 05 00 03 02 07 04 .nf .SH BUGS Please direct bug reports to jutta@cs.tu-berlin.de and cabo@cs.tu-berlin.de. .SH "SEE ALSO" gsm(3), gsm_explode(3) rplay-3.3.2/gsm/gsm_print.c100644 153 62 11471 6552756454 14317 0ustar boynsstaff/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /usr/local/cvsroot/rplay/gsm/gsm_print.c,v 1.1.1.1 1998/07/14 22:35:24 mrb Exp $ */ #include #include "private.h" #include "gsm.h" #include "proto.h" int gsm_print P3((f, s, c), FILE * f, gsm s, gsm_byte * c) { word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4]; /* GSM_MAGIC = (*c >> 4) & 0xF; */ if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1; LARc[0] = (*c++ & 0xF) << 2; /* 1 */ LARc[0] |= (*c >> 6) & 0x3; LARc[1] = *c++ & 0x3F; LARc[2] = (*c >> 3) & 0x1F; LARc[3] = (*c++ & 0x7) << 2; LARc[3] |= (*c >> 6) & 0x3; LARc[4] = (*c >> 2) & 0xF; LARc[5] = (*c++ & 0x3) << 2; LARc[5] |= (*c >> 6) & 0x3; LARc[6] = (*c >> 3) & 0x7; LARc[7] = *c++ & 0x7; Nc[0] = (*c >> 1) & 0x7F; bc[0] = (*c++ & 0x1) << 1; bc[0] |= (*c >> 7) & 0x1; Mc[0] = (*c >> 5) & 0x3; xmaxc[0] = (*c++ & 0x1F) << 1; xmaxc[0] |= (*c >> 7) & 0x1; xmc[0] = (*c >> 4) & 0x7; xmc[1] = (*c >> 1) & 0x7; xmc[2] = (*c++ & 0x1) << 2; xmc[2] |= (*c >> 6) & 0x3; xmc[3] = (*c >> 3) & 0x7; xmc[4] = *c++ & 0x7; xmc[5] = (*c >> 5) & 0x7; xmc[6] = (*c >> 2) & 0x7; xmc[7] = (*c++ & 0x3) << 1; /* 10 */ xmc[7] |= (*c >> 7) & 0x1; xmc[8] = (*c >> 4) & 0x7; xmc[9] = (*c >> 1) & 0x7; xmc[10] = (*c++ & 0x1) << 2; xmc[10] |= (*c >> 6) & 0x3; xmc[11] = (*c >> 3) & 0x7; xmc[12] = *c++ & 0x7; Nc[1] = (*c >> 1) & 0x7F; bc[1] = (*c++ & 0x1) << 1; bc[1] |= (*c >> 7) & 0x1; Mc[1] = (*c >> 5) & 0x3; xmaxc[1] = (*c++ & 0x1F) << 1; xmaxc[1] |= (*c >> 7) & 0x1; xmc[13] = (*c >> 4) & 0x7; xmc[14] = (*c >> 1) & 0x7; xmc[15] = (*c++ & 0x1) << 2; xmc[15] |= (*c >> 6) & 0x3; xmc[16] = (*c >> 3) & 0x7; xmc[17] = *c++ & 0x7; xmc[18] = (*c >> 5) & 0x7; xmc[19] = (*c >> 2) & 0x7; xmc[20] = (*c++ & 0x3) << 1; xmc[20] |= (*c >> 7) & 0x1; xmc[21] = (*c >> 4) & 0x7; xmc[22] = (*c >> 1) & 0x7; xmc[23] = (*c++ & 0x1) << 2; xmc[23] |= (*c >> 6) & 0x3; xmc[24] = (*c >> 3) & 0x7; xmc[25] = *c++ & 0x7; Nc[2] = (*c >> 1) & 0x7F; bc[2] = (*c++ & 0x1) << 1; /* 20 */ bc[2] |= (*c >> 7) & 0x1; Mc[2] = (*c >> 5) & 0x3; xmaxc[2] = (*c++ & 0x1F) << 1; xmaxc[2] |= (*c >> 7) & 0x1; xmc[26] = (*c >> 4) & 0x7; xmc[27] = (*c >> 1) & 0x7; xmc[28] = (*c++ & 0x1) << 2; xmc[28] |= (*c >> 6) & 0x3; xmc[29] = (*c >> 3) & 0x7; xmc[30] = *c++ & 0x7; xmc[31] = (*c >> 5) & 0x7; xmc[32] = (*c >> 2) & 0x7; xmc[33] = (*c++ & 0x3) << 1; xmc[33] |= (*c >> 7) & 0x1; xmc[34] = (*c >> 4) & 0x7; xmc[35] = (*c >> 1) & 0x7; xmc[36] = (*c++ & 0x1) << 2; xmc[36] |= (*c >> 6) & 0x3; xmc[37] = (*c >> 3) & 0x7; xmc[38] = *c++ & 0x7; Nc[3] = (*c >> 1) & 0x7F; bc[3] = (*c++ & 0x1) << 1; bc[3] |= (*c >> 7) & 0x1; Mc[3] = (*c >> 5) & 0x3; xmaxc[3] = (*c++ & 0x1F) << 1; xmaxc[3] |= (*c >> 7) & 0x1; xmc[39] = (*c >> 4) & 0x7; xmc[40] = (*c >> 1) & 0x7; xmc[41] = (*c++ & 0x1) << 2; xmc[41] |= (*c >> 6) & 0x3; xmc[42] = (*c >> 3) & 0x7; xmc[43] = *c++ & 0x7; /* 30 */ xmc[44] = (*c >> 5) & 0x7; xmc[45] = (*c >> 2) & 0x7; xmc[46] = (*c++ & 0x3) << 1; xmc[46] |= (*c >> 7) & 0x1; xmc[47] = (*c >> 4) & 0x7; xmc[48] = (*c >> 1) & 0x7; xmc[49] = (*c++ & 0x1) << 2; xmc[49] |= (*c >> 6) & 0x3; xmc[50] = (*c >> 3) & 0x7; xmc[51] = *c & 0x7; /* 33 */ fprintf(f, "LARc:\t%2.2d %2.2d %2.2d %2.2d %2.2d %2.2d %2.2d %2.2d\n", LARc[0],LARc[1],LARc[2],LARc[3],LARc[4],LARc[5],LARc[6],LARc[7]); fprintf(f, "#1: Nc %4.4d bc %d Mc %d xmaxc %d\n", Nc[0], bc[0], Mc[0], xmaxc[0]); fprintf(f, "\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n", xmc[0],xmc[1],xmc[2],xmc[3],xmc[4],xmc[5],xmc[6], xmc[7],xmc[8],xmc[9],xmc[10],xmc[11],xmc[12] ); fprintf(f, "#2: Nc %4.4d bc %d Mc %d xmaxc %d\n", Nc[1], bc[1], Mc[1], xmaxc[1]); fprintf(f, "\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n", xmc[13+0],xmc[13+1],xmc[13+2],xmc[13+3],xmc[13+4],xmc[13+5], xmc[13+6], xmc[13+7],xmc[13+8],xmc[13+9],xmc[13+10],xmc[13+11], xmc[13+12] ); fprintf(f, "#3: Nc %4.4d bc %d Mc %d xmaxc %d\n", Nc[2], bc[2], Mc[2], xmaxc[2]); fprintf(f, "\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n", xmc[26+0],xmc[26+1],xmc[26+2],xmc[26+3],xmc[26+4],xmc[26+5], xmc[26+6], xmc[26+7],xmc[26+8],xmc[26+9],xmc[26+10],xmc[26+11], xmc[26+12] ); fprintf(f, "#4: Nc %4.4d bc %d Mc %d xmaxc %d\n", Nc[3], bc[3], Mc[3], xmaxc[3]); fprintf(f, "\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n", xmc[39+0],xmc[39+1],xmc[39+2],xmc[39+3],xmc[39+4],xmc[39+5], xmc[39+6], xmc[39+7],xmc[39+8],xmc[39+9],xmc[39+10],xmc[39+11], xmc[39+12] ); return 0; } rplay-3.3.2/gsm/long_term.c100644 153 62 56022 6552756454 14304 0ustar boynsstaff/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /usr/local/cvsroot/rplay/gsm/long_term.c,v 1.1.1.1 1998/07/14 22:35:24 mrb Exp $ */ #include #include #include "private.h" #include "gsm.h" #include "proto.h" /* * 4.2.11 .. 4.2.12 LONG TERM PREDICTOR (LTP) SECTION */ /* * This module computes the LTP gain (bc) and the LTP lag (Nc) * for the long term analysis filter. This is done by calculating a * maximum of the cross-correlation function between the current * sub-segment short term residual signal d[0..39] (output of * the short term analysis filter; for simplification the index * of this array begins at 0 and ends at 39 for each sub-segment of the * RPE-LTP analysis) and the previous reconstructed short term * residual signal dp[ -120 .. -1 ]. A dynamic scaling must be * performed to avoid overflow. */ /* The next procedure exists in six versions. First two integer * version (if USE_FLOAT_MUL is not defined); then four floating * point versions, twice with proper scaling (USE_FLOAT_MUL defined), * once without (USE_FLOAT_MUL and FAST defined, and fast run-time * option used). Every pair has first a Cut version (see the -C * option to toast or the LTP_CUT option to gsm_option()), then the * uncut one. (For a detailed explanation of why this is altogether * a bad idea, see Henry Spencer and Geoff Collyer, ``#ifdef Considered * Harmful''.) */ #ifndef USE_FLOAT_MUL #ifdef LTP_CUT static void Cut_Calculation_of_the_LTP_parameters P5((st, d,dp,bc_out,Nc_out), struct gsm_state * st, register word * d, /* [0..39] IN */ register word * dp, /* [-120..-1] IN */ word * bc_out, /* OUT */ word * Nc_out /* OUT */ ) { register int k, lambda; word Nc, bc; word wt[40]; longword L_result; longword L_max, L_power; word R, S, dmax, scal, best_k; word ltp_cut; register word temp, wt_k; /* Search of the optimum scaling of d[0..39]. */ dmax = 0; for (k = 0; k <= 39; k++) { temp = d[k]; temp = GSM_ABS( temp ); if (temp > dmax) { dmax = temp; best_k = k; } } temp = 0; if (dmax == 0) scal = 0; else { assert(dmax > 0); temp = gsm_norm( (longword)dmax << 16 ); } if (temp > 6) scal = 0; else scal = 6 - temp; assert(scal >= 0); /* Search for the maximum cross-correlation and coding of the LTP lag */ L_max = 0; Nc = 40; /* index for the maximum cross-correlation */ wt_k = SASR(d[best_k], scal); for (lambda = 40; lambda <= 120; lambda++) { L_result = (longword)wt_k * dp[best_k - lambda]; if (L_result > L_max) { Nc = lambda; L_max = L_result; } } *Nc_out = Nc; L_max <<= 1; /* Rescaling of L_max */ assert(scal <= 100 && scal >= -100); L_max = L_max >> (6 - scal); /* sub(6, scal) */ assert( Nc <= 120 && Nc >= 40); /* Compute the power of the reconstructed short term residual * signal dp[..] */ L_power = 0; for (k = 0; k <= 39; k++) { register longword L_temp; L_temp = SASR( dp[k - Nc], 3 ); L_power += L_temp * L_temp; } L_power <<= 1; /* from L_MULT */ /* Normalization of L_max and L_power */ if (L_max <= 0) { *bc_out = 0; return; } if (L_max >= L_power) { *bc_out = 3; return; } temp = gsm_norm( L_power ); R = SASR( L_max << temp, 16 ); S = SASR( L_power << temp, 16 ); /* Coding of the LTP gain */ /* Table 4.3a must be used to obtain the level DLB[i] for the * quantization of the LTP gain b to get the coded version bc. */ for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break; *bc_out = bc; } #endif /* LTP_CUT */ static void Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out), register word * d, /* [0..39] IN */ register word * dp, /* [-120..-1] IN */ word * bc_out, /* OUT */ word * Nc_out /* OUT */ ) { register int k, lambda; word Nc, bc; word wt[40]; longword L_max, L_power; word R, S, dmax, scal; register word temp; /* Search of the optimum scaling of d[0..39]. */ dmax = 0; for (k = 0; k <= 39; k++) { temp = d[k]; temp = GSM_ABS( temp ); if (temp > dmax) dmax = temp; } temp = 0; if (dmax == 0) scal = 0; else { assert(dmax > 0); temp = gsm_norm( (longword)dmax << 16 ); } if (temp > 6) scal = 0; else scal = 6 - temp; assert(scal >= 0); /* Initialization of a working array wt */ for (k = 0; k <= 39; k++) wt[k] = SASR( d[k], scal ); /* Search for the maximum cross-correlation and coding of the LTP lag */ L_max = 0; Nc = 40; /* index for the maximum cross-correlation */ for (lambda = 40; lambda <= 120; lambda++) { # undef STEP # define STEP(k) (longword)wt[k] * dp[k - lambda] register longword L_result; L_result = STEP(0) ; L_result += STEP(1) ; L_result += STEP(2) ; L_result += STEP(3) ; L_result += STEP(4) ; L_result += STEP(5) ; L_result += STEP(6) ; L_result += STEP(7) ; L_result += STEP(8) ; L_result += STEP(9) ; L_result += STEP(10) ; L_result += STEP(11) ; L_result += STEP(12) ; L_result += STEP(13) ; L_result += STEP(14) ; L_result += STEP(15) ; L_result += STEP(16) ; L_result += STEP(17) ; L_result += STEP(18) ; L_result += STEP(19) ; L_result += STEP(20) ; L_result += STEP(21) ; L_result += STEP(22) ; L_result += STEP(23) ; L_result += STEP(24) ; L_result += STEP(25) ; L_result += STEP(26) ; L_result += STEP(27) ; L_result += STEP(28) ; L_result += STEP(29) ; L_result += STEP(30) ; L_result += STEP(31) ; L_result += STEP(32) ; L_result += STEP(33) ; L_result += STEP(34) ; L_result += STEP(35) ; L_result += STEP(36) ; L_result += STEP(37) ; L_result += STEP(38) ; L_result += STEP(39) ; if (L_result > L_max) { Nc = lambda; L_max = L_result; } } *Nc_out = Nc; L_max <<= 1; /* Rescaling of L_max */ assert(scal <= 100 && scal >= -100); L_max = L_max >> (6 - scal); /* sub(6, scal) */ assert( Nc <= 120 && Nc >= 40); /* Compute the power of the reconstructed short term residual * signal dp[..] */ L_power = 0; for (k = 0; k <= 39; k++) { register longword L_temp; L_temp = SASR( dp[k - Nc], 3 ); L_power += L_temp * L_temp; } L_power <<= 1; /* from L_MULT */ /* Normalization of L_max and L_power */ if (L_max <= 0) { *bc_out = 0; return; } if (L_max >= L_power) { *bc_out = 3; return; } temp = gsm_norm( L_power ); R = SASR( L_max << temp, 16 ); S = SASR( L_power << temp, 16 ); /* Coding of the LTP gain */ /* Table 4.3a must be used to obtain the level DLB[i] for the * quantization of the LTP gain b to get the coded version bc. */ for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break; *bc_out = bc; } #else /* USE_FLOAT_MUL */ #ifdef LTP_CUT static void Cut_Calculation_of_the_LTP_parameters P5((st, d,dp,bc_out,Nc_out), struct gsm_state * st, /* IN */ register word * d, /* [0..39] IN */ register word * dp, /* [-120..-1] IN */ word * bc_out, /* OUT */ word * Nc_out /* OUT */ ) { register int k, lambda; word Nc, bc; word ltp_cut; float wt_float[40]; float dp_float_base[120], * dp_float = dp_float_base + 120; longword L_max, L_power; word R, S, dmax, scal; register word temp; /* Search of the optimum scaling of d[0..39]. */ dmax = 0; for (k = 0; k <= 39; k++) { temp = d[k]; temp = GSM_ABS( temp ); if (temp > dmax) dmax = temp; } temp = 0; if (dmax == 0) scal = 0; else { assert(dmax > 0); temp = gsm_norm( (longword)dmax << 16 ); } if (temp > 6) scal = 0; else scal = 6 - temp; assert(scal >= 0); ltp_cut = (longword)SASR(dmax, scal) * st->ltp_cut / 100; /* Initialization of a working array wt */ for (k = 0; k < 40; k++) { register word w = SASR( d[k], scal ); if (w < 0 ? w > -ltp_cut : w < ltp_cut) { wt_float[k] = 0.0; } else { wt_float[k] = w; } } for (k = -120; k < 0; k++) dp_float[k] = dp[k]; /* Search for the maximum cross-correlation and coding of the LTP lag */ L_max = 0; Nc = 40; /* index for the maximum cross-correlation */ for (lambda = 40; lambda <= 120; lambda += 9) { /* Calculate L_result for l = lambda .. lambda + 9. */ register float *lp = dp_float - lambda; register float W; register float a = lp[-8], b = lp[-7], c = lp[-6], d = lp[-5], e = lp[-4], f = lp[-3], g = lp[-2], h = lp[-1]; register float E; register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0, S5 = 0, S6 = 0, S7 = 0, S8 = 0; # undef STEP # define STEP(K, a, b, c, d, e, f, g, h) \ if ((W = wt_float[K]) != 0.0) { \ E = W * a; S8 += E; \ E = W * b; S7 += E; \ E = W * c; S6 += E; \ E = W * d; S5 += E; \ E = W * e; S4 += E; \ E = W * f; S3 += E; \ E = W * g; S2 += E; \ E = W * h; S1 += E; \ a = lp[K]; \ E = W * a; S0 += E; } else (a = lp[K]) # define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h) # define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a) # define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b) # define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c) # define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d) # define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e) # define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f) # define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g) STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3); STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7); STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11); STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15); STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19); STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23); STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27); STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31); STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35); STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39); if (S0 > L_max) { L_max = S0; Nc = lambda; } if (S1 > L_max) { L_max = S1; Nc = lambda + 1; } if (S2 > L_max) { L_max = S2; Nc = lambda + 2; } if (S3 > L_max) { L_max = S3; Nc = lambda + 3; } if (S4 > L_max) { L_max = S4; Nc = lambda + 4; } if (S5 > L_max) { L_max = S5; Nc = lambda + 5; } if (S6 > L_max) { L_max = S6; Nc = lambda + 6; } if (S7 > L_max) { L_max = S7; Nc = lambda + 7; } if (S8 > L_max) { L_max = S8; Nc = lambda + 8; } } *Nc_out = Nc; L_max <<= 1; /* Rescaling of L_max */ assert(scal <= 100 && scal >= -100); L_max = L_max >> (6 - scal); /* sub(6, scal) */ assert( Nc <= 120 && Nc >= 40); /* Compute the power of the reconstructed short term residual * signal dp[..] */ L_power = 0; for (k = 0; k <= 39; k++) { register longword L_temp; L_temp = SASR( dp[k - Nc], 3 ); L_power += L_temp * L_temp; } L_power <<= 1; /* from L_MULT */ /* Normalization of L_max and L_power */ if (L_max <= 0) { *bc_out = 0; return; } if (L_max >= L_power) { *bc_out = 3; return; } temp = gsm_norm( L_power ); R = SASR( L_max << temp, 16 ); S = SASR( L_power << temp, 16 ); /* Coding of the LTP gain */ /* Table 4.3a must be used to obtain the level DLB[i] for the * quantization of the LTP gain b to get the coded version bc. */ for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break; *bc_out = bc; } #endif /* LTP_CUT */ static void Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out), register word * d, /* [0..39] IN */ register word * dp, /* [-120..-1] IN */ word * bc_out, /* OUT */ word * Nc_out /* OUT */ ) { register int k, lambda; word Nc, bc; float wt_float[40]; float dp_float_base[120], * dp_float = dp_float_base + 120; longword L_max, L_power; word R, S, dmax, scal; register word temp; /* Search of the optimum scaling of d[0..39]. */ dmax = 0; for (k = 0; k <= 39; k++) { temp = d[k]; temp = GSM_ABS( temp ); if (temp > dmax) dmax = temp; } temp = 0; if (dmax == 0) scal = 0; else { assert(dmax > 0); temp = gsm_norm( (longword)dmax << 16 ); } if (temp > 6) scal = 0; else scal = 6 - temp; assert(scal >= 0); /* Initialization of a working array wt */ for (k = 0; k < 40; k++) wt_float[k] = SASR( d[k], scal ); for (k = -120; k < 0; k++) dp_float[k] = dp[k]; /* Search for the maximum cross-correlation and coding of the LTP lag */ L_max = 0; Nc = 40; /* index for the maximum cross-correlation */ for (lambda = 40; lambda <= 120; lambda += 9) { /* Calculate L_result for l = lambda .. lambda + 9. */ register float *lp = dp_float - lambda; register float W; register float a = lp[-8], b = lp[-7], c = lp[-6], d = lp[-5], e = lp[-4], f = lp[-3], g = lp[-2], h = lp[-1]; register float E; register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0, S5 = 0, S6 = 0, S7 = 0, S8 = 0; # undef STEP # define STEP(K, a, b, c, d, e, f, g, h) \ W = wt_float[K]; \ E = W * a; S8 += E; \ E = W * b; S7 += E; \ E = W * c; S6 += E; \ E = W * d; S5 += E; \ E = W * e; S4 += E; \ E = W * f; S3 += E; \ E = W * g; S2 += E; \ E = W * h; S1 += E; \ a = lp[K]; \ E = W * a; S0 += E # define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h) # define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a) # define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b) # define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c) # define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d) # define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e) # define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f) # define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g) STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3); STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7); STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11); STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15); STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19); STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23); STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27); STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31); STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35); STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39); if (S0 > L_max) { L_max = S0; Nc = lambda; } if (S1 > L_max) { L_max = S1; Nc = lambda + 1; } if (S2 > L_max) { L_max = S2; Nc = lambda + 2; } if (S3 > L_max) { L_max = S3; Nc = lambda + 3; } if (S4 > L_max) { L_max = S4; Nc = lambda + 4; } if (S5 > L_max) { L_max = S5; Nc = lambda + 5; } if (S6 > L_max) { L_max = S6; Nc = lambda + 6; } if (S7 > L_max) { L_max = S7; Nc = lambda + 7; } if (S8 > L_max) { L_max = S8; Nc = lambda + 8; } } *Nc_out = Nc; L_max <<= 1; /* Rescaling of L_max */ assert(scal <= 100 && scal >= -100); L_max = L_max >> (6 - scal); /* sub(6, scal) */ assert( Nc <= 120 && Nc >= 40); /* Compute the power of the reconstructed short term residual * signal dp[..] */ L_power = 0; for (k = 0; k <= 39; k++) { register longword L_temp; L_temp = SASR( dp[k - Nc], 3 ); L_power += L_temp * L_temp; } L_power <<= 1; /* from L_MULT */ /* Normalization of L_max and L_power */ if (L_max <= 0) { *bc_out = 0; return; } if (L_max >= L_power) { *bc_out = 3; return; } temp = gsm_norm( L_power ); R = SASR( L_max << temp, 16 ); S = SASR( L_power << temp, 16 ); /* Coding of the LTP gain */ /* Table 4.3a must be used to obtain the level DLB[i] for the * quantization of the LTP gain b to get the coded version bc. */ for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break; *bc_out = bc; } #ifdef FAST #ifdef LTP_CUT static void Cut_Fast_Calculation_of_the_LTP_parameters P5((st, d,dp,bc_out,Nc_out), struct gsm_state * st, /* IN */ register word * d, /* [0..39] IN */ register word * dp, /* [-120..-1] IN */ word * bc_out, /* OUT */ word * Nc_out /* OUT */ ) { register int k, lambda; register float wt_float; word Nc, bc; word wt_max, best_k, ltp_cut; float dp_float_base[120], * dp_float = dp_float_base + 120; register float L_result, L_max, L_power; wt_max = 0; for (k = 0; k < 40; ++k) { if ( d[k] > wt_max) wt_max = d[best_k = k]; else if (-d[k] > wt_max) wt_max = -d[best_k = k]; } assert(wt_max >= 0); wt_float = (float)wt_max; for (k = -120; k <= 0; ++k) dp_float[k] = (float)dp[k]; /* Search for the maximum cross-correlation and coding of the LTP lag */ L_max = 0; Nc = 40; /* index for the maximum cross-correlation */ for (lambda = 40; lambda <= 120; lambda++) { L_result = wt_float * dp_float[best_k - lambda]; if (L_result > L_max) { Nc = lambda; L_max = L_result; } } *Nc_out = Nc; if (L_max <= 0.) { *bc_out = 0; return; } /* Compute the power of the reconstructed short term residual * signal dp[..] */ dp_float -= Nc; L_power = 0; for (k = 0; k < 40; ++k) { register float f = dp_float[k]; L_power += f * f; } if (L_max >= L_power) { *bc_out = 3; return; } /* Coding of the LTP gain * Table 4.3a must be used to obtain the level DLB[i] for the * quantization of the LTP gain b to get the coded version bc. */ lambda = L_max / L_power * 32768.; for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break; *bc_out = bc; } #endif /* LTP_CUT */ static void Fast_Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out), register word * d, /* [0..39] IN */ register word * dp, /* [-120..-1] IN */ word * bc_out, /* OUT */ word * Nc_out /* OUT */ ) { register int k, lambda; word Nc, bc; float wt_float[40]; float dp_float_base[120], * dp_float = dp_float_base + 120; register float L_max, L_power; for (k = 0; k < 40; ++k) wt_float[k] = (float)d[k]; for (k = -120; k <= 0; ++k) dp_float[k] = (float)dp[k]; /* Search for the maximum cross-correlation and coding of the LTP lag */ L_max = 0; Nc = 40; /* index for the maximum cross-correlation */ for (lambda = 40; lambda <= 120; lambda += 9) { /* Calculate L_result for l = lambda .. lambda + 9. */ register float *lp = dp_float - lambda; register float W; register float a = lp[-8], b = lp[-7], c = lp[-6], d = lp[-5], e = lp[-4], f = lp[-3], g = lp[-2], h = lp[-1]; register float E; register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0, S5 = 0, S6 = 0, S7 = 0, S8 = 0; # undef STEP # define STEP(K, a, b, c, d, e, f, g, h) \ W = wt_float[K]; \ E = W * a; S8 += E; \ E = W * b; S7 += E; \ E = W * c; S6 += E; \ E = W * d; S5 += E; \ E = W * e; S4 += E; \ E = W * f; S3 += E; \ E = W * g; S2 += E; \ E = W * h; S1 += E; \ a = lp[K]; \ E = W * a; S0 += E # define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h) # define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a) # define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b) # define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c) # define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d) # define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e) # define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f) # define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g) STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3); STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7); STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11); STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15); STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19); STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23); STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27); STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31); STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35); STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39); if (S0 > L_max) { L_max = S0; Nc = lambda; } if (S1 > L_max) { L_max = S1; Nc = lambda + 1; } if (S2 > L_max) { L_max = S2; Nc = lambda + 2; } if (S3 > L_max) { L_max = S3; Nc = lambda + 3; } if (S4 > L_max) { L_max = S4; Nc = lambda + 4; } if (S5 > L_max) { L_max = S5; Nc = lambda + 5; } if (S6 > L_max) { L_max = S6; Nc = lambda + 6; } if (S7 > L_max) { L_max = S7; Nc = lambda + 7; } if (S8 > L_max) { L_max = S8; Nc = lambda + 8; } } *Nc_out = Nc; if (L_max <= 0.) { *bc_out = 0; return; } /* Compute the power of the reconstructed short term residual * signal dp[..] */ dp_float -= Nc; L_power = 0; for (k = 0; k < 40; ++k) { register float f = dp_float[k]; L_power += f * f; } if (L_max >= L_power) { *bc_out = 3; return; } /* Coding of the LTP gain * Table 4.3a must be used to obtain the level DLB[i] for the * quantization of the LTP gain b to get the coded version bc. */ lambda = L_max / L_power * 32768.; for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break; *bc_out = bc; } #endif /* FAST */ #endif /* USE_FLOAT_MUL */ /* 4.2.12 */ static void Long_term_analysis_filtering P6((bc,Nc,dp,d,dpp,e), word bc, /* IN */ word Nc, /* IN */ register word * dp, /* previous d [-120..-1] IN */ register word * d, /* d [0..39] IN */ register word * dpp, /* estimate [0..39] OUT */ register word * e /* long term res. signal [0..39] OUT */ ) /* * In this part, we have to decode the bc parameter to compute * the samples of the estimate dpp[0..39]. The decoding of bc needs the * use of table 4.3b. The long term residual signal e[0..39] * is then calculated to be fed to the RPE encoding section. */ { register int k; register longword ltmp; # undef STEP # define STEP(BP) \ for (k = 0; k <= 39; k++) { \ dpp[k] = GSM_MULT_R( BP, dp[k - Nc]); \ e[k] = GSM_SUB( d[k], dpp[k] ); \ } switch (bc) { case 0: STEP( 3277 ); break; case 1: STEP( 11469 ); break; case 2: STEP( 21299 ); break; case 3: STEP( 32767 ); break; } } void Gsm_Long_Term_Predictor P7((S,d,dp,e,dpp,Nc,bc), /* 4x for 160 samples */ struct gsm_state * S, word * d, /* [0..39] residual signal IN */ word * dp, /* [-120..-1] d' IN */ word * e, /* [0..39] OUT */ word * dpp, /* [0..39] OUT */ word * Nc, /* correlation lag OUT */ word * bc /* gain factor OUT */ ) { assert( d ); assert( dp ); assert( e ); assert( dpp); assert( Nc ); assert( bc ); #if defined(FAST) && defined(USE_FLOAT_MUL) if (S->fast) #if defined (LTP_CUT) if (S->ltp_cut) Cut_Fast_Calculation_of_the_LTP_parameters(S, d, dp, bc, Nc); else #endif /* LTP_CUT */ Fast_Calculation_of_the_LTP_parameters(d, dp, bc, Nc ); else #endif /* FAST & USE_FLOAT_MUL */ #ifdef LTP_CUT if (S->ltp_cut) Cut_Calculation_of_the_LTP_parameters(S, d, dp, bc, Nc); else #endif Calculation_of_the_LTP_parameters(d, dp, bc, Nc); Long_term_analysis_filtering( *bc, *Nc, dp, d, dpp, e ); } /* 4.3.2 */ void Gsm_Long_Term_Synthesis_Filtering P5((S,Ncr,bcr,erp,drp), struct gsm_state * S, word Ncr, word bcr, register word * erp, /* [0..39] IN */ register word * drp /* [-120..-1] IN, [0..40] OUT */ ) /* * This procedure uses the bcr and Ncr parameter to realize the * long term synthesis filtering. The decoding of bcr needs * table 4.3b. */ { register longword ltmp; /* for ADD */ register int k; word brp, drpp, Nr; /* Check the limits of Nr. */ Nr = Ncr < 40 || Ncr > 120 ? S->nrp : Ncr; S->nrp = Nr; assert(Nr >= 40 && Nr <= 120); /* Decoding of the LTP gain bcr */ brp = gsm_QLB[ bcr ]; /* Computation of the reconstructed short term residual * signal drp[0..39] */ assert(brp != MIN_WORD); for (k = 0; k <= 39; k++) { drpp = GSM_MULT_R( brp, drp[ k - Nr ] ); drp[k] = GSM_ADD( erp[k], drpp ); } /* * Update of the reconstructed short term residual signal * drp[ -1..-120 ] */ for (k = 0; k <= 119; k++) drp[ -120 + k ] = drp[ -80 + k ]; } rplay-3.3.2/gsm/lpc.c100644 153 62 15647 6552756454 13104 0ustar boynsstaff/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /usr/local/cvsroot/rplay/gsm/lpc.c,v 1.1.1.1 1998/07/14 22:35:24 mrb Exp $ */ #include #include #include "private.h" #include "gsm.h" #include "proto.h" #undef P /* * 4.2.4 .. 4.2.7 LPC ANALYSIS SECTION */ /* 4.2.4 */ static void Autocorrelation P2((s, L_ACF), word * s, /* [0..159] IN/OUT */ longword * L_ACF) /* [0..8] OUT */ /* * The goal is to compute the array L_ACF[k]. The signal s[i] must * be scaled in order to avoid an overflow situation. */ { register int k, i; word temp, smax, scalauto; #ifdef USE_FLOAT_MUL float float_s[160]; #endif /* Dynamic scaling of the array s[0..159] */ /* Search for the maximum. */ smax = 0; for (k = 0; k <= 159; k++) { temp = GSM_ABS( s[k] ); if (temp > smax) smax = temp; } /* Computation of the scaling factor. */ if (smax == 0) scalauto = 0; else { assert(smax > 0); scalauto = 4 - gsm_norm( (longword)smax << 16 );/* sub(4,..) */ } /* Scaling of the array s[0...159] */ if (scalauto > 0) { # ifdef USE_FLOAT_MUL # define SCALE(n) \ case n: for (k = 0; k <= 159; k++) \ float_s[k] = (float) \ (s[k] = GSM_MULT_R(s[k], 16384 >> (n-1)));\ break; # else # define SCALE(n) \ case n: for (k = 0; k <= 159; k++) \ s[k] = GSM_MULT_R( s[k], 16384 >> (n-1) );\ break; # endif /* USE_FLOAT_MUL */ switch (scalauto) { SCALE(1) SCALE(2) SCALE(3) SCALE(4) } # undef SCALE } # ifdef USE_FLOAT_MUL else for (k = 0; k <= 159; k++) float_s[k] = (float) s[k]; # endif /* Compute the L_ACF[..]. */ { # ifdef USE_FLOAT_MUL register float * sp = float_s; register float sl = *sp; # define STEP(k) L_ACF[k] += (longword)(sl * sp[ -(k) ]); # else word * sp = s; word sl = *sp; # define STEP(k) L_ACF[k] += ((longword)sl * sp[ -(k) ]); # endif # define NEXTI sl = *++sp for (k = 9; k--; L_ACF[k] = 0) ; STEP (0); NEXTI; STEP(0); STEP(1); NEXTI; STEP(0); STEP(1); STEP(2); NEXTI; STEP(0); STEP(1); STEP(2); STEP(3); NEXTI; STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); NEXTI; STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); NEXTI; STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); NEXTI; STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); STEP(7); for (i = 8; i <= 159; i++) { NEXTI; STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); STEP(7); STEP(8); } for (k = 9; k--; L_ACF[k] <<= 1) ; } /* Rescaling of the array s[0..159] */ if (scalauto > 0) { assert(scalauto <= 4); for (k = 160; k--; *s++ <<= scalauto) ; } } #if defined(USE_FLOAT_MUL) && defined(FAST) static void Fast_Autocorrelation P2((s, L_ACF), word * s, /* [0..159] IN/OUT */ longword * L_ACF) /* [0..8] OUT */ { register int k, i; float f_L_ACF[9]; float scale; float s_f[160]; register float *sf = s_f; for (i = 0; i < 160; ++i) sf[i] = s[i]; for (k = 0; k <= 8; k++) { register float L_temp2 = 0; register float *sfl = sf - k; for (i = k; i < 160; ++i) L_temp2 += sf[i] * sfl[i]; f_L_ACF[k] = L_temp2; } scale = MAX_LONGWORD / f_L_ACF[0]; for (k = 0; k <= 8; k++) { L_ACF[k] = f_L_ACF[k] * scale; } } #endif /* defined (USE_FLOAT_MUL) && defined (FAST) */ /* 4.2.5 */ static void Reflection_coefficients P2( (L_ACF, r), longword * L_ACF, /* 0...8 IN */ register word * r /* 0...7 OUT */ ) { register int i, m, n; register word temp; register longword ltmp; word ACF[9]; /* 0..8 */ word P[ 9]; /* 0..8 */ word K[ 9]; /* 2..8 */ /* Schur recursion with 16 bits arithmetic. */ if (L_ACF[0] == 0) { for (i = 8; i--; *r++ = 0) ; return; } assert( L_ACF[0] != 0 ); temp = gsm_norm( L_ACF[0] ); assert(temp >= 0 && temp < 32); /* ? overflow ? */ for (i = 0; i <= 8; i++) ACF[i] = SASR( L_ACF[i] << temp, 16 ); /* Initialize array P[..] and K[..] for the recursion. */ for (i = 1; i <= 7; i++) K[ i ] = ACF[ i ]; for (i = 0; i <= 8; i++) P[ i ] = ACF[ i ]; /* Compute reflection coefficients */ for (n = 1; n <= 8; n++, r++) { temp = P[1]; temp = GSM_ABS(temp); if (P[0] < temp) { for (i = n; i <= 8; i++) *r++ = 0; return; } *r = gsm_div( temp, P[0] ); assert(*r >= 0); if (P[1] > 0) *r = -*r; /* r[n] = sub(0, r[n]) */ assert (*r != MIN_WORD); if (n == 8) return; /* Schur recursion */ temp = GSM_MULT_R( P[1], *r ); P[0] = GSM_ADD( P[0], temp ); for (m = 1; m <= 8 - n; m++) { temp = GSM_MULT_R( K[ m ], *r ); P[m] = GSM_ADD( P[ m+1 ], temp ); temp = GSM_MULT_R( P[ m+1 ], *r ); K[m] = GSM_ADD( K[ m ], temp ); } } } /* 4.2.6 */ static void Transformation_to_Log_Area_Ratios P1((r), register word * r /* 0..7 IN/OUT */ ) /* * The following scaling for r[..] and LAR[..] has been used: * * r[..] = integer( real_r[..]*32768. ); -1 <= real_r < 1. * LAR[..] = integer( real_LAR[..] * 16384 ); * with -1.625 <= real_LAR <= 1.625 */ { register word temp; register int i; /* Computation of the LAR[0..7] from the r[0..7] */ for (i = 1; i <= 8; i++, r++) { temp = *r; temp = GSM_ABS(temp); assert(temp >= 0); if (temp < 22118) { temp >>= 1; } else if (temp < 31130) { assert( temp >= 11059 ); temp -= 11059; } else { assert( temp >= 26112 ); temp -= 26112; temp <<= 2; } *r = *r < 0 ? -temp : temp; assert( *r != MIN_WORD ); } } /* 4.2.7 */ static void Quantization_and_coding P1((LAR), register word * LAR /* [0..7] IN/OUT */ ) { register word temp; longword ltmp; /* This procedure needs four tables; the following equations * give the optimum scaling for the constants: * * A[0..7] = integer( real_A[0..7] * 1024 ) * B[0..7] = integer( real_B[0..7] * 512 ) * MAC[0..7] = maximum of the LARc[0..7] * MIC[0..7] = minimum of the LARc[0..7] */ # undef STEP # define STEP( A, B, MAC, MIC ) \ temp = GSM_MULT( A, *LAR ); \ temp = GSM_ADD( temp, B ); \ temp = GSM_ADD( temp, 256 ); \ temp = SASR( temp, 9 ); \ *LAR = temp>MAC ? MAC - MIC : (tempfast) Fast_Autocorrelation (s, L_ACF ); else #endif Autocorrelation (s, L_ACF ); Reflection_coefficients (L_ACF, LARc ); Transformation_to_Log_Area_Ratios (LARc); Quantization_and_coding (LARc); } rplay-3.3.2/gsm/preprocess.c100644 153 62 4707 6552756454 14466 0ustar boynsstaff/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /usr/local/cvsroot/rplay/gsm/preprocess.c,v 1.1.1.1 1998/07/14 22:35:24 mrb Exp $ */ #include #include #include "private.h" #include "gsm.h" #include "proto.h" /* 4.2.0 .. 4.2.3 PREPROCESSING SECTION * * After A-law to linear conversion (or directly from the * Ato D converter) the following scaling is assumed for * input to the RPE-LTP algorithm: * * in: 0.1.....................12 * S.v.v.v.v.v.v.v.v.v.v.v.v.*.*.* * * Where S is the sign bit, v a valid bit, and * a "don't care" bit. * The original signal is called sop[..] * * out: 0.1................... 12 * S.S.v.v.v.v.v.v.v.v.v.v.v.v.0.0 */ void Gsm_Preprocess P3((S, s, so), struct gsm_state * S, word * s, word * so ) /* [0..159] IN/OUT */ { word z1 = S->z1; longword L_z2 = S->L_z2; word mp = S->mp; word s1; longword L_s2; longword L_temp; word msp, lsp; word SO; longword ltmp; /* for ADD */ ulongword utmp; /* for L_ADD */ register int k = 160; while (k--) { /* 4.2.1 Downscaling of the input signal */ SO = SASR( *s, 3 ) << 2; s++; assert (SO >= -0x4000); /* downscaled by */ assert (SO <= 0x3FFC); /* previous routine. */ /* 4.2.2 Offset compensation * * This part implements a high-pass filter and requires extended * arithmetic precision for the recursive part of this filter. * The input of this procedure is the array so[0...159] and the * output the array sof[ 0...159 ]. */ /* Compute the non-recursive part */ s1 = SO - z1; /* s1 = gsm_sub( *so, z1 ); */ z1 = SO; assert(s1 != MIN_WORD); /* Compute the recursive part */ L_s2 = s1; L_s2 <<= 15; /* Execution of a 31 bv 16 bits multiplication */ msp = SASR( L_z2, 15 ); lsp = L_z2-((longword)msp<<15); /* gsm_L_sub(L_z2,(msp<<15)); */ L_s2 += GSM_MULT_R( lsp, 32735 ); L_temp = (longword)msp * 32735; /* GSM_L_MULT(msp,32735) >> 1;*/ L_z2 = GSM_L_ADD( L_temp, L_s2 ); /* Compute sof[k] with rounding */ L_temp = GSM_L_ADD( L_z2, 16384 ); /* 4.2.3 Preemphasis */ msp = GSM_MULT_R( mp, -28180 ); mp = SASR( L_temp, 15 ); *so++ = GSM_ADD( mp, msp ); } S->z1 = z1; S->L_z2 = L_z2; S->mp = mp; } rplay-3.3.2/gsm/private.h100644 153 62 16536 6552756454 14003 0ustar boynsstaff/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /*$Header: /usr/local/cvsroot/rplay/gsm/private.h,v 1.1.1.1 1998/07/14 22:35:24 mrb Exp $*/ #ifndef PRIVATE_H #define PRIVATE_H typedef short word; /* 16 bit signed int */ typedef long longword; /* 32 bit signed int */ typedef unsigned short uword; /* unsigned word */ typedef unsigned long ulongword; /* unsigned longword */ struct gsm_state { word dp0[ 280 ]; word z1; /* preprocessing.c, Offset_com. */ longword L_z2; /* Offset_com. */ int mp; /* Preemphasis */ word u[8]; /* short_term_aly_filter.c */ word LARpp[2][8]; /* */ word j; /* */ word ltp_cut; /* long_term.c, LTP crosscorr. */ word nrp; /* 40 */ /* long_term.c, synthesis */ word v[9]; /* short_term.c, synthesis */ word msr; /* decoder.c, Postprocessing */ char verbose; /* only used if !NDEBUG */ char fast; /* only used if FAST */ }; #define MIN_WORD ((-32767)-1) #define MAX_WORD ( 32767) #define MIN_LONGWORD ((-2147483647)-1) #define MAX_LONGWORD ( 2147483647) #ifdef SASR /* >> is a signed arithmetic shift right */ #undef SASR #define SASR(x, by) ((x) >> (by)) #endif /* SASR */ #include "proto.h" /* * Prototypes from add.c */ extern word gsm_mult P((word a, word b)); extern longword gsm_L_mult P((word a, word b)); extern word gsm_mult_r P((word a, word b)); extern word gsm_div P((word num, word denum)); extern word gsm_add P(( word a, word b )); extern longword gsm_L_add P(( longword a, longword b )); extern word gsm_sub P((word a, word b)); extern longword gsm_L_sub P((longword a, longword b)); extern word gsm_abs P((word a)); extern word gsm_norm P(( longword a )); extern longword gsm_L_asl P((longword a, int n)); extern word gsm_asl P((word a, int n)); extern longword gsm_L_asr P((longword a, int n)); extern word gsm_asr P((word a, int n)); /* * Inlined functions from add.h */ /* * #define GSM_MULT_R(a, b) (* word a, word b, !(a == b == MIN_WORD) *) \ * (0x0FFFF & SASR(((longword)(a) * (longword)(b) + 16384), 15)) */ #define GSM_MULT_R(a, b) /* word a, word b, !(a == b == MIN_WORD) */ \ (SASR( ((longword)(a) * (longword)(b) + 16384), 15 )) # define GSM_MULT(a,b) /* word a, word b, !(a == b == MIN_WORD) */ \ (SASR( ((longword)(a) * (longword)(b)), 15 )) # define GSM_L_MULT(a, b) /* word a, word b */ \ (((longword)(a) * (longword)(b)) << 1) # define GSM_L_ADD(a, b) \ ( (a) < 0 ? ( (b) >= 0 ? (a) + (b) \ : (utmp = (ulongword)-((a) + 1) + (ulongword)-((b) + 1)) \ >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)utmp-2 ) \ : ((b) <= 0 ? (a) + (b) \ : (utmp = (ulongword)(a) + (ulongword)(b)) >= MAX_LONGWORD \ ? MAX_LONGWORD : utmp)) /* * # define GSM_ADD(a, b) \ * ((ltmp = (longword)(a) + (longword)(b)) >= MAX_WORD \ * ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp) */ /* Nonportable, but faster: */ #define GSM_ADD(a, b) \ ((ulongword)((ltmp = (longword)(a) + (longword)(b)) - MIN_WORD) > \ MAX_WORD - MIN_WORD ? (ltmp > 0 ? MAX_WORD : MIN_WORD) : ltmp) # define GSM_SUB(a, b) \ ((ltmp = (longword)(a) - (longword)(b)) >= MAX_WORD \ ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp) # define GSM_ABS(a) ((a) < 0 ? ((a) == MIN_WORD ? MAX_WORD : -(a)) : (a)) /* Use these if necessary: # define GSM_MULT_R(a, b) gsm_mult_r(a, b) # define GSM_MULT(a, b) gsm_mult(a, b) # define GSM_L_MULT(a, b) gsm_L_mult(a, b) # define GSM_L_ADD(a, b) gsm_L_add(a, b) # define GSM_ADD(a, b) gsm_add(a, b) # define GSM_SUB(a, b) gsm_sub(a, b) # define GSM_ABS(a) gsm_abs(a) */ /* * More prototypes from implementations.. */ extern void Gsm_Coder P(( struct gsm_state * S, word * s, /* [0..159] samples IN */ word * LARc, /* [0..7] LAR coefficients OUT */ word * Nc, /* [0..3] LTP lag OUT */ word * bc, /* [0..3] coded LTP gain OUT */ word * Mc, /* [0..3] RPE grid selection OUT */ word * xmaxc,/* [0..3] Coded maximum amplitude OUT */ word * xMc /* [13*4] normalized RPE samples OUT */)); extern void Gsm_Long_Term_Predictor P(( /* 4x for 160 samples */ struct gsm_state * S, word * d, /* [0..39] residual signal IN */ word * dp, /* [-120..-1] d' IN */ word * e, /* [0..40] OUT */ word * dpp, /* [0..40] OUT */ word * Nc, /* correlation lag OUT */ word * bc /* gain factor OUT */)); extern void Gsm_LPC_Analysis P(( struct gsm_state * S, word * s, /* 0..159 signals IN/OUT */ word * LARc)); /* 0..7 LARc's OUT */ extern void Gsm_Preprocess P(( struct gsm_state * S, word * s, word * so)); extern void Gsm_Encoding P(( struct gsm_state * S, word * e, word * ep, word * xmaxc, word * Mc, word * xMc)); extern void Gsm_Short_Term_Analysis_Filter P(( struct gsm_state * S, word * LARc, /* coded log area ratio [0..7] IN */ word * d /* st res. signal [0..159] IN/OUT */)); extern void Gsm_Decoder P(( struct gsm_state * S, word * LARcr, /* [0..7] IN */ word * Ncr, /* [0..3] IN */ word * bcr, /* [0..3] IN */ word * Mcr, /* [0..3] IN */ word * xmaxcr, /* [0..3] IN */ word * xMcr, /* [0..13*4] IN */ word * s)); /* [0..159] OUT */ extern void Gsm_Decoding P(( struct gsm_state * S, word xmaxcr, word Mcr, word * xMcr, /* [0..12] IN */ word * erp)); /* [0..39] OUT */ extern void Gsm_Long_Term_Synthesis_Filtering P(( struct gsm_state* S, word Ncr, word bcr, word * erp, /* [0..39] IN */ word * drp)); /* [-120..-1] IN, [0..40] OUT */ void Gsm_RPE_Decoding P(( struct gsm_state *S, word xmaxcr, word Mcr, word * xMcr, /* [0..12], 3 bits IN */ word * erp)); /* [0..39] OUT */ void Gsm_RPE_Encoding P(( struct gsm_state * S, word * e, /* -5..-1][0..39][40..44 IN/OUT */ word * xmaxc, /* OUT */ word * Mc, /* OUT */ word * xMc)); /* [0..12] OUT */ extern void Gsm_Short_Term_Synthesis_Filter P(( struct gsm_state * S, word * LARcr, /* log area ratios [0..7] IN */ word * drp, /* received d [0...39] IN */ word * s)); /* signal s [0..159] OUT */ extern void Gsm_Update_of_reconstructed_short_time_residual_signal P(( word * dpp, /* [0...39] IN */ word * ep, /* [0...39] IN */ word * dp)); /* [-120...-1] IN/OUT */ /* * Tables from table.c */ #ifndef GSM_TABLE_C extern word gsm_A[8], gsm_B[8], gsm_MIC[8], gsm_MAC[8]; extern word gsm_INVA[8]; extern word gsm_DLB[4], gsm_QLB[4]; extern word gsm_H[11]; extern word gsm_NRFAC[8]; extern word gsm_FAC[8]; #endif /* GSM_TABLE_C */ /* * Debugging */ #ifdef NDEBUG # define gsm_debug_words(a, b, c, d) /* nil */ # define gsm_debug_longwords(a, b, c, d) /* nil */ # define gsm_debug_word(a, b) /* nil */ # define gsm_debug_longword(a, b) /* nil */ #else /* !NDEBUG => DEBUG */ extern void gsm_debug_words P((char * name, int, int, word *)); extern void gsm_debug_longwords P((char * name, int, int, longword *)); extern void gsm_debug_longword P((char * name, longword)); extern void gsm_debug_word P((char * name, word)); #endif /* !NDEBUG */ #include "unproto.h" #endif /* PRIVATE_H */ rplay-3.3.2/gsm/proto.h100644 153 62 3075 6552756454 13446 0ustar boynsstaff/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /*$Header: /usr/local/cvsroot/rplay/gsm/proto.h,v 1.1.1.1 1998/07/14 22:35:24 mrb Exp $*/ #ifndef PROTO_H #define PROTO_H #if __cplusplus # define NeedFunctionPrototypes 1 #endif #if __STDC__ # define NeedFunctionPrototypes 1 #endif #ifdef _NO_PROTO # undef NeedFunctionPrototypes #endif #undef P /* gnu stdio.h actually defines this... */ #undef P0 #undef P1 #undef P2 #undef P3 #undef P4 #undef P5 #undef P6 #undef P7 #undef P8 #if NeedFunctionPrototypes # define P( protos ) protos # define P0() (void) # define P1(x, a) (a) # define P2(x, a, b) (a, b) # define P3(x, a, b, c) (a, b, c) # define P4(x, a, b, c, d) (a, b, c, d) # define P5(x, a, b, c, d, e) (a, b, c, d, e) # define P6(x, a, b, c, d, e, f) (a, b, c, d, e, f) # define P7(x, a, b, c, d, e, f, g) (a, b, c, d, e, f, g) # define P8(x, a, b, c, d, e, f, g, h) (a, b, c, d, e, f, g, h) #else /* !NeedFunctionPrototypes */ # define P( protos ) ( /* protos */ ) # define P0() () # define P1(x, a) x a; # define P2(x, a, b) x a; b; # define P3(x, a, b, c) x a; b; c; # define P4(x, a, b, c, d) x a; b; c; d; # define P5(x, a, b, c, d, e) x a; b; c; d; e; # define P6(x, a, b, c, d, e, f) x a; b; c; d; e; f; # define P7(x, a, b, c, d, e, f, g) x a; b; c; d; e; f; g; # define P8(x, a, b, c, d, e, f, g, h) x a; b; c; d; e; f; g; h; #endif /* !NeedFunctionPrototypes */ #endif /* PROTO_H */ rplay-3.3.2/gsm/rpe.c100644 153 62 25452 6552756454 13107 0ustar boynsstaff/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /usr/local/cvsroot/rplay/gsm/rpe.c,v 1.1.1.1 1998/07/14 22:35:24 mrb Exp $ */ #include #include #include "private.h" #include "gsm.h" #include "proto.h" /* 4.2.13 .. 4.2.17 RPE ENCODING SECTION */ /* 4.2.13 */ static void Weighting_filter P2((e, x), register word * e, /* signal [-5..0.39.44] IN */ word * x /* signal [0..39] OUT */ ) /* * The coefficients of the weighting filter are stored in a table * (see table 4.4). The following scaling is used: * * H[0..10] = integer( real_H[ 0..10] * 8192 ); */ { /* word wt[ 50 ]; */ register longword L_result; register int k /* , i */ ; /* Initialization of a temporary working array wt[0...49] */ /* for (k = 0; k <= 4; k++) wt[k] = 0; * for (k = 5; k <= 44; k++) wt[k] = *e++; * for (k = 45; k <= 49; k++) wt[k] = 0; * * (e[-5..-1] and e[40..44] are allocated by the caller, * are initially zero and are not written anywhere.) */ e -= 5; /* Compute the signal x[0..39] */ for (k = 0; k <= 39; k++) { L_result = 8192 >> 1; /* for (i = 0; i <= 10; i++) { * L_temp = GSM_L_MULT( wt[k+i], gsm_H[i] ); * L_result = GSM_L_ADD( L_result, L_temp ); * } */ #undef STEP #define STEP( i, H ) (e[ k + i ] * (longword)H) /* Every one of these multiplications is done twice -- * but I don't see an elegant way to optimize this. * Do you? */ #ifdef STUPID_COMPILER L_result += STEP( 0, -134 ) ; L_result += STEP( 1, -374 ) ; /* + STEP( 2, 0 ) */ L_result += STEP( 3, 2054 ) ; L_result += STEP( 4, 5741 ) ; L_result += STEP( 5, 8192 ) ; L_result += STEP( 6, 5741 ) ; L_result += STEP( 7, 2054 ) ; /* + STEP( 8, 0 ) */ L_result += STEP( 9, -374 ) ; L_result += STEP( 10, -134 ) ; #else L_result += STEP( 0, -134 ) + STEP( 1, -374 ) /* + STEP( 2, 0 ) */ + STEP( 3, 2054 ) + STEP( 4, 5741 ) + STEP( 5, 8192 ) + STEP( 6, 5741 ) + STEP( 7, 2054 ) /* + STEP( 8, 0 ) */ + STEP( 9, -374 ) + STEP(10, -134 ) ; #endif /* L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x2) *) * L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x4) *) * * x[k] = SASR( L_result, 16 ); */ /* 2 adds vs. >>16 => 14, minus one shift to compensate for * those we lost when replacing L_MULT by '*'. */ L_result = SASR( L_result, 13 ); x[k] = ( L_result < MIN_WORD ? MIN_WORD : (L_result > MAX_WORD ? MAX_WORD : L_result )); } } /* 4.2.14 */ static void RPE_grid_selection P3((x,xM,Mc_out), word * x, /* [0..39] IN */ word * xM, /* [0..12] OUT */ word * Mc_out /* OUT */ ) /* * The signal x[0..39] is used to select the RPE grid which is * represented by Mc. */ { /* register word temp1; */ register int /* m, */ i; register longword L_result, L_temp; longword EM; /* xxx should be L_EM? */ word Mc; longword L_common_0_3; EM = 0; Mc = 0; /* for (m = 0; m <= 3; m++) { * L_result = 0; * * * for (i = 0; i <= 12; i++) { * * temp1 = SASR( x[m + 3*i], 2 ); * * assert(temp1 != MIN_WORD); * * L_temp = GSM_L_MULT( temp1, temp1 ); * L_result = GSM_L_ADD( L_temp, L_result ); * } * * if (L_result > EM) { * Mc = m; * EM = L_result; * } * } */ #undef STEP #define STEP( m, i ) L_temp = SASR( x[m + 3 * i], 2 ); \ L_result += L_temp * L_temp; /* common part of 0 and 3 */ L_result = 0; STEP( 0, 1 ); STEP( 0, 2 ); STEP( 0, 3 ); STEP( 0, 4 ); STEP( 0, 5 ); STEP( 0, 6 ); STEP( 0, 7 ); STEP( 0, 8 ); STEP( 0, 9 ); STEP( 0, 10); STEP( 0, 11); STEP( 0, 12); L_common_0_3 = L_result; /* i = 0 */ STEP( 0, 0 ); L_result <<= 1; /* implicit in L_MULT */ EM = L_result; /* i = 1 */ L_result = 0; STEP( 1, 0 ); STEP( 1, 1 ); STEP( 1, 2 ); STEP( 1, 3 ); STEP( 1, 4 ); STEP( 1, 5 ); STEP( 1, 6 ); STEP( 1, 7 ); STEP( 1, 8 ); STEP( 1, 9 ); STEP( 1, 10); STEP( 1, 11); STEP( 1, 12); L_result <<= 1; if (L_result > EM) { Mc = 1; EM = L_result; } /* i = 2 */ L_result = 0; STEP( 2, 0 ); STEP( 2, 1 ); STEP( 2, 2 ); STEP( 2, 3 ); STEP( 2, 4 ); STEP( 2, 5 ); STEP( 2, 6 ); STEP( 2, 7 ); STEP( 2, 8 ); STEP( 2, 9 ); STEP( 2, 10); STEP( 2, 11); STEP( 2, 12); L_result <<= 1; if (L_result > EM) { Mc = 2; EM = L_result; } /* i = 3 */ L_result = L_common_0_3; STEP( 3, 12 ); L_result <<= 1; if (L_result > EM) { Mc = 3; EM = L_result; } /**/ /* Down-sampling by a factor 3 to get the selected xM[0..12] * RPE sequence. */ for (i = 0; i <= 12; i ++) xM[i] = x[Mc + 3*i]; *Mc_out = Mc; } /* 4.12.15 */ static void APCM_quantization_xmaxc_to_exp_mant P3((xmaxc,exp_out,mant_out), word xmaxc, /* IN */ word * exp_out, /* OUT */ word * mant_out ) /* OUT */ { word exp, mant; /* Compute exponent and mantissa of the decoded version of xmaxc */ exp = 0; if (xmaxc > 15) exp = SASR(xmaxc, 3) - 1; mant = xmaxc - (exp << 3); if (mant == 0) { exp = -4; mant = 7; } else { while (mant <= 7) { mant = mant << 1 | 1; exp--; } mant -= 8; } assert( exp >= -4 && exp <= 6 ); assert( mant >= 0 && mant <= 7 ); *exp_out = exp; *mant_out = mant; } static void APCM_quantization P5((xM,xMc,mant_out,exp_out,xmaxc_out), word * xM, /* [0..12] IN */ word * xMc, /* [0..12] OUT */ word * mant_out, /* OUT */ word * exp_out, /* OUT */ word * xmaxc_out /* OUT */ ) { int i, itest; word xmax, xmaxc, temp, temp1, temp2; word exp, mant; /* Find the maximum absolute value xmax of xM[0..12]. */ xmax = 0; for (i = 0; i <= 12; i++) { temp = xM[i]; temp = GSM_ABS(temp); if (temp > xmax) xmax = temp; } /* Qantizing and coding of xmax to get xmaxc. */ exp = 0; temp = SASR( xmax, 9 ); itest = 0; for (i = 0; i <= 5; i++) { itest |= (temp <= 0); temp = SASR( temp, 1 ); assert(exp <= 5); if (itest == 0) exp++; /* exp = add (exp, 1) */ } assert(exp <= 6 && exp >= 0); temp = exp + 5; assert(temp <= 11 && temp >= 0); xmaxc = gsm_add( SASR(xmax, temp), exp << 3 ); /* Quantizing and coding of the xM[0..12] RPE sequence * to get the xMc[0..12] */ APCM_quantization_xmaxc_to_exp_mant( xmaxc, &exp, &mant ); /* This computation uses the fact that the decoded version of xmaxc * can be calculated by using the exponent and the mantissa part of * xmaxc (logarithmic table). * So, this method avoids any division and uses only a scaling * of the RPE samples by a function of the exponent. A direct * multiplication by the inverse of the mantissa (NRFAC[0..7] * found in table 4.5) gives the 3 bit coded version xMc[0..12] * of the RPE samples. */ /* Direct computation of xMc[0..12] using table 4.5 */ assert( exp <= 4096 && exp >= -4096); assert( mant >= 0 && mant <= 7 ); temp1 = 6 - exp; /* normalization by the exponent */ temp2 = gsm_NRFAC[ mant ]; /* inverse mantissa */ for (i = 0; i <= 12; i++) { assert(temp1 >= 0 && temp1 < 16); temp = xM[i] << temp1; temp = GSM_MULT( temp, temp2 ); temp = SASR(temp, 12); xMc[i] = temp + 4; /* see note below */ } /* NOTE: This equation is used to make all the xMc[i] positive. */ *mant_out = mant; *exp_out = exp; *xmaxc_out = xmaxc; } /* 4.2.16 */ static void APCM_inverse_quantization P4((xMc,mant,exp,xMp), register word * xMc, /* [0..12] IN */ word mant, word exp, register word * xMp) /* [0..12] OUT */ /* * This part is for decoding the RPE sequence of coded xMc[0..12] * samples to obtain the xMp[0..12] array. Table 4.6 is used to get * the mantissa of xmaxc (FAC[0..7]). */ { int i; word temp, temp1, temp2, temp3; longword ltmp; assert( mant >= 0 && mant <= 7 ); temp1 = gsm_FAC[ mant ]; /* see 4.2-15 for mant */ temp2 = gsm_sub( 6, exp ); /* see 4.2-15 for exp */ temp3 = gsm_asl( 1, gsm_sub( temp2, 1 )); for (i = 13; i--;) { assert( *xMc <= 7 && *xMc >= 0 ); /* 3 bit unsigned */ /* temp = gsm_sub( *xMc++ << 1, 7 ); */ temp = (*xMc++ << 1) - 7; /* restore sign */ assert( temp <= 7 && temp >= -7 ); /* 4 bit signed */ temp <<= 12; /* 16 bit signed */ temp = GSM_MULT_R( temp1, temp ); temp = GSM_ADD( temp, temp3 ); *xMp++ = gsm_asr( temp, temp2 ); } } /* 4.2.17 */ static void RPE_grid_positioning P3((Mc,xMp,ep), word Mc, /* grid position IN */ register word * xMp, /* [0..12] IN */ register word * ep /* [0..39] OUT */ ) /* * This procedure computes the reconstructed long term residual signal * ep[0..39] for the LTP analysis filter. The inputs are the Mc * which is the grid position selection and the xMp[0..12] decoded * RPE samples which are upsampled by a factor of 3 by inserting zero * values. */ { int i = 13; assert(0 <= Mc && Mc <= 3); switch (Mc) { case 3: *ep++ = 0; case 2: do { *ep++ = 0; case 1: *ep++ = 0; case 0: *ep++ = *xMp++; } while (--i); } while (++Mc < 4) *ep++ = 0; /* int i, k; for (k = 0; k <= 39; k++) ep[k] = 0; for (i = 0; i <= 12; i++) { ep[ Mc + (3*i) ] = xMp[i]; } */ } /* 4.2.18 */ /* This procedure adds the reconstructed long term residual signal * ep[0..39] to the estimated signal dpp[0..39] from the long term * analysis filter to compute the reconstructed short term residual * signal dp[-40..-1]; also the reconstructed short term residual * array dp[-120..-41] is updated. */ #if 0 /* Has been inlined in code.c */ void Gsm_Update_of_reconstructed_short_time_residual_signal P3((dpp, ep, dp), word * dpp, /* [0...39] IN */ word * ep, /* [0...39] IN */ word * dp) /* [-120...-1] IN/OUT */ { int k; for (k = 0; k <= 79; k++) dp[ -120 + k ] = dp[ -80 + k ]; for (k = 0; k <= 39; k++) dp[ -40 + k ] = gsm_add( ep[k], dpp[k] ); } #endif /* Has been inlined in code.c */ void Gsm_RPE_Encoding P5((S,e,xmaxc,Mc,xMc), struct gsm_state * S, word * e, /* -5..-1][0..39][40..44 IN/OUT */ word * xmaxc, /* OUT */ word * Mc, /* OUT */ word * xMc) /* [0..12] OUT */ { word x[40]; word xM[13], xMp[13]; word mant, exp; Weighting_filter(e, x); RPE_grid_selection(x, xM, Mc); APCM_quantization( xM, xMc, &mant, &exp, xmaxc); APCM_inverse_quantization( xMc, mant, exp, xMp); RPE_grid_positioning( *Mc, xMp, e ); } void Gsm_RPE_Decoding P5((S, xmaxcr, Mcr, xMcr, erp), struct gsm_state * S, word xmaxcr, word Mcr, word * xMcr, /* [0..12], 3 bits IN */ word * erp /* [0..39] OUT */ ) { word exp, mant; word xMp[ 13 ]; APCM_quantization_xmaxc_to_exp_mant( xmaxcr, &exp, &mant ); APCM_inverse_quantization( xMcr, mant, exp, xMp ); RPE_grid_positioning( Mcr, xMp, erp ); } rplay-3.3.2/gsm/short_term.c100644 153 62 24230 6552756454 14500 0ustar boynsstaff/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /usr/local/cvsroot/rplay/gsm/short_term.c,v 1.1.1.1 1998/07/14 22:35:24 mrb Exp $ */ #include #include #include "private.h" #include "gsm.h" #include "proto.h" /* * SHORT TERM ANALYSIS FILTERING SECTION */ /* 4.2.8 */ static void Decoding_of_the_coded_Log_Area_Ratios P2((LARc,LARpp), word * LARc, /* coded log area ratio [0..7] IN */ word * LARpp) /* out: decoded .. */ { register word temp1 /* , temp2 */; register long ltmp; /* for GSM_ADD */ /* This procedure requires for efficient implementation * two tables. * * INVA[1..8] = integer( (32768 * 8) / real_A[1..8]) * MIC[1..8] = minimum value of the LARc[1..8] */ /* Compute the LARpp[1..8] */ /* for (i = 1; i <= 8; i++, B++, MIC++, INVA++, LARc++, LARpp++) { * * temp1 = GSM_ADD( *LARc, *MIC ) << 10; * temp2 = *B << 1; * temp1 = GSM_SUB( temp1, temp2 ); * * assert(*INVA != MIN_WORD); * * temp1 = GSM_MULT_R( *INVA, temp1 ); * *LARpp = GSM_ADD( temp1, temp1 ); * } */ #undef STEP #define STEP( B, MIC, INVA ) \ temp1 = GSM_ADD( *LARc++, MIC ) << 10; \ temp1 = GSM_SUB( temp1, B << 1 ); \ temp1 = GSM_MULT_R( INVA, temp1 ); \ *LARpp++ = GSM_ADD( temp1, temp1 ); STEP( 0, -32, 13107 ); STEP( 0, -32, 13107 ); STEP( 2048, -16, 13107 ); STEP( -2560, -16, 13107 ); STEP( 94, -8, 19223 ); STEP( -1792, -8, 17476 ); STEP( -341, -4, 31454 ); STEP( -1144, -4, 29708 ); /* NOTE: the addition of *MIC is used to restore * the sign of *LARc. */ } /* 4.2.9 */ /* Computation of the quantized reflection coefficients */ /* 4.2.9.1 Interpolation of the LARpp[1..8] to get the LARp[1..8] */ /* * Within each frame of 160 analyzed speech samples the short term * analysis and synthesis filters operate with four different sets of * coefficients, derived from the previous set of decoded LARs(LARpp(j-1)) * and the actual set of decoded LARs (LARpp(j)) * * (Initial value: LARpp(j-1)[1..8] = 0.) */ static void Coefficients_0_12 P3((LARpp_j_1, LARpp_j, LARp), register word * LARpp_j_1, register word * LARpp_j, register word * LARp) { register int i; register longword ltmp; for (i = 1; i <= 8; i++, LARp++, LARpp_j_1++, LARpp_j++) { *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 )); *LARp = GSM_ADD( *LARp, SASR( *LARpp_j_1, 1)); } } static void Coefficients_13_26 P3((LARpp_j_1, LARpp_j, LARp), register word * LARpp_j_1, register word * LARpp_j, register word * LARp) { register int i; register longword ltmp; for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) { *LARp = GSM_ADD( SASR( *LARpp_j_1, 1), SASR( *LARpp_j, 1 )); } } static void Coefficients_27_39 P3((LARpp_j_1, LARpp_j, LARp), register word * LARpp_j_1, register word * LARpp_j, register word * LARp) { register int i; register longword ltmp; for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) { *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 )); *LARp = GSM_ADD( *LARp, SASR( *LARpp_j, 1 )); } } static void Coefficients_40_159 P2((LARpp_j, LARp), register word * LARpp_j, register word * LARp) { register int i; for (i = 1; i <= 8; i++, LARp++, LARpp_j++) *LARp = *LARpp_j; } /* 4.2.9.2 */ static void LARp_to_rp P1((LARp), register word * LARp) /* [0..7] IN/OUT */ /* * The input of this procedure is the interpolated LARp[0..7] array. * The reflection coefficients, rp[i], are used in the analysis * filter and in the synthesis filter. */ { register int i; register word temp; register longword ltmp; for (i = 1; i <= 8; i++, LARp++) { /* temp = GSM_ABS( *LARp ); * * if (temp < 11059) temp <<= 1; * else if (temp < 20070) temp += 11059; * else temp = GSM_ADD( temp >> 2, 26112 ); * * *LARp = *LARp < 0 ? -temp : temp; */ if (*LARp < 0) { temp = *LARp == MIN_WORD ? MAX_WORD : -(*LARp); *LARp = - ((temp < 11059) ? temp << 1 : ((temp < 20070) ? temp + 11059 : GSM_ADD( temp >> 2, 26112 ))); } else { temp = *LARp; *LARp = (temp < 11059) ? temp << 1 : ((temp < 20070) ? temp + 11059 : GSM_ADD( temp >> 2, 26112 )); } } } /* 4.2.10 */ static void Short_term_analysis_filtering P4((S,rp,k_n,s), struct gsm_state * S, register word * rp, /* [0..7] IN */ register int k_n, /* k_end - k_start */ register word * s /* [0..n-1] IN/OUT */ ) /* * This procedure computes the short term residual signal d[..] to be fed * to the RPE-LTP loop from the s[..] signal and from the local rp[..] * array (quantized reflection coefficients). As the call of this * procedure can be done in many ways (see the interpolation of the LAR * coefficient), it is assumed that the computation begins with index * k_start (for arrays d[..] and s[..]) and stops with index k_end * (k_start and k_end are defined in 4.2.9.1). This procedure also * needs to keep the array u[0..7] in memory for each call. */ { register word * u = S->u; register int i; register word di, zzz, ui, sav, rpi; register longword ltmp; for (; k_n--; s++) { di = sav = *s; for (i = 0; i < 8; i++) { /* YYY */ ui = u[i]; rpi = rp[i]; u[i] = sav; zzz = GSM_MULT_R(rpi, di); sav = GSM_ADD( ui, zzz); zzz = GSM_MULT_R(rpi, ui); di = GSM_ADD( di, zzz ); } *s = di; } } #if defined(USE_FLOAT_MUL) && defined(FAST) static void Fast_Short_term_analysis_filtering P4((S,rp,k_n,s), struct gsm_state * S, register word * rp, /* [0..7] IN */ register int k_n, /* k_end - k_start */ register word * s /* [0..n-1] IN/OUT */ ) { register word * u = S->u; register int i; float uf[8], rpf[8]; register float scalef = 3.0517578125e-5; register float sav, di, temp; for (i = 0; i < 8; ++i) { uf[i] = u[i]; rpf[i] = rp[i] * scalef; } for (; k_n--; s++) { sav = di = *s; for (i = 0; i < 8; ++i) { register float rpfi = rpf[i]; register float ufi = uf[i]; uf[i] = sav; temp = rpfi * di + ufi; di += rpfi * ufi; sav = temp; } *s = di; } for (i = 0; i < 8; ++i) u[i] = uf[i]; } #endif /* ! (defined (USE_FLOAT_MUL) && defined (FAST)) */ static void Short_term_synthesis_filtering P5((S,rrp,k,wt,sr), struct gsm_state * S, register word * rrp, /* [0..7] IN */ register int k, /* k_end - k_start */ register word * wt, /* [0..k-1] IN */ register word * sr /* [0..k-1] OUT */ ) { register word * v = S->v; register int i; register word sri, tmp1, tmp2; register longword ltmp; /* for GSM_ADD & GSM_SUB */ while (k--) { sri = *wt++; for (i = 8; i--;) { /* sri = GSM_SUB( sri, gsm_mult_r( rrp[i], v[i] ) ); */ tmp1 = rrp[i]; tmp2 = v[i]; tmp2 = ( tmp1 == MIN_WORD && tmp2 == MIN_WORD ? MAX_WORD : 0x0FFFF & (( (longword)tmp1 * (longword)tmp2 + 16384) >> 15)) ; sri = GSM_SUB( sri, tmp2 ); /* v[i+1] = GSM_ADD( v[i], gsm_mult_r( rrp[i], sri ) ); */ tmp1 = ( tmp1 == MIN_WORD && sri == MIN_WORD ? MAX_WORD : 0x0FFFF & (( (longword)tmp1 * (longword)sri + 16384) >> 15)) ; v[i+1] = GSM_ADD( v[i], tmp1); } *sr++ = v[0] = sri; } } #if defined(FAST) && defined(USE_FLOAT_MUL) static void Fast_Short_term_synthesis_filtering P5((S,rrp,k,wt,sr), struct gsm_state * S, register word * rrp, /* [0..7] IN */ register int k, /* k_end - k_start */ register word * wt, /* [0..k-1] IN */ register word * sr /* [0..k-1] OUT */ ) { register word * v = S->v; register int i; float va[9], rrpa[8]; register float scalef = 3.0517578125e-5, temp; for (i = 0; i < 8; ++i) { va[i] = v[i]; rrpa[i] = (float)rrp[i] * scalef; } while (k--) { register float sri = *wt++; for (i = 8; i--;) { sri -= rrpa[i] * va[i]; if (sri < -32768.) sri = -32768.; else if (sri > 32767.) sri = 32767.; temp = va[i] + rrpa[i] * sri; if (temp < -32768.) temp = -32768.; else if (temp > 32767.) temp = 32767.; va[i+1] = temp; } *sr++ = va[0] = sri; } for (i = 0; i < 9; ++i) v[i] = va[i]; } #endif /* defined(FAST) && defined(USE_FLOAT_MUL) */ void Gsm_Short_Term_Analysis_Filter P3((S,LARc,s), struct gsm_state * S, word * LARc, /* coded log area ratio [0..7] IN */ word * s /* signal [0..159] IN/OUT */ ) { word * LARpp_j = S->LARpp[ S->j ]; word * LARpp_j_1 = S->LARpp[ S->j ^= 1 ]; word LARp[8]; #undef FILTER #if defined(FAST) && defined(USE_FLOAT_MUL) # define FILTER (* (S->fast \ ? Fast_Short_term_analysis_filtering \ : Short_term_analysis_filtering )) #else # define FILTER Short_term_analysis_filtering #endif Decoding_of_the_coded_Log_Area_Ratios( LARc, LARpp_j ); Coefficients_0_12( LARpp_j_1, LARpp_j, LARp ); LARp_to_rp( LARp ); FILTER( S, LARp, 13, s); Coefficients_13_26( LARpp_j_1, LARpp_j, LARp); LARp_to_rp( LARp ); FILTER( S, LARp, 14, s + 13); Coefficients_27_39( LARpp_j_1, LARpp_j, LARp); LARp_to_rp( LARp ); FILTER( S, LARp, 13, s + 27); Coefficients_40_159( LARpp_j, LARp); LARp_to_rp( LARp ); FILTER( S, LARp, 120, s + 40); } void Gsm_Short_Term_Synthesis_Filter P4((S, LARcr, wt, s), struct gsm_state * S, word * LARcr, /* received log area ratios [0..7] IN */ word * wt, /* received d [0..159] IN */ word * s /* signal s [0..159] OUT */ ) { word * LARpp_j = S->LARpp[ S->j ]; word * LARpp_j_1 = S->LARpp[ S->j ^=1 ]; word LARp[8]; #undef FILTER #if defined(FAST) && defined(USE_FLOAT_MUL) # define FILTER (* (S->fast \ ? Fast_Short_term_synthesis_filtering \ : Short_term_synthesis_filtering )) #else # define FILTER Short_term_synthesis_filtering #endif Decoding_of_the_coded_Log_Area_Ratios( LARcr, LARpp_j ); Coefficients_0_12( LARpp_j_1, LARpp_j, LARp ); LARp_to_rp( LARp ); FILTER( S, LARp, 13, wt, s ); Coefficients_13_26( LARpp_j_1, LARpp_j, LARp); LARp_to_rp( LARp ); FILTER( S, LARp, 14, wt + 13, s + 13 ); Coefficients_27_39( LARpp_j_1, LARpp_j, LARp); LARp_to_rp( LARp ); FILTER( S, LARp, 13, wt + 27, s + 27 ); Coefficients_40_159( LARpp_j, LARp ); LARp_to_rp( LARp ); FILTER(S, LARp, 120, wt + 40, s + 40); } rplay-3.3.2/gsm/table.c100644 153 62 4131 6552756454 13357 0ustar boynsstaff/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /usr/local/cvsroot/rplay/gsm/table.c,v 1.1.1.1 1998/07/14 22:35:24 mrb Exp $ */ /* Most of these tables are inlined at their point of use. */ /* 4.4 TABLES USED IN THE FIXED POINT IMPLEMENTATION OF THE RPE-LTP * CODER AND DECODER * * (Most of them inlined, so watch out.) */ #define GSM_TABLE_C #include "private.h" #include "gsm.h" /* Table 4.1 Quantization of the Log.-Area Ratios */ /* i 1 2 3 4 5 6 7 8 */ word gsm_A[8] = {20480, 20480, 20480, 20480, 13964, 15360, 8534, 9036}; word gsm_B[8] = { 0, 0, 2048, -2560, 94, -1792, -341, -1144}; word gsm_MIC[8] = { -32, -32, -16, -16, -8, -8, -4, -4 }; word gsm_MAC[8] = { 31, 31, 15, 15, 7, 7, 3, 3 }; /* Table 4.2 Tabulation of 1/A[1..8] */ word gsm_INVA[8]={ 13107, 13107, 13107, 13107, 19223, 17476, 31454, 29708 }; /* Table 4.3a Decision level of the LTP gain quantizer */ /* bc 0 1 2 3 */ word gsm_DLB[4] = { 6554, 16384, 26214, 32767 }; /* Table 4.3b Quantization levels of the LTP gain quantizer */ /* bc 0 1 2 3 */ word gsm_QLB[4] = { 3277, 11469, 21299, 32767 }; /* Table 4.4 Coefficients of the weighting filter */ /* i 0 1 2 3 4 5 6 7 8 9 10 */ word gsm_H[11] = {-134, -374, 0, 2054, 5741, 8192, 5741, 2054, 0, -374, -134 }; /* Table 4.5 Normalized inverse mantissa used to compute xM/xmax */ /* i 0 1 2 3 4 5 6 7 */ word gsm_NRFAC[8] = { 29128, 26215, 23832, 21846, 20165, 18725, 17476, 16384 }; /* Table 4.6 Normalized direct mantissa used to compute xM/xmax */ /* i 0 1 2 3 4 5 6 7 */ word gsm_FAC[8] = { 18431, 20479, 22527, 24575, 26623, 28671, 30719, 32767 }; rplay-3.3.2/gsm/toast.1100644 153 62 7513 6552756454 13347 0ustar boynsstaff.\" .\" Copyright 1992 by Jutta Degener and Carsten Bormann, Technische .\" Universitaet Berlin. See the accompanying file "COPYRIGHT" for .\" details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. .\" .if n .ds mU u .if t .ds mU \(*m .\" .PU .TH TOAST 1 local .SH NAME toast \(em GSM\ 06.10 lossy sound compression .SH SYNOPSIS .ll +8 .B toast [ .B \-cdfpvhualsFC ] [ .I "filename...\&" ] .LP .B untoast [ .B \-cfpvhuaslF ] [ .I "filename...\&" ] .LP .B tcat [ .B \-vhuaslF ] [ .I "filename...\&" ] .ll -8 .SH DESCRIPTION Toast compresses the sound files given on its command line. Each file is replaced by a file with the extension .I \&.gsm . If no files are specified, the compression is applied to the standard input, and its result is written to standard output. .PP Toasted files can be restored to something not quite unlike their original form by running toast .I "\-d" , or .I untoast , on the \&.gsm-files or standard input. .PP The program .I tcat (the same as running .I "untoast \-c" ) uncompresses its input on standard output, but leaves the compressed .gsm\-files alone. .PP When files are compressed or uncompressed into other files, the ownership (if run by root), modes, accessed and modified times are maintained between both versions. .SH OPTIONS .TP .B \-c (cat) Write to the standard output; no files are changed. .TP .B \-d (decode) Decode, rather than encode, the files. .TP .B \-f (force) Force replacement of output files if they exist. If \-f is omitted and toast (or untoast) is run interactively from a terminal, the user is prompted as to whether the file should be replaced. .TP .B \-p (precious) Do not delete the source files. Source files are implicitly left alone whenever \-c is specified or tcat is run. .TP .B \-C (LTP cut-off) Ignore most sample values when calculating the GSM long-term correlation lag during encoding. (The multiplications that do this are a bottleneck of the algorithm.) The resulting encoding process will not produce exactly the same results as GSM 06.10 would, but remains close enough to be compatible. .br The .B \-C option applies only to the encoder and is silently ignored by the decoder. .TP .B \-F (fast) On systems with a floating point processor, but without a multiplication instruction, \-F sacrifices standard conformance to performance and nearly doubles the speed of the algorithm. .br The resulting encoding and decoding process will not produce exactly the same results as GSM 06.10 would, but remains close enough to be compatible. .br The default is standard-conforming operation. .TP .B \-v (version)\ outputs the version of toast (or untoast or tcat) to stdout and exits. .TP .B \-h (help)\ prints a short overview of the options. .PP Toast, untoast and tcat try to guess the appropriate audio data format from the file suffix. Command line options can also specify a format to be used for all files. .br The following formats are supported: .TP .B "\-u" (\(*mU-law) 8 kHz, 8 bit \(*mU-law encoding (file suffix .u) .TP .B "\-a" (A-law) 8 kHz, 8 bit A-law encoding (file suffix .A) .TP .B "\-s" (Sun audio) 8 kHz, 8 bit \(*mU-law encoding with audio header (file suffix .au) .TP .B "-l" (linear) 8 kHz, 16 bit signed linear encoding in host byte order with 13 significant bits (file suffix .l) .PP In absence of options or suffixes to specify a format, \(*mU-law encoding as forced by \-u is assumed. .PP .SH PECULIARITIES A four bit magic number is prefixed to each 32 1/2-byte GSM frame, mainly because 32 1/2-bytes are rather clumsy to handle. .SH WARNING The compression algorithm used is a lossy compression algorithm devised especially for speech; on no account should it be used for text, pictures or any other non-speech-data you consider valuable. .SH BUGS Please direct bug reports to jutta@cs.tu-berlin.de. .SH "SEE ALSO" gsm(3) .\" .\" Toast is dedicated to Bill Sienkiewicz, author of "Stray Toasters". rplay-3.3.2/gsm/toast.c100644 153 62 42307 6552756454 13451 0ustar boynsstaff/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /usr/local/cvsroot/rplay/gsm/toast.c,v 1.1.1.1 1998/07/14 22:35:24 mrb Exp $ */ #include "toast.h" /* toast -- lossy sound compression using the gsm library. */ char * progname; int f_decode = 0; /* decode rather than encode (-d) */ int f_cat = 0; /* write to stdout, not foo.gsm (-c) */ int f_force = 0; /* force deletion (-f) */ int f_precious = 0; /* avoid deletion (-p) */ int f_fast = 0; /* use faster fpt algorithm (-F) */ int f_verbose = 0; /* debugging (-V) */ int f_ltp_cut = 0; /* LTP cut-off margin (-C) */ struct stat instat; /* stat (inname) */ FILE *in, *out; char *inname, *outname; /* * The function (*output)() writes a frame of 160 samples given as * 160 signed 16 bit values (gsm_signals) to . * The function (*input)() reads one such frame from . * The function (*init_output)() begins output (e.g. writes a header)., * The function (*init_input)() begins input (e.g. skips a header). * * There are different versions of input, output, init_input and init_output * for different formats understood by toast; which ones are used * depends on the command line arguments and, in their absence, the * filename; the fallback is #defined in toast.h * * The specific implementations of input, output, init_input and init_output * for a format `foo' live in toast_foo.c. */ int (*output ) P((gsm_signal *)), (*input ) P((gsm_signal *)); int (*init_input) P((void)), (*init_output) P((void)); static int generic_init P0() { return 0; } /* NOP */ struct fmtdesc { char * name, * longname, * suffix; int (* init_input ) P((void)), (* init_output) P((void)); int (* input ) P((gsm_signal * )), (* output) P((gsm_signal * )); } f_audio = { "audio", "8 kHz, 8 bit u-law encoding with Sun audio header", ".au", audio_init_input, audio_init_output, ulaw_input, ulaw_output }, f_ulaw = { "u-law", "plain 8 kHz, 8 bit u-law encoding", ".u", generic_init, generic_init, ulaw_input, ulaw_output }, f_alaw = { "A-law", "8 kHz, 8 bit A-law encoding", ".A", generic_init, generic_init, alaw_input, alaw_output }, f_linear = { "linear", "16 bit (13 significant) signed 8 kHz signal", ".l", generic_init, generic_init, linear_input, linear_output }; struct fmtdesc * alldescs[] = { &f_audio, &f_alaw, &f_ulaw, &f_linear, (struct fmtdesc *)NULL }; #define DEFAULT_FORMAT f_ulaw /* default audio format, others */ /* are: f_alaw,f_audio,f_linear */ struct fmtdesc * f_format = 0; /* * basename + suffix of a pathname */ static char * endname P1((name), char * name) { if (name) { char * s = strrchr(name, '/'); if (s && s[1]) name = s + 1; } return name; } /* * Try to figure out what we're supposed to do from the argv[0], if * any, and set the parameters accordingly. */ static void parse_argv0 P1((av0), char * av0 ) { int l; progname = av0 = endname(av0 ? av0 : "toast"); /* If the name starts with `un', we want to decode, not code. * If the name ends in `cat', we want to write to stdout, * and decode as well. */ if (!strncmp(av0, "un", 2)) f_decode = 1; if ( (l = strlen(av0)) >= 3 /* strlen("cat") */ && !strcmp( av0 + l - 3, "cat" )) f_cat = f_decode = 1; } /* * Check whether the name (possibly generated by appending * .gsm to something else) is short enough for this system. */ static int length_okay P1((name), char * name) { long max_filename_length = 0; char * end; /* If our _pathname_ is too long, we'll usually not be * able to open the file at all -- don't worry about that. * * But if the _filename_ is too long, there is danger of * silent truncation on some systems, which results * in the target replacing the source! */ if (!name) return 0; end = endname(name); #ifdef NAME_MAX max_filename_length = NAME_MAX; #else #ifdef _PC_NAME_MAX #ifdef USE_PATHCONF { char * s, tmp; /* s = dirname(name) */ if ((s = end) > name) { if (s > name + 1) s--; tmp = s; *s = 0; } errno = 0; max_filename_length = pathconf(s > name ? name : ".", _PC_NAME_MAX); if (max_filename_length == -1 && errno) { perror( s > name ? name : "." ); fprintf(stderr, "%s: cannot get dynamic filename length limit for %s.\n", progname, s > name ? name : "."); return 0; } if (s > name) *s = tmp; } #endif /* USE_PATHCONF */ #endif /* _PC_NAME_MAX */ #endif /* !NAME_MAX */ if (max_filename_length > 0 && strlen(end) > max_filename_length) { fprintf(stderr, "%s: filename \"%s\" is too long (maximum is %ld)\n", progname, endname(name), max_filename_length ); return 0; } return 1; } /* * Return a pointer the suffix of a string, if any. * A suffix alone has no suffix, an empty suffix can not be had. */ static char * suffix P2((name, suf), char *name, char * suf) { size_t nlen = strlen(name); size_t slen = strlen(suf); if (!slen || nlen <= slen) return (char *)0; name += nlen - slen; return memcmp(name, suf, slen) ? (char *)0 : name; } static void catch_signals P1((fun), SIGHANDLER_T (*fun) ()) { #ifdef SIGHUP signal( SIGHUP, fun ); #endif #ifdef SIGINT signal( SIGINT, fun ); #endif #ifdef SIGPIPE signal( SIGPIPE, fun ); #endif #ifdef SIGTERM signal( SIGTERM, fun ); #endif #ifdef SIGXFSZ signal( SIGXFSZ, fun ); #endif } static SIGHANDLER_T onintr P0() { char * tmp = outname; #ifdef HAS_SYSV_SIGNALS catch_signals( SIG_IGN ); #endif outname = (char *)0; if (tmp) (void)unlink(tmp); exit(1); } /* * Allocate some memory and complain if it fails. */ static char * emalloc P1((len), size_t len) { char * s; if (!(s = malloc(len))) { fprintf(stderr, "%s: failed to malloc %d bytes -- abort\n", progname, len); onintr(); exit(1); } return s; } static char* normalname P3((name, want, cut), char *name, char *want,char *cut) { size_t maxlen; char * s, * p; p = (char *)0; if (!name) return p; maxlen = strlen(name) + 1 + strlen(want) + strlen(cut); p = strcpy(emalloc(maxlen), name); if (s = suffix(p, cut)) strcpy(s, want); else if (*want && !suffix(p, want)) strcat(p, want); return p; } /* * Generate a `plain' (non-encoded) name from a given name. */ static char * plainname P1((name), char *name) { return normalname(name, "", SUFFIX_TOASTED ); } /* * Generate a `code' name from a given name. */ static char * codename P1((name), char *name) { return normalname( name, SUFFIX_TOASTED, "" ); } /* * If we're supposed to ask (fileno (stderr) is a tty, and f_force not * set), ask the user whether to overwrite a file or not. */ static int ok_to_replace P1(( name ), char * name) { int reply, c; if (f_force) return 1; /* YES, do replace */ if (!isatty(fileno(stderr))) return 0; /* NO, don't replace */ fprintf(stderr, "%s already exists; do you wish to overwrite %s (y or n)? ", name, name); fflush(stderr); for (c = reply = getchar(); c != '\n' && c != EOF; c = getchar()) ; if (reply == 'y') return 1; fprintf(stderr, "\tnot overwritten\n"); return 0; } static void update_mode P0() { if (!instat.st_nlink) return; /* couldn't stat in */ #ifdef HAS_FCHMOD if (fchmod(fileno(out), instat.st_mode & 07777)) { perror(outname); fprintf(stderr, "%s: could not change file mode of \"%s\"\n", progname, outname); } #else if (outname && chmod(outname, instat.st_mode & 07777)) { perror(outname); fprintf(stderr, "%s: could not change file mode of \"%s\"\n", progname, outname); } #endif /* HAS_FCHMOD */ } static void update_own P0() { if (!instat.st_nlink) return; /* couldn't stat in */ #ifdef HAS_FCHOWN (void)fchown(fileno(out), instat.st_uid, instat.st_gid); #else (void)chown(outname, instat.st_uid, instat.st_gid); #endif /* HAS_FCHOWN */ } static void update_times P0() { if (!instat.st_nlink) return; /* couldn't stat in */ #ifdef HAS_UTIMES if (outname) { struct timeval tv[2]; tv[0].tv_sec = instat.st_atime; tv[1].tv_sec = instat.st_mtime; tv[0].tv_usec = tv[1].tv_usec = 0; (void) utimes(outname, tv); } #else #ifdef HAS_UTIME if (outname) { #ifdef HAS_UTIMBUF struct utimbuf ut; ut.actime = instat.st_atime; ut.modtime = instat.st_mtime; # ifdef HAS_UTIMEUSEC ut.acusec = instat.st_ausec; ut.modusec = instat.st_musec; # endif /* HAS_UTIMEUSEC */ (void) utime(outname, &ut); #else /* UTIMBUF */ time_t ut[2]; ut[0] = instat.st_atime; ut[1] = instat.st_mtime; (void) utime(outname, ut); #endif /* UTIMBUF */ } #endif /* HAS_UTIME */ #endif /* HAS_UTIMES */ } static int okay_as_input P3((name,f,st), char* name, FILE* f, struct stat * st) { # ifdef HAS_FSTAT if (fstat(fileno(f), st) < 0) # else if (stat(name, st) < 0) # endif { perror(name); fprintf(stderr, "%s: cannot stat \"%s\"\n", progname, name); return 0; } if (!S_ISREG(st->st_mode)) { fprintf(stderr, "%s: \"%s\" is not a regular file -- unchanged.\n", progname, name); return 0; } if (st->st_nlink > 1 && !f_cat && !f_precious) { fprintf(stderr, "%s: \"%s\" has %s other link%s -- unchanged.\n", progname,name,st->st_nlink - 1,"s" + (st->st_nlink<=2)); return 0; } return 1; } static void prepare_io P1(( desc), struct fmtdesc * desc) { output = desc->output; input = desc->input; init_input = desc->init_input; init_output = desc->init_output; } static struct fmtdesc * grok_format P1((name), char * name) { char * c; struct fmtdesc ** f; if (name) { c = plainname(name); for (f = alldescs; *f; f++) { if ( (*f)->suffix && *(*f)->suffix && suffix(c, (*f)->suffix)) { free(c); return *f; } } free(c); } return (struct fmtdesc *)0; } static int open_input P2((name, st), char * name, struct stat * st) { struct fmtdesc * f = f_format; st->st_nlink = 0; /* indicates `undefined' value */ if (!name) { inname = (char *)NULL; in = stdin; } else { if (f_decode) inname = codename(name); else { if (!f_cat && suffix(name, SUFFIX_TOASTED)) { fprintf(stderr, "%s: %s already has \"%s\" suffix -- unchanged.\n", progname, name, SUFFIX_TOASTED ); return 0; } inname = strcpy(emalloc(strlen(name)+1), name); } if (!(in = fopen(inname, READ))) { perror(inname); /* not guaranteed to be valid here */ fprintf(stderr, "%s: cannot open \"%s\" for reading\n", progname, inname); return 0; } if (!okay_as_input(inname, in, st)) return 0; if (!f) f = grok_format(inname); } prepare_io( f ? f : & DEFAULT_FORMAT ); return 1; } static int open_output P1((name), char *name) { if (!name || f_cat) { out = stdout; outname = (char *)NULL; } else { int outfd = -1; char * o; o = (*(f_decode ? plainname : codename))(name); if (!length_okay(o)) return 0; if ((outfd = open(o, O_WRITE_EXCL, 0666)) >= 0) out = fdopen(outfd, WRITE); else if (errno != EEXIST) out = (FILE *)NULL; else if (ok_to_replace(o)) out = fopen(o, WRITE); else return 0; if (!out) { perror(o); fprintf(stderr, "%s: can't open \"%s\" for writing\n", progname, o); if (outfd >= 0) (void)close(outfd); return 0; } outname = o; } return 1; } static int process_encode P0() { gsm r; gsm_signal s[ 160 ]; gsm_frame d; int cc; if (!(r = gsm_create())) { perror(progname); return -1; } (void)gsm_option(r, GSM_OPT_FAST, &f_fast); (void)gsm_option(r, GSM_OPT_VERBOSE, &f_verbose); (void)gsm_option(r, GSM_OPT_LTP_CUT, &f_ltp_cut); while ((cc = (*input)(s)) > 0) { if (cc < sizeof(s) / sizeof(*s)) memset((char *)(s+cc), 0, sizeof(s)-(cc * sizeof(*s))); gsm_encode(r, s, d); if (fwrite((char *)d, sizeof(d), 1, out) != 1) { perror(outname ? outname : "stdout"); fprintf(stderr, "%s: error writing to %s\n", progname, outname ? outname : "stdout"); gsm_destroy(r); return -1; } } if (cc < 0) { perror(inname ? inname : "stdin"); fprintf(stderr, "%s: error reading from %s\n", progname, inname ? inname : "stdin"); gsm_destroy(r); return -1; } gsm_destroy(r); return 0; } static int process_decode P0() { gsm r; gsm_frame s; gsm_signal d[ 160 ]; int cc; if (!(r = gsm_create())) { /* malloc failed */ perror(progname); return -1; } (void)gsm_option(r, GSM_OPT_FAST, &f_fast); (void)gsm_option(r, GSM_OPT_VERBOSE, &f_verbose); while ((cc = fread(s, 1, sizeof(s), in)) > 0) { if (cc != sizeof(s)) { if (cc >= 0) fprintf(stderr, "%s: incomplete frame (%d byte%s missing) from %s\n", progname, sizeof(s) - cc, "s" + (sizeof(s) - cc == 1), inname ? inname : "stdin" ); gsm_destroy(r); errno = 0; return -1; } if (gsm_decode(r, s, d)) { fprintf(stderr, "%s: bad frame in %s\n", progname, inname ? inname : "stdin"); gsm_destroy(r); errno = 0; return -1; } if ((*output)(d) < 0) { perror(outname); fprintf(stderr, "%s: error writing to %s\n", progname, outname); gsm_destroy(r); return -1; } } if (cc < 0) { perror(inname ? inname : "stdin" ); fprintf(stderr, "%s: error reading from %s\n", progname, inname ? inname : "stdin"); gsm_destroy(r); return -1; } gsm_destroy(r); return 0; } static int process P1((name), char * name) { int step = 0; out = (FILE *)0; in = (FILE *)0; outname = (char *)0; inname = (char *)0; if (!open_input(name, &instat) || !open_output(name)) goto err; if ((*(f_decode ? init_output : init_input))()) { fprintf(stderr, "%s: error %s %s\n", progname, f_decode ? "writing header to" : "reading header from", f_decode ? (outname ? outname : "stdout") : (inname ? inname : "stdin")); goto err; } if ((*(f_decode ? process_decode : process_encode))()) goto err; if (fflush(out) < 0 || ferror(out)) { perror(outname ? outname : "stdout"); fprintf(stderr, "%s: error writing \"%s\"\n", progname, outname ? outname:"stdout"); goto err; } if (out != stdout) { update_times(); update_mode (); update_own (); if (fclose(out) < 0) { perror(outname); fprintf(stderr, "%s: error writing \"%s\"\n", progname, outname); goto err; } if (outname != name) free(outname); outname = (char *)0; } out = (FILE *)0; if (in != stdin) { (void)fclose(in), in = (FILE *)0; if (!f_cat && !f_precious) { if (unlink(inname) < 0) { perror(inname); fprintf(stderr, "%s: source \"%s\" not deleted.\n", progname, inname); } goto err; } if (inname != name) free(inname); inname = (char *)0; } return 0; /* * Error handling and cleanup: * - error out: close out, unlink it, close in, free the names. * - */ err: if (out && out != stdout) { (void)fclose(out), out = (FILE *)0; if (unlink(outname) < 0 && errno != ENOENT && errno != EINTR) { perror(outname); fprintf(stderr, "%s: could not unlink \"%s\"\n", progname, outname); } } if (in && in != stdin) (void)fclose(in), in = (FILE *)0; if (inname && inname != name) free(inname); if (outname && outname != name) free(outname); return -1; } static void version P0() { printf( "%s 1.0, version %s\n", progname, "$Id: toast.c,v 1.1.1.1 1998/07/14 22:35:24 mrb Exp $" ); } static void help P0() { printf("Usage: %s [-fcpdhvaulsFC] [files...]\n", progname); printf("\n"); printf(" -f force Replace existing files without asking\n"); printf(" -c cat Write to stdout, do not remove source files\n"); printf(" -d decode Decode data (default is encode)\n"); printf(" -p precious Do not delete the source\n"); printf("\n"); printf(" -u u-law Force 8 kHz/8 bit u-law in/output format\n"); printf(" -s sun .au Force Sun .au u-law in/output format\n"); printf(" -a A-law Force 8 kHz/8 bit A-law in/output format\n"); printf(" -l linear Force 16 bit linear in/output format\n"); printf("\n"); printf(" -F fast Sacrifice conformance to performance\n"); printf(" -C cutoff Ignore most samples during LTP\n"); printf(" -v version Show version information\n"); printf(" -h help Print this text\n"); printf("\n"); } static void set_format P1((f), struct fmtdesc * f) { if (f_format && f_format != f) { fprintf( stderr, "%s: only one of -[uals] is possible (%s -h for help)\n", progname, progname); exit(1); } f_format = f; } int main P2((ac, av), int ac, char **av) { int opt; extern int optind; extern char * optarg; parse_argv0(*av); while ((opt = getopt(ac, av, "fcdpvhuaslVFC:")) != EOF) switch (opt) { case 'd': f_decode = 1; break; case 'f': f_force = 1; break; case 'c': f_cat = 1; break; case 'p': f_precious = 1; break; case 'F': f_fast = 1; break; case 'C': f_ltp_cut = 100; break; #ifndef NDEBUG case 'V': f_verbose = 1; break; /* undocumented */ #endif case 'u': set_format( &f_ulaw ); break; case 'l': set_format( &f_linear ); break; case 'a': set_format( &f_alaw ); break; case 's': set_format( &f_audio ); break; case 'v': version(); exit(0); case 'h': help(); exit(0); default: usage: fprintf(stderr, "Usage: %s [-fcpdhvuaslFC] [files...] (-h for help)\n", progname); exit(1); } f_precious |= f_cat; av += optind; ac -= optind; catch_signals(onintr); if (ac <= 0) process( (char *)0 ); else while (ac--) process( *av++ ); exit(0); } rplay-3.3.2/gsm/toast.h100644 153 62 4220 6552756454 13426 0ustar boynsstaff/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /usr/local/cvsroot/rplay/gsm/toast.h,v 1.1.1.1 1998/07/14 22:35:24 mrb Exp $ */ #ifndef TOAST_H #define TOAST_H /* Guard against multiple includes */ #include "config.h" #include #include #include #include #include #include #include #ifndef HAS_ERRNO_DECL extern int errno; #endif #ifdef HAS_LIMITS_H #include #endif #ifdef HAS_FCNTL_H # include #endif #ifdef HAS_UTIME # ifdef HAS_UTIME_H # include # endif #endif #include "gsm.h" #ifndef S_ISREG #define S_ISREG(x) ((x) & S_IFREG) #endif /* S_ISREG */ # define READ "rb" # define WRITE "wb" #ifdef O_BINARY # define O_WRITE_EXCL O_WRONLY|O_CREAT|O_EXCL|O_BINARY #else # define O_WRITE_EXCL O_WRONLY|O_CREAT|O_EXCL #endif #ifndef SIGHANDLER_T #define SIGHANDLER_T void /* what does a signal handler return? */ #endif #ifdef HAS_STRING_H #include #else # ifdef HAS_STRINGS_H # include # else # include "proto.h" extern int strlen P((char *)); extern char * strcpy P((char *, char *)); extern char * strcat P((char *, char *)); extern char * strrchr P((char *, int)); # include "unproto.h" # endif #endif #ifdef HAS_STDLIB_H #include #else # include "proto.h" # ifdef HAS_MALLOC_H # include # else extern char * malloc P((unsigned)); # endif extern int exit P((int)); # include "unproto.h" #endif #ifdef HAS_UNISTD_H # include #endif /* * This suffix is tacked onto/removed from filenames * similar to the way freeze and compress do it. */ #define SUFFIX_TOASTED ".gsm" #include "proto.h" extern int audio_init_input P((void)), audio_init_output P((void)); extern int ulaw_input P((gsm_signal*)), ulaw_output P((gsm_signal *)); extern int alaw_input P((gsm_signal*)), alaw_output P((gsm_signal *)); extern int linear_input P((gsm_signal*)), linear_output P((gsm_signal *)); #endif /* TOAST_H */ rplay-3.3.2/gsm/toast_alaw.c100644 153 62 45734 6552756454 14464 0ustar boynsstaff/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /usr/local/cvsroot/rplay/gsm/toast_alaw.c,v 1.1.1.1 1998/07/14 22:35:24 mrb Exp $ */ #include "toast.h" /* toast_alaw.c -- manipulate A-law encoded sound. */ extern FILE * in, * out; #define A2S(x) (a2s[ (unsigned char )(x) ]) #define S2A(x) (s2a[ ((unsigned short)(x)) >> 4 ]) static unsigned short a2s[] = { 5120,60160, 320,65200,20480,44032, 1280,64192, 2560,62848, 64,65456,10240,54784, 640,64864, 7168,58112, 448,65072,28672,35840, 1792,63680, 3584,61824, 192,65328,14336,50688, 896,64608, 4096,61184, 256,65264,16384,48128, 1024,64448, 2048,63360, 0,65520, 8192,56832, 512,64992, 6144,59136, 384,65136,24576,39936, 1536,63936, 3072,62336, 128,65392,12288,52736, 768,64736, 5632,59648, 352,65168,22528,41984, 1408,64064, 2816,62592, 96,65424,11264,53760, 704,64800, 7680,57600, 480,65040,30720,33792, 1920,63552, 3840,61568, 224,65296,15360,49664, 960,64544, 4608,60672, 288,65232,18432,46080, 1152,64320, 2304,63104, 32,65488, 9216,55808, 576,64928, 6656,58624, 416,65104,26624,37888, 1664,63808, 3328,62080, 160,65360,13312,51712, 832,64672, 5376,59904, 336,65184,21504,43008, 1344,64128, 2688,62720, 80,65440,10752,54272, 672,64832, 7424,57856, 464,65056,29696,34816, 1856,63616, 3712,61696, 208,65312,14848,50176, 928,64576, 4352,60928, 272,65248,17408,47104, 1088,64384, 2176,63232, 16,65504, 8704,56320, 544,64960, 6400,58880, 400,65120,25600,38912, 1600,63872, 3200,62208, 144,65376,12800,52224, 800,64704, 5888,59392, 368,65152,23552,40960, 1472,64000, 2944,62464, 112,65408,11776,53248, 736,64768, 7936,57344, 496,65024,31744,32768, 1984,63488, 3968,61440, 240,65280,15872,49152, 992,64512, 4864,60416, 304,65216,19456,45056, 1216,64256, 2432,62976, 48,65472, 9728,55296, 608,64896, 6912,58368, 432,65088,27648,36864, 1728,63744, 3456,61952, 176,65344,13824,51200, 864,64640 }; static unsigned char s2a[] = { 170, 42,234,106,138, 10,202, 74,186, 58,250,122,154, 26,218, 90, 162, 34,226, 98,130, 2,194, 66,178, 50,242,114,146, 18,210, 82, 174, 46, 46,238,238,110,110,142,142, 14, 14,206,206, 78, 78,190, 190, 62, 62,254,254,126,126,158,158, 30, 30,222,222, 94, 94,166, 166, 38, 38, 38, 38,230,230,230,230,102,102,102,102,134,134,134, 134, 6, 6, 6, 6,198,198,198,198, 70, 70, 70, 70,182,182,182, 182, 54, 54, 54, 54,246,246,246,246,118,118,118,118,150,150,150, 150, 22, 22, 22, 22,214,214,214,214, 86, 86, 86, 86,168,168,168, 168, 40, 40, 40, 40, 40, 40, 40, 40,232,232,232,232,232,232,232, 232,104,104,104,104,104,104,104,104,136,136,136,136,136,136,136, 136, 8, 8, 8, 8, 8, 8, 8, 8,200,200,200,200,200,200,200, 200, 72, 72, 72, 72, 72, 72, 72, 72,184,184,184,184,184,184,184, 184, 56, 56, 56, 56, 56, 56, 56, 56,248,248,248,248,248,248,248, 248,120,120,120,120,120,120,120,120,152,152,152,152,152,152,152, 152, 24, 24, 24, 24, 24, 24, 24, 24,216,216,216,216,216,216,216, 216, 88, 88, 88, 88, 88, 88, 88, 88,160,160,160,160,160,160,160, 160, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, 224, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192, 192, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, 176, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, 240,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, 112,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144, 144, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, 208, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, 172, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, 236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, 236,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, 108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, 108,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, 140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140, 140, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, 204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204, 204, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, 188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188, 188, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, 252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, 252,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, 124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, 124,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, 156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156, 156, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, 220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220, 220, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, 164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164, 164, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, 228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, 228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, 228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228, 228,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, 100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100, 100,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, 132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, 132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, 132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132, 132, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, 196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, 196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, 196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196, 196, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, 180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180, 180, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, 244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, 244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, 244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, 244,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, 116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, 116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, 116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, 116,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, 148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, 148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, 148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148, 148, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, 212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, 212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, 212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, 212, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 84, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, 213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, 213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, 213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213, 213, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, 149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, 149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, 149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149, 149,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, 117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, 117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, 117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117, 117,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, 245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, 245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, 245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, 245, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, 181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, 181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, 181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181, 181, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, 197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, 197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, 197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, 197, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, 133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, 133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, 133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133, 133,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, 101,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, 229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, 229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, 229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229, 229, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, 165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, 165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, 165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165, 165, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, 221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221, 221, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, 157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157, 157,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, 125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, 125,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, 253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, 253, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, 189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189, 189, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, 205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, 205, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, 141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, 141,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, 109,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, 237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, 237, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, 173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173, 173, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209, 209, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145, 145,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, 113,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241, 241, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177, 177, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, 193, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, 129, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, 225, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161, 161, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,217,217,217,217,217,217,217,217, 25, 25, 25, 25, 25, 25, 25, 25,153,153,153,153,153,153,153,153,121,121,121,121,121,121,121, 121,249,249,249,249,249,249,249,249, 57, 57, 57, 57, 57, 57, 57, 57,185,185,185,185,185,185,185,185, 73, 73, 73, 73, 73, 73, 73, 73,201,201,201,201,201,201,201,201, 9, 9, 9, 9, 9, 9, 9, 9,137,137,137,137,137,137,137,137,105,105,105,105,105,105,105, 105,233,233,233,233,233,233,233,233, 41, 41, 41, 41, 41, 41, 41, 41,169,169,169,169,169,169,169,169, 87, 87, 87, 87, 87, 87, 87, 87,215,215,215,215, 23, 23, 23, 23,151,151,151,151,119,119,119, 119,247,247,247,247, 55, 55, 55, 55,183,183,183,183, 71, 71, 71, 71,199,199,199,199, 7, 7, 7, 7,135,135,135,135,103,103,103, 103,231,231,231,231, 39, 39, 39, 39,167,167,167,167, 95, 95, 95, 95,223,223, 31, 31,159,159,127,127,255,255, 63, 63,191,191, 79, 79,207,207, 15, 15,143,143,111,111,239,239, 47, 47,175,175, 83, 83,211, 19,147,115,243, 51,179, 67,195, 3,131, 99,227, 35,163, 91,219, 27,155,123,251, 59,187, 75,203, 11,139,107,235, 43,171 }; int alaw_input P1((buf), gsm_signal * buf) { int i, c; for (i = 0; i < 160 && (c = fgetc(in)) != EOF; i++) buf[i] = A2S( c ); if (c == EOF && ferror(in)) return -1; return i; } int alaw_output P1((buf), gsm_signal * buf) { int i; for (i = 0; i < 160; i++, buf++) if (fputc( S2A( *buf ), out) == EOF) return -1; return 0; } rplay-3.3.2/gsm/toast_audio.c100644 153 62 5506 6552756454 14612 0ustar boynsstaff/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /usr/local/cvsroot/rplay/gsm/toast_audio.c,v 1.1.1.1 1998/07/14 22:35:24 mrb Exp $ */ #include "toast.h" /* toast_audio -- functions to manipulate SunOS audio files. * * This is reverse engineered from our present soundfiles * and in no way portable, durable or aesthetically pleasing. */ extern FILE * in, * out; extern char * inname; extern char * progname; extern int (*output) P((gsm_signal *)), (*input ) P((gsm_signal *)); extern int alaw_input P((gsm_signal *)), ulaw_input P((gsm_signal *)), linear_input P((gsm_signal *)); extern int ulaw_output P((gsm_signal *)); static int put_u32 P2((f, u), FILE * f, unsigned long u) { /* Write a 32-bit unsigned value msb first. */ if ( putc( (char)((u>>24) & 0x0FF), f) == EOF || putc( (char)((u>>16) & 0x0FF), f) == EOF || putc( (char)((u>> 8) & 0x0FF), f) == EOF || putc( (char)( u & 0x0FF), f) == EOF) return -1; return 0; } static int get_u32 P2((f, up), FILE * f, unsigned long * up) { /* Read a 32-bit unsigned value msb first. */ int i; unsigned long u; if ( (i = getc(f)) == EOF || ((u = (unsigned char)i), (i = getc(f)) == EOF) || ((u = (u<<8)|(unsigned char)i), (i = getc(f)) == EOF) || ((u = (u<<8)|(unsigned char)i), (i = getc(f)) == EOF)) return -1; *up = (u<<8)|(unsigned char)i; return 0; } int audio_init_input P0() { unsigned long len, enc; /* unsigned 32 bits */ if ( fgetc(in) != '.' || fgetc(in) != 's' || fgetc(in) != 'n' || fgetc(in) != 'd' || get_u32( in, &len ) || get_u32( in, &enc ) /* skip this */ || get_u32( in, &enc )) { fprintf(stderr, "%s: bad (missing?) header in Sun audio file \"%s\";\n\ Try one of -u, -a, -l instead (%s -h for help).\n", progname, inname ? inname : "stdin", progname); return -1; } switch (enc) { case 1: input = ulaw_input; break; case 2: input = alaw_input; break; case 3: input = linear_input; break; default: fprintf(stderr, "%s: warning: file format #%lu for %s not implemented, defaulting to u-law.\n", progname, enc, inname); input = ulaw_input; break; } while (len > 4*4) if (getc(in) == EOF) { fprintf(stderr, "%s: EOF in header of Sun audio file \"%s\";\n\ Try one of -u, -a, -l instead (%s -h for help).\n", progname, inname ? inname : "stdin", progname); return -1; } else len--; return 0; } int audio_init_output P0() { if ( fputs(".snd", out) == EOF || put_u32(out, 32) || put_u32(out, ~(unsigned long)0) || put_u32(out, 1) || put_u32(out, 8000) || put_u32(out, 1) || put_u32(out, 0) || put_u32(out, 0)) return -1; return 0; } rplay-3.3.2/gsm/toast_lin.c100644 153 62 1206 6552756454 14264 0ustar boynsstaff/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /usr/local/cvsroot/rplay/gsm/toast_lin.c,v 1.1.1.1 1998/07/14 22:35:24 mrb Exp $ */ #include "toast.h" /* toast_linear.c -- read and write 16 bit linear sound in host byte order. */ extern FILE *in, *out; int linear_input (buf) gsm_signal * buf; { return fread( (char *)buf, sizeof(*buf), 160, in ); } int linear_output P1((buf), gsm_signal * buf) { return -( fwrite( (char *)buf, sizeof(*buf), 160, out ) != 160 ); } rplay-3.3.2/gsm/toast_ulaw.c100644 153 62 126372 6552756454 14526 0ustar boynsstaff/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /usr/local/cvsroot/rplay/gsm/toast_ulaw.c,v 1.1.1.1 1998/07/14 22:35:24 mrb Exp $ */ #include "toast.h" /* toast_ulaw -- functions to manipulate u-law encoded sound. */ extern FILE *in, *out; #define U2S(x) (u2s[ (unsigned char)(x) ]) #define S2U(x) (s2u[ ((unsigned short)(x)) >> 3 ]) static unsigned short u2s[] = { 33280, 34308, 35336, 36364, 37393, 38421, 39449, 40477, 41505, 42534, 43562, 44590, 45618, 46647, 47675, 48703, 49474, 49988, 50503, 51017, 51531, 52045, 52559, 53073, 53587, 54101, 54616, 55130, 55644, 56158, 56672, 57186, 57572, 57829, 58086, 58343, 58600, 58857, 59114, 59371, 59628, 59885, 60142, 60399, 60656, 60913, 61171, 61428, 61620, 61749, 61877, 62006, 62134, 62263, 62392, 62520, 62649, 62777, 62906, 63034, 63163, 63291, 63420, 63548, 63645, 63709, 63773, 63838, 63902, 63966, 64030, 64095, 64159, 64223, 64287, 64352, 64416, 64480, 64544, 64609, 64657, 64689, 64721, 64753, 64785, 64818, 64850, 64882, 64914, 64946, 64978, 65010, 65042, 65075, 65107, 65139, 65163, 65179, 65195, 65211, 65227, 65243, 65259, 65275, 65291, 65308, 65324, 65340, 65356, 65372, 65388, 65404, 65416, 65424, 65432, 65440, 65448, 65456, 65464, 65472, 65480, 65488, 65496, 65504, 65512, 65520, 65528, 0, 32256, 31228, 30200, 29172, 28143, 27115, 26087, 25059, 24031, 23002, 21974, 20946, 19918, 18889, 17861, 16833, 16062, 15548, 15033, 14519, 14005, 13491, 12977, 12463, 11949, 11435, 10920, 10406, 9892, 9378, 8864, 8350, 7964, 7707, 7450, 7193, 6936, 6679, 6422, 6165, 5908, 5651, 5394, 5137, 4880, 4623, 4365, 4108, 3916, 3787, 3659, 3530, 3402, 3273, 3144, 3016, 2887, 2759, 2630, 2502, 2373, 2245, 2116, 1988, 1891, 1827, 1763, 1698, 1634, 1570, 1506, 1441, 1377, 1313, 1249, 1184, 1120, 1056, 992, 927, 879, 847, 815, 783, 751, 718, 686, 654, 622, 590, 558, 526, 494, 461, 429, 397, 373, 357, 341, 325, 309, 293, 277, 261, 245, 228, 212, 196, 180, 164, 148, 132, 120, 112, 104, 96, 88, 80, 72, 64, 56, 48, 40, 32, 24, 16, 8, 0 }; static unsigned char s2u[] = { 0377,0376,0375,0374,0373,0372,0371,0370,0367,0366,0365,0364,0363,0362,0361, 0360,0357,0357,0356,0356,0355,0355,0354,0354,0353,0353,0352,0352,0351,0351, 0350,0350,0347,0347,0346,0346,0345,0345,0344,0344,0343,0343,0342,0342,0341, 0341,0340,0340,0337,0337,0337,0337,0336,0336,0336,0336,0335,0335,0335,0335, 0334,0334,0334,0334,0333,0333,0333,0333,0332,0332,0332,0332,0331,0331,0331, 0331,0330,0330,0330,0330,0327,0327,0327,0327,0326,0326,0326,0326,0325,0325, 0325,0325,0324,0324,0324,0324,0323,0323,0323,0323,0322,0322,0322,0322,0321, 0321,0321,0321,0320,0320,0320,0320,0317,0317,0317,0317,0317,0317,0317,0317, 0316,0316,0316,0316,0316,0316,0316,0316,0315,0315,0315,0315,0315,0315,0315, 0315,0314,0314,0314,0314,0314,0314,0314,0314,0313,0313,0313,0313,0313,0313, 0313,0313,0312,0312,0312,0312,0312,0312,0312,0312,0311,0311,0311,0311,0311, 0311,0311,0311,0310,0310,0310,0310,0310,0310,0310,0310,0307,0307,0307,0307, 0307,0307,0307,0307,0306,0306,0306,0306,0306,0306,0306,0306,0305,0305,0305, 0305,0305,0305,0305,0305,0304,0304,0304,0304,0304,0304,0304,0304,0303,0303, 0303,0303,0303,0303,0303,0303,0303,0302,0302,0302,0302,0302,0302,0302,0302, 0301,0301,0301,0301,0301,0301,0301,0301,0300,0300,0300,0300,0300,0300,0300, 0300,0277,0277,0277,0277,0277,0277,0277,0277,0277,0277,0277,0277,0277,0277, 0277,0277,0276,0276,0276,0276,0276,0276,0276,0276,0276,0276,0276,0276,0276, 0276,0276,0276,0275,0275,0275,0275,0275,0275,0275,0275,0275,0275,0275,0275, 0275,0275,0275,0275,0274,0274,0274,0274,0274,0274,0274,0274,0274,0274,0274, 0274,0274,0274,0274,0274,0273,0273,0273,0273,0273,0273,0273,0273,0273,0273, 0273,0273,0273,0273,0273,0273,0272,0272,0272,0272,0272,0272,0272,0272,0272, 0272,0272,0272,0272,0272,0272,0272,0271,0271,0271,0271,0271,0271,0271,0271, 0271,0271,0271,0271,0271,0271,0271,0271,0270,0270,0270,0270,0270,0270,0270, 0270,0270,0270,0270,0270,0270,0270,0270,0270,0267,0267,0267,0267,0267,0267, 0267,0267,0267,0267,0267,0267,0267,0267,0267,0267,0266,0266,0266,0266,0266, 0266,0266,0266,0266,0266,0266,0266,0266,0266,0266,0266,0265,0265,0265,0265, 0265,0265,0265,0265,0265,0265,0265,0265,0265,0265,0265,0265,0264,0264,0264, 0264,0264,0264,0264,0264,0264,0264,0264,0264,0264,0264,0264,0264,0263,0263, 0263,0263,0263,0263,0263,0263,0263,0263,0263,0263,0263,0263,0263,0263,0262, 0262,0262,0262,0262,0262,0262,0262,0262,0262,0262,0262,0262,0262,0262,0262, 0262,0261,0261,0261,0261,0261,0261,0261,0261,0261,0261,0261,0261,0261,0261, 0261,0261,0260,0260,0260,0260,0260,0260,0260,0260,0260,0260,0260,0260,0260, 0260,0260,0260,0257,0257,0257,0257,0257,0257,0257,0257,0257,0257,0257,0257, 0257,0257,0257,0257,0257,0257,0257,0257,0257,0257,0257,0257,0257,0257,0257, 0257,0257,0257,0257,0257,0256,0256,0256,0256,0256,0256,0256,0256,0256,0256, 0256,0256,0256,0256,0256,0256,0256,0256,0256,0256,0256,0256,0256,0256,0256, 0256,0256,0256,0256,0256,0256,0256,0255,0255,0255,0255,0255,0255,0255,0255, 0255,0255,0255,0255,0255,0255,0255,0255,0255,0255,0255,0255,0255,0255,0255, 0255,0255,0255,0255,0255,0255,0255,0255,0255,0254,0254,0254,0254,0254,0254, 0254,0254,0254,0254,0254,0254,0254,0254,0254,0254,0254,0254,0254,0254,0254, 0254,0254,0254,0254,0254,0254,0254,0254,0254,0254,0254,0253,0253,0253,0253, 0253,0253,0253,0253,0253,0253,0253,0253,0253,0253,0253,0253,0253,0253,0253, 0253,0253,0253,0253,0253,0253,0253,0253,0253,0253,0253,0253,0253,0252,0252, 0252,0252,0252,0252,0252,0252,0252,0252,0252,0252,0252,0252,0252,0252,0252, 0252,0252,0252,0252,0252,0252,0252,0252,0252,0252,0252,0252,0252,0252,0252, 0251,0251,0251,0251,0251,0251,0251,0251,0251,0251,0251,0251,0251,0251,0251, 0251,0251,0251,0251,0251,0251,0251,0251,0251,0251,0251,0251,0251,0251,0251, 0251,0251,0251,0250,0250,0250,0250,0250,0250,0250,0250,0250,0250,0250,0250, 0250,0250,0250,0250,0250,0250,0250,0250,0250,0250,0250,0250,0250,0250,0250, 0250,0250,0250,0250,0250,0247,0247,0247,0247,0247,0247,0247,0247,0247,0247, 0247,0247,0247,0247,0247,0247,0247,0247,0247,0247,0247,0247,0247,0247,0247, 0247,0247,0247,0247,0247,0247,0247,0246,0246,0246,0246,0246,0246,0246,0246, 0246,0246,0246,0246,0246,0246,0246,0246,0246,0246,0246,0246,0246,0246,0246, 0246,0246,0246,0246,0246,0246,0246,0246,0246,0245,0245,0245,0245,0245,0245, 0245,0245,0245,0245,0245,0245,0245,0245,0245,0245,0245,0245,0245,0245,0245, 0245,0245,0245,0245,0245,0245,0245,0245,0245,0245,0245,0244,0244,0244,0244, 0244,0244,0244,0244,0244,0244,0244,0244,0244,0244,0244,0244,0244,0244,0244, 0244,0244,0244,0244,0244,0244,0244,0244,0244,0244,0244,0244,0244,0243,0243, 0243,0243,0243,0243,0243,0243,0243,0243,0243,0243,0243,0243,0243,0243,0243, 0243,0243,0243,0243,0243,0243,0243,0243,0243,0243,0243,0243,0243,0243,0243, 0242,0242,0242,0242,0242,0242,0242,0242,0242,0242,0242,0242,0242,0242,0242, 0242,0242,0242,0242,0242,0242,0242,0242,0242,0242,0242,0242,0242,0242,0242, 0242,0242,0242,0241,0241,0241,0241,0241,0241,0241,0241,0241,0241,0241,0241, 0241,0241,0241,0241,0241,0241,0241,0241,0241,0241,0241,0241,0241,0241,0241, 0241,0241,0241,0241,0241,0240,0240,0240,0240,0240,0240,0240,0240,0240,0240, 0240,0240,0240,0240,0240,0240,0240,0240,0240,0240,0240,0240,0240,0240,0240, 0240,0240,0240,0240,0240,0240,0240,0237,0237,0237,0237,0237,0237,0237,0237, 0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237, 0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237, 0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237, 0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0237,0236,0236,0236,0236, 0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236, 0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236, 0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236, 0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236,0236, 0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235, 0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235, 0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235, 0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235,0235, 0235,0235,0235,0235,0235,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234, 0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234, 0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234, 0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234,0234, 0234,0234,0234,0234,0234,0234,0234,0234,0234,0233,0233,0233,0233,0233,0233, 0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233, 0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233, 0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233, 0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0233,0232,0232, 0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232, 0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232, 0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232, 0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232,0232, 0232,0232,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231, 0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231, 0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231, 0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231,0231, 0231,0231,0231,0231,0231,0231,0231,0230,0230,0230,0230,0230,0230,0230,0230, 0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230, 0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230, 0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230, 0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0230,0227,0227,0227,0227, 0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227, 0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227, 0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227, 0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227,0227, 0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226, 0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226, 0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226, 0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226,0226, 0226,0226,0226,0226,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225, 0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225, 0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225, 0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225,0225, 0225,0225,0225,0225,0225,0225,0225,0225,0225,0224,0224,0224,0224,0224,0224, 0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224, 0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224, 0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224, 0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0224,0223,0223, 0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223, 0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223, 0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223, 0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223,0223, 0223,0223,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222, 0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222, 0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222, 0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222,0222, 0222,0222,0222,0222,0222,0222,0221,0221,0221,0221,0221,0221,0221,0221,0221, 0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221, 0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221, 0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221, 0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0221,0220,0220,0220,0220, 0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220, 0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220, 0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220, 0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220,0220, 0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217, 0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217, 0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217, 0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217, 0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217, 0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217, 0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217, 0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217,0217, 0217,0217,0217,0217,0217,0217,0217,0217,0217,0216,0216,0216,0216,0216,0216, 0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216, 0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216, 0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216, 0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216, 0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216, 0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216, 0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216, 0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216,0216, 0216,0216,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215, 0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215, 0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215, 0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215, 0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215, 0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215, 0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215, 0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215, 0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0215,0214,0214,0214,0214, 0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214, 0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214, 0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214, 0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214, 0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214, 0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214, 0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214, 0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214,0214, 0214,0214,0214,0214,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213, 0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213, 0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213, 0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213, 0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213, 0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213, 0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213, 0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213, 0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0213,0212,0212, 0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212, 0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212, 0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212, 0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212, 0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212, 0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212, 0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212, 0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212,0212, 0212,0212,0212,0212,0212,0212,0211,0211,0211,0211,0211,0211,0211,0211,0211, 0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211, 0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211, 0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211, 0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211, 0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211, 0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211, 0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211, 0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211,0211, 0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210, 0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210, 0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210, 0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210, 0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210, 0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210, 0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210, 0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210,0210, 0210,0210,0210,0210,0210,0210,0210,0210,0207,0207,0207,0207,0207,0207,0207, 0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207, 0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207, 0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207, 0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207, 0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207, 0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207, 0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207, 0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207,0207, 0207,0207,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206, 0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206, 0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206, 0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206, 0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206, 0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206, 0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206, 0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0206, 0206,0206,0206,0206,0206,0206,0206,0206,0206,0206,0205,0205,0205,0205,0205, 0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205, 0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205, 0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205, 0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205, 0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205, 0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205, 0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205, 0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205,0205, 0205,0205,0205,0205,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204, 0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204, 0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204, 0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204, 0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204, 0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204, 0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204, 0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204, 0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0204,0203,0203,0203, 0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203, 0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203, 0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203, 0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203, 0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203, 0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203, 0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203, 0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203,0203, 0203,0203,0203,0203,0203,0203,0202,0202,0202,0202,0202,0202,0202,0202,0202, 0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202, 0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202, 0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202, 0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202, 0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202, 0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202, 0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202, 0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0202,0201, 0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201, 0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201, 0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201, 0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201, 0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201, 0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201, 0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201, 0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201,0201, 0201,0201,0201,0201,0201,0201,0201,0201,0200,0200,0200,0200,0200,0200,0200, 0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200, 0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200, 0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200, 0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200, 0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200, 0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200, 0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200, 0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200,0200, 0200,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000, 0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000, 0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000, 0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000, 0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000, 0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000, 0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000, 0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000, 0000,0000,0000,0000,0000,0000,0000,0000,0000,0001,0001,0001,0001,0001,0001, 0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001, 0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001, 0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001, 0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001, 0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001, 0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001, 0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001, 0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001,0001, 0001,0001,0001,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002, 0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002, 0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002, 0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002, 0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002, 0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002, 0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002, 0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002, 0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0002,0003,0003,0003,0003, 0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003, 0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003, 0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003, 0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003, 0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003, 0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003, 0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003, 0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003,0003, 0003,0003,0003,0003,0003,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004, 0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004, 0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004, 0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004, 0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004, 0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004, 0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004, 0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004, 0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0004,0005,0005, 0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005, 0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005, 0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005, 0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005, 0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005, 0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005, 0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005, 0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005,0005, 0005,0005,0005,0005,0005,0005,0005,0006,0006,0006,0006,0006,0006,0006,0006, 0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006, 0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006, 0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006, 0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006, 0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006, 0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006, 0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006, 0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006,0006, 0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007, 0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007, 0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007, 0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007, 0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007, 0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007, 0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007, 0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007,0007, 0007,0007,0007,0007,0007,0007,0007,0007,0007,0010,0010,0010,0010,0010,0010, 0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010, 0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010, 0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010, 0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010, 0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010, 0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010, 0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010, 0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010,0010, 0010,0010,0010,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011, 0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011, 0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011, 0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011, 0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011, 0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011, 0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011, 0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011, 0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0011,0012,0012,0012,0012, 0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012, 0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012, 0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012, 0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012, 0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012, 0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012, 0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012, 0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012,0012, 0012,0012,0012,0012,0012,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013, 0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013, 0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013, 0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013, 0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013, 0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013, 0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013, 0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013, 0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0013,0014,0014, 0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014, 0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014, 0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014, 0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014, 0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014, 0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014, 0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014, 0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014,0014, 0014,0014,0014,0014,0014,0014,0014,0015,0015,0015,0015,0015,0015,0015,0015, 0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015, 0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015, 0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015, 0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015, 0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015, 0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015, 0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015, 0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015,0015, 0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016, 0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016, 0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016, 0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016, 0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016, 0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016, 0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016, 0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016,0016, 0016,0016,0016,0016,0016,0016,0016,0016,0016,0017,0017,0017,0017,0017,0017, 0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017, 0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017, 0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017, 0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017, 0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017, 0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017, 0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017, 0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017,0017, 0017,0017,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020, 0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020, 0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020, 0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020,0020, 0020,0020,0020,0020,0020,0020,0021,0021,0021,0021,0021,0021,0021,0021,0021, 0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021, 0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021, 0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021, 0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0021,0022,0022,0022,0022, 0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022, 0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022, 0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022, 0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022,0022, 0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023, 0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023, 0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023, 0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023,0023, 0023,0023,0023,0023,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024, 0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024, 0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024, 0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024,0024, 0024,0024,0024,0024,0024,0024,0024,0024,0024,0025,0025,0025,0025,0025,0025, 0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025, 0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025, 0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025, 0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0025,0026,0026, 0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026, 0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026, 0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026, 0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026,0026, 0026,0026,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027, 0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027, 0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027, 0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027,0027, 0027,0027,0027,0027,0027,0027,0030,0030,0030,0030,0030,0030,0030,0030,0030, 0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030, 0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030, 0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030, 0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0030,0031,0031,0031,0031, 0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031, 0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031, 0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031, 0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031,0031, 0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032, 0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032, 0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032, 0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032,0032, 0032,0032,0032,0032,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033, 0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033, 0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033, 0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033,0033, 0033,0033,0033,0033,0033,0033,0033,0033,0034,0034,0034,0034,0034,0034,0034, 0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034, 0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034, 0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034, 0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0034,0035,0035, 0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035, 0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035, 0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035, 0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035,0035, 0035,0035,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036, 0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036, 0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036, 0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036,0036, 0036,0036,0036,0036,0036,0036,0037,0037,0037,0037,0037,0037,0037,0037,0037, 0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0037, 0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0037, 0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0037, 0037,0037,0037,0037,0037,0037,0037,0037,0037,0037,0040,0040,0040,0040,0040, 0040,0040,0040,0040,0040,0040,0040,0040,0040,0040,0040,0040,0040,0040,0040, 0040,0040,0040,0040,0040,0040,0040,0040,0040,0040,0040,0040,0040,0041,0041, 0041,0041,0041,0041,0041,0041,0041,0041,0041,0041,0041,0041,0041,0041,0041, 0041,0041,0041,0041,0041,0041,0041,0041,0041,0041,0041,0041,0041,0041,0041, 0042,0042,0042,0042,0042,0042,0042,0042,0042,0042,0042,0042,0042,0042,0042, 0042,0042,0042,0042,0042,0042,0042,0042,0042,0042,0042,0042,0042,0042,0042, 0042,0042,0043,0043,0043,0043,0043,0043,0043,0043,0043,0043,0043,0043,0043, 0043,0043,0043,0043,0043,0043,0043,0043,0043,0043,0043,0043,0043,0043,0043, 0043,0043,0043,0043,0044,0044,0044,0044,0044,0044,0044,0044,0044,0044,0044, 0044,0044,0044,0044,0044,0044,0044,0044,0044,0044,0044,0044,0044,0044,0044, 0044,0044,0044,0044,0044,0044,0045,0045,0045,0045,0045,0045,0045,0045,0045, 0045,0045,0045,0045,0045,0045,0045,0045,0045,0045,0045,0045,0045,0045,0045, 0045,0045,0045,0045,0045,0045,0045,0045,0046,0046,0046,0046,0046,0046,0046, 0046,0046,0046,0046,0046,0046,0046,0046,0046,0046,0046,0046,0046,0046,0046, 0046,0046,0046,0046,0046,0046,0046,0046,0046,0046,0047,0047,0047,0047,0047, 0047,0047,0047,0047,0047,0047,0047,0047,0047,0047,0047,0047,0047,0047,0047, 0047,0047,0047,0047,0047,0047,0047,0047,0047,0047,0047,0047,0047,0050,0050, 0050,0050,0050,0050,0050,0050,0050,0050,0050,0050,0050,0050,0050,0050,0050, 0050,0050,0050,0050,0050,0050,0050,0050,0050,0050,0050,0050,0050,0050,0050, 0051,0051,0051,0051,0051,0051,0051,0051,0051,0051,0051,0051,0051,0051,0051, 0051,0051,0051,0051,0051,0051,0051,0051,0051,0051,0051,0051,0051,0051,0051, 0051,0051,0052,0052,0052,0052,0052,0052,0052,0052,0052,0052,0052,0052,0052, 0052,0052,0052,0052,0052,0052,0052,0052,0052,0052,0052,0052,0052,0052,0052, 0052,0052,0052,0052,0053,0053,0053,0053,0053,0053,0053,0053,0053,0053,0053, 0053,0053,0053,0053,0053,0053,0053,0053,0053,0053,0053,0053,0053,0053,0053, 0053,0053,0053,0053,0053,0053,0054,0054,0054,0054,0054,0054,0054,0054,0054, 0054,0054,0054,0054,0054,0054,0054,0054,0054,0054,0054,0054,0054,0054,0054, 0054,0054,0054,0054,0054,0054,0054,0054,0055,0055,0055,0055,0055,0055,0055, 0055,0055,0055,0055,0055,0055,0055,0055,0055,0055,0055,0055,0055,0055,0055, 0055,0055,0055,0055,0055,0055,0055,0055,0055,0055,0056,0056,0056,0056,0056, 0056,0056,0056,0056,0056,0056,0056,0056,0056,0056,0056,0056,0056,0056,0056, 0056,0056,0056,0056,0056,0056,0056,0056,0056,0056,0056,0056,0057,0057,0057, 0057,0057,0057,0057,0057,0057,0057,0057,0057,0057,0057,0057,0057,0057,0057, 0057,0057,0057,0057,0057,0057,0057,0057,0057,0057,0057,0057,0057,0057,0057, 0060,0060,0060,0060,0060,0060,0060,0060,0060,0060,0060,0060,0060,0060,0060, 0060,0061,0061,0061,0061,0061,0061,0061,0061,0061,0061,0061,0061,0061,0061, 0061,0061,0062,0062,0062,0062,0062,0062,0062,0062,0062,0062,0062,0062,0062, 0062,0062,0062,0063,0063,0063,0063,0063,0063,0063,0063,0063,0063,0063,0063, 0063,0063,0063,0063,0064,0064,0064,0064,0064,0064,0064,0064,0064,0064,0064, 0064,0064,0064,0064,0064,0065,0065,0065,0065,0065,0065,0065,0065,0065,0065, 0065,0065,0065,0065,0065,0065,0066,0066,0066,0066,0066,0066,0066,0066,0066, 0066,0066,0066,0066,0066,0066,0066,0067,0067,0067,0067,0067,0067,0067,0067, 0067,0067,0067,0067,0067,0067,0067,0067,0070,0070,0070,0070,0070,0070,0070, 0070,0070,0070,0070,0070,0070,0070,0070,0070,0071,0071,0071,0071,0071,0071, 0071,0071,0071,0071,0071,0071,0071,0071,0071,0071,0072,0072,0072,0072,0072, 0072,0072,0072,0072,0072,0072,0072,0072,0072,0072,0072,0073,0073,0073,0073, 0073,0073,0073,0073,0073,0073,0073,0073,0073,0073,0073,0073,0074,0074,0074, 0074,0074,0074,0074,0074,0074,0074,0074,0074,0074,0074,0074,0074,0075,0075, 0075,0075,0075,0075,0075,0075,0075,0075,0075,0075,0075,0075,0075,0075,0075, 0076,0076,0076,0076,0076,0076,0076,0076,0076,0076,0076,0076,0076,0076,0076, 0076,0077,0077,0077,0077,0077,0077,0077,0077,0077,0077,0077,0077,0077,0077, 0077,0077,0100,0100,0100,0100,0100,0100,0100,0100,0101,0101,0101,0101,0101, 0101,0101,0101,0102,0102,0102,0102,0102,0102,0102,0102,0103,0103,0103,0103, 0103,0103,0103,0103,0104,0104,0104,0104,0104,0104,0104,0104,0105,0105,0105, 0105,0105,0105,0105,0105,0106,0106,0106,0106,0106,0106,0106,0106,0107,0107, 0107,0107,0107,0107,0107,0107,0110,0110,0110,0110,0110,0110,0110,0110,0111, 0111,0111,0111,0111,0111,0111,0111,0112,0112,0112,0112,0112,0112,0112,0112, 0113,0113,0113,0113,0113,0113,0113,0113,0114,0114,0114,0114,0114,0114,0114, 0114,0115,0115,0115,0115,0115,0115,0115,0115,0116,0116,0116,0116,0116,0116, 0116,0116,0117,0117,0117,0117,0117,0117,0117,0117,0120,0120,0120,0120,0121, 0121,0121,0121,0122,0122,0122,0122,0123,0123,0123,0123,0124,0124,0124,0124, 0125,0125,0125,0125,0126,0126,0126,0126,0127,0127,0127,0127,0130,0130,0130, 0130,0131,0131,0131,0131,0132,0132,0132,0132,0133,0133,0133,0133,0134,0134, 0134,0134,0135,0135,0135,0135,0136,0136,0136,0136,0137,0137,0137,0137,0140, 0140,0141,0141,0142,0142,0143,0143,0144,0144,0145,0145,0146,0146,0147,0147, 0150,0150,0150,0151,0151,0152,0152,0153,0153,0154,0154,0155,0155,0156,0156, 0157,0157,0160,0161,0162,0163,0164,0165,0166,0167,0170,0171,0172,0173,0174, 0175,0176 }; int ulaw_input P1((buf), gsm_signal * buf) { int i, c; for (i = 0; i < 160 && (c = fgetc(in)) != EOF; i++) buf[i] = U2S(c); if (c == EOF && ferror(in)) return -1; return i; } int ulaw_output P1((buf), gsm_signal * buf) { int i; for(i = 0; i < 160; i++, buf++) if (fputc( (char)S2U( (unsigned short)*buf ), out) == EOF) return -1; return 0; } rplay-3.3.2/gsm/unproto.h100644 153 62 716 6552756454 13770 0ustar boynsstaff/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /*$Header: /usr/local/cvsroot/rplay/gsm/unproto.h,v 1.1.1.1 1998/07/14 22:35:24 mrb Exp $*/ #ifdef PROTO_H /* sic */ #undef PROTO_H #undef P #undef P0 #undef P1 #undef P2 #undef P3 #undef P4 #undef P5 #undef P6 #undef P7 #undef P8 #endif /* PROTO_H */ rplay-3.3.2/include/ 40755 153 62 0 6727650077 12663 5ustar boynsstaffrplay-3.3.2/include/Makefile.in100644 153 62 766 6552756452 15016 0ustar boynsstaffinclude @RPLAY_TOP@/Makefile.config srcdir = @srcdir@ VPATH = @srcdir@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ MKINSTALLDIRS= @srcdir@/../mkinstalldirs TARGET= rplay.h all: $(TARGET): install: $(TARGET) $(MKINSTALLDIRS) $(includedir) $(INSTALL_DATA) @srcdir@/$(TARGET) $(includedir)/$(TARGET) uninstall: $(RM) $(includedir)/$(TARGET) clean: $(RM) *~ *.bak *.orig distclean: clean $(RM) Makefile config.h tags: TAGS: etags: depend: rplay-3.3.2/include/config.h.in100644 153 62 14633 6727404320 15016 0ustar boynsstaff/* $Id: config.h.in,v 1.4 1999/06/09 06:25:20 boyns Exp $ -*- c -*- */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _config_h #define _config_h #undef SVR4 /* * rplayd user and group privs. (default unset) * * Example: * #define RPLAYD_USER "nobody" * #define RPLAYD_GROUP "audio" */ #undef RPLAYD_USER #undef RPLAYD_GROUP /* * Use host authentication. */ #define AUTH /* * Support rplay 2.0 packets. If you define this then you * should also define OLD_RPLAY_PORTS below. */ #define OLD_RPLAY /* * Support older RPLAY port 55555 and RPTP port 55556. * This option really enables support for 2 RPLAY ports and 2 RPTP ports * which default to 5555/55555 for RPLAY and 5556/55556 for RPTP. */ #define OTHER_RPLAY_PORTS /* * Maximum number of sounds that can be playing at once. */ #define SPOOL_SIZE 12 /* * The size of rplayd's internal sound hash table. */ #define MAX_SOUNDS 4001 /* yes that is a prime number */ /* * Should rplayd log by default? */ /* #define RPLAYD_ALWAYS_LOG */ /* * Define the default rplayd logging level: * 1 - System and rplayd errors. * 2 - + RPTP connections, get, put, find. * 3 - + play, stop, pause, continue, etc. * 4 - + Debug messages. * * Note that the logging level can also be specified with * rplayd command line options. This is only used if * RPLAYD_ALWAYS_LOG is defined above. */ #define RPLAYD_LOG_LEVEL 1 /* * By default, rplayd will never timeout. If you would rather * have rplayd exit after some period of idle time, change the zero * below to the appropriate number of seconds. * * NOTE: This value used to be 360 instead of 0. */ #define RPLAYD_TIMEOUT 0 /* seconds */ /* * Maximum size of the rplay.cache directory. * * The size you choose should at least be big enough to hold the * largest sound you plan on playing. Note that this is the disk * cache and not the memory cache which is mentioned below. */ #define RPLAY_CACHE_SIZE (8*1024*1024) /* * Memory cache. * * Sounds are cached using mmap (if available) or malloc (no mmap). * Non-cached sounds are read piece by piece. * * MEMORY_CACHE_SOUND_SIZE - maximum size of a sound that can be cached in memory. * MEMORY_CACHE_SIZE - maximum size of the entire memory cache. * * Setting MEMORY_CACHE_SIZE=0 will disable the memory cache. */ #define MEMORY_CACHE_SOUND_SIZE (2*1024*1024) #define MEMORY_CACHE_SIZE (4*1024*1024) /* * Delay time between RPTP server pings. */ #define RPTP_PING_DELAY 5 /* * Number of times to try and connect to an RPTP server. */ #define RPTP_CONNECT_ATTEMPTS 3 /* * Close RPTP connections after 300 idle seconds (disabled with zero). */ #define RPTP_CONNECTION_TIMEOUT 300 /* * Maximum number of RPTP client connections (disabled with zero). */ #define RPTP_MAX_CONNECTIONS 16 /* * Enable simulated hardware volume control. */ /* #define FAKE_VOLUME */ /* * Enable the automatic re-reading of rplayd's configuration files when * they are modified. */ #define AUTO_REREAD /* * The maximum sample rate that rplayd will/can ever output. */ #define MAX_SAMPLE_RATE 48000 /* 48000 Hz */ /* * A list of directories that cannot be accessed to obtain sound files. * This feature can be disabled using `#undef BAD_DIRS'. */ #define BAD_DIRS "/dev:/etc:/devices:/proc" #define HAVE_ADPCM #define HAVE_GSM #undef HAVE_CDROM #undef HAVE_CDDA #if defined (sun) && defined (SVR4) /* Solaris 2.x */ #define HAVE_CDROM #define HAVE_CDDA #endif /* Solaris 2.x */ #if defined (linux) #define HAVE_OSS #define HAVE_CDROM #endif #define HAVE_HELPERS /*************** EVERYTHING BELOW THIS LINE SHOULD BE OK *********************/ #undef HAVE_STRDUP #undef HAVE_STRERROR #undef HAVE_MMAP #undef HAVE_FSTAT #undef HAVE_FCHMOD #undef HAVE_FCHOWN #undef HAVE_UTIME #undef HAVE_UTIMES #undef HAVE_MEMMOVE #undef HAVE_SIGSET #undef HAVE_WAITPID #undef HAVE_SNPRINTF #undef HAVE_VSNPRINTF #undef HAVE_LIBREADLINE #undef HAVE_RANDOM #undef HAVE_SRANDOM #undef HAVE_STDC_HEADERS #undef HAVE_MEMORY_H #undef HAVE_STRING_H #undef HAVE_STDLIB_H #undef HAVE_LIMITS_H #undef HAVE_FCNTL_H #undef HAVE_STRING_H #undef HAVE_STRINGS_H #undef HAVE_UNISTD_H #undef HAVE_UTIME_H #undef HAVE_SYS_WAIT_H #undef HAVE_GSM_H #undef HAVE_GSM_GSM_H #undef HAVE_RXPOSIX_H #undef HAVE_RX_RXPOSIX_H /* Convert HAVE_ to HAS_ for gsm. See gsm/include/config.h.gsm */ #ifdef HAVE_STDLIB_H #define HAS_STDLIB_H #endif #ifdef HAVE_LIMITS_H #define HAS_LIMITS_H #endif #ifdef HAVE_FCNTL_H #define HAS_FCNTL_H #endif #ifdef HAVE_FSTAT #define HAS_FSTAT #endif #ifdef HAVE_FCHOWN #define HAS_FCHOWN #endif #ifdef HAVE_STRING_H #define HAS_STRING_H #endif #ifdef HAVE_STRINGS_H #define HAS_STRINGS_H #endif #ifdef HAVE_UNISTD_H #define HAS_UNISTD_H #endif #ifdef HAVE_UTIME #define HAS_UTIME #endif #ifdef HAVE_UTIMES #define HAS_UTIMES #endif #ifdef HAVE_UTIME_H #define HAS_UTIMES_H #endif /* * Maximum UDP packet size. */ #define MAX_PACKET 8192 /* * Solaris 2.x using gcc or SunPro cc and HP-UX */ #if (defined(sun) && (defined(__svr4__) || defined(SVR4))) || defined(__hpux) #ifndef HAVE_RANDOM #define random() lrand48() #endif #ifndef HAVE_SRANDOM #define srandom(x) srand48(x) #endif #endif #ifndef MIN #define MIN(a,b) (((a)<(b))?(a):(b)) #endif #ifndef MAX #define MAX(a,b) (((a)>(b))?(a):(b)) #endif #ifndef HAVE_MEMMOVE #define memmove(d, s, n) bcopy ((s), (d), (n)) #endif #ifdef HAVE_SNPRINTF #define SNPRINTF snprintf #else #define SNPRINTF sprintf #endif #ifdef HAVE_VSNPRINTF #define VSNPRINTF vsnprintf #else #define VSNPRINTF vsprintf #endif #if defined(HAVE_SNPRINTF) || defined(HAVE_VSNPRINTF) #define SIZE(buf, n) buf,n #else #define SIZE(buf, n) buf #endif #ifndef RPLAY_VERSION #define RPLAY_VERSION "" #endif #endif /* _config_h */ rplay-3.3.2/include/rplay.h100644 153 62 25164 6671422747 14307 0ustar boynsstaff/* $Id: rplay.h,v 1.3 1999/03/10 07:57:27 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _rplay_h #define _rplay_h #include #include #include #include #include #undef FALSE #define FALSE 0 #undef TRUE #define TRUE 1 #define RPLAY_PORT 5555 #define RPTP_PORT 5556 #define OLD_RPLAY_PORT 55555 #define OLD_RPTP_PORT 55556 #define RPLAY_PACKET_ID 30 /* id sent with rplay 3.x packets */ /* Attributes: */ #define RPLAY_NULL 0 #define RPLAY_PLAY 1 #define RPLAY_STOP 2 #define RPLAY_PAUSE 3 #define RPLAY_CONTINUE 4 #define RPLAY_SOUND 5 #define RPLAY_VOLUME 6 #define RPLAY_NSOUNDS 7 #define RPLAY_COMMAND 8 #define RPLAY_APPEND 9 #define RPLAY_INSERT 10 #define RPLAY_DELETE 11 #define RPLAY_CHANGE 12 #define RPLAY_COUNT 13 #define RPLAY_LIST_COUNT 14 #define RPLAY_PRIORITY 15 #define RPLAY_RANDOM_SOUND 16 #define RPLAY_PING 17 #define RPLAY_RPTP_SERVER 18 #define RPLAY_RPTP_SERVER_PORT 19 #define RPLAY_RPTP_SEARCH 20 #define RPLAY_RPTP_FROM_SENDER 21 #define RPLAY_SAMPLE_RATE 22 #define RPLAY_RESET 23 #define RPLAY_DONE 24 #define RPLAY_CLIENT_DATA 25 #define RPLAY_LIST_NAME 26 #define RPLAY_PUT 27 #define RPLAY_ID 28 #define RPLAY_SEQUENCE 29 #define RPLAY_DATA 30 #define RPLAY_DATA_SIZE 31 /* audio formats */ #define RPLAY_FORMAT_NONE 0 #define RPLAY_FORMAT_LINEAR_8 1 /* 8-bit linear PCM */ #define RPLAY_FORMAT_ULINEAR_8 2 /* 8-bit unsigned linear PCM */ #define RPLAY_FORMAT_LINEAR_16 3 /* 16-bit linear PCM */ #define RPLAY_FORMAT_ULINEAR_16 4 /* 16-bit unsigned linear PCM */ #define RPLAY_FORMAT_ULAW 5 /* 8-bit ISDN u-law */ #define RPLAY_FORMAT_G721 6 /* CCITT G.721 4-bits ADPCM */ #define RPLAY_FORMAT_G723_3 7 /* CCITT G.723 3-bits ADPCM */ #define RPLAY_FORMAT_G723_5 8 /* CCITT G.723 5-bits ADPCM */ #define RPLAY_FORMAT_GSM 9 /* GSM 0.610 13 kbit/s RPE/LTP speech compression */ /* audio byte order */ #define RPLAY_BIG_ENDIAN 1 #define RPLAY_LITTLE_ENDIAN 2 /* Audio ports: */ #define RPLAY_AUDIO_PORT_NONE (1<<0) #define RPLAY_AUDIO_PORT_SPEAKER (1<<1) #define RPLAY_AUDIO_PORT_HEADPHONE (1<<2) #define RPLAY_AUDIO_PORT_LINEOUT (1<<3) /* Attribute restrictions: */ #define RPLAY_MIN_VOLUME 0 #define RPLAY_MAX_VOLUME 255 #define RPLAY_MIN_PRIORITY 0 #define RPLAY_MAX_PRIORITY 255 /* Attribute defaults: */ #define RPLAY_DEFAULT_VOLUME 127 #define RPLAY_DEFAULT_PRIORITY 0 #define RPLAY_DEFAULT_COUNT 1 #define RPLAY_DEFAULT_LIST_COUNT 1 #define RPLAY_DEFAULT_RANDOM_SOUND -1 #define RPLAY_DEFAULT_SAMPLE_RATE 0 #define RPLAY_DEFAULT_OFFSET 0 #define RPLAY_DEFAULT_BYTE_ORDER 0 #define RPLAY_DEFAULT_CHANNELS 0 #define RPLAY_DEFAULT_BITS 0 /* RPLAY errors used by rplay_errno: */ #define RPLAY_ERROR_NONE 0 #define RPLAY_ERROR_MEMORY 1 #define RPLAY_ERROR_HOST 2 #define RPLAY_ERROR_CONNECT 3 #define RPLAY_ERROR_SOCKET 4 #define RPLAY_ERROR_WRITE 5 #define RPLAY_ERROR_CLOSE 6 #define RPLAY_ERROR_PACKET_SIZE 7 #define RPLAY_ERROR_BROADCAST 8 #define RPLAY_ERROR_ATTRIBUTE 9 #define RPLAY_ERROR_COMMAND 10 #define RPLAY_ERROR_INDEX 11 #define RPLAY_ERROR_MODIFIER 12 /* RPTP errors used by rptp_errno: */ #define RPTP_ERROR_NONE 0 #define RPTP_ERROR_MEMORY 1 #define RPTP_ERROR_HOST 2 #define RPTP_ERROR_CONNECT 3 #define RPTP_ERROR_SOCKET 4 #define RPTP_ERROR_OPEN 5 #define RPTP_ERROR_READ 6 #define RPTP_ERROR_WRITE 7 #define RPTP_ERROR_PING 8 #define RPTP_ERROR_TIMEOUT 9 #define RPTP_ERROR_PROTOCOL 10 /* RPTP response types: */ #define RPTP_ERROR '-' #define RPTP_OK '+' #define RPTP_TIMEOUT '!' #define RPTP_NOTIFY '@' /* RPLAY 2.0 support: */ #define OLD_RPLAY_PLAY 1 #define OLD_RPLAY_STOP 2 #define OLD_RPLAY_PAUSE 3 #define OLD_RPLAY_CONTINUE 4 /* Definitions for the RPTP asynchronous I/O system: */ #define RPTP_ASYNC_READ 1 #define RPTP_ASYNC_WRITE 2 #define RPTP_ASYNC_RAW 4 #define RPTP_ASYNC_ENABLE 1 #define RPTP_ASYNC_DISABLE 2 /* These event can be used to specify a mask: */ #define RPTP_EVENT_OK (1 << 0) #define RPTP_EVENT_ERROR (1 << 1) #define RPTP_EVENT_TIMEOUT (1 << 2) #define RPTP_EVENT_OTHER (1 << 3) #define RPTP_EVENT_CONTINUE (1 << 4) #define RPTP_EVENT_DONE (1 << 5) #define RPTP_EVENT_PAUSE (1 << 6) #define RPTP_EVENT_PLAY (1 << 7) #define RPTP_EVENT_SKIP (1 << 8) #define RPTP_EVENT_STATE (1 << 9) #define RPTP_EVENT_STOP (1 << 10) #define RPTP_EVENT_VOLUME (1 << 11) #define RPTP_EVENT_CLOSE (1 << 12) #define RPTP_EVENT_FLOW (1 << 13) #define RPTP_EVENT_MODIFY (1 << 14) #define RPTP_EVENT_LEVEL (1 << 15) #define RPTP_EVENT_POSITION (1 << 16) #define RPTP_EVENT_ALL 0x0000ffff /* Size restrictions for RPTP: */ #define RPTP_MAX_LINE 1024 #define RPTP_MAX_ARGS 32 /* rplay object attributes: */ typedef struct _rplay_attrs { struct _rplay_attrs *next; char *sound; int volume; int count; char *rptp_server; unsigned short rptp_server_port; int rptp_search; unsigned long sample_rate; char *client_data; } RPLAY_ATTRS; /* the rplay object */ typedef struct _rplay { struct _rplay_attrs *attrs; struct _rplay_attrs **attrsp; char *buf; int len; int size; int command; int nsounds; int count; int priority; int random_sound; char *list_name; int id; unsigned long sequence; unsigned short data_size; char *data; } RPLAY; extern int rplay_errno; extern int rptp_errno; extern char *rplay_errlist[]; extern char *rptp_errlist[]; #ifdef __cplusplus #ifndef __STDC__ #define __STDC__ #endif extern "C" { #endif #ifdef __STDC__ extern void * xmalloc(size_t size); extern RPLAY *rplay_create (int rplay_command); extern char *rplay_convert (char *buf); extern int rplay_pack (RPLAY * rp); extern RPLAY *rplay_unpack (char *buf); extern void rplay_destroy (RPLAY * rp); extern long rplay_set (RPLAY *,...); extern long rplay_get (RPLAY *,...); extern int rplay_open (char *host); extern int rplay_open_port (char *host, int port); extern int rplay_open_sockaddr_in (struct sockaddr_in *saddr); extern int rplay (int rplay_fd, RPLAY * rp); extern int rplay_close (int rplay_fd); extern void rplay_perror (char *message); extern int rplay_open_display (void); extern int rplay_display (char *sound); extern int rplay_local (char *sound); extern int rplay_host (char *host, char *sound); extern int rplay_host_volume (char *host, char *sound, int volume); extern int rplay_sound (int rplay_fd, char *sound); extern int rplay_ping (char *host); extern int rplay_ping_sockaddr_in (struct sockaddr_in *saddr); extern int rplay_ping_sockfd (int sock_fd); extern char *rplay_default_host (void); extern int rplay_default (char *sound); extern int rplay_open_default (void); extern int rptp_open (char *host, int port, char *response, int response_size); extern int rptp_read (int rptp_fd, char *buf, int nbytes); extern int rptp_write (int rptp_fd, char *buf, int nbytes); extern int rptp_close (int rptp_fd); extern void rptp_perror (char *message); extern int rptp_putline (int rptp_fd, char *fmt,...); extern int rptp_getline (int rptp_fd, char *buf, int nbytes); extern int rptp_command (int rptp_fd, char *command, char *response, int response_size); extern char *rptp_parse (char *response, char *name); extern int rptp_async_putline (int rptp_fd, void (*callback)(), char *fmt, ...); extern int rptp_async_write (int rptp_fd, void (*callback)(), char *ptr, int nbytes); extern void rptp_async_register(int rptp_fd, int what, void (*callback)()); extern void rptp_async_notify (int rptp_fd, int mask, void (*callback)()); extern void rptp_async_process (int rptp_fd, int what); extern int rptp_main_loop (void); extern void rptp_stop_main_loop (int); #else extern RPLAY *rplay_create ( /* int rplay_command */ ); extern char *rplay_convert ( /* char *buf */ ); extern int rplay_pack ( /* RPLAY *rp */ ); extern RPLAY *rplay_unpack ( /* char *buf */ ); extern void rplay_destroy ( /* RPLAY *rp */ ); extern int rplay_set ( /* RPLAY *, ... */ ); extern int rplay_get ( /* RPLAY *, ... */ ); extern int rplay_open ( /* char *host */ ); extern int rplay_open_port ( /* char *host, int port */ ); extern int rplay_open_sockaddr_in ( /* struct sockaddr_in *saddr */ ); extern int rplay ( /* int rplay_fd, RPLAY *rp */ ); extern int rplay_close ( /* int rplay_fd */ ); extern void rplay_perror ( /* char *message */ ); extern int rplay_open_display (); extern int rplay_display ( /* char *sound */ ); extern int rplay_local ( /* char *sound */ ); extern int rplay_host ( /* char *host, char *sound */ ); extern int rplay_host_volume ( /* char *host, char *sound, int volume */ ); extern int rplay_sound ( /* int rplay_fd, char *sound */ ); extern int rplay_ping ( /* char *host */ ); extern int rplay_ping_sockaddr_in ( /* struct sockaddr_in *saddr */ ); extern int rplay_ping_sockfd ( /* int sock_fd */ ); extern char *rplay_default_host (); extern int rplay_default ( /* char *sound */ ); extern int rplay_open_default (); extern int rptp_open ( /* char *host, int port, char *response, int response_size */ ); extern int rptp_read ( /* int rptp_fd, char *buf, int nbytes */ ); extern int rptp_write ( /* int rptp_fd, char *buf, int nbytes */ ); extern int rptp_close ( /* int rptp_fd */ ); extern void rptp_perror ( /* char *message */ ); extern int rptp_putline ( /* int rptp_fd, char *fmt, ... */ ); extern int rptp_getline ( /* int rptp_fd, char *buf, int nbytes */ ); extern int rptp_command ( /* int rptp_fd, char *command, char *response, int response_size */ ); extern char *rptp_parse ( /* char *response, char *name */ ); extern int rptp_async_putline ( /* int rptp_fd, void (callback *)(), char *fmt, ... */ ); extern int rptp_async_write ( /* int rptp_fd, void (callback *)(), char *ptr, int nbytes */ ); extern void rptp_async_register (/* int rptp_fd, int what, void (callback*)() */ ); extern void rptp_async_notify ( /* int rptp_fd, int what, void (*callback)() */ ); extern void rptp_async_process ( /* int rptp_fd, int what */ ); extern int rptp_main_loop (); extern void rptp_stop_main_loop (); #endif #ifdef __cplusplus } #endif #endif /* _rplay_h */ rplay-3.3.2/include/version.h100644 153 62 2041 6671422747 14612 0ustar boynsstaff/* $Id: version.h,v 1.5 1999/03/10 07:57:27 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _version_h #define _version_h #define RPLAY_MAJOR_VERSION 3 #define RPLAY_MINOR_VERSION 3 #define RPLAY_PATCHLEVEL 2 #define RPLAY_STATUS "" #endif /* _version_h */ rplay-3.3.2/java/ 40755 153 62 0 6727650077 12161 5ustar boynsstaffrplay-3.3.2/java/org/ 40755 153 62 0 6727650077 12750 5ustar boynsstaffrplay-3.3.2/java/org/doit/ 40755 153 62 0 6727650077 13707 5ustar boynsstaffrplay-3.3.2/java/org/doit/io/ 40755 153 62 0 6727650077 14316 5ustar boynsstaffrplay-3.3.2/java/org/doit/io/ByteArray.java100644 153 62 7102 6564574526 17163 0ustar boynsstaff/* $Id: ByteArray.java,v 1.2 1998/08/13 14:33:58 boyns Exp $ */ /* * Copyright (C) 1996-98 Mark R. Boyns * * This file is part of Muffin. * * Muffin is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Muffin is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Muffin; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ package org.doit.io; /** * Class used to represent an array of bytes as an Object. * * @author Mark Boyns */ public class ByteArray { public byte bytes[]; public int offset = 0; /** * Create a ByteArray with the default size. */ public ByteArray () { this (512); } /** * Create a ByteArray with a specific default size. */ public ByteArray (int size) { bytes = new byte[size]; } /** * Create a ByteArray from a String. */ public ByteArray (String s) { this (s.length ()); append (s); } /** * Create a ByteArray from an array of bytes. */ public ByteArray (byte b[]) { this (b.length); append (b); } /** * Append a byte. */ public void append (byte ch) { if (offset == bytes.length) { byte tmpbytes[] = bytes; bytes = new byte[tmpbytes.length * 2]; System.arraycopy (tmpbytes, 0, bytes, 0, offset); } bytes[offset++] = ch; } /** * Append a ByteArray. */ public void append (ByteArray b) { if (bytes.length - offset < b.length ()) { byte tmpbytes[] = bytes; bytes = new byte[tmpbytes.length + b.length ()]; System.arraycopy (tmpbytes, 0, bytes, 0, offset); } System.arraycopy (b.bytes, 0, bytes, offset, b.length ()); offset += b.length (); } /** * Append an array of bytes. */ public void append (byte b[]) { if (bytes.length - offset < b.length) { byte tmpbytes[] = bytes; bytes = new byte[tmpbytes.length + b.length]; System.arraycopy (tmpbytes, 0, bytes, 0, offset); } System.arraycopy (b, 0, bytes, offset, b.length); offset += b.length; } /** * Append a String. */ public void append (String s) { append (s.getBytes ()); } /** * Convert to String. */ public String toString () { return new String (bytes, 0, offset); } /** * Return the bytes. */ public byte getBytes () [] { return bytes; } public byte get (int i) { return bytes[i]; } /** * Return the number of bytes. */ public int length () { return offset; } public void erase () { offset = 0; } public void chop () { chop (1); } public void chop (int i) { offset -= i; if (offset < 0) { offset = 0; } } public static void main (String args[]) { ByteArray b = new ByteArray (3); b.append ("foo"); b.append ("bar"); b.append ("joe"); System.out.println (b.toString ()); ByteArray tmp = new ByteArray (1); tmp.append ("test"); b.append (tmp); System.out.println (b.toString ()); } } rplay-3.3.2/java/org/doit/rplay/ 40755 153 62 0 6727650077 15036 5ustar boynsstaffrplay-3.3.2/java/org/doit/rplay/RPlay.java100644 153 62 7223 6564574527 17035 0ustar boynsstaff/* $Id: RPlay.java,v 1.3 1998/08/13 14:33:59 boyns Exp $ */ /* * Copyright (C) 1998 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ package org.doit.rplay; import org.doit.io.ByteArray; import java.util.*; import java.net.*; public class RPlay { final byte RPLAY_PACKET_ID = 30; final byte RPLAY_NULL = 0; final byte RPLAY_PLAY = 1; final byte RPLAY_STOP = 2; final byte RPLAY_PAUSE = 3; final byte RPLAY_CONTINUE = 4; final byte RPLAY_SOUND = 5; final byte RPLAY_VOLUME = 6; final byte RPLAY_PRIORITY = 15; final byte RPLAY_RANDOM_SOUND = 16; final byte RPLAY_SAMPLE_RATE = 22; final byte RPLAY_PUT = 27; final byte RPLAY_ID = 28; final byte RPLAY_SEQUENCE = 29; final byte RPLAY_DATA = 30; final byte RPLAY_DATA_SIZE = 31; final int RPLAY_PORT = 5555; private DatagramSocket socket; private InetAddress serverAddr; private Hashtable attrs = new Hashtable (); private byte command; public void open (String hostname) throws Exception { serverAddr = InetAddress.getByName (hostname); socket = new DatagramSocket (); } public void close () { socket.close (); } public void play (String sound) { command = RPLAY_PLAY; attrs.put ("sound", sound); doit (); } public void stop (String sound) { command = RPLAY_STOP; attrs.put ("sound", sound); doit (); } public void pause (String sound) { command = RPLAY_PAUSE; attrs.put ("sound", sound); doit (); } public void resume (String sound) { command = RPLAY_CONTINUE; attrs.put ("sound", sound); doit (); } public void put (int id, int sequence, byte data[]) { command = RPLAY_PUT; attrs.put ("id", new Byte (id)); attrs.put ("sequence", new Integer (sequence)); attrs.put ("data", new ByteArray (data)); doit (); } void doit () { ByteArray pack = new ByteArray (); pack.append (RPLAY_PACKET_ID); pack.append (command); Enumeration e = attrs.keys (); while (e.hasMoreElements ()) { String key = (String) e.nextElement (); if (key.equals ("sound")) { pack.append (RPLAY_SOUND); pack.append ((String) attrs.get (key)); pack.append ((byte)0); } else if (key.equals ("id")) { pack.append (RPLAY_ID); pack.append (((Byte) attrs.get (key)).byteValue ()); } else if (key.equals ("sequence")) { pack.append (RPLAY_ID); /* // need network byte order -> pack.append (((Integer) attrs.get (key)).Value ()); */ } } pack.append (RPLAY_NULL); pack.append (RPLAY_NULL); DatagramPacket packet = new DatagramPacket (pack.getBytes (), pack.length (), serverAddr, RPLAY_PORT); try { socket.send (packet); } catch (Exception ex) { System.out.println (ex); } } public static void main (String argv[]) throws Exception { RPlay rp = new RPlay (); rp.open ("doit.sdsu.edu"); rp.play (argv[0]); rp.close (); } } rplay-3.3.2/lib/ 40755 153 62 0 6727650077 12006 5ustar boynsstaffrplay-3.3.2/lib/Makefile.in100644 153 62 1337 6552756453 14155 0ustar boynsstaffinclude @RPLAY_TOP@/Makefile.config srcdir = @srcdir@ VPATH = @srcdir@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ CPPFLAGS= $(CC_OPTIONS) -I. -I../include -I@srcdir@/../include -I@srcdir@/../lib @DEFS@ .c.o: $(CC) -c $(CPPFLAGS) $(CFLAGS) $< TARGET= librp.a SRCS= getopt.c getopt1.c hash.c strdup.c tilde.c xmalloc.c OBJS= getopt.o getopt1.o hash.o strdup.o tilde.o xmalloc.o all: $(TARGET) $(TARGET): $(OBJS) $(AR) rcv $@ $? $(RANLIB) $@ install: uninstall: clean: $(RM) $(OBJS) $(TARGET) a.out core *~ *.bak *.orig TAGS distclean: clean $(RM) Makefile tags: $(TAGS) *.[ch] TAGS: tags etags: tags depend: $(MAKEDEPEND) -- $(CPPFLAGS) $(CFLAGS) -- $(SRCS) rplay-3.3.2/lib/ansidecl.h100644 153 62 10406 6552756453 14060 0ustar boynsstaff/* ANSI and traditional C compatability macros Copyright 1991, 1992 Free Software Foundation, Inc. This file is part of the GNU C Library. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ANSI and traditional C compatibility macros ANSI C is assumed if __STDC__ is #defined. Macro ANSI C definition Traditional C definition ----- ---- - ---------- ----------- - ---------- PTR `void *' `char *' LONG_DOUBLE `long double' `double' VOLATILE `volatile' `' SIGNED `signed' `' PTRCONST `void *const' `char *' ANSI_PROTOTYPES 1 not defined CONST is also defined, but is obsolete. Just use const. DEFUN (name, arglist, args) Defines function NAME. ARGLIST lists the arguments, separated by commas and enclosed in parentheses. ARGLIST becomes the argument list in traditional C. ARGS list the arguments with their types. It becomes a prototype in ANSI C, and the type declarations in traditional C. Arguments should be separated with `AND'. For functions with a variable number of arguments, the last thing listed should be `DOTS'. DEFUN_VOID (name) Defines a function NAME, which takes no arguments. obsolete -- EXFUN (name, (prototype)) -- obsolete. Replaced by PARAMS. Do not use; will disappear someday soon. Was used in external function declarations. In ANSI C it is `NAME PROTOTYPE' (so PROTOTYPE should be enclosed in parentheses). In traditional C it is `NAME()'. For a function that takes no arguments, PROTOTYPE should be `(void)'. PARAMS ((args)) We could use the EXFUN macro to handle prototype declarations, but the name is misleading and the result is ugly. So we just define a simple macro to handle the parameter lists, as in: static int foo PARAMS ((int, char)); This produces: `static int foo();' or `static int foo (int, char);' EXFUN would have done it like this: static int EXFUN (foo, (int, char)); but the function is not external...and it's hard to visually parse the function name out of the mess. EXFUN should be considered obsolete; new code should be written to use PARAMS. For example: extern int printf PARAMS ((CONST char *format DOTS)); int DEFUN(fprintf, (stream, format), FILE *stream AND CONST char *format DOTS) { ... } void DEFUN_VOID(abort) { ... } */ #ifndef _ANSIDECL_H #define _ANSIDECL_H 1 /* Every source file includes this file, so they will all get the switch for lint. */ /* LINTLIBRARY */ #if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) /* All known AIX compilers implement these things (but don't always define __STDC__). The RISC/OS MIPS compiler defines these things in SVR4 mode, but does not define __STDC__. */ #define PTR void * #define PTRCONST void *CONST #define LONG_DOUBLE long double #define AND , #define NOARGS void #define CONST const #define VOLATILE volatile #define SIGNED signed #define DOTS , ... #define EXFUN(name, proto) name proto #define DEFUN(name, arglist, args) name(args) #define DEFUN_VOID(name) name(void) #define PROTO(type, name, arglist) type name arglist #define PARAMS(paramlist) paramlist #define ANSI_PROTOTYPES 1 #else /* Not ANSI C. */ #define PTR char * #define PTRCONST PTR #define LONG_DOUBLE double #define AND ; #define NOARGS #define CONST #ifndef const /* some systems define it in header files for non-ansi mode */ #define const #endif #define VOLATILE #define SIGNED #define DOTS #define EXFUN(name, proto) name() #define DEFUN(name, arglist, args) name arglist args; #define DEFUN_VOID(name) name() #define PROTO(type, name, arglist) type name () #define PARAMS(paramlist) () #endif /* ANSI C. */ #endif /* ansidecl.h */ rplay-3.3.2/lib/getopt.c100644 153 62 52421 6552756453 13576 0ustar boynsstaff/* Getopt for GNU. NOTE: getopt is now part of the C library, so if you don't know what "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu before changing it! Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* This tells Alpha OSF/1 not to define a getopt prototype in . Ditto for AIX 3.2 and . */ #ifndef _NO_PROTO #define _NO_PROTO #endif #ifdef HAVE_CONFIG_H #if defined (emacs) || defined (CONFIG_BROKETS) /* We use instead of "config.h" so that a compilation using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h (which it would do because it found this file in $srcdir). */ #include #else #include "config.h" #endif #endif #ifndef __STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ #ifndef const #define const #endif #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #if defined (_LIBC) || !defined (__GNU_LIBRARY__) /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ /* Don't include stdlib.h for non-GNU C libraries because some of them contain conflicting prototypes for getopt. */ #include #endif /* GNU C library. */ /* This version of `getopt' appears to the caller like standard Unix `getopt' but it behaves differently for the user, since it allows the user to intersperse the options with the other arguments. As `getopt' works, it permutes the elements of ARGV so that, when it is done, all the options precede everything else. Thus all application programs are extended to handle flexible argument order. Setting the environment variable POSIXLY_CORRECT disables permutation. Then the behavior is completely standard. GNU application programs can use a third alternative mode in which they can distinguish the relative order of options and other arguments. */ #include "getopt.h" /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ char *optarg = NULL; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns EOF, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ /* XXX 1003.2 says this must be 1 before any call. */ int optind = 0; /* The next char to be scanned in the option-element in which the last option character we returned was found. This allows us to pick up the scan where we left off. If this is zero, or a null string, it means resume the scan by advancing to the next ARGV-element. */ static char *nextchar; /* Callers store zero here to inhibit the error message for unrecognized options. */ int opterr = 1; /* Set to an option character which was unrecognized. This must be initialized on some systems to avoid linking in the system's own getopt implementation. */ int optopt = '?'; /* Describe how to deal with options that follow non-option ARGV-elements. If the caller did not specify anything, the default is REQUIRE_ORDER if the environment variable POSIXLY_CORRECT is defined, PERMUTE otherwise. REQUIRE_ORDER means don't recognize them as options; stop option processing when the first non-option is seen. This is what Unix does. This mode of operation is selected by either setting the environment variable POSIXLY_CORRECT, or using `+' as the first character of the list of option characters. PERMUTE is the default. We permute the contents of ARGV as we scan, so that eventually all the non-options are at the end. This allows options to be given in any order, even with programs that were not written to expect this. RETURN_IN_ORDER is an option available to programs that were written to expect options and other ARGV-elements in any order and that care about the ordering of the two. We describe each non-option ARGV-element as if it were the argument of an option with character code 1. Using `-' as the first character of the list of option characters selects this mode of operation. The special argument `--' forces an end of option-scanning regardless of the value of `ordering'. In the case of RETURN_IN_ORDER, only `--' can cause `getopt' to return EOF with `optind' != ARGC. */ static enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering; #ifdef __GNU_LIBRARY__ /* We want to avoid inclusion of string.h with non-GNU libraries because there are many ways it can cause trouble. On some systems, it contains special magic macros that don't work in GCC. */ #include #define my_index strchr #else /* Avoid depending on library functions or files whose names are inconsistent. */ char *getenv (); static char * my_index (str, chr) const char *str; int chr; { while (*str) { if (*str == chr) return (char *) str; str++; } return 0; } /* If using GCC, we can safely declare strlen this way. If not using GCC, it is ok not to declare it. */ #ifdef __GNUC__ /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. That was relevant to code that was here before. */ #ifndef __STDC__ /* gcc with -traditional declares the built-in strlen to return int, and has done so at least since version 2.4.5. -- rms. */ extern int strlen (const char *); #endif /* not __STDC__ */ #endif /* __GNUC__ */ #endif /* not __GNU_LIBRARY__ */ /* Handle permutation of arguments. */ /* Describe the part of ARGV that contains non-options that have been skipped. `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is the index after the last of them. */ static int first_nonopt; static int last_nonopt; /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) which contains all the non-options that have been skipped so far. The other is elements [last_nonopt,optind), which contains all the options processed since those non-options were skipped. `first_nonopt' and `last_nonopt' are relocated so that they describe the new indices of the non-options in ARGV after they are moved. */ static void exchange (argv) char **argv; { int bottom = first_nonopt; int middle = last_nonopt; int top = optind; char *tem; /* Exchange the shorter segment with the far end of the longer segment. That puts the shorter segment into the right place. It leaves the longer segment in the right place overall, but it consists of two parts that need to be swapped next. */ while (top > middle && middle > bottom) { if (top - middle > middle - bottom) { /* Bottom segment is the short one. */ int len = middle - bottom; register int i; /* Swap it with the top part of the top segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[top - (middle - bottom) + i]; argv[top - (middle - bottom) + i] = tem; } /* Exclude the moved bottom segment from further swapping. */ top -= len; } else { /* Top segment is the short one. */ int len = top - middle; register int i; /* Swap it with the bottom part of the bottom segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[middle + i]; argv[middle + i] = tem; } /* Exclude the moved top segment from further swapping. */ bottom += len; } } /* Update records for the slots the non-options now occupy. */ first_nonopt += (optind - last_nonopt); last_nonopt = optind; } /* Initialize the internal data when the first call is made. */ static const char * _getopt_initialize (optstring) const char *optstring; { /* Start processing options with ARGV-element 1 (since ARGV-element 0 is the program name); the sequence of previously skipped non-option ARGV-elements is empty. */ first_nonopt = last_nonopt = optind = 1; nextchar = NULL; /* Determine how to handle the ordering of options and nonoptions. */ if (optstring[0] == '-') { ordering = RETURN_IN_ORDER; ++optstring; } else if (optstring[0] == '+') { ordering = REQUIRE_ORDER; ++optstring; } else if (getenv ("POSIXLY_CORRECT") != NULL) ordering = REQUIRE_ORDER; else ordering = PERMUTE; return optstring; } /* Scan elements of ARGV (whose length is ARGC) for option characters given in OPTSTRING. If an element of ARGV starts with '-', and is not exactly "-" or "--", then it is an option element. The characters of this element (aside from the initial '-') are option characters. If `getopt' is called repeatedly, it returns successively each of the option characters from each of the option elements. If `getopt' finds another option character, it returns that character, updating `optind' and `nextchar' so that the next call to `getopt' can resume the scan with the following option character or ARGV-element. If there are no more option characters, `getopt' returns `EOF'. Then `optind' is the index in ARGV of the first ARGV-element that is not an option. (The ARGV-elements have been permuted so that those that are not options now come last.) OPTSTRING is a string containing the legitimate option characters. If an option character is seen that is not listed in OPTSTRING, return '?' after printing an error message. If you set `opterr' to zero, the error message is suppressed but we still return '?'. If a char in OPTSTRING is followed by a colon, that means it wants an arg, so the following text in the same ARGV-element, or the text of the following ARGV-element, is returned in `optarg'. Two colons mean an option that wants an optional arg; if there is text in the current ARGV-element, it is returned in `optarg', otherwise `optarg' is set to zero. If OPTSTRING starts with `-' or `+', it requests different methods of handling the non-option ARGV-elements. See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. Long-named options begin with `--' instead of `-'. Their names may be abbreviated as long as the abbreviation is unique or is an exact match for some defined option. If they have an argument, it follows the option name in the same ARGV-element, separated from the option name by a `=', or else the in next ARGV-element. When `getopt' finds a long-named option, it returns 0 if that option's `flag' field is nonzero, the value of the option's `val' field if the `flag' field is zero. The elements of ARGV aren't really const, because we permute them. But we pretend they're const in the prototype to be compatible with other systems. LONGOPTS is a vector of `struct option' terminated by an element containing a name which is zero. LONGIND returns the index in LONGOPT of the long-named option found. It is only valid when a long-named option has been found by the most recent call. If LONG_ONLY is nonzero, '-' as well as '--' can introduce long-named options. */ int _getopt_internal (argc, argv, optstring, longopts, longind, long_only) int argc; char *const *argv; const char *optstring; const struct option *longopts; int *longind; int long_only; { optarg = NULL; if (optind == 0) optstring = _getopt_initialize (optstring); if (nextchar == NULL || *nextchar == '\0') { /* Advance to the next ARGV-element. */ if (ordering == PERMUTE) { /* If we have just processed some options following some non-options, exchange them so that the options come first. */ if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (last_nonopt != optind) first_nonopt = optind; /* Skip any additional non-options and extend the range of non-options previously skipped. */ while (optind < argc && (argv[optind][0] != '-' || argv[optind][1] == '\0')) optind++; last_nonopt = optind; } /* The special ARGV-element `--' means premature end of options. Skip it like a null option, then exchange with previous non-options as if it were an option, then skip everything else like a non-option. */ if (optind != argc && !strcmp (argv[optind], "--")) { optind++; if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (first_nonopt == last_nonopt) first_nonopt = optind; last_nonopt = argc; optind = argc; } /* If we have done all the ARGV-elements, stop the scan and back over any non-options that we skipped and permuted. */ if (optind == argc) { /* Set the next-arg-index to point at the non-options that we previously skipped, so the caller will digest them. */ if (first_nonopt != last_nonopt) optind = first_nonopt; return EOF; } /* If we have come to a non-option and did not permute it, either stop the scan or describe it to the caller and pass it by. */ if ((argv[optind][0] != '-' || argv[optind][1] == '\0')) { if (ordering == REQUIRE_ORDER) return EOF; optarg = argv[optind++]; return 1; } /* We have found another option-ARGV-element. Skip the initial punctuation. */ nextchar = (argv[optind] + 1 + (longopts != NULL && argv[optind][1] == '-')); } /* Decode the current option-ARGV-element. */ /* Check whether the ARGV-element is a long option. If long_only and the ARGV-element has the form "-f", where f is a valid short option, don't consider it an abbreviated form of a long option that starts with f. Otherwise there would be no way to give the -f short option. On the other hand, if there's a long option "fubar" and the ARGV-element is "-fu", do consider that an abbreviation of the long option, just like "--fu", and not "-f" with arg "u". This distinction seems to be the most useful approach. */ if (longopts != NULL && (argv[optind][1] == '-' || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) { char *nameend; const struct option *p; const struct option *pfound = NULL; int exact = 0; int ambig = 0; int indfound; int option_index; for (nameend = nextchar; *nameend && *nameend != '='; nameend++) /* Do nothing. */ ; /* Test all long options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp (p->name, nextchar, nameend - nextchar)) { if (nameend - nextchar == strlen (p->name)) { /* Exact match found. */ pfound = p; indfound = option_index; exact = 1; break; } else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else /* Second or later nonexact match found. */ ambig = 1; } if (ambig && !exact) { if (opterr) fprintf (stderr, "%s: option `%s' is ambiguous\n", argv[0], argv[optind]); nextchar += strlen (nextchar); optind++; return '?'; } if (pfound != NULL) { option_index = indfound; optind++; if (*nameend) { /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */ if (pfound->has_arg) optarg = nameend + 1; else { if (opterr) { if (argv[optind - 1][1] == '-') /* --option */ fprintf (stderr, "%s: option `--%s' doesn't allow an argument\n", argv[0], pfound->name); else /* +option or -option */ fprintf (stderr, "%s: option `%c%s' doesn't allow an argument\n", argv[0], argv[optind - 1][0], pfound->name); } nextchar += strlen (nextchar); return '?'; } } else if (pfound->has_arg == 1) { if (optind < argc) optarg = argv[optind++]; else { if (opterr) fprintf (stderr, "%s: option `%s' requires an argument\n", argv[0], argv[optind - 1]); nextchar += strlen (nextchar); return optstring[0] == ':' ? ':' : '?'; } } nextchar += strlen (nextchar); if (longind != NULL) *longind = option_index; if (pfound->flag) { *(pfound->flag) = pfound->val; return 0; } return pfound->val; } /* Can't find it as a long option. If this is not getopt_long_only, or the option starts with '--' or is not a valid short option, then it's an error. Otherwise interpret it as a short option. */ if (!long_only || argv[optind][1] == '-' || my_index (optstring, *nextchar) == NULL) { if (opterr) { if (argv[optind][1] == '-') /* --option */ fprintf (stderr, "%s: unrecognized option `--%s'\n", argv[0], nextchar); else /* +option or -option */ fprintf (stderr, "%s: unrecognized option `%c%s'\n", argv[0], argv[optind][0], nextchar); } nextchar = (char *) ""; optind++; return '?'; } } /* Look at and handle the next short option-character. */ { char c = *nextchar++; char *temp = my_index (optstring, c); /* Increment `optind' when we start to process its last character. */ if (*nextchar == '\0') ++optind; if (temp == NULL || c == ':') { if (opterr) { /* 1003.2 specifies the format of this message. */ fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c); } optopt = c; return '?'; } if (temp[1] == ':') { if (temp[2] == ':') { /* This is an option that accepts an argument optionally. */ if (*nextchar != '\0') { optarg = nextchar; optind++; } else optarg = NULL; nextchar = NULL; } else { /* This is an option that requires an argument. */ if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ optind++; } else if (optind == argc) { if (opterr) { /* 1003.2 specifies the format of this message. */ fprintf (stderr, "%s: option requires an argument -- %c\n", argv[0], c); } optopt = c; if (optstring[0] == ':') c = ':'; else c = '?'; } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ optarg = argv[optind++]; nextchar = NULL; } } return c; } } int getopt (argc, argv, optstring) int argc; char *const *argv; const char *optstring; { return _getopt_internal (argc, argv, optstring, (const struct option *) 0, (int *) 0, 0); } #endif /* _LIBC or not __GNU_LIBRARY__. */ #ifdef TEST /* Compile with -DTEST to make an executable for use in testing the above definition of `getopt'. */ int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; c = getopt (argc, argv, "abc:d:0123456789"); if (c == EOF) break; switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ rplay-3.3.2/lib/getopt.h100644 153 62 10474 6552756453 13605 0ustar boynsstaff/* Declarations for getopt. Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _GETOPT_H #define _GETOPT_H 1 #ifdef __cplusplus extern "C" { #endif /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ extern char *optarg; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns EOF, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ extern int optind; /* Callers store zero here to inhibit the error message `getopt' prints for unrecognized options. */ extern int opterr; /* Set to an option character which was unrecognized. */ extern int optopt; /* Describe the long-named options requested by the application. The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector of `struct option' terminated by an element containing a name which is zero. The field `has_arg' is: no_argument (or 0) if the option does not take an argument, required_argument (or 1) if the option requires an argument, optional_argument (or 2) if the option takes an optional argument. If the field `flag' is not NULL, it points to a variable that is set to the value given in the field `val' when the option is found, but left unchanged if the option is not found. To have a long-named option do something other than set an `int' to a compiled-in constant, such as set a value from `optarg', set the option's `flag' field to zero and its `val' field to a nonzero value (the equivalent single-letter option character, if there is one). For long options that have a zero `flag' field, `getopt' returns the contents of the `val' field. */ struct option { #if __STDC__ const char *name; #else char *name; #endif /* has_arg can't be an enum because some compilers complain about type mismatches in all the code that assumes it is an int. */ int has_arg; int *flag; int val; }; /* Names for the values of the `has_arg' field of `struct option'. */ #define no_argument 0 #define required_argument 1 #define optional_argument 2 #if __STDC__ #if defined(__GNU_LIBRARY__) /* Many other libraries have conflicting prototypes for getopt, with differences in the consts, in stdlib.h. To avoid compilation errors, only prototype getopt for the GNU C library. */ extern int getopt (int argc, char *const *argv, const char *shortopts); #else /* not __GNU_LIBRARY__ */ extern int getopt (); #endif /* not __GNU_LIBRARY__ */ extern int getopt_long (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); extern int getopt_long_only (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); /* Internal only. Users should not call this directly. */ extern int _getopt_internal (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind, int long_only); #else /* not __STDC__ */ extern int getopt (); extern int getopt_long (); extern int getopt_long_only (); extern int _getopt_internal (); #endif /* not __STDC__ */ #ifdef __cplusplus } #endif #endif /* _GETOPT_H */ rplay-3.3.2/lib/getopt1.c100644 153 62 10640 6552756453 13654 0ustar boynsstaff/* getopt_long and getopt_long_only entry points for GNU getopt. Copyright (C) 1987, 88, 89, 90, 91, 92, 1993 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef HAVE_CONFIG_H #if defined (emacs) || defined (CONFIG_BROKETS) /* We use instead of "config.h" so that a compilation using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h (which it would do because it found this file in $srcdir). */ #include #else #include "config.h" #endif #endif #include "getopt.h" #ifndef __STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ #ifndef const #define const #endif #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #if defined (_LIBC) || !defined (__GNU_LIBRARY__) /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ #include #else char *getenv (); #endif #ifndef NULL #define NULL 0 #endif int getopt_long (argc, argv, options, long_options, opt_index) int argc; char *const *argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal (argc, argv, options, long_options, opt_index, 0); } /* Like getopt_long, but '-' as well as '--' can indicate a long option. If an option that starts with '-' (not '--') doesn't match a long option, but does match a short option, it is parsed as a short option instead. */ int getopt_long_only (argc, argv, options, long_options, opt_index) int argc; char *const *argv; const char *options; const struct option *long_options; int *opt_index; { return _getopt_internal (argc, argv, options, long_options, opt_index, 1); } #endif /* _LIBC or not __GNU_LIBRARY__. */ #ifdef TEST #include int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; int option_index = 0; static struct option long_options[] = { {"add", 1, 0, 0}, {"append", 0, 0, 0}, {"delete", 1, 0, 0}, {"verbose", 0, 0, 0}, {"create", 0, 0, 0}, {"file", 1, 0, 0}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "abc:d:0123456789", long_options, &option_index); if (c == EOF) break; switch (c) { case 0: printf ("option %s", long_options[option_index].name); if (optarg) printf (" with arg %s", optarg); printf ("\n"); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case 'd': printf ("option d with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ rplay-3.3.2/lib/hash.c100644 153 62 67337 6564502011 13211 0ustar boynsstaff/* hash.c - hash table lookup strings - Copyright (C) 1987, 1990, 1991, 1992 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. GAS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GAS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GAS; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * BUGS, GRIPES, APOLOGIA etc. * * A typical user doesn't need ALL this: I intend to make a library out * of it one day - Dean Elsner. * Also, I want to change the definition of a symbol to (address,length) * so I can put arbitrary binary in the names stored. [see hsh.c for that] * * This slime is common coupled inside the module. Com-coupling (and other * vandalism) was done to speed running time. The interfaces at the * module's edges are adequately clean. * * There is no way to (a) run a test script through this heap and (b) * compare results with previous scripts, to see if we have broken any * code. Use GNU (f)utilities to do this. A few commands assist test. * The testing is awkward: it tries to be both batch & interactive. * For now, interactive rules! */ /* * The idea is to implement a symbol table. A test jig is here. * Symbols are arbitrary strings; they can't contain '\0'. * [See hsh.c for a more general symbol flavour.] * Each symbol is associated with a char*, which can point to anything * you want, allowing an arbitrary property list for each symbol. * * The basic operations are: * * new creates symbol table, returns handle * find (symbol) returns char* * insert (symbol,char*) error if symbol already in table * delete (symbol) returns char* if symbol was in table * apply so you can delete all symbols before die() * die destroy symbol table (free up memory) * * Supplementary functions include * * say how big? what % full? * replace (symbol,newval) report previous value * jam (symbol,value) assert symbol:=value * * You, the caller, have control over errors: this just reports them. * * This package requires malloc(), free(). * Malloc(size) returns NULL or address of char[size]. * Free(address) frees same. */ /* * The code and its structures are re-enterent. * * Before you do anything else, you must call hash_new() which will * return the address of a hash-table-control-block. You then use * this address as a handle of the symbol table by passing it to all * the other hash_...() functions. The only approved way to recover * the memory used by the symbol table is to call hash_die() with the * handle of the symbol table. * * Before you call hash_die() you normally delete anything pointed to * by individual symbols. After hash_die() you can't use that symbol * table again. * * The char* you associate with a symbol may not be NULL (0) because * NULL is returned whenever a symbol is not in the table. Any other * value is OK, except DELETED, #defined below. * * When you supply a symbol string for insertion, YOU MUST PRESERVE THE * STRING until that symbol is deleted from the table. The reason is that * only the address you supply, NOT the symbol string itself, is stored * in the symbol table. * * You may delete and add symbols arbitrarily. * Any or all symbols may have the same 'value' (char *). In fact, these * routines don't do anything with your symbol values. * * You have no right to know where the symbol:char* mapping is stored, * because it moves around in memory; also because we may change how it * works and we don't want to break your code do we? However the handle * (address of struct hash_control) is never changed in * the life of the symbol table. * * What you CAN find out about a symbol table is: * how many slots are in the hash table? * how many slots are filled with symbols? * (total hashes,collisions) for (reads,writes) (*) * All of the above values vary in time. * (*) some of these numbers will not be meaningful if we change the * internals. */ /* * I N T E R N A L * * Hash table is an array of hash_entries; each entry is a pointer to a * a string and a user-supplied value 1 char* wide. * * The array always has 2 ** n elements, n>0, n integer. * There is also a 'wall' entry after the array, which is always empty * and acts as a sentinel to stop running off the end of the array. * When the array gets too full, we create a new array twice as large * and re-hash the symbols into the new array, then forget the old array. * (Of course, we copy the values into the new array before we junk the * old array!) * */ #include #include #ifndef FALSE #define FALSE (0) #define TRUE (!FALSE) #endif /* no FALSE yet */ #include #define min(a, b) ((a) < (b) ? (a) : (b)) #if 0 #include "as.h" #else #include "hash.h" #endif #define error as_fatal #define DELETED ((PTR)1) /* guarenteed invalid address */ #define START_POWER (11) /* power of two: size of new hash table */ /* TRUE if a symbol is in entry @ ptr. */ #define islive(ptr) (ptr->hash_string && ptr->hash_string!=DELETED) /* Number of slots in hash table. The wall does not count here. We expect this is always a power of 2. */ #define STAT_SIZE (0) #define STAT_ACCESS (1) /* number of hash_ask()s */ #define STAT__READ (0) /* reading */ #define STAT__WRITE (1) /* writing */ /* Number of collisions (total). This may exceed STAT_ACCESS if we have lots of collisions/access. */ #define STAT_COLLIDE (3) #define STAT_USED (5) /* slots used right now */ #define STATLENGTH (6) /* size of statistics block */ #if STATLENGTH != HASH_STATLENGTH Panic! Please make #include "stat.h" agree with previous definitions! #endif /* #define SUSPECT to do runtime checks */ /* #define TEST to be a test jig for hash...() */ #ifdef TEST /* TEST: use smaller hash table */ #undef START_POWER #define START_POWER (3) #undef START_SIZE #define START_SIZE (8) #undef START_FULL #define START_FULL (4) #endif /*------------------ plan ---------------------------------- i = internal struct hash_control * c; struct hash_entry * e; i int b[z]; buffer for statistics z size of b char * s; symbol string (address) [ key ] char * v; value string (address) [datum] boolean f; TRUE if we found s in hash table i char * t; error string; 0 means OK int a; access type [0...n) i c=hash_new () create new hash_control hash_die (c) destroy hash_control (and hash table) table should be empty. doesn't check if table is empty. c has no meaning after this. hash_say (c,b,z) report statistics of hash_control. also report number of available statistics. v=hash_delete (c,s) delete symbol, return old value if any. ask() NULL means no old value. f v=hash_replace (c,s,v) replace old value of s with v. ask() NULL means no old value: no table change. f t=hash_insert (c,s,v) insert (s,v) in c. ask() return error string. f it is an error to insert if s is already in table. if any error, c is unchanged. t=hash_jam (c,s,v) assert that new value of s will be v. i ask() it may decide to GROW the table. i f i grow() i t=hash_grow (c) grow the hash table. i jam() will invoke JAM. i ?=hash_apply (c,y) apply y() to every symbol in c. y evtries visited in 'unspecified' order. v=hash_find (c,s) return value of s, or NULL if s not in c. ask() f f,e=hash_ask() (c,s,a) return slot where s SHOULD live. i code() maintain collision stats in c. i .=hash_code (c,s) compute hash-code for s, i from parameters of c. i */ /* Returned by hash_ask() to stop extra testing. hash_ask() wants to return both a slot and a status. This is the status. TRUE: found symbol FALSE: absent: empty or deleted slot Also returned by hash_jam(). TRUE: we replaced a value FALSE: we inserted a value. */ static char hash_found; static struct hash_entry *hash_ask PARAMS ((struct hash_control *, const char *, int)); static int hash_code PARAMS ((struct hash_control *, const char *)); static const char *hash_grow PARAMS ((struct hash_control *)); /* Create a new hash table. Return NULL if failed; otherwise return handle (address of struct hash). */ struct hash_control * hash_new () { struct hash_control *retval; struct hash_entry *room; /* points to hash table */ struct hash_entry *wall; struct hash_entry *entry; int *ip; /* scan stats block of struct hash_control */ int *nd; /* limit of stats block */ room = (struct hash_entry *) xmalloc (sizeof (struct hash_entry) /* +1 for the wall entry */ * ((1 << START_POWER) + 1)); retval = (struct hash_control *) xmalloc (sizeof (struct hash_control)); nd = retval->hash_stat + STATLENGTH; for (ip = retval->hash_stat; ip < nd; ip++) *ip = 0; retval->hash_stat[STAT_SIZE] = 1 << START_POWER; retval->hash_mask = (1 << START_POWER) - 1; retval->hash_sizelog = START_POWER; /* works for 1's compl ok */ retval->hash_where = room; retval->hash_wall = wall = room + (1 << START_POWER); retval->hash_full = (1 << START_POWER) / 2; for (entry = room; entry <= wall; entry++) entry->hash_string = NULL; return retval; } /* * h a s h _ d i e ( ) * * Table should be empty, but this is not checked. * To empty the table, try hash_apply()ing a symbol deleter. * Return to free memory both the hash table and it's control * block. * 'handle' has no meaning after this function. * No errors are recoverable. */ void hash_die (handle) struct hash_control *handle; { free ((char *) handle->hash_where); free ((char *) handle); } /* * h a s h _ s a y ( ) * * Return the size of the statistics table, and as many statistics as * we can until either (a) we have run out of statistics or (b) caller * has run out of buffer. * NOTE: hash_say treats all statistics alike. * These numbers may change with time, due to insertions, deletions * and expansions of the table. * The first "statistic" returned is the length of hash_stat[]. * Then contents of hash_stat[] are read out (in ascending order) * until your buffer or hash_stat[] is exausted. */ void hash_say (handle, buffer, bufsiz) struct hash_control *handle; int buffer[ /*bufsiz*/ ]; int bufsiz; { int *nd; /* limit of statistics block */ int *ip; /* scan statistics */ ip = handle->hash_stat; nd = ip + min (bufsiz - 1, STATLENGTH); if (bufsiz > 0) /* trust nothing! bufsiz<=0 is dangerous */ { *buffer++ = STATLENGTH; for (; ip < nd; ip++, buffer++) { *buffer = *ip; } } } /* * h a s h _ d e l e t e ( ) * * Try to delete a symbol from the table. * If it was there, return its value (and adjust STAT_USED). * Otherwise, return NULL. * Anyway, the symbol is not present after this function. * */ PTR /* NULL if string not in table, else */ /* returns value of deleted symbol */ hash_delete (handle, string) struct hash_control *handle; const char *string; { PTR retval; struct hash_entry *entry; entry = hash_ask (handle, string, STAT__WRITE); if (hash_found) { retval = entry->hash_value; entry->hash_string = DELETED; handle->hash_stat[STAT_USED] -= 1; #ifdef SUSPECT if (handle->hash_stat[STAT_USED] < 0) { error ("hash_delete"); } #endif /* def SUSPECT */ } else { retval = NULL; } return (retval); } /* * h a s h _ r e p l a c e ( ) * * Try to replace the old value of a symbol with a new value. * Normally return the old value. * Return NULL and don't change the table if the symbol is not already * in the table. */ PTR hash_replace (handle, string, value) struct hash_control *handle; const char *string; PTR value; { struct hash_entry *entry; char *retval; entry = hash_ask (handle, string, STAT__WRITE); if (hash_found) { retval = entry->hash_value; entry->hash_value = value; } else { retval = NULL; } ; return retval; } /* * h a s h _ i n s e r t ( ) * * Insert a (symbol-string, value) into the hash table. * Return an error string, 0 means OK. * It is an 'error' to insert an existing symbol. */ const char * /* return error string */ hash_insert (handle, string, value) struct hash_control *handle; const char *string; PTR value; { struct hash_entry *entry; const char *retval; retval = 0; if (handle->hash_stat[STAT_USED] > handle->hash_full) { retval = hash_grow (handle); } if (!retval) { entry = hash_ask (handle, string, STAT__WRITE); if (hash_found) { retval = "exists"; } else { entry->hash_value = value; entry->hash_string = string; handle->hash_stat[STAT_USED] += 1; } } return retval; } /* * h a s h _ j a m ( ) * * Regardless of what was in the symbol table before, after hash_jam() * the named symbol has the given value. The symbol is either inserted or * (its value is) relpaced. * An error message string is returned, 0 means OK. * * WARNING: this may decide to grow the hashed symbol table. * To do this, we call hash_grow(), WHICH WILL recursively CALL US. * * We report status internally: hash_found is TRUE if we replaced, but * false if we inserted. */ const char * hash_jam (handle, string, value) struct hash_control *handle; const char *string; PTR value; { const char *retval; struct hash_entry *entry; retval = 0; if (handle->hash_stat[STAT_USED] > handle->hash_full) { retval = hash_grow (handle); } if (!retval) { entry = hash_ask (handle, string, STAT__WRITE); if (!hash_found) { entry->hash_string = string; handle->hash_stat[STAT_USED] += 1; } entry->hash_value = value; } return retval; } /* * h a s h _ g r o w ( ) * * Grow a new (bigger) hash table from the old one. * We choose to double the hash table's size. * Return a human-scrutible error string: 0 if OK. * Warning! This uses hash_jam(), which had better not recurse * back here! Hash_jam() conditionally calls us, but we ALWAYS * call hash_jam()! * Internal. */ static const char * hash_grow (handle) /* make a hash table grow */ struct hash_control *handle; { struct hash_entry *newwall; struct hash_entry *newwhere; struct hash_entry *newtrack; struct hash_entry *oldtrack; struct hash_entry *oldwhere; struct hash_entry *oldwall; int temp; int newsize; const char *string; const char *retval; #ifdef SUSPECT int oldused; #endif /* * capture info about old hash table */ oldwhere = handle->hash_where; oldwall = handle->hash_wall; #ifdef SUSPECT oldused = handle->hash_stat[STAT_USED]; #endif /* * attempt to get enough room for a hash table twice as big */ temp = handle->hash_stat[STAT_SIZE]; if ((newwhere = ((struct hash_entry *) xmalloc ((unsigned long) ((temp + temp + 1) * sizeof (struct hash_entry))))) != NULL) /* +1 for wall slot */ { retval = 0; /* assume success until proven otherwise */ /* * have enough room: now we do all the work. * double the size of everything in handle, * note: hash_mask frob works for 1's & for 2's complement machines */ handle->hash_mask = handle->hash_mask + handle->hash_mask + 1; handle->hash_stat[STAT_SIZE] <<= 1; newsize = handle->hash_stat[STAT_SIZE]; handle->hash_where = newwhere; handle->hash_full <<= 1; handle->hash_sizelog += 1; handle->hash_stat[STAT_USED] = 0; handle->hash_wall = newwall = newwhere + newsize; /* * set all those pesky new slots to vacant. */ for (newtrack = newwhere; newtrack <= newwall; newtrack++) { newtrack->hash_string = NULL; } /* * we will do a scan of the old table, the hard way, using the * new control block to re-insert the data into new hash table. */ handle->hash_stat[STAT_USED] = 0; /* inserts will bump it up to correct */ for (oldtrack = oldwhere; oldtrack < oldwall; oldtrack++) if (((string = oldtrack->hash_string) != NULL) && string != DELETED) if ((retval = hash_jam (handle, string, oldtrack->hash_value))) break; #ifdef SUSPECT if (!retval && handle->hash_stat[STAT_USED] != oldused) { retval = "hash_used"; } #endif if (!retval) { /* * we have a completely faked up control block. * return the old hash table. */ free ((char *) oldwhere); /* * Here with success. retval is already 0. */ } } else { retval = "no room"; } return retval; } /* * h a s h _ a p p l y ( ) * * Use this to scan each entry in symbol table. * For each symbol, this calls (applys) a nominated function supplying the * symbol's value (and the symbol's name). * The idea is you use this to destroy whatever is associted with * any values in the table BEFORE you destroy the table with hash_die. * Of course, you can use it for other jobs; whenever you need to * visit all extant symbols in the table. * * We choose to have a call-you-back idea for two reasons: * asthetic: it is a neater idea to use apply than an explicit loop * sensible: if we ever had to grow the symbol table (due to insertions) * then we would lose our place in the table when we re-hashed * symbols into the new table in a different order. * * The order symbols are visited depends entirely on the hashing function. * Whenever you insert a (symbol, value) you risk expanding the table. If * you do expand the table, then the hashing function WILL change, so you * MIGHT get a different order of symbols visited. In other words, if you * want the same order of visiting symbols as the last time you used * hash_apply() then you better not have done any hash_insert()s or * hash_jam()s since the last time you used hash_apply(). * * In future we may use the value returned by your nominated function. * One idea is to abort the scan if, after applying the function to a * certain node, the function returns a certain code. * To be safe, please make your functions of type char *. If you always * return NULL, then the scan will complete, visiting every symbol in * the table exactly once. ALL OTHER RETURNED VALUES have no meaning yet! * Caveat Actor! * * The function you supply should be of the form: * char * myfunct(string,value) * char * string; |* the symbol's name *| * char * value; |* the symbol's value *| * { * |* ... *| * return(NULL); * } * * The returned value of hash_apply() is (char*)NULL. In future it may return * other values. NULL means "completed scan OK". Other values have no meaning * yet. (The function has no graceful failures.) */ char * hash_apply (handle, function) struct hash_control *handle; char *(*function) (); { struct hash_entry *entry; struct hash_entry *wall; wall = handle->hash_wall; for (entry = handle->hash_where; entry < wall; entry++) { if (islive (entry)) /* silly code: tests entry->string twice! */ { (*function) (entry->hash_string, entry->hash_value); } } return (NULL); } /* * h a s h _ f i n d ( ) * * Given symbol string, find value (if any). * Return found value or NULL. */ PTR hash_find (handle, string) struct hash_control *handle; const char *string; { struct hash_entry *entry; entry = hash_ask (handle, string, STAT__READ); if (hash_found) return entry->hash_value; else return NULL; } /* * h a s h _ a s k ( ) * * Searches for given symbol string. * Return the slot where it OUGHT to live. It may be there. * Return hash_found: TRUE only if symbol is in that slot. * Access argument is to help keep statistics in control block. * Internal. */ static struct hash_entry * /* string slot, may be empty or deleted */ hash_ask (handle, string, access) struct hash_control *handle; const char *string; int access; /* access type */ { const char *string1; /* JF avoid strcmp calls */ const char *s; int c; struct hash_entry *slot; int collision; /* count collisions */ /* start looking here */ slot = handle->hash_where + hash_code (handle, string); handle->hash_stat[STAT_ACCESS + access] += 1; collision = 0; hash_found = FALSE; while (((s = slot->hash_string) != NULL) && s != DELETED) { for (string1 = string;;) { if ((c = *s++) == 0) { if (!*string1) hash_found = TRUE; break; } if (*string1++ != c) break; } if (hash_found) break; collision++; slot++; } /* * slot: return: * in use: we found string slot * at empty: * at wall: we fell off: wrap round ???? * in table: dig here slot * at DELETED: dig here slot */ if (slot == handle->hash_wall) { slot = handle->hash_where;/* now look again */ while (((s = slot->hash_string) != NULL) && s != DELETED) { for (string1 = string; *s; string1++, s++) { if (*string1 != *s) break; } if (*s == *string1) { hash_found = TRUE; break; } collision++; slot++; } /* * slot: return: * in use: we found it slot * empty: wall: ERROR IMPOSSIBLE !!!! * in table: dig here slot * DELETED:dig here slot */ } handle->hash_stat[STAT_COLLIDE + access] += collision; return (slot); /* also return hash_found */ } /* * h a s h _ c o d e * * Does hashing of symbol string to hash number. * Internal. */ static int hash_code (handle, string) struct hash_control *handle; const char *string; { long h; /* hash code built here */ long c; /* each character lands here */ int n; /* Amount to shift h by */ n = (handle->hash_sizelog - 3); h = 0; while ((c = *string++) != 0) { h += c; h = (h << 3) + (h >> n) + c; } return (h & handle->hash_mask); } /* * Here is a test program to exercise above. */ #ifdef TEST #define TABLES (6) /* number of hash tables to maintain */ /* (at once) in any testing */ #define STATBUFSIZE (12) /* we can have 12 statistics */ int statbuf[STATBUFSIZE]; /* display statistics here */ char answer[100]; /* human farts here */ char *hashtable[TABLES]; /* we test many hash tables at once */ char *h; /* points to curent hash_control */ char **pp; char *p; char *name; char *value; int size; int used; char command; int number; /* number 0:TABLES-1 of current hashed */ /* symbol table */ main () { char (*applicatee ()); char *destroy (); char *what (); int *ip; number = 0; h = 0; printf ("type h for help\n"); for (;;) { printf ("hash_test command: "); gets (answer); command = answer[0]; if (isupper (command)) command = tolower (command); /* ecch! */ switch (command) { case '#': printf ("old hash table #=%d.\n", number); whattable (); break; case '?': for (pp = hashtable; pp < hashtable + TABLES; pp++) { printf ("address of hash table #%d control block is %xx\n" ,pp - hashtable, *pp); } break; case 'a': hash_apply (h, applicatee); break; case 'd': hash_apply (h, destroy); hash_die (h); break; case 'f': p = hash_find (h, name = what ("symbol")); printf ("value of \"%s\" is \"%s\"\n", name, p ? p : "NOT-PRESENT"); break; case 'h': printf ("# show old, select new default hash table number\n"); printf ("? display all hashtable control block addresses\n"); printf ("a apply a simple display-er to each symbol in table\n"); printf ("d die: destroy hashtable\n"); printf ("f find value of nominated symbol\n"); printf ("h this help\n"); printf ("i insert value into symbol\n"); printf ("j jam value into symbol\n"); printf ("n new hashtable\n"); printf ("r replace a value with another\n"); printf ("s say what %% of table is used\n"); printf ("q exit this program\n"); printf ("x delete a symbol from table, report its value\n"); break; case 'i': p = hash_insert (h, name = what ("symbol"), value = what ("value")); if (p) { printf ("symbol=\"%s\" value=\"%s\" error=%s\n", name, value, p); } break; case 'j': p = hash_jam (h, name = what ("symbol"), value = what ("value")); if (p) { printf ("symbol=\"%s\" value=\"%s\" error=%s\n", name, value, p); } break; case 'n': h = hashtable[number] = (char *) hash_new (); break; case 'q': exit (); case 'r': p = hash_replace (h, name = what ("symbol"), value = what ("value")); printf ("old value was \"%s\"\n", p ? p : "{}"); break; case 's': hash_say (h, statbuf, STATBUFSIZE); for (ip = statbuf; ip < statbuf + STATBUFSIZE; ip++) { printf ("%d ", *ip); } printf ("\n"); break; case 'x': p = hash_delete (h, name = what ("symbol")); printf ("old value was \"%s\"\n", p ? p : "{}"); break; default: printf ("I can't understand command \"%c\"\n", command); break; } } } char * what (description) char *description; { char *retval; char *malloc (); printf (" %s : ", description); gets (answer); /* will one day clean up answer here */ retval = malloc (strlen (answer) + 1); if (!retval) { error ("room"); } (void) strcpy (retval, answer); return (retval); } char * destroy (string, value) char *string; char *value; { free (string); free (value); return (NULL); } char * applicatee (string, value) char *string; char *value; { printf ("%.20s-%.20s\n", string, value); return (NULL); } whattable () /* determine number: what hash table to use */ /* also determine h: points to hash_control */ { for (;;) { printf (" what hash table (%d:%d) ? ", 0, TABLES - 1); gets (answer); sscanf (answer, "%d", &number); if (number >= 0 && number < TABLES) { h = hashtable[number]; if (!h) { printf ("warning: current hash-table-#%d. has no hash-control\n", number); } return; } else { printf ("invalid hash table number: %d\n", number); } } } #endif /* #ifdef TEST */ /* $Id: hash.c,v 1.2 1998/08/13 06:13:29 boyns Exp $ */ rplay-3.3.2/lib/hash.h100644 153 62 4771 6564502012 13170 0ustar boynsstaff/* hash.h - for hash.c Copyright (C) 1987, 1992 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. GAS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GAS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GAS; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef hashH #define hashH #include "ansidecl.h" struct hash_entry { const char *hash_string; /* points to where the symbol string is */ /* NULL means slot is not used */ /* DELETED means slot was deleted */ PTR hash_value; /* user's datum, associated with symbol */ }; #define HASH_STATLENGTH (6) struct hash_control { struct hash_entry *hash_where;/* address of hash table */ int hash_sizelog; /* Log of ( hash_mask + 1 ) */ int hash_mask; /* masks a hash into index into table */ int hash_full; /* when hash_stat[STAT_USED] exceeds this, */ /* grow table */ struct hash_entry *hash_wall; /* point just after last (usable) entry */ /* here we have some statistics */ int hash_stat[HASH_STATLENGTH]; /* lies & statistics */ /* we need STAT_USED & STAT_SIZE */ }; /* returns control block */ struct hash_control *hash_new PARAMS ((void)); void hash_die PARAMS ((struct hash_control *)); void hash_say PARAMS ((struct hash_control *, int *buffer, int bufsiz)); /* returns previous value */ PTR hash_delete PARAMS ((struct hash_control *, const char *str)); /* returns previous value */ PTR hash_replace PARAMS ((struct hash_control *, const char *str, PTR val)); /* returns error string or null */ const char *hash_insert PARAMS ((struct hash_control *, const char *str, PTR val)); /* return of 0 means OK */ char *hash_apply PARAMS ((struct hash_control *, char *(*fn) (const char *str, PTR val))); /* returns value */ PTR hash_find PARAMS ((struct hash_control *, const char *str)); /* returns error text or null (internal) */ const char *hash_jam PARAMS ((struct hash_control *, const char *str, PTR val)); #endif /* #ifdef hashH */ /* $Id: hash.h,v 1.2 1998/08/13 06:13:30 boyns Exp $ */ rplay-3.3.2/lib/strdup.c100644 153 62 2347 6671423001 13555 0ustar boynsstaff/* $Id: strdup.c,v 1.4 1999/03/10 07:57:53 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "strdup.h" #include #ifndef HAVE_STRDUP #ifdef __STDC__ char * strdup(char *str) #else char * strdup(str) char *str; #endif { char *p; p = (char *) malloc(strlen(str) + 1); if (p == NULL) { return NULL; } else { strcpy(p, str); return p; } } #endif /* HAVE_STRDUP */ rplay-3.3.2/lib/strdup.h100644 153 62 1765 6671423001 13565 0ustar boynsstaff/* $Id: strdup.h,v 1.3 1999/03/10 07:57:53 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifndef HAVE_STRDUP #ifdef __STDC__ char *strdup (char *str); #else char *strdup (/* char *str */); #endif #endif /* HAVE_STRDUP */ rplay-3.3.2/lib/tilde.c100644 153 62 22615 6671423001 13355 0ustar boynsstaff/* $Id: tilde.c,v 1.3 1999/03/10 07:57:53 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #if defined (HAVE_CONFIG_H) # include "config.h" #endif #if defined (HAVE_STRING_H) # include #else /* !HAVE_STRING_H */ # include #endif /* !HAVE_STRING_H */ #if defined (HAVE_STDLIB_H) # include #else # include "ansi_stdlib.h" #endif /* HAVE_STDLIB_H */ #include "tilde.h" #include #include #if defined (USG) && !defined (HAVE_GETPW_DECLS) extern struct passwd *getpwuid (), *getpwnam (); #endif /* USG && !defined (HAVE_GETPW_DECLS) */ #if !defined (savestring) extern char *xmalloc (); # ifndef strcpy extern char *strcpy (); # endif #define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x)) #endif /* !savestring */ #if !defined (NULL) # if defined (__STDC__) # define NULL ((void *) 0) # else # define NULL 0x0 # endif /* !__STDC__ */ #endif /* !NULL */ #if defined (TEST) || defined (STATIC_MALLOC) static char *xmalloc (), *xrealloc (); #else extern char *xmalloc (), *xrealloc (); #endif /* TEST || STATIC_MALLOC */ /* The default value of tilde_additional_prefixes. This is set to whitespace preceding a tilde so that simple programs which do not perform any word separation get desired behaviour. */ static char *default_prefixes[] = { " ~", "\t~", (char *)NULL }; /* The default value of tilde_additional_suffixes. This is set to whitespace or newline so that simple programs which do not perform any word separation get desired behaviour. */ static char *default_suffixes[] = { " ", "\n", (char *)NULL }; /* If non-null, this contains the address of a function to call if the standard meaning for expanding a tilde fails. The function is called with the text (sans tilde, as in "foo"), and returns a malloc()'ed string which is the expansion, or a NULL pointer if there is no expansion. */ CPFunction *tilde_expansion_failure_hook = (CPFunction *)NULL; /* When non-null, this is a NULL terminated array of strings which are duplicates for a tilde prefix. Bash uses this to expand `=~' and `:~'. */ char **tilde_additional_prefixes = default_prefixes; /* When non-null, this is a NULL terminated array of strings which match the end of a username, instead of just "/". Bash sets this to `:' and `=~'. */ char **tilde_additional_suffixes = default_suffixes; /* Find the start of a tilde expansion in STRING, and return the index of the tilde which starts the expansion. Place the length of the text which identified this tilde starter in LEN, excluding the tilde itself. */ static int tilde_find_prefix (string, len) char *string; int *len; { register int i, j, string_len; register char **prefixes = tilde_additional_prefixes; string_len = strlen (string); *len = 0; if (!*string || *string == '~') return (0); if (prefixes) { for (i = 0; i < string_len; i++) { for (j = 0; prefixes[j]; j++) { if (strncmp (string + i, prefixes[j], strlen (prefixes[j])) == 0) { *len = strlen (prefixes[j]) - 1; return (i + *len); } } } } return (string_len); } /* Find the end of a tilde expansion in STRING, and return the index of the character which ends the tilde definition. */ static int tilde_find_suffix (string) char *string; { register int i, j, string_len; register char **suffixes = tilde_additional_suffixes; string_len = strlen (string); for (i = 0; i < string_len; i++) { if (string[i] == '/' || !string[i]) break; for (j = 0; suffixes && suffixes[j]; j++) { if (strncmp (string + i, suffixes[j], strlen (suffixes[j])) == 0) return (i); } } return (i); } /* Return a new string which is the result of tilde expanding STRING. */ char * tilde_expand (string) char *string; { char *result, *tilde_expand_word (); int result_size, result_index; result_size = result_index = 0; result = (char *)NULL; /* Scan through STRING expanding tildes as we come to them. */ while (1) { register int start, end; char *tilde_word, *expansion; int len; /* Make START point to the tilde which starts the expansion. */ start = tilde_find_prefix (string, &len); /* Copy the skipped text into the result. */ if ((result_index + start + 1) > result_size) result = (char *)xrealloc (result, 1 + (result_size += (start + 20))); strncpy (result + result_index, string, start); result_index += start; /* Advance STRING to the starting tilde. */ string += start; /* Make END be the index of one after the last character of the username. */ end = tilde_find_suffix (string); /* If both START and END are zero, we are all done. */ if (!start && !end) break; /* Expand the entire tilde word, and copy it into RESULT. */ tilde_word = (char *)xmalloc (1 + end); strncpy (tilde_word, string, end); tilde_word[end] = '\0'; string += end; expansion = tilde_expand_word (tilde_word); free (tilde_word); len = strlen (expansion); if ((result_index + len + 1) > result_size) result = (char *)xrealloc (result, 1 + (result_size += (len + 20))); strcpy (result + result_index, expansion); result_index += len; free (expansion); } result[result_index] = '\0'; return (result); } /* Do the work of tilde expansion on FILENAME. FILENAME starts with a tilde. If there is no expansion, call tilde_expansion_failure_hook. */ char * tilde_expand_word (filename) char *filename; { char *dirname; dirname = filename ? savestring (filename) : (char *)NULL; if (dirname && *dirname == '~') { char *temp_name; if (!dirname[1] || dirname[1] == '/') { /* Prepend $HOME to the rest of the string. */ char *temp_home = (char *)getenv ("HOME"); /* If there is no HOME variable, look up the directory in the password database. */ if (!temp_home) { struct passwd *entry; entry = getpwuid (getuid ()); if (entry) temp_home = entry->pw_dir; } temp_name = xmalloc (1 + strlen (&dirname[1]) + (temp_home ? strlen (temp_home) : 0)); temp_name[0] = '\0'; if (temp_home) strcpy (temp_name, temp_home); strcat (temp_name, dirname + 1); free (dirname); dirname = temp_name; } else { char *username; struct passwd *user_entry; int i; username = xmalloc (strlen (dirname)); for (i = 1; dirname[i] && dirname[i] != '/'; i++) username[i - 1] = dirname[i]; username[i - 1] = '\0'; if ((user_entry = getpwnam (username)) == 0) { /* If the calling program has a special syntax for expanding tildes, and we couldn't find a standard expansion, then let them try. */ if (tilde_expansion_failure_hook) { char *expansion; expansion = (*tilde_expansion_failure_hook) (username); if (expansion) { temp_name = xmalloc (1 + strlen (expansion) + strlen (&dirname[i])); strcpy (temp_name, expansion); strcat (temp_name, &dirname[i]); free (expansion); free (dirname); dirname = temp_name; } } /* We shouldn't report errors. */ } else { temp_name = xmalloc (1 + strlen (user_entry->pw_dir) + strlen (&dirname[i])); strcpy (temp_name, user_entry->pw_dir); strcat (temp_name, &dirname[i]); free (dirname); dirname = temp_name; } endpwent (); free (username); } } return (dirname); } #if defined (TEST) #undef NULL #include main (argc, argv) int argc; char **argv; { char *result, line[512]; int done = 0; while (!done) { printf ("~expand: "); fflush (stdout); if (!gets (line)) strcpy (line, "done"); if ((strcmp (line, "done") == 0) || (strcmp (line, "quit") == 0) || (strcmp (line, "exit") == 0)) { done = 1; break; } result = tilde_expand (line); printf (" --> %s\n", result); free (result); } exit (0); } static void memory_error_and_abort (); static char * xmalloc (bytes) int bytes; { char *temp = (char *)malloc (bytes); if (!temp) memory_error_and_abort (); return (temp); } static char * xrealloc (pointer, bytes) char *pointer; int bytes; { char *temp; if (!pointer) temp = (char *)malloc (bytes); else temp = (char *)realloc (pointer, bytes); if (!temp) memory_error_and_abort (); return (temp); } static void memory_error_and_abort () { fprintf (stderr, "readline: Out of virtual memory!\n"); abort (); } /* * Local variables: * compile-command: "gcc -g -DTEST -o tilde tilde.c" * end: */ #endif /* TEST */ rplay-3.3.2/lib/tilde.h100644 153 62 2627 6552756453 13365 0ustar boynsstaff/* tilde.h: Externally available variables and function in libtilde.a. */ #if !defined (__TILDE_H__) # define __TILDE_H__ /* Function pointers can be declared as (Function *)foo. */ #if !defined (__FUNCTION_DEF) # define __FUNCTION_DEF typedef int Function (); typedef void VFunction (); typedef char *CPFunction (); typedef char **CPPFunction (); #endif /* _FUNCTION_DEF */ /* If non-null, this contains the address of a function to call if the standard meaning for expanding a tilde fails. The function is called with the text (sans tilde, as in "foo"), and returns a malloc()'ed string which is the expansion, or a NULL pointer if there is no expansion. */ extern CPFunction *tilde_expansion_failure_hook; /* When non-null, this is a NULL terminated array of strings which are duplicates for a tilde prefix. Bash uses this to expand `=~' and `:~'. */ extern char **tilde_additional_prefixes; /* When non-null, this is a NULL terminated array of strings which match the end of a username, instead of just "/". Bash sets this to `:' and `=~'. */ extern char **tilde_additional_suffixes; /* Return a new string which is the result of tilde expanding STRING. */ extern char *tilde_expand (); /* Do the work of tilde expansion on FILENAME. FILENAME starts with a tilde. If there is no expansion, call tilde_expansion_failure_hook. */ extern char *tilde_expand_word (); #endif /* __TILDE_H__ */ rplay-3.3.2/lib/xmalloc.c100644 153 62 3160 6671423001 13665 0ustar boynsstaff/* $Id: xmalloc.c,v 1.4 1999/03/10 07:57:53 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #include "ansidecl.h" #include #include #ifdef __STDC__ #include #else #define size_t unsigned long #endif #ifdef __STDC__ PTR xmalloc(size_t size) #else PTR xmalloc(size) size_t size; #endif { PTR p; p = (PTR) malloc(size); if (p == 0) { fprintf(stderr, "xmalloc: Virtual memory exhausted.\n"); exit(1); } return p; } #ifdef __STDC__ PTR xrealloc(PTR oldmem, size_t size) #else PTR xrealloc(oldmem, size) PTR oldmem; size_t size; #endif { PTR newmem; if (size == 0) { size = 1; } newmem = (oldmem) ? (PTR) realloc(oldmem, size) : (PTR) malloc(size); if (!newmem) { fprintf(stderr, "xrealloc: Virtual memory exhausted.\n"); exit(1); } return newmem; } rplay-3.3.2/librplay/ 40755 153 62 0 6727650100 13041 5ustar boynsstaffrplay-3.3.2/librplay/Makefile.in100644 153 62 2607 6675577256 15236 0ustar boynsstaffinclude @RPLAY_TOP@/Makefile.config srcdir = @srcdir@ VPATH = @srcdir@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ MKINSTALLDIRS= @srcdir@/../mkinstalldirs CPPFLAGS= $(CC_OPTIONS) -I. -I../include -I@srcdir@/../include @DEFS@ LDFLAGS= $(LD_OPTIONS) -shared @LDFLAGS@ .c.o: $(CC) -c $(CPPFLAGS) $(CFLAGS) $< .SUFFIXES: .lo .c.lo: $(CC) -c -fPIC $(CPPFLAGS) $(CFLAGS) -o $@ $< TARGET= $(LIBRPLAY_NAME) SRCS= rplay.c rptp.c async.c OBJS= rplay.o rptp.o async.o SHAREDOBJS= rplay.lo rptp.lo async.lo all: $(TARGET) librplay.so # # Use the following for SunOS 4.1.x, Solaris 2.x, Linux, NetBSD # $(TARGET): $(OBJS) $(AR) rcv $@ $? $(RANLIB) $@ librplay.so: $(SHAREDOBJS) $(CC) -o $@ $(SHAREDOBJS) $(LDFLAGS) # # For HP-UX comment above and uncomment below. # #CFLAGS= +z # #$(TARGET): $(OBJS) # ld -b -s +FPD -o $@ $(OBJS) # -$(MKINSTALLDIRS) $(libdir) # -$(INSTALL) $@ $(libdir) # -chmod a+rx $(libdir) $(libdir)/$@ # install: all $(MKINSTALLDIRS) $(libdir) $(INSTALL_DATA) $(TARGET) $(libdir) $(INSTALL_DATA) librplay.so $(libdir) uninstall: $(RM) $(libdir)/$(TARGET) $(RM) $(libdir)/librplay.so clean: $(RM) $(OBJS) $(SHAREDOBJS) $(TARGET) librplay.so a.out core *~ *.bak *.orig TAGS distclean: clean $(RM) Makefile tags: $(TAGS) *.[ch] TAGS: tags etags: tags depend: $(MAKEDEPEND) -- $(CPPFLAGS) $(CFLAGS) -- $(SRCS) rplay-3.3.2/librplay/async.c100644 153 62 36066 6564502017 14454 0ustar boynsstaff/* $Id: async.c,v 1.2 1998/08/13 06:13:35 boyns Exp $ */ /* * Copyright (C) 1995 Andrew Scherpbier * * This file is part of rplay. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "version.h" #include "rplay.h" #include #include #include #include #include #include #include #include #include #ifdef __STDC__ # include #else # include #endif typedef void (*cb)(); typedef struct obuf_s { struct obuf_s *next; char *data; char *current; int length; cb callback; } obuf; typedef struct ibuf_s { struct ibuf_s *next; char *data; char *current; int length; } ibuf; typedef struct { obuf *olist; obuf *otail; ibuf *ilist; ibuf *itail; int writing; int notify_mask; cb rcallback; int rraw; cb wcallback; int wraw; } grp; static grp group[FD_SETSIZE]; static int looping; static int main_loop_return_value; #ifdef __STDC__ static void write_proc(int rptp_fd); static void do_register(int rptp_fd); static void do_unregister(int rptp_fd); static void notify_line(int rptp_fd, char *line); static void read_proc(int rptp_fd); static void process_input(int rptp_fd); #else static void write_proc(/* int rptp_fd */); static void do_register(/* int rptp_fd */); static void do_unregister(/* int rptp_fd */); static void notify_line(/* int rptp_fd, char *line */); static void read_proc(/* int rptp_fd */); static void process_input(/* int rptp_fd */); #endif /* * Builtin mainloop. Use this if not using another library's event handling routine */ int rptp_main_loop() { fd_set read_fds; fd_set write_fds; int i, n; looping = 1; main_loop_return_value = 0; while (looping) { FD_ZERO(&read_fds); FD_ZERO(&write_fds); for (i = 0; i < FD_SETSIZE; i++) { if (group[i].olist) FD_SET(i, &write_fds); if (group[i].rcallback) FD_SET(i, &read_fds); } n = select(FD_SETSIZE, &read_fds, &write_fds, NULL, NULL); if (n < 0) { if (errno == EINTR) continue; return -1; } for (i = 0; i < FD_SETSIZE && n; i++) { if (FD_ISSET(i, &read_fds)) { n--; if (group[i].rcallback) rptp_async_process(i, RPTP_ASYNC_READ); } if (FD_ISSET(i, &write_fds)) { n--; if (group[i].writing) rptp_async_process(i, RPTP_ASYNC_WRITE); } } } return main_loop_return_value; } /* * Terminate the mainloop at the earliest convenient time. The integer parameter * will be returned by mainloop() */ #ifdef __STDC__ void rptp_stop_main_loop(int return_value) #else void rptp_stop_main_loop(return_value) int return_value; #endif { looping = 0; main_loop_return_value = return_value; } /* * Write a line to the RPTP connection asynchronously. * * "\r\n" is appended to the string. */ #ifdef __STDC__ int rptp_async_putline(int rptp_fd, cb callback, char *fmt, ...) #else int rptp_async_putline(va_alist) va_dcl #endif { va_list args; char buf[RPTP_MAX_LINE]; #ifdef __STDC__ va_start(args, fmt); #else int rptp_fd; char *fmt; cb callback; char *tmp; va_start(args); rptp_fd = va_arg(args, int); tmp = va_arg(args, char *); callback = (cb) tmp; fmt = va_arg(args, char *); #endif if (rptp_fd < 0 || rptp_fd >= FD_SETSIZE) { rptp_errno = RPTP_ERROR_SOCKET; return -1; } rptp_errno = RPTP_ERROR_NONE; vsprintf(buf, fmt, args); va_end(args); strcat(buf, "\r\n"); return rptp_async_write(rptp_fd, callback, buf, strlen(buf)) != strlen(buf) ? -1 : 0; } /* * Write nbytes to the RPTP connection asynchronously * * If a callback function is given, it will be called as soon as all * nbytes have been written. */ #ifdef __STDC__ int rptp_async_write(int rptp_fd, cb callback, char *ptr, int nbytes) #else int rptp_async_write(rptp_fd, callback, ptr, nbytes) int rptp_fd; cb callback; char *ptr; int nbytes; #endif { obuf *new; if (rptp_fd < 0 || rptp_fd >= FD_SETSIZE) { rptp_errno = RPTP_ERROR_SOCKET; return -1; } /* * Create a new obuf with a copy of the data that needs to be written */ new = (obuf *) malloc(sizeof(obuf)); new->next = NULL; if (nbytes > 0 && ptr) { new->data = malloc(nbytes); memcpy(new->data, ptr, nbytes); } else /* allow empty data */ { new->data = NULL; } new->current = new->data; new->length = nbytes; new->callback = callback; /* * Append the obuf to the list of obufs for the given file descriptor */ if (group[rptp_fd].otail) { group[rptp_fd].otail->next = new; group[rptp_fd].otail = new; } else { group[rptp_fd].otail = group[rptp_fd].olist = new; } /* * If the output system is already writing we don't need to do anything else, * but if not, we need to register our output function */ if (!group[rptp_fd].writing) { do_register(rptp_fd); } } /* * Register a callback for I/O operations on a file descriptor. * There are two modes of operation for this call. The mode * depends on whether you use rptp_main_loop() or not. * Case 1 (using rptp_main_loop()): * Use rptp_async_register to register a callback for reading * or writing to a file descriptor. In this case the * what parameter is one of RPTP_ASYNC_READ or RPTP_ASYNC_WRITE | RPTP_ASYNC_RAW. * A typical prototype for the callback will be something like: * void callback(int fd); * Case 2 (NOT using rptp_main_loop()): * In this case, only RPTP_ASYNC_WRITE should be used. This will register * a callback which will have different parameters than the previous case. * void callback(int rptp_fd, int action); * The action parameter will be one of RPTP_ASYNC_ENABLE or RPTP_ASYNC_DISABLE. * If it is RPTP_ASYNC_ENABLE, the callback is supposed to register the rptp_fd * file descriptor with whatever I/O processing system the application uses. * For RPTP_ASYNC_DISABLE, it should be unregistered. */ #ifdef __STDC__ void rptp_async_register(int rptp_fd, int what, cb callback) #else void rptp_async_register(rptp_fd, what, callback) int rptp_fd; int what; cb callback; #endif { if (rptp_fd < 0 || rptp_fd >= FD_SETSIZE) { rptp_errno = RPTP_ERROR_SOCKET; return; } switch (what) { case RPTP_ASYNC_WRITE: group[rptp_fd].wcallback = callback; group[rptp_fd].wraw = 0; break; case RPTP_ASYNC_WRITE | RPTP_ASYNC_RAW: group[rptp_fd].wcallback = callback; group[rptp_fd].wraw = 1; break; case RPTP_ASYNC_READ: group[rptp_fd].rcallback = callback; group[rptp_fd].rraw = 1; break; } } /* * This gets called to let us know that some I/O can be preformed. * When rptp_main_loop() is not used, this function needs to be called * when either data is available or data can be written to a file descriptor. * The what parameter is one of RPTP_ASYNC_READ or RPTP_ASYNC_WRITE. * When rptp_main_loop() is used, this function should NEVER be called * by the application code. */ #ifdef __STDC__ void rptp_async_process(int rptp_fd, int what) #else void rptp_async_process(rptp_fd, what) int rptp_fd; int what; #endif { if (rptp_fd < 0 || rptp_fd >= FD_SETSIZE) { rptp_errno = RPTP_ERROR_SOCKET; return; } switch (what) { case RPTP_ASYNC_READ: if (group[rptp_fd].rraw && group[rptp_fd].rcallback) (*group[rptp_fd].rcallback)(rptp_fd); else read_proc(rptp_fd); break; case RPTP_ASYNC_WRITE: if (group[rptp_fd].wraw && group[rptp_fd].wcallback) (*group[rptp_fd].wcallback)(rptp_fd); else write_proc(rptp_fd); break; } } /* * Register a callback which will be called when data from a RPTP connection * becomes available. * The mask parameter specifies what kinds of events will be looked for and is * the logical OR of RPTP_EVENT_* constants. * The callback function takes 3 parameters. A typical prototype is something * like: * void callback(int rptp_fd, int event, char *string); */ #ifdef __STDC__ void rptp_async_notify(int rptp_fd, int mask, void (*callback)()) #else void rptp_async_notify(rptp_fd, mask, callback) int rptp_fd; int mask; void (*callback)(); #endif { char command[RPTP_MAX_LINE]; char *p; strcpy (command, "set notify="); if (mask & RPTP_EVENT_CONTINUE) strcat(command, "continue,"); if (mask & RPTP_EVENT_DONE) strcat(command, "done,"); if (mask & RPTP_EVENT_PAUSE) strcat(command, "pause,"); if (mask & RPTP_EVENT_PLAY) strcat(command, "play,"); if (mask & RPTP_EVENT_SKIP) strcat(command, "skip,"); if (mask & RPTP_EVENT_STATE) strcat(command, "state,"); if (mask & RPTP_EVENT_STOP) strcat(command, "stop,"); if (mask & RPTP_EVENT_VOLUME) strcat(command, "volume,"); if (mask & RPTP_EVENT_FLOW) strcat(command, "flow,"); if (mask & RPTP_EVENT_MODIFY) strcat(command, "modify,"); if (mask & RPTP_EVENT_LEVEL) strcat(command, "level,"); if (mask & RPTP_EVENT_POSITION) strcat(command, "position,"); p = strrchr(command, ','); if (!p) strcat(command, "none"); else *p = '\0'; rptp_async_putline(rptp_fd, NULL, command); group[rptp_fd].rcallback = callback; group[rptp_fd].notify_mask = mask; group[rptp_fd].rraw = 0; } /*------------------------------------------------------------------------- * Start of static routines. All functions below are only utility routines * for this module */ /* * Attempt to write data from the buffers to an fd. */ #ifdef __STDC__ static void write_proc(int rptp_fd) #else static void write_proc(rptp_fd) #endif { obuf *current; int n; if (!group[rptp_fd].olist) { do_unregister(rptp_fd); } current = group[rptp_fd].olist; if (current->current) { n = write(rptp_fd, current->current, current->length); if (n < 0) { return; } } else { n = 0; } current->length -= n; current->current += n; if (current->length <= 0) { if (current->callback) { (*current->callback)(rptp_fd); } if (current->data) { free(current->data); } group[rptp_fd].olist = current->next; if (group[rptp_fd].otail == current) { group[rptp_fd].otail = NULL; } free(current); if (!group[rptp_fd].olist) { do_unregister(rptp_fd); } } } /* * Attempt to read data from an fd to the buffer. */ #ifdef __STDC__ static void read_proc(int rptp_fd) #else static void read_proc(rptp_fd) #endif { char buffer[RPTP_MAX_LINE]; int n; ibuf *new; n = read(rptp_fd, buffer, sizeof(buffer)); if (n <= 0) { if (group[rptp_fd].notify_mask & RPTP_EVENT_CLOSE && group[rptp_fd].rcallback) { (*group[rptp_fd].rcallback)(rptp_fd, RPTP_EVENT_CLOSE, ""); group[rptp_fd].rcallback = NULL; } return; /* Don't do anything when we get an error. We'll get it later */ } new = (ibuf *) malloc(sizeof(ibuf)); new->next = NULL; new->data = malloc(n); memcpy(new->data, buffer, n); new->length = n; new->current = new->data; if (group[rptp_fd].itail) { group[rptp_fd].itail->next = new; group[rptp_fd].itail = new; } else { group[rptp_fd].itail = group[rptp_fd].ilist = new; } process_input(rptp_fd); } /* * Attempt to make complete lines from the input buffers for the given * file descriptor. */ #ifdef __STDC__ static void process_input(int rptp_fd) #else static void process_input(rptp_fd) int rptp_fd; #endif { char *p; ibuf *ptr; static char line[RPTP_MAX_LINE * 2] = ""; static int length = 0; while ((ptr = group[rptp_fd].ilist)) { if (p = memchr(ptr->current, '\r', ptr->length)) { memcpy(&line[length], ptr->current, p - ptr->current); length += p - ptr->current; line[length] = '\0'; notify_line(rptp_fd, line); length = 0; p+= 2; if (p < ptr->current + ptr->length) { /* * There is still unused data in this block. */ ptr->length -= p - ptr->current; ptr->current = p; } else { free(ptr->data); if (ptr == group[rptp_fd].itail) { group[rptp_fd].ilist = group[rptp_fd].itail = NULL; } else { group[rptp_fd].ilist = ptr->next; } free(ptr); } } else { /* * The current block of data doesn't contain any carriage * returns. We'll just add it to our line and get rid of it. */ memcpy(&line[length], ptr->current, ptr->length); length += ptr->length; free(ptr->data); if (ptr == group[rptp_fd].itail) { group[rptp_fd].ilist = group[rptp_fd].itail = NULL; } else { group[rptp_fd].ilist = ptr->next; } free(ptr); } } } /* * A mapping between event and event mask */ static struct { char *event; int mask; } events[] = { {"continue", RPTP_EVENT_CONTINUE}, {"done", RPTP_EVENT_DONE}, {"pause", RPTP_EVENT_PAUSE}, {"play", RPTP_EVENT_PLAY}, {"skip", RPTP_EVENT_SKIP}, {"state", RPTP_EVENT_STATE}, {"stop", RPTP_EVENT_STOP}, {"volume", RPTP_EVENT_VOLUME}, {"flow", RPTP_EVENT_FLOW}, {"modify", RPTP_EVENT_MODIFY}, {"level", RPTP_EVENT_LEVEL}, {"position", RPTP_EVENT_POSITION}, {NULL, 0} }; /* * Tell the application that a line has arrived from a connection */ #ifdef __STDC__ static void notify_line(int rptp_fd, char *line) #else static void notify_line(rptp_fd, line) int rptp_fd; char *line; #endif { int what; char *event; int i; /* * Make sure that there is a callback registered. No use doing * anything without one... */ if (!group[rptp_fd].rcallback) return; switch (*line) { case '+': what = RPTP_EVENT_OK; break; case '-': what = RPTP_EVENT_ERROR; break; case '!': what = RPTP_EVENT_TIMEOUT; break; case '@': event = rptp_parse(line, "event"); what = RPTP_EVENT_OTHER; for (i = 0; events[i].event; i++) { if (strcmp(events[i].event, event) == 0) { what = events[i].mask; break; } } break; default: what = RPTP_EVENT_OTHER; break; } if (what & group[rptp_fd].notify_mask) { (*group[rptp_fd].rcallback)(rptp_fd, what, line); } #if 0 else { printf("Input line being ignored: '%s'\n", line); } #endif } /* * Register us with whatever controls the write_fds on the select */ #ifdef __STDC__ static void do_register(int rptp_fd) #else static void do_register(rptp_fd) int rptp_fd; #endif { if (group[rptp_fd].wcallback) { (*group[rptp_fd].wcallback)(rptp_fd, RPTP_ASYNC_ENABLE); } group[rptp_fd].writing = 1; } /* * Unregister us with whatever controls the write_fds on the select */ #ifdef __STDC__ static void do_unregister(int rptp_fd) #else static void do_unregister(rptp_fd) int rptp_fd; #endif { if (group[rptp_fd].wcallback) { (*group[rptp_fd].wcallback)(rptp_fd, RPTP_ASYNC_DISABLE); } group[rptp_fd].writing = 0; } /* * Local variables: * tab-width: 4 * End: */ rplay-3.3.2/librplay/rplay.c100644 153 62 70646 6671423004 14465 0ustar boynsstaff/* $Id: rplay.c,v 1.6 1999/03/10 07:57:56 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "version.h" #include "rplay.h" #include #include #include #include #ifdef __STDC__ #include #else #include #endif #ifndef __FreeBSD__ #include #endif #include #ifdef HAVE_STRING_H #include #endif #include #ifdef HAVE_MEMORY_H #include #endif /* Make sure MAXHOSTNAMELEN is defined. */ #ifndef MAXHOSTNAMELEN #define MAXHOSTNAMELEN 256 #endif int rplay_errno; char *rplay_errlist[] = { "no error", /* RPLAY_ERROR_NONE */ "out of memory", /* RPLAY_ERROR_MEMORY */ "host not found", /* RPLAY_ERROR_HOST */ "cannot connect to socket", /* RPLAY_ERROR_CONNECT */ "cannot create socket", /* RPLAY_ERROR_SOCKET */ "error writing to socket", /* RPLAY_ERROR_WRITE */ "error closing socket", /* RPLAY_ERROR_CLOSE */ "max packet size exceeded", /* RPLAY_ERROR_PACKET_SIZE */ "cannot enable broadcast", /* RPLAY_ERROR_BROADCAST */ "unknown rplay attribute", /* RPLAY_ERROR_ATTRIBUTE */ "unknown rplay command", /* RPLAY_ERROR_COMMAND */ "illegal rplay index value", /* RPLAY_ERROR_INDEX */ "unknown rplay modifier", /* RPLAY_ERROR_MODIFIER */ }; /* #ifdef __STDC__ unsigned long inet_addr (char *rp); #else unsigned long inet_addr (); #endif */ /* A simple version a strdup. */ #ifndef HAVE_STRDUP #ifdef __STDC__ static char * strdup(char *str) #else static char * strdup(str) char *str; #endif { char *p; p = (char *) malloc(strlen(str) + 1); if (p == NULL) { return NULL; } else { strcpy(p, str); return p; } } #endif /* HAVE_STRDUP */ /* * create an rplay attributes object */ #ifdef __STDC__ static RPLAY_ATTRS * rplay_attrs_create(void) #else static RPLAY_ATTRS * rplay_attrs_create() #endif { RPLAY_ATTRS *attrs; attrs = (RPLAY_ATTRS *) malloc(sizeof(RPLAY_ATTRS)); if (attrs == NULL) { return NULL; } attrs->next = NULL; attrs->sound = ""; attrs->volume = RPLAY_DEFAULT_VOLUME; attrs->count = RPLAY_DEFAULT_COUNT; attrs->rptp_server = NULL; attrs->rptp_server_port = RPTP_PORT; attrs->rptp_search = TRUE; attrs->sample_rate = RPLAY_DEFAULT_SAMPLE_RATE; attrs->client_data = ""; return attrs; } /* * free memory used by an rplay attributes object */ #ifdef __STDC__ static void rplay_attrs_destroy(RPLAY_ATTRS *attrs) #else static void rplay_attrs_destroy(attrs) RPLAY_ATTRS *attrs; #endif { if (*attrs->sound) { free((char *) attrs->sound); } if (attrs->rptp_server) { free((char *) attrs->rptp_server); } if (*attrs->client_data) { free((char *) attrs->client_data); } free((char *) attrs); } #define COPY_SIZE 128 #define COPY(rp, p, n) \ grow = 0; \ while (rp->len + n > rp->size) \ { \ grow++; \ rp->size += COPY_SIZE; \ if (rp->size > MAX_PACKET) \ { \ rplay_errno = RPLAY_ERROR_PACKET_SIZE; \ return -1; \ } \ } \ if (grow) \ { \ rp->buf = realloc (rp->buf, rp->size); \ if (rp->buf == NULL) \ { \ rplay_errno = RPLAY_ERROR_MEMORY; \ return -1; \ } \ } \ memcpy ((char *) rp->buf + rp->len, (char *) p, n); \ rp->len += n; \ /* * pack the rplay object into the internal buffer * * this routine is called everytime rplay_set is used */ #ifdef __STDC__ int rplay_pack(RPLAY *rp) #else int rplay_pack(rp) RPLAY *rp; #endif { RPLAY_ATTRS *attrs; int len, grow = 0, i; unsigned char val; unsigned long lval; unsigned short sval; short size; rp->len = 0; val = RPLAY_PACKET_ID; COPY(rp, &val, sizeof(val)); val = rp->command; COPY(rp, &val, sizeof(val)); if (rp->count != RPLAY_DEFAULT_LIST_COUNT) { val = RPLAY_LIST_COUNT; COPY(rp, &val, sizeof(val)); val = rp->count; COPY(rp, &val, sizeof(val)); } if (rp->priority != RPLAY_DEFAULT_PRIORITY) { val = RPLAY_PRIORITY; COPY(rp, &val, sizeof(val)); val = rp->priority; COPY(rp, &val, sizeof(val)); } if (*rp->list_name) { val = RPLAY_LIST_NAME; COPY(rp, &val, sizeof(val)); len = strlen(rp->list_name) + 1; COPY(rp, rp->list_name, len); } if (rp->id != RPLAY_NULL) { val = RPLAY_ID; COPY(rp, &val, sizeof(val)); lval = htonl(rp->id); COPY(rp, &lval, sizeof(lval)); } if (rp->sequence != -1) { val = RPLAY_SEQUENCE; COPY(rp, &val, sizeof(val)); lval = htonl(rp->sequence); COPY(rp, &lval, sizeof(lval)); } if (rp->data != RPLAY_NULL && rp->data_size > 0) { val = RPLAY_DATA_SIZE; COPY(rp, &val, sizeof(val)); sval = htons(rp->data_size); COPY(rp, &sval, sizeof(sval)); val = RPLAY_DATA; COPY(rp, &val, sizeof(val)); COPY(rp, rp->data, rp->data_size); } for (i = 0, attrs = rp->attrs; attrs; attrs = attrs->next, i++) { if (rp->random_sound != RPLAY_DEFAULT_RANDOM_SOUND) { if (i != rp->random_sound) { continue; } } if (*attrs->sound) { val = RPLAY_SOUND; COPY(rp, &val, sizeof(val)); len = strlen(attrs->sound) + 1; COPY(rp, attrs->sound, len); } if (attrs->volume != RPLAY_DEFAULT_VOLUME) { val = RPLAY_VOLUME; COPY(rp, &val, sizeof(val)); val = attrs->volume; COPY(rp, &val, sizeof(val)); } if (attrs->count != RPLAY_DEFAULT_COUNT) { val = RPLAY_COUNT; COPY(rp, &val, sizeof(val)); val = attrs->count; COPY(rp, &val, sizeof(val)); } if (attrs->rptp_server) { val = RPLAY_RPTP_SERVER; COPY(rp, &val, sizeof(val)); len = strlen(attrs->rptp_server) + 1; COPY(rp, attrs->rptp_server, len); } if (attrs->rptp_server_port != RPTP_PORT) { val = RPLAY_RPTP_SERVER_PORT; COPY(rp, &val, sizeof(val)); size = htons(attrs->rptp_server_port); COPY(rp, &size, sizeof(size)); } if (attrs->rptp_search == FALSE) { val = RPLAY_RPTP_SEARCH; COPY(rp, &val, sizeof(val)); val = attrs->rptp_search; COPY(rp, &val, sizeof(val)); } if (attrs->sample_rate != RPLAY_DEFAULT_SAMPLE_RATE) { val = RPLAY_SAMPLE_RATE; COPY(rp, &val, sizeof(val)); lval = htonl(attrs->sample_rate); COPY(rp, &lval, sizeof(lval)); } if (*attrs->client_data) { val = RPLAY_CLIENT_DATA; COPY(rp, &val, sizeof(val)); len = strlen(attrs->client_data) + 1; COPY(rp, attrs->client_data, len); } val = RPLAY_NULL; COPY(rp, &val, sizeof(val)); } if (i == 0) { val = RPLAY_NULL; COPY(rp, &val, sizeof(val)); } val = RPLAY_NULL; COPY(rp, &val, sizeof(val)); return 0; } /* * unpack an rplay packet into an rplay object */ #ifdef __STDC__ RPLAY * rplay_unpack(char *packet) #else RPLAY * rplay_unpack(packet) char *packet; #endif { RPLAY *rp; int still_going = 1; int version; rplay_errno = RPLAY_ERROR_NONE; version = *packet++; rp = rplay_create(*packet++); if (rp == NULL) { rplay_errno = RPLAY_ERROR_MEMORY; return NULL; } *(rp->attrsp) = rplay_attrs_create(); if (*(rp->attrsp) == NULL) { rplay_errno = RPLAY_ERROR_MEMORY; return NULL; } while (still_going) { switch (*packet++) { case RPLAY_LIST_COUNT: rp->count = (unsigned char) *packet++; break; case RPLAY_LIST_NAME: rp->list_name = strdup(packet); packet += strlen(packet) + 1; break; case RPLAY_PRIORITY: rp->priority = (unsigned char) *packet++; break; case RPLAY_SOUND: (*rp->attrsp)->sound = strdup(packet); packet += strlen(packet) + 1; break; case RPLAY_VOLUME: (*rp->attrsp)->volume = (unsigned char) *packet++; break; case RPLAY_COUNT: (*rp->attrsp)->count = (unsigned char) *packet++; break; case RPLAY_RPTP_SERVER: (*rp->attrsp)->rptp_server = strdup(packet); packet += strlen(packet) + 1; break; case RPLAY_RPTP_SERVER_PORT: memcpy((char *) &(*rp->attrsp)->rptp_server_port, packet, sizeof((*rp->attrsp)->rptp_server_port)); (*rp->attrsp)->rptp_server_port = ntohs((*rp->attrsp)->rptp_server_port); packet += sizeof((*rp->attrsp)->rptp_server_port); break; case RPLAY_RPTP_SEARCH: (*rp->attrsp)->rptp_search = (unsigned char) *packet++; break; case RPLAY_SAMPLE_RATE: memcpy((char *) &(*rp->attrsp)->sample_rate, packet, sizeof((*rp->attrsp)->sample_rate)); (*rp->attrsp)->sample_rate = ntohl((*rp->attrsp)->sample_rate); packet += sizeof((*rp->attrsp)->sample_rate); break; case RPLAY_CLIENT_DATA: (*rp->attrsp)->client_data = strdup(packet); packet += strlen(packet) + 1; break; case RPLAY_ID: memcpy((char *) &rp->id, packet, sizeof(rp->id)); rp->id = ntohl(rp->id); packet += sizeof(rp->id); break; case RPLAY_SEQUENCE: memcpy((char *) &rp->sequence, packet, sizeof(rp->sequence)); rp->sequence = ntohl(rp->sequence); packet += sizeof(rp->sequence); break; case RPLAY_DATA_SIZE: memcpy((char *) &rp->data_size, packet, sizeof(rp->data_size)); rp->data_size = ntohs(rp->data_size); packet += sizeof(rp->data_size); break; case RPLAY_DATA: rp->data = (char *) malloc(rp->data_size); memcpy(rp->data, packet, rp->data_size); packet += rp->data_size; break; case RPLAY_NULL: rp->nsounds++; rp->attrsp = &(*rp->attrsp)->next; if (*packet == RPLAY_NULL) { still_going = 0; } else { *(rp->attrsp) = rplay_attrs_create(); if (*(rp->attrsp) == NULL) { rplay_errno = RPLAY_ERROR_MEMORY; return NULL; } } break; default: rplay_errno = RPLAY_ERROR_ATTRIBUTE; #if 1 printf("unpack: unknown attr '%d'\n", *packet); #endif return NULL; } } return rp; } /* * create an rplay object for the given command * * currently all commands use the same internal representation but this can * be changed in the future */ #ifdef __STDC__ RPLAY * rplay_create(int command) #else RPLAY * rplay_create(command) int command; #endif { RPLAY *rp; rplay_errno = RPLAY_ERROR_NONE; rp = (RPLAY *) malloc(sizeof(RPLAY)); if (rp == NULL) { rplay_errno = RPLAY_ERROR_MEMORY; return NULL; } rp->attrs = NULL; rp->attrsp = &rp->attrs; rp->buf = (char *) malloc(COPY_SIZE); if (rp->buf == NULL) { rplay_errno = RPLAY_ERROR_MEMORY; return NULL; } rp->len = 0; rp->size = 0; rp->command = RPLAY_NULL; rp->nsounds = 0; rp->count = RPLAY_DEFAULT_LIST_COUNT; rp->priority = RPLAY_DEFAULT_PRIORITY; rp->random_sound = RPLAY_DEFAULT_RANDOM_SOUND; rp->list_name = ""; rp->id = RPLAY_NULL; rp->sequence = -1; rp->data = NULL; rp->data_size = 0; switch (command) { case RPLAY_PLAY: case RPLAY_STOP: case RPLAY_PAUSE: case RPLAY_CONTINUE: case RPLAY_PING: case RPLAY_RESET: case RPLAY_DONE: case RPLAY_PUT: rp->command = command; break; default: rplay_errno = RPLAY_ERROR_COMMAND; return NULL; } return rp; } /* * return the rplay attributes for the given index */ #ifdef __STDC__ static RPLAY_ATTRS * get_attrs(RPLAY_ATTRS *attrs, int index) #else static RPLAY_ATTRS * get_attrs(attrs, index) RPLAY_ATTRS *attrs; int index; #endif { int i; if (index < 0) { return NULL; } for (i = 0; i < index && attrs; i++, attrs = attrs->next) ; return attrs; } /* * set rplay attributes for the given rplay object * * The argument list should be NULL terminated but this is * not always checked. */ #ifdef __STDC__ long rplay_set(RPLAY *rp,...) #else long rplay_set(va_alist) va_dcl #endif { va_list args; RPLAY_ATTRS *attrs = NULL, *prev = NULL, *curr; int index, i, modifier; char *data; time_t seed; #ifdef __STDC__ va_start(args, rp); #else RPLAY *rp; va_start(args); rp = va_arg(args, RPLAY *); #endif rplay_errno = RPLAY_ERROR_NONE; modifier = va_arg(args, long); switch (modifier) { case RPLAY_APPEND: *(rp->attrsp) = attrs = rplay_attrs_create(); if (attrs == NULL) { rplay_errno = RPLAY_ERROR_MEMORY; return -1; } rp->attrsp = &attrs->next; rp->nsounds++; break; case RPLAY_INSERT: index = va_arg(args, long); if (index < 0) { rplay_errno = RPLAY_ERROR_INDEX; return -1; } for (i = 0, curr = rp->attrs; i < index && curr; i++) { prev = curr; curr = curr->next; } if (curr == NULL && i != index) { rplay_errno = RPLAY_ERROR_INDEX; return -1; } attrs = rplay_attrs_create(); if (attrs == NULL) { rplay_errno = RPLAY_ERROR_MEMORY; return -1; } if (prev) { prev->next = attrs; } else { *(rp->attrsp) = attrs; } attrs->next = curr; if (attrs->next == NULL) { rp->attrsp = &attrs->next; } rp->nsounds++; break; case RPLAY_DELETE: index = va_arg(args, long); if (index < 0) { rplay_errno = RPLAY_ERROR_INDEX; return -1; } for (i = 0, curr = rp->attrs; i < index && curr; i++) { prev = curr; curr = curr->next; } if (curr == NULL) { rplay_errno = RPLAY_ERROR_INDEX; return -1; } if (prev) { prev->next = curr->next; if (prev->next == NULL) { rp->attrsp = &prev->next; } } else { rp->attrs = curr->next; if (rp->attrs == NULL) { rp->attrsp = &rp->attrs; } } rplay_attrs_destroy(curr); rp->nsounds--; break; case RPLAY_CHANGE: index = va_arg(args, long); attrs = get_attrs(rp->attrs, index); if (attrs == NULL) { rplay_errno = RPLAY_ERROR_INDEX; return -1; } break; case RPLAY_LIST_COUNT: rp->count = va_arg(args, long); break; case RPLAY_LIST_NAME: if (*rp->list_name) { free((char *) rp->list_name); } rp->list_name = strdup(va_arg(args, char *)); break; case RPLAY_PRIORITY: rp->priority = va_arg(args, long); break; case RPLAY_RANDOM_SOUND: seed = time(0); srandom((int) seed); rp->random_sound = (int) (random() % rp->nsounds); break; case RPLAY_ID: rp->id = va_arg(args, long); break; case RPLAY_SEQUENCE: rp->sequence = va_arg(args, unsigned long); break; case RPLAY_DATA_SIZE: rplay_errno = RPLAY_ERROR_MODIFIER; return -1; case RPLAY_DATA: if (rp->data) { free((char *) rp->data); } data = va_arg(args, char *); rp->data_size = va_arg(args, long); rp->data = (char *) malloc(rp->data_size); if (rp->data == NULL) { rplay_errno = RPLAY_ERROR_MEMORY; return -1; } memcpy(rp->data, data, rp->data_size); break; default: rplay_errno = RPLAY_ERROR_MODIFIER; return -1; } if (attrs) { int attribute; while ((attribute = va_arg(args, long))) { switch (attribute) { case RPLAY_LIST_COUNT: rp->count = va_arg(args, long); break; case RPLAY_LIST_NAME: if (*rp->list_name) { free((char *) rp->list_name); } rp->list_name = strdup(va_arg(args, char *)); break; case RPLAY_PRIORITY: rp->priority = va_arg(args, long); break; case RPLAY_SOUND: if (*attrs->sound) { free((char *) attrs->sound); } attrs->sound = strdup(va_arg(args, char *)); break; case RPLAY_VOLUME: attrs->volume = va_arg(args, long); break; case RPLAY_COUNT: attrs->count = va_arg(args, long); break; case RPLAY_RPTP_SERVER: case RPLAY_RPTP_FROM_SENDER: { struct hostent *hp; u_long addr; struct sockaddr_in s; char *host = va_arg(args, char *); char hostname[MAXHOSTNAMELEN]; if (attribute == RPLAY_RPTP_FROM_SENDER) { if (gethostname(hostname, sizeof(hostname)) < 0) { rplay_errno = RPLAY_ERROR_HOST; return -1; } host = hostname; } else { host = va_arg(args, char *); } memset((char *) &s, 0, sizeof(s)); addr = inet_addr(host); if (addr == 0xffffffff) { hp = gethostbyname(host); if (hp == NULL) { rplay_errno = RPLAY_ERROR_HOST; return -1; } memcpy((char *) &s.sin_addr.s_addr, (char *) hp->h_addr, hp->h_length); } else { memcpy((char *) &s.sin_addr.s_addr, (char *) &addr, sizeof(addr)); } attrs->rptp_server = strdup((char *) inet_ntoa(s.sin_addr)); break; } case RPLAY_RPTP_SERVER_PORT: attrs->rptp_server_port = (unsigned short) va_arg(args, long); break; case RPLAY_RPTP_SEARCH: attrs->rptp_search = va_arg(args, long); break; case RPLAY_SAMPLE_RATE: attrs->sample_rate = va_arg(args, unsigned long); break; case RPLAY_CLIENT_DATA: if (*attrs->client_data) { free((char *) attrs->client_data); } attrs->client_data = strdup(va_arg(args, char *)); break; default: rplay_errno = RPLAY_ERROR_ATTRIBUTE; return -1; } } } return rplay_pack(rp); } /* * retrieve rplay attributes from the given rplay object */ #ifdef __STDC__ long rplay_get(RPLAY *rp,...) #else long rplay_get(va_alist) va_dcl #endif { va_list args; RPLAY_ATTRS *attrs; int get, index; #ifdef __STDC__ va_start(args, rp); #else RPLAY *rp; va_start(args); rp = va_arg(args, RPLAY *); #endif rplay_errno = RPLAY_ERROR_NONE; get = va_arg(args, long); switch (get) { case RPLAY_NSOUNDS: return rp->nsounds; case RPLAY_COMMAND: return rp->command; case RPLAY_LIST_COUNT: return rp->count; case RPLAY_LIST_NAME: return (long) rp->list_name; case RPLAY_PRIORITY: return rp->priority; case RPLAY_RANDOM_SOUND: return rp->random_sound; case RPLAY_ID: return rp->id; case RPLAY_SEQUENCE: return rp->sequence; case RPLAY_DATA_SIZE: return rp->data_size; case RPLAY_DATA: return (long) rp->data; case RPLAY_SOUND: index = va_arg(args, long); attrs = get_attrs(rp->attrs, index); if (attrs == NULL) { rplay_errno = RPLAY_ERROR_INDEX; return -1; } return (long) attrs->sound; case RPLAY_VOLUME: index = va_arg(args, long); attrs = get_attrs(rp->attrs, index); if (attrs == NULL) { rplay_errno = RPLAY_ERROR_INDEX; return -1; } return attrs->volume; case RPLAY_COUNT: index = va_arg(args, long); attrs = get_attrs(rp->attrs, index); if (attrs == NULL) { rplay_errno = RPLAY_ERROR_INDEX; return -1; } return attrs->count; case RPLAY_RPTP_SERVER: index = va_arg(args, long); attrs = get_attrs(rp->attrs, index); if (attrs == NULL) { rplay_errno = RPLAY_ERROR_INDEX; return -1; } return (long) attrs->rptp_server; case RPLAY_RPTP_SERVER_PORT: index = va_arg(args, long); attrs = get_attrs(rp->attrs, index); if (attrs == NULL) { rplay_errno = RPLAY_ERROR_INDEX; return -1; } return (long) attrs->rptp_server_port; case RPLAY_RPTP_SEARCH: index = va_arg(args, long); attrs = get_attrs(rp->attrs, index); if (attrs == NULL) { rplay_errno = RPLAY_ERROR_INDEX; return -1; } return attrs->rptp_search; case RPLAY_SAMPLE_RATE: index = va_arg(args, long); attrs = get_attrs(rp->attrs, index); if (attrs == NULL) { rplay_errno = RPLAY_ERROR_INDEX; return -1; } return attrs->sample_rate; case RPLAY_CLIENT_DATA: index = va_arg(args, int); attrs = get_attrs(rp->attrs, index); if (attrs == NULL) { rplay_errno = RPLAY_ERROR_INDEX; return -1; } return (long) attrs->client_data; default: rplay_errno = RPLAY_ERROR_ATTRIBUTE; return -1; } } /* * free memory used by the given rplay object */ #ifdef __STDC__ void rplay_destroy(RPLAY *rp) #else void rplay_destroy(rp) RPLAY *rp; #endif { RPLAY_ATTRS *p, *q; rplay_errno = RPLAY_ERROR_NONE; for (p = rp->attrs; p; q = p, p = p->next, rplay_attrs_destroy(q)) ; if (*rp->list_name) { free((char *) rp->list_name); } if (rp->data) { free((char *) rp->data); } free((char *) rp->buf); free((char *) rp); } /* * support routine to convert rplay 2.0 packets to rplay 3.0 */ #ifdef OLD_RPLAY #ifdef __STDC__ char * rplay_convert(char *p) #else char * rplay_convert(p) char *p; #endif { static char buf[MAX_PACKET]; char *q = buf; int len; *q++ = RPLAY_PACKET_ID; switch (*p++) { case OLD_RPLAY_PLAY: *q++ = RPLAY_PLAY; break; case OLD_RPLAY_STOP: *q++ = RPLAY_STOP; break; case OLD_RPLAY_PAUSE: *q++ = RPLAY_PAUSE; break; case OLD_RPLAY_CONTINUE: *q++ = RPLAY_CONTINUE; break; } do { *q++ = RPLAY_SOUND; strcpy(q, p); len = strlen(p) + 1; p += len; q += len; *q++ = RPLAY_VOLUME; *q++ = *p++; *q++ = RPLAY_NULL; } while (*p); *q++ = RPLAY_NULL; return buf; } #endif /* OLD_RPLAY */ static int default_rplay_port() { struct servent *sp; int port; sp = getservbyname("rplay", "udp"); if (sp) { port = ntohs(sp->s_port); /* htons is used later */ } else { port = RPLAY_PORT; } return port; } #ifdef __STDC__ int rplay_open(char *host) #else int rplay_open(host) char *host; #endif { int port; port = default_rplay_port(); return rplay_open_port(host, port); } /* * Open a UDP socket for the given host and port. * * The host can be either a name or an IP address. */ #ifdef __STDC__ int rplay_open_port(char *host, int port) #else int rplay_open_port(host, port) char *host; int port; #endif { struct hostent *hp; u_long addr; struct sockaddr_in s; rplay_errno = RPLAY_ERROR_NONE; memset((char *) &s, 0, sizeof(s)); addr = inet_addr(host); if (addr == 0xffffffff) { hp = gethostbyname(host); if (hp == NULL) { rplay_errno = RPLAY_ERROR_HOST; return -1; } memcpy((char *) &s.sin_addr.s_addr, (char *) hp->h_addr, hp->h_length); } else { memcpy((char *) &s.sin_addr.s_addr, (char *) &addr, sizeof(addr)); } s.sin_port = htons(port); s.sin_family = AF_INET; return rplay_open_sockaddr_in(&s); } #ifdef __STDC__ int rplay_open_sockaddr_in(struct sockaddr_in *saddr) #else int rplay_open_sockaddr_in(saddr) struct sockaddr_in *saddr; #endif { int rplay_fd; int on = 1; rplay_fd = socket(AF_INET, SOCK_DGRAM, 0); if (rplay_fd < 0) { rplay_errno = RPLAY_ERROR_SOCKET; return -1; } /* * enable broadcasting */ if (setsockopt(rplay_fd, SOL_SOCKET, SO_BROADCAST, (char *) &on, sizeof(on)) < 0) { rplay_errno = RPLAY_ERROR_BROADCAST; return -1; } if (connect(rplay_fd, (struct sockaddr *) saddr, sizeof(*saddr)) < 0) { rplay_errno = RPLAY_ERROR_CONNECT; return -1; } return rplay_fd; } /* * send an rplay packet to a host */ #ifdef __STDC__ int rplay(int rplay_fd, RPLAY *rp) #else int rplay(rplay_fd, rp) int rplay_fd; RPLAY *rp; #endif { rplay_errno = RPLAY_ERROR_NONE; if (write(rplay_fd, rp->buf, rp->len) != rp->len) { rplay_errno = RPLAY_ERROR_WRITE; return -1; } return 0; } /* * close the socket */ #ifdef __STDC__ int rplay_close(int rplay_fd) #else int rplay_close(rplay_fd) int rplay_fd; #endif { rplay_errno = RPLAY_ERROR_NONE; if (close(rplay_fd) < 0) { rplay_errno = RPLAY_ERROR_CLOSE; return -1; } return 0; } /* * report rplay error messages */ #ifdef __STDC__ void rplay_perror(char *s) #else void rplay_perror(s) char *s; #endif { fprintf(stderr, "%s: %s\n", s, rplay_errlist[rplay_errno]); } /* * open a socket using the current X display * (uses the DISPLAY environment variable) */ #ifdef __STDC__ int rplay_open_display(void) #else int rplay_open_display() #endif { char *display, *p; char host[MAXHOSTNAMELEN]; display = getenv("DISPLAY"); if (display == NULL || display[0] == ':') { strcpy(host, "localhost"); } else { strcpy(host, display); p = strchr(host, ':'); if (p) { *p = '\0'; } if (strcmp(host, "unix") == 0 || strcmp(host, "local") == 0 || strcmp(host, "X") == 0) { strcpy(host, "localhost"); } } return rplay_open(host); } /* * play a sound on the current X display */ #ifdef __STDC__ int rplay_display(char *sound) #else int rplay_display(sound) char *sound; #endif { int rplay_fd; rplay_fd = rplay_open_display(); if (rplay_fd < 0) { return -1; } return rplay_sound(rplay_fd, sound); } /* * play a sound on the localhost */ #ifdef __STDC__ int rplay_local(char *sound) #else int rplay_local(sound) char *sound; #endif { return rplay_host("localhost", sound); } /* * play a sound on a host */ #ifdef __STDC__ int rplay_host(char *host, char *sound) #else int rplay_host(host, sound) char *host; char *sound; #endif { int rplay_fd; rplay_fd = rplay_open(host); if (rplay_fd < 0) { return -1; } return rplay_sound(rplay_fd, sound); } /* * play a sound given a socket */ #ifdef __STDC__ int rplay_sound(int rplay_fd, char *sound) #else int rplay_sound(rplay_fd, sound) int rplay_fd; char *sound; #endif { RPLAY *rp; rp = rplay_create(RPLAY_PLAY); if (rp == NULL) { return -1; } if (rplay_set(rp, RPLAY_APPEND, RPLAY_SOUND, sound, NULL) < 0) { return -1; } if (rplay(rplay_fd, rp) < 0) { return -1; } rplay_destroy(rp); return 0; } /* * ping an rplay server */ #ifdef __STDC__ int rplay_ping(char *host) #else int rplay_ping(host) char *host; #endif { int rplay_fd; int port; int error1 = 0, error2 = 0; /* Ping the default port. */ port = default_rplay_port(); rplay_fd = rplay_open_port(host, port); if (rplay_fd < 0) { return -1; } error1 = rplay_ping_sockfd(rplay_fd); #ifdef OTHER_RPLAY_PORTS /* Pick an alternative port. */ if (port == RPLAY_PORT) { port = OLD_RPLAY_PORT; } else { port = RPLAY_PORT; } /* Ping the alternative port. */ rplay_fd = rplay_open_port(host, port); if (rplay_fd < 0) { return -1; } error2 = rplay_ping_sockfd(rplay_fd); #endif /* OTHER_RPLAY_PORTS */ /* Only return -1 if both pings fail. */ if (error1 < 0 && error2 < 0) { return -1; } else { return 0; } } #ifdef __STDC__ int rplay_ping_sockfd(int rplay_fd) #else int rplay_ping_sockfd(rplay_fd) int rplay_fd; #endif { RPLAY *rp; rp = rplay_create(RPLAY_PING); if (rp == NULL) { return -1; } if (rplay_pack(rp) < 0) { return -1; } if (rplay(rplay_fd, rp) < 0) { return -1; } rplay_close(rplay_fd); rplay_destroy(rp); return 0; } #ifdef __STDC__ int rplay_ping_sockaddr_in(struct sockaddr_in *saddr) #else int rplay_ping_sockaddr_in(saddr) struct sockaddr_in *saddr; #endif { int rplay_fd; rplay_fd = rplay_open_sockaddr_in(saddr); if (rplay_fd < 0) { return -1; } return rplay_ping_sockfd(rplay_fd); } /* * play a sound on a host with a specific volume */ #ifdef __STDC__ int rplay_host_volume(char *host, char *sound, int volume) #else int rplay_host_volume(host, sound, volume) char *host; char *sound; int volume; #endif { int rplay_fd; RPLAY *rp; rplay_fd = rplay_open(host); if (rplay_fd < 0) { return -1; } rp = rplay_create(RPLAY_PLAY); if (rp == NULL) { return -1; } if (rplay_set(rp, RPLAY_APPEND, RPLAY_SOUND, sound, RPLAY_VOLUME, volume, NULL) < 0) { return -1; } if (rplay(rplay_fd, rp) < 0) { return -1; } rplay_destroy(rp); return 0; } /* * obtain the default rplay host */ #ifdef __STDC__ char * rplay_default_host(void) #else char * rplay_default_host() #endif { char *host; host = getenv("RPLAY_HOST"); return host ? host : "localhost"; } /* * play a sound on the default rplay host */ #ifdef __STDC__ int rplay_default(char *sound) #else int rplay_default(sound) char *sound; #endif { return rplay_host(rplay_default_host(), sound); } /* * open the default host */ #ifdef __STDC__ int rplay_open_default(void) #else int rplay_open_default() #endif { return rplay_open(rplay_default_host()); } rplay-3.3.2/librplay/rptp.c100644 153 62 26252 6671423004 14315 0ustar boynsstaff/* $Id: rptp.c,v 1.4 1999/03/10 07:57:56 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "version.h" #include "rplay.h" #include #ifdef ultrix #include #else #include #endif #include #include #ifdef HAVE_STRING_H #include #endif #ifdef __STDC__ #include #else #include #endif #include int rptp_errno = RPTP_ERROR_NONE; char *rptp_errlist[] = { "no error", /* RPTP_ERROR_NONE */ "out of memory", /* RPTP_ERROR_MEMORY */ "host not found", /* RPTP_ERROR_HOST */ "connection failed", /* RPTP_ERROR_CONNECT */ "cannot create socket", /* RPTP_ERROR_SOCKET */ "cannot open socket", /* RPTP_ERROR_OPEN */ "cannot read from socket", /* RPTP_ERROR_READ */ "cannot write to socket", /* RPTP_ERROR_WRITE */ "cannot ping rplay server", /* RPTP_ERROR_PING */ "connection timeout", /* RPTP_ERROR_TIMEOUT */ "RPTP protocol error", /* RPTP_ERROR_PROTOCOL */ }; #ifdef __STDC__ unsigned long inet_addr(char *rp); #else unsigned long inet_addr(); #endif #ifndef HAVE_STRDUP #ifdef __STDC__ static char * strdup(char *str) #else static char * strdup(str) char *str; #endif { char *p; p = (char *) malloc(strlen(str) + 1); if (p == NULL) { return NULL; } else { strcpy(p, str); return p; } } #endif /* HAVE_STRDUP */ /* * open an RPTP connection to host using port * the connection response will be stored in the response buffer */ #ifdef __STDC__ int rptp_open(char *host, int port, char *response, int response_size) #else int rptp_open(host, port, response, response_size) char *host; int port; char *response; int response_size; #endif { u_long addr; struct sockaddr_in s; struct hostent *hp; int rptp_fd; int i, n; rptp_errno = RPTP_ERROR_NONE; memset((char *) &s, 0, sizeof(s)); addr = inet_addr(host); if (addr == 0xffffffff) { hp = gethostbyname(host); if (hp == NULL) { rptp_errno = RPTP_ERROR_HOST; return -1; } memcpy((char *) &s.sin_addr.s_addr, (char *) hp->h_addr, hp->h_length); } else { memcpy((char *) &s.sin_addr.s_addr, (char *) &addr, sizeof(addr)); } s.sin_port = htons(port); s.sin_family = AF_INET; for (i = 0; i < RPTP_CONNECT_ATTEMPTS; i++) { if (rplay_ping(host) < 0) { rptp_errno = RPTP_ERROR_PING; return -1; } rptp_fd = socket(AF_INET, SOCK_STREAM, 0); if (rptp_fd < 0) { rptp_errno = RPTP_ERROR_SOCKET; return -1; } n = connect(rptp_fd, (struct sockaddr *) &s, sizeof(s)); if (n == 0) { /* * successful connection */ rptp_getline(rptp_fd, response, response_size); if (response[0] == RPTP_ERROR) { rptp_errno = RPTP_ERROR_OPEN; return -1; } return rptp_fd; } switch (errno) { case ECONNREFUSED: case EINTR: close(rptp_fd); if (i + 1 != RPTP_CONNECT_ATTEMPTS) { sleep(RPTP_PING_DELAY); } break; default: rptp_errno = RPTP_ERROR_CONNECT; return -1; } } rptp_errno = RPTP_ERROR_CONNECT; return -1; } /* * read nbytes from the RPTP connection * * return the number of bytes actually read * * The routine was adapted from readn() in "Unix Network Programming" * by W. Richard Stevens, page 279. */ #ifdef __STDC__ int rptp_read(int rptp_fd, char *ptr, int nbytes) #else int rptp_read(rptp_fd, ptr, nbytes) int rptp_fd; char *ptr; int nbytes; #endif { int nleft, nread; rptp_errno = RPTP_ERROR_NONE; nleft = nbytes; while (nleft > 0) { nread = read(rptp_fd, ptr, nleft); if (nread < 0) { if (errno == EINTR) { continue; } rptp_errno = RPTP_ERROR_READ; return -1; } if (nread == 0) { break; } nleft -= nread; ptr += nread; } return nbytes - nleft; } /* * write nbytes to the RPTP connection * * return the number of bytes actually written * * The routine was adapted from writen() in "Unix Network Programming" * by W. Richard Stevens, page 279-80. */ #ifdef __STDC__ int rptp_write(int rptp_fd, char *ptr, int nbytes) #else int rptp_write(rptp_fd, ptr, nbytes) int rptp_fd; char *ptr; int nbytes; #endif { int nleft, nwritten; rptp_errno = RPTP_ERROR_NONE; nleft = nbytes; while (nleft > 0) { nwritten = write(rptp_fd, ptr, nleft); if (nwritten < 0) { if (errno == EINTR) { continue; } rptp_errno = RPTP_ERROR_WRITE; return -1; } else if (nwritten == 0) { rptp_errno = RPTP_ERROR_WRITE; return -1; } nleft -= nwritten; ptr += nwritten; } return nbytes - nleft; } /* * write a line to the RPTP connection * * "\r\n" is appened to the string */ #ifdef __STDC__ int rptp_putline(int rptp_fd, char *fmt,...) #else int rptp_putline(va_alist) va_dcl #endif { va_list args; char buf[RPTP_MAX_LINE]; #ifdef __STDC__ va_start(args, fmt); #else int rptp_fd; char *fmt; va_start(args); rptp_fd = va_arg(args, int); fmt = va_arg(args, char *); #endif rptp_errno = RPTP_ERROR_NONE; vsprintf(buf, fmt, args); va_end(args); strcat(buf, "\r\n"); return rptp_write(rptp_fd, buf, strlen(buf)) != strlen(buf) ? -1 : 0; } /* * read a line from the RPTP connection * * "\r\n" is removed from the line */ #ifdef __STDC__ int rptp_getline(int rptp_fd, char *buf, int nbytes) #else int rptp_getline(rptp_fd, buf, nbytes) int rptp_fd; char *buf; int nbytes; #endif { int i, n, nleft, x; char *ptr; char tmp_buf[RPTP_MAX_LINE]; rptp_errno = RPTP_ERROR_NONE; nleft = nbytes; ptr = buf; while (nleft > 0) { /* * peek at the message so only the necessary data * is actually read */ n = recv(rptp_fd, ptr, nleft, MSG_PEEK); if (n < 0) { if (errno == EINTR) { continue; } rptp_errno = RPTP_ERROR_READ; return -1; } else if (n == 0) { rptp_errno = RPTP_ERROR_READ; return -1; } nleft -= n; for (i = 0; i < n; i++) { if (ptr[i] == '\r') { ptr[i] = '\0'; } else if (ptr[i] == '\n') { ptr[i] = '\0'; break; } } again: x = read(rptp_fd, tmp_buf, i == n ? n : i + 1); if (x < 0) { if (errno == EINTR) { goto again; } rptp_errno = RPTP_ERROR_READ; return -1; } else if (x == 0) { rptp_errno = RPTP_ERROR_READ; return -1; } else if (i < n) { return 0; } else { ptr += n; } } rptp_errno = RPTP_ERROR_READ; return -1; } /* * send the RPTP command to the RPTP connection storing the response in the * response buffer */ #ifdef __STDC__ int rptp_command(int rptp_fd, char *command, char *response, int response_size) #else int rptp_command(rptp_fd, command, response, response_size) int rptp_fd; char *command; char *response; int response_size; #endif { rptp_errno = RPTP_ERROR_NONE; if (rptp_putline(rptp_fd, command) < 0) { return -1; } if (rptp_getline(rptp_fd, response, response_size) < 0) { return -1; } switch (response[0]) { case RPTP_TIMEOUT: rptp_errno = RPTP_ERROR_TIMEOUT; return -1; case RPTP_ERROR: return 1; case RPTP_OK: case RPTP_NOTIFY: return 0; default: rptp_errno = RPTP_ERROR_PROTOCOL; return -1; } } /* * close the RPTP connection */ #ifdef __STDC__ int rptp_close(int rptp_fd) #else int rptp_close(rptp_fd) int rptp_fd; #endif { rptp_errno = RPTP_ERROR_NONE; close(rptp_fd); return 0; } /* * report RPTP errors */ #ifdef __STDC__ void rptp_perror(char *message) #else void rptp_perror(message) char *message; #endif { fprintf(stderr, "%s: %s\n", message, rptp_errlist[rptp_errno]); } /* * List definitions used in rptp_parse. */ typedef struct _list { struct _list *next; char *name; char *value; } LIST; static LIST *list = NULL, **list_next = &list; #define list_alloc() \ *list_next = (LIST *) malloc (sizeof(LIST)); \ if (!*list_next) \ { \ return NULL; \ } #define list_add(xname, xvalue) \ list_alloc(); \ (*list_next)->name = xname; \ (*list_next)->value = xvalue; \ list_next = &(*list_next)->next; \ *list_next = NULL; #define list_free() \ { \ LIST *l; \ for (; list; l = list, list = list->next, free ((char *)l)); \ list = NULL; \ list_next = &list; \ } #ifdef __STDC__ char * rptp_parse(char *response, char *name) #else char * rptp_parse(response, name) char *response; char *name; #endif { static char *buf; static LIST *list_pos, *cache_pos; /* No more name-value pairs. */ if (!response && !name && !list_pos) { return NULL; } /* Load the new `name=value' list. */ else if (response) { char *p; char *response_name = "", *response_value = ""; list_free(); if (buf) { free((char *) buf); } buf = strdup(response); p = buf; /* Skip any initial RPTP characters. */ switch (*p) { case RPTP_ERROR: case RPTP_OK: case RPTP_NOTIFY: p++; break; } while (p && *p) { /* Skip white-space. */ if (isspace(*p)) { for (p++; isspace(*p); p++) ; continue; } /* `name' */ response_name = p; p = strpbrk(p, "= \t\r\n"); /* `value' */ if (p && *p == '=') { int quoted = 0; *p++ = '\0'; /* Remove the `=' */ if (*p == '"') /* Start of a quoted value */ { p++; quoted++; } response_value = p; if (quoted) { p = strchr(p, '"'); } else { p = strpbrk(p, " \t\r\n"); } if (p) { *p++ = '\0'; } } else if (p) { *p++ = '\0'; } list_add(response_name, response_value); response_name = ""; response_value = ""; } list_pos = list; cache_pos = NULL; } /* Search for `name'. */ if (name) { LIST *l; char *p; /* Skip any leading dashes. */ while (*name == '-') { name++; } if (cache_pos) { for (p = cache_pos->name; *p && *p == '-'; p++) ; /* skip leading dashes */ if (strcmp(name, p) == 0) { return cache_pos->value; } } for (l = list; l; l = l->next) { for (p = l->name; *p && *p == '-'; p++) ; /* skip leading dashes */ if (strcmp(p, name) == 0) { return l->value; } } return NULL; /* Not found */ } /* Cycle through the names. */ else if (list_pos) { cache_pos = list_pos; list_pos = list_pos->next; return cache_pos->name; } return NULL; } rplay-3.3.2/perl/ 40755 153 62 0 6727650100 12165 5ustar boynsstaffrplay-3.3.2/perl/.Mailsounds100644 153 62 1321 6552756454 14415 0ustar boynsstaff## Mailing lists ^(To|Cc):.*ding.* sound=ding.au ^(To|Cc):.*xpilot.* sound=wheres_the_kaboom.au ^(To|Cc):.*gopher.* sound=monkey-3.au ^(To|Cc):.*fvwm.* sound=ploop.au ## People ^From garrett@?.* sound=Doh-echo.au ^From boyns@?.* sound=excellent.au ^From turtle@?.* sound=LookDone.au ^From Andrew@?.* sound=LookDone.au ^From andrew@?.* sound=LookDone.au ^From root@?.* sound=bogus.au ^From news@?.* sound=beep.au ## Things ^From [P|p]ostmaster@?.* sound=boooing.au ^From uucp@?.* sound=SynthHornsC3.au ^From MAILER@?.* sound=boooing.au ^From daemon@?.* sound=boooing.au ^From mailer@?.* sound=boooing.au ^From license@?.* sound=hallelujah.au ## Everything else... .* sound=Thank_you_very_much.au rplay-3.3.2/perl/Mailsound100755 153 62 4262 6600776021 14150 0ustar boynsstaff#!/usr/bin/perl # # $Id: Mailsound,v 1.3 1998/09/19 18:46:41 boyns Exp $ # # Copyright (C) 1993-98 Mark R. Boyns # # This file is part of rplay. # # rplay is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # rplay is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with rplay; see the file COPYING. If not, write to the # Free Software Foundation, Inc., # 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. # unshift (@INC, "/usr/local/lib"); use RPlay; use Getopt::Long; if ($ENV{'HOME'}) { $opt_file = "$ENV{'HOME'}/.Mailsounds"; } else { $opt_file = (getpwuid ($<))[7] . "/.Mailsounds"; } $opt_matches = 1; $opt_host = "localhost"; $opt_priority = undef; $opt_volume = undef; GetOptions ('file=s', 'host=s', 'priority=i', 'volume=i'); @patterns = (); @attributes = (); $matches = 0; $defaults{'priority'} = $opt_priority if defined $opt_priority; $defaults{'volume'} = $opt_volume if defined $opt_volume; open (CONF, $opt_file) || die "$opt_file: $!"; while () { next if (/^\#/ || /^[ \t\n]/); chop; ($pattern, $args) = split (/\t+/); push (@patterns, $pattern); local (%attrs) = %defaults; foreach (split (/[\t ]+/, $args)) { ($name, $value) = split ('='); $attrs{$name} = $value; } push (@attributes, \%attrs); } close (CONF); @lines = ; foreach $i (0 .. $#patterns) { foreach (@lines) { last if /^\n/; if (/$patterns[$i]/) { $hash_ref = $attributes[$i]; %attrs = %$hash_ref; $host = $attrs{'host'}; $host = $opt_host unless $host; foreach $h (split (':', $host)) { $rp = new RPlay; $rp->connect ($h); $rp->play ($hash_ref); $rp->disconnect (); } $matches++; last; } } last if $matches == $opt_matches; } exit 0; rplay-3.3.2/perl/Mailsound.1100644 153 62 3055 6600776326 14313 0ustar boynsstaff.TH MAILSOUND 1 9/19/98 .SH NAME Mailsound \- Play sounds when mail arrives .SH SYNOPSIS .B Mailsound [options] .SH DESCRIPTION Mailsound is an rplay utility used to play sounds when mail arrives. Different sounds can be played depending on the contents of mail message headers. Mailsound configuration is stored in the file .B ~/.Mailsounds. Each line in this file contains a perl5 regular expression followed by rplay attributes. See the EXAMPLE section below. .P Mailsound needs to be invoked upon mail arrival. This can be done in many ways, but most users will probably use either a .I .forward or .I .procmailrc file. With a .I .forward file, use something like: .nf \\yourusername, |"/usr/local/bin/Mailsound -h soundhostname" .fi For .I .procmailrc use: .nf :0 ic | /usr/local/bin/Mailsound -h doctor:doit .fi .SH OPTIONS .TP .I \-\-host=hostname[:hostname ...] Play sounds on the specifed host(s). .TP .I \-\-file=filename Specify an alternate configuration file. .TP .I \-\-volume=NUMBER Default volume for all sounds. .TP .I \-\-priority=NUMBER Default priority for all sounds. .SH EXAMPLE .nf ## Mailing lists ^(To|Cc):.*ding.* sound=ding.au volume=50 ^(To|Cc):.*xpilot.* sound=wheres_the_kaboom.au ^(To|Cc):.*gopher.* sound=monkey-3.au ^(To|Cc):.*fvwm.* sound=ploop.au ^From root@?.* sound=bogus.au priority=255 ^From news@?.* sound=beep.au ## Everything else... .* sound=Thank_you_very_much.au .SH FILES .B ~/.Mailsounds rplay-3.3.2/perl/RPTP.pm100644 153 62 13341 6672261101 13425 0ustar boynsstaff# $Id: RPTP.pm,v 1.2 1999/03/12 18:51:45 boyns Exp $ -*-perl-*- # # Copyright (C) 1993-98 Mark R. Boyns # # This file is part of rplay. # # rplay is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # rplay is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with rplay; see the file COPYING. If not, write to the # Free Software Foundation, Inc., # 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. # require "rplay.ph"; require 5.000; package RPTP; require "shellwords.pl"; use FileHandle; use Socket; use strict; ## Create a new RPlay object. sub new { my $self = {}; bless $self; $self->{debug} = 0; $self->{server} = (); $self->{callbacks} = (); $self->{socket} = undef; $self; } sub debug { my $self = shift; $self->{debug} = @_[0]; } ## Connect to a rplay server. sub connect { my $self = shift; my ($that_host, $that_port) = @_; my ($pat, $name, $aliases, $proto, $port, $udp); my (@bytes, $addrtype, $length, $old); my ($that, $that_addr); my ($this, $this_addr, $this_host); my $sockaddr = 'S n a4 x8'; ($name, $aliases, $proto) = getprotobyname ('tcp'); my $tcp = $proto; #($name, $aliases, $port, $proto) = getservbyname ('rplay', 'udp'); $that_port = &main::RPTP_PORT; chop ($this_host = `hostname`); ($name, $aliases, $addrtype, $length, $this_addr) = gethostbyname ($this_host); die "$this_host: unknown host\n" unless $name; ($name, $aliases, $addrtype, $length, $that_addr) = gethostbyname ($that_host); die "$that_host: unknown host\n" unless $name; $this = pack ($sockaddr, AF_INET, 0, $this_addr); $that = pack ($sockaddr, AF_INET, $that_port, $that_addr); $self->{socket} = new FileHandle; socket ($self->{socket}, AF_INET, SOCK_STREAM, $udp) || die "socket: $!"; connect ($self->{socket}, $that) || die "connect: $!"; $old = select ($self->{socket}); $| = 1; select ($old); my %hash = $self->readline(); foreach (keys %hash) { $self->{"server_$_"} = $hash{$_}; } } ## Close the rplay server connection. sub disconnect { my $self = shift; close ($self->{socket}); } sub server_info { my $self = shift; $self->{"server_".@_[0]}; } ## sub readline { my $self = shift; my %hash; my $sock = $self->{socket}; chomp(my $line = <$sock>); print "readline: $line\n" if $self->{debug}; my $type = substr($line, 0, 1); $hash{'_type'} = $type; $line = substr($line, 1); foreach (shellwords($line)) { my ($name, $value) = split('='); $hash{$name} = $value; } %hash; } ## sub writeline { my $self = shift; my $sock = $self->{socket}; print "writeline: ", join(" ", @_), "\n" if $self->{debug}; print $sock join(" ", @_), "\n"; } ## Convert different types arguments to a list of hash references. sub parse { my $self = shift; my ($r, @refs); $r = ref ($_[0]); if ($r eq "HASH") { @refs = @_; } elsif ($r eq "ARRAY") { foreach (@_) { my (%attr, $i, @list); @list = @$_; for ($i = 0; $i < $#list; $i+=2) { $attr{$list[$i]} = $list[$i+1]; } push (@refs, \%attr); } } else { my (%attr, $i); for ($i = 0; $i < $#_; $i+=2) { $attr{$_[$i]} = $_[$i+1]; } push (@refs, \%attr); } return @refs; } ## Create the appropriate RPLAY packet and send it to the server. sub doit { my $self = shift; my $command = shift; my @refs = $self->parse (@_); my (%attrs, $line); #die "Not connected - use connect() first." unless $connected; $line = "$command"; foreach (@refs) { %attrs = %$_; foreach (keys %attrs) { $line .= " $_=\"$attrs{$_}\""; } } die "Missing id or sound." unless $attrs{sound} or $attrs{id}; $self->writeline($line); } ## Play sounds. sub play { my $self = shift; $self->doit ("play", @_); } ## Pause sounds. sub pause { my $self = shift; $self->doit ("pause", @_); } ## Continue sounds. sub continue { my $self = shift; $self->doit ("continue", @_); } ## Stop sounds. sub stop { my $self = shift; $self->doit ("stop", @_); } ## Done sounds. sub done { my $self = shift; $self->doit ("done", @_); } # "continue" # "done" # "error" # "flow" # "level" # "modify" # "ok" # "pause" # "play" # "position" # "skip" # "stop" # "timeout" # "volume" sub notify { my $self = shift; my($type, $func) = @_; $self->{callbacks}{$type} = $func; } my %proto = ( "+" => "ok", "-" => "error", "!" => "timeout", "@" => "event" ); sub mainloop { my $self = shift; my $single = shift; if (!$self->{initialized}) { my $emask; foreach (keys %{$self->{callbacks}}) { next if /(ok|error|timeout|event)/; $emask .= "$_|"; } chop $emask; $self->writeline("set notify=$emask"); $self->{initialized} = 1; } for (;;) { my %hash = $self->readline(); my $type = $proto{$hash{_type}}; next if ($hash{command} eq "set"); my $func; if (exists($self->{callbacks}{all})) { $func = $self->{callbacks}{all}; } elsif (exists($self->{callbacks}{$type})) { $func = $self->{callbacks}{$type}; } else { $func = $self->{callbacks}{$hash{$type}}; } &$func(%hash) if $func; last if $single; } } 1; rplay-3.3.2/perl/RPlay.pm100644 153 62 13017 6727647572 13714 0ustar boynsstaff# $Id: RPlay.pm,v 1.4 1999/06/10 05:39:06 boyns Exp $ -*-perl-*- # # Copyright (C) 1993-98 Mark R. Boyns # # This file is part of rplay. # # rplay is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # rplay is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with rplay; see the file COPYING. If not, write to the # Free Software Foundation, Inc., # 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. # require "rplay.ph"; require 5.000; package RPlay; use Socket; $connected = 0; ## Create a new RPlay object. sub new { my $self = {}; bless $self; return $self; } ## Connect to a rplay server. sub connect { my $self = shift; my ($that_host, $that_port) = @_; my ($pat, $name, $aliases, $proto, $port, $udp); my (@bytes, $addrtype, $length, $old); my ($that, $that_addr, $that_addr); my ($this, $this_addr, $this_addr); $sockaddr = 'S n a4 x8'; ($name, $aliases, $proto) = getprotobyname ('udp'); $udp = $proto; ($name, $aliases, $port, $proto) = getservbyname ('rplay', 'udp'); if (!$that_port) { $that_port = $name ? $port : &main::RPLAY_PORT; } chop ($this_host = `hostname`); ($name, $aliases, $addrtype, $length, $this_addr) = gethostbyname ($this_host); die "$this_host: unknown host\n" unless $name; ($name, $aliases, $addrtype, $length, $that_addr) = gethostbyname ($that_host); die "$that_host: unknown host\n" unless $name; $this = pack ($sockaddr, AF_INET, 0, $this_addr); $that = pack ($sockaddr, AF_INET, $that_port, $that_addr); socket (RPLAY, AF_INET, SOCK_DGRAM, $udp) || die "socket: $!"; ## bind (RPLAY, $this) || die "bind: $!"; connect (RPLAY, $that) || die "connect: $!"; $old = select (RPLAY); $| = 1; select ($old); $connected = 1; } ## Close the rplay server connection. sub disconnect { my $self = shift; close (RPLAY); $connected = 0; } ## Convert different types arguments to a list of hash references. sub parse { my $self = shift; my ($r, @refs); $r = ref ($_[0]); if ($r eq "HASH") { @refs = @_; } elsif ($r eq "ARRAY") { foreach (@_) { my (%attr, $i, @list); @list = @$_; for ($i = 0; $i < $#list; $i+=2) { $attr{$list[$i]} = $list[$i+1]; } push (@refs, \%attr); } } else { my (%attr, $i); for ($i = 0; $i < $#_; $i+=2) { $attr{$_[$i]} = $_[$i+1]; } push (@refs, \%attr); } return @refs; } ## Create the appropriate RPLAY packet and send it to the server. sub doit { my $self = shift; my $command = shift; my @refs = $self->parse (@_); my (%attrs, $name, $packet, $data_size, $data); die "Not connected - use connect () first." unless $connected; ## Packet header. $packet = pack ("C", &main::RPLAY_PACKET_ID); $packet .= pack ("C", $command); ## Convert name-value hash pairs to RPLAY attributes. foreach (@refs) { %attrs = %$_; if (!$attrs{'sound'} && $command ne &main::RPLAY_PUT) { die "Missing `sound' attribute."; } foreach (keys %attrs) { if (/sound/) { $packet .= pack ("C", &main::RPLAY_SOUND); $packet .= "$attrs{$_}\0"; } elsif (/volume/) { $packet .= pack ("C", &main::RPLAY_VOLUME); $packet .= pack ("C", $attrs{$_}); } elsif (/list_count/) { $packet .= pack ("C", &main::RPLAY_LIST_COUNT); $packet .= pack ("C", $attrs{$_}); } elsif (/priority/) { $packet .= pack ("C", &main::RPLAY_PRIORITY); $packet .= pack ("C", $attrs{$_}); } elsif (/sample_rate/) { $packet .= pack ("C", &main::RPLAY_SAMPLE_RATE); $packet .= pack ("N", $attrs{$_}); } elsif (/list_name/) { $packet .= pack ("C", &main::RPLAY_LIST_NAME); $packet .= "$attrs{$_}\0"; } elsif (/id/) { $packet .= pack ("C", &main::RPLAY_ID); $packet .= pack ("N", $attrs{$_}); } elsif (/sequence/) { $packet .= pack ("C", &main::RPLAY_SEQUENCE); $packet .= pack ("N", $attrs{$_}); } elsif (/data_size/) { $data_size = $attrs{$_}; } elsif (/data/) { $data = $attrs{$_}; } else { #warn "Uknown attribute `$_'"; } } if ($data && $data_size) { $packet .= pack ("C", &main::RPLAY_DATA_SIZE); $packet .= pack ("n", $data_size); $packet .= pack ("C", &main::RPLAY_DATA); $packet .= $data; } $packet .= pack ("C", &main::RPLAY_NULL); } $packet .= pack ("C", &main::RPLAY_NULL); send (RPLAY, $packet, 0) || die "send: $!"; } ## Play sounds. sub play { my $self = shift; $self->doit (&main::RPLAY_PLAY, @_); } ## Pause sounds. sub pause { my $self = shift; $self->doit (&main::RPLAY_PAUSE, @_); } ## Continue sounds. sub continue { my $self = shift; $self->doit (&main::RPLAY_CONTINUE, @_); } ## Stop sounds. sub stop { my $self = shift; $self->doit (&main::RPLAY_STOP, @_); } ## Done sounds. sub done { my $self = shift; $self->doit (&main::RPLAY_DONE, @_); } sub put { my $self = shift; $self->doit (&main::RPLAY_PUT, @_); } 1; rplay-3.3.2/perl/example.pl100755 153 62 212 6552756454 14247 0ustar boynsstaff#!/usr/bin/perl use RPlay; $rp = new RPlay; $rp->connect ("localhost"); $rp->play ("sound" => "bogus.au"); $rp->disconnect (); exit 0; rplay-3.3.2/perl/rplay.ph100644 153 62 11753 6552756454 14010 0ustar boynsstaffif (!defined &_rplay_h) { #require 'sys/socket.ph'; eval 'sub FALSE {0;}'; eval 'sub TRUE {1;}'; eval 'sub RPLAY_PORT {5555;}'; eval 'sub RPTP_PORT {5556;}'; eval 'sub OLD_RPLAY_PORT {55555;}'; eval 'sub OLD_RPTP_PORT {55556;}'; eval 'sub RPLAY_PACKET_ID {30;}'; eval 'sub RPLAY_NULL {0;}'; eval 'sub RPLAY_PLAY {1;}'; eval 'sub RPLAY_STOP {2;}'; eval 'sub RPLAY_PAUSE {3;}'; eval 'sub RPLAY_CONTINUE {4;}'; eval 'sub RPLAY_SOUND {5;}'; eval 'sub RPLAY_VOLUME {6;}'; eval 'sub RPLAY_NSOUNDS {7;}'; eval 'sub RPLAY_COMMAND {8;}'; eval 'sub RPLAY_APPEND {9;}'; eval 'sub RPLAY_INSERT {10;}'; eval 'sub RPLAY_DELETE {11;}'; eval 'sub RPLAY_CHANGE {12;}'; eval 'sub RPLAY_COUNT {13;}'; eval 'sub RPLAY_LIST_COUNT {14;}'; eval 'sub RPLAY_PRIORITY {15;}'; eval 'sub RPLAY_RANDOM_SOUND {16;}'; eval 'sub RPLAY_PING {17;}'; eval 'sub RPLAY_RPTP_SERVER {18;}'; eval 'sub RPLAY_RPTP_SERVER_PORT {19;}'; eval 'sub RPLAY_RPTP_SEARCH {20;}'; eval 'sub RPLAY_RPTP_FROM_SENDER {21;}'; eval 'sub RPLAY_SAMPLE_RATE {22;}'; eval 'sub RPLAY_RESET {23;}'; eval 'sub RPLAY_DONE {24;}'; eval 'sub RPLAY_CLIENT_DATA {25;}'; eval 'sub RPLAY_LIST_NAME {26;}'; eval 'sub RPLAY_PUT {27;}'; eval 'sub RPLAY_ID {28;}'; eval 'sub RPLAY_SEQUENCE {29;}'; eval 'sub RPLAY_DATA {30;}'; eval 'sub RPLAY_DATA_SIZE {31;}'; eval 'sub RPLAY_FORMAT_NONE {0;}'; eval 'sub RPLAY_FORMAT_LINEAR_8 {1;}'; eval 'sub RPLAY_FORMAT_ULINEAR_8 {2;}'; eval 'sub RPLAY_FORMAT_LINEAR_16 {3;}'; eval 'sub RPLAY_FORMAT_ULINEAR_16 {4;}'; eval 'sub RPLAY_FORMAT_ULAW {5;}'; eval 'sub RPLAY_FORMAT_G721 {6;}'; eval 'sub RPLAY_FORMAT_G723_3 {7;}'; eval 'sub RPLAY_FORMAT_G723_5 {8;}'; eval 'sub RPLAY_FORMAT_GSM {9;}'; eval 'sub RPLAY_BIG_ENDIAN {1;}'; eval 'sub RPLAY_LITTLE_ENDIAN {2;}'; eval 'sub RPLAY_AUDIO_PORT_NONE {(1<<0);}'; eval 'sub RPLAY_AUDIO_PORT_SPEAKER {(1<<1);}'; eval 'sub RPLAY_AUDIO_PORT_HEADPHONE {(1<<2);}'; eval 'sub RPLAY_AUDIO_PORT_LINEOUT {(1<<3);}'; eval 'sub RPLAY_MIN_VOLUME {0;}'; eval 'sub RPLAY_MAX_VOLUME {255;}'; eval 'sub RPLAY_MIN_PRIORITY {0;}'; eval 'sub RPLAY_MAX_PRIORITY {255;}'; eval 'sub RPLAY_DEFAULT_VOLUME {127;}'; eval 'sub RPLAY_DEFAULT_PRIORITY {0;}'; eval 'sub RPLAY_DEFAULT_COUNT {1;}'; eval 'sub RPLAY_DEFAULT_LIST_COUNT {1;}'; eval 'sub RPLAY_DEFAULT_RANDOM_SOUND {-1;}'; eval 'sub RPLAY_DEFAULT_SAMPLE_RATE {0;}'; eval 'sub RPLAY_DEFAULT_OFFSET {0;}'; eval 'sub RPLAY_DEFAULT_BYTE_ORDER {0;}'; eval 'sub RPLAY_DEFAULT_CHANNELS {0;}'; eval 'sub RPLAY_DEFAULT_BITS {0;}'; eval 'sub RPLAY_ERROR_NONE {0;}'; eval 'sub RPLAY_ERROR_MEMORY {1;}'; eval 'sub RPLAY_ERROR_HOST {2;}'; eval 'sub RPLAY_ERROR_CONNECT {3;}'; eval 'sub RPLAY_ERROR_SOCKET {4;}'; eval 'sub RPLAY_ERROR_WRITE {5;}'; eval 'sub RPLAY_ERROR_CLOSE {6;}'; eval 'sub RPLAY_ERROR_PACKET_SIZE {7;}'; eval 'sub RPLAY_ERROR_BROADCAST {8;}'; eval 'sub RPLAY_ERROR_ATTRIBUTE {9;}'; eval 'sub RPLAY_ERROR_COMMAND {10;}'; eval 'sub RPLAY_ERROR_INDEX {11;}'; eval 'sub RPLAY_ERROR_MODIFIER {12;}'; eval 'sub RPTP_ERROR_NONE {0;}'; eval 'sub RPTP_ERROR_MEMORY {1;}'; eval 'sub RPTP_ERROR_HOST {2;}'; eval 'sub RPTP_ERROR_CONNECT {3;}'; eval 'sub RPTP_ERROR_SOCKET {4;}'; eval 'sub RPTP_ERROR_OPEN {5;}'; eval 'sub RPTP_ERROR_READ {6;}'; eval 'sub RPTP_ERROR_WRITE {7;}'; eval 'sub RPTP_ERROR_PING {8;}'; eval 'sub RPTP_ERROR_TIMEOUT {9;}'; eval 'sub RPTP_ERROR_PROTOCOL {10;}'; eval 'sub RPTP_ERROR {ord(\'-\');}'; eval 'sub RPTP_OK {ord(\'+\');}'; eval 'sub RPTP_TIMEOUT {ord(\'!\');}'; eval 'sub RPTP_NOTIFY {ord(\'@\');}'; eval 'sub OLD_RPLAY_PLAY {1;}'; eval 'sub OLD_RPLAY_STOP {2;}'; eval 'sub OLD_RPLAY_PAUSE {3;}'; eval 'sub OLD_RPLAY_CONTINUE {4;}'; eval 'sub RPTP_ASYNC_READ {1;}'; eval 'sub RPTP_ASYNC_WRITE {2;}'; eval 'sub RPTP_ASYNC_RAW {4;}'; eval 'sub RPTP_ASYNC_ENABLE {1;}'; eval 'sub RPTP_ASYNC_DISABLE {2;}'; eval 'sub RPTP_EVENT_OK {(1 << 0);}'; eval 'sub RPTP_EVENT_ERROR {(1 << 1);}'; eval 'sub RPTP_EVENT_TIMEOUT {(1 << 2);}'; eval 'sub RPTP_EVENT_OTHER {(1 << 3);}'; eval 'sub RPTP_EVENT_CONTINUE {(1 << 4);}'; eval 'sub RPTP_EVENT_DONE {(1 << 5);}'; eval 'sub RPTP_EVENT_PAUSE {(1 << 6);}'; eval 'sub RPTP_EVENT_PLAY {(1 << 7);}'; eval 'sub RPTP_EVENT_SKIP {(1 << 8);}'; eval 'sub RPTP_EVENT_STATE {(1 << 9);}'; eval 'sub RPTP_EVENT_STOP {(1 << 10);}'; eval 'sub RPTP_EVENT_VOLUME {(1 << 11);}'; eval 'sub RPTP_EVENT_CLOSE {(1 << 12);}'; eval 'sub RPTP_EVENT_FLOW {(1 << 13);}'; eval 'sub RPTP_EVENT_MODIFY {(1 << 14);}'; eval 'sub RPTP_EVENT_LEVEL {(1 << 15);}'; eval 'sub RPTP_EVENT_POSITION {(1 << 16);}'; eval 'sub RPTP_EVENT_ALL {0x0000ffff;}'; eval 'sub RPTP_MAX_LINE {1024;}'; eval 'sub RPTP_MAX_ARGS {32;}'; } 1; rplay-3.3.2/rplay/ 40755 153 62 0 6727650100 12352 5ustar boynsstaffrplay-3.3.2/rplay/Makefile.in100644 153 62 2014 6675040411 14511 0ustar boynsstaffinclude @RPLAY_TOP@/Makefile.config srcdir = @srcdir@ VPATH = @srcdir@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ MKINSTALLDIRS= @srcdir@/../mkinstalldirs CPPFLAGS= $(CC_OPTIONS) -I. -I../include -I@srcdir@/../include -I@srcdir@/../lib @DEFS@ .c.o: $(CC) -c $(CPPFLAGS) $(CFLAGS) $< LDFLAGS= $(LD_OPTIONS) -L../librplay -lrplay -L../lib -lrp @LDFLAGS@ @LIBS@ TARGET= rplay SRCS= rplay.c OBJS= rplay.o all: $(TARGET) $(TARGET): $(OBJS) ../librplay/$(LIBRPLAY_NAME) ../lib/librp.a $(CC) -o $@ $(OBJS) $(LDFLAGS) ../librplay/$(LIBRPLAY_NAME): (cd ../librplay; $(MAKE) $(MFLAGS)) ../lib/librp.a: (cd ../lib; $(MAKE) $(MFLAGS)) install: all $(MKINSTALLDIRS) $(bindir) $(INSTALL_PROGRAM) $(TARGET) $(bindir)/$(TARGET) uninstall: $(RM) $(bindir)/$(TARGET) clean: $(RM) $(OBJS) $(TARGET) a.out core *~ *.bak *.orig TAGS distclean: clean $(RM) Makefile tags: $(TAGS) *.[ch] TAGS: tags etags: tags depend: $(MAKEDEPEND) -- $(CPPFLAGS) $(CFLAGS) -- $(SRCS) rplay-3.3.2/rplay/rplay.c100644 153 62 53736 6671423007 14002 0ustar boynsstaff/* $Id: rplay.c,v 1.8 1999/03/10 07:57:59 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #ifdef HAVE_STRING_H #include #endif #include #include "rplay.h" #include "getopt.h" #undef DEBUG #define OPTIONS "+spcN:P:h:rv:n:R:b:i:" struct option longopts[] = { {"continue", no_argument, NULL, 'c'}, {"count", required_argument, NULL, 'n'}, {"flow", required_argument, NULL, 14}, {"help", no_argument, NULL, 3}, {"host", required_argument, NULL, 'h'}, {"hosts", required_argument, NULL, 'h'}, {"info", required_argument, NULL, 'i'}, {"info-amd", no_argument, NULL, 8}, {"info-ulaw", no_argument, NULL, 8}, {"info-cs4231", no_argument, NULL, 10}, {"info-dbri", no_argument, NULL, 9}, {"info-gsm", no_argument, NULL, 13}, {"info-cd", no_argument, NULL, 15}, {"buffer-size", required_argument, NULL, 'b'}, {"list-count", required_argument, NULL, 'N'}, {"list-name", required_argument, NULL, 7}, {"pause", no_argument, NULL, 'p'}, {"port", required_argument, NULL, 4}, {"priority", required_argument, NULL, 'P'}, {"random", no_argument, NULL, 'r'}, {"reset", no_argument, NULL, 5}, {"rplay", no_argument, NULL, 11}, {"RPLAY", no_argument, NULL, 11}, {"rptp", no_argument, NULL, 12}, {"RPTP", no_argument, NULL, 12}, {"sample-rate", required_argument, NULL, 'R'}, {"stop", no_argument, NULL, 's'}, {"version", no_argument, NULL, 2}, {"volume", required_argument, NULL, 'v'}, {NULL, 0, NULL, 0} }; #define PROTOCOL_GUESS 0 #define PROTOCOL_RPLAY 1 #define PROTOCOL_RPTP 2 #define BUFFER_SIZE 8196 #ifdef __STDC__ typedef int (*PLAY_FUNC) (int, char *, int, RPLAY *, int); #else typedef int (*PLAY_FUNC) (); #endif void doit(), play(), usage(), interrupt(); int server_has_sound(); char *info2str(); int play_with_flow(), play_with_play(); RPLAY *rp; char cwd[MAXPATHLEN]; int interrupted = 0; int which_protocol = PROTOCOL_GUESS; int which_port = -1; int buffer_size = BUFFER_SIZE; #ifdef __STDC__ main(int argc, char **argv) #else main(argc, argv) int argc; char **argv; #endif { int i, n, c, command, volume, val; int list_count, count, priority, do_random; unsigned long sample_rate; char *hosts, *name, *list_name, *sound_info = ""; int optind_val = optind; char buf[RPTP_MAX_LINE]; extern char *optarg; extern int optind, opterr; if (argc < 2) { usage(); } signal(SIGPIPE, SIG_IGN); if (getcwd(cwd, sizeof(cwd)) == NULL) { cwd[0] = '\0'; } command = RPLAY_PLAY; list_count = RPLAY_DEFAULT_LIST_COUNT; list_name = NULL; priority = RPLAY_DEFAULT_PRIORITY; do_random = 0; hosts = rplay_default_host(); name = NULL; sample_rate = RPLAY_DEFAULT_SAMPLE_RATE; volume = RPLAY_DEFAULT_VOLUME; count = RPLAY_DEFAULT_COUNT; /* First scan the args to see what the command is. */ opterr = 0; /* disable getopt errors */ while ((c = getopt_long(argc, argv, OPTIONS, longopts, 0)) != -1) { switch (c) { case 2: /* --version */ printf("rplay %s\n", RPLAY_VERSION); exit(0); case 3: /* --help */ usage(); case 5: /* --reset */ if (command != RPLAY_PLAY) { usage(); } command = RPLAY_RESET; break; case 's': if (command != RPLAY_PLAY) { usage(); } command = RPLAY_STOP; break; case 'p': if (command != RPLAY_PLAY) { usage(); } command = RPLAY_PAUSE; break; case 'c': if (command != RPLAY_PLAY) { usage(); } command = RPLAY_CONTINUE; break; } } opterr = 1; /* enable getopt errors */ optind = optind_val; /* reset optind */ /* Create the RPLAY object. */ rp = rplay_create(command); if (rp == NULL) { rplay_perror("rplay_create"); exit(1); } /* Build a list of sounds to be played along with their attributes. */ while (argc > 1) { while ((c = getopt_long(argc, argv, OPTIONS, longopts, 0)) != -1) { switch (c) { case 0: /* getopt has processed a long-named option -- do nothing */ break; case 1: break; case 2: /* --version */ printf("rplay %s\n", RPLAY_VERSION); exit(0); case 3: /* --help */ usage(); case 4: /* --port */ which_port = atoi(optarg); break; case 5: /* --reset */ case 's': case 'p': case 'c': break; case 7: /* --list-name */ list_name = optarg; break; case 8: /* --info-amd, --info-ulaw */ /* Sun's amd audio device. */ sound_info = "ulaw,8000,8,1,big-endian,0"; break; case 9: /* --info-dbri */ /* Sun's dbri audio device. */ sound_info = "linear16,11025,16,1,big-endian,0"; break; case 10: /* --info-cs4231 */ /* Sun's CS4231 audio device. */ sound_info = "linear16,11025,16,1,big-endian,0"; break; case 11: /* --rplay */ which_protocol = PROTOCOL_RPLAY; break; case 12: /* --rptp */ which_protocol = PROTOCOL_RPTP; break; case 13: /* --info-gsm */ /* GSM encoded u-law files */ sound_info = "gsm,8000"; break; case 15: /* --info-cd */ /* cd quality */ sound_info = "linear16,44100,16,2,little-endian"; break; case 'N': list_count = atoi(optarg); break; case 'P': priority = atoi(optarg); break; case 'r': do_random++; break; case 'h': hosts = optarg; break; case 'v': volume = atoi(optarg); break; case 'n': count = atoi(optarg); break; case 'R': sample_rate = atoi(optarg); break; case 'i': sound_info = optarg; break; case 'b': buffer_size = atoi(optarg); break; default: fprintf(stderr, "Try `rplay --help' for more information.\n"); exit(1); } } if (argc == optind) { if (command == RPLAY_PLAY) { usage(); } name = "#0"; } /* Convert relative file names to absolute. */ else if ((*(argv[optind]) != '/') && (strchr(argv[optind], '/'))) { if (*cwd) { name = (char *) malloc(strlen(cwd) + strlen(argv[optind]) + 2); strcpy(name, cwd); strcat(name, "/"); if (strncmp(argv[optind], "./", 2) == 0) { strcat(name, argv[optind] + 2); } else { strcat(name, argv[optind]); } } else { name = argv[optind]; } } else { name = argv[optind]; } argv += optind; argc -= optind; optind = optind_val; if (rplay_set(rp, RPLAY_LIST_COUNT, list_count, NULL) < 0) { rplay_perror("rplay_set"); exit(1); } if (rplay_set(rp, RPLAY_PRIORITY, priority, NULL) < 0) { rplay_perror("rplay_set"); exit(1); } if (list_name && rplay_set(rp, RPLAY_LIST_NAME, list_name, NULL) < 0) { rplay_perror("rplay_set"); exit(1); } val = rplay_set(rp, RPLAY_APPEND, RPLAY_SOUND, name, RPLAY_VOLUME, volume, RPLAY_COUNT, count, RPLAY_SAMPLE_RATE, sample_rate, RPLAY_CLIENT_DATA, sound_info, NULL); if (val < 0) { rplay_perror("rplay_set"); exit(1); } } /* Pick the random sound. */ if (do_random) { val = rplay_set(rp, RPLAY_RANDOM_SOUND, NULL); if (val < 0) { rplay_perror("rplay_set"); exit(1); } } doit(hosts); exit(0); } #ifdef __STDC__ void doit(char *hostp) #else void doit(hostp) char *hostp; #endif { PLAY_FUNC *play_table; char *host; play_table = (PLAY_FUNC *) malloc(rplay_get(rp, RPLAY_NSOUNDS) * sizeof(PLAY_FUNC)); if (play_table == NULL) { fprintf(stderr, "rplay: out of memory\n"); exit(1); } /* Cycle through each colon-separated host. */ do { int protocol, port; int rplay_fd = -1; host = hostp; hostp = strchr(host, ':'); if (hostp != NULL) { *hostp++ = '\0'; } /* Determine which protocol to use. */ if (rplay_get(rp, RPLAY_COMMAND) != RPLAY_PLAY) { protocol = PROTOCOL_RPLAY; } else if (strcmp((char *) rplay_get(rp, RPLAY_SOUND, 0), "-") == 0) { protocol = PROTOCOL_RPTP; play_table[0] = play_with_flow; } else if (which_protocol == PROTOCOL_GUESS) { char response[RPTP_MAX_LINE]; rplay_fd = rptp_open(host, RPTP_PORT, response, sizeof(response)); if (rplay_fd < 0) { protocol = PROTOCOL_RPLAY; } else { int i, n, sounds_not_found = 0; char *sound_name; /* Count the number of sounds the server doesn't have */ n = (int) rplay_get(rp, RPLAY_NSOUNDS); for (i = 0; i < n; i++) { struct stat st; sound_name = (char *) rplay_get(rp, RPLAY_SOUND, i); if (stat(sound_name, &st) < 0) { st.st_size = 0; } if (!server_has_sound(rplay_fd, sound_name, (int) st.st_size)) { if (st.st_size) { play_table[i] = play_with_flow; sounds_not_found++; } else { /* Assume the server can get the sound from another server. */ play_table[i] = play_with_play; } } else { play_table[i] = play_with_play; } } /* XXX is this right??? should they be switched?? */ if (sounds_not_found > 0) { protocol = PROTOCOL_RPTP; } else { protocol = PROTOCOL_RPLAY; } } } /* Allow the protocol choice to be overridden. */ if (which_protocol != PROTOCOL_GUESS && rplay_get(rp, RPLAY_COMMAND) == RPLAY_PLAY) { int i, n; protocol = which_protocol; n = (int) rplay_get(rp, RPLAY_NSOUNDS); for (i = 0; i < n; i++) { play_table[i] = (protocol == PROTOCOL_RPTP) ? play_with_flow : play_with_play; } } port = which_port; if (port == -1) { switch (protocol) { case PROTOCOL_RPLAY: port = RPLAY_PORT; break; case PROTOCOL_RPTP: port = RPTP_PORT; break; } } switch (protocol) { case PROTOCOL_RPTP: play(rplay_fd, host, port, rp, play_table); break; case PROTOCOL_RPLAY: if (rplay_fd != -1) { rptp_close(rplay_fd); } rplay_fd = rplay_open_port(host, port); if (rplay_fd < 0) { rplay_perror(host); exit(1); } if (rplay(rplay_fd, rp) < 0) { rplay_perror(host); exit(1); } rplay_close(rplay_fd); break; default: fprintf(stderr, "unknown protocol\n"); exit(1); } } while (hostp != NULL); } #ifdef __STDC__ int server_has_sound(int rplay_fd, char *sound_name, int size) #else int server_has_sound(rplay_fd, sound_name, size) int rplay_fd; char *sound_name; int size; #endif { char command[RPTP_MAX_LINE]; char response[RPTP_MAX_LINE]; char *p; int try; int remote_size; for (try = 0; try < 2; try++) { if (try == 0) { sprintf(command, "info sound=%s", sound_name); } else { sprintf(command, "info sound=%s/%s", cwd, sound_name); } if (rptp_command(rplay_fd, command, response, sizeof(response)) < 0) { return 0; } remote_size = -1; p = rptp_parse(response, "size"); if (p) remote_size = atoi(p); if (remote_size != -1 && (size == 0 || remote_size == 0 || size == remote_size)) { return 1; } } return 0; } #ifdef __STDC__ void play(int rplay_fd, char *host, int port, RPLAY *rp, PLAY_FUNC *play_table) #else void play(rplay_fd, rp, play_table) int rplay_fd; RPLAY *rp; PLAY_TABLE *play_table; #endif { int i, n; char response[RPTP_MAX_LINE]; n = rplay_get(rp, RPLAY_NSOUNDS); for (i = 0; i < n; i++) { if (rplay_fd < 0) { rplay_fd = rptp_open(host, port, response, sizeof(response)); } if (rplay_fd < 0) { rptp_perror(host); continue; } if ((*play_table[i]) (rplay_fd, host, port, rp, i) < 0) { rptp_close(rplay_fd); rplay_fd = -1; } } } #ifdef __STDC__ int play_with_play(int rplay_fd, char *host, int port, RPLAY *rp, int index) #else int play_with_play(rplay_fd, host, port, rp, index) int rplay_fd; char *host; int port; RPLAY *rp; int index; #endif { int n, spool_id; char response[RPTP_MAX_LINE]; /* Enable `done' notification. */ rptp_putline(rplay_fd, "set notify=done,position notify-rate=1.0"); rptp_getline(rplay_fd, response, sizeof(response)); /* Play the sound. */ rptp_putline(rplay_fd, "play priority=%d sample-rate=%d volume=%d list-name=\"%s\" sound=\"%s\"", (int) rplay_get(rp, RPLAY_PRIORITY, index), (int) rplay_get(rp, RPLAY_SAMPLE_RATE, index), (int) rplay_get(rp, RPLAY_VOLUME, index), rplay_get(rp, RPLAY_LIST_NAME) ? (char *) rplay_get(rp, RPLAY_LIST_NAME) : "", (int) rplay_get(rp, RPLAY_SOUND, index)); n = rptp_getline(rplay_fd, response, sizeof(response)); if (n < 0 || response[0] != RPTP_OK) { fprintf(stderr, "rplay: can't play `%s'\n", (int) rplay_get(rp, RPLAY_SOUND, index)); return -1; } /* Grab the spool id. */ spool_id = atoi(1 + rptp_parse(response, "id")); /* Wait for the sound to finish playing. */ signal(SIGINT, interrupt); interrupted = 0; for (;;) { n = rptp_getline(rplay_fd, response, sizeof(response)); if (interrupted) { break; } if (n < 0) { return -1; } else if (response[0] != RPTP_NOTIFY) { fprintf(stderr, "rplay: %s\n", response + 1); break; } rptp_parse(response, NULL); if (strcmp(rptp_parse(NULL, "event"), "done") == 0 && atoi(1 + rptp_parse(NULL, "id")) == spool_id) { break; } } signal(SIGINT, SIG_DFL); /* Eat any events and turn off notification. */ rptp_putline(rplay_fd, "set notify=none"); for (;;) { n = rptp_getline(rplay_fd, response, sizeof(response)); if (n < 0) { return -1; } else if (response[0] == RPTP_OK || response[0] == RPTP_ERROR) { break; } } return 0; } #ifdef __STDC__ int play_with_flow(int rplay_fd, char *host, int port, RPLAY *rp, int index) #else int play_with_flow(rplay_fd, host, port, rp, index) int rplay_fd; char *host; int port; RPLAY *rp; int index; #endif { char *sound_name = (char *) rplay_get(rp, RPLAY_SOUND, index); char *sound_info = (char *) rplay_get(rp, RPLAY_CLIENT_DATA, index); char command[RPTP_MAX_LINE]; char response[RPTP_MAX_LINE]; char *buffer; int spool_id, n, fd, flow_fd; if (strcmp(sound_name, "-") == 0) { fd = 0; } else { fd = open(sound_name, O_RDONLY, 0); if (fd < 0) { fprintf(stderr, "rplay: sound `%s' not found\n", sound_name); return 0; } } /* Open a connection for the flow. */ flow_fd = rptp_open(host, port, response, sizeof(response)); if (flow_fd < 0) { rptp_perror(host); return -1; } /* Enable `done' notification. */ rptp_putline(rplay_fd, "set notify=done"); rptp_getline(rplay_fd, response, sizeof(response)); /* Send the flow play command. */ rptp_putline(flow_fd, "play input=flow %s priority=%d sample-rate=%d volume=%d list-name=\"%s\" sound=\"%s\"", info2str(sound_info), (int) rplay_get(rp, RPLAY_PRIORITY, index), (int) rplay_get(rp, RPLAY_SAMPLE_RATE, index), (int) rplay_get(rp, RPLAY_VOLUME, index), rplay_get(rp, RPLAY_LIST_NAME) ? (char *) rplay_get(rp, RPLAY_LIST_NAME) : "", strcmp(sound_name, "-") ? sound_name : "stdin"); n = rptp_getline(flow_fd, response, sizeof(response)); if (n < 0 || response[0] != RPTP_OK) { fprintf(stderr, "rplay: can't play `%s'\n", (int) rplay_get(rp, RPLAY_SOUND, index)); return -1; } /* Grab the spool id. */ spool_id = atoi(1 + rptp_parse(response, "id")); /* Send the put command. */ rptp_putline(flow_fd, "put id=#%d size=0", spool_id); n = rptp_getline(flow_fd, response, sizeof(response)); if (n < 0 || response[0] != RPTP_OK) { fprintf(stderr, "rplay: can't play `%s'\n", (int) rplay_get(rp, RPLAY_SOUND, index)); return -1; } /* Allocate the buffer. */ buffer = (char *) malloc(buffer_size); if (buffer == NULL) { fprintf(stderr, "rplay: out of memory\n"); exit(1); } signal(SIGINT, interrupt); interrupted = 0; for (;;) { if (interrupted) { break; } n = read(fd, buffer, buffer_size); if (n <= 0) { break; } if (rptp_write(flow_fd, buffer, n) != n) { break; } } close(fd); /*sleep (1); */ rptp_close(flow_fd); /* Wait for the sound to finish. */ for (;;) { n = rptp_getline(rplay_fd, response, sizeof(response)); if (interrupted) { break; } if (n < 0) { return -1; } else if (response[0] != RPTP_NOTIFY) { fprintf(stderr, "rplay: %s\n", response + 1); break; } else if (atoi(1 + rptp_parse(response, "id")) == spool_id) { break; } } signal(SIGINT, SIG_DFL); /* Eat any events and turn off notification. */ rptp_putline(rplay_fd, "set notify=none"); for (;;) { n = rptp_getline(rplay_fd, response, sizeof(response)); if (n < 0) { return -1; } else if (response[0] == RPTP_OK || response[0] == RPTP_ERROR) { break; } } return 0; } #ifdef __STDC__ char * info2str(char *sound_info) #else char * info2str(sound_info) char *sound_info; #endif { static char str[1024]; str[0] = '\0'; if (sound_info && *sound_info) { char buf[1024]; char *p; strcpy(buf, sound_info); /* Example: ulaw,8000,8,1,big-endian,offset */ p = strtok(buf, ", "); if (p) sprintf(str + strlen(str), "input-format=%s ", p); p = strtok(NULL, ", "); if (p) sprintf(str + strlen(str), "input-sample-rate=%s ", p); p = strtok(NULL, ", "); if (p) sprintf(str + strlen(str), "input-bits=%s ", p); p = strtok(NULL, ", "); if (p) sprintf(str + strlen(str), "input-channels=%s ", p); p = strtok(NULL, ", "); if (p) sprintf(str + strlen(str), "input-byte-order=%s ", p); p = strtok(NULL, ", "); if (p) sprintf(str + strlen(str), "input-offset=%s ", p); } return str; } void interrupt() { interrupted++; fprintf(stderr, "rplay: *interrupt*\n"); } void usage() { printf("\nrplay %s\n\n", RPLAY_VERSION); printf("usage: rplay [options] [sound ... ]\n\n"); printf("-b BYTES, --buffer-size=BYTES\n"); printf("\tUse of a buffer size of BYTES when playing sounds using RPTP flows.\n"); printf("\tThe default is 8K.\n"); printf("\n"); printf("-c, --continue\n"); printf("\tContinue sounds.\n"); printf("\n"); printf("-n N, --count=N\n"); printf("\tNumber of times to play the sound, default = %d.\n", RPLAY_DEFAULT_COUNT); printf("\n"); printf("-N N, --list-count=N\n"); printf("\tNumber of times to play all the sounds, default = %d.\n", RPLAY_DEFAULT_LIST_COUNT); printf("\n"); printf("--list-name=NAME\n"); printf("\tName this list NAME. rplayd appends sounds with the same\n"); printf("\tNAME into the same sound list -- it plays them sequentially.\n"); printf("\n"); printf("--help\n"); printf("\tDisplay helpful information.\n"); printf("\n"); printf("-h HOST, --host=HOST, --hosts=HOST\n"); printf("\tSpecify the rplay host, default = %s.\n", rplay_default_host()); printf("\n"); printf("-i INFO, --info=INFO\n"); printf("\tAudio information for a sound file. This option is intended\n"); printf("\tto be used when sounds are read from standard input.\n"); printf("\tINFO must be of the form:\n"); printf("\t `format,sample-rate,bits,channels,byte-order,offset'\n"); printf("\tExamples: ulaw,8000,8,1,big-endian,0\n"); printf("\t gsm,8000\n"); printf("\tShorthand info is provided for Sun's audio devices using the\n"); printf("\tfollowing options: --info-amd, --info-dbri, --info-cs4231.\n"); printf("\tThere's also: --info-ulaw and --info-gsm.\n"); printf("\n"); printf("-p, --pause\n"); printf("\tPause sounds.\n"); printf("\n"); printf("--port=PORT\n"); printf("\tUse PORT instead of the default RPLAY/UDP or RPTP/TCP port.\n"); printf("\n"); printf("-P N, --priority=N\n"); printf("\tPlay sounds at priority N (%d <= N <= %d), default = %d.\n", RPLAY_MIN_PRIORITY, RPLAY_MAX_PRIORITY, RPLAY_DEFAULT_PRIORITY); printf("\n"); printf("-r, --random\n"); printf("\tRandomly choose one of the given sounds.\n"); printf("\n"); printf("--reset\n"); printf("\tTell the server to reset itself.\n"); printf("\n"); printf("--rplay, --RPLAY\n"); printf("\tForce the use of the RPLAY protocol.\n"); printf("\ \tThe default protocol to be used is determined by checking whether or not\n\ \tthe server has local access to the specified sounds. RPLAY is used when\n\ \tsounds are accessible, otherwise RPTP and possibly flows are used.\n\ \tRPLAY will also be used when sound accessibility cannot be determined.\n"); printf("\n"); printf("--rptp, --RPTP\n"); printf("\tForce the use of the RPTP protocol.\n"); printf("\tSee `--rplay' for more information about protocols.\n"); printf("\n"); printf("-R N, --sample-rate=N\n"); printf("\tPlay sounds at sample rate N, default = %d.\n", RPLAY_DEFAULT_SAMPLE_RATE); printf("\n"); printf("-s, --stop\n"); printf("\tStop sounds.\n"); printf("\n"); printf("--version\n"); printf("\tPrint the rplay version and exit.\n"); printf("\n"); printf("-v N, --volume=N\n"); printf("\tPlay sounds at volume N (%d <= N <= %d), default = %d.\n", RPLAY_MIN_VOLUME, RPLAY_MAX_VOLUME, RPLAY_DEFAULT_VOLUME); exit(1); } rplay-3.3.2/rplayd/ 40755 153 62 0 6727650100 12516 5ustar boynsstaffrplay-3.3.2/rplayd/Makefile.in100644 153 62 3753 6727404537 14703 0ustar boynsstaffinclude @RPLAY_TOP@/Makefile.config srcdir = @srcdir@ VPATH = @srcdir@ sysconfdir = @sysconfdir@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ MKINSTALLDIRS= @srcdir@/../mkinstalldirs CPPFLAGS = $(CC_OPTIONS) -I. -I../include -I${srcdir} -I${srcdir}/../include \ -I${srcdir}/../lib -I${srcdir}/../adpcm \ @GSM_INCS@ \ @RX_INCS@ @DEFS@ \ -DRPLAY_CONF=\"${sysconfdir}/rplay.conf\" \ -DRPLAY_HOSTS=\"${sysconfdir}/rplay.hosts\" \ -DRPLAY_SERVERS=\"${sysconfdir}/rplay.servers\" \ -DRPLAY_HELPERS=\"${sysconfdir}/rplay.helpers\" \ -DRPLAY_CACHE=\"/tmp/.rplay-cache\" \ -DRPLAY_LOG=\"/tmp/rplay.log\" \ -DRPLAYDRC=\"\~/.rplaydrc\" .c.o: $(CC) -c $(CPPFLAGS) $(CFLAGS) $< LDFLAGS= $(LD_OPTIONS) -L../librplay -lrplay -L../lib -lrp \ -L../adpcm -ladpcm @GSM_LIBS@ -L../rx -lrx @LDFLAGS@ @LIBS@ -lm TARGET= rplayd SRCS= audio.c buffer.c cache.c cdrom.c command.c connection.c flange.c \ helper.c host.c misc.c native.c rplayd.c server.c sound.c \ spool.c timer.c ulaw.c xhash.c OBJS= audio.o buffer.o cache.o cdrom.o command.o connection.o flange.o \ helper.o host.o misc.o native.o rplayd.o server.o sound.o \ spool.o timer.o ulaw.o xhash.o all: $(TARGET) $(TARGET): $(OBJS) ../librplay/$(LIBRPLAY_NAME) ../lib/librp.a ../adpcm/libadpcm.a $(CC) -o $@ $(OBJS) $(LDFLAGS) ../librplay/$(LIBRPLAY_NAME): (cd ../librplay; $(MAKE) $(MFLAGS)) ../lib/librp.a: (cd ../lib; $(MAKE) $(MFLAGS)) ../adpcm/libadpcm.a: (cd ../adpcm; $(MAKE) $(MFLAGS)) install: all $(MKINSTALLDIRS) $(sbindir) $(INSTALL_PROGRAM) $(TARGET) $(sbindir)/$(TARGET) @test -x $(bindir)/$(TARGET) && echo "" && echo " Note: Consider removing $(bindir)/$(TARGET)" && echo "" uninstall: $(RM) $(bindir)/$(TARGET) clean: $(RM) $(OBJS) $(TARGET) a.out core *~ *.bak *.orig TAGS cd audio; $(RM) *~ *.bak *.orig distclean: clean $(RM) Makefile audio.c audio.h tags: $(TAGS) *.[ch] TAGS: tags etags: tags depend: $(MAKEDEPEND) -- $(CPPFLAGS) $(CFLAGS) -- $(SRCS) rplay-3.3.2/rplayd/buffer.c100644 153 62 6511 6671423012 14231 0ustar boynsstaff/* $Id: buffer.c,v 1.4 1999/03/10 07:58:02 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "rplayd.h" #include "buffer.h" static BUFFER *buffers = NULL; static int nbuffers = 0; /* number of buffers on the free list */ static int next_id = 0; /* next buffer id number */ #ifdef __STDC__ BUFFER * buffer_create(void) #else BUFFER * buffer_create() #endif { BUFFER *b; if (buffers == NULL) { b = (BUFFER *) malloc(sizeof(BUFFER)); if (b == NULL) { report(REPORT_ERROR, "buffer_create: out of memory\n"); done(1); } b->id = ++next_id; } else { nbuffers--; b = buffers; buffers = buffers->next; } b->nbytes = 0; b->buf[0] = '\0'; b->status = BUFFER_FREE; b->offset = 0; b->next = NULL; return b; } #ifdef __STDC__ void buffer_destroy(BUFFER *b) #else void buffer_destroy(b) BUFFER *b; #endif { if (b == NULL || b->status == BUFFER_KEEP) { /* Do nothing. */ return; } else if (b->status == BUFFER_REUSE) { /* Always put REUSE buffers on the free list. This will probably cause rplayd to grow bigger, but it prevents problems with calling free() inside the timer interrupt. */ nbuffers++; b->next = buffers; buffers = b; } else { /* Free the buffer. */ free((char *) b); } } /* * Allocate enough buffers to hold nbytes. */ #ifdef __STDC__ BUFFER * buffer_alloc(int nbytes, int type) #else BUFFER * buffer_alloc(nbytes, type) int nbytes; int type; #endif { BUFFER *head, **next = &head; do { *next = buffer_create(); nbytes -= BUFFER_SIZE; (*next)->status = type; next = &(*next)->next; } while (nbytes > 0); *next = NULL; return head; } #ifdef __STDC__ void buffer_dealloc(BUFFER *b, int force) #else void buffer_dealloc(b, force) BUFFER *b; int force; #endif { BUFFER *next; while (b) { next = b->next; if (force) { b->status = BUFFER_FREE; } buffer_destroy(b); b = next; } } #ifdef __STDC__ void buffer_cleanup(void) #else void buffer_cleanup() #endif { BUFFER *b; report(REPORT_DEBUG, "cleaning up buffers - %d bytes\n", nbuffers * BUFFER_SIZE); while (buffers) { b = buffers; buffers = buffers->next; free((char *) b); } buffers = NULL; nbuffers = 0; next_id = 0; } #ifdef __STDC__ int buffer_nbytes(BUFFER *b) #else int buffer_nbytes(b) BUFFER *b; #endif { int n = 0; while (b) { n += b->nbytes; b = b->next; } return n; } rplay-3.3.2/rplayd/buffer.h100644 153 62 3710 6671423012 14234 0ustar boynsstaff/* $Id: buffer.h,v 1.3 1999/03/10 07:58:02 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _buffer_h #define _buffer_h #ifdef HAVE_CONFIG_H #include "config.h" #endif #define BUFFER_SIZE 8192 /* must be >= RPTP_MAX_LINE, divisible by 2 & 4 */ /* * Maximum number of buffers to have on the free list. * The number should really depend on the value of BUFFER_SIZE. */ #define BUFFER_MAX_FREE 64 #define BUFFER_FREE 0 /* temporary buffer - put on free list or destroy */ #define BUFFER_KEEP 1 /* permanent buffer - not put on free list */ #define BUFFER_REUSE 2 /* temporary buffer - always put on free list */ typedef struct _buffer { struct _buffer *next; int id; int nbytes; char buf[BUFFER_SIZE]; int status; int offset; } BUFFER; #ifdef __STDC__ BUFFER *buffer_create (void); void buffer_destroy (BUFFER *b); BUFFER *buffer_alloc (int nbytes, int type); void buffer_dealloc (BUFFER *b, int force); void buffer_cleanup (void); #else BUFFER *buffer_create (); void buffer_destroy ( /* BUFFER *b */ ); BUFFER *buffer_alloc ( /* int nbytes, int type */ ); void buffer_dealloc ( /* BUFFER *b, int force */ ); void buffer_cleanup (); #endif #endif /* _buffer_h */ rplay-3.3.2/rplayd/cache.c100644 153 62 15502 6671423012 14043 0ustar boynsstaff/* $Id: cache.c,v 1.4 1999/03/10 07:58:02 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #ifdef ultrix #include #else #include #endif #include #include #ifdef HAVE_STRING_H #include #endif #include #include "rplayd.h" #include "sound.h" #include "spool.h" #include "cache.h" static DIR *cache_dir; static char cache_path[MAXPATHLEN]; static char cache_directory[MAXPATHLEN]; int cache_max_size = RPLAY_CACHE_SIZE; int cache_remove = 0; /* * initialize the cache */ #ifdef __STDC__ void cache_init(char *dir_name) #else void cache_init(dir_name) char *dir_name; #endif { struct stat st; strcpy(cache_directory, dir_name); if (stat(cache_directory, &st) < 0) { report(REPORT_DEBUG, "creating cache directory `%s'\n", cache_directory); if (mkdir(cache_directory, 0777) < 0) { report(REPORT_ERROR, "cache_init: cannot create cache directory '%s'\n", cache_directory); } } else if (!S_ISDIR(st.st_mode)) { report(REPORT_ERROR, "cache_init: %s not a directory\n", cache_directory); done(1); } } /* * return the name of the first cache entry */ char * cache_first() { if (cache_dir) { rewinddir(cache_dir); } else { cache_dir = opendir(cache_directory); if (cache_dir == NULL) { report(REPORT_ERROR, "cache_first: opendir %s: %s\n", cache_directory, sys_err_str(errno)); return NULL; } } return cache_next(); } /* * return the name of the next cache entry */ char * cache_next() { struct dirent *dp; do { dp = readdir(cache_dir); if (dp == NULL) { closedir(cache_dir); cache_dir = NULL; return ""; } } while (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0); SNPRINTF(SIZE(cache_path, sizeof(cache_path)), "%s/%s", cache_directory, dp->d_name); return cache_path; } /* * calculate the size of the cache */ int cache_size() { struct stat st; int size = 0; char *file; for (file = cache_first(); file && *file; file = cache_next()) { if (stat(file, &st) < 0) { report(REPORT_ERROR, "cache_size: stat %s: %s\n", file, sys_err_str(errno)); return -1; } size += (int) st.st_size; } return (int) size; } /* * load files that are already in the cache */ void cache_read() { char *file; for (file = cache_first(); file && *file; file = cache_next()) { sound_insert(file, SOUND_READY, SOUND_FILE); } } /* * prepend the cache path to the sound * * this returns static data! */ #ifdef __STDC__ char * cache_name(char *sound) #else char * cache_name(sound) char *sound; #endif { static char _cache_path[MAXPATHLEN]; SNPRINTF(SIZE(_cache_path, sizeof(_cache_path)), "%s/%s", cache_directory, sound); return _cache_path; } /* * free enough space in the cache for size bytes */ #ifdef __STDC__ int cache_free(int size) #else int cache_free(size) int size; #endif { int curr_size, limit; char *file; SOUND *s; struct stat st; int n; if (cache_max_size == 0) { return 0; } if (size > cache_max_size) { report(REPORT_DEBUG, "%d bytes cannot fit in the cache\n", size); return -1; } curr_size = cache_size(); report(REPORT_DEBUG, "sound_count = %d, current cache size = %d bytes\n", sound_count, curr_size); if (size + curr_size <= cache_max_size) { return 0; } /* * set the initial limit */ limit = sound_count / 2; for (;;) { report(REPORT_DEBUG, "removing cache entries (limit = %d)\n", limit); for (file = cache_first(); file && *file; file = cache_next()) { s = sound_lookup(file, SOUND_DONT_COUNT, NULL); if (s == NULL || s->status != SOUND_READY) { continue; } if (s->count < limit) { if (stat(file, &st) < 0) { report(REPORT_ERROR, "cache_free: stat %s: %s\n", file, sys_err_str(errno)); continue; } curr_size -= (int) st.st_size; spool_remove(s); sound_delete(s, 1); report(REPORT_DEBUG, "removed %s size=%d count=%d\n", file, st.st_size, s->count); } } if (size + curr_size <= cache_max_size) { break; } else if (limit == sound_count) { report(REPORT_ERROR, "cache_free: cannot make room for %d bytes in the cache\n", size); return -1; } else { n = limit / 4; limit += n ? n : 1; limit = MIN(limit, sound_count); } } return 0; } /* * create room in the cache for the file of size bytes */ #ifdef __STDC__ int cache_create(char *name, int size) #else int cache_create(name, size) char *name; int size; #endif { int fd; fd = open(name, O_RDWR | O_CREAT, 0666); if (fd < 0) { report(REPORT_ERROR, "cache_create: open: %s\n", sys_err_str(errno)); return -1; } if (lseek(fd, size - 1, SEEK_SET) < 0) { report(REPORT_ERROR, "cache_create: lseek: %d %s\n", sys_err_str(errno)); return -1; } restart: if (write(fd, "", 1) != 1) { if (errno == EINTR || errno == EAGAIN) { goto restart; } report(REPORT_ERROR, "cache_create: write: %s\n", sys_err_str(errno)); return -1; } if (lseek(fd, 0, SEEK_SET) < 0) { report(REPORT_ERROR, "cache_create: lseek: 0 %s\n", sys_err_str(errno)); unlink(name); return -1; } return fd; } /* Optionally remove the cache directory and all its contents. */ void cache_cleanup() { int size; char *file; if (*cache_directory == '\0') /* cache_init wasn't called */ { return; } size = cache_size(); if (size == 0 || cache_remove) { report(REPORT_DEBUG, "cleaning `%s'\n", cache_directory); for (file = cache_first(); file && *file; file = cache_next()) { if (unlink(file) < 0) { report(REPORT_ERROR, "cache_cleanup: unlink %s: %s\n", file, sys_err_str(errno)); } } if (rmdir(cache_directory) < 0) { report(REPORT_ERROR, "cache_cleanup: rmdir %s: %s\n", cache_directory, sys_err_str(errno)); } } } rplay-3.3.2/rplayd/cache.h100644 153 62 3251 6671423012 14026 0ustar boynsstaff/* $Id: cache.h,v 1.3 1999/03/10 07:58:02 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _cache_h #define _cache_h #ifdef HAVE_CONFIG_H #include "config.h" #endif extern int cache_max_size; extern int cache_remove; #ifdef __STDC__ extern void cache_init (char *dir_name); extern char *cache_first (); extern char *cache_next (); extern int cache_size (); extern void cache_read (); extern char *cache_name (char *sound); extern int cache_free (int size); extern int cache_create (char *name, int size); extern void cache_cleanup (); #else extern void cache_init ( /* char *dir_name */ ); extern char *cache_first (); extern char *cache_next (); extern int cache_size (); extern void cache_read (); extern char *cache_name ( /* char *sound */ ); extern int cache_free ( /* int size */ ); extern int cache_create ( /* char *name, int size */ ); extern void cache_cleanup (); #endif #endif /* _cache_h */ rplay-3.3.2/rplayd/cdrom.c100644 153 62 31703 6671423012 14105 0ustar boynsstaff/* $Id: cdrom.c,v 1.4 1999/03/10 07:58:02 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /* A lot of the CDDA code is based on read_cdda 1.01 by Jim Mintha (mintha@geog.ubc.ca) which seems to have borrowed code from Workman sources written by Steven Grimm (koreth@hyperion.com). */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_CDROM #include #include #include "rplayd.h" #include "cdrom.h" CDROM_TABLE cdrom_table[MAX_CDROMS] = { #if defined (sun) && defined (SVR4) /* Solaris 2.x */ {"cdrom:", "/vol/dev/aliases/cdrom0", 0, 0}, {"cdrom0:", "/vol/dev/aliases/cdrom0", 0, 0}, {"cdrom1:", "/vol/dev/aliases/cdrom1", 0, 0}, {"cdrom2:", "/vol/dev/aliases/cdrom2", 0, 0}, {"cdrom3:", "/vol/dev/aliases/cdrom3", 0, 0}, #else /* not solaris */ #if defined (linux) {"cdrom:", "/dev/cdrom", 0, 0}, {"cdrom0:", "/dev/cdrom0", 0, 0}, {"cdrom1:", "/dev/cdrom1", 0, 0}, {"cdrom2:", "/dev/cdrom2", 0, 0}, {"cdrom3:", "/dev/cdrom3", 0, 0}, #endif /* linux */ #endif }; typedef struct { char *device; int starting_track; int ending_track; int num_blocks; int fd; char *buffer; int buffer_length; int starting_block; int current_block; int ending_block; } CDROM_INFO; /* Internal prototypes. */ #ifdef HAVE_CDDA #ifdef __STDC__ static void cdda_cdrom_reader(CDROM_TABLE * cdt, int starting_track, int ending_track, int output_fd); #else static void cdda_cdrom_reader( /* CDROM_TABLE *cdt, int starting_track, int ending_track, int output_fd */ ); #endif #endif /* HAVE_CDDA */ #ifdef linux #ifdef __STDC__ static void linux_cdrom_reader(CDROM_TABLE * cdt, int starting_track, int ending_track, int output_fd); #else static void linux_cdrom_reader( /* CDROM_TABLE *cdt, int starting_track, int ending_track, int output_fd */ ); #endif #endif /* linux */ /* starting_track and ending_track can be 0 which means first and last */ #ifdef __STDC__ void cdrom_reader(int index, int starting_track, int ending_track, int output_fd) #else void cdrom_reader(index, starting_track, ending_track, output_fd) int index; int starting_track; int ending_track; int output_fd; #endif { CDROM_TABLE *cdt; cdt = &cdrom_table[index]; report(REPORT_DEBUG, "cdrom_reader: %s%s tracks %d..%d\n", cdt->name, cdt->device, starting_track, ending_track); rplay_audio_close(); /* prevent device busy problems */ #ifdef HAVE_CDDA cdda_cdrom_reader(cdt, starting_track, ending_track, output_fd); #else #ifdef linux linux_cdrom_reader(cdt, starting_track, ending_track, output_fd); #endif /* linux */ #endif /* HAVE_CDDA */ /* Add more cdrom readers here. */ exit(0); } /******************************************************************************/ #ifdef HAVE_CDDA /* A nicer interface to reading from the CDDA interface using the CDROM_INFO structure and the cdda_open, cdda_read, and cdda_close routines. */ #define CDDA_BLOCK_SIZE 2368 #define CDDA_BLOCK_IGNORE 16 static int cdda_open(CDROM_INFO * info); static int cdda_read(CDROM_INFO * info); static int cdda_close(CDROM_INFO * info); static int internal_cdda_init(CDROM_INFO * info); static int internal_cdda_read(CDROM_INFO * info); static int internal_cdda_toc(CDROM_INFO * info); #ifdef __STDC__ static void cdda_cdrom_reader(CDROM_TABLE * cdt, int starting_track, int ending_track, int output_fd) #else static void cdda_cdrom_reader(cdt, starting_track, ending_track, output_fd) CDROM_TABLE *cdt; int starting_track; int ending_track; int output_fd; #endif { CDROM_INFO info; int n, i; char *p; info.device = cdt->device; info.starting_track = starting_track; info.ending_track = ending_track; info.num_blocks = 30; info.fd = -1; info.buffer = NULL; if (cdda_open(&info) < 0) { return; } for (;;) { n = cdda_read(&info); if (n <= 0) { break; } p = info.buffer; for (i = 0; i < info.num_blocks; i++) { write(output_fd, p, CDDA_BLOCK_SIZE - CDDA_BLOCK_IGNORE); p += CDDA_BLOCK_SIZE; } } cdda_close(&info); } #ifdef __STDC__ static int cdda_open(CDROM_INFO * info) #else static int cdda_open(info) CDROM_INFO *info; #endif { if (info->fd < 0) { if (internal_cdda_init(info) < 0) { return -1; } } return internal_cdda_toc(info); } #ifdef __STDC__ static int cdda_read(CDROM_INFO * info) #else static int cdda_read(info) CDROM_INFO *info; #endif { int n; n = internal_cdda_read(info); if (n < 0) { return -1; } return n; } #ifdef __STDC__ static int cdda_close(CDROM_INFO * info) #else static int cdda_close(info) CDROM_INFO *info; #endif { close(info->fd); info->fd = -1; if (info->buffer) { free((char *) info->buffer); } info->buffer = NULL; return 0; } /* End of nicer CDDA interface. */ #include #include #include #include #include #include #include #define CDDABLKSIZE 2368 #define SAMPLES_PER_BLK 588 #ifdef __STDC__ static int internal_cdda_init(CDROM_INFO * info) #else static int internal_cdda_init(info) CDROM_INFO *info; #endif { struct cdrom_cdda cdda; info->fd = open(info->device, 0); if (info->fd < 0) { perror(info->device); return -1; } info->buffer = (char *) malloc(info->num_blocks * CDDABLKSIZE + CDDABLKSIZE); if (info->buffer == NULL) { fprintf(stderr, "malloc: out of memory\n"); return -1; } info->buffer_length = info->num_blocks * CDDABLKSIZE; cdda.cdda_addr = 200; cdda.cdda_length = 1; cdda.cdda_data = info->buffer; cdda.cdda_subcode = CDROM_DA_SUBQ; if (ioctl(info->fd, CDROMCDDA, &cdda) < 0) { perror("ioctl: CDROMCDDA"); free((char *) info->buffer); info->buffer = NULL; close(info->fd); return -1; } return 0; } #ifdef __STDC__ static int internal_cdda_read(CDROM_INFO * info) #else static int internal_cdda_read(info) CDROM_INFO *info; #endif { struct cdrom_cdda cdda; int blk; unsigned char *q; if (info->current_block >= info->ending_block) { return 0; } cdda.cdda_addr = info->current_block; if (info->current_block + info->num_blocks > info->ending_block) { cdda.cdda_length = info->ending_block - info->current_block; } else { cdda.cdda_length = info->num_blocks; } cdda.cdda_data = info->buffer; cdda.cdda_subcode = CDROM_DA_SUBQ; if (ioctl(info->fd, CDROMCDDA, &cdda) < 0) { if (errno == ENXIO) { perror("ioctl: CDROMCDDA: CD ejected"); return -1; } if (info->current_block + info->num_blocks > info->ending_block) { return 0; } if (ioctl(info->fd, CDROMCDDA, &cdda) < 0) { if (ioctl(info->fd, CDROMCDDA, &cdda) < 0) { if (ioctl(info->fd, CDROMCDDA, &cdda) < 0) { perror("ioctl: CDROMCDDA"); return -1; } } } } info->current_block += cdda.cdda_length; return cdda.cdda_length * CDDABLKSIZE; } #ifdef __STDC__ static int internal_cdda_toc(CDROM_INFO * info) #else static int internal_cdda_toc(info) CDROM_INFO *info; #endif { struct cdrom_tochdr hdr; struct cdrom_tocentry entry; int i; if (ioctl(info->fd, CDROMREADTOCHDR, &hdr) < 0) { perror("ioctl: CDROMREADTOCHDR"); return -1; } info->starting_block = 0; info->ending_block = 0; if (info->starting_track == 0) { info->starting_track = hdr.cdth_trk0; } if (info->ending_track == 0) { info->ending_track = hdr.cdth_trk1; } for (i = 1; i <= hdr.cdth_trk1; i++) { entry.cdte_track = i; entry.cdte_format = CDROM_MSF; if (ioctl(info->fd, CDROMREADTOCENTRY, &entry) < 0) { perror("ioctl: CDROMREADTOCENTRY"); return -1; } if (i == info->starting_track) { info->starting_block = entry.cdte_addr.msf.minute * 60 * 75 + entry.cdte_addr.msf.second * 75 + entry.cdte_addr.msf.frame; } if (i == info->ending_track + 1) { info->ending_block = entry.cdte_addr.msf.minute * 60 * 75 + entry.cdte_addr.msf.second * 75 + entry.cdte_addr.msf.frame; } } entry.cdte_track = CDROM_LEADOUT; entry.cdte_format = CDROM_MSF; if (ioctl(info->fd, CDROMREADTOCENTRY, &entry) < 0) { perror("ioctl: CDROMREADTOCENTRY"); return -1; } if (info->ending_block == 0) { info->ending_block = entry.cdte_addr.msf.minute * 60 * 75 + entry.cdte_addr.msf.second * 75 + entry.cdte_addr.msf.frame; } /* Move back two seconds - don't know why but works */ info->starting_block -= 150; info->ending_block -= 150; info->current_block = info->starting_block; return 0; } #else /******************************************************************************/ #if defined (linux) #include #ifdef __STDC__ static int linux_read_toc(CDROM_INFO * info) #else static int linux_read_toc(info) CDROM_INFO *info; #endif { struct cdrom_tochdr hdr; struct cdrom_tocentry entry; int i; if (ioctl(info->fd, CDROMREADTOCHDR, &hdr) < 0) { perror("ioctl: CDROMREADTOCHDR"); return -1; } info->starting_block = 0; info->ending_block = 0; if (info->starting_track == 0) { info->starting_track = hdr.cdth_trk0; } if (info->ending_track == 0) { info->ending_track = hdr.cdth_trk1; } for (i = 1; i <= hdr.cdth_trk1; i++) { entry.cdte_track = i; entry.cdte_format = CDROM_MSF; if (ioctl(info->fd, CDROMREADTOCENTRY, &entry) < 0) { perror("ioctl: CDROMREADTOCENTRY"); return -1; } if (i == info->starting_track) { info->starting_block = entry.cdte_addr.msf.minute * 60 * 75 + entry.cdte_addr.msf.second * 75 + entry.cdte_addr.msf.frame; } if (i == info->ending_track + 1) { info->ending_block = entry.cdte_addr.msf.minute * 60 * 75 + entry.cdte_addr.msf.second * 75 + entry.cdte_addr.msf.frame; } } entry.cdte_track = CDROM_LEADOUT; entry.cdte_format = CDROM_MSF; if (ioctl(info->fd, CDROMREADTOCENTRY, &entry) < 0) { perror("ioctl: CDROMREADTOCENTRY"); return -1; } if (info->ending_block == 0) { info->ending_block = entry.cdte_addr.msf.minute * 60 * 75 + entry.cdte_addr.msf.second * 75 + entry.cdte_addr.msf.frame; } /* Move back two seconds - don't know why but works */ info->starting_block -= 150; info->ending_block -= 150; info->current_block = info->starting_block; return 0; } #ifdef __STDC__ static void linux_cdrom_reader(CDROM_TABLE * cdt, int starting_track, int ending_track, int output_fd) #else static void linux_cdrom_reader(cdt, starting_track, ending_track, output_fd) CDROM_TABLE *cdt; int starting_track; int ending_track; int output_fd; #endif { CDROM_INFO info; int n, i; char *p; info.device = cdt->device; info.starting_track = starting_track; info.ending_track = ending_track; info.num_blocks = 30; info.fd = -1; info.buffer = NULL; info.fd = open(info.device, 0); if (info.fd < 0) { perror(info.device); return; } info.buffer = (char *) malloc(info.num_blocks * CD_FRAMESIZE_RAW + CD_FRAMESIZE_RAW); if (info.buffer == NULL) { fprintf(stderr, "malloc: out of memory\n"); return; } linux_read_toc(&info); /* printf ("start track=%d block=%d\n", info.starting_track, info.starting_block); */ /* printf ("end track=%d block=%d\n", info.ending_track, info.ending_block); */ while (info.current_block < info.ending_block) { int frames; int max_retries = 5; if (info.current_block + info.num_blocks > info.ending_block) { frames = info.ending_block - info.current_block; } else { frames = info.num_blocks; } for (i = 0; i < max_retries; i++) { struct cdrom_read_audio audio; audio.addr_format = CDROM_LBA; audio.addr.lba = info.current_block; audio.nframes = frames; audio.buf = info.buffer; if (ioctl(info.fd, CDROMREADAUDIO, &audio) >= 0) { break; } } if (i == max_retries) { perror(info.device); break; } if (write(output_fd, info.buffer, CD_FRAMESIZE_RAW * frames) < 0) { break; } info.current_block += frames; } free(info.buffer); close(info.fd); } #endif /* linux */ #endif /* HAVE_CDDA */ #endif /* HAVE_CDROM */ rplay-3.3.2/rplayd/cdrom.h100644 153 62 2765 6671423012 14100 0ustar boynsstaff/* $Id: cdrom.h,v 1.3 1999/03/10 07:58:02 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _cdrom_h #define _cdrom_h #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_CDROM /* The maximum number of CDROM devices. Also see cdrom.c. This is really the size of cdrom_table. */ #define MAX_CDROMS 5 typedef struct { char *name; char *device; int number_of_tracks; int current_track; } CDROM_TABLE; extern CDROM_TABLE cdrom_table[]; #ifdef __STDC_ extern void cdrom_reader (int index, int starting_track, int ending_track, int output_fd); #else extern void cdrom_reader (/* int index, int starting_track, int ending_track, int output_fd */); #endif #endif /* HAVE_CDROM */ #endif /* _cdrom_h */ rplay-3.3.2/rplayd/command.c100644 153 62 151000 6671423012 14430 0ustar boynsstaff/* $Id: command.c,v 1.6 1999/03/10 07:58:02 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifdef HAVE_STRING_H #include #endif #include "rplayd.h" #include "command.h" #include "connection.h" #include "server.h" #include "host.h" #include "spool.h" #include "cache.h" #include "sound.h" #include "misc.h" #include "strdup.h" #include "getopt.h" #ifdef HAVE_HELPERS #include "helper.h" #endif /* HAVE_HELPERS */ #undef is_true #define is_true(string) \ (strcmp (string, "true") == 0 \ || strcmp (string, "t") == 0 \ || strcmp (string, "1") == 0 \ || strcmp (string, "yes") == 0 \ || strcmp (string, "y") == 0 \ || strcmp (string, "on") == 0) \ typedef struct { char *name; int min_args; int max_args; char *usage; #ifdef __STDC__ int (*func) (CONNECTION *c, int argc, char **argv); #else int (*func) ( /* CONNECTION *c, int argc, char **argv */ ); #endif } COMMAND; #ifdef __STDC__ static int do_command(CONNECTION *c, int argc, char **argv); static int command_quit(CONNECTION *c, int argc, char **argv); static int command_unknown(CONNECTION *c, int argc, char **argv); static int command_help(CONNECTION *c, int argc, char **argv); static int command_get(CONNECTION *c, int argc, char **argv); static int command_put(CONNECTION *c, int argc, char **argv); static int command_list(CONNECTION *c, int argc, char **argv); static int command_find(CONNECTION *c, int argc, char **argv); static int command_execute(CONNECTION *c, int argc, char **argv); static int command_access(CONNECTION *c, int argc, char **argv); static int command_volume(CONNECTION *c, int argc, char **argv); static int command_info(CONNECTION *c, int argc, char **argv); static int command_version(CONNECTION *c, int argc, char **argv); static int command_wait(CONNECTION *c, int argc, char **argv); static int do_execute(CONNECTION *c, int argc, char **argv); static int command_status(CONNECTION *c, int argc, char **argv); static int command_application(CONNECTION *c, int argc, char **argv); static int command_reset(CONNECTION *c, int argc, char **argv); static int command_skip(CONNECTION *c, int argc, char **argv); static int command_set(CONNECTION *c, int argc, char **argv); static int command_modify(CONNECTION *c, int argc, char **argv); static int command_monitor(CONNECTION *c, int argc, char **argv); #else static int do_command( /* CONNECTION *c, int argc, char **argv */ ); static int command_quit( /* CONNECTION *c, int argc, char **argv */ ); static int command_unknown( /* CONNECTION *c, int argc, char **argv */ ); static int command_help( /* CONNECTION *c, int argc, char **argv */ ); static int command_get( /* CONNECTION *c, int argc, char **argv */ ); static int command_put( /* CONNECTION *c, int argc, char **argv */ ); static int command_list( /* CONNECTION *c, int argc, char **argv */ ); static int command_find( /* CONNECTION *c, int argc, char **argv */ ); static int command_execute( /* CONNECTION *c, int argc, char **argv */ ); static int command_access( /* CONNECTION *c, int argc, char **argv */ ); static int command_volume( /* CONNECTION *c, int argc, char **argv */ ); static int command_info( /* CONNECTION *c, int argc, char **argv */ ); static int command_version( /* CONNECTION *c, int argc, char **argv */ ); static int command_wait( /* CONNECTION *c, int argc, char **argv */ ); static int do_execute( /* CONNECTION *c, int argc, char **argv */ ); static int command_status( /* CONNECTION *c, int argc, char **argv */ ); static int command_application( /* CONNECTION *c, int argc, char **argv */ ); static int command_reset( /* CONNECTION *c, int argc, char **argv */ ); static int command_skip( /* CONNECTION *c, int argc, char **argv */ ); static int command_set( /* CONNECTION *c, int argc, char **argv */ ); static int command_modify( /* CONNECTION *c, int argc, char **argv */ ); static int command_monitor( /* CONNECTION *c, int argc, char **argv */ ); #endif #ifdef DEBUG extern int command_die( /* CONNECTION *c, int argc, char **argv */ ); #endif static COMMAND commands[] = { /* * command min max usage function */ {"access", -1, -1, "", command_access}, {"application", 1, -1, "name", command_application}, {"continue", 1, -1, "id|sound ...", command_execute}, #ifdef DEBUG {"die", -1, -1, "", command_die}, #endif {"done", 1, -1, "id|sound ...", command_execute}, {"find", 1, 1, "sound", command_find}, {"get", 1, 1, "sound", command_get}, {"help", -1, -1, "", command_help}, {"info", 1, 1, "sound", command_info}, #ifdef AUTH {"list", 0, 1, "[connections|hosts|servers|spool|sounds]", command_list}, #else {"list", 0, 1, "[connections|servers|sounds}", command_list}, #endif /* AUTH */ {"modify", 2, -1, "id [count|list-count|priority|sample-rate|volume] ...", command_modify}, {"monitor", -1, -1, "", command_monitor}, {"pause", 1, -1, "id|sound ...", command_execute}, {"play", 1, -1, "sound ...", command_execute}, {"put", 2, -1, "id|sound size", command_put}, {"quit", 0, 0, "", command_quit}, {"reset", 0, 0, "", command_reset}, {"set", 1, -1, "name[=value] ...", command_set}, {"skip", 1, -1, "id count", command_skip}, {"status", 0, 0, "", command_status}, {"stop", 1, -1, "id|sound ...", command_execute}, {"version", 0, 0, "", command_version}, {"volume", 0, 1, "[[+|-]volume]", command_volume}, {"wait", -1, -1, "id|event|RPTP command", command_wait}, }; #define NCOMMANDS (sizeof(commands)/sizeof(COMMAND)) /* Copy of the current RPTP command. */ static char command_buffer[RPTP_MAX_LINE]; static char *default_client_data = ""; #ifdef __STDC__ int command(CONNECTION *c, char *buf) #else int command(c, buf) CONNECTION *c; char *buf; #endif { char *argv[RPTP_MAX_ARGS], *p; int argc = 0, first = 1; report(REPORT_INFO, "%s command=\"%s\"\n", inet_ntoa(c->sin.sin_addr), buf); strncpy(command_buffer, buf, sizeof(command_buffer)); while ((p = strtok(first ? buf : NULL, " \t"))) { argv[argc++] = p; first = 0; if (argc == RPTP_MAX_ARGS - 1) { break; } } argv[argc] = NULL; if (argc == 0) { return 0; } else { return do_command(c, argc, argv); } } #ifdef __STDC__ static int do_command(CONNECTION *c, int argc, char **argv) #else static int do_command(c, argc, argv) CONNECTION *c; int argc; char **argv; #endif { int i; for (i = 0; i < NCOMMANDS; i++) { if (strcmp(commands[i].name, argv[0]) == 0) { if ((commands[i].min_args >= 0 && argc - 1 < commands[i].min_args) || (commands[i].max_args >= 0 && argc - 1 > commands[i].max_args)) { connection_reply(c, "%cerror=\"usage: %s %s\"", RPTP_ERROR, commands[i].name, commands[i].usage); return 0; } else { return (*commands[i].func) (c, argc, argv); } } } return command_unknown(c, argc, argv); } #ifdef __STDC__ static int command_quit(CONNECTION *c, int argc, char **argv) #else static int command_quit(c, argc, argv) CONNECTION *c; int argc; char **argv; #endif { /* connection_close (c); */ return -1; } #ifdef __STDC__ static int command_unknown(CONNECTION *c, int argc, char **argv) #else static int command_unknown(c, argc, argv) CONNECTION *c; int argc; char **argv; #endif { char *client_data; client_data = rptp_parse(command_buffer, "client-data"); if (!client_data) { client_data = default_client_data; } connection_reply(c, "%cerror=\"unknown command `%s'\" command=\"%s\" client-data=\"%s\"", RPTP_ERROR, argv[0], argv[0], client_data); return 0; } #ifdef __STDC__ static int command_help(CONNECTION *c, int argc, char **argv) #else static int command_help(c, argc, argv) CONNECTION *c; int argc; char **argv; #endif { int i; char fmt[1024]; EVENT *e; static BUFFER *b; if (b == NULL) { b = buffer_create(); b->status = BUFFER_KEEP; SNPRINTF(SIZE(b->buf, BUFFER_SIZE), "%cmessage=\"command summary\" command=help\r\n", RPTP_OK); b->nbytes += strlen(b->buf); for (i = 0; i < NCOMMANDS; i++) { SNPRINTF(SIZE(fmt, sizeof(fmt)), "%-8s %s\r\n", commands[i].name, commands[i].usage); SNPRINTF(SIZE(b->buf + b->nbytes, BUFFER_SIZE - b->nbytes), fmt); b->nbytes += strlen(fmt); } SNPRINTF(SIZE(b->buf + b->nbytes, BUFFER_SIZE - b->nbytes), ".\r\n"); b->nbytes += 3; } e = event_create(EVENT_WRITE, b); event_insert(c, e); return 0; } #ifdef __STDC__ static int command_get(CONNECTION *c, int argc, char **argv) #else static int command_get(c, argc, argv) CONNECTION *c; int argc; char **argv; #endif { SOUND *s; EVENT *e; char *sound_name = NULL; int old_style = 0; char *client_data = default_client_data; if (strchr(command_buffer, '=')) { sound_name = rptp_parse(command_buffer, "sound"); client_data = rptp_parse(0, "client-data"); if (!client_data) { client_data = default_client_data; } } if (!sound_name) { sound_name = argv[1]; old_style++; } #ifdef AUTH if (!host_access(c->sin, HOST_READ)) { report(REPORT_NOTICE, "%s get %s - read access denied\n", inet_ntoa(c->sin.sin_addr), argv[1]); connection_reply(c, "%cerror=\"access denied\" command=get client-data=\"%s\"", RPTP_ERROR, client_data); return 0; } #endif /* AUTH */ s = sound_lookup(sound_name, SOUND_DONT_FIND, NULL); if (s == NULL || s->status != SOUND_READY) { report(REPORT_NOTICE, "%s get %s - not found\n", inet_ntoa(c->sin.sin_addr), sound_name); connection_reply(c, "%cerror=\"%s not found\" command=get client-data=\"%s\"", RPTP_ERROR, sound_name, client_data); } else if (s->type != SOUND_FILE) { connection_reply(c, "%cerror=\"%s not a file\" command=get client-data=\"%s\"", RPTP_ERROR, s->name, client_data); } else { e = event_create(EVENT_WRITE_SOUND, s); if (e == NULL) { report(REPORT_NOTICE, "%s get %s - cannot open\n", inet_ntoa(c->sin.sin_addr), s->name); connection_reply(c, "%cerror=\"cannot open %s\" command=get client-data=\"%s\"", RPTP_ERROR, s->name, client_data); } else { report(REPORT_NOTICE, "%s get %s %d\n", inet_ntoa(c->sin.sin_addr), s->name, s->size); if (old_style) { connection_reply(c, "%c%s %d", RPTP_OK, s->name, s->size); } else { connection_reply(c, "%csound=\"%s\" size=%d command=get client-data=\"%s\"", RPTP_OK, s->name, s->size, client_data); } event_insert(c, e); } } return 0; } #ifdef __STDC__ static int command_put(CONNECTION *c, int argc, char **argv) #else static int command_put(c, argc, argv) CONNECTION *c; int argc; char **argv; #endif { EVENT *e; int sound_size; char *name, *sound_name = NULL, *p; SOUND *s; int fd; int old_style = 0; int spool_id = 0; char *client_data = default_client_data; if (strchr(command_buffer, '=')) { client_data = rptp_parse(command_buffer, "client-data"); if (!client_data) { client_data = default_client_data; } } else { old_style++; } #ifdef AUTH if (!host_access(c->sin, HOST_WRITE)) { report(REPORT_NOTICE, "%s put %s - write access denied\n", inet_ntoa(c->sin.sin_addr), argv[1]); connection_reply(c, "%cerror=\"access denied\" command=put client-data=\"%s\"", RPTP_ERROR, client_data); return 0; } #endif /* AUTH */ if (!old_style) { char *p; sound_name = rptp_parse(0, "sound"); p = rptp_parse(0, "size"); if (!p) { connection_reply(c, "%cerror=\"missing `size='\" command=put client-data=\"%s\"", RPTP_ERROR, client_data); return 0; } sound_size = atoi(p); p = rptp_parse(0, "id"); if (p && *p && p[0] == '#') { spool_id = atoi(p + 1); } } else /* old-style */ { sound_name = argv[1]; sound_size = atoi(argv[2]); old_style++; } if (spool_id) { SPOOL *sp; #ifdef HAVE_HELPERS HELPER *hp; #endif sp = spool_find(spool_id); if (!sp) { connection_reply(c, "%cerror=\"`%d' no such spool id\" command=put client-data=\"%s\"", RPTP_ERROR, spool_id, client_data); return 0; } else if (sp->sound[sp->curr_sound]->type != SOUND_FLOW) { connection_reply(c, "%cerror=\"`%d' spool id is not a flow\" command=put client-data=\"%s\"", RPTP_ERROR, spool_id, client_data); return 0; } connection_reply(c, "%cid=#%d size=%d command=put client-data=\"%s\"", RPTP_OK, spool_id, sound_size, client_data); #ifdef HAVE_HELPERS /* XXX - it isn't known yet whether or not this sound will need a helper. Check here too. */ hp = helper_lookup(sp->sound[sp->curr_sound]->path); if (hp) { SOUND *s = sp->sound[sp->curr_sound]; e = event_create(EVENT_PIPE_FLOW, spool_id, s); event_insert(c, e); s->status = SOUND_READY; sound_map(s); spool_ready(s); } else #endif /* HAVE_HELPERS */ { e = event_create(EVENT_READ_FLOW, spool_id, sound_size); event_insert(c, e); } return 0; } else { /* strip pathnames -- files can only be put in the cache directory */ p = strrchr(sound_name, '/'); if (p) { sound_name = p + 1; } name = cache_name(sound_name); s = sound_lookup(name, SOUND_DONT_FIND, NULL); if (s != NULL) { connection_reply(c, "%cerror=\"%s already is in the cache\" command=put client-data=\"%s\"", RPTP_ERROR, sound_name, client_data); return 0; } if (cache_free(sound_size) < 0) { connection_reply(c, "%cerror=\"the cache is full\" command=put client-data=\"%s\"", RPTP_ERROR, client_data); } else { fd = cache_create(name, sound_size); if (fd < 0) { connection_reply(c, "%cerror=\"cache error\" command=put client-data=\"%s\"", RPTP_ERROR, client_data); } else { report(REPORT_NOTICE, "%s put %s %d\n", inet_ntoa(c->sin.sin_addr), sound_name, sound_size); s = sound_insert(name, SOUND_NOT_READY, SOUND_FILE); if (old_style) { connection_reply(c, "%c%s %d", RPTP_OK, sound_name, sound_size); } else { connection_reply(c, "%csound=\"%s\" size=%d command=put client-data=\"%s\"", RPTP_OK, sound_name, sound_size, client_data); } e = event_create(EVENT_READ_SOUND, fd, buffer_create(), sound_size, s); event_insert(c, e); } } return 0; } } #ifdef __STDC__ static int command_list(CONNECTION *c, int argc, char **argv) #else static int command_list(c, argc, argv) CONNECTION *c; int argc; char **argv; #endif { EVENT *e; char *client_data = default_client_data; BUFFER *b; if (strchr(command_buffer, '=')) { client_data = rptp_parse(command_buffer, "client-data"); if (!client_data) { client_data = default_client_data; } } if (argv[1] == NULL || strcmp(argv[1], "sounds") == 0) { b = sound_list_create(); if (b) { e = event_create(EVENT_WRITE, b); event_insert(c, e); } else { connection_reply(c, "%cerror=\"no sounds available\" command=list client-data=\"%s\"", RPTP_ERROR, client_data); } } else if (strcmp(argv[1], "connections") == 0) { b = connection_list_create(); if (b) { e = event_create(EVENT_WRITE, b); event_insert(c, e); } else { connection_reply(c, "%cerror=\"no connections available\" command=list client-data=\"%s\"", RPTP_ERROR, client_data); } } else if (strcmp(argv[1], "servers") == 0) { if (server_list) { e = event_create(EVENT_WRITE, server_list); event_insert(c, e); } else { connection_reply(c, "%cerror=\"no servers available\" command=list client-data=\"%s\"", RPTP_ERROR, client_data); } } else if (strcmp(argv[1], "spool") == 0) { b = spool_list_create(); if (b) { e = event_create(EVENT_WRITE, b); event_insert(c, e); } else { connection_reply(c, "%cerror=\"no spool available\" command=list client-data=\"%s\"", RPTP_ERROR, client_data); } } #ifdef AUTH else if (strcmp(argv[1], "hosts") == 0) { b = host_list; if (b) { e = event_create(EVENT_WRITE, b); event_insert(c, e); } else { connection_reply(c, "%cerror=\"no hosts available\" command=list client-data=\"%s\"", RPTP_ERROR, client_data); } } #endif /* AUTH */ else { connection_reply(c, "%cerror=\"cannot list `%s'\" command=list client-data=\"%s\"", RPTP_ERROR, argv[1], client_data); } return 0; } #ifdef __STDC__ static int command_find(CONNECTION *c, int argc, char **argv) #else static int command_find(c, argc, argv) CONNECTION *c; int argc; char **argv; #endif { SOUND *s; char *sound_name = NULL; int old_style = 0; char *client_data = default_client_data; if (strchr(command_buffer, '=')) { sound_name = rptp_parse(command_buffer, "sound"); client_data = rptp_parse(0, "client-data"); if (!client_data) { client_data = default_client_data; } } if (!sound_name) { sound_name = argv[1]; old_style++; } s = sound_lookup(sound_name, SOUND_DONT_FIND, NULL); if (s == NULL || s->status != SOUND_READY) { report(REPORT_NOTICE, "%s find %s - not found\n", inet_ntoa(c->sin.sin_addr), sound_name); connection_reply(c, "%cerror=\"%s not found\" command=find client-data=\"%s\"", RPTP_ERROR, sound_name, client_data); } else { report(REPORT_NOTICE, "%s find %s %d\n", inet_ntoa(c->sin.sin_addr), sound_name, s->size); if (old_style) { connection_reply(c, "%c%s %d", RPTP_OK, s->name, s->size); } else { connection_reply(c, "%csound=\"%s\" size=%d command=find client-data=\"%s\"", RPTP_OK, s->name, s->size, client_data); } } return 0; } #ifdef __STDC__ static int command_access(CONNECTION *c, int argc, char **argv) #else static int command_access(c, argc, argv) CONNECTION *c; int argc; char **argv; #endif { char buf[4]; char *client_data = default_client_data; if (strchr(command_buffer, '=')) { client_data = rptp_parse(command_buffer, "client-data"); if (!client_data) { client_data = default_client_data; } } buf[0] = '\0'; #ifdef AUTH if (host_access(c->sin, HOST_READ)) { strcat(buf, "r"); } if (host_access(c->sin, HOST_WRITE)) { strcat(buf, "w"); } if (host_access(c->sin, HOST_EXECUTE)) { strcat(buf, "x"); } #else /* AUTH */ strcat(buf, "rwx"); #endif /* AUTH */ connection_reply(c, "%caccess=%s command=access client-data=\"%s\"", RPTP_OK, buf, client_data); return 0; } #ifdef __STDC__ static int command_execute(CONNECTION *c, int argc, char **argv) #else static int command_execute(c, argc, argv) CONNECTION *c; int argc; char **argv; #endif { SPOOL *sp; int id = do_execute(c, argc, argv); if (id > 0) { sp = spool_find(id); connection_reply(c, "%cid=#%d sound=\"%s\" command=%s client-data=\"%s\" list-name=\"%s\"", RPTP_OK, id, sp->curr_attrs->sound, argv[0], sp->curr_attrs->client_data, sp->rp->list_name); } return 0; } /* * Return -1 for errors, 0 for stop, pause, continue, and return * a spool id for play. */ #ifdef __STDC__ static int do_execute(CONNECTION *c, int argc, char **argv) #else static int do_execute(c, argc, argv) CONNECTION *c; int argc; char **argv; #endif { int old_style = 0; int i, n, command = RPLAY_PLAY, val = 0; RPLAY *rp; int volume, list_count, count, priority, sample_rate; int do_random = 0; int do_search = 1; /* search by default */ int input = SOUND_FILE; int input_offset = 0; int input_format = 0; int input_byte_order = 0; int input_sample_rate = 0; float input_precision = 0; int input_channels = 0; int input_storage = SOUND_STORAGE_NONE; /* Don't store flows by default. */ char *client_data = default_client_data; char *list_name = NULL; if (strcmp(argv[0], "play") == 0) { command = RPLAY_PLAY; } else if (strcmp(argv[0], "stop") == 0) { command = RPLAY_STOP; } else if (strcmp(argv[0], "pause") == 0) { command = RPLAY_PAUSE; } else if (strcmp(argv[0], "continue") == 0) { command = RPLAY_CONTINUE; } else if (strcmp(argv[0], "done") == 0) { command = RPLAY_DONE; } if (strchr(command_buffer, '=')) { client_data = rptp_parse(command_buffer, "client-data"); if (!client_data) { client_data = default_client_data; } } else { old_style++; } #ifdef AUTH if (!host_access(c->sin, HOST_EXECUTE)) { report(REPORT_NOTICE, "%s %s access denied\n", argv[0], inet_ntoa(c->sin.sin_addr)); connection_reply(c, "%cerror=\"access denied\" command=%s client-data=\"%s\"", RPTP_ERROR, argv[0], client_data); return -1; } #endif /* AUTH */ rp = rplay_create(command); if (rp == NULL) { connection_reply(c, "%cerror=\"%s failed\" command=%s client_data=\"%s\"", RPTP_ERROR, argv[0], argv[0], client_data); return -1; } volume = RPLAY_DEFAULT_VOLUME; count = RPLAY_DEFAULT_COUNT; list_count = RPLAY_DEFAULT_LIST_COUNT; priority = RPLAY_DEFAULT_PRIORITY; sample_rate = RPLAY_DEFAULT_SAMPLE_RATE; if (!old_style) { char *name, *value; rptp_parse(command_buffer, 0); while (name = rptp_parse(0, 0)) { value = rptp_parse(0, name); if (!value || !*value) { continue; } else if (strcmp(name, "sound") == 0 || (command != RPLAY_PLAY && strcmp(name, "id") == 0)) { val = rplay_set(rp, RPLAY_APPEND, RPLAY_SOUND, value, RPLAY_VOLUME, volume, RPLAY_COUNT, count, RPLAY_SAMPLE_RATE, sample_rate, RPLAY_RPTP_SEARCH, do_search, RPLAY_CLIENT_DATA, client_data, NULL); if (val < 0) { connection_reply(c, "%cerror=\"%s failed\" command=%s client-data=\"%s\"", RPTP_ERROR, argv[0], argv[0], client_data); return -1; } } else if (strcmp(name, "client-data") == 0) { client_data = value; } else if (strcmp(name, "volume") == 0) { volume = atoi(value); } else if (strcmp(name, "count") == 0) { count = atoi(value); } else if (strcmp(name, "list-count") == 0) { list_count = atoi(value); } else if (strcmp(name, "priority") == 0) { priority = atoi(value); } else if (strcmp(name, "sample-rate") == 0) { sample_rate = atoi(value); } else if (strcmp(name, "search") == 0 || strcmp(name, "rptp-search") == 0) { do_search = is_true(value); } else if (strcmp(name, "random") == 0) { do_random = is_true(value); } else if (strcmp(name, "list-name") == 0) { list_name = value; } else if (strcmp(name, "input") == 0) { input = string_to_input(value); } else if (strcmp(name, "input-offset") == 0) { input_offset = atoi(value); } else if (strcmp(name, "input-format") == 0) { input_format = string_to_audio_format(value); } else if (strcmp(name, "input-byte-order") == 0) { input_byte_order = string_to_byte_order(value); } else if (strcmp(name, "input-sample-rate") == 0) { input_sample_rate = atoi(value); } else if (strcmp(name, "input-bits") == 0) { input_precision = atof(value); } else if (strcmp(name, "input-channels") == 0) { input_channels = atoi(value); } else if (strcmp(name, "input-storage") == 0) { input_storage = string_to_storage(value); } else if (strcmp(name, "input-info") == 0) { char *p = strtok(value, ","); if (p) input_format = string_to_audio_format(p); p = strtok(NULL, ","); if (p) input_sample_rate = atoi(p); p = strtok(NULL, ","); if (p) input_precision = atoi(p); p = strtok(NULL, ","); if (p) input_channels = atoi(p); p = strtok(NULL, ","); if (p) input_byte_order = string_to_byte_order(p); p = strtok(NULL, ","); if (p) input_offset = atoi(p); } } } else /* old-style */ { extern char *optarg; extern int optind; optind = 0; while ((n = getopt(argc, argv, "+P:R:N:n:v:")) != -1) { switch (n) { case 'v': volume = atoi(optarg); break; case 'n': count = atoi(optarg); break; case 'N': list_count = atoi(optarg); break; case 'P': priority = atoi(optarg); break; case 'R': sample_rate = atoi(optarg); break; default: argc = optind; break; } } if (argc == optind) { for (i = 0; i < NCOMMANDS; i++) { if (strcmp(commands[i].name, argv[0]) == 0) { connection_reply(c, "%cerror=\"usage: %s %s\" command=%s", RPTP_ERROR, commands[i].name, commands[i].usage, argv[0]); return -1; } } } while (argv[optind] != NULL) { val = rplay_set(rp, RPLAY_APPEND, RPLAY_SOUND, argv[optind++], RPLAY_VOLUME, volume, RPLAY_COUNT, count, RPLAY_SAMPLE_RATE, sample_rate, RPLAY_RPTP_SEARCH, do_search, NULL); if (val < 0) { connection_reply(c, "%cerror=\"%s failed\" command=%s", RPTP_ERROR, argv[0], argv[0]); return -1; } } } if (rplay_set(rp, RPLAY_LIST_COUNT, list_count, NULL) < 0) { connection_reply(c, "%cerror=\"%s failed\" command=%s client-data=\"%s\"", RPTP_ERROR, argv[0], argv[0], client_data); return -1; } if (rplay_set(rp, RPLAY_PRIORITY, priority, NULL) < 0) { connection_reply(c, "%cerror=\"%s failed\" command=%s client-data=\"%s\"", RPTP_ERROR, argv[0], argv[0], client_data); return -1; } if (do_random && rplay_set(rp, RPLAY_RANDOM_SOUND, NULL) < 0) { connection_reply(c, "%cerror=\"%s failed\" command=%s client-data=\"%s\"", RPTP_ERROR, argv[0], argv[0], client_data); return -1; } if (list_name && rplay_set(rp, RPLAY_LIST_NAME, list_name, NULL) < 0) { connection_reply(c, "%cerror=\"%s failed\" command=%s client-data=\"%s\"", RPTP_ERROR, argv[0], argv[0], client_data); return -1; } /* Flows */ if (input == SOUND_FLOW && command == RPLAY_PLAY) { int spool_id, i; SOUND *s; char buf[RPTP_MAX_LINE], *sound_name, *p; #ifdef AUTH /* Flows require `write' access along with the previously checked `execute' access. */ if (!host_access(c->sin, HOST_WRITE)) { report(REPORT_NOTICE, "%s %s access denied\n", argv[0], inet_ntoa(c->sin.sin_addr)); connection_reply(c, "%cerror=\"access denied\" command=%s client-data=\"%s\"", RPTP_ERROR, argv[0], client_data); return -1; } #endif /* AUTH */ /* Generate a unique sound name. */ sound_name = (char *) rplay_get(rp, RPLAY_SOUND, 0); if (!sound_name) { connection_reply(c, "%cerror=\"missing required `sound' attribute\" command=%s client-data=\"%s\"", RPTP_ERROR, argv[0], client_data); return -1; } p = strrchr(sound_name, '/'); if (p) { sound_name = p + 1; } i = 0; do { if (i) { SNPRINTF(SIZE(buf, sizeof(buf)), "rplay%d-%s", i, sound_name); } else { SNPRINTF(SIZE(buf, sizeof(buf)), sound_name); } i++; } while (sound_lookup(buf, SOUND_DONT_FIND, NULL)); sound_name = cache_name(buf); rplay_set(rp, RPLAY_CHANGE, 0, RPLAY_SOUND, sound_name, RPLAY_RPTP_SEARCH, FALSE, /* never search */ NULL); s = sound_insert(sound_name, SOUND_NOT_READY, SOUND_FLOW); if (!s) { connection_reply(c, "%cerror=\"%s failed\" command=%s client-data=\"%s\"", RPTP_ERROR, argv[0], argv[0], client_data); return -1; } s->offset = input_offset; s->format = input_format; s->byte_order = input_byte_order; s->sample_rate = input_sample_rate; s->input_precision = input_precision; s->output_precision = input_precision; s->channels = input_channels; s->storage = input_storage; /* Grab a spool entry. */ spool_id = rplayd_play(rp, c->sin); if (spool_id < 0) { connection_reply(c, "%cerror=\"spool full\" command=%s client-data=\"%s\"", RPTP_ERROR, argv[0], client_data); sound_delete(s, 0); return -1; } connection_reply(c, "%cid=#%d sound=\"%s\" command=%s client-data=\"%s\"", RPTP_OK, spool_id, buf, argv[0], client_data); return 0; } else { switch (command) { case RPLAY_PLAY: val = rplayd_play(rp, c->sin); break; case RPLAY_STOP: val = rplayd_stop(rp, c->sin); break; case RPLAY_PAUSE: val = rplayd_pause(rp, c->sin); break; case RPLAY_CONTINUE: val = rplayd_continue(rp, c->sin); break; case RPLAY_DONE: val = rplayd_done(rp, c->sin); break; } if (val == 0) { connection_reply(c, "%cmessage=\"%s successful\" command=%s client-data=\"%s\"", RPTP_OK, argv[0], argv[0], client_data); } else if (val < 0) { connection_reply(c, "%cerror=\"%s failed\" command=%s client-data=\"%s\"", RPTP_ERROR, argv[0], argv[0], client_data); } return val; } } /* OBSOLETE */ #ifdef __STDC__ static int command_volume(CONNECTION *c, int argc, char **argv) #else static int command_volume(c, argc, argv) CONNECTION *c; int argc; char **argv; #endif { int volume; int n; #ifdef AUTH if (!host_access(c->sin, HOST_EXECUTE)) { report(REPORT_NOTICE, "%s volume access denied\n", inet_ntoa(c->sin.sin_addr)); connection_reply(c, "%cerror=\"access denied\" command=volume", RPTP_ERROR); return 0; } #endif /* AUTH */ if (argv[1] == NULL) { volume = rplay_audio_get_volume(); if (volume >= 0) { connection_reply(c, "%c%d", RPTP_OK, volume); } else { connection_reply(c, "%cerror=\"volume failed\" command=volume", RPTP_ERROR); } } else if (*argv[1] == '+') { volume = rplay_audio_get_volume(); if (volume < 0) { connection_reply(c, "%cerror=\"volume failed\" command=volume", RPTP_ERROR); } volume += atoi(argv[1] + 1); n = rplay_audio_set_volume(volume); if (n >= 0) { connection_reply(c, "%c%d", RPTP_OK, n); connection_notify(0, NOTIFY_VOLUME, n); } else { connection_reply(c, "%cerror=\"volume failed\" command=volume", RPTP_ERROR); } } else if (*argv[1] == '-') { volume = rplay_audio_get_volume(); if (volume < 0) { connection_reply(c, "%cerror=\"volume failed\" command=volume", RPTP_ERROR); } volume -= atoi(argv[1] + 1); n = rplay_audio_set_volume(volume); if (n >= 0) { connection_reply(c, "%c%d", RPTP_OK, n); connection_notify(0, NOTIFY_VOLUME, n); } else { connection_reply(c, "%cerror=\"volume failed\" command=volume", RPTP_ERROR); } } else { volume = atoi(argv[1]); n = rplay_audio_set_volume(volume); if (n >= 0) { connection_reply(c, "%c%d", RPTP_OK, n); connection_notify(0, NOTIFY_VOLUME, n); } else { connection_reply(c, "%cerror=\"volume failed\" command=volume", RPTP_ERROR); } } return 0; } #ifdef __STDC__ static int command_info(CONNECTION *c, int argc, char **argv) #else static int command_info(c, argc, argv) CONNECTION *c; int argc; char **argv; #endif { SOUND *s; char *sound_name = NULL; char *client_data = default_client_data; #ifdef AUTH if (!host_access(c->sin, HOST_READ)) { report(REPORT_NOTICE, "%s info %s - read access denied\n", inet_ntoa(c->sin.sin_addr), argv[1]); connection_reply(c, "%cerror=\"access denied\" command=info client-data=\"%s\"", RPTP_ERROR, client_data); return 0; } #endif /* AUTH */ if (strchr(command_buffer, '=')) { sound_name = rptp_parse(command_buffer, "sound"); client_data = rptp_parse(0, "client-data"); if (!client_data) { client_data = default_client_data; } } if (!sound_name) { sound_name = argv[1]; } /* s = sound_lookup (sound_name, SOUND_CREATE, NULL); */ s = sound_lookup(sound_name, SOUND_LOAD, NULL); if (s == NULL || s->status != SOUND_READY) { report(REPORT_NOTICE, "%s info %s - not found\n", inet_ntoa(c->sin.sin_addr), sound_name); connection_reply(c, "%cerror=\"%s not found\" command=info client-data=\"%s\"", RPTP_ERROR, sound_name, client_data); } else { connection_reply(c, "\ %csound=\"%s\" size=%d bits=%g sample-rate=%d channels=%d format=%s byte-order=%s input=%s seconds=%.2f command=info client-data=\"%s\"", RPTP_OK, s->name, s->size, s->input_precision, s->sample_rate, s->channels, audio_format_to_string(s->format), byte_order_to_string(s->byte_order), input_to_string(s->type), s->sample_rate && s->samples ? (double) s->samples / s->sample_rate : 0, client_data); } return 0; } #ifdef __STDC__ static int command_version(CONNECTION *c, int argc, char **argv) #else static int command_version(c, argc, argv) CONNECTION *c; int argc; char **argv; #endif { char *client_data; client_data = rptp_parse(command_buffer, "client-data"); if (!client_data) { client_data = default_client_data; } connection_reply(c, "%cversion=%s command=version client-data=\"%s\"", RPTP_OK, RPLAY_VERSION, client_data); return 0; } #ifdef __STDC__ static void do_events(char *event_string, int *mask, int *spool_id) #else static void do_events(event_string, mask, spool_id) char *event_string; int *mask; int *spool_id; #endif { char buf[RPTP_MAX_LINE]; int first = 1; char *p; int operator, bit; *spool_id = 0; strncpy(buf, event_string, sizeof(buf)); while (p = strtok(first ? buf : NULL, ",| ")) { first = 0; bit = 0; operator = 0; if (*p == '+') { operator = 0; p++; } else if (*p == '-') { operator = 1; p++; } if (strcmp(p, "all") == 0 || strcmp(p, "any") == 0) { bit = NOTIFY_ANY; } else if (strcmp(p, "none") == 0) { *mask = 0; } else if (strcmp(p, "play") == 0) { bit = NOTIFY_PLAY; } else if (strcmp(p, "stop") == 0) { bit = NOTIFY_STOP; } else if (strcmp(p, "pause") == 0) { bit = NOTIFY_PAUSE; } else if (strcmp(p, "continue") == 0) { bit = NOTIFY_CONTINUE; } else if (strcmp(p, "volume") == 0) { bit = NOTIFY_VOLUME; } else if (strcmp(p, "done") == 0) { bit = NOTIFY_DONE; } else if (strcmp(p, "skip") == 0) { bit = NOTIFY_SKIP; } else if (strcmp(p, "state") == 0) { bit = NOTIFY_STATE; } else if (strcmp(p, "flow") == 0) { bit = NOTIFY_FLOW; } else if (p[0] == '#') { *spool_id = atoi(p + 1); } else if (strcmp(p, "modify") == 0) { bit = NOTIFY_MODIFY; } else if (strcmp(p, "level") == 0) { bit = NOTIFY_LEVEL; } else if (strcmp(p, "position") == 0) { bit = NOTIFY_POSITION; } if (operator == 0) { SET_BIT(*mask, bit); } else { CLR_BIT(*mask, bit); } } /* If a spool id is set and there's no mask, assign a default mask which will notify everything than can happen to the spool entry. */ if (*spool_id && !*mask) { SET_BIT(*mask, NOTIFY_SPOOL); } } #ifdef __STDC__ static int command_wait(CONNECTION *c, int argc, char **argv) #else static int command_wait(c, argc, argv) CONNECTION *c; int argc; char **argv; #endif { EVENT *e; char *client_data; client_data = rptp_parse(command_buffer, "client-data"); if (!client_data) { client_data = default_client_data; } /* `wait' - wait for anything */ if (argc == 1) { e = event_create(EVENT_NOTIFY); SET_BIT(e->wait_mask, NOTIFY_ANY); event_insert(c, e); return 0; } /* `wait id=#spool-id' or `wait event=event,event,event' */ else if (argc == 2 && strchr(argv[1], '=')) { char *value; value = rptp_parse(argv[1], "id"); if (value && *value) { e = event_create(EVENT_NOTIFY); SET_BIT(e->wait_mask, NOTIFY_DONE); e->id = atoi(value + 1); event_insert(c, e); return 0; } value = rptp_parse(argv[1], "event"); if (value && *value) { e = event_create(EVENT_NOTIFY); do_events(value, &e->wait_mask, &e->id); event_insert(c, e); return 0; } connection_reply(c, "%cerror=\"unknown wait attribute `%s'\" command=wait client-data=\"%s\"", RPTP_ERROR, argv[1], client_data); return 0; } /* `wait play ...' */ else if (strcmp(argv[1], "play") == 0) { int id; id = do_execute(c, argc - 1, argv + 1); if (id > 0) { e = event_create(EVENT_NOTIFY); SET_BIT(e->wait_mask, NOTIFY_DONE); e->id = id; event_insert(c, e); } return 0; } else { /* XXX: Need to fix command_buffer */ int i, n; command_buffer[0] = '\0'; n = 0; for (i = 1; i < argc; i++) { SNPRINTF(SIZE(command_buffer + n, sizeof(command_buffer) - n), argv[i]); n += strlen(argv[i]); if (i + 1 != argc) { SNPRINTF(SIZE(command_buffer + n, sizeof(command_buffer) - n), " "); n++; } } return do_command(c, argc - 1, argv + 1); } } #ifdef __STDC__ static int command_status(CONNECTION *c, int argc, char **argv) #else static int command_status(c, argc, argv) CONNECTION *c; int argc; char **argv; #endif { EVENT *e; e = event_create(EVENT_WRITE, rplayd_status()); event_insert(c, e); return 0; } /* OBSOLETE */ #ifdef __STDC__ static int command_application(CONNECTION *c, int argc, char **argv) #else static int command_application(c, argc, argv) CONNECTION *c; int argc; char **argv; #endif { int i, n; char buf[RPTP_MAX_LINE]; buf[0] = '\0'; n = 0; for (i = 1; i < argc; i++) { SNPRINTF(SIZE(buf + n, sizeof(buf) - n), argv[i]); n += strlen(argv[i]); if (i + 1 != argc) { SNPRINTF(SIZE(buf + n, sizeof(buf) - n), " "); n++; } } if (c->application) { free(c->application); } c->application = strdup(buf); connection_reply(c, "%c%s", RPTP_OK, c->application); return 0; } #ifdef DEBUG #ifdef __STDC__ static int command_die(CONNECTION *c, int argc, char **argv) #else static int command_die(c, argc, argv) CONNECTION *c; int argc; char **argv; #endif { report(REPORT_DEBUG, "time to die...\n"); connection_close(c); done(0); return -1; /* not reached */ } #endif /* DEBUG */ #ifdef __STDC__ static int command_reset(CONNECTION *c, int argc, char **argv) #else static int command_reset(c, argc, argv) CONNECTION *c; int argc; char **argv; #endif { char *client_data; client_data = rptp_parse(command_buffer, "client-data"); if (!client_data) { client_data = default_client_data; } #ifdef AUTH if (!host_access(c->sin, HOST_EXECUTE)) { report(REPORT_NOTICE, "%s reset access denied\n", inet_ntoa(c->sin.sin_addr)); connection_reply(c, "%cerror=\"access denied\" command=reset client-data=\"%s\"", RPTP_ERROR, client_data); return 0; } #endif /* AUTH */ need_reset(); connection_reply(c, "%cmessage=\"reset successful\" command=reset client-data=\"%s\"", RPTP_OK, client_data); return 0; } #ifdef __STDC__ static int command_skip(CONNECTION *c, int argc, char **argv) #else static int command_skip(c, argc, argv) CONNECTION *c; int argc; char **argv; #endif { SPOOL *sp; int id = 0, count = 1; /* default */ int nskipped = 0; char *p; char *client_data; client_data = rptp_parse(command_buffer, "client-data"); if (!client_data) { client_data = default_client_data; } #ifdef AUTH if (!host_access(c->sin, HOST_EXECUTE)) { report(REPORT_NOTICE, "%s skip access denied\n", inet_ntoa(c->sin.sin_addr)); connection_reply(c, "%cerror=\"access denied\" command=skip client-data=\"%s\"", RPTP_ERROR, client_data); return 0; } #endif /* AUTH */ p = rptp_parse(0, "id"); if (p) { id = atoi(p + 1); } p = rptp_parse(0, "count"); if (p) { count = atoi(p); } for (sp = spool; sp; sp = sp->next) { if (!id || sp->id == id) { spool_skip(sp, count); nskipped++; } } if (nskipped) { connection_reply(c, "%cmessage=\"skipped\" command=skip client-data=\"%s\"", RPTP_OK, client_data); } else { connection_reply(c, "%cerror=\"skip failed\" command=skip client-data=\"%s\"", RPTP_ERROR, client_data); } return 0; } #ifdef __STDC__ static int command_set(CONNECTION *c, int argc, char **argv) #else static int command_set(c, argc, argv) CONNECTION *c; int argc; char **argv; #endif { char *name, *value; BUFFER *b; EVENT *e; int volume_changed = 0; int priority_threshold_changed = 0; int audio_port_changed = 0; int notify_enabled = 0; SPOOL *sp; int notify_mask = 0; int notify_id = 0; char *client_data; char buf[RPTP_MAX_LINE]; client_data = rptp_parse(command_buffer, "client-data"); if (!client_data) { client_data = default_client_data; } #ifdef AUTH if (!host_access(c->sin, HOST_EXECUTE)) { report(REPORT_NOTICE, "%s set access denied\n", inet_ntoa(c->sin.sin_addr)); connection_reply(c, "%cerror=\"access denied\" command=set client-data=\"%s\"", RPTP_ERROR, client_data); return 0; } #endif /* AUTH */ b = buffer_create(); b->buf[0] = RPTP_OK; b->buf[1] = '\0'; b->nbytes = 1; rptp_parse(command_buffer, 0); while (name = rptp_parse(0, 0)) { value = rptp_parse(0, name); if (strcmp(name, "application") == 0) /* `application=value' */ { if (value && *value) { if (c->application) { free(c->application); } c->application = strdup(value); } SNPRINTF(SIZE(buf, sizeof(buf)), "application=\"%s\"", c->application ? c->application : "-1"); strncat(b->buf + b->nbytes, buf, BUFFER_SIZE - b->nbytes); b->nbytes += strlen(buf); } else if (strcmp(name, "notify") == 0) /* `notify=[event,...]' */ { if (value) { do_events(value, &c->notify_mask, &c->notify_id); } if (!c->notify_mask) { SNPRINTF(SIZE(buf, sizeof(buf)), "notify=none"); strncat(b->buf + b->nbytes, buf, BUFFER_SIZE - b->nbytes); b->nbytes += strlen(buf); } else { SNPRINTF(SIZE(buf, sizeof(buf)), "notify=\"%s\"", value); strncat(b->buf + b->nbytes, buf, BUFFER_SIZE - b->nbytes); b->nbytes += strlen(buf); notify_enabled++; } } else if (strcmp(name, "volume") == 0) /* `volume=[+|-]value' */ { int volume = rplay_audio_get_volume(); if (value && *value) { switch (value[0]) { case '+': volume += atoi(value + 1); break; case '-': volume -= atoi(value + 1); break; case '*': volume *= atoi(value + 1); break; case '/': volume /= atoi(value + 1); break; default: volume = atoi(value); } volume = rplay_audio_set_volume(volume); } if (volume >= 0) { SNPRINTF(SIZE(buf, sizeof(buf)), "volume=%d", volume); strncat(b->buf + b->nbytes, buf, BUFFER_SIZE - b->nbytes); b->nbytes += strlen(buf); volume_changed++; } else { SNPRINTF(SIZE(buf, sizeof(buf)), "volume=-1"); strncat(b->buf + b->nbytes, buf, BUFFER_SIZE - b->nbytes); b->nbytes += strlen(buf); } } else if (strcmp(name, "priority-threshold") == 0) /* `priority-threshold=value' */ { if (value && *value) { rplay_priority_threshold = atoi(value); if (rplay_priority_threshold < RPLAY_MIN_PRIORITY) { rplay_priority_threshold = RPLAY_MIN_PRIORITY; } else if (rplay_priority_threshold > RPLAY_MAX_PRIORITY) { rplay_priority_threshold = RPLAY_MAX_PRIORITY; } priority_threshold_changed++; } SNPRINTF(SIZE(buf, sizeof(buf)), "priority-threshold=%d", rplay_priority_threshold); strncat(b->buf + b->nbytes, buf, BUFFER_SIZE - b->nbytes); b->nbytes += strlen(buf); } else if (strcmp(name, "notify-rate") == 0) /* `notify-rate=value' */ { if (value && *value) { int i; double rate; rate = atof(value); for (i = 0; i < NOTIFY_RATE_MAX; i++) { c->notify_rate[i].rate = rate; c->notify_rate[i].next = 0.0; } } SNPRINTF(SIZE(buf, sizeof(buf)), "level-notify-rate=%.2f position-notify-rate=%.2f", c->notify_rate[NOTIFY_RATE_LEVEL].rate, c->notify_rate[NOTIFY_RATE_POSITION].rate); strncat(b->buf + b->nbytes, buf, BUFFER_SIZE - b->nbytes); b->nbytes += strlen(buf); } else if (strcmp(name, "level-notify-rate") == 0) { if (value && *value) { c->notify_rate[NOTIFY_RATE_LEVEL].rate = atof(value); c->notify_rate[NOTIFY_RATE_LEVEL].next = 0.0; } SNPRINTF(SIZE(buf, sizeof(buf)), "level-notify-rate=%.2f", c->notify_rate[NOTIFY_RATE_LEVEL].rate); strncat(b->buf + b->nbytes, buf, BUFFER_SIZE - b->nbytes); b->nbytes += strlen(buf); } else if (strcmp(name, "position-notify-rate") == 0) { if (value && *value) { c->notify_rate[NOTIFY_RATE_POSITION].rate = atof(value); c->notify_rate[NOTIFY_RATE_POSITION].next = 0.0; } SNPRINTF(SIZE(buf, sizeof(buf)), "position-notify-rate=%.2f", c->notify_rate[NOTIFY_RATE_POSITION].rate); strncat(b->buf + b->nbytes, buf, BUFFER_SIZE - b->nbytes); b->nbytes += strlen(buf); } else if (strcmp(name, "audio-port") == 0) { int n; optional_port = rplay_audio_port; if (strstr(value, "none")) { optional_port = 0; } if (strstr(value, "speaker")) { SET_BIT(optional_port, RPLAY_AUDIO_PORT_SPEAKER); } if (strstr(value, "headphone")) { SET_BIT(optional_port, RPLAY_AUDIO_PORT_HEADPHONE); } if (strstr(value, "lineout")) { SET_BIT(optional_port, RPLAY_AUDIO_PORT_LINEOUT); } if (optional_port != rplay_audio_port) { n = rplay_audio_init(); if (n >= 0) { audio_port_changed++; } } else { n = 0; } if (n < 0) { SNPRINTF(SIZE(buf, sizeof(buf)), "audio-port=-1"); strncat(b->buf + b->nbytes, buf, BUFFER_SIZE - b->nbytes); b->nbytes += strlen(buf); } else { SNPRINTF(SIZE(buf, sizeof(buf)), "audio-port=%s", value); strncat(b->buf + b->nbytes, buf, BUFFER_SIZE - b->nbytes); b->nbytes += strlen(buf); } } else if (strcmp(name, "audio-info") == 0) { char info[1024], *p; SPOOL *sp, *sp_next; int bufsize, rate; /* Stop all sounds. */ for (sp = spool; sp; sp = sp_next) { sp_next = sp->next; spool_stop(sp); } /* Example: ulaw,8000,8,1 */ strncpy(info, value, sizeof(info)); p = strtok(info, ", "); if (p) optional_format = string_to_audio_format(p); p = strtok(NULL, ","); if (p) optional_sample_rate = atoi(p); p = strtok(NULL, ","); if (p) optional_precision = atoi(p); p = strtok(NULL, ","); if (p) optional_channels = atoi(p); #ifndef HAVE_OSS bufsize = rplay_audio_bufsize; /* XXX: force recalculation */ rplay_audio_bufsize = 0; #endif /* !HAVE_OSS */ rate = rplay_audio_rate; rplay_audio_rate = 0; if (rplayd_audio_init() < 0) { SNPRINTF(SIZE(buf, sizeof(buf)), "audio-info=-1"); strncat(b->buf + b->nbytes, buf, BUFFER_SIZE - b->nbytes); b->nbytes += strlen(buf); #ifndef HAVE_OSS rplay_audio_bufsize = bufsize; #endif /* !HAVE_OSS */ rplay_audio_rate = rate; } else { SNPRINTF(SIZE(buf, sizeof(buf)), "audio-info=%s", value); strncat(b->buf + b->nbytes, buf, BUFFER_SIZE - b->nbytes); b->nbytes += strlen(buf); } } else if (strcmp(name, "audio-close") == 0) { if (value && *value) { extern int rplay_audio_timeout; rplay_audio_timeout = atoi(value); SNPRINTF(SIZE(buf, sizeof(buf)), "audio-close=%d", rplay_audio_timeout); strncat(b->buf + b->nbytes, buf, BUFFER_SIZE - b->nbytes); b->nbytes += strlen(buf); } } else { SNPRINTF(SIZE(buf, sizeof(buf)), "%s=-1", name); strncat(b->buf + b->nbytes, buf, BUFFER_SIZE - b->nbytes); b->nbytes += strlen(buf); } SNPRINTF(SIZE(buf, sizeof(buf)), " "); strncat(b->buf + b->nbytes, buf, BUFFER_SIZE - b->nbytes); b->nbytes += strlen(buf); } SNPRINTF(SIZE(buf, sizeof(buf)), "command=set client-data=\"%s\"\r\n", client_data); strncat(b->buf + b->nbytes, buf, BUFFER_SIZE - b->nbytes); b->nbytes += strlen(buf); e = event_create(EVENT_WRITE, b); event_insert(c, e); if (notify_enabled) { /* Notify the current status. */ for (sp = spool; sp; sp = sp->next) { switch (sp->state) { case SPOOL_PLAY: connection_notify(c, NOTIFY_PLAY, sp); break; case SPOOL_PAUSE: connection_notify(c, NOTIFY_PAUSE, sp); break; } } connection_notify(c, NOTIFY_VOLUME, rplay_audio_volume); e = event_create(EVENT_NOTIFY); event_insert(c, e); } if (volume_changed) { connection_notify(0, NOTIFY_VOLUME, rplay_audio_volume); } if (priority_threshold_changed || audio_port_changed) { connection_notify(0, NOTIFY_STATE); } connection_want_level_notify = 0; for (c = connections; c; c = c->next) { if (BIT(c->notify_mask, NOTIFY_LEVEL) || (c->event && BIT(c->event->wait_mask, NOTIFY_LEVEL))) { connection_want_level_notify++; } } return 0; } #ifdef __STDC__ static int command_modify(CONNECTION *c, int argc, char **argv) #else static int command_modify(c, argc, argv) CONNECTION *c; int argc; char **argv; #endif { SPOOL *sp; int id = 0; char *p; int new_sample_rate = -1; int new_volume = -1; int new_count = -1; int new_priority = -1; int new_list_count = -1; char *new_client_data = NULL; int modified, total_modified = 0; #ifdef AUTH if (!host_access(c->sin, HOST_EXECUTE)) { report(REPORT_NOTICE, "%s modify access denied\n", inet_ntoa(c->sin.sin_addr)); connection_reply(c, "%cerror=\"access denied\" command=modify", RPTP_ERROR); return 0; } #endif /* AUTH */ p = rptp_parse(command_buffer, "id"); if (!p || !*p) { connection_reply(c, "%cerror=\"missing `id'\" command=modify", RPTP_ERROR); return 0; } id = atoi(p + 1); p = rptp_parse(0, "count"); if (p) { new_count = atoi(p); } p = rptp_parse(0, "list-count"); if (p) { new_list_count = atoi(p); } p = rptp_parse(0, "priority"); if (p) { new_priority = atoi(p); } p = rptp_parse(0, "sample-rate"); if (p) { new_sample_rate = atoi(p); } p = rptp_parse(0, "volume"); if (p) { new_volume = atoi(p); } p = rptp_parse(0, "client-data"); if (p) { new_client_data = p; } for (sp = spool; sp; sp = sp->next) { if (!id || sp->id == id) { modified = 0; if (new_count != -1) { spool_set_count(sp, new_count); modified++; } if (new_list_count != -1) { spool_set_list_count(sp, new_list_count); modified++; } if (new_priority != -1) { spool_set_priority(sp, new_priority); modified++; } if (new_sample_rate != -1) { spool_set_sample_rate(sp, new_sample_rate); modified++; } if (new_volume != -1) { spool_set_volume(sp, new_volume); modified++; } if (new_client_data) { spool_set_client_data(sp, new_client_data); modified++; } if (modified) { connection_notify(c, NOTIFY_MODIFY, sp); total_modified++; } } } if (total_modified) { connection_reply(c, "%cmessage=\"modified\" command=modify", RPTP_OK); } else { connection_reply(c, "%cerror=\"nothing modified\" command=modify", RPTP_ERROR); } return 0; } #ifdef __STDC__ static int command_monitor(CONNECTION *c, int argc, char **argv) #else static int command_monitor(c, argc, argv) CONNECTION *c; int argc; char **argv; #endif { EVENT *e; #ifdef AUTH if (!host_access(c->sin, HOST_MONITOR)) { report(REPORT_NOTICE, "%s monitor - monitor access denied\n", inet_ntoa(c->sin.sin_addr)); connection_reply(c, "%cerror=\"access denied\" command=monitor", RPTP_ERROR); return 0; } #endif /* AUTH */ if (monitor_count == 0) { monitor_alloc(); } monitor_count++; connection_reply(c, "%caudio-info=\"%s,%d,%d,%d,%s\"", RPTP_OK, audio_format_to_string(rplay_audio_format), rplay_audio_sample_rate, rplay_audio_precision, rplay_audio_channels, byte_order_to_string(RPLAY_AUDIO_BYTE_ORDER)); e = event_create(EVENT_WAIT_MONITOR); event_insert(c, e); c->monitor = 1; return 0; } rplay-3.3.2/rplayd/command.h100644 153 62 2176 6671423012 14406 0ustar boynsstaff/* $Id: command.h,v 1.3 1999/03/10 07:58:02 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _command_h #define _command_h #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "connection.h" #ifdef __STDC__ extern int command (CONNECTION *c, char *buf); #else extern int command ( /* CONNECTION *c, char *buf */ ); #endif #endif /* _command_h */ rplay-3.3.2/rplayd/connection.c100644 153 62 150641 6671423013 15164 0ustar boynsstaff/* $Id: connection.c,v 1.6 1999/03/10 07:58:03 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #ifdef HAVE_STRING_H #include #endif #ifdef __STDC__ #include #else #include #endif #include "rplayd.h" #include "connection.h" #include "command.h" #include "version.h" #include "sound.h" #include "server.h" #include "host.h" #include "cache.h" #include "rplay.h" #include "spool.h" #include "timer.h" #include "buffer.h" #include "strdup.h" CONNECTION *connections = NULL; int nconnections = 0; int connection_want_level_notify = 0; int connection_level_notify = 0; #undef EVENT_DEBUG #ifdef EVENT_DEBUG static void event_print(CONNECTION *c, char *message); #endif /* * create a connection object * types are CONNECTION_CLIENT and CONNECTION_SERVER */ #ifdef __STDC__ CONNECTION * connection_create(int type) #else CONNECTION * connection_create(type) int type; #endif { CONNECTION *c; int i; c = (CONNECTION *) malloc(sizeof(CONNECTION)); if (c == NULL) { report(REPORT_ERROR, "connection_create: out of memory\n"); done(1); } c->type = type; c->fd = -1; c->event = NULL; c->ep = &c->event; c->server = NULL; c->time = time(0); c->application = NULL; c->notify_mask = 0; c->notify_id = 0; for (i = 0; i < NOTIFY_RATE_MAX; i++) { c->notify_rate[i].rate = 0.0; c->notify_rate[i].next = 0.0; } c->monitor = 0; /* * insert new connection into the connection list */ c->prev = NULL; c->next = connections; if (connections) { connections->prev = c; } connections = c; if (type == CONNECTION_CLIENT) { nconnections++; } return c; } /* * destroy the connection and remove it from the connection list */ #ifdef __STDC__ void connection_destroy(CONNECTION *c) #else void connection_destroy(c) CONNECTION *c; #endif { if (c->type == CONNECTION_CLIENT) { nconnections--; } if (c->prev) { c->prev->next = c->next; } else { connections = c->next; } if (c->next) { c->next->prev = c->prev; } if (c->application) { free(c->application); } free((char *) c); connection_want_level_notify = 0; for (c = connections; c; c = c->next) { if (BIT(c->notify_mask, NOTIFY_LEVEL) || (c->event && BIT(c->event->wait_mask, NOTIFY_LEVEL))) { connection_want_level_notify++; } } } /* * start a server connection to try and find the given sound * * The sound can be NULL which means that events have already * been created and will be forwarded to this server. */ #ifdef __STDC__ CONNECTION * connection_server_open(SERVER *server, SOUND *sound) #else CONNECTION * connection_server_open(server, sound) SERVER *server; SOUND *sound; #endif { int n; CONNECTION *c; EVENT *e; /* * see if there is already a connection to that server */ for (c = connections; c; c = c->next) { if (c->type == CONNECTION_SERVER && c->server == server) { break; } } if (c == NULL) { c = connection_create(CONNECTION_SERVER); c->server = server; c->sin = server->sin; } if (c->fd == -1) { c->fd = socket(AF_INET, SOCK_STREAM, 0); if (c->fd < 0) { report(REPORT_ERROR, "connection_open_server: socket: %s\n", sys_err_str(errno)); done(1); } fd_nonblock(c->fd); /* * ping the server */ connection_server_ping(c); /* * try to connect to the server immediately */ report(REPORT_DEBUG, "%s server connection attempt\n", inet_ntoa(c->server->sin.sin_addr)); n = connect(c->fd, (struct sockaddr *) &c->server->sin, sizeof(c->server->sin)); e = event_create(EVENT_CONNECT); e->time = time(0); event_insert(c, e); } /* * create events to try and find the sound */ if (sound) { BUFFER *b; b = buffer_create(); SNPRINTF(SIZE(b->buf, BUFFER_SIZE), "find %s\r\n", sound->name); b->nbytes = strlen(b->buf); e = event_create(EVENT_WRITE_FIND, b, sound); event_insert(c, e); } return c; } #ifdef __STDC__ void connection_server_reopen(CONNECTION *c) #else void connection_server_reopen(c) CONNECTION *c; #endif { EVENT *e; CONNECTION *server; close(c->fd); c->fd = -1; e = c->event; c->event = NULL; c->ep = &c->event; server = connection_server_open(c->server, NULL); if (server != c) { report(REPORT_ERROR, "connection_server_reopen: server != c\n"); done(1); } event_insert(server, e); } /* * send a ping packet to the server */ #ifdef __STDC__ void connection_server_ping(CONNECTION *c) #else void connection_server_ping(c) CONNECTION *c; #endif { struct sockaddr_in ping_addr; memcpy((char *) &ping_addr, (char *) &c->server->sin, sizeof(ping_addr)); ping_addr.sin_port = htons(RPLAY_PORT); rplay_ping_sockaddr_in(&ping_addr); } /* * open a client connection */ #ifdef __STDC__ void connection_client_open(int sock_fd) #else void connection_client_open(sock_fd) int sock_fd; #endif { struct sockaddr_in f; int fd, flen = sizeof(f); CONNECTION *c; EVENT *e; char line[RPTP_MAX_LINE]; fd = accept(sock_fd, (struct sockaddr *) &f, &flen); if (fd < 0) { report(REPORT_ERROR, "accept: %s\n", sys_err_str(errno)); return; } #ifdef DEBUG report(REPORT_DEBUG, "%s client connection request\n", inet_ntoa(f.sin_addr)); #endif #ifdef AUTH /* * see if this host has any access */ if (!host_access(f, HOST_READ) && !host_access(f, HOST_WRITE) && !host_access(f, HOST_WRITE)) { report(REPORT_NOTICE, "%s RPTP access denied\n", inet_ntoa(f.sin_addr)); SNPRINTF(SIZE(line, sizeof(line)), "%cerror=\"connection refused\"\r\n", RPTP_ERROR); write(fd, line, strlen(line)); close(fd); return; } #endif /* AUTH */ /* * see if there are too many connections */ if (nconnections + 1 == RPTP_MAX_CONNECTIONS) { SNPRINTF(SIZE(line, sizeof(line)), "%cerror=\"connection refused\"\r\n", RPTP_ERROR); write(fd, line, strlen(line)); close(fd); return; } c = connection_create(CONNECTION_CLIENT); c->fd = fd; fd_nonblock(c->fd); c->sin = f; #if 1 report(REPORT_NOTICE, "%s client connection established\n", inet_ntoa(c->sin.sin_addr)); #endif /* Greet the connection with the server's status. */ e = event_create(EVENT_WRITE, rplayd_status()); event_insert(c, e); } /* * Update connections by monitoring the read and write fd_sets. * * If the given fd_sets are NULL then select must be called to update * the fd_sets. (This should not be necessary anymore) */ #ifdef __STDC__ void connection_update(fd_set * read_fds, fd_set * write_fds) #else void connection_update(read_fds, write_fds) fd_set *read_fds; fd_set *write_fds; #endif { int i, n, size; CONNECTION *c; struct timeval tv; fd_set rfds, wfds; time_t t; char buf[RPTP_MAX_LINE]; EVENT *e; SOUND *s; SPOOL *sp; fd_set cmask; if (read_fds == NULL && write_fds == NULL) { int nfds; tv.tv_sec = 0; tv.tv_usec = 0; rfds = read_mask; wfds = write_mask; FD_CLR(rplay_fd, &rfds); #ifdef __hpux nfds = select(FD_SETSIZE, (int *) &rfds, (int *) &wfds, 0, &tv); #else nfds = select(FD_SETSIZE, &rfds, &wfds, 0, &tv); #endif if (nfds == 0) { /* nothing to do */ return; } else if (nfds < 0) { report(REPORT_ERROR, "connection_update: select: %s\n", sys_err_str(errno)); done(1); } } else { rfds = *read_fds; wfds = *write_fds; } /* * Check for new RPTP connections. */ if (FD_ISSET(rptp_fd, &rfds)) { connection_client_open(rptp_fd); } #ifdef OTHER_RPLAY_PORTS if (FD_ISSET(other_rptp_fd, &rfds)) { connection_client_open(other_rptp_fd); } #endif t = time(0); /* It's not safe to simply traverse the connection list since connections can be closed during this loop. Instead a bitmask is used to keep track of the connections that have been updated. (efence) */ FD_ZERO(&cmask); for (;;) { for (c = connections; c; c = c->next) { if (!FD_ISSET(c->fd, &cmask)) { break; } } if (c == NULL) { break; } FD_SET(c->fd, &cmask); /* connection has no events */ if (c->event == NULL) { continue; } /* * read events */ if (FD_ISSET(c->fd, &rfds)) { c->time = t; switch (c->event->type) { case EVENT_READ_SOUND: restart: n = read(c->fd, c->event->buffer->buf, MIN(c->event->nleft, sizeof(c->event->buffer->buf))); if (n < 0 && (errno == EINTR || errno == EAGAIN)) { goto restart; } #ifdef DEBUG report(REPORT_DEBUG, "- %s read %d (%d)\n", inet_ntoa(c->sin.sin_addr), n, c->event->nleft); #endif if (n <= 0) { event_update(c); } else { int r; restart1: r = write(c->event->fd, c->event->buffer->buf, n); if (r < 0 && (errno == EINTR || errno == EAGAIN)) { goto restart1; } c->event->nleft -= n; c->event->byte_offset += n; if (c->event->nleft == 0) { c->event->success++; event_update(c); } } break; case EVENT_READ_FLOW: /* Find the spool entry. */ sp = spool_find(c->event->id); if (!sp) { if (c->event->nbytes == -1) /* single-put flow */ { event_update(c); break; } /* The spool entry no longer exists. The rest of this flow must be read -- the next `put' will fail. */ c->event->buffer = buffer_create(); retry: n = read(c->fd, c->event->buffer->buf, MIN(BUFFER_SIZE, c->event->nleft)); if (n < 0 && (errno == EINTR || errno == EAGAIN)) { goto retry; } #if 0 report(REPORT_DEBUG, "eating %d flow bytes (%d), id=#%d\n", n, c->event->nleft, c->event->id); #endif buffer_destroy(c->event->buffer); /* Eat the flow. */ c->event->buffer = NULL; if (n <= 0) { event_update(c); break; } c->event->nleft -= n; if (c->event->nleft <= 0) { c->event->success++; event_update(c); break; } break; } /* Pause the connection if the high_water_mark has been exceeded. */ if (sp->si && ((sp->si->water_mark - sp->si->offset) >= sp->si->high_water_mark)) { connection_notify(0, NOTIFY_FLOW, sp); connection_flow_pause(sp); break; } /* Read data from the flow. single-put flows will always try to read BUFFER_SIZE. */ c->event->buffer = buffer_create(); /* calculate the number of bytes to read without going over the high_water_mark. */ #if 1 size = MIN(BUFFER_SIZE, sp->si ? sp->si->high_water_mark - (sp->si->water_mark - sp->si->offset) : BUFFER_SIZE); #else size = MIN(BUFFER_SIZE, c->event->nbytes == -1 ? BUFFER_SIZE : c->event->nleft); #endif redo: n = read(c->fd, c->event->buffer->buf, size); if (n < 0 && (errno == EINTR || errno == EAGAIN)) { goto redo; } if (n <= 0) { /* End of a single-put flow */ if (c->event->nbytes == -1) { spool_done(sp); connection_close(c); } else { event_update(c); } break; } /* Add the buffer to the sound's flow. */ c->event->buffer->nbytes = n; if (spool_flow_insert(sp, c->event->buffer) < 0) { c->event->buffer = NULL; /* efence */ break; } c->event->buffer = NULL; c->event->byte_offset += n; if (c->event->nbytes != -1) { c->event->nleft -= n; } /* single-put flows don't terminate here */ if (c->event->nbytes != -1 && c->event->nleft <= 0) { c->event->success++; event_update(c); } break; case EVENT_NOTIFY: /* Replace the current notify event with a read_command. */ e = event_create(EVENT_READ_COMMAND, buffer_create()); event_replace(c, e); /* fall fall fall */ default: /* Read a command. */ restart2: n = recv(c->fd, c->event->ptr, c->event->nleft, MSG_PEEK); if (n < 0 && (errno == EINTR || errno == EAGAIN)) { goto restart2; } #if 0 report(REPORT_DEBUG, "- %s recv %d (%d)\n", inet_ntoa(c->sin.sin_addr), n, c->event->nleft); #endif if (n <= 0) { event_update(c); } else { /* * search for a newline and replace \r and \n with \0 */ for (i = 0; i < n; i++) { if (c->event->ptr[i] == '\r') { c->event->ptr[i] = '\0'; } else if (c->event->ptr[i] == '\n') { c->event->ptr[i] = '\0'; c->event->success++; break; } } restart3: n = read(c->fd, buf, i == n ? n : i + 1); if (n < 0 && (errno == EINTR || errno == EAGAIN)) { goto restart3; } if (n <= 0) { c->event->success = 0; event_update(c); } else { c->event->ptr += n; c->event->nleft -= n; if (c->event->success || c->event->nleft == 0) { event_update(c); } } } break; } } /* * write events */ else if (FD_ISSET(c->fd, &wfds)) { c->time = t; switch (c->event->type) { case EVENT_CONNECT: event_update(c); break; default: again: n = write(c->fd, c->event->ptr, c->event->nleft); #if 0 report(REPORT_DEBUG, "- %s write %d (%d)\n", inet_ntoa(c->sin.sin_addr), n, c->event->nleft); #endif if (n <= 0) { if ((errno == EINTR || errno == EAGAIN)) { goto again; } event_update(c); } else { c->event->ptr += n; c->event->nleft -= n; c->event->byte_offset += n; if (c->event->nleft == 0) { if (c->event->type == EVENT_WRITE_SOUND) { n = sound_fill(c->event->si, c->event->buffer, 1); if (n > 0) { c->event->nleft = c->event->buffer->nbytes; c->event->ptr = c->event->buffer->buf; c->event->start = c->event->buffer->buf; } else { sound_close(c->event->si); c->event->si = NULL; /* efence */ c->event->success++; event_update(c); } } else { c->event->success++; event_update(c); } } } break; } } } } /* * close and destroy the connection */ #ifdef __STDC__ void connection_close(CONNECTION *c) #else void connection_close(c) CONNECTION *c; #endif { EVENT *e, *next; SOUND *s; SPOOL *sp; switch (c->type) { case CONNECTION_CLIENT: report(REPORT_NOTICE, "%s client connection closed\n", inet_ntoa(c->sin.sin_addr)); break; case CONNECTION_SERVER: report(REPORT_NOTICE, "%s server connection closed\n", inet_ntoa(c->sin.sin_addr)); break; } FD_CLR(c->fd, &read_mask); FD_CLR(c->fd, &write_mask); if (c->monitor) { monitor_count--; } close(c->fd); /* * destroy any events that are left */ for (e = c->event; e; e = next) { next = e->next; switch (e->type) { case EVENT_WRITE_FIND: case EVENT_READ_FIND_REPLY: case EVENT_WRITE_GET: case EVENT_READ_GET_REPLY: case EVENT_READ_SOUND: spool_remove(e->sound); sound_delete(e->sound, 1); break; case EVENT_READ_FLOW: case EVENT_WAIT_FLOW: case EVENT_PIPE_FLOW: /* Dunno if this should happen: */ #if 0 sp = spool_find(e->id); s = sp->sound[sp->curr_sound]; spool_remove(s); sound_delete(s, 0); #endif break; } event_destroy(e); } c->event = NULL; c->ep = &c->event; connection_destroy(c); } /* * update the fd_sets for the connect */ #ifdef __STDC__ void connection_update_fdset(CONNECTION *c) #else void connection_update_fdset(c) CONNECTION *c; #endif { FD_CLR(c->fd, &read_mask); FD_CLR(c->fd, &write_mask); if (c->event == NULL) { return; } switch (c->event->type) { case EVENT_READ_COMMAND: case EVENT_READ_SOUND: case EVENT_READ_CONNECT_REPLY: case EVENT_READ_FIND_REPLY: case EVENT_READ_GET_REPLY: case EVENT_NOTIFY: case EVENT_READ_FLOW: case EVENT_WAIT_MONITOR: FD_SET(c->fd, &read_mask); break; case EVENT_WRITE: case EVENT_WRITE_SOUND: case EVENT_WRITE_FIND: case EVENT_WRITE_GET: case EVENT_CONNECT: case EVENT_WRITE_TIMEOUT: case EVENT_WRITE_MONITOR: FD_SET(c->fd, &write_mask); break; case EVENT_WAIT_FLOW: case EVENT_PIPE_FLOW: /* nothing */ break; default: report(REPORT_ERROR, "connection_update_fdset: unknown event type '%d'\n", c->event->type); done(1); } } /* * send the connection a reply message */ #ifdef __STDC__ void connection_reply(CONNECTION *c, char *fmt,...) #else void connection_reply(va_alist) va_dcl #endif { va_list args; EVENT *e; BUFFER *b; #ifdef __STDC__ va_start(args, fmt); #else CONNECTION *c; char *fmt; va_start(args); c = va_arg(args, CONNECTION *); fmt = va_arg(args, char *); #endif b = buffer_create(); VSNPRINTF(SIZE(b->buf, BUFFER_SIZE), fmt, args); va_end(args); b->nbytes = strlen(b->buf); SNPRINTF(SIZE(b->buf + b->nbytes, BUFFER_SIZE - b->nbytes), "\r\n"); b->nbytes += 2; e = event_create(EVENT_WRITE, b); event_first(c, e); } /* * close all connections */ void connection_cleanup() { CONNECTION *c, *c_next; for (c = connections; c; c = c_next) { c_next = c->next; connection_close(c); } } /* * Check all connections to see if rplayd can enter idle mode. */ int connection_idle() { CONNECTION *c; int idle = 1; for (c = connections; c && idle; c = c->next) { if (c->event && c->event->type != EVENT_NOTIFY && !c->monitor) { idle = 0; } } return idle; } /* * timeout all idle connections */ void connection_check_timeout() { time_t t; CONNECTION *c, *next; if (!rptp_timeout) { return; } t = time(0); for (c = connections; c; c = next) { next = c->next; if (t - c->time >= rptp_timeout) { connection_timeout(c); } } } /* * timeout an idle connection */ #ifdef __STDC__ void connection_timeout(CONNECTION *c) #else void connection_timeout(c) CONNECTION *c; #endif { BUFFER *b; EVENT *e; /* * Don't timeout clients that are waiting. */ if (c->event) { switch (c->event->type) { case EVENT_NOTIFY: case EVENT_WAIT_MONITOR: return; } } if (c->type == CONNECTION_SERVER) { report(REPORT_DEBUG, "%s server connection timeout\n", inet_ntoa(c->sin.sin_addr)); connection_close(c); } else { b = buffer_create(); SNPRINTF(SIZE(b->buf, BUFFER_SIZE), "%cmessage=\"Connection timed out after %d idle seconds.\"\r\n", RPTP_TIMEOUT, rptp_timeout); b->nbytes += strlen(b->buf); e = event_create(EVENT_WRITE_TIMEOUT, b); event_replace(c, e); } } /* * forward the sound request to the next server */ #ifdef __STDC__ void connection_server_forward_sound(CONNECTION *c, SOUND *s) #else void connection_server_forward_sound(c, s) CONNECTION *c; SOUND *s; #endif { CONNECTION *server; if (c->server->next) { server = connection_server_open(c->server->next, s); } else { spool_remove(s); sound_delete(s, 1); } } /* * forward all events to the next server */ #ifdef __STDC__ void connection_server_forward(CONNECTION *c) #else void connection_server_forward(c) CONNECTION *c; #endif { EVENT *e, *next; CONNECTION *server; if (c->server->next) { server = connection_server_open(c->server->next, NULL); event_insert(server, c->event); } else { for (e = c->event; e; e = next) { next = e->next; switch (e->type) { case EVENT_WRITE_FIND: case EVENT_READ_FIND_REPLY: case EVENT_WRITE_GET: case EVENT_READ_GET_REPLY: case EVENT_READ_SOUND: spool_remove(e->sound); sound_delete(e->sound, 1); break; } event_destroy(e); } } c->event = NULL; c->ep = &c->event; } BUFFER * connection_list_create() { CONNECTION *c; BUFFER *b, *connection_list; char line[RPTP_MAX_LINE]; char buf[RPTP_MAX_LINE]; int n, length; time_t t; b = buffer_create(); connection_list = b; SNPRINTF(SIZE(b->buf, BUFFER_SIZE), "+message=\"connections\"\r\n"); b->nbytes += strlen(b->buf); t = time(0); for (c = connections; c; c = c->next) { length = 0; line[0] = '\0'; SNPRINTF(SIZE(buf, sizeof(buf)), "host=%s", inet_ntoa(c->sin.sin_addr)); strncat(line + length, buf, sizeof(line) - length); length += strlen(buf); SNPRINTF(SIZE(buf, sizeof(buf)), " type="); strncat(line + length, buf, sizeof(line) - length); length += strlen(buf); buf[0] = '\0'; switch (c->type) { case CONNECTION_SERVER: SNPRINTF(SIZE(buf, sizeof(buf)), "server"); break; case CONNECTION_CLIENT: SNPRINTF(SIZE(buf, sizeof(buf)), "client"); break; } strncat(line + length, buf, sizeof(line) - length); length += strlen(buf); if (c->event != NULL) { SNPRINTF(SIZE(buf, sizeof(buf)), " what="); strncat(line + length, buf, sizeof(line) - length); length += strlen(buf); buf[0] = '\0'; switch (c->event->type) { case EVENT_READ_COMMAND: SNPRINTF(SIZE(buf, sizeof(buf)), "idle"); break; case EVENT_CONNECT: case EVENT_READ_CONNECT_REPLY: SNPRINTF(SIZE(buf, sizeof(buf)), "connect"); break; case EVENT_WRITE_FIND: case EVENT_READ_FIND_REPLY: SNPRINTF(SIZE(buf, sizeof(buf)), "\"find %s\"", c->event->sound->name); break; case EVENT_WRITE_GET: case EVENT_READ_GET_REPLY: SNPRINTF(SIZE(buf, sizeof(buf)), "\"get %s\"", c->event->sound->name); break; case EVENT_READ_SOUND: if (c->type == CONNECTION_SERVER) SNPRINTF(SIZE(buf, sizeof(buf)), "\"get %s (%d/%d)\"", c->event->sound->name, c->event->byte_offset, c->event->nbytes); else SNPRINTF(SIZE(buf, sizeof(buf)), "\"put %s (%d/%d)\"", c->event->sound->name, c->event->byte_offset, c->event->nbytes); break; case EVENT_WRITE: SNPRINTF(SIZE(buf, sizeof(buf)), "write"); break; case EVENT_WRITE_SOUND: SNPRINTF(SIZE(buf, sizeof(buf)), "\"get %s (%d/%d)\"", c->event->sound->name, c->event->byte_offset, c->event->nbytes); break; case EVENT_NOTIFY: if (c->notify_mask) SNPRINTF(SIZE(buf, sizeof(buf)), "\"notify %08x\"", c->notify_mask); else SNPRINTF(SIZE(buf, sizeof(buf)), "\"wait %08x\"", c->event->wait_mask); break; case EVENT_READ_FLOW: case EVENT_WAIT_FLOW: SNPRINTF(SIZE(buf, sizeof(buf)), "\"put #%d (%d/%d)\"", c->event->id, c->event->byte_offset, c->event->nbytes); break; case EVENT_PIPE_FLOW: SNPRINTF(SIZE(buf, sizeof(buf)), "\"pipe #%d\"", c->event->id); break; } strncat(line + length, buf, sizeof(line) - length); length += strlen(buf); } if (t - c->time) { SNPRINTF(SIZE(buf, sizeof(buf)), " idle=%s", time2string(t - c->time)); strncat(line + length, buf, sizeof(line) - length); length += strlen(buf); } if (c->application) { SNPRINTF(SIZE(buf, sizeof(buf)), " application=\"%s\"", c->application); strncat(line + length, buf, sizeof(line) - length); length += strlen(buf); } SNPRINTF(SIZE(buf, sizeof(buf)), "\r\n"); strncat(line + length, buf, sizeof(line) - length); length += strlen(buf); if (b->nbytes + length > BUFFER_SIZE) { b->next = buffer_create(); b = b->next; } strncat(b->buf + b->nbytes, line, BUFFER_SIZE - b->nbytes); b->nbytes += length; } if (b->nbytes + 3 > BUFFER_SIZE) { b->next = buffer_create(); b = b->next; } strncat(b->buf + b->nbytes, ".\r\n", BUFFER_SIZE - b->nbytes); b->nbytes += 3; return connection_list; } #ifdef __STDC__ void connection_notify(CONNECTION *notify_connection, int notify_event,...) #else void connection_notify(va_alist) va_dcl #endif { static int prev_play = -1, prev_pause = -1, prev_volume = -1; CONNECTION *c; EVENT *e; BUFFER *b; char buf[RPTP_MAX_LINE]; char head[3], *p; int new_volume, n, length; int force_notify = 0; time_t t; SPOOL *sp; va_list args; #ifdef __STDC__ va_start(args, notify_event); #else CONNECTION *notify_connection; int notify_event; va_start(args); notify_connection = va_arg(args, CONNECTION *); notify_event = va_arg(args, int); #endif /* Extract event parameters. */ switch (notify_event) { case NOTIFY_VOLUME: /* (int) */ new_volume = va_arg(args, int); break; case NOTIFY_PLAY: /* (SPOOL *) */ case NOTIFY_PAUSE: case NOTIFY_CONTINUE: case NOTIFY_STOP: case NOTIFY_SKIP: case NOTIFY_DONE: case NOTIFY_FLOW: case NOTIFY_MODIFY: case NOTIFY_POSITION: sp = va_arg(args, SPOOL *); break; case NOTIFY_STATE: /* none */ break; case NOTIFY_LEVEL: /* int */ force_notify = va_arg(args, int); break; } va_end(args); t = time(0); c = notify_connection ? notify_connection : connections; for (; c; c = c->next) { if (notify_connection && c != notify_connection) { break; } if (BIT(c->notify_mask, notify_event) || (c->event && BIT(c->event->wait_mask, notify_event))) { strcpy(buf, "?event="); length = strlen(buf); switch (notify_event) { case NOTIFY_DONE: if ((!c->notify_id || c->notify_id == sp->id) || (c->event && c->event->id == sp->id)) { n = sp->curr_sound; if (n >= sp->rp->nsounds) { n--; } SNPRINTF(SIZE(buf + length, sizeof(buf) - length), "done id=#%d sound=\"%s\" client-data=\"%s\"", sp->id, sp->sound[n]->name, sp->curr_attrs->client_data); } else { continue; } break; case NOTIFY_VOLUME: SNPRINTF(SIZE(buf + length, sizeof(buf) - length), "volume volume=%d", new_volume); break; case NOTIFY_PLAY: if ((!c->notify_id || c->notify_id == sp->id) || (c->event && c->event->id == sp->id)) { SOUND *s = sp->sound[sp->curr_sound]; SNPRINTF(SIZE(buf + length, sizeof(buf) - length), "play\ id=#%d sound=\"%s\" host=%s volume=%d priority=%d count=%d seconds=%.2f size=%d\ sample-rate=%d channels=%d bits=%g input=%s client-data=\"%s\"", sp->id, sp->curr_attrs->sound, inet_ntoa(sp->sin.sin_addr), sp->curr_attrs->volume, sp->rp->priority, sp->curr_attrs->count, (float) s->samples / sp->sample_rate, s->size, sp->sample_rate, s->channels, s->input_precision, input_to_string(s->type), sp->curr_attrs->client_data); } else { continue; } break; case NOTIFY_STOP: if ((!c->notify_id || c->notify_id == sp->id) || (c->event && c->event->id == sp->id)) { SNPRINTF(SIZE(buf + length, sizeof(buf) - length), "stop id=#%d sound=\"%s\" client-data=\"%s\"", sp->id, sp->curr_attrs->sound, sp->curr_attrs->client_data); } else { continue; } break; case NOTIFY_PAUSE: if ((!c->notify_id || c->notify_id == sp->id) || (c->event && c->event->id == sp->id)) { SNPRINTF(SIZE(buf + length, sizeof(buf) - length), "pause id=#%d sound=\"%s\" client-data=\"%s\"", sp->id, sp->curr_attrs->sound, sp->curr_attrs->client_data); } else { continue; } break; case NOTIFY_CONTINUE: if ((!c->notify_id || c->notify_id == sp->id) || (c->event && c->event->id == sp->id)) { SNPRINTF(SIZE(buf + length, sizeof(buf) - length), "continue id=#%d sound=\"%s\" client-data=\"%s\"", sp->id, sp->curr_attrs->sound, sp->curr_attrs->client_data); } else { continue; } break; case NOTIFY_SKIP: if ((!c->notify_id || c->notify_id == sp->id) || (c->event && c->event->id == sp->id)) { SNPRINTF(SIZE(buf + length, sizeof(buf) - length), "skip id=#%d sound=\"%s\" client-data=\"%s\"", sp->id, sp->curr_attrs->sound, sp->curr_attrs->client_data); } else { continue; } break; case NOTIFY_STATE: SNPRINTF(SIZE(buf + length, sizeof(buf) - length), "state play=%d pause=%d volume=%d priority-threshold=%d audio-port=%s", spool_nplaying, spool_npaused, rplay_audio_volume, rplay_priority_threshold, audio_port_to_string(rplay_audio_port)); break; case NOTIFY_FLOW: if ((!c->notify_id || c->notify_id == sp->id) || (c->event && c->event->id == sp->id)) { SNPRINTF(SIZE(buf + length, sizeof(buf) - length), "flow id=#%d sound=\"%s\" mark=%d low=%d high=%d client-data=\"%s\"", sp->id, sp->curr_attrs->sound, sp->si->water_mark - sp->si->offset, sp->si->low_water_mark, sp->si->high_water_mark, sp->curr_attrs->client_data); } else { continue; } break; case NOTIFY_MODIFY: if ((!c->notify_id || c->notify_id == sp->id) || (c->event && c->event->id == sp->id)) { SNPRINTF(SIZE(buf + length, sizeof(buf) - length), "modify \ id=#%d count=%d list-count=%d priority=%d sample-rate=%d volume=%d client-data=\"%s\"", sp->id, sp->curr_count, sp->list_count, sp->rp->priority, sp->sample_rate, sp->curr_attrs->volume, sp->curr_attrs->client_data); } else { continue; } break; case NOTIFY_LEVEL: if (c->notify_rate[NOTIFY_RATE_LEVEL].rate) { if (!force_notify && c->notify_rate[NOTIFY_RATE_LEVEL].next > timer_count) { continue; } c->notify_rate[NOTIFY_RATE_LEVEL].next = timer_count + c->notify_rate[NOTIFY_RATE_LEVEL].rate; } SNPRINTF(SIZE(buf + length, sizeof(buf) - length), "level volume=%d left=%d right=%d", rplay_audio_volume, rplay_audio_left_level, rplay_audio_right_level); break; case NOTIFY_POSITION: if ((!c->notify_id || c->notify_id == sp->id) || (c->event && c->event->id == sp->id)) { SOUND *s = sp->sound[sp->curr_sound]; if (c->notify_rate[NOTIFY_RATE_POSITION].rate) { if (c->notify_rate[NOTIFY_RATE_POSITION].next > timer_count) { continue; } c->notify_rate[NOTIFY_RATE_POSITION].next = timer_count + c->notify_rate[NOTIFY_RATE_POSITION].rate; } SNPRINTF(SIZE(buf + length, sizeof(buf) - length), "position \ id=#%d position=%.2f remain=%.2f seconds=%.2f sample=%d samples=%d client-data=\"%s\"", sp->id, sp->sample_rate && s->samples ? sp->sample_index / sp->sample_rate : 0, sp->sample_rate && s->samples ? ((double) s->samples - sp->sample_index) / sp->sample_rate : 0, sp->sample_rate && s->samples ? (double) s->samples / sp->sample_rate : 0, s->samples ? (int) sp->sample_index : 0, s->samples, sp->curr_attrs->client_data); } else { continue; } } length = strlen(buf); SNPRINTF(SIZE(buf + length, sizeof(buf) - length), "\r\n"); length = strlen(buf); /* Build the head array with the necessary RPTP headers. */ n = 0; if (c->event && BIT(c->event->wait_mask, notify_event)) { head[n++] = RPTP_OK; } if (BIT(c->notify_mask, notify_event)) { head[n++] = RPTP_NOTIFY; } head[n] = '\0'; /* Setup write events to send `buf' using each RPTP header. */ for (p = head; *p; p++) { buf[0] = *p; /* Try to append `buf' to the last write event. This is an attempt use reuse existing write buffers to improve performance. */ for (e = c->event; e && e->next; e = e->next) ; if (e && e->type == EVENT_WRITE && e->buffer->nbytes + length <= BUFFER_SIZE) { strcpy(e->buffer->buf + e->buffer->nbytes, buf); e->buffer->nbytes += length; e->nbytes += length; e->nleft += length; } else { b = buffer_create(); strcpy(b->buf + b->nbytes, buf); b->nbytes += length; e = event_create(EVENT_WRITE, b); if (c->event && c->event->type == EVENT_NOTIFY) { event_replace(c, e); } else { event_insert_before(c, e, EVENT_READ_COMMAND | EVENT_READ_SOUND | EVENT_READ_CONNECT_REPLY | EVENT_READ_FIND_REPLY | EVENT_READ_GET_REPLY | EVENT_READ_FLOW | EVENT_WAIT_FLOW | EVENT_PIPE_FLOW); } } } c->time = t; } } /* Notify state changes. */ switch (notify_event) { default: /* Only notify is the state has _really_ changed. */ if (prev_play != spool_nplaying || prev_pause != spool_npaused || prev_volume != rplay_audio_volume || notify_connection) { prev_play = spool_nplaying; prev_pause = spool_npaused; prev_volume = rplay_audio_volume; /* Recursion is your friend. */ connection_notify(notify_connection, NOTIFY_STATE); } break; case NOTIFY_STATE: break; } } #ifdef __STDC__ void connection_flow_pause(SPOOL *sp) #else void connection_flow_pause(sp) SPOOL *sp; #endif { CONNECTION *c; EVENT *e; for (c = connections; c; c = c->next) { for (e = c->event; e; e = e->next) { if (e->type == EVENT_READ_FLOW && e->id == sp->id) { e->type = EVENT_WAIT_FLOW; if (c->event == e) { connection_update_fdset(c); } break; } } } } #ifdef __STDC__ void connection_flow_continue(SPOOL *sp) #else void connection_flow_continue(sp) SPOOL *sp; #endif { CONNECTION *c; EVENT *e; for (c = connections; c; c = c->next) { for (e = c->event; e; e = e->next) { if (e->type == EVENT_WAIT_FLOW && e->id == sp->id) { e->type = EVENT_READ_FLOW; if (c->event == e) { connection_update_fdset(c); } break; } } } } #ifdef __STDC__ void connection_monitor_pause(CONNECTION *c) #else void connection_monitor_pause(c) CONNECTION *c; #endif { if (c->event && c->event->type == EVENT_WRITE_MONITOR) { c->event->type = EVENT_WAIT_MONITOR; connection_update_fdset(c); } } void connection_monitor_continue() { CONNECTION *c; EVENT *e; for (c = connections; c; c = c->next) { for (e = c->event; e; e = e->next) { if (e->type == EVENT_WAIT_MONITOR) { e->type = EVENT_WRITE_MONITOR; if (c->event == e) { connection_update_fdset(c); } break; } } } } #ifdef __STDC__ void event_update(CONNECTION *c) #else void event_update(c) CONNECTION *c; #endif { int n, size; int fd; EVENT *e; time_t t; char *p; BUFFER *b; if (c->event == NULL) { return; } switch (c->event->type) { case EVENT_READ_COMMAND: if (c->event->success) { if (c->event->start[0] != '\0' && isascii(c->event->start[0])) { b = c->event->buffer; /* save the event's buffer */ c->event->buffer = NULL; event_delete(c, 0); if (command(c, b->buf) != 0) { connection_close(c); } buffer_destroy(b); } else { event_delete(c, 1); } } else { connection_close(c); } break; case EVENT_CONNECT: /* * check the time to delay between connect attempts */ t = time(0); if (t - c->event->time < RPTP_PING_DELAY) { break; } c->event->time = t; /* * check the socket to see if it is connected */ n = connect(c->fd, (struct sockaddr *) &c->server->sin, sizeof(c->server->sin)); if (n == 0 || errno == EISCONN) { /* * got a connection */ report(REPORT_NOTICE, "%s server connection established\n", inet_ntoa(c->server->sin.sin_addr)); /* * prepare to read the connect reply, this must replace the * connect event */ e = event_create(EVENT_READ_CONNECT_REPLY, buffer_create()); event_replace(c, e); } else { /* * socket is not connected */ c->event->nconnects++; report(REPORT_DEBUG, "%s server connection failed attempt #%d\n", inet_ntoa(c->server->sin.sin_addr), c->event->nconnects); if (c->event->nconnects < RPTP_CONNECT_ATTEMPTS) { switch (errno) { case ECONNREFUSED: case EINTR: case EAGAIN: case EINVAL: case EPIPE: /* * ping the server again */ connection_server_ping(c); FD_CLR(c->fd, &read_mask); FD_CLR(c->fd, &write_mask); close(c->fd); c->fd = socket(AF_INET, SOCK_STREAM, 0); fd_nonblock(c->fd); /* * try and connect again */ connect(c->fd, (struct sockaddr *) &c->server->sin, sizeof(c->server->sin)); connection_update_fdset(c); return; default: break; } } /* * connection failed, remove connect event and forward all other * events to the next server */ report(REPORT_NOTICE, "%s server connection failed\n", inet_ntoa(c->server->sin.sin_addr)); event_delete(c, 1); connection_server_forward(c); connection_close(c); } break; case EVENT_READ_CONNECT_REPLY: if (c->event->success) { if (c->event->start[0] == RPTP_OK) { event_delete(c, 1); } else { event_delete(c, 1); connection_server_forward(c); connection_close(c); } } else { report(REPORT_NOTICE, "cannot read connect reply from %s\n", inet_ntoa(c->server->sin.sin_addr)); event_delete(c, 1); connection_server_forward(c); connection_close(c); } break; case EVENT_WRITE_FIND: if (c->event->success) { e = event_create(EVENT_READ_FIND_REPLY, buffer_create(), c->event->sound); event_replace(c, e); } else { connection_server_forward(c); connection_close(c); } break; case EVENT_READ_FIND_REPLY: if (c->event->success) { switch (c->event->start[0]) { case RPTP_OK: if (strchr(c->event->start, '=')) { size = atoi(rptp_parse(c->event->start, "size")); } else /* old-style */ { p = strtok(c->event->start, " "); size = atoi(strtok(NULL, "\r\n")); } /* * see if the sound will fit in the cache */ if (cache_free(size) < 0) { /* * the sound is too big for the cache */ spool_remove(c->event->sound); sound_delete(c->event->sound, 1); event_delete(c, 1); break; } b = buffer_create(); SNPRINTF(SIZE(b->buf, BUFFER_SIZE), "get %s\r\n", c->event->sound->name); /* old-style */ b->nbytes = strlen(b->buf); e = event_create(EVENT_WRITE_GET, b, c->event->sound); event_replace(c, e); break; case RPTP_ERROR: report(REPORT_NOTICE, "%s server does not have %s\n", inet_ntoa(c->sin.sin_addr), c->event->sound->name); connection_server_forward_sound(c, c->event->sound); event_delete(c, 1); break; case RPTP_TIMEOUT: report(REPORT_NOTICE, "%s server connection timed out\n", inet_ntoa(c->sin.sin_addr)); b = buffer_create(); SNPRINTF(SIZE(b->buf, BUFFER_SIZE), "find %s\r\n", c->event->sound->name); /* old-style */ b->nbytes = strlen(b->buf); e = event_create(EVENT_WRITE_FIND, b, c->event->sound); event_replace(c, e); connection_server_reopen(c); break; default: report(REPORT_ERROR, "event_update: unknown find reply '%c'\n", c->event->start[0]); done(1); } } else { report(REPORT_NOTICE, "cannot read find reply from %s\n", inet_ntoa(c->sin.sin_addr)); b = buffer_create(); SNPRINTF(SIZE(b->buf, BUFFER_SIZE), "find %s\r\n", c->event->sound->name); /* old-style */ b->nbytes = strlen(b->buf); e = event_create(EVENT_WRITE_FIND, b, c->event->sound); event_replace(c, e); connection_server_forward(c); connection_close(c); } break; case EVENT_WRITE_GET: if (c->event->success) { e = event_create(EVENT_READ_GET_REPLY, buffer_create(), c->event->sound); event_replace(c, e); } else { b = buffer_create(); SNPRINTF(SIZE(b->buf, BUFFER_SIZE), "find %s\r\n", c->event->sound->name); /* old-style */ b->nbytes = strlen(b->buf); e = event_create(EVENT_WRITE_FIND, b, c->event->sound); event_replace(c, e); connection_server_forward(c); connection_close(c); } break; case EVENT_READ_GET_REPLY: if (c->event->success) { char *sound_name; switch (c->event->start[0]) { case RPTP_OK: if (strchr(c->event->start, '=')) { sound_name = rptp_parse(c->event->start, "sound"); size = atoi(rptp_parse(0, "size")); } else /* old-style */ { p = strtok(c->event->start, " "); p++; sound_name = p; size = atoi(strtok(NULL, "\r\n")); } free((char *) c->event->sound->path); c->event->sound->path = strdup(cache_name(sound_name)); c->event->sound->name = c->event->sound->path[0] == '/' ? strrchr(c->event->sound->path, '/') + 1 : c->event->sound->path; fd = cache_create(c->event->sound->path, size); if (fd < 0) { spool_remove(c->event->sound); sound_delete(c->event->sound, 1); event_delete(c, 1); } else { e = event_create(EVENT_READ_SOUND, fd, buffer_create(), size, c->event->sound); c->event->sound->status = SOUND_NOT_READY; event_replace(c, e); } break; case RPTP_ERROR: report(REPORT_NOTICE, "%s server does not have %s\n", inet_ntoa(c->sin.sin_addr), c->event->sound->name); connection_server_forward_sound(c, c->event->sound); event_delete(c, 1); break; case RPTP_TIMEOUT: report(REPORT_NOTICE, "%s server connection timed out\n", inet_ntoa(c->sin.sin_addr)); b = buffer_create(); SNPRINTF(SIZE(b->buf, BUFFER_SIZE), "get %s\r\n", c->event->sound->name); /* old-style */ b->nbytes = strlen(b->buf); e = event_create(EVENT_WRITE_GET, b, c->event->sound); event_replace(c, e); connection_server_reopen(c); break; default: report(REPORT_ERROR, "event_update: unknown get reply '%c'\n", c->event->start[0]); done(1); } } else { report(REPORT_NOTICE, "cannot read get reply from %s\n", inet_ntoa(c->server->sin.sin_addr)); b = buffer_create(); SNPRINTF(SIZE(b->buf, BUFFER_SIZE), "find %s\r\n", c->event->sound->name); /* old-style */ b->nbytes = strlen(b->buf); e = event_create(EVENT_WRITE_FIND, b, c->event->sound); event_replace(c, e); connection_server_forward(c); connection_close(c); } break; case EVENT_READ_SOUND: if (c->event->success) { close(c->event->fd); sound_map(c->event->sound); spool_ready(c->event->sound); c->event->sound->status = SOUND_READY; report(REPORT_DEBUG, "sound %s is ready\n", c->event->sound->name); event_delete(c, 1); } else { report(REPORT_NOTICE, "cannot read sound %s from %s\n", c->event->sound->name, inet_ntoa(c->sin.sin_addr)); if (c->type == CONNECTION_SERVER) { b = buffer_create(); SNPRINTF(SIZE(b->buf, BUFFER_SIZE), "find %s\r\n", c->event->sound->name); /* old-style */ b->nbytes = strlen(b->buf); e = event_create(EVENT_WRITE_FIND, b, c->event->sound); event_replace(c, e); connection_server_forward(c); } connection_close(c); } break; case EVENT_WRITE_SOUND: if (c->event->success) { event_delete(c, 1); } else { connection_close(c); } break; case EVENT_WRITE: if (c->event->success) { b = c->event->buffer; c->event->buffer = c->event->buffer->next; if (b->status == BUFFER_FREE) { buffer_destroy(b); } if (c->event->buffer) { c->event->start = c->event->buffer->buf; c->event->ptr = c->event->start; c->event->nleft = c->event->buffer->nbytes; c->event->nbytes = c->event->nleft; c->event->success = 0; } else { event_delete(c, 1); } } else { connection_close(c); } break; case EVENT_WRITE_TIMEOUT: report(REPORT_DEBUG, "%s client connection timeout\n", inet_ntoa(c->sin.sin_addr)); connection_close(c); break; case EVENT_READ_FLOW: case EVENT_WAIT_FLOW: case EVENT_PIPE_FLOW: if (c->event->success) { event_delete(c, 1); } else { connection_close(c); } break; case EVENT_NOTIFY: report(REPORT_DEBUG, "event_update: `%d' update?\n", c->event->type); break; case EVENT_WRITE_MONITOR: if (c->event->success) { /* move to the next monitor buffer */ c->event->buffer = c->event->buffer->next; c->event->start = c->event->buffer->buf; c->event->ptr = c->event->start; c->event->nleft = c->event->buffer->nbytes; c->event->nbytes = c->event->nleft; c->event->success = 0; /* need to wait for the buffer to be complete */ if (c->event->buffer == monitor_buffers) { connection_monitor_pause(c); } } else { connection_close(c); } break; case EVENT_WAIT_MONITOR: connection_close(c); break; default: report(REPORT_ERROR, "event_update: unknown event `%d'\n", c->event->type); done(1); } } #ifdef __STDC__ void event_first(CONNECTION *c, EVENT *e) #else void event_first(c, e) CONNECTION *c; EVENT *e; #endif { EVENT *tail; for (tail = e; tail->next; tail = tail->next) ; tail->next = c->event; c->event = e; if (!c->event->next) { c->ep = &c->event->next; } connection_update_fdset(c); #ifdef EVENT_DEBUG event_print(c, "first"); #endif } #ifdef __STDC__ void event_insert_before(CONNECTION *c, EVENT *e, int mask) #else void event_insert_before(c, e, mask) CONNECTION *c; EVENT *e; int mask; #endif { if (!c->event || (c->event->type & mask)) { event_first(c, e); } else { EVENT *tail, *event; for (tail = e; tail->next; tail = tail->next) ; for (event = c->event; event->next; event = event->next) { if (event->next->type & mask) { break; } } tail->next = event->next; event->next = e; if (!tail->next) { c->ep = &tail->next; } if (c->event == e) { connection_update_fdset(c); } #ifdef EVENT_DEBUG event_print(c, "before"); #endif } } #ifdef __STDC__ void event_insert(CONNECTION *c, EVENT *e) #else void event_insert(c, e) CONNECTION *c; EVENT *e; #endif { EVENT *tail; for (tail = e; tail->next; tail = tail->next) ; *c->ep = e; c->ep = &tail->next; if (c->event == e) { connection_update_fdset(c); } #ifdef EVENT_DEBUG event_print(c, "insert"); #endif } #ifdef __STDC__ void event_replace(CONNECTION *c, EVENT *e) #else void event_replace(c, e) CONNECTION *c; EVENT *e; #endif { if (c->event) { e->next = c->event->next; event_destroy(c->event); } c->event = e; if (c->event->next == NULL) { c->ep = &c->event->next; } connection_update_fdset(c); #ifdef EVENT_DEBUG event_print(c, "replace"); #endif } #ifdef __STDC__ void event_delete(CONNECTION *c, int replace) #else void event_delete(c, replace) CONNECTION *c; int replace; #endif { EVENT *e; if (c->event == NULL) { connection_update_fdset(c); return; } e = c->event; c->event = c->event->next; event_destroy(e); if (c->event == NULL) { c->ep = &c->event; /* Replace the empty event with notify or read_command. */ if (replace && c->type == CONNECTION_CLIENT) { if (c->notify_mask) { e = event_create(EVENT_NOTIFY); } else { e = event_create(EVENT_READ_COMMAND, buffer_create()); } event_insert(c, e); } } connection_update_fdset(c); #ifdef EVENT_DEBUG event_print(c, "delete"); #endif } /* * EVENT_READ_COMMAND, BUFFER *b * EVENT_CONNECT * EVENT_READ_CONNECT_REPLY, BUFFER *b * EVENT_WRITE_FIND, BUFFER *b, SOUND *sound * EVENT_READ_FIND_REPLY, BUFFER *b, SOUND *sound * EVENT_WRITE_GET, BUFFER *b, SOUND *sound * EVENT_READ_GET_REPLY, BUFFER *b, SOUND *sound * EVENT_READ_SOUND, int fd, BUFFER *b, int nbytes, SOUND *sound * EVENT_WRITE, BUFFER *buffer * EVENT_WRITE_SOUND, SOUND *sound * EVENT_NOTIFY * EVENT_READ_FLOW, int spool_id, int nbytes */ #ifdef __STDC__ EVENT * event_create(int type,...) #else EVENT * event_create(va_alist) va_dcl #endif { EVENT *e; va_list args; #ifdef __STDC__ va_start(args, type); #else int type; va_start(args); type = va_arg(args, int); #endif e = (EVENT *) malloc(sizeof(EVENT)); if (e == NULL) { report(REPORT_ERROR, "event_create: out of memory\n"); done(1); } /* * defaults */ e->next = NULL; e->type = type; e->nbytes = 0; e->byte_offset = 0; e->nleft = 0; e->start = NULL; e->ptr = NULL; e->sound = NULL; e->fd = -1; e->nconnects = 0; e->time = 0; e->success = 0; e->buffer = NULL; e->id = 0; e->wait_mask = NOTIFY_NONE; e->si = NULL; switch (e->type) { case EVENT_READ_COMMAND: case EVENT_READ_CONNECT_REPLY: e->buffer = va_arg(args, BUFFER *); e->nleft = RPTP_MAX_LINE; e->nbytes = e->nleft; e->ptr = e->buffer->buf; e->start = e->ptr; break; case EVENT_CONNECT: break; case EVENT_WRITE_FIND: case EVENT_WRITE_GET: e->buffer = va_arg(args, BUFFER *); e->nleft = e->buffer->nbytes; e->nbytes = e->nleft; e->ptr = e->buffer->buf; e->start = e->ptr; e->sound = va_arg(args, SOUND *); break; case EVENT_READ_FIND_REPLY: case EVENT_READ_GET_REPLY: e->buffer = va_arg(args, BUFFER *); e->nleft = RPTP_MAX_LINE; e->nbytes = e->nleft; e->ptr = e->buffer->buf; e->start = e->ptr; e->sound = va_arg(args, SOUND *); break; case EVENT_READ_SOUND: e->fd = va_arg(args, int); e->buffer = va_arg(args, BUFFER *); e->nbytes = va_arg(args, int); e->nleft = e->nbytes; e->sound = va_arg(args, SOUND *); break; case EVENT_WRITE_SOUND: e->sound = va_arg(args, SOUND *); e->buffer = buffer_create(); e->si = sound_open(e->sound, 0); if (e->si == NULL) { event_destroy(e); return NULL; } if (sound_fill(e->si, e->buffer, 1) <= 0) { event_destroy(e); return NULL; } e->nbytes = e->sound->size; /* total number of bytes */ e->nleft = e->buffer->nbytes; /* # bytes in the buffer */ e->ptr = e->buffer->buf; e->start = e->buffer->buf; break; case EVENT_WRITE: case EVENT_WRITE_TIMEOUT: e->buffer = va_arg(args, BUFFER *); e->ptr = e->buffer->buf; e->start = e->ptr; e->nleft = e->buffer->nbytes; e->nbytes = e->nleft; break; case EVENT_NOTIFY: break; case EVENT_READ_FLOW: e->id = va_arg(args, int); e->nbytes = va_arg(args, int); if (e->nbytes == 0) { e->nbytes = -1; } e->nleft = e->nbytes; break; case EVENT_WAIT_FLOW: /* XXX */ break; case EVENT_PIPE_FLOW: e->id = va_arg(args, int); e->sound = va_arg(args, SOUND *); break; case EVENT_WAIT_MONITOR: e->buffer = monitor_buffers; e->ptr = e->buffer->buf; e->start = e->ptr; e->nleft = e->buffer->nbytes; e->nbytes = e->nleft; break; } va_end(args); return e; } #ifdef __STDC__ void event_destroy(EVENT *e) #else void event_destroy(e) EVENT *e; #endif { if (e->buffer && e->buffer->status == BUFFER_FREE) { buffer_destroy(e->buffer); } if (e->si) { sound_close(e->si); } free((char *) e); } #ifdef EVENT_DEBUG static void event_print(CONNECTION *c, char *message) { EVENT *e; printf("%8s %s (%s) -> ", message, c->application, inet_ntoa(c->sin.sin_addr)); e = c->event; for (; e; e = e->next) { switch (e->type) { case EVENT_READ_COMMAND: printf("read_command "); break; case EVENT_CONNECT: printf("connect "); break; case EVENT_READ_CONNECT_REPLY: printf("read_connect_reply "); break; case EVENT_WRITE_FIND: printf("write_find "); break; case EVENT_READ_FIND_REPLY: printf("read_find_reply "); break; case EVENT_WRITE_GET: printf("write_get "); break; case EVENT_READ_GET_REPLY: printf("read_get_reply "); break; case EVENT_READ_SOUND: printf("read_sound "); break; case EVENT_WRITE: printf("write "); break; case EVENT_WRITE_SOUND: printf("write_sound "); break; case EVENT_WRITE_TIMEOUT: printf("write_timeout "); break; case EVENT_NOTIFY: printf("notify "); break; case EVENT_READ_FLOW: printf("read_flow "); break; case EVENT_WAIT_FLOW: printf("wait_flow "); break; case EVENT_PIPE_FLOW: printf("pipe_flow "); break; default: printf("`%d' ", e->type); break; } } if (FD_ISSET(c->fd, &write_mask)) { printf("[write] "); } if (FD_ISSET(c->fd, &read_mask)) { printf("[read] "); } printf("\n"); } #endif rplay-3.3.2/rplayd/connection.h100644 153 62 15710 6671423013 15146 0ustar boynsstaff/* $Id: connection.h,v 1.3 1999/03/10 07:58:03 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _connection_h #define _connection_h #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "sound.h" #include "server.h" #include "buffer.h" #include "spool.h" /* * event types */ #define EVENT_NULL 0 #define EVENT_READ_COMMAND (1<<0) /* read an RPTP command (client) */ #define EVENT_CONNECT (1<<1) /* connect to a server (server) */ #define EVENT_READ_CONNECT_REPLY (1<<2) /* read a connect reply (server) */ #define EVENT_WRITE_FIND (1<<3) /* write a find command (server) */ #define EVENT_READ_FIND_REPLY (1<<4) /* read a find reply (server) */ #define EVENT_WRITE_GET (1<<5) /* write a get command (server) */ #define EVENT_READ_GET_REPLY (1<<6) /* read a get reply (server) */ #define EVENT_READ_SOUND (1<<7) /* read a sound (both) */ #define EVENT_WRITE (1<<8) /* write buffers (client) */ #define EVENT_WRITE_SOUND (1<<9) /* write a sound (client) */ #define EVENT_WRITE_TIMEOUT (1<<10) /* write connection timeout message (both) */ #define EVENT_NOTIFY (1<<11) /* event notification (client) */ #define EVENT_READ_FLOW (1<<12) /* read a flow */ #define EVENT_WAIT_FLOW (1<<13) /* pause the incoming flow data */ #define EVENT_PIPE_FLOW (1<<14) /* piped flow data */ #define EVENT_WRITE_MONITOR (1<<15) /* write audio monitor data */ #define EVENT_WAIT_MONITOR (1<<16) /* write audio monitor data */ /* * notify events */ #define NOTIFY_NONE 0 #define NOTIFY_VOLUME (1<<0) #define NOTIFY_PLAY (1<<1) #define NOTIFY_PAUSE (1<<2) #define NOTIFY_CONTINUE (1<<3) #define NOTIFY_STOP (1<<4) #define NOTIFY_DONE (1<<5) #define NOTIFY_SKIP (1<<6) #define NOTIFY_STATE (1<<7) #define NOTIFY_FLOW (1<<8) #define NOTIFY_MODIFY (1<<9) #define NOTIFY_LEVEL (1<<10) #define NOTIFY_POSITION (1<<11) #define NOTIFY_MONITOR (1<<12) #define NOTIFY_ANY (0xffffffff) #define NOTIFY_SPOOL (NOTIFY_PLAY|NOTIFY_PAUSE|NOTIFY_CONTINUE|NOTIFY_STOP|NOTIFY_DONE|NOTIFY_SKIP|NOTIFY_MODIFY|NOTIFY_FLOW) /* * connection types */ #define CONNECTION_NULL 0 #define CONNECTION_CLIENT 1 #define CONNECTION_SERVER 2 typedef struct _event { struct _event *next; int type; int nbytes; int byte_offset; int nleft; char *start; char *ptr; BUFFER *buffer; SOUND *sound; int fd; int nconnects; time_t time; int success; int id; int wait_mask; SINDEX *si; } EVENT; #define NOTIFY_RATE_LEVEL 0 #define NOTIFY_RATE_POSITION 1 #define NOTIFY_RATE_MAX 2 typedef struct { double rate; /* event notify-rate */ double next; /* next notify time */ } NOTIFY_RATE; typedef struct _connection { struct _connection *next; struct _connection *prev; struct sockaddr_in sin; int type; int fd; EVENT *event; EVENT **ep; SERVER *server; time_t time; char *application; int notify_mask; int notify_id; NOTIFY_RATE notify_rate[NOTIFY_RATE_MAX]; int monitor; } CONNECTION; extern CONNECTION *connections; extern int nconnections; extern int connection_want_level_notify; extern int connection_level_notify; #ifdef __STDC__ extern CONNECTION *connection_create (int type); extern void connection_destroy (CONNECTION *c); extern void connection_client_open (int fd); extern void connection_update (fd_set * read_fds, fd_set * write_fds); extern void connection_close (CONNECTION *c); extern void connection_cleanup (); extern void connection_update_fdset (CONNECTION *c); extern void connection_reply (CONNECTION *c, char *fmt,...); extern CONNECTION *connection_server_open (SERVER *server, SOUND *sound); extern void connection_server_reopen (CONNECTION *c); extern void connection_server_ping (CONNECTION *c); extern void connection_check_timeout (); extern void connection_timeout (CONNECTION *c); extern void connection_server_forward_sound (CONNECTION *c, SOUND *s); extern void connection_server_foward (CONNECTION *c); extern BUFFER *connection_list_create (); extern void connection_notify (CONNECTION *c, int wait_event,...); extern void connection_flow_pause (SPOOL *sp); extern void connection_flow_continue (SPOOL *sp); extern int connection_idle (); extern EVENT *event_create (int event_type,...); extern void event_first (CONNECTION *c, EVENT *e); extern void event_insert_before (CONNECTION *c, EVENT *e, int mask); extern void event_insert (CONNECTION *c, EVENT *e); extern void event_delete (CONNECTION *c, int replace); extern void event_update (CONNECTION *c); extern void event_destroy (EVENT *e); extern void event_replace (CONNECTION *c, EVENT *e); #else extern CONNECTION *connection_create ( /* int type */ ); extern void connection_destroy ( /* CONNECTION *c */ ); extern void connection_client_open ( /* int fd */ ); extern void connection_update ( /* fd_set *read_fds, fd_set *write_fds */ ); extern void connection_close ( /* CONNECTION *c */ ); extern void connection_cleanup (); extern void connection_update_fdset ( /* CONNECTION *c */ ); extern void connection_reply ( /* CONNECTION *c, char *fmt, ... */ ); extern CONNECTION *connection_server_open ( /* SERVER *server, SOUND *sound */ ); extern void connection_server_ping ( /* CONNECTION *c */ ); extern void connection_check_timeout (); extern void connection_timeout ( /* CONNECTION *c */ ); extern void connection_server_forward_sound ( /* CONNECTION *c, SOUND *s */ ); extern void connection_server_foward ( /* CONNECTION *c */ ); extern BUFFER *connection_list_create (); extern void connection_notify ( /* CONNECTION *c, int wait_event, ... */ ); extern void connection_flow_pause ( /* SPOOL *sp */ ); extern void connection_flow_continue ( /* SPOOL *sp */ ); extern int connection_idle (); extern EVENT *event_create ( /* int event_type, ... */ ); extern void event_first ( /* CONNECTION *c, EVENT *e */ ); extern void event_insert_before ( /* CONNECTION *c, EVENT *e, int mask */ ); extern void event_insert ( /* CONNECTION *c, EVENT *e */ ); extern void event_delete ( /* CONNECTION *c, int replace */ ); extern void event_update ( /* CONNECTION *c */ ); extern void event_destroy ( /* EVENT *e */ ); extern void event_replace ( /* CONNECTION *c, EVENT *e */ ); #endif #endif /* _connection_h */ rplay-3.3.2/rplayd/flange.c100644 153 62 5771 6671423013 14224 0ustar boynsstaff/* $Id: flange.c,v 1.4 1999/03/10 07:58:03 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #include "rplayd.h" #ifdef TEST_FLANGE typedef struct { float rate; /* rate of delay change (-1.0 - 1.0) */ float sweep; /* sweep range in milliseconds */ float delay; /* fixed additional delay in milliseconds */ float dry_mix; /* mix of unaffected signal (-1.0 - 1.0) */ float wet_mix; /* mix of affected signal (-1.0 - 1.0) */ float feedback; /* amount of recirculation (-1.0 - 1.0) */ float depth; } parameters; parameters p = {2.0, 20.0, 0.0, 0.5, 0.5, 0.0, 10}; #define SPMS 8 #define SPS 8000 #define BFSZ 1024 float Buf[BFSZ]; typedef union { unsigned char b[2]; unsigned short w; } bw; typedef union { unsigned short w[2]; long l; } wl; void flange(char *native_buf, int nsamples, int nchannels) { short *sample = (short *) native_buf; short *flanged = (short *) native_buf; int size = nsamples * nchannels; static int first = 1; static int i, fp, ep1, ep2; static int step, depth, delay, min_sweep, max_sweep; static float inval, outval, ifac = 65536.0; static wl sweep; if (first) { first = 0; step = (int) (p.rate * 65.536); depth = (int) (p.depth * (float) SPMS); delay = (int) (p.delay * (float) SPMS); max_sweep = BFSZ - 2 - delay; min_sweep = max_sweep - depth; if (min_sweep < 0) { exit(1); } sweep.w[0] = (min_sweep + max_sweep) / 2; sweep.w[1] = 0; fp = ep1 = ep2 = 0; } #if 0 printf("step = %d, depth = %d, delay = %d\n", step, depth, delay); printf("max_sweep = %d, min_sweep = %d\n", max_sweep, min_sweep); #endif for (i = 0; i < size; i++) { outval = (Buf[ep1] * sweep.w[1] + Buf[ep2] * (ifac - sweep.w[1])) / ifac; Buf[fp] = (inval = (float) sample[i]) + outval * p.feedback; outval = outval * p.wet_mix + inval * p.dry_mix; if (outval > 32000) flanged[i] = 32000; else if (outval < -32000) flanged[i] = -32000; else flanged[i] = (int) outval; fp = (fp + 1) & (BFSZ - 1); sweep.l += step; ep1 = (fp + sweep.w[0]) & (BFSZ - 1); ep2 = (ep1 - 1) & (BFSZ - 1); if (sweep.w[0] > max_sweep) step = -step; else if (sweep.w[0] < min_sweep) step = -step; } } #endif /* TEST_FLANGE */ rplay-3.3.2/rplayd/flange.h100644 153 62 2121 6671423013 14213 0ustar boynsstaff/* $Id: flange.h,v 1.3 1999/03/10 07:58:03 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifdef TEST_FLANGE #ifndef _flange_h #define _flange_h #ifdef HAVE_CONFIG_H #include "config.h" #endif extern void flange (char *native_buf, int nsamples, int nchannels); #endif /* _flange_h */ #endif /* TEST_FLANGE */ rplay-3.3.2/rplayd/helper.c100644 153 62 10675 6671423013 14266 0ustar boynsstaff/* $Id: helper.c,v 1.4 1999/03/10 07:58:03 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_HELPERS #include #include #include #include #include #include #include #ifdef HAVE_STRING_H #include #endif #include "rplayd.h" #include "helper.h" #include "misc.h" HELPER *helpers = NULL; static time_t helper_read_time; #ifdef __STDC__ void helper_read(char *filename) #else void helper_read(filename) char *filename; #endif { FILE *fp; char buf[MAXPATHLEN]; char *pat, *prog, *p, *info; HELPER *hp, *hp_next, *tail; int line = 0; int error; helper_read_time = time(0); fp = fopen(filename, "r"); if (fp == NULL) { return; } while (fgets(buf, sizeof(buf), fp) != NULL) { line++; switch (buf[0]) { case '#': case ' ': case '\t': case '\n': continue; } p = strchr(buf, '\n'); if (p) { *p = '\0'; } hp = (HELPER *) malloc(sizeof(HELPER)); if (hp == NULL) { report(REPORT_ERROR, "helper_read: out of memory\n"); done(1); } hp->next = NULL; hp->program = NULL; hp->format = 0; hp->sample_rate = 0; hp->precision = 0; hp->channels = 0; hp->byte_order = 0; /* pattern */ pat = strtok(buf, " \t"); if (!pat) { report(REPORT_ERROR, "helper_read: parse error line %d\n", line); done(1); } //memset ((char *) &hp->pattern, 0, sizeof (hp->pattern)); error = regncomp(&hp->pattern, pat, strlen(pat), REG_ICASE | REG_NOSUB); if (error) { report(REPORT_ERROR, "helper_read: %d line %d\n", error, line); done(1); } /* info */ info = strtok(NULL, " \t"); if (!info) { report(REPORT_ERROR, "helper_read: parse error line %d\n", line); done(1); } for (; *info && (*info == ' ' || *info == '\t'); info++) ; /* program */ prog = strtok(NULL, ""); if (!prog) { report(REPORT_ERROR, "helper_read: parse error line %d\n", line); done(1); } for (; *prog && (*prog == ' ' || *prog == '\t'); prog++) ; hp->program = strdup(prog); /* parse info */ p = strtok(info, ","); if (p) hp->format = string_to_audio_format(p); p = strtok(NULL, ","); if (p) hp->sample_rate = atoi(p); p = strtok(NULL, ","); if (p) hp->precision = atoi(p); p = strtok(NULL, ","); if (p) hp->channels = atoi(p); p = strtok(NULL, ","); if (p) hp->byte_order = string_to_byte_order(p); if (!hp->format || !hp->sample_rate || !hp->precision || !hp->channels || !hp->byte_order) { report(REPORT_ERROR, "helper_read: parse error line %d\n", line); done(1); } report(REPORT_DEBUG, "adding helper for \"%s\"\n", pat); if (helpers == NULL) { helpers = hp; tail = hp; } else { tail->next = hp; tail = hp; } } fclose(fp); } #ifdef __STDC__ HELPER * helper_lookup(char *sound) #else HELPER * helper_lookup(sound) char *sound; #endif { HELPER *hp; for (hp = helpers; hp; hp = hp->next) { if (regnexec(&hp->pattern, sound, strlen(sound), 0, 0, 0) == 0) { return hp; } } return NULL; } #ifdef __STDC__ void helper_reread(char *filename) #else void helper_reread(filename) char *filename; #endif { HELPER *hp, *hp_next; report(REPORT_DEBUG, "re-reading helpers\n"); for (hp = helpers; hp; hp = hp_next) { hp_next = hp->next; regfree(&hp->pattern); free(hp->program); } helpers = NULL; helper_read(filename); } #ifdef __STDC__ void helper_stat(char *filename) #else void helper_stat(filename) char *filename; #endif { if (modified(filename, helper_read_time)) { helper_reread(filename); } } #endif /* HAVE_HELPERS */ rplay-3.3.2/rplayd/helper.h100644 153 62 2726 6727404540 14257 0ustar boynsstaff/* $Id: helper.h,v 1.4 1999/06/09 06:27:44 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _helper_h #define _helper_h #ifdef HAVE_HELPERS #ifdef HAVE_RX_RXPOSIX_H #include #else #ifdef HAVE_RXPOSIX_H #include #else #include "rxposix.h" #endif #endif typedef struct _helper { struct _helper *next; regex_t pattern; char *program; int format; int sample_rate; int precision; int channels; int byte_order; } HELPER; extern HELPER *helpers; extern void helper_read (/* char *filename */); extern void helper_stat (/* char *filename */); extern HELPER *helper_lookup (/* char *sound */); #endif /* HAVE_HELPERS */ #endif /* _helper_h */ rplay-3.3.2/rplayd/host.c100644 153 62 22270 6727404540 13764 0ustar boynsstaff/* $Id: host.c,v 1.6 1999/06/09 06:27:44 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "rplayd.h" #include #include #ifdef HAVE_STRING_H #include #endif #include "host.h" #include "buffer.h" #include "misc.h" #ifdef HAVE_RX_RXPOSIX_H #include #else #ifdef HAVE_RXPOSIX_H #include #else #include "rxposix.h" #endif #endif #ifdef AUTH static regex_t access_read, access_write, access_execute, access_monitor; BUFFER *host_list = NULL; BUFFER *b; static time_t host_read_time = 0; /* * read the rplay hosts file * * This routine will build a regular expression for each type of access. * The expressions are of the form: * \(130\.191\.224\.2\|130\.191\..*\) */ #ifdef __STDC__ void host_read(char *filename) #else void host_read(filename) char *filename; #endif { FILE *fp; char buf[BUFSIZ], *perms, *name, *p; char expr_read[HOST_EXPR_SIZE]; char expr_write[HOST_EXPR_SIZE]; char expr_execute[HOST_EXPR_SIZE]; char expr_monitor[HOST_EXPR_SIZE]; int error = 0; host_read_time = time(0); fp = fopen(filename, "r"); if (fp == NULL) { report(REPORT_ERROR, "host_read: cannot open %s\n", filename); /* Don't exit anymore. Localhost will be added automatically later. */ } b = buffer_create(); b->status = BUFFER_KEEP; strcpy(b->buf, "+message=\"hosts\"\r\n"); b->nbytes += strlen(b->buf); host_list = b; //memset ((char *) &access_read, 0, sizeof (access_read)); //memset ((char *) &access_write, 0, sizeof (access_write)); //memset ((char *) &access_execute, 0, sizeof (access_execute)); strcpy(expr_read, "^\\("); strcpy(expr_write, "^\\("); strcpy(expr_execute, "^\\("); strcpy(expr_monitor, "^\\("); do { if (fp) { p = fgets(buf, sizeof(buf), fp); if (!p) { fclose(fp); break; } } else { /* rplay.hosts wasn't found and AUTH was defined in config.h. Assume that only the localhost should have access. */ SNPRINTF(SIZE(buf, sizeof(buf)), "%s:rwx", hostaddr); report(REPORT_NOTICE, "host_read: adding %s\n", buf); } switch (buf[0]) { case '#': case ' ': case '\t': case '\n': continue; } p = strchr(buf, '\n'); if (p) { *p = '\0'; } name = buf; perms = strchr(buf, ':'); if (perms) { *perms = '\0'; perms++; } else { perms = HOST_DEFAULT_ACCESS; } host_insert(expr_read, expr_write, expr_execute, expr_monitor, name, perms); } while (fp); if (b->nbytes + 3 > BUFFER_SIZE) /* room for .\r\n */ { b->next = buffer_create(); b = b->next; b->status = BUFFER_KEEP; } SNPRINTF(SIZE(b->buf + strlen(b->buf), BUFFER_SIZE - b->nbytes), ".\r\n"); b->nbytes += 3; if (strlen(expr_read) == 3) { strcat(expr_read, "\\)"); } else { expr_read[strlen(expr_read) - 1] = ')'; } strcat(expr_read, "$"); if (strlen(expr_write) == 3) { strcat(expr_write, "\\)"); } else { expr_write[strlen(expr_write) - 1] = ')'; } strcat(expr_write, "$"); if (strlen(expr_execute) == 3) { strcat(expr_execute, "\\)"); } else { expr_execute[strlen(expr_execute) - 1] = ')'; } strcat(expr_execute, "$"); if (strlen(expr_monitor) == 3) { strcat(expr_monitor, "\\)"); } else { expr_monitor[strlen(expr_monitor) - 1] = ')'; } strcat(expr_monitor, "$"); error = regncomp(&access_read, expr_read, strlen(expr_read), REG_ICASE | REG_NOSUB); if (error) { report(REPORT_ERROR, "host_read: regncomp: %d\n", error); done(1); } error = regncomp(&access_write, expr_write, strlen(expr_write), REG_ICASE | REG_NOSUB); if (error) { report(REPORT_ERROR, "host_read: regncomp: %d\n", error); done(1); } error = regncomp(&access_execute, expr_execute, strlen(expr_execute), REG_ICASE | REG_NOSUB); if (error) { report(REPORT_ERROR, "host_read: regncomp: %d\n", error); done(1); } error = regncomp(&access_monitor, expr_monitor, strlen(expr_monitor), REG_ICASE | REG_NOSUB); if (error) { report(REPORT_ERROR, "host_read: regncomp: %d\n", error); done(1); } } #ifdef __STDC__ void host_reread(char *filename) #else void host_reread(filename) char *filename; #endif { BUFFER *b, *bb; report(REPORT_DEBUG, "re-reading hosts\n"); /* * Free the old host buffer list. */ for (b = host_list; b; bb = b, b = b->next, bb->status = BUFFER_FREE, buffer_destroy(bb)) ; host_list = NULL; host_read(filename); } #ifdef __STDC__ void host_stat(char *filename) #else void host_stat(filename) char *filename; #endif { if (modified(filename, host_read_time)) { host_reread(filename); } } #ifdef __STDC__ void host_insert(char *expr_read, char *expr_write, char *expr_execute, char *expr_monitor, char *name, char *perms) #else void host_insert(expr_read, expr_write, expr_execute, expr_monitor, name, perms) char *expr_read; char *expr_write; char *expr_execute; char *expr_monitor; char *name; char *perms; #endif { unsigned long addr; struct in_addr addr_in; struct hostent *hp; int n; char **ap, *p; char *re_name = 0; char line[RPTP_MAX_LINE]; SNPRINTF(SIZE(line, sizeof(line)), "host=%s access=%s\r\n", name, perms); n = strlen(line); if (b->nbytes + n > BUFFER_SIZE) { b->next = buffer_create(); b = b->next; b->status = BUFFER_KEEP; } strcat(b->buf, line); b->nbytes += n; if (strchr(name, '*')) { re_name = host_ip_to_regex(name); } else { addr = inet_addr(name); if (addr == 0xffffffff) { hp = gethostbyname(name); if (hp == NULL) { report(REPORT_NOTICE, "warning: %s unknown host\n", name); return; } /* * Handle multiple IP address. */ for (ap = hp->h_addr_list + 1; *ap; ap++) { memcpy((char *) &addr_in, *ap, hp->h_length); host_insert(expr_read, expr_write, expr_execute, expr_monitor, inet_ntoa(addr_in), perms); } memcpy((char *) &addr_in, (char *) hp->h_addr, sizeof(addr_in)); re_name = host_ip_to_regex(inet_ntoa(addr_in)); } else { memcpy((char *) &addr_in, (char *) &addr, sizeof(addr_in)); re_name = host_ip_to_regex(inet_ntoa(addr_in)); } /* * Add localhost automatically. */ if (strcmp(hostaddr, "127.0.0.1") != 0 && strcmp(inet_ntoa(addr_in), hostaddr) == 0) { report(REPORT_DEBUG, "host_insert: adding localhost (127.0.0.1)\n"); host_insert(expr_read, expr_write, expr_execute, expr_monitor, "127.0.0.1", perms); } } for (p = perms; *p; p++) { switch (*p) { case HOST_READ: strcat(expr_read, re_name); strcat(expr_read, "\\|"); break; case HOST_WRITE: strcat(expr_write, re_name); strcat(expr_write, "\\|"); break; case HOST_EXECUTE: strcat(expr_execute, re_name); strcat(expr_execute, "\\|"); break; case HOST_MONITOR: strcat(expr_monitor, re_name); strcat(expr_monitor, "\\|"); break; default: report(REPORT_ERROR, "host_insert: '%c' unknown host access permission\n", *p); done(1); } } if (re_name) { free(re_name); } } /* return 1 if allowed */ #ifdef __STDC__ int host_access(struct sockaddr_in sin, char access_mode) #else int host_access(sin, access_mode) struct sockaddr_in sin; char access_mode; #endif { char *p; regex_t *re; int n; /* * Accept all accesses when authentication is not enabled. */ if (!auth_enabled) { return 1; } p = inet_ntoa(sin.sin_addr); switch (access_mode) { case HOST_READ: re = &access_read; break; case HOST_WRITE: re = &access_write; break; case HOST_EXECUTE: re = &access_execute; break; case HOST_MONITOR: re = &access_monitor; break; default: report(REPORT_ERROR, "host_access: unknown access mode '%s'\n", access_mode); done(1); } n = regnexec(re, p, strlen(p), 0, 0, 0); return !n; } #ifdef __STDC__ char * host_ip_to_regex(char *p) #else char * host_ip_to_regex(p) char *p; #endif { char buf[64]; char *q; for (q = buf; *p; p++, q++) { switch (*p) { case '.': *q++ = '\\'; *q = '.'; break; case '*': *q++ = '.'; *q = '*'; break; default: *q = *p; } } *q = '\0'; return strdup(buf); } #endif /* AUTH */ rplay-3.3.2/rplayd/host.h100644 153 62 3603 6671423013 13742 0ustar boynsstaff/* $Id: host.h,v 1.3 1999/03/10 07:58:03 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _host_h #define _host_h #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "buffer.h" #ifdef AUTH #define HOST_EXPR_SIZE 1024 #define HOST_READ 'r' #define HOST_WRITE 'w' #define HOST_EXECUTE 'x' #define HOST_MONITOR 'm' #define HOST_DEFAULT_ACCESS "rx" extern BUFFER *host_list; #ifdef __STDC__ extern void host_read (char *filename); extern void host_reread (char *filename); extern void host_stat (char *filename); extern char *host_ip_to_regex (char *ip_addr); extern int host_access (struct sockaddr_in sin, char access_mode); extern void host_insert (char *expr_read, char *expr_write, char *expr_execute, char *expr_monitor, char *name, char *perms); #else extern void host_read ( /* char *filename */ ); extern void host_reread ( /* char *filename */ ); extern void host_stat ( /* char *filename */ ); extern char *host_ip_to_regex ( /* char *ip_addr */ ); extern int host_access ( /* struct sockaddr_in sin, char access_mode */ ); extern void host_insert (); #endif #endif /* AUTH */ #endif /* _host_h */ rplay-3.3.2/rplayd/misc.c100644 153 62 31400 6671423013 13727 0ustar boynsstaff/* $Id: misc.c,v 1.5 1999/03/10 07:58:03 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "rplayd.h" #include #include #include #include #ifdef ultrix #include #else #include #endif #include #include #include #include #include "sound.h" #include "timer.h" #ifdef __STDC__ char * sys_err_str(int error) #else char * sys_err_str(error) int error; #endif { #ifdef HAVE_STRERROR return (char *) strerror(error); #else extern char *sys_errlist[]; return sys_errlist[error]; #endif } #ifdef __STDC__ int udp_socket(int port) #else int udp_socket(port) int port; #endif { int fd; struct sockaddr_in s; fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { report(REPORT_ERROR, "socket: %s\n", sys_err_str(errno)); done(1); } s.sin_family = AF_INET; s.sin_port = htons(port); s.sin_addr.s_addr = INADDR_ANY; if (bind(fd, (struct sockaddr *) &s, sizeof(s)) < 0) { report(REPORT_ERROR, "bind: %s\n", sys_err_str(errno)); done(1); } return fd; } #ifdef __STDC__ int tcp_socket(int port) #else int tcp_socket(port) int port; #endif { int fd; struct sockaddr_in s; int on = 1; fd = socket(AF_INET, SOCK_STREAM, 0); if (fd < 0) { report(REPORT_ERROR, "socket: %s\n", sys_err_str(errno)); done(1); } if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on)) < 0) { report(REPORT_ERROR, "setsockopt: SO_REUSEADDR: %s\n", sys_err_str(errno)); done(1); } s.sin_family = AF_INET; s.sin_port = htons(port); s.sin_addr.s_addr = INADDR_ANY; if (bind(fd, (struct sockaddr *) &s, sizeof(s)) < 0) { report(REPORT_ERROR, "bind: %s\n", sys_err_str(errno)); done(1); } if (listen(fd, 5) < 0) { report(REPORT_ERROR, "listen: %s\n", sys_err_str(errno)); done(1); } return fd; } /* * make a file descriptor non-blocking */ #ifdef __STDC__ void fd_nonblock(int fd) #else void fd_nonblock(fd) int fd; #endif { int flags; flags = fcntl(fd, F_GETFL, 0); if (flags < 0) { report(REPORT_ERROR, "fd_nonblock: F_GETFL fcntl: %s\n", sys_err_str(errno)); done(1); } #ifdef linux flags |= O_NONBLOCK; #else flags |= FNDELAY; #endif if (fcntl(fd, F_SETFL, flags) < 0) { report(REPORT_ERROR, "fd_nonblock: F_SETFL fcntl: %s\n", sys_err_str(errno)); done(1); } } /* * make a file descriptor blocking */ #ifdef __STDC__ void fd_block(int fd) #else void fd_block(fd) int fd; #endif { int flags; flags = fcntl(fd, F_GETFL, 0); if (flags < 0) { report(REPORT_ERROR, "fd_block: F_GETFL fcntl: %s\n", sys_err_str(errno)); done(1); } #ifdef linux flags &= ~O_NONBLOCK; #else flags &= ~FNDELAY; #endif if (fcntl(fd, F_SETFL, flags) < 0) { report(REPORT_ERROR, "fd_block: F_SETFL fcntl: %s\n", sys_err_str(errno)); done(1); } } #ifdef __STDC__ int modified(char *filename, time_t since) #else int modified(filename, since) char *filename; time_t since; #endif { struct stat st; if (stat(filename, &st) < 0) { report(REPORT_ERROR, "%s: %s\n", filename, sys_err_str(errno)); return 0; } return ((time_t) st.st_mtime > since) ? 1 : 0; } #ifdef __STDC__ char * time2string(time_t t) #else char * time2string(t) time_t t; #endif { static char buf[64]; int days, hours, mins, secs; days = t / (60 * 60 * 24); t %= (60 * 60 * 24); hours = t / (60 * 60); t %= (60 * 60); mins = t / 60; t %= 60; secs = t; buf[0] = '\0'; if (days > 0) { SNPRINTF(SIZE(buf, sizeof(buf)), "%d+", days); } SNPRINTF(SIZE(buf + strlen(buf), sizeof(buf) - strlen(buf)), "%02d:%02d:%02d", hours, mins, secs); return buf; } #ifdef __STDC__ char * audio_format_to_string(int format) #else char * audio_format_to_string(format) int format; #endif { switch (format) { case RPLAY_FORMAT_ULAW: return "ulaw"; case RPLAY_FORMAT_LINEAR_8: return "linear-8"; case RPLAY_FORMAT_ULINEAR_8: return "ulinear-8"; case RPLAY_FORMAT_LINEAR_16: return "linear-16"; case RPLAY_FORMAT_ULINEAR_16: return "ulinear-16"; case RPLAY_FORMAT_G721: return "g721"; case RPLAY_FORMAT_G723_3: return "g723-3"; case RPLAY_FORMAT_G723_5: return "g723-5"; case RPLAY_FORMAT_GSM: return "gsm"; default: return "unknown"; } } #ifdef __STDC__ int string_to_audio_format(char *string) #else int string_to_audio_format(string) char *string; #endif { if (strcmp(string, "ulaw") == 0 || strcmp(string, "u_law") == 0 || strcmp(string, "u-law") == 0) { return RPLAY_FORMAT_ULAW; } else if (strcmp(string, "linear-16") == 0 || strcmp(string, "linear_16") == 0 || strcmp(string, "linear16") == 0) { return RPLAY_FORMAT_LINEAR_16; } else if (strcmp(string, "ulinear-16") == 0 || strcmp(string, "ulinear_16") == 0 || strcmp(string, "ulinear16") == 0) { return RPLAY_FORMAT_ULINEAR_16; } else if (strcmp(string, "linear-8") == 0 || strcmp(string, "linear_8") == 0 || strcmp(string, "linear8") == 0) { return RPLAY_FORMAT_LINEAR_8; } else if (strcmp(string, "ulinear-8") == 0 || strcmp(string, "ulinear_8") == 0 || strcmp(string, "ulinear8") == 0) { return RPLAY_FORMAT_ULINEAR_8; } else if (strcmp(string, "g721") == 0) { return RPLAY_FORMAT_G721; } else if (strcmp(string, "g723-3") == 0 || strcmp(string, "g723_3") == 0) { return RPLAY_FORMAT_G723_3; } else if (strcmp(string, "g723-5") == 0 || strcmp(string, "g723_5") == 0) { return RPLAY_FORMAT_G723_5; } else if (strcmp(string, "gsm") == 0 || strcmp(string, "GSM") == 0) { return RPLAY_FORMAT_GSM; } else { return RPLAY_FORMAT_NONE; } } #ifdef __STDC__ char * byte_order_to_string(int byte_order) #else char * byte_order_to_string(byte_order) int byte_order; #endif { switch (byte_order) { case RPLAY_BIG_ENDIAN: return "big-endian"; case RPLAY_LITTLE_ENDIAN: return "little-endian"; default: return "unknown"; } } #ifdef __STDC__ int string_to_byte_order(char *string) #else int string_to_byte_order(string) char *string; #endif { if (strcmp(string, "big-endian") == 0 || strcmp(string, "big") == 0) { return RPLAY_BIG_ENDIAN; } else if (strcmp(string, "little-endian") == 0 || strcmp(string, "little") == 0) { return RPLAY_LITTLE_ENDIAN; } else { return 0; } } #ifdef __STDC__ char * storage_to_string(int storage) #else char * storage_to_string(storage) int storage; #endif { switch (storage) { case SOUND_STORAGE_NONE: return "none"; case SOUND_STORAGE_DISK: return "disk"; case SOUND_STORAGE_MEMORY: return "memory"; default: return "unknown"; } } #ifdef __STDC__ int string_to_storage(char *string) #else int string_to_storage(string) char *string; #endif { if (strcmp(string, "none") == 0) { return SOUND_STORAGE_NONE; } else if (strcmp(string, "disk") == 0) { return SOUND_STORAGE_DISK; } else if (strcmp(string, "memory") == 0) { return SOUND_STORAGE_MEMORY; } else { return SOUND_STORAGE_NULL; } } #ifdef __STDC__ char * input_to_string(int input) #else char * input_to_string(input) int input; #endif { switch (input) { case SOUND_FILE: return "file"; case SOUND_FLOW: return "flow"; #ifdef HAVE_CDROM case SOUND_CDROM: return "cdrom"; #endif /* HAVE_CDROM */ case SOUND_VIRTUAL: return "virtual"; default: return "unknown"; } } #ifdef __STDC__ int string_to_input(char *string) #else int string_to_input(string) char *string; #endif { if (strcmp(string, "file") == 0) { return SOUND_FILE; } else if (strcmp(string, "flow") == 0) { return SOUND_FLOW; } else { return 0; } } #ifdef __STDC__ char * audio_port_to_string(int port) #else char * audio_port_to_string(port) int port; #endif { static char string[128]; int n; string[0] = '\0'; if (BIT(port, RPLAY_AUDIO_PORT_NONE)) { strncat(string, "none,", sizeof(string) - strlen(string)); } if (BIT(port, RPLAY_AUDIO_PORT_SPEAKER)) { strncat(string, "speaker,", sizeof(string) - strlen(string)); } if (BIT(port, RPLAY_AUDIO_PORT_HEADPHONE)) { strncat(string, "headphone,", sizeof(string) - strlen(string)); } if (BIT(port, RPLAY_AUDIO_PORT_LINEOUT)) { strncat(string, "lineout,", sizeof(string) - strlen(string)); } string[strlen(string) - 1] = '\0'; return string; } unsigned short little_short(p) char *p; { return (((unsigned long) (((unsigned char *) p)[1])) << 8) | ((unsigned long) (((unsigned char *) p)[0])); } unsigned short big_short(p) char *p; { return (((unsigned long) (((unsigned char *) p)[0])) << 8) | ((unsigned long) (((unsigned char *) p)[1])); } unsigned long little_long(p) char *p; { return (((unsigned long) (((unsigned char *) p)[3])) << 24) | (((unsigned long) (((unsigned char *) p)[2])) << 16) | (((unsigned long) (((unsigned char *) p)[1])) << 8) | ((unsigned long) (((unsigned char *) p)[0])); } unsigned long big_long(p) char *p; { return (((unsigned long) (((unsigned char *) p)[0])) << 24) | (((unsigned long) (((unsigned char *) p)[1])) << 16) | (((unsigned long) (((unsigned char *) p)[2])) << 8) | ((unsigned long) (((unsigned char *) p)[3])); } /* * C O N V E R T F R O M I E E E E X T E N D E D */ /* * Copyright (C) 1988-1991 Apple Computer, Inc. * All rights reserved. * * Machine-independent I/O routines for IEEE floating-point numbers. * * NaN's and infinities are converted to HUGE_VAL or HUGE, which * happens to be infinity on IEEE machines. Unfortunately, it is * impossible to preserve NaN's in a machine-independent way. * Infinities are, however, preserved on IEEE machines. * * These routines have been tested on the following machines: * Apple Macintosh, MPW 3.1 C compiler * Apple Macintosh, THINK C compiler * Silicon Graphics IRIS, MIPS compiler * Cray X/MP and Y/MP * Digital Equipment VAX * * * Implemented by Malcolm Slaney and Ken Turkowski. * * Malcolm Slaney contributions during 1988-1990 include big- and little- * endian file I/O, conversion to and from Motorola's extended 80-bit * floating-point format, and conversions to and from IEEE single- * precision floating-point format. * * In 1991, Ken Turkowski implemented the conversions to and from * IEEE double-precision format, added more precision to the extended * conversions, and accommodated conversions involving +/- infinity, * NaN's, and denormalized numbers. */ #ifndef HUGE_VAL #define HUGE_VAL HUGE #endif /*HUGE_VAL */ #define UnsignedToFloat(u) (((double)((long)(u - 2147483647L - 1))) + 2147483648.0) /**************************************************************** * Extended precision IEEE floating-point conversion routine. ****************************************************************/ double ConvertFromIeeeExtended(bytes) unsigned char *bytes; /* LCN */ { double f; int expon; unsigned long hiMant, loMant; expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF); hiMant = ((unsigned long) (bytes[2] & 0xFF) << 24) | ((unsigned long) (bytes[3] & 0xFF) << 16) | ((unsigned long) (bytes[4] & 0xFF) << 8) | ((unsigned long) (bytes[5] & 0xFF)); loMant = ((unsigned long) (bytes[6] & 0xFF) << 24) | ((unsigned long) (bytes[7] & 0xFF) << 16) | ((unsigned long) (bytes[8] & 0xFF) << 8) | ((unsigned long) (bytes[9] & 0xFF)); if (expon == 0 && hiMant == 0 && loMant == 0) { f = 0; } else { if (expon == 0x7FFF) { /* Infinity or NaN */ f = HUGE_VAL; } else { expon -= 16383; f = ldexp(UnsignedToFloat(hiMant), expon -= 31); f += ldexp(UnsignedToFloat(loMant), expon -= 32); } } if (bytes[0] & 0x80) return -f; else return f; } rplay-3.3.2/rplayd/misc.h100644 153 62 5320 6671423013 13716 0ustar boynsstaff/* $Id: misc.h,v 1.3 1999/03/10 07:58:03 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _misc_h #define _misc_h #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #ifdef __STDC__ extern char *sys_err_str (int error); extern int udp_socket (int port); extern int tcp_socket (int port); extern void fd_nonblock (int fd); extern void fd_block (int fd); extern int modified (char *filename, time_t since); extern char *time2string (time_t t); extern int string_to_audio_format (char *string); extern char *audio_format_to_string (int format); extern int string_to_byte_order (char *string); extern char *byte_order_to_string (int byte_order); extern int string_to_storage (char *string); extern char *storage_to_string (int storage); extern int string_to_input (char *string); extern char *input_to_string (int input); extern char *audio_port_to_string (int port); #else extern char *sys_err_str ( /* int error */ ); extern int udp_socket ( /* int port */ ); extern int tcp_socket ( /* int port */ ); extern void fd_nonblock ( /* int fd */ ); extern void fd_block ( /* int fd */ ); extern int modified ( /* char *filename, time_t since */ ); extern char *time2string ( /* time_t t */ ); extern int string_to_audio_format ( /* char *string */ ); extern char *audio_format_to_string ( /* int format */ ); extern int string_to_byte_order ( /* char *string */ ); extern char *byte_order_to_string ( /* int byte_order */ ); extern int string_to_storage ( /* char *string */ ); extern char *storage_to_string ( /* int storage */ ); extern int string_to_input ( /* char *string */ ); extern char *input_to_string ( /* int input */ ); extern char *audio_port_to_string ( /* int port */ ); #endif unsigned short little_short ( /* char *p */ ); unsigned short big_short ( /* char *p */ ); unsigned long little_long ( /* char *p */ ); unsigned long big_long ( /* char *p */ ); double ConvertFromIeeeExtended ( /* unsigned char *bytes */ ); #endif /* _misc_h */ rplay-3.3.2/rplayd/native.c100644 153 62 32304 6671423013 14266 0ustar boynsstaff/* $Id: native.c,v 1.4 1999/03/10 07:58:03 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "spool.h" #include "sound.h" #include "buffer.h" #include "rplayd.h" #include "native.h" #include "ulaw.h" /* Native means 16-bit signed. */ static int ulaw_to_native( /* SPOOL *sp, char *native_buf, int nsamples, int nchannels */ ); static int s8_to_native( /* SPOOL *sp, char *native_buf, int nsamples, int nchannels */ ); static int u8_to_native( /* SPOOL *sp, char *native_buf, int nsamples, int nchannels */ ); static int big_s16_to_native( /* SPOOL *sp, char *native_buf, int nsamples, int nchannels */ ); static int big_u16_to_native( /* SPOOL *sp, char *native_buf, int nsamples, int nchannels */ ); static int little_s16_to_native( /* SPOOL *sp, char *native_buf, int nsamples, int nchannels */ ); static int little_u16_to_native( /* SPOOL *sp, char *native_buf, int nsamples, int nchannels */ ); static int native_to_native( /* SPOOL *sp, char *native_buf, int nsamples, int nchannels */ ); static int native_to_ulaw( /* char *native_buf, int nsamples, int nchannels */ ); static int native_to_s8( /* char *native_buf, int nsamples, int nchannels */ ); static int native_to_u8( /* char *native_buf, int nsamples, int nchannels */ ); static int native_to_s16( /* char *native_buf, int nsamples, int nchannels */ ); static int native_to_u16( /* char *native_buf, int nsamples, int nchannels */ ); static int native_to_g721( /* char *native_buf, int nsamples, int nchannels */ ); static int native_to_g723_3( /* char *native_buf, int nsamples, int nchannels */ ); static int native_to_g723_5( /* char *native_buf, int nsamples, int nchannels */ ); static int native_to_gsm( /* char *native_buf, int nsamples, int nchannels */ ); /* Setup the to and from native table. */ NATIVE_TABLE native_table[] = { { {0, 0}, {0, 0}}, { {s8_to_native, s8_to_native}, {native_to_s8, native_to_s8}}, { {u8_to_native, u8_to_native}, {native_to_u8, native_to_u8}}, { {big_s16_to_native, little_s16_to_native}, {native_to_s16, native_to_s16}}, { {big_u16_to_native, little_u16_to_native}, {native_to_u16, native_to_u16}}, { {ulaw_to_native, ulaw_to_native}, {native_to_ulaw, native_to_ulaw}}, #ifdef HAVE_ADPCM { {native_to_native, native_to_native}, {native_to_g721, native_to_g721}}, { {native_to_native, native_to_native}, {native_to_g723_3, native_to_g723_5}}, { {native_to_native, native_to_native}, {native_to_g723_3, native_to_g723_5}}, #endif /* HAVE_ADPCM */ #ifdef HAVE_GSM { {native_to_native, native_to_native}, {native_to_gsm, native_to_gsm}}, #endif /* HAVE_GSM */ }; /* Initialize the native audio buffer. */ void zero_native(native_buf, nsamples, nchannels) char *native_buf; int nsamples; int nchannels; { memset(native_buf, 0, nsamples * nchannels * 2); /* 2 == 16-bit */ } void level(native_buf, nsamples, nchannels) char *native_buf; int nsamples; int nchannels; { short *p = (short *) native_buf, sample; int n = nsamples * nchannels; long left_max = 0, right_max = 0; /* Optimize the cases for stereo and mono output. */ if (nchannels == 2) /* stereo */ { while (n--) { #ifdef FAKE_VOLUME sample = (*p++ >> 7); #else sample = (*p++ * rplay_audio_volume) >> 14; #endif if (n & 1) { if (sample > right_max) { right_max = sample; } } else { if (sample > left_max) { left_max = sample; } } } } else /* mono */ { while (n--) { #ifdef FAKE_VOLUME sample = (*p++ >> 7); #else sample = (*p++ * rplay_audio_volume) >> 14; #endif if (sample > left_max) { left_max = sample; } } right_max = left_max; } rplay_audio_left_level = left_max; rplay_audio_right_level = right_max; } #ifdef FAKE_VOLUME /* Simulate hardware volume control. */ void fake_volume(native_buf, nsamples, nchannels) char *native_buf; int nsamples; int nchannels; { short *p = (short *) native_buf; int n = nsamples * nchannels; while (n--) { *p++ = (*p * rplay_audio_volume) >> 7; } } #endif /* FAKE_VOLUME */ /* Move `sp' to the next sample. */ #define next_sample(sp, s) \ { \ int sample_delta; \ \ sample_delta = sp->sample_index; \ sp->sample_index += sp->sample_factor; \ sample_delta = sp->sample_index - sample_delta; \ sp->offset = sample_delta * s->output_sample_size; \ if (s->samples > 0 \ && sp->sample_index >= s->samples \ && (s->type == SOUND_FILE || sp->si->eof)) \ { \ return 0; \ } \ } #define check_buffers(sp) \ { \ /* Compute the next offset. */ \ sp->offset = sp->ptr - sp->ptr_end; \ \ /* Try to use curr_buffer's next buffer. */ \ if (sp->curr_buffer->next && sp->curr_buffer->next->nbytes > 0) \ { \ BUFFER *b = sp->curr_buffer; \ \ /* report (REPORT_DEBUG, "* using curr_buffer->next\n"); */ \ \ sp->curr_buffer = sp->curr_buffer->next; \ sp->ptr = (unsigned char *)sp->curr_buffer->buf; \ sp->ptr_end = (unsigned char *)sp->curr_buffer->buf \ + sp->curr_buffer->nbytes; \ \ buffer_destroy (b); \ } \ /* Try to use next_buffer. */ \ else if (sp->next_buffer) \ { \ BUFFER *b = sp->curr_buffer; \ \ /* report (REPORT_DEBUG, "* using next_buffer\n"); */ \ \ sp->curr_buffer = sp->next_buffer; \ sp->ptr = (unsigned char *)sp->curr_buffer->buf; \ sp->ptr_end = (unsigned char *)sp->curr_buffer->buf \ + sp->curr_buffer->nbytes; \ \ sp->next_buffer = NULL; \ \ buffer_dealloc (b, 0); \ } \ /* No more buffers are available. */ \ else \ { \ /* report (REPORT_DEBUG, "* no buffers!\n"); */ \ \ buffer_dealloc (sp->curr_buffer, 0); \ sp->curr_buffer = NULL; \ \ break; \ } \ } /* Return 0 when the sound is over, otherwise return 1. */ #define x_to_native(FUNC, SAMPLE_TO_NATIVE) \ static int \ FUNC (sp, native_buf, nsamples, nchannels) \ SPOOL *sp; \ short *native_buf; \ int nsamples; \ int nchannels; \ { \ SOUND *curr_sound; \ short new_volume; \ int sample_count = 0; \ int curr_channel; \ short linear; \ short orig_linear; \ short *buf = (short *)native_buf; \ \ /* Find the sound that being played. */ \ curr_sound = sp->sound[sp->curr_sound]; \ \ /* Compute the new volume for the sound using priorities. */ \ new_volume = sp->curr_attrs->volume; \ if (spool_prio && spool_nplaying > 1) \ { \ new_volume -= (spool_prio - sp->rp->priority) >> 1; \ new_volume = MAX(new_volume, RPLAY_MIN_VOLUME); \ } \ \ /* do oversampling */ \ if (sp->sample_factor < 1) \ { \ while (sp->curr_buffer && sample_count < nsamples) \ { \ sp->ptr += sp->offset; \ if (sp->ptr < sp->ptr_end) \ { \ for (curr_channel = 0; curr_channel < nchannels; curr_channel++) \ { \ if (curr_channel < curr_sound->channels) \ { \ SAMPLE_TO_NATIVE; \ orig_linear = linear; \ linear = sp->oversample[curr_channel]; \ sp->oversample[curr_channel] += sp->oversample_inc[curr_channel]; \ if (sp->sample_index + sp->sample_factor > sp->offset + 1) \ { \ sp->oversample_inc[curr_channel] = (orig_linear - \ sp->oversample[curr_channel]) * sp->sample_factor; \ } \ } \ *buf++ += ((linear * new_volume) >> 7); \ } \ sample_count++; \ next_sample (sp, curr_sound); \ } \ else \ { \ check_buffers (sp); \ } \ } \ } \ /* read the sound as-is */ \ else \ { \ while (sp->curr_buffer && sample_count < nsamples) \ { \ sp->ptr += sp->offset; \ if (sp->ptr < sp->ptr_end) \ { \ for (curr_channel = 0; curr_channel < nchannels; curr_channel++) \ { \ if (curr_channel < curr_sound->channels) \ { \ SAMPLE_TO_NATIVE; \ } \ *buf++ += ((linear * new_volume) >> 7); \ } \ sample_count++; \ next_sample (sp, curr_sound); \ } \ else \ { \ check_buffers (sp); \ } \ } \ } \ \ return 1; \ } /* ulaw */ x_to_native ( ulaw_to_native, linear = ulaw_to_linear(*(sp->ptr + curr_channel)) ) /* signed 8-bit */ x_to_native ( s8_to_native, linear = (char) *(sp->ptr + curr_channel); linear <<= 8 ) /* unsigned 8-bit */ x_to_native ( u8_to_native, linear = (unsigned char) *(sp->ptr + curr_channel) ^ 0x80; linear <<= 8 ) /* signed 16-bit big-endian */ x_to_native ( big_s16_to_native, linear = (short) (sp->ptr[curr_channel << 1] << 8 | sp->ptr[(curr_channel << 1) + 1]) ) /* signed 16-bit little-endian */ x_to_native ( little_s16_to_native, linear = (short) (sp->ptr[(curr_channel << 1) + 1] << 8 | sp->ptr[curr_channel << 1]) ) /* unsigned 16-bit big-endian */ x_to_native ( big_u16_to_native, linear = (short) (sp->ptr[curr_channel << 1] << 8 | sp->ptr[(curr_channel << 1) + 1]) ^ 0x8000; ) /* unsigned 16-bit little-endian */ x_to_native ( little_u16_to_native, linear = (short) (sp->ptr[(curr_channel << 1) + 1] << 8 | sp->ptr[curr_channel << 1]) ^ 0x8000; ) /* native to native */ x_to_native ( native_to_native, linear = (*((short *) sp->ptr + curr_channel)) ) static int native_to_ulaw(native_buf, nsamples, nchannels) char *native_buf; int nsamples; int nchannels; { short *from = (short *) native_buf; char *to = (char *) native_buf; int n = nsamples * nchannels; while (n--) { *to++ = linear_to_ulaw(*from++); } return 0; } static int native_to_s8(native_buf, nsamples, nchannels) char *native_buf; int nsamples; int nchannels; { short *from = (short *) native_buf; char *to = (char *) native_buf; int n = nsamples * nchannels; while (n--) { *to++ = (*from++ >> 8); } return 0; } static int native_to_u8(native_buf, nsamples, nchannels) char *native_buf; int nsamples; int nchannels; { short *from = (short *) native_buf; char *to = (char *) native_buf; int n = nsamples * nchannels; while (n--) { *to++ = (*from++ >> 8) ^ 0x80; } return 0; } static int native_to_s16(native_buf, nsamples, nchannels) char *native_buf; int nsamples; int nchannels; { /* The native audio buffer is already signed 16-bit. */ return 0; } static int native_to_u16(native_buf, nsamples, nchannels) char *native_buf; int nsamples; int nchannels; { short *from = (short *) native_buf; short *to = (short *) native_buf; int n = nsamples * nchannels; while (n--) { *to++ = *from++ ^ 0x8000; } return 0; } #ifdef HAVE_ADPCM static int native_to_g721(native_buf, nsamples, nchannels) char *native_buf; int nsamples; int nchannels; { /* NOT SUPPORTED */ return 0; } static int native_to_g723_3(native_buf, nsamples, nchannels) char *native_buf; int nsamples; int nchannels; { /* NOT SUPPORTED */ return 0; } static int native_to_g723_5(native_buf, nsamples, nchannels) char *native_buf; int nsamples; int nchannels; { /* NOT SUPPORTED */ return 0; } #endif /* HAVE_ADPCM */ #ifdef HAVE_GSM static int native_to_gsm(native_buf, nsamples, nchannels) char *native_buf; int nsamples; int nchannels; { /* NOT SUPPORTED */ return 0; } #endif /* HAVE_GSM */ rplay-3.3.2/rplayd/native.h100644 153 62 3000 6671423014 14243 0ustar boynsstaff/* $Id: native.h,v 1.3 1999/03/10 07:58:04 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _native_h #define _native_h #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "spool.h" #ifdef __STDC__ typedef int (*NATIVE_FUNC) (char *, int, int); #else typedef int (*NATIVE_FUNC) (); #endif typedef struct { NATIVE_FUNC to_native[2]; NATIVE_FUNC from_native[2]; } NATIVE_TABLE; extern NATIVE_TABLE native_table[]; extern void zero_native ( /* char *native_buf, int nsamples, int nchannels */ ); extern void level ( /* char *native_buf, int nsamples, int nchannels */ ); #ifdef FAKE_VOLUME extern void fake_volume ( /* char *native_buf, int nsamples, int nchannels */ ); #endif /* FAKE_VOLUME */ #endif /* _native_h */ rplay-3.3.2/rplayd/rplayd.c100644 153 62 160532 6671423014 14321 0ustar boynsstaff/* $Id: rplayd.c,v 1.8 1999/03/10 07:58:04 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "version.h" #include "rplay.h" #include #include #include #include #include #ifdef HAVE_SYS_WAIT_H #include #endif /* HAVE_SYS_WAIT_H */ #ifdef ultrix #include #else #include #endif #include #include #include #include #include #ifdef HAVE_STRING_H #include #endif #include #ifdef __STDC__ #include #else #include #endif #include #include #include "rplayd.h" #include "connection.h" #include "spool.h" #include "sound.h" #ifdef AUTH #include "host.h" #endif /* AUTH */ #include "server.h" #include "misc.h" #include "cache.h" #include "timer.h" #include "strdup.h" #include "getopt.h" #include "tilde.h" #ifdef HAVE_CDROM #include "cdrom.h" #endif /* HAVE_CDROM */ #ifdef HAVE_HELPERS #include "helper.h" #endif /* HAVE_HELPERS */ /* Make sure MAXHOSTNAMELEN is defined. */ #ifndef MAXHOSTNAMELEN #define MAXHOSTNAMELEN 256 #endif /* Global variables */ fd_set read_mask; /* Mask of RPTP clients that are reading. */ fd_set write_mask; /* Mask of RPTP clients that are writing. */ int debug = 0; /* Is debugging enable? (--debug) */ int rptp_timeout = RPTP_CONNECTION_TIMEOUT; /* --connection-timeout */ char hostname[MAXHOSTNAMELEN]; /* Name of the local system. */ char *hostaddr; /* IP address of the local system. */ int rplay_fd = -1; /* Socket used for RPLAY packets. */ int rptp_fd = -1; /* Socket used for RPTP connections. */ #ifdef OTHER_RPLAY_PORTS int other_rplay_fd = -1; /* Another RPLAY socket. */ int other_rptp_fd = -1; /* Another RPTP socket. */ #endif int curr_rate; /* Current audio rate. */ #ifndef HAVE_OSS int curr_bufsize; /* Current audio bufsize. */ #endif /* !HAVE_OSS */ int rplayd_pid; /* Process ID of rplayd. */ time_t starttime; /* The time in seconds that rplayd started. */ #ifdef AUTH int auth_enabled = 1; /* Host authentication. (--auth, --no-auth) */ #endif /* AUTH */ int rplay_priority_threshold = RPLAY_DEFAULT_PRIORITY; /* Default priority level allowed. */ /* Global audio-specific variables */ char *rplay_audio_device = RPLAY_AUDIO_DEVICE; /* Which audio device to use. */ #ifndef HAVE_OSS int rplay_audio_bufsize = 0; /* --audio-bufsize */ #endif /* !HAVE_OSS */ int rplay_audio_rate = 0; /* --audio-rate */ int rplay_audio_sample_rate = 0; /* --audio-sample-rate */ int rplay_audio_channels = 0; /* --audio-channels */ int rplay_audio_format = 0; /* --audio-format */ int rplay_audio_precision = 0; /* --audio-precison */ int rplay_audio_port = 0; /* --audio_port */ int audio_enabled = 1; /* --no-audio */ int rplay_audio_volume = RPLAY_DEFAULT_VOLUME; /* Current audio volume. */ int rplay_audio_match = 0; RPLAY_AUDIO_TABLE *rplay_audio_table = NULL; /* Optional audio parameters specified on the command line. */ int optional_sample_rate = 0; int optional_precision = 0; int optional_channels = 0; int optional_format = 0; int optional_port = 0; /* Default audio parameters. */ int default_sample_rate = 0; int default_precision = 0; int default_channels = 0; int default_format = 0; int default_port = 0; #ifdef HAVE_OSS int rplay_audio_fragsize = 0; int optional_fragsize = 0; int default_fragsize = 0; #endif /* HAVE_OSS */ /* The audio buffer and its current and maximum size. */ int rplay_audio_size = 0; char *rplay_audio_buf = NULL; int max_rplay_audio_bufsize = 0; /* Audio levels. */ int rplay_audio_left_level = 0; int rplay_audio_right_level = 0; static int monitor_total_bytes = 176400 * 5; /* 5 seconds */ static int monitor_update = 0; int monitor_count = 0; BUFFER *monitor_buffers = NULL; int rplay_audio_timeout = RPLAY_AUDIO_TIMEOUT; static int rplay_audio_flush_timeout = RPLAY_AUDIO_FLUSH_TIMEOUT; static int rplayd_timeout = RPLAYD_TIMEOUT; /* seconds */ static int sound_cleanup_timeout = 10; /* seconds */ static int buffer_cleanup_timeout = 10; /* seconds */ static int spool_cleanup_timeout = 0; /* seconds -- disabled for now */ static int need_to_reset = 0; static char *progname; static char *sounds_file = NULL; #ifdef AUTH static char *hosts_file = NULL; #endif /* AUTH */ static char *servers_file = NULL; static char *cache_dir = NULL; static char *log_file = NULL; #ifdef HAVE_HELPERS static char *helpers_file = NULL; #endif /* HAVE_HELPERS */ static int logging = 0; static int report_level; static int log_fd = -1; static int forward_fd = -1; static char *forward = NULL; static int rplay_port = 0; static int rptp_port = 0; #ifdef OTHER_RPLAY_PORTS static int other_rplay_port = 0; static int other_rptp_port = 0; #endif /* OTHER_RPLAY_PORTS */ static int audio_test_mode = 0; /* enable audio test mode */ static int do_fork = 1; static int inetd = 0; /* Was rplayd started by inetd? */ #ifndef RPLAYD_USER #define RPLAYD_USER "" #endif #ifndef RPLAYD_GROUP #define RPLAYD_GROUP "" #endif static char *run_as_user = RPLAYD_USER; static char *run_as_group = RPLAYD_GROUP; extern char *optarg; /* getopt_long */ extern int optind; /* getopt_long */ /* * Long options for getopt_long. */ static struct option longopts[] = { {"audio-device", required_argument, NULL, 'A'}, #ifndef HAVE_OSS {"audio-bufsize", required_argument, NULL, 'b'}, #endif /* !HAVE_OSS */ {"audio-bits", required_argument, NULL, 'B'}, {"audio-channels", required_argument, NULL, 1}, {"audio-close", required_argument, NULL, 'c'}, {"audio-flush", required_argument, NULL, 'F'}, {"audio-format", required_argument, NULL, 3}, #ifdef HAVE_OSS {"audio-fragsize", required_argument, NULL, 18}, #endif /* HAVE_OSS */ {"audio-info", required_argument, NULL, 'i'}, {"audio-info-ulaw", no_argument, NULL, 13}, {"audio-match", no_argument, &rplay_audio_match, 1}, {"audio-port", required_argument, NULL, 10}, {"audio-rate", required_argument, NULL, 'r'}, {"audio-sample-rate", required_argument, NULL, 'R'}, {"audio-test", no_argument, &audio_test_mode, 1}, #ifdef AUTH {"auth", no_argument, &auth_enabled, 1}, #endif {"cache-directory", required_argument, NULL, 'D'}, {"cache-remove", no_argument, NULL, 12}, {"cache-size", required_argument, NULL, 's'}, #ifdef HAVE_CDROM {"cdrom0", required_argument, NULL, 14}, {"cdrom1", required_argument, NULL, 15}, {"cdrom2", required_argument, NULL, 16}, {"cdrom3", required_argument, NULL, 17}, #endif /* HAVE_CDROM */ {"conf", required_argument, NULL, 'C'}, {"connection-timeout", required_argument, NULL, 'T'}, {"debug", no_argument, NULL, 'd'}, {"fork", no_argument, &do_fork, 1}, {"forward", required_argument, NULL, 'f'}, {"group", required_argument, NULL, 21}, {"help", no_argument, NULL, 2}, #ifdef HAVE_HELPERS {"helpers", required_argument, NULL, 20}, #endif /* HAVE_HELPERS */ #ifdef AUTH {"hosts", required_argument, NULL, 'H'}, #endif {"inetd", no_argument, &inetd, 1}, {"info", required_argument, NULL, 'i'}, {"info-ulaw", no_argument, NULL, 13}, {"log-file", required_argument, NULL, 'L'}, {"log-level", required_argument, NULL, 'l'}, {"memory-cache-size", required_argument, NULL, 4}, {"memory-cache-sound-size", required_argument, NULL, 5}, {"no-audio", no_argument, NULL, 'N'}, #ifdef AUTH {"no-auth", no_argument, &auth_enabled, 0}, #endif {"no-fork", no_argument, &do_fork, 0}, {"no-inetd", no_argument, NULL, 'n'}, {"option-file", required_argument, NULL, 11}, {"options-file", required_argument, NULL, 11}, #ifdef OTHER_RPLAY_PORTS {"other-rplay-port", required_argument, NULL, 9}, {"other-rptp-port", required_argument, NULL, 8}, #endif {"port", required_argument, NULL, 6}, {"rplay-port", required_argument, NULL, 6}, {"rptp-port", required_argument, NULL, 7}, {"servers", required_argument, NULL, 'S'}, {"timeout", required_argument, NULL, 't'}, {"user", required_argument, NULL, 22}, {"version", no_argument, NULL, 'v'}, {NULL, 0, NULL, 0} }; #ifdef sun #ifdef __STDC__ extern int gethostname(char *name, int namelen); #else extern int gethostname( /* char *name, int namelen */ ); #endif #endif extern char *ctime(); #ifdef __STDC__ static void do_option_file(char *option_file); static void do_option(int option_value); #else static void do_option_file( /* char *option_file */ ); static void do_option( /* int option_value */ ); #endif static void doit(); static void handle_signals(); static void handle_sighup(); static void handle_sigint(); static void handle_sigchld(); static void reset(); static void audio_test(); #if defined(HAVE_CDROM) || defined(HAVE_HELPERS) #ifdef __STDC__ void rplayd_pipe_read( /* fd_set *rfds */ ); #else void rplayd_pipe_read( /* fd_set *rfds */ ); #endif #endif #ifdef AUTH #define OPTIONS "A:C:D:F:S:b:B:c:df:l:L:Nnr:R:s:t:T:vi:H:" #else #define OPTIONS "A:C:D:F:S:b:B:c:df:l:L:Nnr:R:s:t:T:vi:" #endif #ifdef __STDC__ main(int argc, char **argv) #else main(argc, argv) int argc; char **argv; #endif { int c; struct hostent *hp; struct in_addr addr; char *rplaydrc; starttime = time(0); progname = argv[0]; servers_file = tilde_expand(RPLAY_SERVERS); #ifdef HAVE_HELPERS helpers_file = tilde_expand(RPLAY_HELPERS); #endif /* HAVE_HELPERS */ sounds_file = tilde_expand(RPLAY_CONF); #ifdef AUTH hosts_file = tilde_expand(RPLAY_HOSTS); #endif /* AUTH */ cache_dir = tilde_expand(RPLAY_CACHE); log_file = tilde_expand(RPLAY_LOG); #ifdef RPLAYD_ALWAYS_LOG report_level = RPLAYD_LOG_LEVEL; if (report_level != REPORT_NONE) { logging++; } #else report_level = REPORT_ERROR; #endif /* Parse RPLAYDRC. */ rplaydrc = tilde_expand(RPLAYDRC); if (rplaydrc) { struct stat st; if (stat(rplaydrc, &st) == 0 && S_ISREG(st.st_mode)) { do_option_file(rplaydrc); } free(rplaydrc); } /* Parse command line options. */ while ((c = getopt_long(argc, argv, OPTIONS, longopts, 0)) != -1) { do_option(c); } if (audio_test_mode) { report_level = 0; /* don't want debug output */ audio_test(); done(0); } if (run_as_group && *run_as_group) { struct group *gr = getgrnam(run_as_group); if (!gr) { fprintf(stderr, "Unknown group `%s'.\n", run_as_group); done(1); } if (setgid(gr->gr_gid) < 0) { report(REPORT_ERROR, "setgid: %s\n", sys_err_str(errno)); done(1); } report(REPORT_DEBUG, "running as group %s (%d)\n", run_as_group, gr->gr_gid); } if (run_as_user && *run_as_user) { struct passwd *pw = getpwnam(run_as_user); if (!pw) { fprintf(stderr, "Unknown user `%s'.\n", run_as_user); done(1); } if (setuid(pw->pw_uid) < 0) { report(REPORT_ERROR, "setuid: %s\n", sys_err_str(errno)); done(1); } report(REPORT_DEBUG, "running as user %s (%d)\n", run_as_user, pw->pw_uid); } if (debug) { logging = 0; do_fork = 0; } /* Fork */ if (do_fork) { int pid = fork(); if (pid != 0) { exit(0); } } if (gethostname(hostname, sizeof(hostname)) < 0) { report(REPORT_ERROR, "gethostname: %s\n", sys_err_str(errno)); done(1); } hp = gethostbyname(hostname); if (hp == NULL) { report(REPORT_ERROR, "gethostbyname: cannot resolve hostname: %s\n", hostname); done(1); } memcpy((char *) &addr, (char *) hp->h_addr, hp->h_length); hostaddr = strdup(inet_ntoa(addr)); rplayd_pid = getpid(); handle_signals(); /* Call all the initialization routines. */ rplayd_init(); #ifdef HAVE_HELPERS helper_read(helpers_file); #endif /* HAVE_HELPERS */ sound_read(sounds_file); cache_init(cache_dir); cache_read(); #ifdef AUTH host_read(hosts_file); #endif /* AUTH */ server_read(servers_file); spool_init(); timer_init(); if (rplayd_audio_init() < 0) { /* Disable audio. */ audio_enabled = 0; report(REPORT_DEBUG, "audio disabled\n"); } else { /* Save the initial audio configuration. */ default_sample_rate = rplay_audio_sample_rate; default_precision = rplay_audio_precision; default_channels = rplay_audio_channels; default_format = rplay_audio_format; default_port = rplay_audio_port; /* Close audio device to avoid hogging it. */ rplay_audio_close(); } #ifdef AUTH report(REPORT_DEBUG, "authentication %s\n", auth_enabled ? "enabled" : "disabled"); #else report(REPORT_DEBUG, "no authentication\n"); #endif if (forward) { report(REPORT_DEBUG, "forwarding sounds to %s\n", forward); } report(REPORT_DEBUG, "%s rplayd %s ready.\n", hostname, RPLAY_VERSION); doit(); } #ifdef __STDC__ static void do_option_file(char *option_file) #else static void do_option_file(option_file) char *option_file; #endif { int first, c; char buf[BUFSIZ], *p; FILE *fp; int saved_optind; char *argv[1024]; /* that should be enough */ int argc = 0; fp = fopen(option_file, "r"); if (fp == NULL) { report(REPORT_ERROR, "cannot open `%s'.\n", option_file); return; } argv[argc++] = progname; tilde_additional_prefixes = (char **) xmalloc(2 * sizeof(char *)); tilde_additional_prefixes[0] = "=~"; tilde_additional_prefixes[1] = (char *) NULL; while (fgets(buf, sizeof(buf), fp)) { switch (buf[0]) { case '#': case ' ': case '\n': case '\t': continue; } first = 1; while (p = (char *) strtok(first ? buf : NULL, " \t\n")) { first = 0; argv[argc++] = tilde_expand(p); } } fclose(fp); free((char *) tilde_additional_prefixes); tilde_additional_prefixes = NULL; argv[argc] = NULL; saved_optind = optind; /* save optind */ optind = 1; /* reset optind */ while ((c = getopt_long(argc, argv, OPTIONS, longopts, 0)) != -1) { do_option(c); } optind = saved_optind; /* restore optind */ } #ifdef __STDC__ static void do_option(int option_value) #else static void do_option(option_value) int option_value; #endif { static int within_file; int i; char *p; switch (option_value) { case 0: /* getopt has processed a long-named option -- do nothing */ break; case 1: /* --audio-channels */ optional_channels = atoi(optarg); if (optional_channels != 1 && optional_channels != 2) { usage(); done(1); } break; case 2: /* --help */ usage(); done(1); case 3: /* --audio-format */ optional_format = string_to_audio_format(optarg); if (optional_format < 0) { usage(); done(1); } break; case 4: /* --memory-cache-size */ sound_cache_max_size = atoi(optarg); break; case 5: /* --memory-cache-sound-size */ sound_cache_max_sound_size = atoi(optarg); break; case 6: /* --port or --rplay-port */ rplay_port = atoi(optarg); break; case 7: /* --rptp-port */ rptp_port = atoi(optarg); break; #ifdef OTHER_RPLAY_PORTS case 8: /* --other-rplay-port */ other_rplay_port = atoi(optarg); break; case 9: /* --other-rptp-port */ other_rptp_port = atoi(optarg); break; #endif /* OTHER_RPTP_PORTS */ case 10: /* --audio-port */ if (strstr(optarg, "none")) { SET_BIT(optional_port, RPLAY_AUDIO_PORT_NONE); } if (strstr(optarg, "speaker")) { SET_BIT(optional_port, RPLAY_AUDIO_PORT_SPEAKER); } if (strstr(optarg, "headphone")) { SET_BIT(optional_port, RPLAY_AUDIO_PORT_HEADPHONE); } if (strstr(optarg, "lineout")) { SET_BIT(optional_port, RPLAY_AUDIO_PORT_LINEOUT); } break; case 11: do_option_file(optarg); break; case 12: /* --cache-remove */ cache_remove++; break; case 13: /* --audio-info-ulaw, --info-ulaw */ optional_format = RPLAY_FORMAT_ULAW; optional_sample_rate = 8000; optional_precision = 8; optional_channels = 1; break; #ifdef HAVE_CDROM case 14: /* cdrom0 */ for (i = 0; i < MAX_CDROMS; i++) { if (strncmp(cdrom_table[i].name, "cdrom0", 6) == 0) { cdrom_table[i].device = optarg; break; } } break; case 15: /* cdrom1 */ for (i = 0; i < MAX_CDROMS; i++) { if (strncmp(cdrom_table[i].name, "cdrom1", 6) == 0) { cdrom_table[i].device = optarg; break; } } break; case 16: /* cdrom2 */ for (i = 0; i < MAX_CDROMS; i++) { if (strncmp(cdrom_table[i].name, "cdrom2", 6) == 0) { cdrom_table[i].device = optarg; break; } } break; case 17: /* cdrom3 */ for (i = 0; i < MAX_CDROMS; i++) { if (strncmp(cdrom_table[i].name, "cdrom3", 6) == 0) { cdrom_table[i].device = optarg; break; } } break; #endif /* HAVE_CDROM */ #ifdef HAVE_OSS case 18: /* audio-fragsize */ optional_fragsize = atoi(optarg); break; #endif /* HAVE_OSS */ case 19: /* fork */ do_fork++; break; case 20: /* helpers */ helpers_file = optarg; break; case 21: /* group */ run_as_group = optarg; break; case 22: /* user */ run_as_user = optarg; break; case 'A': rplay_audio_device = optarg; break; #ifndef HAVE_OSS case 'b': rplay_audio_bufsize = atoi(optarg); break; #endif /* !HAVE_OSS */ case 'B': optional_precision = atoi(optarg); if (optional_precision != 8 && optional_precision != 16) { usage(); done(1); } break; case 'c': rplay_audio_timeout = atoi(optarg); break; case 'C': sounds_file = optarg; break; case 'd': debug++; report_level = REPORT_DEBUG; break; case 'D': cache_dir = optarg; break; case 'f': forward = optarg; break; case 'F': rplay_audio_flush_timeout = atoi(optarg); break; #ifdef AUTH case 'H': hosts_file = optarg; break; #endif /* AUTH */ case 'i': /* --audio-info, --info */ /* Example: ulaw,8000,8,1 */ p = strtok(optarg, ", "); if (p) optional_format = string_to_audio_format(p); p = strtok(NULL, ","); if (p) optional_sample_rate = atoi(p); p = strtok(NULL, ","); if (p) optional_precision = atoi(p); p = strtok(NULL, ","); if (p) optional_channels = atoi(p); break; case 'l': logging++; report_level = atoi(optarg); break; case 'L': log_file = optarg; break; case 'n': inetd = 0; break; case 'N': audio_enabled = 0; break; case 'r': rplay_audio_rate = atoi(optarg); break; case 'R': optional_sample_rate = atoi(optarg); break; case 's': cache_max_size = atoi(optarg); break; case 'S': servers_file = optarg; break; case 't': rplayd_timeout = atoi(optarg); break; case 'T': rptp_timeout = atoi(optarg); break; case 'v': printf("rplay %s\n", RPLAY_VERSION); done(0); break; default: fprintf(stderr, "Try `%s --help' for more information.\n", progname); done(1); } } /* * The main loop of rplayd. */ static void doit() { int nfds, icount = 0; int idle = 1; struct timeval select_timeout; fd_set rfds, wfds; SPOOL *sp; /* Initialize the fd_sets before starting. */ FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&read_mask); FD_ZERO(&write_mask); FD_SET(rplay_fd, &read_mask); FD_SET(rptp_fd, &read_mask); #ifdef OTHER_RPLAY_PORTS FD_SET(other_rplay_fd, &read_mask); FD_SET(other_rptp_fd, &read_mask); #endif for (;;) { if (need_to_reset) { reset(); need_to_reset = 0; } if (audio_enabled) { if (timer_enabled) { if (!spool_nplaying) { timer_stop(); rplay_audio_size = 0; if (rplay_audio_flush_timeout == -1) { report(REPORT_DEBUG, "flushing %s\n", rplay_audio_device); rplay_audio_flush(); } /* Notify the final zero levels. */ rplay_audio_left_level = 0; rplay_audio_right_level = 0; if (connection_want_level_notify) { connection_notify(0, NOTIFY_LEVEL, 1); /* force notification */ } } else { /* keep trying to open */ if (!rplay_audio_isopen()) { rplay_audio_open(); } if (connection_level_notify) { connection_notify(0, NOTIFY_LEVEL, 0); connection_level_notify = 0; } for (sp = spool; sp; sp = sp->next) { if (sp->notify_position) { connection_notify(0, NOTIFY_POSITION, sp); sp->notify_position = 0; } } if (monitor_count && monitor_update) { connection_monitor_continue(); monitor_update = 0; } } } else if (spool_nplaying) { if (!rplay_audio_isopen()) { report(REPORT_DEBUG, "opening %s\n", rplay_audio_device); if (rplay_audio_open() < 0) { report(REPORT_ERROR, "rplay_audio_open: %s: %s (will keep trying)\n", rplay_audio_device, sys_err_str(errno)); } } /* start the timer even if the audio device isn't open */ timer_start(curr_rate); } if (spool_needs_update) { spool_update(); } } if (connections) { connection_check_timeout(); } rfds = read_mask; wfds = write_mask; if (idle) { report(REPORT_DEBUG, "entering idle mode\n"); select_timeout.tv_sec = rplayd_timeout; select_timeout.tv_usec = 0; #ifdef __hpux nfds = select(FD_SETSIZE, (int *) &rfds, (int *) &wfds, 0, rplayd_timeout ? &select_timeout : 0); #else nfds = select(FD_SETSIZE, &rfds, &wfds, 0, rplayd_timeout ? &select_timeout : 0); #endif if (nfds == 0) { done(0); } #ifdef AUTO_REREAD #ifdef HAVE_HELPERS helper_stat(helpers_file); #endif /* HAVE_HELPERS */ sound_stat(sounds_file); #ifdef AUTH host_stat(hosts_file); #endif /* AUTH */ server_stat(servers_file); #endif /* AUTO_REREAD */ idle = 0; icount = 0; } else { select_timeout.tv_sec = 1; select_timeout.tv_usec = 0; #ifdef __hpux nfds = select(FD_SETSIZE, (int *) &rfds, (int *) &wfds, 0, &select_timeout); #else nfds = select(FD_SETSIZE, &rfds, &wfds, 0, &select_timeout); #endif } switch (nfds) { case -1: if (errno != EINTR && errno != EAGAIN) { report(REPORT_ERROR, "select: %s\n", sys_err_str(errno)); done(1); } break; case 0: icount++; /* * Timeouts that occur when no sounds are playing. */ if (!spool_nplaying && !rplay_audio_size) { if (audio_enabled && rplay_audio_timeout && icount == rplay_audio_timeout && rplay_audio_isopen()) { report(REPORT_DEBUG, "closing %s\n", rplay_audio_device); rplay_audio_close(); } if (audio_enabled && rplay_audio_flush_timeout > 0 && icount == rplay_audio_flush_timeout && rplay_audio_isopen()) { report(REPORT_DEBUG, "flushing %s\n", rplay_audio_device); rplay_audio_flush(); } if (sound_cleanup_timeout && icount == sound_cleanup_timeout) { sound_cleanup(); } if (buffer_cleanup_timeout && icount == buffer_cleanup_timeout) { buffer_cleanup(); } if (spool_cleanup_timeout && icount == spool_cleanup_timeout) { spool_cleanup(); } /* * See if rplayd should enter idle mode. * Idle mode should only be entered when *nothing* * is happening. */ if (icount >= rplay_audio_timeout && connection_idle() && icount >= rplay_audio_flush_timeout && icount >= sound_cleanup_timeout && icount >= buffer_cleanup_timeout && icount >= spool_cleanup_timeout) { idle = 1; if (monitor_buffers) { if (!monitor_count) { report(REPORT_DEBUG, "cleaning monitor buffers - %d bytes\n", monitor_total_bytes); monitor_cleanup(); } else { report(REPORT_DEBUG, "keeping monitor buffers - %d bytes\n", monitor_total_bytes); } } } } break; default: if (FD_ISSET(rplay_fd, &rfds)) { rplayd_read(rplay_fd); } #ifdef OTHER_RPLAY_PORTS if (FD_ISSET(other_rplay_fd, &rfds)) { rplayd_read(other_rplay_fd); } #endif connection_update(&rfds, &wfds); #if defined(HAVE_CDROM) || defined(HAVE_HELPERS) rplayd_pipe_read(&rfds); #endif icount = 0; break; } } } /* * Set up the sockets to receive RPLAY packets and RPTP connections. */ void rplayd_init() { struct sockaddr_in s; struct servent *sp; if (inetd) { rplay_fd = 0; #ifdef OTHER_RPLAY_PORTS /* Try to figure out which port is being used by inetd. */ sp = getservbyname("rplay", "udp"); if (sp == NULL) { report(REPORT_ERROR, "can't find rplay/udp service\n"); done(1); } if (ntohs(sp->s_port) == RPLAY_PORT) { other_rplay_fd = udp_socket(other_rplay_port ? other_rplay_port : OLD_RPLAY_PORT); } else { other_rplay_fd = udp_socket(other_rplay_port ? other_rplay_port : RPLAY_PORT); } #endif } else { rplay_fd = udp_socket(rplay_port ? rplay_port : RPLAY_PORT); #ifdef OTHER_RPLAY_PORTS other_rplay_fd = udp_socket(other_rplay_port ? other_rplay_port : OLD_RPLAY_PORT); #endif } /* * Make the RPLAY sockets non-blocking. */ fd_nonblock(rplay_fd); #ifdef OTHER_RPLAY_PORTS fd_nonblock(other_rplay_fd); #endif if (forward) { unsigned long addr = inet_addr(forward); memset((char *) &s, 0, sizeof(s)); s.sin_family = AF_INET; s.sin_port = htons(RPLAY_PORT); if (addr == 0xffffffff) { struct hostent *hp = gethostbyname(forward); if (hp == NULL) { report(REPORT_ERROR, "gethostbyname: %s unknown host\n", forward); done(1); } memcpy((char *) &s.sin_addr.s_addr, (char *) hp->h_addr, hp->h_length); } else { memcpy((char *) &s.sin_addr.s_addr, (char *) &addr, sizeof(addr)); } forward_fd = socket(AF_INET, SOCK_DGRAM, 0); if (forward_fd < 0) { report(REPORT_ERROR, "socket: %s\n", sys_err_str(errno)); done(1); } if (connect(forward_fd, (struct sockaddr *) &s, sizeof(s)) < 0) { report(REPORT_ERROR, "connect: %s\n", sys_err_str(errno)); done(1); } } rptp_fd = tcp_socket(rptp_port ? rptp_port : RPTP_PORT); #ifdef OTHER_RPLAY_PORTS other_rptp_fd = tcp_socket(other_rptp_port ? other_rptp_port : OLD_RPTP_PORT); #endif /* * Make the RPTP sockets non-blocking. */ fd_nonblock(rptp_fd); #ifdef OTHER_RPLAY_PORTS fd_nonblock(other_rptp_fd); #endif } int rplayd_audio_init() { int sample_size; if (!audio_enabled) { return -1; } if (optional_sample_rate && optional_sample_rate > MAX_SAMPLE_RATE) { optional_sample_rate = MAX_SAMPLE_RATE; } /* Call rplay_audio_init() which sets all the rplay_audio variables. */ rplay_audio_table = NULL; /* will be set by rplay_audio_init() */ if (rplay_audio_init() < 0) { return -1; } /* XXX */ optional_sample_rate = rplay_audio_sample_rate; optional_precision = rplay_audio_precision; optional_channels = rplay_audio_channels; optional_format = rplay_audio_format; optional_port = rplay_audio_port; sample_size = (rplay_audio_precision >> 3) * rplay_audio_channels; if (rplay_audio_match || rplay_audio_rate == 0) { rplay_audio_rate = RPLAY_AUDIO_RATE; } curr_rate = rplay_audio_rate; #ifndef HAVE_OSS /* Click prevention: Make sure curr_rate won't split up samples. If it will, it's easiest right now to modify the rate and not the sample_rate. */ if (rplay_audio_sample_rate % curr_rate) { while (rplay_audio_sample_rate % curr_rate) { curr_rate--; /* Slow it down. */ } report(REPORT_DEBUG, "changed curr_rate from %d to %d\n", rplay_audio_rate, curr_rate); } if (rplay_audio_match || rplay_audio_bufsize == 0) { rplay_audio_bufsize = rplay_audio_sample_rate / curr_rate * sample_size; } curr_bufsize = rplay_audio_bufsize; /* More click prevention: Make sure curr_bufsize won't split up samples. If it will, curr_bufsize should be increased, not decreased. */ if (curr_bufsize % sample_size) { while (curr_bufsize % sample_size) { curr_bufsize++; /* Add a little. */ } report(REPORT_DEBUG, "changed curr_bufsize from %d to %d\n", rplay_audio_bufsize, curr_bufsize); } #endif /* !HAVE_OSS */ /* * Create the audio buffer which holds at most 1 second of 16-bit * stereo audio data sampled at MAX_SAMPLE_RATE Hz. */ max_rplay_audio_bufsize = MAX_SAMPLE_RATE * 2 /* 16-bit */ * 2 /* stereo */ ; if (rplay_audio_buf) { free((char *) rplay_audio_buf); } rplay_audio_buf = (char *) malloc(max_rplay_audio_bufsize); if (rplay_audio_buf == NULL) { report(REPORT_ERROR, "cannot allocate rplay_audio_buf, size=%d\n", max_rplay_audio_bufsize); done(1); } /* * Update the volume of the audio device. */ rplay_audio_volume = rplay_audio_get_volume(); if (rplay_audio_volume < 0) { rplay_audio_volume = 0; } report(REPORT_DEBUG, "\ audio: bits=%d sample-rate=%d channels=%d format=%s volume=%d port-mask=%0x\n", rplay_audio_precision, rplay_audio_sample_rate, rplay_audio_channels, audio_format_to_string(rplay_audio_format), rplay_audio_volume, rplay_audio_port); #ifdef HAVE_OSS report(REPORT_DEBUG, "timer: rate=%d, min bytes/sec=%d\n", curr_rate, (rplay_audio_sample_rate / curr_rate * sample_size)); #else report(REPORT_DEBUG, "timer: rate=%d, bufsize=%d\n", curr_rate, curr_bufsize); #endif return 0; } /* Attempt to match the audio device configuration with the sound in `sp'. Currenly only the sample-rate is matched. */ #ifdef __STDC__ void rplayd_audio_match(SPOOL *match_sp) #else void rplayd_audio_match(match_sp) SPOOL *match_sp; #endif { if (rplay_audio_match && spool_nplaying == 0 /* Only is nothing else is playing. */ && match_sp->sample_rate != rplay_audio_sample_rate) { RPLAY_AUDIO_TABLE *t; SPOOL *sp; int prev_sample_rate; /* Find the closest matching table entry. */ optional_sample_rate = match_sp->sample_rate; prev_sample_rate = rplay_audio_table ? rplay_audio_table->sample_rate : 0; for (t = rplay_audio_table; t; t++) { if (t->sample_rate == 0 || optional_sample_rate < prev_sample_rate) { optional_sample_rate = prev_sample_rate; break; } else if (optional_sample_rate >= prev_sample_rate && optional_sample_rate <= t->sample_rate) { if ((t->sample_rate - optional_sample_rate) > (optional_sample_rate - prev_sample_rate)) { optional_sample_rate = prev_sample_rate; } else { optional_sample_rate = t->sample_rate; } break; } prev_sample_rate = t->sample_rate; } report(REPORT_DEBUG, "matched %d with %d\n", match_sp->sample_rate, optional_sample_rate); if (rplayd_audio_init() < 0) { /* That sample rate didn't work -- Use the default instead. */ optional_sample_rate = default_sample_rate; rplayd_audio_init(); } if (timer_enabled) { timer_restart(curr_rate); } /* Update the spool entries with the new sample-rate. */ for (sp = spool; sp; sp = sp->next) { sp->sample_factor = (double) sp->sample_rate / (double) rplay_audio_sample_rate; } } } monitor_alloc() { if (!monitor_buffers) { BUFFER *b, *end; monitor_buffers = buffer_alloc(monitor_total_bytes, BUFFER_KEEP); for (b = monitor_buffers; b; b = b->next) { /* these will always be full buffers */ b->nbytes = BUFFER_SIZE; if (!b->next) { end = b; } } /* make the list of buffer cyclic */ end->next = monitor_buffers; } monitor_update = 0; } monitor_cleanup() { BUFFER *b, *b_next; for (b = monitor_buffers; b->next != monitor_buffers; b = b->next); b->next = NULL; buffer_dealloc(monitor_buffers, 1); monitor_buffers = NULL; } /* * Write nbytes of audio data from the audio buffer to the audio device. */ #ifdef __STDC__ void rplayd_write(int nbytes) #else void rplayd_write(nbytes) int nbytes; #endif { int nwritten = 0; /* Insert `nbytes' of audio data from the spool into `rplay_audio_buf'. */ spool_process(rplay_audio_buf, nbytes); /* * Write the audio data if the audio device is open. * Otherwise forget about the data. */ if (rplay_audio_size && rplay_audio_isopen()) { nwritten = rplay_audio_write(rplay_audio_buf, rplay_audio_size); #if 0 report(REPORT_DEBUG, "audio_write: %d -> %d\n", rplay_audio_size, nwritten); #endif /* Flush after every write? */ if (rplay_audio_flush_timeout == -2) { report(REPORT_DEBUG, "flushing %s\n", rplay_audio_device); rplay_audio_flush(); } } if (monitor_count) { char *buf = rplay_audio_buf; int size = rplay_audio_size; int n; while (size) { n = MIN(BUFFER_SIZE - monitor_buffers->offset, size); memcpy(monitor_buffers->buf + monitor_buffers->offset, buf, n); monitor_buffers->offset += n; buf += n; size -= n; if (monitor_buffers->offset == BUFFER_SIZE) { monitor_buffers = monitor_buffers->next; monitor_buffers->offset = 0; monitor_update++; } } } rplay_audio_size = 0; /* Flush when the audio stream has ended. */ if (spool_nplaying == 0 && rplay_audio_size == 0) { if (rplay_audio_flush_timeout == -1) { report(REPORT_DEBUG, "flushing %s\n", rplay_audio_device); rplay_audio_flush(); } } } /* * Read RPLAY packets from the UDP socket. */ #ifdef __STDC__ void rplayd_read(int fd) #else void rplayd_read(fd) int fd; #endif { static char recv_buf[MAX_PACKET]; char *packet; struct sockaddr_in f; int j, n, flen; RPLAY *rp; for (j = 0; j < SPOOL_SIZE; j++) { flen = sizeof(f); n = recvfrom(fd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr *) &f, &flen); if (n <= 0) { continue; } if (forward) { write(forward_fd, recv_buf, n); continue; } #ifdef AUTH if (!host_access(f, HOST_EXECUTE)) { if (!host_access(f, HOST_READ) && !host_access(f, HOST_WRITE)) { report(REPORT_NOTICE, "%s permission denied\n", inet_ntoa(f.sin_addr)); } continue; } #endif /* AUTH */ packet = recv_buf; switch (*packet) { #ifdef OLD_RPLAY case OLD_RPLAY_PLAY: case OLD_RPLAY_STOP: case OLD_RPLAY_PAUSE: case OLD_RPLAY_CONTINUE: packet = rplay_convert(recv_buf); #endif /* OLD_RPLAY */ case RPLAY_PACKET_ID: rp = rplay_unpack(packet); if (rp == NULL) { report(REPORT_ERROR, "rplay_unpack: %s\n", rplay_errlist[rplay_errno]); break; } switch (rp->command) { case RPLAY_PING: #ifdef DEBUG report(REPORT_DEBUG, "received a ping packet\n"); #endif rplay_destroy(rp); break; case RPLAY_PLAY: report(REPORT_INFO, "%s play %s\n", inet_ntoa(f.sin_addr), (char *) rplay_get(rp, RPLAY_SOUND, 0)); rplayd_play(rp, f); break; case RPLAY_STOP: report(REPORT_INFO, "%s stop %s\n", inet_ntoa(f.sin_addr), (char *) rplay_get(rp, RPLAY_SOUND, 0)); rplayd_stop(rp, f); break; case RPLAY_PAUSE: report(REPORT_INFO, "%s pause %s\n", inet_ntoa(f.sin_addr), (char *) rplay_get(rp, RPLAY_SOUND, 0)); rplayd_pause(rp, f); break; case RPLAY_CONTINUE: report(REPORT_INFO, "%s continue %s\n", inet_ntoa(f.sin_addr), (char *) rplay_get(rp, RPLAY_SOUND, 0)); rplayd_continue(rp, f); break; case RPLAY_RESET: report(REPORT_INFO, "received a reset packet\n"); need_reset(); rplay_destroy(rp); break; case RPLAY_DONE: report(REPORT_INFO, "%s done %s\n", inet_ntoa(f.sin_addr), (char *) rplay_get(rp, RPLAY_SOUND, 0)); rplayd_done(rp, f); break; case RPLAY_PUT: report(REPORT_INFO, "%s put id=%d sequence=%d size=%d\n", inet_ntoa(f.sin_addr), rp->id, rp->sequence, rp->data_size); rplayd_put(rp, f); break; } break; default: report(REPORT_ERROR, "unknown RPLAY packet received from %s\n", inet_ntoa(f.sin_addr)); break; } } } #if defined(HAVE_CDROM) || defined(HAVE_HELPERS) /* Read data from piped devices and insert it into the spool entry. This is done using rplayd main select loop for efficiency. */ #ifdef __STDC__ void rplayd_pipe_read(fd_set * rfds) #else void rplayd_pipe_read(rfds) fd_set *rfds; #endif { SPOOL *sp, *sp_next; extern BUFFER *sound_pipe_read(SINDEX *si); for (sp = spool; sp; sp = sp_next) { sp_next = sp->next; if (!sp->si) { continue; } #ifdef HAVE_CDROM if (sp->si->sound->type == SOUND_CDROM && FD_ISSET(sp->si->fd, rfds)) { BUFFER *b = sound_pipe_read(sp->si); if (b) { spool_flow_insert(sp, b); } } #endif #ifdef HAVE_HELPERS if (sp->si->sound->needs_helper && FD_ISSET(sp->si->fd, rfds)) { BUFFER *b = sound_pipe_read(sp->si); if (b) { spool_flow_insert(sp, b); } } #endif } } #endif #ifdef __STDC__ int rplayd_play(RPLAY *rp, struct sockaddr_in sin) #else int rplayd_play(rp, sin) RPLAY *rp; struct sockaddr_in sin; #endif { SPOOL *sp = NULL; int i, n; int start_sound, end_sound, merged_lists; RPLAY_ATTRS *attrs; if (!audio_enabled) { return -1; } /* If a list_name is specified, try to find a matching list. */ if (*rp->list_name) { for (sp = spool; sp; sp = sp->next) { if (*sp->rp->list_name && strcmp(rp->list_name, sp->rp->list_name) == 0) { break; } } if (sp) { *(sp->rp->attrsp) = rp->attrs; /* Append the new attrs. */ sp->rp->attrsp = rp->attrsp; start_sound = sp->rp->nsounds; sp->rp->nsounds += rp->nsounds; end_sound = sp->rp->nsounds; merged_lists = 1; } } /* Find a spool entry. */ if (!sp) { /* Check the priority level. rplayd will ignore all sounds with priorities less than rplay_priority_threshold. */ if (rp->priority < rplay_priority_threshold) { report(REPORT_DEBUG, "sound at priority %d ignored\n", rp->priority); rplay_destroy(rp); return -1; } sp = spool_next(rp->priority); if (!sp) { report(REPORT_DEBUG, "spool full\n"); rplay_destroy(rp); return -1; } start_sound = 0; end_sound = rp->nsounds; merged_lists = 0; } /* Gotta have attributes! */ if (!rp->attrs) { report(REPORT_DEBUG, "`rp' missing attributes\n"); rplay_destroy(rp); spool_destroy(sp); return -1; } /* Add the sounds to the spool entry. */ n = 0; for (i = start_sound, attrs = rp->attrs; i < end_sound && attrs; i++, attrs = attrs->next) { if (attrs->rptp_server) { SERVER *s; s = (SERVER *) malloc(sizeof(SERVER)); s->next = NULL; s->sin.sin_family = AF_INET; s->sin.sin_port = htons(attrs->rptp_server_port); s->sin.sin_addr.s_addr = inet_addr(attrs->rptp_server); sp->sound[i] = sound_lookup(attrs->sound, attrs->rptp_search ? SOUND_FIND : SOUND_DONT_FIND, s); } else { sp->sound[i] = sound_lookup(attrs->sound, attrs->rptp_search ? SOUND_FIND : SOUND_DONT_FIND, NULL); } if (sp->sound[i] == NULL) { rplay_destroy(rp); spool_destroy(sp); return -1; } if (sp->sound[i]->status != SOUND_READY) { n++; } } /* Set-up the spool entry only if it's a new sound list. */ if (!merged_lists) { sp->rp = rp; sp->curr_attrs = rp->attrs; sp->curr_sound = 0; sp->curr_count = sp->curr_attrs->count; sp->list_count = rp->count; sp->sin = sin; if (n) { sp->state = SPOOL_WAIT; } else { spool_play(sp); } } return sp->id; } #ifdef __STDC__ int rplayd_stop(RPLAY *rp, struct sockaddr_in sin) #else int rplayd_stop(rp, sin) RPLAY *rp; struct sockaddr_in sin; #endif { int n; if (!audio_enabled) { rplay_destroy(rp); return -1; } n = spool_match(rp, spool_stop, sin); rplay_destroy(rp); return n > 0 ? 0 : -1; } #ifdef __STDC__ int rplayd_pause(RPLAY *rp, struct sockaddr_in sin) #else int rplayd_pause(rp, sin) RPLAY *rp; struct sockaddr_in sin; #endif { int n; if (!audio_enabled) { rplay_destroy(rp); return -1; } n = spool_match(rp, spool_pause, sin); rplay_destroy(rp); return n > 0 ? 0 : -1; } #ifdef __STDC__ int rplayd_continue(RPLAY *rp, struct sockaddr_in sin) #else int rplayd_continue(rp, sin) RPLAY *rp; struct sockaddr_in sin; #endif { int n; if (!audio_enabled) { rplay_destroy(rp); return -1; } n = spool_match(rp, spool_continue, sin); rplay_destroy(rp); return n > 0 ? 0 : -1; } #ifdef __STDC__ int rplayd_done(RPLAY *rp, struct sockaddr_in sin) #else int rplayd_done(rp, sin) RPLAY *rp; struct sockaddr_in sin; #endif { int n; if (!audio_enabled) { rplay_destroy(rp); return -1; } n = spool_match(rp, spool_done, sin); rplay_destroy(rp); return n > 0 ? 0 : -1; } #ifdef __STDC__ int rplayd_put(RPLAY *rp, struct sockaddr_in sin) #else int rplayd_put(rp, sin) RPLAY *rp; struct sockaddr_in sin; #endif { BUFFER *b; SPOOL *sp; if (!audio_enabled) { rplay_destroy(rp); return -1; } /* Find the spool entry. */ sp = spool_find(rp->id); if (!sp) { report(REPORT_DEBUG, "put: `%d' no such spool id\n", rp->id); rplay_destroy(rp); return -1; } /* Create a buffer and insert the flow data. */ b = buffer_create(); b->nbytes = rp->data_size; memcpy(b->buf, rp->data, b->nbytes); spool_flow_insert(sp, b); rplay_destroy(rp); return 0; } BUFFER * rplayd_status() { BUFFER *b; b = buffer_create(); b->buf[0] = RPTP_OK; b->buf[1] = '\0'; SNPRINTF(SIZE(b->buf + strlen(b->buf), BUFFER_SIZE), "host=%s", hostname); SNPRINTF(SIZE(b->buf + strlen(b->buf), BUFFER_SIZE), " version=%s", RPLAY_VERSION); SNPRINTF(SIZE(b->buf + strlen(b->buf), BUFFER_SIZE), " uptime=%s", time2string(time(0) - starttime)); if (audio_enabled) { SNPRINTF(SIZE(b->buf + strlen(b->buf), BUFFER_SIZE), " audio-bits=%d", rplay_audio_precision); #ifndef HAVE_OSS SNPRINTF(SIZE(b->buf + strlen(b->buf), BUFFER_SIZE), " audio-bufsize=%d", rplay_audio_bufsize); #endif /* !HAVE_OSS */ SNPRINTF(SIZE(b->buf + strlen(b->buf), BUFFER_SIZE), " audio-byte-order=%s", byte_order_to_string(RPLAY_AUDIO_BYTE_ORDER)); SNPRINTF(SIZE(b->buf + strlen(b->buf), BUFFER_SIZE), " audio-channels=%d", rplay_audio_channels); SNPRINTF(SIZE(b->buf + strlen(b->buf), BUFFER_SIZE), " audio-device=%s", rplay_audio_device); SNPRINTF(SIZE(b->buf + strlen(b->buf), BUFFER_SIZE), " audio-format=%s", audio_format_to_string(rplay_audio_format)); #ifdef HAVE_OSS SNPRINTF(SIZE(b->buf + strlen(b->buf), BUFFER_SIZE), " audio-fragsize=%d", rplay_audio_fragsize); #endif /* HAVE_OSS */ SNPRINTF(SIZE(b->buf + strlen(b->buf), BUFFER_SIZE), " audio-port=%s", audio_port_to_string(rplay_audio_port)); SNPRINTF(SIZE(b->buf + strlen(b->buf), BUFFER_SIZE), " audio-rate=%d", rplay_audio_rate); SNPRINTF(SIZE(b->buf + strlen(b->buf), BUFFER_SIZE), " audio-sample-rate=%d", rplay_audio_sample_rate); SNPRINTF(SIZE(b->buf + strlen(b->buf), BUFFER_SIZE), " volume=%d", rplay_audio_volume); #ifndef HAVE_OSS SNPRINTF(SIZE(b->buf + strlen(b->buf), BUFFER_SIZE), " curr-bufsize=%d", curr_bufsize); #endif /* !HAVE_OSS */ SNPRINTF(SIZE(b->buf + strlen(b->buf), BUFFER_SIZE), " curr-rate=%d", curr_rate); SNPRINTF(SIZE(b->buf + strlen(b->buf), BUFFER_SIZE), " priority-threshold=%d", rplay_priority_threshold); SNPRINTF(SIZE(b->buf + strlen(b->buf), BUFFER_SIZE), " audio-close=%d", rplay_audio_timeout); SNPRINTF(SIZE(b->buf + strlen(b->buf), BUFFER_SIZE), " audio-device-status=%s", rplay_audio_isopen() ? "open" : "closed"); } SNPRINTF(SIZE(b->buf + strlen(b->buf), BUFFER_SIZE), "\r\n"); b->nbytes = strlen(b->buf); return b; } void need_reset() { need_to_reset++; } /* Reset rplayd's state. */ static void reset() { int was_enabled = timer_enabled; if (was_enabled) { timer_stop(); } spool_init(); connection_cleanup(); #ifdef HAVE_HELPERS helper_reread(helpers_file); #endif /* HAVE_HELPERS */ sound_reread(sounds_file); cache_init(cache_dir); cache_read(); #ifdef AUTH host_reread(hosts_file); #endif /* AUTH */ server_reread(servers_file); if (was_enabled) { timer_start(curr_rate); } } static void handle_signals() { /* Ingore SIGPIPE since read will handle closed TCP connections. Handle SIGHUP, SIGINT, and SIGCHLD. */ #ifdef HAVE_SIGSET sigset(SIGPIPE, SIG_IGN); sigset(SIGHUP, handle_sighup); sigset(SIGINT, handle_sigint); sigset(SIGCHLD, handle_sigchld); #else signal(SIGPIPE, SIG_IGN); signal(SIGHUP, handle_sighup); signal(SIGINT, handle_sigint); signal(SIGCHLD, handle_sigchld); #endif } static void handle_sighup() { report(REPORT_DEBUG, "received SIGHUP signal\n"); need_reset(); } static void handle_sigint() { report(REPORT_DEBUG, "received SIGINT signal\n"); done(0); } static void handle_sigchld() { pid_t pid; SPOOL *sp; #ifdef linux handle_signals(); #endif report(REPORT_DEBUG, "received SIGCHLD signal\n"); #ifdef HAVE_WAITPID pid = waitpid((pid_t) - 1, NULL, WNOHANG); #else /* not HAVE_WAITPID */ pid = wait(NULL); #endif /* not HAVE_WAITPID */ if (pid <= 0) { return; } } static void audio_test() { static char *spin = "|\\-/"; static int spin_pos; printf("Testing supported audio configurations (this may take a long time)...\n"); for (optional_sample_rate = 4000; optional_sample_rate <= 48000; optional_sample_rate += 5) for (optional_precision = 8; optional_precision <= 16; optional_precision += 8) for (optional_channels = 1; optional_channels <= 2; optional_channels++) for (optional_format = 1; optional_format <= 5; optional_format++) { if (!spin[spin_pos]) { spin_pos = 0; } fprintf(stderr, "%c\r", spin[spin_pos++]); if (rplay_audio_init() >= 0) { printf(" { %5d, %-24s, %2d, %d },\n", rplay_audio_sample_rate, rplay_audio_format == RPLAY_FORMAT_ULAW ? "RPLAY_FORMAT_ULAW" : rplay_audio_format == RPLAY_FORMAT_LINEAR_8 ? "RPLAY_FORMAT_LINEAR_8" : rplay_audio_format == RPLAY_FORMAT_ULINEAR_8 ? "RPLAY_FORMAT_ULINEAR_8" : rplay_audio_format == RPLAY_FORMAT_LINEAR_16 ? "RPLAY_FORMAT_LINEAR_16" : rplay_audio_format == RPLAY_FORMAT_ULINEAR_16 ? "RPLAY_FORMAT_ULINEAR_16" : "?", rplay_audio_precision, rplay_audio_channels); } } } #ifdef __STDC__ void done(int exit_value) #else void done(exit_value) int exit_value; #endif { SPOOL *sp; /* #ifdef HAVE_CDROM */ /* for (sp = spool; sp; sp = sp->next) */ /* { */ /* if (sp->si && sp->si->pid > 0) */ /* { */ /* report (REPORT_DEBUG, "killing process %d\n", sp->si->pid); */ /* if (kill (sp->si->pid, SIGKILL) < 0) */ /* { */ /* report (REPORT_DEBUG, "kill %d: %s\n", sp->si->pid, sys_err_str (errno)); */ /* } */ /* } */ /* } */ /* #endif */ /* connection_cleanup (); */ cache_cleanup(); rplay_audio_close(); close(rplay_fd); close(rptp_fd); #ifdef OTHER_RPLAY_PORTS close(other_rplay_fd); close(other_rptp_fd); #endif report(REPORT_DEBUG, "exit(%d)\n", exit_value); if (logging && log_fd >= 0) { close(log_fd); } exit(exit_value); } #ifdef __STDC__ void report(int level, char *fmt,...) #else void report(va_alist) va_dcl #endif { va_list args; char *p; time_t now; static struct iovec iov[2]; static char header[256]; static char message[2048]; /* XXX: largest message */ #ifdef __STDC__ va_start(args, fmt); #else char *fmt; int level; va_start(args); level = va_arg(args, int); fmt = va_arg(args, char *); #endif if (report_level >= level) { VSNPRINTF(SIZE(message, sizeof(message)), fmt, args); iov[1].iov_base = message; iov[1].iov_len = strlen(message); if (logging) { now = time(0); p = ctime(&now); p += 4; p[15] = '\0'; if (log_fd < 0) { #ifndef O_SYNC #define O_SYNC 0 #endif log_fd = open(log_file, O_WRONLY | O_CREAT | O_APPEND | O_SYNC, 0644); if (log_fd < 0) { fprintf(stderr, "%s: cannot open logfile `%s': %s\n", progname, log_file, sys_err_str(errno)); /* * Turn off logging to avoid further problems. */ logging = 0; log_fd = -1; return; } } SNPRINTF(SIZE(header, sizeof(header)), "%s %s rplayd[%d]: ", p, hostname, rplayd_pid); iov[0].iov_base = header; iov[0].iov_len = strlen(header); if (writev(log_fd, iov, 2) < 0) { fprintf(stderr, "%s: cannot write to log file `%s': %s\n", progname, log_file, sys_err_str(errno)); logging = 0; log_fd = -1; fprintf(stderr, "%s: logging disabled\n", progname); } } if (debug || level == REPORT_ERROR) { SNPRINTF(SIZE(header, sizeof(header)), "%s: ", progname); iov[0].iov_base = header; iov[0].iov_len = strlen(header); #ifndef STDERR_FILENO #define STDERR_FILENO 2 #endif writev(STDERR_FILENO, iov, 2); } } va_end(args); } void usage() { printf("\n"); printf("rplay %s\n", RPLAY_VERSION); printf("\n"); printf("usage: %s [options]\n", progname); printf("\n"); printf("-A DEVICE, --audio-device=DEVICE\n"); printf("\tUse DEVICE for the audio device (%s).\n", rplay_audio_device); printf("\n"); #ifndef HAVE_OSS printf("-b N, --audio-bufsize=N\n"); printf("\tAudio buffer size (%d).\n", rplay_audio_bufsize); printf("\n"); #endif /* !HAVE_OSS */ printf("-B N, --audio-bits=N\n"); printf("\tAudio device bits per sample, 8 or 16.\n"); printf("\n"); printf("--audio-channels=N\n"); printf("\tNumber of audio channels to use, 1 == mono, 2 == stereo.\n"); printf("\n"); printf("-c N, --audio-close=N\n"); printf("\tClose %s after N idle seconds, disabled with 0 (%d).\n", RPLAY_AUDIO_DEVICE, rplay_audio_timeout); printf("\n"); printf("-F N, --audio_flush=N\n"); printf("\tFlush %s after N idle seconds, disabled with 0 (%d).\n", RPLAY_AUDIO_DEVICE, rplay_audio_flush_timeout); printf("\tN = -1 : flush when spool is empty.\n"); printf("\tN = -2 : flush after each audio write. (not recommended)\n"); printf("\tN should be <= to the audio close timeout.\n"); printf("\n"); printf("--audio-format=FORMAT\n"); printf("\tTell rplayd to write audio data using FORMAT, where FORMAT\n"); printf("\tcan be ulaw, linear-8, ulinear-8, linear-16, or ulinear-16.\n"); printf("\t(linear = signed, ulinear = unsigned)\n"); printf("\n"); #ifdef HAVE_OSS printf("--audio-fragsize=N\n"); printf("\tAudio fragment size (%d). The default size is zero which lets\n", rplay_audio_fragsize); printf("\tthe audio driver pick the \"best\" size. The size specified must\n"); printf("\tbe a power of 2 greater than 16. Example: 256, 1024, 4096.\n"); printf("\n"); #endif /* HAVE_OSS */ printf("--audio-info=INFO, --info=INFO, -i INFO\n"); printf("\tSpecify complete audio device information with one option.\n"); printf("\tINFO is of the form: format,sample-rate,bits,channels\n"); printf("\tExamples: `ulaw,8000,8,1' and `linear-16,44100,16,2'\n"); printf("\tAlso provided are:\n"); printf("\t --audio-info-ulaw, --info-ulaw -> ulaw,8000,8,1\n"); printf("\n"); printf("--audio-match\n"); printf("\tAttempt to match the sample rate of the audio device with\n"); printf("\tthe sample rate of the current sound when no other sounds\n"); printf("\tare playing. If the match fails, --audio-sample-rate is used.\n"); printf("\tThis option overrides --audio-bufsize.\n"); printf("\n"); printf("--audio-port=PORT[,PORT...]\n"); printf("\tOutput audio to the specified audio port(s).\n"); printf("\tValid ports are `speaker', `headphone', and `lineout'.\n"); printf("\tMultiple ports can be specified using `speaker,headphone,lineout'\n"); printf("\n"); printf("-r N, --audio-rate=N\n"); printf("\tWrite the audio buffer N times per second (%d).\n", rplay_audio_rate); printf("\n"); printf("-R N, --audio-sample-rate=N\n"); printf("\tSample rate of the audio device.\n"); printf("\n"); #ifdef AUTH printf("--auth\n"); printf("\tEnable host access authentication.\n"); printf("\n"); #endif printf("-D DIR, --cache-directory=DIR\n"); printf("\tUse DIR for rplay.cache (%s).\n", RPLAY_CACHE); printf("\n"); printf("--cache-remove\n"); printf("\tRemove the cache directory and all its contents when rplayd exists.\n"); printf("\n"); printf("-s N, --cache-size=N\n"); printf("\tMaximum size in bytes of the rplay cache, disabled with 0 (%d).\n", RPLAY_CACHE_SIZE); printf("\n"); #ifdef HAVE_CDROM printf("--cdrom0=DEVICE, --cdrom1=DEVICE, --cdrom2=DEVICE, --cdrom3=DEVICE\n"); printf("\tSpecify the cdrom[0-3] to DEVICE mapping. For Solaris 2.x the default\n"); printf("\tmapping is cdrom[0-3] -> /vol/dev/aliases/cdrom[0-3].\n"); printf("\tLinux uses cdrom[0-3] -> /dev/cdrom[0-3].\n"); printf("\n"); #endif /* HAVE_CDROM */ printf("-C FILE, --conf=FILE\n"); printf("\tUse FILE for rplay.conf (%s).\n", RPLAY_CONF); printf("\n"); printf("-T N, --connection-timeout=N\n"); printf("\tClose idle RPTP connections after N seconds, disabled with 0 (%d).\n", rptp_timeout); printf("\n"); printf("-d, --debug\n"); printf("\tEnable debug mode.\n"); printf("\n"); printf("-f HOST, --forward=HOST\n"); printf("\tForward all RPLAY packets to HOST.\n"); printf("\n"); printf("--fork\n"); printf("\tEnable backgrounding rplayd at startup. (%s)\n", do_fork ? "enabled" : "disabled"); printf("\n"); printf("--group=GROUP\n"); printf("\tRun with GROUP privs. (%s)\n", run_as_group); printf("\n"); printf("--help\n"); printf("\tDisplay helpful information.\n"); printf("\n"); #ifdef HAVE_HELPERS printf("--helpers=FILE\n"); printf("\tUse FILE for rplay.helpers (%s).\n", RPLAY_HELPERS); printf("\n"); #endif /* HAVE_HELPERS */ #ifdef AUTH printf("-H FILE, --hosts=FILE\n"); printf("\tUse FILE for rplay.hosts (%s).\n", RPLAY_HOSTS); printf("\n"); #endif /* AUTH */ printf("--inetd\n"); printf("\tEnable inetd mode. (%s)\n", inetd ? "enabled" : "disabled"); printf("\n"); printf("-L FILE, --log-file=FILE\n"); printf("\tUse file for rplay.log (%s).\n", RPLAY_LOG); printf("\n"); printf("-l N, --log-level=N\n"); printf("\tUse logging level N where %d <= n <= %d.\n", REPORT_MIN, REPORT_MAX); printf("\n"); printf("--memory-cache-size=N\n"); printf("\tMaximum size in bytes of the memory cache, disable caching with 0 (%d).\n", MEMORY_CACHE_SIZE); printf("\n"); printf("--memory-cache-sound-size=N\n"); printf("\tMaximum size in bytes of a sound that can be cached in memory.\n"); printf("\tA value of 0 means to try and cache all sounds. (%d)\n", MEMORY_CACHE_SOUND_SIZE); printf("\n"); printf("-N, --no-audio\n"); printf("\tDisable audio, RPTP file server mode.\n"); printf("\n"); #ifdef AUTH printf("--no-auth\n"); printf("\tDisable host access authentication.\n"); printf("\n"); #endif printf("-n, --no-inetd\n"); printf("\tDisable inetd mode. (%s)\n", inetd ? "enabled" : "disabled"); printf("\n"); printf("--no-fork\n"); printf("\tDisable backgrounding rplayd at startup. (%s)\n", do_fork ? "enabled" : "disabled"); printf("\n"); printf("--options-file=FILE\n"); printf("\tRead rplayd options from FILE.\n"); printf("\n"); printf("--port=PORT, --rplay-port=PORT\n"); printf("\tUse PORT as the RPLAY/UDP port. (%d)\n", RPLAY_PORT); printf("\t(--other-rplay-port may also be available)\n"); printf("\n"); printf("--rptp-port=PORT\n"); printf("\tUse PORT as the RPTP/TCP port. (%d)\n", RPTP_PORT); printf("\t(--other-rptp-port may also be available)\n"); printf("\n"); printf("-S FILE, --servers=FILE\n"); printf("\tUse FILE for rplay.servers (%s).\n", RPLAY_SERVERS); printf("\n"); printf("-t N, --timeout=N\n"); printf("\tExit after N idle seconds, disabled with 0 (%d).\n", rplayd_timeout); printf("\n"); printf("--user=USER\n"); printf("\tRun with USER privs. (%s)\n", run_as_user); printf("\n"); printf("-v, --version\n"); printf("\tPrint the rplay version and exit.\n"); } rplay-3.3.2/rplayd/rplayd.h100644 153 62 14246 6671423014 14306 0ustar boynsstaff/* $Id: rplayd.h,v 1.3 1999/03/10 07:58:04 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _rplayd_h #define _rplayd_h #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "rplay.h" #include "misc.h" #include "audio.h" #include "buffer.h" #include "spool.h" /* Report levels */ #define REPORT_NONE 0 /* Nothing. */ #define REPORT_ERROR 1 /* System and rplayd errors. */ #define REPORT_NOTICE 2 /* ... + RPTP connections, get, put, find */ #define REPORT_INFO 3 /* ... + play, stop, pause, continue, etc */ #define REPORT_DEBUG 4 /* ... + Debug messages. */ #define REPORT_MIN 0 #define REPORT_MAX 4 /* $Id: rplayd.h,v 1.3 1999/03/10 07:58:04 boyns Exp $ */ #define SET_BIT(w, bit) ( (w) |= (bit) ) #define CLR_BIT(w, bit) ( (w) &= ~(bit) ) #define BIT(w, bit) ( (w) & (bit) ) #define TOGGLE_BIT(w, bit) ( (w) ^= (bit) ) /* UIO_MAXIOV probably isn't defined so lets assume it's 16. */ #ifndef UIO_MAXIOV #define UIO_MAXIOV 16 #endif /* Table of audio parameters supported by the audio device. */ typedef struct { int sample_rate; int format; int bits; int channels; } RPLAY_AUDIO_TABLE; extern RPLAY_AUDIO_TABLE *rplay_audio_table; /* Global variables that are declared in rplayd.c. (See rplayd.c for descriptions) */ extern fd_set read_mask; extern fd_set write_mask; extern int debug; extern int inetd; extern int rptp_timeout; extern char hostname[]; extern char *hostaddr; extern int rplay_fd; extern int rptp_fd; #ifdef OTHER_RPLAY_PORTS extern int other_rplay_fd; extern int other_rptp_fd; #endif extern int curr_rate; #ifndef HAVE_OSS extern int curr_bufsize; #endif /* !HAVE_OSS */ extern int rplayd_pid; extern time_t starttime; #ifdef AUTH extern int auth_enabled; #endif /* AUTH */ extern int rplay_priority_threshold; extern char *rplay_audio_device; #ifndef HAVE_OSS extern int rplay_audio_bufsize; #endif /* !HAVE_OSS */ extern int rplay_audio_rate; extern int rplay_audio_sample_rate; extern int rplay_audio_channels; extern int rplay_audio_format; extern int rplay_audio_precision; extern int rplay_audio_port; extern int audio_enabled; extern int rplay_audio_volume; extern int rplay_audio_match; extern int rplay_audio_size; extern char *rplay_audio_buf; extern int max_rplay_audio_bufsize; extern int rplay_audio_left_level; extern int rplay_audio_right_level; extern int optional_sample_rate; extern int optional_precision; extern int optional_channels; extern int optional_format; extern int optional_port; extern int default_sample_rate; extern int default_precision; extern int default_channels; extern int default_format; extern int default_port; #ifdef HAVE_OSS extern int rplay_audio_fragsize; extern int optional_fragsize; extern int default_fragsize; #endif /* HAVE_OSS */ extern int monitor_count; extern BUFFER *monitor_buffers; extern int errno; #ifdef __STDC__ extern void usage (); extern void done (int exit_value); extern unsigned long inet_addr (char *); extern char *inet_ntoa (struct in_addr); extern void report (int level_mask, char *fmt,...); extern void rplayd_read (int fd); extern void rplayd_write (int nbytes); extern void rplayd_init (); extern int rplayd_play (RPLAY *rp, struct sockaddr_in sin); extern int rplayd_stop (RPLAY *rp, struct sockaddr_in sin); extern int rplayd_pause (RPLAY *rp, struct sockaddr_in sin); extern int rplayd_continue (RPLAY *rp, struct sockaddr_in sin); extern int rplayd_done (RPLAY *rp, struct sockaddr_in sin); extern int rplayd_put (RPLAY *rp, struct sockaddr_in sin); extern BUFFER *rplayd_status (); extern void need_reset (); extern int rplayd_audio_init (); extern void rplayd_audio_match (SPOOL *sp); #else extern void usage (); extern void done ( /* int exit_value */ ); extern unsigned long inet_addr ( /* char * */ ); extern char *inet_ntoa ( /* struct in_addr */ ); extern void report ( /* int level_mask, char *fmt, ... */ ); extern void rplayd_read ( /* int fd */ ); extern void rplayd_write ( /* int nbytes */ ); extern void rplayd_init (); extern int rplayd_play ( /* RPLAY *rp, struct sockaddr_in sin */ ); extern int rplayd_stop ( /* RPLAY *rp, struct sockaddr_in sin */ ); extern int rplayd_pause ( /* RPLAY *rp, struct sockaddr_in sin */ ); extern int rplayd_continue ( /* RPLAY *rp, struct sockaddr_in sin */ ); extern int rplayd_done ( /* RPLAY *rp, struct sockaddr_in sin */ ); extern int rplayd_put ( /* RPLAY *rp, struct sockaddr_in sin */ ); extern BUFFER *rplayd_status (); extern void need_reset (); extern int rplayd_audio_init (); extern void rplayd_audio_match ( /* SPOOL *sp */ ); #endif /* * Prototypes for the audio stubs: */ #ifdef __STDC__ extern int rplay_audio_init (); extern int rplay_audio_open (); extern int rplay_audio_isopen (); extern int rplay_audio_flush (); extern int rplay_audio_close (); extern int rplay_audio_write (char *buf, int nbytes); extern int rplay_audio_audio_get_volume (); extern int rplay_audio_audio_set_volume (int volume); extern int rplay_audio_get_volume (); extern int rplay_audio_set_volume (int volume); #else extern int rplay_audio_init (); extern int rplay_audio_open (); extern int rplay_audio_isopen (); extern int rplay_audio_flush (); extern int rplay_audio_close (); extern int rplay_audio_write ( /* char *buf, int nbytes */ ); extern int rplay_audio_audio_get_volume (); extern int rplay_audio_audio_set_volume ( /* int volume */ ); extern int rplay_audio_get_volume (); extern int rplay_audio_set_volume ( /* int volume */ ); #endif #endif /* _rplayd_h */ rplay-3.3.2/rplayd/server.c100644 153 62 11140 6671423014 14302 0ustar boynsstaff/* $Id: server.c,v 1.5 1999/03/10 07:58:04 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "rplay.h" #include #include #include #include #ifdef HAVE_STRING_H #include #endif #include "rplayd.h" #include "server.h" #include "connection.h" #include "buffer.h" BUFFER *server_list = NULL; SERVER *servers = NULL; static time_t server_read_time; #ifdef __STDC__ void server_read(char *filename) #else void server_read(filename) char *filename; #endif { FILE *fp; char buf[BUFSIZ], *p; char line[RPTP_MAX_LINE]; struct hostent *hp, *local_hp; unsigned long addr, local_addr; struct sockaddr_in sin; int port, n; SERVER **s = &servers; BUFFER *b; server_read_time = time(0); fp = fopen(filename, "r"); if (fp == NULL) { /* * I guess it's ok to not have any servers. */ report(REPORT_NOTICE, "warning: cannot open %s\n", filename); return; } local_hp = gethostbyname(hostname); if (local_hp == NULL) { report(REPORT_ERROR, "server_read: %s unknown host?!\n", hostname); done(1); } memcpy((char *) &local_addr, (char *) local_hp->h_addr, local_hp->h_length); b = buffer_create(); strcpy(b->buf, "+message=\"servers\"\r\n"); b->nbytes += strlen(b->buf); b->status = BUFFER_KEEP; server_list = b; while (fgets(buf, sizeof(buf), fp)) { switch (buf[0]) { case '#': case ' ': case '\t': case '\n': continue; } p = strchr(buf, '\n'); if (p) { *p = '\0'; } p = strchr(buf, ':'); if (p) { *p = '\0'; port = atoi(p + 1); } else { port = RPTP_PORT; } addr = inet_addr(buf); memset((char *) &sin, 0, sizeof(sin)); if (addr == 0xffffffff) { hp = gethostbyname(buf); if (hp == NULL) { report(REPORT_NOTICE, "warning: %s unknown host in %s\n", buf, filename); continue; } memcpy((char *) &sin.sin_addr.s_addr, (char *) hp->h_addr, hp->h_length); } else { memcpy((char *) &sin.sin_addr.s_addr, (char *) &addr, sizeof(addr)); } if (memcmp((char *) &sin.sin_addr.s_addr, (char *) &local_addr, sizeof(local_addr)) == 0) { /* * ignore the server if it's the local host */ continue; } *s = (SERVER *) malloc(sizeof(SERVER)); if (*s == NULL) { report(REPORT_ERROR, "server_read: out of memory\n"); done(1); } sin.sin_family = AF_INET; sin.sin_port = htons(port); SNPRINTF(SIZE(line, sizeof(line)), "host=%s port=%d\r\n", buf, port); n = strlen(line); if (b->nbytes + n > BUFFER_SIZE) { b->next = buffer_create(); b = b->next; b->status = BUFFER_KEEP; } SNPRINTF(SIZE(b->buf + b->nbytes, BUFFER_SIZE - b->nbytes), line); b->nbytes += n; (*s)->sin = sin; s = &(*s)->next; report(REPORT_DEBUG, "server %s port %d\n", inet_ntoa(sin.sin_addr), port); } *s = NULL; fclose(fp); if (b->nbytes + 3 > BUFFER_SIZE) { b->next = buffer_create(); b = b->next; b->status = BUFFER_KEEP; } SNPRINTF(SIZE(b->buf + b->nbytes, BUFFER_SIZE - b->nbytes), ".\r\n"); b->nbytes += 3; } #ifdef __STDC__ void server_reread(char *filename) #else void server_reread(filename) char *filename; #endif { BUFFER *b, *bb; SERVER *s, *ss; report(REPORT_DEBUG, "re-reading servers\n"); /* * Free the server_list buffers. */ for (b = server_list; b; bb = b, b = b->next, bb->status = BUFFER_FREE, buffer_destroy(bb)) ; /* * Free the servers list. */ for (s = servers; s; ss = s, s = s->next, free((char *) ss)) ; server_list = NULL; servers = NULL; server_read(filename); } #ifdef __STDC__ void server_stat(char *filename) #else void server_stat(filename) char *filename; #endif { if (modified(filename, server_read_time)) { server_reread(filename); } } rplay-3.3.2/rplayd/server.h100644 153 62 2667 6671423014 14305 0ustar boynsstaff/* $Id: server.h,v 1.3 1999/03/10 07:58:04 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _server_h #define _server_h #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "buffer.h" typedef struct _server { struct _server *next; struct sockaddr_in sin; } SERVER; extern BUFFER *server_list; extern SERVER *servers; #ifdef __STDC__ extern void server_read (char *filename); extern void server_reread (char *filename); extern void server_stat (char *filename); #else extern void server_read ( /* char *filename */ ); extern void server_reread ( /* char *filename */ ); extern void server_stat ( /* char *filename */ ); #endif #endif /* _server_h */ rplay-3.3.2/rplayd/sound.c100644 153 62 151362 6727404540 14164 0ustar boynsstaff/* $Id: sound.c,v 1.10 1999/06/09 06:27:44 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #ifdef ultrix #include #else #include #endif #include #ifdef HAVE_MMAP #include #endif #include #ifdef HAVE_STRING_H #include #endif #include #include #include #include "sound.h" #include "rplayd.h" #include "cache.h" #include "ulaw.h" #include "xhash.h" #include "server.h" #include "buffer.h" #include "connection.h" #include "misc.h" #include "strdup.h" #include "spool.h" #ifdef HAVE_CDROM #include "cdrom.h" #endif /* HAVE_CDROM */ #ifdef HAVE_HELPERS #include "helper.h" #endif /* HAVE_HELPERS */ #ifdef HAVE_RX_RXPOSIX_H #include #else #ifdef HAVE_RXPOSIX_H #include #else #include "rxposix.h" #endif #endif SOUND *sounds = NULL; int sound_count = 0; static time_t sound_read_time; int sound_cache_size = 0; int sound_cache_max_sound_size = MEMORY_CACHE_SOUND_SIZE; int sound_cache_max_size = MEMORY_CACHE_SIZE; #ifdef BAD_DIRS static regex_t bad_dirs; /* Prepare `bad_dirs'. */ static void bad_dirs_init() { static char *buf; char *p; char *dirs; int first, length; dirs = strdup(BAD_DIRS); /* XXX */ length = strlen("^\\(") + strlen("\\)") + strlen(dirs) + 1; //length += strlen ("^"); for (p = dirs; *p; p++) { if (*p == ':') { length += strlen("\\|") - strlen(":"); } } if (buf) { free(buf); } buf = (char *) malloc(length); if (buf == NULL) { report(REPORT_ERROR, "bad_dir_init: out of memory\n"); done(1); } first = 1; strcpy(buf, "^\\("); while (p = (char *) strtok(first ? dirs : 0, ":")) { if (first) { //strcat (buf, "^"); first = 0; } else { //strcat (buf, "\\|^"); strcat(buf, "\\|"); } strcat(buf, p); } strcat(buf, "\\)"); #if 0 report(REPORT_DEBUG, "bad_dirs=%s, strlen=%d, length=%d\n", buf, strlen(buf), length); #endif //memset ((char *) &bad_dirs, 0, sizeof (bad_dirs)); if (regncomp(&bad_dirs, buf, strlen(buf), REG_ICASE | REG_NOSUB)) { report(REPORT_ERROR, "bad_dirs: regncomp failed\n"); done(1); } free(dirs); } #ifdef __STDC__ static int bad_dir(char *dir) #else static int bad_dir(dir) char *dir; #endif { /* return 1 if bad */ return regnexec(&bad_dirs, dir, strlen(dir), 0, 0, 0) ? 0 : 1; } #endif /* BAD_DIRS */ #ifdef __STDC__ void sound_read_directory(char *dirname) #else void sound_read_directory(dirname) char *dirname; #endif { char soundname[MAXPATHLEN]; struct dirent *dp; DIR *dir = opendir(dirname); if (dir == NULL) { report(REPORT_ERROR, "opendir %s: %s", sys_err_str(errno)); return; } while ((dp = readdir(dir)) != NULL) { if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) { continue; } sprintf(soundname, "%s/%s", dirname, dp->d_name); sound_insert(soundname, SOUND_READY, SOUND_FILE); } closedir(dir); } /* * read the rplay configuration file and load the hash table */ #ifdef __STDC__ void sound_read(char *filename) #else void sound_read(filename) char *filename; #endif { FILE *fp; char buf[MAXPATHLEN], *p; struct stat st; xhash_init(MAX_SOUNDS); #ifdef BAD_DIRS bad_dirs_init(); #endif #ifdef HAVE_CDROM { /* Insert the CDROM devices into the sound list. */ int i; for (i = 0; i < MAX_CDROMS; i++) { sound_insert(cdrom_table[i].name, SOUND_READY, SOUND_CDROM); } } #endif /* HAVE_CDROM */ sound_read_time = time(0); fp = fopen(filename, "r"); if (fp == NULL) { report(REPORT_NOTICE, "warning: cannot open %s\n", filename); /* * no local sounds */ return; } while (fgets(buf, sizeof(buf), fp) != NULL) { switch (buf[0]) { case '#': case ' ': case '\t': case '\n': continue; } p = strchr(buf, '\n'); if (p) { *p = '\0'; } if (stat(buf, &st) < 0) { report(REPORT_ERROR, "sound_read: %s: %s\n", buf, sys_err_str(errno)); continue; } if (S_ISDIR(st.st_mode)) { sound_read_directory(buf); } else { sound_insert(buf, SOUND_READY, SOUND_FILE); } } fclose(fp); } #ifdef __STDC__ static char * destroy(char *hash_string, char *hash_value) #else static char * destroy(hash_string, hash_value) char *hash_string; char *hash_value; #endif { SOUND *s = (SOUND *) hash_value; sound_free(s); free((char *) s); return NULL; } /* * Re-read the rplay configuration file and reload the hash table. */ #ifdef __STDC__ void sound_reread(char *filename) #else void sound_reread(filename) char *filename; #endif { SOUND *s1, *s1_next, *s2, *s2_next; report(REPORT_DEBUG, "re-reading sounds\n"); /* * Delete all the sounds. */ #if 1 for (s1 = sounds; s1; s1 = s1_next) { s1_next = s1->list; for (s2 = s1; s2; s2 = s2_next) { s2_next = s2->next; /* xhash_delete(s2->hash_key); */ sound_free(s2); free((char *) s2); } } #else xhash_apply(destroy); #endif xhash_die(); xhash_init(MAX_SOUNDS); sounds = NULL; sound_count = 0; /* * and now load the sounds */ sound_read(filename); /* * don't forget the cache... */ cache_read(); } #ifdef __STDC__ void sound_stat(char *filename) #else void sound_stat(filename) char *filename; #endif { if (modified(filename, sound_read_time)) { sound_reread(filename); } } BUFFER * sound_list_create() { SOUND *s; int n; BUFFER *start, *b; char line[RPTP_MAX_LINE]; b = buffer_create(); start = b; SNPRINTF(SIZE(b->buf + strlen(b->buf), BUFFER_SIZE), "+message=\"sounds\"\r\n"); b->nbytes += strlen(b->buf); for (s = sounds; s; s = s->list) { if (s->status != SOUND_READY) { continue; } if (s->mapped) { SNPRINTF(SIZE(line, sizeof(line)), "\ sound=\"%s\" size=%d bits=%g sample_rate=%d channels=%d samples=%d\r\n", s->name, s->size, s->input_precision, s->sample_rate, s->channels, s->samples); } else { SNPRINTF(SIZE(line, sizeof(line)), "sound=\"%s\"\r\n", s->name); } n = strlen(line); if (b->nbytes + n > BUFFER_SIZE) { b->next = buffer_create(); b = b->next; } strncat(b->buf + b->nbytes, line, BUFFER_SIZE - b->nbytes); b->nbytes += n; } if (b->nbytes + 3 > BUFFER_SIZE) { b->next = buffer_create(); b = b->next; } SNPRINTF(SIZE(b->buf + b->nbytes, BUFFER_SIZE - b->nbytes), ".\r\n"); b->nbytes += 3; return start; } #ifdef __STDC__ SOUND * sound_insert(char *path, int status, int type) #else SOUND * sound_insert(path, status, type) char *path; int status; int type; #endif { SOUND *s; char *hash_val; #ifdef BAD_DIRS if (bad_dir(path)) { report(REPORT_NOTICE, "bad_dir: attempt to load %s\n", path); return NULL; } #endif s = sound_create(); if (s == NULL) { report(REPORT_ERROR, "sound_insert: out of memory\n"); done(1); } s->type = type; s->path = strdup(path); if (s->path == NULL) { report(REPORT_ERROR, "sound_insert: out of memory\n"); done(1); } s->hash_key = strdup(xhash_name(s->path)); if (s->hash_key == NULL) { report(REPORT_ERROR, "sound_insert: out of memory\n"); done(1); } s->name = s->path[0] == '/' ? strrchr(s->path, '/') + 1 : s->path; s->status = status; hash_val = xhash_get(s->hash_key); if (hash_val == NULL) { xhash_put(s->hash_key, (char *) s); s->list_prev = NULL; s->list = sounds; if (sounds) { sounds->list_prev = s; } sounds = s; } else { SOUND *ss, *prev = NULL; for (ss = (SOUND *) hash_val; ss; prev = ss, ss = ss->next) { if (strcmp(ss->path, s->path) == 0) { free((char *) s); return ss; } } prev->next = s; s->prev = prev; } return s; } /* * create a sound */ #ifdef __STDC__ SOUND * sound_create(void) #else SOUND * sound_create() #endif { SOUND *s; s = (SOUND *) malloc(sizeof(SOUND)); if (s == NULL) { return s; } s->list = NULL; s->list_prev = NULL; s->next = NULL; s->prev = NULL; s->type = 0; s->storage = SOUND_STORAGE_NULL; s->path = NULL; s->name = NULL; s->hash_key = NULL; s->status = SOUND_NULL; s->count = 0; s->format = RPLAY_FORMAT_NONE; s->byte_order = 0; s->sample_rate = 0; s->input_precision = 0; s->output_precision = 0; s->channels = 0; s->samples = 0; s->input_sample_size = 0; s->output_sample_size = 0; s->offset = 0; s->size = 0; s->tail = 0; s->chunk_size = 0; s->mapped = 0; s->cache = NULL; s->flow = NULL; s->flowp = &s->flow; #ifdef HAVE_CDROM s->starting_track = 0; s->ending_track = 0; #endif /* HAVE_CDROM */ #ifdef HAVE_HELPERS s->needs_helper = 0; #endif /* HAVE_HELPERS */ return s; } /* * Lookup the sound name in the hash table and map the sound file if * necessary. */ #ifdef __STDC__ SOUND * sound_lookup(char *name, int mode, SERVER *lookup_server) #else SOUND * sound_lookup(name, mode, lookup_server) char *name; int mode; SERVER *lookup_server; #endif { SOUND *s = NULL; int has_extension = 0, has_pathname = 0; struct stat st; int i; #ifdef HAVE_CDROM /* Map sounds with cdrom prefixes to the cdrom itself. */ for (i = 0; i < MAX_CDROMS; i++) { if (strncmp(name, cdrom_table[i].name, strlen(cdrom_table[i].name)) == 0) { break; } } if (i < MAX_CDROMS) { s = (SOUND *) xhash_get(xhash_name(cdrom_table[i].name)); } #endif /* HAVE_CDROM */ if (s == NULL) { s = (SOUND *) xhash_get(xhash_name(name)); } if (s == NULL) { report(REPORT_DEBUG, "%s not in hash table\n", name); if (mode == SOUND_DONT_FIND || mode == SOUND_DONT_COUNT) { return NULL; } /* * see if a local file can be loaded (mode == SOUND_LOAD) */ if (stat(name, &st) == 0) { report(REPORT_DEBUG, "loading local file %s\n", name); s = sound_insert(name, SOUND_READY, SOUND_FILE); if (s == NULL) { return NULL; } } #if 0 /* virtual sounds cause searching problems */ #ifdef HAVE_HELPERS else if (mode == SOUND_CREATE && helper_lookup(name)) { s = sound_insert(name, SOUND_READY, SOUND_VIRTUAL); } #endif #endif else if (mode == SOUND_FIND) { if (name[0] == '/') { report(REPORT_DEBUG, "not searching for %s\n", name); return NULL; } if (lookup_server) { report(REPORT_DEBUG, "searching for %s\n", name); s = sound_insert(cache_name(name), SOUND_SEARCH, SOUND_FILE); if (s == NULL) { return NULL; } connection_server_open(lookup_server, s); } else if (servers) { report(REPORT_DEBUG, "searching for %s\n", name); s = sound_insert(cache_name(name), SOUND_SEARCH, SOUND_FILE); if (s == NULL) { return NULL; } connection_server_open(servers, s); } else { return NULL; } } else { return NULL; } } else { /* * Make sure the sound found has the correct path and dot * extension. */ if (name[0] == '/') { has_pathname++; } else if (strrchr(name, '.')) { has_extension++; } for (; s; s = s->next) { if (has_pathname && (!s->path || strcmp(name, s->path) != 0)) { continue; } if (has_extension && (!s->path || strcmp(name, s->name) != 0)) { continue; } break; } if (s == NULL) { if (has_pathname) { report(REPORT_DEBUG, "`%s' file name not in hash table\n", name); if (stat(name, &st) == 0) { report(REPORT_DEBUG, "loading local file `%s'\n", name); s = sound_insert(name, SOUND_READY, SOUND_FILE); if (s == NULL) { return NULL; } } else { return NULL; } } else if (has_extension) { report(REPORT_DEBUG, "`%s' extension not in hash table\n", name); return NULL; } } } if (mode == SOUND_DONT_COUNT) { return s; } else { sound_count++; s->count = sound_count; } switch (s->status) { case SOUND_NOT_READY: case SOUND_SEARCH: return s; } if (!s->mapped) { return sound_map(s) == 0 ? s : NULL; } else { return s; } } /* * Map a sound using its header or file extension. */ #ifdef __STDC__ int sound_map(SOUND *s) #else int sound_map(s) SOUND *s; #endif { SINDEX *si; BUFFER *b; int n, storage; int optional_offset; int optional_format; int optional_byte_order; int optional_sample_rate; float optional_input_precision; int optional_output_precision; int optional_channels; int optional_storage; char buf[SOUND_MAX_HEADER_SIZE]; int sound_chunk_size = 0; #ifdef HAVE_HELPERS HELPER *helper = NULL; #endif /* HAVE_HELPERS */ if (s->mapped) { return 0; } /* Save the optional settings. */ optional_offset = s->offset; optional_format = s->format; optional_byte_order = s->byte_order; optional_sample_rate = s->sample_rate; optional_input_precision = s->input_precision; optional_output_precision = s->output_precision; optional_channels = s->channels; optional_storage = s->storage; #ifdef HAVE_HELPERS helper = helper_lookup(s->path); if (helper) { s->needs_helper++; strcpy(buf, "HELPER"); /* XXX: not used; see below */ } else #endif /* HAVE_HELPERS */ #ifdef HAVE_CDROM if (s->type == SOUND_CDROM) { strcpy(buf, "CDROM"); } else #endif /* HAVE_CDROM */ { si = sound_open(s, 1); if (si == NULL) { return -1; } /* Trick sound_fill to not free any buffers used to determine what sort of sound this is. */ storage = s->storage; s->storage = SOUND_STORAGE_MEMORY; b = buffer_alloc(SOUND_MAX_HEADER_SIZE, BUFFER_FREE); n = sound_fill(si, b, 1); s->storage = storage; if (n <= 0) { report(REPORT_DEBUG, "sound_map: sound_fill %d\n", n); buffer_dealloc(b, 1); return -1; } sound_close(si); /* Copy the buffer contents to `buf' so `b' can be destroyed. */ memcpy(buf, b->buf, MIN(sizeof(buf), b->nbytes)); buffer_dealloc(b, 1); } /* u-law */ if (strncmp(buf, ".snd", 4) == 0) { long ulaw_hdr_size; int encoding; int data_size; char *p; p = buf + 4; ulaw_hdr_size = big_long(p); p += 4; if (ulaw_hdr_size < ULAW_HDRSIZE) { report(REPORT_DEBUG, "%s not a ulaw file\n", s->path); return -1; } /* * The audio data size which may be ~0. * This value is ignored. */ data_size = big_long(p); p += 4; encoding = big_long(p); p += 4; switch (encoding) { case ULAW_MULAW_8: s->format = RPLAY_FORMAT_ULAW; s->input_precision = 8; s->output_precision = 8; break; case ULAW_LINEAR_8: s->format = RPLAY_FORMAT_LINEAR_8; s->input_precision = 8; s->output_precision = 8; break; case ULAW_LINEAR_16: s->format = RPLAY_FORMAT_LINEAR_16; s->input_precision = 16; s->output_precision = 16; break; #ifdef HAVE_ADPCM case ULAW_G721: s->format = RPLAY_FORMAT_G721; s->input_precision = 4; s->output_precision = 16; /* uncompressed to 16-bit */ break; case ULAW_G723_3: s->format = RPLAY_FORMAT_G723_3; s->input_precision = 3; s->output_precision = 16; /* uncompressed to 16-bit */ break; case ULAW_G723_5: s->format = RPLAY_FORMAT_G723_5; s->input_precision = 5; s->output_precision = 16; /* uncompressed to 16-bit */ break; #endif /* HAVE_ADPCM */ default: report(REPORT_DEBUG, "%s: %d - unsupported ulaw encoding\n", s->path, encoding); return -1; } /* * Byte order. */ s->byte_order = RPLAY_BIG_ENDIAN; /* * Sample rate. */ s->sample_rate = big_long(p); p += 4; /* * Number of channels. */ s->channels = big_long(p); p += 4; s->offset = ulaw_hdr_size; if (data_size == ~0) { sound_chunk_size = s->size - s->offset; } else { sound_chunk_size = data_size; } } /* aiff */ else if (strncmp(buf, "FORM", 4) == 0) { unsigned long total_size; unsigned long chunk_size; unsigned long frames; unsigned long offset; unsigned long block_size; double rate; int channels; int bits; char id[5]; char *p; p = buf + 4; total_size = big_long(p); p += 4; if (memcmp(p, "AIFF", 4) != 0) { return -1; } p += 4; /* * Scan the chunks. */ for (;;) { /* * Chunk id. */ memcpy(id, p, 4); id[4] = '\0'; p += 4; /* * Chunk size. */ chunk_size = big_long(p); p += 4; /* * COMM Chunk. */ if (memcmp(id, "COMM", 4) == 0) { channels = big_short(p); p += 2; frames = big_long(p); p += 4; bits = big_short(p); p += 2; rate = ConvertFromIeeeExtended((unsigned char *) p); p += 10; } /* * SSN Chunk. */ else if (memcmp(id, "SSND", 4) == 0) { offset = big_long(p); p += 4; block_size = big_long(p); sound_chunk_size = block_size; p += 4; break; } /* * Ignore other chunks. */ else { p += chunk_size; /* * skip the pad byte, if necessary */ if (chunk_size % 2 == 1) p++; } } /* * Byte order. */ s->byte_order = RPLAY_BIG_ENDIAN; s->offset = p - buf; s->sample_rate = rate; s->input_precision = bits; s->output_precision = bits; s->channels = channels; switch ((int) s->input_precision) { case 8: s->format = RPLAY_FORMAT_LINEAR_8; break; case 16: s->format = RPLAY_FORMAT_LINEAR_16; break; default: report(REPORT_ERROR, "unsupported aiff precision `%g'\n", s->input_precision); return -1; } } /* deadsnd files */ else if (*((long *) &buf) == 0x4a02b6d2) { DSID *dsid = (DSID *) & buf; s->offset = sizeof(DSID); s->sample_rate = dsid->freq; s->input_precision = s->output_precision = dsid->bps; s->channels = (dsid->mode + 1); s->byte_order = RPLAY_LITTLE_ENDIAN; switch (dsid->bps) { case 8: s->format = RPLAY_FORMAT_ULINEAR_8; break; case 16: s->format = RPLAY_FORMAT_LINEAR_16; break; default: report(REPORT_ERROR, "unsupported deadsnd precision `%d'\n", dsid->bps); return -1; } } /* wave */ else if (strncmp(buf, "RIFF", 4) == 0) { unsigned long chunk_size; short chunk_type; double rate; int channels; int bits; char id[5]; char *p; p = buf + 4; p += 4; if (memcmp(p, "WAVE", 4) != 0) { report(REPORT_ERROR, "wave file missing `WAVE' header\n"); return -1; } p += 4; /* * Scan the chunks. */ for (;;) { /* * Chunk id. */ memcpy(id, p, 4); id[4] = '\0'; p += 4; /* * Chunk size. */ chunk_size = little_long(p); p += 4; /* * 'fmt ' Chunk. */ if (memcmp(id, "fmt ", 4) == 0) { char *start_of_chunk = p; chunk_type = little_short(p); p += 2; /* * Only one wave format is supported. */ if (chunk_type == 0x0001) { channels = little_short(p); p += 2; rate = little_long(p); p += 4; p += 4; /* bytes/second ? */ p += 2; /* block align ? */ bits = little_short(p); p += 2; } else { report(REPORT_ERROR, "unknown wave chunk `%x'\n", chunk_type); return -1; } p = start_of_chunk + chunk_size; } /* * data Chunk. */ else if (memcmp(id, "data", 4) == 0) { /* size */ sound_chunk_size = chunk_size; break; } /* * Ignore other chunks. */ else { report(REPORT_DEBUG, "ignoring chunk - %s (%d)\n", id, chunk_size); p += chunk_size; /* * skip the pad byte, if necessary */ if (chunk_size % 2 == 1) p++; } } s->offset = p - buf; s->sample_rate = rate; s->input_precision = bits; s->output_precision = bits; s->channels = channels; switch ((int) s->input_precision) { case 8: s->format = RPLAY_FORMAT_ULINEAR_8; break; case 16: s->format = RPLAY_FORMAT_LINEAR_16; break; default: report(REPORT_ERROR, "unsupported wave precision `%g'\n", s->input_precision); return -1; } /* * Byte order. */ s->byte_order = RPLAY_LITTLE_ENDIAN; } /* voc */ else if (strncmp(buf, "Creative Voice File\032", 20) == 0) { char *p; short header_size; unsigned long block_length; unsigned char block_id, rate; p = buf + 20; header_size = little_short(p); /* sizeof header */ p += 2; /* major/minor version + checksum of version */ p += 2 * sizeof(short); for (;;) { block_id = *p++; if (block_id == 0) /* VOC_TERM */ { break; } /* Block length */ block_length = (unsigned char) *p++; block_length |= ((unsigned char) *p++ << 8); block_length |= ((unsigned char) *p++ << 16); if (block_id == 1) /* VOC_DATA */ { //sound_chunk_size = block_length; rate = *p++; s->input_precision = 8; s->output_precision = 8; s->sample_rate = 1000000.0 / (256 - rate); s->channels = 1; break; } else if (block_id == 9) /* VOC_DATA_16 */ { //sound_chunk_size = block_length; s->sample_rate = little_long(p); p += 4; switch (*p) { case 8: s->input_precision = 8; s->output_precision = 8; break; case 16: s->input_precision = 16; s->output_precision = 16; break; default: report(REPORT_ERROR, "unsupported voc_data_16 precision `%d'\n", *p); return -1; } *p++; s->channels = *p++; p++; /* unknown */ p++; /* not used */ p++; /* not used */ p++; /* not used */ p++; /* not used */ p++; /* not used */ break; } p += block_length; } s->offset = p - buf; s->byte_order = RPLAY_LITTLE_ENDIAN; switch ((int) s->input_precision) { case 8: s->format = RPLAY_FORMAT_ULINEAR_8; break; case 16: s->format = RPLAY_FORMAT_ULINEAR_16; break; default: report(REPORT_ERROR, "unsupported voc precision `%d'\n", s->input_precision); return -1; } } #ifdef HAVE_GSM /* gsm */ else if (((*buf >> 4) & 0xf) == GSM_MAGIC) { s->offset = 0; s->format = RPLAY_FORMAT_GSM; s->byte_order = RPLAY_BIG_ENDIAN; /* ??? */ s->sample_rate = 8000; s->input_precision = 1.65; s->output_precision = 16; s->channels = 1; } #endif /* HAVE_GSM */ #ifdef HAVE_CDROM else if (strcmp(buf, "CDROM") == 0) { s->offset = 0; s->format = RPLAY_FORMAT_LINEAR_16; s->byte_order = RPLAY_LITTLE_ENDIAN; s->sample_rate = 44100; s->input_precision = 16; s->output_precision = 16; s->channels = 2; s->storage = SOUND_STORAGE_NONE; } #endif /* HAVE_CDROM */ /* Unknown audio header -- try to use the extension. */ else { char *p; report(REPORT_DEBUG, "%s missing sound header; trying helper or extension\n", s->path); p = strrchr(s->path, '.'); #ifdef HAVE_HELPERS if (s->needs_helper) { s->offset = 0; s->format = helper->format; s->byte_order = helper->byte_order; s->sample_rate = helper->sample_rate; s->input_precision = helper->precision; s->output_precision = helper->precision; s->channels = helper->channels; s->storage = SOUND_STORAGE_NONE; } else #endif if (p && strcmp(p, ".ub") == 0) { report(REPORT_DEBUG, "%s assuming ub\n", s->path); s->offset = 0; s->format = RPLAY_FORMAT_ULINEAR_8; s->byte_order = RPLAY_BIG_ENDIAN; s->sample_rate = 11025; s->input_precision = 8; s->output_precision = 8; s->channels = 1; } else if (p && (strcmp(p, ".au") == 0 || strcmp(p, ".ul") == 0)) { report(REPORT_DEBUG, "%s assuming ulaw\n", s->path); s->offset = 0; s->format = RPLAY_FORMAT_ULAW; s->byte_order = RPLAY_BIG_ENDIAN; s->sample_rate = 8000; s->input_precision = 8; s->output_precision = 8; s->channels = 1; } #ifdef HAVE_GSM else if (p && (strcmp(p, ".gsm") == 0 || strcmp(p, ".GSM") == 0)) { report(REPORT_DEBUG, "%s assuming gsm\n", s->path); s->offset = 0; s->format = RPLAY_FORMAT_GSM; s->byte_order = RPLAY_BIG_ENDIAN; /* ??? */ s->sample_rate = 8000; s->input_precision = 1.65; s->output_precision = 16; s->channels = 1; } #endif /* HAVE_GSM */ else if (!optional_format && !optional_byte_order && !optional_sample_rate && !optional_input_precision && !optional_channels) { report(REPORT_ERROR, "`%s' unknown audio file\n", s->path); return -1; } } if (optional_offset) s->offset = optional_offset; if (optional_format) s->format = optional_format; if (optional_byte_order) s->byte_order = optional_byte_order; if (optional_sample_rate) s->sample_rate = optional_sample_rate; if (optional_input_precision) s->input_precision = optional_input_precision; if (optional_output_precision) s->output_precision = optional_output_precision; if (optional_channels) s->channels = optional_channels; if (optional_storage) s->storage = optional_storage; switch (s->format) { #ifdef HAVE_ADPCM /* G.72X files *must* have 16-bit output. */ case RPLAY_FORMAT_G721: case RPLAY_FORMAT_G723_3: case RPLAY_FORMAT_G723_5: s->output_precision = 16; break; #endif /* HAVE_ADPCM */ #ifdef HAVE_GSM /* Fix-up GSM info. */ case RPLAY_FORMAT_GSM: s->output_precision = 16; s->input_precision = 1.65; s->byte_order = RPLAY_BIG_ENDIAN; s->channels = 1; s->offset = 0; break; #endif /* HAVE_GSM */ default: break; } if (!s->format || !s->byte_order || !s->sample_rate || !s->input_precision || !s->output_precision || !s->channels) { report(REPORT_ERROR, "`%s' invalid audio parameters\n", s->path); return -1; } /* The input sample size is a floating point number since compressed samples can be smaller than 8 bits. */ /* XXX output_precision -> input_precision */ s->input_sample_size = (s->input_precision / 8) * s->channels; s->output_sample_size = (s->output_precision >> 3) * s->channels; if (sound_chunk_size > 0) { /* Make sure sound_chunk_size is valid */ if (s->size == 0 || sound_chunk_size < s->size) /* size==0 for flows */ { s->chunk_size = sound_chunk_size; } } /* Calculate tail only if chunk_size is in sound header */ if (s->chunk_size) { s->tail = s->offset + s->chunk_size; } /* Calculate chunk_size */ if (!s->chunk_size && s->size) { s->chunk_size = s->size - s->offset; } #if 0 printf("SOUND: %s size=%d chunk=%d tail=%d offset=%d\n", s->name, s->size, s->chunk_size, s->tail, s->offset); #endif if (s->type != SOUND_FILE) { s->size = 0; s->samples = 0; } #ifdef HAVE_HELPERS /* helper sounds should never have size and samples set */ else if (s->needs_helper) { s->size = 0; s->samples = 0; } #endif else { s->samples = number_of_samples(s, 0); // NUMBER_OF_SAMPLES (s); } s->mapped = 1; report(REPORT_DEBUG, "\ %s input=%s bits=%g sample-rate=%d channels=%d samples=%d format=%s byte-order=%s\n", s->name, input_to_string(s->type), s->input_precision, s->sample_rate, s->channels, s->samples, audio_format_to_string(s->format), byte_order_to_string(s->byte_order)); return 0; } /* * unmap a sound -- forget about it */ #ifdef __STDC__ int sound_unmap(SOUND *s) #else int sound_unmap(s) SOUND *s; #endif { if (s->type == SOUND_FILE) { if (s->cache) { #ifdef HAVE_MMAP munmap(s->cache, s->size); #else /* not HAVE_MMAP */ free((char *) s->cache); #endif /* not HAVE_MMAP */ s->cache = NULL; sound_cache_size -= s->size; } } if (s->type == SOUND_FLOW || s->needs_helper) { buffer_dealloc(s->flow, 1); s->flow = NULL; s->flowp = &s->flow; } s->mapped = 0; return 0; } /* Free *all* memory used by a sound. */ #ifdef __STDC__ int sound_free(SOUND *s) #else int sound_free(s) SOUND *s; #endif { sound_unmap(s); free((char *) s->path); s->path = NULL; free((char *) s->hash_key); s->hash_key = NULL; return 0; } /* Delete a sound from the list of sounds. */ #ifdef __STDC__ void sound_delete(SOUND *s, int remove) #else void sound_delete(s, remove) SOUND *s; int remove; #endif { /* No other sounds with the same hash key. This is the general case. */ if (s->next == NULL && s->prev == NULL) { if (s->hash_key) { xhash_delete(s->hash_key); } if (s->list_prev) { s->list_prev->list = s->list; } else { sounds = s->list; } if (s->list) { s->list->list_prev = s->list_prev; } } /* Sounds with same hash key. */ else { /* not the first node */ if (s->prev) { s->prev->next = s->next; if (s->next) { s->next->prev = s->prev; } } /* the first node with a next node */ else { if (s->list_prev) { s->list_prev->list = s->next; } else { sounds = s->next; } if (s->list) { s->list->list_prev = s->next; } /* Copy the list links. */ s->next->list = s->list; s->next->list_prev = s->list_prev; xhash_replace(s->next->hash_key, (char *) s->next); } } if (remove) { struct stat st; if (stat(s->path, &st) == 0) { if (unlink(s->path) < 0) { report(REPORT_ERROR, "sound_delete: unlink %s: %s\n", s->path, sys_err_str(errno)); } } } sound_free(s); free((char *) s); } /* * Free cached sounds and delete sound flows. */ void sound_cleanup() { SOUND *s1, *s1_next, *s, *s_next; EVENT *e; CONNECTION *c; SPOOL *sp; int n; report(REPORT_DEBUG, "cleaning up sounds\n"); for (s1 = sounds; s1; s1 = s1_next) { s1_next = s1->list; for (s = s1; s; s = s_next) { s_next = s->next; /* Cached sounds */ if (s->type == SOUND_FILE && s->status == SOUND_READY && s->cache) { n = 0; for (c = connections; c && n == 0; c = c->next) { /* Don't clean sounds with events. */ for (e = c->event; e && n == 0; e = e->next) { switch (e->type) { case EVENT_WRITE_FIND: case EVENT_READ_FIND_REPLY: case EVENT_WRITE_GET: case EVENT_READ_GET_REPLY: case EVENT_READ_SOUND: case EVENT_WRITE_SOUND: if (e->sound == s) { n++; } break; } } /* Don't clean sounds in the spool. */ for (sp = spool; sp; sp = sp->next) { if (sp->sound[sp->curr_sound] == s) { n++; } } } if (n == 0) { sound_unmap(s); } } /* Flows */ else if (s->type == SOUND_FLOW) { /* Don't cleanup flows in the spool. */ n = 0; for (sp = spool; sp; sp = sp->next) { if (sp->sound[sp->curr_sound] == s) { n++; } } if (n != 0) { report(REPORT_DEBUG, "sound_clean: not cleaning flow `%s'\n", s->name); } else { sound_clean(s); } } #ifdef HAVE_CDROM else if (s->type == SOUND_CDROM) { n = 0; for (sp = spool; sp; sp = sp->next) { if (sp->sound[sp->curr_sound] == s) { n++; } } if (n != 0) { report(REPORT_DEBUG, "sound_clean: not cleaning cdrom `%s'\n", s->name); } else { sound_clean(s); } } #endif /* HAVE_CDROM */ } } sound_cache_size = 0; } #ifdef __STDC__ void sound_clean(SOUND *s) #else void sound_clean(s) SOUND *s; #endif { BUFFER *b; int n, fd; #ifdef HAVE_HELPERS if (s->needs_helper) { s->samples = 0; s->offset = 0; s->size = 0; if (s->flow) { buffer_dealloc(s->flow, 1); } s->flow = NULL; s->flowp = &s->flow; return; } #endif /* HAVE_HELPERS */ if (s->type == SOUND_FILE) { return; } #ifdef HAVE_CDROM else if (s->type == SOUND_CDROM) { s->samples = 0; s->offset = 0; s->size = 0; if (s->flow) { buffer_dealloc(s->flow, 1); } s->flow = NULL; s->flowp = &s->flow; return; } #endif /* HAVE_CDROM */ switch (s->storage) { case SOUND_STORAGE_NONE: /* nothing to free -- delete it */ report(REPORT_DEBUG, "sound_clean: deleting flow `%s'\n", s->name); sound_delete(s, 0); break; case SOUND_STORAGE_MEMORY: /* keep it in memory? */ report(REPORT_DEBUG, "sound_clean: keeping flow `%s' in memory\n", s->name); break; case SOUND_STORAGE_DISK: /* Save the flow in the disk cache. */ if (cache_free(s->size) < 0) { report(REPORT_ERROR, "sound_clean: can't cache_free %d bytes\n", s->size); sound_delete(s, 0); /* delete it */ break; } fd = cache_create(s->path, s->size); if (fd < 0) { report(REPORT_ERROR, "sound_clean: can't cache_create %d bytes\n", s->size); sound_delete(s, 0); break; } /* Dump the flow buffers to disk. */ report(REPORT_DEBUG, "sound_clean: storing %s\n", s->path); for (b = s->flow; b; b = b->next) { retry: n = write(fd, b->buf, b->nbytes); if (n < 0) { if (errno == EINTR || errno == EINTR) { goto retry; } else { report(REPORT_ERROR, "sound_clean: write: %s\n", sys_err_str(errno)); sound_delete(s, 1); s = NULL; break; } } } close(fd); if (s) { /* The flow is now a file. */ sound_unmap(s); s->type = SOUND_FILE; } break; } } #ifdef __STDC__ SINDEX * sound_open(SOUND *s, int use_helper) #else SINDEX * sound_open(s, use_helper) SOUND *s; int use_helper; #endif { SINDEX *si; int n; si = (SINDEX *) malloc(sizeof(SINDEX)); if (si == NULL) { return NULL; } si->sound = s; si->offset = 0; si->is_cached = 0; si->eof = 0; si->fd = 0; si->skip = 0; si->buffer_offset = 0; si->is_flow = 0; si->flowp = NULL; si->water_mark = 0; si->low_water_mark = 0; si->high_water_mark = 0; #if defined (HAVE_CDROM) || defined (HAVE_HELPERS) si->pid = -1; #endif switch (s->format) { #ifdef HAVE_ADPCM case RPLAY_FORMAT_G721: case RPLAY_FORMAT_G723_3: case RPLAY_FORMAT_G723_5: g72x_init_state(&si->adpcm_state[0]); g72x_init_state(&si->adpcm_state[1]); si->adpcm_in_buffer = 0; si->adpcm_in_bits = 0; break; #endif /* HAVE_ADPCM */ #ifdef HAVE_GSM case RPLAY_FORMAT_GSM: si->gsm_object = gsm_create(); si->gsm_bit_frame_bytes = 0; si->gsm_fixed_buffer_size = 0; break; #endif /* HAVE_GSM */ default: break; } #ifdef HAVE_HELPERS if (use_helper && s->needs_helper) { int fds[2]; HELPER *helper; helper = helper_lookup(s->path); if (!helper) { report(REPORT_ERROR, "%s helper not found\n", s->path); done(1); } si->is_flow = 1; si->flowp = &s->flow; if (pipe(fds) < 0) { report(REPORT_ERROR, "helper pipe: %s\n", sys_err_str(errno)); sound_close(si); return NULL; } si->pid = fork(); if (si->pid < 0) { report(REPORT_ERROR, "helper fork: %s\n", sys_err_str(errno)); sound_close(si); return NULL; } if (si->pid == 0) /* child */ { int first; char *argv[64]; /* XXX */ int argc = 0; char buf[MAXPATHLEN], *p; int input_fd = -1; if (s->type == SOUND_FILE) { input_fd = open(s->path, O_RDONLY /* | O_NDELAY */ , 0); if (input_fd < 0) { report(REPORT_ERROR, "can't open %s: %s\n", s->path, sys_err_str(errno)); exit(1); } } else if (s->type == SOUND_FLOW) { CONNECTION *c; EVENT *e; for (c = connections; c && input_fd == -1; c = c->next) { for (e = c->event; e; e = e->next) { if (e->type == EVENT_PIPE_FLOW && e->sound == s) { input_fd = c->fd; fd_block(input_fd); break; } } } } if (input_fd == -1) { report(REPORT_ERROR, "No input for helper, type=%d.\n", s->type); exit(1); } first = 1; while (p = (char *) strtok(first ? helper->program : NULL, " \t\n")) { first = 0; argv[argc++] = p; } argv[argc] = NULL; close(fds[0]); if (input_fd != -1) { if (dup2(input_fd, 0) != 0) /* input for the helper */ { report(REPORT_ERROR, "can't dup2 stdin: %s\n", sys_err_str(errno)); exit(1); } } if (dup2(fds[1], 1) != 1) /* output for rplayd */ { report(REPORT_ERROR, "can't dup2 stdout: %s\n", sys_err_str(errno)); exit(1); } execv(argv[0], argv); report(REPORT_ERROR, "can't execute %s: %s\n", argv[0], sys_err_str(errno)); exit(1); } report(REPORT_DEBUG, "forked helper process %d\n", si->pid); close(fds[1]); si->fd = fds[0]; FD_SET(si->fd, &read_mask); } #else if (0) { /* hack */ } #endif /* HAVE_HELPERS */ else if (s->type == SOUND_FILE) { if (!s->cache) { struct stat st; si->fd = open(s->path, O_RDONLY | O_NDELAY, 0); if (si->fd < 0) { report(REPORT_DEBUG, "sound_open: open %s: %s\n", s->path, sys_err_str(errno)); sound_close(si); return NULL; } fd_nonblock(si->fd); if (!s->mapped || (s->mapped && !s->size)) { if (fstat(si->fd, &st) < 0) { report(REPORT_ERROR, "sound_open: fstat %s: %s\n", s->path, sys_err_str(errno)); sound_close(si); return NULL; } if (S_ISDIR(st.st_mode)) { report(REPORT_ERROR, "sound_open: %s is a directory\n", s->path); sound_close(si); return NULL; } s->size = (int) st.st_size; /* See if the entire sound can be cached. */ if (sound_cache_max_size && !helper_lookup(s->path) && (sound_cache_max_sound_size == 0 || (s->size <= sound_cache_max_sound_size)) && (sound_cache_size + s->size <= sound_cache_max_size)) { /* Use mmap to load the entire sound. */ #ifdef HAVE_MMAP #ifndef MAP_FILE #define MAP_FILE 0 #endif s->cache = mmap(0, s->size, PROT_READ, MAP_SHARED | MAP_FILE, si->fd, 0); if (s->cache == (caddr_t) - 1) { report(REPORT_ERROR, "sound_open: %s size=%d mmap: %s\n", s->path, s->size, sys_err_str(errno)); sound_close(si); return NULL; } #else /* not HAVE_MMAP */ /* Use malloc+read to load the entire sound. */ s->cache = (char *) malloc(s->size); if (s->cache == NULL) { report(REPORT_ERROR, "sound_open: %s size=%d malloc: %s\n", s->path, s->size, sys_err_str(errno)); sound_close(si); return NULL; } again: n = read(si->fd, s->cache, s->size); if (n < 0 && (errno == EINTR || errno == EAGAIN)) { goto again; } if (n != s->size) { report(REPORT_ERROR, "sound_open: read %s %d: %s\n", s->path, s->size, sys_err_str(errno)); free((char *) s->cache); s->cache = NULL; sound_close(si); return NULL; } #endif /* not HAVE_MMAP */ sound_cache_size += s->size; #if 0 report(REPORT_DEBUG, "- cached %s %d, cache_size=%d\n", s->path, s->size, sound_cache_size); #endif /* Cached sounds won't need the file descriptor. */ close(si->fd); si->fd = 0; } } } if (s->cache) { si->is_cached = 1; } else { si->is_cached = 0; } } else if (s->type == SOUND_FLOW) { si->is_flow = 1; si->flowp = &s->flow; } #ifdef HAVE_CDROM /* Fork the reader process and treat it like a flow, reading audio data from the pipe. */ else if (s->type == SOUND_CDROM) { int fds[2]; si->is_flow = 1; si->flowp = &s->flow; if (pipe(fds) < 0) { report(REPORT_ERROR, "cdrom pipe: %s\n", sys_err_str(errno)); sound_close(si); return NULL; } si->pid = fork(); if (si->pid < 0) { report(REPORT_ERROR, "cdrom fork: %s\n", sys_err_str(errno)); sound_close(si); return NULL; } if (si->pid == 0) /* child */ { int i; close(fds[0]); #ifdef HAVE_SIGSET sigset(SIGHUP, SIG_DFL); sigset(SIGINT, SIG_DFL); sigset(SIGCHLD, SIG_DFL); #else signal(SIGHUP, SIG_DFL); signal(SIGINT, SIG_DFL); signal(SIGCHLD, SIG_DFL); #endif for (i = 0; i < MAX_CDROMS; i++) { if (strcmp(cdrom_table[i].name, si->sound->name) == 0) { cdrom_reader(i, si->sound->starting_track, si->sound->ending_track, fds[1]); exit(0); } } report(REPORT_DEBUG, "cdrom `%s' not found\n", si->sound->name); exit(1); } report(REPORT_DEBUG, "forked cdrom process %d\n", si->pid); close(fds[1]); si->fd = fds[0]; FD_SET(si->fd, &read_mask); } #endif /* HAVE_CDROM */ return si; } #ifdef __STDC__ int sound_close(SINDEX *si) #else int sound_close(si) SINDEX *si; #endif { #ifdef HAVE_HELPERS if (si->sound->needs_helper) { if (si->pid != -1) { report(REPORT_DEBUG, "killing helper process %d\n", si->pid); if (kill(si->pid, SIGKILL) < 0) { report(REPORT_DEBUG, "kill %d: %s\n", si->pid, sys_err_str(errno)); } } if (si->fd != 0) { FD_CLR(si->fd, &read_mask); close(si->fd); } if (si->sound->type == SOUND_FLOW) { CONNECTION *c, *c_next; EVENT *e; for (c = connections; c; c = c_next) { c_next = c->next; for (e = c->event; e; e = e->next) { if (e->type == EVENT_PIPE_FLOW && e->sound == si->sound) { connection_close(c); break; } } } } } #endif /* HAVE_HELPERS */ if (si->sound->type == SOUND_FILE) { if (!si->is_cached) { close(si->fd); } } #ifdef HAVE_CDROM else if (si->sound->type == SOUND_CDROM) { if (si->pid != -1) { report(REPORT_DEBUG, "killing cdrom process %d\n", si->pid); if (kill(si->pid, SIGKILL) < 0) { report(REPORT_DEBUG, "kill %d: %s\n", si->pid, sys_err_str(errno)); } } if (si->fd != 0) { FD_CLR(si->fd, &read_mask); close(si->fd); } } #endif /* HAVE_CDROM */ switch (si->sound->format) { #ifdef HAVE_GSM case RPLAY_FORMAT_GSM: gsm_destroy(si->gsm_object); break; #endif /* HAVE_GSM */ default: break; } free((char *) si); return 0; } #ifdef HAVE_ADPCM /* This routine is based on the unpack_input routine from Sun's CCITT ADPCM decoder. */ static int adpcm_unpack(si, b, code, bits) SINDEX *si; BUFFER *b; unsigned char *code; int bits; { unsigned char in_byte; if (si->adpcm_in_bits < bits) { if (b->offset >= b->nbytes) { *code = 0; return -1; } in_byte = b->buf[b->offset++]; si->adpcm_in_buffer |= (in_byte << si->adpcm_in_bits); si->adpcm_in_bits += 8; } *code = si->adpcm_in_buffer & ((1 << bits) - 1); si->adpcm_in_buffer >>= bits; si->adpcm_in_bits -= bits; return si->adpcm_in_bits > 0; } /* Uncompress the `data' buffers into 16-bit linear data. */ static void adpcm_decode(si, data, decode_routine, decode_bits) SINDEX *si; BUFFER *data; int (*decode_routine) (); int decode_bits; { BUFFER *b = buffer_create(); short *ptr; unsigned char code; int channel = 0; for (; data && data->nbytes; data = data->next) { memcpy(b->buf, data->buf, data->nbytes); b->nbytes = data->nbytes; b->offset = 0; ptr = (short *) data->buf; data->nbytes = 0; while (adpcm_unpack(si, b, &code, decode_bits) >= 0) { *ptr++ = (*decode_routine) (code, AUDIO_ENCODING_LINEAR, &si->adpcm_state[channel]); if (si->sound->channels == 2) { channel ^= 1; } data->nbytes += 2; /* 16-bit */ } #if 1 report(REPORT_DEBUG, "adpcm_decode: uncompressed from %d to %d bytes\n", b->nbytes, data->nbytes); #endif } buffer_destroy(b); } #endif /* HAVE_ADPCM */ #ifdef HAVE_GSM /* Uncompress the `data' buffers into 16-bit linear data. */ static void gsm_uncompress(si, data) SINDEX *si; BUFFER *data; { BUFFER *b = buffer_create(); gsm_signal sample[160]; int nbytes; for (; data; data = data->next) { memcpy(b->buf, data->buf, data->nbytes); b->nbytes = data->nbytes; b->offset = 0; data->nbytes = 0; do { nbytes = MIN(b->nbytes - b->offset, sizeof(si->gsm_bit_frame) - si->gsm_bit_frame_bytes); memcpy(si->gsm_bit_frame, b->buf + b->offset, nbytes); b->offset += nbytes; si->gsm_bit_frame_bytes += nbytes; if (si->gsm_bit_frame_bytes == sizeof(si->gsm_bit_frame)) /* Only decode complete frames */ { gsm_decode(si->gsm_object, si->gsm_bit_frame, sample); memcpy(data->buf + data->nbytes, (char *) sample, sizeof(sample)); data->nbytes += sizeof(sample); si->gsm_bit_frame_bytes = 0; } #if 0 printf("b->offset=%d data->nbytes=%d gsm_bit_frame_bytes=%d\n", b->offset, data->nbytes, si->gsm_bit_frame_bytes); #endif } while (b->offset < b->nbytes); #if 1 report(REPORT_DEBUG, "gsm_uncompress: uncompressed from %d to %d bytes\n", b->nbytes, data->nbytes); #endif } buffer_destroy(b); } #endif /* HAVE_GSM */ #ifdef __STDC__ int sound_fill(SINDEX *si, BUFFER *data, int as_is) #else int sound_fill(si, data, as_is) SINDEX *si; BUFFER *data; int as_is; #endif { static struct iovec iov[UIO_MAXIOV]; int i, n; int total = 0; /* The total number of bytes filled. */ BUFFER *b; float bit_factor; int max_per_buffer; if (si->eof && !si->is_flow) { return 0; } if (si->sound->mapped) { /* ADPCM compression expands from 3/4/5 bit input to 16 bit output. */ bit_factor = ((float) si->sound->input_precision / si->sound->output_precision); } else { bit_factor = 1.0; } max_per_buffer = BUFFER_SIZE * bit_factor; /* Force the buffer size to be a multiple of the GSM bit frame size. */ if (si->sound->format == RPLAY_FORMAT_GSM) { if (si->gsm_fixed_buffer_size == 0) { si->gsm_fixed_buffer_size = max_per_buffer; while (si->gsm_fixed_buffer_size % sizeof(si->gsm_bit_frame)) { si->gsm_fixed_buffer_size--; } } max_per_buffer = si->gsm_fixed_buffer_size; } /* Read from a flow. */ if (si->is_flow) { BUFFER *f, *f_next; if (!si->flowp) { return 0; } if (!si->high_water_mark) { #ifdef HAVE_CDROM if (si->sound->type == SOUND_CDROM) { SOUND *s = si->sound; si->low_water_mark = (s->sample_rate * s->input_sample_size) / 2; si->high_water_mark = s->sample_rate * s->input_sample_size; } #endif #ifdef HAVE_HELPERS if (!si->high_water_mark && si->sound->needs_helper) { SOUND *s = si->sound; si->low_water_mark = (s->sample_rate * s->input_sample_size) / 4; si->high_water_mark = (s->sample_rate * s->input_sample_size) / 2; } #endif if (!si->high_water_mark) { #if 1 /* XXX test */ SOUND *s = si->sound; si->low_water_mark = (s->sample_rate * s->input_sample_size) / 4; si->high_water_mark = (s->sample_rate * s->input_sample_size) / 2; #else si->low_water_mark = LOW_WATER_MARK(si->sound); si->high_water_mark = HIGH_WATER_MARK(si->sound); #endif } } f = *si->flowp; for (b = data; b && f; b = b->next) { while (f && b->nbytes < max_per_buffer) { /* Calculate the total number of bytes available. */ n = f->nbytes - si->buffer_offset - si->skip; if (n < 0) { si->buffer_offset += si->skip; si->skip -= f->nbytes; } else { /* Calculate the number of bytes needed. */ i = MIN(n, max_per_buffer - b->nbytes); memcpy(b->buf + b->nbytes, f->buf + si->buffer_offset + si->skip, i); si->skip = 0; b->nbytes += i; total += i; si->offset += i; si->buffer_offset += i; } /* See if a new flow buffer is needed. */ if (si->buffer_offset >= f->nbytes) { BUFFER *f_next = f->next; si->buffer_offset = 0; si->flowp = &f->next; /* Free the buffer. */ if (si->sound->storage == SOUND_STORAGE_NONE || si->sound->storage == SOUND_STORAGE_NULL) { buffer_destroy(f); } f = f_next; } } } /* Update the flow pointers if the sound is not being stored. */ if (si->sound->storage == SOUND_STORAGE_NONE || si->sound->storage == SOUND_STORAGE_NULL) { si->sound->flow = f; if (!f) { si->sound->flowp = &si->sound->flow; } si->flowp = &si->sound->flow; } if (si->sound->tail && si->offset >= si->sound->tail) { si->eof = 1; } } /* Read from the cache. */ else if (si->is_cached) { n = si->sound->size - si->offset; for (b = data; b; b = b->next) { i = MIN(n, max_per_buffer); if (i > 0) { #ifdef DEBUG report(REPORT_DEBUG, "- cache-read %s %d\n", si->sound->name, i); #endif memcpy(b->buf, si->sound->cache + si->offset, i); b->nbytes = i; si->offset += i; n -= i; total += i; } else { b->nbytes = 0; n -= i; } } if (si->offset >= si->sound->size) { si->eof = 1; } } /* Read from disk. */ else { for (b = data, i = 0; b && i < UIO_MAXIOV; b = b->next, i++) { iov[i].iov_base = b->buf; iov[i].iov_len = max_per_buffer; } n = readv(si->fd, iov, i); if (n < 0) { report(REPORT_ERROR, "sound_fill: readv: %s, fd=%d, %s\n", si->sound->name, si->fd, sys_err_str(errno)); return -1; } else if (n == 0) { si->eof = 1; return 0; } else { si->offset += n; for (b = data, i = n; b; b = b->next, i -= max_per_buffer) { if (i < 0) { i = 0; } b->nbytes = MIN(i, max_per_buffer); } total = n; } } /* uncompress/decode */ if (total && si->sound->mapped && !as_is) { switch (si->sound->format) { #ifdef HAVE_ADPCM case RPLAY_FORMAT_G721: adpcm_decode(si, data, g721_decoder, 4); break; case RPLAY_FORMAT_G723_3: adpcm_decode(si, data, g723_24_decoder, 3); break; case RPLAY_FORMAT_G723_5: adpcm_decode(si, data, g723_40_decoder, 5); break; #endif /* HAVE_ADPCM */ #ifdef HAVE_GSM case RPLAY_FORMAT_GSM: gsm_uncompress(si, data); break; #endif /* HAVE_GSM */ } } return total; } #ifdef __STDC__ int sound_seek(SINDEX *si, int offset, int whence) #else int sound_seek(si, offset, whence) SINDEX *si; int offset; int whence; #endif { if (si->is_flow) { si->skip += offset; /* XXX: whence is ignored */ return 0; } else if (si->is_cached) { si->offset += offset; /* XXX: whence is ignored */ return 0; } #ifdef HAVE_CDROM else if (si->sound->type == SOUND_CDROM) { return 0; } #endif /* HAVE_CDROM */ #ifdef HAVE_HELPERS else if (si->sound->needs_helper) { return 0; } #endif /* HAVE_HELPERS */ else { return lseek(si->fd, offset, whence); } } #if defined(HAVE_CDROM) || defined (HAVE_HELPERS) /* Read data from the pipe and return the data in a buffer list. */ #ifdef __STDC__ BUFFER * sound_pipe_read(SINDEX *si) #else BUFFER * sound_pipe_read(si) SINDEX *si; #endif { static struct iovec iov[UIO_MAXIOV]; int i, n, nbytes; BUFFER *b; BUFFER *data; /* Pause */ if (si->water_mark - si->offset > si->high_water_mark) { FD_CLR(si->fd, &read_mask); return NULL; } /* Determine the number of bytes available in the pipe. */ #if defined (sun) && defined (SVR4) /* Solaris 2.x */ { struct stat st; if (fstat(si->fd, &st) < 0) { report(REPORT_DEBUG, "sound_pipe_read: fstat: %s\n", sys_err_str(errno)); return NULL; } nbytes = st.st_size; } #else /* not Solaris */ #if 0 /* disable FIONREAD for now */ #ifdef FIONREAD if (ioctl(si->fd, FIONREAD, &nbytes) < 0) { report(REPORT_DEBUG, "sound_pipe_read: ioctl FIONREAD: %s\n", sys_err_str(errno)); return NULL; } #endif /* not FIONREAD */ #endif /* guess */ nbytes = (si->sound->sample_rate * si->sound->input_sample_size) / 2; #endif /* not Solaris */ data = buffer_alloc(nbytes, BUFFER_FREE); for (b = data, i = 0; b && i < UIO_MAXIOV; b = b->next, i++) { iov[i].iov_base = b->buf; iov[i].iov_len = BUFFER_SIZE; } n = readv(si->fd, iov, i); if (n <= 0) { buffer_dealloc(data, 1); spool_remove(si->sound); /* XXX */ return NULL; } for (b = data, i = n; b; b = b->next, i -= BUFFER_SIZE) { if (i < 0) { i = 0; } b->nbytes = MIN(i, BUFFER_SIZE); } return data; } #endif #ifdef __STDC__ static int bytes_in_sound(SOUND *s) #else static int bytes_in_sound(s) SOUND *s; #endif { int bytes = 0; if (s->chunk_size) { bytes = s->chunk_size; } else if (s->tail) { bytes = s->tail - s->offset; } else if (s->size) { bytes = s->size - s->offset; } return bytes; } #ifdef __STDC__ int number_of_samples(SOUND *s, int bytes) #else int number_of_samples(s, bytes) SOUND *s; int bytes; #endif { if (!bytes) { bytes = bytes_in_sound(s); } return (bytes << 3) / (s->input_precision * s->channels); } rplay-3.3.2/rplayd/sound.h100644 153 62 17436 6727404540 14154 0ustar boynsstaff/* $Id: sound.h,v 1.4 1999/06/09 06:27:44 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _sound_h #define _sound_h #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "buffer.h" #include "rplay.h" #include "server.h" #include #include #ifdef HAVE_ADPCM #include "g72x.h" #endif /* HAVE_ADPCM */ #ifdef HAVE_GSM #ifdef HAVE_GSM_GSM_H #include #else #ifdef HAVE_GSM_H #include #else #include "gsm.h" #endif #endif #endif /* HAVE_GSM */ #undef NUMBER_OF_SAMPLES #define NUMBER_OF_SAMPLES(s) (((s->tail ? (s->tail - s->offset) : (s->size - s->offset)) << 3) / (s->input_precision * s->channels)) #undef HIGH_WATER_MARK #define HIGH_WATER_MARK(s) (s->sample_rate * s->input_sample_size * 2) /* 2 seconds */ #undef LOW_WATER_MARK #define LOW_WATER_MARK(s) (s->sample_rate * s->input_sample_size * 1) /* 1 seconds */ #define SOUND_LIST_SIZE 256 /* maximum size of a sound list */ /* * Sound types */ #define SOUND_FILE 1 /* A sound file. */ #define SOUND_FLOW 2 /* A sound flow. */ #ifdef HAVE_CDROM #define SOUND_CDROM 3 /* Sound is on a CDROM. */ #endif /* HAVE_CDROM */ #define SOUND_VIRTUAL 4 /* Virtual sound */ /* * Sound storage methods */ #define SOUND_STORAGE_NULL 0 #define SOUND_STORAGE_NONE 1 /* Input is discarded. */ #define SOUND_STORAGE_DISK 2 /* Input is stored on disk. */ #define SOUND_STORAGE_MEMORY 3 /* Input is stored in memory. */ /* * sound status values */ #define SOUND_NULL 0 #define SOUND_READY 1 /* sound is ready to be played */ #define SOUND_NOT_READY 2 /* sound is being transferred */ #define SOUND_SEARCH 3 /* sound is being searched for */ /* * sound lookup modes */ #define SOUND_FIND 1 #define SOUND_DONT_FIND 2 #define SOUND_DONT_COUNT 3 #define SOUND_LOAD 4 #define SOUND_CREATE 5 /* * Maximum size of an audio file header. */ #define SOUND_MAX_HEADER_SIZE 1024 /* * Maximum piece of a sound that can be read by sound_fill (). */ #define SOUND_FILL_SIZE (UIO_MAXIOV * BUFFER_SIZE) typedef struct _sound { struct _sound *list; /* next pointer for entire sound list */ struct _sound *list_prev; /* prev pointer for entire sound list */ struct _sound *next; /* list for sounds with the same hash key */ struct _sound *prev; /* prev pointer for the next list */ int type; /* type of sound */ int storage; /* storage method */ char *name; /* name of the sound */ char *hash_key; /* sound's hash key */ char *path; /* complete path of the sound */ int count; /* relative sound count, use for caching */ int status; /* status of the sound */ int format; /* format of the audio data - RPLAY_FORMAT_* */ int byte_order; /* big endian or little endian */ int sample_rate; /* audio sample rate */ float input_precision; /* bits per sample in the audio file */ int output_precision; /* bits per sample that are output */ int channels; /* number of channels */ int samples; /* number of samples */ float input_sample_size; /* size of one input sample = bits/sample * channels */ int output_sample_size; /* size of one output sample = bits/sample * channels */ int offset; /* audio data offset in the file */ int size; /* total size of the sound file */ int tail; /* audio offset from the end of the file */ int chunk_size; /* size of audio data */ int mapped; /* sound info is known */ char *cache; /* audio data cache */ BUFFER *flow; /* list of flow data */ BUFFER **flowp; /* where the next flow data will be put */ #ifdef HAVE_CDROM int starting_track; /* CD start track */ int ending_track; /* CD end track */ #endif /* HAVE_CDROM */ #ifdef HAVE_HELPERS int needs_helper; #endif /* HAVE_HELPERS */ } SOUND; typedef struct _sindex { SOUND *sound; /* the sound being referenced */ int offset; /* current position */ int is_cached; /* is the sound cached? */ int fd; /* file descriptor used when sound isn't cached */ int eof; /* the end has been reached */ int skip; int buffer_offset; /* offset in a shared BUFFER */ int is_flow; /* is this sound a flow? */ BUFFER **flowp; /* pointer to a sound's flow */ int water_mark; int low_water_mark; int high_water_mark; #ifdef HAVE_ADPCM struct g72x_state adpcm_state[2]; /* state used in adpcm_decode */ unsigned int adpcm_in_buffer; /* state variable used adpcm_unpack */ int adpcm_in_bits; /* state variable used adpcm_unpack */ #endif /* HAVE_ADPCM */ #ifdef HAVE_GSM gsm gsm_object; /* GSM state object */ gsm_frame gsm_bit_frame; /* GSM bit buffer - 33 bytes */ int gsm_bit_frame_bytes; /* Number of bytes in gsm_bit_frame */ int gsm_fixed_buffer_size; #endif /* HAVE_GSM */ #ifdef HAVE_CDROM int pid; #endif /* HAVE_CDROM */ } SINDEX; /* The deadsnd header. */ typedef struct { long id; long freq; int bps; int mode; char title[80]; } DSID; extern SOUND *sounds; /* list of all sounds. */ extern int sound_count; /* sound reference count used in LRU caching */ extern int sound_cache_size; /* current size of the cache */ extern int sound_cache_max_sound_size; /* maximum size of a sound that can be cached */ extern int sound_cache_max_size; /* maximum size of cached sounds */ #ifdef __STDC__ extern void sound_read (char *filename); extern void sound_reread (char *filename); extern void sound_stat (char *filename); extern SOUND *sound_lookup (char *sound_name, int mode, SERVER *server); extern SOUND *sound_create (void); extern SOUND *sound_insert (char *, int, int); extern int sound_map (SOUND *s); extern int sound_unmap (SOUND *s); extern void sound_delete (SOUND *s, int remove); extern BUFFER *sound_list_create (); extern void sound_cleanup (); extern SINDEX *sound_open (SOUND *, int); extern int sound_close (SINDEX *); extern int sound_fill (SINDEX *, BUFFER *data, int as_is); extern int sound_seek (SINDEX *, int offset, int whence); extern void sound_clean (SOUND *s); extern int number_of_samples (SOUND *s, int bytes); #else extern void sound_read ( /* char *filename */ ); extern void sound_reread ( /* char *filename */ ); extern void sound_stat ( /* char *filename */ ); extern SOUND *sound_lookup ( /* char *sound_name, int mode, SERVER *server */ ); extern SOUND *sound_create (); extern SOUND *sound_insert ( /* char *, int, int */ ); extern int sound_map ( /* SOUND *s */ ); extern int sound_unmap ( /* SOUND *s */ ); extern void sound_delete ( /* SOUND *s, int remove */ ); extern BUFFER *sound_list_create (); extern void sound_cleanup (); extern SINDEX *sound_open ( /* SOUND *, int */ ); extern int sound_close ( /* SINDEX * */ ); extern int sound_fill ( /* SINDEX *, BUFFER *data, int as_is */ ); extern int sound_seek ( /* SINDEX *, int offset, int whence */ ); extern void sound_clean ( /* SOUND *s */ ); extern int number_of_samples ( /* SOUND *s, int bytes */ ); #endif #if defined(HAVE_CDROM) || defined(HAVE_HELPERS) #ifdef __STDC__ extern BUFFER *sound_pipe_read (SINDEX *si); #else extern BUFFER *sound_pipe_read (/* SINDEX *si */); #endif #endif #endif /* _sound_h */ rplay-3.3.2/rplayd/spool.c100644 153 62 63775 6671560276 14171 0ustar boynsstaff/* $Id: spool.c,v 1.6 1999/03/10 21:14:38 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #ifdef HAVE_STRING_H #include #endif #include #include "rplayd.h" #include "rplay.h" #include "spool.h" #include "sound.h" #include "buffer.h" #include "timer.h" #include "connection.h" #include "native.h" #ifdef TEST_FLANGE #include "flange.h" #endif SPOOL *spool = NULL; /* List of spool entries. */ int spool_size = 0; /* Number of entries in the spool. */ int spool_nplaying = 0; /* Number of playing sounds. */ int spool_npaused = 0; /* Number of paused sounds. */ int spool_prio = 0; /* Highest priority spool entry. */ int spool_needs_update = 0; /* Need to call spool_update(). */ /* * initialize the sound spool */ void spool_init() { SPOOL *sp, *sp_next; /* Destroy any existing spool entries (reset). */ for (sp = spool; sp; sp = sp_next) { sp_next = sp->next; spool_destroy(sp); } spool = NULL; spool_nplaying = 0; spool_prio = 0; spool_size = 0; } /* Create a new spool entry. */ SPOOL * spool_create() { SPOOL *sp = (SPOOL *) malloc(sizeof(SPOOL)); if (sp == NULL) { report(REPORT_ERROR, "spool_create: out of memory\n"); done(1); } /* `sp' must be initialized before being reset. */ memset((char *) sp, 0, sizeof(SPOOL)); sp->id = -1; /* XXX */ spool_reset(sp); /* Insert the new entry into the spool list. */ sp->next = spool; sp->prev = NULL; if (spool) { spool->prev = sp; } spool = sp; spool_size++; return sp; } /* Destroy the given spool entry. */ #ifdef __STDC__ void spool_destroy(SPOOL *sp) #else void spool_destroy(sp) SPOOL *sp; #endif { /* Reset `sp' in case any resources are allocated. */ spool_reset(sp); /* Remove `sp' from the spool list. */ if (sp->prev) { sp->prev->next = sp->next; } else { spool = sp->next; } if (sp->next) { sp->next->prev = sp->prev; } spool_size--; free((char *) sp); } /* * Return the next available spool entry. * * `priority' is the priority of a new sound and is used to replace * lower priority spool entries when the spool is full. */ #ifdef __STDC__ SPOOL * spool_next(int priority) #else SPOOL * spool_next(priority) int priority; #endif { int i; int min_priority = RPLAY_MAX_PRIORITY, index = -1; SPOOL *sp, *lowest = NULL; /* There's room for a new entry. */ if (spool_size < SPOOL_SIZE) { sp = spool_create(); sp->id = spool_id(); return sp; } /* The spool is full, try to replace an entry. */ /* Find the lowest priority sound. */ for (sp = spool; sp; sp = sp->next) { if (sp->state == SPOOL_PLAY) { if (sp->rp->priority < min_priority) { min_priority = sp->rp->priority; lowest = sp; } } } /* Replace the lowest priority sound, if possible. */ if (priority > min_priority && lowest) { sp = lowest; if (sp->notify_position) { connection_notify(0, NOTIFY_POSITION, sp); sp->notify_position = 0; } connection_notify(0, NOTIFY_DONE, sp); spool_reset(sp); spool_nplaying--; sp->id = spool_id(); return sp; } else { return NULL; } } /* Reset a spool entry to an initial state. `next' and `prev' are NOT changed. */ #ifdef __STDC__ void spool_reset(SPOOL *sp) #else void spool_reset(sp) SPOOL *sp; #endif { sp->state = SPOOL_NULL; if (sp->id > 0) { /* Wakeup any connections that may be waiting for this spool entry. Their flow data will be ignored. */ connection_flow_continue(sp); } sp->id = -1; sp->time = 0; if (sp->rp) { int i; for (i = 0; i < sp->rp->nsounds; i++) { sound_clean(sp->sound[i]); } rplay_destroy(sp->rp); } sp->rp = NULL; sp->ptr = NULL; sp->ptr_end = NULL; sp->sample_rate = 0; sp->sample_index = 0; sp->sample_factor = 0; sp->oversample[0] = 0; sp->oversample[1] = 0; sp->oversample_inc[0] = 0; sp->oversample_inc[1] = 0; if (sp->curr_buffer) { buffer_dealloc(sp->curr_buffer, 1); } sp->curr_buffer = NULL; if (sp->next_buffer) { buffer_dealloc(sp->next_buffer, 1); } sp->next_buffer = NULL; sp->offset = 0; if (sp->si) { sound_close(sp->si); } sp->si = NULL; sp->to_native = NULL; sp->skip_count = 0; sp->auto_pause = 0; sp->notify_position = 0; spool_setprio(); } /* Find the maximum spool priority. */ #ifdef __STDC__ void spool_setprio(void) #else void spool_setprio() #endif { SPOOL *sp; spool_prio = 0; for (sp = spool; sp; sp = sp->next) { if (sp->state == SPOOL_PLAY) { spool_prio = MAX(spool_prio, sp->rp->priority); } } } /* Find the given RPLAY object in the spool. */ #ifdef __STDC__ int spool_match(RPLAY *match, void (*action) (SPOOL *), struct sockaddr_in sin) #else int spool_match(match, action, sin) RPLAY *match; void (*action) (); struct sockaddr_in sin; #endif { int i, id, nmatch = 0; RPLAY *rp; RPLAY_ATTRS *a1, *a2; SPOOL *sp, *sp_next; for (sp = spool; sp; sp = sp_next) { sp_next = sp->next; /* sp may be destroyed */ if (sp->state == SPOOL_NULL) { continue; } a2 = match->attrs; if (a2 && a2->sound[0] == '#') { for (; a2; a2 = a2->next) { id = atoi(a2->sound + 1); if (id == 0 || id == sp->id) { sp->sin = sin; (*action) (sp); nmatch++; break; } } continue; } rp = sp->rp; for (a1 = rp->attrs, a2 = match->attrs; a1 && a2; a1 = a1->next, a2 = a2->next) { if (strcmp(a1->sound, a2->sound)) { break; } } if (!a1 && !a2) { sp->sin = sin; (*action) (sp); nmatch++; } } return nmatch; } /* Remove any spool entries with `sound' from the spool. */ #ifdef __STDC__ void spool_remove(SOUND *sound) #else void spool_remove(sound) SOUND *sound; #endif { int i, j, n; SPOOL *sp, *sp_next; for (sp = spool; sp; sp = sp_next) { sp_next = sp->next; /* sp may be destroyed */ if (sp->state == SPOOL_NULL) { continue; } n = 0; for (j = 0; j < sp->rp->nsounds; j++) { if (sp->sound[j] == sound) { n++; } } if (n) { spool_done(sp); } } } /* * Make all spool entries waiting for `sound' ready to be played. */ #ifdef __STDC__ void spool_ready(SOUND *sound) #else void spool_ready(sound) SOUND *sound; #endif { int j, number_not_ready, has_the_sound; SPOOL *sp; for (sp = spool; sp; sp = sp->next) { if (sp->state == SPOOL_WAIT) { number_not_ready = 0; has_the_sound = 0; for (j = 0; j < sp->rp->nsounds; j++) { if (sp->sound[j]->status != SOUND_READY) { number_not_ready++; if (sp->sound[j] == sound) { number_not_ready--; } } if (sp->sound[j] == sound) { has_the_sound++; } } if (number_not_ready == 0 && has_the_sound) { for (j = 0; j < sp->rp->nsounds; j++) { sound_map(sp->sound[j]); } spool_play(sp); } } } } /* Return a buffer list for the `list spool' command. */ BUFFER * spool_list_create() { BUFFER *spool_list, *b; int i, n; char buf[RPTP_MAX_LINE]; char line[RPTP_MAX_LINE]; SOUND *s; SPOOL *sp; int length; b = buffer_create(); spool_list = b; SNPRINTF(SIZE(b->buf, BUFFER_SIZE), "+message=\"spool\"\r\n"); b->nbytes += strlen(b->buf); for (sp = spool; sp; sp = sp->next) { length = 0; line[0] = '\0'; SNPRINTF(SIZE(buf, sizeof(buf)), "id=#%d state=", sp->id); strncat(line + length, buf, sizeof(line) - length); length += strlen(buf); switch (sp->state) { case SPOOL_PLAY: SNPRINTF(SIZE(buf, sizeof(buf)), "play"); break; case SPOOL_PAUSE: SNPRINTF(SIZE(buf, sizeof(buf)), "pause"); break; case SPOOL_WAIT: SNPRINTF(SIZE(buf, sizeof(buf)), "wait"); break; case SPOOL_NEXT: SNPRINTF(SIZE(buf, sizeof(buf)), "next"); break; case SPOOL_SKIP: SNPRINTF(SIZE(buf, sizeof(buf)), "skip"); break; default: continue; } strncat(line + length, buf, sizeof(line) - length); length += strlen(buf); s = sp->sound[sp->curr_sound]; SNPRINTF(SIZE(buf, sizeof(buf)), "\ sound=\"%s\" host=%s volume=%d priority=%d count=%d position=%.2f remain=%.2f seconds=%.2f size=%d\ sample-rate=%d channels=%d bits=%g input=%s client-data=\"%s\" list-name=\"%s\"\r\n", sp->curr_attrs->sound, inet_ntoa(sp->sin.sin_addr), sp->curr_attrs->volume, sp->rp->priority, sp->curr_count, sp->sample_rate && s->samples ? sp->sample_index / sp->sample_rate : 0, sp->sample_rate && s->samples ? ((double) s->samples - sp->sample_index) / sp->sample_rate : 0, sp->sample_rate && s->samples ? (double) s->samples / sp->sample_rate : 0, s->size, sp->sample_rate, s->channels, s->input_precision, input_to_string(s->type), sp->curr_attrs->client_data, sp->rp->list_name); strncat(line + length, buf, sizeof(line) - length); length += strlen(buf); if (b->nbytes + length > BUFFER_SIZE) { b->next = buffer_create(); b = b->next; } strncat(b->buf + b->nbytes, line, BUFFER_SIZE - b->nbytes); b->nbytes += length; } if (b->nbytes + 3 > BUFFER_SIZE) { b->next = buffer_create(); b = b->next; } strncat(b->buf + b->nbytes, ".\r\n", BUFFER_SIZE - b->nbytes); b->nbytes += 3; return spool_list; } /* * Return a unique spool id. */ int spool_id() { static int id = 0; SPOOL *sp; for (;;) { id++; if (id > SPOOL_MAX_ID) { id = SPOOL_MIN_ID; } for (sp = spool; sp; sp = sp->next) /* see if the id is in use */ { if (sp->state != SPOOL_NULL && sp->id == id) { break; } } if (!sp) { return id; } } } #ifdef __STDC__ void spool_stop(SPOOL *sp) #else void spool_stop(sp) SPOOL *sp; #endif { timer_block(); switch (sp->state) { case SPOOL_PLAY: case SPOOL_PAUSE: case SPOOL_WAIT: if (sp->state == SPOOL_PLAY) { spool_nplaying--; } else if (sp->state == SPOOL_PAUSE) { spool_npaused--; } if (sp->notify_position) { connection_notify(0, NOTIFY_POSITION, sp); sp->notify_position = 0; } connection_notify(0, NOTIFY_STOP, sp); connection_notify(0, NOTIFY_DONE, sp); spool_destroy(sp); break; } timer_unblock(); } #ifdef __STDC__ void spool_pause(SPOOL *sp) #else void spool_pause(sp) SPOOL *sp; #endif { timer_block(); if (sp->state == SPOOL_PLAY) { sp->state = SPOOL_PAUSE; spool_nplaying--; spool_npaused++; if (sp->notify_position) { connection_notify(0, NOTIFY_POSITION, sp); sp->notify_position = 0; } connection_notify(0, NOTIFY_PAUSE, sp); } timer_unblock(); } #ifdef __STDC__ void spool_continue(SPOOL *sp) #else void spool_continue(sp) SPOOL *sp; #endif { timer_block(); if (sp->state == SPOOL_PAUSE) { sp->state = SPOOL_PLAY; if (rplay_audio_match) { rplayd_audio_match(sp); } spool_nplaying++; spool_npaused--; spool_needs_update++; connection_notify(0, NOTIFY_CONTINUE, sp); } timer_unblock(); } #ifdef __STDC__ void spool_done(SPOOL *sp) #else void spool_done(sp) SPOOL *sp; #endif { timer_block(); switch (sp->state) { case SPOOL_PLAY: case SPOOL_PAUSE: case SPOOL_WAIT: if (sp->si && sp->si->is_flow && sp->state == SPOOL_PLAY) { sp->si->eof = 1; /* spool_update will deal with this */ } else { if (sp->state == SPOOL_PLAY) { spool_nplaying--; } else if (sp->state == SPOOL_PAUSE) { spool_npaused--; } if (sp->notify_position) { connection_notify(0, NOTIFY_POSITION, sp); sp->notify_position = 0; } connection_notify(0, NOTIFY_DONE, sp); spool_destroy(sp); } break; } timer_unblock(); } #ifdef __STDC__ void spool_flow_pause(SPOOL *sp) #else void spool_flow_pause(sp) SPOOL *sp; #endif { timer_block(); if (sp->state == SPOOL_PLAY) { sp->state = SPOOL_WAIT; spool_nplaying--; } timer_unblock(); } #ifdef __STDC__ void spool_flow_continue(SPOOL *sp) #else void spool_flow_continue(sp) SPOOL *sp; #endif { timer_block(); if (sp->state == SPOOL_WAIT) { sp->state = SPOOL_PLAY; spool_nplaying++; spool_needs_update++; } timer_unblock(); } #ifdef __STDC__ int spool_flow_insert(SPOOL *sp, BUFFER *b) #else int spool_flow_insert(sp, b) SPOOL *sp; BUFFER *b; #endif { SOUND *s; BUFFER *tmp_buf; s = sp->sound[sp->curr_sound]; *s->flowp = b; for (tmp_buf = b; tmp_buf->next; tmp_buf = tmp_buf->next) ; s->flowp = &tmp_buf->next; /* Enable the sound. */ if (s->status == SOUND_NOT_READY) { s->status = SOUND_READY; if (sound_map(s) < 0) { /* Punt - can't determine what type of sound it is. */ spool_remove(s); /* spool_remove now deletes the sound - sound_delete (s, 0); */ return -1; } spool_ready(s); } for (tmp_buf = b; tmp_buf; tmp_buf = tmp_buf->next) { //s->size += tmp_buf->nbytes; sp->si->water_mark += tmp_buf->nbytes; } s->samples = number_of_samples(s, sp->si->water_mark); /* Wakeup the spool entry. */ if (sp->state == SPOOL_WAIT) { spool_flow_continue(sp); } return 0; } #ifdef __STDC__ void spool_skip(SPOOL *sp, int count) #else void spool_skip(sp, count) SPOOL *sp; int count; #endif { SOUND *s; timer_block(); s = sp->sound[sp->curr_sound]; /* Only sounds that are playing or paused can be skipped. Flows can't be skipped right now. */ if ((sp->state == SPOOL_PLAY || sp->state == SPOOL_PAUSE) && s->type == SOUND_FILE) { if (sp->state == SPOOL_PAUSE) { spool_npaused--; sp->auto_pause++; } sp->state = SPOOL_SKIP; sp->skip_count = count; spool_needs_update++; connection_notify(0, NOTIFY_SKIP, sp); } timer_unblock(); } #ifdef __STDC__ void spool_play(SPOOL *sp) #else void spool_play(sp) SPOOL *sp; #endif { SOUND *s; s = sp->sound[sp->curr_sound]; #ifdef HAVE_CDROM /* Parse the name of the cdrom device that was specified. */ if (s->type == SOUND_CDROM) { char name_buf[MAXPATHLEN]; char *p; strncpy(name_buf, sp->curr_attrs->sound, sizeof(name_buf)); p = strchr(name_buf, ':'); if (p == NULL) { report(REPORT_DEBUG, "spool_play: can't parse cdrom name `%s'\n", s->name); return; } *p++ = '\0'; if (strchr(p, '-')) { p = strtok(p, "-"); if (p) { s->starting_track = atoi(p); p = strtok(NULL, ""); if (p) { s->ending_track = atoi(p); } } } else { s->starting_track = atoi(p); s->ending_track = atoi(p); } } #endif /* HAVE_CDROM */ sp->si = sound_open(s, 1); if (sp->si == NULL) { spool_destroy(sp); return; } sound_seek(sp->si, s->offset, SEEK_SET); /* skip the audio header */ sp->curr_buffer = NULL; sp->next_buffer = NULL; sp->sample_index = 0; sp->to_native = native_table[s->format].to_native[s->byte_order - 1]; spool_set_sample_rate(sp, (sp->curr_attrs->sample_rate == RPLAY_DEFAULT_SAMPLE_RATE) ? s->sample_rate : sp->curr_attrs->sample_rate); /* Change the state to SPOOL_PLAY when ALL fields have been assigned. */ sp->state = SPOOL_PLAY; spool_nplaying++; spool_setprio(); spool_needs_update++; connection_notify(0, NOTIFY_PLAY, sp); connection_notify(0, NOTIFY_POSITION, sp); if (sp->auto_pause) { spool_pause(sp); sp->auto_pause = 0; } } #ifdef __STDC__ void spool_update(void) #else void spool_update() #endif { int i, n; SPOOL *sp, *sp_next; SOUND *s; BUFFER *b; time_t now; spool_needs_update = 0; now = time(0); for (sp = spool; sp; sp = sp_next) { sp_next = sp->next; /* sp may be destroyed */ /* Some sounds must end here. */ if (sp->state == SPOOL_PLAY && !sp->curr_buffer && !sp->si) { sp->state = SPOOL_NEXT; } switch (sp->state) { case SPOOL_SKIP: case SPOOL_NEXT: if (sp->notify_position) { connection_notify(0, NOTIFY_POSITION, sp); sp->notify_position = 0; } if (!sp->auto_pause) /* something was playing */ { spool_nplaying--; } if (sp->si) { sound_close(sp->si); sp->si = NULL; } buffer_dealloc(sp->curr_buffer, 0); buffer_dealloc(sp->next_buffer, 0); sp->curr_buffer = NULL; sp->next_buffer = NULL; sp->offset = 0; if (sp->state == SPOOL_SKIP) { /* The current sound is now `done'. */ connection_notify(0, NOTIFY_DONE, sp); if (sp->skip_count == 0) { sp->curr_count++; /* "play it again Sam" */ } else { sp->curr_count = 1; /* end the current sound */ /* * Skip to the next sound. */ /* Repeat the current sound if more than 1 second has been played. Otherwise, move to the previous sound. */ if (sp->skip_count < 0 && sp->sample_index > rplay_audio_sample_rate) { sp->skip_count++; } sp->curr_sound += sp->skip_count - 1; /* Skipping before the first sound will always skip to the first sound. */ if (sp->curr_sound < 0) { sp->curr_sound = -1; } /* Skipping after the last sound will always skip to the last sound. */ else if (sp->curr_sound == sp->rp->nsounds) { sp->curr_sound = sp->rp->nsounds - 1; } } } if (sp->curr_count > 1) { sp->curr_count--; } else if (sp->curr_count) { /* Save a pointer to the sound that was playing. */ s = sp->sound[sp->curr_sound]; sp->curr_sound++; if (sp->curr_sound == sp->rp->nsounds) { if (sp->list_count > 1) { sp->list_count--; sp->curr_attrs = sp->rp->attrs; sp->curr_sound = 0; } else if (sp->list_count == 0) { sp->curr_attrs = sp->rp->attrs; sp->curr_sound = 0; } else /* The spool entry is finished. */ { if (sp->state != SPOOL_SKIP) /* already sent `done' */ { connection_notify(0, NOTIFY_DONE, sp); } spool_destroy(sp); continue; } } else { /* Update `curr_attrs' to point to the next set of attributes. */ if (sp->state == SPOOL_SKIP) { /* This does a linear search. Bad, bad, bad */ int i; sp->curr_attrs = sp->rp->attrs; for (i = 0; i < sp->curr_sound; i++) { sp->curr_attrs = sp->curr_attrs->next; } sp->skip_count = 0; } else { sp->curr_attrs = sp->curr_attrs->next; } } sp->curr_count = sp->curr_attrs->count; } spool_play(sp); /* break; */ case SPOOL_PLAY: if (!sp->curr_buffer || (!sp->next_buffer && sp->si && !sp->si->eof)) { s = sp->sound[sp->curr_sound]; #ifdef HAVE_OSS b = buffer_alloc(MIN(s->sample_rate * s->output_sample_size, SOUND_FILL_SIZE), BUFFER_REUSE); #else b = buffer_alloc(MIN(MAX(curr_bufsize * curr_rate, s->sample_rate * s->output_sample_size), SOUND_FILL_SIZE), BUFFER_REUSE); #endif n = sound_fill(sp->si, b, 0); if (n <= 0) { buffer_dealloc(b, 1); if (s->needs_helper) { if (!sp->curr_buffer && !sp->next_buffer) { if (sp->si->eof) { sound_close(sp->si); sp->si = NULL; /* rplayd_write will see this as a dead sound */ spool_needs_update++; } else { spool_flow_pause(sp); } } } else if (s->type == SOUND_FILE) { sound_close(sp->si); sp->si = NULL; /* rplayd_write will see this as a dead sound */ } else if (s->type == SOUND_FLOW) { if (!sp->curr_buffer && !sp->next_buffer) { if (sp->si->eof) { sound_close(sp->si); sp->si = NULL; /* rplayd_write will see this as a dead sound */ spool_needs_update++; } else { spool_flow_pause(sp); } } } #ifdef HAVE_CDROM else if (s->type == SOUND_CDROM) { if (!sp->curr_buffer && !sp->next_buffer) { if (sp->si->eof) { sound_close(sp->si); sp->si = NULL; /* rplayd_write will see this as a dead sound */ spool_needs_update++; } else { spool_flow_pause(sp); } } #endif /* HAVE_CDROM */ } } else { sp->time = now; if (!sp->curr_buffer) { timer_block(); sp->ptr = (unsigned char *) b->buf + sp->offset; sp->ptr_end = (unsigned char *) b->buf + b->nbytes; sp->curr_buffer = b; timer_unblock(); } else { sp->next_buffer = b; } #ifdef HAVE_HELPERS if (s->needs_helper && ((sp->si->water_mark - sp->si->offset) < sp->si->low_water_mark)) { FD_SET(sp->si->fd, &read_mask); } #else if (0) { /* hack */ } #endif /* HAVE_HELPERS */ else if (s->type == SOUND_FLOW && ((sp->si->water_mark - sp->si->offset) < sp->si->low_water_mark)) { connection_notify(0, NOTIFY_FLOW, sp); connection_flow_continue(sp); } #ifdef HAVE_CDROM else if (s->type == SOUND_CDROM && ((sp->si->water_mark - sp->si->offset) < sp->si->low_water_mark)) { FD_SET(sp->si->fd, &read_mask); } #endif /* HAVE_CDROM */ } } break; } } } #ifdef __STDC__ int spool_process(char *buf, int nbytes) #else int spool_process(buf, nbytes) char *buf; int nbytes; #endif { SPOOL *sp, *sp_next; int number_playing = 0; int nsamples; /* Determine the number of samples that need to be processed. */ nsamples = nbytes / ((rplay_audio_precision >> 3) * rplay_audio_channels); zero_native(rplay_audio_buf, nsamples, rplay_audio_channels); for (sp = spool; sp; sp = sp_next) { sp_next = sp->next; if (sp->state == SPOOL_PLAY) { number_playing++; /* See if the end of sound has been reached. */ if (!(*sp->to_native) (sp, rplay_audio_buf, nsamples, rplay_audio_channels)) { sp->state = SPOOL_NEXT; spool_needs_update++; } /* See if more buffers need to be filled by `spool_update'. */ else if (sp->curr_buffer == NULL || (sp->si && !sp->si->eof && !sp->next_buffer)) { spool_needs_update++; } sp->notify_position++; } } if (number_playing) { #ifdef TEST_FLANGE flange(rplay_audio_buf, nsamples, rplay_audio_channels); #endif #ifdef FAKE_VOLUME fake_volume(rplay_audio_buf, nsamples, rplay_audio_channels); #endif /* Only calculate left and right levels if there's a connection that needs the information. */ if (connection_want_level_notify) { level(rplay_audio_buf, nsamples, rplay_audio_channels); connection_level_notify++; } /* Convert rplay_audio_buf to the audio device format. */ (*native_table[rplay_audio_format].from_native[RPLAY_AUDIO_BYTE_ORDER - 1]) (rplay_audio_buf, nsamples, rplay_audio_channels); rplay_audio_size = nbytes; } } #ifdef __STDC__ SPOOL * spool_find(int id) #else SPOOL * spool_find(id) int id; #endif { SPOOL *sp; for (sp = spool; sp; sp = sp->next) { if (sp->id == id) { break; } } return sp; } /* This routine can be used to remove idle flows from the spool. */ #ifdef __STDC__ void spool_cleanup(void) #else void spool_cleanup() #endif { SPOOL *sp; int flows_cleaned = 0; for (sp = spool; sp; sp = sp->next) { if (sp->state == SPOOL_WAIT && sp->sound[sp->curr_sound]->type == SOUND_FLOW) { spool_done(sp); flows_cleaned++; } } report(REPORT_DEBUG, "cleaning up the spool - %d flows\n", flows_cleaned); } #ifdef __STDC__ void spool_set_count(SPOOL *sp, int count) #else void spool_set_count(sp, count) SPOOL *sp; int count; #endif { if (sp) { sp->curr_count = count; sp->curr_attrs->count = count; } } #ifdef __STDC__ void spool_set_list_count(SPOOL *sp, int count) #else void spool_set_list_count(sp, count) SPOOL *sp; int count; #endif { if (sp) { sp->list_count = count; sp->rp->count = count; } } #ifdef __STDC__ void spool_set_priority(SPOOL *sp, int priority) #else void spool_set_priority(sp, priority) SPOOL *sp; int priority; #endif { if (sp) { sp->rp->priority = priority; spool_setprio(); } } #ifdef __STDC__ void spool_set_sample_rate(SPOOL *sp, int sample_rate) #else void spool_set_sample_rate(sp, sample_rate) SPOOL *sp; int sample_rate; #endif { if (sp) { sp->sample_rate = sample_rate > 0 ? sample_rate : sp->sound[sp->curr_sound]->sample_rate; sp->curr_attrs->sample_rate = sample_rate; sp->sample_factor = (double) sp->sample_rate / (double) rplay_audio_sample_rate; if (rplay_audio_match) { rplayd_audio_match(sp); } } } #ifdef __STDC__ void spool_set_volume(SPOOL *sp, int volume) #else void spool_set_volume(sp, volume) SPOOL *sp; int volume; #endif { if (sp) { sp->curr_attrs->volume = volume; } } #ifdef __STDC__ void spool_set_client_data(SPOOL *sp, char *client_data) #else void spool_set_client_data(sp, client_data) SPOOL *sp; char *client_data; #endif { if (sp) { if (*sp->curr_attrs->client_data) { free((char *) sp->curr_attrs->client_data); } sp->curr_attrs->client_data = strdup(client_data); } } #ifdef __STDC__ SPOOL * spool_find_pid(int pid) #else SPOOL * spool_find_pid(pid) int pid; #endif { SPOOL *sp; #if defined(HAVE_CDROM) || defined(HAVE_HELPERS) for (sp = spool; sp; sp = sp->next) { if (sp->si && sp->si->pid == pid) { return sp; } } #endif return NULL; } rplay-3.3.2/rplayd/spool.h100644 153 62 13705 6671423014 14146 0ustar boynsstaff/* $Id: spool.h,v 1.3 1999/03/10 07:58:04 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _spool_h #define _spool_h #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "rplay.h" #include "sound.h" #include "buffer.h" #define SPOOL_NULL 0 /* nothing */ #define SPOOL_PLAY 1 /* Spool entry is playing. */ #define SPOOL_PAUSE 2 /* Spool entry is plaused. */ #define SPOOL_WAIT 3 /* Spool entry is waiting for more data. */ #define SPOOL_NEXT 4 /* Current sound is done. */ #define SPOOL_SKIP 5 /* Current sound has been skipped. */ #define SPOOL_MIN_ID 1 #define SPOOL_MAX_ID 999 typedef struct _spool { struct _spool *next; struct _spool *prev; int id; /* unique spool id */ int state; /* state of spool entry */ time_t time; /* time since data was last read */ int curr_sound; /* current sound */ int curr_count; /* # times left to play curr_sound */ int list_count; /* # times left to play the sound list */ SOUND *sound[SOUND_LIST_SIZE]; /* list of sounds */ SINDEX *si; /* Index of the current sound. */ BUFFER *curr_buffer; /* Buffer of audio that's currently playing. */ BUFFER *next_buffer; /* Buffer of audio that will be played next. */ int offset; /* Position in the current audio file. */ unsigned char *ptr; /* Pointer to the current sample. */ unsigned char *ptr_end; /* The end of the current buffer. */ RPLAY *rp; /* RPLAY packet received */ RPLAY_ATTRS *curr_attrs; /* current rplay attributes */ struct sockaddr_in sin; /* client's address */ unsigned long sample_rate; /* sample rate of curr_sound */ double sample_index; /* Must use float to avoid rounding errors. */ double sample_factor; /* Factor to increase the sample index by. */ double oversample[2]; /* The current sample value when oversampling */ double oversample_inc[2]; /* The delta to increase the oversample with */ int (*to_native) (); /* Convert curr_sound samples to native. */ int skip_count; /* skip curr_sound */ int auto_pause; /* pause before play */ int notify_position; /* notify clients needing position information */ } SPOOL; extern SPOOL *spool; extern int spool_size; extern int spool_nplaying; extern int spool_npaused; extern int spool_prio; extern int spool_needs_update; #ifdef __STDC__ extern void spool_init (); extern SPOOL *spool_create (); extern void spool_destroy (SPOOL *sp); extern int spool_match (RPLAY *match, void (*action) (SPOOL *), struct sockaddr_in sin); extern SPOOL *spool_next (int priority); extern void spool_ready (SOUND *sound); extern void spool_remove (SOUND *sound); extern BUFFER *spool_list_create (); extern void spool_reset (SPOOL *sp); extern void spool_setprio (void); extern int spool_id (void); extern void spool_stop (SPOOL *sp); extern void spool_pause (SPOOL *sp); extern void spool_continue (SPOOL *sp); extern void spool_done (SPOOL *sp); extern void spool_flow_pause (SPOOL *sp); extern void spool_flow_continue (SPOOL *sp); extern int spool_flow_insert (SPOOL *sp, BUFFER *b); extern void spool_skip (SPOOL *sp, int count); extern void spool_play (SPOOL *sp); extern void spool_update (void); extern int spool_process (char *buf, int nbytes); extern SPOOL *spool_find (int id); extern void spool_cleanup (void); extern void spool_set_count (SPOOL *sp, int count); extern void spool_set_list_count (SPOOL *sp, int count); extern void spool_set_priority (SPOOL *sp, int priority); extern void spool_set_sample_rate (SPOOL *sp, int sample_rate); extern void spool_set_volume (SPOOL *sp, int volume); extern void spool_set_client_data (SPOOL *sp, char *client_data); extern SPOOL *spool_find_pid (int pid); #else extern void spool_init (); extern SPOOL *spool_create (); extern void spool_destroy ( /* SPOOL *sp */ ); extern int spool_match ( /* RPLAY *match, void (*action)(SPOOL *), struct sockaddr_in sin */ ); extern SPOOL *spool_next ( /* int priority */ ); extern void spool_ready ( /* SOUND *sound */ ); extern void spool_remove ( /* SOUND *sound */ ); extern BUFFER *spool_list_create (); extern void spool_reset ( /* SPOOL *sp */ ); extern void spool_setprio (); extern int spool_id (); extern void spool_stop ( /* SPOOL *sp */ ); extern void spool_pause ( /* SPOOL *sp */ ); extern void spool_continue ( /* SPOOL *sp */ ); extern void spool_done ( /* SPOOL *sp */ ); extern void spool_flow_pause ( /* SPOOL *sp */ ); extern void spool_flow_continue ( /* SPOOL *sp */ ); extern int spool_flow_insert ( /* SPOOL *sp, BUFFER *b */ ); extern void spool_skip ( /* SPOOL *sp, int count */ ); extern void spool_play ( /* SPOOL *sp */ ); extern void spool_update (); extern int spool_process ( /* char *buf, int nbytes */ ); extern SPOOL *spool_find ( /* int id */ ); extern void spool_cleanup ( /* void */ ); extern void spool_set_count ( /* SPOOL *sp, int count */ ); extern void spool_set_list_count ( /* SPOOL *sp, int count */ ); extern void spool_set_priority ( /* SPOOL *sp, int count */ ); extern void spool_set_sample_rate ( /* SPOOL *sp, int sample_rate */ ); extern void spool_set_volume ( /* SPOOL *sp, int volume */ ); extern void spool_set_client_data ( /* SPOOL *sp, char *client_data */ ); extern SPOOL *spool_find_pid ( /* int pid */ ); #endif #endif /* _spool_h */ rplay-3.3.2/rplayd/timer.c100644 153 62 7536 6671423014 14112 0ustar boynsstaff/* $Id: timer.c,v 1.4 1999/03/10 07:58:04 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "rplayd.h" #include "timer.h" double timer_rate = 0.0; double timer_count = 0.0; int timer_enabled = 0; void timer_update() { #ifdef HAVE_OSS int bytes = rplay_audio_getospace_bytes(); /* check bytes and sample size? */ if (bytes > 0) { rplayd_write(bytes); } /* if audio device isn't open, just pretend to keep spool going */ else if (!rplay_audio_isopen()) { /* approximate the amount to be written */ int sample_size = (rplay_audio_precision >> 3) * rplay_audio_channels; rplayd_write(rplay_audio_sample_rate / curr_rate * sample_size); } #else rplayd_write(curr_bufsize); #endif timer_count += timer_rate; } void timer_init() { struct sigaction sa; sa.sa_handler = timer_update; sa.sa_flags = 0; #if defined(SA_RESTART) && ! defined(sgi) sa.sa_flags |= SA_RESTART; #endif sigemptyset(&sa.sa_mask); sigaddset(&sa.sa_mask, SIGALRM); if (sigaction(SIGALRM, &sa, (struct sigaction *) NULL) < 0) { report(REPORT_ERROR, "timer_init: sigaction: %s\n", sys_err_str(errno)); done(1); } timer_enabled = 0; } void timer_block() { sigset_t sigset; sigemptyset(&sigset); sigaddset(&sigset, SIGALRM); if (sigprocmask(SIG_BLOCK, &sigset, NULL) < 0) { report(REPORT_ERROR, "timer_block: sigsetprocmask: %s\n", sys_err_str(errno)); done(1); } } void timer_unblock() { sigset_t sigset; sigemptyset(&sigset); sigaddset(&sigset, SIGALRM); if (sigprocmask(SIG_UNBLOCK, &sigset, NULL) < 0) { report(REPORT_ERROR, "timer_block: sigsetprocmask: %s\n", sys_err_str(errno)); done(1); } } #ifdef __STDC__ void timer_restart(int new_rate) #else void timer_restart(new_rate) int new_rate; #endif { struct itimerval it; timer_enabled = 1; if (new_rate <= 0) { report(REPORT_ERROR, "timer_restart: new_rate=%d, must be >= 1\n", new_rate); done(1); } else if (new_rate == 1) { it.it_interval.tv_sec = 1; it.it_interval.tv_usec = 0; } else { it.it_interval.tv_sec = 0; it.it_interval.tv_usec = 1000000 / new_rate; } it.it_value = it.it_interval; if (setitimer(ITIMER_REAL, &it, NULL) < 0) { report(REPORT_ERROR, "timer_restart: setitimer: %s\n", sys_err_str(errno)); done(1); } if (it.it_interval.tv_sec) { timer_rate = it.it_interval.tv_sec; } else { timer_rate = (double) it.it_interval.tv_usec / 1000000; } } #ifdef __STDC__ void timer_start(int new_rate) #else void timer_start(new_rate) int new_rate; #endif { timer_restart(new_rate); } void timer_stop() { struct itimerval it; timer_enabled = 0; it.it_interval.tv_sec = 0; it.it_interval.tv_usec = 0; it.it_value = it.it_interval; if (setitimer(ITIMER_REAL, &it, NULL) < 0) { report(REPORT_ERROR, "timer_stop: setitimer: %s\n", sys_err_str(errno)); done(1); } } rplay-3.3.2/rplayd/timer.h100644 153 62 3056 6671423014 14110 0ustar boynsstaff/* $Id: timer.h,v 1.3 1999/03/10 07:58:04 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _timer_h #define _timer_h #ifdef HAVE_CONFIG_H #include "config.h" #endif #include extern double timer_rate; extern double timer_count; extern int timer_enabled; #ifdef __STDC__ extern void timer_update (); extern void timer_init (); extern void timer_block (); extern void timer_unblock (); extern void timer_start (int interval); extern void timer_restart (int interval); extern void timer_stop (); #else extern void timer_update (); extern void timer_init (); extern void timer_block (); extern void timer_unblock (); extern void timer_start ( /* int interval */ ); extern void timer_restart ( /* int interval */ ); extern void timer_stop (); #endif #endif /* _timer_h */ rplay-3.3.2/rplayd/ulaw.c100644 153 62 117013 6671423014 13772 0ustar boynsstaff/* $Id: ulaw.c,v 1.4 1999/03/10 07:58:04 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "ulaw.h" short _ulaw2linear[256] = { -32256, -31228, -30200, -29172, -28143, -27115, -26087, -25059, -24031, -23002, -21974, -20946, -19918, -18889, -17861, -16833, -16062, -15548, -15033, -14519, -14005, -13491, -12977, -12463, -11949, -11435, -10920, -10406, -9892, -9378, -8864, -8350, -7964, -7707, -7450, -7193, -6936, -6679, -6422, -6165, -5908, -5651, -5394, -5137, -4880, -4623, -4365, -4108, -3916, -3787, -3659, -3530, -3402, -3273, -3144, -3016, -2887, -2759, -2630, -2502, -2373, -2245, -2116, -1988, -1891, -1827, -1763, -1698, -1634, -1570, -1506, -1441, -1377, -1313, -1249, -1184, -1120, -1056, -992, -927, -879, -847, -815, -783, -751, -718, -686, -654, -622, -590, -558, -526, -494, -461, -429, -397, -373, -357, -341, -325, -309, -293, -277, -261, -245, -228, -212, -196, -180, -164, -148, -132, -120, -112, -104, -96, -88, -80, -72, -64, -56, -48, -40, -32, -24, -16, -8, 0, 32256, 31228, 30200, 29172, 28143, 27115, 26087, 25059, 24031, 23002, 21974, 20946, 19918, 18889, 17861, 16833, 16062, 15548, 15033, 14519, 14005, 13491, 12977, 12463, 11949, 11435, 10920, 10406, 9892, 9378, 8864, 8350, 7964, 7707, 7450, 7193, 6936, 6679, 6422, 6165, 5908, 5651, 5394, 5137, 4880, 4623, 4365, 4108, 3916, 3787, 3659, 3530, 3402, 3273, 3144, 3016, 2887, 2759, 2630, 2502, 2373, 2245, 2116, 1988, 1891, 1827, 1763, 1698, 1634, 1570, 1506, 1441, 1377, 1313, 1249, 1184, 1120, 1056, 992, 927, 879, 847, 815, 783, 751, 718, 686, 654, 622, 590, 558, 526, 494, 461, 429, 397, 373, 357, 341, 325, 309, 293, 277, 261, 245, 228, 212, 196, 180, 164, 148, 132, 120, 112, 104, 96, 88, 80, 72, 64, 56, 48, 40, 32, 24, 16, 8, 0}; static unsigned char _ulinear2ulaw[8192] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, 66, 66, 66, 66, 66, 66, 66, 66, 67, 67, 67, 67, 67, 67, 67, 67, 68, 68, 68, 68, 68, 68, 68, 68, 69, 69, 69, 69, 69, 69, 69, 69, 70, 70, 70, 70, 70, 70, 70, 70, 71, 71, 71, 71, 71, 71, 71, 71, 72, 72, 72, 72, 72, 72, 72, 72, 73, 73, 73, 73, 73, 73, 73, 73, 74, 74, 74, 74, 74, 74, 74, 74, 75, 75, 75, 75, 75, 75, 75, 75, 76, 76, 76, 76, 76, 76, 76, 76, 77, 77, 77, 77, 77, 77, 77, 77, 78, 78, 78, 78, 78, 78, 78, 78, 79, 79, 79, 79, 79, 79, 79, 79, 80, 80, 80, 80, 81, 81, 81, 81, 82, 82, 82, 82, 83, 83, 83, 83, 84, 84, 84, 84, 85, 85, 85, 85, 86, 86, 86, 86, 87, 87, 87, 87, 88, 88, 88, 88, 89, 89, 89, 89, 90, 90, 90, 90, 91, 91, 91, 91, 92, 92, 92, 92, 93, 93, 93, 93, 94, 94, 94, 94, 95, 95, 95, 95, 96, 96, 97, 97, 98, 98, 99, 99, 100, 100, 101, 101, 102, 102, 103, 103, 104, 104, 104, 105, 105, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110, 111, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240, 239, 239, 238, 238, 237, 237, 236, 236, 235, 235, 234, 234, 233, 233, 232, 232, 231, 231, 230, 230, 229, 229, 228, 228, 227, 227, 226, 226, 225, 225, 224, 224, 223, 223, 223, 223, 222, 222, 222, 222, 221, 221, 221, 221, 220, 220, 220, 220, 219, 219, 219, 219, 218, 218, 218, 218, 217, 217, 217, 217, 216, 216, 216, 216, 215, 215, 215, 215, 214, 214, 214, 214, 213, 213, 213, 213, 212, 212, 212, 212, 211, 211, 211, 211, 210, 210, 210, 210, 209, 209, 209, 209, 208, 208, 208, 208, 207, 207, 207, 207, 207, 207, 207, 207, 206, 206, 206, 206, 206, 206, 206, 206, 205, 205, 205, 205, 205, 205, 205, 205, 204, 204, 204, 204, 204, 204, 204, 204, 203, 203, 203, 203, 203, 203, 203, 203, 202, 202, 202, 202, 202, 202, 202, 202, 201, 201, 201, 201, 201, 201, 201, 201, 200, 200, 200, 200, 200, 200, 200, 200, 199, 199, 199, 199, 199, 199, 199, 199, 198, 198, 198, 198, 198, 198, 198, 198, 197, 197, 197, 197, 197, 197, 197, 197, 196, 196, 196, 196, 196, 196, 196, 196, 195, 195, 195, 195, 195, 195, 195, 195, 195, 194, 194, 194, 194, 194, 194, 194, 194, 193, 193, 193, 193, 193, 193, 193, 193, 192, 192, 192, 192, 192, 192, 192, 192, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 147, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}; unsigned char *_linear2ulaw = _ulinear2ulaw + 4096; rplay-3.3.2/rplayd/ulaw.h100644 153 62 4141 6671423015 13735 0ustar boynsstaff/* $Id: ulaw.h,v 1.3 1999/03/10 07:58:05 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _ulaw_h #define _ulaw_h #ifdef HAVE_CONFIG_H #include "config.h" #endif /* * ulaw formats */ #define ULAW_MULAW_8 1 /* 8-bit ISDN u-law (CCITT G.711) */ #define ULAW_LINEAR_8 2 /* 8-bit linear PCM */ #define ULAW_LINEAR_16 3 /* 16-bit linear PCM */ #define ULAW_LINEAR_24 4 /* 24-bit linear PCM */ #define ULAW_LINEAR_32 5 /* 32-bit linear PCM */ #define ULAW_LINEAR_FLOAT 6 /* 32-bit IEEE floating point */ #define ULAW_LINEAR_DOUBLE 7 /* 64-bit IEEE floating point */ #define ULAW_G721 23 /* CCITT G.721 4-bits ADPCM */ #define ULAW_G723_3 25 /* CCITT G.723 3-bits ADPCM */ #define ULAW_G723_5 26 /* CCITT G.723 5-bits ADPCM */ #define ULAW_MAGIC 0x2e736e64 /* ".snd" ulaw file header */ #define ULAW_HDRSIZE 24 /* minimum ulaw header size */ extern short _ulaw2linear[]; extern unsigned char *_linear2ulaw; #define ulaw_to_linear(ulaw8) (_ulaw2linear[(unsigned char)(ulaw8)]) #define linear_to_ulaw(lin16) (_linear2ulaw[(short)(lin16) >> 3]) #if 0 #ifdef __STDC__ extern unsigned char st_linear_to_ulaw (int sample); extern int st_ulaw_to_linear (unsigned char ulawbyte); #else extern unsigned char st_linear_to_ulaw ( /* int sample */ ); extern int st_ulaw_to_linear ( /* unsigned char ulawbyte */ ); #endif #endif #endif /* _ulaw_h */ rplay-3.3.2/rplayd/xhash.c100644 153 62 5512 6671423015 14076 0ustar boynsstaff/* $Id: xhash.c,v 1.4 1999/03/10 07:58:05 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifdef HAVE_STRING_H #include #endif #include "xhash.h" #include "hash.h" #include "rplayd.h" static struct hash_control *htable; #ifdef DEBUG static void xhash_stats() { int statbuf[HASH_STATLENGTH]; hash_say(htable, statbuf, HASH_STATLENGTH); printf(" %d size, %d read, %d write, %d collisions, %d used\n", statbuf[1], statbuf[2], statbuf[3], statbuf[4], statbuf[5]); } #endif #ifdef __STDC__ void xhash_init(int hash_table_size) #else void xhash_init(hash_table_size) int hash_table_size; #endif { htable = hash_new(); } #ifdef __STDC__ char * xhash_get(char *hash_key) #else char * xhash_get(hash_key) char *hash_key; #endif { return (char *) hash_find(htable, hash_key); } #ifdef __STDC__ void xhash_put(char *hash_key, char *data) #else void xhash_put(hash_key, data) char *hash_key; char *data; #endif { hash_insert(htable, hash_key, data); } #ifdef __STDC__ void xhash_replace(char *hash_key, char *data) #else void xhash_replace(hash_key, data) char *hash_key; char *data; #endif { hash_replace(htable, hash_key, data); } #ifdef __STDC__ void xhash_delete(char *hash_key) #else void xhash_delete(hash_key) char *hash_key; #endif { hash_delete(htable, hash_key); } /* * create a hash key name for the given sound */ #ifdef __STDC__ char * xhash_name(char *pathname) #else char * xhash_name(pathname) char *pathname; #endif { static char name[MAXPATHLEN]; char *extension; if (pathname[0] == '/') { pathname = strrchr(pathname, '/') + 1; } strncpy(name, pathname, sizeof(name)); extension = strrchr(name, '.'); if (extension) { *extension = '\0'; } return name; } #ifdef __STDC__ void xhash_apply(char *(*func) ()) #else void xhash_apply(func) char *(*func) (); #endif { hash_apply(htable, func); } void xhash_die() { hash_die(htable); } rplay-3.3.2/rplayd/xhash.h100644 153 62 3354 6671423015 14105 0ustar boynsstaff/* $Id: xhash.h,v 1.3 1999/03/10 07:58:05 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _xhash_h #define _xhash_h #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef __STDC__ extern void xhash_init (int hash_table_size); extern char *xhash_get (char *hash_key); extern void xhash_put (char *hash_key, char *data); extern void xhash_replace (char *hash_key, char *data); extern void xhash_delete (char *hash_key); extern char *xhash_name (char *pathname); extern void xhash_apply (char *(*func) ()); extern void xhash_die (); #else extern void xhash_init ( /* int hash_table_size */ ); extern char *xhash_get ( /* char *hash_key */ ); extern void xhash_put ( /* char *hash_key, char *data */ ); extern void xhash_replace ( /* char *hash_key, char *data */ ); extern void xhash_delete ( /* char *hash_key */ ); extern char *xhash_name ( /* char *pathname */ ); extern void xhash_apply ( /* char *(*func) () */ ); extern void xhash_die (); #endif #endif /* _xhash_h */ rplay-3.3.2/rplayd/audio/ 40755 153 62 0 6727650100 13617 5ustar boynsstaffrplay-3.3.2/rplayd/audio/README100644 153 62 406 6552756453 14572 0ustar boynsstaff This directory contains system specific audio code. audio_generic.c should be used as a template for new systems. audio.old contains the old audio.c from 3.1.1beta and could be used as a reference. Please read the ../../PORTING file for more information. rplay-3.3.2/rplayd/audio/audio_FreeBSD.c100644 153 62 23425 6671423022 16500 0ustar boynsstaff/* $Id: audio_FreeBSD.c,v 1.5 1999/03/10 07:58:10 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /* FreeBSD audio code was written by Andreas S. Wetzel . */ #include "rplayd.h" /* * System audio include files: */ #include #include #include #include #include #include /* * for the poor folks who don't have a sound card, but use the pc speaker * driver pcsndrv version 0.6 (no SNDCTL_DSP_POST ....yet) */ #ifndef SNDCTL_DSP_POST #define SNDCTL_DSP_POST SNDCTL_DSP_SYNC #endif /* * External variables: */ extern char *rplay_audio_device; extern int rplay_audio_sample_rate; extern int rplay_audio_channels; extern int rplay_audio_precision; extern int rplay_audio_format; extern int rplay_audio_port; extern int optional_sample_rate; extern int optional_precision; extern int optional_channels; extern int optional_format; extern int optional_port; extern int max_rplay_audio_bufsize; /* * Internal variables: */ int rplay_audio_fd = -1; /* * Initialize the audio device. * This routine must set the following external variables: * rplay_audio_sample_rate * rplay_audio_precision * rplay_audio_channels * rplay_audio_format * * and may use the following optional parameters: * optional_sample_rate * optional_precision * optional_channels * optional_format * * optional_* variables with values of zero should be ignored. * * Return 0 on success and -1 on error. */ int rplay_audio_init(void) { int n; if (rplay_audio_fd == -1) { if (rplay_audio_open() == -1) { report(REPORT_ERROR, "rplay_audio_init: cannot open %s\n", rplay_audio_device); return -1; } } rplay_audio_sample_rate = optional_sample_rate ? optional_sample_rate : 44100; rplay_audio_precision = optional_precision ? optional_precision : 16; rplay_audio_channels = optional_channels ? optional_channels : 2; rplay_audio_format = optional_format ? optional_format : rplay_audio_precision == 16 ? RPLAY_FORMAT_LINEAR_16 : RPLAY_FORMAT_ULINEAR_8; /* * Set dsp sample size */ n = rplay_audio_precision; if (ioctl(rplay_audio_fd, SNDCTL_DSP_SAMPLESIZE, &n) == -1) { report(REPORT_ERROR, "rplay_audio_init: can't set audio precision to %d (%d)\n", rplay_audio_precision, n); return -1; } if (n != rplay_audio_precision) { report(REPORT_NOTICE, "rplay_audio_init: audio precision changed from %d to %d\n", rplay_audio_precision, n); rplay_audio_precision = n; } /* * Set # of channels */ n = rplay_audio_channels; if (ioctl(rplay_audio_fd, SOUND_PCM_WRITE_CHANNELS, &n) == -1) { report(REPORT_ERROR, "rplay_audio_init: can't set audio channels to %d (%d)\n", rplay_audio_channels, n); return -1; } if (n != rplay_audio_channels) { report(REPORT_NOTICE, "rplay_audio_init: audio channels changed from %d to %d\n", rplay_audio_channels, n); rplay_audio_channels = n; } /* * Set the sampling rate */ n = rplay_audio_sample_rate; if (ioctl(rplay_audio_fd, SNDCTL_DSP_SPEED, &n) == -1) { report(REPORT_ERROR, "rplay_audio_init: can't set audio sample rate to %d (%d)\n", rplay_audio_sample_rate, n); return (-1); } if (n != rplay_audio_sample_rate) { report(REPORT_NOTICE, "rplay_audio_init: audio sample rate changed from %d to %d\n", rplay_audio_sample_rate, n); rplay_audio_sample_rate = n; } /* * Set the data format */ switch (rplay_audio_format) { case RPLAY_FORMAT_NONE: break; /* ??? */ case RPLAY_FORMAT_LINEAR_8: n = AFMT_S8; break; case RPLAY_FORMAT_ULINEAR_8: n = AFMT_U8; break; case RPLAY_FORMAT_LINEAR_16: n = AFMT_S16_LE; break; case RPLAY_FORMAT_ULINEAR_16: n = AFMT_U16_LE; break; case RPLAY_FORMAT_ULAW: n = AFMT_MU_LAW; break; case RPLAY_FORMAT_G721: case RPLAY_FORMAT_G723_3: case RPLAY_FORMAT_G723_5: n = AFMT_IMA_ADPCM; break; default: report(REPORT_ERROR, "rplay_audio_init: unknown audio format (%d)\n", rplay_audio_format); return (-1); } if (ioctl(rplay_audio_fd, SNDCTL_DSP_SETFMT, &n) == -1) { report(REPORT_ERROR, "rplay_audio_init: can't set audio format\n"); return (-1); } /* * Set the audio blocksize */ if (n = curr_bufsize) { if (ioctl(rplay_audio_fd, SNDCTL_DSP_SETBLKSIZE, &n) == -1) { report(REPORT_ERROR, "rplay_audio_init: can't set audio blocksize to %d\n", curr_bufsize); return (-1); } report(REPORT_DEBUG, "rplay_audio_init: device blksize set to %d\n", n); } rplay_audio_port = RPLAY_AUDIO_PORT_SPEAKER; return 0; } /* * Open the audio device. * * Return 0 on success and -1 on error. */ int rplay_audio_open(void) { if ((rplay_audio_fd = open(rplay_audio_device, (O_WRONLY | O_NONBLOCK), 0)) < 0) return -1; if (fcntl(rplay_audio_fd, F_SETFD, 1) < 0) { report(REPORT_ERROR, "rplay_audio_open: close-on-exec %d\n", sys_err_str(errno)); /* return -1; */ } if (rplay_audio_init() < 0) return -1; return 0; } /* * Is the audio device open? * * Return 1 for true and 0 for false. */ int rplay_audio_isopen(void) { return (rplay_audio_fd != -1); } /* * Flush the audio device. * * Return 0 on success and -1 on error. */ int rplay_audio_flush(void) { if (rplay_audio_fd != -1) return (ioctl(rplay_audio_fd, SNDCTL_DSP_POST, 0)); return 0; } /* * Write nbytes from buf to the audio device. * * Return bytes written on success and -1 on error. */ int rplay_audio_write(char *buf, int nbytes) { int remain = nbytes; int xr; while (remain > 0) { if ((xr = write(rplay_audio_fd, buf, remain)) == -1) { switch (errno) { case EWOULDBLOCK: continue; default: report(REPORT_ERROR, "Error while writing to audio device (%s)\n", strerror(errno)); return (-1); } } else { remain -= xr; } } return (nbytes); } /* * Close the audio device. * * Return 0 on success and -1 on error. */ int rplay_audio_close(void) { if (rplay_audio_fd != -1) { close(rplay_audio_fd); } rplay_audio_fd = -1; return 0; } /* * Return the volume of the audio device. * * Return 0-255 or -1 on error. */ int rplay_audio_get_volume(void) { #ifndef FAKE_VOLUME int mx; int mxdevmask; int left_vol; int right_vol; int vol; vol = left_vol = right_vol = 0; if ((mx = open(RPLAY_MIXER_DEVICE, O_RDONLY)) == -1) { report(REPORT_ERROR, "rplay_audio_get_volume: unable to open mixer device\n"); return (-1); } if (ioctl(mx, SOUND_MIXER_READ_DEVMASK, &mxdevmask) == -1) { report(REPORT_ERROR, "rplay_audio_get_volume: unable to get mixer device mask\n"); close(mx); return (-1); } if (!(mxdevmask & SOUND_MIXER_PCM)) { report(REPORT_ERROR, "rplay_audio_get_volume: pcm mixer device not installed\n"); close(mx); return (-1); } if (ioctl(mx, SOUND_MIXER_READ_PCM, &vol) == -1) { report(REPORT_ERROR, "rplay_audio_get_volume: unable to get mixer volume\n"); close(mx); return (-1); } else { left_vol = (int) ((vol & 0x00ff) * 2.55); right_vol = (int) (((vol & 0xff00) >> 8) * 2.55); vol = (int) ((left_vol + right_vol) / 2); report(REPORT_DEBUG, "current pcm-volume: %d:%d => %d\n", left_vol, right_vol, vol); } close(mx); return (vol); #else return rplay_audio_volume; #endif } /* * Set the volume of the audio device. * Input should be 0-255. * * Return the volume of the audio device 0-255 or -1. */ int rplay_audio_set_volume(int volume) { #ifndef FAKE_VOLUME int mx; int mxdevmask; int left_vol; int right_vol; int vol = (int) (volume / 2.55); vol |= ((vol & 0x00ff) << 8); if ((mx = open(RPLAY_MIXER_DEVICE, O_RDONLY)) == -1) { report(REPORT_ERROR, "rplay_audio_set_volume: unable to open mixer device\n"); return (-1); } if (ioctl(mx, SOUND_MIXER_READ_DEVMASK, &mxdevmask) == -1) { report(REPORT_ERROR, "rplay_audio_set_volume: unable to get mixer device mask\n"); close(mx); return (-1); } if (!(mxdevmask & SOUND_MIXER_PCM)) { report(REPORT_ERROR, "rplay_audio_set_volume: pcm mixer device not installed\n"); close(mx); return (-1); } if (ioctl(mx, SOUND_MIXER_WRITE_PCM, &vol) == -1) { report(REPORT_ERROR, "rplay_audio_set_volume: unable to set mixer volume\n"); close(mx); return (-1); } else { left_vol = (int) ((vol & 0x00ff) * 2.55); right_vol = (int) (((vol & 0xff00) >> 8) * 2.55); vol = (int) ((left_vol + right_vol) / 2); report(REPORT_DEBUG, "rplay_audio_set_volume: pcm-volume set to %d:%d => %d\n", left_vol, right_vol, vol); } close(mx); rplay_audio_volume = vol; return rplay_audio_volume; #else if (volume < RPLAY_MIN_VOLUME) { volume = RPLAY_MIN_VOLUME; } else if (volume > RPLAY_MAX_VOLUME) { volume = RPLAY_MAX_VOLUME; } rplay_audio_volume = volume; return rplay_audio_volume; #endif } rplay-3.3.2/rplayd/audio/audio_FreeBSD.h100644 153 62 2303 6671423022 16455 0ustar boynsstaff/* $Id: audio_FreeBSD.h,v 1.3 1999/03/10 07:58:10 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _audio_FreeBSD_h #define _audio_FreeBSD_h #include "rplay.h" #define RPLAY_AUDIO_DEVICE "/dev/dsp" #define RPLAY_MIXER_DEVICE "/dev/mixer" #define RPLAY_AUDIO_TIMEOUT 3 #define RPLAY_AUDIO_FLUSH_TIMEOUT -1 #define RPLAY_AUDIO_RATE 10 #define RPLAY_AUDIO_BYTE_ORDER RPLAY_LITTLE_ENDIAN #endif /* _audio_FreeBSD_h */ rplay-3.3.2/rplayd/audio/audio_generic.c100644 153 62 12331 6671423022 16674 0ustar boynsstaff/* $Id: audio_generic.c,v 1.5 1999/03/10 07:58:10 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #include "rplayd.h" /* * System audio include files: */ #include #include #include #ifdef ultrix #include #else #include #endif #include /* * External variables: */ extern char *rplay_audio_device; extern int rplay_audio_sample_rate; extern int rplay_audio_channels; extern int rplay_audio_precision; extern int rplay_audio_format; extern int rplay_audio_port; extern int optional_sample_rate; extern int optional_precision; extern int optional_channels; extern int optional_format; extern int optional_port; /* * Internal variables: */ static int rplay_audio_fd = -1; static RPLAY_AUDIO_TABLE generic_table[] = { {8000, RPLAY_FORMAT_ULAW, 1, 1}, {0, 0, 0, 0} }; /* * Initialize the audio device. * This routine must set the following external variables: * rplay_audio_sample_rate * rplay_audio_precision * rplay_audio_channels * rplay_audio_format * rplay_audio_port * * and may use the following optional parameters: * optional_sample_rate * optional_precision * optional_channels * optional_format * optional_port * * optional_* variables with values of zero should be ignored. * * Return 0 on success and -1 on error. */ int rplay_audio_init() { if (rplay_audio_fd == -1) { rplay_audio_open(); if (rplay_audio_fd == -1) { report(REPORT_ERROR, "rplay_audio_init: cannot open %s\n", rplay_audio_device); return -1; } } rplay_audio_sample_rate = 8000; rplay_audio_precision = 8; rplay_audio_channels = 1; rplay_audio_format = RPLAY_FORMAT_ULAW; rplay_audio_port = RPLAY_AUDIO_PORT_SPEAKER; rplay_audio_table = generic_table; return 0; } /* * Open the audio device. * * Return 0 on success and -1 on error. */ int rplay_audio_open() { int flags; rplay_audio_fd = open(rplay_audio_device, O_WRONLY | O_NDELAY, 0); if (rplay_audio_fd < 0) { return -1; } if (fcntl(rplay_audio_fd, F_SETFD, 1) < 0) { report(REPORT_ERROR, "rplay_audio_open: close-on-exec %d\n", sys_err_str(errno)); /* return -1; */ } if (rplay_audio_init() < 0) { return -1; } /* * Make sure the audio device writes are non-blocking. */ flags = fcntl(rplay_audio_fd, F_GETFL, 0); if (flags < 0) { return -1; } flags |= FNDELAY; if (fcntl(rplay_audio_fd, F_SETFL, flags) < 0) { return -1; } return 0; } /* * Is the audio device open? * * Return 1 for true and 0 for false. */ int rplay_audio_isopen() { return rplay_audio_fd != -1; } /* * Flush the audio device. * * Return 0 on success and -1 on error. */ int rplay_audio_flush() { return 0; } /* * Write nbytes from buf to the audio device. * * Return the number of bytes written on success and -1 on error. */ #ifdef __STDC__ int rplay_audio_write(char *buf, int nbytes) #else int rplay_audio_write(buf, nbytes) char *buf; int nbytes; #endif { int n, nleft, nwritten; char *p; nleft = nbytes; nwritten = 0; for (p = buf; nleft > 0; nleft -= n, p += n) { n = write(rplay_audio_fd, p, nleft); if (n < 0) { if (errno == EWOULDBLOCK) { return nwritten; } else if (errno != EINTR) { return -1; } n = 0; } else { nwritten += n; } } return nwritten; } /* * Close the audio device. * * Return 0 on success and -1 on error. */ int rplay_audio_close() { if (rplay_audio_fd != -1) { close(rplay_audio_fd); } rplay_audio_fd = -1; return 0; } /* * Return the volume of the audio device. * * Return 0-255 or -1 on error. */ int rplay_audio_get_volume() { #ifdef FAKE_VOLUME return rplay_audio_volume; #else /* not FAKE_VOLUME */ return -1; #endif /* not FAKE_VOLUME */ } /* * Set the volume of the audio device. * Input should be 0-255. * * Return the volume of the audio device 0-255 or -1. */ #ifdef __STDC__ int rplay_audio_set_volume(int volume) #else int rplay_audio_set_volume(volume) int volume; #endif { #ifdef FAKE_VOLUME if (volume < RPLAY_MIN_VOLUME) { volume = RPLAY_MIN_VOLUME; } else if (volume > RPLAY_MAX_VOLUME) { volume = RPLAY_MAX_VOLUME; } rplay_audio_volume = volume; return rplay_audio_volume; #else /* not FAKE_VOLUME */ return -1; #endif /* not FAKE_VOLUME */ } rplay-3.3.2/rplayd/audio/audio_generic.h100644 153 62 2231 6671423022 16657 0ustar boynsstaff/* $Id: audio_generic.h,v 1.3 1999/03/10 07:58:10 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _audio_generic_h #define _audio_generic_h #include "rplay.h" #define RPLAY_AUDIO_DEVICE "/dev/audio" #define RPLAY_AUDIO_TIMEOUT 5 #define RPLAY_AUDIO_FLUSH_TIMEOUT -1 #define RPLAY_AUDIO_RATE 10 #define RPLAY_AUDIO_BYTE_ORDER RPLAY_BIG_ENDIAN #endif /* _audio_generic_h */ rplay-3.3.2/rplayd/audio/audio_hpux.c100644 153 62 31670 6671423022 16253 0ustar boynsstaff/* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /* * The _hpux version was cobbled together from the _generic version by Hendrik * (J.C.Harrison@ncl.ac.uk). */ #include "rplayd.h" /* * System audio include files: */ #include #include #include #include #include #include #include /* * External variables: */ extern char *rplay_audio_device; extern int rplay_audio_sample_rate; extern int rplay_audio_channels; extern int rplay_audio_precision; extern int rplay_audio_format; extern int rplay_audio_port; extern int optional_sample_rate; extern int optional_precision; extern int optional_channels; extern int optional_format; extern int optional_port; /* * Internal variables: */ static int rplay_audio_fd = -1; /* * Initialize the audio device. * This routine must set the following external variables: * rplay_audio_sample_rate * rplay_audio_precision * rplay_audio_channels * rplay_audio_format * rplay_audio_port * * and may use the following optional parameters: * optional_sample_rate * optional_precision * optional_channels * optional_format * optional_port * * optional_* variables with values of zero should be ignored. * * Return 0 on success and -1 on error. */ int rplay_audio_init() { struct audio_describe ad; struct audio_status as; int af; /* audio_format */ int ar; /* audio_rate */ int ao; /* audio_output */ int ac; /* audio_channels */ /* Open the audio device */ if (rplay_audio_fd == -1) { rplay_audio_open(); if (rplay_audio_fd == -1) { report(REPORT_ERROR, "rplay_audio_init: cannot open %s\n", rplay_audio_device); return -1; } } /* Reset the audio device */ if (ioctl(rplay_audio_fd, AUDIO_RESET, RESET_RX_BUF | RESET_TX_BUF | RESET_RX_OVF | RESET_TX_UNF) < 0) { report(REPORT_ERROR, "rplay_audio_init: AUDIO_RESET: %s\n", sys_err_str(errno)); return -1; } /* Interrogate the audio device */ if (ioctl(rplay_audio_fd, AUDIO_DESCRIBE, &ad) < 0) { report(REPORT_ERROR, "rplay_audio_init: AUDIO_DESCRIBE: %s\n", sys_err_str(errno)); return -1; } if (ioctl(rplay_audio_fd, AUDIO_GET_STATUS, &as) < 0) { report(REPORT_ERROR, "rplay_audio_init: AUDIO_GET_STATUS: %s\n", sys_err_str(errno)); return -1; } if (ioctl(rplay_audio_fd, AUDIO_GET_SAMPLE_RATE, &ar) < 0) { report(REPORT_ERROR, "rplay_audio_init: AUDIO_GET_SAMPLE_RATE: %s\n", sys_err_str(errno)); return -1; } if (ioctl(rplay_audio_fd, AUDIO_GET_DATA_FORMAT, &af) < 0) { report(REPORT_ERROR, "rplay_audio_init: AUDIO_GET_DATA_FORMAT: %s\n", sys_err_str(errno)); return -1; } if (ioctl(rplay_audio_fd, AUDIO_GET_OUTPUT, &ao) < 0) { report(REPORT_ERROR, "rplay_audio_init: AUDIO_GET_OUTPUT: %s\n", sys_err_str(errno)); return -1; } #ifdef DEBUG printf("*** AUDIO_DESCRIBE DATA ***\n"); printf("audio_id:\t\t%d\tnrates:\t\t\t%d\tflags:\t%X\n", ad.audio_id, ad.nrates, ad.flags); printf("max_bits_per_sample:\t%d\tnchannels:\t\t%d\n", ad.max_bits_per_sample, ad.nchannels); printf("min_receive_gain:\t%d\tmin_transmit_gain:\t%d\tmin_monitor_gain:\t%d\n", ad.min_receive_gain, ad.min_transmit_gain, ad.min_monitor_gain); printf("max_receive_gain:\t%d\tmax_transmit_gain:\t%d\tmax_monitor_gain:\t%d\n", ad.max_receive_gain, ad.max_transmit_gain, ad.max_monitor_gain); printf("*** AUDIO_STATUS DATA ***\n"); printf("receive_status: %x\treceive_buffer_count: %d\treceive_overflow_count: %d\n", as.receive_status, as.receive_buffer_count, as.receive_overflow_count); printf("transmit_status: %x\ttransmit_buffer_count: %d\ttransmit_underflow_count: %d\n", as.transmit_status, as.transmit_buffer_count, as.transmit_underflow_count); printf("*** END DATA ***\n"); #endif /* Set internal configuration */ /* Having tried sample rates from 0 upto 500000 in steps of 1, the device will only accept a rate of 8000Hz. Dunno about any other models of HP though. */ rplay_audio_sample_rate = ar = optional_sample_rate ? optional_sample_rate : 8000; rplay_audio_channels = ac = optional_channels ? optional_channels : ad.nchannels; /* Set the channel mask according to the number of channels allowed */ ac = (ac == 2) ? (AUDIO_CHANNEL_LEFT | AUDIO_CHANNEL_RIGHT) : ((ac == 1) ? (AUDIO_CHANNEL_LEFT) : 0); /* Only Ulaw, Alaw and linear 16-bit formats are allowed - anyone know what Alaw is ? */ rplay_audio_format = optional_format ? ((optional_format == RPLAY_FORMAT_ULAW) ? RPLAY_FORMAT_ULAW : RPLAY_FORMAT_LINEAR_16) : RPLAY_FORMAT_LINEAR_16; af = (rplay_audio_format == RPLAY_FORMAT_ULAW) ? AUDIO_FORMAT_ULAW : AUDIO_FORMAT_LINEAR16BIT; /* Precision cannot be set seperatly to sound format (I think) */ rplay_audio_precision = (af == AUDIO_FORMAT_LINEAR16BIT) ? 16 : 8; /* Set the output device - how should this be specified ? */ rplay_audio_port = optional_port ? optional_port : RPLAY_AUDIO_PORT_SPEAKER | RPLAY_AUDIO_PORT_HEADPHONE; /* default ports */ ao = 0; if (BIT(rplay_audio_port, RPLAY_AUDIO_PORT_LINEOUT)) { #ifdef AUDIO_LINE_OUT SET_BIT(ao, AUDIO_LINE_OUT); #endif #ifdef AUDIO_OUT_LINE SET_BIT(ao, AUDIO_OUT_LINE); #endif } if (BIT(rplay_audio_port, RPLAY_AUDIO_PORT_HEADPHONE)) { SET_BIT(ao, AUDIO_OUT_HEADPHONE); } if (BIT(rplay_audio_port, RPLAY_AUDIO_PORT_SPEAKER)) { SET_BIT(ao, AUDIO_OUT_SPEAKER); } /* Program the audio device */ if (ioctl(rplay_audio_fd, AUDIO_SET_SAMPLE_RATE, ar) < 0) { report(REPORT_ERROR, "rplay_audio_init: AUDIO_SET_SAMPLE_RATE: %s\n", sys_err_str(errno)); return -1; } if (ioctl(rplay_audio_fd, AUDIO_SET_CHANNELS, ac) < 0) { report(REPORT_ERROR, "rplay_audio_init: AUDIO_SET_CHANNELS: %s\n", sys_err_str(errno)); return -1; } if (ioctl(rplay_audio_fd, AUDIO_SET_DATA_FORMAT, af) < 0) { report(REPORT_ERROR, "rplay_audio_init: AUDIO_SET_DATA_FORMAT: %s\n", sys_err_str(errno)); return -1; } if (ioctl(rplay_audio_fd, AUDIO_SET_OUTPUT, ao) < 0) { report(REPORT_ERROR, "rplay_audio_init: AUDIO_SET_OUTPUTT: %s\n", sys_err_str(errno)); return -1; } return 0; } /* * Open the audio device. * * Return 0 on success and -1 on error. */ int rplay_audio_open() { int flags; report(REPORT_DEBUG, "opening device >%s<\n", rplay_audio_device); rplay_audio_fd = open(rplay_audio_device, O_WRONLY | O_NDELAY, 0); if (rplay_audio_fd < 0) { return -1; } if (fcntl(rplay_audio_fd, F_SETFD, 1) < 0) { report(REPORT_ERROR, "rplay_audio_open: close-on-exec %d\n", sys_err_str(errno)); /* return -1; */ } if (rplay_audio_init() < 0) { return -1; } /* * Make sure the audio device writes are non-blocking. */ flags = fcntl(rplay_audio_fd, F_GETFL, 0); if (flags < 0) { return -1; } flags |= FNDELAY; if (fcntl(rplay_audio_fd, F_SETFL, flags) < 0) { return -1; } return 0; } /* * Is the audio device open? * * Return 1 for true and 0 for false. */ int rplay_audio_isopen() { return (rplay_audio_fd != -1); } /* * Flush the audio device. * * Return 0 on success and -1 on error. */ int rplay_audio_flush() { if (rplay_audio_fd != -1) { if (ioctl(rplay_audio_fd, AUDIO_DRAIN, 0) < 0) { report(REPORT_ERROR, "rplay_audio_init: AUDIO_DRAIN: %s\n", sys_err_str(errno)); } } return 0; } /* * Write nbytes from buf to the audio device. * * Return the number of bytes written on success and -1 on error. */ #ifdef __STDC__ int rplay_audio_write(char *buf, int nbytes) #else int rplay_audio_write(buf, nbytes) char *buf; int nbytes; #endif { int n, nleft, nwritten; char *p; nleft = nbytes; nwritten = 0; for (p = buf; nleft > 0; nleft -= n, p += n) { if ((n = write(rplay_audio_fd, p, nleft)) < 0) { /* report(RPLAY_DEBUG, "rplay_audio_write: %s\n", sys_err_str(errno)); */ if (errno == EWOULDBLOCK) { return nwritten; } else if (errno != EINTR) { report(REPORT_ERROR, "rplay_audio_write: %s\n", sys_err_str(errno)); return -1; } n = 0; } else { nwritten += n; } } return nwritten; } /* * Close the audio device. * * Return 0 on success and -1 on error. */ int rplay_audio_close() { if (rplay_audio_fd != -1) { close(rplay_audio_fd); } rplay_audio_fd = -1; return 0; } /* * Return the volume of the audio device. * * Return 0-255 or -1 on error. */ int rplay_audio_get_volume() { #ifdef FAKE_VOLUME return rplay_audio_volume; #else /* not FAKE_VOLUME */ struct audio_gain ag; struct audio_describe ad; if (rplay_audio_fd < 0) { rplay_audio_open(); } if (rplay_audio_fd < 0) { return -1; } if (ioctl(rplay_audio_fd, AUDIO_GET_GAINS, &ag) < 0) { report(REPORT_ERROR, "rplay_audio_get_volume: AUDIO_GET_GAINS: %s\n", sys_err_str(errno)); return -1; } if (ioctl(rplay_audio_fd, AUDIO_DESCRIBE, &ad) < 0) { report(REPORT_ERROR, "rplay_audio_get_volume: AUDIO_DESCRIBE: %s\n", sys_err_str(errno)); return -1; } #ifdef DEBUG printf("audio.c: ag.cgain[1].receive_gain: %d\tag.cgain[1].transmit_gain: %d\tag.cgain[1].monitor_gain: %d\n", ag.cgain[1].receive_gain, ag.cgain[1].transmit_gain, ag.cgain[1].monitor_gain); printf("audio.c: ag.cgain[2].receive_gain: %d\tag.cgain[2].transmit_gain: %d\tag.cgain[2].monitor_gain: %d\n", ag.cgain[2].receive_gain, ag.cgain[2].transmit_gain, ag.cgain[2].monitor_gain); printf("audio.c: channel_mask: %d\n", ag.channel_mask); #endif return ((unsigned char) ( ((double) ag.cgain[1].transmit_gain - ad.min_transmit_gain) / (ad.max_transmit_gain - ad.min_transmit_gain) * 256)); #endif /* not FAKE_VOLUME */ } /* * Set the volume of the audio device. * Input should be 0-255. * * Return the volume of the audio device 0-255 or -1. */ #ifdef __STDC__ int rplay_audio_set_volume(int volume) #else int rplay_audio_set_volume(volume) int volume; #endif { #ifdef FAKE_VOLUME if (volume < RPLAY_MIN_VOLUME) { volume = RPLAY_MIN_VOLUME; } else if (volume > RPLAY_MAX_VOLUME) { volume = RPLAY_MAX_VOLUME; } rplay_audio_volume = volume; return rplay_audio_volume; #else /* not FAKE_VOLUME */ struct audio_gain ag; struct audio_describe ad; rplay_audio_volume = 0; if (rplay_audio_fd < 0) { rplay_audio_open(); } if (rplay_audio_fd < 0) { return -1; } if (ioctl(rplay_audio_fd, AUDIO_GET_GAINS, &ag) < 0) { report(REPORT_ERROR, "rplay_audio_get_volume: AUDIO_GET_GAINS: %s\n", sys_err_str(errno)); return -1; } if (ioctl(rplay_audio_fd, AUDIO_DESCRIBE, &ad) < 0) { report(REPORT_ERROR, "rplay_audio_get_volume: AUDIO_DESCRIBE: %s\n", sys_err_str(errno)); return -1; } #ifdef DEBUG printf("ag.cgain[1].receive_gain: %d\tag.cgain[1].transmit_gain: %d\tag.cgain[1].monitor_gain: %d\n", ag.cgain[1].receive_gain, ag.cgain[1].transmit_gain, ag.cgain[1].monitor_gain); printf("ag.cgain[2].receive_gain: %d\tag.cgain[2].transmit_gain: %d\tag.cgain[2].monitor_gain: %d\n", ag.cgain[2].receive_gain, ag.cgain[2].transmit_gain, ag.cgain[2].monitor_gain); printf("channel_mask: %d\n", ag.channel_mask); #endif ag.cgain[1].transmit_gain = ((int) ( (((double) volume) * (ad.max_transmit_gain - ad.min_transmit_gain) / 256) + ad.min_transmit_gain)); #ifdef DEBUG printf("ag.cgain[1].receive_gain: %d\tag.cgain[1].transmit_gain: %d\tag.cgain[1].monitor_gain: %d\n", ag.cgain[1].receive_gain, ag.cgain[1].transmit_gain, ag.cgain[1].monitor_gain); printf("ag.cgain[2].receive_gain: %d\tag.cgain[2].transmit_gain: %d\tag.cgain[2].monitor_gain: %d\n", ag.cgain[2].receive_gain, ag.cgain[2].transmit_gain, ag.cgain[2].monitor_gain); printf("channel_mask: %d\n", ag.channel_mask); #endif if (ioctl(rplay_audio_fd, AUDIO_SET_GAINS, ag) < 0) { report(REPORT_ERROR, "rplay_audio_get_volume: AUDIO_SET_GAINS: %s\n", sys_err_str(errno)); return -1; } rplay_audio_volume = rplay_audio_get_volume(); return rplay_audio_volume; #endif /* not FAKE_VOLUME */ } rplay-3.3.2/rplayd/audio/audio_hpux.h100644 153 62 2301 6671423022 16225 0ustar boynsstaff/* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /* * The _hpux version was cobbled together from the _generic version by Hendrik * (J.C.Harrison@ncl.ac.uk). */ #ifndef _audio_hpux_h #define _audio_hpux_h #include "rplay.h" #define RPLAY_AUDIO_DEVICE "/dev/audio" #define RPLAY_AUDIO_TIMEOUT 5 #define RPLAY_AUDIO_FLUSH_TIMEOUT -1 #define RPLAY_AUDIO_RATE 10 #define RPLAY_AUDIO_BYTE_ORDER RPLAY_BIG_ENDIAN #endif /* _audio_hpux_h */ rplay-3.3.2/rplayd/audio/audio_oss.c100644 153 62 32471 6671423022 16073 0ustar boynsstaff/* $Id: audio_oss.c,v 1.5 1999/03/10 07:58:10 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #include "rplayd.h" /* * System audio include files: */ #include #include #include #include #include #include #include /* * External variables: */ extern char *rplay_audio_device; extern int rplay_audio_sample_rate; extern int rplay_audio_channels; extern int rplay_audio_precision; extern int rplay_audio_format; extern int rplay_audio_port; extern int rplay_audio_fragsize; extern int optional_sample_rate; extern int optional_precision; extern int optional_channels; extern int optional_format; extern int optional_port; extern int optional_fragsize; /* * Internal variables: */ static int rplay_audio_fd = -1; static int rplay_audio_mixer_fd = -1; /* * Initialize the audio device. * This routine must set the following external variables: * rplay_audio_sample_rate * rplay_audio_precision * rplay_audio_channels * rplay_audio_format * * and may use the following optional parameters: * optional_sample_rate * optional_precision * optional_channels * optional_format * * optional_* variables with values of zero should be ignored. * * Return 0 on success and -1 on error. */ int rplay_audio_init() { int n; if (rplay_audio_fd == -1) { rplay_audio_open(); if (rplay_audio_fd == -1) { report(REPORT_ERROR, "rplay_audio_init: cannot open %s\n", rplay_audio_device); return -1; } } /* /dev/audio */ if (strcmp(rplay_audio_device, "/dev/audio") == 0) { rplay_audio_sample_rate = 8000; rplay_audio_precision = 8; rplay_audio_channels = 1; rplay_audio_format = RPLAY_FORMAT_ULAW; rplay_audio_set_port(); } /* /dev/dsp */ else if (strcmp(rplay_audio_device, "/dev/dsp") == 0) { rplay_audio_sample_rate = optional_sample_rate ? optional_sample_rate : 44100; rplay_audio_precision = optional_precision ? optional_precision : 16; rplay_audio_channels = optional_channels ? optional_channels : 2; rplay_audio_set_port(); /* Precision */ n = rplay_audio_precision; if (ioctl(rplay_audio_fd, SNDCTL_DSP_SETFMT, &n) == -1) { report(REPORT_ERROR, "rplay_audio_init: can't set audio precision to %d (%d)\n", rplay_audio_precision, n); return -1; } if (n != rplay_audio_precision) { report(REPORT_NOTICE, "rplay_audio_init: audio precision changed from %d to %d\n", rplay_audio_precision, n); rplay_audio_precision = n; } /* Channels */ n = rplay_audio_channels; if (ioctl(rplay_audio_fd, SNDCTL_DSP_CHANNELS, &n) == -1) { report(REPORT_ERROR, "rplay_audio_init: can't set audio channels to %d (%d)\n", rplay_audio_channels, n); return -1; } if (n != rplay_audio_channels) { report(REPORT_NOTICE, "rplay_audio_init: audio channels changed from %d to %d\n", rplay_audio_channels, n); rplay_audio_channels = n; } /* Sample rate */ n = rplay_audio_sample_rate; ioctl(rplay_audio_fd, SNDCTL_DSP_SYNC, NULL); if (ioctl(rplay_audio_fd, SNDCTL_DSP_SPEED, &n) == -1) { report(REPORT_ERROR, "rplay_audio_init: can't set audio sample rate to %d (%d)\n", rplay_audio_sample_rate, n); return -1; } if (n != rplay_audio_sample_rate) { report(REPORT_NOTICE, "rplay_audio_init: audio sample rate changed from %d to %d\n", rplay_audio_sample_rate, n); rplay_audio_sample_rate = n; } /* Format */ rplay_audio_format = optional_format ? optional_format : rplay_audio_precision == 16 ? RPLAY_FORMAT_LINEAR_16 : RPLAY_FORMAT_ULINEAR_8; } else { report(REPORT_ERROR, "rplay_audio_init: `%s' unknown audio device\n", rplay_audio_device); return -1; } return 0; } /* * Open the audio device. * * Return 0 on success and -1 on error. */ int rplay_audio_open() { int flags; audio_buf_info info; int n, i; rplay_audio_fd = open(rplay_audio_device, O_WRONLY, 0); if (rplay_audio_fd < 0) { return -1; } if (fcntl(rplay_audio_fd, F_SETFD, 1) < 0) { report(REPORT_ERROR, "rplay_audio_open: close-on-exec %d\n", sys_err_str(errno)); /* return -1; */ } /* From the OSS driver docs: Argument of this call is an integer encoded as 0xMMMMSSSS (in hex). The 16 least significant bits determine the fragment size. The size is 2SSSS. For example SSSS=0008 gives fragment size of 256 bytes (28). The minimum is 16 bytes (SSSS=4) and the maximum is total_buffer_size/2. Some devices or processor architectures may require larger fragments in this case the requested fragment size is automatically increased. The 16 most significant bits (MMMM) determine maximum number of fragments. By default the deriver computes this based on available buffer space. The minimum value is 2 and the maximum depends on the situation. Set MMMM=0x7fff if you don't want to limit the number of fragments. */ /* Set the audio buffer fragment size. Default to zero which lets the driver pick. */ rplay_audio_fragsize = optional_fragsize ? optional_fragsize : 0; if (rplay_audio_fragsize) { n = rplay_audio_fragsize; } else { n = 4096; } for (i = 0; n > 1; i++) { n >>= 1; } rplay_audio_setfragsize((0x7fff << 16) | i); ioctl(rplay_audio_fd, SNDCTL_DSP_GETOSPACE, &info); report(REPORT_DEBUG, "OSS info: fragments=%d totalfrags=%d fragsize=%d DSP=%d\n", info.fragments, info.fragstotal, info.fragsize, info.fragsize * info.fragstotal); rplay_audio_fragsize = info.fragsize; if (rplay_audio_init() < 0) { return -1; } return 0; } /* * Is the audio device open? * * Return 1 for true and 0 for false. */ int rplay_audio_isopen() { return rplay_audio_fd != -1; } /* * Flush the audio device. * * Return 0 on success and -1 on error. */ int rplay_audio_flush() { if (rplay_audio_fd != -1) { ioctl(rplay_audio_fd, SNDCTL_DSP_SYNC, 0); } return 0; } /* * Write nbytes from buf to the audio device. * * Return the number of bytes written on success and -1 on error. */ #ifdef __STDC__ int rplay_audio_write(char *buf, int nbytes) #else int rplay_audio_write(buf, nbytes) char *buf; int nbytes; #endif { return write(rplay_audio_fd, buf, nbytes); } /* * Close the audio device. * * Return 0 on success and -1 on error. */ int rplay_audio_close() { if (rplay_audio_fd != -1) { close(rplay_audio_fd); } rplay_audio_fd = -1; return 0; } int rplay_audio_set_port() { int mask = 0; int vol = 0; if (rplay_audio_mixer_fd == -1) { if (rplay_audio_mixer_open() < 0) { return -1; } } if (ioctl(rplay_audio_mixer_fd, SOUND_MIXER_READ_DEVMASK, &mask) < 0) { return -1; } rplay_audio_port = optional_port ? optional_port : RPLAY_AUDIO_PORT_LINEOUT | RPLAY_AUDIO_PORT_SPEAKER | RPLAY_AUDIO_PORT_HEADPHONE; /* Clear any ports that aren't available. */ if (BIT(rplay_audio_port, RPLAY_AUDIO_PORT_LINEOUT | RPLAY_AUDIO_PORT_HEADPHONE)) { if (!(mask & SOUND_MASK_VOLUME)) { CLR_BIT(rplay_audio_port, RPLAY_AUDIO_PORT_LINEOUT | RPLAY_AUDIO_PORT_HEADPHONE); } } if (BIT(rplay_audio_port, RPLAY_AUDIO_PORT_SPEAKER)) { if (!(mask & SOUND_MASK_SPEAKER)) { CLR_BIT(rplay_audio_port, RPLAY_AUDIO_PORT_SPEAKER); } } if (BIT(rplay_audio_port, RPLAY_AUDIO_PORT_LINEOUT | RPLAY_AUDIO_PORT_HEADPHONE)) { rplay_audio_port |= RPLAY_AUDIO_PORT_LINEOUT | RPLAY_AUDIO_PORT_HEADPHONE; /* Make sure the volume isn't zero. */ vol = 0; ioctl(rplay_audio_mixer_fd, SOUND_MIXER_READ_VOLUME, &vol); if (vol == 0) { vol = 50; vol |= ((vol & 0x00ff) << 8); ioctl(rplay_audio_mixer_fd, SOUND_MIXER_WRITE_VOLUME, &vol); } } else { /* Zero the volume. */ vol = 0; ioctl(rplay_audio_mixer_fd, SOUND_MIXER_WRITE_VOLUME, &vol); } if (BIT(rplay_audio_port, RPLAY_AUDIO_PORT_SPEAKER)) { vol = 0; ioctl(rplay_audio_mixer_fd, SOUND_MIXER_READ_SPEAKER, &vol); /* Make sure the volume isn't zero. */ if (vol == 0) { vol = 50; vol |= ((vol & 0x00ff) << 8); ioctl(rplay_audio_mixer_fd, SOUND_MIXER_WRITE_SPEAKER, &vol); } } else { /* Zero the volume. */ vol = 0; ioctl(rplay_audio_mixer_fd, SOUND_MIXER_WRITE_SPEAKER, &vol); } } /* * Return the volume of the audio device. * * Return 0-255 or -1 on error. */ int rplay_audio_get_volume() { #ifdef FAKE_VOLUME return rplay_audio_volume; #else /* not FAKE_VOLUME */ int mask; int left_vol; int right_vol; int vol; vol = left_vol = right_vol = 0; if (rplay_audio_mixer_fd == -1) { if (rplay_audio_mixer_open() < 0) { return -1; } } if (ioctl(rplay_audio_mixer_fd, SOUND_MIXER_READ_DEVMASK, &mask) < 0) { report(REPORT_ERROR, "rplay_audio_get_volume: unable to get mixer device mask\n"); return -1; } if (!(mask & SOUND_MASK_PCM)) { report(REPORT_ERROR, "rplay_audio_get_volume: pcm mixer device not installed\n"); return -1; } if (ioctl(rplay_audio_mixer_fd, SOUND_MIXER_READ_PCM, &vol) < 0) { report(REPORT_ERROR, "rplay_audio_get_volume: unable to get mixer volume\n"); return -1; } else { left_vol = (int) ((vol & 0x00ff) * 2.55); right_vol = (int) (((vol & 0xff00) >> 8) * 2.55); vol = (int) ((left_vol + right_vol) / 2); } return vol; #endif /* not FAKE_VOLUME */ } /* * Set the volume of the audio device. * Input should be 0-255. * * Return the volume of the audio device 0-255 or -1. */ #ifdef __STDC__ int rplay_audio_set_volume(int volume) #else int rplay_audio_set_volume(volume) int volume; #endif { #ifdef FAKE_VOLUME if (volume < RPLAY_MIN_VOLUME) { volume = RPLAY_MIN_VOLUME; } else if (volume > RPLAY_MAX_VOLUME) { volume = RPLAY_MAX_VOLUME; } rplay_audio_volume = volume; return rplay_audio_volume; #else /* not FAKE_VOLUME */ int mask; int left_vol; int right_vol; int vol = (int) (volume / 2.55); vol |= ((vol & 0x00ff) << 8); if (rplay_audio_mixer_fd == -1) { if (rplay_audio_mixer_open() < 0) { return -1; } } if (ioctl(rplay_audio_mixer_fd, SOUND_MIXER_READ_DEVMASK, &mask) < 0) { report(REPORT_ERROR, "rplay_audio_set_volume: unable to get mixer device mask\n"); return -1; } if (!(mask & SOUND_MASK_PCM)) { report(REPORT_ERROR, "rplay_audio_set_volume: pcm mixer device not installed\n"); return -1; } if (ioctl(rplay_audio_mixer_fd, SOUND_MIXER_WRITE_PCM, &vol) < 0) { report(REPORT_ERROR, "rplay_audio_set_volume: unable to set mixer volume\n"); return -1; } else { left_vol = (int) ((vol & 0x00ff) * 2.55); right_vol = (int) (((vol & 0xff00) >> 8) * 2.55); vol = (int) ((left_vol + right_vol) / 2); } rplay_audio_volume = vol; return rplay_audio_volume; #endif /* not FAKE_VOLUME */ } int rplay_audio_getblksize() { int blksize; if (rplay_audio_fd == -1) { return -1; } if (ioctl(rplay_audio_fd, SNDCTL_DSP_GETBLKSIZE, &blksize) < 0) { report(REPORT_NOTICE, "DSP_GETBLKSIZE failed\n"); return -1; } else { return blksize; } } #ifdef __STDC__ int rplay_audio_setfragsize(int frag) #else int rplay_audio_setfragsize(frag) int frag; #endif { int n; if (rplay_audio_fd == -1) { return -1; } n = ioctl(rplay_audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag); if (n < 0) { report(REPORT_NOTICE, "DSP_SETFRAGMENT failed n = %d\n", n); return -1; } return 0; } int rplay_audio_getospace_bytes() { audio_buf_info info; if (rplay_audio_fd < 0) { return 0; } ioctl(rplay_audio_fd, SNDCTL_DSP_GETOSPACE, &info); /* printf ("frags=%d fragtotal=%d fragsize=%d bytes=%d\n", */ /* info.fragments, info.fragstotal, info.fragsize, info.bytes); */ return info.bytes; } int rplay_audio_getospace_fragsize() { audio_buf_info info; if (rplay_audio_fd < 0) { return 0; } ioctl(rplay_audio_fd, SNDCTL_DSP_GETOSPACE, &info); return info.fragsize; } int rplay_audio_getfd() { return rplay_audio_fd; } int rplay_audio_mixer_open() { rplay_audio_mixer_fd = open(RPLAY_AUDIO_MIXER_DEVICE, O_RDONLY); if (rplay_audio_mixer_fd < 0) { report(REPORT_ERROR, "rplay_audio_mixer_open: unable to open mixer device\n"); return -1; } return 0; } int rplay_audio_mixer_close() { if (rplay_audio_mixer_fd != -1) { close(rplay_audio_mixer_fd); rplay_audio_mixer_fd = -1; } } int rplay_audio_mixer_isopen() { return rplay_audio_mixer_fd != -1; } rplay-3.3.2/rplayd/audio/audio_oss.h100644 153 62 2437 6671423022 16057 0ustar boynsstaff/* $Id: audio_oss.h,v 1.3 1999/03/10 07:58:10 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _audio_oss_h #define _audio_oss_h #include "rplay.h" #define RPLAY_AUDIO_DEVICE "/dev/dsp" #define RPLAY_AUDIO_MIXER_DEVICE "/dev/mixer" #define RPLAY_AUDIO_TIMEOUT 5 #define RPLAY_AUDIO_FLUSH_TIMEOUT -1 #define RPLAY_AUDIO_RATE 10 #if defined (powerpc) || defined (sparc) #define RPLAY_AUDIO_BYTE_ORDER RPLAY_BIG_ENDIAN #else #define RPLAY_AUDIO_BYTE_ORDER RPLAY_LITTLE_ENDIAN #endif #endif /* _audio_oss_h */ rplay-3.3.2/rplayd/audio/audio_sgi.c100644 153 62 17026 6671423022 16050 0ustar boynsstaff /* $Id: audio_sgi.c,v 1.4 1999/03/10 07:58:10 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ /* SGI audio code was written by Rob Kooper . */ #include "rplayd.h" /* * System audio include files: */ #include #include #include #include #include #include #include /* * External variables: */ extern char *rplay_audio_device; extern int rplay_audio_sample_rate; extern int rplay_audio_channels; extern int rplay_audio_precision; extern int rplay_audio_format; extern int rplay_audio_port; extern int optional_sample_rate; extern int optional_precision; extern int optional_channels; extern int optional_format; extern int optional_port; /* * Internal variables: */ static ALport rplay_audio_fd = NULL; /* * Initialize the audio device. * This routine must set the following external variables: * rplay_audio_sample_rate * rplay_audio_precision * rplay_audio_channels * rplay_audio_format * rplay_audio_port * * and may use the following optional parameters: * optional_sample_rate * optional_precision * optional_channels * optional_format * optional_port * * optional_* variables with values of zero should be ignored. * * Return 0 on success and -1 on error. */ int rplay_audio_init() { ALconfig SGIconfig; long PVbuffer[4]; /* * If the cache directory was not found the errno variable is 1. When * calling ALsetwidth errno was not set to 0 when it was OK, and thus * returned an error. */ errno = 0; /* * Create a new config or use the one of the open port. */ if (rplay_audio_fd == NULL) { SGIconfig = ALnewconfig(); } else { SGIconfig = ALgetconfig(rplay_audio_fd); } if (SGIconfig == NULL) { return -1; } /* * Set the precision and the format. The sgi can also play 24 bits * sample rate. But that is not implemented (yet). */ rplay_audio_precision = optional_precision ? optional_precision : 16; switch (rplay_audio_precision) { case 8: ALsetwidth(SGIconfig, AL_SAMPLE_8); if (errno != 0) { return -1; } break; case 16: ALsetwidth(SGIconfig, AL_SAMPLE_16); if (errno != 0) { return -1; } break; default: return -1; } /* * The format is linear (twoscomp) or float/double. Since float/double * is not understood by rplay it is left out. */ rplay_audio_format = (rplay_audio_precision == 16) ? RPLAY_FORMAT_LINEAR_16 : RPLAY_FORMAT_LINEAR_8; #ifdef AL_SAMPFMT_TWOSCOMP if (ALsetsampfmt(SGIconfig, AL_SAMPFMT_TWOSCOMP) < 0) if (errno != 0) { return -1; } #endif /* * The sgi will work in stereo by default. The 4 channel mode of * the indy's is not (yet) supported. */ rplay_audio_channels = optional_channels ? optional_channels : 2; switch (rplay_audio_channels) { case 1: ALsetchannels(SGIconfig, AL_MONO); if (errno != 0) { return -1; } break; case 2: ALsetchannels(SGIconfig, AL_STEREO); if (errno != 0) { return -1; } break; default: return -1; } /* * Open the audio port. */ rplay_audio_fd = ALopenport("rplayd", "w", SGIconfig); if (rplay_audio_fd == NULL) { return -1; } ALfreeconfig(SGIconfig); /* * Set the sample rate of the output port. This defaults to 44100Khz * which is CD quality! */ rplay_audio_sample_rate = optional_sample_rate ? optional_sample_rate : 44100; PVbuffer[0] = AL_OUTPUT_RATE; PVbuffer[1] = rplay_audio_sample_rate; ALsetparams(AL_DEFAULT_DEVICE, PVbuffer, 2); if (errno != 0) { return -1; } /* * Speaker and headphone(line) is the same. There is also digital but * the volume is fixed there. So only speaker is implemented. */ rplay_audio_port = RPLAY_AUDIO_PORT_SPEAKER; return 0; } /* * Open the audio device. * * Return 0 on success and -1 on error. */ int rplay_audio_open() { if (rplay_audio_init() < 0) { return -1; } return 0; } /* * Is the audio device open? * * Return 1 for true and 0 for false. */ int rplay_audio_isopen() { return rplay_audio_fd != NULL; } /* * Flush the audio device. * * Return 0 on success and -1 on error. */ int rplay_audio_flush() { return 0; } /* * Write nbytes from buf to the audio device. * * Return the number of bytes written on success and -1 on error. */ #ifdef __STDC__ int rplay_audio_write(char *buf, int nbytes) #else int rplay_audio_write(buf, nbytes) char *buf; int nbytes; #endif { int samples; if (rplay_audio_fd == NULL) { if (rplay_audio_open() < 0) { return -1; } } /* * Calculate the number of samples. */ samples = nbytes / (rplay_audio_precision >> 3); /* * Write the samples to the audio port. */ ALwritesamps(rplay_audio_fd, buf, samples); if (errno != 0) { return nbytes; } return -1; } /* * Close the audio device. * * Return 0 on success and -1 on error. */ int rplay_audio_close() { if (rplay_audio_fd != NULL) { ALcloseport(rplay_audio_fd); } rplay_audio_fd = NULL; return 0; } /* * Return the volume of the audio device. * * Return 0-255 or -1 on error. */ int rplay_audio_get_volume() { long PVbuffer[4]; #ifdef FAKE_VOLUME return rplay_audio_volume; #else /* not FAKE_VOLUME */ if (rplay_audio_fd == NULL) { rplay_audio_open(); } if (rplay_audio_fd == NULL) { return -1; } PVbuffer[0] = AL_LEFT_SPEAKER_GAIN; PVbuffer[2] = AL_RIGHT_SPEAKER_GAIN; ALgetparams(AL_DEFAULT_DEVICE, PVbuffer, 4); if (errno != 0) { return -1; } return PVbuffer[1]; #endif /* not FAKE_VOLUME */ } /* * Set the volume of the audio device. * Input should be 0-255. * * Return the volume of the audio device 0-255 or -1. */ #ifdef __STDC__ int rplay_audio_set_volume(int volume) #else int rplay_audio_set_volume(volume) int volume; #endif { long PVbuffer[4]; #ifdef FAKE_VOLUME if (volume < RPLAY_MIN_VOLUME) { volume = RPLAY_MIN_VOLUME; } else if (volume > RPLAY_MAX_VOLUME) { volume = RPLAY_MAX_VOLUME; } rplay_audio_volume = volume; return rplay_audio_volume; #else /* not FAKE_VOLUME */ rplay_audio_volume = 0; if (rplay_audio_fd == NULL) { rplay_audio_open(); } if (rplay_audio_fd == NULL) { return -1; } PVbuffer[0] = AL_LEFT_SPEAKER_GAIN; PVbuffer[1] = volume; PVbuffer[2] = AL_RIGHT_SPEAKER_GAIN; PVbuffer[3] = volume; ALsetparams(AL_DEFAULT_DEVICE, PVbuffer, 4); if (errno != 0) { return -1; } rplay_audio_volume = rplay_audio_get_volume(); return rplay_audio_volume; #endif /* not FAKE_VOLUME */ } rplay-3.3.2/rplayd/audio/audio_sgi.h100644 153 62 2211 6671423022 16023 0ustar boynsstaff/* $Id: audio_sgi.h,v 1.3 1999/03/10 07:58:10 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _audio_sgi_h #define _audio_sgi_h #include "rplay.h" #define RPLAY_AUDIO_DEVICE "/dev/audio" #define RPLAY_AUDIO_TIMEOUT 5 #define RPLAY_AUDIO_FLUSH_TIMEOUT -1 #define RPLAY_AUDIO_RATE 10 #define RPLAY_AUDIO_BYTE_ORDER RPLAY_BIG_ENDIAN #endif /* _audio_sgi_h */ rplay-3.3.2/rplayd/audio/audio_solaris.c100644 153 62 27074 6671423022 16746 0ustar boynsstaff/* $Id: audio_solaris.c,v 1.5 1999/03/10 07:58:10 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #include "rplayd.h" /* * System audio include files: */ #include #include #include #include #include #include #include /* * External variables: */ extern char *rplay_audio_device; extern int rplay_audio_sample_rate; extern int rplay_audio_channels; extern int rplay_audio_precision; extern int rplay_audio_format; extern int rplay_audio_port; extern int optional_sample_rate; extern int optional_precision; extern int optional_channels; extern int optional_format; extern int optional_port; /* * Internal variables: */ static int rplay_audio_fd = -1; static RPLAY_AUDIO_TABLE amd_table[] = { {8000, RPLAY_FORMAT_ULAW, 8, 1}, {0, 0, 0, 0} }; static RPLAY_AUDIO_TABLE dbri_table[] = { {6615, RPLAY_FORMAT_LINEAR_16, 16, 1}, {6615, RPLAY_FORMAT_LINEAR_16, 16, 2}, {8000, RPLAY_FORMAT_ULAW, 8, 1}, {8000, RPLAY_FORMAT_LINEAR_16, 16, 1}, {8000, RPLAY_FORMAT_LINEAR_16, 16, 2}, {9600, RPLAY_FORMAT_LINEAR_16, 16, 1}, {9600, RPLAY_FORMAT_LINEAR_16, 16, 2}, {11025, RPLAY_FORMAT_LINEAR_16, 16, 1}, {11025, RPLAY_FORMAT_LINEAR_16, 16, 2}, {16000, RPLAY_FORMAT_LINEAR_16, 16, 1}, {16000, RPLAY_FORMAT_LINEAR_16, 16, 2}, {18900, RPLAY_FORMAT_LINEAR_16, 16, 1}, {18900, RPLAY_FORMAT_LINEAR_16, 16, 2}, {22050, RPLAY_FORMAT_LINEAR_16, 16, 1}, {22050, RPLAY_FORMAT_LINEAR_16, 16, 2}, {32000, RPLAY_FORMAT_LINEAR_16, 16, 1}, {32000, RPLAY_FORMAT_LINEAR_16, 16, 2}, {33075, RPLAY_FORMAT_LINEAR_16, 16, 1}, {33075, RPLAY_FORMAT_LINEAR_16, 16, 2}, {37800, RPLAY_FORMAT_LINEAR_16, 16, 1}, {37800, RPLAY_FORMAT_LINEAR_16, 16, 2}, {44100, RPLAY_FORMAT_LINEAR_16, 16, 1}, {44100, RPLAY_FORMAT_LINEAR_16, 16, 2}, {48000, RPLAY_FORMAT_LINEAR_16, 16, 1}, {48000, RPLAY_FORMAT_LINEAR_16, 16, 2}, {0, 0, 0, 0} }; /* * Initialize the audio device. * This routine must set the following external variables: * rplay_audio_sample_rate * rplay_audio_precision * rplay_audio_channels * rplay_audio_format * rplay_audio_port * * and may use the following optional parameters: * optional_sample_rate * optional_precision * optional_channels * optional_format * optional_port * * optional_* variables with values of zero should be ignored. * * Return 0 on success and -1 on error. */ int rplay_audio_init() { audio_info_t a; audio_device_t d; if (rplay_audio_fd == -1) { rplay_audio_open(); if (rplay_audio_fd == -1) { report(REPORT_ERROR, "rplay_audio_init: cannot open %s\n", rplay_audio_device); return -1; } } if (ioctl(rplay_audio_fd, AUDIO_GETDEV, &d) < 0) { report(REPORT_ERROR, "rplay_audio_init: AUDIO_GETDEV: %s\n", sys_err_str(errno)); return -1; } if (strcmp(d.name, "SUNW,dbri") == 0) { report(REPORT_DEBUG, "%s device detected\n", d.name); rplay_audio_sample_rate = optional_sample_rate ? optional_sample_rate : 11025; rplay_audio_precision = optional_precision ? optional_precision : 16; rplay_audio_channels = optional_channels ? optional_channels : 1; rplay_audio_format = optional_format ? optional_format : rplay_audio_precision == 16 ? RPLAY_FORMAT_LINEAR_16 : RPLAY_FORMAT_LINEAR_8; rplay_audio_port = optional_port ? optional_port : RPLAY_AUDIO_PORT_LINEOUT | RPLAY_AUDIO_PORT_SPEAKER; rplay_audio_table = dbri_table; } else if (strcmp(d.name, "SUNW,CS4231") == 0) { report(REPORT_DEBUG, "%s device detected\n", d.name); rplay_audio_sample_rate = optional_sample_rate ? optional_sample_rate : 11025; rplay_audio_precision = optional_precision ? optional_precision : 16; rplay_audio_channels = optional_channels ? optional_channels : 1; rplay_audio_format = optional_format ? optional_format : rplay_audio_precision == 16 ? RPLAY_FORMAT_LINEAR_16 : RPLAY_FORMAT_LINEAR_8; rplay_audio_port = optional_port ? optional_port : RPLAY_AUDIO_PORT_LINEOUT | RPLAY_AUDIO_PORT_SPEAKER; rplay_audio_table = dbri_table; /* use the dbri table */ } else if (strcmp(d.name, "SUNW,am79c30") == 0) { report(REPORT_DEBUG, "%s device detected\n", d.name); rplay_audio_sample_rate = optional_sample_rate ? optional_sample_rate : 8000; rplay_audio_precision = optional_precision ? optional_precision : 8; rplay_audio_channels = optional_channels ? optional_channels : 1; rplay_audio_format = optional_format ? optional_format : RPLAY_FORMAT_ULAW; rplay_audio_port = optional_port ? optional_port : RPLAY_AUDIO_PORT_SPEAKER; rplay_audio_table = amd_table; } else if (strcmp(d.name, "SUNW,sb16") == 0) { report(REPORT_DEBUG, "%s device detected\n", d.name); rplay_audio_sample_rate = optional_sample_rate ? optional_sample_rate : 44100; rplay_audio_precision = optional_precision ? optional_precision : 16; rplay_audio_channels = optional_channels ? optional_channels : 2; rplay_audio_format = optional_format ? optional_format : rplay_audio_precision == 16 ? RPLAY_FORMAT_LINEAR_16 : RPLAY_FORMAT_LINEAR_8; rplay_audio_port = optional_port ? optional_port : RPLAY_AUDIO_PORT_LINEOUT | RPLAY_AUDIO_PORT_SPEAKER; rplay_audio_table = dbri_table; /* use the dbri table */ } else { report(REPORT_ERROR, "`%s' unknown audio device detected\n", d.name); return -1; } /* Verify the precision and format. */ switch (rplay_audio_precision) { case 8: if (rplay_audio_format != RPLAY_FORMAT_ULAW && rplay_audio_format != RPLAY_FORMAT_LINEAR_8) { report(REPORT_ERROR, "rplay_audio_init: can't use %d bits with format=%d\n", rplay_audio_precision, rplay_audio_format); return -1; } break; case 16: if (rplay_audio_format != RPLAY_FORMAT_LINEAR_16) { report(REPORT_ERROR, "rplay_audio_init: can't use %d bits with format=%d\n", rplay_audio_precision, rplay_audio_format); return -1; } break; default: report(REPORT_ERROR, "rplay_audio_init: `%d' unsupported audio precision\n", rplay_audio_precision); return -1; } AUDIO_INITINFO(&a); switch (rplay_audio_format) { case RPLAY_FORMAT_ULAW: a.play.encoding = AUDIO_ENCODING_ULAW; break; case RPLAY_FORMAT_LINEAR_8: case RPLAY_FORMAT_LINEAR_16: a.play.encoding = AUDIO_ENCODING_LINEAR; break; default: report(REPORT_ERROR, "rplay_audio_init: unsupported audio format `%d'\n", rplay_audio_format); return -1; } /* Audio port. */ if (rplay_audio_port == RPLAY_AUDIO_PORT_NONE) { a.play.port = ~0; /* see AUDIO_INITINFO in /usr/include/sys/audioio.h. */ } else { a.play.port = 0; if (BIT(rplay_audio_port, RPLAY_AUDIO_PORT_LINEOUT)) { #ifdef AUDIO_LINE_OUT SET_BIT(a.play.port, AUDIO_LINE_OUT); #else CLR_BIT(rplay_audio_port, RPLAY_AUDIO_PORT_LINEOUT); #endif } if (BIT(rplay_audio_port, RPLAY_AUDIO_PORT_HEADPHONE)) { #ifdef AUDIO_HEADPHONE SET_BIT(a.play.port, AUDIO_HEADPHONE); #else CLR_BIT(rplay_audio_port, RPLAY_AUDIO_PORT_HEADPHONE); #endif } if (BIT(rplay_audio_port, RPLAY_AUDIO_PORT_SPEAKER)) { #ifdef AUDIO_SPEAKER SET_BIT(a.play.port, AUDIO_SPEAKER); #endif /* Assume speaker is okay. */ } } a.play.sample_rate = rplay_audio_sample_rate; a.play.precision = rplay_audio_precision; a.play.channels = rplay_audio_channels; if (ioctl(rplay_audio_fd, AUDIO_SETINFO, &a) < 0) { report(REPORT_ERROR, "rplay_audio_init: AUDIO_SETINFO: %s\n", sys_err_str(errno)); return -1; } return 0; } /* * Open the audio device. * * Return 0 on success and -1 on error. */ int rplay_audio_open() { int flags; rplay_audio_fd = open(rplay_audio_device, O_WRONLY | O_NDELAY, 0); if (rplay_audio_fd < 0) { return -1; } if (fcntl(rplay_audio_fd, F_SETFD, 1) < 0) { report(REPORT_ERROR, "rplay_audio_open: close-on-exec %d\n", sys_err_str(errno)); /* return -1; */ } if (rplay_audio_init() < 0) { return -1; } /* * Make sure the audio device writes are non-blocking. */ flags = fcntl(rplay_audio_fd, F_GETFL, 0); if (flags < 0) { return -1; } flags |= FNDELAY; if (fcntl(rplay_audio_fd, F_SETFL, flags) < 0) { return -1; } return 0; } /* * Is the audio device open? * * Return 1 for true and 0 for false. */ int rplay_audio_isopen() { return rplay_audio_fd != -1; } /* * Flush the audio device. * * Return 0 on success and -1 on error. */ int rplay_audio_flush() { if (rplay_audio_fd != -1) { ioctl(rplay_audio_fd, AUDIO_DRAIN, 0); } return 0; } /* * Write nbytes from buf to the audio device. * * Return the number of bytes written on success and -1 on error. */ #ifdef __STDC__ int rplay_audio_write(char *buf, int nbytes) #else int rplay_audio_write(buf, nbytes) char *buf; int nbytes; #endif { int n, nleft, nwritten; char *p; nleft = nbytes; nwritten = 0; for (p = buf; nleft > 0; nleft -= n, p += n) { n = write(rplay_audio_fd, p, nleft); if (n < 0) { if (errno == EWOULDBLOCK) { return nwritten; } else if (errno != EINTR) { return -1; } n = 0; } else { nwritten += n; } } return nwritten; } /* * Close the audio device. * * Return 0 on success and -1 on error. */ int rplay_audio_close() { if (rplay_audio_fd != -1) { close(rplay_audio_fd); } rplay_audio_fd = -1; return 0; } /* * Return the volume of the audio device. * * Return 0-255 or -1 on error. */ int rplay_audio_get_volume() { #ifdef FAKE_VOLUME return rplay_audio_volume; #else /* not FAKE_VOLUME */ audio_info_t a; if (rplay_audio_fd < 0) { rplay_audio_open(); } if (rplay_audio_fd < 0) { return -1; } if (ioctl(rplay_audio_fd, AUDIO_GETINFO, &a) < 0) { return -1; } else { return a.play.gain; } #endif /* not FAKE_VOLUME */ } /* * Set the volume of the audio device. * Input should be 0-255. * * Return the volume of the audio device 0-255 or -1. */ #ifdef __STDC__ int rplay_audio_set_volume(int volume) #else int rplay_audio_set_volume(volume) int volume; #endif { #ifdef FAKE_VOLUME if (volume < RPLAY_MIN_VOLUME) { volume = RPLAY_MIN_VOLUME; } else if (volume > RPLAY_MAX_VOLUME) { volume = RPLAY_MAX_VOLUME; } rplay_audio_volume = volume; return rplay_audio_volume; #else /* not FAKE_VOLUME */ audio_info_t a; rplay_audio_volume = 0; if (rplay_audio_fd < 0) { rplay_audio_open(); } if (rplay_audio_fd < 0) { return -1; } AUDIO_INITINFO(&a); a.play.gain = volume; if (ioctl(rplay_audio_fd, AUDIO_SETINFO, &a) < 0) { return -1; } rplay_audio_volume = rplay_audio_get_volume(); return rplay_audio_volume; #endif /* not FAKE_VOLUME */ } rplay-3.3.2/rplayd/audio/audio_solaris.h100644 153 62 2231 6671423022 16717 0ustar boynsstaff/* $Id: audio_solaris.h,v 1.3 1999/03/10 07:58:10 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _audio_solaris_h #define _audio_solaris_h #include "rplay.h" #define RPLAY_AUDIO_DEVICE "/dev/audio" #define RPLAY_AUDIO_TIMEOUT 5 #define RPLAY_AUDIO_FLUSH_TIMEOUT -1 #define RPLAY_AUDIO_RATE 10 #define RPLAY_AUDIO_BYTE_ORDER RPLAY_BIG_ENDIAN #endif /* _audio_solaris_h */ rplay-3.3.2/rplayd/audio/audio_sun.c100644 153 62 27031 6671423022 16070 0ustar boynsstaff/* $Id: audio_sun.c,v 1.5 1999/03/10 07:58:10 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #include "rplayd.h" /* * System audio include files: */ #include #include #include #include #include #include #include /* * External variables: */ extern char *rplay_audio_device; extern int rplay_audio_sample_rate; extern int rplay_audio_channels; extern int rplay_audio_precision; extern int rplay_audio_format; extern int rplay_audio_port; extern int optional_sample_rate; extern int optional_precision; extern int optional_channels; extern int optional_format; extern int optional_port; /* * Internal variables: */ static int rplay_audio_fd = -1; static RPLAY_AUDIO_TABLE amd_table[] = { {8000, RPLAY_FORMAT_ULAW, 8, 1}, {0, 0, 0, 0} }; static RPLAY_AUDIO_TABLE dbri_table[] = { {6615, RPLAY_FORMAT_LINEAR_16, 16, 1}, {6615, RPLAY_FORMAT_LINEAR_16, 16, 2}, {8000, RPLAY_FORMAT_ULAW, 8, 1}, {8000, RPLAY_FORMAT_LINEAR_16, 16, 1}, {8000, RPLAY_FORMAT_LINEAR_16, 16, 2}, {9600, RPLAY_FORMAT_LINEAR_16, 16, 1}, {9600, RPLAY_FORMAT_LINEAR_16, 16, 2}, {11025, RPLAY_FORMAT_LINEAR_16, 16, 1}, {11025, RPLAY_FORMAT_LINEAR_16, 16, 2}, {16000, RPLAY_FORMAT_LINEAR_16, 16, 1}, {16000, RPLAY_FORMAT_LINEAR_16, 16, 2}, {18900, RPLAY_FORMAT_LINEAR_16, 16, 1}, {18900, RPLAY_FORMAT_LINEAR_16, 16, 2}, {22050, RPLAY_FORMAT_LINEAR_16, 16, 1}, {22050, RPLAY_FORMAT_LINEAR_16, 16, 2}, {32000, RPLAY_FORMAT_LINEAR_16, 16, 1}, {32000, RPLAY_FORMAT_LINEAR_16, 16, 2}, {33075, RPLAY_FORMAT_LINEAR_16, 16, 1}, {33075, RPLAY_FORMAT_LINEAR_16, 16, 2}, {37800, RPLAY_FORMAT_LINEAR_16, 16, 1}, {37800, RPLAY_FORMAT_LINEAR_16, 16, 2}, {44100, RPLAY_FORMAT_LINEAR_16, 16, 1}, {44100, RPLAY_FORMAT_LINEAR_16, 16, 2}, {48000, RPLAY_FORMAT_LINEAR_16, 16, 1}, {48000, RPLAY_FORMAT_LINEAR_16, 16, 2}, {0, 0, 0, 0} }; /* * Initialize the audio device. * This routine must set the following external variables: * rplay_audio_sample_rate * rplay_audio_precision * rplay_audio_channels * rplay_audio_format * rplay_audio_port * * and may use the following optional parameters: * optional_sample_rate * optional_precision * optional_channels * optional_format * optional_port * * optional_* variables with values of zero should be ignored. * * Return 0 on success and -1 on error. */ int rplay_audio_init() { int d; audio_info_t a; if (rplay_audio_fd == -1) { rplay_audio_open(); if (rplay_audio_fd == -1) { report(REPORT_ERROR, "rplay_audio_init: cannot open %s\n", rplay_audio_device); return -1; } } /* * Not all versions of SunOS have dbri support. */ #ifdef AUDIO_GETDEV #ifdef AUDIO_DEV_SPEAKERBOX if (ioctl(rplay_audio_fd, AUDIO_GETDEV, &d) < 0) { report(REPORT_ERROR, "rplay_audio_init: AUDIO_GETDEV: %s\n", sys_err_str(errno)); return -1; } if (d == AUDIO_DEV_SPEAKERBOX || d == AUDIO_DEV_CODEC) { report(REPORT_DEBUG, "dbri device detected\n"); rplay_audio_sample_rate = optional_sample_rate ? optional_sample_rate : 11025; rplay_audio_precision = optional_precision ? optional_precision : 16; rplay_audio_channels = optional_channels ? optional_channels : 1; rplay_audio_format = optional_format ? optional_format : rplay_audio_precision == 16 ? RPLAY_FORMAT_LINEAR_16 : RPLAY_FORMAT_LINEAR_8; rplay_audio_port = optional_port ? optional_port : RPLAY_AUDIO_PORT_LINEOUT | RPLAY_AUDIO_PORT_SPEAKER; rplay_audio_table = dbri_table; } else if (d == AUDIO_DEV_AMD) { report(REPORT_DEBUG, "amd device detected\n"); rplay_audio_sample_rate = optional_sample_rate ? optional_sample_rate : 8000; rplay_audio_precision = optional_precision ? optional_precision : 8; rplay_audio_channels = optional_channels ? optional_channels : 1; rplay_audio_format = optional_format ? optional_format : RPLAY_FORMAT_ULAW; rplay_audio_port = optional_port ? optional_port : RPLAY_AUDIO_PORT_SPEAKER; rplay_audio_table = amd_table; } /* The SS5 AUDIO_GETDEV ioctl returns 5. This value is not in . */ #ifndef AUDIO_DEV_CS4231 #define AUDIO_DEV_CS4231 5 #endif else if (d == AUDIO_DEV_CS4231) { report(REPORT_DEBUG, "cs4231 device detected\n"); rplay_audio_sample_rate = optional_sample_rate ? optional_sample_rate : 11025; rplay_audio_precision = optional_precision ? optional_precision : 16; rplay_audio_channels = optional_channels ? optional_channels : 1; rplay_audio_format = optional_format ? optional_format : rplay_audio_precision == 16 ? RPLAY_FORMAT_LINEAR_16 : RPLAY_FORMAT_LINEAR_8; rplay_audio_port = optional_port ? optional_port : RPLAY_AUDIO_PORT_LINEOUT | RPLAY_AUDIO_PORT_SPEAKER; rplay_audio_table = dbri_table; } else #endif /* not AUDIO_DEV_SPEAKERBOX */ #endif /* not AUDIO_GETDEV */ { report(REPORT_DEBUG, "assuming amd device\n"); rplay_audio_sample_rate = optional_sample_rate ? optional_sample_rate : 8000; rplay_audio_precision = optional_precision ? optional_precision : 8; rplay_audio_channels = optional_channels ? optional_channels : 1; rplay_audio_format = optional_format ? optional_format : RPLAY_FORMAT_ULAW; rplay_audio_port = optional_port ? optional_port : RPLAY_AUDIO_PORT_SPEAKER; rplay_audio_table = amd_table; } /* Verify the precision and format. */ switch (rplay_audio_precision) { case 8: if (rplay_audio_format != RPLAY_FORMAT_ULAW && rplay_audio_format != RPLAY_FORMAT_LINEAR_8) { report(REPORT_ERROR, "rplay_audio_init: can't use %d bits with format=%d\n", rplay_audio_precision, rplay_audio_format); return -1; } break; case 16: if (rplay_audio_format != RPLAY_FORMAT_LINEAR_16) { report(REPORT_ERROR, "rplay_audio_init: can't use %d bits with format=%d\n", rplay_audio_precision, rplay_audio_format); return -1; } break; default: report(REPORT_ERROR, "rplay_audio_init: `%d' unsupported audio precision\n", rplay_audio_precision); return -1; } AUDIO_INITINFO(&a); switch (rplay_audio_format) { case RPLAY_FORMAT_ULAW: a.play.encoding = AUDIO_ENCODING_ULAW; break; case RPLAY_FORMAT_LINEAR_8: case RPLAY_FORMAT_LINEAR_16: a.play.encoding = AUDIO_ENCODING_LINEAR; break; default: report(REPORT_ERROR, "rplay_audio_init: unsupported audio format `%d'\n", rplay_audio_format); return -1; } /* Audio port. */ if (rplay_audio_port == RPLAY_AUDIO_PORT_NONE) { a.play.port = ~0; /* see AUDIO_INITINFO in /usr/include/sun/audioio.h. */ } else { a.play.port = 0; if (BIT(rplay_audio_port, RPLAY_AUDIO_PORT_LINEOUT)) { #ifdef AUDIO_LINE_OUT SET_BIT(a.play.port, AUDIO_LINE_OUT); #else CLR_BIT(rplay_audio_port, RPLAY_AUDIO_PORT_LINEOUT); #endif } if (BIT(rplay_audio_port, RPLAY_AUDIO_PORT_HEADPHONE)) { #ifdef AUDIO_HEADPHONE SET_BIT(a.play.port, AUDIO_HEADPHONE); #else CLR_BIT(rplay_audio_port, RPLAY_AUDIO_PORT_HEADPHONE); #endif } if (BIT(rplay_audio_port, RPLAY_AUDIO_PORT_SPEAKER)) { #ifdef AUDIO_SPEAKER SET_BIT(a.play.port, AUDIO_SPEAKER); #endif /* Assume speaker is okay. */ } } a.play.sample_rate = rplay_audio_sample_rate; a.play.precision = rplay_audio_precision; a.play.channels = rplay_audio_channels; if (ioctl(rplay_audio_fd, AUDIO_SETINFO, &a) < 0) { report(REPORT_ERROR, "rplay_audio_init: AUDIO_SETINFO: %s\n", sys_err_str(errno)); return -1; } return 0; } /* * Open the audio device. * * Return 0 on success and -1 on error. */ int rplay_audio_open() { int flags; rplay_audio_fd = open(rplay_audio_device, O_WRONLY | O_NDELAY, 0); if (rplay_audio_fd < 0) { return -1; } if (fcntl(rplay_audio_fd, F_SETFD, 1) < 0) { report(REPORT_ERROR, "rplay_audio_open: close-on-exec %d\n", sys_err_str(errno)); /* return -1; */ } if (rplay_audio_init() < 0) { return -1; } /* * Make sure the audio device writes are non-blocking. */ flags = fcntl(rplay_audio_fd, F_GETFL, 0); if (flags < 0) { return -1; } flags |= FNDELAY; if (fcntl(rplay_audio_fd, F_SETFL, flags) < 0) { return -1; } return 0; } /* * Is the audio device open? * * Return 1 for true and 0 for false. */ int rplay_audio_isopen() { return rplay_audio_fd != -1; } /* * Flush the audio device. * * Return 0 on success and -1 on error. */ int rplay_audio_flush() { if (rplay_audio_fd != -1) { ioctl(rplay_audio_fd, AUDIO_DRAIN, 0); } return 0; } /* * Write nbytes from buf to the audio device. * * Return the number of bytes written on success and -1 on error. */ #ifdef __STDC__ int rplay_audio_write(char *buf, int nbytes) #else int rplay_audio_write(buf, nbytes) char *buf; int nbytes; #endif { int n, nleft, nwritten; char *p; nleft = nbytes; nwritten = 0; for (p = buf; nleft > 0; nleft -= n, p += n) { n = write(rplay_audio_fd, p, nleft); if (n < 0) { if (errno == EWOULDBLOCK) { return nwritten; } else if (errno != EINTR) { return -1; } n = 0; } else { nwritten += n; } } return nwritten; } /* * Close the audio device. * * Return 0 on success and -1 on error. */ int rplay_audio_close() { if (rplay_audio_fd != -1) { close(rplay_audio_fd); } rplay_audio_fd = -1; return 0; } /* * Return the volume of the audio device. * * Return 0-255 or -1 on error. */ int rplay_audio_get_volume() { #ifdef FAKE_VOLUME return rplay_audio_volume; #else /* not FAKE_VOLUME */ audio_info_t a; if (rplay_audio_fd < 0) { rplay_audio_open(); } if (rplay_audio_fd < 0) { return -1; } if (ioctl(rplay_audio_fd, AUDIO_GETINFO, &a) < 0) { return -1; } else { return a.play.gain; } #endif /* not FAKE_VOLUME */ } /* * Set the volume of the audio device. * Input should be 0-255. * * Return the volume of the audio device 0-255 or -1. */ #ifdef __STDC__ int rplay_audio_set_volume(int volume) #else int rplay_audio_set_volume(volume) int volume; #endif { #ifdef FAKE_VOLUME if (volume < RPLAY_MIN_VOLUME) { volume = RPLAY_MIN_VOLUME; } else if (volume > RPLAY_MAX_VOLUME) { volume = RPLAY_MAX_VOLUME; } rplay_audio_volume = volume; return rplay_audio_volume; #else /* not FAKE_VOLUME */ audio_info_t a; rplay_audio_volume = 0; if (rplay_audio_fd < 0) { rplay_audio_open(); } if (rplay_audio_fd < 0) { return -1; } AUDIO_INITINFO(&a); a.play.gain = volume; if (ioctl(rplay_audio_fd, AUDIO_SETINFO, &a) < 0) { return -1; } rplay_audio_volume = rplay_audio_get_volume(); return rplay_audio_volume; #endif /* not FAKE_VOLUME */ } rplay-3.3.2/rplayd/audio/audio_sun.h100644 153 62 2211 6671423022 16046 0ustar boynsstaff/* $Id: audio_sun.h,v 1.3 1999/03/10 07:58:10 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _audio_sun_h #define _audio_sun_h #include "rplay.h" #define RPLAY_AUDIO_DEVICE "/dev/audio" #define RPLAY_AUDIO_TIMEOUT 5 #define RPLAY_AUDIO_FLUSH_TIMEOUT -1 #define RPLAY_AUDIO_RATE 10 #define RPLAY_AUDIO_BYTE_ORDER RPLAY_BIG_ENDIAN #endif /* _audio_sun_h */ rplay-3.3.2/rptp/ 40755 153 62 0 6727650101 12211 5ustar boynsstaffrplay-3.3.2/rptp/Makefile.in100644 153 62 2024 6727404544 14361 0ustar boynsstaffinclude @RPLAY_TOP@/Makefile.config srcdir = @srcdir@ VPATH = @srcdir@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ MKINSTALLDIRS= @srcdir@/../mkinstalldirs CPPFLAGS= $(CC_OPTIONS) -I. -I../include -I@srcdir@/../include -I@srcdir@/../lib @DEFS@ .c.o: $(CC) -c $(CPPFLAGS) $(CFLAGS) $< LDFLAGS= $(LD_OPTIONS) -L../librplay -lrplay -L../lib -lrp @LDFLAGS@ @RL_LIBS@ @LIBS@ TARGET= rptp SRCS= rptp.c OBJS= rptp.o all: $(TARGET) $(TARGET): $(OBJS) ../librplay/$(LIBRPLAY_NAME) ../lib/librp.a $(CC) -o $@ $(OBJS) $(LDFLAGS) ../librplay/$(LIBRPLAY_NAME): (cd ../librplay; $(MAKE) $(MFLAGS)) ../lib/librp.a: (cd ../lib; $(MAKE) $(MFLAGS)) install: all $(MKINSTALLDIRS) $(bindir) $(INSTALL_PROGRAM) $(TARGET) $(bindir)/$(TARGET) uninstall: $(RM) $(bindir)/$(TARGET) clean: $(RM) $(OBJS) $(TARGET) a.out core *~ *.bak *.orig TAGS distclean: clean $(RM) Makefile tags: $(TAGS) *.[ch] TAGS: tags etags: tags depend: $(MAKEDEPEND) -- $(CPPFLAGS) $(CFLAGS) -- $(SRCS) rplay-3.3.2/rptp/rptp.c100644 153 62 50250 6675040424 13464 0ustar boynsstaff/* $Id: rptp.c,v 1.6 1999/03/21 00:45:08 boyns Exp $ */ /* * Copyright (C) 1993-99 Mark R. Boyns * * This file is part of rplay. * * rplay is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * rplay is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rplay; see the file COPYING. If not, write to the * Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "version.h" #include #include #include #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_LIBREADLINE #include #include #endif /* HAVE_LIBREADLINE */ #include "rplay.h" #include "getopt.h" typedef struct { char *name; int min_args; int max_args; char *usage; #ifdef __STDC__ void (*func) (int argc, char **argv); #else void (*func) (); #endif } COMMAND; #ifdef __STDC__ void command_open(int argc, char **argv); void command_close(int argc, char **argv); void command_play(int argc, char **argv); void command_help(int argc, char **argv); void command_list(int argc, char **argv); void command_quit(int argc, char **argv); void command_put(int argc, char **argv); void command_get(int argc, char **argv); void command_unknown(int argc, char **argv); void command_set(int argc, char **argv); void command_status(int argc, char **argv); void command_generic(int argc, char **argv); void command_volume(int argc, char **argv); void command_skip(int argc, char **argv); void command_set(int argc, char **argv); void command_monitor(int argc, char **argv); void argv_to_command(char **argv); int connected(); void done(int exit_value); void usage(); void do_application(); void do_error(char *repsonse); #else void command_open( /* int argc, char **argv */ ); void command_close( /* int argc, char **argv */ ); void command_play( /* int argc, char **argv */ ); void command_help( /* int argc, char **argv */ ); void command_list( /* int argc, char **argv */ ); void command_quit( /* int argc, char **argv */ ); void command_put( /* int argc, char **argv */ ); void command_get( /* int argc, char **argv */ ); void command_unknown( /* int argc, char **argv */ ); void command_status( /* int argc, char **argv */ ); void command_generic( /* int argc, char **argv */ ); void command_volume( /* int argc, char **argv */ ); void command_skip( /* int argc, char **argv */ ); void command_set( /* int argc, char **argv */ ); void command_monitor( /* int argc, char **argv */ ); void argv_to_command( /* char **argv */ ); int connected(); void done( /* int exit_value */ ); void usage(); void do_application(); void do_error( /* char *repsonse */ ); #endif COMMAND commands[] = { "access", 0, 0, "", command_generic, "close", 0, 0, "", command_close, "continue", 1, -1, "#id|sound ...", command_play, "find", 1, 1, "sound", command_generic, "get", 1, 2, "sound [filename]", command_get, "help", 0, 1, "[command]", command_help, "info", 1, 1, "sound", command_generic, "list", 0, 1, "[connections|hosts|servers|spool|sounds]", command_list, "monitor", 0, 0, "", command_monitor, "open", 1, 2, "hostname [port]", command_open, "pause", 1, -1, "#id|sound ...", command_play, "play", 1, -1, "[options] sound ...", command_play, "put", 1, 1, "sound", command_put, "quit", 0, 0, "", command_quit, "reset", 0, 0, "", command_generic, "set", 1, -1, "name=value", command_set, "skip", 0, 2, "[#id] [[+|-]count]", command_skip, "status", 0, 0, "", command_status, "stop", 1, -1, "#id|sound ...", command_play, "version", 0, 0, "", command_generic, "volume", 0, 1, "[[+|-]volume]", command_volume, "wait", 1, -1, "#id|command|event-list", command_generic, }; #define NCOMMANDS (sizeof(commands)/sizeof(COMMAND)) static struct option longopts[] = { {"help", no_argument, NULL, 1}, {"host", required_argument, NULL, 'h'}, {"port", required_argument, NULL, 'p'}, {"prompt", required_argument, NULL, 2}, {"raw", no_argument, NULL, 'r'}, {"version", no_argument, NULL, 'v'}, {NULL, 0, NULL, 0} }; int rptp_fd = -1; char rptp_buf[4096]; char command[RPTP_MAX_LINE]; char response[RPTP_MAX_LINE]; char *prompt = "rptp> "; int interactive = 1; int raw = 0; extern int optind; extern char *optarg; #ifdef __STDC__ main(int argc, char **argv) #else main(argc, argv) int argc; char **argv; #endif { char buf[256]; int i; int port = RPTP_PORT; int c; char *av[RPTP_MAX_ARGS], *p, *host = NULL; int ac, first; char numeric_string[128]; while ((c = getopt_long(argc, argv, "+h:p:rv", longopts, 0)) != -1) { switch (c) { case 0: /* getopt has processed a long-named option -- do nothing */ break; case 1: /* --help */ usage(); done(0); case 2: /* --prompt */ prompt = optarg; break; case 'h': host = optarg; break; case 'p': port = atoi(optarg); break; case 'r': raw++; break; case 'v': printf("rplay %s\n", RPLAY_VERSION); done(0); default: fprintf(stderr, "Try `rptp --help' for more information.\n"); exit(1); } } if (optind != argc) { interactive = 0; } if (host == NULL) { host = rplay_default_host(); } rptp_fd = rptp_open(host, port, response, sizeof(response)); if (rptp_fd < 0) { rptp_perror("open"); } else if (interactive) { if (raw) { printf("%s\n", response); } else { if (strchr(response, '=')) { rptp_parse(response, 0); printf("%s rplayd %s connected\n", rptp_parse(0, "host"), rptp_parse(0, "version")); } else { printf("Connected to %s port %d.\n", host, port); printf("%s\n", response + 1); } } } do_application(); do { if (interactive) { if (!raw) { #ifdef HAVE_LIBREADLINE p = readline(prompt); if (!p) { done(0); } add_history(p); strcpy(buf, p); #else printf(prompt); fflush(stdout); #endif } #ifndef HAVE_LIBREADLINE if (fgets(buf, sizeof(buf), stdin) == NULL) { done(0); } #endif first = 1; ac = 0; while ((p = strtok(first ? buf : NULL, " \t\r\n"))) { av[ac++] = p; first = 0; } av[ac] = NULL; } else { int i; ac = 0; for (i = optind; i < argc; i++) { av[ac++] = argv[i]; } av[ac] = NULL; } if (av[0] == NULL) { continue; } for (i = 0; i < NCOMMANDS; i++) { if (strcasecmp(commands[i].name, av[0]) == 0) { if ((commands[i].min_args >= 0 && ac - 1 < commands[i].min_args) || (commands[i].max_args >= 0 && ac - 1 > commands[i].max_args)) { printf("Usage: %s %s\n", commands[i].name, commands[i].usage); } else { (*commands[i].func) (ac, av); } break; } } if (i == NCOMMANDS) { command_unknown(ac, av); } } while (interactive); done(0); } #ifdef __STDC__ void argv_to_command(char **argv) #else void argv_to_command(argv) char **argv; #endif { command[0] = '\0'; for (; *argv; argv++) { strcat(command, *argv); if (*(argv + 1)) { strcat(command, " "); } } } int connected() { if (rptp_fd != -1) { return 1; } else { printf("You're not connected, use `open' first.\n"); return 0; } } #ifdef __STDC__ void command_open(int argc, char **argv) #else void command_open(argc, argv) int argc; char **argv; #endif { int port; if (rptp_fd != -1) { printf("You're already connected, use `close' first.\n"); } else { port = argc == 3 ? atoi(argv[2]) : RPTP_PORT; rptp_fd = rptp_open(argv[1], port, response, sizeof(response)); if (rptp_fd < 0) { rptp_perror("open"); } else { if (raw) { printf("%s\n", response); } else { if (strchr(response, '=')) { printf("%s rplayd %s connected\n", rptp_parse(response, "host"), rptp_parse(0, "version")); } else { printf("Connected to %s port %d.\n", argv[1], port); printf("%s\n", response + 1); } } do_application(); } } } #ifdef __STDC__ void command_close(int argc, char **argv) #else void command_close(argc, argv) int argc; char **argv; #endif { if (connected()) { rptp_close(rptp_fd); rptp_fd = -1; if (interactive) { printf("Connection closed.\n"); } } } #ifdef __STDC__ void command_play(int argc, char **argv) #else void command_play(argc, argv) int argc; char **argv; #endif { argv_to_command(argv); if (!connected()) { return; } switch (rptp_command(rptp_fd, command, response, sizeof(response))) { case -1: rptp_perror(argv[0]); command_close(argc, argv); return; case 1: do_error(response); return; case 0: break; } if (raw) { printf("%s\n", response); } } #ifdef __STDC__ void command_generic(int argc, char **argv) #else void command_generic(argc, argv) int argc; char **argv; #endif { argv_to_command(argv); if (!connected()) { return; } switch (rptp_command(rptp_fd, command, response, sizeof(response))) { case -1: rptp_perror(argv[0]); command_close(argc, argv); return; case 1: do_error(response); return; case 0: break; } printf("%s\n", raw ? response : response + 1); } #ifdef __STDC__ void command_help(int argc, char **argv) #else void command_help(argc, argv) int argc; char **argv; #endif { int i; if (argc == 2) { for (i = 0; i < NCOMMANDS; i++) { if (strcasecmp(commands[i].name, argv[1]) == 0) { printf("Usage: %s %s\n", commands[i].name, commands[i].usage); return; } } command_unknown(argc, argv); } else { printf("access Display remote access permissions.\n"); printf("close Close the current server connection.\n"); printf("continue Continue paused sounds.\n"); printf("find Search for a sound.\n"); printf("get Retrieve a sound.\n"); printf("help Display help information.\n"); printf("info Display sound information.\n"); printf("list Display various server information.\n"); printf("open Connect to a server.\n"); printf("pause Pause sounds that are playing.\n"); printf("play Play sounds\n"); printf("put Send a sound.\n"); printf("quit Terminate the rptp session.\n"); printf("reset Tell the server to reset itself.\n"); printf("set Change server settings.\n"); printf("skip Skip sounds in a sound list.\n"); printf("status Display server statistics.\n"); printf("stop Stop sounds that are playing.\n"); printf("version Display the version of the server.\n"); printf("volume Get and set the volume of the audio device.\n"); printf("wait Wait for a spool id, volume change, or command execution.\n"); } } #ifdef __STDC__ void command_list(int argc, char **argv) #else void command_list(argc, argv) int argc; char **argv; #endif { int n; if (!connected()) { return; } argv_to_command(argv); switch (rptp_command(rptp_fd, command, response, sizeof(response))) { case -1: rptp_perror(argv[0]); command_close(argc, argv); return; case 1: do_error(response); return; case 0: if (raw) { printf("%s\n", response); } break; } for (;;) { n = rptp_getline(rptp_fd, rptp_buf, sizeof(rptp_buf)); if (n < 0) { rptp_perror("list"); command_close(argc, argv); break; } if (strcmp(rptp_buf, ".") == 0) { if (raw) { printf("%s\n", rptp_buf); } break; } printf("%s\n", rptp_buf); } } #ifdef __STDC__ void command_quit(int argc, char **argv) #else void command_quit(argc, argv) int argc; char **argv; #endif { if (rptp_fd != -1) { rptp_close(rptp_fd); printf("Connection closed.\n"); } done(0); } #ifdef __STDC__ void command_put(int argc, char **argv) #else void command_put(argc, argv) int argc; char **argv; #endif { FILE *fp; int size, n, nwritten; struct stat st; char line[RPTP_MAX_LINE]; int total_size; if (!connected()) { return; } if (stat(argv[1], &st) < 0) { perror(argv[1]); return; } fp = fopen(argv[1], "r"); if (fp == NULL) { perror(argv[1]); return; } size = st.st_size; sprintf(line, "put sound=%s size=%d", argv[1], size); switch (rptp_command(rptp_fd, line, response, sizeof(response))) { case -1: rptp_perror(argv[0]); command_close(argc, argv); return; case 1: do_error(response); return; case 0: break; } if (raw) { printf("%s\n", response); } total_size = size; while (size > 0) { n = fread(rptp_buf, 1, sizeof(rptp_buf), fp); nwritten = rptp_write(rptp_fd, rptp_buf, n); if (nwritten != n) { rptp_perror("put"); command_close(argc, argv); break; } size -= nwritten; sprintf(line, "\r%s %d/%d %d%%", argv[1], total_size - size, total_size, (int)(((float)(total_size-size)/total_size)*100)); write(2, line, strlen(line)); } write(2, "\n", 1); fclose(fp); } #ifdef __STDC__ void command_get(int argc, char **argv) #else void command_get(argc, argv) int argc; char **argv; #endif { FILE *fp; char *filename; char *p; int size, n, nread, total_size; char line[RPTP_MAX_LINE]; if (!connected()) { return; } if (argc == 3) { filename = argv[2]; argv[2] = NULL; } else { filename = argv[1]; } sprintf(line, "get sound=%s", argv[1]); switch (rptp_command(rptp_fd, line, response, sizeof(response))) { case -1: rptp_perror(argv[0]); command_close(argc, argv); return; case 1: do_error(response); return; case 0: break; } if (raw) printf("%s\n", response); fp = fopen(filename, "w"); if (fp == NULL) { perror(filename); return; } if (strchr(response, '=')) { size = atoi(rptp_parse(response, "size")); } else { p = strtok(response + 1, " "); size = atoi(strtok(NULL, "\r\n")); } total_size = size; while (size > 0) { n = MIN(sizeof(rptp_buf), size); nread = rptp_read(rptp_fd, rptp_buf, n); if (nread != n) { rptp_perror("get"); break; } fwrite(rptp_buf, 1, n, fp); size -= n; sprintf(line, "\r%s %d/%d %d%%", filename, total_size - size, total_size, (int)(((float)(total_size-size)/total_size)*100)); write(2, line, strlen(line)); } write(2, "\n", 1); fclose(fp); } #ifdef __STDC__ void command_unknown(int argc, char **argv) #else void command_unknown(argc, argv) int argc; char **argv; #endif { printf("unknown command `%s'.\n", argv[0]); } #ifdef __STDC__ void command_status(int argc, char **argv) #else void command_status(argc, argv) int argc; char **argv; #endif { argv_to_command(argv); if (!connected()) { return; } switch (rptp_command(rptp_fd, command, response, sizeof(response))) { case -1: rptp_perror(argv[0]); command_close(argc, argv); return; case 1: do_error(response); return; case 0: break; } if (raw) { printf("%s\n", response); } else { int first = 1; char *name, *value; while (name = rptp_parse(first ? response : 0, 0)) { first = 0; value = rptp_parse(0, name); printf("%s=%s\n", name, value); } } } #ifdef __STDC__ void command_volume(int argc, char **argv) #else void command_volume(argc, argv) int argc; char **argv; #endif { char *volume; if (!connected()) { return; } if (argc == 2) { sprintf(command, "set volume=%s", argv[1]); } else { sprintf(command, "set volume"); } switch (rptp_command(rptp_fd, command, response, sizeof(response))) { case -1: rptp_perror(argv[0]); command_close(argc, argv); return; case 1: do_error(response); return; case 0: break; } volume = rptp_parse(response, "volume"); if (volume && *volume) { printf("volume=%s\n", volume); } else { printf("unknown response `%s'\n", response); } } #ifdef __STDC__ void command_skip(int argc, char **argv) #else void command_skip(argc, argv) int argc; char **argv; #endif { char *value; if (!connected()) { return; } if (strchr(command, '=')) { /* Leave command alone. */ } else if (argc == 3) { sprintf(command, "skip id=%s count=%s", argv[1], argv[2]); } else if (argc == 2) { sprintf(command, "skip id=%s count=1", argv[1]); } else { sprintf(command, "skip id=#0 count=1"); } switch (rptp_command(rptp_fd, command, response, sizeof(response))) { case -1: rptp_perror(argv[0]); command_close(argc, argv); return; case 1: do_error(response); return; case 0: break; } value = rptp_parse(response, "message"); if (value && *value) { printf("%s\n", value); } else { printf("unknown response `%s'\n", response); } } #ifdef __STDC__ void command_set(int argc, char **argv) #else void command_set(argc, argv) int argc; char **argv; #endif { char *value; if (!connected()) { return; } argv_to_command(argv); switch (rptp_command(rptp_fd, command, response, sizeof(response))) { case -1: rptp_perror(argv[0]); command_close(argc, argv); return; case 1: do_error(response); return; case 0: break; } } #ifdef __STDC__ void command_monitor(int argc, char **argv) #else void command_monitor(argc, argv) int argc; char **argv; #endif { char *value, *p; char buf[8192]; char line[80]; int n, size; int sample_rate, precision, channels, sample_size; if (!connected()) { return; } sprintf(command, "monitor"); switch (rptp_command(rptp_fd, command, response, sizeof(response))) { case -1: rptp_perror(argv[0]); command_close(argc, argv); return; case 1: do_error(response); return; case 0: break; } p = strtok(rptp_parse(response, "audio-info"), ","); // input_format p = strtok(NULL, ","); if (p) sample_rate = atoi(p); p = strtok(NULL, ","); if (p) precision = atoi(p); p = strtok(NULL, ","); if (p) channels = atoi(p); sample_size = precision/8 * channels; fprintf(stderr, "%dhz %dbit %s\n", sample_rate, precision, channels == 2 ? "stereo" : "mono"); while ((n = read(rptp_fd, buf, sizeof(buf))) > 0) { write(1, buf, n); size += n; } close(rptp_fd); } void do_application() { sprintf(command, "set application=\"rptp %s\"", RPLAY_VERSION); switch (rptp_command(rptp_fd, command, response, sizeof(response))) { case -1: rptp_perror("application"); rptp_close(rptp_fd); rptp_fd = -1; return; case 1: do_error(response); return; case 0: break; } } #ifdef __STDC__ void do_error(char *response) #else void do_error(response) char *response; #endif { if (raw) { printf("%s\n", response); } else { char *error; error = rptp_parse(response, "error"); if (!error || !*error) { error = response; } printf("%s\n", error); } } void usage() { printf("\nrplay %s\n\n", RPLAY_VERSION); printf("usage: rptp [options] [command]\n"); printf("--help\n"); printf("\tDisplay helpful information.\n"); printf("\n"); printf("-h HOST, --host=HOST\n"); printf("\tSpecify the RPTP host, default = %s.\n", rplay_default_host()); printf("\n"); printf("-p PORT, --port=PORT\n"); printf("\tUse PORT instead of the default RPTP port, default = %d.\n", RPTP_PORT); printf("\n"); printf("-r, --raw\n"); printf("\tEnable raw RPTP mode.\n"); printf("\n"); printf("-v, --version\n"); printf("\tDisplay rplay version information.\n"); } #ifdef __STDC__ void done(int exit_value) #else void done(exit_value) int exit_value; #endif { exit(exit_value); } rplay-3.3.2/rx/ 40755 153 62 0 6727650102 11656 5ustar boynsstaffrplay-3.3.2/rx/COPYING.LIB100644 153 62 61261 6552756455 13457 0ustar boynsstaff GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library, or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Library General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! rplay-3.3.2/rx/ChangeLog100644 153 62 24370 6552756455 13571 0ustar boynsstaffWed Jan 15 12:00:38 1997 Tom Lord * rxsuper.c (rx_superset_cons): reference count tweak. * rxnode.c (rx_rexp_equal): fixed test for equality of interval expressions. * rxgnucomp.h (enum RE_SYNTAX_BITS): turned the syntax bits from "#define" into "enum" to ease debugging. Mon Jan 13 10:07:39 1997 Tom Lord * rxsuper.c (rx_superset_cons): While hash_store will protect cdr itself it might first allocate hash tables and stuff which might cause it to be garbage collected before it's protected -- (from Greg Stark) * rxgnucomp.c (isa_blank): Test for ==, not != '\t'. (from Andreas Schwab) Tue Dec 3 00:33:27 1996 Tom Lord * rxposix.c (regnexec): When testing to consider freeing REGS, watch out for PMATCH == NULL. * rxspencer.c (rx_next_solution): In case r_parens: Before trying to match a parenthesized subexpression, restore the corresponding regs to their value prior to attempting the match. If the match finally fails, be sure sure to restore the old values then, too. Mon Dec 2 00:52:06 1996 Tom Lord * rxspencer.c (rx_next_solution): After "star_try_next_left_match:"... Only return yes from a star expression whose subexpression fails if the target string has 0 length. * rxposix.c (regnexec, regncomp): reversed the order of the string and string-length arguments to be more like other functions (e.g. strncmp). (Suggested by Mike Haertel) * inst-rxposix.h, rxgnucomp.h (REG_E*): moved declarations of POSIX error codes into the posix header file. * rxgnucomp.c (rx_parse): Don't permit a backreference to an enclosing subexpression. This change returns some code that was bogusly deleted somewhere along the line. This fixes a bug that causes a pattern such as: ((.*)\1)x to core dump. (Reported by Mike Haertel) Sun Nov 24 04:24:13 1996 Tom Lord * rxposix.c (rx_regexec): Added a new optimization that generalizes the fastmap. The new optimization is applied if the length of the string exceeds RX_MANY_CASES. Fri Nov 8 09:07:14 1996 Tom Lord * rxsuper.h (RX_DEFAULT_DFA_CACHE_SIZE): * rxbasic.h (RX_DEFAULT_NFA_DELAY): New macros so these values can be set at compile time. Tue Nov 5 09:37:03 1996 Tom Lord * rxspencer.c (rx_make_solutions): watch out for solns->exp == NULL. Eric Johnson (johnsone@uiuc.edu) detected this bug and also performed useful testing of Rx memory management. Tue Jun 18 11:44:46 1996 Tom Lord * rxanal.c (rx_start_superstate): Don't release an old superstate unless it is known that the new superstate has been successfully constructed. Thu Jun 13 11:18:25 1996 Tom Lord * rxspencer.c etc. (rx_next_solution et al.): remove all traces of rx_maybe Wed May 22 12:28:22 1996 Tom Lord * rxanal.c (rx_start_superstate): Preserve the invariant that a locked superstate is never semifree. Fri May 17 10:21:26 1996 Tom Lord * rgx.c (scm_regexec): added match data support for "#\c" -- the final_tag of the match (for the cut operator). * rxspencer.c (rx_next_solution): propogate is_final data up through the tree of solution streams. * rxnfa.h (struct rx_nfa_state): unsigned int is_final:1 => int is_final for the cut operator. * rxanal.c (rx_match_here_p): * rxanal.c (rx_fit_p): * rxanal.c (rx_longest): When a final state is detected, propogate the value of the is_final flag back to the caller. It may contain data generated by a "cut" operator. * rxsuper.c (superset_allocator): when marking a superset final, mark it with the maximum of the is_final fields of the constituent nfa states (for the "cut" operator which allows users to set that value). * rxgnucomp.c (rx_parse): Replace "[[:set...:]]" with "[[:cut n:]]". cut is regular but set is not, so cut leads to much faster running patterns. * rxnfa.c (rx_build_nfa): compile r_cut nodes. r_cut nodes match the empty string and nothing more. A parameter to the cut node determines whether the empty match leads to a final state, or to a failure. * rx.c (rx_free_rx): * rxsuper.c (release_superset_low): * rxanal.c (rx_start_superstate): fixed the test for a cached starting superset to reflect the simplified memory management of `struct rx' (they are now explicitly freed using rx_free_rx) and `struct rx_superset' (they are now ultimately freed using free and not kept on a free-list). Now the `start_set' field of a `struct rx' is only non-0 if it is valid. Tue May 14 08:56:22 1996 Tom Lord * rxspencer.h (typedef rx_contextfn): take an entire expression tree instead of just a context type since for some context types, parameters in the tree matter ([[:set...:]]) * rxstr.c (rx_str_contextfn): handle [[:set...:]] operator. * rxgnucomp.c (rx_parse): added the [[:set n = x:]] construct to make it easier to lex using regexps. * rxposix.c (regnexec): "This pattern (with 10 subexpressions and 9 backreferences) made no entries in a match array of size 5." (from doug@plan9.att.com) * rxgnucomp.c (rx_parse): new compilation state variable: last_non_regular_expression When compiling, keep track of two, not one point in the tree for concatenating new nodes. The *last_non_regular_expression point is always the same as the *last_expression or is a parent of that node. Concatenations of regular constructs happen at last_expression, others at last_non_regular_expression. The resulting trees have "observable" constructs clustered near the root of the tree which allows those optimizations that apply only to regular subtrees to have a greater impact on overall performance. * rxspencer.c (rx_next_solution): interval satisfaction test was wrong. * rxanal.c (rx_posix_analyze_rexp): An interval is always observed (not truly a regular expression). * rxstr.c (rx_str_contextfn): "when you're doing back-reference matching case insensitively (with REG_ICASE set), you are supposed to also do the BR matching without paying attention to case. Mon May 13 09:59:48 1996 Tom Lord * rxspencer.c (rx_next_solution): Don't construct an NFA when comparing an r_string to some text -- just do a strcmp-like operation. * rxgnucomp.c (rx_parse): new variable: n_members An array keeping track of the size of csets generated by inverting the translation table. (rx_parse): validate_inv_tr and n_members were way to big -- each only needs CHAR_SET_SIZE elements. Mon May 13 09:29:42 1996 Zachary Weinberg * rxnode.c (rx_init_string): New data structure for strings -- part of the overall support for constant string optimization. * rxnode.c (rx_mk_r_str etc.): a new type of rexp-node -- an abbreviation for a concatenation of characters. * rxdbug.c (print_rexp): Added support for printing r_str nodes. * rxgnucomp.c (rx_parse): initial support for constant strings. Wed Jan 31 19:59:46 1996 Preston L. Bannister Changes to compile clean under MSVC 4.0 (w/o warnings). Added makefile for MSVC 4.0 (librx.mak). [! Changes marked *** were made differently from the submitted patches -- the descriptions may not apply exactly.] hashrexp.c: Added __STDC__ variant of function definition. *** rxall.h: Pull in standard C header files. *** Map bzero() to memset(). rxanal.c: Remove unused variable. rxdbug.c: Added stdio include. rxhash.c: Remove unused variable. rxnfa.c: Remove {re,m}alloc definition. rxposix.c: Remove unused variable. *** Cast parameter nmatch declared as size_t to int on use. *** Perhaps nmatch should be passed as int? [made related variables size_t] rxspencer.c: Add rxsimp.h include. Remove unused variables and labels. rxunfa.c: Remove unused variable. Tue Jan 30 10:29:16 1996 Tom Lord * rxsimp.c (rx_simple_rexp): move assignment out of if. ("Preston L. Bannister" ) * Makefile.in (CFLAGS, ALL_CFLAGS): rearranged to allow user specified CFLAGS. * rxposix.h: comment stuff after #endif. (reported by Eric Backus ) Mon Jan 1 13:03:28 1996 Jason Molenda (crash@phydeaux.cygnus.com) * rxbasic.c (rx_basic_make_solutions): argument called 'rexp' is now called 'expression'. Argument 'str' should be unsigned char. * rxbasic.h (rx_basic_make_solutions): argument 'str' should be unsigned char. * rxsuper.h (rx_handle_cache_miss, rx_superstate_eclosure_union): syntax error in prototypes. [Actually fixed in rxsuper.c, from which that section of rxsuper.h is derived.] * rxnode.c (rx_mk_r_cset): fix function decl. Tue Jan 30 09:43:28 1996 Tom Lord * rxposix.c (regnexec): pass rx_regexec "regs", not "pmatch". "regs" is valid even if "pmatch" is NULL. (Fixes testsuite bug "pragma" reported by John.Szetela@amd.com (John J. Szetela) also fixes bug reported by Jongki Suwandi ) Fri Jan 26 14:23:20 1996 Tom Lord * rxdbug.c (AT): Use the GCC feature only if HAVE_POSITIONAL_ARRAY_INITS is defined. * Makefile.in: Fixed depends target to not include system header files. Use @exec_prefix@. (Derek Clegg ) Thu Jan 4 16:13:07 1996 Tom Lord * rxposix.c (rx_regexec): Don't bother checking to see if an anchored pattern matches other than at the beginning of a string. (rx_regmatch): Don't bother looking for matches that are the wrong length if the overall length of the expression is known. This duplicates an optimization already in rx_make_solutions and rx_basic_make_solutions, but its worth it. The make_solutions optimization applies to fixed length subexpressions of a variable length expression. The regmatch optimization can avoid (in sed, for example) many, many uneeded calls to make_solutions and rx_next_solution. * rxspencer.c (rx_make_solutions, rx_basic_make_solutions): If the expression is fixed length and that length doesn't match the buffer, don't bother constructing a new solution stream -- just return the canonical "no solution" stream. Sat Dec 30 21:19:31 1995 Tom Lord * *.[ch]: posixification and algorithmic improvement (thanks henry!). rplay-3.3.2/rx/Makefile.in100644 153 62 11665 6552756455 14067 0ustar boynsstaff# Makefile for librx # Copyright (C) 1994 Free Software Foundation, Inc. # # This file is part of GNU Rx # # GNU Rx is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # GNU Rx is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Rx; see the file COPYING.LIB. If not, write to # the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. SHELL = /bin/sh srcdir = @srcdir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = $(exec_prefix)/bin libdir = $(exec_prefix)/lib includedir = $(prefix)/include infodir = $(prefix)/info #### Start of system configuration section. #### CC = @CC@ INSTALL = @INSTALL@ DEFS = @DEFS@ CFLAGS = @CFLAGS@ ALL_CFLAGS = @opt_cflags@ -I. -I$(srcdir) -I$(srcdir)/../libsystas $(CFLAGS) AR = ar AR_FLAGS = rc RANLIB = @RANLIB@ opt_objs=@opt_objs@ source= hashrexp.c rx.c rxanal.c rxbasic.c rxbitset.c rxcset.c rxdbug.c rxgnucomp.c rxhash.c rxnfa.c rxnode.c rxposix.c rxsimp.c rxspencer.c rxstr.c rxsuper.c rxunfa.c rgx.c headers=_rx.h rx.h rxanal.h rxbasic.h rxbitset.h rxcontext.h rxcset.h rxgnucomp.h rxhash.h rxnfa.h rxnode.h inst-rxposix.h rxposix.h rxproto.h rxsimp.h rxspencer.h rxstr.h rxsuper.h rxunfa.h rxall.h ancillery=configure.in Makefile.in configure \ COPYING.LIB ChangeLog PLUGIN \ ../doc/rx.texi ../doc/rx.info ../doc/texinfo.tex distfiles=$(source) $(headers) $(ancillery) libobjs= hashrexp.o rx.o rxanal.o rxbasic.o rxbitset.o rxcset.o rxdbug.o rxgnucomp.o rxhash.o rxnfa.o rxnode.o rxposix.o rxsimp.o rxspencer.o rxstr.o rxsuper.o rxunfa.o gen_c_files=rgx.x .SUFFIXES: .SUFFIXES: .o .c .h .ps .dvi .info .texinfo .scm .cd .x .c.x: $(CC) $(ALL_CFLAGS) -DSCM_MAGIC_SNARFER -E $< | grep "^%%%" | sed -e "s/^%%%//" > $@ ; \ .c.o: $(CC) -c $(ALL_CFLAGS) $(DEFS) -I$(srcdir) $< all: librx.a install: all test -d $(libdir) || mkdir $(libdir) test -d $(includedir) || mkdir $(includedir) $(INSTALL) librx.a $(libdir)/librx.a $(RANLIB) $(libdir)/librx.a $(INSTALL) $(srcdir)/inst-rxposix.h $(includedir)/rxposix.h uninstall: -rm -f $(libdir)/librx.a -rm -f $(includedir)/rxposix.h clean: -rm -f $(libobjs) librx.a $(opt_objs) distclean: clean -rm Makefile config.status config.log rgx.x mostlyclean: clean realclean: distclean TAGS: etags $(source) info: install-info: clean-info: dvi: check: SUBDIR=. manifest: for file in $(distfiles); do echo $(SUBDIR)/$$file; done dist: $(distfiles) echo rx-`sed -e '/version_string/!d' -e 's/[^0-9.]*\([0-9.]*\).*/\1/' -e q rx.c` > .fname rm -rf `cat .fname` mkdir `cat .fname` ln $(distfiles) `cat .fname` tar chzf `cat .fname`.tar.gz `cat .fname` rm -rf `cat .fname` .fname librx.a: $(libobjs) $(opt_objs) rm -f librx.a $(AR) $(AR_FLAGS) librx.a $(libobjs) $(opt_objs) $(RANLIB) librx.a depends: touch $(gen_c_files) scmconfig.h gcc -MM -I. -I../libsystas $(source) rm $(gen_c_files) scmconfig.h ### hashrexp.o : hashrexp.c rxall.h rxnode.h rxbitset.h rxcset.h rxhash.h rx.o : rx.c rx.h rxhash.h rxbitset.h rxall.h rxnfa.h _rx.h rxcset.h rxnode.h rxsuper.h rxanal.o : rxanal.c rxall.h rxanal.h rxcset.h rxbitset.h rxnode.h rxsuper.h \ rxnfa.h _rx.h rxhash.h rxbasic.o : rxbasic.c rxall.h rxbasic.h rxcontext.h rxnode.h rxbitset.h rxcset.h \ rxspencer.h rxproto.h rxunfa.h _rx.h rxhash.h rxanal.h rxsuper.h rxnfa.h inst-rxposix.h \ rxstr.h rxbitset.o : rxbitset.c rxall.h rxbitset.h rxcset.o : rxcset.c rxall.h rxcset.h rxbitset.h rxdbug.o : rxdbug.c rxall.h rxgnucomp.h rxcset.h rxbitset.h rxnode.h rxnfa.h \ _rx.h rxhash.h rxgnucomp.o : rxgnucomp.c rxall.h rxgnucomp.h rxcset.h rxbitset.h rxnode.h rxhash.o : rxhash.c rxall.h rxhash.h rxbitset.h rxnfa.o : rxnfa.c rxall.h rxnfa.h _rx.h rxhash.h rxbitset.h rxcset.h rxnode.h rxnode.o : rxnode.c rxall.h rxnode.h rxbitset.h rxcset.h rxposix.o : rxposix.c rxall.h rxposix.h rxspencer.h rxproto.h rxnode.h rxbitset.h \ rxcset.h rxunfa.h _rx.h rxhash.h rxanal.h rxsuper.h rxnfa.h inst-rxposix.h rxcontext.h \ rxgnucomp.h rxbasic.h rxsimp.h rxsimp.o : rxsimp.c rxall.h rxsimp.h rxcset.h rxbitset.h rxnode.h rxspencer.o : rxspencer.c rxall.h rxspencer.h rxproto.h rxnode.h rxbitset.h \ rxcset.h rxunfa.h _rx.h rxhash.h rxanal.h rxsuper.h rxnfa.h inst-rxposix.h rxstr.o : rxstr.c rxall.h rxstr.h rxspencer.h rxproto.h rxnode.h rxbitset.h \ rxcset.h rxunfa.h _rx.h rxhash.h rxanal.h rxsuper.h rxnfa.h inst-rxposix.h rxcontext.h rxsuper.o : rxsuper.c rxall.h rxsuper.h rxnfa.h _rx.h rxhash.h rxbitset.h rxcset.h \ rxnode.h rxunfa.o : rxunfa.c rxall.h rx.h rxhash.h rxbitset.h rxunfa.h _rx.h rxcset.h \ rxnfa.h rxnode.h rgx.o : rgx.c rgx.x rplay-3.3.2/rx/_rx.h100644 153 62 11601 6552756454 12750 0ustar boynsstaff/* classes: h_files */ #ifndef _RXH #define _RXH /* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include #include "rxhash.h" #include "rxcset.h" struct rx_cache; struct rx_superset; struct rx; struct rx_se_list; /* Suppose that from some NFA state and next character, more than one * path through side-effect edges is possible. In what order should * the paths be tried? A function of type rx_se_list_order answers * that question. It compares two lists of side effects, and says * which list comes first. */ #ifdef __STDC__ typedef int (*rx_se_list_order) (struct rx *, struct rx_se_list *, struct rx_se_list *); #else typedef int (*rx_se_list_order) (); #endif /* Struct RX holds an NFA and cache state for the corresponding super NFA. */ struct rx { /* The compiler assigns a unique id to every pattern. * Like sequence numbers in X, there is a subtle bug here * if you use Rx in a system that runs for a long time. * But, because of the way the caches work out, it is almost * impossible to trigger the Rx version of this bug. * * The id is used to validate superstates found in a cache * of superstates. It isn't sufficient to let a superstate * point back to the rx for which it was compiled -- the caller * may be re-using a `struct rx' in which case the superstate * is not really valid. So instead, superstates are validated * by checking the sequence number of the pattern for which * they were built. */ int rx_id; /* This is memory mgt. state for superstates. This may be * shared by more than one struct rx. */ struct rx_cache * cache; /* Every nfa defines the size of its own character set. * Each superstate has an array of this size, with each element * a `struct rx_inx'. So, don't make this number too large. * In particular, don't make it 2^16. */ int local_cset_size; /* Lists of side effects as stored in the NFA are `hash consed'..meaning * that lists with the same elements are ==. During compilation, * this table facilitates hash-consing. */ struct rx_hash se_list_memo; /* Lists of NFA states are also hashed. */ struct rx_hash set_list_memo; /* The compiler and matcher must build a number of instruction frames. * The format of these frames is fixed (c.f. struct rx_inx). The values * of the instruction opcodes is not fixed. * * An enumerated type (enum rx_opcode) defines the set of instructions * that the compiler or matcher might generate. When filling an instruction * frame, the INX field is found by indexing this instruction table * with an opcode: */ void ** instruction_table; /* The list of all states in an NFA. * The NEXT field of NFA states links this list. */ struct rx_nfa_state *nfa_states; struct rx_nfa_state *start_nfa_states; struct rx_superset * start_set; /* This orders the search through super-nfa paths. * See the comment near the typedef of rx_se_list_order. */ rx_se_list_order se_list_cmp; int next_nfa_id; }; /* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer, * `re_match_2' returns information about at least this many registers * the first time a `regs' structure is passed. * * Also, this is the greatest number of backreferenced subexpressions * allowed in a pattern being matched without caller-supplied registers. */ #ifndef RE_NREGS #define RE_NREGS 30 #endif #ifndef emacs #define CHARBITS 8 #define CHAR_SET_SIZE (1 << CHARBITS) #define Sword 1 #define SYNTAX(c) re_syntax_table[c] extern char re_syntax_table[CHAR_SET_SIZE]; #endif /* Should we use malloc or alloca? If REGEX_MALLOC is not defined, we * use `alloca' instead of `malloc' for the backtracking stack. * * Emacs will die miserably if we don't do this. */ #ifdef REGEX_MALLOC #define REGEX_ALLOCATE malloc #else /* not REGEX_MALLOC */ #define REGEX_ALLOCATE alloca #endif /* not REGEX_MALLOC */ #undef MAX #undef MIN #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) extern void * rx_id_instruction_table[]; extern struct rx_cache * rx_default_cache; #ifdef __STDC__ #else /* STDC */ #endif /* STDC */ #endif /* _RXH */ rplay-3.3.2/rx/configure100755 153 62 111641 6552756455 13744 0ustar boynsstaff#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated automatically using autoconf version 2.10 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # Defaults: ac_help= ac_default_prefix=/usr/local # Any additions from configure.in: # Initialize some variables set by options. # The variables have the same names as the options, with # dashes changed to underlines. build=NONE cache_file=./config.cache exec_prefix=NONE host=NONE no_create= nonopt=NONE no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= target=NONE verbose= x_includes=NONE x_libraries=NONE bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi case "$ac_option" in -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) ac_optarg= ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case "$ac_option" in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir="$ac_optarg" ;; -build | --build | --buil | --bui | --bu) ac_prev=build ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build="$ac_optarg" ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file="$ac_optarg" ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir="$ac_optarg" ;; -disable-* | --disable-*) ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` eval "enable_${ac_feature}=no" ;; -enable-* | --enable-*) ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "enable_${ac_feature}='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix="$ac_optarg" ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he) # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat << EOF Usage: configure [options] [host] Options: [defaults in brackets after descriptions] Configuration: --cache-file=FILE cache test results in FILE --help print this message --no-create do not create output files --quiet, --silent do not print \`checking...' messages --version print the version of autoconf that created configure Directory and file names: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [same as prefix] --bindir=DIR user executables in DIR [EPREFIX/bin] --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] --libexecdir=DIR program executables in DIR [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data in DIR [PREFIX/share] --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data in DIR [PREFIX/com] --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] --libdir=DIR object code libraries in DIR [EPREFIX/lib] --includedir=DIR C header files in DIR [PREFIX/include] --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] --infodir=DIR info documentation in DIR [PREFIX/info] --mandir=DIR man documentation in DIR [PREFIX/man] --srcdir=DIR find the sources in DIR [configure dir or ..] --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names EOF cat << EOF Host type: --build=BUILD configure for building on BUILD [BUILD=HOST] --host=HOST configure for HOST [guessed] --target=TARGET configure for TARGET [TARGET=HOST] Features and packages: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR EOF if test -n "$ac_help"; then echo "--enable and --with options recognized:$ac_help" fi exit 0 ;; -host | --host | --hos | --ho) ac_prev=host ;; -host=* | --host=* | --hos=* | --ho=*) host="$ac_optarg" ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir="$ac_optarg" ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir="$ac_optarg" ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir="$ac_optarg" ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir="$ac_optarg" ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir="$ac_optarg" ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir="$ac_optarg" ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir="$ac_optarg" ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix="$ac_optarg" ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix="$ac_optarg" ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix="$ac_optarg" ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name="$ac_optarg" ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir="$ac_optarg" ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir="$ac_optarg" ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site="$ac_optarg" ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir="$ac_optarg" ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir="$ac_optarg" ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target="$ac_optarg" ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers) echo "configure generated by autoconf version 2.10" exit 0 ;; -with-* | --with-*) ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "with_${ac_package}='$ac_optarg'" ;; -without-* | --without-*) ac_package=`echo $ac_option|sed -e 's/-*without-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` eval "with_${ac_package}=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes="$ac_optarg" ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries="$ac_optarg" ;; -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } ;; *) if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then echo "configure: warning: $ac_option: invalid host type" 1>&2 fi if test "x$nonopt" != xNONE; then { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } fi nonopt="$ac_option" ;; esac done if test -n "$ac_prev"; then { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } fi trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 # File descriptor usage: # 0 standard input # 1 file creation # 2 errors and warnings # 3 some systems may open it to /dev/tty # 4 used on the Kubota Titan # 6 checking for... messages and results # 5 compiler messages saved in config.log if test "$silent" = yes; then exec 6>/dev/null else exec 6>&1 fi exec 5>./config.log echo "\ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. " 1>&5 # Strip out --no-create and --no-recursion so they do not pile up. # Also quote any args containing shell metacharacters. ac_configure_args= for ac_arg do case "$ac_arg" in -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) ac_configure_args="$ac_configure_args '$ac_arg'" ;; *) ac_configure_args="$ac_configure_args $ac_arg" ;; esac done # NLS nuisances. # Only set LANG and LC_ALL to C if already set. # These must not be set unconditionally because not all systems understand # e.g. LANG=C (notably SCO). if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi if test "${LANG+set}" = set; then LANG=C; export LANG; fi # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo > confdefs.h # A filename unique to this package, relative to the directory that # configure is in, which we can look for to find out if srcdir is correct. ac_unique_file=rx.c # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_prog=$0 ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } else { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } fi fi srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then echo "loading site script $ac_site_file" . "$ac_site_file" fi done if test -r "$cache_file"; then echo "loading cache $cache_file" . $cache_file else echo "creating cache $cache_file" > $cache_file fi ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then ac_n= ac_c=' ' ac_t=' ' else ac_n=-n ac_c= ac_t= fi else ac_n= ac_c='\c' ac_t= fi # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="gcc" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" ac_prog_rejected=no for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" break fi done IFS="$ac_save_ifs" if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# -gt 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift set dummy "$ac_dir/$ac_word" "$@" shift ac_cv_prog_CC="$@" fi fi fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } fi echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no fi fi echo "$ac_t""$ac_cv_prog_gcc" 1>&6 if test $ac_cv_prog_gcc = yes; then GCC=yes if test "${CFLAGS+set}" != set; then echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_prog_gcc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo 'void f(){}' > conftest.c if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then ac_cv_prog_gcc_g=yes else ac_cv_prog_gcc_g=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_prog_gcc_g" 1>&6 if test $ac_cv_prog_gcc_g = yes; then CFLAGS="-g -O" else CFLAGS="-O" fi fi else GCC= test "${CFLAGS+set}" = set || CFLAGS="-g" fi echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # This must be in double quotes, not single quotes, because CPP may get # substituted into the Makefile and "${CC-cc}" will confuse make. CPP="${CC-cc} -E" # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:661: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then : else echo "$ac_err" >&5 rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:676: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then : else echo "$ac_err" >&5 rm -rf conftest* CPP=/lib/cpp fi rm -f conftest* fi rm -f conftest* ac_cv_prog_CPP="$CPP" fi CPP="$ac_cv_prog_CPP" else ac_cv_prog_CPP="$CPP" fi echo "$ac_t""$CPP" 1>&6 # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_RANLIB="ranlib" break fi done IFS="$ac_save_ifs" test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" fi fi RANLIB="$ac_cv_prog_RANLIB" if test -n "$RANLIB"; then echo "$ac_t""$RANLIB" 1>&6 else echo "$ac_t""no" 1>&6 fi ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do if test -f $ac_dir/install-sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f $ac_dir/install.sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break fi done if test -z "$ac_aux_dir"; then { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } fi ac_config_guess=$ac_aux_dir/config.guess ac_config_sub=$ac_aux_dir/config.sub ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" for ac_dir in $PATH; do # Account for people who put trailing slashes in PATH elements. case "$ac_dir/" in /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. for ac_prog in ginstall installbsd scoinst install; do if test -f $ac_dir/$ac_prog; then if test $ac_prog = install && grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. # OSF/1 installbsd also uses dspmsg, but is usable. : else ac_cv_path_install="$ac_dir/$ac_prog -c" break 2 fi fi done ;; esac done IFS="$ac_save_ifs" fi if test "${ac_cv_path_install+set}" = set; then INSTALL="$ac_cv_path_install" else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL="$ac_install_sh" fi fi echo "$ac_t""$INSTALL" 1>&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo $ac_n "checking for working const""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; } ; return 0; } EOF if { (eval echo configure:857: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else rm -rf conftest* ac_cv_c_const=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_c_const" 1>&6 if test $ac_cv_c_const = no; then cat >> confdefs.h <<\EOF #define const EOF fi # If we cannot run a trivial program, we must be cross compiling. echo $ac_n "checking whether cross-compiling""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_c_cross'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then ac_cv_c_cross=yes else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } if test -s conftest && (./conftest; exit) 2>/dev/null; then ac_cv_c_cross=no else ac_cv_c_cross=yes fi fi rm -fr conftest* fi echo "$ac_t""$ac_cv_c_cross" 1>&6 cross_compiling=$ac_cv_c_cross echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #include #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:916: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* ac_cv_header_stdc=yes else echo "$ac_err" >&5 rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "memchr" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "free" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') #define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF { (eval echo configure:981: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } if test -s conftest && (./conftest; exit) 2>/dev/null; then : else ac_cv_header_stdc=no fi fi rm -fr conftest* fi fi echo "$ac_t""$ac_cv_header_stdc" 1>&6 if test $ac_cv_header_stdc = yes; then cat >> confdefs.h <<\EOF #define STDC_HEADERS 1 EOF fi opt_objs= opt_cflags= if test -d ../libsystas ; then opt_objs=rgx.o opt_cflags="-I$srcdir/../libsystas -I../libsystas -DRX_WANT_RX_DEFS" fi trap '' 1 2 15 cat > confcache <<\EOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs. It is not useful on other systems. # If it contains results you don't want to keep, you may remove or edit it. # # By default, configure uses ./config.cache as the cache file, # creating it if it does not exist already. You can give configure # the --cache-file=FILE option to use a different cache file; that is # what configure does when it calls configure scripts in # subdirectories, so they share the cache. # Giving --cache-file=/dev/null disables caching, for debugging configure. # config.status only pays attention to the cache file if you give it the # --recheck option to rerun configure. # EOF # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. (set) 2>&1 | sed -n "s/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=\${\1='\2'}/p" \ >> confcache if cmp -s $cache_file confcache; then : else if test -w $cache_file; then echo "updating cache $cache_file" cat confcache > $cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Any assignment to VPATH causes Sun make to only execute # the first set of double-colon rules, so remove it if not needed. # If there is a colon in the path, we need to keep it. if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' fi trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. cat > conftest.defs <<\EOF s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g s%\[%\\&%g s%\]%\\&%g s%\$%$$%g EOF DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` rm -f conftest.defs # Without the "./", some shells look in PATH for config.status. : ${CONFIG_STATUS=./config.status} echo creating $CONFIG_STATUS rm -f $CONFIG_STATUS cat > $CONFIG_STATUS </dev/null | sed 1q`: # # $0 $ac_configure_args # # Compiler output produced by configure, useful for debugging # configure, is in ./config.log if it exists. ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" for ac_option do case "\$ac_option" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) echo "$CONFIG_STATUS generated by autoconf version 2.10" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; *) echo "\$ac_cs_usage"; exit 1 ;; esac done ac_given_srcdir=$srcdir ac_given_INSTALL="$INSTALL" trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF $ac_vpsub $extrasub s%@CFLAGS@%$CFLAGS%g s%@CPPFLAGS@%$CPPFLAGS%g s%@CXXFLAGS@%$CXXFLAGS%g s%@DEFS@%$DEFS%g s%@LDFLAGS@%$LDFLAGS%g s%@LIBS@%$LIBS%g s%@exec_prefix@%$exec_prefix%g s%@prefix@%$prefix%g s%@program_transform_name@%$program_transform_name%g s%@bindir@%$bindir%g s%@sbindir@%$sbindir%g s%@libexecdir@%$libexecdir%g s%@datadir@%$datadir%g s%@sysconfdir@%$sysconfdir%g s%@sharedstatedir@%$sharedstatedir%g s%@localstatedir@%$localstatedir%g s%@libdir@%$libdir%g s%@includedir@%$includedir%g s%@oldincludedir@%$oldincludedir%g s%@infodir@%$infodir%g s%@mandir@%$mandir%g s%@CC@%$CC%g s%@CPP@%$CPP%g s%@RANLIB@%$RANLIB%g s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g s%@INSTALL_DATA@%$INSTALL_DATA%g s%@opt_objs@%$opt_objs%g s%@opt_cflags@%$opt_cflags%g CEOF EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then # Support "outfile[:infile]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac # Adjust relative srcdir, etc. for subdirectories. # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" # A "../" for each directory in $ac_dir_suffix. ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` else ac_dir_suffix= ac_dots= fi case "$ac_given_srcdir" in .) srcdir=. if test -z "$ac_dots"; then top_srcdir=. else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; *) # Relative path. srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" top_srcdir="$ac_dots$ac_given_srcdir" ;; esac case "$ac_given_INSTALL" in [/$]*) INSTALL="$ac_given_INSTALL" ;; *) INSTALL="$ac_dots$ac_given_INSTALL" ;; esac echo creating "$ac_file" rm -f "$ac_file" configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." case "$ac_file" in *Makefile*) ac_comsub="1i\\ # $configure_input" ;; *) ac_comsub= ;; esac sed -e "$ac_comsub s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g s%@INSTALL@%$INSTALL%g " -f conftest.subs $ac_given_srcdir/$ac_file_in > $ac_file fi; done rm -f conftest.subs exit 0 EOF chmod +x $CONFIG_STATUS rm -fr confdefs* $ac_clean_files test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 rplay-3.3.2/rx/configure.in100644 153 62 563 6552756455 14266 0ustar boynsstaffdnl Process this file with autoconf to produce a configure script. AC_INIT(rx.c) AC_PROG_CC AC_PROG_CPP AC_PROG_RANLIB AC_PROG_INSTALL AC_C_CONST AC_STDC_HEADERS opt_objs= opt_cflags= if test -d ../libsystas ; then opt_objs=rgx.o opt_cflags="-I$srcdir/../libsystas -I../libsystas -DRX_WANT_RX_DEFS" fi AC_SUBST(opt_objs) AC_SUBST(opt_cflags) AC_OUTPUT(Makefile) rplay-3.3.2/rx/hashrexp.c100644 153 62 2735 6552756454 13765 0ustar boynsstaff/* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "rxall.h" #include "rxnode.h" #include "rxhash.h" #ifdef __STDC__ static int rexp_node_equal (void * va, void * vb) #else static int rexp_node_equal (va, vb) void * va; void * vb; #endif { struct rexp_node * a; struct rexp_node * b; a = (struct rexp_node *)va; b = (struct rexp_node *)vb; return ( (va == vb) || ( (a->type == b->type) && (a->params.intval == b->params.intval) && (a->params.intval2 == b->params.intval2) && rx_bitset_is_equal (a->params.cset_size, a->params.cset, b->params.cset) && rexp_node_equal (a->params.pair.left, b->params.pair.left) && rexp_node_equal (a->params.pair.right, b->params.pair.right))); } rplay-3.3.2/rx/inst-rxposix.h100644 153 62 11444 6552756455 14655 0ustar boynsstaff/* classes: h_files */ #ifndef INST_RXPOSIXH #define INST_RXPOSIXH /* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ struct rx_posix_regex { struct rexp_node * pattern; struct rexp_node ** subexps; size_t re_nsub; unsigned char * translate; unsigned int newline_anchor:1;/* If true, an anchor at a newline matches.*/ unsigned int no_sub:1; /* If set, don't return register offsets. */ unsigned int is_anchored:1; unsigned int is_nullable:1; unsigned char fastmap[256]; void * owner_data; }; typedef struct rx_posix_regex regex_t; /* Type for byte offsets within the string. POSIX mandates this. */ typedef int regoff_t; typedef struct rx_registers { regoff_t rm_so; /* Byte offset from string's start to substring's start. */ regoff_t rm_eo; /* Byte offset from string's start to substring's end. */ regoff_t final_tag; /* data from the cut operator (only pmatch[0]) */ } regmatch_t; /* If any error codes are removed, changed, or added, update the * `rx_error_msg' table. */ #define REG_NOERROR 0 /* Success. */ #define REG_NOMATCH 1 /* Didn't find a match (for regexec). */ /* POSIX regcomp return error codes. * (In the order listed in the standard.) */ #define REG_BADPAT 2 /* Invalid pattern. */ #define REG_ECOLLATE 3 /* Not implemented. */ #define REG_ECTYPE 4 /* Invalid character class name. */ #define REG_EESCAPE 5 /* Trailing backslash. */ #define REG_ESUBREG 6 /* Invalid back reference. */ #define REG_EBRACK 7 /* Unmatched left bracket. */ #define REG_EPAREN 8 /* Parenthesis imbalance. */ #define REG_EBRACE 9 /* Unmatched \{. */ #define REG_BADBR 10 /* Invalid contents of \{\}. */ #define REG_ERANGE 11 /* Invalid range end. */ #define REG_ESPACE 12 /* Ran out of memory. */ #define REG_BADRPT 13 /* No preceding re for repetition op. */ /* Error codes we've added. */ #define REG_EEND 14 /* Premature end. */ #define REG_ESIZE 15 /* Compiled pattern bigger than 2^16 bytes. */ #define REG_ERPAREN 16 /* Unmatched ) or \); not returned from regcomp. */ /* * POSIX `cflags' bits (i.e., information for `regcomp'). */ /* If this bit is set, then use extended regular expression syntax. * If not set, then use basic regular expression syntax. */ #define REG_EXTENDED 1 /* If this bit is set, then ignore case when matching. * If not set, then case is significant. */ #define REG_ICASE (REG_EXTENDED << 1) /* If this bit is set, then anchors do not match at newline * characters in the string. * If not set, then anchors do match at newlines. */ #define REG_NEWLINE (REG_ICASE << 1) /* If this bit is set, then report only success or fail in regexec. * If not set, then returns differ between not matching and errors. */ #define REG_NOSUB (REG_NEWLINE << 1) /* * POSIX `eflags' bits (i.e., information for regexec). */ /* If this bit is set, then the beginning-of-line operator doesn't match * the beginning of the string (presumably because it's not the * beginning of a line). * If not set, then the beginning-of-line operator does match the * beginning of the string. */ #define REG_NOTBOL 1 /* Like REG_NOTBOL, except for the end-of-line. */ #define REG_NOTEOL (REG_NOTBOL << 1) /* For regnexec only. Allocate register storage and return that. */ #define REG_ALLOC_REGS (REG_NOTEOL << 1) #ifdef __STDC__ extern int regncomp (regex_t * preg, const char * pattern, int len, int cflags); extern int regcomp (regex_t * preg, const char * pattern, int cflags); extern size_t regerror (int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size); extern int regnexec (const regex_t *preg, const char *string, int len, size_t nmatch, regmatch_t **pmatch, int eflags); extern int regexec (const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags); extern void regfree (regex_t *preg); #else /* STDC */ extern int regncomp (); extern int regcomp (); extern size_t regerror (); extern int regnexec (); extern int regexec (); extern void regfree (); #endif /* STDC */ #endif /* INST_RXPOSIXH */ rplay-3.3.2/rx/rgx.c100644 153 62 36230 6552756454 12760 0ustar boynsstaff/* Copyright (C) 1995 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * * As a special exception, the Free Software Foundation gives permission * for additional uses of the text contained in its release of SYSTAS. * * The exception is that, if you link the SYSTAS library with other files * to produce an executable, this does not by itself cause the * resulting executable to be covered by the GNU General Public License. * Your use of that executable is in no way restricted on account of * linking the SYSTAS library code into it. * * This exception does not however invalidate any other reasons why * the executable file might be covered by the GNU General Public License. * * This exception applies only to the code released by the * Free Software Foundation under the name SYSTAS. If you copy * code from other Free Software Foundation releases into a copy of * SYSTAS, as the General Public License permits, the exception does * not apply to the code that you add in this way. To avoid misleading * anyone as to the status of such modified files, you must delete * this exception notice from them. * * If you write modifications of your own for SYSTAS, it is your choice * whether to permit this exception to apply to your modifications. * If you do not wish that, delete this exception notice. */ #include #include <_scm.h> #include "inst-rxposix.h" #include "rxgnucomp.h" #include "rxanal.h" #include "rxunfa.h" #include "rxbasic.h" SCM_CONST_LONG (scm_REG_EXTENDED, "REG_EXTENDED", REG_EXTENDED); SCM_CONST_LONG (scm_REG_ICASE, "REG_ICASE", REG_ICASE); SCM_CONST_LONG (scm_REG_NEWLINE, "REG_NEWLINE", REG_NEWLINE); SCM_CONST_LONG (scm_REG_NOSUB, "REG_NOSUB", REG_NOSUB); SCM_CONST_LONG (scm_REG_NOTBOL, "REG_NOTBOL", REG_NOTBOL); SCM_CONST_LONG (scm_REG_NOTEOL, "REG_NOTEOL", REG_NOTEOL); long scm_tc16_regex_t; #define RGX(X) ((regex_t *)SCM_CDR(X)) #define RGXP(X) (SCM_CAR(X) == (SCM)scm_tc16_regex_t) #ifdef __STDC__ size_t free_regex_t (SCM obj) #else size_t free_regex_t (obj) SCM obj; #endif { regex_t *r; r = RGX(obj); free ((char *)(r->owner_data)); regfree (r); return 0; } #ifdef __STDC__ int print_regex_t (SCM obj, SCM port, int writing) #else int print_regex_t (obj, port, writing) SCM obj; SCM port; int writing; #endif { regex_t *r; r = RGX (obj); scm_gen_puts (scm_regular_string, "#owner_data), port); scm_gen_puts (scm_regular_string, ">", port); return 1; } static scm_smobfuns regex_t_smob = { scm_mark0, free_regex_t, print_regex_t, 0 }; SCM_PROC (s_compiled_regexp_p, "compiled-regexp?", 1, 0, 0, scm_compiled_regexp_p); #ifdef __STDC__ SCM scm_compiled_regexp_p (SCM obj) #else SCM scm_compiled_regexp_p (obj) SCM obj; #endif { return ((SCM_NIMP (obj) && RGXP (obj)) ? SCM_BOOL_T : SCM_BOOL_F); } SCM_PROC(s_regcomp, "regcomp", 1, 1, 0, scm_regcomp); #ifdef __STDC__ SCM scm_regcomp (SCM pat, SCM cfl) #else SCM scm_regcomp (pat, cfl) SCM pat; SCM cfl; #endif { SCM answer; SCM_ASSERT (SCM_NIMP (pat) && SCM_RO_STRINGP (pat), pat, SCM_ARG1, s_regcomp); if (cfl == SCM_UNDEFINED) cfl = SCM_INUM0; SCM_ASSERT (SCM_INUMP (cfl), cfl, SCM_ARG2, s_regcomp); SCM_NEWCELL (answer); SCM_DEFER_INTS; { regex_t * it; int status; it = malloc (sizeof (*it)); if (!it) { allocation: SCM_ALLOW_INTS; SCM_ASSERT (0, pat, "allocation failure", s_regcomp); } status = regncomp (it, SCM_RO_CHARS (pat), SCM_RO_LENGTH (pat), SCM_INUM (cfl)); if (status) { free (it); answer = SCM_MAKINUM (status); } else { it->owner_data = (void *)malloc (SCM_RO_LENGTH (pat) + 1); if (!it->owner_data) { regfree (it); free (it); goto allocation; } memcpy (it->owner_data, SCM_RO_CHARS (pat), SCM_RO_LENGTH (pat)); ((char *)it->owner_data)[SCM_RO_LENGTH (pat)] = 0; SCM_SETCAR (answer, scm_tc16_regex_t); SCM_SETCDR (answer, (SCM)it); } } SCM_ALLOW_INTS; return answer; } SCM_PROC(s_regexec, "regexec", 2, 2, 0, scm_regexec); #ifdef __STDC__ SCM scm_regexec (SCM rgx, SCM str, SCM match_pick, SCM eflags) #else SCM scm_regexec (rgx, str, match_pick, eflags) SCM rgx; SCM str; SCM match_pick; SCM eflags; #endif { SCM answer; SCM malloc_protect; regmatch_t * pmatch; int vector_result; SCM_ASSERT (SCM_NIMP (rgx) && RGXP (rgx), rgx, SCM_ARG1, s_regexec); SCM_ASSERT (SCM_NIMP (str) && SCM_RO_STRINGP (str), str, SCM_ARG2, s_regexec); if (eflags == SCM_UNDEFINED) eflags = SCM_INUM0; SCM_ASSERT (SCM_INUMP (eflags), eflags, SCM_ARG4, s_regexec); vector_result = (SCM_NIMP (match_pick) && SCM_VECTORP (match_pick)); if (RGX(rgx)->re_nsub) { SCM starts; SCM ends; starts = scm_make_vector (SCM_MAKINUM (RGX(rgx)->re_nsub), SCM_BOOL_F, SCM_BOOL_F); ends = scm_make_vector (SCM_MAKINUM (RGX(rgx)->re_nsub), SCM_BOOL_F, SCM_BOOL_F); answer = scm_cons (starts, ends); } malloc_protect = scm_malloc_obj (0); SCM_DEFER_INTS; { int status; pmatch = 0; status = regnexec (RGX(rgx), SCM_RO_CHARS (str), SCM_RO_LENGTH (str), 0, &pmatch, SCM_INUM (eflags) | REG_ALLOC_REGS); if (status) { SCM_ALLOW_INTS; if (vector_result) return SCM_MAKINUM (status); else { if (status == REG_NOMATCH) return SCM_BOOL_F; else scm_throw (SCM_CAR (scm_intern0 ("regexp-error")), scm_listify (SCM_MAKINUM (status), rgx, str, match_pick, eflags, SCM_UNDEFINED)); } } if (match_pick == SCM_BOOL_F) free (pmatch); else SCM_SETMALLOCDATA (malloc_protect, pmatch); } SCM_ALLOW_INTS; if (match_pick == SCM_BOOL_F) return SCM_BOOL_T; else if ((match_pick == SCM_BOOL_T) || (match_pick == SCM_UNDEFINED)) { answer = (scm_listify (scm_make_shared_substring (str, SCM_MAKINUM (0), SCM_MAKINUM (pmatch[0].rm_so)), scm_make_shared_substring (str, SCM_MAKINUM (pmatch[0].rm_so), SCM_MAKINUM (pmatch[0].rm_eo)), scm_make_shared_substring (str, SCM_MAKINUM (pmatch[0].rm_eo), SCM_UNDEFINED), SCM_UNDEFINED)); return answer; } else if (vector_result) { int i; size_t bound; int vlen; bound = RGX(rgx)->re_nsub; vlen = SCM_LENGTH (match_pick); if (vlen < bound) bound = vlen; for (i = 0; i < bound; ++i) if (pmatch[0].rm_so >= 0) SCM_VELTS (match_pick)[i] = scm_cons (SCM_MAKINUM (pmatch[i].rm_so), SCM_MAKINUM (pmatch[i].rm_eo)); else SCM_VELTS (match_pick)[i] = SCM_BOOL_F; while (i < vlen) { SCM_VELTS (match_pick)[i] = SCM_BOOL_F; ++i; } return match_pick; } else { SCM spec; size_t bound; SCM ans_pos; answer = scm_cons (SCM_BOOL_F, SCM_BOOL_F); ans_pos = answer; bound = RGX(rgx)->re_nsub; for (spec = match_pick; spec != SCM_EOL; spec = SCM_CDR (spec)) { SCM item; SCM frm; SCM to; SCM_ASSERT (SCM_NIMP (spec) && SCM_CONSP (spec), spec, SCM_ARG3, s_regexec); item = SCM_CAR (spec); if (SCM_ICHRP (item)) { if (SCM_ICHR (item) == '<') { frm = SCM_INUM0; to = SCM_MAKINUM (pmatch[0].rm_so); SCM_SETCDR (ans_pos, scm_cons (scm_make_shared_substring (str, frm, to), SCM_EOL)); } else if (SCM_ICHR (item) == '>') { frm = SCM_MAKINUM (pmatch[0].rm_eo); to = SCM_UNDEFINED; SCM_SETCDR (ans_pos, scm_cons (scm_make_shared_substring (str, frm, to), SCM_EOL)); } else if (SCM_ICHR (item) == 'c') { SCM_SETCDR (ans_pos, scm_cons (SCM_MAKINUM (pmatch[0].final_tag), SCM_EOL)); } else SCM_ASSERT (0, spec, SCM_ARG3, s_regexec); ans_pos = SCM_CDR (ans_pos); } else if (SCM_NIMP (item) && SCM_CONSP (item)) { SCM ipos; int solved; solved = 0; for (ipos = item; SCM_NIMP (ipos) && SCM_CONSP (ipos); ipos = SCM_CDR (ipos)) { SCM iitem; int ival; iitem = SCM_CAR (ipos); SCM_ASSERT (SCM_INUMP (iitem), spec, SCM_ARG3, s_regexec); ival = SCM_INUM (iitem); SCM_ASSERT ((ival >= 0) && (ival < bound), spec, SCM_OUTOFRANGE, s_regexec); if (pmatch[ival].rm_so >= 0) { SCM_SETCDR (ans_pos, scm_cons (SCM_MAKINUM (ival), SCM_EOL)); ans_pos = SCM_CDR (ans_pos); solved = 1; break; } } if (!solved) { SCM_SETCDR (ans_pos, scm_cons (SCM_BOOL_F, SCM_EOL)); ans_pos = SCM_CDR (ans_pos); } } else { int n; SCM_ASSERT (SCM_INUMP (item), spec, SCM_ARG3, s_regexec); n = SCM_INUM (item); SCM_ASSERT ((n >= 0) && (n < bound), spec, SCM_OUTOFRANGE, s_regexec); if (pmatch[n].rm_so < 0) { SCM_SETCDR (ans_pos, scm_cons (SCM_BOOL_F, SCM_EOL)); ans_pos = SCM_CDR (ans_pos); continue; } frm = SCM_MAKINUM (pmatch[n].rm_so); to = SCM_MAKINUM (pmatch[n].rm_eo); SCM_SETCDR (ans_pos, scm_cons (scm_make_shared_substring (str, frm, to), SCM_EOL)); ans_pos = SCM_CDR (ans_pos); } } return SCM_CDR (answer); } } struct rx_dfa_state { struct rx_classical_system frame; struct rx_unfa * unfa; }; long scm_tc16_dfa_t; #define DFA(X) ((struct rx_dfa_state *)SCM_CDR(X)) #define DFAP(X) (SCM_CAR(X) == (SCM)scm_tc16_dfa_t) #ifdef __STDC__ size_t free_dfa_t (SCM obj) #else size_t free_dfa_t (obj) SCM obj; #endif { struct rx_dfa_state *r; r = DFA(obj); rx_terminate_system (&r->frame); rx_free_unfa (r->unfa); scm_must_free ((char *)r); return sizeof (struct rx_dfa_state); } #ifdef __STDC__ int print_dfa_t (SCM obj, SCM port, int writing) #else int print_dfa_t (obj, port, writing) SCM obj; SCM port; int writing; #endif { struct rx_dfa_state *r; r = DFA (obj); scm_gen_puts (scm_regular_string, "#frame.rx->rx_id, 10, port); scm_gen_puts (scm_regular_string, ">", port); return 1; } static scm_smobfuns dfa_t_smob = { scm_mark0, free_dfa_t, print_dfa_t, 0 }; SCM_PROC (s_regexp_to_dfa, "regexp->dfa", 1, 1, 0, scm_regexp_to_dfa); #ifdef __STDC__ SCM scm_regexp_to_dfa (SCM regexp, SCM cfl) #else SCM scm_regexp_to_dfa (regexp, cfl) SCM regexp; SCM cfl; #endif { int ret; unsigned int syntax; struct rx_dfa_state *r; struct rexp_node * parsed; int cflags; char * pattern; int len; SCM answer; SCM_ASSERT (SCM_NIMP (regexp) && SCM_RO_STRINGP (regexp), regexp, SCM_ARG1, s_regexp_to_dfa); if (cfl == SCM_UNDEFINED) cfl = SCM_INUM0; SCM_ASSERT (SCM_INUMP (cfl), cfl, SCM_ARG2, s_regexp_to_dfa); pattern = SCM_RO_CHARS (regexp); len = SCM_RO_LENGTH (regexp); cflags = SCM_INUM (cfl); SCM_NEWCELL (answer); SCM_DEFER_INTS; syntax = ((cflags & REG_EXTENDED) ? RE_SYNTAX_POSIX_EXTENDED : RE_SYNTAX_POSIX_BASIC); if (cflags & REG_NEWLINE) { syntax &= ~RE_DOT_NEWLINE; syntax |= RE_HAT_LISTS_NOT_NEWLINE; } ret = rx_parse (&parsed, pattern, len, syntax, 256, 0); if (ret) { SCM_ALLOW_INTS; return SCM_MAKINUM (ret); } r = (struct rx_dfa_state *)scm_must_malloc (sizeof (struct rx_dfa_state), s_regexp_to_dfa); r->unfa = rx_unfa (rx_basic_unfaniverse (), parsed, 256); rx_free_rexp (parsed); if (!r->unfa) { scm_mallocated -= sizeof (*r); scm_must_free ((char *)r); SCM_ALLOW_INTS; SCM_ASSERT (0, regexp, "internal error constructing rx_unfa", s_regexp_to_dfa); } rx_init_system (&r->frame, r->unfa->nfa); SCM_SETCAR (answer, scm_tc16_dfa_t); SCM_SETCDR (answer, (SCM)r); SCM_ALLOW_INTS; return answer; } SCM_PROC (s_dfa_fork, "dfa-fork", 1, 0, 0, scm_dfa_fork); #ifdef __STDC__ SCM scm_dfa_fork (SCM dfa) #else SCM scm_dfa_fork (dfa) SCM dfa; #endif { struct rx_dfa_state *r; SCM answer; SCM_ASSERT (SCM_NIMP (dfa) && DFAP (dfa), dfa, SCM_ARG1, s_dfa_fork); SCM_NEWCELL (answer); SCM_DEFER_INTS; r = (struct rx_dfa_state *)scm_must_malloc (sizeof (struct rx_dfa_state), s_dfa_fork); rx_save_unfa (DFA (dfa)->unfa); r->unfa = DFA (dfa)->unfa; rx_init_system (&r->frame, r->unfa->nfa); r->frame.state = DFA(dfa)->frame.state; if (r->frame.state) rx_lock_superstate (r->frame.rx, r->frame.state); SCM_SETCAR (answer, scm_tc16_dfa_t); SCM_SETCDR (answer, (SCM)r); SCM_ALLOW_INTS; return answer; } SCM_PROC (s_reset_dfa_x, "reset-dfa!", 1, 0, 0, scm_reset_dfa_x); #ifdef __STDC__ SCM scm_reset_dfa_x (SCM dfa) #else SCM scm_reset_dfa_x (dfa) SCM dfa; #endif { SCM_ASSERT (SCM_NIMP (dfa) && DFAP (dfa), dfa, SCM_ARG1, s_reset_dfa_x); SCM_DEFER_INTS; if (rx_yes != rx_start_superstate (&DFA(dfa)->frame)) { SCM_ALLOW_INTS; SCM_ASSERT (0, dfa, "internal error constructing rx starting superstate", s_reset_dfa_x); } SCM_ALLOW_INTS; return dfa; } SCM_PROC (s_dfa_final_tag, "dfa-final-tag", 1, 0, 0, scm_dfa_final_tag); #ifdef __STDC__ SCM scm_dfa_final_tag (SCM dfa) #else SCM scm_dfa_final_tag (dfa) SCM dfa; #endif { SCM_ASSERT (SCM_NIMP (dfa) && DFAP (dfa), dfa, SCM_ARG1, s_dfa_final_tag); if (DFA (dfa)->frame.state) return scm_long2num ((long)DFA (dfa)->frame.state->contents->is_final); else return SCM_INUM0; } SCM_PROC (s_dfa_continuable_p, "dfa-continuable?", 1, 0, 0, scm_dfa_continuable_p); #ifdef __STDC__ SCM scm_dfa_continuable_p (SCM dfa) #else SCM scm_dfa_continuable_p (dfa) SCM dfa; #endif { SCM_ASSERT (SCM_NIMP (dfa) && DFAP (dfa), dfa, SCM_ARG1, s_dfa_continuable_p); return ((DFA (dfa)->frame.state && DFA (dfa)->frame.state->contents->has_cset_edges) ? SCM_BOOL_T : SCM_BOOL_F); } SCM_PROC (s_advance_dfa_x, "advance-dfa!", 2, 0, 0, scm_advance_dfa_x); #ifdef __STDC__ SCM scm_advance_dfa_x (SCM dfa, SCM s) #else SCM scm_advance_dfa_x (dfa, s) SCM dfa; SCM s; #endif { struct rx_dfa_state * d; char * str; int len; int matched; SCM_ASSERT (SCM_NIMP (dfa) && DFAP (dfa), dfa, SCM_ARG1, s_advance_dfa_x); SCM_ASSERT (SCM_NIMP (s) && SCM_RO_STRINGP (s), s, SCM_ARG2, s_advance_dfa_x); str = SCM_RO_CHARS (s); len = SCM_RO_LENGTH (s); d = DFA (dfa); SCM_DEFER_INTS; matched = rx_advance_to_final (&d->frame, (unsigned char *)str, len); SCM_ALLOW_INTS; if (matched >= 0) scm_return_first (SCM_MAKINUM (matched), dfa, s); else SCM_ASSERT (0, dfa, "internal error in rx_advance_to_final", s_advance_dfa_x); } #ifdef __STDC__ void scm_init_rgx (void) #else void scm_init_rgx () #endif { scm_tc16_regex_t = scm_newsmob (®ex_t_smob); scm_tc16_dfa_t = scm_newsmob (&dfa_t_smob); #include "rgx.x" } rplay-3.3.2/rx/rx.c100644 153 62 3440 6552756454 12566 0ustar boynsstaff/* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "rx.h" #include "rxall.h" #include "rxhash.h" #include "rxnfa.h" #include "rxsuper.h" const char rx_version_string[] = "GNU Rx version 1.5"; #ifdef __STDC__ struct rx * rx_make_rx (int cset_size) #else struct rx * rx_make_rx (cset_size) int cset_size; #endif { static int rx_id = 0; struct rx * new_rx; new_rx = (struct rx *)malloc (sizeof (*new_rx)); rx_bzero ((char *)new_rx, sizeof (*new_rx)); new_rx->rx_id = rx_id++; new_rx->cache = rx_default_cache; new_rx->local_cset_size = cset_size; new_rx->instruction_table = rx_id_instruction_table; new_rx->next_nfa_id = 0; return new_rx; } #ifdef __STDC__ void rx_free_rx (struct rx * rx) #else void rx_free_rx (rx) struct rx * rx; #endif { if (rx->start_set) rx->start_set->starts_for = 0; rx_free_nfa (rx); free (rx); } #ifdef __STDC__ void rx_bzero (char * mem, int size) #else void rx_bzero (mem, size) char * mem; int size; #endif { while (size) { *mem = 0; ++mem; --size; } } rplay-3.3.2/rx/rx.h100644 153 62 2267 6552756454 12601 0ustar boynsstaff/* classes: h_files */ #ifndef RXH #define RXH /* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "rxhash.h" extern const char rx_version_string[]; #ifdef __STDC__ extern struct rx * rx_make_rx (int cset_size); extern void rx_free_rx (struct rx * rx); extern void rx_bzero (char * mem, int size); #else /* STDC */ extern struct rx * rx_make_rx (); extern void rx_free_rx (); extern void rx_bzero (); #endif /* STDC */ #endif /* RXH */ rplay-3.3.2/rx/rxall.h100644 153 62 1725 6552756455 13271 0ustar boynsstaff/* classes: h_files */ #ifndef RXALLH #define RXALLH /* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #if 0 #include #include "malloc.h" #endif #ifdef __STDC__ #else /* STDC */ #endif /* STDC */ #endif /* RXALLH */ rplay-3.3.2/rx/rxanal.c100644 153 62 40660 6552756454 13447 0ustar boynsstaff/* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "rxall.h" #include "rxanal.h" #include "rxbitset.h" #include "rxsuper.h" #ifdef __STDC__ int rx_posix_analyze_rexp (struct rexp_node *** subexps, size_t * re_nsub, struct rexp_node * node, int id) #else int rx_posix_analyze_rexp (subexps, re_nsub, node, id) struct rexp_node *** subexps; size_t * re_nsub; struct rexp_node * node; int id; #endif { if (node) { size_t this_subexp; if (node->type == r_parens) { if (node->params.intval >= 0) { this_subexp = *re_nsub; ++*re_nsub; if (!*subexps) *subexps = (struct rexp_node **)malloc (sizeof (struct rexp_node *) * *re_nsub); else *subexps = (struct rexp_node **)realloc (*subexps, sizeof (struct rexp_node *) * *re_nsub); } } if (node->params.pair.left) id = rx_posix_analyze_rexp (subexps, re_nsub, node->params.pair.left, id); if (node->params.pair.right) id = rx_posix_analyze_rexp (subexps, re_nsub, node->params.pair.right, id); switch (node->type) { case r_cset: node->len = 1; node->observed = 0; break; case r_string: node->len = node->params.cstr.len; node->observed = 0; break; case r_cut: node->len = 0; node->observed = 0; break; case r_concat: case r_alternate: { int lob, rob; int llen, rlen; lob = (!node->params.pair.left ? 0 : node->params.pair.left->observed); rob = (!node->params.pair.right ? 0 : node->params.pair.right->observed); llen = (!node->params.pair.left ? 0 : node->params.pair.left->len); rlen = (!node->params.pair.right ? 0 : node->params.pair.right->len); node->len = ((llen >= 0) && (rlen >= 0) ? ((node->type == r_concat) ? llen + rlen : ((llen == rlen) ? llen : -1)) : -1); node->observed = lob || rob; break; } case r_opt: case r_star: case r_plus: node->len = -1; node->observed = (node->params.pair.left ? node->params.pair.left->observed : 0); break; case r_interval: node->len = -1; node->observed = 1; break; case r_parens: if (node->params.intval >= 0) { node->observed = 1; (*subexps)[this_subexp] = node; } else node->observed = (node->params.pair.left ? node->params.pair.left->observed : 0); node->len = (node->params.pair.left ? node->params.pair.left->len : 0); break; case r_context: switch (node->params.intval) { default: node->observed = 1; node->len = -1; break; case '^': case '$': case '=': case '<': case '>': case 'b': case 'B': case '`': case '\'': node->observed = 1; node->len = 0; break; } break; } if (node->observed) node->id = id++; return id; } return id; } /* Returns 0 unless the pattern can match the empty string. */ #ifdef __STDC__ int rx_fill_in_fastmap (int cset_size, unsigned char * map, struct rexp_node * exp) #else int rx_fill_in_fastmap (cset_size, map, exp) int cset_size; unsigned char * map; struct rexp_node * exp; #endif { if (!exp) { can_match_empty: { int x; for (x = 0; x < cset_size; ++x) map[x] = 1; } return 1; } switch (exp->type) { case r_cset: { int x; int most; most = exp->params.cset_size; for (x = 0; x < most; ++x) if (RX_bitset_member (exp->params.cset, x)) map[x] = 1; } return 0; case r_string: if (exp->params.cstr.len) { map[exp->params.cstr.contents[0]] = 1; return 0; } else return 1; case r_cut: return 1; case r_concat: return rx_fill_in_fastmap (cset_size, map, exp->params.pair.left); /* Why not the right branch? If the left branch * can't be empty it doesn't matter. If it can, then * the fastmap is already saturated, and again, the * right branch doesn't matter. */ case r_alternate: return ( rx_fill_in_fastmap (cset_size, map, exp->params.pair.left) | rx_fill_in_fastmap (cset_size, map, exp->params.pair.right)); case r_parens: case r_plus: return rx_fill_in_fastmap (cset_size, map, exp->params.pair.left); case r_opt: case r_star: goto can_match_empty; /* Why not the subtree? These operators already saturate * the fastmap. */ case r_interval: if (exp->params.intval == 0) goto can_match_empty; else return rx_fill_in_fastmap (cset_size, map, exp->params.pair.left); case r_context: goto can_match_empty; } /* this should never happen but gcc seems to like it */ return 0; } #ifdef __STDC__ int rx_is_anchored_p (struct rexp_node * exp) #else int rx_is_anchored_p (exp) struct rexp_node * exp; #endif { if (!exp) return 0; switch (exp->type) { case r_opt: case r_star: case r_cset: case r_string: case r_cut: return 0; case r_parens: case r_plus: case r_concat: return rx_is_anchored_p (exp->params.pair.left); case r_alternate: return ( rx_is_anchored_p (exp->params.pair.left) && rx_is_anchored_p (exp->params.pair.right)); case r_interval: if (exp->params.intval == 0) return 0; else return rx_is_anchored_p (exp->params.pair.left); case r_context: return (exp->params.intval == '^'); } /* this should never happen but gcc seems to like it */ return 0; } #ifdef __STDC__ enum rx_answers rx_start_superstate (struct rx_classical_system * frame) #else enum rx_answers rx_start_superstate (frame) struct rx_classical_system * frame; #endif { struct rx_superset * start_contents; struct rx_nfa_state_set * start_nfa_set; if (frame->rx->start_set) start_contents = frame->rx->start_set; else { { struct rx_possible_future * futures; futures = rx_state_possible_futures (frame->rx, frame->rx->start_nfa_states); if (!futures) return rx_bogus; if (futures->next) return rx_start_state_with_too_many_futures; start_nfa_set = futures->destset; } start_contents = rx_superstate_eclosure_union (frame->rx, rx_superset_cons (frame->rx, 0, 0), start_nfa_set); if (!start_contents) return rx_bogus; start_contents->starts_for = frame->rx; frame->rx->start_set = start_contents; } if ( start_contents->superstate && (start_contents->superstate->rx_id == frame->rx->rx_id)) { if (frame->state) { rx_unlock_superstate (frame->rx, frame->state); } frame->state = start_contents->superstate; /* The cached superstate may be in a semifree state. * We need to lock it and preserve the invariant * that a locked superstate is never semifree. * So refresh it. */ rx_refresh_this_superstate (frame->rx->cache, frame->state); rx_lock_superstate (frame->rx, frame->state); return rx_yes; } else { struct rx_superstate * state; rx_protect_superset (frame->rx, start_contents); state = rx_superstate (frame->rx, start_contents); rx_release_superset (frame->rx, start_contents); if (!state) return rx_bogus; if (frame->state) { rx_unlock_superstate (frame->rx, frame->state); } frame->state = state; rx_lock_superstate (frame->rx, frame->state); return rx_yes; } } #ifdef __STDC__ enum rx_answers rx_fit_p (struct rx_classical_system * frame, unsigned const char * burst, int len) #else enum rx_answers rx_fit_p (frame, burst, len) struct rx_classical_system * frame; unsigned const char * burst; int len; #endif { struct rx_inx * inx_table; struct rx_inx * inx; if (!frame->state) return rx_bogus; if (!len) { frame->final_tag = frame->state->contents->is_final; return (frame->state->contents->is_final ? rx_yes : rx_no); } inx_table = frame->state->transitions; rx_unlock_superstate (frame->rx, frame->state); while (len--) { struct rx_inx * next_table; inx = inx_table + *burst; next_table = (struct rx_inx *)inx->data; while (!next_table) { struct rx_superstate * state; state = ((struct rx_superstate *) ((char *)inx_table - ((unsigned long) ((struct rx_superstate *)0)->transitions))); switch ((int)inx->inx) { case rx_backtrack: /* RX_BACKTRACK means that we've reached the empty * superstate, indicating that match can't succeed * from this point. */ frame->state = 0; return rx_no; case rx_cache_miss: /* Because the superstate NFA is lazily constructed, * and in fact may erode from underneath us, we sometimes * have to construct the next instruction from the hard way. * This invokes one step in the lazy-conversion. */ inx = rx_handle_cache_miss (frame->rx, state, *burst, inx->data_2); if (!inx) { frame->state = 0; return rx_bogus; } next_table = (struct rx_inx *)inx->data; continue; /* No other instructions are legal here. * (In particular, this function does not handle backtracking * or the related instructions.) */ default: frame->state = 0; return rx_bogus; } } inx_table = next_table; ++burst; } if (inx->data_2) /* indicates a final superstate */ { frame->final_tag = (int)inx->data_2; frame->state = ((struct rx_superstate *) ((char *)inx_table - ((unsigned long) ((struct rx_superstate *)0)->transitions))); rx_lock_superstate (frame->rx, frame->state); return rx_yes; } frame->state = ((struct rx_superstate *) ((char *)inx_table - ((unsigned long) ((struct rx_superstate *)0)->transitions))); rx_lock_superstate (frame->rx, frame->state); return rx_no; } #ifdef __STDC__ enum rx_answers rx_advance (struct rx_classical_system * frame, unsigned const char * burst, int len) #else enum rx_answers rx_advance (frame, burst, len) struct rx_classical_system * frame; unsigned const char * burst; int len; #endif { struct rx_inx * inx_table; if (!frame->state) return rx_bogus; if (!len) return rx_yes; inx_table = frame->state->transitions; rx_unlock_superstate (frame->rx, frame->state); while (len--) { struct rx_inx * inx; struct rx_inx * next_table; inx = inx_table + *burst; next_table = (struct rx_inx *)inx->data; while (!next_table) { struct rx_superstate * state; state = ((struct rx_superstate *) ((char *)inx_table - ((unsigned long) ((struct rx_superstate *)0)->transitions))); switch ((int)inx->inx) { case rx_backtrack: /* RX_BACKTRACK means that we've reached the empty * superstate, indicating that match can't succeed * from this point. */ frame->state = 0; return rx_no; case rx_cache_miss: /* Because the superstate NFA is lazily constructed, * and in fact may erode from underneath us, we sometimes * have to construct the next instruction from the hard way. * This invokes one step in the lazy-conversion. */ inx = rx_handle_cache_miss (frame->rx, state, *burst, inx->data_2); if (!inx) { frame->state = 0; return rx_bogus; } next_table = (struct rx_inx *)inx->data; continue; /* No other instructions are legal here. * (In particular, this function does not handle backtracking * or the related instructions.) */ default: frame->state = 0; return rx_bogus; } } inx_table = next_table; ++burst; } frame->state = ((struct rx_superstate *) ((char *)inx_table - ((unsigned long) ((struct rx_superstate *)0)->transitions))); rx_lock_superstate (frame->rx, frame->state); return rx_yes; } #ifdef __STDC__ int rx_advance_to_final (struct rx_classical_system * frame, unsigned const char * burst, int len) #else int rx_advance_to_final (frame, burst, len) struct rx_classical_system * frame; unsigned const char * burst; int len; #endif { int initial_len; struct rx_inx * inx_table; struct rx_superstate * this_state; if (!frame->state) return 0; if (!len) { frame->final_tag = frame->state->contents->is_final; return 0; } inx_table = frame->state->transitions; initial_len = len; this_state = frame->state; while (len--) { struct rx_inx * inx; struct rx_inx * next_table; /* this_state holds the state for the position we're * leaving. this_state is locked. */ inx = inx_table + *burst; next_table = (struct rx_inx *)inx->data; while (!next_table) { struct rx_superstate * state; state = ((struct rx_superstate *) ((char *)inx_table - ((unsigned long) ((struct rx_superstate *)0)->transitions))); switch ((int)inx->inx) { case rx_backtrack: /* RX_BACKTRACK means that we've reached the empty * superstate, indicating that match can't succeed * from this point. * * Return to the state for the position prior to what * we failed at, and return that position. */ frame->state = this_state; frame->final_tag = this_state->contents->is_final; return (initial_len - len) - 1; case rx_cache_miss: /* Because the superstate NFA is lazily constructed, * and in fact may erode from underneath us, we sometimes * have to construct the next instruction from the hard way. * This invokes one step in the lazy-conversion. */ inx = rx_handle_cache_miss (frame->rx, state, *burst, inx->data_2); if (!inx) { rx_unlock_superstate (frame->rx, this_state); frame->state = 0; return -1; } next_table = (struct rx_inx *)inx->data; continue; /* No other instructions are legal here. * (In particular, this function does not handle backtracking * or the related instructions.) */ default: rx_unlock_superstate (frame->rx, this_state); frame->state = 0; return -1; } } /* Release the superstate for the preceeding position: */ rx_unlock_superstate (frame->rx, this_state); /* Compute the superstate for the new position: */ inx_table = next_table; this_state = ((struct rx_superstate *) ((char *)inx_table - ((unsigned long) ((struct rx_superstate *)0)->transitions))); /* Lock it (see top-of-loop invariant): */ rx_lock_superstate (frame->rx, this_state); /* Check to see if we should stop: */ if (this_state->contents->is_final) { frame->final_tag = this_state->contents->is_final; frame->state = this_state; return (initial_len - len); } ++burst; } /* Consumed all of the characters. */ frame->state = this_state; frame->final_tag = this_state->contents->is_final; /* state already locked (see top-of-loop invariant) */ return initial_len; } #ifdef __STDC__ void rx_terminate_system (struct rx_classical_system * frame) #else void rx_terminate_system (frame) struct rx_classical_system * frame; #endif { if (frame->state) { rx_unlock_superstate (frame->rx, frame->state); frame->state = 0; } } #ifdef __STDC__ void rx_init_system (struct rx_classical_system * frame, struct rx * rx) #else void rx_init_system (frame, rx) struct rx_classical_system * frame; struct rx * rx; #endif { frame->rx = rx; frame->state = 0; } rplay-3.3.2/rx/rxanal.h100644 153 62 4546 6552756454 13437 0ustar boynsstaff/* classes: h_files */ #ifndef RXANALH #define RXANALH /* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "rxcset.h" #include "rxnode.h" #include "rxsuper.h" enum rx_answers { rx_yes = 0, rx_no = 1, rx_bogus = -1, rx_start_state_with_too_many_futures = rx_bogus - 1 /* n < 0 -- error */ }; struct rx_classical_system { struct rx * rx; struct rx_superstate * state; int final_tag; }; #ifdef __STDC__ extern int rx_posix_analyze_rexp (struct rexp_node *** subexps, size_t * re_nsub, struct rexp_node * node, int id); extern int rx_fill_in_fastmap (int cset_size, unsigned char * map, struct rexp_node * exp); extern int rx_is_anchored_p (struct rexp_node * exp); extern enum rx_answers rx_start_superstate (struct rx_classical_system * frame); extern enum rx_answers rx_fit_p (struct rx_classical_system * frame, unsigned const char * burst, int len); extern enum rx_answers rx_advance (struct rx_classical_system * frame, unsigned const char * burst, int len); extern int rx_advance_to_final (struct rx_classical_system * frame, unsigned const char * burst, int len); extern void rx_terminate_system (struct rx_classical_system * frame); extern void rx_init_system (struct rx_classical_system * frame, struct rx * rx); #else /* STDC */ extern int rx_posix_analyze_rexp (); extern int rx_fill_in_fastmap (); extern int rx_is_anchored_p (); extern enum rx_answers rx_start_superstate (); extern enum rx_answers rx_fit_p (); extern enum rx_answers rx_advance (); extern int rx_advance_to_final (); extern void rx_terminate_system (); extern void rx_init_system (); #endif /* STDC */ #endif /* RXANALH */ rplay-3.3.2/rx/rxbasic.c100644 153 62 5566 6552756454 13603 0ustar boynsstaff/* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "rxall.h" #include "rxbasic.h" #include "rxstr.h" int rx_basic_unfaniverse_delay = RX_DEFAULT_NFA_DELAY; static struct rx_unfaniverse * rx_basic_uv = 0; static int init_basic_once () { if (rx_basic_uv) return 0; rx_basic_uv = rx_make_unfaniverse (rx_basic_unfaniverse_delay); return (rx_basic_uv ? 0 : -1); } #ifdef __STDC__ struct rx_unfaniverse * rx_basic_unfaniverse (void) #else struct rx_unfaniverse * rx_basic_unfaniverse () #endif { if (init_basic_once ()) return 0; return rx_basic_uv; } static char * silly_hack = 0; #ifdef __STDC__ struct rx_solutions * rx_basic_make_solutions (struct rx_registers * regs, struct rexp_node * expression, struct rexp_node ** subexps, int start, int end, struct rx_context_rules * rules, const unsigned char * str) #else struct rx_solutions * rx_basic_make_solutions (regs, expression, subexps, start, end, rules, str) struct rx_registers * regs; struct rexp_node * expression; struct rexp_node ** subexps; int start; int end; struct rx_context_rules * rules; const unsigned char * str; #endif { struct rx_str_closure * closure; if (init_basic_once ()) return 0; /* bogus but rare */ if ( expression && (expression->len >= 0) && (expression->len != (end - start))) return &rx_no_solutions; if (silly_hack) { closure = (struct rx_str_closure *)silly_hack; silly_hack = 0; } else closure = (struct rx_str_closure *)malloc (sizeof (*closure)); if (!closure) return 0; closure->str = str; closure->len = end; closure->rules = *rules; return rx_make_solutions (regs, rx_basic_uv, expression, subexps, 256, start, end, rx_str_vmfn, rx_str_contextfn, (void *)closure); } #ifdef __STDC__ void rx_basic_free_solutions (struct rx_solutions * solns) #else void rx_basic_free_solutions (solns) struct rx_solutions * solns; #endif { if (solns == &rx_no_solutions) return; if (!silly_hack) silly_hack = (char *)solns->closure; else free (solns->closure); solns->closure = 0; rx_free_solutions (solns); } rplay-3.3.2/rx/rxbasic.h100644 153 62 3415 6552756454 13577 0ustar boynsstaff/* classes: h_files */ #ifndef RXBASICH #define RXBASICH /* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "rxcontext.h" #include "rxnode.h" #include "rxspencer.h" #include "rxunfa.h" #ifndef RX_DEFAULT_NFA_DELAY /* This value bounds the number of NFAs kept in a cache of recent NFAs. * This value is used whenever the rx_basic_* entry points are used, * for example, when the Posix entry points are invoked. */ #define RX_DEFAULT_NFA_DELAY 64 #endif #ifdef __STDC__ extern struct rx_unfaniverse * rx_basic_unfaniverse (void); extern struct rx_solutions * rx_basic_make_solutions (struct rx_registers * regs, struct rexp_node * expression, struct rexp_node ** subexps, int start, int end, struct rx_context_rules * rules, const unsigned char * str); extern void rx_basic_free_solutions (struct rx_solutions * solns); #else /* STDC */ extern struct rx_unfaniverse * rx_basic_unfaniverse (); extern struct rx_solutions * rx_basic_make_solutions (); extern void rx_basic_free_solutions (); #endif /* STDC */ #endif /* RXBASICH */ rplay-3.3.2/rx/rxbitset.c100644 153 62 14567 6552756454 14035 0ustar boynsstaff/* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* * Tom Lord (lord@cygnus.com, lord@gnu.ai.mit.edu) */ #include "rxall.h" #include "rxbitset.h" #ifdef __STDC__ int rx_bitset_is_equal (int size, rx_Bitset a, rx_Bitset b) #else int rx_bitset_is_equal (size, a, b) int size; rx_Bitset a; rx_Bitset b; #endif { int x; RX_subset s; if (size == 0) return 1; s = b[0]; b[0] = ~a[0]; for (x = rx_bitset_numb_subsets(size) - 1; a[x] == b[x]; --x) ; b[0] = s; return !x && (s == a[0]); } #ifdef __STDC__ int rx_bitset_is_subset (int size, rx_Bitset a, rx_Bitset b) #else int rx_bitset_is_subset (size, a, b) int size; rx_Bitset a; rx_Bitset b; #endif { int x; x = rx_bitset_numb_subsets(size) - 1; while (x-- && ((a[x] & b[x]) == a[x])); return x == -1; } #ifdef __STDC__ int rx_bitset_empty (int size, rx_Bitset set) #else int rx_bitset_empty (size, set) int size; rx_Bitset set; #endif { int x; RX_subset s; s = set[0]; set[0] = 1; for (x = rx_bitset_numb_subsets(size) - 1; !set[x]; --x) ; set[0] = s; return !s; } #ifdef __STDC__ void rx_bitset_null (int size, rx_Bitset b) #else void rx_bitset_null (size, b) int size; rx_Bitset b; #endif { rx_bzero ((char *)b, rx_sizeof_bitset(size)); } #ifdef __STDC__ void rx_bitset_universe (int size, rx_Bitset b) #else void rx_bitset_universe (size, b) int size; rx_Bitset b; #endif { int x = rx_bitset_numb_subsets (size); while (x--) *b++ = ~(RX_subset)0; } #ifdef __STDC__ void rx_bitset_complement (int size, rx_Bitset b) #else void rx_bitset_complement (size, b) int size; rx_Bitset b; #endif { int x = rx_bitset_numb_subsets (size); while (x--) { *b = ~*b; ++b; } } #ifdef __STDC__ void rx_bitset_assign (int size, rx_Bitset a, rx_Bitset b) #else void rx_bitset_assign (size, a, b) int size; rx_Bitset a; rx_Bitset b; #endif { int x; for (x = rx_bitset_numb_subsets(size) - 1; x >=0; --x) a[x] = b[x]; } #ifdef __STDC__ void rx_bitset_union (int size, rx_Bitset a, rx_Bitset b) #else void rx_bitset_union (size, a, b) int size; rx_Bitset a; rx_Bitset b; #endif { int x; for (x = rx_bitset_numb_subsets(size) - 1; x >=0; --x) a[x] |= b[x]; } #ifdef __STDC__ void rx_bitset_intersection (int size, rx_Bitset a, rx_Bitset b) #else void rx_bitset_intersection (size, a, b) int size; rx_Bitset a; rx_Bitset b; #endif { int x; for (x = rx_bitset_numb_subsets(size) - 1; x >=0; --x) a[x] &= b[x]; } #ifdef __STDC__ void rx_bitset_difference (int size, rx_Bitset a, rx_Bitset b) #else void rx_bitset_difference (size, a, b) int size; rx_Bitset a; rx_Bitset b; #endif { int x; for (x = rx_bitset_numb_subsets(size) - 1; x >=0; --x) a[x] &= ~ b[x]; } #ifdef __STDC__ void rx_bitset_revdifference (int size, rx_Bitset a, rx_Bitset b) #else void rx_bitset_revdifference (size, a, b) int size; rx_Bitset a; rx_Bitset b; #endif { int x; for (x = rx_bitset_numb_subsets(size) - 1; x >=0; --x) a[x] = ~a[x] & b[x]; } #ifdef __STDC__ void rx_bitset_xor (int size, rx_Bitset a, rx_Bitset b) #else void rx_bitset_xor (size, a, b) int size; rx_Bitset a; rx_Bitset b; #endif { int x; for (x = rx_bitset_numb_subsets(size) - 1; x >=0; --x) a[x] ^= b[x]; } #ifdef __STDC__ unsigned long rx_bitset_hash (int size, rx_Bitset b) #else unsigned long rx_bitset_hash (size, b) int size; rx_Bitset b; #endif { int x; unsigned long answer; answer = 0; for (x = 0; x < size; ++x) { if (RX_bitset_member (b, x)) answer += (answer << 3) + x; } return answer; } RX_subset rx_subset_singletons [RX_subset_bits] = { 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000, 0x20000, 0x40000, 0x80000, 0x100000, 0x200000, 0x400000, 0x800000, 0x1000000, 0x2000000, 0x4000000, 0x8000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000 }; /* * (define l (let loop ((x 0) (l '())) (if (eq? x 256) l (loop (+ x 1) (cons x l))))) * (define lb (map (lambda (n) (number->string n 2)) l)) * (define lc (map string->list lb)) * (define ln (map (lambda (l) (map (lambda (c) (if (eq? c #\1) 1 0)) l)) lc)) * (define lt (map (lambda (l) (apply + l)) ln)) */ static int char_pops[256] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 }; #define RX_char_population(C) (char_pops[C]) #ifdef __STDC__ int rx_bitset_population (int size, rx_Bitset a) #else int rx_bitset_population (size, a) int size; rx_Bitset a; #endif { int x; int total; unsigned char s; if (size == 0) return 0; total = 0; x = sizeof (RX_subset) * rx_bitset_numb_subsets(size) - 1; while (x >= 0) { s = ((unsigned char *)a)[x]; --x; total = total + RX_char_population (s); } return total; } rplay-3.3.2/rx/rxbitset.h100644 153 62 7116 6552756454 14012 0ustar boynsstaff/* classes: h_files */ #ifndef RXBITSETH #define RXBITSETH /* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ typedef unsigned long RX_subset; #define RX_subset_bits (8 * sizeof (RX_subset)) #define RX_subset_mask (RX_subset_bits - 1) typedef RX_subset * rx_Bitset; #ifdef __STDC__ typedef void (*rx_bitset_iterator) (rx_Bitset, int member_index); #else typedef void (*rx_bitset_iterator) (); #endif /* Return the index of the word containing the Nth bit. */ #define rx_bitset_subset(N) ((N) / RX_subset_bits) /* Return the conveniently-sized supset containing the Nth bit. */ #define rx_bitset_subset_val(B,N) ((B)[rx_bitset_subset(N)]) /* Genericly combine the word containing the Nth bit with a 1 bit mask * of the Nth bit position within that word. */ #define RX_bitset_access(B,N,OP) \ ((B)[rx_bitset_subset(N)] OP rx_subset_singletons[(N) & RX_subset_mask]) #define RX_bitset_member(B,N) RX_bitset_access(B, N, &) #define RX_bitset_enjoin(B,N) RX_bitset_access(B, N, |=) #define RX_bitset_remove(B,N) RX_bitset_access(B, N, &= ~) #define RX_bitset_toggle(B,N) RX_bitset_access(B, N, ^= ) /* How many words are needed for N bits? */ #define rx_bitset_numb_subsets(N) (((N) + RX_subset_bits - 1) / RX_subset_bits) /* How much memory should be allocated for a bitset with N bits? */ #define rx_sizeof_bitset(N) (rx_bitset_numb_subsets(N) * sizeof(RX_subset)) extern RX_subset rx_subset_singletons[]; #ifdef __STDC__ extern int rx_bitset_is_equal (int size, rx_Bitset a, rx_Bitset b); extern int rx_bitset_is_subset (int size, rx_Bitset a, rx_Bitset b); extern int rx_bitset_empty (int size, rx_Bitset set); extern void rx_bitset_null (int size, rx_Bitset b); extern void rx_bitset_universe (int size, rx_Bitset b); extern void rx_bitset_complement (int size, rx_Bitset b); extern void rx_bitset_assign (int size, rx_Bitset a, rx_Bitset b); extern void rx_bitset_union (int size, rx_Bitset a, rx_Bitset b); extern void rx_bitset_intersection (int size, rx_Bitset a, rx_Bitset b); extern void rx_bitset_difference (int size, rx_Bitset a, rx_Bitset b); extern void rx_bitset_revdifference (int size, rx_Bitset a, rx_Bitset b); extern void rx_bitset_xor (int size, rx_Bitset a, rx_Bitset b); extern unsigned long rx_bitset_hash (int size, rx_Bitset b); extern int rx_bitset_population (int size, rx_Bitset a); #else /* STDC */ extern int rx_bitset_is_equal (); extern int rx_bitset_is_subset (); extern int rx_bitset_empty (); extern void rx_bitset_null (); extern void rx_bitset_universe (); extern void rx_bitset_complement (); extern void rx_bitset_assign (); extern void rx_bitset_union (); extern void rx_bitset_intersection (); extern void rx_bitset_difference (); extern void rx_bitset_revdifference (); extern void rx_bitset_xor (); extern unsigned long rx_bitset_hash (); extern int rx_bitset_population (); #endif /* STDC */ #endif /* RXBITSETH */ rplay-3.3.2/rx/rxcontext.h100644 153 62 2304 6552756454 14176 0ustar boynsstaff/* classes: h_files */ #ifndef RXCONTEXTH #define RXCONTEXTH /* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ struct rx_context_rules { unsigned int newline_anchor:1;/* If true, an anchor at a newline matches.*/ unsigned int not_bol:1; /* If set, the anchors ('^' and '$') don't */ unsigned int not_eol:1; /* match at the ends of the string. */ unsigned int case_indep:1; }; #ifdef __STDC__ #else /* STDC */ #endif /* STDC */ #endif /* RXCONTEXTH */ rplay-3.3.2/rx/rxcset.c100644 153 62 3053 6552756454 13445 0ustar boynsstaff/* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* * Tom Lord (lord@cygnus.com, lord@gnu.ai.mit.edu) */ #include "rxall.h" #include "rxcset.h" /* Utilities for manipulating bitset represntations of characters sets. */ #ifdef __STDC__ rx_Bitset rx_cset (int size) #else rx_Bitset rx_cset (size) int size; #endif { rx_Bitset b; b = (rx_Bitset) malloc (rx_sizeof_bitset (size)); if (b) rx_bitset_null (size, b); return b; } #ifdef __STDC__ rx_Bitset rx_copy_cset (int size, rx_Bitset a) #else rx_Bitset rx_copy_cset (size, a) int size; rx_Bitset a; #endif { rx_Bitset cs; cs = rx_cset (size); if (cs) rx_bitset_union (size, cs, a); return cs; } #ifdef __STDC__ void rx_free_cset (rx_Bitset c) #else void rx_free_cset (c) rx_Bitset c; #endif { if (c) free ((char *)c); } rplay-3.3.2/rx/rxcset.h100644 153 62 2302 6552756454 13446 0ustar boynsstaff/* classes: h_files */ #ifndef RXCSETH #define RXCSETH /* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* lord Sun May 7 12:34:11 1995 */ #include "rxbitset.h" #ifdef __STDC__ extern rx_Bitset rx_cset (int size); extern rx_Bitset rx_copy_cset (int size, rx_Bitset a); extern void rx_free_cset (rx_Bitset c); #else /* STDC */ extern rx_Bitset rx_cset (); extern rx_Bitset rx_copy_cset (); extern void rx_free_cset (); #endif /* STDC */ #endif /* RXCSETH */ rplay-3.3.2/rx/rxdbug.c100644 153 62 12233 6552756454 13450 0ustar boynsstaff/* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include #include "rxall.h" #include "rxgnucomp.h" #include "rxnfa.h" #ifdef HAVE_POSITIONAL_ARRAY_INITS #define AT(X) [X] = #else #define AT(X) #endif char *node_type_names[] = { AT(r_cset) "r_cset", AT(r_concat) "r_concat", AT(r_alternate) "r_alternate", AT(r_opt) "r_opt", AT(r_star) "r_star", AT(r_plus) "r_plus", AT(r_string) "r_string", AT(r_cut) "r_cut", AT(r_interval) "r_interval", AT(r_parens) "r_parens", AT(r_context) "r_context" }; void print_cset (cset_size, cs) int cset_size; rx_Bitset cs; { int x; if (!cs) printf ("nil"); else { putchar ('['); for (x = 0; x < cset_size; ++x) if (RX_bitset_member (cs, x)) { if (isprint(x)) putchar (x); else printf ("\\0%o ", x); } putchar (']'); } } void print_string(struct rx_string *s, char bracket) { int x; if (!s && bracket) printf ("nil"); else { if (bracket) putchar ('\"'); for (x = 0; x < s->len; ++x) if (isprint(s->contents[x])) putchar (s->contents[x]); else printf ("\\0%o ", x); if (bracket) putchar ('\"'); } } void spaces (n) int n; { while (n--) putchar (' '); } void print_rexp (cset_size, indent, rexp) int cset_size; int indent; struct rexp_node * rexp; { spaces (indent); if (!rexp) printf ("nil\n"); else { printf ("Node %d type %d (%s), iv=%d(%c), iv2=%d, len=%d obs=%d cs=", rexp->id, rexp->type, node_type_names[rexp->type], rexp->params.intval, (isprint (rexp->params.intval) ? rexp->params.intval : ' '), rexp->params.intval2, rexp->len, rexp->observed); print_cset (cset_size, rexp->params.cset); printf (" s="); print_string (&(rexp->params.cstr), 1); putchar ('\n'); if (rexp->params.pair.left || rexp->params.pair.right) { print_rexp (cset_size, indent + 2, rexp->params.pair.left); print_rexp (cset_size, indent + 2, rexp->params.pair.right); } } } void unparse_print_rexp (cset_size, rexp) int cset_size; struct rexp_node * rexp; { if (!rexp) return; else switch (rexp->type) { case r_cset: if (1 != rx_bitset_population (cset_size, rexp->params.cset)) print_cset (cset_size, rexp->params.cset); else { int x; rx_Bitset cs; cs = rexp->params.cset; for (x = 0; x < cset_size; ++x) if (RX_bitset_member (cs, x)) { if (isprint(x)) putchar (x); else printf ("\\0%o ", x); } } break; case r_string: print_string (&(rexp->params.cstr), 0); break; case r_parens: putchar ('('); unparse_print_rexp (cset_size, rexp->params.pair.left); putchar (')'); break; case r_context: putchar ('\\'); putchar (rexp->params.intval); break; case r_cut: printf ("[[:cut %d:]]", rexp->params.intval); break; case r_concat: unparse_print_rexp (cset_size, rexp->params.pair.left); unparse_print_rexp (cset_size, rexp->params.pair.right); break; case r_alternate: unparse_print_rexp (cset_size, rexp->params.pair.left); putchar ('|'); unparse_print_rexp (cset_size, rexp->params.pair.right); break; case r_opt: unparse_print_rexp (cset_size, rexp->params.pair.left); putchar ('?'); break; case r_star: unparse_print_rexp (cset_size, rexp->params.pair.left); putchar ('*'); break; case r_plus: unparse_print_rexp (cset_size, rexp->params.pair.left); putchar ('+'); break; case r_interval: unparse_print_rexp (cset_size, rexp->params.pair.left); printf ("{%d,%d}", rexp->params.intval, rexp->params.intval2); break; } } void print_nfa_state (rx, state) struct rx * rx; struct rx_nfa_state * state; { struct rx_nfa_edge * e; printf ("state %d, is_final %d, is_start %d\n", state->id, state->is_final, state->is_start); for (e = state->edges; e; e = e->next) { printf ("\tEdge %s to %d ", (e->type == ne_cset ? "cset" : (e->type == ne_epsilon ? "epsilon" : "side effect")), e->dest->id); if (e->type == ne_cset) print_cset (rx->local_cset_size, e->params.cset); else printf ("%d", (int)e->params.side_effect); putchar ('\n'); } } void print_nfa (rx) struct rx * rx; { struct rx_nfa_state * state; for (state = rx->nfa_states; state; state = state->next) print_nfa_state (rx, state); } rplay-3.3.2/rx/rxgnucomp.c100644 153 62 125466 6552756454 14234 0ustar boynsstaff/* Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include #include "rxall.h" #include "rxgnucomp.h" #include "inst-rxposix.h" /* {A Syntax Table} */ /* Define the syntax basics for \<, \>, etc. */ #ifndef emacs #define CHARBITS 8 #define CHAR_SET_SIZE (1 << CHARBITS) #define Sword 1 #define SYNTAX(c) re_syntax_table[c] char re_syntax_table[CHAR_SET_SIZE]; #ifdef __STDC__ static void init_syntax_once (void) #else static void init_syntax_once () #endif { register int c; static int done = 0; if (done) return; rx_bzero ((char *)re_syntax_table, sizeof re_syntax_table); for (c = 'a'; c <= 'z'; c++) re_syntax_table[c] = Sword; for (c = 'A'; c <= 'Z'; c++) re_syntax_table[c] = Sword; for (c = '0'; c <= '9'; c++) re_syntax_table[c] = Sword; re_syntax_table['_'] = Sword; done = 1; } #endif /* not emacs */ const char *rx_error_msg[] = { 0, /* REG_NOUT */ "No match", /* REG_NOMATCH */ "Invalid regular expression", /* REG_BADPAT */ "Invalid collation character", /* REG_ECOLLATE */ "Invalid character class name", /* REG_ECTYPE */ "Trailing backslash", /* REG_EESCAPE */ "Invalid back reference", /* REG_ESUBREG */ "Unmatched [ or [^", /* REG_EBRACK */ "Unmatched ( or \\(", /* REG_EPAREN */ "Unmatched \\{", /* REG_EBRACE */ "Invalid content of \\{\\}", /* REG_BADBR */ "Invalid range end", /* REG_ERANGE */ "Memory exhausted", /* REG_ESPACE */ "Invalid preceding regular expression", /* REG_BADRPT */ "Premature end of regular expression", /* REG_EEND */ "Regular expression too big", /* REG_ESIZE */ "Unmatched ) or \\)", /* REG_ERPAREN */ }; /* * Macros used while compiling patterns. * * By convention, PEND points just past the end of the uncompiled pattern, * P points to the read position in the pattern. `translate' is the name * of the translation table (`TRANSLATE' is the name of a macro that looks * things up in `translate'). */ /* * Fetch the next character in the uncompiled pattern---translating it * if necessary. *Also cast from a signed character in the constant * string passed to us by the user to an unsigned char that we can use * as an array index (in, e.g., `translate'). */ #define PATFETCH(c) \ do {if (p == pend) return REG_EEND; \ c = (unsigned char) *p++; \ c = translate[c]; \ } while (0) /* * Fetch the next character in the uncompiled pattern, with no * translation. */ #define PATFETCH_RAW(c) \ do {if (p == pend) return REG_EEND; \ c = (unsigned char) *p++; \ } while (0) /* Go backwards one character in the pattern. */ #define PATUNFETCH p-- #define TRANSLATE(d) translate[(unsigned char) (d)] typedef int regnum_t; /* Since offsets can go either forwards or backwards, this type needs to * be able to hold values from -(MAX_BUF_SIZE - 1) to MAX_BUF_SIZE - 1. */ typedef int pattern_offset_t; typedef struct { struct rexp_node ** top_expression; struct rexp_node ** last_expression; struct rexp_node ** last_non_regular_expression; pattern_offset_t inner_group_offset; regnum_t regnum; } compile_stack_elt_t; typedef struct { compile_stack_elt_t *stack; unsigned size; unsigned avail; /* Offset of next open position. */ } compile_stack_type; #define INIT_COMPILE_STACK_SIZE 32 #define COMPILE_STACK_EMPTY (compile_stack.avail == 0) #define COMPILE_STACK_FULL (compile_stack.avail == compile_stack.size) /* The next available element. */ #define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail]) /* Set the bit for character C in a list. */ #define SET_LIST_BIT(c) \ (b[((unsigned char) (c)) / CHARBITS] \ |= 1 << (((unsigned char) c) % CHARBITS)) /* Get the next unsigned number in the uncompiled pattern. */ #define GET_UNSIGNED_NUMBER(num) \ { if (p != pend) \ { \ PATFETCH (c); \ while (isdigit (c)) \ { \ if (num < 0) \ num = 0; \ num = num * 10 + c - '0'; \ if (p == pend) \ break; \ PATFETCH (c); \ } \ } \ } #define CHAR_CLASS_MAX_LENGTH 64 #define IS_CHAR_CLASS(string) \ (!strcmp (string, "alpha") || !strcmp (string, "upper") \ || !strcmp (string, "lower") || !strcmp (string, "digit") \ || !strcmp (string, "alnum") || !strcmp (string, "xdigit") \ || !strcmp (string, "space") || !strcmp (string, "print") \ || !strcmp (string, "punct") || !strcmp (string, "graph") \ || !strcmp (string, "cntrl") || !strcmp (string, "blank")) /* These predicates are used in regex_compile. */ /* P points to just after a ^ in PATTERN. Return true if that ^ comes * after an alternative or a begin-subexpression. We assume there is at * least one character before the ^. */ #ifdef __STDC__ static int at_begline_loc_p (const char *pattern, const char * p, unsigned long syntax) #else static int at_begline_loc_p (pattern, p, syntax) const char *pattern; const char * p; unsigned long syntax; #endif { const char *prev = p - 2; int prev_prev_backslash = ((prev > pattern) && (prev[-1] == '\\')); return (/* After a subexpression? */ ((*prev == '(') && ((syntax & RE_NO_BK_PARENS) || prev_prev_backslash)) || /* After an alternative? */ ((*prev == '|') && ((syntax & RE_NO_BK_VBAR) || prev_prev_backslash)) ); } /* The dual of at_begline_loc_p. This one is for $. We assume there is * at least one character after the $, i.e., `P < PEND'. */ #ifdef __STDC__ static int at_endline_loc_p (const char *p, const char *pend, int syntax) #else static int at_endline_loc_p (p, pend, syntax) const char *p; const char *pend; int syntax; #endif { const char *next = p; int next_backslash = (*next == '\\'); const char *next_next = (p + 1 < pend) ? (p + 1) : 0; return ( /* Before a subexpression? */ ((syntax & RE_NO_BK_PARENS) ? (*next == ')') : (next_backslash && next_next && (*next_next == ')'))) || /* Before an alternative? */ ((syntax & RE_NO_BK_VBAR) ? (*next == '|') : (next_backslash && next_next && (*next_next == '|'))) ); } unsigned char rx_id_translation[256] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 }; /* The compiler keeps an inverted translation table. * This looks up/inititalize elements. * VALID is an array of booleans that validate CACHE. */ #ifdef __STDC__ static rx_Bitset inverse_translation (int * n_members, int cset_size, char * valid, rx_Bitset cache, unsigned char * translate, int c) #else static rx_Bitset inverse_translation (n_members, cset_size, valid, cache, translate, c) int * n_members; int cset_size; char * valid; rx_Bitset cache; unsigned char * translate; int c; #endif { rx_Bitset cs; cs = cache + c * rx_bitset_numb_subsets (cset_size); if (!valid[c]) { int x; int c_tr; int membs; c_tr = TRANSLATE(c); rx_bitset_null (cset_size, cs); membs = 0; for (x = 0; x < 256; ++x) if (TRANSLATE(x) == c_tr) { RX_bitset_enjoin (cs, x); membs++; } valid[c] = 1; n_members[c] = membs; } return cs; } /* More subroutine declarations and macros for regex_compile. */ /* Returns true if REGNUM is in one of COMPILE_STACK's elements and * false if it's not. */ #ifdef __STDC__ static int group_in_compile_stack (compile_stack_type compile_stack, regnum_t regnum) #else static int group_in_compile_stack (compile_stack, regnum) compile_stack_type compile_stack; regnum_t regnum; #endif { int this_element; for (this_element = compile_stack.avail - 1; this_element >= 0; this_element--) if (compile_stack.stack[this_element].regnum == regnum) return 1; return 0; } /* * Read the ending character of a range (in a bracket expression) from the * uncompiled pattern *P_PTR (which ends at PEND). We assume the * starting character is in `P[-2]'. (`P[-1]' is the character `-'.) * Then we set the translation of all bits between the starting and * ending characters (inclusive) in the compiled pattern B. * * Return an error code. * * We use these short variable names so we can use the same macros as * `regex_compile' itself. */ #ifdef __STDC__ static int compile_range (int * n_members, int cset_size, rx_Bitset cs, const char ** p_ptr, const char * pend, unsigned char * translate, unsigned long syntax, rx_Bitset inv_tr, char * valid_inv_tr) #else static int compile_range (n_members, cset_size, cs, p_ptr, pend, translate, syntax, inv_tr, valid_inv_tr) int * n_members; int cset_size; rx_Bitset cs; const char ** p_ptr; const char * pend; unsigned char * translate; unsigned long syntax; rx_Bitset inv_tr; char * valid_inv_tr; #endif { unsigned this_char; const char *p = *p_ptr; unsigned char range_end; unsigned char range_start = TRANSLATE(p[-2]); if (p == pend) return REG_ERANGE; PATFETCH (range_end); (*p_ptr)++; if (range_start > range_end) return syntax & RE_NO_EMPTY_RANGES ? REG_ERANGE : REG_NOERROR; for (this_char = range_start; this_char <= range_end; this_char++) { rx_Bitset it = inverse_translation (n_members, cset_size, valid_inv_tr, inv_tr, translate, this_char); rx_bitset_union (cset_size, cs, it); } return REG_NOERROR; } #ifdef __STDC__ static int pointless_if_repeated (struct rexp_node * node) #else static int pointless_if_repeated (node) struct rexp_node * node; #endif { if (!node) return 1; switch (node->type) { case r_cset: case r_string: case r_cut: return 0; case r_concat: case r_alternate: return (pointless_if_repeated (node->params.pair.left) && pointless_if_repeated (node->params.pair.right)); case r_opt: case r_star: case r_interval: case r_parens: return pointless_if_repeated (node->params.pair.left); case r_context: switch (node->params.intval) { case '=': case '<': case '^': case 'b': case 'B': case '`': case '\'': return 1; default: return 0; } default: return 0; } } #ifdef __STDC__ static int factor_string (struct rexp_node *** lastp, int cset_size) #else static int factor_string (lastp, cset_size) struct rexp_node *** lastp; int cset_size; #endif { struct rexp_node ** expp; struct rexp_node * exp; rx_Bitset cs; struct rexp_node * cset_node; expp = *lastp; exp = *expp; /* presumed r_string */ cs = rx_cset (cset_size); if (!cs) return -1; RX_bitset_enjoin (cs, exp->params.cstr.contents[exp->params.cstr.len - 1]); cset_node = rx_mk_r_cset (r_cset, cset_size, cs); if (!cset_node) { rx_free_cset (cs); return -1; } if (exp->params.cstr.len == 1) { rx_free_rexp (exp); *expp = cset_node; /* lastp remains the same */ return 0; } else { struct rexp_node * concat_node; exp->params.cstr.len--; concat_node = rx_mk_r_binop (r_concat, exp, cset_node); if (!concat_node) { rx_free_rexp (cset_node); return -1; } *expp = concat_node; *lastp = &concat_node->params.pair.right; return 0; } } #define isa_blank(C) (((C) == ' ') || ((C) == '\t')) #ifdef __STDC__ int rx_parse (struct rexp_node ** rexp_p, const char *pattern, int size, unsigned long syntax, int cset_size, unsigned char *translate) #else int rx_parse (rexp_p, pattern, size, syntax, cset_size, translate) struct rexp_node ** rexp_p; const char *pattern; int size; unsigned long syntax; int cset_size; unsigned char *translate; #endif { int compile_error; RX_subset inverse_translate [CHAR_SET_SIZE * rx_bitset_numb_subsets(CHAR_SET_SIZE)]; char validate_inv_tr [CHAR_SET_SIZE]; int n_members [CHAR_SET_SIZE]; /* We fetch characters from PATTERN here. Even though PATTERN is * `char *' (i.e., signed), we declare these variables as unsigned, so * they can be reliably used as array indices. */ register unsigned char c; register unsigned char c1; /* A random tempory spot in PATTERN. */ const char *p1; /* Keeps track of unclosed groups. */ compile_stack_type compile_stack; /* Points to the current (ending) position in the pattern. */ const char *p; const char *pend; /* When parsing is done, this will hold the expression tree. */ struct rexp_node * rexp; /* This and top_expression are saved on the compile stack. */ struct rexp_node ** top_expression; struct rexp_node ** last_non_regular_expression; struct rexp_node ** last_expression; /* Parameter to `goto append_node' */ struct rexp_node * append; /* Counts open-groups as they are encountered. This is the index of the * innermost group being compiled. */ regnum_t regnum; /* True iff the sub-expression just started * is purely syntactic. Otherwise, a regmatch data * slot is allocated for the subexpression. */ int syntax_only_parens; /* Place in the uncompiled pattern (i.e., the {) to * which to go back if the interval is invalid. */ const char *beg_interval; int side; if (!translate) translate = rx_id_translation; /* Points to the current (ending) position in the pattern. */ p = pattern; pend = pattern + size; /* When parsing is done, this will hold the expression tree. */ rexp = 0; /* In the midst of compilation, this holds onto the regexp * first parst while rexp goes on to aquire additional constructs. */ top_expression = &rexp; last_non_regular_expression = top_expression; last_expression = top_expression; /* Counts open-groups as they are encountered. This is the index of the * innermost group being compiled. */ regnum = 0; rx_bzero ((char *)validate_inv_tr, sizeof (validate_inv_tr)); /* Initialize the compile stack. */ compile_stack.stack = (( compile_stack_elt_t *) malloc ((INIT_COMPILE_STACK_SIZE) * sizeof ( compile_stack_elt_t))); if (compile_stack.stack == 0) return REG_ESPACE; compile_stack.size = INIT_COMPILE_STACK_SIZE; compile_stack.avail = 0; #if !defined (emacs) && !defined (SYNTAX_TABLE) /* Initialize the syntax table. */ init_syntax_once (); #endif /* Loop through the uncompiled pattern until we're at the end. */ while (p != pend) { PATFETCH (c); switch (c) { case '^': { if ( /* If at start of pattern, it's an operator. */ p == pattern + 1 /* If context independent, it's an operator. */ || syntax & RE_CONTEXT_INDEP_ANCHORS /* Otherwise, depends on what's come before. */ || at_begline_loc_p (pattern, p, syntax)) { struct rexp_node * n = rx_mk_r_int (r_context, '^'); if (!n) goto space_error; append = n; goto append_node; } else goto normal_char; } break; case '$': { if ( /* If at end of pattern, it's an operator. */ p == pend /* If context independent, it's an operator. */ || syntax & RE_CONTEXT_INDEP_ANCHORS /* Otherwise, depends on what's next. */ || at_endline_loc_p (p, pend, syntax)) { struct rexp_node * n = rx_mk_r_int (r_context, '$'); if (!n) goto space_error; append = n; goto append_node; } else goto normal_char; } break; case '+': case '?': if ((syntax & RE_BK_PLUS_QM) || (syntax & RE_LIMITED_OPS)) goto normal_char; handle_plus: case '*': /* If there is no previous pattern... */ if (pointless_if_repeated (*last_expression)) { if (syntax & RE_CONTEXT_INVALID_OPS) { compile_error = REG_BADRPT; goto error_return; } else if (!(syntax & RE_CONTEXT_INDEP_OPS)) goto normal_char; } { /* 1 means zero (many) matches is allowed. */ char zero_times_ok = 0, many_times_ok = 0; /* If there is a sequence of repetition chars, collapse it down to just one (the right one). We can't combine interval operators with these because of, e.g., `a{2}*', which should only match an even number of `a's. */ for (;;) { zero_times_ok |= c != '+'; many_times_ok |= c != '?'; if (p == pend) break; PATFETCH (c); if (c == '*' || (!(syntax & RE_BK_PLUS_QM) && (c == '+' || c == '?'))) ; else if (syntax & RE_BK_PLUS_QM && c == '\\') { if (p == pend) { compile_error = REG_EESCAPE; goto error_return; } PATFETCH (c1); if (!(c1 == '+' || c1 == '?')) { PATUNFETCH; PATUNFETCH; break; } c = c1; } else { PATUNFETCH; break; } /* If we get here, we found another repeat character. */ } /* Now we know whether or not zero matches is allowed * and also whether or not two or more matches is allowed. */ { struct rexp_node * inner_exp; struct rexp_node * star; if (*last_expression && ((*last_expression)->type == r_string)) if (factor_string (&last_expression, cset_size)) goto space_error; inner_exp = *last_expression; star = rx_mk_r_monop ((many_times_ok ? (zero_times_ok ? r_star : r_plus) : r_opt), inner_exp); if (!star) goto space_error; *last_expression = star; } } break; case '.': { rx_Bitset cs; struct rexp_node * n; cs = rx_cset (cset_size); if (!cs) goto space_error; n = rx_mk_r_cset (r_cset, cset_size, cs); if (!n) { rx_free_cset (cs); goto space_error; } rx_bitset_universe (cset_size, cs); if (!(syntax & RE_DOT_NEWLINE)) RX_bitset_remove (cs, '\n'); if (syntax & RE_DOT_NOT_NULL) RX_bitset_remove (cs, 0); append = n; goto append_node; break; } case '[': if (p == pend) { compile_error = REG_EBRACK; goto error_return; } { int had_char_class; rx_Bitset cs; struct rexp_node * node; int is_inverted; had_char_class = 0; is_inverted = *p == '^'; cs = rx_cset (cset_size); if (!cs) goto space_error; node = rx_mk_r_cset (r_cset, cset_size ,cs); if (!node) { rx_free_cset (cs); goto space_error; } /* This branch of the switch is normally exited with *`goto append_node' */ append = node; if (is_inverted) p++; /* Remember the first position in the bracket expression. */ p1 = p; /* Read in characters and ranges, setting map bits. */ for (;;) { if (p == pend) { compile_error = REG_EBRACK; goto error_return; } PATFETCH (c); /* \ might escape characters inside [...] and [^...]. */ if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\') { if (p == pend) { compile_error = REG_EESCAPE; goto error_return; } PATFETCH (c1); { rx_Bitset it = inverse_translation (n_members, cset_size, validate_inv_tr, inverse_translate, translate, c1); rx_bitset_union (cset_size, cs, it); } continue; } /* Could be the end of the bracket expression. If it's not (i.e., when the bracket expression is `[]' so far), the ']' character bit gets set way below. */ if (c == ']' && p != p1 + 1) goto finalize_class_and_append; /* Look ahead to see if it's a range when the last thing was a character class. */ if (had_char_class && c == '-' && *p != ']') { compile_error = REG_ERANGE; goto error_return; } /* Look ahead to see if it's a range when the last thing was a character: if this is a hyphen not at the beginning or the end of a list, then it's the range operator. */ if (c == '-' && !(p - 2 >= pattern && p[-2] == '[') && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^') && *p != ']') { int ret = compile_range (n_members, cset_size, cs, &p, pend, translate, syntax, inverse_translate, validate_inv_tr); if (ret != REG_NOERROR) { compile_error = ret; goto error_return; } } else if (p[0] == '-' && p[1] != ']') { /* This handles ranges made up of characters only. */ int ret; /* Move past the `-'. */ PATFETCH (c1); ret = compile_range (n_members, cset_size, cs, &p, pend, translate, syntax, inverse_translate, validate_inv_tr); if (ret != REG_NOERROR) { compile_error = ret; goto error_return; } } /* See if we're at the beginning of a possible character class. */ else if ((syntax & RE_CHAR_CLASSES) && (c == '[') && (*p == ':')) { char str[CHAR_CLASS_MAX_LENGTH + 1]; PATFETCH (c); c1 = 0; /* If pattern is `[[:'. */ if (p == pend) { compile_error = REG_EBRACK; goto error_return; } for (;;) { PATFETCH (c); if (c == ':' || c == ']' || p == pend || c1 == CHAR_CLASS_MAX_LENGTH) break; str[c1++] = c; } str[c1] = '\0'; /* If isn't a word bracketed by `[:' and:`]': undo the ending character, the letters, and leave the leading `:' and `[' (but set bits for them). */ if (c == ':' && *p == ']') { if (!strncmp (str, "cut", 3)) { int val; if (1 != sscanf (str + 3, " %d", &val)) { compile_error = REG_ECTYPE; goto error_return; } /* Throw away the ]] */ PATFETCH (c); PATFETCH (c); { struct rexp_node * cut; cut = rx_mk_r_int (r_cut, val); append = cut; goto append_node; } } else if (!strncmp (str, "(", 1)) { /* Throw away the ]] */ PATFETCH (c); PATFETCH (c); syntax_only_parens = 1; goto handle_open; } else if (!strncmp (str, ")", 1)) { /* Throw away the ]] */ PATFETCH (c); PATFETCH (c); syntax_only_parens = 1; goto handle_close; } else { int ch; int is_alnum = !strcmp (str, "alnum"); int is_alpha = !strcmp (str, "alpha"); int is_blank = !strcmp (str, "blank"); int is_cntrl = !strcmp (str, "cntrl"); int is_digit = !strcmp (str, "digit"); int is_graph = !strcmp (str, "graph"); int is_lower = !strcmp (str, "lower"); int is_print = !strcmp (str, "print"); int is_punct = !strcmp (str, "punct"); int is_space = !strcmp (str, "space"); int is_upper = !strcmp (str, "upper"); int is_xdigit = !strcmp (str, "xdigit"); if (!IS_CHAR_CLASS (str)) { compile_error = REG_ECTYPE; goto error_return; } /* Throw away the ] at the end of the character class. */ PATFETCH (c); if (p == pend) { compile_error = REG_EBRACK; goto error_return; } for (ch = 0; ch < 1 << CHARBITS; ch++) { if ( (is_alnum && isalnum (ch)) || (is_alpha && isalpha (ch)) || (is_blank && isa_blank (ch)) || (is_cntrl && iscntrl (ch)) || (is_digit && isdigit (ch)) || (is_graph && isgraph (ch)) || (is_lower && islower (ch)) || (is_print && isprint (ch)) || (is_punct && ispunct (ch)) || (is_space && isspace (ch)) || (is_upper && isupper (ch)) || (is_xdigit && isxdigit (ch))) { rx_Bitset it = inverse_translation (n_members, cset_size, validate_inv_tr, inverse_translate, translate, ch); rx_bitset_union (cset_size, cs, it); } } had_char_class = 1; } } else { c1++; while (c1--) PATUNFETCH; { rx_Bitset it = inverse_translation (n_members, cset_size, validate_inv_tr, inverse_translate, translate, '['); rx_bitset_union (cset_size, cs, it); } { rx_Bitset it = inverse_translation (n_members, cset_size, validate_inv_tr, inverse_translate, translate, ':'); rx_bitset_union (cset_size, cs, it); } had_char_class = 0; } } else { had_char_class = 0; { rx_Bitset it = inverse_translation (n_members, cset_size, validate_inv_tr, inverse_translate, translate, c); rx_bitset_union (cset_size, cs, it); } } } finalize_class_and_append: if (is_inverted) { rx_bitset_complement (cset_size, cs); if (syntax & RE_HAT_LISTS_NOT_NEWLINE) RX_bitset_remove (cs, '\n'); } goto append_node; } break; case '(': if (syntax & RE_NO_BK_PARENS) { syntax_only_parens = 0; goto handle_open; } else goto normal_char; case ')': if (syntax & RE_NO_BK_PARENS) { syntax_only_parens = 0; goto handle_close; } else goto normal_char; case '\n': if (syntax & RE_NEWLINE_ALT) goto handle_alt; else goto normal_char; case '|': if (syntax & RE_NO_BK_VBAR) goto handle_alt; else goto normal_char; case '{': if ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES)) goto handle_interval; else goto normal_char; case '\\': if (p == pend) { compile_error = REG_EESCAPE; goto error_return; } /* Do not translate the character after the \, so that we can distinguish, e.g., \B from \b, even if we normally would translate, e.g., B to b. */ PATFETCH_RAW (c); switch (c) { case '(': if (syntax & RE_NO_BK_PARENS) goto normal_backslash; syntax_only_parens = 0; handle_open: if (!syntax_only_parens) regnum++; if (COMPILE_STACK_FULL) { compile_stack.stack = ((compile_stack_elt_t *) realloc (compile_stack.stack, (compile_stack.size << 1) * sizeof (compile_stack_elt_t))); if (compile_stack.stack == 0) goto space_error; compile_stack.size <<= 1; } if (*last_non_regular_expression) { struct rexp_node * concat; concat = rx_mk_r_binop (r_concat, *last_non_regular_expression, 0); if (!concat) goto space_error; *last_non_regular_expression = concat; last_non_regular_expression = &concat->params.pair.right; last_expression = last_non_regular_expression; } /* * These are the values to restore when we hit end of this * group. */ COMPILE_STACK_TOP.top_expression = top_expression; COMPILE_STACK_TOP.last_expression = last_expression; COMPILE_STACK_TOP.last_non_regular_expression = last_non_regular_expression; if (syntax_only_parens) COMPILE_STACK_TOP.regnum = -1; else COMPILE_STACK_TOP.regnum = regnum; compile_stack.avail++; top_expression = last_non_regular_expression; break; case ')': if (syntax & RE_NO_BK_PARENS) goto normal_backslash; syntax_only_parens = 0; handle_close: /* See similar code for backslashed left paren above. */ if (COMPILE_STACK_EMPTY) if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD) goto normal_char; else { compile_error = REG_ERPAREN; goto error_return; } /* Since we just checked for an empty stack above, this * ``can't happen''. */ { /* We don't just want to restore into `regnum', because * later groups should continue to be numbered higher, * as in `(ab)c(de)' -- the second group is #2. */ regnum_t this_group_regnum; struct rexp_node ** inner; struct rexp_node * parens; inner = top_expression; compile_stack.avail--; if (!!syntax_only_parens != (COMPILE_STACK_TOP.regnum == -1)) { compile_error = REG_ERPAREN; goto error_return; } top_expression = COMPILE_STACK_TOP.top_expression; last_expression = COMPILE_STACK_TOP.last_expression; last_non_regular_expression = COMPILE_STACK_TOP.last_non_regular_expression; this_group_regnum = COMPILE_STACK_TOP.regnum; { parens = rx_mk_r_monop (r_parens, *inner); if (!parens) goto space_error; parens->params.intval = this_group_regnum; *inner = parens; break; } } case '|': /* `\|'. */ if ((syntax & RE_LIMITED_OPS) || (syntax & RE_NO_BK_VBAR)) goto normal_backslash; handle_alt: if (syntax & RE_LIMITED_OPS) goto normal_char; { struct rexp_node * alt; alt = rx_mk_r_binop (r_alternate, *top_expression, 0); if (!alt) goto space_error; *top_expression = alt; last_expression = &alt->params.pair.right; last_non_regular_expression = &alt->params.pair.right; } break; case '{': /* If \{ is a literal. */ if (!(syntax & RE_INTERVALS) /* If we're at `\{' and it's not the open-interval operator. */ || ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES)) || (p - 2 == pattern && p == pend)) goto normal_backslash; handle_interval: { /* If got here, then the syntax allows intervals. */ /* At least (most) this many matches must be made. */ int lower_bound; int upper_bound; lower_bound = -1; upper_bound = -1; /* We're about to parse the bounds of the interval. * It may turn out that this isn't an interval after * all, in which case these same characters will have * to be reparsed as literals. This remembers * the backtrack point in the parse: */ beg_interval = p - 1; if (p == pend) { if (syntax & RE_NO_BK_BRACES) goto unfetch_interval; else { compile_error = REG_EBRACE; goto error_return; } } GET_UNSIGNED_NUMBER (lower_bound); if (c == ',') { GET_UNSIGNED_NUMBER (upper_bound); if (upper_bound < 0) upper_bound = RE_DUP_MAX; } else /* Interval such as `{n}' => match exactly n times. */ upper_bound = lower_bound; if (lower_bound < 0 || upper_bound > RE_DUP_MAX || lower_bound > upper_bound) { if (syntax & RE_NO_BK_BRACES) goto unfetch_interval; else { compile_error = REG_BADBR; goto error_return; } } if (!(syntax & RE_NO_BK_BRACES)) { if (c != '\\') { compile_error = REG_EBRACE; goto error_return; } PATFETCH (c); } if (c != '}') { if (syntax & RE_NO_BK_BRACES) goto unfetch_interval; else { compile_error = REG_BADBR; goto error_return; } } /* We just parsed a valid interval. * lower_bound and upper_bound are set. */ /* If it's invalid to have no preceding re. */ if (pointless_if_repeated (*last_expression)) { if (syntax & RE_CONTEXT_INVALID_OPS) { compile_error = REG_BADRPT; goto error_return; } else if (!(syntax & RE_CONTEXT_INDEP_OPS)) /* treat the interval spec as literal chars. */ goto unfetch_interval; } { struct rexp_node * interval; if (*last_expression && ((*last_expression)->type == r_string)) if (factor_string (&last_expression, cset_size)) goto space_error; interval = rx_mk_r_monop (r_interval, *last_expression); if (!interval) goto space_error; interval->params.intval = lower_bound; interval->params.intval2 = upper_bound; *last_expression = interval; last_non_regular_expression = last_expression; } beg_interval = 0; } break; unfetch_interval: /* If an invalid interval, match the characters as literals. */ p = beg_interval; beg_interval = 0; /* normal_char and normal_backslash need `c'. */ PATFETCH (c); if (!(syntax & RE_NO_BK_BRACES)) { if ((p > pattern) && (p[-1] == '\\')) goto normal_backslash; } goto normal_char; #ifdef emacs /* There is no way to specify the before_dot and after_dot * operators. rms says this is ok. --karl */ case '=': side = '='; goto add_side_effect; break; case 's': case 'S': { rx_Bitset cs; struct rexp_node * set; cs = rx_cset (&cset_size); if (!cs) goto space_error; set = rx_mk_r_cset (r_cset, cset_size, cs); if (!set) { rx_free_cset (cs); goto space_error; } if (c == 'S') rx_bitset_universe (cset_size, cs); PATFETCH (c); { int x; enum syntaxcode code = syntax_spec_code [c]; for (x = 0; x < 256; ++x) { if (SYNTAX (x) == code) { rx_Bitset it = inverse_translation (n_members, cset_size, validate_inv_tr, inverse_translate, translate, x); rx_bitset_xor (cset_size, cs, it); } } } append = set; goto append_node; } break; #endif /* emacs */ case 'w': case 'W': { rx_Bitset cs; struct rexp_node * n; cs = rx_cset (cset_size); n = (cs ? rx_mk_r_cset (r_cset, cset_size, cs) : 0); if (!(cs && n)) { if (cs) rx_free_cset (cs); goto space_error; } if (c == 'W') rx_bitset_universe (cset_size ,cs); { int x; for (x = cset_size - 1; x > 0; --x) if (SYNTAX(x) & Sword) RX_bitset_toggle (cs, x); } append = n; goto append_node; } break; case '<': side = '<'; goto add_side_effect; break; case '>': side = '>'; goto add_side_effect; break; case 'b': side = 'b'; goto add_side_effect; break; case 'B': side = 'B'; goto add_side_effect; break; case '`': side = '`'; goto add_side_effect; break; case '\'': side = '\''; goto add_side_effect; break; add_side_effect: { struct rexp_node * se; se = rx_mk_r_int (r_context, side); if (!se) goto space_error; append = se; goto append_node; } break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (syntax & RE_NO_BK_REFS) goto normal_char; c1 = c - '0'; /* Can't back reference to a subexpression if inside of it. */ if (group_in_compile_stack (compile_stack, c1)) goto normal_char; if (c1 > regnum) { compile_error = REG_ESUBREG; goto error_return; } side = c; goto add_side_effect; break; case '+': case '?': if (syntax & RE_BK_PLUS_QM) goto handle_plus; else goto normal_backslash; default: normal_backslash: /* You might think it would be useful for \ to mean * not to translate; but if we don't translate it * it will never match anything. */ c = TRANSLATE (c); goto normal_char; } break; default: /* Expects the character in `c'. */ normal_char: { rx_Bitset cs; struct rexp_node * match; rx_Bitset it; it = inverse_translation (n_members, cset_size, validate_inv_tr, inverse_translate, translate, c); if (1 != n_members[c]) { cs = rx_cset (cset_size); match = (cs ? rx_mk_r_cset (r_cset, cset_size, cs) : 0); if (!(cs && match)) { if (cs) rx_free_cset (cs); goto space_error; } rx_bitset_union (CHAR_SET_SIZE, cs, it); append = match; goto append_node; } else { if (*last_expression && (*last_expression)->type == r_string) { if (rx_adjoin_string (&((*last_expression)->params.cstr), c)) goto space_error; break; } else { append = rx_mk_r_str (r_string, c); if(!append) goto space_error; goto append_node; } } break; append_node: /* This genericly appends the rexp APPEND to *LAST_EXPRESSION * and then parses the next character normally. */ if (RX_regular_node_type (append->type)) { if (!*last_expression) *last_expression = append; else { struct rexp_node * concat; concat = rx_mk_r_binop (r_concat, *last_expression, append); if (!concat) goto space_error; *last_expression = concat; last_expression = &concat->params.pair.right; } } else { if (!*last_non_regular_expression) { *last_non_regular_expression = append; last_expression = last_non_regular_expression; } else { struct rexp_node * concat; concat = rx_mk_r_binop (r_concat, *last_non_regular_expression, append); if (!concat) goto space_error; *last_non_regular_expression = concat; last_non_regular_expression = &concat->params.pair.right; last_expression = last_non_regular_expression; } } } } /* switch (c) */ } /* while p != pend */ /* Through the pattern now. */ if (!COMPILE_STACK_EMPTY) { compile_error = REG_EPAREN; goto error_return; } free (compile_stack.stack); *rexp_p = rexp; return REG_NOERROR; space_error: compile_error = REG_ESPACE; error_return: free (compile_stack.stack); /* Free expressions pushed onto the compile stack! */ if (rexp) rx_free_rexp (rexp); return compile_error; } rplay-3.3.2/rx/rxgnucomp.h100644 153 62 17600 6552756454 14207 0ustar boynsstaff/* classes: h_files */ #ifndef RXGNUCOMPH #define RXGNUCOMPH /* Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "rxcset.h" #include "rxnode.h" /* This is an array of error messages corresponding to the error codes. */ extern const char *rx_error_msg[]; /* {Syntax Bits} */ /* The following bits are used to determine the regexp syntax we recognize. The set/not-set meanings are chosen so that Emacs syntax remains the value 0. The bits are given in alphabetical order, and the definitions shifted by one from the previous bit; thus, when we add or remove a bit, only one other definition need change. */ enum RE_SYNTAX_BITS { /* If this bit is not set, then \ inside a bracket expression is literal. If set, then such a \ quotes the following character. */ RE_BACKSLASH_ESCAPE_IN_LISTS = (1), /* If this bit is not set, then + and ? are operators, and \+ and \? are literals. If set, then \+ and \? are operators and + and ? are literals. */ RE_BK_PLUS_QM = (RE_BACKSLASH_ESCAPE_IN_LISTS << 1), /* If this bit is set, then character classes are supported. They are: [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:], [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:]. If not set, then character classes are not supported. */ RE_CHAR_CLASSES = (RE_BK_PLUS_QM << 1), /* If this bit is set, then ^ and $ are always anchors (outside bracket expressions, of course). If this bit is not set, then it depends: ^ is an anchor if it is at the beginning of a regular expression or after an open-group or an alternation operator; $ is an anchor if it is at the end of a regular expression, or before a close-group or an alternation operator. This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because POSIX draft 11.2 says that * etc. in leading positions is undefined. We already implemented a previous draft which made those constructs invalid, though, so we haven't changed the code back. */ RE_CONTEXT_INDEP_ANCHORS = (RE_CHAR_CLASSES << 1), /* If this bit is set, then special characters are always special regardless of where they are in the pattern. If this bit is not set, then special characters are special only in some contexts; otherwise they are ordinary. Specifically, * + ? and intervals are only special when not after the beginning, open-group, or alternation operator. */ RE_CONTEXT_INDEP_OPS = (RE_CONTEXT_INDEP_ANCHORS << 1), /* If this bit is set, then *, +, ?, and { cannot be first in an re or immediately after an alternation or begin-group operator. */ RE_CONTEXT_INVALID_OPS = (RE_CONTEXT_INDEP_OPS << 1), /* If this bit is set, then . matches newline. If not set, then it doesn't. */ RE_DOT_NEWLINE = (RE_CONTEXT_INVALID_OPS << 1), /* If this bit is set, then . doesn't match NUL. If not set, then it does. */ RE_DOT_NOT_NULL = (RE_DOT_NEWLINE << 1), /* If this bit is set, nonmatching lists [^...] do not match newline. If not set, they do. */ RE_HAT_LISTS_NOT_NEWLINE = (RE_DOT_NOT_NULL << 1), /* If this bit is set, either \{...\} or {...} defines an interval, depending on RE_NO_BK_BRACES. If not set, \{, \}, {, and } are literals. */ RE_INTERVALS = (RE_HAT_LISTS_NOT_NEWLINE << 1), /* If this bit is set, +, ? and | aren't recognized as operators. If not set, they are. */ RE_LIMITED_OPS = (RE_INTERVALS << 1), /* If this bit is set, newline is an alternation operator. If not set, newline is literal. */ RE_NEWLINE_ALT = (RE_LIMITED_OPS << 1), /* If this bit is set, then `{...}' defines an interval, and \{ and \} are literals. If not set, then `\{...\}' defines an interval. */ RE_NO_BK_BRACES = (RE_NEWLINE_ALT << 1), /* If this bit is set, (...) defines a group, and \( and \) are literals. If not set, \(...\) defines a group, and ( and ) are literals. */ RE_NO_BK_PARENS = (RE_NO_BK_BRACES << 1), /* If this bit is set, then \ matches . If not set, then \ is a back-reference. */ RE_NO_BK_REFS = (RE_NO_BK_PARENS << 1), /* If this bit is set, then | is an alternation operator, and \| is literal. If not set, then \| is an alternation operator, and | is literal. */ RE_NO_BK_VBAR = (RE_NO_BK_REFS << 1), /* If this bit is set, then an ending range point collating higher than the starting range point, as in [z-a], is invalid. If not set, then when ending range point collates higher than the starting range point, the range is ignored. */ RE_NO_EMPTY_RANGES = (RE_NO_BK_VBAR << 1), /* If this bit is set, then an unmatched ) is ordinary. If not set, then an unmatched ) is invalid. */ RE_UNMATCHED_RIGHT_PAREN_ORD = (RE_NO_EMPTY_RANGES << 1), RE_SYNTAX_EMACS = 0, RE_SYNTAX_AWK = (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL | RE_NO_BK_PARENS | RE_NO_BK_REFS | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES | RE_UNMATCHED_RIGHT_PAREN_ORD), RE_SYNTAX_GREP = (RE_BK_PLUS_QM | RE_CHAR_CLASSES | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS | RE_NEWLINE_ALT), RE_SYNTAX_EGREP = (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE | RE_NEWLINE_ALT | RE_NO_BK_PARENS | RE_NO_BK_VBAR), RE_SYNTAX_POSIX_EGREP = (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES), /* Syntax bits common to both basic and extended POSIX regex syntax. */ _RE_SYNTAX_POSIX_COMMON = (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL | RE_INTERVALS | RE_NO_EMPTY_RANGES), RE_SYNTAX_POSIX_BASIC = (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM), /* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. */ RE_SYNTAX_POSIX_MINIMAL_BASIC = (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS), RE_SYNTAX_POSIX_EXTENDED = (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES | RE_NO_BK_PARENS | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD), /* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added. */ RE_SYNTAX_POSIX_MINIMAL_EXTENDED = (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES | RE_NO_BK_PARENS | RE_NO_BK_REFS | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD), RE_SYNTAX_SED = RE_SYNTAX_POSIX_BASIC, RE_SYNTAX_POSIX_AWK = (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS) }; /* Maximum number of duplicates an interval can allow. Some systems (erroneously) define this in other header files, but we want our value, so remove any previous define. */ #undef RE_DUP_MAX #define RE_DUP_MAX ((1 << 15) - 1) #ifdef __STDC__ extern int rx_parse (struct rexp_node ** rexp_p, const char *pattern, int size, unsigned long syntax, int cset_size, unsigned char *translate); #else /* STDC */ extern int rx_parse (); #endif /* STDC */ #endif /* RXGNUCOMPH */ rplay-3.3.2/rx/rxhash.c100644 153 62 21607 6552756454 13457 0ustar boynsstaff/* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* * Tom Lord (lord@cygnus.com, lord@gnu.ai.mit.edu) */ #include "rxall.h" #include "rxhash.h" #ifdef __STDC__ static struct rx_hash * default_hash_alloc (struct rx_hash_rules * rules) #else static struct rx_hash * default_hash_alloc (rules) struct rx_hash_rules * rules; #endif { return (struct rx_hash *)malloc (sizeof (struct rx_hash)); } #ifdef __STDC__ static struct rx_hash_item * default_hash_item_alloc (struct rx_hash_rules * rules, void * value) #else static struct rx_hash_item * default_hash_item_alloc (rules, value) struct rx_hash_rules * rules; void * value; #endif { struct rx_hash_item * it; it = (struct rx_hash_item *)malloc (sizeof (*it)); if (it) { it->data = value; it->binding = 0; } return it; } #ifdef __STDC__ static void default_free_hash (struct rx_hash * tab, struct rx_hash_rules * rules) #else static void default_free_hash (tab, rules) struct rx_hash * tab; struct rx_hash_rules * rules; #endif { free ((char *)tab); } #ifdef __STDC__ static void default_free_hash_item (struct rx_hash_item * item, struct rx_hash_rules * rules) #else static void default_free_hash_item (item, rules) struct rx_hash_item * item; struct rx_hash_rules * rules; #endif { free ((char *)item); } #ifdef __STDC__ static int default_eq (void * va, void * vb) #else static int default_eq (va, vb) void * va; void * vb; #endif { return va == vb; } #define EQ(rules) ((rules && rules->eq) ? rules->eq : default_eq) #define HASH_ALLOC(rules) ((rules && rules->hash_alloc) ? rules->hash_alloc : default_hash_alloc) #define FREE_HASH(rules) ((rules && rules->free_hash) ? rules->free_hash : default_free_hash) #define ITEM_ALLOC(rules) ((rules && rules->hash_item_alloc) ? rules->hash_item_alloc : default_hash_item_alloc) #define FREE_HASH_ITEM(rules) ((rules && rules->free_hash_item) ? rules->free_hash_item : default_free_hash_item) static unsigned long rx_hash_masks[4] = { 0x12488421, 0x96699669, 0xbe7dd7eb, 0xffffffff }; /* hash to bucket */ #define JOIN_BYTE(H, B) (((H) + ((H) << 3) + (B)) & 0xf) #define H2B(X) JOIN_BYTE (JOIN_BYTE (JOIN_BYTE ((X & 0xf), ((X>>8) & 0xf)), ((X>>16) & 0xf)), ((X>>24) & 0xf)) #define BKTS 16 /* Hash tables */ #ifdef __STDC__ struct rx_hash_item * rx_hash_find (struct rx_hash * table, unsigned long hash, void * value, struct rx_hash_rules * rules) #else struct rx_hash_item * rx_hash_find (table, hash, value, rules) struct rx_hash * table; unsigned long hash; void * value; struct rx_hash_rules * rules; #endif { rx_hash_eq eq = EQ (rules); int maskc = 0; long mask = rx_hash_masks [0]; int bucket = H2B(hash & mask); while (RX_bitset_member (&table->nested_p, bucket)) { table = (struct rx_hash *)(table->children [bucket]); ++maskc; mask = rx_hash_masks[maskc]; bucket = H2B (hash & mask); } { struct rx_hash_item * it; it = (struct rx_hash_item *)(table->children[bucket]); while (it) if (eq (it->data, value)) return it; else it = it->next_same_hash; } return 0; } #ifdef __STDC__ static int listlen (struct rx_hash_item * bucket) #else static int listlen (bucket) struct rx_hash_item * bucket; #endif { int i; for (i = 0; bucket; ++i, bucket = bucket->next_same_hash) ; return i; } #ifdef __STDC__ static int overflows (struct rx_hash_item * bucket) #else static int overflows (bucket) struct rx_hash_item * bucket; #endif { return !( bucket && bucket->next_same_hash && bucket->next_same_hash->next_same_hash && bucket->next_same_hash->next_same_hash->next_same_hash); } #ifdef __STDC__ struct rx_hash_item * rx_hash_store (struct rx_hash * table, unsigned long hash, void * value, struct rx_hash_rules * rules) #else struct rx_hash_item * rx_hash_store (table, hash, value, rules) struct rx_hash * table; unsigned long hash; void * value; struct rx_hash_rules * rules; #endif { rx_hash_eq eq = EQ (rules); int maskc = 0; long mask = rx_hash_masks [0]; int bucket = H2B(hash & mask); int depth = 0; while (RX_bitset_member (&table->nested_p, bucket)) { table = (struct rx_hash *)(table->children [bucket]); ++maskc; mask = rx_hash_masks[maskc]; bucket = H2B(hash & mask); ++depth; } { struct rx_hash_item * it; it = (struct rx_hash_item *)(table->children[bucket]); while (it) if (eq (it->data, value)) return it; else it = it->next_same_hash; } { if ( (depth < 3) && (overflows ((struct rx_hash_item *)table->children [bucket]))) { struct rx_hash * newtab; newtab = (struct rx_hash *) HASH_ALLOC(rules) (rules); if (!newtab) goto add_to_bucket; rx_bzero ((char *)newtab, sizeof (*newtab)); newtab->parent = table; { struct rx_hash_item * them; unsigned long newmask; them = (struct rx_hash_item *)table->children[bucket]; newmask = rx_hash_masks[maskc + 1]; while (them) { struct rx_hash_item * save = them->next_same_hash; int new_buck = H2B(them->hash & newmask); them->next_same_hash = ((struct rx_hash_item *) newtab->children[new_buck]); ((struct rx_hash_item **)newtab->children)[new_buck] = them; them->table = newtab; them = save; ++newtab->refs; --table->refs; } ((struct rx_hash **)table->children)[bucket] = newtab; RX_bitset_enjoin (&table->nested_p, bucket); ++table->refs; table = newtab; bucket = H2B(hash & newmask); } } } add_to_bucket: { struct rx_hash_item * it = ((struct rx_hash_item *) ITEM_ALLOC(rules) (rules, value)); if (!it) return 0; it->hash = hash; it->table = table; /* DATA and BINDING are to be set in hash_item_alloc */ it->next_same_hash = (struct rx_hash_item *)table->children [bucket]; ((struct rx_hash_item **)table->children)[bucket] = it; ++table->refs; return it; } } #ifdef __STDC__ void rx_hash_free (struct rx_hash_item * it, struct rx_hash_rules * rules) #else void rx_hash_free (it, rules) struct rx_hash_item * it; struct rx_hash_rules * rules; #endif { if (it) { struct rx_hash * table = it->table; unsigned long hash = it->hash; int depth = (table->parent ? (table->parent->parent ? (table->parent->parent->parent ? 3 : 2) : 1) : 0); int bucket = H2B (hash & rx_hash_masks [depth]); struct rx_hash_item ** pos = (struct rx_hash_item **)&table->children [bucket]; while (*pos != it) pos = &(*pos)->next_same_hash; *pos = it->next_same_hash; FREE_HASH_ITEM(rules) (it, rules); --table->refs; while (!table->refs && depth) { struct rx_hash * save = table; table = table->parent; --depth; bucket = H2B(hash & rx_hash_masks [depth]); --table->refs; table->children[bucket] = 0; RX_bitset_remove (&table->nested_p, bucket); FREE_HASH (rules) (save, rules); } } } #ifdef __STDC__ void rx_free_hash_table (struct rx_hash * tab, rx_hash_freefn freefn, struct rx_hash_rules * rules) #else void rx_free_hash_table (tab, freefn, rules) struct rx_hash * tab; rx_hash_freefn freefn; struct rx_hash_rules * rules; #endif { int x; for (x = 0; x < BKTS; ++x) if (RX_bitset_member (&tab->nested_p, x)) { rx_free_hash_table ((struct rx_hash *)tab->children[x], freefn, rules); FREE_HASH (rules) ((struct rx_hash *)tab->children[x], rules); } else { struct rx_hash_item * them = (struct rx_hash_item *)tab->children[x]; while (them) { struct rx_hash_item * that = them; them = that->next_same_hash; freefn (that); FREE_HASH_ITEM (rules) (that, rules); } } } #ifdef __STDC__ int rx_count_hash_nodes (struct rx_hash * st) #else int rx_count_hash_nodes (st) struct rx_hash * st; #endif { int x; int count = 0; for (x = 0; x < BKTS; ++x) count += ((RX_bitset_member (&st->nested_p, x)) ? rx_count_hash_nodes ((struct rx_hash *)st->children[x]) : listlen ((struct rx_hash_item *)(st->children[x]))); return count; } rplay-3.3.2/rx/rxhash.h100644 153 62 5704 6552756454 13444 0ustar boynsstaff/* classes: h_files */ #ifndef RXHASHH #define RXHASHH /* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* * Tom Lord (lord@cygnus.com, lord@gnu.ai.mit.edu) */ #include "rxbitset.h" /* giant inflatable hash trees */ struct rx_hash_item { struct rx_hash_item * next_same_hash; struct rx_hash * table; unsigned long hash; void * data; void * binding; }; struct rx_hash { struct rx_hash * parent; int refs; RX_subset nested_p; void ** children[16]; }; struct rx_hash_rules; /* rx_hash_eq should work like the == operator. */ #ifdef __STDC__ typedef int (*rx_hash_eq)(void *, void *); typedef struct rx_hash * (*rx_alloc_hash)(struct rx_hash_rules *); typedef void (*rx_free_hash)(struct rx_hash *, struct rx_hash_rules *); typedef struct rx_hash_item * (*rx_alloc_hash_item)(struct rx_hash_rules *, void *); typedef void (*rx_free_hash_item)(struct rx_hash_item *, struct rx_hash_rules *); typedef void (*rx_hash_freefn) (struct rx_hash_item * it); #else typedef int (*rx_hash_eq)(); typedef struct rx_hash * (*rx_alloc_hash)(); typedef void (*rx_free_hash)(); typedef struct rx_hash_item * (*rx_alloc_hash_item)(); typedef void (*rx_free_hash_item)(); typedef void (*rx_hash_freefn) (); #endif struct rx_hash_rules { rx_hash_eq eq; rx_alloc_hash hash_alloc; rx_free_hash free_hash; rx_alloc_hash_item hash_item_alloc; rx_free_hash_item free_hash_item; }; #ifdef __STDC__ extern struct rx_hash_item * rx_hash_find (struct rx_hash * table, unsigned long hash, void * value, struct rx_hash_rules * rules); extern struct rx_hash_item * rx_hash_store (struct rx_hash * table, unsigned long hash, void * value, struct rx_hash_rules * rules); extern void rx_hash_free (struct rx_hash_item * it, struct rx_hash_rules * rules); extern void rx_free_hash_table (struct rx_hash * tab, rx_hash_freefn freefn, struct rx_hash_rules * rules); extern int rx_count_hash_nodes (struct rx_hash * st); #else /* STDC */ extern struct rx_hash_item * rx_hash_find (); extern struct rx_hash_item * rx_hash_store (); extern void rx_hash_free (); extern void rx_free_hash_table (); extern int rx_count_hash_nodes (); #endif /* STDC */ #endif /* RXHASHH */ rplay-3.3.2/rx/rxnfa.c100644 153 62 44764 6552756454 13311 0ustar boynsstaff/* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* * Tom Lord (lord@cygnus.com, lord@gnu.ai.mit.edu) */ #include "rxall.h" #include "rxnfa.h" #define remalloc(M, S) (M ? realloc (M, S) : malloc (S)) /* {Low Level Data Structure Code} */ /* Constructs a new nfa node. */ #ifdef __STDC__ struct rx_nfa_state * rx_nfa_state (struct rx *rx) #else struct rx_nfa_state * rx_nfa_state (rx) struct rx *rx; #endif { struct rx_nfa_state * n = (struct rx_nfa_state *)malloc (sizeof (*n)); if (!n) return 0; rx_bzero ((char *)n, sizeof (*n)); n->next = rx->nfa_states; rx->nfa_states = n; return n; } #ifdef __STDC__ static void rx_free_nfa_state (struct rx_nfa_state * n) #else static void rx_free_nfa_state (n) struct rx_nfa_state * n; #endif { free ((char *)n); } /* This adds an edge between two nodes, but doesn't initialize the * edge label. */ #ifdef __STDC__ struct rx_nfa_edge * rx_nfa_edge (struct rx *rx, enum rx_nfa_etype type, struct rx_nfa_state *start, struct rx_nfa_state *dest) #else struct rx_nfa_edge * rx_nfa_edge (rx, type, start, dest) struct rx *rx; enum rx_nfa_etype type; struct rx_nfa_state *start; struct rx_nfa_state *dest; #endif { struct rx_nfa_edge *e; e = (struct rx_nfa_edge *)malloc (sizeof (*e)); if (!e) return 0; e->next = start->edges; start->edges = e; e->type = type; e->dest = dest; return e; } #ifdef __STDC__ static void rx_free_nfa_edge (struct rx_nfa_edge * e) #else static void rx_free_nfa_edge (e) struct rx_nfa_edge * e; #endif { free ((char *)e); } /* This constructs a POSSIBLE_FUTURE, which is a kind epsilon-closure * of an NFA. These are added to an nfa automaticly by eclose_nfa. */ #ifdef __STDC__ static struct rx_possible_future * rx_possible_future (struct rx * rx, struct rx_se_list * effects) #else static struct rx_possible_future * rx_possible_future (rx, effects) struct rx * rx; struct rx_se_list * effects; #endif { struct rx_possible_future *ec; ec = (struct rx_possible_future *) malloc (sizeof (*ec)); if (!ec) return 0; ec->destset = 0; ec->next = 0; ec->effects = effects; return ec; } #ifdef __STDC__ static void rx_free_possible_future (struct rx_possible_future * pf) #else static void rx_free_possible_future (pf) struct rx_possible_future * pf; #endif { free ((char *)pf); } #ifdef __STDC__ static void rx_free_nfa_graph (struct rx *rx) #else static void rx_free_nfa_graph (rx) struct rx *rx; #endif { while (rx->nfa_states) { while (rx->nfa_states->edges) { switch (rx->nfa_states->edges->type) { case ne_cset: rx_free_cset (rx->nfa_states->edges->params.cset); break; default: break; } { struct rx_nfa_edge * e; e = rx->nfa_states->edges; rx->nfa_states->edges = rx->nfa_states->edges->next; rx_free_nfa_edge (e); } } /* while (rx->nfa_states->edges) */ { /* Iterate over the partial epsilon closures of rx->nfa_states */ struct rx_possible_future * pf = rx->nfa_states->futures; while (pf) { struct rx_possible_future * pft = pf; pf = pf->next; rx_free_possible_future (pft); } } { struct rx_nfa_state *n; n = rx->nfa_states; rx->nfa_states = rx->nfa_states->next; rx_free_nfa_state (n); } } } /* {Translating a Syntax Tree into an NFA} * */ /* This is the Thompson regexp->nfa algorithm. * It is modified to allow for `side-effect epsilons.' Those are * edges that are taken whenever a similarly placed epsilon edge * would be, but which also imply that some side effect occurs * when the edge is taken. * * Side effects are used to model parts of the pattern langauge * that are not regular. */ #ifdef __STDC__ int rx_build_nfa (struct rx *rx, struct rexp_node *rexp, struct rx_nfa_state **start, struct rx_nfa_state **end) #else int rx_build_nfa (rx, rexp, start, end) struct rx *rx; struct rexp_node *rexp; struct rx_nfa_state **start; struct rx_nfa_state **end; #endif { struct rx_nfa_edge *edge; /* Start & end nodes may have been allocated by the caller. */ *start = *start ? *start : rx_nfa_state (rx); if (!*start) return 0; if (!rexp) { *end = *start; return 1; } *end = *end ? *end : rx_nfa_state (rx); if (!*end) { rx_free_nfa_state (*start); return 0; } switch (rexp->type) { case r_cset: edge = rx_nfa_edge (rx, ne_cset, *start, *end); (*start)->has_cset_edges = 1; if (!edge) return 0; edge->params.cset = rx_copy_cset (rx->local_cset_size, rexp->params.cset); if (!edge->params.cset) { rx_free_nfa_edge (edge); return 0; } return 1; case r_string: { if (rexp->params.cstr.len == 1) { edge = rx_nfa_edge (rx, ne_cset, *start, *end); (*start)->has_cset_edges = 1; if (!edge) return 0; edge->params.cset = rx_cset (rx->local_cset_size); if (!edge->params.cset) { rx_free_nfa_edge (edge); return 0; } RX_bitset_enjoin (edge->params.cset, rexp->params.cstr.contents[0]); return 1; } else { struct rexp_node copied; struct rx_nfa_state * shared; copied = *rexp; shared = 0; copied.params.cstr.len--; copied.params.cstr.contents++; if (!rx_build_nfa (rx, &copied, &shared, end)) return 0; copied.params.cstr.len = 1; copied.params.cstr.contents--; return rx_build_nfa (rx, &copied, start, &shared); } } case r_opt: return (rx_build_nfa (rx, rexp->params.pair.left, start, end) && rx_nfa_edge (rx, ne_epsilon, *start, *end)); case r_plus: { struct rx_nfa_state * star_start = 0; struct rx_nfa_state * star_end = 0; struct rx_nfa_state * shared; shared = 0; if (!rx_build_nfa (rx, rexp->params.pair.left, start, &shared)) return 0; return (rx_build_nfa (rx, rexp->params.pair.left, &star_start, &star_end) && star_start && star_end && rx_nfa_edge (rx, ne_epsilon, star_start, star_end) && rx_nfa_edge (rx, ne_epsilon, shared, star_start) && rx_nfa_edge (rx, ne_epsilon, star_end, *end) && rx_nfa_edge (rx, ne_epsilon, star_end, star_start)); } case r_interval: case r_star: { struct rx_nfa_state * star_start = 0; struct rx_nfa_state * star_end = 0; return (rx_build_nfa (rx, rexp->params.pair.left, &star_start, &star_end) && star_start && star_end && rx_nfa_edge (rx, ne_epsilon, star_start, star_end) && rx_nfa_edge (rx, ne_epsilon, *start, star_start) && rx_nfa_edge (rx, ne_epsilon, star_end, *end) && rx_nfa_edge (rx, ne_epsilon, star_end, star_start)); } case r_cut: { struct rx_nfa_state * cut_end = 0; cut_end = rx_nfa_state (rx); if (!(cut_end && rx_nfa_edge (rx, ne_epsilon, *start, cut_end))) { rx_free_nfa_state (*start); rx_free_nfa_state (*end); if (cut_end) rx_free_nfa_state (cut_end); return 0; } cut_end->is_final = rexp->params.intval; return 1; } case r_parens: return rx_build_nfa (rx, rexp->params.pair.left, start, end); case r_concat: { struct rx_nfa_state *shared = 0; return (rx_build_nfa (rx, rexp->params.pair.left, start, &shared) && rx_build_nfa (rx, rexp->params.pair.right, &shared, end)); } case r_alternate: { struct rx_nfa_state *ls = 0; struct rx_nfa_state *le = 0; struct rx_nfa_state *rs = 0; struct rx_nfa_state *re = 0; return (rx_build_nfa (rx, rexp->params.pair.left, &ls, &le) && rx_build_nfa (rx, rexp->params.pair.right, &rs, &re) && rx_nfa_edge (rx, ne_epsilon, *start, ls) && rx_nfa_edge (rx, ne_epsilon, *start, rs) && rx_nfa_edge (rx, ne_epsilon, le, *end) && rx_nfa_edge (rx, ne_epsilon, re, *end)); } case r_context: edge = rx_nfa_edge (rx, ne_side_effect, *start, *end); if (!edge) return 0; edge->params.side_effect = (void *)rexp->params.intval; return 1; } /* this should never happen */ return 0; } /* {Low Level Data Structures for the Static NFA->SuperNFA Analysis} * * There are side effect lists -- lists of side effects occuring * along an uninterrupted, acyclic path of side-effect epsilon edges. * Such paths are collapsed to single edges in the course of computing * epsilon closures. The resulting single edges are labled with a list * of all the side effects from the original multi-edge path. Equivalent * lists of side effects are made == by the constructors below. * * There are also nfa state sets. These are used to hold a list of all * states reachable from a starting state for a given type of transition * and side effect list. These are also hash-consed. */ /* The next several functions compare, construct, etc. lists of side * effects. See ECLOSE_NFA (below) for details. */ /* Ordering of rx_se_list * (-1, 0, 1 return value convention). */ #ifdef __STDC__ static int se_list_cmp (void * va, void * vb) #else static int se_list_cmp (va, vb) void * va; void * vb; #endif { struct rx_se_list * a = (struct rx_se_list *)va; struct rx_se_list * b = (struct rx_se_list *)vb; return ((va == vb) ? 0 : (!va ? -1 : (!vb ? 1 : ((long)a->car < (long)b->car ? 1 : ((long)a->car > (long)b->car ? -1 : se_list_cmp ((void *)a->cdr, (void *)b->cdr)))))); } #ifdef __STDC__ static int se_list_equal (void * va, void * vb) #else static int se_list_equal (va, vb) void * va; void * vb; #endif { return !(se_list_cmp (va, vb)); } static struct rx_hash_rules se_list_hash_rules = { se_list_equal, 0, 0, 0, 0 }; #ifdef __STDC__ static struct rx_se_list * side_effect_cons (struct rx * rx, void * se, struct rx_se_list * list) #else static struct rx_se_list * side_effect_cons (rx, se, list) struct rx * rx; void * se; struct rx_se_list * list; #endif { struct rx_se_list * l; l = ((struct rx_se_list *) malloc (sizeof (*l))); if (!l) return 0; l->car = se; l->cdr = list; return l; } #ifdef __STDC__ static struct rx_se_list * hash_cons_se_prog (struct rx * rx, struct rx_hash * memo, void * car, struct rx_se_list * cdr) #else static struct rx_se_list * hash_cons_se_prog (rx, memo, car, cdr) struct rx * rx; struct rx_hash * memo; void * car; struct rx_se_list * cdr; #endif { long hash = (long)car ^ (long)cdr; struct rx_se_list template; template.car = car; template.cdr = cdr; { struct rx_hash_item * it = rx_hash_store (memo, hash, (void *)&template, &se_list_hash_rules); if (!it) return 0; if (it->data == (void *)&template) { struct rx_se_list * consed; consed = (struct rx_se_list *) malloc (sizeof (*consed)); *consed = template; it->data = (void *)consed; } return (struct rx_se_list *)it->data; } } #ifdef __STDC__ static struct rx_se_list * hash_se_prog (struct rx * rx, struct rx_hash * memo, struct rx_se_list * prog) #else static struct rx_se_list * hash_se_prog (rx, memo, prog) struct rx * rx; struct rx_hash * memo; struct rx_se_list * prog; #endif { struct rx_se_list * answer = 0; while (prog) { answer = hash_cons_se_prog (rx, memo, prog->car, answer); if (!answer) return 0; prog = prog->cdr; } return answer; } /* {Constructors, etc. for NFA State Sets} */ #ifdef __STDC__ static int nfa_set_cmp (void * va, void * vb) #else static int nfa_set_cmp (va, vb) void * va; void * vb; #endif { struct rx_nfa_state_set * a = (struct rx_nfa_state_set *)va; struct rx_nfa_state_set * b = (struct rx_nfa_state_set *)vb; return ((va == vb) ? 0 : (!va ? -1 : (!vb ? 1 : (a->car->id < b->car->id ? 1 : (a->car->id > b->car->id ? -1 : nfa_set_cmp ((void *)a->cdr, (void *)b->cdr)))))); } #ifdef __STDC__ static int nfa_set_equal (void * va, void * vb) #else static int nfa_set_equal (va, vb) void * va; void * vb; #endif { return !nfa_set_cmp (va, vb); } static struct rx_hash_rules nfa_set_hash_rules = { nfa_set_equal, 0, 0, 0, 0 }; #ifdef __STDC__ static struct rx_nfa_state_set * nfa_set_cons (struct rx * rx, struct rx_hash * memo, struct rx_nfa_state * state, struct rx_nfa_state_set * set) #else static struct rx_nfa_state_set * nfa_set_cons (rx, memo, state, set) struct rx * rx; struct rx_hash * memo; struct rx_nfa_state * state; struct rx_nfa_state_set * set; #endif { struct rx_nfa_state_set template; struct rx_hash_item * node; template.car = state; template.cdr = set; node = rx_hash_store (memo, (((long)state) >> 8) ^ (long)set, &template, &nfa_set_hash_rules); if (!node) return 0; if (node->data == &template) { struct rx_nfa_state_set * l; l = (struct rx_nfa_state_set *) malloc (sizeof (*l)); node->data = (void *) l; if (!l) return 0; *l = template; } return (struct rx_nfa_state_set *)node->data; } #ifdef __STDC__ static struct rx_nfa_state_set * nfa_set_enjoin (struct rx * rx, struct rx_hash * memo, struct rx_nfa_state * state, struct rx_nfa_state_set * set) #else static struct rx_nfa_state_set * nfa_set_enjoin (rx, memo, state, set) struct rx * rx; struct rx_hash * memo; struct rx_nfa_state * state; struct rx_nfa_state_set * set; #endif { if (!set || (state->id < set->car->id)) return nfa_set_cons (rx, memo, state, set); if (state->id == set->car->id) return set; else { struct rx_nfa_state_set * newcdr = nfa_set_enjoin (rx, memo, state, set->cdr); if (newcdr != set->cdr) set = nfa_set_cons (rx, memo, set->car, newcdr); return set; } } /* {Computing Epsilon/Side-effect Closures.} */ struct eclose_frame { struct rx_se_list *prog_backwards; }; /* This is called while computing closures for "outnode". * The current node in the traversal is "node". * "frame" contains a list of a all side effects between * "outnode" and "node" from most to least recent. * * Explores forward from "node", adding new possible * futures to outnode. * * Returns 0 on allocation failure. */ #ifdef __STDC__ static int eclose_node (struct rx *rx, struct rx_nfa_state *outnode, struct rx_nfa_state *node, struct eclose_frame *frame) #else static int eclose_node (rx, outnode, node, frame) struct rx *rx; struct rx_nfa_state *outnode; struct rx_nfa_state *node; struct eclose_frame *frame; #endif { struct rx_nfa_edge *e = node->edges; /* For each node, we follow all epsilon paths to build the closure. * The closure omits nodes that have only epsilon edges. * The closure is split into partial closures -- all the states in * a partial closure are reached by crossing the same list of * of side effects (though not necessarily the same path). */ if (node->mark) return 1; node->mark = 1; /* If "node" has more than just epsilon and * and side-effect transitions (id >= 0), or is final, * then it has to be added to the possible futures * of "outnode". */ if (node->id >= 0 || node->is_final) { struct rx_possible_future **ec; struct rx_se_list * prog_in_order; int cmp; prog_in_order = ((struct rx_se_list *)hash_se_prog (rx, &rx->se_list_memo, frame->prog_backwards)); ec = &outnode->futures; while (*ec) { cmp = se_list_cmp ((void *)(*ec)->effects, (void *)prog_in_order); if (cmp <= 0) break; ec = &(*ec)->next; } if (!*ec || (cmp < 0)) { struct rx_possible_future * pf; pf = rx_possible_future (rx, prog_in_order); if (!pf) return 0; pf->next = *ec; *ec = pf; } if (node->id >= 0) { (*ec)->destset = nfa_set_enjoin (rx, &rx->set_list_memo, node, (*ec)->destset); if (!(*ec)->destset) return 0; } } /* Recurse on outgoing epsilon and side effect nodes. */ while (e) { switch (e->type) { case ne_epsilon: if (!eclose_node (rx, outnode, e->dest, frame)) return 0; break; case ne_side_effect: { frame->prog_backwards = side_effect_cons (rx, e->params.side_effect, frame->prog_backwards); if (!frame->prog_backwards) return 0; if (!eclose_node (rx, outnode, e->dest, frame)) return 0; { struct rx_se_list * dying = frame->prog_backwards; frame->prog_backwards = frame->prog_backwards->cdr; free ((char *)dying); } break; } default: break; } e = e->next; } node->mark = 0; return 1; } #ifdef __STDC__ struct rx_possible_future * rx_state_possible_futures (struct rx * rx, struct rx_nfa_state * n) #else struct rx_possible_future * rx_state_possible_futures (rx, n) struct rx * rx; struct rx_nfa_state * n; #endif { if (n->futures_computed) return n->futures; else { struct eclose_frame frame; frame.prog_backwards = 0; if (!eclose_node (rx, n, n, &frame)) return 0; else { n->futures_computed = 1; return n->futures; } } } /* {Storing the NFA in a Contiguous Region of Memory} */ #ifdef __STDC__ static void se_memo_freer (struct rx_hash_item * node) #else static void se_memo_freer (node) struct rx_hash_item * node; #endif { free ((char *)node->data); } #ifdef __STDC__ static void nfa_set_freer (struct rx_hash_item * node) #else static void nfa_set_freer (node) struct rx_hash_item * node; #endif { free ((char *)node->data); } #ifdef __STDC__ void rx_free_nfa (struct rx *rx) #else void rx_free_nfa (rx) struct rx *rx; #endif { rx_free_hash_table (&rx->se_list_memo, se_memo_freer, &se_list_hash_rules); rx_bzero ((char *)&rx->se_list_memo, sizeof (rx->se_list_memo)); rx_free_hash_table (&rx->set_list_memo, nfa_set_freer, &nfa_set_hash_rules); rx_bzero ((char *)&rx->set_list_memo, sizeof (rx->set_list_memo)); rx_free_nfa_graph (rx); } rplay-3.3.2/rx/rxnfa.h100644 153 62 14766 6552756454 13315 0ustar boynsstaff/* classes: h_files */ #ifndef RXNFAH #define RXNFAH /* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* * Tom Lord (lord@cygnus.com, lord@gnu.ai.mit.edu) */ #include "_rx.h" #include "rxnode.h" /* NFA * * A syntax tree is compiled into an NFA. This page defines the structure * of that NFA. */ struct rx_nfa_state { /* These are kept in a list as the NFA is being built. * Here is the link. */ struct rx_nfa_state *next; /* After the NFA is built, states are given integer id's. * States whose outgoing transitions are all either epsilon or * side effect edges are given ids less than 0. Other states * are given successive non-negative ids starting from 0. * * Here is the id for this state: */ int id; /* The list of NFA edges that go from this state to some other. */ struct rx_nfa_edge *edges; /* If you land in this state, then you implicitly land * in all other states reachable by only epsilon translations. * Call the set of maximal loop-less paths to such states the * epsilon closure of this state. * * There may be other states that are reachable by a mixture of * epsilon and side effect edges. Consider the set of maximal loop-less * paths of that sort from this state. Call it the epsilon-side-effect * closure of the state. * * The epsilon closure of the state is a subset of the epsilon-side- * effect closure. It consists of all the paths that contain * no side effects -- only epsilon edges. * * The paths in the epsilon-side-effect closure can be partitioned * into equivalance sets. Two paths are equivalant if they have the * same set of side effects, in the same order. The epsilon-closure * is one of these equivalance sets. Let's call these equivalance * sets: observably equivalant path sets. That name is chosen * because equivalance of two paths means they cause the same side * effects -- so they lead to the same subsequent observations other * than that they may wind up in different target states. * * The superstate nfa, which is derived from this nfa, is based on * the observation that all of the paths in an observably equivalant * path set can be explored at the same time, provided that the * matcher keeps track not of a single nfa state, but of a set of * states. In particular, after following all the paths in an * observably equivalant set, you wind up at a set of target states. * That set of target states corresponds to one state in the * superstate NFA. * * Staticly, before matching begins, it is convenient to analyze the * nfa. Each state is labeled with a list of the observably * equivalant path sets who's union covers all the * epsilon-side-effect paths beginning in this state. This list is * called the possible futures of the state. * * A trivial example is this NFA: * s1 * A ---> B * * s2 * ---> C * * epsilon s1 * ---------> D ------> E * * * In this example, A has two possible futures. * One invokes the side effect `s1' and contains two paths, * one ending in state B, the other in state E. * The other invokes the side effect `s2' and contains only * one path, landing in state C. * * Here is a list of the possible futures of this state: */ struct rx_possible_future *futures; int futures_computed:1; /* There is exactly one distinguished starting state in every NFA: */ unsigned int is_start:1; int has_cset_edges:1; /* There may be many final states if the "cut" operator was used. * each will have a different non-0 value for this field: */ int is_final; /* These are used internally during NFA construction... */ unsigned int eclosure_needed:1; unsigned int mark:1; }; /* An edge in an NFA is typed: */ enum rx_nfa_etype { /* A cset edge is labled with a set of characters one of which * must be matched for the edge to be taken. */ ne_cset, /* An epsilon edge is taken whenever its starting state is * reached. */ ne_epsilon, /* A side effect edge is taken whenever its starting state is * reached. Side effects may cause the match to fail or the * position of the matcher to advance. */ ne_side_effect }; struct rx_nfa_edge { struct rx_nfa_edge *next; enum rx_nfa_etype type; struct rx_nfa_state *dest; union { rx_Bitset cset; void * side_effect; } params; }; /* A possible future consists of a list of side effects * and a set of destination states. Below are their * representations. These structures are hash-consed so * that lists with the same elements share a representation * (their addresses are ==). */ struct rx_nfa_state_set { struct rx_nfa_state * car; struct rx_nfa_state_set * cdr; }; struct rx_se_list { void * car; struct rx_se_list * cdr; }; struct rx_possible_future { struct rx_possible_future *next; struct rx_se_list * effects; struct rx_nfa_state_set * destset; }; #ifdef __STDC__ extern struct rx_nfa_state * rx_nfa_state (struct rx *rx); extern struct rx_nfa_edge * rx_nfa_edge (struct rx *rx, enum rx_nfa_etype type, struct rx_nfa_state *start, struct rx_nfa_state *dest); extern int rx_build_nfa (struct rx *rx, struct rexp_node *rexp, struct rx_nfa_state **start, struct rx_nfa_state **end); extern struct rx_possible_future * rx_state_possible_futures (struct rx * rx, struct rx_nfa_state * n); extern void rx_free_nfa (struct rx *rx); #else /* STDC */ extern struct rx_nfa_state * rx_nfa_state (); extern struct rx_nfa_edge * rx_nfa_edge (); extern int rx_build_nfa (); extern struct rx_possible_future * rx_state_possible_futures (); extern void rx_free_nfa (); #endif /* STDC */ #endif /* RXNFAH */ rplay-3.3.2/rx/rxnode.c100644 153 62 24331 6552756454 13456 0ustar boynsstaff/* classes: src_files */ /* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "rxall.h" #include "rxnode.h" #define INITSIZE 8 #define EXPANDSIZE 8 #ifdef __STDC__ static int rx_init_string(struct rx_string *thisone, char first) #else static int rx_init_string(thisone, first) struct rx_string *thisone; char first; #endif { char *tmp; tmp = (char *) malloc (INITSIZE); if(!tmp) return -1; thisone->contents = tmp; thisone->contents[0] = first; thisone->reallen = INITSIZE; thisone->len = 1; return 0; } #ifdef __STDC__ static void rx_free_string (struct rx_string *junk) #else static void rx_free_string (junk) struct rx_string *junk; #endif { free (junk->contents); junk->len = junk->reallen = 0; junk->contents = 0; } #ifdef __STDC__ int rx_adjoin_string (struct rx_string *str, char c) #else int rx_adjoin_string (str, c) struct rx_string *str; char c; #endif { if (!str->contents) return rx_init_string (str, c); if (str->len == str->reallen) { char *temp; temp = (char *) realloc (str->contents, str->reallen + EXPANDSIZE); if(!temp) return -1; str->contents = temp; str->reallen += EXPANDSIZE; } str->contents[str->len++] = c; return 0; } #ifdef __STDC__ static int rx_copy_string (struct rx_string *to, struct rx_string *from) #else static int rx_copy_string (to, from) struct rx_string *to; struct rx_string *from; #endif { char *tmp; if (from->len) { tmp = (char *) malloc (from->reallen); if (!tmp) return -1; } rx_free_string (to); to->len = from->len; to->reallen = from->reallen; to->contents = tmp; memcpy (to->contents, from->contents, from->reallen); return 0; } #ifdef __STDC__ static int rx_compare_rx_strings (struct rx_string *a, struct rx_string *b) #else static int rx_compare_rx_strings (a, b) struct rx_string *a; struct rx_string *b; #endif { if (a->len != b->len) return 0; if (a->len) return !memcmp (a->contents, b->contents, a->len); else return 1; /* trivial case: "" == "" */ } #ifdef __STDC__ static unsigned long rx_string_hash (unsigned long seed, struct rx_string *str) #else static unsigned long rx_string_hash (seed, str) unsigned long seed; struct rx_string *str; #endif { /* From Tcl: */ unsigned long result; int c; char * string; int len; string = str->contents; len = str->len; result = seed; while (len--) { c = *string; string++; result += (result<<3) + c; } return result; } #ifdef __STDC__ struct rexp_node * rexp_node (int type) #else struct rexp_node * rexp_node (type) int type; #endif { struct rexp_node *n; n = (struct rexp_node *) malloc (sizeof (*n)); rx_bzero ((char *)n, sizeof (*n)); if (n) { n->type = type; n->id = -1; n->refs = 1; } return n; } /* free_rexp_node assumes that the bitset passed to rx_mk_r_cset * can be freed using rx_free_cset. */ #ifdef __STDC__ struct rexp_node * rx_mk_r_cset (int type, int size, rx_Bitset b) #else struct rexp_node * rx_mk_r_cset (type, size, b) int type; int size; rx_Bitset b; #endif { struct rexp_node * n; n = rexp_node (type); if (n) { n->params.cset = b; n->params.cset_size = size; } return n; } #ifdef __STDC__ struct rexp_node * rx_mk_r_int (int type, int intval) #else struct rexp_node * rx_mk_r_int (type, intval) int type; int intval; #endif { struct rexp_node * n; n = rexp_node (type); if (n) n->params.intval = intval; return n; } #ifdef __STDC__ struct rexp_node * rx_mk_r_str (int type, char c) #else struct rexp_node * rx_mk_r_str (type, c) int type; char c; #endif { struct rexp_node *n; n = rexp_node (type); if (n) rx_init_string (&(n->params.cstr), c); return n; } #ifdef __STDC__ struct rexp_node * rx_mk_r_binop (int type, struct rexp_node * a, struct rexp_node * b) #else struct rexp_node * rx_mk_r_binop (type, a, b) int type; struct rexp_node * a; struct rexp_node * b; #endif { struct rexp_node * n = rexp_node (type); if (n) { n->params.pair.left = a; n->params.pair.right = b; } return n; } #ifdef __STDC__ struct rexp_node * rx_mk_r_monop (int type, struct rexp_node * a) #else struct rexp_node * rx_mk_r_monop (type, a) int type; struct rexp_node * a; #endif { return rx_mk_r_binop (type, a, 0); } #ifdef __STDC__ void rx_free_rexp (struct rexp_node * node) #else void rx_free_rexp (node) struct rexp_node * node; #endif { if (node && !--node->refs) { if (node->params.cset) rx_free_cset (node->params.cset); if (node->params.cstr.reallen) rx_free_string (&(node->params.cstr)); rx_free_rexp (node->params.pair.left); rx_free_rexp (node->params.pair.right); rx_free_rexp (node->simplified); free ((char *)node); } } #ifdef __STDC__ void rx_save_rexp (struct rexp_node * node) #else void rx_save_rexp (node) struct rexp_node * node; #endif { if (node) ++node->refs; } #ifdef __STDC__ struct rexp_node * rx_copy_rexp (int cset_size, struct rexp_node *node) #else struct rexp_node * rx_copy_rexp (cset_size, node) int cset_size; struct rexp_node *node; #endif { if (!node) return 0; else { struct rexp_node *n; n = rexp_node (node->type); if (!n) return 0; if (node->params.cset) { n->params.cset = rx_copy_cset (cset_size, node->params.cset); if (!n->params.cset) { rx_free_rexp (n); return 0; } } if (node->params.cstr.reallen) if (rx_copy_string (&(n->params.cstr), &(node->params.cstr))) { rx_free_rexp(n); return 0; } n->params.intval = node->params.intval; n->params.intval2 = node->params.intval2; n->params.pair.left = rx_copy_rexp (cset_size, node->params.pair.left); n->params.pair.right = rx_copy_rexp (cset_size, node->params.pair.right); if ( (node->params.pair.left && !n->params.pair.left) || (node->params.pair.right && !n->params.pair.right)) { rx_free_rexp (n); return 0; } n->id = node->id; n->len = node->len; n->observed = node->observed; return n; } } #ifdef __STDC__ struct rexp_node * rx_shallow_copy_rexp (int cset_size, struct rexp_node *node) #else struct rexp_node * rx_shallow_copy_rexp (cset_size, node) int cset_size; struct rexp_node *node; #endif { if (!node) return 0; else { struct rexp_node *n; n = rexp_node (node->type); if (!n) return 0; if (node->params.cset) { n->params.cset = rx_copy_cset (cset_size, node->params.cset); if (!n->params.cset) { rx_free_rexp (n); return 0; } } if (node->params.cstr.reallen) if (rx_copy_string (&(n->params.cstr), &(node->params.cstr))) { rx_free_rexp(n); return 0; } n->params.intval = node->params.intval; n->params.intval2 = node->params.intval2; n->params.pair.left = node->params.pair.left; rx_save_rexp (node->params.pair.left); n->params.pair.right = node->params.pair.right; rx_save_rexp (node->params.pair.right); n->id = node->id; n->len = node->len; n->observed = node->observed; return n; } } #ifdef __STDC__ int rx_rexp_equal (struct rexp_node * a, struct rexp_node * b) #else int rx_rexp_equal (a, b) struct rexp_node * a; struct rexp_node * b; #endif { int ret; if (a == b) return 1; if ((a == 0) || (b == 0)) return 0; if (a->type != b->type) return 0; switch (a->type) { case r_cset: ret = ( (a->params.cset_size == b->params.cset_size) && rx_bitset_is_equal (a->params.cset_size, a->params.cset, b->params.cset)); break; case r_string: ret = rx_compare_rx_strings (&(a->params.cstr), &(b->params.cstr)); break; case r_cut: ret = (a->params.intval == b->params.intval); break; case r_concat: case r_alternate: ret = ( rx_rexp_equal (a->params.pair.left, b->params.pair.left) && rx_rexp_equal (a->params.pair.right, b->params.pair.right)); break; case r_opt: case r_star: case r_plus: ret = rx_rexp_equal (a->params.pair.left, b->params.pair.left); break; case r_interval: ret = ( (a->params.intval == b->params.intval) && (a->params.intval2 == b->params.intval2) && rx_rexp_equal (a->params.pair.left, b->params.pair.left)); break; case r_parens: ret = ( (a->params.intval == b->params.intval) && rx_rexp_equal (a->params.pair.left, b->params.pair.left)); break; case r_context: ret = (a->params.intval == b->params.intval); break; default: return 0; } return ret; } #ifdef __STDC__ unsigned long rx_rexp_hash (struct rexp_node * node, unsigned long seed) #else unsigned long rx_rexp_hash (node, seed) struct rexp_node * node; unsigned long seed; #endif { if (!node) return seed; seed = rx_rexp_hash (node->params.pair.left, seed); seed = rx_rexp_hash (node->params.pair.right, seed); seed = rx_bitset_hash (node->params.cset_size, node->params.cset); seed = rx_string_hash (seed, &(node->params.cstr)); seed += (seed << 3) + node->params.intval; seed += (seed << 3) + node->params.intval2; seed += (seed << 3) + node->type; seed += (seed << 3) + node->id; #if 0 seed += (seed << 3) + node->len; seed += (seed << 3) + node->observed; #endif return seed; } rplay-3.3.2/rx/rxnode.h100644 153 62 7146 6552756454 13450 0ustar boynsstaff/* classes: h_files */ #ifndef RXNODEH #define RXNODEH /* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* * Tom Lord (lord@cygnus.com, lord@gnu.ai.mit.edu) */ #include "rxbitset.h" #include "rxcset.h" enum rexp_node_type { r_cset = 0, /* Match from a character set. `a' or `[a-z]'*/ r_concat = 1, /* Concat two subexpressions. `ab' */ r_alternate = 2, /* Choose one of two subexpressions. `a\|b' */ r_opt = 3, /* Optional subexpression. `a?' */ r_star = 4, /* Repeated subexpression. `a*' */ r_plus = 5, /* Nontrivially repeated subexpression. `a+' */ r_string = 6, /* Shorthand for a concatenation of characters */ r_cut = 7, /* Generates a tagged, final nfa state. */ /* see RX_regular_node_type */ r_interval = 8, /* Counted subexpression. `a{4, 1000}' */ r_parens = 9, /* Parenthesized subexpression */ r_context = 10 /* Context-sensative operator such as "^" */ }; #define RX_regular_node_type(T) ((T) <= r_interval) struct rx_string { unsigned long len; unsigned long reallen; unsigned char *contents; }; struct rexp_node { int refs; enum rexp_node_type type; struct { int cset_size; rx_Bitset cset; int intval; int intval2; struct { struct rexp_node *left; struct rexp_node *right; } pair; struct rx_string cstr; } params; int id; int len; int observed; struct rexp_node * simplified; struct rx_cached_rexp * cr; }; #ifdef __STDC__ extern int rx_adjoin_string (struct rx_string *str, char c); extern struct rexp_node * rexp_node (int type); extern struct rexp_node * rx_mk_r_cset (int type, int size, rx_Bitset b); extern struct rexp_node * rx_mk_r_int (int type, int intval); extern struct rexp_node * rx_mk_r_str (int type, char c); extern struct rexp_node * rx_mk_r_binop (int type, struct rexp_node * a, struct rexp_node * b); extern struct rexp_node * rx_mk_r_monop (int type, struct rexp_node * a); extern void rx_free_rexp (struct rexp_node * node); extern void rx_save_rexp (struct rexp_node * node); extern struct rexp_node * rx_copy_rexp (int cset_size, struct rexp_node *node); extern struct rexp_node * rx_shallow_copy_rexp (int cset_size, struct rexp_node *node); extern int rx_rexp_equal (struct rexp_node * a, struct rexp_node * b); extern unsigned long rx_rexp_hash (struct rexp_node * node, unsigned long seed); #else /* STDC */ extern int rx_adjoin_string (); extern struct rexp_node * rexp_node (); extern struct rexp_node * rx_mk_r_cset (); extern struct rexp_node * rx_mk_r_int (); extern struct rexp_node * rx_mk_r_str (); extern struct rexp_node * rx_mk_r_binop (); extern struct rexp_node * rx_mk_r_monop (); extern void rx_free_rexp (); extern void rx_save_rexp (); extern struct rexp_node * rx_copy_rexp (); extern struct rexp_node * rx_shallow_copy_rexp (); extern int rx_rexp_equal (); extern unsigned long rx_rexp_hash (); #endif /* STDC */ #endif /* RXNODEH */ rplay-3.3.2/rx/rxposix.c100644 153 62 25740 6552756454 13700 0ustar boynsstaff/* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "rxall.h" #include "rxposix.h" #include "rxgnucomp.h" #include "rxbasic.h" #include "rxsimp.h" /* regcomp takes a regular expression as a string and compiles it. * * PATTERN is the address of the pattern string. * * CFLAGS is a series of bits which affect compilation. * * If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we * use POSIX basic syntax. * * If REG_NEWLINE is set, then . and [^...] don't match newline. * Also, regexec will try a match beginning after every newline. * * If REG_ICASE is set, then we considers upper- and lowercase * versions of letters to be equivalent when matching. * * If REG_NOSUB is set, then when PREG is passed to regexec, that * routine will report only success or failure, and nothing about the * registers. * * It returns 0 if it succeeds, nonzero if it doesn't. (See regex.h for * the return codes and their meanings.) */ #ifdef __STDC__ int regncomp (regex_t * preg, const char * pattern, int len, int cflags) #else int regncomp (preg, pattern, len, cflags) regex_t * preg; const char * pattern; int len; int cflags; #endif { int ret; unsigned int syntax; rx_bzero ((char *)preg, sizeof (*preg)); syntax = ((cflags & REG_EXTENDED) ? RE_SYNTAX_POSIX_EXTENDED : RE_SYNTAX_POSIX_BASIC); if (!(cflags & REG_ICASE)) preg->translate = 0; else { unsigned i; preg->translate = (unsigned char *) malloc (256); if (!preg->translate) return (int) REG_ESPACE; /* Map uppercase characters to corresponding lowercase ones. */ for (i = 0; i < CHAR_SET_SIZE; i++) preg->translate[i] = isupper (i) ? tolower (i) : i; } /* If REG_NEWLINE is set, newlines are treated differently. */ if (!(cflags & REG_NEWLINE)) preg->newline_anchor = 0; else { /* REG_NEWLINE implies neither . nor [^...] match newline. */ syntax &= ~RE_DOT_NEWLINE; syntax |= RE_HAT_LISTS_NOT_NEWLINE; /* It also changes the matching behavior. */ preg->newline_anchor = 1; } preg->no_sub = !!(cflags & REG_NOSUB); ret = rx_parse (&preg->pattern, pattern, len, syntax, 256, preg->translate); /* POSIX doesn't distinguish between an unmatched open-group and an * unmatched close-group: both are REG_EPAREN. */ if (ret == REG_ERPAREN) ret = REG_EPAREN; if (!ret) { preg->re_nsub = 1; preg->subexps = 0; rx_posix_analyze_rexp (&preg->subexps, &preg->re_nsub, preg->pattern, 0); preg->is_nullable = rx_fill_in_fastmap (256, preg->fastmap, preg->pattern); preg->is_anchored = rx_is_anchored_p (preg->pattern); } return (int) ret; } #ifdef __STDC__ int regcomp (regex_t * preg, const char * pattern, int cflags) #else int regcomp (preg, pattern, cflags) regex_t * preg; const char * pattern; int cflags; #endif { /* POSIX says a null character in the pattern terminates it, so we * can use strlen here in compiling the pattern. */ return regncomp (preg, pattern, strlen (pattern), cflags); } /* Returns a message corresponding to an error code, ERRCODE, returned from either regcomp or regexec. */ #ifdef __STDC__ size_t regerror (int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size) #else size_t regerror (errcode, preg, errbuf, errbuf_size) int errcode; const regex_t *preg; char *errbuf; size_t errbuf_size; #endif { const char *msg; size_t msg_size; msg = rx_error_msg[errcode] == 0 ? "Success" : rx_error_msg[errcode]; msg_size = strlen (msg) + 1; /* Includes the 0. */ if (errbuf_size != 0) { if (msg_size > errbuf_size) { strncpy (errbuf, msg, errbuf_size - 1); errbuf[errbuf_size - 1] = 0; } else strcpy (errbuf, msg); } return msg_size; } #ifdef __STDC__ int rx_regmatch (regmatch_t pmatch[], const regex_t *preg, struct rx_context_rules * rules, int start, int end, const char *string) #else int rx_regmatch (pmatch, preg, rules, start, end, string) regmatch_t pmatch[]; const regex_t *preg; struct rx_context_rules * rules; int start; int end; const char *string; #endif { struct rx_solutions * solutions; enum rx_answers answer; struct rx_context_rules local_rules; int orig_end; int end_lower_bound; int end_upper_bound; local_rules = *rules; orig_end = end; if (!preg->pattern) { end_lower_bound = start; end_upper_bound = start; } else if (preg->pattern->len >= 0) { end_lower_bound = start + preg->pattern->len; end_upper_bound = start + preg->pattern->len; } else { end_lower_bound = start; end_upper_bound = end; } end = end_upper_bound; while (end >= end_lower_bound) { local_rules.not_eol = (rules->not_eol ? ( (end == orig_end) || !local_rules.newline_anchor || (string[end] != '\n')) : ( (end != orig_end) && (!local_rules.newline_anchor || (string[end] != '\n')))); solutions = rx_basic_make_solutions (pmatch, preg->pattern, preg->subexps, start, end, &local_rules, string); if (!solutions) return REG_ESPACE; answer = rx_next_solution (solutions); if (answer == rx_yes) { if (pmatch) { pmatch[0].rm_so = start; pmatch[0].rm_eo = end; pmatch[0].final_tag = solutions->final_tag; } rx_basic_free_solutions (solutions); return 0; } else rx_basic_free_solutions (solutions); --end; } switch (answer) { default: case rx_bogus: return REG_ESPACE; case rx_no: return REG_NOMATCH; } } #ifdef __STDC__ int rx_regexec (regmatch_t pmatch[], const regex_t *preg, struct rx_context_rules * rules, int start, int end, const char *string) #else int rx_regexec (pmatch, preg, rules, start, end, string) regmatch_t pmatch[]; const regex_t *preg; struct rx_context_rules * rules; int start; int end; const char *string; #endif { int x; int stat; int anchored; struct rexp_node * simplified; struct rx_unfa * unfa; struct rx_classical_system machine; anchored = preg->is_anchored; unfa = 0; if ((end - start) > RX_MANY_CASES) { if (0 > rx_simple_rexp (&simplified, 256, preg->pattern, preg->subexps)) return REG_ESPACE; unfa = rx_unfa (rx_basic_unfaniverse (), simplified, 256); if (!unfa) { rx_free_rexp (simplified); return REG_ESPACE; } rx_init_system (&machine, unfa->nfa); rx_free_rexp (simplified); } for (x = start; x <= end; ++x) { if (preg->is_nullable || ((x < end) && (preg->fastmap[((unsigned char *)string)[x]]))) { if ((end - start) > RX_MANY_CASES) { int amt; if (rx_start_superstate (&machine) != rx_yes) { rx_free_unfa (unfa); return REG_ESPACE; } amt = rx_advance_to_final (&machine, string + x, end - start - x); if (!machine.final_tag && (amt < (end - start - x))) goto nomatch; } stat = rx_regmatch (pmatch, preg, rules, x, end, string); if (!stat || (stat != REG_NOMATCH)) { rx_free_unfa (unfa); return stat; } } nomatch: if (anchored) if (!preg->newline_anchor) { rx_free_unfa (unfa); return REG_NOMATCH; } else while (x < end) if (string[x] == '\n') break; else ++x; } rx_free_unfa (unfa); return REG_NOMATCH; } /* regexec searches for a given pattern, specified by PREG, in the * string STRING. * * If NMATCH is zero or REG_NOSUB was set in the cflags argument to * `regcomp', we ignore PMATCH. Otherwise, we assume PMATCH has at * least NMATCH elements, and we set them to the offsets of the * corresponding matched substrings. * * EFLAGS specifies `execution flags' which affect matching: if * REG_NOTBOL is set, then ^ does not match at the beginning of the * string; if REG_NOTEOL is set, then $ does not match at the end. * * We return 0 if we find a match and REG_NOMATCH if not. */ #ifdef __STDC__ int regnexec (const regex_t *preg, const char *string, int len, size_t nmatch, regmatch_t **pmatch, int eflags) #else int regnexec (preg, string, len, nmatch, pmatch, eflags) const regex_t *preg; const char *string; int len; size_t nmatch; regmatch_t **pmatch; int eflags; #endif { int want_reg_info; struct rx_context_rules rules; regmatch_t * regs; size_t nregs; int stat; want_reg_info = (!preg->no_sub && (nmatch > 0)); rules.newline_anchor = preg->newline_anchor; rules.not_bol = !!(eflags & REG_NOTBOL); rules.not_eol = !!(eflags & REG_NOTEOL); rules.case_indep = !!(eflags & REG_ICASE); if (nmatch >= preg->re_nsub) { regs = *pmatch; nregs = nmatch; } else { regs = (regmatch_t *)malloc (preg->re_nsub * sizeof (*regs)); if (!regs) return REG_ESPACE; nregs = preg->re_nsub; } { int x; for (x = 0; x < nregs; ++x) regs[x].rm_so = regs[x].rm_eo = -1; } stat = rx_regexec (regs, preg, &rules, 0, len, string); if (!stat && want_reg_info && pmatch && (regs != *pmatch)) { size_t x; for (x = 0; x < nmatch; ++x) (*pmatch)[x] = regs[x]; } if (!stat && (eflags & REG_ALLOC_REGS)) *pmatch = regs; else if (regs && (!pmatch || (regs != *pmatch))) free (regs); return stat; } #ifdef __STDC__ int regexec (const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags) #else int regexec (preg, string, nmatch, pmatch, eflags) const regex_t *preg; const char *string; size_t nmatch; regmatch_t pmatch[]; int eflags; #endif { return regnexec (preg, string, strlen (string), nmatch, &pmatch, (eflags & ~REG_ALLOC_REGS)); } /* Free dynamically allocated space used by PREG. */ #ifdef __STDC__ void regfree (regex_t *preg) #else void regfree (preg) regex_t *preg; #endif { if (preg->pattern) { rx_free_rexp (preg->pattern); preg->pattern = 0; } if (preg->subexps) { free (preg->subexps); preg->subexps = 0; } if (preg->translate != 0) { free (preg->translate); preg->translate = 0; } } rplay-3.3.2/rx/rxposix.h100644 153 62 3713 6552756455 13662 0ustar boynsstaff/* classes: h_files */ #ifndef RXPOSIXH #define RXPOSIXH /* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "rxspencer.h" #include "rxcontext.h" #include "inst-rxposix.h" #ifdef __STDC__ extern int regncomp (regex_t * preg, const char * pattern, int len, int cflags); extern int regcomp (regex_t * preg, const char * pattern, int cflags); extern size_t regerror (int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size); extern int rx_regmatch (regmatch_t pmatch[], const regex_t *preg, struct rx_context_rules * rules, int start, int end, const char *string); extern int rx_regexec (regmatch_t pmatch[], const regex_t *preg, struct rx_context_rules * rules, int start, int end, const char *string); extern int regnexec (const regex_t *preg, const char *string, int len, size_t nmatch, regmatch_t **pmatch, int eflags); extern int regexec (const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags); extern void regfree (regex_t *preg); #else /* STDC */ extern int regncomp (); extern int regcomp (); extern size_t regerror (); extern int rx_regmatch (); extern int rx_regexec (); extern int regnexec (); extern int regexec (); extern void regfree (); #endif /* STDC */ #endif /* RXPOSIXH */ rplay-3.3.2/rx/rxproto.h100644 153 62 1746 6552756455 13667 0ustar boynsstaff/* classes: h_files */ #ifndef RXPROTOH #define RXPROTOH /* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifdef __STDC__ #define P(X) X #else #define P(X) () #endif #ifdef __STDC__ #else /* STDC */ #endif /* STDC */ #endif /* RXPROTOH */ rplay-3.3.2/rx/rxsimp.c100644 153 62 5656 6552756454 13472 0ustar boynsstaff/* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "rxall.h" #include "rxsimp.h" /* Could reasonably hashcons instead of in rxunfa.c */ #ifdef __STDC__ int rx_simple_rexp (struct rexp_node ** answer, int cset_size, struct rexp_node *node, struct rexp_node ** subexps) #else int rx_simple_rexp (answer, cset_size, node, subexps) struct rexp_node ** answer; int cset_size; struct rexp_node *node; struct rexp_node ** subexps; #endif { int stat; if (!node) { *answer = 0; return 0; } if (!node->observed) { rx_save_rexp (node); *answer = node; return 0; } if (node->simplified) { rx_save_rexp (node->simplified); *answer = node->simplified; return 0; } switch (node->type) { default: case r_cset: case r_string: case r_cut: return -2; /* an internal error, really */ case r_parens: stat = rx_simple_rexp (answer, cset_size, node->params.pair.left, subexps); break; case r_context: if (isdigit (node->params.intval)) stat = rx_simple_rexp (answer, cset_size, subexps [node->params.intval - '0'], subexps); else { *answer = 0; stat = 0; } break; case r_concat: case r_alternate: case r_opt: case r_star: case r_plus: case r_interval: { struct rexp_node *n; n = rexp_node (node->type); if (!n) return -1; if (node->params.cset) { n->params.cset = rx_copy_cset (cset_size, node->params.cset); if (!n->params.cset) { rx_free_rexp (n); return -1; } } n->params.intval = node->params.intval; n->params.intval2 = node->params.intval2; { int s; s = rx_simple_rexp (&n->params.pair.left, cset_size, node->params.pair.left, subexps); if (!s) s = rx_simple_rexp (&n->params.pair.right, cset_size, node->params.pair.right, subexps); if (!s) { *answer = n; stat = 0; } else { rx_free_rexp (n); stat = s; } } } break; } if (!stat) { node->simplified = *answer; rx_save_rexp (node->simplified); } return stat; } rplay-3.3.2/rx/rxsimp.h100644 153 62 2174 6552756455 13470 0ustar boynsstaff/* classes: h_files */ #ifndef RXSIMPH #define RXSIMPH /* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "rxcset.h" #include "rxnode.h" #ifdef __STDC__ extern int rx_simple_rexp (struct rexp_node ** answer, int cset_size, struct rexp_node *node, struct rexp_node ** subexps); #else /* STDC */ extern int rx_simple_rexp (); #endif /* STDC */ #endif /* RXSIMPH */ rplay-3.3.2/rx/rxspencer.c100644 153 62 64733 6552756454 14202 0ustar boynsstaff/* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include #include "rxall.h" #include "rxspencer.h" #include "rxsimp.h" static char * silly_hack_2 = 0; struct rx_solutions rx_no_solutions; #ifdef __STDC__ struct rx_solutions * rx_make_solutions (struct rx_registers * regs, struct rx_unfaniverse * verse, struct rexp_node * expression, struct rexp_node ** subexps, int cset_size, int start, int end, rx_vmfn vmfn, rx_contextfn contextfn, void * closure) #else struct rx_solutions * rx_make_solutions (regs, verse, expression, subexps, cset_size, start, end, vmfn, contextfn, closure) struct rx_registers * regs; struct rx_unfaniverse * verse; struct rexp_node * expression; struct rexp_node ** subexps; int cset_size; int start; int end; rx_vmfn vmfn; rx_contextfn contextfn; void * closure; #endif { struct rx_solutions * solns; if ( expression && (expression->len >= 0) && (expression->len != (end - start))) return &rx_no_solutions; if (silly_hack_2) { solns = (struct rx_solutions *)silly_hack_2; silly_hack_2 = 0; } else solns = (struct rx_solutions *)malloc (sizeof (*solns)); if (!solns) return 0; rx_bzero ((char *)solns, sizeof (*solns)); solns->step = 0; solns->cset_size = cset_size; solns->subexps = subexps; solns->exp = expression; rx_save_rexp (expression); solns->verse = verse; solns->regs = regs; solns->start = start; solns->end = end; solns->vmfn = vmfn; solns->contextfn = contextfn; solns->closure = closure; if (!solns->exp || !solns->exp->observed) { solns->dfa = rx_unfa (verse, expression, cset_size); if (!solns->dfa) goto err_return; rx_init_system (&solns->match_engine, solns->dfa->nfa); if (rx_yes != rx_start_superstate (&solns->match_engine)) goto err_return; } else { struct rexp_node * simplified; int status; status = rx_simple_rexp (&simplified, cset_size, solns->exp, subexps); if (status) goto err_return; solns->dfa = rx_unfa (verse, simplified, cset_size); if (!solns->dfa) { rx_free_rexp (simplified); goto err_return; } rx_init_system (&solns->match_engine, solns->dfa->nfa); if (rx_yes != rx_start_superstate (&solns->match_engine)) goto err_return; rx_free_rexp (simplified); } if (expression && ( (expression->type == r_concat) || (expression->type == r_plus) || (expression->type == r_star) || (expression->type == r_interval))) { struct rexp_node * subexp; subexp = solns->exp->params.pair.left; if (!subexp || !subexp->observed) { solns->left_dfa = rx_unfa (solns->verse, subexp, solns->cset_size); } else { struct rexp_node * simplified; int status; status = rx_simple_rexp (&simplified, solns->cset_size, subexp, solns->subexps); if (status) goto err_return; solns->left_dfa = rx_unfa (solns->verse, simplified, solns->cset_size); rx_free_rexp (simplified); } if (!solns->left_dfa) goto err_return; rx_bzero ((char *)&solns->left_match_engine, sizeof (solns->left_match_engine)); rx_init_system (&solns->left_match_engine, solns->left_dfa->nfa); } return solns; err_return: rx_free_rexp (solns->exp); free (solns); return 0; } #ifdef __STDC__ void rx_free_solutions (struct rx_solutions * solns) #else void rx_free_solutions (solns) struct rx_solutions * solns; #endif { if (!solns) return; if (solns == &rx_no_solutions) return; if (solns->left) { rx_free_solutions (solns->left); solns->left = 0; } if (solns->right) { rx_free_solutions (solns->right); solns->right = 0; } if (solns->dfa) { rx_free_unfa (solns->dfa); solns->dfa = 0; } if (solns->left_dfa) { rx_terminate_system (&solns->left_match_engine); rx_free_unfa (solns->left_dfa); solns->left_dfa = 0; } rx_terminate_system (&solns->match_engine); if (solns->exp) { rx_free_rexp (solns->exp); solns->exp = 0; } if (!silly_hack_2) silly_hack_2 = (char *)solns; else free (solns); } #ifdef __STDC__ static enum rx_answers rx_solution_fit_p (struct rx_solutions * solns) #else static enum rx_answers rx_solution_fit_p (solns) struct rx_solutions * solns; #endif { unsigned const char * burst; int burst_addr; int burst_len; int burst_end_addr; int rel_pos_in_burst; enum rx_answers vmstat; int current_pos; current_pos = solns->start; next_burst: vmstat = solns->vmfn (solns->closure, &burst, &burst_len, &burst_addr, current_pos, solns->end, current_pos); if (vmstat != rx_yes) return vmstat; rel_pos_in_burst = current_pos - burst_addr; burst_end_addr = burst_addr + burst_len; if (burst_end_addr >= solns->end) { enum rx_answers fit_status; fit_status = rx_fit_p (&solns->match_engine, burst + rel_pos_in_burst, solns->end - current_pos); return fit_status; } else { enum rx_answers fit_status; fit_status = rx_advance (&solns->match_engine, burst + rel_pos_in_burst, burst_len - rel_pos_in_burst); if (fit_status != rx_yes) { return fit_status; } else { current_pos += burst_len - rel_pos_in_burst; goto next_burst; } } } #ifdef __STDC__ static enum rx_answers rx_solution_fit_str_p (struct rx_solutions * solns) #else static enum rx_answers rx_solution_fit_str_p (solns) struct rx_solutions * solns; #endif { int current_pos; unsigned const char * burst; int burst_addr; int burst_len; int burst_end_addr; int rel_pos_in_burst; enum rx_answers vmstat; int count; unsigned char * key; current_pos = solns->start; count = solns->exp->params.cstr.len; key = (unsigned char *)solns->exp->params.cstr.contents; next_burst: vmstat = solns->vmfn (solns->closure, &burst, &burst_len, &burst_addr, current_pos, solns->end, current_pos); if (vmstat != rx_yes) return vmstat; rel_pos_in_burst = current_pos - burst_addr; burst_end_addr = burst_addr + burst_len; { unsigned const char * pos; pos = burst + rel_pos_in_burst; if (burst_end_addr >= solns->end) { while (count) { if (*pos != *key) return rx_no; ++pos; ++key; --count; } return rx_yes; } else { int part_count; int part_count_init; part_count_init = burst_len - rel_pos_in_burst; part_count = part_count_init; while (part_count) { if (*pos != *key) return rx_no; ++pos; ++key; --part_count; } count -= part_count_init; current_pos += burst_len - rel_pos_in_burst; goto next_burst; } } } #if 0 #ifdef __STDC__ int rx_best_end_guess (struct rx_solutions * solns, struct rexp_node * exp, int bound) #else int rx_best_end_guess (solns, exp, bound) struct rx_solutions * solns; struct rexp_node * exp; int bound; #endif { int current_pos; unsigned const char * burst; int burst_addr; int burst_len; int burst_end_addr; int rel_pos_in_burst; int best_guess; enum rx_answers vmstat; #if 0 unparse_print_rexp (256, solns->exp); printf ("\n"); unparse_print_rexp (256, exp); printf ("\nbound %d \n", bound); #endif if (rx_yes != rx_start_superstate (&solns->left_match_engine)) { return bound - 1; } best_guess = current_pos = solns->start; next_burst: #if 0 printf (" best_guess %d\n", best_guess); #endif vmstat = solns->vmfn (solns->closure, &burst, &burst_len, &burst_addr, current_pos, bound, current_pos); #if 0 printf (" str>%s\n", burst); #endif if (vmstat != rx_yes) { return bound - 1; } rel_pos_in_burst = current_pos - burst_addr; burst_end_addr = burst_addr + burst_len; if (burst_end_addr > bound) { burst_end_addr = bound; burst_len = bound - burst_addr; } { int amt_advanced; #if 0 printf (" rel_pos_in_burst %d burst_len %d\n", rel_pos_in_burst, burst_len); #endif while (rel_pos_in_burst < burst_len) { amt_advanced= rx_advance_to_final (&solns->left_match_engine, burst + rel_pos_in_burst, burst_len - rel_pos_in_burst); #if 0 printf (" amt_advanced %d", amt_advanced); #endif if (amt_advanced < 0) { return bound - 1; } current_pos += amt_advanced; rel_pos_in_burst += amt_advanced; if (solns->left_match_engine.final_tag) best_guess = current_pos; #if 0 printf (" best_guess %d\n", best_guess); printf (" current_pos %d\n", current_pos); #endif if (amt_advanced == 0) { return best_guess; } } if (current_pos == bound) { return best_guess; } goto next_burst; } } #endif #ifdef __STDC__ enum rx_answers rx_next_solution (struct rx_solutions * solns) #else enum rx_answers rx_next_solution (solns) struct rx_solutions * solns; #endif { if (!solns) return rx_bogus; if (solns == &rx_no_solutions) { return rx_no; } if (!solns->exp) { if (solns->step != 0) { return rx_no; } else { solns->step = 1; solns->final_tag = 1; return (solns->start == solns->end ? rx_yes : rx_no); } } else if ( (solns->exp->len >= 0) && (solns->exp->len != (solns->end - solns->start))) { return rx_no; } else if (!solns->exp->observed) { if (solns->step != 0) { return rx_no; } else if (solns->exp->type == r_string) { enum rx_answers ans; ans = rx_solution_fit_str_p (solns); solns->final_tag = 1; solns->step = -1; return ans; } else { enum rx_answers ans; ans = rx_solution_fit_p (solns); solns->final_tag = solns->match_engine.final_tag; solns->step = -1; return ans; } } else if (solns->exp->observed) { enum rx_answers fit_p; switch (solns->step) { case -2: if (solns->exp->params.intval) { solns->regs[solns->exp->params.intval].rm_so = solns->saved_rm_so; solns->regs[solns->exp->params.intval].rm_eo = solns->saved_rm_eo; } return rx_no; case -1: return rx_no; case 0: fit_p = rx_solution_fit_p (solns); /* Set final_tag here because this rough fit test * may be all the matching that gets done. * For example, consider a paren node containing * a true regular expression ending with a cut * operator. */ solns->final_tag = solns->match_engine.final_tag; switch (fit_p) { case rx_no: solns->step = -1; return rx_no; case rx_yes: solns->step = 1; goto resolve_fit; case rx_bogus: default: solns->step = -1; return fit_p; } default: resolve_fit: switch (solns->exp->type) { case r_cset: case r_string: case r_cut: solns->step = -1; return rx_bogus; case r_parens: { enum rx_answers paren_stat; switch (solns->step) { case 1: if (solns->exp->params.intval) { solns->saved_rm_so = solns->regs[solns->exp->params.intval].rm_so; solns->saved_rm_eo = solns->regs[solns->exp->params.intval].rm_eo; } if ( !solns->exp->params.pair.left || !solns->exp->params.pair.left->observed) { if (solns->exp->params.intval) { solns->regs[solns->exp->params.intval].rm_so = solns->start; solns->regs[solns->exp->params.intval].rm_eo = solns->end; } solns->step = -2; /* Keep the final_tag from the fit_p test. */ return rx_yes; } else { solns->left = rx_make_solutions (solns->regs, solns->verse, solns->exp->params.pair.left, solns->subexps, solns->cset_size, solns->start, solns->end, solns->vmfn, solns->contextfn, solns->closure); if (!solns->left) { solns->step = -1; return rx_bogus; } } solns->step = 2; /* fall through */ case 2: if (solns->exp->params.intval) { solns->regs[solns->exp->params.intval].rm_so = solns->saved_rm_so; solns->regs[solns->exp->params.intval].rm_eo = solns->saved_rm_eo; } paren_stat = rx_next_solution (solns->left); if (paren_stat == rx_yes) { if (solns->exp->params.intval) { solns->regs[solns->exp->params.intval].rm_so = solns->start; solns->regs[solns->exp->params.intval].rm_eo = solns->end; } solns->final_tag = solns->left->final_tag; return rx_yes; } else { solns->step = -1; rx_free_solutions (solns->left); solns->left = 0; if (solns->exp->params.intval) { solns->regs[solns->exp->params.intval].rm_so = solns->saved_rm_so; solns->regs[solns->exp->params.intval].rm_eo = solns->saved_rm_eo; } return paren_stat; } } } case r_opt: { enum rx_answers opt_stat; switch (solns->step) { case 1: solns->left = rx_make_solutions (solns->regs, solns->verse, solns->exp->params.pair.left, solns->subexps, solns->cset_size, solns->start, solns->end, solns->vmfn, solns->contextfn, solns->closure); if (!solns->left) { solns->step = -1; return rx_bogus; } solns->step = 2; /* fall through */ case 2: opt_stat = rx_next_solution (solns->left); if (opt_stat == rx_yes) { solns->final_tag = solns->left->final_tag; return rx_yes; } else { solns->step = -1; rx_free_solutions (solns->left); solns->left = 0; return ((solns->start == solns->end) ? rx_yes : rx_no); } } } case r_alternate: { enum rx_answers alt_stat; switch (solns->step) { case 1: solns->left = rx_make_solutions (solns->regs, solns->verse, solns->exp->params.pair.left, solns->subexps, solns->cset_size, solns->start, solns->end, solns->vmfn, solns->contextfn, solns->closure); if (!solns->left) { solns->step = -1; return rx_bogus; } solns->step = 2; /* fall through */ case 2: alt_stat = rx_next_solution (solns->left); if (alt_stat == rx_yes) { solns->final_tag = solns->left->final_tag; return alt_stat; } else { solns->step = 3; rx_free_solutions (solns->left); solns->left = 0; /* fall through */ } case 3: solns->right = rx_make_solutions (solns->regs, solns->verse, solns->exp->params.pair.right, solns->subexps, solns->cset_size, solns->start, solns->end, solns->vmfn, solns->contextfn, solns->closure); if (!solns->right) { solns->step = -1; return rx_bogus; } solns->step = 4; /* fall through */ case 4: alt_stat = rx_next_solution (solns->right); if (alt_stat == rx_yes) { solns->final_tag = solns->right->final_tag; return alt_stat; } else { solns->step = -1; rx_free_solutions (solns->right); solns->right = 0; return alt_stat; } } } case r_concat: { switch (solns->step) { enum rx_answers concat_stat; case 1: solns->split_guess = solns->end; #if 0 solns->split_guess = ((solns->end - solns->start) > RX_MANY_CASES ? rx_best_end_guess (solns, solns->exp->params.pair.left, solns->end) : solns->end); #endif concat_split_guess_loop: solns->left = rx_make_solutions (solns->regs, solns->verse, solns->exp->params.pair.left, solns->subexps, solns->cset_size, solns->start, solns->split_guess, solns->vmfn, solns->contextfn, solns->closure); if (!solns->left) { solns->step = -1; return rx_bogus; } solns->step = 2; case 2: concat_try_next_left_match: concat_stat = rx_next_solution (solns->left); if (concat_stat != rx_yes) { rx_free_solutions (solns->left); rx_free_solutions (solns->right); solns->left = solns->right = 0; solns->split_guess = solns->split_guess - 1; #if 0 solns->split_guess = ((solns->split_guess - solns->start) > RX_MANY_CASES ? rx_best_end_guess (solns, solns->exp->params.pair.left, solns->split_guess - 1) : solns->split_guess - 1); #endif if (solns->split_guess >= solns->start) goto concat_split_guess_loop; else { solns->step = -1; return concat_stat; } } else { solns->step = 3; /* fall through */ } case 3: solns->right = rx_make_solutions (solns->regs, solns->verse, solns->exp->params.pair.right, solns->subexps, solns->cset_size, solns->split_guess, solns->end, solns->vmfn, solns->contextfn, solns->closure); if (!solns->right) { rx_free_solutions (solns->left); solns->left = 0; solns->step = -1; return rx_bogus; } solns->step = 4; /* fall through */ case 4: /* concat_try_next_right_match: */ concat_stat = rx_next_solution (solns->right); if (concat_stat == rx_yes) { solns->final_tag = solns->right->final_tag; return concat_stat; } else if (concat_stat == rx_no) { rx_free_solutions (solns->right); solns->right = 0; solns->step = 2; goto concat_try_next_left_match; } else /* concat_stat == rx_bogus */ { rx_free_solutions (solns->left); solns->left = 0; rx_free_solutions (solns->right); solns->right = 0; solns->step = -1; return concat_stat; } } } case r_plus: case r_star: { switch (solns->step) { enum rx_answers star_stat; case 1: solns->split_guess = solns->end; #if 0 solns->split_guess = ((solns->end - solns->start) > RX_MANY_CASES ? rx_best_end_guess (solns, solns->exp->params.pair.left, solns->end) : solns->end); #endif star_split_guess_loop: solns->left = rx_make_solutions (solns->regs, solns->verse, solns->exp->params.pair.left, solns->subexps, solns->cset_size, solns->start, solns->split_guess, solns->vmfn, solns->contextfn, solns->closure); if (!solns->left) { solns->step = -1; return rx_bogus; } solns->step = 2; case 2: star_try_next_left_match: star_stat = rx_next_solution (solns->left); if (star_stat != rx_yes) { rx_free_solutions (solns->left); rx_free_solutions (solns->right); solns->left = solns->right = 0; solns->split_guess = solns->split_guess - 1; #if 0 solns->split_guess = ((solns->split_guess - solns->start) > RX_MANY_CASES ? rx_best_end_guess (solns, solns->exp->params.pair.left, solns->split_guess - 1) : solns->split_guess - 1); #endif if (solns->split_guess >= solns->start) goto star_split_guess_loop; else { solns->step = -1; if ( (solns->exp->type == r_star) && (solns->start == solns->end) && (star_stat == rx_no)) { solns->final_tag = 1; return rx_yes; } else return star_stat; } } else { solns->step = 3; /* fall through */ } if (solns->split_guess == solns->end) { solns->final_tag = solns->left->final_tag; return rx_yes; } case 3: solns->right = rx_make_solutions (solns->regs, solns->verse, solns->exp, solns->subexps, solns->cset_size, solns->split_guess, solns->end, solns->vmfn, solns->contextfn, solns->closure); if (!solns->right) { rx_free_solutions (solns->left); solns->left = 0; solns->step = -1; return rx_bogus; } solns->step = 4; /* fall through */ case 4: /* star_try_next_right_match: */ star_stat = rx_next_solution (solns->right); if (star_stat == rx_yes) { solns->final_tag = solns->right->final_tag; return star_stat; } else if (star_stat == rx_no) { rx_free_solutions (solns->right); solns->right = 0; solns->step = 2; goto star_try_next_left_match; } else /* star_stat == rx_bogus */ { rx_free_solutions (solns->left); solns->left = 0; rx_free_solutions (solns->right); solns->right = 0; solns->step = -1; return star_stat; } } } case r_interval: { switch (solns->step) { enum rx_answers interval_stat; case 1: /* If the interval permits nothing, * return immediately. */ if (solns->exp->params.intval2 < solns->interval_x) { solns->step = -1; return rx_no; } /* If the interval permits only 0 iterations, * return immediately. Success depends on the * emptiness of the match. */ if ( (solns->exp->params.intval2 == solns->interval_x) && (solns->exp->params.intval <= solns->interval_x)) { solns->step = -1; solns->final_tag = 1; return ((solns->start == solns->end) ? rx_yes : rx_no); } /* The interval permits at most 0 iterations, * but also requires more. A bug. */ if (solns->exp->params.intval2 == solns->interval_x) { /* indicates a regexp compilation error, actually */ solns->step = -1; return rx_bogus; } solns->split_guess = solns->end; #if 0 solns->split_guess = ((solns->end - solns->start) > RX_MANY_CASES ? rx_best_end_guess (solns, solns->exp->params.pair.left, solns->end) : solns->end); #endif /* The interval permits more than 0 iterations. * If it permits 0 and the match is to be empty, * the trivial match is the most preferred answer. */ if (solns->exp->params.intval <= solns->interval_x) { solns->step = 2; if (solns->start == solns->end) { solns->final_tag = 1; return rx_yes; } /* If this isn't a trivial match, or if the trivial match * is rejected, look harder. */ } case 2: interval_split_guess_loop: /* The match requires at least one iteration, either because * there are characters to match, or because the interval starts * above 0. * * Look for the first iteration: */ solns->left = rx_make_solutions (solns->regs, solns->verse, solns->exp->params.pair.left, solns->subexps, solns->cset_size, solns->start, solns->split_guess, solns->vmfn, solns->contextfn, solns->closure); if (!solns->left) { solns->step = -1; return rx_bogus; } solns->step = 3; case 3: interval_try_next_left_match: interval_stat = rx_next_solution (solns->left); if (interval_stat != rx_yes) { rx_free_solutions (solns->left); rx_free_solutions (solns->right); solns->left = solns->right = 0; solns->split_guess = solns->split_guess - 1; #if 0 solns->split_guess = ((solns->split_guess - solns->start) > RX_MANY_CASES ? rx_best_end_guess (solns, solns->exp->params.pair.left, solns->split_guess - 1) : solns->split_guess - 1); #endif if (solns->split_guess >= solns->start) goto interval_split_guess_loop; else { solns->step = -1; return interval_stat; } } else { solns->step = 4; /* fall through */ } case 4: { /* After matching one required iteration, construct a smaller * interval and try to match that against the rest. * * To avoid thwarting unfa caching, instead of building a new * rexp node with different interval extents, we keep interval_x * in each solns structure to keep track of the number of * iterations matched so far. */ solns->right = rx_make_solutions (solns->regs, solns->verse, solns->exp, solns->subexps, solns->cset_size, solns->split_guess, solns->end, solns->vmfn, solns->contextfn, solns->closure); solns->right->interval_x = solns->interval_x + 1; } if (!solns->right) { rx_free_solutions (solns->left); solns->left = 0; solns->step = -1; return rx_bogus; } solns->step = 5; /* fall through */ case 5: /* interval_try_next_right_match: */ interval_stat = rx_next_solution (solns->right); if (interval_stat == rx_yes) { solns->final_tag = solns->right->final_tag; return interval_stat; } else if (interval_stat == rx_no) { rx_free_solutions (solns->right); solns->right = 0; solns->step = 2; goto interval_try_next_left_match; } else /* interval_stat == rx_bogus */ { rx_free_solutions (solns->left); solns->left = 0; rx_free_solutions (solns->right); solns->right = 0; solns->step = -1; return interval_stat; } } } case r_context: { solns->step = -1; solns->final_tag = 1; return solns->contextfn (solns->closure, solns->exp, solns->start, solns->end, solns->regs); } } } return rx_bogus; } } rplay-3.3.2/rx/rxspencer.h100644 153 62 5103 6552756455 14152 0ustar boynsstaff/* classes: h_files */ #ifndef RXSPENCERH #define RXSPENCERH /* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "rxproto.h" #include "rxnode.h" #include "rxunfa.h" #include "rxanal.h" #include "inst-rxposix.h" #define RX_MANY_CASES 30 typedef enum rx_answers (*rx_vmfn) P((void * closure, unsigned const char ** burst, int * len, int * offset, int start, int end, int need)); typedef enum rx_answers (*rx_contextfn) P((void * closure, struct rexp_node * node, int start, int end, struct rx_registers * regs)); struct rx_solutions { int step; int cset_size; struct rexp_node * exp; struct rexp_node ** subexps; struct rx_registers * regs; int start; int end; rx_vmfn vmfn; rx_contextfn contextfn; void * closure; struct rx_unfaniverse * verse; struct rx_unfa * dfa; struct rx_classical_system match_engine; struct rx_unfa * left_dfa; struct rx_classical_system left_match_engine; int split_guess; struct rx_solutions * left; struct rx_solutions * right; int interval_x; int saved_rm_so; int saved_rm_eo; int final_tag; }; extern struct rx_solutions rx_no_solutions; #ifdef __STDC__ extern struct rx_solutions * rx_make_solutions (struct rx_registers * regs, struct rx_unfaniverse * verse, struct rexp_node * expression, struct rexp_node ** subexps, int cset_size, int start, int end, rx_vmfn vmfn, rx_contextfn contextfn, void * closure); extern void rx_free_solutions (struct rx_solutions * solns); extern int rx_best_end_guess (struct rx_solutions * solns, struct rexp_node * exp, int bound); extern enum rx_answers rx_next_solution (struct rx_solutions * solns); #else /* STDC */ extern struct rx_solutions * rx_make_solutions (); extern void rx_free_solutions (); extern int rx_best_end_guess (); extern enum rx_answers rx_next_solution (); #endif /* STDC */ #endif /* RXSPENCERH */ rplay-3.3.2/rx/rxstr.c100644 153 62 5774 6552756454 13333 0ustar boynsstaff/* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "rxall.h" #include "rxstr.h" #ifdef __STDC__ enum rx_answers rx_str_vmfn (void * closure, unsigned const char ** burstp, int * lenp, int * offsetp, int start, int end, int need) #else enum rx_answers rx_str_vmfn (closure, burstp, lenp, offsetp, start, end, need) void * closure; unsigned const char ** burstp; int * lenp; int * offsetp; int start; int end; int need; #endif { struct rx_str_closure * strc; strc = (struct rx_str_closure *)closure; if ( (need < 0) || (need > strc->len)) return rx_no; *burstp = strc->str; *lenp = strc->len; *offsetp = 0; return rx_yes; } #ifdef __STDC__ enum rx_answers rx_str_contextfn (void * closure, struct rexp_node * node, int start, int end, struct rx_registers * regs) #else enum rx_answers rx_str_contextfn (closure, node, start, end, regs) void * closure; struct rexp_node * node; int start; int end; struct rx_registers * regs; #endif { struct rx_str_closure * strc; strc = (struct rx_str_closure *)closure; switch (node->params.intval) { case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { int cmp; int regn; regn = node->params.intval - '0'; if ( (regs[regn].rm_so == -1) || ((end - start) != (regs[regn].rm_eo - regs[regn].rm_so))) return rx_no; else { if (strc->rules.case_indep) cmp = strncasecmp (strc->str + start, strc->str + regs[regn].rm_so, end - start); else cmp = strncmp (strc->str + start, strc->str + regs[regn].rm_so, end - start); return (!cmp ? rx_yes : rx_no); } } case '^': { return (( (start == end) && ( ((start == 0) && !strc->rules.not_bol) || ( (start > 0) && strc->rules.newline_anchor && (strc->str[start - 1] == '\n')))) ? rx_yes : rx_no); } case '$': { return (( (start == end) && ( ((start == strc->len) && !strc->rules.not_eol) || ( (start < strc->len) && strc->rules.newline_anchor && (strc->str[start] == '\n')))) ? rx_yes : rx_no); } case '<': case '>': case 'B': case 'b': default: return rx_bogus; } } rplay-3.3.2/rx/rxstr.h100644 153 62 2645 6552756455 13333 0ustar boynsstaff/* classes: h_files */ #ifndef RXSTRH #define RXSTRH /* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "rxspencer.h" #include "rxcontext.h" struct rx_str_closure { struct rx_context_rules rules; const unsigned char * str; int len; }; #ifdef __STDC__ extern enum rx_answers rx_str_vmfn (void * closure, unsigned const char ** burstp, int * lenp, int * offsetp, int start, int end, int need); extern enum rx_answers rx_str_contextfn (void * closure, struct rexp_node * node, int start, int end, struct rx_registers * regs); #else /* STDC */ extern enum rx_answers rx_str_vmfn (); extern enum rx_answers rx_str_contextfn (); #endif /* STDC */ #endif /* RXSTRH */ rplay-3.3.2/rx/rxsuper.c100644 153 62 111750 6552756454 13711 0ustar boynsstaff /* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "rxall.h" #include "rxsuper.h" /* The functions in the next several pages define the lazy-NFA-conversion used * by matchers. The input to this construction is an NFA such as * is built by compactify_nfa (rx.c). The output is the superNFA. */ /* Match engines can use arbitrary values for opcodes. So, the parse tree * is built using instructions names (enum rx_opcode), but the superstate * nfa is populated with mystery opcodes (void *). * * For convenience, here is an id table. The opcodes are == to their inxs * * The lables in re_search_2 would make good values for instructions. */ void * rx_id_instruction_table[rx_num_instructions] = { (void *) rx_backtrack_point, (void *) rx_do_side_effects, (void *) rx_cache_miss, (void *) rx_next_char, (void *) rx_backtrack, (void *) rx_error_inx }; /* The partially instantiated superstate graph has a transition * table at every node. There is one entry for every character. * This fills in the transition for a set. */ #ifdef __STDC__ static void install_transition (struct rx_superstate *super, struct rx_inx *answer, rx_Bitset trcset) #else static void install_transition (super, answer, trcset) struct rx_superstate *super; struct rx_inx *answer; rx_Bitset trcset; #endif { struct rx_inx * transitions = super->transitions; int chr; for (chr = 0; chr < 256; ) if (!*trcset) { ++trcset; chr += 32; } else { RX_subset sub = *trcset; RX_subset mask = 1; int bound = chr + 32; while (chr < bound) { if (sub & mask) transitions [chr] = *answer; ++chr; mask <<= 1; } ++trcset; } } #ifdef __STDC__ static int qlen (struct rx_superstate * q) #else static int qlen (q) struct rx_superstate * q; #endif { int count = 1; struct rx_superstate * it; if (!q) return 0; for (it = q->next_recyclable; it != q; it = it->next_recyclable) ++count; return count; } #ifdef __STDC__ static void check_cache (struct rx_cache * cache) #else static void check_cache (cache) struct rx_cache * cache; #endif { struct rx_cache * you_fucked_up = 0; int total = cache->superstates; int semi = cache->semifree_superstates; if (semi != qlen (cache->semifree_superstate)) check_cache (you_fucked_up); if ((total - semi) != qlen (cache->lru_superstate)) check_cache (you_fucked_up); } #ifdef __STDC__ char * rx_cache_malloc (struct rx_cache * cache, int size) #else char * rx_cache_malloc (cache, size) struct rx_cache * cache; int size; #endif { char * answer; answer = (char *)malloc (size); if (answer) cache->bytes_used += size; return answer; } #ifdef __STDC__ void rx_cache_free (struct rx_cache * cache, int size, char * mem) #else void rx_cache_free (cache, size, mem) struct rx_cache * cache; int size; char * mem; #endif { free (mem); cache->bytes_used -= size; } /* When a superstate is old and neglected, it can enter a * semi-free state. A semi-free state is slated to die. * Incoming transitions to a semi-free state are re-written * to cause an (interpreted) fault when they are taken. * The fault handler revives the semi-free state, patches * incoming transitions back to normal, and continues. * * The idea is basicly to free in two stages, aborting * between the two if the state turns out to be useful again. * When a free is aborted, the rescued superstate is placed * in the most-favored slot to maximize the time until it * is next semi-freed. * * Overall, this approximates truly freeing superstates in * lru order, but does not involve the cost of updating perfectly * accurate timestamps every time a superstate is touched. */ #ifdef __STDC__ static void semifree_superstate (struct rx_cache * cache) #else static void semifree_superstate (cache) struct rx_cache * cache; #endif { int disqualified = cache->semifree_superstates; if (disqualified == cache->superstates) return; while (cache->lru_superstate->locks) { cache->lru_superstate = cache->lru_superstate->next_recyclable; ++disqualified; if (disqualified == cache->superstates) return; } { struct rx_superstate * it = cache->lru_superstate; it->next_recyclable->prev_recyclable = it->prev_recyclable; it->prev_recyclable->next_recyclable = it->next_recyclable; cache->lru_superstate = (it == it->next_recyclable ? 0 : it->next_recyclable); if (!cache->semifree_superstate) { cache->semifree_superstate = it; it->next_recyclable = it; it->prev_recyclable = it; } else { it->prev_recyclable = cache->semifree_superstate->prev_recyclable; it->next_recyclable = cache->semifree_superstate; it->prev_recyclable->next_recyclable = it; it->next_recyclable->prev_recyclable = it; } { struct rx_distinct_future *df; it->is_semifree = 1; ++cache->semifree_superstates; df = it->transition_refs; if (df) { df->prev_same_dest->next_same_dest = 0; for (df = it->transition_refs; df; df = df->next_same_dest) { df->future_frame.inx = cache->instruction_table[rx_cache_miss]; df->future_frame.data = 0; df->future_frame.data_2 = (void *) df; /* If there are any NEXT-CHAR instruction frames that * refer to this state, we convert them to CACHE-MISS frames. */ if (!df->effects && (df->edge->options->next_same_super_edge[0] == df->edge->options)) install_transition (df->present, &df->future_frame, df->edge->cset); } df = it->transition_refs; df->prev_same_dest->next_same_dest = df; } } } } #ifdef __STDC__ static void refresh_semifree_superstate (struct rx_cache * cache, struct rx_superstate * super) #else static void refresh_semifree_superstate (cache, super) struct rx_cache * cache; struct rx_superstate * super; #endif { struct rx_distinct_future *df; if (super->transition_refs) { super->transition_refs->prev_same_dest->next_same_dest = 0; for (df = super->transition_refs; df; df = df->next_same_dest) { df->future_frame.inx = cache->instruction_table[rx_next_char]; df->future_frame.data = (void *) super->transitions; df->future_frame.data_2 = (void *)(super->contents->is_final); /* CACHE-MISS instruction frames that refer to this state, * must be converted to NEXT-CHAR frames. */ if (!df->effects && (df->edge->options->next_same_super_edge[0] == df->edge->options)) install_transition (df->present, &df->future_frame, df->edge->cset); } super->transition_refs->prev_same_dest->next_same_dest = super->transition_refs; } if (cache->semifree_superstate == super) cache->semifree_superstate = (super->prev_recyclable == super ? 0 : super->prev_recyclable); super->next_recyclable->prev_recyclable = super->prev_recyclable; super->prev_recyclable->next_recyclable = super->next_recyclable; if (!cache->lru_superstate) (cache->lru_superstate = super->next_recyclable = super->prev_recyclable = super); else { super->next_recyclable = cache->lru_superstate; super->prev_recyclable = cache->lru_superstate->prev_recyclable; super->next_recyclable->prev_recyclable = super; super->prev_recyclable->next_recyclable = super; } super->is_semifree = 0; --cache->semifree_superstates; } #ifdef __STDC__ void rx_refresh_this_superstate (struct rx_cache * cache, struct rx_superstate * superstate) #else void rx_refresh_this_superstate (cache, superstate) struct rx_cache * cache; struct rx_superstate * superstate; #endif { if (superstate->is_semifree) refresh_semifree_superstate (cache, superstate); else if (cache->lru_superstate == superstate) cache->lru_superstate = superstate->next_recyclable; else if (superstate != cache->lru_superstate->prev_recyclable) { superstate->next_recyclable->prev_recyclable = superstate->prev_recyclable; superstate->prev_recyclable->next_recyclable = superstate->next_recyclable; superstate->next_recyclable = cache->lru_superstate; superstate->prev_recyclable = cache->lru_superstate->prev_recyclable; superstate->next_recyclable->prev_recyclable = superstate; superstate->prev_recyclable->next_recyclable = superstate; } } #ifdef __STDC__ static void release_superset_low (struct rx_cache * cache, struct rx_superset *set) #else static void release_superset_low (cache, set) struct rx_cache * cache; struct rx_superset *set; #endif { if (!--set->refs) { if (set->starts_for) set->starts_for->start_set = 0; if (set->cdr) release_superset_low (cache, set->cdr); rx_hash_free (&set->hash_item, &cache->superset_hash_rules); rx_cache_free (cache, sizeof (struct rx_superset), (char *)set); } } #ifdef __STDC__ void rx_release_superset (struct rx *rx, struct rx_superset *set) #else void rx_release_superset (rx, set) struct rx *rx; struct rx_superset *set; #endif { release_superset_low (rx->cache, set); } /* This tries to add a new superstate to the superstate freelist. * It might, as a result, free some edge pieces or hash tables. * If nothing can be freed because too many locks are being held, fail. */ #ifdef __STDC__ static int rx_really_free_superstate (struct rx_cache * cache) #else static int rx_really_free_superstate (cache) struct rx_cache * cache; #endif { int locked_superstates = 0; struct rx_superstate * it; if (!cache->superstates) return 0; /* scale these */ while ((cache->hits + cache->misses) > cache->superstates) { cache->hits >>= 1; cache->misses >>= 1; } /* semifree superstates faster than they are freed * so popular states can be rescued. */ semifree_superstate (cache); semifree_superstate (cache); semifree_superstate (cache); #if 0 Redundant because semifree_superstate already makes this check; while (cache->semifree_superstate && cache->semifree_superstate->locks) { refresh_semifree_superstate (cache, cache->semifree_superstate); ++locked_superstates; if (locked_superstates == cache->superstates) return 0; } if (cache->semifree_superstate) insert the "it =" block which follows this "if 0" code; else { while (cache->lru_superstate->locks) { cache->lru_superstate = cache->lru_superstate->next_recyclable; ++locked_superstates; if (locked_superstates == cache->superstates) return 0; } it = cache->lru_superstate; it->next_recyclable->prev_recyclable = it->prev_recyclable; it->prev_recyclable->next_recyclable = it->next_recyclable; cache->lru_superstate = ((it == it->next_recyclable) ? 0 : it->next_recyclable); } #endif if (!cache->semifree_superstate) return 0; { it = cache->semifree_superstate; it->next_recyclable->prev_recyclable = it->prev_recyclable; it->prev_recyclable->next_recyclable = it->next_recyclable; cache->semifree_superstate = ((it == it->next_recyclable) ? 0 : it->next_recyclable); --cache->semifree_superstates; } if (it->transition_refs) { struct rx_distinct_future *df; for (df = it->transition_refs, df->prev_same_dest->next_same_dest = 0; df; df = df->next_same_dest) { df->future_frame.inx = cache->instruction_table[rx_cache_miss]; df->future_frame.data = 0; df->future_frame.data_2 = (void *) df; df->future = 0; } it->transition_refs->prev_same_dest->next_same_dest = it->transition_refs; } { struct rx_super_edge *tc = it->edges; while (tc) { struct rx_distinct_future * df; struct rx_super_edge *tct = tc->next; df = tc->options; df->next_same_super_edge[1]->next_same_super_edge[0] = 0; while (df) { struct rx_distinct_future *dft = df; df = df->next_same_super_edge[0]; if (dft->future && dft->future->transition_refs == dft) { dft->future->transition_refs = dft->next_same_dest; if (dft->future->transition_refs == dft) dft->future->transition_refs = 0; } dft->next_same_dest->prev_same_dest = dft->prev_same_dest; dft->prev_same_dest->next_same_dest = dft->next_same_dest; rx_cache_free (cache, sizeof (struct rx_distinct_future), (char *)dft); } rx_cache_free (cache, sizeof (struct rx_super_edge), (char *)tc); tc = tct; } } if (it->contents->superstate == it) it->contents->superstate = 0; release_superset_low (cache, it->contents); rx_cache_free (cache, (sizeof (struct rx_superstate) + cache->local_cset_size * sizeof (struct rx_inx)), (char *)it); --cache->superstates; return 1; } #ifdef __STDC__ static char * rx_cache_malloc_or_get (struct rx_cache * cache, int size) #else static char * rx_cache_malloc_or_get (cache, size) struct rx_cache * cache; int size; #endif { while ( (cache->bytes_used + size > cache->bytes_allowed) && rx_really_free_superstate (cache)) ; return rx_cache_malloc (cache, size); } #ifdef __STDC__ static int supersetcmp (void * va, void * vb) #else static int supersetcmp (va, vb) void * va; void * vb; #endif { struct rx_superset * a = (struct rx_superset *)va; struct rx_superset * b = (struct rx_superset *)vb; return ( (a == b) || (a && b && (a->id == b->id) && (a->car == b->car) && (a->cdr == b->cdr))); } #define rx_abs(A) (((A) > 0) ? (A) : -(A)) #ifdef __STDC__ static struct rx_hash_item * superset_allocator (struct rx_hash_rules * rules, void * val) #else static struct rx_hash_item * superset_allocator (rules, val) struct rx_hash_rules * rules; void * val; #endif { struct rx_cache * cache; struct rx_superset * template; struct rx_superset * newset; cache = ((struct rx_cache *) ((char *)rules - (unsigned long)(&((struct rx_cache *)0)->superset_hash_rules))); template = (struct rx_superset *)val; newset = ((struct rx_superset *) rx_cache_malloc (cache, sizeof (*template))); if (!newset) return 0; { int cdrfinal; int cdredges; cdrfinal = (template->cdr ? template->cdr->is_final : 0); cdredges = (template->cdr ? template->cdr->has_cset_edges : 0); newset->is_final = (rx_abs (template->car->is_final) > rx_abs(cdrfinal) ? template->car->is_final : template->cdr->is_final); newset->has_cset_edges = (template->car->has_cset_edges || cdredges); } newset->refs = 0; newset->id = template->id; newset->car = template->car; newset->cdr = template->cdr; rx_protect_superset (rx, template->cdr); newset->superstate = 0; newset->starts_for = 0; newset->hash_item.data = (void *)newset; newset->hash_item.binding = 0; return &newset->hash_item; } #ifdef __STDC__ static struct rx_hash * super_hash_allocator (struct rx_hash_rules * rules) #else static struct rx_hash * super_hash_allocator (rules) struct rx_hash_rules * rules; #endif { struct rx_cache * cache; cache = ((struct rx_cache *) ((char *)rules - (unsigned long)(&((struct rx_cache *)0)->superset_hash_rules))); return ((struct rx_hash *) rx_cache_malloc (cache, sizeof (struct rx_hash))); } #ifdef __STDC__ static void super_hash_liberator (struct rx_hash * hash, struct rx_hash_rules * rules) #else static void super_hash_liberator (hash, rules) struct rx_hash * hash; struct rx_hash_rules * rules; #endif { struct rx_cache * cache = ((struct rx_cache *) (char *)rules - (long)(&((struct rx_cache *)0)->superset_hash_rules)); rx_cache_free (cache, sizeof (struct rx_hash), (char *)hash); } #ifdef __STDC__ static void superset_hash_item_liberator (struct rx_hash_item * it, struct rx_hash_rules * rules) #else static void superset_hash_item_liberator (it, rules) struct rx_hash_item * it; struct rx_hash_rules * rules; #endif { } int rx_cache_bound = 3; static int rx_default_cache_got = 0; static struct rx_cache default_cache = { { supersetcmp, super_hash_allocator, super_hash_liberator, superset_allocator, superset_hash_item_liberator, }, 0, 0, 0, 0, 0, 0, 0, RX_DEFAULT_DFA_CACHE_SIZE, 0, 256, rx_id_instruction_table, { 0, 0, 0, 0, 0 } }; struct rx_cache * rx_default_cache = &default_cache; /* This adds an element to a superstate set. These sets are lists, such * that lists with == elements are ==. The empty set is returned by * superset_cons (rx, 0, 0) and is NOT equivelent to * (struct rx_superset)0. */ #ifdef __STDC__ struct rx_superset * rx_superset_cons (struct rx * rx, struct rx_nfa_state *car, struct rx_superset *cdr) #else struct rx_superset * rx_superset_cons (rx, car, cdr) struct rx * rx; struct rx_nfa_state *car; struct rx_superset *cdr; #endif { struct rx_cache * cache = rx->cache; if (!car && !cdr) { if (!cache->empty_superset) { cache->empty_superset = ((struct rx_superset *) rx_cache_malloc (cache, sizeof (struct rx_superset))); if (!cache->empty_superset) return 0; rx_bzero ((char *)cache->empty_superset, sizeof (struct rx_superset)); cache->empty_superset->refs = 1000; } return cache->empty_superset; } { struct rx_superset template; struct rx_hash_item * hit; template.car = car; template.cdr = cdr; template.id = rx->rx_id; rx_protect_superset (rx, template.cdr); hit = rx_hash_store (&cache->superset_table, (unsigned long)car ^ car->id ^ (unsigned long)cdr, (void *)&template, &cache->superset_hash_rules); rx_protect_superset (rx, template.cdr); return (hit ? (struct rx_superset *)hit->data : 0); } } /* This computes a union of two NFA state sets. The sets do not have the * same representation though. One is a RX_SUPERSET structure (part * of the superstate NFA) and the other is an NFA_STATE_SET (part of the NFA). */ #ifdef __STDC__ struct rx_superset * rx_superstate_eclosure_union (struct rx * rx, struct rx_superset *set, struct rx_nfa_state_set *ecl) #else struct rx_superset * rx_superstate_eclosure_union (rx, set, ecl) struct rx * rx; struct rx_superset *set; struct rx_nfa_state_set *ecl; #endif { if (!ecl) return set; if (!set->car) return rx_superset_cons (rx, ecl->car, rx_superstate_eclosure_union (rx, set, ecl->cdr)); if (set->car == ecl->car) return rx_superstate_eclosure_union (rx, set, ecl->cdr); { struct rx_superset * tail; struct rx_nfa_state * first; if (set->car->id < ecl->car->id) { tail = rx_superstate_eclosure_union (rx, set->cdr, ecl); first = set->car; } else { tail = rx_superstate_eclosure_union (rx, set, ecl->cdr); first = ecl->car; } if (!tail) return 0; else { struct rx_superset * answer; answer = rx_superset_cons (rx, first, tail); if (!answer) { rx_protect_superset (rx, tail); rx_release_superset (rx, tail); return 0; } else return answer; } } } /* * This makes sure that a list of rx_distinct_futures contains * a future for each possible set of side effects in the eclosure * of a given state. This is some of the work of filling in a * superstate transition. */ #ifdef __STDC__ static struct rx_distinct_future * include_futures (struct rx *rx, struct rx_distinct_future *df, struct rx_nfa_state *state, struct rx_superstate *superstate) #else static struct rx_distinct_future * include_futures (rx, df, state, superstate) struct rx *rx; struct rx_distinct_future *df; struct rx_nfa_state *state; struct rx_superstate *superstate; #endif { struct rx_possible_future *future; struct rx_cache * cache = rx->cache; for (future = rx_state_possible_futures (rx, state); future; future = future->next) { struct rx_distinct_future *dfp; struct rx_distinct_future *insert_before = 0; if (df) df->next_same_super_edge[1]->next_same_super_edge[0] = 0; for (dfp = df; dfp; dfp = dfp->next_same_super_edge[0]) if (dfp->effects == future->effects) break; else { int order = rx->se_list_cmp (rx, dfp->effects, future->effects); if (order > 0) { insert_before = dfp; dfp = 0; break; } } if (df) df->next_same_super_edge[1]->next_same_super_edge[0] = df; if (!dfp) { dfp = ((struct rx_distinct_future *) rx_cache_malloc (cache, sizeof (struct rx_distinct_future))); if (!dfp) return 0; if (!df) { df = insert_before = dfp; df->next_same_super_edge[0] = df->next_same_super_edge[1] = df; } else if (!insert_before) insert_before = df; else if (insert_before == df) df = dfp; dfp->next_same_super_edge[0] = insert_before; dfp->next_same_super_edge[1] = insert_before->next_same_super_edge[1]; dfp->next_same_super_edge[1]->next_same_super_edge[0] = dfp; dfp->next_same_super_edge[0]->next_same_super_edge[1] = dfp; dfp->next_same_dest = dfp->prev_same_dest = dfp; dfp->future = 0; dfp->present = superstate; dfp->future_frame.inx = rx->instruction_table[rx_cache_miss]; dfp->future_frame.data = 0; dfp->future_frame.data_2 = (void *) dfp; dfp->side_effects_frame.inx = rx->instruction_table[rx_do_side_effects]; dfp->side_effects_frame.data = 0; dfp->side_effects_frame.data_2 = (void *) dfp; dfp->effects = future->effects; } } return df; } /* This constructs a new superstate from its state set. The only * complexity here is memory management. */ #ifdef __STDC__ struct rx_superstate * rx_superstate (struct rx *rx, struct rx_superset *set) #else struct rx_superstate * rx_superstate (rx, set) struct rx *rx; struct rx_superset *set; #endif { struct rx_cache * cache = rx->cache; struct rx_superstate * superstate = 0; /* Does the superstate already exist in the cache? */ if (set->superstate) { if (set->superstate->rx_id != rx->rx_id) { /* Aha. It is in the cache, but belongs to a superstate * that refers to an NFA that no longer exists. * (We know it no longer exists because it was evidently * stored in the same region of memory as the current nfa * yet it has a different id.) */ superstate = set->superstate; if (!superstate->is_semifree) { if (cache->lru_superstate == superstate) { cache->lru_superstate = superstate->next_recyclable; if (cache->lru_superstate == superstate) cache->lru_superstate = 0; } { superstate->next_recyclable->prev_recyclable = superstate->prev_recyclable; superstate->prev_recyclable->next_recyclable = superstate->next_recyclable; if (!cache->semifree_superstate) { (cache->semifree_superstate = superstate->next_recyclable = superstate->prev_recyclable = superstate); } else { superstate->next_recyclable = cache->semifree_superstate; superstate->prev_recyclable = cache->semifree_superstate->prev_recyclable; superstate->next_recyclable->prev_recyclable = superstate; superstate->prev_recyclable->next_recyclable = superstate; cache->semifree_superstate = superstate; } ++cache->semifree_superstates; } } set->superstate = 0; goto handle_cache_miss; } ++cache->hits; superstate = set->superstate; rx_refresh_this_superstate (cache, superstate); return superstate; } handle_cache_miss: /* This point reached only for cache misses. */ ++cache->misses; #if RX_DEBUG if (rx_debug_trace > 1) { struct rx_superset * setp = set; fprintf (stderr, "Building a superstet %d(%d): ", rx->rx_id, set); while (setp) { fprintf (stderr, "%d ", setp->id); setp = setp->cdr; } fprintf (stderr, "(%d)\n", set); } #endif { int superstate_size; superstate_size = ( sizeof (*superstate) + ( sizeof (struct rx_inx) * rx->local_cset_size)); superstate = ((struct rx_superstate *) rx_cache_malloc_or_get (cache, superstate_size)); ++cache->superstates; } if (!superstate) return 0; if (!cache->lru_superstate) (cache->lru_superstate = superstate->next_recyclable = superstate->prev_recyclable = superstate); else { superstate->next_recyclable = cache->lru_superstate; superstate->prev_recyclable = cache->lru_superstate->prev_recyclable; ( superstate->prev_recyclable->next_recyclable = superstate->next_recyclable->prev_recyclable = superstate); } superstate->rx_id = rx->rx_id; superstate->transition_refs = 0; superstate->locks = 0; superstate->is_semifree = 0; set->superstate = superstate; superstate->contents = set; rx_protect_superset (rx, set); superstate->edges = 0; { int x; /* None of the transitions from this superstate are known yet. */ for (x = 0; x < rx->local_cset_size; ++x) { struct rx_inx * ifr = &superstate->transitions[x]; ifr->inx = rx->instruction_table [rx_cache_miss]; ifr->data = ifr->data_2 = 0; } } return superstate; } /* This computes the destination set of one edge of the superstate NFA. * Note that a RX_DISTINCT_FUTURE is a superstate edge. * Returns 0 on an allocation failure. */ #ifdef __STDC__ static int solve_destination (struct rx *rx, struct rx_distinct_future *df) #else static int solve_destination (rx, df) struct rx *rx; struct rx_distinct_future *df; #endif { struct rx_super_edge *tc = df->edge; struct rx_superset *nfa_state; struct rx_superset *nil_set = rx_superset_cons (rx, 0, 0); struct rx_superset *solution = nil_set; struct rx_superstate *dest; rx_protect_superset (rx, solution); /* Iterate over all NFA states in the state set of this superstate. */ for (nfa_state = df->present->contents; nfa_state->car; nfa_state = nfa_state->cdr) { struct rx_nfa_edge *e; /* Iterate over all edges of each NFA state. */ for (e = nfa_state->car->edges; e; e = e->next) /* If we find an edge that is labeled with * the characters we are solving for..... */ if ((e->type == ne_cset) && rx_bitset_is_subset (rx->local_cset_size, tc->cset, e->params.cset)) { struct rx_nfa_state *n = e->dest; struct rx_possible_future *pf; /* ....search the partial epsilon closures of the destination * of that edge for a path that involves the same set of * side effects we are solving for. * If we find such a RX_POSSIBLE_FUTURE, we add members to the * stateset we are computing. */ for (pf = rx_state_possible_futures (rx, n); pf; pf = pf->next) if (pf->effects == df->effects) { struct rx_superset * old_sol; old_sol = solution; solution = rx_superstate_eclosure_union (rx, solution, pf->destset); if (!solution) return 0; rx_protect_superset (rx, solution); rx_release_superset (rx, old_sol); } } } /* It is possible that the RX_DISTINCT_FUTURE we are working on has * the empty set of NFA states as its definition. In that case, this * is a failure point. */ if (solution == nil_set) { df->future_frame.inx = (void *) rx_backtrack; df->future_frame.data = 0; df->future_frame.data_2 = 0; return 1; } dest = rx_superstate (rx, solution); rx_release_superset (rx, solution); if (!dest) return 0; { struct rx_distinct_future *dft; dft = df; df->prev_same_dest->next_same_dest = 0; while (dft) { dft->future = dest; dft->future_frame.inx = rx->instruction_table[rx_next_char]; dft->future_frame.data = (void *) dest->transitions; dft->future_frame.data_2 = (void *) dest->contents->is_final; dft = dft->next_same_dest; } df->prev_same_dest->next_same_dest = df; } if (!dest->transition_refs) dest->transition_refs = df; else { struct rx_distinct_future *dft; dft = dest->transition_refs->next_same_dest; dest->transition_refs->next_same_dest = df->next_same_dest; df->next_same_dest->prev_same_dest = dest->transition_refs; df->next_same_dest = dft; dft->prev_same_dest = df; } return 1; } /* This takes a superstate and a character, and computes some edges * from the superstate NFA. In particular, this computes all edges * that lead from SUPERSTATE given CHR. This function also * computes the set of characters that share this edge set. * This returns 0 on allocation error. * The character set and list of edges are returned through * the paramters CSETOUT and DFOUT. */ #ifdef __STDC__ static int compute_super_edge (struct rx *rx, struct rx_distinct_future **dfout, rx_Bitset csetout, struct rx_superstate *superstate, unsigned char chr) #else static int compute_super_edge (rx, dfout, csetout, superstate, chr) struct rx *rx; struct rx_distinct_future **dfout; rx_Bitset csetout; struct rx_superstate *superstate; unsigned char chr; #endif { struct rx_superset *stateset = superstate->contents; /* To compute the set of characters that share edges with CHR, * we start with the full character set, and subtract. */ rx_bitset_universe (rx->local_cset_size, csetout); *dfout = 0; /* Iterate over the NFA states in the superstate state-set. */ while (stateset->car) { struct rx_nfa_edge *e; for (e = stateset->car->edges; e; e = e->next) if (e->type == ne_cset) { if (!RX_bitset_member (e->params.cset, chr)) /* An edge that doesn't apply at least tells us some characters * that don't share the same edge set as CHR. */ rx_bitset_difference (rx->local_cset_size, csetout, e->params.cset); else { /* If we find an NFA edge that applies, we make sure there * are corresponding edges in the superstate NFA. */ { struct rx_distinct_future * saved; saved = *dfout; *dfout = include_futures (rx, *dfout, e->dest, superstate); if (!*dfout) { struct rx_distinct_future * df; df = saved; if (df) df->next_same_super_edge[1]->next_same_super_edge[0] = 0; while (df) { struct rx_distinct_future *dft; dft = df; df = df->next_same_super_edge[0]; if (dft->future && dft->future->transition_refs == dft) { dft->future->transition_refs = dft->next_same_dest; if (dft->future->transition_refs == dft) dft->future->transition_refs = 0; } dft->next_same_dest->prev_same_dest = dft->prev_same_dest; dft->prev_same_dest->next_same_dest = dft->next_same_dest; rx_cache_free (rx->cache, sizeof (*dft), (char *)dft); } return 0; } } /* We also trim the character set a bit. */ rx_bitset_intersection (rx->local_cset_size, csetout, e->params.cset); } } stateset = stateset->cdr; } return 1; } /* This is a constructor for RX_SUPER_EDGE structures. These are * wrappers for lists of superstate NFA edges that share character sets labels. * If a transition class contains more than one rx_distinct_future (superstate * edge), then it represents a non-determinism in the superstate NFA. */ #ifdef __STDC__ static struct rx_super_edge * rx_super_edge (struct rx *rx, struct rx_superstate *super, rx_Bitset cset, struct rx_distinct_future *df) #else static struct rx_super_edge * rx_super_edge (rx, super, cset, df) struct rx *rx; struct rx_superstate *super; rx_Bitset cset; struct rx_distinct_future *df; #endif { struct rx_super_edge *tc; int tc_size; tc_size = ( sizeof (struct rx_super_edge) + rx_sizeof_bitset (rx->local_cset_size)); tc = ((struct rx_super_edge *) rx_cache_malloc (rx->cache, tc_size)); if (!tc) return 0; tc->next = super->edges; super->edges = tc; tc->rx_backtrack_frame.inx = rx->instruction_table[rx_backtrack_point]; tc->rx_backtrack_frame.data = 0; tc->rx_backtrack_frame.data_2 = (void *) tc; tc->options = df; tc->cset = (rx_Bitset) ((char *) tc + sizeof (*tc)); rx_bitset_assign (rx->local_cset_size, tc->cset, cset); if (df) { struct rx_distinct_future * dfp = df; df->next_same_super_edge[1]->next_same_super_edge[0] = 0; while (dfp) { dfp->edge = tc; dfp = dfp->next_same_super_edge[0]; } df->next_same_super_edge[1]->next_same_super_edge[0] = df; } return tc; } /* There are three kinds of cache miss. The first occurs when a * transition is taken that has never been computed during the * lifetime of the source superstate. That cache miss is handled by * calling COMPUTE_SUPER_EDGE. The second kind of cache miss * occurs when the destination superstate of a transition doesn't * exist. SOLVE_DESTINATION is used to construct the destination superstate. * Finally, the third kind of cache miss occurs when the destination * superstate of a transition is in a `semi-free state'. That case is * handled by UNFREE_SUPERSTATE. * * The function of HANDLE_CACHE_MISS is to figure out which of these * cases applies. */ #ifdef __STDC__ static void install_partial_transition (struct rx_superstate *super, struct rx_inx *answer, RX_subset set, int offset) #else static void install_partial_transition (super, answer, set, offset) struct rx_superstate *super; struct rx_inx *answer; RX_subset set; int offset; #endif { int start = offset; int end = start + 32; RX_subset pos = 1; struct rx_inx * transitions = super->transitions; while (start < end) { if (set & pos) transitions[start] = *answer; pos <<= 1; ++start; } } #ifdef __STDC__ struct rx_inx * rx_handle_cache_miss (struct rx *rx, struct rx_superstate *super, unsigned char chr, void *data) #else struct rx_inx * rx_handle_cache_miss (rx, super, chr, data) struct rx *rx; struct rx_superstate *super; unsigned char chr; void *data; #endif { int offset = chr / RX_subset_bits; struct rx_distinct_future *df = data; if (!df) /* must be the shared_cache_miss_frame */ { /* Perhaps this is just a transition waiting to be filled. */ struct rx_super_edge *tc; RX_subset mask = rx_subset_singletons [chr % RX_subset_bits]; for (tc = super->edges; tc; tc = tc->next) if (tc->cset[offset] & mask) { struct rx_inx * answer; df = tc->options; answer = ((tc->options->next_same_super_edge[0] != tc->options) ? &tc->rx_backtrack_frame : (df->effects ? &df->side_effects_frame : &df->future_frame)); install_partial_transition (super, answer, tc->cset [offset], offset * 32); return answer; } /* Otherwise, it's a flushed or newly encountered edge. */ { char cset_space[1024]; /* this limit is far from unreasonable */ rx_Bitset trcset; struct rx_inx *answer; if (rx_sizeof_bitset (rx->local_cset_size) > sizeof (cset_space)) return 0; /* If the arbitrary limit is hit, always fail */ /* cleanly. */ trcset = (rx_Bitset)cset_space; rx_lock_superstate (rx, super); if (!compute_super_edge (rx, &df, trcset, super, chr)) { rx_unlock_superstate (rx, super); return 0; } if (!df) /* We just computed the fail transition. */ { static struct rx_inx shared_fail_frame = { 0, 0, (void *)rx_backtrack, 0 }; answer = &shared_fail_frame; } else { tc = rx_super_edge (rx, super, trcset, df); if (!tc) { rx_unlock_superstate (rx, super); return 0; } answer = ((tc->options->next_same_super_edge[0] != tc->options) ? &tc->rx_backtrack_frame : (df->effects ? &df->side_effects_frame : &df->future_frame)); } install_partial_transition (super, answer, trcset[offset], offset * 32); rx_unlock_superstate (rx, super); return answer; } } else if (df->future) /* A cache miss on an edge with a future? Must be * a semi-free destination. */ { if (df->future->is_semifree) refresh_semifree_superstate (rx->cache, df->future); return &df->future_frame; } else /* no future superstate on an existing edge */ { rx_lock_superstate (rx, super); if (!solve_destination (rx, df)) { rx_unlock_superstate (rx, super); return 0; } if (!df->effects && (df->edge->options->next_same_super_edge[0] == df->edge->options)) install_partial_transition (super, &df->future_frame, df->edge->cset[offset], offset * 32); rx_unlock_superstate (rx, super); return &df->future_frame; } } rplay-3.3.2/rx/rxsuper.h100644 153 62 37726 6552756455 13711 0ustar boynsstaff/* classes: h_files */ #ifndef RXSUPERH #define RXSUPERH /* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* lord Sun May 7 12:40:17 1995 */ #include "rxnfa.h" /* This begins the description of the superstate NFA. * * The superstate NFA corresponds to the NFA in these ways: * * Superstate states correspond to sets of NFA states (nfa_states(SUPER)), * * Superstate edges correspond to NFA paths. * * The superstate has no epsilon transitions; * every edge has a character label, and a (possibly empty) side * effect label. The side effect label corresponds to a list of * side effects that occur in the NFA. These parts are referred * to as: superedge_character(EDGE) and superedge_sides(EDGE). * * For a superstate edge EDGE starting in some superstate SUPER, * the following is true (in pseudo-notation :-): * * exists DEST in nfa_states s.t. * exists nfaEDGE in nfa_edges s.t. * origin (nfaEDGE) == DEST * && origin (nfaEDGE) is a member of nfa_states(SUPER) * && exists PF in possible_futures(dest(nfaEDGE)) s.t. * sides_of_possible_future (PF) == superedge_sides (EDGE) * * also: * * let SUPER2 := superedge_destination(EDGE) * nfa_states(SUPER2) * == union of all nfa state sets S s.t. * exists PF in possible_futures(dest(nfaEDGE)) s.t. * sides_of_possible_future (PF) == superedge_sides (EDGE) * && S == dests_of_possible_future (PF) } * * Or in english, every superstate is a set of nfa states. A given * character and a superstate implies many transitions in the NFA -- * those that begin with an edge labeled with that character from a * state in the set corresponding to the superstate. * * The destinations of those transitions each have a set of possible * futures. A possible future is a list of side effects and a set of * destination NFA states. Two sets of possible futures can be * `merged' by combining all pairs of possible futures that have the * same side effects. A pair is combined by creating a new future * with the same side effect but the union of the two destination sets. * In this way, all the possible futures suggested by a superstate * and a character can be merged into a set of possible futures where * no two elements of the set have the same set of side effects. * * The destination of a possible future, being a set of NFA states, * corresponds to a supernfa state. So, the merged set of possible * futures we just created can serve as a set of edges in the * supernfa. * * The representation of the superstate nfa and the nfa is critical. * The nfa has to be compact, but has to facilitate the rapid * computation of missing superstates. The superstate nfa has to * be fast to interpret, lazilly constructed, and bounded in space. * * To facilitate interpretation, the superstate data structures are * peppered with `instruction frames'. There is an instruction set * defined below which matchers using the supernfa must be able to * interpret. * * We'd like to make it possible but not mandatory to use code * addresses to represent instructions (c.f. gcc's computed goto). * Therefore, we define an enumerated type of opcodes, and when * writing one of these instructions into a data structure, use * the opcode as an index into a table of instruction values. * * Below are the opcodes that occur in the superstate nfa. * * The descriptions of the opcodes refer to data structures that are * described further below. */ enum rx_opcode { /* * BACKTRACK_POINT is invoked when a character transition in * a superstate leads to more than one edge. In that case, * the edges have to be explored independently using a backtracking * strategy. * * A BACKTRACK_POINT instruction is stored in a superstate's * transition table for some character when it is known that that * character crosses more than one edge. On encountering this * instruction, the matcher saves enough state to backtrack to this * point later in the match. */ rx_backtrack_point = 0, /* data is (struct transition_class *) */ /* * RX_DO_SIDE_EFFECTS evaluates the side effects of an epsilon path. * There is one occurence of this instruction per rx_distinct_future. * This instruction is skipped if a rx_distinct_future has no side effects. */ rx_do_side_effects = rx_backtrack_point + 1, /* data is (struct rx_distinct_future *) */ /* * RX_CACHE_MISS instructions are stored in rx_distinct_futures whose * destination superstate has been reclaimed (or was never built). * It recomputes the destination superstate. * RX_CACHE_MISS is also stored in a superstate transition table before * any of its edges have been built. */ rx_cache_miss = rx_do_side_effects + 1, /* data is (struct rx_distinct_future *) */ /* * RX_NEXT_CHAR is called to consume the next character and take the * corresponding transition. This is the only instruction that uses * the DATA field of the instruction frame instead of DATA_2. * The comments about rx_inx explain this further. */ rx_next_char = rx_cache_miss + 1, /* data is (struct superstate *) */ /* RX_BACKTRACK indicates that a transition fails. Don't * confuse this with rx_backtrack_point. */ rx_backtrack = rx_next_char + 1, /* no data */ /* * RX_ERROR_INX is stored only in places that should never be executed. */ rx_error_inx = rx_backtrack + 1, /* Not supposed to occur. */ rx_num_instructions = rx_error_inx + 1 }; /* The heart of the matcher is a `word-code-interpreter' * (like a byte-code interpreter, except that instructions * are a full word wide). * * Instructions are not stored in a vector of code, instead, * they are scattered throughout the data structures built * by the regexp compiler and the matcher. One word-code instruction, * together with the arguments to that instruction, constitute * an instruction frame (struct rx_inx). * * This structure type is padded by hand to a power of 2 because * in one of the dominant cases, we dispatch by indexing a table * of instruction frames. If that indexing can be accomplished * by just a shift of the index, we're happy. * * Instructions take at most one argument, but there are two * slots in an instruction frame that might hold that argument. * These are called data and data_2. The data slot is only * used for one instruction (RX_NEXT_CHAR). For all other * instructions, data should be set to 0. * * RX_NEXT_CHAR is the most important instruction by far. * By reserving the data field for its exclusive use, * instruction dispatch is sped up in that case. There is * no need to fetch both the instruction and the data, * only the data is needed. In other words, a `cycle' begins * by fetching the field data. If that is non-0, then it must * be the destination state of a next_char transition, so * make that value the current state, advance the match position * by one character, and start a new cycle. On the other hand, * if data is 0, fetch the instruction and do a more complicated * dispatch on that. */ struct rx_inx { void * data; void * data_2; void * inx; void * fnord; }; #ifndef RX_TAIL_ARRAY #define RX_TAIL_ARRAY 1 #endif /* A superstate corresponds to a set of nfa states. Those sets are * represented by STRUCT RX_SUPERSET. The constructors * guarantee that only one (shared) structure is created for a given set. */ struct rx_superset { int refs; /* This is a reference counted structure. */ /* We keep these sets in a cache because (in an unpredictable way), * the same set is often created again and again. * * When an NFA is destroyed, some of the supersets for that NFA * may still exist. This can lead to false cache hits -- an apparent cache * hit on a superset that properly belongs to an already free NFA. * * When a cache hit appears to occur, we will have in hand the * nfa for which it may have happened. Every nfa is given * its own sequence number. The cache is validated * by comparing the nfa sequence number to this field: */ int id; struct rx_nfa_state * car; /* May or may not be a valid addr. */ struct rx_superset * cdr; /* If the corresponding superstate exists: */ struct rx_superstate * superstate; /* That is_final field of the constiuent nfa states which has the greatest magnitude. */ int is_final; /* The OR of the corresponding fields of the constiuent nfa states. */ int has_cset_edges; /* There is another bookkeeping problem. It is expensive to * compute the starting nfa state set for an nfa. So, once computed, * it is cached in the `struct rx'. * * But, the state set can be flushed from the superstate cache. * When that happens, the cached value in the `struct rx' has * to be flushed. */ struct rx * starts_for; /* This is used to link into a hash bucket so these objects can * be `hash-consed'. */ struct rx_hash_item hash_item; }; #define rx_protect_superset(RX,CON) (++(CON)->refs) /* The terminology may be confusing (rename this structure?). * Every character occurs in at most one rx_super_edge per super-state. * But, that structure might have more than one option, indicating a point * of non-determinism. * * In other words, this structure holds a list of superstate edges * sharing a common starting state and character label. The edges * are in the field OPTIONS. All superstate edges sharing the same * starting state and character are in this list. */ struct rx_super_edge { struct rx_super_edge *next; struct rx_inx rx_backtrack_frame; int cset_size; rx_Bitset cset; struct rx_distinct_future *options; }; /* A superstate is a set of nfa states (RX_SUPERSET) along * with a transition table. Superstates are built on demand and reclaimed * without warning. To protect a superstate from this ghastly fate, * use LOCK_SUPERSTATE. */ struct rx_superstate { int rx_id; /* c.f. the id field of rx_superset */ int locks; /* protection from reclamation */ /* Within a superstate cache, all the superstates are kept in a big * queue. The tail of the queue is the state most likely to be * reclaimed. The *recyclable fields hold the queue position of * this state. */ struct rx_superstate * next_recyclable; struct rx_superstate * prev_recyclable; /* The supernfa edges that exist in the cache and that have * this state as their destination are kept in this list: */ struct rx_distinct_future * transition_refs; /* The list of nfa states corresponding to this superstate: */ struct rx_superset * contents; /* The list of edges in the cache beginning from this state. */ struct rx_super_edge * edges; /* A tail of the recyclable queue is marked as semifree. A semifree * state has no incoming next_char transitions -- any transition * into a semifree state causes a complex dispatch with the side * effect of rescuing the state from its semifree state into a * fully free state at the head of the queue. * * An alternative to this might be to make next_char more expensive, * and to move a state to the head of the recyclable queue whenever * it is entered. That way, popular states would never be recycled. * * But unilaterally making next_char more expensive actually loses. * So, incoming transitions are only made expensive for states near * the tail of the recyclable queue. The more cache contention * there is, the more frequently a state will have to prove itself * and be moved back to the front of the queue. If there is less * contention, then popular states just aggregate in the front of * the queue and stay there. */ int is_semifree; /* This keeps track of the size of the transition table for this * state. There is a half-hearted attempt to support variable sized * superstates. */ int trans_size; /* Indexed by characters... */ struct rx_inx transitions[RX_TAIL_ARRAY]; }; /* A list of distinct futures define the edges that leave from a * given superstate on a given character. c.f. rx_super_edge. */ struct rx_distinct_future { struct rx_distinct_future * next_same_super_edge[2]; struct rx_distinct_future * next_same_dest; struct rx_distinct_future * prev_same_dest; struct rx_superstate * present; /* source state */ struct rx_superstate * future; /* destination state */ struct rx_super_edge * edge; /* The future_frame holds the instruction that should be executed * after all the side effects are done, when it is time to complete * the transition to the next state. * * Normally this is a next_char instruction, but it may be a * cache_miss instruction as well, depending on whether or not * the superstate is in the cache and semifree. * * If this is the only future for a given superstate/char, and * if there are no side effects to be performed, this frame is * not used (directly) at all. Instead, its contents are copied * into the transition table of the starting state of this dist. future * (a sort of goto elimination). */ struct rx_inx future_frame; struct rx_inx side_effects_frame; struct rx_se_list * effects; }; #define rx_lock_superstate(R,S) ((S)->locks++) #define rx_unlock_superstate(R,S) (--(S)->locks) struct rx_cache; #ifdef __STDC__ typedef void (*rx_morecore_fn)(struct rx_cache *); #else typedef void (*rx_morecore_fn)(); #endif struct rx_cache { struct rx_hash_rules superset_hash_rules; struct rx_superstate * lru_superstate; struct rx_superstate * semifree_superstate; struct rx_superset * empty_superset; int superstates; int semifree_superstates; int hits; int misses; int bytes_allowed; int bytes_used; int local_cset_size; void ** instruction_table; struct rx_hash superset_table; }; #ifndef RX_DEFAULT_DFA_CACHE_SIZE /* This is an upper bound on the number of bytes that may (normally) * be allocated for DFA states. If this threshold would be exceeded, * Rx tries to flush some DFA states from the cache. * * This value is used whenever the rx_default_cache is used (for example, * with the Posix entry points). */ #define RX_DEFAULT_DFA_CACHE_SIZE (1 << 19) #endif extern struct rx_cache * rx_default_cache; #ifdef __STDC__ extern char * rx_cache_malloc (struct rx_cache * cache, int size); extern void rx_cache_free (struct rx_cache * cache, int size, char * mem); extern void rx_release_superset (struct rx *rx, struct rx_superset *set); extern struct rx_superset * rx_superset_cons (struct rx * rx, struct rx_nfa_state *car, struct rx_superset *cdr); extern struct rx_superset * rx_superstate_eclosure_union (struct rx * rx, struct rx_superset *set, struct rx_nfa_state_set *ecl) ; extern struct rx_superstate * rx_superstate (struct rx *rx, struct rx_superset *set); extern struct rx_inx * rx_handle_cache_miss (struct rx *rx, struct rx_superstate *super, unsigned char chr, void *data) ; #else /* STDC */ extern char * rx_cache_malloc (); extern void rx_cache_free (); extern void rx_release_superset (); extern struct rx_superset * rx_superset_cons (); extern struct rx_superset * rx_superstate_eclosure_union (); extern struct rx_superstate * rx_superstate (); extern struct rx_inx * rx_handle_cache_miss (); #endif /* STDC */ #endif /* RXSUPERH */ rplay-3.3.2/rx/rxunfa.c100644 153 62 12714 6552756454 13464 0ustar boynsstaff/* classes: src_files */ /* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "rxall.h" #include "rx.h" #include "rxunfa.h" #include "rxnfa.h" #ifdef __STDC__ static int unfa_equal (void * va, void * vb) #else static int unfa_equal (va, vb) void * va; void * vb; #endif { return rx_rexp_equal ((struct rexp_node *)va, (struct rexp_node *)vb); } struct rx_hash_rules unfa_rules = { unfa_equal, 0, 0, 0, 0 }; #ifdef __STDC__ static struct rx_cached_rexp * canonical_unfa (struct rx_hash * table, struct rexp_node * rexp, int cset_size) #else static struct rx_cached_rexp * canonical_unfa (table, rexp, cset_size) struct rx_hash * table; struct rexp_node * rexp; int cset_size; #endif { struct rx_hash_item * it; it = rx_hash_store (table, rx_rexp_hash (rexp, 0), rexp, &unfa_rules); if (it->binding == 0) { struct rx_cached_rexp * cr; if (it->data == (void *)rexp) rx_save_rexp (rexp); cr = (struct rx_cached_rexp *)malloc (sizeof (*cr)); rx_bzero ((char *)cr, sizeof (*cr)); if (!cr) return 0; it->binding = (void *)cr; cr->unfa.nfa = 0; cr->unfa.exp = rexp; cr->hash_item = it; rx_save_rexp (rexp); } return (struct rx_cached_rexp *)it->binding; } #ifdef __STDC__ static struct rx * rx_unfa_rx (struct rx_cached_rexp * cr, struct rexp_node * exp, int cset_size) #else static struct rx * rx_unfa_rx (cr, exp, cset_size) struct rx_cached_rexp * cr; struct rexp_node * exp; int cset_size; #endif { struct rx * new_rx; if (cr->unfa.nfa) return cr->unfa.nfa; new_rx = rx_make_rx (cset_size); if (!new_rx) return 0; { struct rx_nfa_state * start; struct rx_nfa_state * end; start = end = 0; if (!rx_build_nfa (new_rx, exp, &start, &end)) { free (new_rx); return 0; } new_rx->start_nfa_states = start; end->is_final = 1; start->is_start = 1; { struct rx_nfa_state * s; int x; x = 0; for (s = new_rx->nfa_states; s; s = s->next) s->id = x++; } } cr->unfa.nfa = new_rx; return new_rx; } #ifdef __STDC__ struct rx_unfaniverse * rx_make_unfaniverse (int delay) #else struct rx_unfaniverse * rx_make_unfaniverse (delay) int delay; #endif { struct rx_unfaniverse * it; it = (struct rx_unfaniverse *)malloc (sizeof (*it)); if (!it) return 0; rx_bzero ((char *)it, sizeof (*it)); it->delay = delay; return it; } #ifdef __STDC__ void rx_free_unfaniverse (struct rx_unfaniverse * it) #else void rx_free_unfaniverse (it) struct rx_unfaniverse * it; #endif { } #ifdef __STDC__ struct rx_unfa * rx_unfa (struct rx_unfaniverse * unfaniverse, struct rexp_node * exp, int cset_size) #else struct rx_unfa * rx_unfa (unfaniverse, exp, cset_size) struct rx_unfaniverse * unfaniverse; struct rexp_node * exp; int cset_size; #endif { struct rx_cached_rexp * cr; if (exp && exp->cr) cr = exp->cr; else { cr = canonical_unfa (&unfaniverse->table, exp, cset_size); if (exp) exp->cr = cr; } if (!cr) return 0; if (cr->next) { if (unfaniverse->free_queue == cr) { unfaniverse->free_queue = cr->next; if (unfaniverse->free_queue == cr) unfaniverse->free_queue = 0; } cr->next->prev = cr->prev; cr->prev->next = cr->next; cr->next = 0; cr->prev = 0; --unfaniverse->delayed; } ++cr->unfa.refs; cr->unfa.cset_size = cset_size; cr->unfa.verse = unfaniverse; rx_unfa_rx (cr, exp, cset_size); return &cr->unfa; } #ifdef __STDC__ void rx_free_unfa (struct rx_unfa * unfa) #else void rx_free_unfa (unfa) struct rx_unfa * unfa; #endif { struct rx_cached_rexp * cr; cr = (struct rx_cached_rexp *)unfa; if (!cr) return; if (!--cr->unfa.refs) { if (!unfa->verse->free_queue) { unfa->verse->free_queue = cr; cr->next = cr->prev = cr; } else { cr->next = unfa->verse->free_queue; cr->prev = unfa->verse->free_queue->prev; cr->next->prev = cr; cr->prev->next = cr; } ++unfa->verse->delayed; while (unfa->verse->delayed > unfa->verse->delay) { struct rx_cached_rexp * it; it = unfa->verse->free_queue; unfa->verse->free_queue = it->next; if (!--unfa->verse->delayed) unfa->verse->free_queue = 0; it->prev->next = it->next; it->next->prev = it->prev; if (it->unfa.exp) it->unfa.exp->cr = 0; rx_free_rexp ((struct rexp_node *)it->hash_item->data); rx_hash_free (it->hash_item, &unfa_rules); rx_free_rx (it->unfa.nfa); rx_free_rexp (it->unfa.exp); free (it); if (it == cr) break; } } else return; } #ifdef __STDC__ void rx_save_unfa (struct rx_unfa * unfa) #else void rx_save_unfa (unfa) struct rx_unfa * unfa; #endif { ++(unfa->refs); } rplay-3.3.2/rx/rxunfa.h100644 153 62 3467 6552756455 13457 0ustar boynsstaff#ifndef RXUNFAH #define RXUNFAH /* Copyright (C) 1995, 1996 Tom Lord * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "_rx.h" struct rx_unfaniverse { int delay; int delayed; struct rx_hash table; struct rx_cached_rexp * free_queue; }; struct rx_unfa { int refs; struct rexp_node * exp; struct rx * nfa; int cset_size; struct rx_unfaniverse * verse; }; struct rx_cached_rexp { struct rx_unfa unfa; struct rx_cached_rexp * next; struct rx_cached_rexp * prev; struct rx_hash_item * hash_item; }; #ifdef __STDC__ extern struct rx_unfaniverse * rx_make_unfaniverse (int delay); extern void rx_free_unfaniverse (struct rx_unfaniverse * it); extern struct rx_unfa * rx_unfa (struct rx_unfaniverse * unfaniverse, struct rexp_node * exp, int cset_size); extern void rx_free_unfa (struct rx_unfa * unfa); extern void rx_save_unfa (struct rx_unfa * unfa); #else /* STDC */ extern struct rx_unfaniverse * rx_make_unfaniverse (); extern void rx_free_unfaniverse (); extern struct rx_unfa * rx_unfa (); extern void rx_free_unfa (); extern void rx_save_unfa (); #endif /* STDC */ #endif /* RXUNFAH */ rplay-3.3.2/rx/PLUGIN/ 40755 153 62 0 6727650102 12654 5ustar boynsstaffrplay-3.3.2/rx/PLUGIN/OPT100644 153 62 27 6552756455 13313 0ustar boynsstafflibsystas rx rx systas rplay-3.3.2/rx/PLUGIN/REQ100644 153 62 0 6552756455 13247 0ustar boynsstaffrplay-3.3.2/rx/PLUGIN/greet100644 153 62 1722 6552756455 14022 0ustar boynsstaffxxxxxxxxxxxxxxxx Rx/diSpencer xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxx POSIX regexp functions. xxxxx xxx xxxxx xxx xxxxx xxx Let it fly in the breeze xxxxxxxxxxxxxxx and get caught in the trees xxxxxxxxxxxxxx make a home for the fleas in my Hair. xxxxxxxxx A home for fleas [oh yeah!]; xxxxx xxxx A hive for bees [good god!]; xxxxx xxxx A nest for birds; xxxxx xxxx rrr There ain't no words xxxxx xxxx rrr for the beauty xxxxx xxxxrrr the splender xxxxxxx rxrxr the wonder rrrxrx of my Hair! rrr rxxx rrr xxxx Blow it. Show it. rrr xxxx xx Looongest I can grow it, my Hair. rrr xxxxxx rplay-3.3.2/rx/PLUGIN/systas.config100644 153 62 43 6552756455 15441 0ustar boynsstaffxtra_cflags="-L../rx $xtra_cflags" rplay-3.3.2/rx/PLUGIN/systas.inits100644 153 62 2 6552756455 15275 0ustar boynsstaff rplay-3.3.2/rx/PLUGIN/systas.libs100644 153 62 16 6552756455 15125 0ustar boynsstaff-lsystas -lrx