From lpkruger@tucson.princeton.edu Sun Mar 13 15:20:22 EST 1994 Article: 1854 of comp.os.linux.announce Newsgroups: comp.os.linux.announce Path: bigblue.oit.unc.edu!concert!corpgate!news.utdallas.edu!wupost!math.ohio-state.edu!cyber2.cyberstore.ca!nntp.cs.ubc.ca!uw-beaver!cornell!bounce-bounce From: lpkruger@tucson.princeton.edu (Louis P. Kruger) Subject: maplay mpeg audio player for Linux Message-ID: <1994Mar13.175157.15457@cs.cornell.edu> Followup-To: comp.os.linux.misc Keywords: mpeg, maplay, sound Sender: mdw@cs.cornell.edu (Matt Welsh) Reply-To: lpkruger@tucson.princeton.edu (Louis P. Kruger) Organization: Princeton University Date: Sun, 13 Mar 1994 17:51:57 GMT Approved: linux-announce@tc.cornell.edu (Matt Welsh) Lines: 220 Hi everybody! I've added support for the Linux sound driver to Tobias Bading's very fine program maplay. The original program can be found on sunsite.unc.edu in /pub/electronic-publications/IUMA This version only supports mono output, there wouldn't be too much point in implementing stereo, because the playback is already a little choppy as it is on my 486/66. Pentium owners, enjoy! Since the patches aren't too long, I'm including them in this message. Louis ----------------------------CUT HERE--------------------------------------- --- ./configuration.sh~ Mon Feb 21 12:29:48 1994 +++ ./configuration.sh Sat Mar 12 20:44:39 1994 @@ -46,9 +46,15 @@ INCLUDEDIRS='-I/usr/gnu/lib/g++-include -I/usr/gnu/lib/gcc-lib/decstation/2.5.8/include' LIBRARIES= AUDIO_INCLUDES= ;; + "Linux*") + COMPILER=g++ + COMPILERFLAGS='-O2 -m486 -funroll-loops -Wall -DLINUX -DDAMN_INTEL_BYTE_ORDER' + INCLUDEDIRS='-I/usr/g++-include/ -I/usr/lib/gcc-lib/i486-linux/2.5.8/include/' + LIBRARIES= + AUDIO_INCLUDES='#include ' ;; *) echo "This programm has not been tested on your type of machine yet!" echo "Please modify the file configuration.sh according to your needs!" exit esac export COMPILER COMPILERFLAGS INCLUDEDIRS LIBRARIES --- ./maplay.c~ Mon Feb 21 12:28:18 1994 +++ ./maplay.c Sat Mar 12 19:28:25 1994 @@ -213,17 +213,26 @@ Exit (1); } #else -// #ifdef your_machine -// if (mode == single_channel || which_channels != both) -// buffer = new your_Obuffer (your_parameters); // mono -// else -// buffer = new your_Obuffer (your_parameters); // stereo -// #else +#ifdef LINUX + if (LinuxObuffer::class_suitable( + (mode == single_channel || which_channels != both) ? 1 : 2 )) + { + if(mode == single_channel || which_channels != both) + buffer = new LinuxObuffer (1, header); + else + buffer = new LinuxObuffer (2, header); + } + else + { + cerr << "Sorry, no suitable audio device detected, please use stdout mode.\n"; + Exit(1); + } +#else { cerr << "Sorry, no suitable audio device detected, please use stdout mode.\n"; Exit (1); } -// #endif // !your_machine +#endif // !LINUX #endif // !SPARC #endif // !Indigo --- ./obuffer.c~ Mon Feb 21 12:28:21 1994 +++ ./obuffer.c Sat Mar 12 19:42:43 1994 @@ -75,7 +75,122 @@ bufferp[i] = buffer + i; } +#ifdef LINUX +int LinuxObuffer::audio_fd = -1; + +int LinuxObuffer::open_audio_device (void) +{ + int fd; + + if ((fd = open ("/dev/dsp", O_WRONLY | O_NDELAY, 0)) < 0) + if (errno == EBUSY) + { + cerr << "Sorry, the audio device is busy!\n"; + exit (1); + } + else + { + perror ("can't open /dev/dsp for writing"); + exit (1); + } + return fd; +} + +LinuxObuffer::LinuxObuffer (uint32 number_of_channels, Header *header) +{ +#ifdef DEBUG + if (!number_of_channels || number_of_channels > MAXCHANNELS) + { + cerr << "LinuxObuffer: 0 < number of channels < " << MAXCHANNELS << "!\n"; + exit (1); + } +#endif + channels = number_of_channels; + for (int i = 0; i < number_of_channels; ++i) + bufferp[i] = buffer + i; + + if (audio_fd < 0) + { + cerr << "Internal error, LinuxObuffer::audio_fd has to be initialized\n" + "by LinuxObuffer::class_suitable()!\n"; + exit (1); + } + + // configure the device: + int play_precision = 16; + int play_stereo = channels-1; + int play_sample_rate = header->frequency (); + + if( + ioctl(audio_fd, SNDCTL_DSP_SAMPLESIZE, &play_precision) == -1 || + ioctl(audio_fd, SNDCTL_DSP_STEREO, &play_stereo) == -1 || + ioctl(audio_fd, SNDCTL_DSP_SPEED, &play_sample_rate) == -1 + ) + { + perror ("configuration of /dev/dsp failed"); + exit (1); + } +} + +LinuxObuffer::~LinuxObuffer (void) +{ + sleep (1); + close (audio_fd); +} + + +void LinuxObuffer::append (uint32 channel, int16 value) +{ +#ifdef DEBUG + if (channel >= channels) + { + cerr << "illegal channelnumber in LinuxObuffer::append()!\n"; + exit (1); + } + if (bufferp[channel] - buffer >= OBUFFERSIZE) + { + cerr << "buffer overflow!\n"; + exit (1); + } +#endif + *bufferp[channel] = value; + bufferp[channel] += channels; +} + + +void LinuxObuffer::write_buffer (int) +{ + int length = (int)((char *)bufferp[0] - (char *)buffer); + if (write (audio_fd, buffer, length) != length) + cerr << "Warning: couldn't write all samples to /dev/dsp\n"; + for (int i = 0; i < channels; ++i) + bufferp[i] = buffer + i; +} + +bool LinuxObuffer::class_suitable (int channels) +{ + if(channels != 1) + { + cerr << "Stereo output not supported--use mono or stdout\n"; + return False; + } + // check for the dsp audio device: + audio_fd = open_audio_device (); +#ifdef DEBUG + if (audio_fd != -1) + cerr << "Opened Okay!\n"; + else + cerr << "Error: " << errno << "\n"; +#endif + + if (audio_fd != -1) + return True; + else + return False; +} + +#endif /* LINUX */ #ifdef Indigo IndigoObuffer::IndigoObuffer (uint32 number_of_channels, Header *header) --- ./obuffer.h~ Mon Feb 21 12:28:21 1994 +++ ./obuffer.h Sat Mar 12 19:12:19 1994 @@ -61,6 +61,25 @@ void write_buffer (int fd); }; +#ifdef LINUX +class LinuxObuffer : public Obuffer +{ + int16 buffer[OBUFFERSIZE]; + int16 *bufferp[MAXCHANNELS]; + uint32 channels; + static int audio_fd; + + static int open_audio_device(void); + + public: + LinuxObuffer (uint32 number_of_channels, Header *); + ~LinuxObuffer (void); + void append (uint32 channel, int16 value); + void write_buffer (int dummy); + static bool class_suitable(int); + +}; +#endif #ifdef Indigo // a class for direct sound output on SGI machines: ----------------------------------END-----------------------------------