home *** CD-ROM | disk | FTP | other *** search
/ Windows 95 Secrets / Secrets2.iso / Audio / WAV / MaplayP / _SETUP.1 / os2_obuffer.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-12  |  5.2 KB  |  187 lines

  1. /*  os2_obuffer.cc
  2.  *
  3.  *  This program is free software; you can redistribute it and/or modify
  4.  *  it under the terms of the GNU General Public License as published by
  5.  *  the Free Software Foundation; either version 2 of the License, or
  6.  *  (at your option) any later version.
  7.  *
  8.  *  This program is distributed in the hope that it will be useful,
  9.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.  *  GNU General Public License for more details.
  12.  *
  13.  *  You should have received a copy of the GNU General Public License
  14.  *  along with this program; if not, write to the Free Software
  15.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16.  *
  17.  *  OS2Obuffer DART version written by Kim 'B' Heino (Kim.Heino@utu.fi)
  18.  *
  19.  */
  20.  
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <errno.h>
  25. #include <unistd.h>
  26.  
  27. #include "all.h"
  28. #include "args.h"
  29. #include "obuffer.h"
  30. #include "header.h"
  31.  
  32. #ifdef OS2
  33.  
  34. #define  INCL_OS2MM
  35. #define  INCL_MCIOS2
  36. #define  INCL_DOS
  37. #define  INCL_BASE
  38.  
  39. extern "C" {
  40. #include <os2.h>
  41. #include <os2me.h>
  42. }
  43.  
  44. #define BUF_COUNT   32
  45. #define BUF_SIZE    32*1024
  46.  
  47. USHORT              device;
  48. MCI_MIX_BUFFER      buffers[BUF_COUNT];
  49. MCI_MIXSETUP_PARMS  mix_params;
  50. MCI_BUFFER_PARMS    buffer_params;
  51. int                 stopbut=0, play_pos=0, stop_pos=-1, fill_pos=0;
  52. int                 hz, bits, pchannels;
  53.  
  54. void error(void) {
  55.   printf("error accessing device");
  56.   exit(2);
  57. }
  58.  
  59. LONG APIENTRY MMEvent(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, ULONG ulFlags)
  60. {
  61.   if (ulFlags==MIX_WRITE_COMPLETE) {
  62.     if (play_pos==stop_pos) stopbut=1;
  63.     else {
  64.       mix_params.pmixWrite(mix_params.ulMixHandle,&buffers[play_pos % BUF_COUNT],1);
  65.       play_pos++;
  66.     }
  67.   }
  68.   return(TRUE);
  69. }
  70.  
  71. int OS2Obuffer::open_audio_device (void)
  72. {
  73.   MCI_AMP_OPEN_PARMS amp_params;
  74.  
  75.   memset(&_params,0,sizeof(MCI_AMP_OPEN_PARMS));
  76.   amp_params.usDeviceID=(USHORT)0;
  77.   amp_params.pszDeviceType=(PSZ)MCI_DEVTYPE_AUDIO_AMPMIX;
  78.   if (mciSendCommand(0,MCI_OPEN,MCI_WAIT | MCI_OPEN_TYPE_ID | MCI_OPEN_SHAREABLE,(PVOID)&_params,0)) error();
  79.   device=amp_params.usDeviceID;
  80.  
  81.   memset(&mix_params,0,sizeof(MCI_MIXSETUP_PARMS));
  82.   mix_params.ulBitsPerSample = bits;
  83.   mix_params.ulFormatTag     = MCI_WAVE_FORMAT_PCM;
  84.   mix_params.ulSamplesPerSec = hz;
  85.   mix_params.ulChannels      = pchannels;
  86.   mix_params.pmixEvent       = MMEvent;
  87.   mix_params.ulFormatMode    = MCI_PLAY;
  88.   mix_params.ulDeviceType    = MCI_DEVTYPE_WAVEFORM_AUDIO;
  89.   if (mciSendCommand(device,MCI_MIXSETUP,MCI_WAIT | MCI_MIXSETUP_INIT,(PVOID)&mix_params,0)) error();
  90.  
  91.   buffer_params.ulNumBuffers = BUF_COUNT;
  92.   buffer_params.ulBufferSize = BUF_SIZE;
  93.   buffer_params.pBufList     = buffers;
  94.   if (mciSendCommand(device,MCI_BUFFER,MCI_WAIT | MCI_ALLOCATE_MEMORY,(PVOID)&buffer_params,0)) error();
  95.  
  96.   if (mciSendCommand(device,MCI_MIXSETUP,MCI_WAIT | MCI_MIXSETUP_DEINIT,(PVOID)&mix_params,0)) error();
  97.   mix_params.ulFormatMode=MCI_PLAY;
  98.   if (mciSendCommand(device,MCI_MIXSETUP,MCI_WAIT | MCI_MIXSETUP_INIT,(PVOID)&mix_params,0)) error();
  99.  
  100.   return(1);
  101. }
  102.  
  103. OS2Obuffer::OS2Obuffer (uint32 number_of_channels,
  104.                                MPEG_Args *ma)
  105. {
  106.   channels = number_of_channels;
  107.   for (int i = 0; i < number_of_channels; ++i)
  108.     bufferp[i] = buffer + i;
  109.  
  110.   bits= 16;
  111.   hz = ma->MPEGheader->frequency ();
  112.   pchannels=channels;
  113.  
  114.   open_audio_device();
  115. }
  116.  
  117. OS2Obuffer::~OS2Obuffer (void) {
  118.   MCI_GENERIC_PARMS gen_params;
  119.  
  120.   stop_pos=fill_pos;
  121.   while (!stopbut) DosSleep(50);
  122.   if (mciSendCommand(device,MCI_STOP,MCI_WAIT,(PVOID)&gen_params,0)) error();
  123.   if (mciSendCommand(device,MCI_BUFFER,MCI_WAIT | MCI_DEALLOCATE_MEMORY,(PVOID)&buffer_params,0)) error();
  124.   if (mciSendCommand(device,MCI_CLOSE,MCI_WAIT,(PVOID)&gen_params,0)) error();
  125. }
  126.  
  127. void OS2Obuffer::append (uint32 channel, int16 value)
  128. {
  129.   *bufferp[channel] = value;
  130.   bufferp[channel] += channels;
  131. }
  132.  
  133. void OS2Obuffer::write_buffer (int)
  134. {
  135.   static char *locbuf=NULL;
  136.   static int locpos=0;
  137.   char *p=(char*)buffer;
  138.   int length = (int)((char *)bufferp[0] - (char *)buffer);
  139.  
  140.   if (locbuf==NULL) locbuf=(char*)buffers[fill_pos % BUF_COUNT].pBuffer;
  141.   while (length--) {
  142.     *locbuf++=*p++;
  143.     if (++locpos==BUF_SIZE) {
  144.       while (fill_pos-play_pos>=BUF_COUNT-3) DosSleep(50);
  145.       buffers[fill_pos % BUF_COUNT].ulBufferLength=BUF_SIZE;
  146.       buffers[fill_pos % BUF_COUNT].ulFlags=0;
  147.       fill_pos++;
  148.       if (!play_pos && fill_pos>2) {
  149.         play_pos=2;
  150.         mix_params.pmixWrite(mix_params.ulMixHandle,buffers,2);
  151.       }
  152.       locpos=0;
  153.       locbuf=(char*)buffers[fill_pos % BUF_COUNT].pBuffer;
  154.     }
  155.   }
  156.   for (int i = 0; i < channels; ++i)
  157.     bufferp[i] = buffer + i;
  158. }
  159.  
  160. #ifdef SEEK_STOP
  161. void OS2Obuffer::clear_buffer()
  162. {
  163. }
  164.  
  165. void OS2Obuffer::set_stop_flag()
  166. {
  167. }
  168. #endif // SEEK_STOP
  169.  
  170. Obuffer *create_obuffer(MPEG_Args *maplay_args)
  171. {
  172.   Obuffer *buffer;
  173.  
  174.   enum e_mode mode = maplay_args->MPEGheader->mode();
  175.   enum e_channels which_channels = maplay_args->which_c;
  176.  
  177.   if (mode == single_channel || which_channels != both)
  178.      buffer = new OS2Obuffer(1, maplay_args);
  179.   else
  180.      buffer = new OS2Obuffer(2, maplay_args);
  181.  
  182.   return(buffer);
  183. }
  184.  
  185. #endif    /* OS2 */
  186.  
  187.