Skip to content

Instantly share code, notes, and snippets.

@linneman
Created September 25, 2015 20:16
Show Gist options
  • Save linneman/9da6dabd7d8e2a71992d to your computer and use it in GitHub Desktop.
Save linneman/9da6dabd7d8e2a71992d to your computer and use it in GitHub Desktop.
signal processing architecture in C
/*
* design pattern of descriptor based signal processing framework
* based on ideas of mediastreamer2 library
* 2015 by OL
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
/*
* --- primitive quasi static memory management ---
*/
typedef struct pa_dsp_heap_struct {
void* heapPtr;
void* heapLimit;
} *PA_DSP_HEAP_HANDLE;
void* pa_dsp_alloc( PA_DSP_HEAP_HANDLE hh, int size, int align_addr_to_power_of )
{
void* ptr = hh->heapPtr;
int offset = ((unsigned long)ptr) % align_addr_to_power_of;
ptr += offset;
assert( (hh->heapPtr += (size+offset)) < hh->heapLimit );
return ptr;
}
void pa_dsp_free( PA_DSP_HEAP_HANDLE hh, void* address )
{
}
/*
* --- filter data structures and operations ---
*/
struct pa_dsp_filt_struct;
typedef void (* PA_DSP_FILT_FUNC)( struct pa_dsp_filt_struct * );
typedef void (* PA_DSP_INIT_FUNC)( struct pa_dsp_filt_struct *, PA_DSP_HEAP_HANDLE );
typedef struct pa_dsp_filt_desc_struct {
int id; /* the id declared in allfilters.h */
char* name; /* filter name */
char* text; /*some descriptive text*/
int frame_size;
int ninputs;
int noutputs;
void* data;
PA_DSP_INIT_FUNC init;
PA_DSP_FILT_FUNC config;
PA_DSP_INIT_FUNC release;
PA_DSP_FILT_FUNC proc;
} PA_DSP_FILT_DESC;
typedef struct pa_dsp_filt_struct {
PA_DSP_FILT_DESC* desc;
void** inp;
void** out;
void* state;
} PA_DSP_FILT;
void pa_dsp_connect_inputs( PA_DSP_FILT* filt1, PA_DSP_FILT* filt2 )
{
int i;
assert( filt1->desc->frame_size == filt2->desc->frame_size );
assert( filt1->desc->noutputs == filt2->desc->ninputs );
for( i=0; i<filt1->desc->noutputs; ++i)
filt1->out[i] = filt2->inp[i];
}
typedef struct pa_dsp_filt_lst_struct {
PA_DSP_FILT* filt;
struct pa_dsp_filt_lst_struct *next;
} PA_DSP_FILT_LST;
/*
* --- filter 1 ---
*/
typedef struct filt1_conf_struct {
int a;
int b;
} FILT1_CONF;
static FILT1_CONF filt1_conf = { 1, 2 };
static void init1( PA_DSP_FILT* filt, PA_DSP_HEAP_HANDLE heapHandle )
{
printf("initialize filter 1 ...\n");
filt->inp = pa_dsp_alloc( heapHandle, sizeof(void*), 2 );
filt->out = pa_dsp_alloc( heapHandle, sizeof(void*), 2 );
filt->inp[0] = pa_dsp_alloc( heapHandle, filt->desc->frame_size, 2 );
}
static void release1( PA_DSP_FILT* filt, PA_DSP_HEAP_HANDLE heapHandle )
{
printf("release filter 1 ...\n");
}
static void proc1( PA_DSP_FILT* filt )
{
int i;
int* inp = (int *)filt->inp[0];
int* out = (int *)filt->out[0];
printf("processing filter1, first three input elements: ");
for( i=0; i<3; ++i ) {
printf("%d, ", inp[i] );
out[i] = 1 + inp[i];
}
printf("\n");
}
PA_DSP_FILT_DESC filt_desc1 = {
.id = 1,
.name = "filt1",
.frame_size = 100,
.ninputs = 1,
.noutputs = 1,
.init = init1,
.release = release1,
.proc = proc1,
.data = &filt1_conf,
};
/*
* --- filter 2 ---
*/
typedef struct filt2_conf_struct {
short c;
int d;
} FILT2_CONF;
static FILT2_CONF filt2_conf = { 3, 4 };
static void init2( PA_DSP_FILT* filt, PA_DSP_HEAP_HANDLE heapHandle )
{
printf("initialize filter 2 ...\n");
filt->inp = pa_dsp_alloc( heapHandle, sizeof(void*), 2 );
filt->out = pa_dsp_alloc( heapHandle, sizeof(void*), 2 );
filt->inp[0] = pa_dsp_alloc( heapHandle, filt->desc->frame_size, 2 );
}
static void release2( PA_DSP_FILT* filt, PA_DSP_HEAP_HANDLE heapHandle )
{
printf("release filter 2 ...\n");
}
static void proc2( PA_DSP_FILT* filt )
{
int i;
int* inp = (int *)filt->inp[0];
int* out = (int *)filt->out[0];
printf("processing filter2, first three input elements: ");
for( i=0; i<3; ++i ) {
printf("%d, ", inp[i] );
out[i] = 2 * inp[i];
}
printf("\n");
}
PA_DSP_FILT_DESC filt_desc2 = {
.id = 2,
.name = "filt2",
.frame_size = 100,
.ninputs = 1,
.noutputs = 1,
.init = init2,
.release = release2,
.proc = proc2,
.data = &filt2_conf,
};
int main()
{
#define HEAPSIZE 1000
int heap[HEAPSIZE/sizeof(int)];
struct pa_dsp_heap_struct heapStruct = { .heapPtr = &heap, .heapLimit = &heap + HEAPSIZE };
PA_DSP_HEAP_HANDLE heapHandle = &heapStruct;
PA_DSP_FILT_LST* pList;
int* in;
int out[100];
int i;
/*
* --- list of filters ---
*/
PA_DSP_FILT filt1 = { .desc = &filt_desc1 };
PA_DSP_FILT filt2 = { .desc = &filt_desc2 };
PA_DSP_FILT_LST filter_queue[2];
filter_queue[0].filt = &filt1; filter_queue[0].next = &filter_queue[1];
filter_queue[1].filt = &filt2; filter_queue[1].next = NULL;
/* initialize and connect filters */
for( pList = filter_queue; pList != NULL; pList = pList->next )
pList->filt->desc->init( pList->filt, heapHandle );
pa_dsp_connect_inputs( &filt1, &filt2 );
filt2.out[0] = out;
/* initialize first filter's input with some values */
for( i=0, in=(int*)filt1.inp[0]; i<3; ++i )
in[i] = i;
/* start process */
for( pList = filter_queue; pList != NULL; pList = pList->next )
pList->filt->desc->proc( pList->filt );
/* print output */
printf("processing result: ");
for( i=0; i<3; ++i ) {
printf("%d, ", out[i] );
}
printf("\n");
/* release filters */
for( pList = filter_queue; pList != NULL; pList = pList->next )
pList->filt->desc->release( pList->filt, heapHandle );
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment