Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Personal learning example for creating an encapsulated struct of breakpoints and meta-data.
/* 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