Compare commits
No commits in common. "05ec305a0435c046408a3b064cd1756e69ae8495" and "67f2f79961e052ee7c812d79a224daf6585ab63a" have entirely different histories.
05ec305a04
...
67f2f79961
|
@ -8,10 +8,11 @@ A [Nim] wrapper for the [JACK] [C API]
|
||||||
This software is in *alpha status* and has no official release yet.
|
This software is in *alpha status* and has no official release yet.
|
||||||
|
|
||||||
The majority of JACK client APIs have been wrapped and are functional (see
|
The majority of JACK client APIs have been wrapped and are functional (see
|
||||||
[examples]), but some APIs (e.g. threading) still need wrapping. Others, like
|
[examples]), but some APIs (e.g. threading and ringbuffers) still need
|
||||||
the server control or the deprecated session API, will probably not covered by
|
wrapping. Others, like the server control or the deprecated session API, will
|
||||||
these bindings. While this project is in alpha or beta stage, symbol names may
|
probably not covered by these bindings. While this project is in alpha or beta
|
||||||
still be changed and things moved around before the first public release.
|
stage, 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
|
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
|
from Nim procs and types to C functions and types, probably in the form of
|
||||||
|
|
14
TODO.md
14
TODO.md
|
@ -1,14 +0,0 @@
|
||||||
# TODO
|
|
||||||
|
|
||||||
## Threading API
|
|
||||||
|
|
||||||
Still needs to be wrapped. How to handle `jack_native_thread_t` type?
|
|
||||||
|
|
||||||
## Internal Clients
|
|
||||||
|
|
||||||
Jack 1 and JACK 2 are disagreeing on the signatures of the functions for
|
|
||||||
loading and getting a handles for internal clients:
|
|
||||||
|
|
||||||
* https://github.com/jackaudio/jack2/blob/develop/common/jack/intclient.h#L66
|
|
||||||
* https://github.com/jackaudio/headers/blob/2bfa5069718ca4f4dc091e0be845958f2d8a5ba8/intclient.h#L69
|
|
||||||
* https://jackaudio.org/api/intclient_8h.html#a176a2daf66c8777eb1a845068fd7a822
|
|
|
@ -1,6 +1,7 @@
|
||||||
import std/logging
|
import std/logging
|
||||||
import jacket
|
import jacket
|
||||||
|
|
||||||
|
var jclient: ClientP
|
||||||
var status: cint
|
var status: cint
|
||||||
var log = newConsoleLogger(when defined(release): lvlInfo else: lvlDebug)
|
var log = newConsoleLogger(when defined(release): lvlInfo else: lvlDebug)
|
||||||
|
|
||||||
|
@ -11,7 +12,7 @@ proc errorCb(msg: cstring) {.cdecl.} =
|
||||||
|
|
||||||
addHandler(log)
|
addHandler(log)
|
||||||
setErrorFunction(errorCb)
|
setErrorFunction(errorCb)
|
||||||
var jclient = clientOpen("jacket_info", NullOption.ord, status.addr)
|
jclient = clientOpen("jacket_info", NullOption.ord, status.addr)
|
||||||
debug "JACK server status: " & $status
|
debug "JACK server status: " & $status
|
||||||
|
|
||||||
if jclient == nil:
|
if jclient == nil:
|
||||||
|
@ -21,9 +22,9 @@ if jclient == nil:
|
||||||
echo("JACK version: ", getVersionString())
|
echo("JACK version: ", getVersionString())
|
||||||
echo("Sample rate: ", jclient.getSampleRate)
|
echo("Sample rate: ", jclient.getSampleRate)
|
||||||
echo("Buffer size: ", jclient.getBufferSize)
|
echo("Buffer size: ", jclient.getBufferSize)
|
||||||
echo("RT enabled: ", if jclient.isRealtime > 0: "yes" else: "no")
|
|
||||||
echo("DSP load: ", jclient.cpuLoad, "%")
|
echo("DSP load: ", jclient.cpuLoad, "%")
|
||||||
echo("Server time: ", getTime())
|
echo("Server time: ", getTime())
|
||||||
echo("Client name: ", jclient.getClientName)
|
echo("Client name: ", jclient.getClientName)
|
||||||
|
echo("RT enabled: ", if jclient.isRealtime > 0: "yes" else: "no")
|
||||||
|
|
||||||
discard jclient.clientClose
|
discard jclient.clientClose
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
import std/[logging, strformat]
|
|
||||||
import jacket
|
|
||||||
|
|
||||||
var log = newConsoleLogger(when defined(release): lvlInfo else: lvlDebug)
|
|
||||||
|
|
||||||
|
|
||||||
proc main() =
|
|
||||||
addHandler(log)
|
|
||||||
|
|
||||||
let size = 32
|
|
||||||
var read, written: int
|
|
||||||
var data = [0x64.uint8, 0x65, 0x61, 0x64, 0x62, 0x65, 0x65, 0x66]
|
|
||||||
var recvBuf: array[8, uint8]
|
|
||||||
|
|
||||||
let rb = ringbufferCreate(size.csize_t)
|
|
||||||
debug fmt"Created ringbuffer of {size} bytes size."
|
|
||||||
|
|
||||||
doAssert ringbufferReadSpace(rb) == 0
|
|
||||||
|
|
||||||
written = cast[int](ringbufferWrite(rb, cast[cstring](data.addr), 4))
|
|
||||||
doAssert written == 4
|
|
||||||
debug fmt"Written {written} bytes to ringbuffer."
|
|
||||||
|
|
||||||
doAssert ringbufferReadSpace(rb) == 4
|
|
||||||
|
|
||||||
written = cast[int](ringbufferWrite(rb, cast[cstring](data[4].addr), 4))
|
|
||||||
doAssert written == 4
|
|
||||||
debug fmt"Written {written} bytes to ringbuffer."
|
|
||||||
|
|
||||||
doAssert ringbufferReadSpace(rb) == 8
|
|
||||||
|
|
||||||
read = cast[int](ringbufferRead(rb, cast[cstring](recvBuf.addr), 4))
|
|
||||||
doAssert read == 4
|
|
||||||
debug fmt"Read {read} bytes from ringbuffer into receive buffer: {recvBuf}"
|
|
||||||
|
|
||||||
doAssert ringbufferReadSpace(rb) == 4
|
|
||||||
|
|
||||||
read = cast[int](ringbufferRead(rb, cast[cstring](recvBuf[4].addr), 4))
|
|
||||||
doAssert read == 4
|
|
||||||
debug fmt"Read {read} bytes from ringbuffer into receive buffer: {recvBuf}"
|
|
||||||
|
|
||||||
doAssert ringbufferReadSpace(rb) == 0
|
|
||||||
|
|
||||||
debug "Freeing ringbuffer memory."
|
|
||||||
ringbufferFree(rb)
|
|
||||||
|
|
||||||
|
|
||||||
when(isMainModule):
|
|
||||||
main()
|
|
|
@ -172,17 +172,6 @@ const
|
||||||
EXTENDED_TIME_INFO* = true
|
EXTENDED_TIME_INFO* = true
|
||||||
JACK_TICK_DOUBLE* = true
|
JACK_TICK_DOUBLE* = true
|
||||||
|
|
||||||
# Ringbuffer
|
|
||||||
|
|
||||||
type
|
|
||||||
RingbufferData* = object
|
|
||||||
buf*: ptr char
|
|
||||||
len*: csize_t
|
|
||||||
RingbufferDataP* = ptr RingbufferData
|
|
||||||
|
|
||||||
Ringbuffer = distinct object
|
|
||||||
RingbufferP* = ptr Ringbuffer
|
|
||||||
|
|
||||||
# Metadata
|
# Metadata
|
||||||
|
|
||||||
type
|
type
|
||||||
|
@ -302,22 +291,22 @@ jack_nframes_t jack_thread_wait (jack_client_t *client, int status)
|
||||||
# --------------------------- Internal Clients ----------------------------
|
# --------------------------- Internal Clients ----------------------------
|
||||||
|
|
||||||
# char *jack_get_internal_client_name (jack_client_t *client, jack_intclient_t intclient);
|
# char *jack_get_internal_client_name (jack_client_t *client, jack_intclient_t intclient);
|
||||||
proc getInternalClientName*(client: ClientP; intclient: IntClient): cstring {.
|
proc getInternalClientName(client: ClientP; intclient: IntClient): cstring {.
|
||||||
importc: "jack_get_internal_client_name".}
|
importc: "jack_get_internal_client_name".}
|
||||||
|
|
||||||
# jack_intclient_t jack_internal_client_handle (jack_client_t *client, const char *client_name,
|
# jack_intclient_t jack_internal_client_handle (jack_client_t *client, const char *client_name,
|
||||||
# jack_status_t *status)
|
# jack_status_t *status)
|
||||||
proc internalClientHandle*(client: ClientP; clientName: cstring; status: ptr cint): IntClient {.
|
proc internalClientHandle(client: ClientP; clientName: cstring; status: ptr cint): IntClient {.
|
||||||
importc: "jack_internal_client_handle".}
|
importc: "jack_internal_client_handle".}
|
||||||
|
|
||||||
# jack_intclient_t jack_internal_client_load (jack_client_t *client, const char *client_name,
|
# jack_intclient_t jack_internal_client_load (jack_client_t *client, const char *client_name,
|
||||||
# jack_options_t options, jack_status_t *status, ...)
|
# jack_options_t options, jack_status_t *status, ...)
|
||||||
proc internalClientLoad*(client: ClientP; clientName: cstring; options: cint; status: ptr cint): IntClient {.
|
proc internalClientLoad(client: ClientP; clientName: cstring; options: cint; status: ptr cint): IntClient {.
|
||||||
varargs, importc: "jack_internal_client_load".}
|
varargs, importc: "jack_internal_client_load".}
|
||||||
|
|
||||||
# jack_status_t jack_internal_client_unload (jack_client_t *client, jack_intclient_t intclient)
|
# jack_status_t jack_internal_client_unload (jack_client_t *client, jack_intclient_t intclient)
|
||||||
|
|
||||||
proc internalClientUnload*(client: ClientP; intclient: IntClient): cint {.
|
proc internalClientUnload(client: ClientP; intclient: IntClient): cint {.
|
||||||
importc: "jack_internal_client_unload".}
|
importc: "jack_internal_client_unload".}
|
||||||
|
|
||||||
#[ DEPRECATED
|
#[ DEPRECATED
|
||||||
|
@ -654,47 +643,6 @@ void jack_get_transport_info (jack_client_t *client, jack_transport_info_t *tinf
|
||||||
void jack_set_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)
|
||||||
]#
|
]#
|
||||||
|
|
||||||
# ----------------------------- Ringbuffers -------------------------------
|
|
||||||
|
|
||||||
# jack_ringbuffer_t *jack_ringbuffer_create (size_t sz)
|
|
||||||
proc ringbufferCreate*(sz: csize_t): RingbufferP {.importc: "jack_ringbuffer_create".}
|
|
||||||
|
|
||||||
# void jack_ringbuffer_free (jack_ringbuffer_t *rb)
|
|
||||||
proc ringbufferFree*(rb: RingbufferP) {.importc: "jack_ringbuffer_free".}
|
|
||||||
|
|
||||||
# void jack_ringbuffer_get_read_vector (const jack_ringbuffer_t *rb, jack_ringbuffer_data_t *vec)
|
|
||||||
proc ringbufferGetReadVector*(rb: RingbufferP, vec: var RingbufferDataP) {.importc: "jack_ringbuffer_get_read_vector".}
|
|
||||||
|
|
||||||
# void jack_ringbuffer_get_write_vector (const jack_ringbuffer_t *rb, jack_ringbuffer_data_t *vec)
|
|
||||||
proc ringbufferGetWriteVector*(rb: RingbufferP, vec: var RingbufferDataP) {.importc: "jack_ringbuffer_get_write_vector".}
|
|
||||||
|
|
||||||
# size_t jack_ringbuffer_read (jack_ringbuffer_t *rb, char *dest, size_t cnt)
|
|
||||||
proc ringbufferRead*(rb: RingbufferP, dest: cstring, cnt: csize_t): csize_t {.importc: "jack_ringbuffer_read".}
|
|
||||||
|
|
||||||
# size_t jack_ringbuffer_peek (jack_ringbuffer_t *rb, char *dest, size_t cnt)
|
|
||||||
proc ringbufferPeek*(rb: RingbufferP, dest: cstring, cnt: csize_t): csize_t {.importc: "jack_ringbuffer_peek".}
|
|
||||||
|
|
||||||
# void jack_ringbuffer_read_advance (jack_ringbuffer_t *rb, size_t cnt)
|
|
||||||
proc ringbufferReadAdvance*(rb: RingbufferP, cnt: csize_t) {.importc: "jack_ringbuffer_read_advance".}
|
|
||||||
|
|
||||||
# size_t jack_ringbuffer_read_space (const jack_ringbuffer_t *rb)
|
|
||||||
proc ringbufferReadSpace*(rb: RingbufferP): csize_t {.importc: "jack_ringbuffer_read_space".}
|
|
||||||
|
|
||||||
# int jack_ringbuffer_mlock (jack_ringbuffer_t *rb)
|
|
||||||
proc ringbufferMlock*(rb: RingbufferP): int {.importc: "jack_ringbuffer_mlock".}
|
|
||||||
|
|
||||||
# void jack_ringbuffer_reset (jack_ringbuffer_t *rb)
|
|
||||||
proc ringbufferReset*(rb: RingbufferP) {.importc: "jack_ringbuffer_reset".}
|
|
||||||
|
|
||||||
# size_t jack_ringbuffer_write (jack_ringbuffer_t *rb, const char *src, size_t cnt)
|
|
||||||
proc ringbufferWrite*(rb: RingbufferP, src: cstring, cnt: csize_t): csize_t {.importc: "jack_ringbuffer_write".}
|
|
||||||
|
|
||||||
# void jack_ringbuffer_write_advance (jack_ringbuffer_t *rb, size_t cnt)
|
|
||||||
proc ringbufferWriteAdvance*(rb: RingbufferP, cnt: csize_t) {.importc: "jack_ringbuffer_write_advance".}
|
|
||||||
|
|
||||||
# size_t jack_ringbuffer_write_space (const jack_ringbuffer_t *rb)
|
|
||||||
proc ringbufferWriteSpace*(rb: RingbufferP): csize_t {.importc: "jack_ringbuffer_write_space".}
|
|
||||||
|
|
||||||
# ------------------------------- Metadata --------------------------------
|
# ------------------------------- Metadata --------------------------------
|
||||||
|
|
||||||
# int jack_set_property (jack_client_t*, jack_uuid_t subject, const char* key, const char* value, const char* type)
|
# int jack_set_property (jack_client_t*, jack_uuid_t subject, const char* key, const char* value, const char* type)
|
||||||
|
|
|
@ -1,3 +1 @@
|
||||||
--path:"../src/"
|
--path:"../src/"
|
||||||
--warning[BareExcept]:off
|
|
||||||
--warning[UnusedImport]:off
|
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
import std/[re, strformat, unittest]
|
|
||||||
import jacket
|
|
||||||
|
|
||||||
suite "test version":
|
|
||||||
test "getVersion":
|
|
||||||
var major, minor, micro, proto: cint
|
|
||||||
getVersion(major.addr, minor.addr, micro.addr, proto.addr)
|
|
||||||
#echo fmt"{major}.{minor}.{micro} proto {proto}"
|
|
||||||
check:
|
|
||||||
# yes, the function simply returns 0 for all vars :-D
|
|
||||||
major == 0
|
|
||||||
minor == 0
|
|
||||||
micro == 0
|
|
||||||
proto == 0
|
|
||||||
test "getVersionString":
|
|
||||||
let version = getVersionString()
|
|
||||||
#echo $version
|
|
||||||
check:
|
|
||||||
$typeof(version) == "cstring"
|
|
||||||
match($version, re(r"\d+\.\d+\.\d+"))
|
|
Loading…
Reference in New Issue