|
List Info
Thread: CR: Remove polling inside UNIX audio thread
|
|
| CR: Remove polling inside UNIX audio
thread |

|
2008-04-16 21:34:11 |
I am sending this to the audio-dev list after an initial
review in the
RealPlayer for MID project, but I still need testing on
non-Linux
platforms.
On Wed, 2008-04-09 at 11:29 -0700, Greg Wright wrote:
> If the writelist is not empty then we have removed the
> sleep all together and we will be in a tight spin
until
> we have drained the list. This might not happen for
the
> whole length of the clip. Perhaps we can sleep while
the
> list is full and then wait on that event when the list
> becomes empty. I don't mind changing the sleep time,
it
> might be too aggressive. Basically we know how much
data
> the audio hardware can hole (pushdown) in MS so we
just
> need to make sure we can wake up and push more data
before
> that runs out.
It is likely that I am not understanding the failure case,
but the tight
loop will lock and then unlock the writelist lock, giving
the other
thread a chance to write more blocks.
I can't seem to find a failure case where the lack of a
sleep breaks
anything (causing audio or video artifacts), and adding a
sleep only
seems to add unneeded interrupts.
Description
----------------------------------
The audio out class for UNIX is creating a thread that
continuously
attempts to read from the list of available audio data
buffers, and
then use the device specific method for writting that data
to the audio
device.
This change will introduce a new HXEvent for letting the
main thread
signal the data writing thread when new data is available
for pushing to
the audio device, instead of having the audio thread do a
bunch of small
micro sleeps while it waits for some new data to push.
By doing this we remove a source of interrupts that tend to
drive
the CPU into high C0 (full power mode) residency. This is
especially
true when on a MID device that has the ASound prealloc
buffer max'ed
out, allowing large periods of time for the original output
audio thread
to wait for new blocks of data.
Files Modified
----------------------------------
audio/device/platform/unix/audUnix.cpp
audio/device/pub/platform/unix/audUnix.h
Branches
---------------------------------
HEAD, hxclient_3_1_0_atlas
Index: platform/unix/audUnix.cpp
============================================================
=======
RCS file: /cvsroot/audio/device/platform/unix/audUnix.cpp,v
retrieving revision 1.12
diff -u -r1.12 audUnix.cpp
--- platform/unix/audUnix.cpp 6 Jul 2007 20:21:16
-0000 1.12
+++ platform/unix/audUnix.cpp 16 Apr 2008 00:42:15 -0000
 -63,7
+63,6 
#include "hxmutex.h"
#include "debug.h"
-#include "microsleep.h"
//me.
#include "audUnix.h"
 -73,7
+72,8 
#include "hxprefs.h"
#endif
-
+#include "hxtlogutil.h"
+#include "ihxtlogsystem.h"
//-1 is usually considered to be no file descriptor.
const int CAudioOutUNIX::NO_FILE_DESCRIPTOR = -1;
 -101,7
+101,7 
m_mtxDeviceStateLock(NULL),
m_audioThread(NULL),
m_bUserWantsThreads(TRUE),
- m_ulSleepTime(0),
+ m_pAvailableDataEvent(NULL),
#endif
m_pRollbackBuffer(NULL)
{
 -114,7
+114,6 
//Allco our write buffer list. Want to throw from here?
You will,
like
//it or not.
m_pWriteList = new CHXSimpleList();
-
}
void CAudioOutUNIX::_initAfterContext()
 -142,6
+141,7 
CreateInstanceCCF(CLSID_IHXMutex,
(void**)&m_mtxWriteListPlayStateLock, m_pContext);
CreateInstanceCCF(CLSID_IHXMutex,
(void**)&m_mtxDeviceStateLock,
m_pContext);
CreateInstanceCCF(CLSID_IHXThread,
(void**)&m_audioThread,
m_pContext);
+ HXEvent::MakeEvent(m_pAvailableDataEvent, "Available
Audio Data",
FALSE);
}
#endif
 -194,6
+194,7 
HX_RELEASE( m_mtxWriteListPlayStateLock );
HX_RELEASE( m_mtxDeviceStateLock );
HX_RELEASE( m_audioThread );
+ HX_DELETE( m_pAvailableDataEvent );
}
#endif
 -271,14
