alsa.audio: fill the complete free buffer before executing another audio loop
[AROS.git] / workbench / devs / AHI / Drivers / Alsa / alsa-playslave.c
blob27c13c38fb9d069f0ae80877c8439aa0d0ad323c
1 /*
2 Copyright © 2015, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <config.h>
8 #include <devices/ahi.h>
9 #include <exec/execbase.h>
10 #include <libraries/ahi_sub.h>
12 #include "DriverData.h"
13 #include "library.h"
15 #define dd ((struct AlsaData*) AudioCtrl->ahiac_DriverData)
17 #define min(a,b) ( (a) < (b) ? (a) : (b) )
19 /******************************************************************************
20 ** The slave process **********************************************************
21 ******************************************************************************/
23 #undef SysBase
25 void Slave( struct ExecBase* SysBase );
27 #include <aros/asmcall.h>
29 AROS_UFH3(LONG, SlaveEntry,
30 AROS_UFHA(STRPTR, argPtr, A0),
31 AROS_UFHA(ULONG, argSize, D0),
32 AROS_UFHA(struct ExecBase *, SysBase, A6))
34 AROS_USERFUNC_INIT
35 Slave( SysBase );
36 AROS_USERFUNC_EXIT
39 void
40 Slave( struct ExecBase* SysBase )
42 struct AHIAudioCtrlDrv* AudioCtrl;
43 struct DriverBase* AHIsubBase;
44 struct AlsaBase* AlsaBase;
45 BOOL running;
46 ULONG signals;
47 LONG framesready = 0;
48 APTR framesptr = NULL;
50 AudioCtrl = (struct AHIAudioCtrlDrv*) FindTask(NULL)->tc_UserData;
51 AHIsubBase = (struct DriverBase*) dd->ahisubbase;
52 AlsaBase = (struct AlsaBase*) AHIsubBase;
54 dd->slavesignal = AllocSignal( -1 );
56 if( dd->slavesignal != -1 )
58 // Everything set up. Tell Master we're alive and healthy.
60 Signal( (struct Task*) dd->mastertask,
61 1L << dd->mastersignal );
63 running = TRUE;
65 while( running )
67 signals = SetSignal(0L,0L);
69 if( signals & ( SIGBREAKF_CTRL_C | (1L << dd->slavesignal) ) )
71 running = FALSE;
73 else
75 LONG framesfree = 0;
77 while(TRUE)
79 framesfree = ALSA_Avail(dd->alsahandle);
80 if (framesfree > 1024)
81 break;
82 Delay(1);
85 /* Loop until alsa buffer is filled */
86 while (framesfree > 0)
88 LONG written;
90 if (framesready == 0)
92 CallHookPkt(AudioCtrl->ahiac_PlayerFunc, AudioCtrl, NULL );
93 CallHookPkt(AudioCtrl->ahiac_MixerFunc, AudioCtrl, dd->mixbuffer );
94 framesready = AudioCtrl->ahiac_BuffSamples;
95 framesptr = dd->mixbuffer;
98 written = ALSA_Write(dd->alsahandle, framesptr, min(framesready, framesfree));
100 framesready -= written;
101 framesfree -= written;
102 framesptr += written * 4;
104 CallHookA(AudioCtrl->ahiac_PostTimerFunc, (Object*) AudioCtrl, 0);
110 FreeSignal( dd->slavesignal );
111 dd->slavesignal = -1;
113 Forbid();
115 // Tell the Master we're dying
117 Signal( (struct Task*) dd->mastertask, 1L << dd->mastersignal );
119 dd->slavetask = NULL;
121 // Multitaking will resume when we are dead.