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/group___p_c_m.html#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
> [EMAIL PROTECTED]
> http://lists.helixcommunity.org/mailman/listinfo/midplayer-private-dev
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 17 Apr 2008 23:36:50 -0000
@@ -73,7 +73,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;
@@ -102,6 +103,7 @@
m_audioThread(NULL),
m_bUserWantsThreads(TRUE),
m_ulSleepTime(0),
+ m_pAvailableDataEvent(NULL),
#endif
m_pRollbackBuffer(NULL)
{
@@ -114,7 +116,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 +143,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);
+ CreateInstanceCCF(CLSID_IHXEvent, (void**)&m_pAvailableDataEvent, m_pContext);
}
#endif
@@ -194,6 +196,7 @@
HX_RELEASE( m_mtxWriteListPlayStateLock );
HX_RELEASE( m_mtxDeviceStateLock );
HX_RELEASE( m_audioThread );
+ HX_RELEASE( m_pAvailableDataEvent );
}
#endif
@@ -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();
@@ -353,6 +356,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 +783,21 @@
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)
+ {
+ if (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(ALLFS);
+ }
+ else
+ {
+#if !defined(HELIX_FEATURE_ALSA)
+ // OK, sleep the amount of time it takes to play 1/4 of the device's buffer.
+ microsleep(that->m_ulSleepTime/4);
+#endif
+ }
+ }
}
//Signal the parent thread that we are done.
@@ -833,6 +851,7 @@
}
UNLOCK(m_mtxWriteListPlayStateLock);
+ HXLOGL4 (HXLOG_ADEV, "CAudioUnixOUT::_PushBits() writing %i bits", (int)ulBufLen);
_WriteBytes(pData, ulBufLen, lCount);
LOCK(m_mtxWriteListPlayStateLock);
@@ -995,6 +1014,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 17 Apr 2008 23:36:50 -0000
@@ -289,6 +289,7 @@
IHXThread* m_audioThread;
HXBOOL m_bUserWantsThreads;
ULONG32 m_ulSleepTime;
+ IHXEvent* m_pAvailableDataEvent;
#endif
private:
_______________________________________________
Audio-dev mailing list
[email protected]
http://lists.helixcommunity.org/mailman/listinfo/audio-dev