Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 87 additions & 5 deletions jack.py
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,20 @@ def transport_stop(self):
"""Stop JACK transport."""
_lib.jack_transport_stop(self._ptr)

@property
def transport_state(self):
"""JACK transport state.

This is one of :attr:`STOPPED`, :attr:`ROLLING`,
:attr:`STARTING`, :attr:`NETSTARTING`.

See Also
--------
transport_query

"""
return TransportState(_lib.jack_transport_query(self._ptr, _ffi.NULL))

def transport_locate(self, frame):
"""Reposition the JACK transport to a new frame number.

Expand All @@ -691,6 +705,46 @@ def transport_locate(self, frame):
def transport_query(self):
"""Query the current transport state and position.

This is a convenience function that does the same as
:meth:`transport_query_struct` but it only returns the valid
fields in an easy-to-use ``dict``.

Returns
-------
state : TransportState
The transport state can take following values:
:attr:`STOPPED`, :attr:`ROLLING`, :attr:`STARTING` and
:attr:`NETSTARTING`.
position : dict
A dictionary containing only the valid fields of the
structure returned by :meth:`transport_query_struct`.

See Also
--------
:attr:`transport_state`

"""
state, pos = self.transport_query_struct()
assert pos.unique_1 == pos.unique_2

keys = ['usecs', 'frame_rate', 'frame']
if pos.valid & _lib.JackPositionBBT:
keys += ['bar', 'beat', 'tick', 'bar_start_tick', 'beats_per_bar',
'beat_type', 'ticks_per_beat', 'beats_per_minute']
if pos.valid & _lib.JackPositionTimecode:
keys += ['frame_time', 'next_time']
if pos.valid & _lib.JackBBTFrameOffset:
keys += ['bbt_offset']
if pos.valid & _lib.JackAudioVideoRatio:
keys += ['audio_frames_per_video_frame']
if pos.valid & _lib.JackVideoFrameOffset:
keys += ['video_offset']

return TransportState(state), dict((k, getattr(pos, k)) for k in keys)

def transport_query_struct(self):
"""Query the current transport state and position.

This function is realtime-safe, and can be called from any
thread. If called from the process thread, the returned
position corresponds to the first frame of the current cycle and
Expand All @@ -708,6 +762,10 @@ def transport_query(self):

__ http://jackaudio.org/files/docs/html/structjack__position__t.html

See Also
--------
transport_query

"""
state = _lib.jack_transport_query(self._ptr, self._position)
return state, self._position
Expand Down Expand Up @@ -2160,9 +2218,13 @@ def redirected(self, *args):

names = set(['__gt__', '__ge__'])
names.update(numbers.Integral.__abstractmethods__)
methods = dict((name, redirect(name)) for name in names)
methods.update({'__eq__': lambda self, other: int(self) == other})
return type("_StatusBase", (), methods)
namespace = dict((name, redirect(name)) for name in names)
namespace.update({
'__slots__': '_code',
'__init__': lambda self, code: setattr(self, '_code', code),
'__eq__': lambda self, other: int(self) == other,
})
return type("_StatusBase", (), namespace)

_StatusBase = _make_statusbase()
del _make_statusbase
Expand All @@ -2172,8 +2234,7 @@ class Status(_StatusBase):

"""Representation of the JACK status bits."""

def __init__(self, statuscode):
self._code = statuscode
__slots__ = ()

def __repr__(self):
flags = ", ".join(name for name in dir(self)
Expand Down Expand Up @@ -2266,6 +2327,27 @@ def _hasflag(self, flag):
return bool(self & flag)


class TransportState(_StatusBase):

"""Representation of the JACK transport state.

See Also
--------
:attr:`Client.transport_state`, :meth:`Client.transport_query`

"""

__slots__ = ()

def __repr__(self):
return "jack." + {
_lib.JackTransportStopped: 'STOPPED',
_lib.JackTransportRolling: 'ROLLING',
_lib.JackTransportStarting: 'STARTING',
_lib.JackTransportNetStarting: 'NETSTARTING',
}[int(self)]


class JackError(Exception):

"""Exception for all kinds of JACK-related errors."""
Expand Down