summaryrefslogtreecommitdiffhomepage
path: root/src/lingot-config.c
diff options
context:
space:
mode:
authorpp <pp@455248ca-bdda-0310-9134-f4ebb693071a>2008-03-12 14:44:11 +0000
committerpp <pp@455248ca-bdda-0310-9134-f4ebb693071a>2008-03-12 14:44:11 +0000
commit4a2b70d02706c2343fdb31e8c6f50fa20b422b88 (patch)
treea076a5190e1d6d6011093730886f76225834bfb1 /src/lingot-config.c
- initial import of the original 0.7.6 release
git-svn-id: https://lampka.siedziba.pl:790/svn/repos/lingot-win32@291 455248ca-bdda-0310-9134-f4ebb693071a
Diffstat (limited to 'src/lingot-config.c')
-rw-r--r--src/lingot-config.c261
1 files changed, 261 insertions, 0 deletions
diff --git a/src/lingot-config.c b/src/lingot-config.c
new file mode 100644
index 0000000..c03a717
--- /dev/null
+++ b/src/lingot-config.c
@@ -0,0 +1,261 @@
+//-*- C++ -*-
+/*
+ * lingot, a musical instrument tuner.
+ *
+ * Copyright (C) 2004-2007 Ibán Cereijo Graña, Jairo Chapela Martínez.
+ *
+ * This file is part of lingot.
+ *
+ * lingot is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * lingot is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with lingot; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+#include "lingot-config.h"
+#include "lingot-mainframe.h"
+
+// the following tokens will appear in the config file.
+char* token[] =
+ { "AUDIO_DEV", "SAMPLE_RATE", "OVERSAMPLING", "ROOT_FREQUENCY_ERROR",
+ "MIN_FREQUENCY", "FFT_SIZE", "TEMPORAL_WINDOW", "NOISE_THRESHOLD",
+ "CALCULATION_RATE", "VISUALIZATION_RATE", "PEAK_NUMBER", "PEAK_ORDER",
+ "PEAK_REJECTION_RELATION", "DFT_NUMBER", "DFT_SIZE", NULL // NULL terminated array
+ };
+
+// print/scan param formats.
+const char* format = "sddffdffffddfdd";
+
+//----------------------------------------------------------------------------
+
+LingotConfig* lingot_config_new()
+ {
+
+ LingotConfig* config = malloc(sizeof(LingotConfig));
+
+ lingot_config_reset(config); // set default values.
+
+ // internal parameters mapped to each token in the config file.
+ void* c_param[] =
+ { &config->audio_dev, &config->sample_rate, &config->oversampling,
+ &config->root_frequency_error, &config->min_frequency,
+ &config->fft_size, &config->temporal_window,
+ &config->noise_threshold_db, &config->calculation_rate,
+ &config->visualization_rate, &config->peak_number,
+ &config->peak_order, &config->peak_rejection_relation_db,
+ &config->dft_number, &config->dft_size };
+
+ memcpy(config->param, c_param, 15*sizeof(void*));
+
+ return config;
+ }
+
+void lingot_config_destroy(LingotConfig* config)
+ {
+ free(config);
+ }
+
+//----------------------------------------------------------------------------
+void lingot_config_reset(LingotConfig* config)
+ {
+ sprintf(config->audio_dev, "%s", "/dev/dsp");
+
+ config->sample_rate = 8000; // Hz
+ config->oversampling = 5;
+ config->root_frequency_error = 0; // Hz
+ config->min_frequency = 15; // Hz
+ config->fft_size = 512; // samples
+ config->temporal_window = 0.32; // seconds
+ config->calculation_rate = 20; // Hz
+ config->visualization_rate = 30; // Hz
+ config->noise_threshold_db = 20.0; // dB
+
+ config->peak_number = 3; // peaks
+ config->peak_order = 1; // samples
+ config->peak_rejection_relation_db = 20; // dB
+
+ config->dft_number = 2; // DFTs
+ config->dft_size = 15; // samples
+
+ config->max_nr_iter = 10; // iterations
+
+ //--------------------------------------------------------------------------
+
+ config->vr = -0.45; // near to minimum
+
+ lingot_config_update_internal_params(config);
+ }
+
+//----------------------------------------------------------------------------
+
+int lingot_config_update_internal_params(LingotConfig* config)
+ {
+ int result = 1;
+
+ // derived parameters.
+ config->root_frequency = 440.0
+ *pow(2.0, config->root_frequency_error/1200.0);
+ config->temporal_buffer_size = (unsigned int)ceil(config->temporal_window
+ *config->sample_rate/config->oversampling);
+ config->read_buffer_size = (unsigned int)ceil(config->sample_rate
+ /(config->calculation_rate*config->oversampling));
+ config->peak_rejection_relation_nu = pow(10.0,
+ config->peak_rejection_relation_db/10.0);
+ config->noise_threshold_nu = pow(10.0, config->noise_threshold_db/10.0);
+
+ if (config->temporal_buffer_size < config->fft_size)
+ {
+ config->temporal_window = ((double) config->fft_size
+ *config->oversampling)/config->sample_rate;
+ config->temporal_buffer_size = config->fft_size;
+ result = 0;
+ }
+
+ return result;
+ }
+
+//----------------------------------------------------------------------------
+
+void lingot_config_save(LingotConfig* config, char* filename)
+ {
+ unsigned int i;
+ FILE* fp;
+
+ if ((fp = fopen(filename, "w")) == NULL)
+ {
+ char buff[100];
+ sprintf(buff, "error saving config file %s ", filename);
+ perror(buff);
+ return;
+ }
+
+ fprintf(fp, "# Config file automatically created by lingot\n\n");
+
+ for (i = 0; token[i]; i++)
+ switch (format[i])
+ {
+ case 's':
+ fprintf(fp, "%s = %s\n", token[i], (char*) config->param[i]);
+ break;
+ case 'd':
+ fprintf(fp, "%s = %d\n", token[i],
+ *((unsigned int*) config->param[i]));
+ break;
+ case 'f':
+ fprintf(fp, "%s = %0.3f\n", token[i], *((FLT*) config->param[i]));
+ break;
+ }
+
+ fclose(fp);
+ }
+
+//----------------------------------------------------------------------------
+
+void lingot_config_load(LingotConfig* config, char* filename)
+ {
+ FILE* fp;
+ float aux;
+ int line;
+ int token_index;
+ char* char_buffer_pointer;
+
+ const static char* delim = " \t=\n";
+
+# define MAX_LINE_SIZE 100
+
+ char char_buffer[MAX_LINE_SIZE];
+
+ if ((fp = fopen(filename, "r")) == NULL)
+ {
+ sprintf(char_buffer,
+ "error opening config file %s, assuming default values ", filename);
+ perror(char_buffer);
+ return;
+ }
+
+ line = 0;
+
+ for (;;)
+ {
+
+ line++;
+
+ if (!fgets(char_buffer, MAX_LINE_SIZE, fp))
+ break;;
+
+ // printf("line %d: %s\n", line, s1);
+
+ if (char_buffer[0] == '#')
+ continue;
+
+ // tokens into the line.
+ char_buffer_pointer = strtok(char_buffer, delim);
+
+ if (!char_buffer_pointer)
+ continue; // blank line.
+
+ for (token_index = 0; token[token_index]; token_index++)
+ {
+ if (!strcmp(char_buffer_pointer, token[token_index]))
+ {
+ break; // found token.
+ }
+ }
+
+ if (!token[token_index])
+ {
+ fprintf(stderr,
+ "warning: parse error at line %i: unknown keyword %s\n",
+ line, char_buffer_pointer);
+ continue;
+ }
+
+ // take the attribute value.
+ char_buffer_pointer = strtok(NULL, delim);
+
+ if (!char_buffer_pointer)
+ {
+ fprintf(stderr, "warning: parse error at line %i: value expected\n",
+ line);
+ continue;
+ }
+
+ // asign the value to the parameter.
+ switch (format[token_index])
+ {
+ case 's':
+ sprintf(((char*) config->param[token_index]), "%s",
+ char_buffer_pointer);
+ break;
+ case 'd':
+ sscanf(char_buffer_pointer, "%d",
+ (unsigned int*) config->param[token_index]);
+ break;
+ case 'f':
+ sscanf(char_buffer_pointer, "%f", &aux);
+ *((FLT*) config->param[token_index]) = aux;
+ break;
+ }
+
+ }
+
+ fclose(fp);
+
+ lingot_config_update_internal_params(config);
+
+# undef MAX_LINE_SIZE
+ }