feat: wrap transport API and add transport query example
Signed-off-by: Christopher Arndt <chris@chrisarndt.de>
This commit is contained in:
parent
ada9b13857
commit
2d8533d122
|
@ -7,10 +7,10 @@ A [Nim] wrapper for the [JACK] [C API]
|
|||
|
||||
This software is in *alpha status* and has no official release yet.
|
||||
|
||||
The basic JACK APIs (client lifecycle, ports, callbacks) have been wrapped and
|
||||
are functional (see [examples]), but latency, transport and meta-data APIs still
|
||||
need wrapping. Also, symbol names may still be changed and things moved around
|
||||
before the first public release.
|
||||
The basic JACK APIs (client lifecycle, ports, callbacks, MIDI, transport) have
|
||||
been wrapped and are functional (see [examples]), but latency, threading and
|
||||
meta-data APIs still need wrapping. Also, symbol names may still be changed
|
||||
and things moved around before the first public release.
|
||||
|
||||
Also, I plan to add a higher-level abstraction on top of the direct mapping
|
||||
from Nim procs and types to C functions and types, probably in the form of
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
import std/[logging, strformat]
|
||||
import jacket
|
||||
|
||||
var
|
||||
jclient: ClientP
|
||||
status: cint
|
||||
pos: Position
|
||||
transportState: TransportState
|
||||
|
||||
var log = newConsoleLogger(when defined(release): lvlInfo else: lvlDebug)
|
||||
|
||||
proc errorCb(msg: cstring) {.cdecl.} =
|
||||
# Suppress verbose JACK error messages when server is not available by
|
||||
# default. Pass ``lvlAll`` when creating the logger to enable them.
|
||||
debug "JACK error: " & $msg
|
||||
|
||||
addHandler(log)
|
||||
setErrorFunction(errorCb)
|
||||
jclient = clientOpen("jacket_info", NullOption.ord, status.addr)
|
||||
debug "JACK server status: " & $status
|
||||
|
||||
if jclient == nil:
|
||||
error getJackStatusErrorString(status)
|
||||
quit 1
|
||||
|
||||
transportState = transportQuery(jclient, pos.addr)
|
||||
|
||||
echo fmt"usecs: {pos.usecs}"
|
||||
echo fmt"frameRate: {pos.frameRate}"
|
||||
echo fmt"frame: {pos.frame}"
|
||||
echo fmt"valid: {pos.valid.ord}"
|
||||
|
||||
if bool(pos.valid.ord and PositionBBT.ord):
|
||||
echo fmt"bar: {pos.bar}"
|
||||
echo fmt"beat: {pos.beat}"
|
||||
echo fmt"tick: {pos.tick}"
|
||||
echo fmt"barStartTick: {pos.barStartTick}"
|
||||
echo fmt"beatsPerBar: {pos.beatsPerBar}"
|
||||
echo fmt"beatType: {pos.beatType}"
|
||||
echo fmt"beatsPerMinute: {pos.beatsPerMinute}"
|
||||
|
||||
case transportState
|
||||
of TransportStopped:
|
||||
echo "JACK transport stopped, starting it now."
|
||||
transportStart(jclient)
|
||||
of TransportRolling:
|
||||
echo "JACK transport rolling, stopping it now."
|
||||
transportStop(jclient)
|
||||
of TransportStarting:
|
||||
echo "JACK transport starting, nothing to do."
|
||||
else:
|
||||
echo "Unknown JACK transport state."
|
||||
|
||||
discard jclient.clientClose
|
127
src/jacket.nim
127
src/jacket.nim
|
@ -89,7 +89,86 @@ type
|
|||
CaptureLatency,
|
||||
PlaybackLatency
|
||||
|
||||
# Transport
|
||||
|
||||
type
|
||||
PositionBits* {.size: sizeof(cint).} = enum
|
||||
PositionBBT = 0x10,
|
||||
PositionTimecode = 0x20,
|
||||
BBTFrameOffset = 0x40,
|
||||
AudioVideoRatio = 0x80,
|
||||
VideoFrameOffset = 0x100,
|
||||
TickDouble = 0x200
|
||||
|
||||
TransportState* {.size: sizeof(cint).} = enum
|
||||
TransportStopped = 0,
|
||||
TransportRolling = 1,
|
||||
TransportLooping = 2,
|
||||
TransportStarting = 3,
|
||||
TransportNetStarting = 4
|
||||
|
||||
type
|
||||
Position* = object
|
||||
unique1*: uint64
|
||||
usecs*: Time
|
||||
frameRate*: NFrames
|
||||
frame*: NFrames
|
||||
valid*: PositionBits
|
||||
bar*: int32
|
||||
beat*: int32
|
||||
tick*: int32
|
||||
barStartTick*: cdouble
|
||||
beatsPerBar*: cfloat
|
||||
beatType*: cfloat
|
||||
ticksPerBeat*: cdouble
|
||||
beatsPerMinute*: cdouble
|
||||
frameTime*: cdouble
|
||||
nextTime*: cdouble
|
||||
bbtOffset*: NFrames
|
||||
audioFramesPerVideoFrame*: cfloat
|
||||
videoOffset*: NFrames
|
||||
tickDouble*: cdouble
|
||||
padding*: array[5, int32]
|
||||
unique2*: uint64
|
||||
PositionP* = ptr Position
|
||||
|
||||
#[ DEPRECATED
|
||||
typedef enum {
|
||||
JackTransportState = 0x1,
|
||||
JackTransportPosition = 0x2,
|
||||
JackTransportLoop = 0x4,
|
||||
JackTransportSMPTE = 0x8,
|
||||
JackTransportBBT = 0x10
|
||||
} jack_transport_bits_t;
|
||||
|
||||
typedef struct {
|
||||
jack_nframes_t frame_rate;
|
||||
jack_time_t usecs;
|
||||
jack_transport_bits_t valid;
|
||||
jack_transport_state_t transport_state;
|
||||
jack_nframes_t frame;
|
||||
jack_nframes_t loop_start;
|
||||
jack_nframes_t loop_end;
|
||||
long smpte_offset
|
||||
float smpte_frame_rate;
|
||||
int bar;
|
||||
int beat;
|
||||
int tick;
|
||||
double bar_start_tick;
|
||||
float beats_per_bar;
|
||||
float beat_type;
|
||||
double ticks_per_beat;
|
||||
double beats_per_minute;
|
||||
} jack_transport_info_t;
|
||||
]#
|
||||
|
||||
const
|
||||
JACK_POSITION_MASK* = (PositionBBT.ord or PositionTimecode.ord)
|
||||
EXTENDED_TIME_INFO* = true
|
||||
JACK_TICK_DOUBLE* = true
|
||||
|
||||
# Callback function types
|
||||
|
||||
type
|
||||
JackProcessCallback* = proc (nframes: NFrames; arg: pointer): cint {.cdecl.}
|
||||
JackThreadCallback* = proc (arg: pointer): pointer {.cdecl.}
|
||||
|
@ -109,6 +188,10 @@ type
|
|||
JackInfoCallback* = proc (msg: cstring) {.cdecl.}
|
||||
JackErrorCallback* = proc (msg: cstring) {.cdecl.}
|
||||
|
||||
JackSyncCallback* = proc (state: TransportState; pos: ptr Position; arg: pointer): cint {.cdecl.}
|
||||
JackTimebaseCallback* = proc (state: TransportState; nframes: NFrames; pos: ptr Position; newPos: cint;
|
||||
arg: pointer) {.cdecl.}
|
||||
|
||||
|
||||
# ----------------------------- Version info ------------------------------
|
||||
|
||||
|
@ -476,6 +559,50 @@ proc timeToFrames*(client: ClientP; time: Time): NFrames {.importc: "jack_time_t
|
|||
# jack_time_t jack_get_time(void)
|
||||
proc getTime*(): Time {.importc: "jack_get_time".}
|
||||
|
||||
|
||||
# ------------------------------- Transport -------------------------------
|
||||
|
||||
# int jack_release_timebase (jack_client_t *client)
|
||||
proc releaseTimebase*(client: ClientP): cint {.importc: "jack_release_timebase".}
|
||||
|
||||
# int jack_set_sync_callback (jack_client_t *client, JackSyncCallback sync_callback, void *arg)
|
||||
proc setSyncCallback*(client: ClientP; syncCallback: JackSyncCallback; arg: pointer): cint {.
|
||||
importc: "jack_set_sync_callback".}
|
||||
|
||||
# int jack_set_sync_timeout (jack_client_t *client, jack_time_t timeout)
|
||||
proc setSyncTimeout*(client: ClientP; timeout: Time): cint {.importc: "jack_set_sync_timeout".}
|
||||
|
||||
# int jack_set_timebase_callback (jack_client_t *client,
|
||||
# int conditional,
|
||||
# JackTimebaseCallback timebase_callback,
|
||||
# void *arg)
|
||||
proc setTimebaseCallback*(client: ClientP; conditional: cint; timebaseCallback: JackTimebaseCallback;
|
||||
arg: pointer): cint {.
|
||||
importc: "jack_set_timebase_callback".}
|
||||
|
||||
# int jack_transport_locate (jack_client_t *client, jack_nframes_t frame)
|
||||
proc transportLocate*(client: ClientP; frame: NFrames): cint {.importc: "jack_transport_locate".}
|
||||
|
||||
# jack_transport_state_t jack_transport_query (const jack_client_t *client, jack_position_t *pos)
|
||||
proc transportQuery*(client: ClientP; pos: PositionP): TransportState {.importc: "jack_transport_query".}
|
||||
|
||||
# jack_nframes_t jack_get_current_transport_frame (const jack_client_t *client)
|
||||
proc getCurrentTransportFrame*(client: ClientP): NFrames {.importc: "jack_get_current_transport_frame".}
|
||||
|
||||
# int jack_transport_reposition (jack_client_t *client, const jack_position_t *pos)
|
||||
proc transportReposition*(client: ClientP; pos: PositionP): cint {.importc: "jack_transport_reposition".}
|
||||
|
||||
# void jack_transport_start (jack_client_t *client)
|
||||
proc transportStart*(client: ClientP) {.importc: "jack_transport_start".}
|
||||
|
||||
# void jack_transport_stop (jack_client_t *client)
|
||||
proc transportStop*(client: ClientP) {.importc: "jack_transport_stop".}
|
||||
|
||||
#[ DEPRECATED
|
||||
void jack_get_transport_info (jack_client_t *client, jack_transport_info_t *tinfo)
|
||||
void jack_set_transport_info (jack_client_t *client, jack_transport_info_t *tinfo)
|
||||
]#
|
||||
|
||||
# ---------------------------- Error handling -----------------------------
|
||||
|
||||
proc setErrorFunction*(errorCallback: JackErrorCallback) {.importc: "jack_set_error_function".}
|
||||
|
|
Loading…
Reference in New Issue