From bff6f5e9fad71a898ba9c7e4f297a4768a611e50 Mon Sep 17 00:00:00 2001 From: Christopher Arndt Date: Wed, 24 May 2023 10:58:59 +0200 Subject: [PATCH] feat: wrap ringbuffer API and add usage example Signed-off-by: Christopher Arndt --- README.md | 9 +++--- examples/jacket_ringbuffer.nim | 49 ++++++++++++++++++++++++++++++++ src/jacket.nim | 52 ++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 5 deletions(-) create mode 100644 examples/jacket_ringbuffer.nim diff --git a/README.md b/README.md index 6d7a825..4e49390 100644 --- a/README.md +++ b/README.md @@ -8,11 +8,10 @@ A [Nim] wrapper for the [JACK] [C API] 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 -[examples]), but some APIs (e.g. threading and ringbuffers) still need -wrapping. Others, like the server control or the deprecated session API, will -probably not covered by these bindings. While this project is in alpha or beta -stage, symbol names may still be changed and things moved around before the -first public release. +[examples]), but some APIs (e.g. threading) still need wrapping. Others, like +the server control or the deprecated session API, will probably not covered by +these bindings. While this project is in alpha or beta 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 from Nim procs and types to C functions and types, probably in the form of diff --git a/examples/jacket_ringbuffer.nim b/examples/jacket_ringbuffer.nim new file mode 100644 index 0000000..9018ea1 --- /dev/null +++ b/examples/jacket_ringbuffer.nim @@ -0,0 +1,49 @@ +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() diff --git a/src/jacket.nim b/src/jacket.nim index 924882a..4bf74fe 100644 --- a/src/jacket.nim +++ b/src/jacket.nim @@ -172,6 +172,17 @@ const EXTENDED_TIME_INFO* = 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 type @@ -643,6 +654,47 @@ 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) ]# +# ----------------------------- 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 -------------------------------- # int jack_set_property (jack_client_t*, jack_uuid_t subject, const char* key, const char* value, const char* type)