aboutsummaryrefslogtreecommitdiff
path: root/common.h
blob: 75bd3fbb5041144964e859e85fb4a69512382440 (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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190

// here i put common data structures and functions

// ------------------------------------------------ data structures


// --------- theme notation


typedef struct t_note t_note;
typedef struct t_duration t_duration;
typedef struct t_note_event t_note_event;

typedef struct t_note
{
	unsigned short int chord; // 0 if is not a chord (strong) note, 1 if it is
	unsigned short int diatonic; // 0 if is a note not belonging to this tonality
	int interval; // semitones from prefious note
};
typedef struct t_duration
{
	int numerator; // like in music notation: in a 1/4 note the numerator is 1
	int denominator; // like in music notation: in a 1/4 note the denominator is 4
};
struct t_note_event
{
	unsigned short int voice;
	t_note note;
	t_duration start; // moment of the noteon event
	t_duration duration; // duration of this event
	t_note_event *previous; // this is a list, link to the previous element
	t_note_event *next;  // this is a list, link to the next element
};


// --------- rhythm notation

// data structures

// this describes a rhythm
typedef struct t_rhythm_event t_rhythm_event;
struct t_rhythm_event
{
	unsigned short int voice;
	t_duration start; // moment of the noteon event
	t_duration duration; // duration of this event
	t_rhythm_event *previous; // this is a list, link to the previous element
	t_rhythm_event *next;  // this is a list, link to the next element
};

// rhythms memory graph

// list implementation
// this implements a graph that stores the memory of the current rhythm sub-elements
// list of links
// the actual implementation will be an array of nodes, each node 

// this describes a probability transition table
typedef struct t_rhythm_memory_arc t_rhythm_memory_arc;
typedef struct t_rhythm_memory_node t_rhythm_memory_node;
// graph node
struct t_rhythm_memory_node
{
	// start is implicit:
	// this is in an array
	// use int2duration and duration2int 
	// against the index in the array to get its value
	unsigned short int first; // how many times this has been the first event
	unsigned short int weight; // how many times this has been an event
	t_rhythm_memory_arc *arcs; // the list of arcs to other nodes
} ;
// graph arc: related to t_rhythm_memory_node
struct t_rhythm_memory_arc
{
	unsigned short int to_node_index; // the target of this link (arc)
	t_rhythm_memory_arc *next_arc; // next link in the list
} ;
// it will be arranged in a heap list.. ?

#define num_possible_denominators 11
static unsigned short int possible_denominators[] = {1,2,3,4,6,8,12,16,18,24,32};

// this defines a space for rhythms, variations, transitions and representations
typedef struct t_rhythm_memory_representation t_rhythm_memory_representation;
typedef struct t_rhythm_memory_element t_rhythm_memory_element;
typedef struct t_rhythm_memory_first_node t_rhythm_memory_first_node;
// element of a list of rhythms
struct t_rhythm_memory_element
{
	t_rhythm_event *rhythm; // this rhythm
	t_rhythm_memory_element *next; // next element of the list
	unsigned short int id; // its sub id
} ;
// a rhythm in memory, each rhythm is :
// - its probability transition table
// - similar rhythms played
// - each one has its main id and each different played rhythm its sub-id
struct t_rhythm_memory_representation
{
	t_rhythm_memory_node *transitions;
	unsigned short int max_weight;
	t_rhythm_memory_element *rhythms;
	unsigned short int id; // its main id
	unsigned short int last_sub_id; // last sub assigned
	// I can express a list of representations with this data structure
	t_rhythm_memory_representation *next;
} ;

// ------------------------------------------------ functions

// ----------- rhythm manipolation functions

// converts from integer to duration: used to know this table index
// what corresponds in terms of duration
t_duration int2duration(int n);
// converts from duration to integer: used to know this duration
// what corresponds in terms table index
unsigned short int duration2int(t_duration dur);
// tells you how many durations there are
int possible_durations();

// converts from float (0-1) to duration. it performs quantization
t_duration float2duration(float fduration);

// converts from numerator/denominator to a float (0-1)
float duration2float(t_duration duration);

// --- rhythms creation and manupulation functions

// set the first beat of a sequence
// this also creates a new rhythm
void setFirstBeat(t_rhythm_event **firstEvent, unsigned short int voice, float fstart, float fduration);

//adds a beat at the end of this list
void concatenateBeat(t_rhythm_event *currentEvent, unsigned short int voice, float fstart, float fduration);

// used to free the memory allocated by this list
void freeBeats(t_rhythm_event *currentEvent);


// --- memory representation of rhythms

// add an arc to this node
void add_t_rhythm_memory_arc(t_rhythm_memory_node *srcNode, unsigned short int dstNode);

// create and initialize this representation, allocate memory for the pointers
// I must pass its id also
void create_rhythm_memory_representation(t_rhythm_memory_representation **this_rep, unsigned short int id);

// define a return value to express "rhythm not found in this representation"
#define INVALID_RHYTHM 65535

// add a new rhythm in the list of similar rhythms related to one main rhythm
// the sub id is auto-generated and returned
unsigned short int add_similar_rhythm(t_rhythm_memory_representation *this_rep, t_rhythm_event *new_rhythm);

// free the list of representations
void free_memory_representations(t_rhythm_memory_representation *this_rep);

// compares this rhythm to this representation
// and tells you how close it is to it
// I return values using pointers
// the unsigned short and the 2 floats should be already allocated
void compare_rhythm_vs_representation(t_rhythm_memory_representation *this_rep, 
						 t_rhythm_event *src_rhythm, // the src rhythm 
						 unsigned short int *sub_id, // the sub-id of the closest sub-rhythm 
						 float *root_closeness, // how much this rhythm is close to the root (1=identical, 0=nothing common)
						 float *sub_closeness // how much this rhythm is close to the closest sub-rhythm (1=identical, 0=nothing common)
						 );

// same as before but search all available representations
void find_rhythm_in_memory(t_rhythm_memory_representation *rep_list, 
						 t_rhythm_event *src_rhythm, // the src rhythm 
						 unsigned short int *id, // the id of the closest rhythm
						 unsigned short int *sub_id, // the sub-id of the closest sub-rhythm 
						 float *root_closeness, // how much this rhythm is close to the root (1=identical, 0=nothing common)
						 float *sub_closeness // how much this rhythm is close to the closest sub-rhythm (1=identical, 0=nothing common)
						 );

// -------- notes manipulation functions

// set the first beat of a sequence
void setFirstNote(t_note_event **firstEvent, unsigned short int voice, float fstart, float fduration, t_note note);

//adds a beat at the end of this list
void concatenateNote(t_note_event *currentEvent, unsigned short int voice, float fstart, float fduration, t_note note);

// used to free the memory allocated by this list
void freeNotes(t_note_event *currentEvent);