waveview/lib/wavetable.c

301 lines
6.6 KiB
C
Raw Normal View History

2022-09-24 17:47:18 -04:00
/*
* wavetable.c - wavetable interface functions
*
* include LICENSE
*/
#include <stdio.h>
#include <string.h>
#include <strmem.h>
#include <wavetable.h>
#ifdef TRACE_MEM
#include <tracemem.h>
#endif
/*
* wave table regroup all datasets
*/
/*
*** \brief Allocates memory for a new WaveTable object.
*/
WaveTable *wavetable_new( AppClass *datafile, char *tblname )
{
WaveTable *wt;
wt = app_new0(WaveTable, 1);
wavetable_construct( wt, datafile, tblname );
app_class_overload_destroy( (AppClass *) wt, wavetable_destroy );
return wt;
}
/** \brief Constructor for the WaveTable object. */
void wavetable_construct( WaveTable *wt, AppClass *datafile, char *tblname )
{
app_class_construct( (AppClass *) wt );
wt->tables = g_ptr_array_new ();
wt->datafile = datafile;
wt->tblname = app_strdup(tblname);
wt->swvars = g_ptr_array_new ();
wavetable_add(wt); /* create 1 dataset */
}
/** \brief Destructor for the WaveTable object. */
void wavetable_destroy(void *wt)
{
WaveTable *this = (WaveTable *) wt;
int i;
if (wt == NULL) {
return;
}
for ( i = 0 ; i < this->nswvars ; i++ ) {
WaveVar *swvar = g_ptr_array_index( this->swvars, i );
wavevar_destroy ( swvar) ;
}
g_ptr_array_free (this->swvars, FALSE);
for (i = 0; i < this->ntables ; i++) {
WDataSet *wds = g_ptr_array_index( this->tables, i );
dataset_destroy( wds );
}
g_ptr_array_free (this->tables, FALSE);
app_free(this->tblname);
/* now nuke the reading object */
if ( this->streamDestroyFunc ){
(this->streamDestroyFunc)( this->dataSrc);
}
app_class_destroy( wt );
}
void wavetable_set_funcs ( WaveTable *wt, AppClass *src, ReadVarsFP hdrfunc,
ReadDataFP rdfunc, StreamDestroyFP destroyfunc )
{
wt->dataSrc = src;
wt->rdVarsFunc = hdrfunc;
wt->rdDataFunc = rdfunc;
wt->streamDestroyFunc = destroyfunc;
}
void wavetable_set_datafile ( WaveTable *wt, void *datafile )
{
wt->datafile = datafile;
}
char *wavetable_get_tblname ( WaveTable *wt )
{
return wt->tblname;
}
void *wavetable_get_datafile ( WaveTable *wt )
{
return wt->datafile;
}
int wavetable_get_ntables ( WaveTable *wt )
{
return wt->ntables;
}
WDataSet *wavetable_add( WaveTable *wt)
{
WDataSet *wds = dataset_new(0, (AppClass *) wt, wt->ntables);
g_ptr_array_add (wt->tables, (gpointer) wds);
wt->ntables++;
return wds;
}
WDataSet *wavetable_get_dataset( WaveTable *wt, int idx)
{
if ( idx < 0 || idx >= wt->ntables ) {
return NULL;
}
WDataSet *wds = g_ptr_array_index( wt->tables, idx );
return wds;
}
WDataSet *wavetable_get_cur_dataset( WaveTable *wt)
{
return wavetable_get_dataset( wt, wt->ntables - 1);
}
void wavetable_remove( WaveTable *wt, int idx)
{
if ( idx < 0 || idx >= wt->ntables ) {
msg_error( _("Try to remove not existing index %d ntables %d"),
idx, wt->ntables );
return;
}
WDataSet *wds = g_ptr_array_index( wt->tables, idx );
if ( g_ptr_array_remove (wt->tables, (gpointer) wds) ) {
dataset_destroy (wds);
wt->ntables--;
}
}
void wavetable_swvar_add(WaveTable *wt, char *varName, int type, int ncols)
{
WaveVar *swvar = wavevar_new( NULL, varName, type, wt->nswvars, ncols);
wavevar_set_wavetable(swvar, (AppClass *) wt, 0 );
g_ptr_array_add (wt->swvars, (gpointer) swvar);
wt->nswvars++;
}
char *wavetable_swvar_name_get(WaveTable *wt, int index)
{
WaveVar *swvar = g_ptr_array_index( wt->swvars, index );
return swvar->varName;
}
int wavetable_is_multisweep( WaveTable *wt)
{
if ( wt->nswvars ){
return 1;
}
return 0;
}
int wavetable_read_vars( WaveTable *wt, int n)
{
int ret;
if ( wt->rdVarsFunc ) {
ret = wt->rdVarsFunc ( wt->dataSrc );
if ( ret <= 0 ) {
if ( n == 0 ) {
return ret;
} else {
msg_dbg("Removing Table %d", wt->ntables - 1);
wavetable_remove( wt, wt->ntables - 1);
return 0;
}
}
}
return 1;
}
int wavetable_fill_tables( WaveTable *wt, char *filename )
{
int ret;
int n = 0;
while ( 1 ) {
if ( (ret = wavetable_read_vars( wt, n)) != 1 ) {
return ret;
}
if ( wt->rdDataFunc ) {
WDataSet *wds;
ret = wt->rdDataFunc( wt->dataSrc );
wds = wavetable_get_cur_dataset(wt);
msg_dbg("Table %d read with %d rows, ret code %d",
wt->ntables - 1, wds->nrows, ret );
if ( ret == 0 && wds->nrows == 0 ) {
msg_warning("Empty table in file %s\n"
"Please, respect the file format.\n",
filename );
wavetable_remove( wt, wt->ntables - 1);
}
if ( ret < 2 ) {
break;
}
wavetable_add( wt);
n++;
}
}
return ret;
}
/*
* Iterate over all WaveVars in all sweeps/segments in the WaveFile,
* calling the function for each one.
*/
void
wavetable_foreach_wavevar(WaveTable *wt, GFunc func, gpointer *p)
{
WaveVar *var;
WDataSet *wds;
int i, j;
for ( i = 0; i < wt->ntables; i++) {
wds = g_ptr_array_index(wt->tables, i);
if (wds->nrows > 0 ){
for (j = 1 ; j < wds->numVars; j++) {
var = (WaveVar *) dataset_get_wavevar( wds, j );
(func)(var, p);
}
}
}
}
2022-09-24 17:54:11 -04:00
typedef struct {
char *name;
int index;
} keyval;
int keyval_compare(const void *k1, const void *k2) {
return strcmp(((keyval*)k1)->name, ((keyval*)k2)->name);
}
/*
* Iterate over all WaveVars in all sweeps/segments in the WaveFile,
* calling the function for each one.
*/
void
wavetable_foreach_wavevar_sorted(WaveTable *wt, GFunc func, gpointer *p)
{
keyval k;
WaveVar *var;
WDataSet *wds;
int i, j;
for ( i = 0; i < wt->ntables; i++) {
wds = g_ptr_array_index(wt->tables, i);
if (wds->nrows > 0 ){
keyval names[wds->numVars-1];
for (j = 1; j < wds->numVars; j++) {
var = (WaveVar *) dataset_get_wavevar(wds, j);
k.index = j;
k.name = wavevar_get_name(var);
names[j-1] = k;
}
qsort(names, wds->numVars-1, sizeof(keyval), &keyval_compare);
for (j = 0 ; j < wds->numVars-1; j++) {
msg_dbg("%d %s %d\n", j, names[j].name, names[j].index);
var = (WaveVar *) dataset_get_wavevar(wds, names[j].index);
(func)(var, p);
}
}
}
}
2022-09-24 17:47:18 -04:00
/*
* find a cooresponding name in new dataset after file reload
* with corresponding table num
*/
WaveVar *wavetable_get_var_for_name(WaveTable *wt, char *varName, int tblno )
{
WDataSet *wds = wavetable_get_dataset( wt, tblno);
if ( wds == NULL ){
return NULL;
}
return ( WaveVar *) dataset_get_var_for_name(wds, varName );
}