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 }