1 |
#include <string.h> |
2 |
#include <stdlib.h> |
3 |
#include <time.h> |
4 |
#include <assert.h> |
5 |
#include "graph.h" |
6 |
|
7 |
void node_destroy(struct node* n) |
8 |
{ |
9 |
int i; |
10 |
for(i = 0; i < n->count; i++) { |
11 |
node_unlink(n, n->neighbours[i].to); |
12 |
} |
13 |
free(n->neighbours); |
14 |
n->neighbours = NULL; |
15 |
return; |
16 |
} |
17 |
|
18 |
void node_randomize(struct node* n) |
19 |
{ |
20 |
n->event.pitch = rand() % 128; |
21 |
n->event.duration = rand(); |
22 |
n->event.attack = rand() % 128; |
23 |
n->event.decay = rand() % 128; |
24 |
n->event.sustain = rand() % 128; |
25 |
n->event.release = rand() % 128; |
26 |
n->event.instrument = rand() % 128; |
27 |
n->event.modulation = rand() % 128; |
28 |
n->event.detune = rand() % 128; |
29 |
n->event.velocity = rand() % 128; |
30 |
n->event.volume = rand() % 128; |
31 |
} |
32 |
|
33 |
void edge_randomize(struct edge* e) |
34 |
{ |
35 |
e->distance = rand(); |
36 |
} |
37 |
|
38 |
int node_is_linked(struct node* a, struct node* b) |
39 |
{ |
40 |
int i; |
41 |
for (i = 0; i < a->count; i++) { |
42 |
if (a->neighbours[i].to == b) |
43 |
return 1; |
44 |
} |
45 |
return 0; |
46 |
} |
47 |
|
48 |
int node_link(struct node* a, struct node* b, int distance) |
49 |
{ |
50 |
struct edge *nba, *nbb; |
51 |
|
52 |
assert (a != b); |
53 |
|
54 |
a->count++; |
55 |
nba = realloc(a->neighbours, a->count * sizeof(struct edge)); |
56 |
if (!nba) { |
57 |
a->count--; |
58 |
return -1; |
59 |
} |
60 |
nba[a->count - 1].distance = distance; |
61 |
nba[a->count - 1].to = b; |
62 |
|
63 |
b->count++; |
64 |
nbb = realloc(b->neighbours, b->count * sizeof(struct edge)); |
65 |
if (!nbb) { |
66 |
a->count--; |
67 |
b->count--; |
68 |
free(nba); |
69 |
return -1; |
70 |
} |
71 |
nbb[b->count - 1].distance = distance; |
72 |
nbb[b->count - 1].to = a; |
73 |
|
74 |
a->neighbours = nba; |
75 |
b->neighbours = nbb; |
76 |
return 0; |
77 |
} |
78 |
|
79 |
int node_unlink(struct node* a, struct node* b) |
80 |
{ |
81 |
struct edge *nba, *nbb; |
82 |
int i, j; |
83 |
a->count--; |
84 |
nba = malloc(a->count * sizeof(struct edge)); |
85 |
if (!nba) { |
86 |
a->count++; |
87 |
return -1; |
88 |
} |
89 |
for (i = 0, j = 0; i < a->count; i++, j++) { |
90 |
if (a->neighbours[i].to != b) { |
91 |
nba[j].to = a->neighbours[i].to; |
92 |
nba[j].distance = a->neighbours[i].distance; |
93 |
} else { |
94 |
j--; |
95 |
} |
96 |
} |
97 |
|
98 |
nbb = malloc(b->count * sizeof(struct edge)); |
99 |
if (!nbb) { |
100 |
a->count++; |
101 |
b->count++; |
102 |
free(nba); |
103 |
return - 1; |
104 |
} |
105 |
for (i = 0, j = 0; i < b->count; i++, j++) { |
106 |
if (b->neighbours[i].to != a) { |
107 |
nbb[j].to = b->neighbours[i].to; |
108 |
nbb[j].distance = b->neighbours[i].distance; |
109 |
} else { |
110 |
j--; |
111 |
} |
112 |
} |
113 |
free(a->neighbours); |
114 |
free(b->neighbours); |
115 |
a->neighbours = nba; |
116 |
b->neighbours = nbb; |
117 |
return 0; |
118 |
} |
119 |
|
120 |
struct graph* graph_new(int n) |
121 |
{ |
122 |
struct graph* g; |
123 |
|
124 |
g = malloc(sizeof(struct graph)); |
125 |
if (!g) { |
126 |
return NULL; |
127 |
} |
128 |
|
129 |
g->nodes = malloc(n * sizeof(struct node)); |
130 |
if (!(g->nodes)) { |
131 |
free(g); |
132 |
return NULL; |
133 |
} |
134 |
|
135 |
memset(g->nodes, 0, n * sizeof(struct node)); |
136 |
g->count = n; |
137 |
return g; |
138 |
} |
139 |
|
140 |
int graph_randomize(struct graph* g) |
141 |
{ |
142 |
int en; |
143 |
int m, n, i, j; |
144 |
|
145 |
srand(time(NULL)); |
146 |
for (i = 0; i < g->count; i++) { |
147 |
node_randomize(&(g->nodes[i])); |
148 |
en = rand() % ((g->count) / 2); |
149 |
for (j = 0; j < en; j++) { |
150 |
m = rand() % g->count; |
151 |
n = rand() % g->count; |
152 |
if ((m == n) || node_is_linked(&(g->nodes[m]), &(g->nodes[n]))) { |
153 |
continue; |
154 |
} |
155 |
if (node_link(&(g->nodes[m]), &(g->nodes[n]), rand())) { |
156 |
goto revert; |
157 |
} |
158 |
} |
159 |
} |
160 |
|
161 |
return 0; |
162 |
revert: |
163 |
for (i = 0; i < g->count; i++) { |
164 |
node_destroy(&(g->nodes[i])); |
165 |
} |
166 |
memset(g->nodes, 0, g->count * sizeof(struct node)); |
167 |
return -1; |
168 |
} |
169 |
|