View Javadoc

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 }