/* * This file is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify this file without charge, but are not authorized to * license or distribute it to anyone else except as part of a product * or program developed by the user. * * THIS FILE 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. * * This file 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 FILE * 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 */ #include "X.h" #define NEED_REPLIES #include "Xlibint.h" #include "Xproto.h" #include "Xprotostr.h" #include "audio.h" #include #include /* GetReq() is a given Macro in Xlibint.h */ /* Notice : no space allowed between fields */ #define GETAUDIOREQ(dpy,reqname,req) \ if (!code[ConnectionNumber(dpy)] ) \ return(0); \ GetReq(reqname,req); \ req->reqType = code[ConnectionNumber(dpy)]; /* this is storage of Request code on different displays, each server can have different request code for the same extension */ /* 64 file descriptors - hopefully enough for most machines */ int code[] = { 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, }; int Find_req_code(dpy) Display *dpy; { int Rcode; int first_event, first_error; if (code[ConnectionNumber(dpy)] == 0) { XQueryExtension(dpy, AUDIONAME,&Rcode, &first_event, &first_error); code[ConnectionNumber(dpy)] = Rcode; } return( code[ConnectionNumber(dpy)] ); } /* XAudioOpen(dpy) has to be called first before all other audio calls. */ /* * Open the audio port on the server. * returns 1 if opened, 0 if error */ XAudioOpen(dpy) Display *dpy; { xAudio_Reply rep; register xAudio_OpenReq *req; int AudioReqCode = 0; LockDisplay(dpy); AudioReqCode = Find_req_code(dpy); if (AudioReqCode <= 0) return(0); GetReq(Audio_Open, req); req->reqType = AudioReqCode; req->minor_opcode = X_AUDIO_OPEN; if (!_XReply (dpy, (xReply *)&rep, 0, xFalse)) { UnlockDisplay(dpy); SyncHandle(); return(0); } UnlockDisplay(dpy); SyncHandle(); return(rep.opened); } /* * Close the audio port * If there is still data pending, the extension code * will refuse to close till all data are processed. */ XAudioClose(dpy) Display *dpy; { xAudio_Reply rep; register xAudio_CloseReq *req; GETAUDIOREQ(dpy,Audio_Close,req) req->minor_opcode = X_AUDIO_CLOSE; if (!_XReply (dpy, (xReply *)&rep, 0, xFalse)) { SyncHandle(); return(-1); } /* rep.closed = 1 if actually closed */ if (rep.closed) code[ConnectionNumber(dpy)] = 0; return(rep.closed); } /* * Send a buffer to the audio port for playing. */ XAudioPlay(dpy,buffer,sizeofbuffer) Display *dpy; char *buffer; int sizeofbuffer; { xAudio_Reply rep; register long nbytes; register xAudio_PlayReq *req; GETAUDIOREQ(dpy,Audio_Play,req) req->minor_opcode = X_AUDIO_PLAY; /* sizeofbuffer has to be divisable by 4, drop the extras */ nbytes = sizeofbuffer - sizeofbuffer%4; req->length += nbytes >> 2; /* do this here, not in arguments to PackData, since PackData may be a macro which uses its arguments more than once */ #ifdef DEBUG fprintf(stderr,"XAudioPlay:size of buffer=%d\n",nbytes); #endif DEBUG PackData(dpy, buffer, nbytes ); if (!_XReply (dpy, (xReply *)&rep, 0, xFalse)) { SyncHandle(); return(-1); } return(rep.status); } /* * Stop the playing. */ XAudioPlayOff(dpy,forced) Display *dpy; int forced; { register xAudio_Play_OffReq *req; GETAUDIOREQ(dpy,Audio_Play_Off,req) req->minor_opcode = X_AUDIO_PLAY_OFF; req->forced = forced; SyncHandle(); return(1); } /* * Set the volume. * change the play volume and record into 3 registers * that the server takes. */ XAudioSetVolume(dpy, play_volume, record_volume) Display *dpy; int play_volume, record_volume; { int tmp1, tmp2; register xAudio_Set_VolumeReq *req; GETAUDIOREQ(dpy,Audio_Set_Volume,req) req->minor_opcode = X_AUDIO_SET_VOLUME ; tmp1 = play_volume/2; tmp2 = play_volume - tmp1; if (tmp1 < MIN_VOLUME) { tmp1 = -10; tmp2 = play_volume - tmp1; } if (tmp2 > MAX_VOLUME) { tmp2 = 12; tmp1 = play_volume - tmp2; } req->ger = tmp1; req->gr = tmp2; req->gx = record_volume; SyncHandle(); return(1); } /* * Record a buffer full of data. */ XAudioRecord(dpy,buffer) Display *dpy; char *buffer; { register int size; register xAudio_RecordReq *req; xAudio_RecordReply rep; GETAUDIOREQ(dpy,Audio_Record,req) req->minor_opcode = X_AUDIO_RECORD; #ifdef DEBUG fprintf(stderr,"XAudioRecord:\n"); #endif DEBUG if (!_XReply (dpy, (xReply *)&rep, 0, xFalse)) { return(-1); } size= rep.length << 2; #ifdef DEBUG fprintf(stderr,"XAudioRecord:req=%d bytes\n",size); #endif DEBUG _XReadPad (dpy, buffer, (long)size); return(size); } /* * Stop recording - do not read anymore data. */ XAudioRecordOff(dpy) Display *dpy; { register xAudio_Record_OffReq *req; GETAUDIOREQ(dpy,Audio_Record_Off,req) req->minor_opcode = X_AUDIO_RECORD_OFF; SyncHandle(); return(1); }