Created
September 25, 2015 20:16
-
-
Save linneman/9da6dabd7d8e2a71992d to your computer and use it in GitHub Desktop.
signal processing architecture in C
This file contains hidden or 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
/* | |
* 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