aboutsummaryrefslogtreecommitdiffhomepage
path: root/midimonster.h
blob: 8d439f52eaf403ef3ded75541676ced201210555 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#ifndef MIDIMONSTER_HEADER
#define MIDIMONSTER_HEADER
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define max(a,b) (((a) > (b)) ? (a) : (b))

#define DEFAULT_CFG "monster.cfg"

struct _channel_value;
struct _backend_channel;
struct _backend_instance;
struct _managed_fd;

typedef int (*mmbackend_handle_event)(struct _backend_instance* inst, size_t channels, struct _backend_channel** c, struct _channel_value* v);
typedef struct _backend_instance* (*mmbackend_create_instance)();
typedef struct _backend_channel* (*mmbackend_parse_channel)(struct _backend_instance* instance, char* spec);
typedef void (*mmbackend_free_channel)(struct _backend_channel* c);
typedef int (*mmbackend_configure)(char* option, char* value);
typedef int (*mmbackend_configure_instance)(struct _backend_instance* instance, char* option, char* value);
typedef int (*mmbackend_process_fd)(size_t nfds, struct _managed_fd* fds);
typedef int (*mmbackend_start)();
typedef uint32_t (*mmbackend_interval)();
typedef int (*mmbackend_shutdown)();

typedef struct _channel_value {
	union {
		double dbl;
		uint64_t u64;
	} raw;
	double normalised;
} channel_value;

typedef struct /*_mm_backend*/ {
	char* name;
	mmbackend_configure conf;
	mmbackend_create_instance create;
	mmbackend_configure_instance conf_instance;
	mmbackend_parse_channel channel;
	mmbackend_handle_event handle;
	mmbackend_process_fd process;
	mmbackend_start start;
	mmbackend_shutdown shutdown;
	mmbackend_free_channel channel_free;
	mmbackend_interval interval;
} backend;

typedef struct _backend_instance {
	backend* backend;
	uint64_t ident;
	void* impl;
	char* name;
} instance;

typedef struct _backend_channel {
	instance* instance;
	uint64_t ident;
	void* impl;
} channel;

//FIXME might be replaced by struct pollfd
//FIXME who frees impl
typedef struct _managed_fd {
	int fd;
	backend* backend;
	void* impl;
} managed_fd;

typedef struct /*_mm_channel_mapping*/ {
	channel* from;
	size_t destinations;
	channel** to;
} channel_mapping;

/*
 * Register a new backend.
 */
int mm_backend_register(backend b);

/*
 * Provides a pointer to a newly (zero-)allocated instance.
 * All instance pointers need to be allocated via this API
 * in order to be assignable from the configuration parser.
 * This API should be called from the mmbackend_create_instance
 * call of your backend.
 *
 * Instances returned from this call are freed by midimonster.
 * The contents of the impl members should be freed in the
 * mmbackend_shutdown procedure of the backend, eg. by querying
 * all instances for the backend.
 */
instance* mm_instance();
/*
 * Finds an instance matching the specified backend and identifier.
 * Since setting an identifier for an instance is optional,
 * this may not work depending on the backend.
 * Instance identifiers may for example be set in the backends
 * mmbackend_start call.
 */
instance* mm_instance_find(char* backend, uint64_t ident);
/*
 * Provides a pointer to a channel structure, pre-filled with
 * the provided instance reference and identifier.
 * Will return previous allocations if the provided fields
 * match.
 * This API is just a convenience function. The array
 * of channels is only used for mapping internally,
 * creating and managing your own channel store is
 * possible.
 * For each channel with a non-NULL impl field, the backend
 * will receive a call to its channel_free function.
 */
channel* mm_channel(instance* i, uint64_t ident, uint8_t create);
//TODO channel* mm_channel_find()
/*
 * Register a file descriptor to be selected on. The backend
 * will be notified via the mmbackend_process_fd call.
 * This function may only be called from within the
 * mmbackend_start procedure.
 */
int mm_manage_fd(int fd, char* backend, int manage, void* impl);
int mm_channel_event(channel* c, channel_value v);
/*
 * Query all active instances for a given backend.
 * *i will need to be freed by the caller.
 */
int mm_backend_instances(char* backend, size_t* n, instance*** i);
int mm_map_channel(channel* from, channel* to);
#endif