Some Atom handling refactoring
Signed-off-by: Christopher Arndt <chris@chrisarndt.de>
This commit is contained in:
parent
d39cea5a98
commit
11c9fc653d
|
@ -29,7 +29,7 @@ proc instantiate(descriptor: ptr Lv2Descriptor; sampleRate: cdouble;
|
||||||
if amp.map == nil:
|
if amp.map == nil:
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
amp.midi_urid = amp.map[].map(amp.map[].handle, lv2MidiMidiEvent)
|
amp.midi_urid = amp.map.map(amp.map.handle, lv2MidiMidiEvent)
|
||||||
|
|
||||||
return cast[Lv2Handle](amp)
|
return cast[Lv2Handle](amp)
|
||||||
|
|
||||||
|
@ -56,17 +56,17 @@ proc run(instance: Lv2Handle; nSamples: cuint) {.cdecl.} =
|
||||||
atomSequenceClear(amp.output)
|
atomSequenceClear(amp.output)
|
||||||
amp.output.atom.type = amp.input.atom.type
|
amp.output.atom.type = amp.input.atom.type
|
||||||
|
|
||||||
if amp.input.atom.size > 8:
|
if not atomSequenceIsEmpty(amp.input):
|
||||||
#echo &"Event sequence size: {amp.input.atom.size}"
|
#echo &"Event sequence size: {amp.input.atom.size}"
|
||||||
|
let noteOffset = clamp(floor(amp.transposition[] + 0.5), -12, 12).uint8
|
||||||
|
|
||||||
for ev in items(amp.input):
|
for ev in amp.input:
|
||||||
if Urid(ev.body.`type`) == amp.midi_urid:
|
if ev.body.`type` == amp.midi_urid:
|
||||||
var msg = cast[ptr UncheckedArray[uint8]](atomContents(AtomEvent, ev))
|
var msg = cast[ptr UncheckedArray[uint8]](atomContents(AtomEvent, ev))
|
||||||
#echo &"0x{toHex(msg[0], 2)} 0x{toHex(msg[1], 2)} 0x{toHex(msg[2], 2)}"
|
#echo &"0x{toHex(msg[0], 2)} 0x{toHex(msg[1], 2)} 0x{toHex(msg[2], 2)}"
|
||||||
|
|
||||||
case midiGetMessageType(msg[]):
|
case midiGetMessageType(msg[]):
|
||||||
of midiMsgNoteOff, midiMsgNoteOn, midiMsgNotePressure:
|
of midiMsgNoteOff, midiMsgNoteOn, midiMsgNotePressure:
|
||||||
let noteOffset = clamp(floor(amp.transposition[] + 0.5), -12, 12).uint8
|
|
||||||
msg[1] = clamp(msg[1] + noteOffset, 0, 127).uint8
|
msg[1] = clamp(msg[1] + noteOffset, 0, 127).uint8
|
||||||
else:
|
else:
|
||||||
discard
|
discard
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
##
|
##
|
||||||
|
|
||||||
import ptrmath
|
import ptrmath
|
||||||
|
import urid
|
||||||
|
|
||||||
const
|
const
|
||||||
lv2AtomBaseUri ="http://lv2plug.in/ns/ext/atom"
|
lv2AtomBaseUri ="http://lv2plug.in/ns/ext/atom"
|
||||||
|
@ -64,7 +65,7 @@ type
|
||||||
## The header of an atom:Atom.
|
## The header of an atom:Atom.
|
||||||
Atom* {.bycopy.} = object
|
Atom* {.bycopy.} = object
|
||||||
size*: uint32 ## Size in bytes, not including type and size.
|
size*: uint32 ## Size in bytes, not including type and size.
|
||||||
`type`*: uint32 ## of this atom (mapped URI).
|
`type`*: Urid ## Type of this atom (mapped URI).
|
||||||
|
|
||||||
## An atom:Int or atom:Bool. May be cast to Atom.
|
## An atom:Int or atom:Bool. May be cast to Atom.
|
||||||
AtomInt* {.bycopy.} = object
|
AtomInt* {.bycopy.} = object
|
||||||
|
@ -92,7 +93,7 @@ type
|
||||||
## An atom:URID. May be cast to Atom.
|
## An atom:URID. May be cast to Atom.
|
||||||
AtomUrid* {.bycopy.} = object
|
AtomUrid* {.bycopy.} = object
|
||||||
atom*: Atom ## Atom header.
|
atom*: Atom ## Atom header.
|
||||||
body*: uint32 ## URID.
|
body*: Urid ## Urid.
|
||||||
|
|
||||||
## An atom:String. May be cast to Atom.
|
## An atom:String. May be cast to Atom.
|
||||||
AtomString* {.bycopy.} = object
|
AtomString* {.bycopy.} = object
|
||||||
|
@ -101,8 +102,8 @@ type
|
||||||
|
|
||||||
## The body of an atom:Literal.
|
## The body of an atom:Literal.
|
||||||
AtomLiteralBody* {.bycopy.} = object
|
AtomLiteralBody* {.bycopy.} = object
|
||||||
datatype*: uint32 ## DataURID.
|
datatype*: Urid ## Datatype Urid.
|
||||||
lang*: uint32 ## Language URID.
|
lang*: Urid ## Language Urid.
|
||||||
## Contents (a null-terminated UTF-8 string) follow here.
|
## Contents (a null-terminated UTF-8 string) follow here.
|
||||||
|
|
||||||
## An atom:Literal. May be cast to Atom.
|
## An atom:Literal. May be cast to Atom.
|
||||||
|
@ -128,8 +129,8 @@ type
|
||||||
|
|
||||||
## The body of an atom:Property (typically in an atom:Object).
|
## The body of an atom:Property (typically in an atom:Object).
|
||||||
AtomPropertyBody* {.bycopy.} = object
|
AtomPropertyBody* {.bycopy.} = object
|
||||||
key*: uint32 ## Key (predicate) (mapped URI).
|
key*: Urid ## Key (predicate) (mapped URI).
|
||||||
context*: uint32 ## Context URID (may be, and generally is, 0).
|
context*: Urid ## Context URID (may be, and generally is, 0).
|
||||||
value*: Atom ## Value atom header.
|
value*: Atom ## Value atom header.
|
||||||
## Value atom body follows here.
|
## Value atom body follows here.
|
||||||
|
|
||||||
|
@ -140,8 +141,8 @@ type
|
||||||
|
|
||||||
## The body of an atom:Object. May be cast to Atom.
|
## The body of an atom:Object. May be cast to Atom.
|
||||||
AtomObjectBody* {.bycopy.} = object
|
AtomObjectBody* {.bycopy.} = object
|
||||||
id*: uint32 ## URID, or 0 for blank.
|
id*: Urid ## Urid, or 0 for blank.
|
||||||
otype*: uint32 ## URID (same as rdf:type, for fast dispatch).
|
otype*: Urid ## Urid (same as rdf:type, for fast dispatch).
|
||||||
## Contents (a series of property bodies) follow here.
|
## Contents (a series of property bodies) follow here.
|
||||||
|
|
||||||
## An atom:Object. May be cast to Atom.
|
## An atom:Object. May be cast to Atom.
|
||||||
|
@ -176,7 +177,7 @@ type
|
||||||
## </pre>
|
## </pre>
|
||||||
##
|
##
|
||||||
AtomSequenceBody* {.bycopy.} = object
|
AtomSequenceBody* {.bycopy.} = object
|
||||||
unit*: uint32 ## URID of unit of event time stamps.
|
unit*: Urid ## Urid of unit of event time stamps.
|
||||||
pad*: uint32 ## Currently unused.
|
pad*: uint32 ## Currently unused.
|
||||||
## Contents (a series of events) follow here.
|
## Contents (a series of events) follow here.
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
from system/ansi_c import c_memcmp, c_memcpy
|
from system/ansi_c import c_memcmp, c_memcpy
|
||||||
import ../atom
|
import ../atom
|
||||||
import ../ptrmath
|
import ../ptrmath
|
||||||
|
import ../urid
|
||||||
|
|
||||||
##
|
##
|
||||||
## Pad a size to 64 bits.
|
## Pad a size to 64 bits.
|
||||||
|
@ -31,7 +32,7 @@ proc atomTotalSize*(atom: ptr Atom): uint32 {.inline.} =
|
||||||
## Return true iff `atom` is null.
|
## Return true iff `atom` is null.
|
||||||
##
|
##
|
||||||
proc atomIsNull*(atom: ptr Atom): bool {.inline.} =
|
proc atomIsNull*(atom: ptr Atom): bool {.inline.} =
|
||||||
return atom == nil or (atom.`type` == 0 and atom.size == 0)
|
return atom == nil or (atom.`type` == Urid(0) and atom.size == 0)
|
||||||
|
|
||||||
##
|
##
|
||||||
## Return true iff `a` is equal to `b`.
|
## Return true iff `a` is equal to `b`.
|
||||||
|
@ -46,31 +47,30 @@ proc atomEquals*(a: ptr Atom; b: ptr Atom): bool {.inline.} =
|
||||||
##
|
##
|
||||||
## Get an iterator pointing to the first event in a Sequence body.
|
## Get an iterator pointing to the first event in a Sequence body.
|
||||||
##
|
##
|
||||||
proc atomSequenceBegin*(body: ptr AtomSequenceBody): ptr AtomEvent {.inline.} =
|
template atomSequenceBegin*(body: ptr AtomSequenceBody): ptr AtomEvent =
|
||||||
return cast[ptr AtomEvent](body + 1)
|
cast[ptr AtomEvent](body + 1)
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
## Get an iterator pointing to the end of a Sequence body.
|
## Get an iterator pointing to the end of a Sequence body.
|
||||||
##
|
##
|
||||||
proc atomSequenceEnd*(body: ptr AtomSequenceBody; size: uint32): ptr AtomEvent {.inline.} =
|
template atomSequenceEnd*(body: ptr AtomSequenceBody; size: Natural): ptr AtomEvent =
|
||||||
return cast[ptr AtomEvent](cast[ptr uint8](body) + atomPadSize(size))
|
cast[ptr AtomEvent](cast[ptr uint8](body) + atomPadSize(size.uint32))
|
||||||
|
|
||||||
##
|
##
|
||||||
## Return true iff `i` has reached the end of `body`.
|
## Return true iff `i` has reached the end of `body`.
|
||||||
##
|
##
|
||||||
proc atomSequenceIsEnd*(body: ptr AtomSequenceBody; size: Natural; i: ptr AtomEvent): bool {.inline.} =
|
template atomSequenceIsEnd*(body: ptr AtomSequenceBody; size: Natural; i: ptr AtomEvent): bool =
|
||||||
return cast[ptr uint8](i) >= (cast[ptr uint8](body) + size.uint)
|
cast[ptr uint8](i) >= (cast[ptr uint8](body) + size.uint)
|
||||||
|
|
||||||
##
|
##
|
||||||
## Return an iterator to the element following `i`.
|
## Return an iterator to the element following `i`.
|
||||||
##
|
##
|
||||||
proc atomSequenceNext*(i: ptr AtomEvent): ptr AtomEvent {.inline.} =
|
template atomSequenceNext*(i: ptr AtomEvent): ptr AtomEvent =
|
||||||
return cast[ptr AtomEvent](cast[ptr uint8](i) + sizeof(AtomEvent) + atomPadSize(i.body.size))
|
cast[ptr AtomEvent](cast[ptr uint8](i) + sizeof(AtomEvent) + atomPadSize(i.body.size))
|
||||||
|
|
||||||
##
|
##
|
||||||
## An iterator for looping over all events in a Sequence.
|
## An iterator for looping over all events in an AtomSequence.
|
||||||
## @param seq The sequence to iterate over
|
## @param seq Pointer to the sequence to iterate over
|
||||||
##
|
##
|
||||||
iterator items*(seq: ptr AtomSequence): ptr AtomEvent {.inline.} =
|
iterator items*(seq: ptr AtomSequence): ptr AtomEvent {.inline.} =
|
||||||
var event = atomSequenceBegin(seq.body.addr)
|
var event = atomSequenceBegin(seq.body.addr)
|
||||||
|
@ -78,11 +78,28 @@ iterator items*(seq: ptr AtomSequence): ptr AtomEvent {.inline.} =
|
||||||
yield event
|
yield event
|
||||||
event = atomSequenceNext(event)
|
event = atomSequenceNext(event)
|
||||||
|
|
||||||
## TODO: Like LV2_ATOM_SEQUENCE_FOREACH but for a headerless sequence body.
|
##
|
||||||
|
## An iterator for looping over all events in an AtomSequenceBody.
|
||||||
|
## @param body Pointer to the sequence body to iterate over
|
||||||
|
## @param size Size in bytes of the sequence body (including the 8 bytes of AtomSequenceBody)
|
||||||
|
##
|
||||||
|
iterator items*(body: ptr AtomSequenceBody, size: Natural): ptr AtomEvent {.inline.} =
|
||||||
|
var event = atomSequenceBegin(body)
|
||||||
|
while not atomSequenceIsEnd(body, size, event):
|
||||||
|
yield event
|
||||||
|
event = atomSequenceNext(event)
|
||||||
|
|
||||||
##
|
##
|
||||||
## Sequence Utilities
|
## Sequence Utilities
|
||||||
##
|
##
|
||||||
|
|
||||||
|
##
|
||||||
|
## Test if AtomSequence is empty, i.e the body has no events
|
||||||
|
##
|
||||||
|
template atomSequenceIsEmpty*(seq: ptr AtomSequence): bool =
|
||||||
|
seq.atom.size == sizeof(AtomSequenceBody).uint32
|
||||||
|
|
||||||
|
##
|
||||||
## Clear all events from `sequence`.
|
## Clear all events from `sequence`.
|
||||||
##
|
##
|
||||||
## This simply resets the size field, the other fields are left untouched.
|
## This simply resets the size field, the other fields are left untouched.
|
||||||
|
@ -118,48 +135,60 @@ proc atomSequenceAppendEvent*(seq: ptr AtomSequence; capacity: uint32;
|
||||||
##
|
##
|
||||||
## Get an iterator pointing to the first element in `tup`.
|
## Get an iterator pointing to the first element in `tup`.
|
||||||
##
|
##
|
||||||
proc atomTupleBegin*(tup: ptr AtomTuple): ptr Atom {.inline.} =
|
template atomTupleBegin*(tup: ptr AtomTuple): ptr Atom =
|
||||||
return cast[ptr Atom](atomContents(Atom, tup))
|
cast[ptr Atom](atomContents(Atom, tup))
|
||||||
|
|
||||||
##
|
##
|
||||||
## Return true iff `i` has reached the end of `body`.
|
## Return true iff `i` has reached the end of `body`.
|
||||||
##
|
##
|
||||||
proc atomTupleIsEnd*(body: pointer; size: Natural; i: ptr Atom): bool {.inline.} =
|
template atomTupleIsEnd*(body: pointer; size: Natural; i: ptr Atom): bool =
|
||||||
return cast[ptr uint8](i) >= (cast[ptr uint8](body) + size.int)
|
cast[ptr uint8](i) >= (cast[ptr uint8](body) + size.uint)
|
||||||
|
|
||||||
##
|
##
|
||||||
## Return an iterator to the element following `i`.
|
## Return an iterator to the element following `i`.
|
||||||
##
|
##
|
||||||
proc atomTupleNext*(i: ptr Atom): ptr Atom {.inline.} =
|
template atomTupleNext*(i: ptr Atom): ptr Atom =
|
||||||
return cast[ptr Atom](cast[ptr uint8](i) + sizeof(Atom) + atomPadSize(i.size))
|
cast[ptr Atom](cast[ptr uint8](i) + sizeof(Atom) + atomPadSize(i.size))
|
||||||
|
|
||||||
|
|
||||||
## TODO:
|
|
||||||
##
|
##
|
||||||
## A iterator for looping over all properties of a Tuple.
|
## An iterator for looping over all elements of an AtomTuple.
|
||||||
## @param tuple The tuple to iterate over
|
## @param tuple Pointer to the tuple to iterate over
|
||||||
|
##
|
||||||
|
iterator items*(tup: ptr AtomTuple): ptr Atom {.inline.} =
|
||||||
|
var atom = atomTupleBegin(tup)
|
||||||
|
while not atomTupleIsEnd(atomBody(tup), tup.atom.size, atom):
|
||||||
|
yield atom
|
||||||
|
atom = atomTupleNext(atom)
|
||||||
|
|
||||||
## TODO:
|
##
|
||||||
## Like LV2_ATOM_TUPLE_FOREACH but for a headerless tuple body.
|
## An iterator for looping over all elements of a headerless tuple.
|
||||||
|
## @param tuple Pointer to the first Atom of the tuple to iterate over
|
||||||
|
## @param size Size in bytes of the tuple body
|
||||||
|
##
|
||||||
|
iterator items*(tup: ptr Atom, size: Natural): ptr Atom {.inline.} =
|
||||||
|
var atom = tup
|
||||||
|
while not atomTupleIsEnd(tup, size, atom):
|
||||||
|
yield atom
|
||||||
|
atom = atomTupleNext(atom)
|
||||||
|
|
||||||
##
|
##
|
||||||
## Object Iterator
|
## Object Iterator
|
||||||
##
|
##
|
||||||
## Return a pointer to the first property in `body`.
|
## Return a pointer to the first property in `body`.
|
||||||
##
|
##
|
||||||
proc atomObjectBegin*(body: ptr AtomObjectBody): ptr AtomPropertyBody {.inline.} =
|
template atomObjectBegin*(body: ptr AtomObjectBody): ptr AtomPropertyBody =
|
||||||
return cast[ptr AtomPropertyBody](body + 1)
|
cast[ptr AtomPropertyBody](body + 1)
|
||||||
|
|
||||||
##
|
##
|
||||||
## Return true iff `i` has reached the end of `obj`.
|
## Return true iff `i` has reached the end of `obj`.
|
||||||
##
|
##
|
||||||
proc atomObjectIsEnd*(body: ptr AtomObjectBody; size: Natural; i: ptr AtomPropertyBody): bool {.inline.} =
|
template atomObjectIsEnd*(body: ptr AtomObjectBody; size: Natural; i: ptr AtomPropertyBody): bool =
|
||||||
return cast[ptr uint8](i) >= (cast[ptr uint8](body) + size.int)
|
cast[ptr uint8](i) >= (cast[ptr uint8](body) + size.uint)
|
||||||
|
|
||||||
##
|
##
|
||||||
## Return an iterator to the property following `i`.
|
## Return an iterator to the property following `i`.
|
||||||
##
|
##
|
||||||
proc atomObjectNext*(i: ptr AtomPropertyBody): ptr AtomPropertyBody {.inline.} =
|
template atomObjectNext*(i: ptr AtomPropertyBody): ptr AtomPropertyBody =
|
||||||
let value = cast[ptr Atom](cast[ptr uint8](i) + 2 * sizeof(uint32))
|
let value = cast[ptr Atom](cast[ptr uint8](i) + 2 * sizeof(uint32))
|
||||||
return cast[ptr AtomPropertyBody](cast[ptr uint8](i) + atomPadSize(sizeof(AtomPropertyBody).uint32 + value.size))
|
return cast[ptr AtomPropertyBody](cast[ptr uint8](i) + atomPadSize(sizeof(AtomPropertyBody).uint32 + value.size))
|
||||||
|
|
||||||
|
|
|
@ -14,25 +14,26 @@ const
|
||||||
lv2UridMap* = lv2UridPrefix & "map"
|
lv2UridMap* = lv2UridPrefix & "map"
|
||||||
lv2UridUnmap* = lv2UridPrefix & "unmap"
|
lv2UridUnmap* = lv2UridPrefix & "unmap"
|
||||||
|
|
||||||
|
type
|
||||||
|
##
|
||||||
|
## URI mapped to an integer.
|
||||||
|
##
|
||||||
|
Urid* = distinct uint32
|
||||||
|
|
||||||
##
|
##
|
||||||
## Opaque pointer to host data for UridMap.
|
## Opaque pointer to host data for UridMap.
|
||||||
##
|
##
|
||||||
type UridMapHandle* = pointer
|
UridMapHandle* = pointer
|
||||||
|
|
||||||
##
|
##
|
||||||
## Opaque pointer to host data for uridUnmap.
|
## Opaque pointer to host data for uridUnmap.
|
||||||
##
|
##
|
||||||
type UridUnmapHandle* = pointer
|
UridUnmapHandle* = pointer
|
||||||
|
|
||||||
##
|
|
||||||
## URI mapped to an integer.
|
|
||||||
##
|
|
||||||
type Urid* = distinct uint32
|
|
||||||
|
|
||||||
##
|
##
|
||||||
## URID Map Feature (lv2UridMap)
|
## URID Map Feature (lv2UridMap)
|
||||||
##
|
##
|
||||||
type UridMap* {.bycopy.} = object
|
UridMap* {.bycopy.} = object
|
||||||
##
|
##
|
||||||
## Opaque pointer to host data.
|
## Opaque pointer to host data.
|
||||||
##
|
##
|
||||||
|
@ -66,7 +67,7 @@ type UridMap* {.bycopy.} = object
|
||||||
##
|
##
|
||||||
## URI Unmap Feature (lv2UridUnmap)
|
## URI Unmap Feature (lv2UridUnmap)
|
||||||
##
|
##
|
||||||
type UridUnmap* {.bycopy.} = object
|
UridUnmap* {.bycopy.} = object
|
||||||
##
|
##
|
||||||
## Opaque pointer to host data.
|
## Opaque pointer to host data.
|
||||||
##
|
##
|
||||||
|
|
Loading…
Reference in New Issue