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
}
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:25:14 -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,18 @@
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(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 +848,7 @@
}
UNLOCK(m_mtxWriteListPlayStateLock);
+ HXLOGL4 (HXLOG_ADEV, "CAudioUnixOUT::_PushBits() writing %i bits", (int)ulBufLen);
_WriteBytes(pData, ulBufLen, lCount);
LOCK(m_mtxWriteListPlayStateLock);
@@ -995,6 +1011,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:25:14 -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