1 package net.sf.jack4j;
2
3 /*
4 Copyright (C) 2008 Ondrej Par
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20 */
21
22 /**
23 * JackClient with additional transport-related methods.
24 *
25 * @author repa
26 *
27 */
28 public abstract class JackTransportClient extends JackClient {
29
30 public JackTransportClient(String clientName, boolean useExactName, boolean canStartServer, String serverName)
31 throws JackException {
32 super(clientName, useExactName, canStartServer, serverName);
33
34 populateCallbackStructure();
35 }
36
37 /**
38 * Starts the Jack transport.
39 */
40 public native void startTransport();
41
42 /**
43 * Stops the Jack transport.
44 */
45 public native void stopTransport();
46
47 /**
48 * Queries current state and position of Jack transport.
49 *
50 * <p>
51 * If the <code>position</code> parameter is not null, the given structure
52 * will be updated with the current positional information.
53 */
54 public native JackTransportState queryTransport(TransportPosition position);
55
56 /**
57 * Return an estimate of the current transport frame, including any time
58 * elapsed since the last transport positional update.
59 */
60 public native int getCurrentTransportFrame();
61
62 /**
63 * Reposition the transport to a new frame number.
64 *
65 * <p>
66 * May be May be called at any time by any client. The new position takes
67 * effect in two process cycles. If there are slow-sync clients and the
68 * transport is already rolling, it will enter the
69 * {@link JackTransportState#STARTING} state and begin invoking their
70 * synchronization callbacks until ready. This function is realtime-safe.
71 */
72 public native void locateTransport(int frame) throws JackException;
73
74 /**
75 * Request a new transport position.
76 *
77 * <p>
78 * May be May be called at any time by any client. The new position takes
79 * effect in two process cycles. If there are slow-sync clients and the
80 * transport is already rolling, it will enter the
81 * {@link JackTransportState#STARTING} state and begin invoking their
82 * synchronization callbacks until ready. This function is realtime-safe.
83 */
84 public native void repositionTransport(TransportPosition position) throws JackException;
85
86 /**
87 * Set the timeout value for slow-sync clients.
88 */
89 public native void setSyncTimeout(long microseconds) throws JackException;
90
91 /**
92 * Declares this client as a slow-sync client, using default callback.
93 *
94 * <p>
95 * Setting up a sync callback declares this client as a slow-sync client,
96 * one that cannot respond immediately to transport position changes.
97 *
98 * <p>
99 * After the default callback is set, the method
100 * {@link #syncCallback(JackTransportState, TransportPosition)} will be
101 * invoked accordingly to Jack synchronization rules (see the description of
102 * <code>syncCallback</code> method).
103 */
104 public native void setDefaultSyncCallback() throws JackException;
105
106 /**
107 * Declares this client as a slow-sync client, using default callback.
108 *
109 * <p>
110 * Setting up a sync callback declares this client as a slow-sync client,
111 * one that cannot respond immediately to transport position changes.
112 *
113 * <p>
114 * The <code>pointer</code> must be a native <code>JackSyncCallback</code>
115 * pointer, represented as <code>long</code>.
116 *
117 * @param pointer
118 * the pointer to native function
119 * @param arg
120 * the value passed as <code>void* arg</code> parameter to the
121 * callback
122 * @see #setDefaultSyncCallback()
123 */
124 public native void setSyncCallback(long pointer, long arg) throws JackException;
125
126 /**
127 * Declares that the client is not slow-sync anymore, and unregisters native
128 * sync callback.
129 *
130 * <p>
131 * After this method is called, the
132 * {@link #syncCallback(JackTransportState, TransportPosition)} method won't
133 * be called anymore.
134 */
135 public native void unsetSyncCallback() throws JackException;
136
137 /**
138 * Registers this client as timebase master for the Jack.
139 *
140 * <p>
141 * The timebase master registers a callback that updates extended position
142 * information such as beats or timecode whenever necessary. Without this
143 * extended information, there is no need for this function.
144 *
145 * <p>
146 * There is never more than one master at a time. When a new client takes
147 * over, the former timebase callback is no longer called. Taking over the
148 * timebase may be done conditionally, so it fails if there was a master
149 * already.
150 *
151 * @param conditional
152 * if true, the request is made conditionally, ie. if there
153 * already is a timebase master, the method does nothing
154 * @param pointer
155 * the pointer to native function
156 * @param arg
157 * the value passed as <code>void* arg</code> parameter to the
158 * callback
159 * @return true if the call was successful; false if conditional request was
160 * made and there's already timebase master.
161 * @see #setDefaultTimebaseCallback(boolean)
162 */
163 public native boolean setTimebaseCallback(boolean conditional, long pointer, long arg) throws JackException;
164
165 /**
166 * Registers this client as timebase master for the Jack, using default
167 * callback.
168 *
169 * <p>
170 * The timebase master registers a callback that updates extended position
171 * information such as beats or timecode whenever necessary. Without this
172 * extended information, there is no need for this function.
173 *
174 * <p>
175 * There is never more than one master at a time. When a new client takes
176 * over, the former timebase callback is no longer called. Taking over the
177 * timebase may be done conditionally, so it fails if there was a master
178 * already.
179 *
180 * <p>
181 * The default timebase callback invokes the method
182 * {@link #timebaseCallback(JackTransportState, int, TransportPosition, boolean)}
183 * of this client.
184 *
185 * @param conditional
186 * if true, the request is made conditionally, ie. if there
187 * already is a timebase master, the method does nothing
188 * @return true if the call was successful; false if conditional request was
189 * made and there's already timebase master.
190 */
191 public native boolean setDefaultTimebaseCallback(boolean conditional) throws JackException;
192
193 /**
194 * Releases this client from timebase master responsibility.
195 *
196 * <p>
197 * After this call, this Jack client is not timebase master anymore. The
198 * transport state keeps rolling if it was started, but no extended
199 * positional information will be available. The
200 * {@link #timebaseCallback(JackTransportState, int, TransportPosition, boolean)}
201 * will not be invoked anymore.
202 *
203 * @see #setDefaultTimebaseCallback(boolean)
204 */
205 public native void releaseTimebase() throws JackException;
206
207 /**
208 * Synchronization callback for slow-sync clients.
209 *
210 * <p>
211 * <b>The method is never invoked until the
212 * {@link #setDefaultSyncCallback()} is called.</b>
213 *
214 * <p>
215 * After the default slow-sync callback is set up, this method will be
216 * called during the next process cycle (if the client is active), or after
217 * the call to {@link JackClient#activate()} (if the client was previously
218 * inactive).
219 *
220 * <p>
221 * Then, the method is called again whenever the transport starts, and
222 * whenever some client requests new transport position.
223 *
224 * <p>
225 * The method must return boolean value that indicates whether the client is
226 * ready to roll.
227 *
228 * <p>
229 * <b>The <code>position</code> structure is only valid during the call.</b>
230 * If you need the positional information outside the callback, you can
231 * create a clone with {@link TransportPosition#clone()}.
232 *
233 * @param state
234 * current transport state
235 * @param position
236 * new transport position
237 * @return true if the client is ready, false otherwise.
238 */
239 public abstract boolean syncCallback(JackTransportState state, TransportPosition position);
240
241 /**
242 * Callback that provides extended position information to Jack transport.
243 *
244 * <p>
245 * This method is never invoked unless the
246 * {@link #setDefaultTimebaseCallback(boolean)} was successfully called.
247 *
248 * <p>
249 * This method is called immediately after <code>proces</code> callback in
250 * the same thread whenever the transport is rolling, or when any client has
251 * requested a new position in the previous cycle. The first cycle after the
252 * (default) native timebase callback was registered is also treated as a
253 * new position, or the first cycle after {@link #activate()} if the client
254 * had been inactive.
255 *
256 * <p>
257 * The method is responsible for setting extended position information into
258 * <code>pos</code> structure. The actual transport position can not be
259 * set using <code>frame</code> field of that structure; use
260 * {@link #locateTransport(int)} instead. <b>The <code>position</code>
261 * structure is only valid during the call.</b> If you need the positional
262 * information outside the callback, you can create a clone with
263 * {@link TransportPosition#clone()}.
264 *
265 * @param state
266 * current transport state
267 * @param nframes
268 * period length
269 * @param pos
270 * position structure for the <i>next</i> cycle; if newPos is
271 * false, the structure already contains extended positional
272 * information from current cycle
273 * @param newPos
274 * if true, new position was requested; in such case, pos
275 * structure doesn't contain valid extended information
276 */
277 public abstract void timebaseCallback(JackTransportState state, int nframes, TransportPosition pos, boolean newPos);
278
279 private native void populateCallbackStructure();
280 }