* 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>
|
2004-04-13 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* winsup.h (IMPLEMENT_STATUS_FLAG): New macro to define status flag
|
* 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 query (int rate, int bits, int channels);
|
||||||
bool start (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);
|
bool write (const char *pSampleData, int nBytes);
|
||||||
void buf_info (audio_buf_info *p, int rate, int bits, int channels);
|
void buf_info (audio_buf_info *p, int rate, int bits, int channels);
|
||||||
void callback_sampledone (WAVEHDR *pHdr);
|
void callback_sampledone (WAVEHDR *pHdr);
|
||||||
|
@ -152,6 +152,7 @@ public:
|
||||||
bool start (int rate, int bits, int channels);
|
bool start (int rate, int bits, int channels);
|
||||||
void stop ();
|
void stop ();
|
||||||
bool read (char *pSampleData, int &nBytes);
|
bool read (char *pSampleData, int &nBytes);
|
||||||
|
void buf_info (audio_buf_info *p, int rate, int bits, int channels);
|
||||||
void callback_blockfull (WAVEHDR *pHdr);
|
void callback_blockfull (WAVEHDR *pHdr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -418,7 +419,7 @@ fhandler_dev_dsp::Audio_out::start (int rate, int bits, int channels)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fhandler_dev_dsp::Audio_out::stop ()
|
fhandler_dev_dsp::Audio_out::stop (bool immediately)
|
||||||
{
|
{
|
||||||
MMRESULT rc;
|
MMRESULT rc;
|
||||||
WAVEHDR *pHdr;
|
WAVEHDR *pHdr;
|
||||||
|
@ -428,8 +429,11 @@ fhandler_dev_dsp::Audio_out::stop ()
|
||||||
GetCurrentProcessId (), getOwner ());
|
GetCurrentProcessId (), getOwner ());
|
||||||
if (getOwner () && !denyAccess ())
|
if (getOwner () && !denyAccess ())
|
||||||
{
|
{
|
||||||
sendcurrent (); // force out last block whatever size..
|
if (!immediately)
|
||||||
waitforallsent (); // block till finished..
|
{
|
||||||
|
sendcurrent (); // force out last block whatever size..
|
||||||
|
waitforallsent (); // block till finished..
|
||||||
|
}
|
||||||
|
|
||||||
rc = waveOutReset (dev_);
|
rc = waveOutReset (dev_);
|
||||||
debug_printf ("waveOutReset rc=%d", rc);
|
debug_printf ("waveOutReset rc=%d", rc);
|
||||||
|
@ -507,7 +511,7 @@ fhandler_dev_dsp::Audio_out::write (const char *pSampleData, int nBytes)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return number of (partially) empty blocks back.
|
// return number of (completely) empty blocks back.
|
||||||
int
|
int
|
||||||
fhandler_dev_dsp::Audio_out::emptyblocks ()
|
fhandler_dev_dsp::Audio_out::emptyblocks ()
|
||||||
{
|
{
|
||||||
|
@ -516,8 +520,6 @@ fhandler_dev_dsp::Audio_out::emptyblocks ()
|
||||||
n = Qisr2app_->query ();
|
n = Qisr2app_->query ();
|
||||||
unlock ();
|
unlock ();
|
||||||
n += Qapp2app_->query ();
|
n += Qapp2app_->query ();
|
||||||
if (pHdr_ != NULL)
|
|
||||||
n++;
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -531,8 +533,8 @@ fhandler_dev_dsp::Audio_out::buf_info (audio_buf_info *p,
|
||||||
{
|
{
|
||||||
p->fragments = emptyblocks ();
|
p->fragments = emptyblocks ();
|
||||||
if (pHdr_ != NULL)
|
if (pHdr_ != NULL)
|
||||||
p->bytes = p->fragsize - bufferIndex_ +
|
p->bytes = (int)pHdr_->dwUser - bufferIndex_
|
||||||
p->fragsize * (p->fragments - 1);
|
+ p->fragsize * p->fragments;
|
||||||
else
|
else
|
||||||
p->bytes = p->fragsize * p->fragments;
|
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 *end = pData + nBytes;
|
||||||
const char *pDat;
|
const char *pDat;
|
||||||
int skip = 0;
|
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'
|
if (!(pData[0] == 'R' && pData[1] == 'I'
|
||||||
&& pData[2] == 'F' && pData[3] == 'F'))
|
&& pData[2] == 'F' && pData[3] == 'F'))
|
||||||
return false;
|
return false;
|
||||||
|
@ -971,6 +975,31 @@ fhandler_dev_dsp::Audio_in::waitfordata ()
|
||||||
bufferIndex_ = 0;
|
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..
|
// This is called on an interrupt so use locking..
|
||||||
void
|
void
|
||||||
fhandler_dev_dsp::Audio_in::callback_blockfull (WAVEHDR *pHdr)
|
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_)
|
if (audio_out_)
|
||||||
{
|
{
|
||||||
RETURN_ERROR_WHEN_BUSY (audio_out_);
|
RETURN_ERROR_WHEN_BUSY (audio_out_);
|
||||||
audioformat_ = AFMT_U8;
|
audio_out_->stop (true);
|
||||||
audiofreq_ = 8000;
|
|
||||||
audiobits_ = 8;
|
|
||||||
audiochannels_ = 1;
|
|
||||||
audio_out_->stop ();
|
|
||||||
audio_out_->setformat (audioformat_);
|
|
||||||
}
|
}
|
||||||
if (audio_in_)
|
if (audio_in_)
|
||||||
{
|
{
|
||||||
RETURN_ERROR_WHEN_BUSY (audio_in_);
|
RETURN_ERROR_WHEN_BUSY (audio_in_);
|
||||||
audioformat_ = AFMT_U8;
|
|
||||||
audiofreq_ = 8000;
|
|
||||||
audiobits_ = 8;
|
|
||||||
audiochannels_ = 1;
|
|
||||||
audio_in_->stop ();
|
audio_in_->stop ();
|
||||||
audio_in_->setformat (audioformat_);
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
|
@ -1416,6 +1435,20 @@ fhandler_dev_dsp::ioctl (unsigned int cmd, void *ptr)
|
||||||
}
|
}
|
||||||
break;
|
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)
|
CASE (SNDCTL_DSP_SETFRAGMENT)
|
||||||
{
|
{
|
||||||
// Fake!! esound & mikmod require this on non PowerPC platforms.
|
// Fake!! esound & mikmod require this on non PowerPC platforms.
|
||||||
|
|
Loading…
Reference in New Issue