-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBreakpoints.c
158 lines (132 loc) · 5.13 KB
/
Breakpoints.c
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
/*--------------------------------------------------------------------Breakpoints.c--------------------------------------------------------------------*/
/*
* Created by Vishal Menon (Laziemo) in association with Richard Dobson (The Audio Programming Book)
* Version 1.0: September 23, 2017
* Envelope Generator Origins
*
*Input:
* - InputFile containing BreakPoint data
*Output:
* - Duration of the envelope
* - Maximum Breakpoint value
*/
/*--------------------------------------------------------------------Breakpoints.c--------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#define NPOINTS 64
typedef struct{
double time;
double value;
} BREAKPOINT;
BREAKPOINT* get_breakpoints(FILE* fp, unsigned long* psize);
BREAKPOINT max_point(const BREAKPOINT* points, unsigned long npoints);
//char* fgets(char* line, int maxline, FILE* fp)';
//int* sscanf(char* string, const char* format,..); returns number of succesful conversions made
/*--------------------------------------------------------------------main--------------------------------------------------------------------*/
int main(int argc, char* argv[] ){
unsigned long size;
double dur;
BREAKPOINT* points;
BREAKPOINT maxpoint;
FILE* fp;
printf("Breakpoints Program: Envelope Shaping Origins\n");
if (argc != 2){
printf("Insufficient command line arguments! Breakpoints takes 2 arguments. \n Usage: Breakpoints inputfile.txt \n");
return 0;
}
fp = fopen(argv[1], "r"); //open file in read mode
if(fp == NULL) return 0;
size = 0;
points = get_breakpoints(fp, &size);
if(points==NULL){
printf("No breakpoints read\n");
fclose(fp);
return 1;
}
if (size < 2){
printf("Error: Atleast 2 breakpoints required!");
free(points);
fclose(fp);
return 1;
}
if (points[0].time != 0){
printf("Error in breakpoint data: First point must start at 0 time.");
free(points);
fclose(fp);
return 1;
}
/*Error Checks Complete
*
* Display Outputs
*/
printf("read %lu breakpoints \n", size);
dur = points[size-1].time;
printf("Envelope Duration = %lf seconds \n", dur);
maxpoint = max_point(points, size);
printf("Maximum value: %lf at %lf seconds \n", maxpoint.value, maxpoint.time);
free(points);
fclose(fp);
return 0;
}
/*-----------------------------------------------------------------FUNCTION DEFINITIONS-----------------------------------------------------------------*/
/*
*
*/
BREAKPOINT* get_breakpoints(FILE* fp, unsigned long* psize){
int got;
unsigned long npoints = 0 , size = NPOINTS; // Envelope with 64 BREAKPOINTS = array of 64 BREAKPOINTS ~ Might have to increase the size
double lasttime = 0.0;
BREAKPOINT* points = NULL;
char line[80];
if (fp == NULL) return NULL;
points = (BREAKPOINT*) malloc (size * sizeof(BREAKPOINT));
if(points == NULL) return NULL;
while(fgets(line,80,fp)){
//Scan for errors in fgets output to line array
got = sscanf(line, "%lf%lf", &points[npoints].time, &points[npoints].value);
if(got < 0) continue;
if(got == 0) {
printf("Line %lu has non-numeric data \n", npoints+1);
break;
}
if(got == 1){
printf("Incomplete breakpoint found at point %lu \n", npoints+1);
break;
}
if(points[npoints].time < lasttime){
printf("data error at point %lu: time not increasing \n", npoints+1);
break;
}
lasttime = points[npoints].time;
//Auto-increament through array
if(++npoints == size){ //While fgets - if more BREAKPOINT data exists than initial size allocated - reallocate memory and re-size
BREAKPOINT* tmp;
size += NPOINTS;
tmp=(BREAKPOINT*) realloc(points, sizeof(BREAKPOINT) * size);
if(tmp=NULL){
npoints=0;
free(points);
points = NULL;
break;
}
points = tmp;
}
}
if(npoints) *psize = npoints;
return points;
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------
BREAKPOINT max_point(const BREAKPOINT* points, unsigned long npoints){
int i;
BREAKPOINT point;
point.time = points[0].time;
point.value = points[0].value;
for(i=1; i<npoints;i++){
if(point.value<points[i].value){
point.value = points[i].value;
point.time = points[i].time;
}
}
return point;
}
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------