* fhandler_dsp.cc (fhandler_dev_dsp::Audio_out::stop): Add optional
boolean argument so that playing can be stopped without playing pending buffers. (fhandler_dev_dsp::ioctl): Stop playback immediately for SNDCTL_DSP_RESET. Do not reset audio parameters in this case. Add support for ioctl SNDCTL_DSP_GETISPACE. (fhandler_dev_dsp::Audio_out::emptyblocks): Now returns the number of completely empty blocks. (fhandler_dev_dsp::Audio_out::buf_info): p->fragments is now the number of completely empty blocks. This conforms with the OSS specification. (fhandler_dev_dsp::Audio_out::parsewav): Ignore wave headers that are not aligned on four byte boundary. (fhandler_dev_dsp::Audio_in::buf_info): New, needed for SNDCTL_DSP_GETISPACE.
This commit is contained in:
parent
825b388289
commit
37194b25f6
|
@ -1,3 +1,20 @@
|
|||
2004-04-13 Gerd Spalink <Gerd.Spalink@t-online.de>
|
||||
|
||||
* fhandler_dsp.cc (fhandler_dev_dsp::Audio_out::stop): Add optional
|
||||
boolean argument so that playing can be stopped without playing
|
||||
pending buffers.
|
||||
(fhandler_dev_dsp::ioctl): Stop playback immediately for
|
||||
SNDCTL_DSP_RESET. Do not reset audio parameters in this case.
|
||||
Add support for ioctl SNDCTL_DSP_GETISPACE.
|
||||
(fhandler_dev_dsp::Audio_out::emptyblocks): Now returns the number of
|
||||
completely empty blocks.
|
||||
(fhandler_dev_dsp::Audio_out::buf_info): p->fragments is now the number
|
||||
of completely empty blocks. This conforms with the OSS specification.
|
||||
(fhandler_dev_dsp::Audio_out::parsewav): Ignore wave headers that are
|
||||
not aligned on four byte boundary.
|
||||
(fhandler_dev_dsp::Audio_in::buf_info): New, needed for
|
||||
SNDCTL_DSP_GETISPACE.
|
||||
|
||||
2004-04-13 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* winsup.h (IMPLEMENT_STATUS_FLAG): New macro to define status flag
|
||||
|
|
|
@ -113,7 +113,7 @@ class fhandler_dev_dsp::Audio_out: public Audio
|
|||
|
||||
bool query (int rate, int bits, int channels);
|
||||
bool start (int rate, int bits, int channels);
|
||||
void stop ();
|
||||
void stop (bool immediately = false);
|
||||
bool write (const char *pSampleData, int nBytes);
|
||||
void buf_info (audio_buf_info *p, int rate, int bits, int channels);
|
||||
void callback_sampledone (WAVEHDR *pHdr);
|
||||
|
@ -152,6 +152,7 @@ public:
|
|||
bool start (int rate, int bits, int channels);
|
||||
void stop ();
|
||||
bool read (char *pSampleData, int &nBytes);
|
||||
void buf_info (audio_buf_info *p, int rate, int bits, int channels);
|
||||
void callback_blockfull (WAVEHDR *pHdr);
|
||||
|
||||
private:
|
||||
|
@ -418,7 +419,7 @@ fhandler_dev_dsp::Audio_out::start (int rate, int bits, int channels)
|
|||
}
|
||||
|
||||
void
|
||||
fhandler_dev_dsp::Audio_out::stop ()
|
||||
fhandler_dev_dsp::Audio_out::stop (bool immediately)
|
||||
{
|
||||
MMRESULT rc;
|
||||
WAVEHDR *pHdr;
|
||||
|
@ -427,9 +428,12 @@ fhandler_dev_dsp::Audio_out::stop ()
|
|||
debug_printf ("dev_=%08x pid=%d owner=%d", (int)dev_,
|
||||
GetCurrentProcessId (), getOwner ());
|
||||
if (getOwner () && !denyAccess ())
|
||||
{
|
||||
if (!immediately)
|
||||
{
|
||||
sendcurrent (); // force out last block whatever size..
|
||||
waitforallsent (); // block till finished..
|
||||
}
|
||||
|
||||
rc = waveOutReset (dev_);
|
||||
debug_printf ("waveOutReset rc=%d", rc);
|
||||
|
@ -507,7 +511,7 @@ fhandler_dev_dsp::Audio_out::write (const char *pSampleData, int nBytes)
|
|||
return true;
|
||||
}
|
||||
|
||||
// return number of (partially) empty blocks back.
|
||||
// return number of (completely) empty blocks back.
|
||||
int
|
||||
fhandler_dev_dsp::Audio_out::emptyblocks ()
|
||||
{
|
||||
|
@ -516,8 +520,6 @@ fhandler_dev_dsp::Audio_out::emptyblocks ()
|
|||
n = Qisr2app_->query ();
|
||||
unlock ();
|
||||
n += Qapp2app_->query ();
|
||||
if (pHdr_ != NULL)
|
||||
n++;
|
||||
return n;
|
||||
}
|
||||
|
||||
|
@ -531,8 +533,8 @@ fhandler_dev_dsp::Audio_out::buf_info (audio_buf_info *p,
|
|||
{
|
||||
p->fragments = emptyblocks ();
|
||||
if (pHdr_ != NULL)
|
||||
p->bytes = p->fragsize - bufferIndex_ +
|
||||
p->fragsize * (p->fragments - 1);
|
||||
p->bytes = (int)pHdr_->dwUser - bufferIndex_
|
||||
+ p->fragsize * p->fragments;
|
||||
else
|
||||
p->bytes = p->fragsize * p->fragments;
|
||||
}
|
||||
|
@ -685,7 +687,9 @@ fhandler_dev_dsp::Audio_out::parsewav (const char * &pData, int &nBytes,
|
|||
const char *end = pData + nBytes;
|
||||
const char *pDat;
|
||||
int skip = 0;
|
||||
|
||||
// Check alignment first: A lot of the code below depends on it
|
||||
if (((int)pData & 0x3) != 0)
|
||||
return false;
|
||||
if (!(pData[0] == 'R' && pData[1] == 'I'
|
||||
&& pData[2] == 'F' && pData[3] == 'F'))
|
||||
return false;
|
||||
|
@ -971,6 +975,31 @@ fhandler_dev_dsp::Audio_in::waitfordata ()
|
|||
bufferIndex_ = 0;
|
||||
}
|
||||
|
||||
void
|
||||
fhandler_dev_dsp::Audio_in::buf_info (audio_buf_info *p,
|
||||
int rate, int bits, int channels)
|
||||
{
|
||||
p->fragstotal = MAX_BLOCKS;
|
||||
p->fragsize = blockSize (rate, bits, channels);
|
||||
if (getOwner ())
|
||||
{
|
||||
lock ();
|
||||
p->fragments = Qisr2app_->query ();
|
||||
unlock ();
|
||||
p->fragments += Qapp2app_->query ();
|
||||
if (pHdr_ != NULL)
|
||||
p->bytes = pHdr_->dwBytesRecorded - bufferIndex_
|
||||
+ p->fragsize * p->fragments;
|
||||
else
|
||||
p->bytes = p->fragsize * p->fragments;
|
||||
}
|
||||
else
|
||||
{
|
||||
p->fragments = 0;
|
||||
p->bytes = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// This is called on an interrupt so use locking..
|
||||
void
|
||||
fhandler_dev_dsp::Audio_in::callback_blockfull (WAVEHDR *pHdr)
|
||||
|
@ -1214,22 +1243,12 @@ fhandler_dev_dsp::ioctl (unsigned int cmd, void *ptr)
|
|||
if (audio_out_)
|
||||
{
|
||||
RETURN_ERROR_WHEN_BUSY (audio_out_);
|
||||
audioformat_ = AFMT_U8;
|
||||
audiofreq_ = 8000;
|
||||
audiobits_ = 8;
|
||||
audiochannels_ = 1;
|
||||
audio_out_->stop ();
|
||||
audio_out_->setformat (audioformat_);
|
||||
audio_out_->stop (true);
|
||||
}
|
||||
if (audio_in_)
|
||||
{
|
||||
RETURN_ERROR_WHEN_BUSY (audio_in_);
|
||||
audioformat_ = AFMT_U8;
|
||||
audiofreq_ = 8000;
|
||||
audiobits_ = 8;
|
||||
audiochannels_ = 1;
|
||||
audio_in_->stop ();
|
||||
audio_in_->setformat (audioformat_);
|
||||
}
|
||||
return 0;
|
||||
break;
|
||||
|
@ -1416,6 +1435,20 @@ fhandler_dev_dsp::ioctl (unsigned int cmd, void *ptr)
|
|||
}
|
||||
break;
|
||||
|
||||
CASE (SNDCTL_DSP_GETISPACE)
|
||||
{
|
||||
audio_buf_info *p = (audio_buf_info *) ptr;
|
||||
if (audio_in_)
|
||||
{
|
||||
RETURN_ERROR_WHEN_BUSY (audio_in_);
|
||||
audio_in_->buf_info (p, audiofreq_, audiobits_, audiochannels_);
|
||||
debug_printf ("ptr=%p frags=%d fragsize=%d bytes=%d",
|
||||
ptr, p->fragments, p->fragsize, p->bytes);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
CASE (SNDCTL_DSP_SETFRAGMENT)
|
||||
{
|
||||
// Fake!! esound & mikmod require this on non PowerPC platforms.
|
||||
|
|
Loading…
Reference in New Issue