Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/fhandler_dsp.cc')
-rw-r--r--winsup/cygwin/fhandler_dsp.cc646
1 files changed, 0 insertions, 646 deletions
diff --git a/winsup/cygwin/fhandler_dsp.cc b/winsup/cygwin/fhandler_dsp.cc
deleted file mode 100644
index f809b93cc..000000000
--- a/winsup/cygwin/fhandler_dsp.cc
+++ /dev/null
@@ -1,646 +0,0 @@
-/* fhandler_dev_dsp: code to emulate OSS sound model /dev/dsp
-
- Copyright 2001, 2002 Red Hat, Inc
-
- Written by Andy Younger (andy@snoogie.demon.co.uk)
-
-This file is part of Cygwin.
-
-This software is a copyrighted work licensed under the terms of the
-Cygwin license. Please consult the file "CYGWIN_LICENSE" for
-details. */
-
-#include "winsup.h"
-#include <stdio.h>
-#include <errno.h>
-#include <windows.h>
-#include <sys/soundcard.h>
-#include <mmsystem.h>
-#include "cygerrno.h"
-#include "security.h"
-#include "fhandler.h"
-
-//------------------------------------------------------------------------
-// Simple encapsulation of the win32 audio device.
-//
-static void CALLBACK wave_callback (HWAVE hWave, UINT msg, DWORD instance,
- DWORD param1, DWORD param2);
-class Audio
-{
-public:
- enum
- {
- MAX_BLOCKS = 12,
- BLOCK_SIZE = 16384,
- TOT_BLOCK_SIZE = BLOCK_SIZE + sizeof (WAVEHDR)
- };
-
- Audio ();
- ~Audio ();
-
- bool open (int rate, int bits, int channels, bool bCallback = false);
- void close ();
- int getvolume ();
- void setvolume (int newVolume);
- bool write (const void *pSampleData, int nBytes);
- int blocks ();
- void callback_sampledone (void *pData);
- void setformat (int format) {formattype_ = format;}
- int numbytesoutput ();
-
- void *operator new (size_t, void *p) {return p;}
-
-private:
- char *initialisebuffer ();
- void waitforcallback ();
- bool flush ();
-
- HWAVEOUT dev_;
- volatile int nBlocksInQue_;
- int nBytesWritten_;
- char *buffer_;
- int bufferIndex_;
- CRITICAL_SECTION lock_;
- char *freeblocks_[MAX_BLOCKS];
- int formattype_;
-
- char bigwavebuffer_[MAX_BLOCKS * TOT_BLOCK_SIZE];
-};
-
-static char audio_buf[sizeof (class Audio)];
-
-Audio::Audio ()
-{
- InitializeCriticalSection (&lock_);
- memset (bigwavebuffer_, 0, sizeof (bigwavebuffer_));
- for (int i = 0; i < MAX_BLOCKS; i++)
- freeblocks_[i] = &bigwavebuffer_[i * TOT_BLOCK_SIZE];
-}
-
-Audio::~Audio ()
-{
- if (dev_)
- close ();
- DeleteCriticalSection (&lock_);
-}
-
-bool
-Audio::open (int rate, int bits, int channels, bool bCallback)
-{
- WAVEFORMATEX format;
- int nDevices = waveOutGetNumDevs ();
-
- nBytesWritten_ = 0L;
- bufferIndex_ = 0;
- buffer_ = 0L;
- debug_printf ("number devices %d\n", nDevices);
- if (nDevices <= 0)
- return false;
-
- debug_printf ("trying to map device freq %d, bits %d, "
- "channels %d, callback %d\n", rate, bits, channels,
- bCallback);
-
- int bytesperSample = bits / 8;
-
- memset (&format, 0, sizeof (format));
- format.wFormatTag = WAVE_FORMAT_PCM;
- format.wBitsPerSample = bits;
- format.nChannels = channels;
- format.nSamplesPerSec = rate;
- format.nAvgBytesPerSec = format.nSamplesPerSec * format.nChannels *
- bytesperSample;
- format.nBlockAlign = format.nChannels * bytesperSample;
-
- nBlocksInQue_ = 0;
- HRESULT res = waveOutOpen (&dev_, WAVE_MAPPER, &format, (DWORD) wave_callback,
- (DWORD) this, bCallback ? CALLBACK_FUNCTION : 0);
- if (res == S_OK)
- {
- debug_printf ("Sucessfully opened!");
- return true;
- }
- else
- {
- debug_printf ("failed to open");
- return false;
- }
-}
-
-void
-Audio::close ()
-{
- if (dev_)
- {
- flush (); // force out last block whatever size..
-
- while (blocks ()) // block till finished..
- waitforcallback ();
-
- waveOutReset (dev_);
- waveOutClose (dev_);
- dev_ = 0L;
- }
- nBytesWritten_ = 0L;
-}
-
-int
-Audio::numbytesoutput ()
-{
- return nBytesWritten_;
-}
-
-int
-Audio::getvolume ()
-{
- DWORD volume;
-
- waveOutGetVolume (dev_, &volume);
- return ((volume >> 16) + (volume & 0xffff)) >> 1;
-}
-
-void
-Audio::setvolume (int newVolume)
-{
- waveOutSetVolume (dev_, (newVolume << 16) | newVolume);
-}
-
-char *
-Audio::initialisebuffer ()
-{
- EnterCriticalSection (&lock_);
- WAVEHDR *pHeader = 0L;
- for (int i = 0; i < MAX_BLOCKS; i++)
- {
- char *pData = freeblocks_[i];
- if (pData)
- {
- pHeader = (WAVEHDR *) pData;
- if (pHeader->dwFlags & WHDR_DONE)
- {
- waveOutUnprepareHeader (dev_, pHeader, sizeof (WAVEHDR));
- }
- freeblocks_[i] = 0L;
- break;
- }
- }
- LeaveCriticalSection (&lock_);
-
- if (pHeader)
- {
- memset (pHeader, 0, sizeof (WAVEHDR));
- pHeader->dwBufferLength = BLOCK_SIZE;
- pHeader->lpData = (LPSTR) (&pHeader[1]);
- return (char *) pHeader->lpData;
- }
- return 0L;
-}
-
-bool
-Audio::write (const void *pSampleData, int nBytes)
-{
- // split up big blocks into smaller BLOCK_SIZE chunks
- while (nBytes > BLOCK_SIZE)
- {
- write (pSampleData, BLOCK_SIZE);
- nBytes -= BLOCK_SIZE;
- pSampleData = (void *) ((char *) pSampleData + BLOCK_SIZE);
- }
-
- // Block till next sound is flushed
- if (blocks () == MAX_BLOCKS)
- waitforcallback ();
-
- // Allocate new wave buffer if necessary
- if (buffer_ == 0L)
- {
- buffer_ = initialisebuffer ();
- if (buffer_ == 0L)
- return false;
- }
-
-
- // Handle gathering blocks into larger buffer
- int sizeleft = BLOCK_SIZE - bufferIndex_;
- if (nBytes < sizeleft)
- {
- memcpy (&buffer_[bufferIndex_], pSampleData, nBytes);
- bufferIndex_ += nBytes;
- nBytesWritten_ += nBytes;
- return true;
- }
-
- // flushing when we reach our limit of BLOCK_SIZE
- memcpy (&buffer_[bufferIndex_], pSampleData, sizeleft);
- bufferIndex_ += sizeleft;
- nBytesWritten_ += sizeleft;
- flush ();
-
- // change pointer to rest of sample, and size accordingly
- pSampleData = (void *) ((char *) pSampleData + sizeleft);
- nBytes -= sizeleft;
-
- // if we still have some sample left over write it out
- if (nBytes)
- return write (pSampleData, nBytes);
-
- return true;
-}
-
-// return number of blocks back.
-int
-Audio::blocks ()
-{
- EnterCriticalSection (&lock_);
- int ret = nBlocksInQue_;
- LeaveCriticalSection (&lock_);
- return ret;
-}
-
-// This is called on an interupt so use locking.. Note nBlocksInQue_ is
-// modified by it so we should wrap all references to it in locks.
-void
-Audio::callback_sampledone (void *pData)
-{
- EnterCriticalSection (&lock_);
-
- nBlocksInQue_--;
- for (int i = 0; i < MAX_BLOCKS; i++)
- if (!freeblocks_[i])
- {
- freeblocks_[i] = (char *) pData;
- break;
- }
-
- LeaveCriticalSection (&lock_);
-}
-
-void
-Audio::waitforcallback ()
-{
- int n = blocks ();
- if (!n)
- return;
- do
- {
- Sleep (250);
- }
- while (n == blocks ());
-}
-
-bool
-Audio::flush ()
-{
- if (!buffer_)
- return false;
-
- // Send internal buffer out to the soundcard
- WAVEHDR *pHeader = ((WAVEHDR *) buffer_) - 1;
- pHeader->dwBufferLength = bufferIndex_;
-
- // Quick bit of sample buffer conversion
- if (formattype_ == AFMT_S8)
- {
- unsigned char *p = ((unsigned char *) buffer_);
- for (int i = 0; i < bufferIndex_; i++)
- {
- p[i] -= 0x7f;
- }
- }
-
- if (waveOutPrepareHeader (dev_, pHeader, sizeof (WAVEHDR)) == S_OK &&
- waveOutWrite (dev_, pHeader, sizeof (WAVEHDR)) == S_OK)
- {
- EnterCriticalSection (&lock_);
- nBlocksInQue_++;
- LeaveCriticalSection (&lock_);
- bufferIndex_ = 0;
- buffer_ = 0L;
- return true;
- }
- else
- {
- EnterCriticalSection (&lock_);
- for (int i = 0; i < MAX_BLOCKS; i++)
- if (!freeblocks_[i])
- {
- freeblocks_[i] = (char *) pHeader;
- break;
- }
- LeaveCriticalSection (&lock_);
- }
- return false;
-}
-
-//------------------------------------------------------------------------
-// Call back routine
-static void CALLBACK
-wave_callback (HWAVE hWave, UINT msg, DWORD instance, DWORD param1,
- DWORD param2)
-{
- if (msg == WOM_DONE)
- {
- Audio *ptr = (Audio *) instance;
- ptr->callback_sampledone ((void *) param1);
- }
-}
-
-//------------------------------------------------------------------------
-// /dev/dsp handler
-static Audio *s_audio; // static instance of the Audio handler
-
-//------------------------------------------------------------------------
-// wav file detection..
-#pragma pack(1)
-struct wavchunk
-{
- char id[4];
- unsigned int len;
-};
-struct wavformat
-{
- unsigned short wFormatTag;
- unsigned short wChannels;
- unsigned int dwSamplesPerSec;
- unsigned int dwAvgBytesPerSec;
- unsigned short wBlockAlign;
- unsigned short wBitsPerSample;
-};
-#pragma pack()
-
-bool
-fhandler_dev_dsp::setupwav (const char *pData, int nBytes)
-{
- int len;
- const char *end = pData + nBytes;
-
- if (!(pData[0] == 'R' && pData[1] == 'I' &&
- pData[2] == 'F' && pData[3] == 'F'))
- return false;
- if (!(pData[8] == 'W' && pData[9] == 'A' &&
- pData[10] == 'V' && pData[11] == 'E'))
- return false;
-
- len = *(int *) &pData[4];
- pData += 12;
- while (len && pData < end)
- {
- wavchunk * pChunk = (wavchunk *) pData;
- int blklen = pChunk-> len;
- if (pChunk->id[0] == 'f' && pChunk->id[1] == 'm' &&
- pChunk->id[2] == 't' && pChunk->id[3] == ' ')
- {
- wavformat *format = (wavformat *) (pChunk + 1);
- if ((char *) (format + 1) > end)
- return false;
-
- // Open up audio device with correct frequency for wav file
- //
- // FIXME: should through away all the header & not output
- // it to the soundcard.
- s_audio->close ();
- if (s_audio->open (format->dwSamplesPerSec, format->wBitsPerSample,
- format->wChannels) == false)
- {
- s_audio->open (audiofreq_, audiobits_, audiochannels_);
- }
- else
- {
- audiofreq_ = format->dwSamplesPerSec;
- audiobits_ = format->wBitsPerSample;
- audiochannels_ = format->wChannels;
- }
- return true;
- }
-
- pData += blklen + sizeof (wavchunk);
- }
- return false;
-}
-
-//------------------------------------------------------------------------
-fhandler_dev_dsp::fhandler_dev_dsp ():
- fhandler_base (FH_OSS_DSP)
-{
-}
-
-fhandler_dev_dsp::~fhandler_dev_dsp ()
-{
-}
-
-int
-fhandler_dev_dsp::open (path_conv *, int flags, mode_t mode)
-{
- // currently we only support writing
- if ((flags & (O_WRONLY | O_RDONLY | O_RDWR)) != O_WRONLY)
- {
- set_errno (EACCES);
- return 0;
- }
-
- set_flags (flags & ~O_TEXT, O_BINARY);
-
- if (!s_audio)
- s_audio = new (audio_buf) Audio;
-
- // Work out initial sample format & frequency
- // dev/dsp defaults
- audioformat_ = AFMT_S8;
- audiofreq_ = 8000;
- audiobits_ = 8;
- audiochannels_ = 1;
-
- int res;
- if (!s_audio->open (audiofreq_, audiobits_, audiochannels_))
- res = 0;
- else
- {
- set_open_status ();
- res = 1;
- }
-
- debug_printf ("returns %d", res);
- return res;
-}
-
-int
-fhandler_dev_dsp::write (const void *ptr, size_t len)
-{
- if (s_audio->numbytesoutput () == 0)
- {
- // check for wave file & setup frequencys properly if possible.
- setupwav ((const char *) ptr, len);
-
- // Open audio device properly with callbacks.
- s_audio->close ();
- if (!s_audio->open (audiofreq_, audiobits_, audiochannels_, true))
- return 0;
- }
-
- s_audio->write (ptr, len);
- return len;
-}
-
-int __stdcall
-fhandler_dev_dsp::read (void *ptr, size_t len)
-{
- return len;
-}
-
-__off64_t
-fhandler_dev_dsp::lseek (__off64_t offset, int whence)
-{
- return 0;
-}
-
-int
-fhandler_dev_dsp::close (void)
-{
- s_audio->close ();
- return 0;
-}
-
-int
-fhandler_dev_dsp::dup (fhandler_base * child)
-{
- fhandler_dev_dsp *fhc = (fhandler_dev_dsp *) child;
-
- fhc->set_flags (get_flags ());
- fhc->audiochannels_ = audiochannels_;
- fhc->audiobits_ = audiobits_;
- fhc->audiofreq_ = audiofreq_;
- fhc->audioformat_ = audioformat_;
- return 0;
-}
-
-int
-fhandler_dev_dsp::ioctl (unsigned int cmd, void *ptr)
-{
- int *intptr = (int *) ptr;
- switch (cmd)
- {
-#define CASE(a) case a : debug_printf("/dev/dsp: ioctl %s\n", #a);
-
- CASE (SNDCTL_DSP_RESET)
- audioformat_ = AFMT_S8;
- audiofreq_ = 8000;
- audiobits_ = 8;
- audiochannels_ = 1;
- return 0;
-
- CASE (SNDCTL_DSP_GETBLKSIZE)
- *intptr = Audio::BLOCK_SIZE;
- return 0;
-
- CASE (SNDCTL_DSP_SETFMT)
- {
- int nBits = 0;
- if (*intptr == AFMT_S16_LE)
- nBits = 16;
- else if (*intptr == AFMT_U8)
- nBits = 8;
- else if (*intptr == AFMT_S8)
- nBits = 8;
- if (nBits)
- {
- s_audio->setformat (*intptr);
- s_audio->close ();
- if (s_audio->open (audiofreq_, nBits, audiochannels_) == true)
- {
- audiobits_ = nBits;
- return 0;
- }
- else
- {
- s_audio->open (audiofreq_, audiobits_, audiochannels_);
- return -1;
- }
- }
- }
- break;
-
- CASE (SNDCTL_DSP_SPEED)
- s_audio->close ();
- if (s_audio->open (*intptr, audiobits_, audiochannels_) == true)
- {
- audiofreq_ = *intptr;
- return 0;
- }
- else
- {
- s_audio->open (audiofreq_, audiobits_, audiochannels_);
- return -1;
- }
- break;
-
- CASE (SNDCTL_DSP_STEREO)
- {
- int nChannels = *intptr + 1;
-
- s_audio->close ();
- if (s_audio->open (audiofreq_, audiobits_, nChannels) == true)
- {
- audiochannels_ = nChannels;
- return 0;
- }
- else
- {
- s_audio->open (audiofreq_, audiobits_, audiochannels_);
- return -1;
- }
- }
- break;
-
- CASE (SNDCTL_DSP_GETOSPACE)
- {
- audio_buf_info *p = (audio_buf_info *) ptr;
-
- int nBlocks = s_audio->blocks ();
- int leftblocks = ((Audio::MAX_BLOCKS - nBlocks) - 1);
- if (leftblocks < 0)
- leftblocks = 0;
- if (leftblocks > 1)
- leftblocks = 1;
- int left = leftblocks * Audio::BLOCK_SIZE;
-
- p->fragments = leftblocks;
- p->fragstotal = Audio::MAX_BLOCKS;
- p->fragsize = Audio::BLOCK_SIZE;
- p->bytes = left;
-
- debug_printf ("ptr %p nblocks %d leftblocks %d left bytes %d ",
- ptr, nBlocks, leftblocks, left);
-
- return 0;
- }
- break;
-
- CASE (SNDCTL_DSP_SETFRAGMENT)
- {
- // Fake!! esound & mikmod require this on non PowerPC platforms.
- //
- return 0;
- }
- break;
-
- default:
- debug_printf ("/dev/dsp: ioctl not handled yet! FIXME:\n");
- break;
-
-#undef CASE
- };
- return -1;
-}
-
-void
-fhandler_dev_dsp::dump ()
-{
- paranoid_printf ("here, fhandler_dev_dsp");
-}
-
-void
-fhandler_dev_dsp::fixup_after_exec (HANDLE)
-{
- /* FIXME: Is there a better way to do this? */
- s_audio = new (audio_buf) Audio;
-}