pkg://xcdroast-debuginfo-0.98a15-12.2.1.x86_64.rpm:624090/
usr/
src/
debug/
xcdroast-0.98alpha15/
src/wavplay.c
info downloads
/*
wavplay.c
30.05.99 tn
simple wavfile-player. plays only 44.1khz,16bit,stereo files.
gui-mode to fully control all play-functions via external interface
works fine on little and big endian machines.
21.11.01 tn
MacosX code thx to Shawn Hsiao <phsiao@mac.com>
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "largefile.h"
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#if defined(linux) || defined(__CYGWIN32__)
# include <getopt.h>
#endif
#include <sys/stat.h>
#if defined(linux) || defined(__FreeBSD__)
# include <sys/soundcard.h>
# include <sys/ioctl.h>
#endif
#if defined(sun) || defined(__OpenBSD__)
# include <sys/ioctl.h>
# include <sys/audioio.h>
#endif
#ifdef aix
#include <errno.h>
#include <sys/audio.h>
#endif
#ifdef hpux
# ifndef hpux_alib
# include <sys/audio.h>
# else
# include <sys/socket.h>
# include <netdb.h>
# include <netinet/in.h>
# include <netinet/tcp.h>
# include <Alib.h>
# endif
#endif
#include <glib.h>
#include "xcdroast.h"
#if (defined(__MACH__) && defined(__APPLE__))
#include <CoreAudio/CoreAudio.h>
#include <machine/limits.h>
#include <pthread.h>
#endif
#if defined(__sgi)
#include <dmedia/audio.h>
#endif
static guchar waveHdr[44];
static gint abuf_size;
static guchar *audiobuf;
gint read_line(gint fd, gchar *ptr, gint maxlen);
gint is_std_wav_file(guchar *hdr);
gint is_in_cd_quality(guchar *hdr);
#if defined(linux) || defined(__FreeBSD__)
#define DEFAULT_AUDIO_DEVICE "/dev/dsp"
#elif defined (aix)
#define DEFAULT_AUDIO_DEVICE ""
#elif defined(__sgi)
#define DEFAULT_AUDIO_DEVICE ""
#else
#define DEFAULT_AUDIO_DEVICE "/dev/audio"
#endif
#define DEFAULT_BUFFER_SIZE 22050
#if (defined(__MACH__) && defined(__APPLE__))
#define BUF_SIZE 4096
static AudioDeviceID gOutputDeviceID;
static float OutputDataBuf[BUF_SIZE];
static int OutputWroteSamples = 0;
static pthread_mutex_t mutexOutput;
static pthread_cond_t condOutput;
static int audioPlaybackStarted = 0;
static int coreaudio_has_output_device = 0;
static int coreaudio_init = 0;
OSStatus PlaybackIOProc(AudioDeviceID inDevice,
const AudioTimeStamp *inNow,
const AudioBufferList *inInputData,
const AudioTimeStamp *inInputTime,
AudioBufferList *outOutputData,
const AudioTimeStamp *inOutputTime,
void *inClientData)
{
float *bufPtr = outOutputData->mBuffers[0].mData;
int i;
pthread_mutex_lock(&mutexOutput);
for (i = 0; i < OutputWroteSamples; i++)
bufPtr[i] = OutputDataBuf[i];
for ( ; i < BUF_SIZE; i++)
bufPtr[i] = 0;
OutputWroteSamples = 0;
pthread_mutex_unlock(&mutexOutput);
pthread_cond_signal(&condOutput);
return (kAudioHardwareNoError);
}
/*
* This is called to reset the device status.
* Returns -2 to indicate the device failed to initialize;
* returns -1 means any of rate/size/{mono,stereo} mismatched.
*/
gint open_macosx_audio() {
#define LEN_DEVICE_NAME 64
OSStatus status;
UInt32 propertySize, bufferByteCount;
char deviceName[LEN_DEVICE_NAME];
struct AudioStreamBasicDescription streamDesc;
int rval;
/*
* We only need to do this once, the rest are taken cared by
* disable/enable calback.
*/
if (coreaudio_init) {
return (0);
}
/* get default output device */
propertySize = sizeof(gOutputDeviceID);
status = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice,
&propertySize,
&gOutputDeviceID);
if (status) {
fprintf(stderr, "get default output device failed, status = %d\n",
(int)status);
return (-2);
}
if (gOutputDeviceID != kAudioDeviceUnknown) {
/* got default output device */
coreaudio_has_output_device = 1;
/* get output device name */
propertySize = sizeof(char)*LEN_DEVICE_NAME;
status = AudioDeviceGetProperty(gOutputDeviceID,
1,
0,
kAudioDevicePropertyDeviceName,
&propertySize,
deviceName);
if (status) {
fprintf(stderr, "get device name failed, status = %d\n",
(int)status);
return (-2);
}
/* get output format */
propertySize = sizeof(struct AudioStreamBasicDescription);
status = AudioDeviceGetProperty(gOutputDeviceID,
1,
0,
kAudioDevicePropertyStreamFormat,
&propertySize,
&streamDesc);
if (status) {
fprintf(stderr, "get device property failed, status = %d\n",
(int)status);
return (-2);
}
if ((streamDesc.mSampleRate != 44100.0) ||
(streamDesc.mFormatID != kAudioFormatLinearPCM) ||
!(streamDesc.mFormatFlags & kLinearPCMFormatFlagIsFloat) ||
(streamDesc.mChannelsPerFrame != 2))
{
fprintf (stderr, "unsupported device.\n");
return (-2);
}
/* set buffer size */
bufferByteCount = BUF_SIZE * sizeof(float);
propertySize = sizeof(bufferByteCount);
status = AudioDeviceSetProperty(gOutputDeviceID,
0,
0,
0,
kAudioDevicePropertyBufferSize,
propertySize,
&bufferByteCount);
if (status) {
fprintf(stderr, "set device property failed, status = %d\n",
(int)status);
}
/*
fprintf(stderr, "using device %s for output:\n", deviceName);
fprintf(stderr, "\twith sample rate %f, %ld channels and %ld-bit sample\n",
streamDesc.mSampleRate,
streamDesc.mChannelsPerFrame,
streamDesc.mBitsPerChannel);
*/
rval = pthread_mutex_init(&mutexOutput, NULL);
if (rval) {
fprintf(stderr, "mutex init failed\n");
return (-1);
}
rval = pthread_cond_init(&condOutput, NULL);
if (rval) {
fprintf(stderr, "condition init failed\n");
return (-1);
}
/* Registers PlaybackIOProc with the device without activating it. */
status = AudioDeviceAddIOProc(gOutputDeviceID, PlaybackIOProc, (void *)1);
}
if (!coreaudio_has_output_device) {
fprintf(stderr, "unknown output device.\n");
return (-2);
}
/* Indicates the initialization is done */
coreaudio_init = 1;
abuf_size = DEFAULT_BUFFER_SIZE;
return 0;
}
void audio_close()
{
OSStatus status;
if (coreaudio_has_output_device && audioPlaybackStarted) {
status = AudioDeviceStop(gOutputDeviceID, PlaybackIOProc);
audioPlaybackStarted = 0;
}
return;
}
int audio_write( void *buffer, int buf_size )
{
OSStatus status;
float scale = 1.0 / SHRT_MAX;
int remain_to_write = buf_size;
if (!coreaudio_has_output_device)
return -1;
if (!audioPlaybackStarted) {
status = AudioDeviceStart(gOutputDeviceID, PlaybackIOProc);
audioPlaybackStarted = 1;
}
while (remain_to_write)
{
pthread_mutex_lock(&mutexOutput);
while(OutputWroteSamples == BUF_SIZE)
pthread_cond_wait(&condOutput, &mutexOutput);
{
short *src_data = (short *)buffer + (buf_size - remain_to_write) / sizeof(short);
float *dst_data = OutputDataBuf + OutputWroteSamples;
int src_samples = remain_to_write / sizeof(short);
int dst_samples = BUF_SIZE - OutputWroteSamples;
int n = (dst_samples < src_samples) ? dst_samples : src_samples;
int i;
for (i = 0; i < n; i++)
dst_data[i] = scale * src_data[i];
OutputWroteSamples += n;
remain_to_write -= n * sizeof(short);
}
pthread_mutex_unlock(&mutexOutput);
}
return (buf_size);
}
#endif
#if defined(linux) || defined(__FreeBSD__)
/* open the sound-device of linux and set cd-quality */
gint open_linux_audio(gchar *dev) {
gint audio;
gint tmp;
gint samplesize = 16;
gint dsp_stereo = 1;
gint dsp_speed = 44100;
gint flags;
/* First try open with O_NONBLOCK so it doesn't hang */
audio = open (dev, (O_WRONLY | O_NONBLOCK),0);
if (audio == -1) {
/* error opening sound device */
return -1;
}
/* now undo NONBLOCK setting again */
flags = fcntl(audio,F_GETFL);
fcntl(audio,F_SETFL,flags & ~O_NONBLOCK);
tmp = samplesize;
ioctl(audio, SNDCTL_DSP_SAMPLESIZE, &samplesize);
if (tmp != samplesize) {
/* error setting samplesize */
g_warning("Unable to set samplesize to 16 bit\n");
return -1;
}
if (ioctl (audio, SNDCTL_DSP_STEREO, &dsp_stereo)==-1) {
g_warning("Unable to set audio to stereo\n");
return -1;
}
if (ioctl (audio, SNDCTL_DSP_SPEED, &dsp_speed) == -1) {
g_warning("Unable to set audio to 44.1 kHz\n");
return -1;
}
if (ioctl (audio, SNDCTL_DSP_GETBLKSIZE, &abuf_size) == -1) {
g_warning("Unable to get blocksize for audio-device\n");
return -1;
}
return audio;
}
#endif
#if defined(sun) || defined(__OpenBSD__)
/* open the sound-device of solaris and set cd-quality */
gint open_solaris_audio(gchar *dev) {
gint audio;
audio_info_t info;
gint flags;
/* First try open with O_NONBLOCK so it doesn't hang */
if ((audio = open(dev, (O_WRONLY | O_NONBLOCK))) == -1) {
/* error opening sound device */
return -1;
}
/* now undo NONBLOCK setting again */
flags = fcntl(audio,F_GETFL);
fcntl(audio,F_SETFL,flags & ~O_NONBLOCK);
abuf_size = DEFAULT_BUFFER_SIZE;
AUDIO_INITINFO(&info);
info.play.sample_rate = 44100;
info.play.channels = 2;
info.play.precision = 16;
info.play.encoding = AUDIO_ENCODING_LINEAR;
info.play.buffer_size = abuf_size;
#ifndef __OpenBSD__
info.output_muted = 0;
#endif
if (ioctl(audio, AUDIO_SETINFO, &info) == -1) {
g_warning("Unable to set audio parameters\n");
return -1;
}
return audio;
}
#endif
#ifdef aix
/* open the audio device of an IBM RS/6000 with AIX Ultimedia Services
and set cd-quality */
gint open_aix_audio(gchar *dev) {
audio_init ainfo;
audio_control acontrol;
audio_change achange;
gint audio;
if (strlen (dev) == 0) {
if(getenv("AUDIODEV")) {
strcpy (dev, getenv("AUDIODEV"));
audio = open (dev, O_WRONLY);
} else {
/* Try to use the device of a machine with PCI bus */
strcpy (dev, "/dev/paud0/1");
audio = open (dev, O_WRONLY);
if ((audio == -1) & (errno == ENOENT)) {
/* Try the device of a machine with MCA */
/* bus as last default */
strcpy (dev, "/dev/baud0/1");
audio = open (dev, O_WRONLY);
}
}
} else {
/* Try the device given in the commandline */
audio = open (dev, O_WRONLY);
}
if(dev < 0) {
/* error opening audio device */
return -1;
}
/* Initialize the default audio description */
/* (the size of the buffer is given in msec) */
memset (&ainfo, '\0', sizeof (audio_init));
ainfo.srate = 44100;
ainfo.channels = 2;
ainfo.mode = PCM;
ainfo.bits_per_sample = 16;
ainfo.flags = BIG_ENDIAN | TWOS_COMPLEMENT;
ainfo.operation = PLAY;
ainfo.bsize = 8 * 1000 *DEFAULT_BUFFER_SIZE
/ (ainfo.srate * ainfo.channels * ainfo.bits_per_sample);
if (ioctl (audio, AUDIO_INIT, &ainfo) == -1) {
g_warning("Unable to set default audio parameters\n");
return -1;
}
memset ( & acontrol, '\0', sizeof (acontrol));
/* Tell the audio device to start output */
acontrol.ioctl_request = AUDIO_START;
acontrol.request_info = NULL;
acontrol.position = 0;
if (ioctl (audio, AUDIO_CONTROL, & acontrol) == -1) {
g_warning("Unable to start audio operation\n");
return -1;
}
abuf_size = DEFAULT_BUFFER_SIZE;
memset ( & achange, '\0', sizeof (achange));
memset ( & acontrol, '\0', sizeof (acontrol));
/* set the output to line out + internal speaker */
/* else the output device will be set to the predifined */
/* value in the cde environment. */
achange.balance = AUDIO_IGNORE;
achange.balance_delay = AUDIO_IGNORE;
achange.volume = AUDIO_IGNORE;
achange.volume_delay = AUDIO_IGNORE;
achange.input = AUDIO_IGNORE;
achange.output = EXTERNAL_SPEAKER;
/* achange.output = INTERNAL_SPEAKER */
/* achange.output = OUTPUT_1 */
achange.treble = AUDIO_IGNORE;
achange.bass = AUDIO_IGNORE;
achange.pitch = AUDIO_IGNORE;
achange.monitor = AUDIO_IGNORE;
achange.dev_info = (char *) NULL;
acontrol.ioctl_request = AUDIO_CHANGE;
acontrol.position = 0;
acontrol.request_info = (char *) & achange;
/* if ((mix = open(setupdata.mix_device, O_RDWR)) == -1) {
g_warning("Can't open mixer-device %s\n", setupdata.mix_device);
return -1;
}*/
if (ioctl (audio, AUDIO_CONTROL, & acontrol) == -1) {
g_warning("Error writing mixer\n");
return -1;
}
return audio;
}
#endif
#ifdef hpux
# ifndef hpux_alib
/* open the audio device on a HP9000 with HP-UX and set cd-quality */
gint open_hpux_audio(gchar *dev) {
gint audio;
audio = open (dev, O_WRONLY | O_NONBLOCK);
if (audio == -1) {
/* error opening audio device */
return -1;
}
if (ioctl(audio, AUDIO_SET_DATA_FORMAT,
AUDIO_FORMAT_LINEAR16BIT) == -1) {
g_warning("Unable to set samplesize to 16 bit\n");
return -1;
}
if (ioctl (audio, AUDIO_SET_CHANNELS, 2)==-1) {
g_warning("Unable to set audio to stereo\n");
return -1;
}
if (ioctl (audio, AUDIO_SET_SAMPLE_RATE, 44100) == -1) {
g_warning("Unable to set audio to 44.1 kHz\n");
return -1;
}
abuf_size = DEFAULT_BUFFER_SIZE;
return audio;
}
# else
/* Some global variables for the hp-ux audio lib */
/* Code mostly taken from simpleAudio.c sample of hpux */
static Audio *audioServer = (Audio *) NULL;
static struct protoent *tcpProtocolEntry;
gint open_hpux_audio(gchar *dev) {
int streamSocket;
long status;
SSPlayParams playParams;
AGainEntry gainEntry[4];
AudioAttrMask AttribsMask;
AudioAttributes Attribs;
SStream audioStream;
int i;
ATransID xid;
/* a_name specifies the audio controller name as a string. */
/* We specify NULL, so the value of the AUDIO environment */
/* variable is used. */
char a_name = '\0';
/* open audio connection */
audioServer = AOpenAudio(&a_name, NULL);
if (audioServer == NULL) {
/* error opening audio device */
g_warning("Unable to open audio device\n");
return -1;
}
tcpProtocolEntry=getprotobyname("tcp");
streamSocket = socket (AF_INET, SOCK_STREAM, 0);
if( streamSocket < 0 ) {
g_warning("Unable to request audio socket stream\n");
return -1;
}
/* Set the default audio description */
Attribs.type = ATSampled;
Attribs.attr.sampled_attr.sampling_rate = 44100;
Attribs.attr.sampled_attr.channels = 2;
Attribs.attr.sampled_attr.data_format = ADFLin16;
AttribsMask = ASSamplingRateMask | ASChannelsMask | ASDataFormatMask;
/* Use the transmit gain and the output channel defined */
/* by the SPEAKER environment */
gainEntry[0].u.o.out_ch = AOCTMono;
gainEntry[0].gain = AUnityGain;
gainEntry[0].u.o.out_dst = AODTDefaultOutput;
playParams.gain_matrix.type = AGMTOutput;
playParams.gain_matrix.num_entries = 1;
playParams.gain_matrix.gain_entries = gainEntry;
playParams.play_volume = AUnityGain;
playParams.priority = APriorityNormal;
playParams.event_mask = 0;
/* Create an audio stream */
xid = APlaySStream( audioServer, AttribsMask, &Attribs,
&playParams, &audioStream, NULL);
/* Connect the stream socket to the audio stream port */
status = connect( streamSocket, (struct sockaddr *)&audioStream.tcp_sockaddr,
sizeof(struct sockaddr_in));
if (status < 0) {
printf ("Errno: %d\n", errno);
g_warning ("Connection of an audio stream socket failed\n");
/* close (streamSocket);*/
return -1;
}
/* Tell TCP to not delay sending data written to this socket */
i = -1;
setsockopt( streamSocket, tcpProtocolEntry->p_proto, TCP_NODELAY,
&i, sizeof(i) );
abuf_size = DEFAULT_BUFFER_SIZE;
return (streamSocket);
}
# endif
#endif
#if defined(__sgi)
static ALport irixAudioPort = NULL; /* Our interface to SGI audio device */
static int irixAudioRate = 44100; /* The samples rate */
gint open_irix_audio(gchar *devName) {
ALvalue v [1];
ALpv pv [2], q [1];
ALconfig audioConfig;
int dev;
if (irixAudioPort != NULL) /* The device is already open. */
return 0;
/* Find the selected audio device */
if (devName[0] == '\0') {
dev = AL_DEFAULT_OUTPUT;
}
else {
q[0].param = AL_LABEL;
q[0].value.ptr = devName;
q[0].sizeIn = strlen(devName) + 1;
if (alQueryValues(AL_SYSTEM, AL_DEVICES, v, 1, q, 1) <= 0) {
g_warning("Invalid audio port name\n");
return -1;
}
dev = v[0].i;
}
/* Allocate a config structure */
audioConfig = alNewConfig();
/* Set the audio device */
if (alSetDevice(audioConfig, dev) < 0) {
g_warning("Unable to set the audio device\n");
return -1;
}
/* Set the buffer size to contain 1/2 second of samples */
abuf_size = irixAudioRate;
if (alSetQueueSize(audioConfig, abuf_size / 2) < 0) {
g_warning("Unable to set queue size\n");
return -1;
}
/* Set the samples width */
if (alSetWidth(audioConfig, AL_SAMPLE_16) < 0) {
g_warning("Unable to set sample size to 16 bit\n");
return -1;
}
/* Set the number of channels */
if (alSetChannels(audioConfig, AL_STEREO) < 0) {
g_warning("Unable to set audio to stereo\n");
return -1;
}
/* Open the audio port */
if ((irixAudioPort = alOpenPort("wavplay", "w", audioConfig) ) == NULL) {
g_warning("Unable to open audio port\n");
return -1;
}
/* Set the samples rate */
pv[0].param = AL_RATE;
pv[0].value.ll = alDoubleToFixed((double) irixAudioRate);
if (alSetParams(dev, pv, 1) < 0 ) {
g_warning("Unable to set audio to 44.1 kHz\n");
return -1;
}
return 0;
}
void close_irix_audio() {
if (irixAudioPort != NULL) {
(void) alClosePort(irixAudioPort);
irixAudioPort = NULL;
}
}
void write_irix_audio(void *buffer, int bufferSize) {
int frames = bufferSize / 4;
while (alGetFillable(irixAudioPort) < frames) {
usleep(100);
}
if (alWriteFrames(irixAudioPort, buffer, frames) < 0) {
g_warning("Error while writing to the audio port\n");
}
}
#endif
/* print usage info */
void usage(gchar *cmd) {
g_print("Usage: %s [options] filename (Version: %s)\n", cmd, XCDROAST_VERSION);
g_print("Options:\n");
g_print(" -d audio-device\n");
g_print(" -g : gui-mode\n");
g_print(" -q : quiet-mode\n");
}
/* main programm */
gint main(gint argc, gchar **argv) {
gint c;
gchar audio_dev[MAXLINE];
gchar wavname[MAXLINE];
gint audio = -1;
gint fd;
gint l;
gint guimode = 0;
gint quiet = 0;
gint doplay = 1;
gint tick = 0;
gint oldtick = 0;
off_t bytessofar = 0;
off_t totalbytes;
struct stat stat_buf;
gint min,sec;
gchar keybuffer[MAXLINE];
#if !(defined(linux))
gint ii;
guchar tmpswap;
#endif
/* if no device given, set default device */
strcpy(audio_dev,DEFAULT_AUDIO_DEVICE);
strcpy(wavname,"");
while ((c = getopt(argc, argv, "d:gq")) != EOF)
switch ((gchar)c) {
case 'd':
strncpy(audio_dev,optarg,MAXLINE);
break;
case 'g':
guimode = 1;
quiet = 1;
break;
case 'q':
quiet = 1;
break;
default:
usage(argv[0]);
exit(1);
}
/* additional parameter given? */
if (optind > argc -1) {
usage(argv[0]);
exit(1);
} else {
strncpy(wavname,argv[optind++],MAXLINE);
}
/* the open sets also the global abuf_size-variable */
#if defined(linux) || defined(__FreeBSD__)
audio = open_linux_audio(audio_dev);
#endif
#if defined(sun) || defined(__OpenBSD__)
audio = open_solaris_audio(audio_dev);
#endif
#ifdef aix
audio = open_aix_audio(audio_dev);
#endif
#ifdef hpux
audio = open_hpux_audio(audio_dev);
#endif
#if (defined(__MACH__) && defined(__APPLE__))
audio = open_macosx_audio();
#endif
#if defined(__sgi)
audio = open_irix_audio(audio_dev);
#endif
if (audio < 0) {
g_warning("Can't init sound-system\n");
exit(1);
}
if ((audiobuf = (guchar *)g_new(guchar *,abuf_size)) == NULL) {
g_warning("Unable to allocate audio-buffer\n");
exit(1);
}
/* open wavfile */
fd = open (wavname, O_RDONLY, 0);
if (fd == -1) {
#if !(defined(__MACH__) && defined(__APPLE__))
close(audio);
#endif
g_warning("Can't open wav-file\n");
exit(1);
}
/* get filesize */
fstat(fd, &stat_buf);
totalbytes = (off_t) (stat_buf.st_size - (off_t)sizeof(waveHdr));
read(fd, &waveHdr, sizeof(waveHdr));
/* is it a wav-file? */
if (!is_std_wav_file(waveHdr)) {
g_warning("No valid wavfile\n");
exit(0);
}
/* is it in cd-quality? */
if (!is_in_cd_quality(waveHdr)) {
g_warning("wavfile not in cd-quality\n");
exit(0);
}
if (!quiet) {
min = (gint) (totalbytes/(CDDAFRAME*75*60));
sec = (gint) ((totalbytes/CDDAFRAME) % (60*75))/75;
g_print("Playing: %s [%d:%02d]\n", wavname,
min,sec);
}
if (guimode) {
/* in gui-mode we communicate via stdin and stdout */
/* stdin must be nonblocking */
fcntl(STDIN_FILENO,F_SETFL,O_NONBLOCK);
/* update display */
g_print("secs%d\n",(gint) (totalbytes/CDDAFRAME)/75);
fflush(stdout);
}
/* ok..all set now, start playing */
while (1) {
/* guimode: look for commands from stdin */
if (guimode && (read_line(STDIN_FILENO,keybuffer,MAXLINE) > 0)) {
/* stop command */
if (g_strncasecmp(keybuffer,"stop",4) == 0) {
lseek(fd, sizeof(waveHdr), SEEK_SET);
bytessofar = 0;
tick = 0;
doplay = 0;
g_print("stop0\n");
fflush(stdout);
}
/* play command */
if (g_strncasecmp(keybuffer,"play",4) == 0) {
doplay = 1;
}
/* pause command */
if (g_strncasecmp(keybuffer,"pause",5) == 0) {
doplay=1-doplay;
g_print("%s%d\n",doplay?"play":"stop",tick);
fflush(stdout);
}
/* setxxx command */
if (g_strncasecmp(keybuffer,"set",3) == 0) {
tick = atoi(keybuffer+3);
bytessofar = (off_t)tick *CDDAFRAME*75;
lseek(fd, (off_t)sizeof(waveHdr)+bytessofar,
SEEK_SET);
g_print("%s%d\n",doplay?"play":"stop",tick);
fflush(stdout);
}
/* quit command */
if (g_strncasecmp(keybuffer,"quit",4) == 0) {
break;
}
}
/* we are in play mode right now */
if (doplay) {
/* read from wav-file */
l = read(fd, audiobuf, abuf_size);
if (l > 0) {
#if !(defined(linux))
/* turn byte order only on non linux platforms */
/* linux on spark wont work with that */
if (G_BYTE_ORDER == G_BIG_ENDIAN) {
/* turn endian-ness */
for (ii=0; ii<l; ii+=2) {
tmpswap=audiobuf[ii];
audiobuf[ii]=audiobuf[ii+1];
audiobuf[ii+1]=tmpswap;
}
}
#endif
if (guimode) {
/* at which second are we right now? */
tick=(gint)(bytessofar/CDDAFRAME/75);
if (tick != oldtick) {
g_print("play%d\n",tick);
fflush(stdout);
oldtick = tick;
}
}
#if (defined(__MACH__) && defined(__APPLE__))
audio_write(audiobuf,l);
#elif defined(__sgi)
write_irix_audio(audiobuf, l);
#else
if (write(audio, audiobuf, l) != l) {
g_print("write error to audio-device\n");
exit(-1);
}
#endif
bytessofar+=(off_t)abuf_size;
} else {
/* read error on wav-file */
if (l == -1) {
g_print("read error on wav-file\n");
exit(-1);
}
/* EOF reached */
doplay = 0;
if (guimode) {
/* roll back */
lseek(fd, sizeof(waveHdr), SEEK_SET);
bytessofar = 0;
tick = 0;
g_print("done%d\n",tick);
fflush(stdout);
} else {
break;
}
}
} else {
/* we are in pause-mode */
/* wait a short while and then look for commands again */
usleep(100);
}
}
close(fd);
#if (defined(__MACH__) && defined(__APPLE__))
audio_close();
#elif defined(__sgi)
close_irix_audio();
#else
close(audio);
#endif
#if (defined hpux) && (defined hpux_alib)
ASetCloseDownMode( audioServer, AKeepTransactions, NULL );
ACloseAudio( audioServer, NULL );
#endif
return 0;
}