home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / ABUSESRC.ZIP / AbuseSrc / imlib / port / aix / aix_sdrv.c next >
Encoding:
C/C++ Source or Header  |  1996-07-26  |  8.6 KB  |  331 lines

  1. /*
  2.  
  3. AIX UMS sound module.
  4.  
  5. Biggest weirdo thing in here besides the include "gen_drv.c" (legacy)
  6. is that there is a bug in the AIX UMS sound support.  UMS won't play
  7. sound unless there are at least 8k (?) samples submitted.  Because this
  8. is almost a second when playing 8-bit 11kHz mono sound, the latency
  9. would kill the usefulness.  So the sound driver plays at 44kHz in
  10. 16-bit stereo simply so that it can submit 8k chunks without hurting
  11. the sound latency.
  12.  
  13. Seeing as how we were 16-bit, gen_drv.c was modified to support 13-bit
  14. mixing instead of 8-bit.  The clip was deferred until the output step
  15. to avoid an extra pass over the 13-bit buffer.
  16.  
  17. */
  18.  
  19. #include <strings.h>
  20. #include <sys/ipc.h>
  21. #include <sys/shm.h>
  22. #include <signal.h>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <fcntl.h>
  27. #include <unistd.h>
  28. #include <sys/types.h>
  29. #include <sys/time.h>
  30. #include <sys/ioctl.h>
  31. #include <sys/types.h>
  32. #include <sys/stat.h>
  33. #include <sys/select.h>
  34.  
  35. #include <UMSAudioDevice.h>
  36.  
  37. void output_samples(short *buf);
  38. void sound_uninit();
  39. int sound_init();
  40.  
  41. #define BUF_SIZE 512
  42.  
  43. static UMSAudioDevice audio_device;
  44. static UMSAudioTypes_Buffer output_buffer;
  45. static Environment *audio_env;
  46. static int output_buffer_samples;
  47. static float usecs_per_samplepair;
  48. static int samplepair_latency;
  49. static short *output_buffer_data;
  50. static int last_sample;
  51. static char str[1024];
  52.  
  53. #include "gen_drv.c"
  54.  
  55. void output_samples(short *buf)
  56. {
  57.  
  58.     long samplepairs_written;
  59.     long samplepairs_en_route;
  60.     int i;
  61.     int delta;
  62.     int d_prev;
  63.     int d_next;
  64.  
  65.     output_buffer._length = output_buffer._maximum;
  66.  
  67. // translate 13-bit mono 11kHz (1k) output buffer to linearly interpolated
  68. // 16-bit stereo 44kHz output buffer (8k).  for smooth transition between
  69. // buffers, first sample must be remembered from the last buffer.
  70.  
  71.     d_prev = last_sample;
  72.  
  73.     d_next = buf[0] << 3;
  74.     if (d_next < -32768) d_next = -32768;
  75.     else if (d_next > 32767) d_next = 32767;
  76.  
  77.     delta = (d_next - d_prev) >> 2;
  78.     output_buffer_data[0] = d_prev;
  79.     output_buffer_data[2] = output_buffer_data[0] + delta;
  80.     output_buffer_data[4] = output_buffer_data[2] + delta;
  81.     output_buffer_data[6] = output_buffer_data[4] + delta;
  82.     output_buffer_data[1] = output_buffer_data[0];
  83.     output_buffer_data[3] = output_buffer_data[2];
  84.     output_buffer_data[5] = output_buffer_data[4];
  85.     output_buffer_data[7] = output_buffer_data[6];
  86.  
  87.     d_prev = d_next;
  88.  
  89.     for (i=1 ; i<BUF_SIZE ; i++)
  90.     {
  91.  
  92.         d_next = buf[i] << 3;
  93.         if (d_next < -32768) d_next = -32768;
  94.         else if (d_next > 32767) d_next = 32767;
  95.  
  96.         delta = (d_next - d_prev)>>2;
  97.         output_buffer_data[i*8] = d_prev;
  98.         output_buffer_data[i*8+2] = output_buffer_data[i*8] + delta;
  99.         output_buffer_data[i*8+4] = output_buffer_data[i*8+2] + delta;
  100.         output_buffer_data[i*8+6] = output_buffer_data[i*8+4] + delta;
  101.         output_buffer_data[i*8+1] = output_buffer_data[i*8];
  102.         output_buffer_data[i*8+3] = output_buffer_data[i*8+2];
  103.         output_buffer_data[i*8+5] = output_buffer_data[i*8+4];
  104.         output_buffer_data[i*8+7] = output_buffer_data[i*8+6];
  105.  
  106.         d_prev = d_next;
  107.     }
  108.  
  109.     last_sample = d_prev;
  110.  
  111. // an essentially non-blocking write()
  112.     UMSAudioDevice_write(audio_device, audio_env, &output_buffer,
  113.         output_buffer_samples, &samplepairs_written);
  114.  
  115. // simulate a blocking write() with usleep()
  116.     UMSAudioDevice_write_buff_used(audio_device, audio_env,
  117.         &samplepairs_en_route);
  118.     if (samplepairs_en_route > samplepair_latency)
  119.         usleep((int) ((samplepairs_en_route - samplepair_latency)
  120.         * usecs_per_samplepair));
  121.  
  122. }
  123.  
  124. void sound_uninit()
  125. {
  126.     UMSAudioDevice_play_remaining_data(audio_device, audio_env, TRUE);
  127.     UMSAudioDevice_stop(audio_device, audio_env);
  128.     UMSAudioDevice_close(audio_device, audio_env);
  129. }
  130.  
  131. char *newpaths[] = 
  132. {
  133.     "bin",
  134.     "dt/bin",
  135.     "speech/speech_reco/bin",
  136.     "Demos/speech_reco/bin",
  137.     "Demos/tts/bin"
  138. };
  139.  
  140. char *newlibpaths[] =
  141. {
  142.     "lib",
  143.     "speech/speech_reco/lib",
  144.     "Demos/tts/lib"
  145. };
  146.  
  147. void run_ums(void)
  148. {
  149.     char *path, *u;
  150.     int i;
  151.  
  152.     if (!getenv("SOMBASE"))
  153.         putenv("SOMBASE=/usr/lpp/som");
  154.     fprintf(stderr, "SOMBASE=%s\n", getenv("SOMBASE"));
  155.     if (!getenv("UMSDIR"))
  156.         putenv("UMSDIR=/usr/lpp/UMS");
  157.     fprintf(stderr, "UMSDIR=%s\n", getenv("UMSDIR"));
  158.     sprintf(str, "PATH=");
  159.     path = getenv("PATH");
  160.     if (!path || *path==0) path=".";
  161.     strcat(str, path);
  162.     for (i=0 ; i<5 ; i++)
  163.     {
  164.         sprintf(str+512, "%s/%s", getenv("UMSDIR"), newpaths[i]);
  165.         fprintf(stderr, "str+512=[%s]\n", str+512);
  166.         if (!strstr(path, str+512))
  167.         {
  168.             strcat(str, ":");
  169.             strcat(str, str+512);
  170.             fprintf(stderr, "str=[%s]\n", str);
  171.         }
  172.     }
  173.     putenv(str);
  174.     fprintf(stderr, "PATH=%s\n", getenv("PATH"));
  175.  
  176.     sprintf(str, "LIBPATH=");
  177.     path = getenv("LIBPATH");
  178.     if (!path || *path==0) path=".";
  179.     fprintf(stderr, "[[%s]]\n", path);
  180.     strcat(str, path);
  181.     if (!strstr(path, "/usr/lib"))
  182.         strcat(str, ":/usr/lib");
  183.     sprintf(str+512, "%s/lib", getenv("SOMBASE"));
  184.     if (!strstr(path, str+512))
  185.     {
  186.         strcat(str, ":");
  187.         strcat(str, str+512);
  188.     }
  189.     for (i=0 ; i<3 ; i++)
  190.     {
  191.         sprintf(str+512, "%s/%s", getenv("UMSDIR"), newlibpaths[i]);
  192.         if (!strstr(path, str+512))
  193.         {
  194.             strcat(str, ":");
  195.             strcat(str, str+512);
  196.         }
  197.     }
  198.     putenv(str);
  199.     fprintf(stderr, "LIBPATH=%s\n", getenv("LIBPATH"));
  200.  
  201.     sprintf(str, "NLSPATH=");
  202.     path = getenv("NLSPATH");
  203.     if (!path || *path == 0) path=".";
  204.     strcat(str, path);
  205.     sprintf(str+512, "%s/msg/%%N", getenv("SOMBASE"));
  206.     if (!strstr(path, str+512))
  207.     {
  208.         strcat(str, ":");
  209.         strcat(str, str+512);
  210.     }
  211.     putenv(str);
  212.     fprintf(stderr, "NLSPATH=%s\n", getenv("NLSPATH"));
  213.  
  214.     sprintf(str, "SOMIR=");
  215.     path = getenv("SOMIR");
  216.     if (!path || *path == 0) path=".";
  217.     strcat(str, path);
  218.     sprintf(str+512, "%s/etc/UMS.ir", getenv("UMSDIR"));
  219.     if (!strstr(path, str+512))
  220.     {
  221.         strcat(str, ":");
  222.         strcat(str, str+512);
  223.     }
  224.     sprintf(str+512, "%s/etc/som.ir", getenv("UMSDIR"));
  225.     if (!strstr(path, str+512))
  226.     {
  227.         strcat(str, ":");
  228.         strcat(str, str+512);
  229.     }
  230.     putenv(str);
  231.     fprintf(stderr, "SOMIR=%s\n", getenv("SOMIR"));
  232.     putenv("MALLOCTYPE=");
  233. }
  234.  
  235. int sound_init()
  236. {
  237.  
  238.     UMSAudioDeviceMClass audio_device_class;
  239.     char *alias;
  240.     long flags;
  241.     UMSAudioDeviceMClass_ErrorCode audio_device_class_error;
  242.     char *error_string;
  243.     char *audio_formats_alias;
  244.     char *audio_inputs_alias;
  245.     char *audio_outputs_alias;
  246.     int bits_per_sample;
  247.     long out_rate;
  248.     int channels;
  249.     long left_gain;
  250.     long right_gain;
  251.     char *sl;
  252.  
  253. //    run_ums();
  254.  
  255.     audio_env = somGetGlobalEnvironment();
  256.  
  257.     audio_device_class = UMSAudioDeviceNewClass(UMSAudioDevice_MajorVersion,
  258.         UMSAudioDevice_MinorVersion);
  259.     if (audio_device_class == NULL)
  260.     {
  261.         fprintf(stderr, "sound driver: Can't create AudioDeviceMClass metaclass\n");
  262.         return 0;
  263.     }
  264.  
  265.     alias = "Audio";
  266.     flags = UMSAudioDevice_BlockingIO;
  267.  
  268.     audio_device = UMSAudioDeviceMClass_make_by_alias(audio_device_class,
  269.         audio_env, alias, "PLAY", flags, &audio_device_class_error,
  270.         &error_string, &audio_formats_alias, &audio_inputs_alias,
  271.         &audio_outputs_alias);
  272.  
  273.     if (audio_device == NULL)
  274.     {
  275.         fprintf(stderr, "sound driver : Can't create audio device object\n");
  276.         return 0;
  277.     }
  278.  
  279.     channels = 2;
  280.     bits_per_sample = 16;
  281.  
  282.     UMSAudioDevice_set_sample_rate(audio_device, audio_env, 44100, &out_rate);
  283.     UMSAudioDevice_set_bits_per_sample(audio_device, audio_env,
  284.         bits_per_sample);
  285.     UMSAudioDevice_set_number_of_channels(audio_device, audio_env, channels);
  286.  
  287.     if (out_rate != 44100)
  288.     {
  289.         fprintf(stderr, "sound driver : Doesn't support 44.1kHz\n");
  290.         return 0;
  291.     }
  292.  
  293.     UMSAudioDevice_set_audio_format_type(audio_device, audio_env, "PCM");
  294.     UMSAudioDevice_set_byte_order(audio_device, audio_env, "MSB");
  295.     UMSAudioDevice_set_number_format(audio_device, audio_env,
  296.         "TWOS_COMPLEMENT");
  297.     UMSAudioDevice_set_volume(audio_device, audio_env, 100);
  298.     UMSAudioDevice_set_balance(audio_device, audio_env, 0);
  299.  
  300.     output_buffer_samples = BUF_SIZE * 4;
  301.     UMSAudioDevice_set_time_format(audio_device, audio_env,
  302.         UMSAudioTypes_Samples);
  303.  
  304.     left_gain = right_gain = 100;
  305.     UMSAudioDevice_enable_output(audio_device, audio_env, "INTERNAL_SPEAKER",
  306.         &left_gain, &right_gain);
  307.     left_gain = right_gain = 100;
  308.     UMSAudioDevice_enable_output(audio_device, audio_env, "LINE_OUT",
  309.         &left_gain, &right_gain);
  310.  
  311.     UMSAudioDevice_initialize(audio_device, audio_env);
  312.     UMSAudioDevice_start(audio_device, audio_env);
  313.  
  314.     output_buffer._maximum = BUF_SIZE*8*2;
  315.     output_buffer_data = (short *) malloc(output_buffer._maximum);
  316.     output_buffer._buffer = (octet *) output_buffer_data;
  317.  
  318.     usecs_per_samplepair = 1000000.0 / out_rate;
  319.  
  320.     samplepair_latency = 1500;
  321.     sl = getenv("SAMPLEPAIR_LATENCY");
  322.     if (sl) samplepair_latency = atoi(sl);
  323.  
  324.     last_sample = 0;
  325.  
  326.     return 1;
  327.  
  328. }
  329.  
  330.  
  331.