home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / MM1 / SOUNDUTILS / mm1_tracker.lzh / TRACKER4.6 / Hpux / alib_audio.c < prev    next >
Text File  |  1994-11-24  |  8KB  |  361 lines

  1. /* hpalib_audio.c 
  2.     vi:ts=3 sw=3:
  3.  */
  4.  
  5. /* port to hp using the Alib library */
  6. /* $Id: hpux_audio.c,v 1.2 1993/12/04 16:12:50 espie Exp espie $
  7.  * $Log: hpux_audio.c,v $
  8.  * Revision 1.2  1993/12/04  16:12:50  espie
  9.  * BOOL -> boolean.
  10.  *
  11.  * Revision 1.1  1993/07/14  16:33:41  espie
  12.  * Initial revision
  13.  *
  14.  */
  15.  
  16. #include <malloc.h>
  17. #include <stdio.h>
  18. #include "defs.h"
  19. #include "extern.h"
  20. #include <audio/Alib.h>
  21. #include <sys/socket.h>
  22. #include <netinet/in.h>
  23. #include <netinet/tcp.h>
  24.  
  25. ID("$Id: hpux_audio.c,v 1.2 1993/12/04 16:12:50 espie Exp espie $")
  26.  
  27.  
  28. Audio    *audio;        /* AUDIO connection for Alib, like DISPLAY for Xlib */
  29.  
  30. LOCAL int stereo;        /* are we playing stereo or not? */
  31. LOCAL int freq;            /* which frequency do we want? */
  32.  
  33. LOCAL int primary, secondary;    /* 256th of primary/secondary source for */
  34.                 /* that side. */
  35. AErrorHandler    prevHandler;    /* pointer to previous handler */    
  36.  
  37. LOCAL int    audioPaused = True;
  38. LOCAL int    streamSocket = 0;
  39. LOCAL int    pauseCount;
  40.  
  41. LOCAL short    *inBuf = NULL, *bufBase = NULL;
  42. LOCAL int    inBufIndex = 0;
  43. LOCAL long    inLen;
  44.  
  45. LOCAL ATransID    xid;
  46.  
  47. LOCAL AConvertParams    *convert_params;
  48.  
  49. LOCAL AudioAttrMask    AttribsMask = 0, PlayAttribsMask = 0, ignoredMask = 0;
  50. LOCAL AudioAttributes    Attribs, PlayAttribs;
  51. LOCAL AGainEntry    gainEntry[4];    /* Need to be global since */
  52.                     /* PlayAttribs is global and it */
  53.                     /* contains a pointer to gainEntry */
  54. LOCAL SSPlayParams    streamParams;
  55.  
  56.  
  57.  
  58. long myErrorHandler(audio, err_event)
  59.     Audio        *audio;
  60.     AErrorEvent    *err_event;
  61. {
  62.     char    errorbuf[132];
  63.  
  64.     AGetErrorText(audio, err_event->error_code, errorbuf, 131);
  65.      end_all(errorbuf);
  66. }
  67.  
  68.  
  69. void set_mix(percent)
  70. int percent;
  71. {
  72.     percent = (percent * 256) / 100;
  73.     primary = percent;
  74.     secondary = 512 - percent;
  75. }
  76.  
  77.  
  78. void create_playstream()
  79. {
  80.     LOCAL SStream    audioStream;
  81.  
  82.     /*
  83.      * Initiate transaction.
  84.      */
  85.     xid = APlaySStream(audio, ~0, &PlayAttribs, &streamParams,
  86.                &audioStream, NULL);
  87.  
  88.     /*
  89.      * Create a stream socket.
  90.      */
  91.     streamSocket = socket(AF_INET, SOCK_STREAM, 0);
  92.     if(streamSocket < 0) {
  93.      end_all("Socket creation failed");
  94.     }
  95.   
  96.     /*
  97.      * Connect the stream socket to the audio stream port.
  98.      */
  99.     if (connect(streamSocket,
  100.         (struct sockaddr *)&audioStream.tcp_sockaddr,
  101.         sizeof(struct sockaddr_in)) < 0) {
  102.         end_all("Connect failed");
  103.     }
  104. }  
  105.  
  106.  
  107. int open_audio(f, s)
  108. int f;
  109. int s;
  110. {
  111.     char        *pSpeaker;
  112.     int            useIntSpeaker;
  113.     int            seekOffset, data_length;
  114.     AByteOrder        play_byte_order, byte_order;
  115.  
  116.  
  117.     audio = AOpenAudio(NULL, NULL);
  118.  
  119.     if (!audio) {
  120.         end_all("Error opening audio device");
  121.     }
  122.  
  123.     /* replace default error handler */
  124.     prevHandler = ASetErrorHandler(myErrorHandler);
  125.  
  126.     stereo = s;
  127.     if (stereo) {
  128.         Attribs.attr.sampled_attr.channels = 2;
  129.         AttribsMask |= (AttribsMask | ASChannelsMask);
  130.     }
  131.  
  132.     /*
  133.      * Get the best attributes from the server?
  134.      */
  135.     if (f <= 0) {
  136.     AudioAttributes    *bestAttr;
  137.  
  138.     bestAttr = ABestAudioAttributes(audio);
  139.     freq = bestAttr->attr.sampled_attr.sampling_rate;
  140.     } else
  141.     freq = f;
  142.  
  143.     PlayAttribs.attr.sampled_attr.sampling_rate = freq;
  144.     PlayAttribsMask |= ASSamplingRateMask;
  145.  
  146.     Attribs.attr.sampled_attr.sampling_rate = freq;
  147.     AttribsMask |= ASSamplingRateMask;
  148.  
  149.     AChooseSourceAttributes(audio, NULL, NULL, AFFRawLin16,
  150.                 AttribsMask, &Attribs, &seekOffset,
  151.                 &data_length, &byte_order, NULL);
  152.  
  153.     AChoosePlayAttributes(audio, &Attribs, PlayAttribsMask,
  154.               &PlayAttribs, &play_byte_order, NULL);
  155.  
  156.     /*
  157.      * Prepare for conversion.
  158.      * Must remember to free convert_params by calling AEndConversion.
  159.      */
  160.     convert_params = ASetupConversion(audio, &Attribs, &byte_order,
  161.                       &PlayAttribs, &play_byte_order, NULL);
  162.  
  163.     pSpeaker = getenv("SPEAKER");    /* get user speaker preference */
  164.     if (pSpeaker) {
  165.     useIntSpeaker = (*pSpeaker == 'i' || *pSpeaker == 'I');
  166.     } else {
  167.     /*
  168.      * SPEAKER env.var not found - use internal speaker.
  169.      */  
  170.     useIntSpeaker = 1;
  171.     }
  172.  
  173.     switch (PlayAttribs.attr.sampled_attr.channels) {
  174.  
  175.     case 1:    /* Mono */
  176.     gainEntry[0].u.o.out_ch = AOCTMono;
  177.     gainEntry[0].gain = AUnityGain;
  178.     gainEntry[0].u.o.out_dst
  179.         = (useIntSpeaker) ? AODTMonoIntSpeaker : AODTMonoJack;
  180.     break;
  181.  
  182.     case 2:    /* Stereo */
  183.     default:
  184.     gainEntry[0].u.o.out_ch = AOCTLeft;
  185.     gainEntry[0].gain = AUnityGain;
  186.     gainEntry[0].u.o.out_dst
  187.         = (useIntSpeaker) ? AODTLeftIntSpeaker : AODTLeftJack;
  188.     gainEntry[1].u.o.out_ch = AOCTRight;
  189.     gainEntry[1].gain = AUnityGain;
  190.     gainEntry[1].u.o.out_dst
  191.         = (useIntSpeaker) ? AODTRightIntSpeaker : AODTRightJack;
  192.     break;
  193.     }
  194.     streamParams.gain_matrix.type = AGMTOutput;    /* gain matrix */
  195.     streamParams.gain_matrix.num_entries
  196.     = PlayAttribs.attr.sampled_attr.channels;
  197.     streamParams.gain_matrix.gain_entries = gainEntry;
  198.     streamParams.play_volume = AUnityGain;    /* play volume */
  199.     streamParams.priority = APriorityNormal;    /* normal priority */
  200.     streamParams.event_mask = 0;        /* don't solicit any events */
  201.  
  202.     /*
  203.      * Create an audio stream.
  204.      */
  205.     create_playstream();
  206.  
  207.     /*
  208.      * Calculate the required buffer size for the data prior to conversion
  209.      * and allocate memory for the pre-converted data.
  210.      */
  211.     inLen = ACalculateLength(audio, audio->block_size,
  212.                  &PlayAttribs, &Attribs, NULL); 
  213.     inBuf = malloc(inLen);
  214.     inBufIndex = 0;
  215.  
  216.     /*
  217.      * Allocate a buffer for the converted data.
  218.      */
  219.     bufBase = malloc(inLen);
  220.  
  221.     /*
  222.      * Start stream paused so we can transfer enough data (3 seconds worth)
  223.      * before playing starts to prevent stream from running out.
  224.      */
  225.     APauseAudio(audio, xid, NULL, NULL);
  226.     pauseCount = 3
  227.         * PlayAttribs.attr.sampled_attr.channels
  228.         * PlayAttribs.attr.sampled_attr.sampling_rate
  229.         * (PlayAttribs.attr.sampled_attr.bits_per_sample >> 3);
  230.     audioPaused = True;
  231.  
  232.     freq = PlayAttribs.attr.sampled_attr.sampling_rate;
  233.  
  234.     if (freq != f)
  235.         {
  236.         static char buf[50];
  237.         sprintf(buf, "Frequency used is %d\n", freq);
  238.         notice(buf);
  239.         }
  240.  
  241.     set_mix(30);
  242.  
  243.     return freq;
  244. }
  245.  
  246.  
  247. void output_samples(left, right)
  248. int left, right;
  249. {
  250.     if (inBufIndex > inLen - 2)
  251.     flush_buffer();
  252.  
  253.     if (stereo) {
  254.         inBuf[inBufIndex++] = (left * primary + right * secondary) / 256;
  255.         inBuf[inBufIndex++] = (right * primary + left * secondary) / 256;
  256.     } else {
  257.         inBuf[inBufIndex++] = left + right;
  258.     }
  259. }
  260.  
  261.  
  262. void discard_buffer()
  263. {
  264.     /*
  265.      * Destroy old playstream.
  266.      */
  267.     AStopAudio(audio, xid, ASMThisTrans, NULL, NULL);
  268.     close(streamSocket);
  269.     streamSocket = 0;
  270.  
  271.     /*
  272.      * Recreate new playstream.
  273.      */
  274.     create_playstream();
  275.     inBufIndex = 0;
  276. }
  277.  
  278.  
  279. void flush_buffer()
  280. {
  281.     int        len_written = 0, len, bytes_written, bytes_read;
  282.     short    *buf = inBuf;
  283.  
  284.     /*
  285.      * Convert buffer
  286.      */
  287.     AConvertBuffer(audio, convert_params, inBuf, inBufIndex * sizeof(short),
  288.            bufBase, inLen, &bytes_read, &bytes_written, NULL);
  289.     len = bytes_written;
  290.     buf = bufBase;    
  291.  
  292.     /*
  293.      * Write the converted data to the stream socket
  294.      */
  295.     while (len) {
  296.         /*
  297.      * write converted data to stream socket until we have emptied buffer
  298.      */
  299.     if ((len_written = write(streamSocket, buf, len)) < 0) {
  300.         end_all("Write failed");
  301.         }
  302.     buf += len_written;
  303.     len -= len_written;
  304.  
  305.     if (audioPaused) {
  306.         pauseCount -= len_written;
  307.         if (len_written == 0 || pauseCount <= 0) {
  308.         AResumeAudio(audio, xid, NULL, NULL);
  309.         audioPaused = False;
  310.         }
  311.     }
  312.     }
  313.     inBufIndex = 0;
  314. }
  315.  
  316.  
  317. void close_audio()
  318. {
  319.     int        bytes_written;
  320.  
  321.  
  322.     if (audioPaused) {
  323.     AResumeAudio(audio, xid, NULL, NULL);
  324.     }
  325.     /*
  326.      * Free the convert_params structure and flush out
  327.      * the conversion pipeline
  328.      */
  329.     AEndConversion(audio, convert_params, bufBase,
  330.            audio->block_size, &bytes_written, NULL);
  331.  
  332.     ASetCloseDownMode(audio, AKeepTransactions, NULL);
  333.     ASetErrorHandler(prevHandler);
  334.     ACloseAudio(audio, NULL);
  335.  
  336.     if (streamSocket)    close(streamSocket);
  337.     if (inBuf)        free(inBuf);
  338.     if (bufBase)    free(bufBase);
  339.  
  340.     end_all(0);
  341. }
  342.  
  343.  
  344. int update_frequency()
  345. {
  346.     /* not implemented */
  347.     return 0;
  348. }
  349.  
  350.  
  351. void set_synchro(sync)
  352. int sync;
  353. {
  354.     if (streamSocket) {
  355.     if (sync)
  356.         setsockopt(streamSocket, SOL_SOCKET, TCP_NODELAY, 1);
  357.     else
  358.         setsockopt(streamSocket, SOL_SOCKET, TCP_NODELAY, 0);
  359.     }
  360. }
  361.