1 /* Fhandler_dev_dsp: code to emulate OSS sound model /dev/dsp
3 Copyright 2001, 2002, 2003, 2004, 2008 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
16 #include <sys/soundcard.h>
24 /*------------------------------------------------------------------------
25 Simple encapsulation of the win32 audio device.
28 1. Audio structures are malloced just before the first read or
29 write to /dev/dsp. The actual buffer size is determined at that time,
30 such that one buffer holds about 125ms of audio data.
31 At the time of this writing, 12 buffers are allocated,
32 so that up to 1.5 seconds can be buffered within Win32.
33 The buffer size can be queried with the ioctl SNDCTL_DSP_GETBLKSIZE,
34 but for this implementation only returns meaningful results if
35 sampling rate, number of channels and number of bits per sample
36 are not changed afterwards.
37 The audio structures are freed when the device is reset or closed,
38 and they are not passed to exec'ed processes.
39 The dev_ member is cleared after a fork. This forces the child
40 to reopen the audio device._
42 2. Every open call creates a new instance of the handler. After a
43 successful open, every subsequent open from the same process
44 to the device fails with EBUSY.
45 The structures are shared between duped handles, but not with
46 children. They only inherit the settings from the parent.
49 class fhandler_dev_dsp::Audio
50 { // This class contains functionality common to Audio_in and Audio_out
58 void setconvert (int format);
59 void convert_none (unsigned char *buffer, int size_bytes) { }
60 void convert_U8_S8 (unsigned char *buffer, int size_bytes);
61 void convert_S16LE_U16LE (unsigned char *buffer, int size_bytes);
62 void convert_S16LE_U16BE (unsigned char *buffer, int size_bytes);
63 void convert_S16LE_S16BE (unsigned char *buffer, int size_bytes);
64 void fillFormat (WAVEFORMATEX * format,
65 int rate, int bits, int channels);
66 unsigned blockSize (int rate, int bits, int channels);
67 void (fhandler_dev_dsp::Audio::*convert_)
68 (unsigned char *buffer, int size_bytes);
70 enum { MAX_BLOCKS = 12 };
71 int bufferIndex_; // offset into pHdr_->lpData
72 WAVEHDR *pHdr_; // data to be filled by write
73 WAVEHDR wavehdr_[MAX_BLOCKS];
74 char *bigwavebuffer_; // audio samples only
75 // Member variables below must be locked
76 queue *Qisr2app_; // blocks passed from wave callback
79 class fhandler_dev_dsp::Audio::queue
80 { // non-blocking fixed size queues for buffer management
82 queue (int depth = 4);
85 bool send (WAVEHDR *); // queue an item, returns true if successful
86 bool recv (WAVEHDR **); // retrieve an item, returns true if successful
88 int query (); // return number of items queued
89 inline void lock () { EnterCriticalSection (&lock_); }
90 inline void unlock () { LeaveCriticalSection (&lock_); }
91 inline void dellock () { debug_printf ("Deleting Critical Section"); DeleteCriticalSection (&lock_); }
92 bool isvalid () { return storage_; }
94 CRITICAL_SECTION lock_;
101 static void CALLBACK waveOut_callback (HWAVEOUT hWave, UINT msg, DWORD instance,
102 DWORD param1, DWORD param2);
104 class fhandler_dev_dsp::Audio_out: public Audio
107 void fork_fixup (HANDLE parent);
108 bool query (int rate, int bits, int channels);
110 void stop (bool immediately = false);
111 bool write (const char *pSampleData, int nBytes);
112 void buf_info (audio_buf_info *p, int rate, int bits, int channels);
113 void callback_sampledone (WAVEHDR *pHdr);
114 bool parsewav (const char *&pData, int &nBytes,
115 int rate, int bits, int channels);
118 void init (unsigned blockSize);
119 void waitforallsent ();
120 void waitforspace ();
123 enum { MAX_BLOCKS = 12 };
124 HWAVEOUT dev_; // The wave device
125 /* Private copies of audiofreq_, audiobits_, audiochannels_,
126 possibly set from wave file */
132 static void CALLBACK waveIn_callback (HWAVEIN hWave, UINT msg, DWORD instance,
133 DWORD param1, DWORD param2);
135 class fhandler_dev_dsp::Audio_in: public Audio
138 void fork_fixup (HANDLE parent);
139 bool query (int rate, int bits, int channels);
140 bool start (int rate, int bits, int channels);
142 bool read (char *pSampleData, int &nBytes);
143 void buf_info (audio_buf_info *p, int rate, int bits, int channels);
144 void callback_blockfull (WAVEHDR *pHdr);
147 bool init (unsigned blockSize);
148 bool queueblock (WAVEHDR *pHdr);
149 void waitfordata (); // blocks until we have a good pHdr_
154 /* --------------------------------------------------------------------
157 // Simple fixed length FIFO queue implementation for audio buffer management
158 fhandler_dev_dsp::Audio::queue::queue (int depth)
160 // allow space for one extra object in the queue
161 // so we can distinguish full and empty status
163 storage_ = new WAVEHDR *[depth_ + 1];
166 fhandler_dev_dsp::Audio::queue::~queue ()
172 fhandler_dev_dsp::Audio::queue::reset ()
174 /* When starting, after reset and after fork */
176 debug_printf ("InitializeCriticalSection");
177 memset (&lock_, 0, sizeof (lock_));
178 InitializeCriticalSection (&lock_);
182 fhandler_dev_dsp::Audio::queue::send (WAVEHDR *x)
186 if (query () == depth_)
187 system_printf ("Queue overflow");
191 if (++tail_ > depth_)
200 fhandler_dev_dsp::Audio::queue::recv (WAVEHDR **x)
206 *x = storage_[head_];
207 if (++head_ > depth_)
216 fhandler_dev_dsp::Audio::queue::query ()
218 int n = tail_ - head_;
224 // Audio class implements functionality need for both read and write
225 fhandler_dev_dsp::Audio::Audio ()
227 bigwavebuffer_ = NULL;
228 Qisr2app_ = new queue (MAX_BLOCKS);
229 convert_ = &fhandler_dev_dsp::Audio::convert_none;
232 fhandler_dev_dsp::Audio::~Audio ()
236 delete[] bigwavebuffer_;
240 fhandler_dev_dsp::Audio::isvalid ()
242 return bigwavebuffer_ && Qisr2app_ && Qisr2app_->isvalid ();
246 fhandler_dev_dsp::Audio::setconvert (int format)
251 convert_ = &fhandler_dev_dsp::Audio::convert_U8_S8;
252 debug_printf ("U8_S8");
255 convert_ = &fhandler_dev_dsp::Audio::convert_S16LE_U16LE;
256 debug_printf ("S16LE_U16LE");
259 convert_ = &fhandler_dev_dsp::Audio::convert_S16LE_U16BE;
260 debug_printf ("S16LE_U16BE");
263 convert_ = &fhandler_dev_dsp::Audio::convert_S16LE_S16BE;
264 debug_printf ("S16LE_S16BE");
267 convert_ = &fhandler_dev_dsp::Audio::convert_none;
268 debug_printf ("none");
273 fhandler_dev_dsp::Audio::convert_U8_S8 (unsigned char *buffer,
276 while (size_bytes-- > 0)
278 *buffer ^= (unsigned char)0x80;
284 fhandler_dev_dsp::Audio::convert_S16LE_U16BE (unsigned char *buffer,
287 int size_samples = size_bytes / 2;
288 unsigned char hi, lo;
289 while (size_samples-- > 0)
294 *buffer++ = hi ^ (unsigned char)0x80;
299 fhandler_dev_dsp::Audio::convert_S16LE_U16LE (unsigned char *buffer,
302 int size_samples = size_bytes / 2;
303 while (size_samples-- > 0)
306 *buffer ^= (unsigned char)0x80;
312 fhandler_dev_dsp::Audio::convert_S16LE_S16BE (unsigned char *buffer,
315 int size_samples = size_bytes / 2;
316 unsigned char hi, lo;
317 while (size_samples-- > 0)
327 fhandler_dev_dsp::Audio::fillFormat (WAVEFORMATEX * format,
328 int rate, int bits, int channels)
330 memset (format, 0, sizeof (*format));
331 format->wFormatTag = WAVE_FORMAT_PCM;
332 format->wBitsPerSample = bits;
333 format->nChannels = channels;
334 format->nSamplesPerSec = rate;
335 format->nAvgBytesPerSec = format->nSamplesPerSec * format->nChannels
337 format->nBlockAlign = format->nChannels * (bits / 8);
340 // calculate a good block size
342 fhandler_dev_dsp::Audio::blockSize (int rate, int bits, int channels)
345 blockSize = ((bits / 8) * channels * rate) / 8; // approx 125ms per block
346 // round up to multiple of 64
352 //=======================================================================
354 fhandler_dev_dsp::Audio_out::fork_fixup (HANDLE parent)
357 It will be necessary to reset the queue, open the device
358 and create a lock when writing */
359 debug_printf ("parent=0x%08x", parent);
365 fhandler_dev_dsp::Audio_out::query (int rate, int bits, int channels)
370 fillFormat (&format, rate, bits, channels);
371 rc = waveOutOpen (NULL, WAVE_MAPPER, &format, 0L, 0L, WAVE_FORMAT_QUERY);
372 debug_printf ("%d = waveOutOpen (freq=%d bits=%d channels=%d)", rc, rate, bits, channels);
373 return (rc == MMSYSERR_NOERROR);
377 fhandler_dev_dsp::Audio_out::start ()
381 unsigned bSize = blockSize (freq_, bits_, channels_);
386 /* In case of fork bigwavebuffer may already exist */
388 bigwavebuffer_ = new char[MAX_BLOCKS * bSize];
393 fillFormat (&format, freq_, bits_, channels_);
394 rc = waveOutOpen (&dev_, WAVE_MAPPER, &format, (DWORD) waveOut_callback,
395 (DWORD) this, CALLBACK_FUNCTION);
396 if (rc == MMSYSERR_NOERROR)
399 debug_printf ("%d = waveOutOpen (freq=%d bits=%d channels=%d)", rc, freq_, bits_, channels_);
401 return (rc == MMSYSERR_NOERROR);
405 fhandler_dev_dsp::Audio_out::stop (bool immediately)
410 debug_printf ("dev_=%08x", (int)dev_);
415 sendcurrent (); // force out last block whatever size..
416 waitforallsent (); // block till finished..
419 rc = waveOutReset (dev_);
420 debug_printf ("%d = waveOutReset ()", rc);
421 while (Qisr2app_->recv (&pHdr))
423 rc = waveOutUnprepareHeader (dev_, pHdr, sizeof (WAVEHDR));
424 debug_printf ("%d = waveOutUnprepareHeader (0x%08x)", rc, pHdr);
427 rc = waveOutClose (dev_);
428 debug_printf ("%d = waveOutClose ()", rc);
430 Qisr2app_->dellock ();
435 fhandler_dev_dsp::Audio_out::init (unsigned blockSize)
439 // internally queue all of our buffer for later use by write
441 for (i = 0; i < MAX_BLOCKS; i++)
443 wavehdr_[i].lpData = &bigwavebuffer_[i * blockSize];
444 wavehdr_[i].dwUser = (int) blockSize;
445 wavehdr_[i].dwFlags = 0;
446 if (!Qisr2app_->send (&wavehdr_[i]))
448 system_printf ("Internal Error i=%d", i);
449 break; // should not happen
456 fhandler_dev_dsp::Audio_out::write (const char *pSampleData, int nBytes)
459 { // Block if all blocks used until at least one is free
462 int sizeleft = (int)pHdr_->dwUser - bufferIndex_;
463 if (nBytes < sizeleft)
464 { // all data fits into the current block, with some space left
465 memcpy (&pHdr_->lpData[bufferIndex_], pSampleData, nBytes);
466 bufferIndex_ += nBytes;
470 { // data will fill up the current block
471 memcpy (&pHdr_->lpData[bufferIndex_], pSampleData, sizeleft);
472 bufferIndex_ += sizeleft;
474 pSampleData += sizeleft;
482 fhandler_dev_dsp::Audio_out::buf_info (audio_buf_info *p,
483 int rate, int bits, int channels)
485 p->fragstotal = MAX_BLOCKS;
488 /* If the device is running we use the internal values,
489 possibly set from the wave file. */
490 p->fragsize = blockSize (freq_, bits_, channels_);
491 p->fragments = Qisr2app_->query ();
493 p->bytes = (int)pHdr_->dwUser - bufferIndex_
494 + p->fragsize * p->fragments;
496 p->bytes = p->fragsize * p->fragments;
500 p->fragsize = blockSize (rate, bits, channels);
501 p->fragments = MAX_BLOCKS;
502 p->bytes = p->fragsize * p->fragments;
506 /* This is called on an interupt so use locking.. Note Qisr2app_
507 is used so we should wrap all references to it in locks. */
509 fhandler_dev_dsp::Audio_out::callback_sampledone (WAVEHDR *pHdr)
511 Qisr2app_->send (pHdr);
515 fhandler_dev_dsp::Audio_out::waitforspace ()
518 MMRESULT rc = WAVERR_STILLPLAYING;
522 while (!Qisr2app_->recv (&pHdr))
524 debug_printf ("100ms");
529 /* Errors are ignored here. They will probbaly cause a failure
530 in the subsequent PrepareHeader */
531 rc = waveOutUnprepareHeader (dev_, pHdr, sizeof (WAVEHDR));
532 debug_printf ("%d = waveOutUnprepareHeader (0x%08x)", rc, pHdr);
539 fhandler_dev_dsp::Audio_out::waitforallsent ()
541 while (Qisr2app_->query () != MAX_BLOCKS)
543 debug_printf ("%d blocks in Qisr2app", Qisr2app_->query ());
548 // send the block described by pHdr_ and bufferIndex_ to wave device
550 fhandler_dev_dsp::Audio_out::sendcurrent ()
552 WAVEHDR *pHdr = pHdr_;
554 debug_printf ("pHdr=0x%08x bytes=%d", pHdr, bufferIndex_);
560 // Sample buffer conversion
561 (this->*convert_) ((unsigned char *)pHdr->lpData, bufferIndex_);
563 // Send internal buffer out to the soundcard
564 pHdr->dwBufferLength = bufferIndex_;
565 rc = waveOutPrepareHeader (dev_, pHdr, sizeof (WAVEHDR));
566 debug_printf ("%d = waveOutPrepareHeader (0x%08x)", rc, pHdr);
567 if (rc == MMSYSERR_NOERROR)
569 rc = waveOutWrite (dev_, pHdr, sizeof (WAVEHDR));
570 debug_printf ("%d = waveOutWrite (0x%08x)", rc, pHdr);
572 if (rc == MMSYSERR_NOERROR)
575 /* FIXME: Should we return an error instead ?*/
576 pHdr->dwFlags = 0; /* avoid calling UnprepareHeader again */
577 Qisr2app_->send (pHdr);
581 //------------------------------------------------------------------------
584 waveOut_callback (HWAVEOUT hWave, UINT msg, DWORD instance, DWORD param1,
589 fhandler_dev_dsp::Audio_out *ptr =
590 (fhandler_dev_dsp::Audio_out *) instance;
591 ptr->callback_sampledone ((WAVEHDR *) param1);
595 //------------------------------------------------------------------------
596 // wav file detection..
605 unsigned short wFormatTag;
606 unsigned short wChannels;
607 unsigned int dwSamplesPerSec;
608 unsigned int dwAvgBytesPerSec;
609 unsigned short wBlockAlign;
610 unsigned short wBitsPerSample;
615 fhandler_dev_dsp::Audio_out::parsewav (const char * &pData, int &nBytes,
616 int dev_freq, int dev_bits, int dev_channels)
619 const char *end = pData + nBytes;
623 /* Start with default values from the device handler */
626 channels_ = dev_channels;
627 setconvert (bits_ == 8 ? AFMT_U8 : AFMT_S16_LE);
629 // Check alignment first: A lot of the code below depends on it
630 if (((int)pData & 0x3) != 0)
632 if (!(pData[0] == 'R' && pData[1] == 'I'
633 && pData[2] == 'F' && pData[3] == 'F'))
635 if (!(pData[8] == 'W' && pData[9] == 'A'
636 && pData[10] == 'V' && pData[11] == 'E'))
639 len = *(int *) &pData[4];
643 while ((len > 0) && (pDat + sizeof (wavchunk) < end))
644 { /* We recognize two kinds of wavchunk:
645 "fmt " for the PCM parameters (only PCM supported here)
646 "data" for the start of PCM data */
647 wavchunk * pChunk = (wavchunk *) pDat;
648 int blklen = pChunk-> len;
649 if (pChunk->id[0] == 'f' && pChunk->id[1] == 'm'
650 && pChunk->id[2] == 't' && pChunk->id[3] == ' ')
652 wavformat *format = (wavformat *) (pChunk + 1);
653 if ((char *) (format + 1) >= end)
655 // We have found the parameter chunk
656 if (format->wFormatTag == 0x0001)
657 { // Micr*s*ft PCM; check if parameters work with our device
658 if (query (format->dwSamplesPerSec, format->wBitsPerSample,
660 { // return the parameters we found
661 freq_ = format->dwSamplesPerSec;
662 bits_ = format->wBitsPerSample;
663 channels_ = format->wChannels;
669 if (pChunk->id[0] == 'd' && pChunk->id[1] == 'a'
670 && pChunk->id[2] == 't' && pChunk->id[3] == 'a')
671 { // throw away all the header & not output it to the soundcard.
672 skip += sizeof (wavchunk);
673 debug_printf ("Discard %d bytes wave header", skip);
676 setconvert (bits_ == 8 ? AFMT_U8 : AFMT_S16_LE);
680 pDat += blklen + sizeof (wavchunk);
681 skip += blklen + sizeof (wavchunk);
682 len -= blklen + sizeof (wavchunk);
687 /* ========================================================================
688 Buffering concept for Audio_in:
689 On the first read, we queue all blocks of our bigwavebuffer
690 for reception and start the wave-in device.
691 We manage queues of pointers to WAVEHDR
692 When a block has been filled, the callback puts the corresponding
693 WAVEHDR pointer into a queue.
694 The function read() blocks (polled, sigh) until at least one good buffer
695 has arrived, then the data is copied into the buffer provided to read().
696 After a buffer has been fully used by read(), it is queued again
697 to the wave-in device immediately.
698 The function read() iterates until all data requested has been
699 received, there is no way to interrupt it */
702 fhandler_dev_dsp::Audio_in::fork_fixup (HANDLE parent)
705 It will be necessary to reset the queue, open the device
706 and create a lock when reading */
707 debug_printf ("parent=0x%08x", parent);
712 fhandler_dev_dsp::Audio_in::query (int rate, int bits, int channels)
717 fillFormat (&format, rate, bits, channels);
718 rc = waveInOpen (NULL, WAVE_MAPPER, &format, 0L, 0L, WAVE_FORMAT_QUERY);
719 debug_printf ("%d = waveInOpen (freq=%d bits=%d channels=%d)", rc, rate, bits, channels);
720 return (rc == MMSYSERR_NOERROR);
724 fhandler_dev_dsp::Audio_in::start (int rate, int bits, int channels)
728 unsigned bSize = blockSize (rate, bits, channels);
733 /* In case of fork bigwavebuffer may already exist */
735 bigwavebuffer_ = new char[MAX_BLOCKS * bSize];
740 fillFormat (&format, rate, bits, channels);
741 rc = waveInOpen (&dev_, WAVE_MAPPER, &format, (DWORD) waveIn_callback,
742 (DWORD) this, CALLBACK_FUNCTION);
743 debug_printf ("%d = waveInOpen (rate=%d bits=%d channels=%d)", rc, rate, bits, channels);
745 if (rc == MMSYSERR_NOERROR)
750 return (rc == MMSYSERR_NOERROR);
754 fhandler_dev_dsp::Audio_in::stop ()
759 debug_printf ("dev_=%08x", (int)dev_);
762 /* Note that waveInReset calls our callback for all incomplete buffers.
763 Since all the win32 wave functions appear to use a common lock,
764 we must not call into the wave API from the callback.
765 Otherwise we end up in a deadlock. */
766 rc = waveInReset (dev_);
767 debug_printf ("%d = waveInReset ()", rc);
769 while (Qisr2app_->recv (&pHdr))
771 rc = waveInUnprepareHeader (dev_, pHdr, sizeof (WAVEHDR));
772 debug_printf ("%d = waveInUnprepareHeader (0x%08x)", rc, pHdr);
775 rc = waveInClose (dev_);
776 debug_printf ("%d = waveInClose ()", rc);
778 Qisr2app_->dellock ();
783 fhandler_dev_dsp::Audio_in::queueblock (WAVEHDR *pHdr)
786 rc = waveInPrepareHeader (dev_, pHdr, sizeof (WAVEHDR));
787 debug_printf ("%d = waveInPrepareHeader (0x%08x)", rc, pHdr);
788 if (rc == MMSYSERR_NOERROR)
790 rc = waveInAddBuffer (dev_, pHdr, sizeof (WAVEHDR));
791 debug_printf ("%d = waveInAddBuffer (0x%08x)", rc, pHdr);
793 if (rc == MMSYSERR_NOERROR)
796 /* FIXME: Should the calling function return an error instead ?*/
797 pHdr->dwFlags = 0; /* avoid calling UnprepareHeader again */
798 pHdr->dwBytesRecorded = 0; /* no data will have been read */
799 Qisr2app_->send (pHdr);
804 fhandler_dev_dsp::Audio_in::init (unsigned blockSize)
809 // try to queue all of our buffer for reception
811 for (i = 0; i < MAX_BLOCKS; i++)
813 wavehdr_[i].lpData = &bigwavebuffer_[i * blockSize];
814 wavehdr_[i].dwBufferLength = blockSize;
815 wavehdr_[i].dwFlags = 0;
816 if (!queueblock (&wavehdr_[i]))
820 rc = waveInStart (dev_);
821 debug_printf ("%d = waveInStart (), queued=%d", rc, i);
822 return (rc == MMSYSERR_NOERROR);
826 fhandler_dev_dsp::Audio_in::read (char *pSampleData, int &nBytes)
828 int bytes_to_read = nBytes;
830 debug_printf ("pSampleData=%08x nBytes=%d", pSampleData, bytes_to_read);
831 while (bytes_to_read != 0)
832 { // Block till next sound has been read
835 // Handle gathering our blocks into smaller or larger buffer
836 int sizeleft = pHdr_->dwBytesRecorded - bufferIndex_;
837 if (bytes_to_read < sizeleft)
838 { // The current buffer holds more data than requested
839 memcpy (pSampleData, &pHdr_->lpData[bufferIndex_], bytes_to_read);
840 (this->*convert_) ((unsigned char *)pSampleData, bytes_to_read);
841 nBytes += bytes_to_read;
842 bufferIndex_ += bytes_to_read;
843 debug_printf ("got %d", bytes_to_read);
844 break; // done; use remaining data in next call to read
847 { // not enough or exact amount in the current buffer
849 { // use up what we have
850 memcpy (pSampleData, &pHdr_->lpData[bufferIndex_], sizeleft);
851 (this->*convert_) ((unsigned char *)pSampleData, sizeleft);
853 bytes_to_read -= sizeleft;
854 pSampleData += sizeleft;
855 debug_printf ("got %d", sizeleft);
857 queueblock (pHdr_); // re-queue this block to ISR
858 pHdr_ = NULL; // need to wait for a new block
859 // if more samples are needed, we need a new block now
862 debug_printf ("end nBytes=%d", nBytes);
867 fhandler_dev_dsp::Audio_in::waitfordata ()
874 while (!Qisr2app_->recv (&pHdr))
876 debug_printf ("100ms");
879 if (pHdr->dwFlags) /* Zero if queued following error in queueblock */
881 /* Errors are ignored here. They will probbaly cause a failure
882 in the subsequent PrepareHeader */
883 rc = waveInUnprepareHeader (dev_, pHdr, sizeof (WAVEHDR));
884 debug_printf ("%d = waveInUnprepareHeader (0x%08x)", rc, pHdr);
891 fhandler_dev_dsp::Audio_in::buf_info (audio_buf_info *p,
892 int rate, int bits, int channels)
894 p->fragstotal = MAX_BLOCKS;
895 p->fragsize = blockSize (rate, bits, channels);
898 p->fragments = Qisr2app_->query ();
900 p->bytes = pHdr_->dwBytesRecorded - bufferIndex_
901 + p->fragsize * p->fragments;
903 p->bytes = p->fragsize * p->fragments;
913 fhandler_dev_dsp::Audio_in::callback_blockfull (WAVEHDR *pHdr)
915 Qisr2app_->send (pHdr);
919 waveIn_callback (HWAVEIN hWave, UINT msg, DWORD instance, DWORD param1,
924 fhandler_dev_dsp::Audio_in *ptr =
925 (fhandler_dev_dsp::Audio_in *) instance;
926 ptr->callback_blockfull ((WAVEHDR *) param1);
931 /* ------------------------------------------------------------------------
933 ------------------------------------------------------------------------ */
934 fhandler_dev_dsp::fhandler_dev_dsp ():
937 debug_printf ("0x%08x", (int)this);
943 fhandler_dev_dsp::open (int flags, mode_t mode)
945 if (cygheap->fdtab.find_archetype (dev ()))
951 UINT num_in = 0, num_out = 0;
952 set_flags ((flags & ~O_TEXT) | O_BINARY);
953 // Work out initial sample format & frequency, /dev/dsp defaults
954 audioformat_ = AFMT_U8;
958 switch (flags & O_ACCMODE)
961 if ((num_in = waveInGetNumDevs ()) == 0)
965 if ((num_out = waveOutGetNumDevs ()) == 0)
969 if ((num_in = waveInGetNumDevs ()) == 0)
979 need_fork_fixup (true);
982 // FIXME: Do this better someday
983 fhandler_dev_dsp *arch = (fhandler_dev_dsp *) cmalloc_abort (HEAP_ARCHETYPES, sizeof (*this));
985 *((fhandler_dev_dsp **) cygheap->fdtab.add_archetype ()) = arch;
987 archetype->usecount = 1;
992 debug_printf ("ACCMODE=0x%08x audio_in=%d audio_out=%d, err=%d",
993 flags & O_ACCMODE, num_in, num_out, err);
997 #define IS_WRITE() ((get_flags() & O_ACCMODE) != O_RDONLY)
998 #define IS_READ() ((get_flags() & O_ACCMODE) != O_WRONLY)
1001 fhandler_dev_dsp::write (const void *ptr, size_t len)
1003 debug_printf ("ptr=%08x len=%d", ptr, len);
1004 if ((fhandler_dev_dsp *) archetype != this)
1005 return ((fhandler_dev_dsp *)archetype)->write(ptr, len);
1008 const char *ptr_s = static_cast <const char *> (ptr);
1013 debug_printf ("Allocating");
1014 if (!(audio_out_ = new Audio_out))
1017 /* check for wave file & get parameters & skip header if possible. */
1019 if (audio_out_->parsewav (ptr_s, len_s,
1020 audiofreq_, audiobits_, audiochannels_))
1021 debug_printf ("=> ptr_s=%08x len_s=%d", ptr_s, len_s);
1025 set_errno (EBADF); // device was opened for read?
1029 /* Open audio device properly with callbacks.
1030 Private parameters were set in call to parsewav.
1031 This is a no-op when there are successive writes in the same process */
1032 if (!audio_out_->start ())
1038 audio_out_->write (ptr_s, len_s);
1043 fhandler_dev_dsp::read (void *ptr, size_t& len)
1045 debug_printf ("ptr=%08x len=%d", ptr, len);
1046 if ((fhandler_dev_dsp *) archetype != this)
1047 return ((fhandler_dev_dsp *)archetype)->read(ptr, len);
1052 debug_printf ("Allocating");
1053 if (!(audio_in_ = new Audio_in))
1058 audio_in_->setconvert (audioformat_);
1063 set_errno (EBADF); // device was opened for write?
1067 /* Open audio device properly with callbacks.
1068 This is a noop when there are successive reads in the same process */
1069 if (!audio_in_->start (audiofreq_, audiobits_, audiochannels_))
1076 audio_in_->read ((char *)ptr, (int&)len);
1080 fhandler_dev_dsp::lseek (_off64_t offset, int whence)
1086 fhandler_dev_dsp::close_audio_in ()
1097 fhandler_dev_dsp::close_audio_out (bool immediately)
1101 audio_out_->stop (immediately);
1108 fhandler_dev_dsp::close ()
1110 debug_printf ("audio_in=%08x audio_out=%08x",
1111 (int)audio_in_, (int)audio_out_);
1114 if ((fhandler_dev_dsp *) archetype != this)
1115 return ((fhandler_dev_dsp *) archetype)->close ();
1117 if (--usecount == 0)
1120 close_audio_out (exit_state != ES_NOT_EXITING);
1127 fhandler_dev_dsp::dup (fhandler_base * child)
1130 child->archetype = archetype;
1131 child->set_flags (get_flags ());
1132 archetype->usecount++;
1137 fhandler_dev_dsp::ioctl (unsigned int cmd, void *ptr)
1139 debug_printf ("audio_in=%08x audio_out=%08x",
1140 (int)audio_in_, (int)audio_out_);
1141 if ((fhandler_dev_dsp *) archetype != this)
1142 return ((fhandler_dev_dsp *)archetype)->ioctl(cmd, ptr);
1144 int *intptr = (int *) ptr;
1147 #define CASE(a) case a : debug_printf ("/dev/dsp: ioctl %s", #a);
1149 CASE (SNDCTL_DSP_RESET)
1151 close_audio_out (true);
1155 CASE (SNDCTL_DSP_GETBLKSIZE)
1156 /* This is valid even if audio_X is NULL */
1159 *intptr = audio_out_->blockSize (audiofreq_,
1164 { // I am very sure that IS_READ is valid
1165 *intptr = audio_in_->blockSize (audiofreq_,
1171 CASE (SNDCTL_DSP_SETFMT)
1177 *intptr = audioformat_;
1193 if (nBits && IS_WRITE ())
1196 if (audio_out_->query (audiofreq_, nBits, audiochannels_))
1199 audioformat_ = *intptr;
1203 *intptr = audiobits_;
1207 if (nBits && IS_READ ())
1210 if (audio_in_->query (audiofreq_, nBits, audiochannels_))
1213 audioformat_ = *intptr;
1217 *intptr = audiobits_;
1224 CASE (SNDCTL_DSP_SPEED)
1228 if (audio_out_->query (*intptr, audiobits_, audiochannels_))
1229 audiofreq_ = *intptr;
1232 *intptr = audiofreq_;
1239 if (audio_in_->query (*intptr, audiobits_, audiochannels_))
1240 audiofreq_ = *intptr;
1243 *intptr = audiofreq_;
1249 CASE (SNDCTL_DSP_STEREO)
1251 int nChannels = *intptr + 1;
1252 int res = ioctl (SNDCTL_DSP_CHANNELS, &nChannels);
1253 *intptr = nChannels - 1;
1257 CASE (SNDCTL_DSP_CHANNELS)
1259 int nChannels = *intptr;
1264 if (audio_out_->query (audiofreq_, audiobits_, nChannels))
1265 audiochannels_ = nChannels;
1268 *intptr = audiochannels_;
1275 if (audio_in_->query (audiofreq_, audiobits_, nChannels))
1276 audiochannels_ = nChannels;
1279 *intptr = audiochannels_;
1286 CASE (SNDCTL_DSP_GETOSPACE)
1293 audio_buf_info *p = (audio_buf_info *) ptr;
1294 audio_out_->buf_info (p, audiofreq_, audiobits_, audiochannels_);
1295 debug_printf ("ptr=%p frags=%d fragsize=%d bytes=%d",
1296 ptr, p->fragments, p->fragsize, p->bytes);
1300 CASE (SNDCTL_DSP_GETISPACE)
1307 audio_buf_info *p = (audio_buf_info *) ptr;
1308 audio_in_->buf_info (p, audiofreq_, audiobits_, audiochannels_);
1309 debug_printf ("ptr=%p frags=%d fragsize=%d bytes=%d",
1310 ptr, p->fragments, p->fragsize, p->bytes);
1314 CASE (SNDCTL_DSP_SETFRAGMENT)
1315 // Fake!! esound & mikmod require this on non PowerPC platforms.
1319 CASE (SNDCTL_DSP_GETFMTS)
1320 *intptr = AFMT_S16_LE | AFMT_U8; // only native formats returned here
1323 CASE (SNDCTL_DSP_GETCAPS)
1324 *intptr = DSP_CAP_BATCH | DSP_CAP_DUPLEX;
1327 CASE (SNDCTL_DSP_POST)
1328 CASE (SNDCTL_DSP_SYNC)
1329 // Stop audio out device
1331 // Stop audio in device
1336 debug_printf ("/dev/dsp: ioctl 0x%08x not handled yet! FIXME:", cmd);
1346 fhandler_dev_dsp::fixup_after_fork (HANDLE parent)
1347 { // called from new child process
1348 debug_printf ("audio_in=%08x audio_out=%08x",
1349 (int)audio_in_, (int)audio_out_);
1350 if (archetype != this)
1351 return ((fhandler_dev_dsp *)archetype)->fixup_after_fork (parent);
1354 audio_in_ ->fork_fixup (parent);
1356 audio_out_->fork_fixup (parent);
1360 fhandler_dev_dsp::fixup_after_exec ()
1362 debug_printf ("audio_in=%08x audio_out=%08x, close_on_exec %d",
1363 (int) audio_in_, (int) audio_out_, close_on_exec ());
1364 if (!close_on_exec ())
1366 if (archetype != this)
1367 return ((fhandler_dev_dsp *) archetype)->fixup_after_exec ();