/*
* simple audio Lib for HPUX
* for use by mpg123
* by Erwan Ducroquet
* from source code by HP
*/
/*
*
* for mpg123 :
* hpux:
* $(MAKE) \
* CC=cc \
* LDFLAGS=-L/opt/audio/lib \
* AUDIO_LIB=-lAlib \
* OBJECTS=decode.o dct64.o \
* CFLAGS=-Ae +O3 -DREAL_IS_FLOAT -D_HPUX_SOURCE -DHPUX -I/opt/audio/include \
* mpg123
*/
/*
* Rem:
* I don't use the "set_rate" and "set_channels" functions
* these are set directly in the "audio_open" function
*
*/
/*
* For the user :
* If you launch mpg123 on a XTerm with sound capabilities, it's OK
* Else, you have to set the environment variable "AUDIO" to the name of
* an HP Xterm with sound card.
*/
/**************************************************************************/
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <errno.h>
#include "mpg123.h"
#include "Alib.h" /* /opt/audio/include */
#include "CUlib.h" /* /opt/audio/include */
/*
*
* used :
*
* int audio_open(struct audio_info_struct *ai);
* int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len);
* int audio_close(struct audio_info_struct *ai);
*
* unused :
*
* int audio_set_rate(struct audio_info_struct *ai);
* int audio_set_channels(struct audio_info_struct *ai);
*
*/
/**************************************************************************/
/*
* Some things used only for HP Audio
*/
static Audio *audioServer = (Audio *) NULL;
static struct protoent *tcpProtocolEntry;
static ATransID xid;
static void printAudioError(Audio *audio,char *message,int errorCode) {
char errorbuff[132];
AGetErrorText(audio, errorCode, errorbuff, 131);
fprintf ( stderr, "%s: %s\n", message, errorbuff);
}
static long myHandler(Audio *audio,AErrorEvent *err_event) {
printAudioError( audio, "Audio error", err_event->error_code );
exit(1);
}
/**************************************************************************/
/*
* Set the fn element of ai
* Use ai->rate and ai->channels
* Doesn't set any volume
*/
int audio_open(struct audio_info_struct *ai) {
AudioAttributes Attribs;
AudioAttrMask AttribsMask;
AGainEntry gainEntry[4];
SSPlayParams playParams;
SStream audioStream;
AErrorHandler prevHandler;
char server[1];
int i;
long status;
if(audioServer)
{fprintf(stderr,"openAudio: audio already open\n");exit(1);}
prevHandler = ASetErrorHandler(myHandler);
server[0] = '\0';
audioServer = AOpenAudio( server, NULL );
if(audioServer==NULL)
{fprintf(stderr,"Error: could not open audio\n");exit(1);}
ai->fn = socket( AF_INET, SOCK_STREAM, 0 );
if(ai->fn<0)
{fprintf(stderr,"Socket creation failed");exit(1);}
Attribs.type = ATSampled;
Attribs.attr.sampled_attr.sampling_rate = ai->rate;
Attribs.attr.sampled_attr.channels = ai->channels;
Attribs.attr.sampled_attr.data_format = ADFLin16;
AttribsMask = ASSamplingRateMask | ASChannelsMask | ASDataFormatMask;
gainEntry[0].gain = AUnityGain;
gainEntry[0].u.o.out_ch = AOCTMono;
gainEntry[0].u.o.out_dst = AODTDefaultOutput;
playParams.gain_matrix.type = AGMTOutput; /* gain matrix */
playParams.gain_matrix.num_entries = 1;
playParams.gain_matrix.gain_entries = gainEntry;
playParams.play_volume = AUnityGain; /* play volume */
playParams.priority = APriorityNormal; /* normal priority */
playParams.event_mask = 0; /* don't solicit any events */
xid=APlaySStream(audioServer,AttribsMask,&Attribs,
&playParams,&audioStream,NULL);
status=connect(ai->fn,
(struct sockaddr *) &audioStream.tcp_sockaddr,
sizeof(struct sockaddr_in) );
if(status<0){fprintf(stderr,"Connect failed");exit(1);}
i=-1;
tcpProtocolEntry=getprotobyname("tcp");
setsockopt(ai->fn,tcpProtocolEntry->p_proto,TCP_NODELAY,&i,sizeof(i));
return ai->fn;
}
/**************************************************************************/
int audio_close(struct audio_info_struct *ai)
{
close(ai->fn);
ASetCloseDownMode( audioServer, AKeepTransactions, NULL );
ACloseAudio( audioServer, NULL );
audioServer = (Audio *) NULL;
return 0;
}
/**************************************************************************/
/*
* very simple
* deserv to be inline
*/
int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len)
{
return write(ai->fn,buf,len*2);
}
/**************************************************************************/
/* unused */
int audio_set_rate(struct audio_info_struct *ai) {
return 0;
}
/**************************************************************************/
/* unused */
int audio_set_channels(struct audio_info_struct *ai) {
return 0;
}
int audio_get_formats(struct audio_info_struct *ai)
{
return AUDIO_FORMAT_SIGNED_16;
}
/**************************************************************************
* T H A T ' S A L L F O L K S
**************************************************************************/