\doxysection{ad\+\_\+s60.\+cpp}
\label{ad__s60_8cpp_source}\index{src/libsphinxad/ad\_s60.cpp@{src/libsphinxad/ad\_s60.cpp}}

\begin{DoxyCode}{0}
\DoxyCodeLine{00001\ \textcolor{comment}{/*}}
\DoxyCodeLine{00002\ \textcolor{comment}{\ \ \ This\ file\ is\ part\ of\ the\ imp\ project.}}
\DoxyCodeLine{00003\ \textcolor{comment}{\ \ \ Copyright\ (C)\ 2009\ Università degli\ Studi\ di\ Bergamo,\ Politecnico\ di\ Milano}}
\DoxyCodeLine{00004\ \textcolor{comment}{\ \ \ Authors:}}
\DoxyCodeLine{00005\ \textcolor{comment}{\ \ \ \ \ \ \ Cristian\ Gatti,\ gatti\ DOT\ kris\ AT\ gmail\ DOT\ com}}
\DoxyCodeLine{00006\ \textcolor{comment}{\ \ \ \ \ \ \ Silvio\ Moioli,\ silvio\ AT\ moioli\ DOT\ net,\ <http://www.moioli.net>}}
\DoxyCodeLine{00007\ \textcolor{comment}{\ */}}
\DoxyCodeLine{00008\ }
\DoxyCodeLine{00009\ \textcolor{preprocessor}{\#include\ "{}config.h"{}}}
\DoxyCodeLine{00010\ }
\DoxyCodeLine{00011\ \textcolor{preprocessor}{\#if\ defined(AD\_BACKEND\_S60)}}
\DoxyCodeLine{00012\ }
\DoxyCodeLine{00013\ \textcolor{comment}{/*}}
\DoxyCodeLine{00014\ \textcolor{comment}{\ \ \ \ S60\ Sphinx\ audio\ backend.}}
\DoxyCodeLine{00015\ \textcolor{comment}{\ \ \ \ Currently\ it\ is\ limited\ to\ recording\ 8kHz\ PCM16\ mono\ audio\ data.}}
\DoxyCodeLine{00016\ \textcolor{comment}{\ */}}
\DoxyCodeLine{00017\ }
\DoxyCodeLine{00018\ \textcolor{comment}{//Symbian\ includes\ must\ go\ first}}
\DoxyCodeLine{00019\ \textcolor{preprocessor}{\#include\ <e32base.h>}}
\DoxyCodeLine{00020\ \textcolor{preprocessor}{\#include\ <e32msgqueue.h>}}
\DoxyCodeLine{00021\ \textcolor{preprocessor}{\#include\ <e32debug.h>}}
\DoxyCodeLine{00022\ \textcolor{preprocessor}{\#include\ <MdaAudioInputStream.h>}}
\DoxyCodeLine{00023\ \textcolor{preprocessor}{\#include\ <mda/common/audio.h>}}
\DoxyCodeLine{00024\ }
\DoxyCodeLine{00025\ \textcolor{preprocessor}{\#include\ "{}ad.h"{}}}
\DoxyCodeLine{00026\ }
\DoxyCodeLine{00027\ \textcolor{comment}{/*\ }}
\DoxyCodeLine{00028\ \textcolor{comment}{\ *\ Implementation\ notes}}
\DoxyCodeLine{00029\ \textcolor{comment}{\ *\ Since\ Symbian\ uses\ a\ callback\ system\ based\ on\ Active\ Objects\ to\ carry\ out\ asynchronous}}
\DoxyCodeLine{00030\ \textcolor{comment}{\ *\ operations\ we\ must\ make\ use\ of\ a\ helper\ thread,\ which\ is\ also\ useful\ for\ priority\ reasons.}}
\DoxyCodeLine{00031\ \textcolor{comment}{\ *\ }}
\DoxyCodeLine{00032\ \textcolor{comment}{\ *\ Sphinxbase\ functions\ are\ implemented\ through\ the\ CAudioDevice\ class\ that\ communicates}}
\DoxyCodeLine{00033\ \textcolor{comment}{\ *\ with\ the\ helper\ thread,\ which\ is\ encapsulated\ in\ CHelperThreadHost.\ Threads\ use:}}
\DoxyCodeLine{00034\ \textcolor{comment}{\ *\ \ -\/\ a\ synchronized\ temporaryBuffer\ and}}
\DoxyCodeLine{00035\ \textcolor{comment}{\ *\ \ -\/\ Symbian\ thread-\/safe\ queues\ (RMsgQueues)}}
\DoxyCodeLine{00036\ \textcolor{comment}{\ *\ to\ communicate.}}
\DoxyCodeLine{00037\ \textcolor{comment}{\ */}}
\DoxyCodeLine{00038\ }
\DoxyCodeLine{00039\ \textcolor{comment}{//constants}}
\DoxyCodeLine{00040\ }
\DoxyCodeLine{00041\ \textcolor{comment}{/*\ }}
\DoxyCodeLine{00042\ \textcolor{comment}{\ *\ Messages\ sent\ through\ RMsgQueues.}}
\DoxyCodeLine{00043\ \textcolor{comment}{\ */}}
\DoxyCodeLine{00044\ \textcolor{keyword}{enum}\ TMessage\ \{}
\DoxyCodeLine{00045\ \ \ \ \ ENullMessage\ =\ 0,}
\DoxyCodeLine{00046\ \ \ \ \ EInited,}
\DoxyCodeLine{00047\ \ \ \ \ EStartRecording,}
\DoxyCodeLine{00048\ \ \ \ \ ERecordingStarted,}
\DoxyCodeLine{00049\ \ \ \ \ EStopRecording,}
\DoxyCodeLine{00050\ \ \ \ \ ERecordingStopped,}
\DoxyCodeLine{00051\ \ \ \ \ EClose,}
\DoxyCodeLine{00052\ \ \ \ \ EClosed}
\DoxyCodeLine{00053\ \};}
\DoxyCodeLine{00054\ }
\DoxyCodeLine{00055\ \textcolor{comment}{/*\ }}
\DoxyCodeLine{00056\ \textcolor{comment}{\ *\ Max\ RMsgQueue\ size\ (will\ block\ if\ full).}}
\DoxyCodeLine{00057\ \textcolor{comment}{\ */}}
\DoxyCodeLine{00058\ \textcolor{keyword}{const}\ TInt\ KQueueLength\ =\ 10;}
\DoxyCodeLine{00059\ }
\DoxyCodeLine{00060\ \textcolor{comment}{/*\ }}
\DoxyCodeLine{00061\ \textcolor{comment}{\ *\ Only\ PCM16\ is\ supported\ at\ the\ moment.}}
\DoxyCodeLine{00062\ \textcolor{comment}{\ */}}
\DoxyCodeLine{00063\ \textcolor{keyword}{const}\ TInt\ KBytesPerSample\ =\ 2;}
\DoxyCodeLine{00064\ }
\DoxyCodeLine{00065\ \textcolor{comment}{/*\ }}
\DoxyCodeLine{00066\ \textcolor{comment}{\ *\ Only\ 16kHz\ audio\ is\ supported\ at\ the\ moment.}}
\DoxyCodeLine{00067\ \textcolor{comment}{\ */}}
\DoxyCodeLine{00068\ \textcolor{keyword}{const}\ TInt\ KSampleRate\ =\ 16000;}
\DoxyCodeLine{00069\ }
\DoxyCodeLine{00070\ \textcolor{comment}{/*\ }}
\DoxyCodeLine{00071\ \textcolor{comment}{\ *\ Temporary\ buffer\ length\ in\ milliseconds.\ The\ temporary\ buffer\ is\ filled}}
\DoxyCodeLine{00072\ \textcolor{comment}{\ *\ by\ the\ OS\ and\ then\ copied\ to\ the\ main\ buffer\ where\ it\ is\ read\ by\ Sphinxbase}}
\DoxyCodeLine{00073\ \textcolor{comment}{\ *\ functions.}}
\DoxyCodeLine{00074\ \textcolor{comment}{\ */}}
\DoxyCodeLine{00075\ \textcolor{keyword}{const}\ TInt\ KTemporaryBufferTime\ =\ 150;}
\DoxyCodeLine{00076\ }
\DoxyCodeLine{00077\ \textcolor{comment}{/*\ }}
\DoxyCodeLine{00078\ \textcolor{comment}{\ *\ Temporary\ buffer\ length\ in\ bytes.}}
\DoxyCodeLine{00079\ \textcolor{comment}{\ */}}
\DoxyCodeLine{00080\ \textcolor{keyword}{const}\ TInt\ KTemporaryBufferSize\ =\ (KTemporaryBufferTime\ *\ KSampleRate\ *\ KBytesPerSample)\ /\ 1000;}
\DoxyCodeLine{00081\ }
\DoxyCodeLine{00082\ \textcolor{comment}{/*\ }}
\DoxyCodeLine{00083\ \textcolor{comment}{\ *\ Helper\ thread\ name.}}
\DoxyCodeLine{00084\ \textcolor{comment}{\ */}}
\DoxyCodeLine{00085\ \_LIT(KHelperThreadName,\ \textcolor{stringliteral}{"{}HelperThread"{}});}
\DoxyCodeLine{00086\ }
\DoxyCodeLine{00087\ \textcolor{comment}{/*\ }}
\DoxyCodeLine{00088\ \textcolor{comment}{\ *\ Possible\ helper\ thread\ states.}}
\DoxyCodeLine{00089\ \textcolor{comment}{\ */}}
\DoxyCodeLine{00090\ \textcolor{keyword}{enum}\ THelperThreadState\ \{EPaused\ =\ 0,\ ERecording,\ EClosing\};}
\DoxyCodeLine{00091\ }
\DoxyCodeLine{00092\ \textcolor{comment}{//classes}}
\DoxyCodeLine{00093\ }
\DoxyCodeLine{00094\ \textcolor{comment}{/*\ }}
\DoxyCodeLine{00095\ \textcolor{comment}{\ *\ Helper\ thread\ wrapper\ class.}}
\DoxyCodeLine{00096\ \textcolor{comment}{\ */}}
\DoxyCodeLine{00097\ \textcolor{keyword}{class\ }CHelperThreadHost\ :\ \textcolor{keyword}{public}\ MMdaAudioInputStreamCallback\ \{}
\DoxyCodeLine{00098\ \ \ \ \ \textcolor{keyword}{public}:}
\DoxyCodeLine{00099\ \ \ \ \ \ \ \ \ CHelperThreadHost(CBufSeg*,\ RFastLock*,\ RMsgQueue<TInt>*,\ RMsgQueue<TInt>*);}
\DoxyCodeLine{00100\ \ \ \ \ \ \ \ \ \textcolor{keyword}{virtual}\ \string~CHelperThreadHost();}
\DoxyCodeLine{00101\ \ \ \ \ \ \ \ \ \textcolor{keyword}{static}\ TInt\ ThreadFunction(TAny*);}
\DoxyCodeLine{00102\ \ \ \ \ \ \ \ \ \textcolor{keywordtype}{void}\ InitializeL();}
\DoxyCodeLine{00103\ \ \ \ \ \ \ \ \ \textcolor{keywordtype}{void}\ DestroyL();}
\DoxyCodeLine{00104\ \ \ \ \ \ \ \ \ }
\DoxyCodeLine{00105\ \ \ \ \ \ \ \ \ \textcolor{keyword}{virtual}\ \textcolor{keywordtype}{void}\ MaiscOpenComplete(TInt);}
\DoxyCodeLine{00106\ \ \ \ \ \ \ \ \ \textcolor{keyword}{virtual}\ \textcolor{keywordtype}{void}\ MaiscBufferCopied(TInt,\ \textcolor{keyword}{const}\ TDesC8\&);}
\DoxyCodeLine{00107\ \ \ \ \ \ \ \ \ \textcolor{keyword}{virtual}\ \textcolor{keywordtype}{void}\ MaiscRecordComplete(TInt);}
\DoxyCodeLine{00108\ \ \ \ \ \ \ \ \ }
\DoxyCodeLine{00109\ \ \ \ \ \textcolor{keyword}{private}:}
\DoxyCodeLine{00110\ \ \ \ \ \ \ \ \ CMdaAudioInputStream*\ iStream;}
\DoxyCodeLine{00111\ \ \ \ \ \ \ \ \ TMdaAudioDataSettings\ iStreamSettings;}
\DoxyCodeLine{00112\ \ \ \ \ \ \ \ \ THelperThreadState\ iState;}
\DoxyCodeLine{00113\ }
\DoxyCodeLine{00114\ \ \ \ \ \ \ \ \ RBuf8\ iTemporaryBuffer;}
\DoxyCodeLine{00115\ }
\DoxyCodeLine{00116\ \ \ \ \ \ \ \ \ CBufSeg*\ iBuffer;}
\DoxyCodeLine{00117\ \ \ \ \ \ \ \ \ RFastLock*\ iBufferLock;}
\DoxyCodeLine{00118\ }
\DoxyCodeLine{00119\ \ \ \ \ \ \ \ \ RMsgQueue<TInt>*\ iCommandQueue;}
\DoxyCodeLine{00120\ \ \ \ \ \ \ \ \ RMsgQueue<TInt>*\ iNotificationQueue;}
\DoxyCodeLine{00121\ \};}
\DoxyCodeLine{00122\ }
\DoxyCodeLine{00123\ \textcolor{comment}{/*\ }}
\DoxyCodeLine{00124\ \textcolor{comment}{\ *\ Class\ used\ to\ invoke\ Symbian\ functions\ from\ Sphinx\ functions.}}
\DoxyCodeLine{00125\ \textcolor{comment}{\ */}}
\DoxyCodeLine{00126\ \textcolor{keyword}{class\ }CAudioDevice\ \{}
\DoxyCodeLine{00127\ \ \ \ \ \textcolor{keyword}{public}:}
\DoxyCodeLine{00128\ \ \ \ \ \ \ \ \ CAudioDevice();}
\DoxyCodeLine{00129\ \ \ \ \ \ \ \ \ \textcolor{keywordtype}{void}\ ConstructL();}
\DoxyCodeLine{00130\ \ \ \ \ \ \ \ \ \textcolor{keyword}{static}\ CAudioDevice*\ NewL();}
\DoxyCodeLine{00131\ \ \ \ \ \ \ \ \ \textcolor{keyword}{virtual}\ \string~CAudioDevice();}
\DoxyCodeLine{00132\ \ \ \ \ \ \ \ \ }
\DoxyCodeLine{00133\ \ \ \ \ \ \ \ \ \textcolor{keywordtype}{void}\ ResumeRecording();}
\DoxyCodeLine{00134\ \ \ \ \ \ \ \ \ \textcolor{keywordtype}{void}\ PauseRecording();}
\DoxyCodeLine{00135\ \ \ \ \ \ \ \ \ TInt\ ReadSamples(TAny*,\ TInt);}
\DoxyCodeLine{00136\ \ \ \ \ \ \ \ \ }
\DoxyCodeLine{00137\ \ \ \ \ \textcolor{keyword}{private}:}
\DoxyCodeLine{00138\ \ \ \ \ \ \ \ \ RThread\ iThread;}
\DoxyCodeLine{00139\ \ \ \ \ \ \ \ \ CHelperThreadHost*\ iThreadHost;}
\DoxyCodeLine{00140\ \ \ \ \ \ \ \ \ }
\DoxyCodeLine{00141\ \ \ \ \ \ \ \ \ CBufSeg*\ iBuffer;}
\DoxyCodeLine{00142\ \ \ \ \ \ \ \ \ RFastLock\ iBufferLock;}
\DoxyCodeLine{00143\ \ \ \ \ \ \ \ \ }
\DoxyCodeLine{00144\ \ \ \ \ \ \ \ \ RMsgQueue<TInt>\ iCommandQueue;}
\DoxyCodeLine{00145\ \ \ \ \ \ \ \ \ RMsgQueue<TInt>\ iNotificationQueue;}
\DoxyCodeLine{00146\ \};}
\DoxyCodeLine{00147\ }
\DoxyCodeLine{00148\ CAudioDevice::CAudioDevice()\{}
\DoxyCodeLine{00149\ \ \ \ \ iCommandQueue.CreateLocal(KQueueLength);}
\DoxyCodeLine{00150\ \ \ \ \ iNotificationQueue.CreateLocal(KQueueLength);}
\DoxyCodeLine{00151\ \}}
\DoxyCodeLine{00152\ }
\DoxyCodeLine{00153\ \textcolor{keywordtype}{void}\ CAudioDevice::ConstructL()\{}
\DoxyCodeLine{00154\ \ \ \ \ iBuffer\ =\ CBufSeg::NewL(KTemporaryBufferSize);}
\DoxyCodeLine{00155\ \ \ \ \ iBufferLock.CreateLocal();}
\DoxyCodeLine{00156\ \ \ \ \ }
\DoxyCodeLine{00157\ \ \ \ \ iThreadHost\ =\ \textcolor{keyword}{new}\ (ELeave)\ CHelperThreadHost(iBuffer,\ \&(iBufferLock),\ \&(iCommandQueue),\ \&(iNotificationQueue));}
\DoxyCodeLine{00158\ \ \ \ \ iThread.Create(KHelperThreadName,\ CHelperThreadHost::ThreadFunction,\ KDefaultStackSize,\ NULL,\ iThreadHost);}
\DoxyCodeLine{00159\ \ \ \ \ iThread.Resume();\ \textcolor{comment}{//new\ thread\ starts\ at\ ThreadFunction}}
\DoxyCodeLine{00160\ \ \ \ \ }
\DoxyCodeLine{00161\ \ \ \ \ \textcolor{comment}{//wait\ until\ init\ is\ done}}
\DoxyCodeLine{00162\ \ \ \ \ TInt\ message\ =\ ENullMessage;}
\DoxyCodeLine{00163\ \ \ \ \ iNotificationQueue.ReceiveBlocking(message);}
\DoxyCodeLine{00164\ \ \ \ \ \textcolor{keywordflow}{if}(message\ !=\ EInited)\{}
\DoxyCodeLine{00165\ \ \ \ \ \ \ \ \ RDebug::Print(\_L(\textcolor{stringliteral}{"{}expecting\ \%d,\ got\ \%d"{}}),\ EInited,\ message);}
\DoxyCodeLine{00166\ \ \ \ \ \}}
\DoxyCodeLine{00167\ \}}
\DoxyCodeLine{00168\ }
\DoxyCodeLine{00169\ CAudioDevice*\ CAudioDevice::NewL()\{}
\DoxyCodeLine{00170\ \ \ \ \ CAudioDevice*\ self\ =\ \textcolor{keyword}{new}\ (ELeave)\ CAudioDevice();}
\DoxyCodeLine{00171\ \ \ \ \ CleanupStack::PushL(self);}
\DoxyCodeLine{00172\ \ \ \ \ self-\/>ConstructL();}
\DoxyCodeLine{00173\ \ \ \ \ CleanupStack::Pop(self);}
\DoxyCodeLine{00174\ \ \ \ \ \textcolor{keywordflow}{return}\ self;}
\DoxyCodeLine{00175\ \}}
\DoxyCodeLine{00176\ }
\DoxyCodeLine{00177\ \textcolor{comment}{/*}}
\DoxyCodeLine{00178\ \textcolor{comment}{\ *\ Request\ to\ record\ samples.}}
\DoxyCodeLine{00179\ \textcolor{comment}{\ */}}
\DoxyCodeLine{00180\ \textcolor{keywordtype}{void}\ CAudioDevice::ResumeRecording()\{}
\DoxyCodeLine{00181\ \ \ \ \ iCommandQueue.SendBlocking(EStartRecording);}
\DoxyCodeLine{00182\ \ \ \ \ }
\DoxyCodeLine{00183\ \ \ \ \ TInt\ message\ =\ ENullMessage;}
\DoxyCodeLine{00184\ \ \ \ \ iNotificationQueue.ReceiveBlocking(message);}
\DoxyCodeLine{00185\ \ \ \ \ \textcolor{keywordflow}{if}(message\ !=\ ERecordingStarted)\{}
\DoxyCodeLine{00186\ \ \ \ \ \ \ \ \ RDebug::Print(\_L(\textcolor{stringliteral}{"{}expecting\ \%d,\ got\ \%d"{}}),\ ERecordingStarted,\ message);}
\DoxyCodeLine{00187\ \ \ \ \ \}}
\DoxyCodeLine{00188\ \}}
\DoxyCodeLine{00189\ }
\DoxyCodeLine{00190\ \textcolor{comment}{/*}}
\DoxyCodeLine{00191\ \textcolor{comment}{\ *\ Request\ to\ stop\ recording\ samples.\ Note\ that\ actually\ we\ don't\ stop\ the\ recording,}}
\DoxyCodeLine{00192\ \textcolor{comment}{\ *\ but\ just\ discard\ incoming\ data\ until\ ResumeRecording\ is\ called\ again.}}
\DoxyCodeLine{00193\ \textcolor{comment}{\ */}}
\DoxyCodeLine{00194\ \textcolor{keywordtype}{void}\ CAudioDevice::PauseRecording()\{}
\DoxyCodeLine{00195\ \ \ \ \ iCommandQueue.SendBlocking(EStopRecording);}
\DoxyCodeLine{00196\ \ \ \ \ }
\DoxyCodeLine{00197\ \ \ \ \ TInt\ message\ =\ ENullMessage;}
\DoxyCodeLine{00198\ \ \ \ \ iNotificationQueue.ReceiveBlocking(message);}
\DoxyCodeLine{00199\ \ \ \ \ \textcolor{keywordflow}{if}(message\ !=\ ERecordingStopped)\{}
\DoxyCodeLine{00200\ \ \ \ \ \ \ \ \ RDebug::Print(\_L(\textcolor{stringliteral}{"{}expecting\ \%d,\ got\ \%d"{}}),\ ERecordingStopped,\ message);}
\DoxyCodeLine{00201\ \ \ \ \ \}}
\DoxyCodeLine{00202\ \}}
\DoxyCodeLine{00203\ }
\DoxyCodeLine{00204\ \textcolor{comment}{/*}}
\DoxyCodeLine{00205\ \textcolor{comment}{\ *\ Reads\ at\ most\ maxSamples\ samples\ into\ destinationBuffer,\ returning}}
\DoxyCodeLine{00206\ \textcolor{comment}{\ *\ the\ actual\ number\ of\ samples\ read.}}
\DoxyCodeLine{00207\ \textcolor{comment}{\ */}}
\DoxyCodeLine{00208\ TInt\ CAudioDevice::ReadSamples(TAny*\ aDestinationBuffer,\ TInt\ aMaxSamples)\{}
\DoxyCodeLine{00209\ \ \ \ \ iBufferLock.Wait();}
\DoxyCodeLine{00210\ \ \ \ \ \ \ \ \ TInt\ availableSamples\ =\ iBuffer-\/>Size()\ /\ KBytesPerSample;}
\DoxyCodeLine{00211\ \ \ \ \ \ \ \ \ TInt\ samplesToCopy\ =\ aMaxSamples;}
\DoxyCodeLine{00212\ \ \ \ \ \ \ \ \ \textcolor{keywordflow}{if}\ (availableSamples\ <\ aMaxSamples)\{}
\DoxyCodeLine{00213\ \ \ \ \ \ \ \ \ \ \ \ \ samplesToCopy\ =\ availableSamples;}
\DoxyCodeLine{00214\ \ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{00215\ \ \ \ \ \ \ \ \ TInt\ bytesToCopy\ =\ samplesToCopy\ *\ KBytesPerSample;}
\DoxyCodeLine{00216\ \ \ \ \ \ \ \ \ iBuffer-\/>Read(0,\ aDestinationBuffer,\ bytesToCopy);}
\DoxyCodeLine{00217\ \ \ \ \ \ \ \ \ iBuffer-\/>Delete(0,\ bytesToCopy);}
\DoxyCodeLine{00218\ \ \ \ \ iBufferLock.Signal();}
\DoxyCodeLine{00219\ }
\DoxyCodeLine{00220\ \ \ \ \ \textcolor{keywordflow}{return}\ samplesToCopy;}
\DoxyCodeLine{00221\ \}}
\DoxyCodeLine{00222\ }
\DoxyCodeLine{00223\ CAudioDevice::\string~CAudioDevice()\{}
\DoxyCodeLine{00224\ \ \ \ \ \textcolor{comment}{//tell\ the\ thread\ to\ stop\ operations}}
\DoxyCodeLine{00225\ \ \ \ \ iCommandQueue.SendBlocking(EClose);}
\DoxyCodeLine{00226\ }
\DoxyCodeLine{00227\ \ \ \ \ TInt\ message\ =\ ENullMessage;}
\DoxyCodeLine{00228\ \ \ \ \ iNotificationQueue.ReceiveBlocking(message);}
\DoxyCodeLine{00229\ \ \ \ \ \textcolor{keywordflow}{if}(message\ !=\ EClosed)\{}
\DoxyCodeLine{00230\ \ \ \ \ \ \ \ \ RDebug::Print(\_L(\textcolor{stringliteral}{"{}expecting\ \%d,\ got\ \%d"{}}),\ EClosed,\ message);}
\DoxyCodeLine{00231\ \ \ \ \ \}}
\DoxyCodeLine{00232\ \ \ \ \ }
\DoxyCodeLine{00233\ \ \ \ \ \textcolor{comment}{//join\ thread}}
\DoxyCodeLine{00234\ \ \ \ \ TRequestStatus\ status;}
\DoxyCodeLine{00235\ \ \ \ \ iThread.Logon(status);}
\DoxyCodeLine{00236\ \ \ \ \ User::WaitForRequest(status);}
\DoxyCodeLine{00237\ \ \ \ \ }
\DoxyCodeLine{00238\ \ \ \ \ \textcolor{comment}{//destroy\ fields}}
\DoxyCodeLine{00239\ \ \ \ \ \textcolor{keyword}{delete}\ iThreadHost;}
\DoxyCodeLine{00240\ \ \ \ \ iThread.Close();}
\DoxyCodeLine{00241\ \ \ \ \ iBufferLock.Close();}
\DoxyCodeLine{00242\ \ \ \ \ \textcolor{keyword}{delete}\ iBuffer;}
\DoxyCodeLine{00243\ \ \ \ \ iNotificationQueue.Close();}
\DoxyCodeLine{00244\ \ \ \ \ iCommandQueue.Close();}
\DoxyCodeLine{00245\ \}}
\DoxyCodeLine{00246\ }
\DoxyCodeLine{00247\ CHelperThreadHost::CHelperThreadHost(CBufSeg*\ aBuffer,\ RFastLock*\ aBufferLock,\ RMsgQueue<TInt>*\ aCommandQueue,\ RMsgQueue<TInt>*\ aNotificationQueue)\{}
\DoxyCodeLine{00248\ \ \ \ \ iBuffer\ =\ aBuffer;}
\DoxyCodeLine{00249\ \ \ \ \ iBufferLock\ =\ aBufferLock;}
\DoxyCodeLine{00250\ \ \ \ \ iCommandQueue\ =\ aCommandQueue;}
\DoxyCodeLine{00251\ \ \ \ \ iNotificationQueue\ =\ aNotificationQueue;}
\DoxyCodeLine{00252\ \ \ \ \ iState\ =\ EPaused;}
\DoxyCodeLine{00253\ \}}
\DoxyCodeLine{00254\ }
\DoxyCodeLine{00255\ TInt\ CHelperThreadHost::ThreadFunction(TAny*\ aParam)\{}
\DoxyCodeLine{00256\ \ \ \ \ CHelperThreadHost*\ host\ =\ (CHelperThreadHost*)\ aParam;}
\DoxyCodeLine{00257\ }
\DoxyCodeLine{00258\ \ \ \ \ \textcolor{comment}{//add\ cleanup\ stack\ support}}
\DoxyCodeLine{00259\ \ \ \ \ CTrapCleanup*\ cleanupStack\ =\ CTrapCleanup::New();}
\DoxyCodeLine{00260\ \ \ \ \ }
\DoxyCodeLine{00261\ \ \ \ \ \textcolor{comment}{//add\ active\ objects\ suppport}}
\DoxyCodeLine{00262\ \ \ \ \ TRAPD(error,\ \ \ }
\DoxyCodeLine{00263\ \ \ \ \ \ \ \ \ CActiveScheduler*\ activeScheduler\ =\ \textcolor{keyword}{new}\ (ELeave)\ CActiveScheduler;}
\DoxyCodeLine{00264\ \ \ \ \ \ \ \ \ CleanupStack::PushL(activeScheduler);}
\DoxyCodeLine{00265\ \ \ \ \ \ \ \ \ CActiveScheduler::Install(activeScheduler);}
\DoxyCodeLine{00266\ \ \ \ \ \ \ \ \ }
\DoxyCodeLine{00267\ \ \ \ \ \ \ \ \ \textcolor{comment}{//init\ multimedia\ system}}
\DoxyCodeLine{00268\ \ \ \ \ \ \ \ \ host-\/>InitializeL();}
\DoxyCodeLine{00269\ \ \ \ \ \ \ \ \ }
\DoxyCodeLine{00270\ \ \ \ \ \ \ \ \ \textcolor{comment}{//run\ active\ scheduler}}
\DoxyCodeLine{00271\ \ \ \ \ \ \ \ \ CActiveScheduler::Start();}
\DoxyCodeLine{00272\ \ \ \ \ \ \ \ \ }
\DoxyCodeLine{00273\ \ \ \ \ \ \ \ \ \textcolor{comment}{//thread\ execution\ ended}}
\DoxyCodeLine{00274\ \ \ \ \ \ \ \ \ CleanupStack::PopAndDestroy(activeScheduler);}
\DoxyCodeLine{00275\ \ \ \ \ );}
\DoxyCodeLine{00276\ \ \ \ \ \textcolor{keywordflow}{if}(error\ !=\ KErrNone)\{}
\DoxyCodeLine{00277\ \ \ \ \ \ \ \ \ RDebug::Print(\_L(\textcolor{stringliteral}{"{}thread\ error:\ \%d"{}}),\ error);}
\DoxyCodeLine{00278\ \ \ \ \ \}}
\DoxyCodeLine{00279\ \ \ \ \ }
\DoxyCodeLine{00280\ \ \ \ \ \textcolor{keyword}{delete}\ cleanupStack;}
\DoxyCodeLine{00281\ \ \ \ \ \textcolor{keywordflow}{return}\ KErrNone;}
\DoxyCodeLine{00282\ \}}
\DoxyCodeLine{00283\ }
\DoxyCodeLine{00284\ \textcolor{comment}{/*}}
\DoxyCodeLine{00285\ \textcolor{comment}{\ *\ Inits\ iStream\ and\ iTemporaryBuffer.}}
\DoxyCodeLine{00286\ \textcolor{comment}{\ */}}
\DoxyCodeLine{00287\ \textcolor{keywordtype}{void}\ CHelperThreadHost::InitializeL()\{}
\DoxyCodeLine{00288\ \ \ \ \ iStream\ =\ CMdaAudioInputStream::NewL(*\textcolor{keyword}{this},\ EMdaPriorityMax,\ EMdaPriorityPreferenceTime);}
\DoxyCodeLine{00289\ \ \ \ \ iStream-\/>Open(\&(iStreamSettings));\ \textcolor{comment}{//calls\ MaiscOpenComplete\ asynchronously}}
\DoxyCodeLine{00290\ \ \ \ \ iTemporaryBuffer.CreateL(KTemporaryBufferSize);}
\DoxyCodeLine{00291\ \}}
\DoxyCodeLine{00292\ }
\DoxyCodeLine{00293\ \textcolor{comment}{/*}}
\DoxyCodeLine{00294\ \textcolor{comment}{\ *\ Destroys\ iStream\ and\ iTemporaryBuffer.}}
\DoxyCodeLine{00295\ \textcolor{comment}{\ */}}
\DoxyCodeLine{00296\ \textcolor{keywordtype}{void}\ CHelperThreadHost::DestroyL()\{}
\DoxyCodeLine{00297\ \ \ \ \ iTemporaryBuffer.Close();}
\DoxyCodeLine{00298\ \textcolor{preprocessor}{\#if\ defined(\_\_WINSCW\_\_)}}
\DoxyCodeLine{00299\ \ \ \ \ iStream-\/>Stop();}
\DoxyCodeLine{00300\ \ \ \ \ CMdaAudioInputStream::Delete(iStream);}
\DoxyCodeLine{00301\ \textcolor{preprocessor}{\#else}}
\DoxyCodeLine{00302\ \ \ \ \ \textcolor{keyword}{delete}\ iStream;}
\DoxyCodeLine{00303\ \textcolor{preprocessor}{\#endif}}
\DoxyCodeLine{00304\ \}}
\DoxyCodeLine{00305\ }
\DoxyCodeLine{00306\ \textcolor{comment}{/*}}
\DoxyCodeLine{00307\ \textcolor{comment}{\ *\ Called\ by\ the\ OS\ when\ iStream\ has\ been\ opened.}}
\DoxyCodeLine{00308\ \textcolor{comment}{\ */}}
\DoxyCodeLine{00309\ \textcolor{keywordtype}{void}\ CHelperThreadHost::MaiscOpenComplete(TInt\ aError)\{}
\DoxyCodeLine{00310\ \ \ \ \ \textcolor{keywordflow}{if}\ (aError\ ==\ KErrNone)\{}
\DoxyCodeLine{00311\ \ \ \ \ \ \ \ \ iNotificationQueue-\/>SendBlocking(EInited);}
\DoxyCodeLine{00312\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ }
\DoxyCodeLine{00313\ \ \ \ \ \ \ \ \ iStream-\/>SetAudioPropertiesL(TMdaAudioDataSettings::ESampleRate16000Hz,\ TMdaAudioDataSettings::EChannelsMono);}
\DoxyCodeLine{00314\ \ \ \ \ \ \ \ \ iStream-\/>SetGain(iStream-\/>MaxGain());}
\DoxyCodeLine{00315\ }
\DoxyCodeLine{00316\ \ \ \ \ \ \ \ \ iStream-\/>ReadL(iTemporaryBuffer);\ \textcolor{comment}{//calls\ MaiscBufferCopied\ asynchronously}}
\DoxyCodeLine{00317\ \ \ \ \ \}}
\DoxyCodeLine{00318\ \ \ \ \ \textcolor{keywordflow}{else}\{}
\DoxyCodeLine{00319\ \ \ \ \ \ \ \ \ RDebug::Print(\_L(\textcolor{stringliteral}{"{}error\ \%d\ in\ MaiscOpenComplete"{}}),\ aError);}
\DoxyCodeLine{00320\ \ \ \ \ \}}
\DoxyCodeLine{00321\ \}}
\DoxyCodeLine{00322\ }
\DoxyCodeLine{00323\ \textcolor{comment}{/*}}
\DoxyCodeLine{00324\ \textcolor{comment}{\ *\ Called\ by\ the\ OS\ when\ iTemporaryBuffer\ has\ been\ filled.}}
\DoxyCodeLine{00325\ \textcolor{comment}{\ */}}
\DoxyCodeLine{00326\ \textcolor{keywordtype}{void}\ CHelperThreadHost::MaiscBufferCopied(TInt\ aError,\ \textcolor{keyword}{const}\ TDesC8\ \&aBuffer)\{}
\DoxyCodeLine{00327\ \ \ \ \ \textcolor{keywordflow}{if}\ (aError\ ==\ KErrNone)\{}
\DoxyCodeLine{00328\ \ \ \ \ \ \ \ \ \textcolor{comment}{//if\ needed,\ record\ data}}
\DoxyCodeLine{00329\ \ \ \ \ \ \ \ \ \textcolor{keywordflow}{if}(iState\ ==\ ERecording)\{}
\DoxyCodeLine{00330\ \ \ \ \ \ \ \ \ \ \ \ \ TInt\ availableBytes\ =\ aBuffer.Size();}
\DoxyCodeLine{00331\ \ \ \ \ \ \ \ \ \ \ \ \ iBufferLock-\/>Wait();}
\DoxyCodeLine{00332\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ TInt\ bufferSize\ =\ iBuffer-\/>Size();}
\DoxyCodeLine{00333\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ iBuffer-\/>ExpandL(bufferSize,\ availableBytes);}
\DoxyCodeLine{00334\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ iBuffer-\/>Write(bufferSize,\ aBuffer,\ availableBytes);}
\DoxyCodeLine{00335\ \ \ \ \ \ \ \ \ \ \ \ \ iBufferLock-\/>Signal();}
\DoxyCodeLine{00336\ \ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{00337\ \ \ \ \ \ \ \ \ }
\DoxyCodeLine{00338\ \ \ \ \ \ \ \ \ \textcolor{comment}{//empty\ buffer}}
\DoxyCodeLine{00339\ \ \ \ \ \ \ \ \ iTemporaryBuffer.Zero();}
\DoxyCodeLine{00340\ \ \ \ \ \ \ \ \ }
\DoxyCodeLine{00341\ \ \ \ \ \ \ \ \ \textcolor{comment}{//process\ pending\ messages}}
\DoxyCodeLine{00342\ \ \ \ \ \ \ \ \ TInt\ message\ =\ ENullMessage;}
\DoxyCodeLine{00343\ \ \ \ \ \ \ \ \ TInt\ result\ =\ iCommandQueue-\/>Receive(message);}
\DoxyCodeLine{00344\ \ \ \ \ \ \ \ \ \textcolor{keywordflow}{if}\ (result\ ==\ KErrNone)\{}
\DoxyCodeLine{00345\ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keywordflow}{if}(message\ ==\ EStartRecording)\{}
\DoxyCodeLine{00346\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ iState\ =\ ERecording;}
\DoxyCodeLine{00347\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ iNotificationQueue-\/>SendBlocking(ERecordingStarted);}
\DoxyCodeLine{00348\ \ \ \ \ \ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{00349\ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keywordflow}{else}\ \textcolor{keywordflow}{if}(message\ ==\ EStopRecording)\{}
\DoxyCodeLine{00350\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ iState\ =\ EPaused;}
\DoxyCodeLine{00351\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ iNotificationQueue-\/>SendBlocking(ERecordingStopped);}
\DoxyCodeLine{00352\ \ \ \ \ \ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{00353\ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keywordflow}{else}\ \textcolor{keywordflow}{if}(message\ ==\ EClose)\{}
\DoxyCodeLine{00354\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ iState\ =\ EClosing;}
\DoxyCodeLine{00355\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ iStream-\/>Stop();\ \textcolor{comment}{//calls\ MaiscRecordComplete\ asynchronously}}
\DoxyCodeLine{00356\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ this-\/>DestroyL();}
\DoxyCodeLine{00357\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ iNotificationQueue-\/>SendBlocking(EClosed);}
\DoxyCodeLine{00358\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ User::Exit(0);}
\DoxyCodeLine{00359\ \ \ \ \ \ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{00360\ \ \ \ \ \ \ \ \ \ \ \ \ \textcolor{keywordflow}{else}\{}
\DoxyCodeLine{00361\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ RDebug::Print(\_L(\textcolor{stringliteral}{"{}received\ unexpected\ \%d"{}}),\ message);}
\DoxyCodeLine{00362\ \ \ \ \ \ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{00363\ \ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{00364\ \ \ \ \ \ \ \ \ }
\DoxyCodeLine{00365\ \ \ \ \ \ \ \ \ \textcolor{comment}{//unless\ stopping,\ request\ filling\ the\ next\ buffer}}
\DoxyCodeLine{00366\ \ \ \ \ \ \ \ \ \textcolor{keywordflow}{if}\ (iState\ !=\ EClosing)\{}
\DoxyCodeLine{00367\ \ \ \ \ \ \ \ \ \ \ \ \ iStream-\/>ReadL(iTemporaryBuffer);\ \textcolor{comment}{//calls\ MaiscBufferCopied\ asynchronously}}
\DoxyCodeLine{00368\ \ \ \ \ \ \ \ \ \}}
\DoxyCodeLine{00369\ \ \ \ \ \}}
\DoxyCodeLine{00370\ \ \ \ \ \textcolor{keywordflow}{else}\ \textcolor{keywordflow}{if}\ (aError\ ==\ KErrAbort)\{}
\DoxyCodeLine{00371\ \ \ \ \ \ \ \ \ \textcolor{comment}{//sent\ when\ discarding\ data\ during\ close,\ nothing\ to\ do\ here}}
\DoxyCodeLine{00372\ \ \ \ \ \}}
\DoxyCodeLine{00373\ \ \ \ \ \textcolor{keywordflow}{else}\{}
\DoxyCodeLine{00374\ \ \ \ \ \ \ \ \ RDebug::Print(\_L(\textcolor{stringliteral}{"{}error\ \%d\ in\ MaiscBufferCopied"{}}),\ aError);}
\DoxyCodeLine{00375\ \ \ \ \ \}}
\DoxyCodeLine{00376\ \}}
\DoxyCodeLine{00377\ }
\DoxyCodeLine{00378\ \textcolor{comment}{/*}}
\DoxyCodeLine{00379\ \textcolor{comment}{\ *\ Should\ be\ called\ by\ the\ OS\ when\ the\ recording\ is\ finished.}}
\DoxyCodeLine{00380\ \textcolor{comment}{\ *\ Due\ to\ a\ bug,\ this\ method\ never\ gets\ called.}}
\DoxyCodeLine{00381\ \textcolor{comment}{\ *\ http://carbidehelp.nokia.com/help/index.jsp?topic=/S60\_5th\_Edition\_Cpp\_Developers\_Library/GUID-\/441D327D-\/D737-\/42A2-\/BCEA-\/FE89FBCA2F35/AudioStreamExample/doc/index.html}}
\DoxyCodeLine{00382\ \textcolor{comment}{\ */}}
\DoxyCodeLine{00383\ \textcolor{keywordtype}{void}\ CHelperThreadHost::MaiscRecordComplete(TInt\ aError)\{}
\DoxyCodeLine{00384\ \ \ \ \ \textcolor{comment}{//nothing\ to\ do\ here}}
\DoxyCodeLine{00385\ \}}
\DoxyCodeLine{00386\ }
\DoxyCodeLine{00387\ CHelperThreadHost::\string~CHelperThreadHost()\{}
\DoxyCodeLine{00388\ \ \ \ \ \textcolor{comment}{//nothing\ to\ do\ here}}
\DoxyCodeLine{00389\ \}}
\DoxyCodeLine{00390\ }
\DoxyCodeLine{00391\ \textcolor{comment}{//Sphinxbase\ methods}}
\DoxyCodeLine{00392\ }
\DoxyCodeLine{00393\ ad\_rec\_t*\ ad\_open(\textcolor{keywordtype}{void})\{}
\DoxyCodeLine{00394\ \ \ \ \ ad\_rec\_t*\ result\ =\ \textcolor{keyword}{new}\ ad\_rec\_t;}
\DoxyCodeLine{00395\ \ \ \ \ result-\/>recorder\ =\ CAudioDevice::NewL();}
\DoxyCodeLine{00396\ \ \ \ \ result-\/>recording\ =\ FALSE;}
\DoxyCodeLine{00397\ \ \ \ \ result-\/>sps\ =\ KSampleRate;}
\DoxyCodeLine{00398\ \ \ \ \ result-\/>bps\ =\ KBytesPerSample;}
\DoxyCodeLine{00399\ \ \ \ \ \textcolor{keywordflow}{return}\ result;}
\DoxyCodeLine{00400\ \}}
\DoxyCodeLine{00401\ }
\DoxyCodeLine{00402\ ad\_rec\_t*\ ad\_open\_dev(\textcolor{keyword}{const}\ \textcolor{keywordtype}{char}*\ dev,\ int32\ sps)\{}
\DoxyCodeLine{00403\ \ \ \ \ \textcolor{comment}{//dummy}}
\DoxyCodeLine{00404\ \ \ \ \ \textcolor{keywordflow}{return}\ ad\_open();}
\DoxyCodeLine{00405\ \}}
\DoxyCodeLine{00406\ }
\DoxyCodeLine{00407\ ad\_rec\_t*\ ad\_open\_sps(int32\ sps)\{}
\DoxyCodeLine{00408\ \ \ \ \ \textcolor{comment}{//dummy}}
\DoxyCodeLine{00409\ \ \ \ \ \textcolor{keywordflow}{return}\ ad\_open();}
\DoxyCodeLine{00410\ \}}
\DoxyCodeLine{00411\ }
\DoxyCodeLine{00412\ ad\_rec\_t*\ ad\_open\_sps\_bufsize(int32\ sps,\ int32\ bufsize\_msec)\{}
\DoxyCodeLine{00413\ \ \ \ \ \textcolor{comment}{//dummy}}
\DoxyCodeLine{00414\ \ \ \ \ \textcolor{keywordflow}{return}\ ad\_open();}
\DoxyCodeLine{00415\ \}}
\DoxyCodeLine{00416\ }
\DoxyCodeLine{00417\ int32\ ad\_start\_rec(ad\_rec\_t*\ r)\{}
\DoxyCodeLine{00418\ \ \ \ \ ((CAudioDevice*)r-\/>recorder)-\/>ResumeRecording();}
\DoxyCodeLine{00419\ \ \ \ \ r-\/>recording\ =\ TRUE;}
\DoxyCodeLine{00420\ \ \ \ \ \textcolor{keywordflow}{return}\ AD\_OK;}
\DoxyCodeLine{00421\ \}}
\DoxyCodeLine{00422\ }
\DoxyCodeLine{00423\ int32\ ad\_read(ad\_rec\_t*\ r,\ int16*\ buf,\ int32\ max)\{}
\DoxyCodeLine{00424\ \ \ \ \ int32\ result\ =\ (int32)\ ((CAudioDevice*)r-\/>recorder)-\/>ReadSamples((TAny*)\ buf,\ (TInt)max);}
\DoxyCodeLine{00425\ \ \ \ \ \textcolor{keywordflow}{if}(result\ ==\ 0\ \&\&\ r-\/>recording\ ==\ FALSE)\{}
\DoxyCodeLine{00426\ \ \ \ \ \ \ \ \ result\ =\ AD\_EOF;}
\DoxyCodeLine{00427\ \ \ \ \ \}}
\DoxyCodeLine{00428\ \ \ \ \ \textcolor{keywordflow}{return}\ result;}
\DoxyCodeLine{00429\ \}}
\DoxyCodeLine{00430\ }
\DoxyCodeLine{00431\ int32\ ad\_stop\_rec(ad\_rec\_t*\ r)\{}
\DoxyCodeLine{00432\ \ \ \ \ ((CAudioDevice*)r-\/>recorder)-\/>PauseRecording();}
\DoxyCodeLine{00433\ \ \ \ \ r-\/>recording\ =\ FALSE;}
\DoxyCodeLine{00434\ \ \ \ \ \textcolor{keywordflow}{return}\ AD\_OK;}
\DoxyCodeLine{00435\ \}}
\DoxyCodeLine{00436\ }
\DoxyCodeLine{00437\ int32\ ad\_close(ad\_rec\_t*\ r)\{}
\DoxyCodeLine{00438\ \ \ \ \ \textcolor{keyword}{delete}\ ((CAudioDevice*)r-\/>recorder);}
\DoxyCodeLine{00439\ \ \ \ \ \textcolor{keyword}{delete}\ r;}
\DoxyCodeLine{00440\ \ \ \ \ \textcolor{keywordflow}{return}\ AD\_OK;}
\DoxyCodeLine{00441\ \}}
\DoxyCodeLine{00442\ }
\DoxyCodeLine{00443\ \textcolor{preprocessor}{\#endif\ }\textcolor{comment}{//defined(AD\_BACKEND\_S60)}}

\end{DoxyCode}
