Mercurial > hg > beaglert
diff projects/heavy/envelopeTrigger/HvMessage.h @ 162:c3e8226a5651 heavy-updated
- added additional flags to C rules (-DNDEBUG, -mfpu=neon)
- sample-accurate envelope triggering pd/heavy example
author | chnrx <chris.heinrichs@gmail.com> |
---|---|
date | Thu, 12 Nov 2015 14:59:46 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/projects/heavy/envelopeTrigger/HvMessage.h Thu Nov 12 14:59:46 2015 +0000 @@ -0,0 +1,188 @@ +/** + * Copyright (c) 2014, 2015, Enzien Audio Ltd. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _HEAVY_MESSAGE_H_ +#define _HEAVY_MESSAGE_H_ + +#include "Utils.h" + +typedef enum ElementType { + BANG, + FLOAT, + SYMBOL, + HASH +} ElementType; + +typedef struct Element { + ElementType type; + union { + float f; // float + char *s; // symbol + hv_uint32_t h; // hash + } data; +} Element; + +typedef struct HvMessage { + hv_uint32_t timestamp; // the sample at which this message should be processed + hv_uint16_t numElements; + hv_uint16_t numBytes; // the number of bytes that this message occupies in memory + Element elem; +} HvMessage; + +#define HV_MESSAGE_ON_STACK(_x) (HvMessage *) hv_alloca(msg_getByteSize(_x)) + +/** Returns the total length in bytes of this message for a given number of elements. */ +static inline hv_size_t msg_getByteSize(hv_size_t numElements) { + hv_assert(numElements > 0); + return sizeof(HvMessage) + ((numElements-1) * sizeof(Element)); +} + +HvMessage *msg_copy(const HvMessage *m); + +/** Returns the number of bytes that this message would occupy on the heap. */ +hv_size_t msg_getNumHeapBytes(const HvMessage *m); + +/** Copies the message into the given buffer. The buffer must be at least as large as msg_getNumHeapBytes(). */ +void msg_copyToBuffer(const HvMessage *m, char *buffer, hv_size_t len); + +void msg_setElementToFrom(HvMessage *n, int indexN, const HvMessage *const m, int indexM); + +/** Frees a message on the heap. Does nothing if argument is NULL. */ +void msg_free(HvMessage *m); + +HvMessage *msg_init(HvMessage *m, hv_size_t numElements, hv_uint32_t timestamp); + +HvMessage *msg_initWithFloat(HvMessage *m, hv_uint32_t timestamp, float f); + +HvMessage *msg_initWithBang(HvMessage *m, hv_uint32_t timestamp); + +HvMessage *msg_initWithSymbol(HvMessage *m, hv_uint32_t timestamp, char *s); + +HvMessage *msg_initWithHash(HvMessage *m, hv_uint32_t timestamp, hv_uint32_t h); + +HvMessage *msg_initV(HvMessage *const m, const hv_uint32_t timestamp, const char *format, ...); + +static inline hv_uint32_t msg_getTimestamp(const HvMessage *m) { + return m->timestamp; +} + +static inline void msg_setTimestamp(HvMessage *m, hv_uint32_t timestamp) { + m->timestamp = timestamp; +} + +static inline int msg_getNumElements(const HvMessage *m) { + return (int) m->numElements; +} + +/** Returns the number of bytes this message in memory. */ +static inline hv_size_t msg_getNumBytes(const HvMessage *m) { + return m->numBytes; +} + +static inline ElementType msg_getType(const HvMessage *m, int index) { + hv_assert(index < msg_getNumElements(m)); // invalid index + return (&(m->elem)+index)->type; +} + +static inline void msg_setBang(HvMessage *m, int index) { + hv_assert(index < msg_getNumElements(m)); // invalid index + (&(m->elem)+index)->type = BANG; + (&(m->elem)+index)->data.s = NULL; +} + +static inline bool msg_isBang(const HvMessage *m, int index) { + return (index < msg_getNumElements(m)) ? (msg_getType(m,index) == BANG) : false; +} + +static inline void msg_setFloat(HvMessage *m, int index, float f) { + hv_assert(index < msg_getNumElements(m)); // invalid index + (&(m->elem)+index)->type = FLOAT; + (&(m->elem)+index)->data.f = f; +} + +static inline float msg_getFloat(const HvMessage *const m, int index) { + hv_assert(index < msg_getNumElements(m)); // invalid index + return (&(m->elem)+index)->data.f; +} + +static inline bool msg_isFloat(const HvMessage *const m, int index) { + return (index < msg_getNumElements(m)) ? (msg_getType(m,index) == FLOAT) : false; +} + +static inline void msg_setHash(HvMessage *m, int index, hv_uint32_t h) { + hv_assert(index < msg_getNumElements(m)); // invalid index + (&(m->elem)+index)->type = HASH; + (&(m->elem)+index)->data.h = h; +} + +static inline bool msg_isHash(const HvMessage *m, int index) { + return (index < msg_getNumElements(m)) ? (msg_getType(m, index) == HASH) : false; +} + +/** Returns true if the element is a hash or symbol. False otherwise. */ +static inline bool msg_isHashLike(const HvMessage *m, int index) { + return (index < msg_getNumElements(m)) ? ((msg_getType(m, index) == HASH) || (msg_getType(m, index) == SYMBOL)) : false; +} + +/** Returns a 32-bit hash of the given string. */ +hv_uint32_t msg_symbolToHash(const char *s); + +/** Returns a 32-bit hash of the given element. */ +hv_uint32_t msg_getHash(const HvMessage *const m, int i); + +static inline void msg_setSymbol(HvMessage *m, int index, char *s) { + hv_assert(index < msg_getNumElements(m)); // invalid index + (&(m->elem)+index)->type = SYMBOL; + (&(m->elem)+index)->data.s = s; +} + +static inline char *msg_getSymbol(const HvMessage *m, int index) { + hv_assert(index < msg_getNumElements(m)); // invalid index + return (&(m->elem)+index)->data.s; +} + +static inline bool msg_isSymbol(const HvMessage *m, int index) { + return (index < msg_getNumElements(m)) ? (msg_getType(m, index) == SYMBOL) : false; +} + +bool msg_compareSymbol(const HvMessage *m, int i, const char *s); + +/** Returns 1 if the element i_m of message m is equal to element i_n of message n. */ +bool msg_equalsElement(const HvMessage *m, int i_m, const HvMessage *n, int i_n); + +bool msg_hasFormat(const HvMessage *m, const char *fmt); + +/** + * Create a string representation of the message. Suitable for use by the print object. + * The resulting string must be freed by the caller. + */ +char *msg_toString(const HvMessage *msg); + +/** + * Resolves any number of dollar arguments and generates a string based on the arguments. + * @param m The message from which to take values + * @param n The message to fill in + * @param z The element index to resolve + * @param buf The scratch (i.e. resolution) buffer + * @param len The length of the scratch buffer + * @param args A string of 'i' and 's' chars indicating the type of the arguments, either indicies or strings + * @param varargs The components to resolve, either dollar indicies or strings. + * If the index is negative, the graph id is used + * @return true if the resolution buffer is needed, false otherwise. + */ +// bool msg_resolveDollarArguments(HvMessage *m, HvMessage *n, int z, char *buf, hv_size_t len, const char *args, ...); + +#endif // _HEAVY_MESSAGE_H_