feat: wrap ringbuffer API and add usage example
Signed-off-by: Christopher Arndt <chris@chrisarndt.de>
This commit is contained in:
		
							parent
							
								
									6112afad73
								
							
						
					
					
						commit
						bff6f5e9fa
					
				@ -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
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										49
									
								
								examples/jacket_ringbuffer.nim
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								examples/jacket_ringbuffer.nim
									
									
									
									
									
										Normal file
									
								
							@ -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()
 | 
			
		||||
@ -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)
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user