summaryrefslogtreecommitdiffstats
path: root/mpeglib/lib/util/audio
diff options
context:
space:
mode:
Diffstat (limited to 'mpeglib/lib/util/audio')
-rw-r--r--mpeglib/lib/util/audio/Makefile.am18
-rw-r--r--mpeglib/lib/util/audio/audioIO.cpp49
-rw-r--r--mpeglib/lib/util/audio/audioIO.h80
-rw-r--r--mpeglib/lib/util/audio/audioIO_AIX.cpp533
-rw-r--r--mpeglib/lib/util/audio/audioIO_BeOS.cpp227
-rw-r--r--mpeglib/lib/util/audio/audioIO_HPUX.cpp190
-rw-r--r--mpeglib/lib/util/audio/audioIO_IRIX.cpp157
-rw-r--r--mpeglib/lib/util/audio/audioIO_Linux.cpp220
-rw-r--r--mpeglib/lib/util/audio/audioIO_SDL.cpp164
-rw-r--r--mpeglib/lib/util/audio/audioIO_SunOS.cpp167
-rw-r--r--mpeglib/lib/util/audio/dspWrapper.cpp193
-rw-r--r--mpeglib/lib/util/audio/dspWrapper.h75
12 files changed, 2073 insertions, 0 deletions
diff --git a/mpeglib/lib/util/audio/Makefile.am b/mpeglib/lib/util/audio/Makefile.am
new file mode 100644
index 00000000..968d1d46
--- /dev/null
+++ b/mpeglib/lib/util/audio/Makefile.am
@@ -0,0 +1,18 @@
+
+# ---- @OS_TYPE@/@ARCH_TYPE@ ----
+
+INCLUDES = $(all_includes)
+
+EXTRA_DIST = audioIO_AIX.cpp audioIO_BeOS.cpp \
+ audioIO_HPUX.cpp \
+ audioIO_IRIX.cpp audioIO_Linux.cpp \
+ audioIO_SunOS.cpp audioIO_SDL.cpp
+
+noinst_HEADERS = audioIO.h dspWrapper.h
+
+noinst_LTLIBRARIES = libaudio.la
+
+libaudio_la_SOURCES = audioIO.cpp dspWrapper.cpp
+
+
+
diff --git a/mpeglib/lib/util/audio/audioIO.cpp b/mpeglib/lib/util/audio/audioIO.cpp
new file mode 100644
index 00000000..d066210f
--- /dev/null
+++ b/mpeglib/lib/util/audio/audioIO.cpp
@@ -0,0 +1,49 @@
+
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#ifdef SDL_WRAPPER
+
+ #include "audioIO_SDL.cpp"
+
+//
+// If native sound is defined compiled for that
+//
+
+#else
+
+
+#ifdef OS_AIX
+ #include "audioIO_AIX.cpp"
+#endif
+
+#ifdef OS_Linux
+ #include "audioIO_Linux.cpp"
+#endif
+
+#ifdef OS_BSD
+ #include "audioIO_Linux.cpp"
+#endif
+
+#if defined(OS_IRIX) || defined(OS_IRIX64)
+ #include "audioIO_IRIX.cpp"
+#endif
+
+#ifdef OS_HPUX
+ #include "audioIO_HPUX.cpp"
+#endif
+
+#ifdef OS_SunOS
+ #include "audioIO_SunOS.cpp"
+#endif
+
+#ifdef __BEOS__
+ #include "audioIO_BeOS.cpp"
+#endif
+
+
+#endif
diff --git a/mpeglib/lib/util/audio/audioIO.h b/mpeglib/lib/util/audio/audioIO.h
new file mode 100644
index 00000000..41e1ceb2
--- /dev/null
+++ b/mpeglib/lib/util/audio/audioIO.h
@@ -0,0 +1,80 @@
+
+
+#ifndef __AUDIOIO_H
+#define __AUDIOIO_H
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+
+extern "C" {
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+}
+
+/* AUSUZ should be the amount of data your audio device will accept after it
+ * has said it is ready to receive data. ie when the device is ready
+ * for data it
+ * will accept it without blocking. It must also be a multiple of 128
+ */
+
+#ifdef OS_AIX
+ #define AUSIZ 32768
+#endif
+
+#ifdef OS_Linux
+ extern int AUSIZ;
+#endif
+
+#ifdef OS_BSD
+ #define AUSIZ 32768
+#endif
+
+#if defined(OS_IRIX) || defined(OS_IRIX64)
+ #define AUSIZ 32768
+#endif
+
+#ifdef OS_HPUX
+ #define AUSIZ 4096
+#endif
+
+#ifdef OS_SunOS
+ #define AUSIZ 4096
+#endif
+
+
+#ifdef DEBUG
+ #define DB(type,cmd) if (debugFlags.type) { cmd ; }
+#else
+ #define DB(type,cmd)
+#endif
+
+
+
+
+//Prototypes:
+
+int audioConstruct();
+void audioDestruct();
+
+
+
+int audioOpen();
+void audioClose();
+void audioInit(int sampleSize,int frequency, int stereo,int sign, int bigendian);
+
+
+int mixerOpen();
+void mixerClose();
+void mixerSetVolume(int volumeLeft,int volumeRight);
+
+int audioWrite(char *buffer, int count);
+int getAudioFd();
+int getAudioBufferSize();
+
+#endif
diff --git a/mpeglib/lib/util/audio/audioIO_AIX.cpp b/mpeglib/lib/util/audio/audioIO_AIX.cpp
new file mode 100644
index 00000000..15316852
--- /dev/null
+++ b/mpeglib/lib/util/audio/audioIO_AIX.cpp
@@ -0,0 +1,533 @@
+/*
+ * AIX audio - griff@acm.org 02aug2000
+ * tested on 43P 260 with builtin audio
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+/* A conflict within AIX 4.3.3 <sys/> headers and probably others as well.
+ * I guess nobody ever uses audio... Shame over AIX header files. */
+#include <sys/machine.h>
+#undef BIG_ENDIAN
+#include <sys/audio.h>
+
+static int audio_fd;
+
+static void debugUpdate( unsigned long& flags, long& bsize );
+
+#ifndef AUDIO_BIG_ENDIAN
+#define AUDIO_BIG_ENDIAN BIG_ENDIAN
+#endif
+
+
+
+int audioConstruct() {
+ printf("audioConstruct AIX ********\n");
+ audio_fd=-1;
+ return true;
+}
+
+
+void audioDestruct() {
+
+}
+
+int audioOpen()
+{
+ char devname[14];
+ for ( int dev=0; dev<4; dev++ )
+ {
+ for ( int chan=1; chan<8; chan++ )
+ {
+ sprintf(devname,"/dev/paud%d/%d",dev,chan);
+ audio_fd = open (devname, O_WRONLY, 0);
+ if ( audio_fd >= 0 )
+ {
+ return 1;
+ }
+ sprintf(devname,"/dev/baud%d/%d",dev,chan);
+ audio_fd = open (devname, O_WRONLY, 0);
+ if ( audio_fd >= 0 )
+ {
+ return 1;
+ }
+ }
+ }
+
+ fprintf(stderr, "Could not open AIX audio device, faking\n" );
+ return 1;
+}
+
+int getAudioBufferSize()
+{
+ audio_buffer paud_bufinfo;
+
+ if( audio_fd < 0 ) return 1024*65;
+
+ if ( ioctl(audio_fd, AUDIO_BUFFER, &paud_bufinfo) < 0 )
+ {
+ perror("ioctl getAudioBufferSize using default");
+ return 1024*65;
+ }
+
+ /*
+ * Do you need the total capacity or the current capacity?
+ * This is the total capacity:
+ */
+ return paud_bufinfo.write_buf_cap;
+ /*
+ * This is the current capacity:
+ * return (paud_bufinfo.write_buf_cap - paud_bufinfo.write_buf_size);
+ */
+}
+
+void audioInit(int sampleSize,int frequency, int stereo, int sign, int bigendian )
+{
+ // int format;
+ int bytes_per_sample;
+ audio_init paud_init;
+ audio_buffer paud_bufinfo;
+ // audio_status paud_status;
+ audio_control paud_control;
+ audio_change paud_change;
+
+ if( audio_fd < 0 ) return;
+
+ /*
+ * We can't set the buffer size - just ask the device for the maximum
+ * that we can have.
+ */
+ if ( ioctl(audio_fd, AUDIO_BUFFER, &paud_bufinfo) < 0 )
+ {
+ perror("Couldn't get audio buffer information");
+ return;
+ }
+
+ /*
+ * Fields in the audio_init structure:
+ *
+ * Ignored by us:
+ *
+ * paud.loadpath[LOAD_PATH]; * DSP code to load, MWave chip only?
+ * paud.slot_number; * slot number of the adapter
+ * paud.device_id; * adapter identification number
+ *
+ * Input:
+ *
+ * paud.srate; * the sampling rate in Hz
+ * paud.bits_per_sample; * 8, 16, 32, ...
+ * paud.bsize; * block size for this rate
+ * paud.mode; * ADPCM, PCM, MU_LAW, A_LAW, SOURCE_MIX
+ * paud.channels; * 1=mono, 2=stereo
+ * paud.flags; * FIXED - fixed length data
+ * * LEFT_ALIGNED, RIGHT_ALIGNED (var len only)
+ * * TWOS_COMPLEMENT - 2's complement data
+ * * SIGNED - signed? comment seems wrong in sys/audio.h
+ * * BIG_ENDIAN
+ * paud.operation; * PLAY, RECORD
+ *
+ * Output:
+ *
+ * paud.flags; * PITCH - pitch is supported
+ * * INPUT - input is supported
+ * * OUTPUT - output is supported
+ * * MONITOR - monitor is supported
+ * * VOLUME - volume is supported
+ * * VOLUME_DELAY - volume delay is supported
+ * * BALANCE - balance is supported
+ * * BALANCE_DELAY - balance delay is supported
+ * * TREBLE - treble control is supported
+ * * BASS - bass control is supported
+ * * BESTFIT_PROVIDED - best fit returned
+ * * LOAD_CODE - DSP load needed
+ * paud.rc; * NO_PLAY - DSP code can't do play requests
+ * * NO_RECORD - DSP code can't do record requests
+ * * INVALID_REQUEST - request was invalid
+ * * CONFLICT - conflict with open's flags
+ * * OVERLOADED - out of DSP MIPS or memory
+ * paud.position_resolution; * smallest increment for position
+ */
+
+ paud_init.srate = frequency;
+ paud_init.mode = PCM;
+ paud_init.operation = PLAY;
+ paud_init.channels = (stereo?2:1);
+
+ /*
+ * options in AIX:
+ * paud_init.bits_per_sample: 8 | 16
+ * paud_init.flags: AUDIO_BIG_ENDIAN (not used here)
+ * SIGNED (always used here)
+ * TWOS_COMPLEMENT (always on for Linux dsp porting?)
+ * FIXED <- that's right for SDL
+ * or LEFT_ALIGNED <- that's right for mpeglib
+ * or RIGHT_ALIGNED
+ * paud_init.bsize: sample byte size,
+ * bits_per_sample * (stereo?2:1) - for SDL
+ * bits_per_sample * (stereo?2:1) * 2 - for mpeglib
+ */
+ if ( sampleSize == 8 )
+ {
+ /* AFMT_S8 in linux dsp */
+ bytes_per_sample = 2; // why not 1 ?
+ paud_init.bits_per_sample = 8;
+ paud_init.flags = TWOS_COMPLEMENT | LEFT_ALIGNED;
+ }
+ else
+ {
+ /* AFMT_S16_LE in linux dsp */
+ bytes_per_sample = 4; // why not 2 ?
+ paud_init.bits_per_sample = 16;
+ paud_init.flags = TWOS_COMPLEMENT | LEFT_ALIGNED;
+ }
+ if( sign ) paud_init.flags |= SIGNED;
+ if( bigendian ) paud_init.flags |= AUDIO_BIG_ENDIAN;
+
+ paud_init.bsize = bytes_per_sample * (stereo?2:1);
+
+#if 0
+ debugUpdate(paud_init.flags, paud_init.bsize);
+
+ printf("CG: sampleSize = %d\n", sampleSize);
+ printf("CG: frequency = %d\n", frequency);
+ printf("CG: stereo = %s\n", (stereo)?"y":"n");
+ printf("CG: mode = %s\n", "PCM");
+ printf("CG: channels = %d\n", paud_init.channels);
+ printf("CG: bsize = %d\n", paud_init.bsize);
+ printf("CG: bits_per_sample = %d\n", paud_init.bits_per_sample);
+ printf("CG: flags & BIG_ENDIAN = %s\n", ((paud_init.flags&AUDIO_BIG_ENDIAN)?"y":"n"));
+ printf("CG: flags & SIGNED = %s\n", ((paud_init.flags&SIGNED)?"y":"n"));
+ printf("CG: flags & TWOS_COMPLEMENT = %s\n", ((paud_init.flags&TWOS_COMPLEMENT)?"y":"n"));
+ printf("CG: flags & FIXED = %s\n", ((paud_init.flags&FIXED)?"y":"n"));
+ printf("CG: flags & LEFT_ALIGNED = %s\n", ((paud_init.flags&LEFT_ALIGNED)?"y":"n"));
+ printf("CG: flags & RIGHT_ALIGNED = %s\n", ((paud_init.flags&RIGHT_ALIGNED)?"y":"n"));
+#endif
+
+ /*
+ * We know the buffer size and the max number of subsequent writes
+ * that can be pending. If more than one can pend, allow the application
+ * to do something like double buffering between our write buffer and
+ * the device's own buffer that we are filling with write() anyway.
+ *
+ * We can calculate the number of samples that fit into the audio
+ * device buffer if that is necessary:
+ *
+ * samples_capacity = paud_bufinfo.write_buf_cap
+ * / bytes_per_sample
+ * / (stereo?2:1);
+ * if ( paud_bufinfo.request_buf_cap != 1 ) samples_capacity /= 2;
+ */
+
+ /*
+ * The AIX paud device init can't modify the values of the audio_init
+ * structure that we pass to it. So we don't need any recalculation
+ * of this stuff and no reinit call as in linux SDL dsp and dma code.
+ *
+ * /dev/paud supports all of the encoding formats, so we don't need
+ * to do anything like reopening the device, either.
+ */
+ if ( ioctl(audio_fd, AUDIO_INIT, &paud_init) < 0 )
+ {
+ switch ( paud_init.rc )
+ {
+ case 1 :
+ perror("Couldn't set audio format: DSP can't do play requests");
+ return;
+ break;
+ case 2 :
+ perror("Couldn't set audio format: DSP can't do record requests");
+ return;
+ break;
+ case 4 :
+ perror("Couldn't set audio format: request was invalid");
+ return;
+ break;
+ case 5 :
+ perror("Couldn't set audio format: conflict with open's flags");
+ return;
+ break;
+ case 6 :
+ perror("Couldn't set audio format: out of DSP MIPS or memory");
+ return;
+ break;
+ default :
+ perror("Couldn't set audio format: not documented in sys/audio.h");
+ return;
+ break;
+ }
+ }
+
+ /*
+ * Set some parameters: full volume, first speaker that we can find.
+ * Ignore the other settings for now.
+ */
+ paud_change.input = AUDIO_IGNORE; /* the new input source */
+ paud_change.output = OUTPUT_1;
+ /* EXTERNAL_SPEAKER,
+ * INTERNAL_SPEAKER,
+ * OUTPUT_1 */
+ paud_change.monitor = AUDIO_IGNORE; /* the new monitor state */
+ paud_change.volume = 0x7fffffff; /* volume level [0-0x7fffffff] */
+ paud_change.volume_delay = AUDIO_IGNORE; /* the new volume delay */
+ paud_change.balance = 0x3fffffff; /* the new balance */
+ paud_change.balance_delay = AUDIO_IGNORE; /* the new balance delay */
+ paud_change.treble = AUDIO_IGNORE; /* the new treble state */
+ paud_change.bass = AUDIO_IGNORE; /* the new bass state */
+ paud_change.pitch = AUDIO_IGNORE; /* the new pitch state */
+
+ paud_control.ioctl_request = AUDIO_CHANGE;
+ paud_control.request_info = (char*)&paud_change;
+ if ( ioctl(audio_fd, AUDIO_CONTROL, &paud_control) < 0 )
+ {
+ perror("Can't change audio display settings (ignoring)" );
+ }
+
+ /*
+ * Tell the device to expect data. Actual start will wait for
+ * the first write() call.
+ */
+ paud_control.ioctl_request = AUDIO_START;
+ paud_control.position = 0;
+ if ( ioctl(audio_fd, AUDIO_CONTROL, &paud_control) < 0 )
+ {
+ perror("Can't start audio play");
+ return;
+ }
+}
+
+
+void audioSetVolume(int volume)
+{
+ long vol = (long)(volume/100.0) * 0x7fffffff;
+ if( audio_fd < 0 ) return;
+
+ audio_control paud_control;
+ audio_change paud_change;
+
+ paud_change.input = AUDIO_IGNORE; /* the new input source */
+ paud_change.output = OUTPUT_1; /* EXTERNAL_SPEAKER,INTERNAL_SPEAKER,
+ OUTPUT_1 */
+ paud_change.monitor = AUDIO_IGNORE; /* the new monitor state */
+ paud_change.volume = vol; /* volume level [0-0x7fffffff] */
+ paud_change.volume_delay = AUDIO_IGNORE; /* the new volume delay */
+ paud_change.balance = AUDIO_IGNORE; /* the new balance */
+ paud_change.balance_delay = AUDIO_IGNORE; /* the new balance delay */
+ paud_change.treble = AUDIO_IGNORE; /* the new treble state */
+ paud_change.bass = AUDIO_IGNORE; /* the new bass state */
+ paud_change.pitch = AUDIO_IGNORE; /* the new pitch state */
+
+ paud_control.ioctl_request = AUDIO_CHANGE;
+ paud_control.request_info = (char*)&paud_change;
+
+ if ( ioctl(audio_fd, AUDIO_CONTROL, &paud_control) < 0 )
+ {
+ perror("Change audio volume failed");
+ }
+}
+
+void audioFlush()
+{
+ if( audio_fd < 0 ) return;
+
+ if ( ioctl(audio_fd, AUDIO_WAIT, NULL) < 0 )
+ {
+ perror("Flush audio buffers failed");
+ }
+}
+
+void audioClose()
+{
+ if( audio_fd < 0 ) return;
+
+ if ( ioctl(audio_fd, AUDIO_WAIT, NULL) < 0 )
+ {
+ perror("Flush audio buffers failed");
+ }
+ close(audio_fd);
+}
+
+int audioWrite(char *buffer, int count)
+{
+ int written = write(audio_fd, buffer, count);
+ if( written < count )
+ {
+ return count;
+ }
+
+ return written;
+}
+
+int
+getAudioFd()
+{
+ return audio_fd;
+}
+
+int mixerOpen()
+{
+ return true;
+}
+
+void mixerClose()
+{
+}
+
+void mixerSetVolume(int leftVolume,int rightVolume)
+{
+ long balance;
+
+ if( audio_fd < 0 ) return;
+
+ balance = 2 * (leftVolume-rightVolume) / (leftVolume+rightVolume);
+ balance = 0x3fffffff + balance*0x3fffffff;
+
+ audio_control paud_control;
+ audio_change paud_change;
+
+ paud_change.input = AUDIO_IGNORE; /* the new input source */
+ paud_change.output = OUTPUT_1; /* EXTERNAL_SPEAKER,INTERNAL_SPEAKER,
+ OUTPUT_1 */
+ paud_change.monitor = AUDIO_IGNORE; /* the new monitor state */
+ paud_change.volume = AUDIO_IGNORE; /* volume level [0-0x7fffffff] */
+ paud_change.volume_delay = AUDIO_IGNORE; /* the new volume delay */
+ paud_change.balance = balance; /* the new balance */
+ paud_change.balance_delay = AUDIO_IGNORE; /* the new balance delay */
+ paud_change.treble = AUDIO_IGNORE; /* the new treble state */
+ paud_change.bass = AUDIO_IGNORE; /* the new bass state */
+ paud_change.pitch = AUDIO_IGNORE; /* the new pitch state */
+
+ paud_control.ioctl_request = AUDIO_CHANGE;
+ paud_control.request_info = (char*)&paud_change;
+
+ if ( ioctl(audio_fd, AUDIO_CONTROL, &paud_control) < 0 )
+ {
+ perror("Change audio volume failed");
+ }
+}
+
+static void debugUpdate( unsigned long& flags, long& bsize )
+{
+ const char* g;
+
+ g = getenv("AUDIO_BIG_ENDIAN");
+ if ( g )
+ {
+ int i = atoi(g);
+ if ( i == 1 )
+ {
+ flags |= AUDIO_BIG_ENDIAN;
+ }
+ else if ( i == 0 )
+ {
+ flags &= ~AUDIO_BIG_ENDIAN;
+ }
+ else
+ {
+ printf("CG: bad AUDIO_BIG_ENDIAN env variable %s\n", g);
+ }
+ }
+
+ g = getenv("SIGNED");
+ if ( g )
+ {
+ int i = atoi(g);
+ if ( i == 1 )
+ {
+ flags |= SIGNED;
+ }
+ else if ( i == 0 )
+ {
+ flags &= ~SIGNED;
+ }
+ else
+ {
+ printf("CG: bad SIGNED env variable %s\n", g);
+ }
+ }
+
+ g = getenv("TWOS_COMPLEMENT");
+ if ( g )
+ {
+ int i = atoi(g);
+ if ( i == 1 )
+ {
+ flags |= TWOS_COMPLEMENT;
+ }
+ else if ( i == 0 )
+ {
+ flags &= ~TWOS_COMPLEMENT;
+ }
+ else
+ {
+ printf("CG: bad TWOS_COMPLEMENT env variable %s\n", g);
+ }
+ }
+
+ g = getenv("FIXED");
+ if ( g )
+ {
+ int i = atoi(g);
+ if ( i == 1 )
+ {
+ flags |= FIXED;
+ }
+ else if ( i == 0 )
+ {
+ flags &= ~FIXED;
+ }
+ else
+ {
+ printf("CG: bad FIXED env variable %s\n", g);
+ }
+ }
+
+ g = getenv("LEFT_ALIGNED");
+ if ( g )
+ {
+ int i = atoi(g);
+ if ( i == 1 )
+ {
+ flags |= LEFT_ALIGNED;
+ }
+ else if ( i == 0 )
+ {
+ flags &= ~LEFT_ALIGNED;
+ }
+ else
+ {
+ printf("CG: bad LEFT_ALIGNED env variable %s\n", g);
+ }
+ }
+
+ g = getenv("RIGHT_ALIGNED");
+ if ( g )
+ {
+ int i = atoi(g);
+ if ( i == 1 )
+ {
+ flags |= RIGHT_ALIGNED;
+ }
+ else if ( i == 0 )
+ {
+ flags &= ~RIGHT_ALIGNED;
+ }
+ else
+ {
+ printf("CG: bad RIGHT_ALIGNED env variable %s\n", g);
+ }
+ }
+
+ g = getenv("BSIZE");
+ if ( g )
+ {
+ bsize = atoi(g);
+ }
+}
+
diff --git a/mpeglib/lib/util/audio/audioIO_BeOS.cpp b/mpeglib/lib/util/audio/audioIO_BeOS.cpp
new file mode 100644
index 00000000..ae4cf5a1
--- /dev/null
+++ b/mpeglib/lib/util/audio/audioIO_BeOS.cpp
@@ -0,0 +1,227 @@
+//
+// BeOS code for amp-0.7.4, (C) 1997 Andy Lo A Foe
+//
+
+
+#include <MediaKit.h>
+#include <KernelKit.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "transform.h"
+#include "audioIO.h"
+#include "audio.h"
+
+// Define the streambuf size here. streambuf is used
+// as a simple fit buffer.
+
+#define STREAMBUF_SIZE (32*1152)
+
+long bytes_in_streambuf;
+
+// streambuf definition and base indicator
+
+BSubscriber *the_sub;
+BDACStream *the_stream;
+
+sem_id ok_to_read;
+sem_id ok_to_write;
+
+
+char streambuf[STREAMBUF_SIZE];
+char *readbase;
+
+static int au_vol = 100;
+
+// Define our own printout function since we are
+// first writing in the streambuf (not needed, I think,
+// but I don't know if the DACStream accepts a buffer
+// size of 1152. Try it...
+
+void printout(void)
+{
+if (A_WRITE_TO_FILE) {
+#ifndef NO_BYTE_SWAPPING
+int i,j;
+short *ptr;
+
+ if (nch==2) {
+ ptr=(short*)stereo_samples;
+ i=j=32 * 18 * 2;
+ } else {
+ ptr=(short*)mono_samples;
+ i=j=32 * 18;
+ }
+
+ for (;i>=0;--i)
+ ptr[i] = ptr[i] << 8 | ptr[i] >> 8;
+#endif
+
+ if (nch==2)
+ fwrite(stereo_samples,1,sizeof stereo_samples,out_file);
+ else
+ fwrite(mono_samples,1,sizeof mono_samples,out_file);
+}
+
+
+ if (A_AUDIO_PLAY) {
+ static char au_buf[STREAMBUF_SIZE];
+ static int au_ptr =0, avail = 0;
+ static int num_smp;
+ static char *readbase = &au_buf[0];
+
+ // Write amount of samples to copy somewhere
+ num_smp = (nch == 2 ? sizeof stereo_samples : sizeof mono_samples);
+
+ // Copy samples in the fit buffer
+ memcpy(au_buf+au_ptr,(nch == 2 ? (char *)stereo_samples : (char *)mono_samples),
+ num_smp);
+
+ // Increase fit buffer pointer and available sample count
+ au_ptr+=num_smp;
+ avail+=num_smp;
+
+ if (avail >= 4096) { // Are there enough smps to feed the stream?
+ audioWrite((char*)readbase,4096); // Feed it!
+ readbase+=4096; // Increase readbase
+ avail-=4096; // Decrease avail smps count
+ if (au_ptr == STREAMBUF_SIZE) { // At end of fit buffer?
+ au_ptr=0; // Reset all pointers
+ readbase=&au_buf[0];
+ }
+ }
+ }
+
+}
+
+
+// Fake Buffer functions, just to keep the sources clean,
+// buffer.c should not be included in the link process...
+
+int AUDIO_BUFFER_SIZE;
+
+int
+audioBufferOpen(int frequency, int stereo, int volume)
+{
+ audioOpen(frequency, stereo, volume);
+}
+
+
+inline void
+audioBufferWrite(char *buf,int bytes)
+{
+ audioWrite(buf, bytes);
+}
+
+
+void
+audioBufferClose()
+{
+ audioClose();
+}
+
+
+int audioRead(char *buffer, int count)
+{
+ //printf("acquiring ok_to_read (%d bytes)\n", count);
+ if (acquire_sem(ok_to_read)==B_NO_ERROR) {
+ for (register int i=0; i < count;i++) {
+ *(buffer++)+=*(readbase++);
+ }
+ bytes_in_streambuf-=count;
+
+ if (bytes_in_streambuf <= 0) {
+ release_sem(ok_to_write);
+ bytes_in_streambuf = 0;
+ } else {
+ release_sem(ok_to_read);
+ }
+ }
+ return (0);
+}
+
+
+bool stream_func(void *arg, char *buf, size_t count, void *header)
+{
+ audioRead(buf, count);
+ return TRUE;
+}
+
+void audioOpen() {
+ readbase = &streambuf[0];
+
+ bytes_in_streambuf = 0;
+
+ the_sub = new BSubscriber("amp DAC writer");
+ the_stream = new BDACStream();
+
+ the_sub->Subscribe(the_stream);
+
+ the_stream->SetSamplingRate(frequency);
+
+ // Create semaphores
+ ok_to_read = create_sem(0, "read sem");
+ ok_to_write = create_sem(1, "write sem");
+
+}
+
+void audioInit(int sampleSize,int frequency, int stereo)
+{
+
+ // Initialize the streambuf
+ bytes_in_streambuf = 0;
+ memset(&streambuf, 0, STREAMBUF_SIZE);
+
+
+ // Enter the stream
+ the_sub->EnterStream(NULL, TRUE, NULL, stream_func, NULL, TRUE);
+}
+
+
+void audioSetVolume(int volume)
+{
+ if (volume > 128) // This allows for a modest volume boost
+ volume = 128;
+ au_vol = volume;
+}
+
+
+void audioClose()
+{
+ the_sub->ExitStream(TRUE);
+ the_sub->Unsubscribe();
+
+ delete_sem(ok_to_read);
+ delete_sem(ok_to_write);
+
+ delete the_sub;
+ delete the_stream;
+}
+
+
+// audioWrite is called from the player thread
+
+int audioWrite(char *buffer, int count)
+{
+ //printf("acquiring ok_to_write (%d bytes)\n", count);
+ if(acquire_sem(ok_to_write)==B_NO_ERROR)
+ {
+ memcpy(&streambuf, buffer, count);
+
+ if (au_vol != 100) { // Handle volume scaling here
+ short *b=(short *)&streambuf;
+ for (int i=0; i < count/2; i++) {
+ int v=((int)b[i]*au_vol)/100;
+ b[i]=(v>32767) ? 32767 : ((v<-32768) ? -32768 : v);
+ }
+ }
+
+ bytes_in_streambuf = count;
+ readbase = &streambuf[0];
+
+ release_sem(ok_to_read);
+ }
+ return 0;
+}
+
diff --git a/mpeglib/lib/util/audio/audioIO_HPUX.cpp b/mpeglib/lib/util/audio/audioIO_HPUX.cpp
new file mode 100644
index 00000000..ae07a148
--- /dev/null
+++ b/mpeglib/lib/util/audio/audioIO_HPUX.cpp
@@ -0,0 +1,190 @@
+/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
+
+ Origional code by: Lutz Vieweg
+ Modified by:
+ * Andrew Richards - moved code from audio.c
+
+ */
+
+
+#include <sys/audio.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/lock.h>
+#include <unistd.h>
+#include <stdio.h>
+#include "audioIO.h"
+
+/* declare these static to effectively isolate the audio device */
+
+static int audio_fd;
+
+
+/* audioOpen() */
+/* should open the audio device, perform any special initialization */
+/* Set the frequency, no of channels and volume. Volume is only set if */
+/* it is not -1 */
+
+void audioOpen() {
+ if ((audio_fd = open("/dev/audio",O_RDWR))==-1)
+ die(" unable to open the audio device\n");
+
+ DB(audio, msg("Audio device opened on %d\n",audio_fd); )
+ }
+
+
+void
+audioInit(int sampleSize,int frequency, int stereo)
+{
+ int flags;
+ int failed = 0;
+ int volume=100;
+
+ if ((flags = fcntl (audio_fd, F_GETFL, 0)) < 0) {
+ die("unable to set non-blocking mode for /dev/audio\n");
+ }
+ flags |= O_NDELAY;
+ if (fcntl (audio_fd, F_SETFL, flags) < 0) {
+ die("unable to set non-blocking mode for /dev/audio\n");
+ }
+
+ if ( ioctl(audio_fd, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_LINEAR16BIT) < 0 ||
+ ioctl(audio_fd, AUDIO_SET_CHANNELS, stereo ? 2 : 1) < 0 ||
+ ioctl(audio_fd, AUDIO_SET_OUTPUT, AUDIO_OUT_SPEAKER | AUDIO_OUT_HEADPHONE
+ | AUDIO_OUT_LINE) < 0 ||
+ ioctl(audio_fd, AUDIO_SET_SAMPLE_RATE, frequency) < 0) {
+ failed = -1;
+ }
+ if (volume != -1) {
+ struct audio_describe description;
+ struct audio_gains gains;
+ float fvolume = (float)volume / 100.0f;
+ if (ioctl(audio_fd, AUDIO_DESCRIBE, &description)) {
+ failed = -1;
+ }
+ if (ioctl (audio_fd, AUDIO_GET_GAINS, &gains)) {
+ failed = -1;
+ }
+
+ gains.transmit_gain = (int)((float)description.min_transmit_gain +
+ (float)(description.max_transmit_gain
+ - description.min_transmit_gain)
+ * fvolume);
+
+ /* gains.monitor_gain = description.min_monitor_gain; */ /* don't monitor ! */
+
+ if (ioctl (audio_fd, AUDIO_SET_GAINS, &gains)) {
+ failed = -1;
+ }
+ }
+
+ if (ioctl(audio_fd, AUDIO_SET_TXBUFSIZE, 4096 * 8)) {
+ failed = -1;
+ }
+ if (failed)
+ die(" unable to setup /dev/audio\n");
+}
+
+
+/* audioSetVolume - only code this if your system can change the volume while */
+/* playing. sets the output volume 0-100 */
+
+void
+audioSetVolume(int volume)
+{
+ struct audio_describe description;
+ struct audio_gains gains;
+ int failed = 0;
+ float fvolume = ((float)volume) / 100.0f;
+ if (ioctl(audio_fd, AUDIO_DESCRIBE, &description)) {
+ failed = -1;
+ }
+ if (ioctl (audio_fd, AUDIO_GET_GAINS, &gains)) {
+ failed = -1;
+}
+
+ gains.transmit_gain = (int)((float)description.min_transmit_gain +
+ (float)(description.max_transmit_gain
+ - description.min_transmit_gain)
+ * fvolume);
+ if (ioctl (audio_fd, AUDIO_SET_GAINS, &gains)) {
+ failed = -1;
+ }
+
+ /* could evaluate "failed" here - but who cares? */
+
+ DB(audio, msg("volume set to %d%%\n",volume); )
+
+}
+
+/* audioFlush() */
+/* should flush the audio device */
+
+inline void
+audioFlush()
+{
+ DB(audio, msg("audio: flush %d\n",audio_fd) );
+}
+
+
+/* audioClose() */
+/* should close the audio device and perform any special shutdown */
+
+void
+audioClose()
+{
+ close(audio_fd);
+ DB(audio, msg("audio: closed %d\n",audio_fd) );
+}
+
+
+/* audioWrite */
+/* writes count bytes from buffer to the audio device */
+/* returns the number of bytes actually written */
+
+int audioWrite(char *buffer, int count)
+{
+ DB(audio, msg("audio: Writing %d bytes to audio descriptor %d\n",count,getAudioFd()) );
+ return(write(audio_fd,buffer,count));
+}
+
+
+/* Let buffer.c have the audio descriptor so it can select on it. This means */
+/* that the program is dependent on an file descriptor to work. Should really */
+/* move the select's etc (with inlines of course) in here so that this is the */
+/* ONLY file which has hardware dependent audio stuff in it */
+
+int
+getAudioFd()
+{
+ return(audio_fd);
+}
+
+/*
+ Try to set the priority of this process to a value which
+ allows us to play without buffering, thus saving memory
+ and avoiding cache-misses.
+ If we cannot get any priority high enough to allow for
+ undisturbed replay (because we don't have sufficient
+ privilege), return a zero, otherwise, return a one.
+*/
+int audioSetPriority(void) {
+
+ /* try to lock process in physical memory, just ignore if this fails */
+ plock(PROCSHLIBLOCK);
+
+ /* try to set a realtime-priority of 64 */
+ if (-1 != rtprio(0, 64)) {
+ DB(audio, msg("using real-time priority\n"); )
+ return 1;
+ }
+
+ /* try to set a nice-level of -20 */
+ if (-1 != nice(-20)) {
+ DB(audio, msg("using nice-level -20\n"); )
+ return 1;
+ }
+
+ DB(audio, msg("using buffered output\n"); )
+ return 0; /* need to use a buffer */
+}
diff --git a/mpeglib/lib/util/audio/audioIO_IRIX.cpp b/mpeglib/lib/util/audio/audioIO_IRIX.cpp
new file mode 100644
index 00000000..8498a487
--- /dev/null
+++ b/mpeglib/lib/util/audio/audioIO_IRIX.cpp
@@ -0,0 +1,157 @@
+/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
+
+ Origional code by: Karl Anders Oygard
+ Modified by:
+ * Andrew Richards - moved code from audio.c
+
+ */
+#include <assert.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <dmedia/audio.h>
+#include "audioIO.h"
+
+/* declare these static to effectively isolate the audio device */
+
+static ALport audioport;
+static ALconfig audioconfig;
+
+
+/* audioOpen() */
+/* should open the audio device, perform any special initialization */
+/* Set the frequency, no of channels and volume. Volume is only set if */
+/* it is not -1 */
+
+
+void audioOpen() {
+ printf("sorry. The audio part for irix must be fixed. \n");
+}
+
+void
+audioInit(int sampleSize,int frequency, int stereo)
+{
+ ALconfig audioconfig;
+ audioconfig = ALnewconfig();
+
+ if (!audioconfig)
+ die("out of memory\n");
+ else {
+ long pvbuf[] = { AL_OUTPUT_COUNT, 0, AL_MONITOR_CTL, 0, AL_OUTPUT_RATE, 0};
+
+ if (ALgetparams(AL_DEFAULT_DEVICE, pvbuf, 6) < 0)
+ if (oserror() == AL_BAD_DEVICE_ACCESS)
+ die("couldn't access audio device\n");
+
+ if (pvbuf[1] == 0 && pvbuf[3] == AL_MONITOR_OFF) {
+ long al_params[] = { AL_OUTPUT_RATE, 0};
+
+ al_params[1] = frequency;
+ ALsetparams(AL_DEFAULT_DEVICE, al_params, 2);
+ } else
+ if (pvbuf[5] != frequency)
+ die("audio device is already in use with wrong sample output rate\n");
+
+ /* ALsetsampfmt(audioconfig, AL_SAMPFMT_TWOSCOMP); this is the default */
+ /* ALsetwidth(audioconfig, AL_SAMPLE_16); this is the default */
+
+ if (!stereo) ALsetchannels(audioconfig, AL_MONO);
+ /* else ALsetchannels(audioconfig, AL_STEREO); this is the default */
+
+ ALsetqueuesize(audioconfig, AUSIZ * 2);
+
+ audioport = ALopenport("amp", "w", audioconfig);
+ if (audioport == (ALport) 0) {
+ switch (oserror()) {
+ case AL_BAD_NO_PORTS:
+ die("system is out of ports\n");
+
+ case AL_BAD_DEVICE_ACCESS:
+ die("couldn't access audio device\n");
+
+ case AL_BAD_OUT_OF_MEM:
+ die("out of memory\n");
+ }
+ exit(-1);
+ }
+ ALsetfillpoint(audioport, AUSIZ);
+ }
+}
+
+
+/* audioSetVolume - only code this if your system can change the volume while */
+/* playing. sets the output volume 0-100 */
+
+void
+audioSetVolume(int volume)
+{
+ long al_params[] = { AL_LEFT_SPEAKER_GAIN, 0, AL_RIGHT_SPEAKER_GAIN, 0};
+
+ al_params[1] = al_params[3] = volume * 100 / 255;
+
+ ALsetparams(AL_DEFAULT_DEVICE, al_params, 4);
+}
+
+
+/* audioFlush() */
+/* should flush the audio device */
+
+void
+audioFlush()
+{
+ DB(audio, msg("audio: flush %d\n",audio_fd) );
+}
+
+
+/* audioClose() */
+/* should close the audio device and perform any special shutdown */
+
+void
+audioClose()
+{
+int write_fd;
+
+ /* wait for all samples to be played */
+
+ write_fd = ALgetfd(audioport);
+ if (write_fd >= 0) {
+ fd_set write_fds;
+
+ FD_ZERO(&write_fds);
+ FD_SET(write_fd, &write_fds);
+
+ ALsetfillpoint(audioport, AUSIZ * 2);
+ select(write_fd + 1, NULL, &write_fds, NULL, NULL);
+ }
+
+ /* now close it */
+
+ ALcloseport(audioport);
+ DB(audio, msg("audio: closed %d\n",audio_fd) );
+}
+
+
+/* audioWrite */
+/* writes count bytes from buffer to the audio device */
+/* returns the number of bytes actually written */
+
+int audioWrite(char *buffer, int count)
+{
+ if (ALwritesamps(audioport, buffer, count / 2) == 0) {
+ ALsetfillpoint(audioport, AUSIZ);
+ return(count);
+ } else
+ return 0;
+}
+
+/* Let buffer.c have the audio descriptor so it can select on it. This
+ means that the program is dependent on an file descriptor to
+ work. Should really move the select's etc (with inlines of course) in
+ here so that this is the ONLY file which has hardware dependent audio
+ stuff in it. */
+
+int
+getAudioFd()
+{
+ return ALgetfd(audioport);
+}
+
diff --git a/mpeglib/lib/util/audio/audioIO_Linux.cpp b/mpeglib/lib/util/audio/audioIO_Linux.cpp
new file mode 100644
index 00000000..5ca9231c
--- /dev/null
+++ b/mpeglib/lib/util/audio/audioIO_Linux.cpp
@@ -0,0 +1,220 @@
+/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
+
+ Origional code by: tomislav uzelac
+ Modified by:
+ * Dan Nelson - BSD mods.
+ * Andrew Richards - moved code from audio.c and added mixer support etc
+ * Martin Vogt
+ */
+
+/* Support for Linux and BSD sound devices */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include "audioIO.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+//
+// Why all these different system cannot make a standard where this
+// soundcard.h file is ?
+//
+#if defined(HAVE_SYS_SOUNDCARD_H)
+ #undef AUSIZ
+ #undef HAVE_SYS_SOUNDCARD_H
+ #include <sys/soundcard.h>
+#elif defined(HAVE_MACHINE_SOUNDCARD_H)
+ #undef AUSIZ
+ #include <machine/soundcard.h>
+#elif defined(__NetBSD__)
+ #undef AUSIZ
+ #include <soundcard.h>
+#else
+ // fallback:
+ #include <linux/soundcard.h>
+#endif
+
+
+/* optimal fragment size */
+
+int AUSIZ = 0;
+
+// declare these static to effectively isolate the audio device
+
+static int audio_fd;
+static int mixer_fd;
+static int volumeIoctl;
+
+
+
+int audioConstruct() {
+ audio_fd=-1;
+ mixer_fd=-1;
+ return true;
+}
+
+
+void audioDestruct() {
+
+}
+
+
+
+/*
+ should open the audio device, perform any special initialization
+*/
+int audioOpen() {
+ audio_fd = open ("/dev/dsp", O_WRONLY, 0);
+ if (audio_fd < 0) {
+ perror("Unable to open the audio");
+ }
+
+ // Ok here something important if your programm forks:
+ if (audio_fd > 0) {
+ if (fcntl(audio_fd,F_SETFD,true) < 0) {
+ perror("fcntl socket");exit(1);
+ }
+ }
+
+ return (audio_fd > 0);
+}
+
+inline void audioFlush() {
+ if (ioctl(audio_fd, SNDCTL_DSP_RESET, 0) == -1)
+ perror("Unable to reset audio device\n");
+}
+
+/*
+ should close the audio device and perform any special shutdown
+*/
+void audioClose() {
+ audioFlush();
+ if (close(audio_fd) < 0) {
+ perror("error close audiodevice:");
+ }
+}
+
+
+void audioInit(int sampleSize,int frequency, int stereo, int sign, int big) {
+ if( sign == 0 )
+ {
+ fprintf(stderr,
+ "%s, %d: expecting signed audio data, "
+ "initialized unsigned (ignored)\n",
+ __FILE__, __LINE__ );
+ }
+ if( big != 0 )
+ {
+ fprintf(stderr,
+ "%s, %d: expecting little endian audio data, "
+ "initialized big endian (ignored)\n",
+ __FILE__, __LINE__ );
+ }
+
+ int play_format=AFMT_S16_LE;
+
+ if (sampleSize == 8) {
+ play_format=AFMT_S8;
+ }
+ ioctl(audio_fd,SNDCTL_DSP_RESET,NULL);
+
+ if (ioctl(audio_fd, SNDCTL_DSP_SETFMT,&play_format) < 0) {
+ perror("Unable to set required audio format\n");
+ }
+
+ /* Set 1 or 2 channels */
+ stereo=(stereo ? 1 : 0);
+
+ if (ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo) < 0) {
+ perror("Unable to set stereo/mono\n");
+ exit(0);
+ }
+
+ /* Set the output frequency */
+ if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &frequency) < 0) {
+ perror("Unable to set frequency");
+ exit(0);
+ }
+
+ if (ioctl(audio_fd, SNDCTL_DSP_GETBLKSIZE, &AUSIZ) == -1) {
+ perror("Unable to get fragment size\n");
+ exit(0);
+ }
+}
+
+
+int getAudioBufferSize() {
+ struct audio_buf_info buf_info;
+ int buf=1024*65;
+ if (ioctl(audio_fd,SNDCTL_DSP_GETOSPACE,&buf_info) == -1) {
+ perror("ioctl getAudioBufferSize using default");
+ } else {
+ buf=buf_info.bytes;
+ }
+ return buf;
+}
+
+
+int mixerOpen() {
+ int supportedMixers;
+
+ if ((mixer_fd=open("/dev/mixer",O_RDWR)) == -1) {
+ perror("Unable to open mixer device");
+ }
+
+ // Ok here something important if your programm forks:
+ if (mixer_fd > 0) {
+ if (fcntl(mixer_fd,F_SETFD,true) < 0) {
+ perror("fcntl socket");exit(1);
+ }
+ }
+
+ if (ioctl(mixer_fd, SOUND_MIXER_READ_DEVMASK, &supportedMixers) == -1){
+ perror("Unable to get mixer info assuming master volume");
+ volumeIoctl=SOUND_MIXER_WRITE_VOLUME;
+ } else {
+ if ((supportedMixers & SOUND_MASK_PCM) != 0)
+ volumeIoctl=SOUND_MIXER_WRITE_PCM;
+ else
+ volumeIoctl=0;
+ }
+
+ return (mixer_fd > 0);
+}
+
+
+void mixerClose() {
+ if (mixer_fd != -1) {
+ close(mixer_fd);
+ }
+}
+
+/*
+ only code this if your system can change the volume while
+ playing
+*/
+void mixerSetVolume(int leftVolume,int rightVolume) {
+ int volume;
+
+ volume=leftVolume+(rightVolume<<8);
+ if ((mixer_fd != -1) && (volumeIoctl!=0)) {
+ if (ioctl(mixer_fd, volumeIoctl, &volume) < 0) {
+ perror("Unable to set sound volume");
+ }
+ }
+}
+
+
+
+int audioWrite(char *buffer, int count) {
+ return(write(audio_fd,buffer,count));
+}
+
+
+int getAudioFd() {
+ return(audio_fd);
+}
diff --git a/mpeglib/lib/util/audio/audioIO_SDL.cpp b/mpeglib/lib/util/audio/audioIO_SDL.cpp
new file mode 100644
index 00000000..782fa388
--- /dev/null
+++ b/mpeglib/lib/util/audio/audioIO_SDL.cpp
@@ -0,0 +1,164 @@
+/*
+ audio wrapper for SDL
+ Copyright (C) 2000 Martin Vogt
+
+ 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.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+#include "../../input/bufferInputStream.h"
+#include <assert.h>
+#include <iostream.h>
+#if defined WIN32
+#include <SDL.h>
+#include <SDL_audio.h>
+#else
+#include <SDL/SDL.h>
+#include <SDL/SDL_audio.h>
+#endif
+
+//static SDL_AudioSpec actual;
+static BufferInputStream* audioRing;
+static TimeStamp* dummy;
+static int lOpen=false;
+
+
+
+int audioConstruct() {
+ cout << "audioConstruct ********* SDL"<<endl;
+ if ( SDL_Init(SDL_INIT_AUDIO) < 0 ) {
+ fprintf(stderr, "Warning: Couldn't init SDL audio: %s\n",
+ SDL_GetError());
+ exit(0);
+ }
+ atexit(SDL_Quit);
+ audioRing=new BufferInputStream(1024*65,1024*8,"audioSDL");
+ audioRing->open("audioSDL");
+ dummy=new TimeStamp();
+ lOpen=false;
+ return true;
+}
+
+
+void audioDestruct() {
+ delete audioRing;
+ delete dummy;
+}
+
+
+
+
+int audioOpen() {
+ return true;
+}
+
+
+void audioClose() {
+ lOpen=false;
+ SDL_CloseAudio();
+}
+
+
+void audioCallback(void *, Uint8 *stream, int len) {
+ char* startPtr;
+ TimeStamp* start;
+ int bytePos;
+
+ int read=audioRing->readRemote(&startPtr,len);
+ SDL_MixAudio(stream, (Uint8*) startPtr, read, SDL_MIX_MAXVOLUME);
+
+ audioRing->forwardReadPtr(read);
+ // dequeue time stamps
+ bytePos=audioRing->getBytePosition();
+ start=audioRing->getTimeStamp(bytePos);
+
+}
+
+
+
+void audioInit(int sampleSize,int frequency, int stereo, int sign, int big) {
+ if( sign == 0 )
+ {
+ fprintf(stderr,
+ "%s, %d: expecting signed audio data, "
+ "initialized unsigned (ignored)\n",
+ __FILE__, __LINE__ );
+ }
+ if( big != 0 )
+ {
+ fprintf(stderr,
+ "%s, %d: expecting little endian audio data, "
+ "initialized big endian (ignored)\n",
+ __FILE__, __LINE__ );
+ }
+
+ cout << "SDL audioInit: "
+ << " sampleSize:"<<sampleSize
+ << " frequency:"<<frequency
+ << " stereo:"<<stereo<<endl;
+ if (lOpen==true) {
+ cout << "SDL is buggy, because open != init -> return"<<endl;
+ return;
+ }
+ lOpen=true;
+ SDL_AudioSpec wanted;
+ //SDL_AudioSpec actual;
+ if (sampleSize == 16) {
+ wanted.format= AUDIO_S16LSB;
+ } else {
+ wanted.format= AUDIO_S8;
+ }
+
+ wanted.freq=frequency;
+ wanted.channels=stereo+1;
+ wanted.samples = 1024;
+ wanted.callback = audioCallback;
+ wanted.userdata = NULL;
+
+ int err=SDL_OpenAudio(&wanted, NULL);
+ if (err != 0) {
+ cout << "SDL_OpenAudio not ok"<<endl;
+ cout << "error is:"<<SDL_GetError()<<endl;
+ exit(0);
+ }
+ SDL_PauseAudio(0);
+
+}
+
+
+int mixerOpen() {
+ return true;
+}
+
+
+void mixerClose() {
+}
+
+
+void mixerSetVolume(int volumeLeft,int volumeRight) {
+ cout << "volumeLeft:"<<volumeLeft
+ << " volumeRight:"<<volumeRight<<endl;
+}
+
+
+int audioWrite(char *buffer, int count) {
+
+ audioRing->write(buffer,count,dummy);
+
+
+ return count;
+}
+
+
+int getAudioFd() {
+ return false;
+}
+
+
+int getAudioBufferSize() {
+ int buf=1024*65;
+ return buf;
+}
diff --git a/mpeglib/lib/util/audio/audioIO_SunOS.cpp b/mpeglib/lib/util/audio/audioIO_SunOS.cpp
new file mode 100644
index 00000000..4e9958a1
--- /dev/null
+++ b/mpeglib/lib/util/audio/audioIO_SunOS.cpp
@@ -0,0 +1,167 @@
+/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
+
+ Origional code by: tomislav uzelac
+ Modified by:
+ * Andrew Richards - moved code from audio.c
+ * Jim Crumley - ported some code from other audioIO_'s
+
+ */
+
+#include <sys/types.h>
+#include <sys/stropts.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/audioio.h>
+#include "audioIO.h"
+#include <iostream.h>
+
+/* declare these static to effectively isolate the audio device */
+
+static int audio_fd;
+static audio_info_t auinfo;
+
+
+int audioConstruct(){
+ audio_fd=-1;
+ return true;
+}
+
+void audioDestruct() {
+
+}
+
+
+/* audioOpen() */
+/* should open the audio device and perform any special initialization */
+/* returns the file descriptior of the audio device */
+
+int audioOpen() {
+ AUDIO_INITINFO(&auinfo);
+
+ if ((audio_fd = open("/dev/audio",O_RDWR))==-1) {
+ perror("unable to open the audio device");
+ }
+ // Ok here something important if your programm forks:
+ if (audio_fd > 0) {
+ if (fcntl(audio_fd,F_SETFD,true) < 0) {
+ perror("fcntl socket");exit(1);
+ }
+ }
+
+ DB(audio, msg("Audio device opened on %d\n",audio_fd) );
+ return (audio_fd > 0);
+}
+
+/* audioFlush() */
+/* should flush the audio device */
+
+inline void audioFlush() {
+ DB(audio, msg("audio: flush %d\n",audio_fd) );
+}
+
+
+/* audioClose() */
+/* should close the audio device and perform any special shutdown */
+
+void audioClose() {
+ close(audio_fd);
+}
+
+
+/**
+ Audio init assumes that the audiodevice is open. It initializes
+ it to the given values
+*/
+
+void audioInit(int sampleSize ,int frequency, int stereo,int sign, int big){
+
+ if (ioctl(audio_fd,AUDIO_GETINFO,&auinfo)<0)
+ perror("Unable to get audio info");
+
+ auinfo.play.precision=sampleSize;
+ auinfo.play.encoding=AUDIO_ENCODING_LINEAR;
+ auinfo.play.channels=(stereo ? 2 : 1);
+ DB(audio, msg("setting sample rate to %d Hz",frequency) );
+ auinfo.play.sample_rate=frequency;
+ if (ioctl(audio_fd,AUDIO_SETINFO,&auinfo)<0)
+ perror("Unable to set audio info");
+
+}
+
+/*
+ only code this if your system can change the volume while
+ playing
+*/
+
+
+int getAudioBufferSize() {
+ int buf;
+ if (ioctl(audio_fd,AUDIO_GETINFO,&auinfo) == -1) {
+ perror("ioctl getAudioBufferSize using default");
+ buf=1024*65;
+ } else {
+ buf=auinfo.play.buffer_size;
+ }
+ return buf;
+}
+
+
+void mixerSetVolume(int leftVolume,int rightVolume) {
+ int volume;
+
+ volume=(leftVolume+rightVolume)/2;
+ auinfo.play.gain=(volume*255)/100;
+
+ // now normalize to values 0...32
+ leftVolume=(32*leftVolume)/100;
+ rightVolume=(32*rightVolume)/100;
+
+ // eg : leftVolume=32, rightVolume=32 => balance=32
+ // eg : leftVolume=0, rightVolume=32 => balance=64
+ // eg : leftVolume=32, rightVolume=0 => balance=0
+
+ //cout << "leftVolume:"<<leftVolume<<endl;
+ //cout << "rightVolume:"<<rightVolume<<endl;
+ int balance=leftVolume-rightVolume+32;
+ //cout << "balance:"<<balance<<endl;
+ //someone should fix the volume on solaris
+ balance=0;
+
+ auinfo.play.balance=(uchar_t)balance;
+ if (ioctl(audio_fd,AUDIO_SETINFO,&auinfo)<0)
+ perror("Unable to set sound volume");
+}
+
+
+
+
+int mixerOpen() {
+ return true;
+}
+
+void mixerClose() {
+}
+
+
+
+
+/* audioWrite */
+/* writes count bytes from buffer to the audio device */
+/* returns the number of bytes actually written */
+
+int audioWrite(char *buffer, int count)
+{
+ return(write(audio_fd,buffer,count));
+}
+
+/* Let buffer.c have the audio descriptor so it can select on it. This means */
+/* that the program is dependent on an file descriptor to work. Should really */
+/* move the select's etc (with inlines of course) in here so that this is the */
+/* ONLY file which has hardware dependent audio stuff in it */
+
+int
+getAudioFd()
+{
+ return(audio_fd);
+}
diff --git a/mpeglib/lib/util/audio/dspWrapper.cpp b/mpeglib/lib/util/audio/dspWrapper.cpp
new file mode 100644
index 00000000..cd9afa57
--- /dev/null
+++ b/mpeglib/lib/util/audio/dspWrapper.cpp
@@ -0,0 +1,193 @@
+/*
+ a wrapper for the audioDevice.
+ Copyright (C) 1998 Martin Vogt
+
+ 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.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+
+#include "dspWrapper.h"
+#include "audioIO.h"
+
+
+#include "../../frame/pcmFrame.h"
+#include "../../frame/floatFrame.h"
+
+#include <iostream>
+
+using namespace std;
+
+DSPWrapper::DSPWrapper() {
+ currentFormat=new PCMFrame(0);
+ lopenDevice=false;
+ lopenMixer=false;
+
+ audioConstruct();
+}
+
+DSPWrapper::~DSPWrapper() {
+ if (lopenDevice) {
+ audioClose();
+ }
+ if (lopenMixer) {
+ mixerClose();
+ }
+ audioDestruct();
+ delete currentFormat;
+}
+
+
+int DSPWrapper::isOpenDevice() {
+ return lopenDevice;
+}
+
+int DSPWrapper::openDevice() {
+ if (lopenDevice==true) {
+ return true;
+ }
+ lopenDevice=audioOpen();
+ return lopenDevice;
+}
+
+int DSPWrapper::closeDevice() {
+ if (isOpenDevice() == true) {
+ audioClose();
+ currentFormat->setFrameFormat(-1,-1);
+ lopenDevice=false;
+ }
+ return true;
+}
+
+
+int DSPWrapper::isOpenMixer() {
+ return lopenMixer;
+}
+
+
+int DSPWrapper::getAudioBufferSize() {
+ return ::getAudioBufferSize();
+}
+
+
+int DSPWrapper::openMixer() {
+ lopenMixer=mixerOpen();
+ return lopenMixer;
+}
+
+int DSPWrapper::closeMixer() {
+ if (isOpenMixer() == true) {
+ mixerClose();
+ lopenMixer=false;
+ }
+ return true;
+}
+
+
+int DSPWrapper::audioPlay(char *buf, int len) {
+ return audioWrite(buf,len);
+}
+
+int DSPWrapper::audioSetup(int stereo,int sampleSize,int lSigned,
+ int lBigEndian,int freq) {
+
+
+ if (isOpenDevice()==false) {
+ cout << "device not open"<<endl;
+ exit(-1);
+ }
+ /*
+ cout << "sampleSize:"<<sampleSize<<endl;
+ cout << "freq:"<<freq<<endl;
+ cout << "stereo:"<<stereo<<endl;
+ cout << "lSigned:"<<lSigned<<endl;
+ cout << "lBigEndian:"<<lBigEndian<<endl;
+ */
+ audioInit(sampleSize,freq,stereo,lSigned,lBigEndian);
+ if (currentFormat->getSampleSize() != sampleSize) {
+ cout << "FIXME: pcmFrame with sampleSize:"<<sampleSize<<endl;
+ }
+ currentFormat->setFrameFormat(stereo,freq);
+ return true;
+}
+
+int DSPWrapper::audioSetup(AudioFrame* audioFrame) {
+ if (audioFrame == NULL) {
+ cout << "audioFrame NULL: DSPWrapper:audioSetup"<<endl;
+ exit(0);
+ }
+ if(audioFrame->isFormatEqual(currentFormat)==false) {
+ audioSetup(audioFrame->getStereo(),audioFrame->getSampleSize(),
+ audioFrame->getSigned(),audioFrame->getBigEndian(),
+ audioFrame->getFrequenceHZ());
+ }
+ return true;
+}
+
+
+int DSPWrapper::audioPlay(PCMFrame* pcmFrame) {
+ if (pcmFrame == NULL) {
+ cout << "pcmFrame NULL: DSPWrapper:audioPlay"<<endl;
+ exit(0);
+ }
+ if(pcmFrame->isFormatEqual(currentFormat)==false) {
+ audioSetup(pcmFrame->getStereo(),pcmFrame->getSampleSize(),
+ pcmFrame->getSigned(),pcmFrame->getBigEndian(),
+ pcmFrame->getFrequenceHZ());
+ }
+ int len=pcmFrame->getLen()*2;
+ int played=audioPlay((char*)pcmFrame->getData(),len);
+ return (len == played);
+}
+
+
+//
+// Misuse our internal currentFormat for the float->int conversion.
+//
+
+int DSPWrapper::audioPlay(FloatFrame* floatFrame) {
+ if (floatFrame == NULL) {
+ cout << "floatFrame NULL: DSPWrapper:audioPlay"<<endl;
+ exit(0);
+ }
+ if(floatFrame->isFormatEqual(currentFormat)==false) {
+ audioSetup(floatFrame->getStereo(),floatFrame->getSampleSize(),
+ floatFrame->getSigned(),floatFrame->getBigEndian(),
+ floatFrame->getFrequenceHZ());
+ }
+
+ int tmpLen=currentFormat->getLen();
+ if (tmpLen < floatFrame->getLen()) {
+ delete currentFormat;
+ currentFormat=new PCMFrame(floatFrame->getLen());
+ floatFrame->copyFormat(currentFormat);
+ }
+ currentFormat->clearrawdata();
+ currentFormat->putFloatData(floatFrame->getData(),floatFrame->getLen());
+ return audioPlay(currentFormat);
+}
+
+void DSPWrapper::audioFlush() {
+ closeDevice();
+}
+
+
+void DSPWrapper::setVolume(float leftPercent,float rightPercent) {
+ if (isOpenMixer()) {
+ mixerSetVolume((int)leftPercent,(int)rightPercent);
+ } else {
+ cout << "cannot set Mixer settings:not open!"<<endl;
+ }
+}
+
+
+void DSPWrapper::print() {
+ cout<<"lopenDevice:"<<lopenDevice<<endl;
+ cout<<"lopenMixer:"<<lopenMixer<<endl;
+ currentFormat->print("currentFormat");
+
+}
diff --git a/mpeglib/lib/util/audio/dspWrapper.h b/mpeglib/lib/util/audio/dspWrapper.h
new file mode 100644
index 00000000..f323096d
--- /dev/null
+++ b/mpeglib/lib/util/audio/dspWrapper.h
@@ -0,0 +1,75 @@
+/*
+ a wrapper for the audioDevice.
+ Copyright (C) 1998 Martin Vogt
+
+ 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.
+
+ For more information look at the file COPYRIGHT in this package
+
+ */
+
+
+
+#ifndef _DSPWRAPPER_H
+#define _DSPWRAPPER_H
+
+class AudioFrame;
+class PCMFrame;
+class FloatFrame;
+#include <kdemacros.h>
+
+/**
+ This class wraps the platform specific /dev/dsp implementation.
+ The only unusal thing is, that it supports each order of
+ init/open.
+ i) you can first init the device and the open
+ ii) you can first open the device and the init it
+ The implementation takes care that the calls are forwarded
+ in the right order to the /dev/dsp implementation.
+ (means: before the init it, we need to open it)
+ But a caller can do it in both orders.
+*/
+
+class KDE_EXPORT DSPWrapper {
+
+ int lopenDevice;
+ int lopenMixer;
+ PCMFrame* currentFormat;
+
+
+ public:
+ DSPWrapper();
+ ~DSPWrapper();
+
+ int openDevice();
+ int closeDevice();
+ int isOpenDevice();
+
+ int openMixer();
+ int closeMixer();
+ int isOpenMixer();
+
+ int getAudioBufferSize();
+ void setVolume(float leftPercent,float rightPercent);
+
+ int audioSetup(int stereo,int sampleSize,int lSigned,
+ int lBigEndian,int freq);
+ int audioSetup(AudioFrame* audioFrame);
+
+ int audioPlay(char *buffer, int size);
+ int audioPlay(PCMFrame* pcmFrame);
+ int audioPlay(FloatFrame* floatFrame);
+ void audioFlush();
+
+ int isEqual(int samplesize,int speed,int stereo,int lSigned,int lBigEndian);
+ int write(char* buf,int len);
+ void print();
+};
+
+#endif
+
+
+
+