+272,6 
}
else
{
-#if defined(_THREADED_AUDIO) &&
defined(_UNIX_THREADS_SUPPORTED)
- //We want to sleep as a function of device
buffer size.
- //If we have a small m_ulDeviceBufferSize
we can only
- //afford to sleep just a little while.
- HX_ASSERT( m_ulDeviceBufferSize != 0 );
- m_ulSleepTime =
(((float)m_ulDeviceBufferSize/(float)m_uSampFrameSize)/
- (float)m_unSampleRate) *
1000 /
(float)m_unNumChannels;
-#endif
if (!m_bMixerPresent)
_OpenMixer();
 -353,6
+346,8 
//Wait for it to do so and clean up.
if( m_bUserWantsThreads )
{
+ HXLOGL4 (HXLOG_ADEV,
"CAudioUnixOUT::_Imp_Close signaling
event...");
+ m_pAvailableDataEvent->SignalEvent();
m_audioThread->Exit(0);
}
 -778,8
+773,11 
that->m_mtxDeviceStateLock->Unlock();
that->m_mtxWriteListPlayStateLock->Unlock();
- //OK, sleep the amount of time it takes to play 1/4
of the
device's buffer.
- microsleep(that->m_ulSleepTime/4);
+ if(bReadyToExit == FALSE &&
(that->m_pWriteList->GetCount() ==
0 || that->m_wState == RA_AOS_OPEN_PAUSED))
+ {
+ HXLOGL4 (HXLOG_ADEV,
"CAudioUnixOUT::AudioThread() waiting for
audio data...");
+ that->m_pAvailableDataEvent->Wait();
+ }
}
//Signal the parent thread that we are done.
 -833,6
+831,7 
}
UNLOCK(m_mtxWriteListPlayStateLock);
+ HXLOGL4 (HXLOG_ADEV, "CAudioUnixOUT::_PushBits()
writing %i bits",
(int)ulBufLen);
_WriteBytes(pData, ulBufLen, lCount);
LOCK(m_mtxWriteListPlayStateLock);
 -995,6
+994,8 
//grab the data and write it to the device.
if( m_bUserWantsThreads )
{
+ HXLOGL4 (HXLOG_ADEV,
"CAudioUnixOUT::_Imp_Write signaling
event...");
+ m_pAvailableDataEvent->SignalEvent();
return RA_AOE_NOERR;
}
#endif
Index: pub/platform/unix/audUnix.h
============================================================
=======
RCS file:
/cvsroot/audio/device/pub/platform/unix/audUnix.h,v
retrieving revision 1.8
diff -u -r1.8 audUnix.h
--- pub/platform/unix/audUnix.h 6 Jul 2007 20:21:19
-0000 1.8
+++ pub/platform/unix/audUnix.h 16 Apr 2008 00:42:15 -0000
 -288,7
+288,7 
IHXMutex* m_mtxDeviceStateLock;
IHXThread* m_audioThread;
HXBOOL m_bUserWantsThreads;
- ULONG32 m_ulSleepTime;
+ HXEvent* m_pAvailableDataEvent;
#endif
private:
_______________________________________________
Audio-dev mailing list
Audio-dev helixcommunity.org
http://lists.helixcommunity.org/mailman/listinfo/audio
-dev
|
|
|
| RE: CR: Remove polling inside UNIX
audio thread |
  United States |
2008-04-17 16:03:22 |
Rusty,
Here are my comments. Greg may want to comment further.
 -142,6
+141,7 
CreateInstanceCCF(CLSID_IHXMutex,
(void**)&m_mtxWriteListPlayStateLock, m_pContext);
CreateInstanceCCF(CLSID_IHXMutex,
(void**)&m_mtxDeviceStateLock, m_pContext);
CreateInstanceCCF(CLSID_IHXThread,
(void**)&m_audioThread, m_pContext);
+ HXEvent::MakeEvent(m_pAvailableDataEvent, "Available
Audio Data", FALSE);
You should create an IHXEvent just like the above
code creates IHXThread or IHXMutex:
+ CreateInstanceCCF(CLSID_IHXEvent, (void**)
&m_pAvailableDataEvent, m_pContext);
and of course, m_pAvailableDataEvent should be an IHXEvent
rather
than an HXEvent:
+ IHXEvent* m_pAvailableDataEvent;
and you should release it rather than delete it:
+ HX_RELEASE( m_pAvailableDataEvent );
What would happen if the audio device was full and we
still had data to write? It seems like we would just
spin in a tight loop until the audio device had space
for us to write. Not really a failure case, but
seems like we should wait in that case as well.
Eric
=============================================
Eric Hyche (ehyche real.com)
Technical Lead
RealNetworks, Inc.
> -----Original Message-----
> From: audio-dev-bounces helixcommunity.org
> [mailto:audio-dev-bounces helixcommunity.org] On
Behalf Of Rusty Lynch
> Sent: Wednesday, April 16, 2008 10:34 PM
> To: audio-dev lists.helixcommunity.org
> Cc: midplayer-private-dev
> Subject: [Audio-dev] CR: Remove polling inside UNIX
audio thread
>
> I am sending this to the audio-dev list after an
initial review in the
> RealPlayer for MID project, but I still need testing on
non-Linux
> platforms.
>
> On Wed, 2008-04-09 at 11:29 -0700, Greg Wright wrote:
> > If the writelist is not empty then we have removed
the
> > sleep all together and we will be in a tight spin
until
> > we have drained the list. This might not happen
for the
> > whole length of the clip. Perhaps we can sleep
while the
> > list is full and then wait on that event when the
list
> > becomes empty. I don't mind changing the sleep
time, it
> > might be too aggressive. Basically we know how
much data
> > the audio hardware can hole (pushdown) in MS so we
just
> > need to make sure we can wake up and push more
data before
> > that runs out.
>
> It is likely that I am not understanding the failure
case,
> but the tight
> loop will lock and then unlock the writelist lock,
giving the other
> thread a chance to write more blocks.
>
> I can't seem to find a failure case where the lack of a
sleep breaks
> anything (causing audio or video artifacts), and adding
a sleep only
> seems to add unneeded interrupts.
>
>
> Description
> ----------------------------------
> The audio out class for UNIX is creating a thread that
continuously
> attempts to read from the list of available audio data
buffers, and
> then use the device specific method for writting that
data to
> the audio
> device.
>
> This change will introduce a new HXEvent for letting
the main thread
> signal the data writing thread when new data is
available for
> pushing to
> the audio device, instead of having the audio thread do
a
> bunch of small
> micro sleeps while it waits for some new data to push.
>
> By doing this we remove a source of interrupts that
tend to drive
> the CPU into high C0 (full power mode) residency. This
is especially
> true when on a MID device that has the ASound prealloc
buffer max'ed
> out, allowing large periods of time for the original
output
> audio thread
> to wait for new blocks of data.
>
> Files Modified
> ----------------------------------
> audio/device/platform/unix/audUnix.cpp
> audio/device/pub/platform/unix/audUnix.h
>
> Branches
> ---------------------------------
> HEAD, hxclient_3_1_0_atlas
>
> Index: platform/unix/audUnix.cpp
>
============================================================
=======
> RCS file:
/cvsroot/audio/device/platform/unix/audUnix.cpp,v
> retrieving revision 1.12
> diff -u -r1.12 audUnix.cpp
> --- platform/unix/audUnix.cpp 6 Jul 2007 20:21:16
-0000 1.12
> +++ platform/unix/audUnix.cpp 16 Apr 2008 00:42:15
-0000
>  -63,7 +63,6 
> #include "hxmutex.h"
> #include "debug.h"
>
> -#include "microsleep.h"
> //me.
> #include "audUnix.h"
>
>  -73,7 +72,8 
> #include "hxprefs.h"
> #endif
>
> -
> +#include "hxtlogutil.h"
> +#include "ihxtlogsystem.h"
>
> //-1 is usually considered to be no file descriptor.
> const int CAudioOutUNIX::NO_FILE_DESCRIPTOR = -1;
>  -101,7 +101,7 
> m_mtxDeviceStateLock(NULL),
> m_audioThread(NULL),
> m_bUserWantsThreads(TRUE),
> - m_ulSleepTime(0),
> + m_pAvailableDataEvent(NULL),
> #endif
> m_pRollbackBuffer(NULL)
> {
>  -114,7 +114,6 
> //Allco our write buffer list. Want to throw from
here? You will,
> like
> //it or not.
> m_pWriteList = new CHXSimpleList();
> -
> }
>
> void CAudioOutUNIX::_initAfterContext()
>  -142,6 +141,7 
> CreateInstanceCCF(CLSID_IHXMutex,
> (void**)&m_mtxWriteListPlayStateLock, m_pContext);
> CreateInstanceCCF(CLSID_IHXMutex,
(void**)&m_mtxDeviceStateLock,
> m_pContext);
> CreateInstanceCCF(CLSID_IHXThread,
(void**)&m_audioThread,
> m_pContext);
> + HXEvent::MakeEvent(m_pAvailableDataEvent,
"Available
> Audio Data",
> FALSE);
> }
> #endif
>
>  -194,6 +194,7 
> HX_RELEASE( m_mtxWriteListPlayStateLock );
> HX_RELEASE( m_mtxDeviceStateLock );
> HX_RELEASE( m_audioThread );
> + HX_DELETE( m_pAvailableDataEvent );
> }
> #endif
>
>  -271,14 +272,6 
> }
> else
> {
> -#if defined(_THREADED_AUDIO) &&
defined(_UNIX_THREADS_SUPPORTED)
> - //We want to sleep as a function of
device
> buffer size.
> - //If we have a small
m_ulDeviceBufferSize we
> can only
> - //afford to sleep just a little
while.
> - HX_ASSERT( m_ulDeviceBufferSize != 0
);
> - m_ulSleepTime =
>
(((float)m_ulDeviceBufferSize/(float)m_uSampFrameSize)/
> -
(float)m_unSampleRate) * 1000 /
> (float)m_unNumChannels;
> -#endif
> if (!m_bMixerPresent)
> _OpenMixer();
>
>  -353,6 +346,8 
> //Wait for it to do so and clean up.
> if( m_bUserWantsThreads )
> {
> + HXLOGL4 (HXLOG_ADEV,
"CAudioUnixOUT::_Imp_Close signaling
> event...");
> + m_pAvailableDataEvent->SignalEvent();
> m_audioThread->Exit(0);
> }
>
>  -778,8 +773,11 
> that->m_mtxDeviceStateLock->Unlock();
>
that->m_mtxWriteListPlayStateLock->Unlock();
>
> - //OK, sleep the amount of time it takes to
play 1/4 of the
> device's buffer.
> - microsleep(that->m_ulSleepTime/4);
> + if(bReadyToExit == FALSE &&
> (that->m_pWriteList->GetCount() ==
> 0 || that->m_wState == RA_AOS_OPEN_PAUSED))
> + {
> + HXLOGL4 (HXLOG_ADEV,
"CAudioUnixOUT::AudioThread()
> waiting for
> audio data...");
> + that->m_pAvailableDataEvent->Wait();
> + }
> }
>
> //Signal the parent thread that we are done.
>  -833,6 +831,7 
> }
>
> UNLOCK(m_mtxWriteListPlayStateLock);
> + HXLOGL4 (HXLOG_ADEV,
"CAudioUnixOUT::_PushBits() writing
> %i bits",
> (int)ulBufLen);
> _WriteBytes(pData, ulBufLen, lCount);
> LOCK(m_mtxWriteListPlayStateLock);
>
>  -995,6 +994,8 
> //grab the data and write it to the device.
> if( m_bUserWantsThreads )
> {
> + HXLOGL4 (HXLOG_ADEV,
"CAudioUnixOUT::_Imp_Write signaling
> event...");
> + m_pAvailableDataEvent->SignalEvent();
> return RA_AOE_NOERR;
> }
> #endif
> Index: pub/platform/unix/audUnix.h
>
============================================================
=======
> RCS file:
/cvsroot/audio/device/pub/platform/unix/audUnix.h,v
> retrieving revision 1.8
> diff -u -r1.8 audUnix.h
> --- pub/platform/unix/audUnix.h 6 Jul 2007 20:21:19
> -0000 1.8
> +++ pub/platform/unix/audUnix.h 16 Apr 2008 00:42:15
-0000
>  -288,7 +288,7 
> IHXMutex* m_mtxDeviceStateLock;
> IHXThread* m_audioThread;
> HXBOOL m_bUserWantsThreads;
> - ULONG32 m_ulSleepTime;
> + HXEvent* m_pAvailableDataEvent;
> #endif
>
> private:
>
>
_______________________________________________
Audio-dev mailing list
Audio-dev helixcommunity.org
http://lists.helixcommunity.org/mailman/listinfo/audio
-dev
|
|
| RE: CR: Remove polling inside UNIX
audio thread |

|
2008-04-17 18:22:56 |
On Thu, 2008-04-17 at 17:03 -0400, Eric Hyche wrote:
> Rusty,
>
> Here are my comments. Greg may want to comment
further.
>
>  -142,6 +141,7 
> CreateInstanceCCF(CLSID_IHXMutex,
(void**)&m_mtxWriteListPlayStateLock, m_pContext);
> CreateInstanceCCF(CLSID_IHXMutex,
(void**)&m_mtxDeviceStateLock, m_pContext);
> CreateInstanceCCF(CLSID_IHXThread,
(void**)&m_audioThread, m_pContext);
> + HXEvent::MakeEvent(m_pAvailableDataEvent,
"Available Audio Data", FALSE);
>
> You should create an IHXEvent just like the above
> code creates IHXThread or IHXMutex:
>
> + CreateInstanceCCF(CLSID_IHXEvent, (void**)
&m_pAvailableDataEvent, m_pContext);
>
> and of course, m_pAvailableDataEvent should be an
IHXEvent rather
> than an HXEvent:
>
> + IHXEvent* m_pAvailableDataEvent;
>
> and you should release it rather than delete it:
>
> + HX_RELEASE( m_pAvailableDataEvent );
>
Ok, I started using IHXEvent, and since I wanted a infinite
wait I am
calling:
m_pAvailableDataEvent->Wait(ALLFS);
... which I am just guessing (from looking at other code) is
cool, but
ALLFS isn't translating to anything sensible in my brain, so
let me know
if that is not something I behavior I can count on.
>
> What would happen if the audio device was full and we
> still had data to write? It seems like we would just
> spin in a tight loop until the audio device had space
> for us to write. Not really a failure case, but
> seems like we should wait in that case as well.
>
> Eric
>
On an ALSA system _WriteBytes will eventually come down to
an
snd_pcm_writei(), and since we are setting the audio device
to blocking
in _OpenAudio(), then snd_pcm_writei() will block until the
device is
able to consume all the bits.
http://www.als
a-project.org/alsa-doc/alsa-lib/group___p_c_m.html#gf13067c0
ebde29118ca05af76e5b17a9
Can I count on other UNIX systems having a blocking write
behavior? I
don't know. I think esd (esound) blocks on write, but I'm
having a hard
time finding any API documentation to verify that.
hmm... looks like Solaris is opening the device node using
O_NONBLOCK.
Ok, here is a version of the patch that will do a microsleep
if there is
data to write, but only if HELIX_FEATURE_ALSA is defined.
The block of code in question now looks more like...
if(bReadyToExit == FALSE &&
(that->m_pWriteList->GetCount() == 0 ||
that->m_wState == RA_AOS_OPEN_PAUSED))
{
that->m_pAvailableDataEvent->Wait(ALLFS);
}
else
{
#if !defined(HELIX_FEATURE_ALSA)
microsleep(that->m_ulSleepTime/4);
#endif
}
_______________________________________________
Audio-dev mailing list
Audio-dev helixcommunity.org
http://lists.helixcommunity.org/mailman/listinfo/audio
-dev
|
|
|
| Take 3 => CR: Remove polling inside
UNIX audio thread |

|
2008-04-17 18:40:19 |
Ahh! Just took a another look at my patch and realized that
I was
adding an extra unneeded micro sleep when exiting. Not a
big deal in
the grand scheme of things, but not very clean.
This version of the patch now only calls micro sleep if the
bReadyToExit
is false and there is data to write.
--rusty
On Thu, 2008-04-17 at 16:22 -0700, Rusty Lynch wrote:
> On Thu, 2008-04-17 at 17:03 -0400, Eric Hyche wrote:
> > Rusty,
> >
> > Here are my comments. Greg may want to comment
further.
> >
> >  -142,6 +141,7 
> > CreateInstanceCCF(CLSID_IHXMutex,
(void**)&m_mtxWriteListPlayStateLock, m_pContext);
> > CreateInstanceCCF(CLSID_IHXMutex,
(void**)&m_mtxDeviceStateLock, m_pContext);
> > CreateInstanceCCF(CLSID_IHXThread,
(void**)&m_audioThread, m_pContext);
> > + HXEvent::MakeEvent(m_pAvailableDataEvent,
"Available Audio Data", FALSE);
> >
> > You should create an IHXEvent just like the above
> > code creates IHXThread or IHXMutex:
> >
> > + CreateInstanceCCF(CLSID_IHXEvent, (void**)
&m_pAvailableDataEvent, m_pContext);
> >
> > and of course, m_pAvailableDataEvent should be an
IHXEvent rather
> > than an HXEvent:
> >
> > + IHXEvent* m_pAvailableDataEvent;
> >
> > and you should release it rather than delete it:
> >
> > + HX_RELEASE( m_pAvailableDataEvent );
> >
>
> Ok, I started using IHXEvent, and since I wanted a
infinite wait I am
> calling:
>
> m_pAvailableDataEvent->Wait(ALLFS);
>
> ... which I am just guessing (from looking at other
code) is cool, but
> ALLFS isn't translating to anything sensible in my
brain, so let me know
> if that is not something I behavior I can count on.
>
> >
> > What would happen if the audio device was full and
we
> > still had data to write? It seems like we would
just
> > spin in a tight loop until the audio device had
space
> > for us to write. Not really a failure case, but
> > seems like we should wait in that case as well.
> >
> > Eric
> >
>
> On an ALSA system _WriteBytes will eventually come down
to an
> snd_pcm_writei(), and since we are setting the audio
device to blocking
> in _OpenAudio(), then snd_pcm_writei() will block until
the device is
> able to consume all the bits.
>
> http://www.als
a-project.org/alsa-doc/alsa-lib/group___p_c_m.html#gf13067c0
ebde29118ca05af76e5b17a9
>
> Can I count on other UNIX systems having a blocking
write behavior? I
> don't know. I think esd (esound) blocks on write, but
I'm having a hard
> time finding any API documentation to verify that.
>
> hmm... looks like Solaris is opening the device node
using O_NONBLOCK.
>
> Ok, here is a version of the patch that will do a
microsleep if there is
> data to write, but only if HELIX_FEATURE_ALSA is
defined.
>
> The block of code in question now looks more like...
>
> if(bReadyToExit == FALSE &&
> (that->m_pWriteList->GetCount() == 0 ||
> that->m_wState == RA_AOS_OPEN_PAUSED))
> {
> that->m_pAvailableDataEvent->Wait(ALLFS);
> }
> else
> {
> #if !defined(HELIX_FEATURE_ALSA)
> microsleep(that->m_ulSleepTime/4);
> #endif
> }
>
>
>
> _______________________________________________
> Midplayer-private-dev mailing list
> Midplayer-private-dev lists.helixcommunity.org
> http://lists.helixcommunity.org/mailman/li
stinfo/midplayer-private-dev
_______________________________________________
Audio-dev mailing list
Audio-dev helixcommunity.org
http://lists.helixcommunity.org/mailman/listinfo/audio
-dev
|
|
|
| RE: Take 3 => CR: Remove polling
inside UNIX audio thread |
  United States |
2008-04-17 22:04:48 |
Further comments:
 -201,6
+204,14 
UINT16 CAudioOutUNIX::_Imp_GetVolume()
{
+#if defined(_THREADED_AUDIO) &&
defined(_UNIX_THREADS_SUPPORTED)
+ //We want to sleep as a function of device
buffer size.
+ //If we have a small m_ulDeviceBufferSize
we can only
+ //afford to sleep just a little while.
+ HX_ASSERT( m_ulDeviceBufferSize != 0 );
+ m_ulSleepTime =
(((float)m_ulDeviceBufferSize/(float)m_uSampFrameSize)/
+ (float)m_unSampleRate) *
1000 / (float)m_unNumChannels;
+#endif
if (!m_bMixerPresent)
_OpenMixer();
 -271,14
+282,6 
}
else
{
-#if defined(_THREADED_AUDIO) &&
defined(_UNIX_THREADS_SUPPORTED)
- //We want to sleep as a function of device
buffer size.
- //If we have a small m_ulDeviceBufferSize
we can only
- //afford to sleep just a little while.
- HX_ASSERT( m_ulDeviceBufferSize != 0 );
- m_ulSleepTime =
(((float)m_ulDeviceBufferSize/(float)m_uSampFrameSize)/
- (float)m_unSampleRate) *
1000 / (float)m_unNumChannels;
-#endif
if (!m_bMixerPresent)
_OpenMixer();
Was there some reason you decided to move this
from _Imp_Open() to _Imp_GetVolume()?
Rest looks good to me. Greg: do you have any
further comments?
Eric
=============================================
Eric Hyche (ehyche real.com)
Technical Lead
RealNetworks, Inc.
> -----Original Message-----
> From: Rusty Lynch [mailto:rusty.lynch intel.com]
> Sent: Thursday, April 17, 2008 7:40 PM
> To: audio-dev
> Cc: midplayer-private-dev; Eric Hyche; Greg Wright
> Subject: Take 3 => CR: Remove polling inside UNIX
audio thread
>
> Ahh! Just took a another look at my patch and realized
that I was
> adding an extra unneeded micro sleep when exiting. Not
a big deal in
> the grand scheme of things, but not very clean.
>
> This version of the patch now only calls micro sleep if
the
> bReadyToExit
> is false and there is data to write.
>
> --rusty
>
> On Thu, 2008-04-17 at 16:22 -0700, Rusty Lynch wrote:
> > On Thu, 2008-04-17 at 17:03 -0400, Eric Hyche
wrote:
> > > Rusty,
> > >
> > > Here are my comments. Greg may want to
comment further.
> > >
> > >  -142,6 +141,7 
> > > CreateInstanceCCF(CLSID_IHXMutex,
> (void**)&m_mtxWriteListPlayStateLock, m_pContext);
> > > CreateInstanceCCF(CLSID_IHXMutex,
> (void**)&m_mtxDeviceStateLock, m_pContext);
> > > CreateInstanceCCF(CLSID_IHXThread,
> (void**)&m_audioThread, m_pContext);
> > > + HXEvent::MakeEvent(m_pAvailableDataEvent,
"Available
> Audio Data", FALSE);
> > >
> > > You should create an IHXEvent just like the
above
> > > code creates IHXThread or IHXMutex:
> > >
> > > + CreateInstanceCCF(CLSID_IHXEvent,
(void**)
> &m_pAvailableDataEvent, m_pContext);
> > >
> > > and of course, m_pAvailableDataEvent should
be an IHXEvent rather
> > > than an HXEvent:
> > >
> > > + IHXEvent* m_pAvailableDataEvent;
> > >
> > > and you should release it rather than delete
it:
> > >
> > > + HX_RELEASE( m_pAvailableDataEvent );
> > >
> >
> > Ok, I started using IHXEvent, and since I wanted a
infinite
> wait I am
> > calling:
> >
> > m_pAvailableDataEvent->Wait(ALLFS);
> >
> > ... which I am just guessing (from looking at
other code)
> is cool, but
> > ALLFS isn't translating to anything sensible in my
brain,
> so let me know
> > if that is not something I behavior I can count
on.
> >
> > >
> > > What would happen if the audio device was
full and we
> > > still had data to write? It seems like we
would just
> > > spin in a tight loop until the audio device
had space
> > > for us to write. Not really a failure case,
but
> > > seems like we should wait in that case as
well.
> > >
> > > Eric
> > >
> >
> > On an ALSA system _WriteBytes will eventually come
down to an
> > snd_pcm_writei(), and since we are setting the
audio device
> to blocking
> > in _OpenAudio(), then snd_pcm_writei() will block
until the
> device is
> > able to consume all the bits.
> >
> >
> http://www.alsa-project.org/alsa-doc/alsa-lib/grou
p___p_c_m.ht
> ml#gf13067c0ebde29118ca05af76e5b17a9
> >
> > Can I count on other UNIX systems having a
blocking write
> behavior? I
> > don't know. I think esd (esound) blocks on write,
but I'm
> having a hard
> > time finding any API documentation to verify
that.
> >
> > hmm... looks like Solaris is opening the device
node using
> O_NONBLOCK.
> >
> > Ok, here is a version of the patch that will do a
> microsleep if there is
> > data to write, but only if HELIX_FEATURE_ALSA is
defined.
> >
> > The block of code in question now looks more
like...
> >
> > if(bReadyToExit == FALSE &&
> > (that->m_pWriteList->GetCount() == 0 ||
> > that->m_wState == RA_AOS_OPEN_PAUSED))
> > {
> >
that->m_pAvailableDataEvent->Wait(ALLFS);
> > }
> > else
> > {
> > #if !defined(HELIX_FEATURE_ALSA)
> > microsleep(that->m_ulSleepTime/4);
> > #endif
> > }
> >
> >
> >
> > _______________________________________________
> > Midplayer-private-dev mailing list
> > Midplayer-private-dev lists.helixcommunity.org
> >
> http://lists.helixcommunity.org/mailman/li
stinfo/midplayer-private-dev
>
_______________________________________________
Audio-dev mailing list
Audio-dev helixcommunity.org
http://lists.helixcommunity.org/mailman/listinfo/audio
-dev
|
|
| Re: Take 3 => CR: Remove polling
inside UNIX audio thread |
  United States |
2008-04-17 22:37:45 |
On Apr 17, 2008, at 8:04 PM, Eric Hyche wrote:
>
>
> Further comments:
>
>  -201,6 +204,14 
>
> UINT16 CAudioOutUNIX::_Imp_GetVolume()
> {
> +#if defined(_THREADED_AUDIO) &&
defined(_UNIX_THREADS_SUPPORTED)
> + //We want to sleep as a function of
device buffer
> size.
> + //If we have a small
m_ulDeviceBufferSize we can only
> + //afford to sleep just a little
while.
> + HX_ASSERT( m_ulDeviceBufferSize != 0
);
> + m_ulSleepTime =
(((float)m_ulDeviceBufferSize/
> (float)m_uSampFrameSize)/
> +
(float)m_unSampleRate) * 1000 /
> (float)m_unNumChannels;
> +#endif
> if (!m_bMixerPresent)
> _OpenMixer();
>
>  -271,14 +282,6 
> }
> else
> {
> -#if defined(_THREADED_AUDIO) &&
defined(_UNIX_THREADS_SUPPORTED)
> - //We want to sleep as a function of
device buffer
> size.
> - //If we have a small
m_ulDeviceBufferSize we can only
> - //afford to sleep just a little
while.
> - HX_ASSERT( m_ulDeviceBufferSize != 0
);
> - m_ulSleepTime =
(((float)m_ulDeviceBufferSize/
> (float)m_uSampFrameSize)/
> -
(float)m_unSampleRate) * 1000 /
> (float)m_unNumChannels;
> -#endif
> if (!m_bMixerPresent)
> _OpenMixer();
>
>
> Was there some reason you decided to move this
> from _Imp_Open() to _Imp_GetVolume()?
I don't think it belongs in any volume call, it should
remain in Open.
Was the case where the buffer was full taken care of(so we
sleep at
least a little)?
--greg.
>
>
> Rest looks good to me. Greg: do you have any
> further comments?
>
> Eric
>
> =============================================
> Eric Hyche (ehyche real.com)
> Technical Lead
> RealNetworks, Inc.
>
>> -----Original Message-----
>> From: Rusty Lynch [mailto:rusty.lynch intel.com]
>> Sent: Thursday, April 17, 2008 7:40 PM
>> To: audio-dev
>> Cc: midplayer-private-dev; Eric Hyche; Greg Wright
>> Subject: Take 3 => CR: Remove polling inside
UNIX audio thread
>>
>> Ahh! Just took a another look at my patch and
realized that I was
>> adding an extra unneeded micro sleep when exiting.
Not a big deal in
>> the grand scheme of things, but not very clean.
>>
>> This version of the patch now only calls micro
sleep if the
>> bReadyToExit
>> is false and there is data to write.
>>
>> --rusty
>>
>> On Thu, 2008-04-17 at 16:22 -0700, Rusty Lynch
wrote:
>>> On Thu, 2008-04-17 at 17:03 -0400, Eric Hyche
wrote:
>>>> Rusty,
>>>>
>>>> Here are my comments. Greg may want to
comment further.
>>>>
>>>>  -142,6 +141,7 
>>>> CreateInstanceCCF(CLSID_IHXMutex,
>> (void**)&m_mtxWriteListPlayStateLock,
m_pContext);
>>>> CreateInstanceCCF(CLSID_IHXMutex,
>> (void**)&m_mtxDeviceStateLock, m_pContext);
>>>> CreateInstanceCCF(CLSID_IHXThread,
>> (void**)&m_audioThread, m_pContext);
>>>> + HXEvent::MakeEvent(m_pAvailableDataEvent,
"Available
>> Audio Data", FALSE);
>>>>
>>>> You should create an IHXEvent just like the
above
>>>> code creates IHXThread or IHXMutex:
>>>>
>>>> + CreateInstanceCCF(CLSID_IHXEvent,
(void**)
>> &m_pAvailableDataEvent, m_pContext);
>>>>
>>>> and of course, m_pAvailableDataEvent should
be an IHXEvent rather
>>>> than an HXEvent:
>>>>
>>>> + IHXEvent* m_pAvailableDataEvent;
>>>>
>>>> and you should release it rather than
delete it:
>>>>
>>>> + HX_RELEASE( m_pAvailableDataEvent );
>>>>
>>>
>>> Ok, I started using IHXEvent, and since I
wanted a infinite
>> wait I am
>>> calling:
>>>
>>> m_pAvailableDataEvent->Wait(ALLFS);
>>>
>>> ... which I am just guessing (from looking at
other code)
>> is cool, but
>>> ALLFS isn't translating to anything sensible in
my brain,
>> so let me know
>>> if that is not something I behavior I can count
on.
>>>
>>>>
>>>> What would happen if the audio device was
full and we
>>>> still had data to write? It seems like we
would just
>>>> spin in a tight loop until the audio device
had space
>>>> for us to write. Not really a failure case,
but
>>>> seems like we should wait in that case as
well.
>>>>
>>>> Eric
>>>>
>>>
>>> On an ALSA system _WriteBytes will eventually
come down to an
>>> snd_pcm_writei(), and since we are setting the
audio device
>> to blocking
>>> in _OpenAudio(), then snd_pcm_writei() will
block until the
>> device is
>>> able to consume all the bits.
>>>
>>>
>> http://www.alsa-project.org/alsa-doc/alsa-lib/grou
p___p_c_m.ht
>> ml#gf13067c0ebde29118ca05af76e5b17a9
>>>
>>> Can I count on other UNIX systems having a
blocking write
>> behavior? I
>>> don't know. I think esd (esound) blocks on
write, but I'm
>> having a hard
>>> time finding any API documentation to verify
that.
>>>
>>> hmm... looks like Solaris is opening the device
node using
>> O_NONBLOCK.
>>>
>>> Ok, here is a version of the patch that will do
a
>> microsleep if there is
>>> data to write, but only if HELIX_FEATURE_ALSA
is defined.
>>>
>>> The block of code in question now looks more
like...
>>>
>>> if(bReadyToExit == FALSE &&
>>> (that->m_pWriteList->GetCount() == 0
||
>>> that->m_wState == RA_AOS_OPEN_PAUSED))
>>> {
>>>
that->m_pAvailableDataEvent->Wait(ALLFS);
>>> }
>>> else
>>> {
>>> #if !defined(HELIX_FEATURE_ALSA)
>>> microsleep(that->m_ulSleepTime/4);
>>> #endif
>>> }
>>>
>>>
>>>
>>>
_______________________________________________
>>> Midplayer-private-dev mailing list
>>> Midplayer-private-dev lists.helixcommunity.org
>>>
>> http://lists.helixcommunity.org/mailman/listi
nfo/midplayer-private-
>> dev
>>
>
_______________________________________________
Audio-dev mailing list
Audio-dev helixcommunity.org
http://lists.helixcommunity.org/mailman/listinfo/audio
-dev
|
|
| RE: Take 3 => CR: Remove polling
inside UNIX audio thread |
  United States |
2008-04-17 22:44:07 |
Greg,
> Was the case where the buffer was full taken care of(so
we sleep at
> least a little)?
>
Read further down the thread. Looks like it's
not an issue for ALSA, so he put in a
microsleep if the buffer was full for
non-ALSA implementations.
Eric
=============================================
Eric Hyche (ehyche real.com)
Technical Lead
RealNetworks, Inc.
> -----Original Message-----
> From: Gregory Wright [mailto:gwright real.com]
> Sent: Thursday, April 17, 2008 11:38 PM
> To: ehyche real.com
> Cc: 'Rusty Lynch'; 'audio-dev';
'midplayer-private-dev'
> Subject: Re: Take 3 => CR: Remove polling inside
UNIX audio thread
>
> On Apr 17, 2008, at 8:04 PM, Eric Hyche wrote:
> >
> >
> > Further comments:
> >
> >  -201,6 +204,14 
> >
> > UINT16 CAudioOutUNIX::_Imp_GetVolume()
> > {
> > +#if defined(_THREADED_AUDIO) &&
defined(_UNIX_THREADS_SUPPORTED)
> > + //We want to sleep as a function
of device buffer
> > size.
> > + //If we have a small
m_ulDeviceBufferSize
> we can only
> > + //afford to sleep just a little
while.
> > + HX_ASSERT( m_ulDeviceBufferSize
!= 0 );
> > + m_ulSleepTime =
(((float)m_ulDeviceBufferSize/
> > (float)m_uSampFrameSize)/
> > +
(float)m_unSampleRate) * 1000 /
> > (float)m_unNumChannels;
> > +#endif
> > if (!m_bMixerPresent)
> > _OpenMixer();
> >
> >  -271,14 +282,6 
> > }
> > else
> > {
> > -#if defined(_THREADED_AUDIO) &&
defined(_UNIX_THREADS_SUPPORTED)
> > - //We want to sleep as a function
of device buffer
> > size.
> > - //If we have a small
m_ulDeviceBufferSize
> we can only
> > - //afford to sleep just a little
while.
> > - HX_ASSERT( m_ulDeviceBufferSize
!= 0 );
> > - m_ulSleepTime =
(((float)m_ulDeviceBufferSize/
> > (float)m_uSampFrameSize)/
> > -
(float)m_unSampleRate) * 1000 /
> > (float)m_unNumChannels;
> > -#endif
> > if (!m_bMixerPresent)
> > _OpenMixer();
> >
> >
> > Was there some reason you decided to move this
> > from _Imp_Open() to _Imp_GetVolume()?
>
> I don't think it belongs in any volume call, it should
remain in Open.
>
> Was the case where the buffer was full taken care of(so
we sleep at
> least a little)?
>
> --greg.
>
>
> >
> >
> > Rest looks good to me. Greg: do you have any
> > further comments?
> >
> > Eric
> >
> > =============================================
> > Eric Hyche (ehyche real.com)
> > Technical Lead
> > RealNetworks, Inc.
> >
> >> -----Original Message-----
> >> From: Rusty Lynch [mailto:rusty.lynch intel.com]
> >> Sent: Thursday, April 17, 2008 7:40 PM
> >> To: audio-dev
> >> Cc: midplayer-private-dev; Eric Hyche; Greg
Wright
> >> Subject: Take 3 => CR: Remove polling
inside UNIX audio thread
> >>
> >> Ahh! Just took a another look at my patch and
realized that I was
> >> adding an extra unneeded micro sleep when
exiting. Not a
> big deal in
> >> the grand scheme of things, but not very
clean.
> >>
> >> This version of the patch now only calls micro
sleep if the
> >> bReadyToExit
> >> is false and there is data to write.
> >>
> >> --rusty
> >>
> >> On Thu, 2008-04-17 at 16:22 -0700, Rusty Lynch
wrote:
> >>> On Thu, 2008-04-17 at 17:03 -0400, Eric
Hyche wrote:
> >>>> Rusty,
> >>>>
> >>>> Here are my comments. Greg may want to
comment further.
> >>>>
> >>>>  -142,6 +141,7 
> >>>> CreateInstanceCCF(CLSID_IHXMutex,
> >> (void**)&m_mtxWriteListPlayStateLock,
m_pContext);
> >>>> CreateInstanceCCF(CLSID_IHXMutex,
> >> (void**)&m_mtxDeviceStateLock,
m_pContext);
> >>>> CreateInstanceCCF(CLSID_IHXThread,
> >> (void**)&m_audioThread, m_pContext);
> >>>>
+ HXEvent::MakeEvent(m_pAvailableDataEvent, "Available
> >> Audio Data", FALSE);
> >>>>
> >>>> You should create an IHXEvent just
like the above
> >>>> code creates IHXThread or IHXMutex:
> >>>>
> >>>> +
CreateInstanceCCF(CLSID_IHXEvent, (void**)
> >> &m_pAvailableDataEvent, m_pContext);
> >>>>
> >>>> and of course, m_pAvailableDataEvent
should be an IHXEvent rather
> >>>> than an HXEvent:
> >>>>
> >>>> + IHXEvent*
m_pAvailableDataEvent;
> >>>>
> >>>> and you should release it rather than
delete it:
> >>>>
> >>>> + HX_RELEASE( m_pAvailableDataEvent
);
> >>>>
> >>>
> >>> Ok, I started using IHXEvent, and since I
wanted a infinite
> >> wait I am
> >>> calling:
> >>>
> >>> m_pAvailableDataEvent->Wait(ALLFS);
> >>>
> >>> ... which I am just guessing (from looking
at other code)
> >> is cool, but
> >>> ALLFS isn't translating to anything
sensible in my brain,
> >> so let me know
> >>> if that is not something I behavior I can
count on.
> >>>
> >>>>
> >>>> What would happen if the audio device
was full and we
> >>>> still had data to write? It seems like
we would just
> >>>> spin in a tight loop until the audio
device had space
> >>>> for us to write. Not really a failure
case, but
> >>>> seems like we should wait in that case
as well.
> >>>>
> >>>> Eric
> >>>>
> >>>
> >>> On an ALSA system _WriteBytes will
eventually come down to an
> >>> snd_pcm_writei(), and since we are setting
the audio device
> >> to blocking
> >>> in _OpenAudio(), then snd_pcm_writei()
will block until the
> >> device is
> >>> able to consume all the bits.
> >>>
> >>>
> >> http://www.alsa-project.org/alsa-doc/alsa-lib/grou
p___p_c_m.ht
> >> ml#gf13067c0ebde29118ca05af76e5b17a9
> >>>
> >>> Can I count on other UNIX systems having a
blocking write
> >> behavior? I
> >>> don't know. I think esd (esound) blocks
on write, but I'm
> >> having a hard
> >>> time finding any API documentation to
verify that.
> >>>
> >>> hmm... looks like Solaris is opening the
device node using
> >> O_NONBLOCK.
> >>>
> >>> Ok, here is a version of the patch that
will do a
> >> microsleep if there is
> >>> data to write, but only if
HELIX_FEATURE_ALSA is defined.
> >>>
> >>> The block of code in question now looks
more like...
> >>>
> >>> if(bReadyToExit == FALSE &&
> >>> (that->m_pWriteList->GetCount() ==
0 ||
> >>> that->m_wState ==
RA_AOS_OPEN_PAUSED))
> >>> {
> >>>
that->m_pAvailableDataEvent->Wait(ALLFS);
> >>> }
> >>> else
> >>> {
> >>> #if !defined(HELIX_FEATURE_ALSA)
> >>> microsleep(that->m_ulSleepTime/4);
> >>> #endif
> >>> }
> >>>
> >>>
> >>>
> >>>
_______________________________________________
> >>> Midplayer-private-dev mailing list
> >>> Midplayer-private-dev lists.helixcommunity.org
> >>>
> >>
> http://lists.helixcommunity.org/mailman/listi
nfo/midplayer-private-
> >> dev
> >>
> >
>
_______________________________________________
Audio-dev mailing list
Audio-dev helixcommunity.org
http://lists.helixcommunity.org/mailman/listinfo/audio
-dev
|
|
[1-7]
|
|