Created
November 28, 2010 18:26
-
-
Save jacobjoaquin/719159 to your computer and use it in GitHub Desktop.
Personal learning example for creating an encapsulated struct of breakpoints and meta-data.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Breakpoint List | |
* Jacob Joaquin <jacobjoaquin@gmail.com> | |
* csoundblog.com | |
* | |
* Based on Section 1.7 of The Audio Programming Book | |
* Edited by Richard Boulanger and Victor Lazzarini | |
* Chapter 1 - Programming in C (pg 130) | |
* Richard Dobson | |
* | |
* I expanded on the Breakpoint example to understand what is involved in | |
* creating an encapsulated structure that contains the BREAKPOINT array | |
* as well as information about the array. The mem_size is the actual size | |
* of the array. The data_size is the size of the array used to hold data. | |
* | |
* Though not utilized in this example, the size of the array could double | |
* everytime data is appended beyond the last element. In theory, this could | |
* reduce the number of malloc/realloc calls, the trade-off being that more | |
* memory is used. | |
* | |
* Remember, this is a learning exercise, so it ain't perfect. :) | |
*/ | |
#include <stdlib.h> | |
#include <stdio.h> | |
typedef struct { | |
double time; | |
double value; | |
} BREAKPOINT; | |
typedef struct { | |
unsigned int mem_size; /* Actual size of BREAKPOINT array */ | |
unsigned int data_size; /* Size of data in BREAKPOINT array */ | |
BREAKPOINT* breakpoint; | |
} BREAKPOINT_list; | |
void init_breakpoint_list(BREAKPOINT_list* bpc); | |
void print_breakpoint_list(BREAKPOINT_list* bpc); | |
void set_breakpoint_list(BREAKPOINT_list* bpc, double* data, | |
int size); | |
void time_bias_breakpoint_list(BREAKPOINT_list* bpc, double amount); | |
void time_scale_breakpoint_list(BREAKPOINT_list* bpc, double factor); | |
main() | |
{ | |
BREAKPOINT_list bpc; | |
double data[] = {0.0, 0.0, 0.5, 1.0, 0.75, 0.333, 2.0, 0.01}; | |
printf("init\n"); | |
init_breakpoint_list(&bpc); | |
print_breakpoint_list(&bpc); | |
printf("\nset breakpoints\n"); | |
set_breakpoint_list(&bpc, data, 8); | |
print_breakpoint_list(&bpc); | |
printf("\ntime scale by 2\n"); | |
time_scale_breakpoint_list(&bpc, 2); | |
print_breakpoint_list(&bpc); | |
printf("\ntime bias by 3\n"); | |
time_bias_breakpoint_list(&bpc, 3); | |
print_breakpoint_list(&bpc); | |
return 0; | |
} | |
/** | |
* Initializes a BREAKPOINT_list. | |
* | |
* @param BREAKPOINT_LIST* bpc The list to initialize. | |
*/ | |
void init_breakpoint_list(BREAKPOINT_list* bpc) | |
{ | |
static const unsigned int init_mem_size = 1; | |
static const unsigned int init_data_size = 1; | |
bpc->mem_size = init_mem_size; | |
bpc->data_size = init_data_size; | |
bpc->breakpoint = (BREAKPOINT*) malloc(sizeof(BREAKPOINT) * init_mem_size); | |
} | |
/** | |
* Print the contents of a BREAKPOINT_list | |
* | |
* @param BREAKPOINT_LIST* bpc The list to print. | |
*/ | |
void print_breakpoint_list(BREAKPOINT_list* bpc) | |
{ | |
int size = bpc->data_size; | |
BREAKPOINT* ptr = bpc->breakpoint; | |
/* See Listing 1.6.2 for my reasons for choosing the "do while" | |
* loop over the alternatives. (pg 114) | |
*/ | |
do | |
{ | |
printf("%f: %f\n", ptr->time, ptr->value); | |
*ptr++; | |
} while (--size); | |
} | |
/** | |
* Sets the contents of a BREAKPOINT_list. Data is passed through an array | |
* of doubles; The size of the array must also be passed. The data array | |
* size should be an even number, though no error checking occurs within | |
* the function. | |
* | |
* @param BREAKPOINT_LIST* bpc The list to set. | |
* @param double* data The list to initialize. | |
* @param int size The size of the data array. | |
*/ | |
void set_breakpoint_list(BREAKPOINT_list* bpc, double* data, int size) | |
{ | |
int npoints = size / 2; | |
BREAKPOINT* ptr = bpc->breakpoint; | |
BREAKPOINT* tmp; | |
/* Adjust size of BREAKPOINT array (if necessary) */ | |
if (bpc->mem_size != npoints) | |
{ | |
tmp = (BREAKPOINT*) realloc(ptr, sizeof(BREAKPOINT) * npoints); | |
if (tmp == NULL) { | |
printf("realloc failed. exiting.\n"); | |
free(ptr); | |
exit(1); | |
} | |
bpc->mem_size = npoints; | |
bpc->data_size = npoints; | |
ptr = bpc->breakpoint = tmp; | |
} | |
do | |
{ | |
ptr->time = *data++; | |
ptr++->value = *data++; | |
} while (--npoints); | |
} | |
/** | |
* Move the times of the breakpoints. | |
* | |
* @param BREAKPOINT_LIST* bpc The breakpoint list. | |
* @param double amount The amount of time to transpose time. | |
*/ | |
void time_bias_breakpoint_list(BREAKPOINT_list* bpc, double amount) | |
{ | |
int size = bpc->data_size; | |
BREAKPOINT* ptr = bpc->breakpoint; | |
do | |
{ | |
ptr++->time += amount; | |
} while (--size); | |
} | |
/** | |
* Compress/expand the time values in a BREAKPOINT_list. The process always | |
* centers at time 0. | |
* | |
* @param BREAKPOINT_LIST* bpc The breakpoint list. | |
* @param double factor The time-scaling factor. | |
*/ | |
void time_scale_breakpoint_list(BREAKPOINT_list* bpc, double factor) | |
{ | |
int size = bpc->data_size; | |
BREAKPOINT* ptr = bpc->breakpoint; | |
do | |
{ | |
ptr++->time *= factor; | |
} while (--size); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment