1 /* Fhandler_dev_dsp: code to emulate OSS sound model /dev/dsp
3 Copyright 2001, 2002, 2003, 2004 Red Hat, Inc
5 Written by Andy Younger (andy@snoogie.demon.co.uk)
6 Extended by Gerd Spalink (Gerd.Spalink@t-online.de)
7 to support recording from the audio input
9 This file is part of Cygwin.
11 This software is a copyrighted work licensed under the terms of the
12 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
18 #include <sys/soundcard.h>
27 /*------------------------------------------------------------------------
28 Simple encapsulation of the win32 audio device.
31 1. Audio structures are malloced just before the first read or
32 write to /dev/dsp. The actual buffer size is determined at that time,
33 such that one buffer holds about 125ms of audio data.
34 At the time of this writing, 12 buffers are allocated,
35 so that up to 1.5 seconds can be buffered within Win32.
36 The buffer size can be queried with the ioctl SNDCTL_DSP_GETBLKSIZE,
37 but for this implementation only returns meaningful results if
38 sampling rate, number of channels and number of bits per sample
39 are not changed afterwards.
40 The audio structures are freed when the device is reset or closed,
41 and they are not passed to exec'ed processes.
42 The dev_ member is cleared after a fork. This forces the child
43 to reopen the audio device._
45 2. Every open call creates a new instance of the handler. After a
46 successful open, every subsequent open from the same process
47 to the device fails with EBUSY.
48 The structures are shared between duped handles, but not with
49 children. They only inherit the settings from the parent.
52 class fhandler_dev_dsp::Audio
53 { // This class contains functionality common to Audio_in and Audio_out
61 void setconvert (int format);
62 void convert_none (unsigned char *buffer, int size_bytes) { }
63 void convert_U8_S8 (unsigned char *buffer, int size_bytes);
64 void convert_S16LE_U16LE (unsigned char *buffer, int size_bytes);
65 void convert_S16LE_U16BE (unsigned char *buffer, int size_bytes);
66 void convert_S16LE_S16BE (unsigned char *buffer, int size_bytes);
67 void fillFormat (WAVEFORMATEX * format,
68 int rate, int bits, int channels);
69 unsigned blockSize (int rate, int bits, int channels);
70 void (fhandler_dev_dsp::Audio::*convert_)
71 (unsigned char *buffer, int size_bytes);
73 enum { MAX_BLOCKS = 12 };
74 int bufferIndex_; // offset into pHdr_->lpData
75 WAVEHDR *pHdr_; // data to be filled by write
76 WAVEHDR wavehdr_[MAX_BLOCKS];
77 char *bigwavebuffer_; // audio samples only
78 // Member variables below must be locked
79 queue *Qisr2app_; // blocks passed from wave callback
82 class fhandler_dev_dsp::Audio::queue
83 { // non-blocking fixed size queues for buffer management
85 queue (int depth = 4);
88 bool send (WAVEHDR *); // queue an item, returns true if successful
89 bool recv (WAVEHDR **); // retrieve an item, returns true if successful
91 int query (); // return number of items queued
92 inline void lock () { EnterCriticalSection (&lock_); }
93 inline void unlock () { LeaveCriticalSection (&lock_); }
94 inline void dellock () { debug_printf ("Deleting Critical Section"); DeleteCriticalSection (&lock_); }
95 bool isvalid () { return storage_; }
97 CRITICAL_SECTION lock_;
104 static void CALLBACK waveOut_callback (HWAVEOUT hWave, UINT msg, DWORD instance,
105 DWORD param1, DWORD param2);
107 class fhandler_dev_dsp::Audio_out: public Audio
110 void fork_fixup (HANDLE parent);
111 bool query (int rate, int bits, int channels);
113 void stop (bool immediately = false);
114 bool write (const char *pSampleData, int nBytes);
115 void buf_info (audio_buf_info *p, int rate, int bits, int channels);
116 void callback_sampledone (WAVEHDR *pHdr);
117 bool parsewav (const char *&pData, int &nBytes,
118 int rate, int bits, int channels);
121 void init (unsigned blockSize);
122 void waitforallsent ();
123 void waitforspace ();
126 enum { MAX_BLOCKS = 12 };
127 HWAVEOUT dev_; // The wave device
128 /* Private copies of audiofreq_, audiobits_, audiochannels_,
129 possibly set from wave file */
135 static void CALLBACK waveIn_callback (HWAVEIN hWave, UINT msg, DWORD instance,
136 DWORD param1, DWORD param2);
138 class fhandler_dev_dsp::Audio_in: public Audio
141 void fork_fixup (HANDLE parent);
142 bool query (int rate, int bits, int channels);
143 bool start (int rate, int bits, int channels);
145 bool read (char *pSampleData, int &nBytes);
146 void buf_info (audio_buf_info *p, int rate, int bits, int channels);
147 void callback_blockfull (WAVEHDR *pHdr);
150 bool init (unsigned blockSize);
151 bool queueblock (WAVEHDR *pHdr);
152 void waitfordata (); // blocks until we have a good pHdr_
157 /* --------------------------------------------------------------------
160 // Simple fixed length FIFO queue implementation for audio buffer management
161 fhandler_dev_dsp::Audio::queue::queue (int depth)
163 // allow space for one extra object in the queue
164 // so we can distinguish full and empty status
166 storage_ = new WAVEHDR *[depth_ + 1];
169 fhandler_dev_dsp::Audio::queue::~queue ()
175 fhandler_dev_dsp::Audio::queue::reset ()
177 /* When starting, after reset and after fork */
179 debug_printf ("InitializeCriticalSection");
180 memset (&lock_, 0, sizeof (lock_));
181 InitializeCriticalSection (&lock_);
185 fhandler_dev_dsp::Audio::queue::send (WAVEHDR *x)
189 if (query () == depth_)
190 system_printf ("Queue overflow");
194 if (++tail_ > depth_)
203 fhandler_dev_dsp::Audio::queue::recv (WAVEHDR **x)
209 *x = storage_[head_];
210 if (++head_ > depth_)
219 fhandler_dev_dsp::Audio::queue::query ()
221 int n = tail_ - head_;
227 // Audio class implements functionality need for both read and write
228 fhandler_dev_dsp::Audio::Audio ()
230 bigwavebuffer_ = NULL;
231 Qisr2app_ = new queue (MAX_BLOCKS);
232 convert_ = &fhandler_dev_dsp::Audio::convert_none;
235 fhandler_dev_dsp::Audio::~Audio ()
239 delete[] bigwavebuffer_;
243 fhandler_dev_dsp::Audio::isvalid ()
245 return bigwavebuffer_ && Qisr2app_ && Qisr2app_->isvalid ();
249 fhandler_dev_dsp::Audio::setconvert (int format)
254 convert_ = &fhandler_dev_dsp::Audio::convert_U8_S8;
255 debug_printf ("U8_S8");
258 convert_ = &fhandler_dev_dsp::Audio::convert_S16LE_U16LE;
259 debug_printf ("S16LE_U16LE");
262 convert_ = &fhandler_dev_dsp::Audio::convert_S16LE_U16BE;
263 debug_printf ("S16LE_U16BE");
266 convert_ = &fhandler_dev_dsp::Audio::convert_S16LE_S16BE;
267 debug_printf ("S16LE_S16BE");
270 convert_ = &fhandler_dev_dsp::Audio::convert_none;
271 debug_printf ("none");
276 fhandler_dev_dsp::Audio::convert_U8_S8 (unsigned char *buffer,
279 while (size_bytes-- > 0)
281 *buffer ^= (unsigned char)0x80;
287 fhandler_dev_dsp::Audio::convert_S16LE_U16BE (unsigned char *buffer,
290 int size_samples = size_bytes / 2;
291 unsigned char hi, lo;
292 while (size_samples-- > 0)
297 *buffer++ = hi ^ (unsigned char)0x80;
302 fhandler_dev_dsp::Audio::convert_S16LE_U16LE (unsigned char *buffer,
305 int size_samples = size_bytes / 2;
306 while (size_samples-- > 0)
309 *buffer ^= (unsigned char)0x80;
315 fhandler_dev_dsp::Audio::convert_S16LE_S16BE (unsigned char *buffer,
318 int size_samples = size_bytes / 2;
319 unsigned char hi, lo;
320 while (size_samples-- > 0)
330 fhandler_dev_dsp::Audio::fillFormat (WAVEFORMATEX * format,
331 int rate, int bits, int channels)
333 memset (format, 0, sizeof (*format));
334 format->wFormatTag = WAVE_FORMAT_PCM;
335 format->wBitsPerSample = bits;
336 format->nChannels = channels;
337 format->nSamplesPerSec = rate;
338 format->nAvgBytesPerSec = format->nSamplesPerSec * format->nChannels
340 format->nBlockAlign = format->nChannels * (bits / 8);
343 // calculate a good block size
345 fhandler_dev_dsp::Audio::blockSize (int rate, int bits, int channels)
348 blockSize = ((bits / 8) * channels * rate) / 8; // approx 125ms per block
349 // round up to multiple of 64
355 //=======================================================================
357 fhandler_dev_dsp::Audio_out::fork_fixup (HANDLE parent)
360 It will be necessary to reset the queue, open the device
361 and create a lock when writing */
362 debug_printf ("parent=0x%08x", parent);
368 fhandler_dev_dsp::Audio_out::query (int rate, int bits, int channels)
373 fillFormat (&format, rate, bits, channels);
374 rc = waveOutOpen (NULL, WAVE_MAPPER, &format, 0L, 0L, WAVE_FORMAT_QUERY);
375 debug_printf ("%d = waveOutOpen (freq=%d bits=%d channels=%d)", rc, rate, bits, channels);
376 return (rc == MMSYSERR_NOERROR);
380 fhandler_dev_dsp::Audio_out::start ()
384 unsigned bSize = blockSize (freq_, bits_, channels_);
389 /* In case of fork bigwavebuffer may already exist */
391 bigwavebuffer_ = new char[MAX_BLOCKS * bSize];
396 fillFormat (&format, freq_, bits_, channels_);
397 rc = waveOutOpen (&dev_, WAVE_MAPPER, &format, (DWORD) waveOut_callback,
398 (DWORD) this, CALLBACK_FUNCTION);
399 if (rc == MMSYSERR_NOERROR)
402 debug_printf ("%d = waveOutOpen (freq=%d bits=%d channels=%d)", rc, freq_, bits_, channels_);
404 return (rc == MMSYSERR_NOERROR);
408 fhandler_dev_dsp::Audio_out::stop (bool immediately)
413 debug_printf ("dev_=%08x", (int)dev_);
418 sendcurrent (); // force out last block whatever size..
419 waitforallsent (); // block till finished..
422 rc = waveOutReset (dev_);
423 debug_printf ("%d = waveOutReset ()", rc);
424 while (Qisr2app_->recv (&pHdr))
426 rc = waveOutUnprepareHeader (dev_, pHdr, sizeof (WAVEHDR));
427 debug_printf ("%d = waveOutUnprepareHeader (0x%08x)", rc, pHdr);
430 rc = waveOutClose (dev_);
431 debug_printf ("%d = waveOutClose ()", rc);
433 Qisr2app_->dellock ();
438 fhandler_dev_dsp::Audio_out::init (unsigned blockSize)
442 // internally queue all of our buffer for later use by write
444 for (i = 0; i < MAX_BLOCKS; i++)
446 wavehdr_[i].lpData = &bigwavebuffer_[i * blockSize];
447 wavehdr_[i].dwUser = (int) blockSize;
448 wavehdr_[i].dwFlags = 0;
449 if (!Qisr2app_->send (&wavehdr_[i]))
451 system_printf ("Internal Error i=%d", i);
452 break; // should not happen
459 fhandler_dev_dsp::Audio_out::write (const char *pSampleData, int nBytes)
462 { // Block if all blocks used until at least one is free
465 int sizeleft = (int)pHdr_->dwUser - bufferIndex_;
466 if (nBytes < sizeleft)
467 { // all data fits into the current block, with some space left
468 memcpy (&pHdr_->lpData[bufferIndex_], pSampleData, nBytes);
469 bufferIndex_ += nBytes;
473 { // data will fill up the current block
474 memcpy (&pHdr_->lpData[bufferIndex_], pSampleData, sizeleft);
475 bufferIndex_ += sizeleft;
477 pSampleData += sizeleft;
485 fhandler_dev_dsp::Audio_out::buf_info (audio_buf_info *p,
486 int rate, int bits, int channels)
488 p->fragstotal = MAX_BLOCKS;
491 /* If the device is running we use the internal values,
492 possibly set from the wave file. */
493 p->fragsize = blockSize (freq_, bits_, channels_);
494 p->fragments = Qisr2app_->query ();
496 p->bytes = (int)pHdr_->dwUser - bufferIndex_
497 + p->fragsize * p->fragments;
499 p->bytes = p->fragsize * p->fragments;
503 p->fragsize = blockSize (rate, bits, channels);
504 p->fragments = MAX_BLOCKS;
505 p->bytes = p->fragsize * p->fragments;
509 /* This is called on an interupt so use locking.. Note Qisr2app_
510 is used so we should wrap all references to it in locks. */
512 fhandler_dev_dsp::Audio_out::callback_sampledone (WAVEHDR *pHdr)
514 Qisr2app_->send (pHdr);
518 fhandler_dev_dsp::Audio_out::waitforspace ()
521 MMRESULT rc = WAVERR_STILLPLAYING;
525 while (!Qisr2app_->recv (&pHdr))
527 debug_printf ("100ms");
532 /* Errors are ignored here. They will probbaly cause a failure
533 in the subsequent PrepareHeader */
534 rc = waveOutUnprepareHeader (dev_, pHdr, sizeof (WAVEHDR));
535 debug_printf ("%d = waveOutUnprepareHeader (0x%08x)", rc, pHdr);
542 fhandler_dev_dsp::Audio_out::waitforallsent ()
544 while (Qisr2app_->query () != MAX_BLOCKS)
546 debug_printf ("%d blocks in Qisr2app", Qisr2app_->query ());
551 // send the block described by pHdr_ and bufferIndex_ to wave device
553 fhandler_dev_dsp::Audio_out::sendcurrent ()
555 WAVEHDR *pHdr = pHdr_;
557 debug_printf ("pHdr=0x%08x bytes=%d", pHdr, bufferIndex_);
563 // Sample buffer conversion
564 (this->*convert_) ((unsigned char *)pHdr->lpData, bufferIndex_);
566 // Send internal buffer out to the soundcard
567 pHdr->dwBufferLength = bufferIndex_;
568 rc = waveOutPrepareHeader (dev_, pHdr, sizeof (WAVEHDR));
569 debug_printf ("%d = waveOutPrepareHeader (0x%08x)", rc, pHdr);
570 if (rc == MMSYSERR_NOERROR)
572 rc = waveOutWrite (dev_, pHdr, sizeof (WAVEHDR));
573 debug_printf ("%d = waveOutWrite (0x%08x)", rc, pHdr);
575 if (rc == MMSYSERR_NOERROR)
578 /* FIXME: Should we return an error instead ?*/
579 pHdr->dwFlags = 0; /* avoid calling UnprepareHeader again */
580 Qisr2app_->send (pHdr);
584 //------------------------------------------------------------------------
587 waveOut_callback (HWAVEOUT hWave, UINT msg, DWORD instance, DWORD param1,
592 fhandler_dev_dsp::Audio_out *ptr =
593 (fhandler_dev_dsp::Audio_out *) instance;
594 ptr->callback_sampledone ((WAVEHDR *) param1);
598 //------------------------------------------------------------------------
599 // wav file detection..
608 unsigned short wFormatTag;
609 unsigned short wChannels;
610 unsigned int dwSamplesPerSec;
611 unsigned int dwAvgBytesPerSec;
612 unsigned short wBlockAlign;
613 unsigned short wBitsPerSample;
618 fhandler_dev_dsp::Audio_out::parsewav (const char * &pData, int &nBytes,
619 int dev_freq, int dev_bits, int dev_channels)
622 const char *end = pData + nBytes;
626 /* Start with default values from the device handler */
629 channels_ = dev_channels;
630 setconvert (bits_ == 8 ? AFMT_U8 : AFMT_S16_LE);
632 // Check alignment first: A lot of the code below depends on it
633 if (((int)pData & 0x3) != 0)
635 if (!(pData[0] == 'R' && pData[1] == 'I'
636 && pData[2] == 'F' && pData[3] == 'F'))
638 if (!(pData[8] == 'W' && pData[9] == 'A'
639 && pData[10] == 'V' && pData[11] == 'E'))
642 len = *(int *) &pData[4];
646 while ((len > 0) && (pDat + sizeof (wavchunk) < end))
647 { /* We recognize two kinds of wavchunk:
648 "fmt " for the PCM parameters (only PCM supported here)
649 "data" for the start of PCM data */
650 wavchunk * pChunk = (wavchunk *) pDat;
651 int blklen = pChunk-> len;
652 if (pChunk->id[0] == 'f' && pChunk->id[1] == 'm'
653 && pChunk->id[2] == 't' && pChunk->id[3] == ' ')
655 wavformat *format = (wavformat *) (pChunk + 1);
656 if ((char *) (format + 1) >= end)
658 // We have found the parameter chunk
659 if (format->wFormatTag == 0x0001)
660 { // Micr*s*ft PCM; check if parameters work with our device
661 if (query (format->dwSamplesPerSec, format->wBitsPerSample,
663 { // return the parameters we found
664 freq_ = format->dwSamplesPerSec;
665 bits_ = format->wBitsPerSample;
666 channels_ = format->wChannels;
672 if (pChunk->id[0] == 'd' && pChunk->id[1] == 'a'
673 && pChunk->id[2] == 't' && pChunk->id[3] == 'a')
674 { // throw away all the header & not output it to the soundcard.
675 skip += sizeof (wavchunk);
676 debug_printf ("Discard %d bytes wave header", skip);
679 setconvert (bits_ == 8 ? AFMT_U8 : AFMT_S16_LE);
683 pDat += blklen + sizeof (wavchunk);
684 skip += blklen + sizeof (wavchunk);
685 len -= blklen + sizeof (wavchunk);
690 /* ========================================================================
691 Buffering concept for Audio_in:
692 On the first read, we queue all blocks of our bigwavebuffer
693 for reception and start the wave-in device.
694 We manage queues of pointers to WAVEHDR
695 When a block has been filled, the callback puts the corresponding
696 WAVEHDR pointer into a queue.
697 The function read() blocks (polled, sigh) until at least one good buffer
698 has arrived, then the data is copied into the buffer provided to read().
699 After a buffer has been fully used by read(), it is queued again
700 to the wave-in device immediately.
701 The function read() iterates until all data requested has been
702 received, there is no way to interrupt it */
705 fhandler_dev_dsp::Audio_in::fork_fixup (HANDLE parent)
708 It will be necessary to reset the queue, open the device
709 and create a lock when reading */
710 debug_printf ("parent=0x%08x", parent);
715 fhandler_dev_dsp::Audio_in::query (int rate, int bits, int channels)
720 fillFormat (&format, rate, bits, channels);
721 rc = waveInOpen (NULL, WAVE_MAPPER, &format, 0L, 0L, WAVE_FORMAT_QUERY);
722 debug_printf ("%d = waveInOpen (freq=%d bits=%d channels=%d)", rc, rate, bits, channels);
723 return (rc == MMSYSERR_NOERROR);
727 fhandler_dev_dsp::Audio_in::start (int rate, int bits, int channels)
731 unsigned bSize = blockSize (rate, bits, channels);
736 /* In case of fork bigwavebuffer may already exist */
738 bigwavebuffer_ = new char[MAX_BLOCKS * bSize];
743 fillFormat (&format, rate, bits, channels);
744 rc = waveInOpen (&dev_, WAVE_MAPPER, &format, (DWORD) waveIn_callback,
745 (DWORD) this, CALLBACK_FUNCTION);
746 debug_printf ("%d = waveInOpen (rate=%d bits=%d channels=%d)", rc, rate, bits, channels);
748 if (rc == MMSYSERR_NOERROR)
753 return (rc == MMSYSERR_NOERROR);
757 fhandler_dev_dsp::Audio_in::stop ()
762 debug_printf ("dev_=%08x", (int)dev_);
765 /* Note that waveInReset calls our callback for all incomplete buffers.
766 Since all the win32 wave functions appear to use a common lock,
767 we must not call into the wave API from the callback.
768 Otherwise we end up in a deadlock. */
769 rc = waveInReset (dev_);
770 debug_printf ("%d = waveInReset ()", rc);
772 while (Qisr2app_->recv (&pHdr))
774 rc = waveInUnprepareHeader (dev_, pHdr, sizeof (WAVEHDR));
775 debug_printf ("%d = waveInUnprepareHeader (0x%08x)", rc, pHdr);
778 rc = waveInClose (dev_);
779 debug_printf ("%d = waveInClose ()", rc);
781 Qisr2app_->dellock ();
786 fhandler_dev_dsp::Audio_in::queueblock (WAVEHDR *pHdr)
789 rc = waveInPrepareHeader (dev_, pHdr, sizeof (WAVEHDR));
790 debug_printf ("%d = waveInPrepareHeader (0x%08x)", rc, pHdr);
791 if (rc == MMSYSERR_NOERROR)
793 rc = waveInAddBuffer (dev_, pHdr, sizeof (WAVEHDR));
794 debug_printf ("%d = waveInAddBuffer (0x%08x)", rc, pHdr);
796 if (rc == MMSYSERR_NOERROR)
799 /* FIXME: Should the calling function return an error instead ?*/
800 pHdr->dwFlags = 0; /* avoid calling UnprepareHeader again */
801 pHdr->dwBytesRecorded = 0; /* no data will have been read */
802 Qisr2app_->send (pHdr);
807 fhandler_dev_dsp::Audio_in::init (unsigned blockSize)
812 // try to queue all of our buffer for reception
814 for (i = 0; i < MAX_BLOCKS; i++)
816 wavehdr_[i].lpData = &bigwavebuffer_[i * blockSize];
817 wavehdr_[i].dwBufferLength = blockSize;
818 wavehdr_[i].dwFlags = 0;
819 if (!queueblock (&wavehdr_[i]))
823 rc = waveInStart (dev_);
824 debug_printf ("%d = waveInStart (), queued=%d", rc, i);
825 return (rc == MMSYSERR_NOERROR);
829 fhandler_dev_dsp::Audio_in::read (char *pSampleData, int &nBytes)
831 int bytes_to_read = nBytes;
833 debug_printf ("pSampleData=%08x nBytes=%d", pSampleData, bytes_to_read);
834 while (bytes_to_read != 0)
835 { // Block till next sound has been read
838 // Handle gathering our blocks into smaller or larger buffer
839 int sizeleft = pHdr_->dwBytesRecorded - bufferIndex_;
840 if (bytes_to_read < sizeleft)
841 { // The current buffer holds more data than requested
842 memcpy (pSampleData, &pHdr_->lpData[bufferIndex_], bytes_to_read);
843 (this->*convert_) ((unsigned char *)pSampleData, bytes_to_read);
844 nBytes += bytes_to_read;
845 bufferIndex_ += bytes_to_read;
846 debug_printf ("got %d", bytes_to_read);
847 break; // done; use remaining data in next call to read
850 { // not enough or exact amount in the current buffer
852 { // use up what we have
853 memcpy (pSampleData, &pHdr_->lpData[bufferIndex_], sizeleft);
854 (this->*convert_) ((unsigned char *)pSampleData, sizeleft);
856 bytes_to_read -= sizeleft;
857 pSampleData += sizeleft;
858 debug_printf ("got %d", sizeleft);
860 queueblock (pHdr_); // re-queue this block to ISR
861 pHdr_ = NULL; // need to wait for a new block
862 // if more samples are needed, we need a new block now
865 debug_printf ("end nBytes=%d", nBytes);
870 fhandler_dev_dsp::Audio_in::waitfordata ()
877 while (!Qisr2app_->recv (&pHdr))
879 debug_printf ("100ms");
882 if (pHdr->dwFlags) /* Zero if queued following error in queueblock */
884 /* Errors are ignored here. They will probbaly cause a failure
885 in the subsequent PrepareHeader */
886 rc = waveInUnprepareHeader (dev_, pHdr, sizeof (WAVEHDR));
887 debug_printf ("%d = waveInUnprepareHeader (0x%08x)", rc, pHdr);
894 fhandler_dev_dsp::Audio_in::buf_info (audio_buf_info *p,
895 int rate, int bits, int channels)
897 p->fragstotal = MAX_BLOCKS;
898 p->fragsize = blockSize (rate, bits, channels);
901 p->fragments = Qisr2app_->query ();
903 p->bytes = pHdr_->dwBytesRecorded - bufferIndex_
904 + p->fragsize * p->fragments;
906 p->bytes = p->fragsize * p->fragments;
916 fhandler_dev_dsp::Audio_in::callback_blockfull (WAVEHDR *pHdr)
918 Qisr2app_->send (pHdr);
922 waveIn_callback (HWAVEIN hWave, UINT msg, DWORD instance, DWORD param1,
927 fhandler_dev_dsp::Audio_in *ptr =
928 (fhandler_dev_dsp::Audio_in *) instance;
929 ptr->callback_blockfull ((WAVEHDR *) param1);
934 /* ------------------------------------------------------------------------
936 ------------------------------------------------------------------------ */
937 fhandler_dev_dsp::fhandler_dev_dsp ():
940 debug_printf ("0x%08x", (int)this);
946 fhandler_dev_dsp::open (int flags, mode_t mode)
948 if (cygheap->fdtab.find_archetype (dev ()))
954 UINT num_in = 0, num_out = 0;
955 set_flags ((flags & ~O_TEXT) | O_BINARY);
956 // Work out initial sample format & frequency, /dev/dsp defaults
957 audioformat_ = AFMT_U8;
961 switch (flags & O_ACCMODE)
964 if ((num_in = waveInGetNumDevs ()) == 0)
968 if ((num_out = waveOutGetNumDevs ()) == 0)
972 if ((num_in = waveInGetNumDevs ()) == 0)
982 need_fork_fixup (true);
985 // FIXME: Do this better someday
986 fhandler_dev_dsp *arch = (fhandler_dev_dsp *) cmalloc (HEAP_ARCHETYPES, sizeof (*this));
988 *((fhandler_dev_dsp **) cygheap->fdtab.add_archetype ()) = arch;
990 archetype->usecount = 1;
995 debug_printf ("ACCMODE=0x%08x audio_in=%d audio_out=%d, err=%d",
996 flags & O_ACCMODE, num_in, num_out, err);
1000 #define IS_WRITE() ((get_flags() & O_ACCMODE) != O_RDONLY)
1001 #define IS_READ() ((get_flags() & O_ACCMODE) != O_WRONLY)
1004 fhandler_dev_dsp::write (const void *ptr, size_t len)
1006 debug_printf ("ptr=%08x len=%d", ptr, len);
1007 if ((fhandler_dev_dsp *) archetype != this)
1008 return ((fhandler_dev_dsp *)archetype)->write(ptr, len);
1011 const char *ptr_s = static_cast <const char *> (ptr);
1016 debug_printf ("Allocating");
1017 if (!(audio_out_ = new Audio_out))
1020 /* check for wave file & get parameters & skip header if possible. */
1022 if (audio_out_->parsewav (ptr_s, len_s,
1023 audiofreq_, audiobits_, audiochannels_))
1024 debug_printf ("=> ptr_s=%08x len_s=%d", ptr_s, len_s);
1028 set_errno (EBADF); // device was opened for read?
1032 /* Open audio device properly with callbacks.
1033 Private parameters were set in call to parsewav.
1034 This is a no-op when there are successive writes in the same process */
1035 if (!audio_out_->start ())
1041 audio_out_->write (ptr_s, len_s);
1046 fhandler_dev_dsp::read (void *ptr, size_t& len)
1048 debug_printf ("ptr=%08x len=%d", ptr, len);
1049 if ((fhandler_dev_dsp *) archetype != this)
1050 return ((fhandler_dev_dsp *)archetype)->read(ptr, len);
1055 debug_printf ("Allocating");
1056 if (!(audio_in_ = new Audio_in))
1061 audio_in_->setconvert (audioformat_);
1066 set_errno (EBADF); // device was opened for write?
1070 /* Open audio device properly with callbacks.
1071 This is a noop when there are successive reads in the same process */
1072 if (!audio_in_->start (audiofreq_, audiobits_, audiochannels_))
1079 audio_in_->read ((char *)ptr, (int&)len);
1083 fhandler_dev_dsp::lseek (_off64_t offset, int whence)
1089 fhandler_dev_dsp::close_audio_in ()
1100 fhandler_dev_dsp::close_audio_out (bool immediately)
1104 audio_out_->stop (immediately);
1111 fhandler_dev_dsp::close ()
1113 debug_printf ("audio_in=%08x audio_out=%08x",
1114 (int)audio_in_, (int)audio_out_);
1117 if ((fhandler_dev_dsp *) archetype != this)
1118 return ((fhandler_dev_dsp *) archetype)->close ();
1120 if (--usecount == 0)
1123 close_audio_out (exit_state != ES_NOT_EXITING);
1130 fhandler_dev_dsp::dup (fhandler_base * child)
1133 child->archetype = archetype;
1134 archetype->usecount++;
1139 fhandler_dev_dsp::ioctl (unsigned int cmd, void *ptr)
1141 debug_printf ("audio_in=%08x audio_out=%08x",
1142 (int)audio_in_, (int)audio_out_);
1143 if ((fhandler_dev_dsp *) archetype != this)
1144 return ((fhandler_dev_dsp *)archetype)->ioctl(cmd, ptr);
1146 int *intptr = (int *) ptr;
1149 #define CASE(a) case a : debug_printf ("/dev/dsp: ioctl %s", #a);
1151 CASE (SNDCTL_DSP_RESET)
1153 close_audio_out (true);
1157 CASE (SNDCTL_DSP_GETBLKSIZE)
1158 /* This is valid even if audio_X is NULL */
1161 *intptr = audio_out_->blockSize (audiofreq_,
1166 { // I am very sure that IS_READ is valid
1167 *intptr = audio_in_->blockSize (audiofreq_,
1173 CASE (SNDCTL_DSP_SETFMT)
1179 *intptr = audioformat_;
1195 if (nBits && IS_WRITE ())
1198 if (audio_out_->query (audiofreq_, nBits, audiochannels_))
1201 audioformat_ = *intptr;
1205 *intptr = audiobits_;
1209 if (nBits && IS_READ ())
1212 if (audio_in_->query (audiofreq_, nBits, audiochannels_))
1215 audioformat_ = *intptr;
1219 *intptr = audiobits_;
1226 CASE (SNDCTL_DSP_SPEED)
1230 if (audio_out_->query (*intptr, audiobits_, audiochannels_))
1231 audiofreq_ = *intptr;
1234 *intptr = audiofreq_;
1241 if (audio_in_->query (*intptr, audiobits_, audiochannels_))
1242 audiofreq_ = *intptr;
1245 *intptr = audiofreq_;
1251 CASE (SNDCTL_DSP_STEREO)
1253 int nChannels = *intptr + 1;
1254 int res = ioctl (SNDCTL_DSP_CHANNELS, &nChannels);
1255 *intptr = nChannels - 1;
1259 CASE (SNDCTL_DSP_CHANNELS)
1261 int nChannels = *intptr;
1266 if (audio_out_->query (audiofreq_, audiobits_, nChannels))
1267 audiochannels_ = nChannels;
1270 *intptr = audiochannels_;
1277 if (audio_in_->query (audiofreq_, audiobits_, nChannels))
1278 audiochannels_ = nChannels;
1281 *intptr = audiochannels_;
1288 CASE (SNDCTL_DSP_GETOSPACE)
1295 audio_buf_info *p = (audio_buf_info *) ptr;
1296 audio_out_->buf_info (p, audiofreq_, audiobits_, audiochannels_);
1297 debug_printf ("ptr=%p frags=%d fragsize=%d bytes=%d",
1298 ptr, p->fragments, p->fragsize, p->bytes);
1302 CASE (SNDCTL_DSP_GETISPACE)
1309 audio_buf_info *p = (audio_buf_info *) ptr;
1310 audio_in_->buf_info (p, audiofreq_, audiobits_, audiochannels_);
1311 debug_printf ("ptr=%p frags=%d fragsize=%d bytes=%d",
1312 ptr, p->fragments, p->fragsize, p->bytes);
1316 CASE (SNDCTL_DSP_SETFRAGMENT)
1317 // Fake!! esound & mikmod require this on non PowerPC platforms.
1321 CASE (SNDCTL_DSP_GETFMTS)
1322 *intptr = AFMT_S16_LE | AFMT_U8; // only native formats returned here
1325 CASE (SNDCTL_DSP_GETCAPS)
1326 *intptr = DSP_CAP_BATCH | DSP_CAP_DUPLEX;
1329 CASE (SNDCTL_DSP_POST)
1330 CASE (SNDCTL_DSP_SYNC)
1331 // Stop audio out device
1333 // Stop audio in device
1338 debug_printf ("/dev/dsp: ioctl 0x%08x not handled yet! FIXME:", cmd);
1348 fhandler_dev_dsp::fixup_after_fork (HANDLE parent)
1349 { // called from new child process
1350 debug_printf ("audio_in=%08x audio_out=%08x",
1351 (int)audio_in_, (int)audio_out_);
1352 if (archetype != this)
1353 return ((fhandler_dev_dsp *)archetype)->fixup_after_fork (parent);
1356 audio_in_ ->fork_fixup (parent);
1358 audio_out_->fork_fixup (parent);
1362 fhandler_dev_dsp::fixup_after_exec ()
1364 debug_printf ("audio_in=%08x audio_out=%08x, close_on_exec %d",
1365 (int) audio_in_, (int) audio_out_, close_on_exec ());
1366 if (!close_on_exec ())
1368 if (archetype != this)
1369 return ((fhandler_dev_dsp *) archetype)->fixup_after_exec ();