home *** CD-ROM | disk | FTP | other *** search
- /* os2_obuffer.cc
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * OS2Obuffer DART version written by Kim 'B' Heino (Kim.Heino@utu.fi)
- *
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- #include <unistd.h>
-
- #include "all.h"
- #include "args.h"
- #include "obuffer.h"
- #include "header.h"
-
- #ifdef OS2
-
- #define INCL_OS2MM
- #define INCL_MCIOS2
- #define INCL_DOS
- #define INCL_BASE
-
- extern "C" {
- #include <os2.h>
- #include <os2me.h>
- }
-
- #define BUF_COUNT 32
- #define BUF_SIZE 32*1024
-
- USHORT device;
- MCI_MIX_BUFFER buffers[BUF_COUNT];
- MCI_MIXSETUP_PARMS mix_params;
- MCI_BUFFER_PARMS buffer_params;
- int stopbut=0, play_pos=0, stop_pos=-1, fill_pos=0;
- int hz, bits, pchannels;
-
- void error(void) {
- printf("error accessing device");
- exit(2);
- }
-
- LONG APIENTRY MMEvent(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, ULONG ulFlags)
- {
- if (ulFlags==MIX_WRITE_COMPLETE) {
- if (play_pos==stop_pos) stopbut=1;
- else {
- mix_params.pmixWrite(mix_params.ulMixHandle,&buffers[play_pos % BUF_COUNT],1);
- play_pos++;
- }
- }
- return(TRUE);
- }
-
- int OS2Obuffer::open_audio_device (void)
- {
- MCI_AMP_OPEN_PARMS amp_params;
-
- memset(&_params,0,sizeof(MCI_AMP_OPEN_PARMS));
- amp_params.usDeviceID=(USHORT)0;
- amp_params.pszDeviceType=(PSZ)MCI_DEVTYPE_AUDIO_AMPMIX;
- if (mciSendCommand(0,MCI_OPEN,MCI_WAIT | MCI_OPEN_TYPE_ID | MCI_OPEN_SHAREABLE,(PVOID)&_params,0)) error();
- device=amp_params.usDeviceID;
-
- memset(&mix_params,0,sizeof(MCI_MIXSETUP_PARMS));
- mix_params.ulBitsPerSample = bits;
- mix_params.ulFormatTag = MCI_WAVE_FORMAT_PCM;
- mix_params.ulSamplesPerSec = hz;
- mix_params.ulChannels = pchannels;
- mix_params.pmixEvent = MMEvent;
- mix_params.ulFormatMode = MCI_PLAY;
- mix_params.ulDeviceType = MCI_DEVTYPE_WAVEFORM_AUDIO;
- if (mciSendCommand(device,MCI_MIXSETUP,MCI_WAIT | MCI_MIXSETUP_INIT,(PVOID)&mix_params,0)) error();
-
- buffer_params.ulNumBuffers = BUF_COUNT;
- buffer_params.ulBufferSize = BUF_SIZE;
- buffer_params.pBufList = buffers;
- if (mciSendCommand(device,MCI_BUFFER,MCI_WAIT | MCI_ALLOCATE_MEMORY,(PVOID)&buffer_params,0)) error();
-
- if (mciSendCommand(device,MCI_MIXSETUP,MCI_WAIT | MCI_MIXSETUP_DEINIT,(PVOID)&mix_params,0)) error();
- mix_params.ulFormatMode=MCI_PLAY;
- if (mciSendCommand(device,MCI_MIXSETUP,MCI_WAIT | MCI_MIXSETUP_INIT,(PVOID)&mix_params,0)) error();
-
- return(1);
- }
-
- OS2Obuffer::OS2Obuffer (uint32 number_of_channels,
- MPEG_Args *ma)
- {
- channels = number_of_channels;
- for (int i = 0; i < number_of_channels; ++i)
- bufferp[i] = buffer + i;
-
- bits= 16;
- hz = ma->MPEGheader->frequency ();
- pchannels=channels;
-
- open_audio_device();
- }
-
- OS2Obuffer::~OS2Obuffer (void) {
- MCI_GENERIC_PARMS gen_params;
-
- stop_pos=fill_pos;
- while (!stopbut) DosSleep(50);
- if (mciSendCommand(device,MCI_STOP,MCI_WAIT,(PVOID)&gen_params,0)) error();
- if (mciSendCommand(device,MCI_BUFFER,MCI_WAIT | MCI_DEALLOCATE_MEMORY,(PVOID)&buffer_params,0)) error();
- if (mciSendCommand(device,MCI_CLOSE,MCI_WAIT,(PVOID)&gen_params,0)) error();
- }
-
- void OS2Obuffer::append (uint32 channel, int16 value)
- {
- *bufferp[channel] = value;
- bufferp[channel] += channels;
- }
-
- void OS2Obuffer::write_buffer (int)
- {
- static char *locbuf=NULL;
- static int locpos=0;
- char *p=(char*)buffer;
- int length = (int)((char *)bufferp[0] - (char *)buffer);
-
- if (locbuf==NULL) locbuf=(char*)buffers[fill_pos % BUF_COUNT].pBuffer;
- while (length--) {
- *locbuf++=*p++;
- if (++locpos==BUF_SIZE) {
- while (fill_pos-play_pos>=BUF_COUNT-3) DosSleep(50);
- buffers[fill_pos % BUF_COUNT].ulBufferLength=BUF_SIZE;
- buffers[fill_pos % BUF_COUNT].ulFlags=0;
- fill_pos++;
- if (!play_pos && fill_pos>2) {
- play_pos=2;
- mix_params.pmixWrite(mix_params.ulMixHandle,buffers,2);
- }
- locpos=0;
- locbuf=(char*)buffers[fill_pos % BUF_COUNT].pBuffer;
- }
- }
- for (int i = 0; i < channels; ++i)
- bufferp[i] = buffer + i;
- }
-
- #ifdef SEEK_STOP
- void OS2Obuffer::clear_buffer()
- {
- }
-
- void OS2Obuffer::set_stop_flag()
- {
- }
- #endif // SEEK_STOP
-
- Obuffer *create_obuffer(MPEG_Args *maplay_args)
- {
- Obuffer *buffer;
-
- enum e_mode mode = maplay_args->MPEGheader->mode();
- enum e_channels which_channels = maplay_args->which_c;
-
- if (mode == single_channel || which_channels != both)
- buffer = new OS2Obuffer(1, maplay_args);
- else
- buffer = new OS2Obuffer(2, maplay_args);
-
- return(buffer);
- }
-
- #endif /* OS2 */
-
-