2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
9 #include <proto/exec.h>
10 #include <proto/alib.h>
11 #include <proto/utility.h>
12 #include <proto/realtime.h>
13 #include <exec/lists.h>
14 #include "realtime_intern.h"
16 /*****************************************************************************
19 #include <libraries/realtime.h>
21 AROS_LH3(LONG
, SetConductorState
,
25 AROS_LHA(struct Player
*, player
, A0
),
26 AROS_LHA(ULONG
, state
, D0
),
27 AROS_LHA(LONG
, time
, D1
),
31 struct Library
*, RealTimeBase
, 10, RealTime
)
35 Changes the state of the conductor connected to a specified player.
36 The possible states are
43 other possible "states" are
45 CONDSTATE_METRIC -- Ask the highest priority conducted node to do a
47 CONDSTATE_SHUTTLE -- Inform the players that the clock value is
48 changing without the clock running
53 player -- The player in question
54 state -- The new state of the conductor
55 time -- Start time offset in realtime.library units
59 0 if OK, otherwise an error code. For now, these are RTE_PLAYING and
64 Going from CONDSTATE_PAUSED to CONDSTATE_RUNNING does not reset the
65 cdt_ClockTime of the conductor.
77 27.7.1999 SDuvan implemented parts
78 27.1.2001 SDuvan implemented the rest
80 ******************************************************************************/
85 struct pmState stateMsg
= { PM_STATE
, 0 };
86 struct pmTime timeMsg
= { 0 , time
};
87 struct Player
*pl
; /* For use in ForeachNode() */
88 struct Conductor
*conductor
= player
->pl_Source
;
90 if (conductor
== NULL
)
92 return RTE_NOCONDUCTOR
;
95 stateMsg
.pms_OldState
= conductor
->cdt_State
;
97 /* Don't report phony states */
100 ForeachNode(&conductor
->cdt_Players
, pl
)
102 /* Filter out QUIET players? */
103 if (pl
->pl_Hook
!= NULL
)
105 CallHookA(pl
->pl_Hook
, player
, &stateMsg
);
112 case CONDSTATE_PAUSED
:
114 /* Pause the clock */
115 conductor
->cdt_State
= CONDSTATE_PAUSED
;
116 conductor
->cdt_Flags
&= ~CONDUCTF_GOTTICK
;
120 case CONDSTATE_STOPPED
:
123 conductor
->cdt_State
= CONDSTATE_STOPPED
;
124 conductor
->cdt_Flags
&= ~CONDUCTF_GOTTICK
;
128 case CONDSTATE_LOCATE
:
132 conductor
->cdt_State
= CONDSTATE_LOCATE
;
134 ObtainSemaphore(&conductor
->cdt_Lock
);
135 oldSignals
= SetSignal(0, SIGF_SINGLE
);
136 conductor
->cdt_Barrier
= FindTask(NULL
);
137 ReleaseSemaphore(&conductor
->cdt_Lock
);
139 ForeachNode(&conductor
->cdt_Players
, pl
)
141 BOOL isReady
= FALSE
;
143 /* Barrier synchronization */
146 struct TagItem tags
[] = { { PLAYER_Ready
, (IPTR
)&isReady
},
147 { TAG_DONE
, (IPTR
)NULL
} };
149 GetPlayerAttrsA(pl
, tags
);
153 /* We are signalled by SetPlayerAttrs() if the tags
154 contain PLAYER_Ready '=' TRUE) */
160 ObtainSemaphore(&conductor
->cdt_Lock
);
161 conductor
->cdt_Barrier
= NULL
;
162 SetSignal(oldSignals
, SIGF_SINGLE
);
163 ReleaseSemaphore(&conductor
->cdt_Lock
);
166 /* Send PM_STATE message with CONDSTATE_LOCATE_SET here? */
170 case CONDSTATE_RUNNING
:
172 conductor
->cdt_ClockTime
= time
;
173 conductor
->cdt_State
= CONDSTATE_RUNNING
;
177 case CONDSTATE_METRIC
:
179 /* Get the highest priority musically aware player and let him
180 take care of the time location process. He will later call
181 SetConductorState() with state CONDSTATE_LOCATE to set the
182 time in realtime units calculated from his internal awareness
184 struct Player
*maestro
= NULL
;
186 ForeachNode(&conductor
->cdt_Players
,pl
)
188 if (pl
->pl_Flags
& PLAYERF_CONDUCTED
)
197 /* There is no defined error to return in this situation */
201 timeMsg
.pmt_Method
= PM_POSITION
;
202 CallHookA(maestro
->pl_Hook
, player
, &timeMsg
);
208 case CONDSTATE_SHUTTLE
:
209 /* Shuttling not allowed when playing */
210 if (conductor
->cdt_State
== CONDSTATE_RUNNING
)
215 conductor
->cdt_StartTime
= time
;
217 timeMsg
.pmt_Method
= PM_SHUTTLE
;
219 ForeachNode(&conductor
->cdt_Players
, pl
)
221 if (pl
->pl_Hook
!= NULL
)
223 CallHookA(pl
->pl_Hook
, player
, &timeMsg
);
230 return 0; /* Success */
233 } /* SetConductorState */