summaryrefslogtreecommitdiffhomepage
path: root/src
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
- 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')
-rw-r--r--src/Makefile.am40
-rw-r--r--src/Makefile.in560
-rw-r--r--src/lingot-audio.c220
-rw-r--r--src/lingot-audio.h49
-rw-r--r--src/lingot-background.xpm139
-rw-r--r--src/lingot-complex.c82
-rw-r--r--src/lingot-complex.h45
-rw-r--r--src/lingot-config-dialog.c472
-rw-r--r--src/lingot-config-dialog.h74
-rw-r--r--src/lingot-config.c261
-rw-r--r--src/lingot-config.h109
-rw-r--r--src/lingot-core.c416
-rw-r--r--src/lingot-core.h109
-rw-r--r--src/lingot-defs.h52
-rw-r--r--src/lingot-fft.c177
-rw-r--r--src/lingot-fft.h52
-rw-r--r--src/lingot-filter.c258
-rw-r--r--src/lingot-filter.h66
-rw-r--r--src/lingot-gauge.c92
-rw-r--r--src/lingot-gauge.h46
-rw-r--r--src/lingot-i18n.h42
-rw-r--r--src/lingot-logo.xpm343
-rw-r--r--src/lingot-mainframe.c766
-rw-r--r--src/lingot-mainframe.h82
-rw-r--r--src/lingot-signal.c153
-rw-r--r--src/lingot-signal.h49
-rw-r--r--src/lingot.c132
27 files changed, 4886 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..97a8b32
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,40 @@
+INCLUDES = \
+ $(PACKAGE_CFLAGS) $(GTK_CFLAGS) $(ALSA_CFLAGS)\
+ -DLINGOT_LOCALEDIR=\""$(datadir)/locale"\"
+
+AM_CXXFLAGS =\
+ -Wall
+
+bin_PROGRAMS = lingot
+
+lingot_SOURCES = \
+ lingot-fft.c\
+ lingot-fft.h\
+ lingot-audio.c\
+ lingot-audio.h\
+ lingot-complex.h\
+ lingot-complex.c\
+ lingot-config.c\
+ lingot-config.h\
+ lingot-core.c\
+ lingot-core.h\
+ lingot-defs.h\
+ lingot-config-dialog.c\
+ lingot-config-dialog.h\
+ lingot-gauge.c\
+ lingot-gauge.h\
+ lingot-mainframe.c\
+ lingot-mainframe.h\
+ lingot-filter.c\
+ lingot-filter.h\
+ lingot-signal.c\
+ lingot-signal.h\
+ lingot.c\
+ lingot-i18n.h
+
+lingot_LDFLAGS =
+
+lingot_LDADD = \
+ $(PACKAGE_LIBS) $(GTK_LIBS) $(ALSA_LIBS)\
+ -lpthread
+
diff --git a/src/Makefile.in b/src/Makefile.in
new file mode 100644
index 0000000..d4816fc
--- /dev/null
+++ b/src/Makefile.in
@@ -0,0 +1,560 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+bin_PROGRAMS = lingot$(EXEEXT)
+subdir = src
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)"
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(bin_PROGRAMS)
+am_lingot_OBJECTS = lingot-fft.$(OBJEXT) lingot-audio.$(OBJEXT) \
+ lingot-complex.$(OBJEXT) lingot-config.$(OBJEXT) \
+ lingot-core.$(OBJEXT) lingot-config-dialog.$(OBJEXT) \
+ lingot-gauge.$(OBJEXT) lingot-mainframe.$(OBJEXT) \
+ lingot-filter.$(OBJEXT) lingot-signal.$(OBJEXT) \
+ lingot.$(OBJEXT)
+lingot_OBJECTS = $(am_lingot_OBJECTS)
+am__DEPENDENCIES_1 =
+lingot_DEPENDENCIES = $(am__DEPENDENCIES_1)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(lingot_SOURCES)
+DIST_SOURCES = $(lingot_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GREP = @GREP@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_LIBS = @GTK_LIBS@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_CAVES_RULE = @INTLTOOL_CAVES_RULE@
+INTLTOOL_DESKTOP_RULE = @INTLTOOL_DESKTOP_RULE@
+INTLTOOL_DIRECTORY_RULE = @INTLTOOL_DIRECTORY_RULE@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_ICONV = @INTLTOOL_ICONV@
+INTLTOOL_KBD_RULE = @INTLTOOL_KBD_RULE@
+INTLTOOL_KEYS_RULE = @INTLTOOL_KEYS_RULE@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_MSGFMT = @INTLTOOL_MSGFMT@
+INTLTOOL_MSGMERGE = @INTLTOOL_MSGMERGE@
+INTLTOOL_OAF_RULE = @INTLTOOL_OAF_RULE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_PONG_RULE = @INTLTOOL_PONG_RULE@
+INTLTOOL_PROP_RULE = @INTLTOOL_PROP_RULE@
+INTLTOOL_SCHEMAS_RULE = @INTLTOOL_SCHEMAS_RULE@
+INTLTOOL_SERVER_RULE = @INTLTOOL_SERVER_RULE@
+INTLTOOL_SERVICE_RULE = @INTLTOOL_SERVICE_RULE@
+INTLTOOL_SHEET_RULE = @INTLTOOL_SHEET_RULE@
+INTLTOOL_SOUNDLIST_RULE = @INTLTOOL_SOUNDLIST_RULE@
+INTLTOOL_THEME_RULE = @INTLTOOL_THEME_RULE@
+INTLTOOL_UI_RULE = @INTLTOOL_UI_RULE@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_XAM_RULE = @INTLTOOL_XAM_RULE@
+INTLTOOL_XGETTEXT = @INTLTOOL_XGETTEXT@
+INTLTOOL_XML_NOMERGE_RULE = @INTLTOOL_XML_NOMERGE_RULE@
+INTLTOOL_XML_RULE = @INTLTOOL_XML_RULE@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
+NO_PREFIX_PACKAGE_DATA_DIR = @NO_PREFIX_PACKAGE_DATA_DIR@
+NO_PREFIX_PACKAGE_DOC_DIR = @NO_PREFIX_PACKAGE_DOC_DIR@
+NO_PREFIX_PACKAGE_HELP_DIR = @NO_PREFIX_PACKAGE_HELP_DIR@
+NO_PREFIX_PACKAGE_MENU_DIR = @NO_PREFIX_PACKAGE_MENU_DIR@
+NO_PREFIX_PACKAGE_PIXMAPS_DIR = @NO_PREFIX_PACKAGE_PIXMAPS_DIR@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_DATA_DIR = @PACKAGE_DATA_DIR@
+PACKAGE_DOC_DIR = @PACKAGE_DOC_DIR@
+PACKAGE_HELP_DIR = @PACKAGE_HELP_DIR@
+PACKAGE_MENU_DIR = @PACKAGE_MENU_DIR@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_PIXMAPS_DIR = @PACKAGE_PIXMAPS_DIR@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+POFILES = @POFILES@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+INCLUDES = \
+ $(PACKAGE_CFLAGS) $(GTK_CFLAGS) $(ALSA_CFLAGS)\
+ -DLINGOT_LOCALEDIR=\""$(datadir)/locale"\"
+
+AM_CXXFLAGS = \
+ -Wall
+
+lingot_SOURCES = \
+ lingot-fft.c\
+ lingot-fft.h\
+ lingot-audio.c\
+ lingot-audio.h\
+ lingot-complex.h\
+ lingot-complex.c\
+ lingot-config.c\
+ lingot-config.h\
+ lingot-core.c\
+ lingot-core.h\
+ lingot-defs.h\
+ lingot-config-dialog.c\
+ lingot-config-dialog.h\
+ lingot-gauge.c\
+ lingot-gauge.h\
+ lingot-mainframe.c\
+ lingot-mainframe.h\
+ lingot-filter.c\
+ lingot-filter.h\
+ lingot-signal.c\
+ lingot-signal.h\
+ lingot.c\
+ lingot-i18n.h
+
+lingot_LDFLAGS =
+lingot_LDADD = \
+ $(PACKAGE_LIBS) $(GTK_LIBS) $(ALSA_LIBS)\
+ -lpthread
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ || test -f $$p1 \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(bindir)/$$f"; \
+ done
+
+clean-binPROGRAMS:
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+lingot$(EXEEXT): $(lingot_OBJECTS) $(lingot_DEPENDENCIES)
+ @rm -f lingot$(EXEEXT)
+ $(LINK) $(lingot_LDFLAGS) $(lingot_OBJECTS) $(lingot_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lingot-audio.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lingot-complex.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lingot-config-dialog.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lingot-config.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lingot-core.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lingot-fft.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lingot-filter.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lingot-gauge.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lingot-mainframe.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lingot-signal.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lingot.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+uninstall-info-am:
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+ for dir in "$(DESTDIR)$(bindir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-binPROGRAMS
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-info-am
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+ clean-generic clean-libtool ctags distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-binPROGRAMS install-data install-data-am install-exec \
+ install-exec-am install-info install-info-am install-man \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am \
+ uninstall-binPROGRAMS uninstall-info-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/lingot-audio.c b/src/lingot-audio.c
new file mode 100644
index 0000000..a0776f6
--- /dev/null
+++ b/src/lingot-audio.c
@@ -0,0 +1,220 @@
+//-*- 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 <stdio.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <sys/soundcard.h>
+#include <stdlib.h>
+
+#include "lingot-defs.h"
+#include "lingot-audio.h"
+
+LingotAudio *
+lingot_audio_new (int channels, int rate, int format, char *fdsp)
+{
+ LingotAudio *audio;
+#ifdef ALSA
+ snd_pcm_hw_params_t *hw_params;
+ int err;
+#endif
+
+ audio = malloc (sizeof (LingotAudio));
+ // int dma = 4;
+
+#ifdef ALSA
+
+ if ((err =
+ snd_pcm_open (&audio->capture_handle, "default", SND_PCM_STREAM_CAPTURE,
+ 0)) < 0)
+ {
+ fprintf (stderr, "cannot open audio device %s (%s)\n",
+ fdsp, snd_strerror (err));
+ exit (1);
+ }
+
+ if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0)
+ {
+ fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n",
+ snd_strerror (err));
+ exit (1);
+ }
+
+ if ((err = snd_pcm_hw_params_any (audio->capture_handle, hw_params)) < 0)
+ {
+ fprintf (stderr,
+ "cannot initialize hardware parameter structure (%s)\n",
+ snd_strerror (err));
+ exit (1);
+ }
+
+ if ((err =
+ snd_pcm_hw_params_set_access (audio->capture_handle, hw_params,
+ SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
+ {
+ fprintf (stderr, "cannot set access type (%s)\n", snd_strerror (err));
+ exit (1);
+ }
+
+ if ((err =
+ snd_pcm_hw_params_set_format (audio->capture_handle, hw_params,
+ SND_PCM_FORMAT_S16_LE)) < 0)
+ {
+ fprintf (stderr, "cannot set sample format (%s)\n", snd_strerror (err));
+ exit (1);
+ }
+
+ if ((err =
+ snd_pcm_hw_params_set_rate_near (audio->capture_handle, hw_params,
+ &rate, 0)) < 0)
+ {
+ fprintf (stderr, "cannot set sample rate (%s)\n", snd_strerror (err));
+ exit (1);
+ }
+
+ if ((err =
+ snd_pcm_hw_params_set_channels (audio->capture_handle, hw_params,
+ channels)) < 0)
+ {
+ fprintf (stderr, "cannot set channel count (%s)\n", snd_strerror (err));
+ exit (1);
+ }
+
+ if ((err = snd_pcm_hw_params (audio->capture_handle, hw_params)) < 0)
+ {
+ fprintf (stderr, "cannot set parameters (%s)\n", snd_strerror (err));
+ exit (1);
+ }
+
+ snd_pcm_hw_params_free (hw_params);
+
+ if ((err = snd_pcm_prepare (audio->capture_handle)) < 0)
+ {
+ fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
+ snd_strerror (err));
+ exit (1);
+ }
+
+#else
+
+ audio->dsp = open (fdsp, O_RDONLY);
+ if (audio->dsp < 0)
+ {
+ char buff[80];
+ sprintf (buff, "Unable to open audio device %s", fdsp);
+ perror (buff);
+ exit (-1);
+ }
+
+ //if (ioctl(audio->dsp, SOUND_PCM_READ_CHANNELS, &channels) < 0)
+ if (ioctl (audio->dsp, SNDCTL_DSP_CHANNELS, &channels) < 0)
+ {
+ perror ("Error setting number of channels");
+ exit (-1);
+ }
+
+ /* if (ioctl(audio->dsp, SOUND_PCM_WRITE_CHANNELS, &channels) < 0)
+ {
+ perror("Error setting number of channels");
+ exit(-1);
+ } */
+
+ // sample size
+ //if (ioctl(audio->dsp, SOUND_PCM_SETFMT, &format) < 0)
+ if (ioctl (audio->dsp, SNDCTL_DSP_SETFMT, &format) < 0)
+ {
+ perror ("Error setting bits per sample");
+ exit (-1);
+ }
+
+ int fragment_size = 1;
+ int DMA_buffer_size = 512;
+ int param = 0;
+
+ for (param = 0; fragment_size < DMA_buffer_size; param++)
+ fragment_size <<= 1;
+
+ param |= 0x00ff0000;
+
+ if (ioctl (audio->dsp, SNDCTL_DSP_SETFRAGMENT, &param) < 0)
+ {
+ perror ("Error setting DMA buffer size");
+ exit (-1);
+ }
+
+ // DMA divisor
+ /* if (ioctl(audio->dsp, SNDCTL_DSP_SUBDIVIDE, &dma) < 0)
+ {
+ perror("Error setting DMA divisor");
+ exit(-1);
+ }
+
+ // Rate de muestreo / reproduccion
+ if (ioctl(audio->dsp, SOUND_PCM_WRITE_RATE, &rate) < 0)
+ {
+ perror("Error setting write rate");
+ exit(-1);
+ } */
+
+ // if (ioctl(audio->dsp, SOUND_PCM_READ_RATE, &rate) < 0)
+ if (ioctl (audio->dsp, SNDCTL_DSP_SPEED, &rate) < 0)
+ {
+ perror ("Error setting sample rate");
+ exit (-1);
+ }
+
+ /*
+ // non-blocking reads.
+ if (fcntl(audio->dsp, F_SETFL, O_NONBLOCK) < 0)
+ {
+ perror("Error setting non-blocking reads");
+ exit(-1);
+ }
+ */
+#endif
+
+ return audio;
+}
+
+void
+lingot_audio_destroy (LingotAudio * audio)
+{
+#ifdef ALSA
+ snd_pcm_close (audio->capture_handle);
+#else
+ close (audio->dsp);
+ free (audio);
+#endif
+}
+
+int
+lingot_audio_read (LingotAudio * audio, void *buffer, int size)
+{
+#ifdef ALSA
+ return snd_pcm_readi (audio->capture_handle, buffer, size);
+#else
+ return read (audio->dsp, buffer, size);
+#endif
+}
+
diff --git a/src/lingot-audio.h b/src/lingot-audio.h
new file mode 100644
index 0000000..996c822
--- /dev/null
+++ b/src/lingot-audio.h
@@ -0,0 +1,49 @@
+//-*- 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
+ */
+
+#ifndef __LINGOT_AUDIO_H__
+#define __LINGOT_AUDIO_H__
+
+
+//#define ALSA
+
+#ifdef ALSA
+#include <alsa/asoundlib.h>
+#endif
+
+typedef struct _LingotAudio LingotAudio;
+
+struct _LingotAudio
+ {
+ #ifdef ALSA
+ snd_pcm_t *capture_handle;
+ #else
+ int dsp; // file handler.
+ #endif
+ };
+
+LingotAudio* lingot_audio_new(int channels, int rate, int format, char* fdsp);
+void lingot_audio_destroy(LingotAudio* audio);
+int lingot_audio_read(LingotAudio* audio, void* buffer, int size);
+
+#endif
diff --git a/src/lingot-background.xpm b/src/lingot-background.xpm
new file mode 100644
index 0000000..7cac040
--- /dev/null
+++ b/src/lingot-background.xpm
@@ -0,0 +1,139 @@
+//-*- 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
+ */
+/* XPM */
+static char * background2_xpm[] = {
+"160 100 14 1",
+" c None",
+". c #000000",
+"+ c #EEEEEE",
+"@ c #8B898B",
+"# c #BDEEBD",
+"$ c #EEBABD",
+"% c #B9B9B9",
+"& c #4F4F4F",
+"* c #848484",
+"= c #6A6A6A",
+"- c #D3D3D3",
+"; c #353535",
+"> c #9E9E9E",
+", c #1B1B1B",
+"................................................................................................................................................................",
+".++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++@@@@@@@@@@@@@@@@@@@+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++@@@@@@+++++++++++++++++++@@@@@@+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.",
+".+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++@@@@@+++++++++++++++++++++++++++++++@@@@@++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.",
+".+++++++++++++++++++++++++++++++++++++++++++++++++++++++@@@@+++++++++++++++++++++++++++++++++++++++++@@@@++++++++++++++++++++++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++++++++++++++++++++@@@+++++++++++++++++++++++++++++++++++++++++++++++++@@@+++++++++++++++++++++++++++++++++++++++++++++++++++.",
+".+++++++++++++++++++++++++++++++++++++++++++++++++@@@+++++++++++++++++++++++++++++++++++++++++++++++++++++++@@@++++++++++++++++++++++++++++++++++++++++++++++++.",
+".+++++++++++++++++++++++++++++++++++++++++++++++@@+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++@@++++++++++++++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++++++++++++@@@+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++@@@+++++++++++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++++++++++@@+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++@@+++++++++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++++++++@@+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++@@+++++++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++++++@@+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++@@+++++++++++++++++++++++++++++++++++++.",
+".+++++++++++++++++++++++++++++++++++++@+++++++++++++++++++++++++++++++++++++++++#+++++++++++++++++++++++++++++++++++++++++@++++++++++++++++++++++++++++++++++++.",
+".+++++++++++++++++++++++++++++++++++@@++++++++++++++++++++++++++++++$$$$$###############$$$$$++++++++++++++++++++++++++++++@@++++++++++++++++++++++++++++++++++.",
+".+++++++++++++++++++++++++++++++++@@+++++++++++++++++++++++++++$$$$$$$$$$###############$$$$$$$$$$+++++++++++++++++++++++++++@@++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++@+++++++++++++++++++++++++$$$$$$$$$$$$$$###############$$$$$$$$$$$$$++++++++++++++++++++++++++@+++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++@@+++++++++++++++++++++++$$$$$$$$$$$$$$$$$###############$$$$$$$$$$$$$$$$$+++++++++++++++++++++++@@+++++++++++++++++++++++++++++.",
+".+++++++++++++++++++++++++++++@+++++++++++++++++++++++$$$$$$$$$$$$$$$$$$$###############$$$$$$$$$$$$$$$$$$$+++++++++++++++++++++++@++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++@+++++++++++++++++++++$$$$$$$$$$$$$$$$$$$$$$#######+#######$$$$$$$$$$$$$$$$$$$$$$+++++++++++++++++++++@+++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++@@++++++++++++++++++++$$$$$$$$$$$$$$$$$$$$+++++++++++++++++++++++$$$$$$$$$$$$$$$$$$$$++++++++++++++++++++@@+++++++++++++++++++++++++.",
+".+++++++++++++++++++++++++@++++++++++++++++++++$$$$$$$$$$$$$$$$$+++++++++++++++++++++++++++++++++$$$$$$$$$$$$$$$$$++++++++++++++++++++@++++++++++++++++++++++++.",
+".++++++++++++++++++++++++@+++++++++++++++++++$$$$$$$$$$$$$$$+++++++++++++++++++++++++++++++++++++++++$$$$$$$$$$$$$$$+++++++++++++++++++@+++++++++++++++++++++++.",
+".+++++++++++++++++++++++@++++++++++++++++++$$$$$$$$$$$$$$+++++++++++++++++++++++++++++++++++++++++++++++$$$$$$$$$$$$$$++++++++++++++++++@++++++++++++++++++++++.",
+".++++++++++++++++++++++@+++++++++++++++++$$$$$$$$$$$$$$+++++++++++++++++++++++++++++++++++++++++++++++++++$$$$$$$$$$$$$$+++++++++++++++++@+++++++++++++++++++++.",
+".++++++++++++++++++++@@+++++++++++++++++$$$$$$$$$$$$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++$$$$$$$$$$$$+++++++++++++++++@@+++++++++++++++++++.",
+".+++++++++++++++++++@+++++++++++++++++$$$$$$$$$$$$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$$$$$$$$$$$$+++++++++++++++++@++++++++++++++++++.",
+".++++++++++++++++++@+++++++++++++++++$$$$$$$$$$$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$$$$$$$$$$$+++++++++++++++++@+++++++++++++++++.",
+".+++++++++++++++++@++++++++++++++++$$$$$$$$$$$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$$$$$$$$$$+++++++++++++++++@++++++++++++++++.",
+".++++++++++++++++@++++++++++++++++$$$$$$$$$$$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$$$$$$$$$$$++++++++++++++++@+++++++++++++++.",
+".++++++++++++++++@+++++++++++++++$$$$$$$$$$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$$$$$$$$$$+++++++++++++++@+++++++++++++++.",
+".+++++++++++++++@+++++++++++++++$$$$$$$$$$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$$$$$$$$$$+++++++++++++++@++++++++++++++.",
+".++++++++++++++@+++++++++++++++$$$$$$$$$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$$$$$$$$$+++++++++++++++@+++++++++++++.",
+".+++++++++++++@+++++++++++++++$$$$$$$$$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$$$$$$$$$+++++++++++++++@++++++++++++.",
+".++++++++++++@++++++++++++++$$$$$$$$$$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$$$$$$$$$$++++++++++++++@+++++++++++.",
+".+++++++++++@++++++++++++++$$$$$$$$$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$$$$$$$$$++++++++++++++@++++++++++.",
+".+++++++++++@+++++++++++++$$$$$$$$$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$$$$$$$$$+++++++++++++@++++++++++.",
+".++++++++++@++++++++++++++$$$$$$$$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$$$$$$$$++++++++++++++@+++++++++.",
+".+++++++++@++++++++++++++$$$$$$$$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$$$$$$$$++++++++++++++@++++++++.",
+".++++++++@++++++++++++++$$$$$$$$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$$$$$$$$++++++++++++++@+++++++.",
+".++++++++@+++++++++++++$$$$$$$$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$$$$$$$$+++++++++++++@+++++++.",
+".+++++++@+++++++++++++$$$$$$$$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$$$$$$$$+++++++++++++@++++++.",
+".++++++@+++++++++++++$$$$$$$$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$$$$$$$$+++++++++++++@+++++.",
+".++++++@++++++++++++$$$$$$$$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$$$$$$$+++++++++++++@+++++.",
+".+++++@+++++++++++++$$$$$$$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$$$$$$$+++++++++++++@++++.",
+".+++++@++++++++++++$$$$$$$$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$$$$$$$$++++++++++++@++++.",
+".++++++@@+++++++++$$$$$$$$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$$$$$$$$+++++++++@@+++++.",
+".++++++++@@+++++++$$$$$$$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$$$$$$$+++++++@@+++++++.",
+".++++++++++@@++++$$$$$$$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$$$$$$$++++@@+++++++++.",
+".++++++++++++@++$$$$$$$$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$$$$$$$$++@+++++++++++.",
+".+++++++++++++@@$$$$$$$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$$$$$$$@@++++++++++++.",
+".+++++++++++++++@@$$$$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$$$$@@++++++++++++++.",
+".+++++++++++++++++@$$$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$$$@++++++++++++++++.",
+".++++++++++++++++++@@+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++@@+++++++++++++++++.",
+".++++++++++++++++++++@@+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++@@+++++++++++++++++++.",
+".++++++++++++++++++++++@@+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++@@+++++++++++++++++++++.",
+".++++++++++++++++++++++++@+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++@+++++++++++++++++++++++.",
+".+++++++++++++++++++++++++@@+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++@@++++++++++++++++++++++++.",
+".+++++++++++++++++++++++++++@@+++++++++++++++++++++++++++++++++++++++++++++@@@@@@@@@@@+++++++++++++++++++++++++++++++++++++++++++++@@++++++++++++++++++++++++++.",
+".+++++++++++++++++++++++++++++@++++++++++++++++++++++++++++++++++++++++@@@@+++++++++++@@@@++++++++++++++++++++++++++++++++++++++++@++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++@@++++++++++++++++++++++++++++++++++++@@+++++++++++++++++++@@++++++++++++++++++++++++++++++++++++@@+++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++@@+++++++++++++++++++++++++++++++@@@+++++++++++++++++++++++@@@+++++++++++++++++++++++++++++++@@+++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++@@++++++++++++++++++++++++++++@+++++++++++++++++++++++++++++@++++++++++++++++++++++++++++@@+++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++++@+++++++++++++++++++++++++@@+++++++++++++++++++++++++++++++@@+++++++++++++++++++++++++@+++++++++++++++++++++++++++++++++++.",
+".+++++++++++++++++++++++++++++++++++++@@++++++++++++++++++++++@+++++++++++++++++++++++++++++++++++@++++++++++++++++++++++@@++++++++++++++++++++++++++++++++++++.",
+".+++++++++++++++++++++++++++++++++++++++@@+++++++++++++++++++@+++++++++++++++++++++++++++++++++++++@+++++++++++++++++++@@++++++++++++++++++++++++++++++++++++++.",
+".+++++++++++++++++++++++++++++++++++++++++@+++++++++++++++++@+++++++++++++++++++++++++++++++++++++++@+++++++++++++++++@++++++++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++++++++++@@++++++++++++++@+++++++++++++++++++++++++++++++++++++++++@++++++++++++++@@+++++++++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++++++++++++@@+++++++++++@+++++++++++++++++++++++++++++++++++++++++++@+++++++++++@@+++++++++++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++++++++++++++@@++++++++@+++++++++++++++++++++++++++++++++++++++++++++@++++++++@@+++++++++++++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++++++++++++++++@++++++@+++++++++++++++++++++++++++++++++++++++++++++++@++++++@+++++++++++++++++++++++++++++++++++++++++++++++.",
+".+++++++++++++++++++++++++++++++++++++++++++++++++@@+++@+++++++++++++++++++++++++++++++++++++++++++++++++@+++@@++++++++++++++++++++++++++++++++++++++++++++++++.",
+".+++++++++++++++%&&&++*&&%++++=&%+*-++++++++++++++++@@+@+++++++++++++++++++++++++++++++++++++++++++++++++@+@@++++++++++++++++++++++++*&&*+-=&=-+++-&=-+=+++++++.",
+".+++++++++++++++=-+++**+-;-++=%+&-;+++++++++++++++++++@+++++++++++++++++++++++++++++++++++++++++++++++++++@++++++++++++++++++++++++++&++++;-+%;+++&--=**+++++++.",
+".+++++++++++++++&%>++&+++>>++=>-;=%+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%%+++&>%++&+++&+++;->=;++++++++.",
+".+++++++++++++++.*>;-&+++>>+++=&-;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>>++>,>*&+&+++&+++-&=>*++++++++.",
+".+++++++++++%>>++++-=&+++>>+++++*%==-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%&;;&*++++*%&+++&++++++&-&*++++++.",
+".+++++++++++%>>%%+++&&+++*>+++++&=>-=+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>>++*+++>>&+++;+++++%*;-*%+++++.",
+".++++++++++++++-;-+&%*=+-,-++++**=--=+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>>++>&+-;+;%+>;+++++;-&+*%+++++.",
+".+++++++++++++++-&&%++*&&%+++++=+-==-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--+++>&=-+-=&=-++++-*+%&*++++++.",
+".++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.",
+".++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.",
+"................................................................................................................................................................"};
diff --git a/src/lingot-complex.c b/src/lingot-complex.c
new file mode 100644
index 0000000..9d3b03a
--- /dev/null
+++ b/src/lingot-complex.c
@@ -0,0 +1,82 @@
+//-*- 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 "lingot-complex.h"
+
+/**
+ * addition. All parameters are overlapables.
+ */
+void lingot_complex_add(LingotComplex* a, LingotComplex* b, LingotComplex* c)
+ {
+ c->r = a->r + b->r;
+ c->i = a->i + b->i;
+ }
+
+/**
+ * substraction. All parameters are overlapables.
+ */
+void lingot_complex_sub(LingotComplex* a, LingotComplex* b, LingotComplex* c)
+ {
+ c->r = a->r - b->r;
+ c->i = a->i - b->i;
+ }
+
+/**
+ * multiplication. All parameters are overlapables.
+ */
+void lingot_complex_mul(LingotComplex* a, LingotComplex* b, LingotComplex* c)
+ {
+ if ((c != a) && (c != b))
+ {
+ c->r = a->r*b->r- a->i*b->i;
+ c->i = a->i*b->r+ a->r*b->i;
+ }
+ else
+ {
+ LingotComplex r;
+ r.r = a->r*b->r- a->i*b->i;
+ r.i = a->i*b->r+ a->r*b->i;
+ *c = r;
+ }
+ }
+
+/**
+ * division. All parameters are overlapables.
+ */
+void lingot_complex_div(LingotComplex* a, LingotComplex* b, LingotComplex* c)
+ {
+ FLT bm2 = b->r*b->r + b->i*b->i;
+
+ if ((c != a) && (c != b))
+ {
+ c->r = (a->r*b->r+ a->i*b->i)/bm2;
+ c->i = (a->i*b->r- a->r*b->i)/bm2;
+ }
+ else
+ {
+ LingotComplex r;
+ r.r = (a->r*b->r+ a->i*b->i)/bm2;
+ r.i = (a->i*b->r- a->r*b->i)/bm2;
+ *c = r;
+ }
+ }
diff --git a/src/lingot-complex.h b/src/lingot-complex.h
new file mode 100644
index 0000000..e764ed0
--- /dev/null
+++ b/src/lingot-complex.h
@@ -0,0 +1,45 @@
+//-*- 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
+ */
+
+#ifndef _LINGOT_COMPLEX_H_
+#define _LINGOT_COMPLEX_H_
+
+#include <math.h>
+#include "lingot-defs.h"
+
+// single complex arithmetic :)
+
+typedef struct _LingotComplex LingotComplex;
+
+struct _LingotComplex
+ {
+ FLT r;
+ FLT i;
+ };
+
+void lingot_complex_add(LingotComplex* a, LingotComplex* b, LingotComplex* c);
+void lingot_complex_sub(LingotComplex* a, LingotComplex* b, LingotComplex* c);
+void lingot_complex_mul(LingotComplex* a, LingotComplex* b, LingotComplex* c);
+void lingot_complex_div(LingotComplex* a, LingotComplex* b, LingotComplex* c);
+
+#endif
diff --git a/src/lingot-config-dialog.c b/src/lingot-config-dialog.c
new file mode 100644
index 0000000..c0c707f
--- /dev/null
+++ b/src/lingot-config-dialog.c
@@ -0,0 +1,472 @@
+//-*- 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 <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <unistd.h>
+#include <signal.h>
+
+#include "lingot-defs.h"
+
+#include "lingot-core.h"
+#include "lingot-config.h"
+#include "lingot-mainframe.h"
+#include "lingot-config-dialog.h"
+#include "lingot-i18n.h"
+
+/* button press event attention routine. */
+void lingot_config_dialog_callback_click(GtkButton *button,
+ LingotConfigDialog *dialog)
+ {
+ if ((GtkWidget*)button == dialog->button_ok)
+ {
+ lingot_config_dialog_apply(dialog);
+ lingot_config_save(dialog->conf, CONFIG_FILE_NAME);
+ lingot_config_dialog_close(dialog);
+ }
+ else if ((GtkWidget*)button == dialog->button_cancel)
+ {
+ lingot_mainframe_change_config(dialog->mainframe, dialog->conf_old); // restore old configuration.
+ lingot_config_dialog_close(dialog);
+ }
+ else if ((GtkWidget*)button == dialog->button_apply)
+ {
+ lingot_config_dialog_apply(dialog);
+ lingot_config_dialog_rewrite(dialog);
+ }
+ else if ((GtkWidget*)button == dialog->button_default)
+ {
+ lingot_config_reset(dialog->conf);
+ lingot_config_dialog_rewrite(dialog);
+ }
+ }
+
+void lingot_config_dialog_callback_close(GtkWidget *widget,
+ LingotConfigDialog *dialog)
+ {
+ gtk_widget_destroy(dialog->win);
+ lingot_config_dialog_destroy(dialog);
+ }
+
+void lingot_config_dialog_callback_change_sample_rate(GtkWidget *widget,
+ LingotConfigDialog *dialog)
+ {
+ char buff[20];
+ float sample_rate =atof(gtk_combo_box_get_active_text(GTK_COMBO_BOX(dialog->combo_sample_rate)));
+ float oversampling=
+ gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(dialog->spin_oversampling));
+ sprintf(buff, " = %0.1f", sample_rate/oversampling);
+ gtk_label_set_text ( GTK_LABEL(dialog->label_sample_rate), buff);
+ }
+
+void lingot_config_dialog_callback_change_a_frequence(GtkWidget *widget,
+ LingotConfigDialog *dialog)
+ {
+ char buff[20];
+
+ float root_freq = 440.0*pow(2.0, gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(dialog->spin_root_frequency_error))/1200.0);
+ sprintf(buff, "%% = %0.2f", root_freq);
+ gtk_label_set_text ( GTK_LABEL(dialog->label_root_frequency), buff);
+ }
+
+void lingot_config_dialog_combo_select_value(GtkWidget* combo, int value)
+ {
+
+ GtkTreeModel* model = gtk_combo_box_get_model(GTK_COMBO_BOX(combo));
+ GtkTreeIter iter;
+
+ gboolean valid = gtk_tree_model_get_iter_first (model, &iter);
+
+ while (valid)
+ {
+ gchar *str_data;
+ gtk_tree_model_get (model, &iter, 0, &str_data, -1);
+ if (atoi(str_data) == value)
+ gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo), &iter);
+ g_free (str_data);
+ valid = gtk_tree_model_iter_next (model, &iter);
+ }
+ }
+
+void lingot_config_dialog_rewrite(LingotConfigDialog* dialog)
+ {
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->spin_calculation_rate), dialog->conf->calculation_rate);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->spin_visualization_rate), dialog->conf->visualization_rate);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->spin_oversampling), dialog->conf->oversampling);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->spin_root_frequency_error), dialog->conf->root_frequency_error);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->spin_temporal_window), dialog->conf->temporal_window);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->spin_noise_threshold), dialog->conf->noise_threshold_db);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->spin_dft_number), dialog->conf->dft_number);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->spin_dft_size), dialog->conf->dft_size);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->spin_peak_number), dialog->conf->peak_number);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->spin_peak_order), dialog->conf->peak_order);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(dialog->spin_peak_rejection_relation), dialog->conf->peak_rejection_relation_db);
+ lingot_config_dialog_combo_select_value(dialog->combo_fft_size,
+ (int) dialog->conf->fft_size);
+ lingot_config_dialog_combo_select_value(dialog->combo_sample_rate,
+ (int) dialog->conf->sample_rate);
+ lingot_config_dialog_callback_change_sample_rate(NULL, dialog);
+ lingot_config_dialog_callback_change_a_frequence(NULL, dialog);
+ }
+
+LingotConfigDialog* lingot_config_dialog_new(LingotMainFrame* frame)
+ {
+ GtkWidget* vertical_box;
+ GtkWidget* frame1;
+ GtkWidget* tab1;
+ GtkWidget* frame2;
+ GtkWidget* tab2;
+ GtkWidget* box;
+ char buff[80];
+ LingotConfigDialog* dialog = malloc(sizeof(LingotConfigDialog));
+
+ dialog->mainframe = frame;
+ dialog->conf = lingot_config_new();
+ dialog->conf_old = lingot_config_new();
+
+ // config copy
+ *dialog->conf = *frame->conf;
+ *dialog->conf_old = *frame->conf;
+
+ dialog->win = gtk_dialog_new_with_buttons (_("lingot configuration"),
+ GTK_WINDOW(frame->win), 0, NULL);
+
+ gtk_container_set_border_width(GTK_CONTAINER(dialog->win), 6);
+
+ // items vertically displayed
+ vertical_box = gtk_vbox_new(FALSE, 6);
+ gtk_container_add(GTK_CONTAINER (GTK_DIALOG(dialog->win)->vbox), vertical_box);
+
+ frame1 = gtk_frame_new(_("General parameters"));
+ gtk_box_pack_start_defaults(GTK_BOX(vertical_box), frame1);
+
+ tab1 = gtk_table_new(5, 3, FALSE);
+ int row = 0;
+
+ gtk_table_set_col_spacings(GTK_TABLE(tab1), 20);
+ gtk_table_set_row_spacings(GTK_TABLE(tab1), 3);
+ gtk_container_set_border_width(GTK_CONTAINER(tab1), 5);
+
+ gtk_container_add(GTK_CONTAINER(frame1), tab1);
+
+ // --------------------------------------------------------------------------
+
+ dialog->spin_calculation_rate = gtk_spin_button_new(
+ (GtkAdjustment*)gtk_adjustment_new(dialog->conf->calculation_rate, 1.0,
+ 60.0, 0.5, 10.0, 15.0), 0.5, 1);
+ gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(dialog->spin_calculation_rate), TRUE);
+ gtk_table_attach_defaults(GTK_TABLE(tab1),
+ gtk_label_new(_("Calculation rate")), 0, 1, row, row + 1);
+ gtk_table_attach_defaults(GTK_TABLE(tab1), dialog->spin_calculation_rate, 1, 2, row, row + 1);
+ gtk_table_attach_defaults(GTK_TABLE(tab1), gtk_label_new(_("Hz")), 2, 3, row, row + 1);
+ row++;
+
+ // --------------------------------------------------------------------------
+
+ dialog->spin_visualization_rate =gtk_spin_button_new(
+ (GtkAdjustment*)gtk_adjustment_new(dialog->conf->visualization_rate,
+ 1.0, 60.0, 0.5, 10.0, 15.0), 0.5, 1);
+ gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(dialog->spin_visualization_rate), TRUE);
+ gtk_table_attach_defaults(GTK_TABLE(tab1),
+ gtk_label_new(_("Visualization rate")), 0, 1, row, row + 1);
+ gtk_table_attach_defaults(GTK_TABLE(tab1), dialog->spin_visualization_rate, 1, 2, row, row + 1);
+ gtk_table_attach_defaults(GTK_TABLE(tab1), gtk_label_new(_("Hz")), 2, 3, row, row + 1);
+ row++;
+
+ // --------------------------------------------------------------------------
+
+ dialog->combo_fft_size = gtk_combo_box_new_text();
+ gtk_combo_box_append_text(GTK_COMBO_BOX(dialog->combo_fft_size), "256");
+ gtk_combo_box_append_text(GTK_COMBO_BOX(dialog->combo_fft_size), "512");
+ gtk_combo_box_append_text(GTK_COMBO_BOX(dialog->combo_fft_size), "1024");
+ gtk_combo_box_append_text(GTK_COMBO_BOX(dialog->combo_fft_size), "2048");
+ gtk_combo_box_append_text(GTK_COMBO_BOX(dialog->combo_fft_size), "4096");
+ lingot_config_dialog_combo_select_value(dialog->combo_fft_size,
+ (int) dialog->conf->fft_size);
+
+ gtk_table_attach_defaults(GTK_TABLE(tab1), gtk_label_new(_("FFT size")), 0, 1, row, row + 1);
+ gtk_table_attach_defaults(GTK_TABLE(tab1), dialog->combo_fft_size, 1, 2, row, row + 1);
+ gtk_table_attach_defaults(GTK_TABLE(tab1), gtk_label_new(_("samples")), 2, 3, row, row + 1);
+ row++;
+
+ // --------------------------------------------------------------------------
+
+ dialog->spin_noise_threshold =gtk_spin_button_new(
+ (GtkAdjustment*)gtk_adjustment_new(dialog->conf->noise_threshold_db,
+ -30.0, 60.0, 0.1, 0.1, 0.1), 0.1, 1);
+ gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(dialog->spin_noise_threshold), TRUE);
+ gtk_spin_button_set_digits(GTK_SPIN_BUTTON(dialog->spin_noise_threshold), 1) ;
+
+ gtk_table_attach_defaults(GTK_TABLE(tab1),
+ gtk_label_new(_("Noise threshold")), 0, 1, row, row + 1);
+ gtk_table_attach_defaults(GTK_TABLE(tab1), gtk_label_new(_("dB")), 2, 3, row, row + 1);
+ gtk_table_attach_defaults(GTK_TABLE(tab1), dialog->spin_noise_threshold, 1, 2, row, row + 1);
+ row++;
+
+ // --------------------------------------------------------------------------
+
+ box = gtk_hbox_new (FALSE, FALSE);
+
+ dialog->combo_sample_rate = gtk_combo_box_new_text();
+ gtk_combo_box_append_text(GTK_COMBO_BOX(dialog->combo_sample_rate), "8000");
+ gtk_combo_box_append_text(GTK_COMBO_BOX(dialog->combo_sample_rate), "11025");
+ gtk_combo_box_append_text(GTK_COMBO_BOX(dialog->combo_sample_rate), "22050");
+ gtk_combo_box_append_text(GTK_COMBO_BOX(dialog->combo_sample_rate), "44100");
+
+ lingot_config_dialog_combo_select_value(dialog->combo_sample_rate,
+ (int) dialog->conf->sample_rate);
+
+ dialog->spin_oversampling = gtk_spin_button_new(
+ (GtkAdjustment*) gtk_adjustment_new(dialog->conf->oversampling, 1.0,
+ 30.0, 1.0, 10.0, 15.0), 1.0, 1);
+
+ gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(dialog->spin_oversampling), TRUE);
+ gtk_spin_button_set_digits(GTK_SPIN_BUTTON(dialog->spin_oversampling), 0) ;
+
+ sprintf(buff, " = %0.1f", atof(gtk_combo_box_get_active_text(GTK_COMBO_BOX(dialog->combo_sample_rate)))
+ /gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(dialog->spin_oversampling)));
+ dialog->label_sample_rate = gtk_label_new(buff);
+
+ gtk_box_pack_start (GTK_BOX(box), dialog->combo_sample_rate, FALSE, FALSE, FALSE);
+ gtk_box_pack_start (GTK_BOX(box), gtk_label_new(" / "), FALSE, FALSE, FALSE);
+ gtk_box_pack_start (GTK_BOX(box), dialog->spin_oversampling, FALSE, FALSE, FALSE);
+ gtk_box_pack_start (GTK_BOX(box), dialog->label_sample_rate, FALSE, FALSE, FALSE);
+
+ gtk_signal_connect(GTK_OBJECT(dialog->combo_sample_rate), "changed",
+ GTK_SIGNAL_FUNC (lingot_config_dialog_callback_change_sample_rate), dialog);
+
+ gtk_signal_connect (GTK_OBJECT (dialog->spin_oversampling), "value_changed",
+ GTK_SIGNAL_FUNC (lingot_config_dialog_callback_change_sample_rate), dialog);
+
+ gtk_table_attach_defaults(GTK_TABLE(tab1),
+ gtk_label_new(_("Sample rate")), 0, 1, row, row + 1);
+ gtk_table_attach_defaults(GTK_TABLE(tab1), box, 1, 2, row, row + 1);
+ gtk_table_attach_defaults(GTK_TABLE(tab1), gtk_label_new(_("Hz")), 2, 3, row, row + 1);
+ row++;
+
+ // --------------------------------------------------------------------------
+
+ frame2 = gtk_frame_new(_("Advanced parameters"));
+ gtk_box_pack_start_defaults(GTK_BOX(vertical_box), frame2);
+
+ tab2 = gtk_table_new(7, 3, FALSE);
+ row = 0;
+
+ gtk_table_set_col_spacings(GTK_TABLE(tab2), 20);
+ gtk_table_set_row_spacings(GTK_TABLE(tab2), 3);
+ gtk_container_set_border_width(GTK_CONTAINER(tab2), 5);
+
+ gtk_container_add(GTK_CONTAINER(frame2), tab2);
+
+ // --------------------------------------------------------------------------
+
+ box = gtk_hbox_new (TRUE, FALSE);
+
+ dialog->spin_root_frequency_error = gtk_spin_button_new(
+ (GtkAdjustment*)gtk_adjustment_new(dialog->conf->root_frequency_error,
+ -500.0, +500.0, 1.0, 10.0, 15.0), 1.0, 1);
+
+ gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(dialog->spin_root_frequency_error), TRUE);
+ gtk_spin_button_set_digits(GTK_SPIN_BUTTON(dialog->spin_root_frequency_error), 0) ;
+
+ gtk_box_pack_start (GTK_BOX(box), gtk_label_new(_(" A (440 Hz) + ")), FALSE, FALSE, FALSE);
+ gtk_box_pack_start (GTK_BOX(box), dialog->spin_root_frequency_error, FALSE, TRUE, FALSE);
+
+ sprintf(buff, "%% = %0.2f", dialog->conf->root_frequency);
+ dialog->label_root_frequency = gtk_label_new(_(buff));
+
+ gtk_box_pack_start (GTK_BOX(box), dialog->label_root_frequency, FALSE, FALSE, FALSE);
+
+ gtk_signal_connect (GTK_OBJECT (dialog->spin_root_frequency_error), "value_changed",
+ GTK_SIGNAL_FUNC (lingot_config_dialog_callback_change_a_frequence), dialog);
+
+ gtk_table_attach_defaults(GTK_TABLE(tab2),
+ gtk_label_new(_("Root frequency")), 0, 1, row, row + 1);
+ gtk_table_attach_defaults(GTK_TABLE(tab2), box, 1, 2, row, row + 1);
+ gtk_table_attach_defaults(GTK_TABLE(tab2), gtk_label_new(_("Hz")), 2, 3, row, row + 1);
+ row++;
+
+ // --------------------------------------------------------------------------
+
+ dialog->spin_temporal_window =gtk_spin_button_new(
+ (GtkAdjustment*)gtk_adjustment_new(dialog->conf->temporal_window, 0.0,
+ 15.0, 0.005, 0.1, 0.1), 0.005, 1);
+ gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(dialog->spin_temporal_window), TRUE);
+ gtk_spin_button_set_digits(GTK_SPIN_BUTTON(dialog->spin_temporal_window), 3) ;
+
+ gtk_table_attach_defaults(GTK_TABLE(tab2),
+ gtk_label_new(_("Temporal window")), 0, 1, row, row + 1);
+ gtk_table_attach_defaults(GTK_TABLE(tab2), gtk_label_new(_("seconds")), 2, 3, row, row + 1);
+ gtk_table_attach_defaults(GTK_TABLE(tab2), dialog->spin_temporal_window, 1, 2, row, row + 1);
+ row++;
+
+ // --------------------------------------------------------------------------
+
+ dialog->spin_dft_number =gtk_spin_button_new(
+ (GtkAdjustment*)gtk_adjustment_new(dialog->conf->dft_number, 0.0, 10.0,
+ 1.0, 1.0, 1.0), 1.0, 1);
+ gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(dialog->spin_dft_number), TRUE);
+ gtk_spin_button_set_digits(GTK_SPIN_BUTTON(dialog->spin_dft_number), 0) ;
+
+ gtk_table_attach_defaults(GTK_TABLE(tab2),
+ gtk_label_new(_("DFT number")), 0, 1, row, row + 1);
+ gtk_table_attach_defaults(GTK_TABLE(tab2), dialog->spin_dft_number, 1, 2, row, row + 1);
+ gtk_table_attach_defaults(GTK_TABLE(tab2), gtk_label_new(_("DFTs")), 2, 3, row, row + 1);
+ row++;
+
+ // --------------------------------------------------------------------------
+
+ dialog->spin_dft_size =gtk_spin_button_new(
+ (GtkAdjustment*)gtk_adjustment_new(dialog->conf->dft_size, 4.0, 100.0,
+ 1.0, 1.0, 1.0), 1.0, 1);
+ gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(dialog->spin_dft_size), TRUE);
+ gtk_spin_button_set_digits(GTK_SPIN_BUTTON(dialog->spin_dft_size), 0) ;
+
+ gtk_table_attach_defaults(GTK_TABLE(tab2), gtk_label_new(_("DFT size")), 0, 1, row, row + 1);
+ gtk_table_attach_defaults(GTK_TABLE(tab2), gtk_label_new(_("samples")), 2, 3, row, row + 1);
+ gtk_table_attach_defaults(GTK_TABLE(tab2), dialog->spin_dft_size, 1, 2, row, row + 1);
+ row++;
+
+ // --------------------------------------------------------------------------
+
+ dialog->spin_peak_number =gtk_spin_button_new(
+ (GtkAdjustment*)gtk_adjustment_new(dialog->conf->peak_number, 1.0,
+ 10.0, 1.0, 1.0, 1.0), 1.0, 1);
+ gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(dialog->spin_peak_number), TRUE);
+ gtk_spin_button_set_digits(GTK_SPIN_BUTTON(dialog->spin_peak_number), 0) ;
+
+ gtk_table_attach_defaults(GTK_TABLE(tab2), gtk_label_new(_("Peak number")), 0, 1, row, row + 1);
+ gtk_table_attach_defaults(GTK_TABLE(tab2), dialog->spin_peak_number, 1, 2, row, row + 1);
+ gtk_table_attach_defaults(GTK_TABLE(tab2), gtk_label_new(_("peaks")), 2, 3, row, row + 1);
+ row++;
+
+ // --------------------------------------------------------------------------
+
+ dialog->spin_peak_order = gtk_spin_button_new(
+ (GtkAdjustment*)gtk_adjustment_new(dialog->conf->peak_order, 1.0, 5.0,
+ 1.0, 1.0, 1.0), 1.0, 1);
+ gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(dialog->spin_peak_order), TRUE);
+ gtk_spin_button_set_digits(GTK_SPIN_BUTTON(dialog->spin_peak_order), 0) ;
+
+ gtk_table_attach_defaults(GTK_TABLE(tab2), gtk_label_new(_("Peak order")), 0, 1, row, row + 1);
+ gtk_table_attach_defaults(GTK_TABLE(tab2), dialog->spin_peak_order, 1, 2, row, row + 1);
+ gtk_table_attach_defaults(GTK_TABLE(tab2), gtk_label_new(_("samples")), 2, 3, row, row + 1);
+ row++;
+
+ // --------------------------------------------------------------------------
+
+ dialog->spin_peak_rejection_relation
+ = gtk_spin_button_new(
+ (GtkAdjustment*)gtk_adjustment_new(
+ dialog->conf->peak_rejection_relation_db, 2.0, 40.0, 0.1, 1.0,
+ 1.0), 0.1, 1);
+ gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(dialog->spin_peak_rejection_relation), TRUE);
+ gtk_spin_button_set_digits(GTK_SPIN_BUTTON(dialog->spin_peak_rejection_relation), 1);
+
+ gtk_table_attach_defaults(GTK_TABLE(tab2),
+ gtk_label_new(_("Rejection peak relation")), 0, 1, row, row + 1);
+ gtk_table_attach_defaults(GTK_TABLE(tab2), dialog->spin_peak_rejection_relation, 1, 2, row, row + 1);
+ gtk_table_attach_defaults(GTK_TABLE(tab2), gtk_label_new(_("dB")), 2, 3, row, row + 1);
+ row++;
+
+ // --------------------------------------------------------------------------
+
+ dialog->button_ok = gtk_button_new_from_stock(GTK_STOCK_OK);
+ dialog->button_cancel = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
+ dialog->button_apply = gtk_button_new_from_stock(GTK_STOCK_APPLY);
+ dialog->button_default = gtk_button_new_with_label(_("Default config"));
+
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog->win)->action_area), dialog->button_default, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog->win)->action_area), dialog->button_apply, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog->win)->action_area), dialog->button_ok, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog->win)->action_area), dialog->button_cancel, TRUE, TRUE, 0);
+
+ g_signal_connect(GTK_OBJECT(dialog->button_default), "clicked", GTK_SIGNAL_FUNC(lingot_config_dialog_callback_click), dialog);
+ g_signal_connect(GTK_OBJECT(dialog->button_apply), "clicked", GTK_SIGNAL_FUNC(lingot_config_dialog_callback_click), dialog);
+ g_signal_connect(GTK_OBJECT(dialog->button_ok), "clicked", GTK_SIGNAL_FUNC(lingot_config_dialog_callback_click), dialog);
+ g_signal_connect(GTK_OBJECT(dialog->button_cancel), "clicked", GTK_SIGNAL_FUNC(lingot_config_dialog_callback_click), dialog);
+
+ g_signal_connect(GTK_OBJECT(dialog->win), "destroy", GTK_SIGNAL_FUNC(lingot_config_dialog_callback_close), dialog);
+
+ lingot_config_dialog_rewrite(dialog);
+ gtk_window_set_resizable(GTK_WINDOW(dialog->win), FALSE);
+ gtk_widget_show_all(dialog->win);
+
+ return dialog;
+ }
+
+void lingot_config_dialog_destroy(LingotConfigDialog* dialog)
+ {
+ dialog->mainframe->config_dialog = NULL;
+ lingot_config_destroy(dialog->conf);
+ lingot_config_destroy(dialog->conf_old);
+
+ //gtk_widget_destroy(dialog->win);
+ free(dialog);
+ }
+
+void lingot_config_dialog_apply(LingotConfigDialog* dialog)
+ {
+ GtkWidget* message_dialog;
+
+ dialog->conf->root_frequency_error = gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(dialog->spin_root_frequency_error));
+ dialog->conf->calculation_rate = gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(dialog->spin_calculation_rate));
+ dialog->conf->visualization_rate = gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(dialog->spin_visualization_rate));
+ dialog->conf->temporal_window = gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(dialog->spin_temporal_window));
+ dialog->conf->noise_threshold_db = gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(dialog->spin_noise_threshold));
+ dialog->conf->oversampling
+ = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(dialog->spin_oversampling));
+ dialog->conf->dft_number= gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(dialog->spin_dft_number));
+ dialog->conf->dft_size = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(dialog->spin_dft_size));
+ dialog->conf->peak_number
+ = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(dialog->spin_peak_number));
+ dialog->conf->peak_order= gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(dialog->spin_peak_order));
+ dialog->conf->peak_rejection_relation_db
+ = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(dialog->spin_peak_rejection_relation));
+ dialog->conf->fft_size = atoi(gtk_combo_box_get_active_text(GTK_COMBO_BOX(dialog->combo_fft_size)));
+ dialog->conf->sample_rate
+ = atoi(gtk_combo_box_get_active_text(GTK_COMBO_BOX(dialog->combo_sample_rate)));
+
+ int result = lingot_config_update_internal_params(dialog->conf);
+
+ lingot_mainframe_change_config(dialog->mainframe, dialog->conf);
+
+ if (!result)
+ {
+ message_dialog
+ = gtk_message_dialog_new(
+ GTK_WINDOW(dialog->win),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_INFO,
+ GTK_BUTTONS_CLOSE,
+ _("Temporal buffer is smaller than FFT size. It has been increased to %0.3f seconds"), dialog->conf->temporal_window);
+ gtk_dialog_run(GTK_DIALOG(message_dialog));
+ gtk_widget_destroy (message_dialog);
+ }
+ }
+
+void lingot_config_dialog_close(LingotConfigDialog* dialog)
+ {
+ gtk_widget_destroy(dialog->win);
+ }
diff --git a/src/lingot-config-dialog.h b/src/lingot-config-dialog.h
new file mode 100644
index 0000000..208e020
--- /dev/null
+++ b/src/lingot-config-dialog.h
@@ -0,0 +1,74 @@
+//-*- 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
+ */
+
+#ifndef __LINGOT_CONFIG_DIALOG_H__
+#define __LINGOT_CONFIG_DIALOG_H__
+
+#include <gtk/gtk.h>
+
+#include "lingot-config.h"
+
+typedef struct _LingotConfigDialog LingotConfigDialog;
+
+struct _LingotConfigDialog
+ {
+
+ // widgets that contains configuration information.
+ GtkWidget* spin_calculation_rate;
+ GtkWidget* spin_visualization_rate;
+ GtkWidget* spin_oversampling;
+ GtkWidget* spin_root_frequency_error;
+ GtkWidget* spin_temporal_window;
+ GtkWidget* spin_noise_threshold;
+ GtkWidget* spin_dft_number;
+ GtkWidget* spin_dft_size;
+ GtkWidget* spin_peak_number;
+ GtkWidget* spin_peak_order;
+ GtkWidget* spin_peak_rejection_relation;
+ GtkWidget* combo_fft_size;
+ GtkWidget* combo_sample_rate;
+
+ GtkWidget* button_ok;
+ GtkWidget* button_cancel;
+ GtkWidget* button_apply;
+ GtkWidget* button_default;
+
+ GtkWidget* label_sample_rate;
+ GtkWidget* label_root_frequency;
+
+ LingotConfig* conf; // provisional configuration.
+ LingotConfig* conf_old; // restoration point for cancel.
+
+ LingotMainFrame* mainframe;
+
+ GtkWidget* win; // window
+ };
+
+LingotConfigDialog* lingot_config_dialog_new(LingotMainFrame*);
+void lingot_config_dialog_destroy(LingotConfigDialog*);
+
+void lingot_config_dialog_rewrite(LingotConfigDialog*);
+void lingot_config_dialog_apply(LingotConfigDialog*);
+void lingot_config_dialog_close(LingotConfigDialog*);
+
+#endif // __LINGOT_CONFIG_DIALOG_H__
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
+ }
diff --git a/src/lingot-config.h b/src/lingot-config.h
new file mode 100644
index 0000000..174730d
--- /dev/null
+++ b/src/lingot-config.h
@@ -0,0 +1,109 @@
+//-*- 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
+ */
+
+#ifndef __LINGOT_CONFIG_H__
+#define __LINGOT_CONFIG_H__
+
+#include "lingot-defs.h"
+
+/*
+ Configuration class. Determines the tuner's behaviour.
+ Some parameters are internal only.
+ */
+
+typedef struct _LingotConfig LingotConfig;
+
+struct _LingotConfig
+ {
+ void* param[15]; // parameter pointer array.
+
+ char audio_dev[80]; // default "/dev/dsp"
+ unsigned int sample_rate; // soundcard sample rate.
+ unsigned int oversampling; // oversampling factor.
+
+ // frequency of the root A note (internal parameter).
+ FLT root_frequency;
+
+ FLT root_frequency_error; // deviation of the above root frequency.
+
+ FLT min_frequency; // minimum valid frequency.
+
+ unsigned int fft_size; // number of samples of the FFT.
+
+ FLT calculation_rate;
+ FLT visualization_rate;
+
+ FLT temporal_window; // duration in seconds of the temporal window.
+
+ // samples stored in the temporal window (internal parameter).
+ unsigned int temporal_buffer_size;
+
+ // samples read from soundcard. (internal parameter)
+ unsigned int read_buffer_size;
+
+ FLT noise_threshold_db; // dB
+ FLT noise_threshold_nu; // natural units (internal parameter)
+
+ // frequency finding algorithm configuration
+ //-------------------------------------------
+
+ unsigned int peak_number; // number of maximum peaks considered.
+
+ // number of adyacent samples needed to consider a peak.
+ unsigned int peak_order;
+
+ /* maximum amplitude relation between principal and secondary peaks.
+ The max peak doesn't has to be the fundamental frequency carrier if it
+ has an amplitude relation with the fundamental considered peak lower than
+ this parameter. */
+ FLT peak_rejection_relation_db; // dBs
+ FLT peak_rejection_relation_nu; // natural units (internal)
+
+ // DFT approximation
+ unsigned int dft_number; // number of DFTs.
+ unsigned int dft_size; // samples of each DFT.
+
+ // max iterations for Newton-Raphson algorithm.
+ unsigned int max_nr_iter;
+
+ //----------------------------------------------------------------------------
+
+ // gauge rest value. (gauge contemplates [-0.5, 0.5])
+ FLT vr;
+
+ //----------------------------------------------------------------------------
+ };
+
+LingotConfig* lingot_config_new();
+void lingot_config_destroy(LingotConfig*);
+
+// back to default configuration.
+void lingot_config_reset(LingotConfig*);
+
+// derivate internal parameters from external ones.
+int lingot_config_update_internal_params(LingotConfig*);
+
+void lingot_config_save(LingotConfig*, char* filename);
+void lingot_config_load(LingotConfig*, char* filename);
+
+#endif // __LINGOT_CONFIG_H__
diff --git a/src/lingot-core.c b/src/lingot-core.c
new file mode 100644
index 0000000..d0cdaec
--- /dev/null
+++ b/src/lingot-core.c
@@ -0,0 +1,416 @@
+//-*- 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 <stdio.h>
+#include <math.h>
+#include <sys/soundcard.h>
+#include <string.h>
+#include <errno.h>
+
+#ifndef LIB_FFTW
+# include "lingot-complex.h"
+#endif
+
+#include "lingot-fft.h"
+#include "lingot-signal.h"
+#include "lingot-core.h"
+#include "lingot-config.h"
+
+LingotCore* lingot_core_new(LingotConfig* conf) {
+
+ LingotCore* core = malloc(sizeof(LingotCore));
+
+ core->conf = conf;
+ core->running = 1;
+
+# ifdef LIBSNDOBJ
+# ifdef OSS
+ core->audio = new SndRTIO(1, SND_INPUT, 512, 512, SHORTSAM_LE, NULL,
+ core->conf->read_buffer_size*core->conf->oversampling, core->conf->sample_rate, core->conf->audio_dev);
+# endif
+# ifdef ALSA
+ core->audio = new SndRTIO(1, SND_INPUT, 512, 4, SHORTSAM_LE, NULL,
+ core->conf->read_buffer_size*core->conf->oversampling, core->conf->sample_rate, "plughw:0,0");
+# endif
+# else
+ // creates an audio handler.
+ core->audio = lingot_audio_new(1, core->conf->sample_rate, SAMPLE_FORMAT,
+ core->conf->audio_dev);
+# endif
+
+ // since the SPD is simmetrical, we only store the 1st half.
+ if (core->conf->fft_size > 256) {
+ core->spd_fft = malloc((core->conf->fft_size >> 1)*sizeof(FLT));
+ core->X = malloc((core->conf->fft_size >> 1)*sizeof(FLT));
+ memset(core->spd_fft, 0, (core->conf->fft_size >> 1)*sizeof(FLT));
+ memset(core->X, 0, (core->conf->fft_size >> 1)*sizeof(FLT));
+ } else { // if the fft size is 256, we store the whole signal for representation.
+ core->spd_fft = malloc((core->conf->fft_size)*sizeof(FLT));
+ core->X = malloc((core->conf->fft_size)*sizeof(FLT));
+ memset(core->spd_fft, 0, core->conf->fft_size*sizeof(FLT));
+ memset(core->X, 0, (core->conf->fft_size)*sizeof(FLT));
+ }
+
+ core->spd_dft = malloc((core->conf->dft_size)*sizeof(FLT));
+ memset(core->spd_dft, 0, core->conf->dft_size*sizeof(FLT));
+
+ core->diff2_spd_fft = malloc(core->conf->fft_size*sizeof(FLT)); // 2nd derivative from SPD.
+ memset(core->diff2_spd_fft, 0, core->conf->fft_size*sizeof(FLT));
+
+ memset(core->spd_dft, 0, core->conf->dft_size*sizeof(FLT));
+
+#ifndef LIB_FFTW
+ lingot_fft_create_phase_factors(conf); // creates the phase factors for FFT.
+ core->fft_out = malloc((core->conf->fft_size)*sizeof(LingotComplex)); // complex signal in freq domain.
+ memset(core->fft_out, 0, core->conf->fft_size*sizeof(LingotComplex));
+#else
+ core->fftw_in = new fftw_complex[core->conf->fft_size];
+ memset(core->fftw_in, 0, core->conf->fft_size*sizeof(fftw_complex));
+ core->fftw_out = new fftw_complex[core->conf->fft_size];
+ memset(core->fftw_out, 0, core->conf->fft_size*sizeof(fftw_complex));
+ core->fftwplan = fftw_create_plan(core->conf->fft_size, FFTW_FORWARD, FFTW_ESTIMATE);
+#endif
+
+ // read buffer from soundcard.
+ core->read_buffer= malloc((core->conf->read_buffer_size
+ *core->conf->oversampling)*sizeof(SAMPLE_TYPE));
+ memset(core->read_buffer, 0, (core->conf->read_buffer_size
+ *core->conf->oversampling)*sizeof(SAMPLE_TYPE));
+
+ // read buffer from soundcard in floating point format.
+ core->flt_read_buffer= malloc((core->conf->read_buffer_size
+ *core->conf->oversampling)*sizeof(FLT));
+ memset(core->flt_read_buffer, 0, (core->conf->read_buffer_size
+ *core->conf->oversampling)*sizeof(FLT));
+
+ // stored samples.
+ core->temporal_buffer = malloc((core->conf->temporal_buffer_size)
+ *sizeof(FLT));
+ memset(core->temporal_buffer, 0, core->conf->temporal_buffer_size
+ *sizeof(FLT));
+
+ core->hamming_window_temporal = malloc((core->conf->temporal_buffer_size)
+ *sizeof(FLT));
+ lingot_signal_hamming_window(core->conf->temporal_buffer_size,
+ core->hamming_window_temporal);
+ core->hamming_window_fft = malloc((core->conf->fft_size) *sizeof(FLT));
+ lingot_signal_hamming_window(core->conf->fft_size, core->hamming_window_fft);
+
+ core->windowed_temporal_buffer = malloc((core->conf->temporal_buffer_size)
+ *sizeof(FLT));
+ memset(core->windowed_temporal_buffer, 0, core->conf->temporal_buffer_size
+ *sizeof(FLT));
+ core->windowed_fft_buffer = malloc((core->conf->fft_size) *sizeof(FLT));
+ memset(core->windowed_fft_buffer, 0, core->conf->fft_size *sizeof(FLT));
+
+ /*
+ * 8 order Chebyshev filters, with wc=0.9/i (normalized respect to
+ * Pi). We take 0.9 instead of 1 to leave a 10% of safety margin,
+ * in order to avoid aliased frequencies near to w=Pi, due to non
+ * ideality of the filter.
+ *
+ * The cut frequencies wc=Pi/i, with i=1..20, correspond with the
+ * oversampling factor, avoiding aliasing at decimation.
+ *
+ * Why Chebyshev filters?, for a given order, those filters yield
+ * abrupt falls than other ones as Butterworth, making the most of
+ * the order. Although Chebyshev filters affects more to the phase,
+ * it doesn't matter due to the analysis is made on the signal
+ * power distribution (only module).
+ */
+ core->antialiasing_filter= lingot_filter_cheby_design(8, 0.5, 0.9
+ /core->conf->oversampling);
+
+ // ------------------------------------------------------------
+
+ core->freq = 0.0;
+ return core;
+}
+
+// -----------------------------------------------------------------------
+
+/* Deallocate resources */
+void lingot_core_destroy(LingotCore* core) {
+ pthread_attr_destroy(&core->attr);
+
+#ifdef LIB_FFTW
+ fftw_destroy_plan(core->fftwplan);
+ free(core->fftw_in);
+ free(core->fftw_out);
+#else
+ lingot_fft_destroy_phase_factors(); // destroy phase factors.
+ free(core->fft_out);
+#endif
+
+ lingot_audio_destroy(core->audio);
+
+ free(core->spd_fft);
+ free(core->X);
+ free(core->spd_dft);
+ free(core->diff2_spd_fft);
+ free(core->read_buffer);
+ free(core->flt_read_buffer);
+ free(core->temporal_buffer);
+
+ free(core->windowed_temporal_buffer);
+ free(core->windowed_fft_buffer);
+
+ free(core->hamming_window_temporal);
+ free(core->hamming_window_fft);
+
+ lingot_filter_destroy(core->antialiasing_filter);
+
+ free(core);
+}
+
+// -----------------------------------------------------------------------
+
+// signal decimation with antialiasing, in & out overlapables.
+void lingot_core_decimate(LingotCore* core, FLT* in, FLT* out) {
+ register unsigned int i, j;
+
+ // low pass filter to avoid aliasing.
+ lingot_filter_filter(core->antialiasing_filter,
+ core->conf->read_buffer_size*core->conf->oversampling, in, in);
+
+ // compression.
+ for (i = j = 0; i < core->conf->read_buffer_size; i++, j
+ += core->conf->oversampling)
+ out[i] = in[j];
+}
+
+// -----------------------------------------------------------------------
+
+void lingot_core_process(LingotCore* core) {
+ register unsigned int i, k; // loop variables.
+ FLT delta_w_FFT = 2.0*M_PI/core->conf->fft_size;
+ // FFT resolution in rads.
+
+# ifdef LIBSNDOBJ
+ audio->Read();
+ for (i = 0; i < core->conf->oversampling*core->conf->read_buffer_size; i++)
+ flt_read_buffer[i] = audio->Output(i);
+# else
+ if ((lingot_audio_read(core->audio, core->read_buffer,
+ core->conf->oversampling*core->conf->read_buffer_size
+ *sizeof(SAMPLE_TYPE)))< 0) {
+ //perror("Error reading samples");
+ return;
+ }
+
+ for (i = 0; i < core->conf->oversampling*core->conf->read_buffer_size; i++)
+ core->flt_read_buffer[i] = core->read_buffer[i];
+# endif
+
+ //
+ // just readed:
+ //
+ // ----------------------------
+ // |bxxxbxxxbxxxbxxxbxxxbxxxbxxx|
+ // ----------------------------
+ //
+ // <----------------------------> read_buffer_size*oversampling
+ //
+
+ /* we shift the temporal window to leave a hollow where place the new piece
+ of data read. The buffer is actually a queue. */
+ if (core->conf->temporal_buffer_size > core->conf->read_buffer_size)
+ memcpy(core->temporal_buffer,
+ &core->temporal_buffer[core->conf->read_buffer_size],
+ (core->conf->temporal_buffer_size
+ - core->conf->read_buffer_size) *sizeof(FLT));
+
+ //
+ // previous buffer situation:
+ //
+ // ------------------------------------------
+ // | xxxxxxxxxxxxxxxxxxxxxx | yyyyy | aaaaaaa |
+ // ------------------------------------------
+ // <------> read_buffer_size
+ // <---------------> fft_size
+ // <----------------------------------------> temporal_buffer_size
+ //
+ // new situation:
+ //
+ // ------------------------------------------
+ // | xxxxxxxxxxxxxxxxyyyyaa | aaaaa | |
+ // ------------------------------------------
+ //
+
+ /* we decimate the read signal and put it at the end of the buffer. */
+ if (core->conf->oversampling > 1)
+ lingot_core_decimate(
+ core,
+ core->flt_read_buffer,
+ &core->temporal_buffer[core->conf->temporal_buffer_size - core->conf->read_buffer_size]);
+ else
+ memcpy(
+ &core->temporal_buffer[core->conf->temporal_buffer_size - core->conf->read_buffer_size],
+ core->flt_read_buffer, core->conf->read_buffer_size*sizeof(FLT));
+ //
+ // ------------------------------------------
+ // | xxxxxxxxxxxxxxxxyyyyaa | aaaaa | bbbbbbb |
+ // ------------------------------------------
+ //
+
+ // ----------------- TRANSFORMATION TO FREQUENCY DOMAIN ----------------
+
+ FLT _1_N2 = 1.0/(core->conf->fft_size*core->conf->fft_size);
+ // SPD normalization constant
+
+ // windowing
+ for (i = 0; i < core->conf->fft_size; i++) {
+ core->windowed_fft_buffer[i]
+ = core->temporal_buffer[core->conf->temporal_buffer_size - core->conf->fft_size + i]
+ *core->hamming_window_fft[i];
+ }
+
+# ifdef LIB_FFTW
+ for (i = 0; i < core->conf->fft_size; i++)
+ fftw_in[i].re = core->windowed_fft_buffer[i];
+
+ // transformation.
+ fftw_one(core->fftwplan, core->fftw_in, core->fftw_out);
+
+ // esteem of SPD from FFT. (normalized squared module)
+ for (i = 0; i < ((core->conf->fft_size > 256) ? (core->conf->fft_size >> 1) : 256); i++)
+ core->spd_fft[i] = (core->fftw_out[i].re*core->fftw_out[i].re +
+ core->fftw_out[i].im*core->fftw_out[i].im)*_1_N2;
+# else
+
+ // transformation.
+ lingot_fft_fft(core->windowed_fft_buffer, core->fft_out,
+ core->conf->fft_size);
+
+ // esteem of SPD from FFT. (normalized squared module)
+ for (i = 0; i < ((core->conf->fft_size > 256) ? (core->conf->fft_size >> 1)
+ : 256); i++)
+ core->spd_fft[i] = (core->fft_out[i].r*core->fft_out[i].r
+ + core->fft_out[i].i*core->fft_out[i].i)*_1_N2;
+# endif
+
+ // representable piece
+ memcpy(core->X, core->spd_fft,
+ ((core->conf->fft_size > 256) ? (core->conf->fft_size >> 1) : 256)
+ *sizeof(FLT));
+
+ // truncated 2nd derivative esteem, to enhance peaks
+ core->diff2_spd_fft[0] = 0.0;
+ for (i = 1; i < (core->conf->fft_size >> 1) - 1; i++) {
+ core->diff2_spd_fft[i] = 2.0*core->spd_fft[i]- core->spd_fft[i - 1]
+ - core->spd_fft[i + 1]; // centred 2nd order derivative, to avoid group delay.
+ if (core->diff2_spd_fft[i] < 0.0)
+ core->diff2_spd_fft[i] = 0.0; // truncation
+ }
+
+ // peaks searching in that signal.
+ int Mi = lingot_signal_get_fundamental_peak(core->conf, core->spd_fft,
+ core->diff2_spd_fft, (core->conf->fft_size >> 1)); // take the fundamental peak.
+
+ if (Mi == (signed) (core->conf->fft_size >> 1)) {
+ core->freq = 0.0;
+ return;
+ }
+
+ FLT w = (Mi - 1)*delta_w_FFT;
+ // frecuencia de la muestra anterior al pico.
+
+ // Approximation to fundamental frequency by selective DFTs
+ // ---------------------------------------------------------
+
+ FLT d_w = delta_w_FFT;
+ for (k = 0; k < core->conf->dft_number; k++) {
+
+ d_w = 2.0*d_w/(core->conf->dft_size - 1); // resolution in rads.
+
+ if (k == 0) {
+ lingot_fft_spd(core->windowed_fft_buffer, core->conf->fft_size, w
+ + d_w, d_w, &core->spd_dft[1], core->conf->dft_size- 2);
+ core->spd_dft[0] = core->spd_fft[Mi - 1];
+ core->spd_dft[core->conf->dft_size - 1] = core->spd_fft[Mi + 1]; // 2 samples known.
+ } else
+ lingot_fft_spd(core->windowed_fft_buffer, core->conf->fft_size, w,
+ d_w, core->spd_dft, core->conf->dft_size);
+
+ lingot_signal_get_max(core->spd_dft, core->conf->dft_size, &Mi); // search the maximum.
+
+ w += (Mi - 1)*d_w; // previous sample to the peak.
+ }
+
+ w += d_w; // approximation by DFTs.
+
+ // windowing
+ for (i = 0; i < core->conf->temporal_buffer_size; i++) {
+ core->windowed_temporal_buffer[i] = core->temporal_buffer[i]
+ *core->hamming_window_temporal[i];
+ }
+
+ // Maximum finding by Newton-Raphson
+ // -----------------------------------
+
+ FLT wk = -1.0e5;
+ FLT wkm1 = w;
+ // first iterator set to the current approximation.
+ FLT d1_SPD, d2_SPD;
+
+ for (k = 0; (k < core->conf->max_nr_iter) && (fabs(wk - wkm1) > 1.0e-8); k++) {
+ wk = wkm1;
+
+ // ! we use the WHOLE temporal window for greater precission.
+ lingot_fft_spd_diffs(core->windowed_temporal_buffer,
+ core->conf->temporal_buffer_size, wk, &d1_SPD, &d2_SPD);
+ //printf("%f %f %f\n", wk, d1_SPD, d2_SPD);
+ wkm1 = wk - d1_SPD/d2_SPD;
+ }
+
+ w = wkm1; // frequency in rads.
+ core->freq = (w*core->conf->sample_rate) /(2.0*M_PI
+ *core->conf->oversampling); // analog frequency.
+
+}
+
+/* start running the core in another thread */
+void lingot_core_start(LingotCore* core) {
+ pthread_attr_init(&core->attr);
+
+ // detached thread.
+ // pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ pthread_create(&core->thread, &core->attr, (void* (*)(void*)) lingot_core_run, core);
+}
+
+/* stop running the core */
+void lingot_core_stop(LingotCore* core) {
+ void* thread_result;
+
+ core->running = 0;
+
+ // wait for the thread exit
+ pthread_join(core->thread, &thread_result);
+}
+
+/* run the core */
+void lingot_core_run(LingotCore* core) {
+ while (core->running) {
+ lingot_core_process(core); // process new data block.
+ }
+}
diff --git a/src/lingot-core.h b/src/lingot-core.h
new file mode 100644
index 0000000..1d58b9a
--- /dev/null
+++ b/src/lingot-core.h
@@ -0,0 +1,109 @@
+//-*- 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
+ */
+
+#ifndef __LINGOT_CORE_H__
+#define __LINGOT_CORE_H__
+
+#include <pthread.h>
+
+#include "lingot-defs.h"
+#include "lingot-complex.h"
+#include "lingot-filter.h"
+#include "lingot-config.h"
+
+#ifdef LIB_FFTW
+# include <fftw.h>
+#endif
+
+#ifdef LIBSNDOBJ
+# include <SndObj/AudioDefs.h>
+#else
+# include "lingot-audio.h"
+#endif
+
+typedef struct _LingotCore LingotCore;
+
+struct _LingotCore {
+
+ // -- shared data --
+ FLT freq; // analog frequency calculated.
+ FLT* X; // visual portion of FFT.
+ // -- shared data --
+
+# ifdef LIBSNDOBJ
+ SndRTIO* audio; // audio handler.
+# else
+ LingotAudio* audio; // audio handler.
+# endif
+
+ SAMPLE_TYPE* read_buffer;
+ FLT* flt_read_buffer;
+ FLT* temporal_buffer; // sample memory.
+
+ // precomputed hamming windows
+ FLT* hamming_window_temporal;
+ FLT* hamming_window_fft;
+
+ // windowed signals
+ FLT* windowed_temporal_buffer;
+ FLT* windowed_fft_buffer;
+
+ // spectral power distribution esteem.
+ FLT* spd_fft;
+ FLT* spd_dft;
+ FLT* diff2_spd_fft;
+
+# ifdef LIB_FFTW
+ fftw_complex* fftw_in;
+ fftw_complex* fftw_out; // complex signals in time and freq.
+ fftw_plan fftwplan;
+# else
+ LingotComplex* fft_out; // complex signal in freq.
+# endif
+
+ LingotFilter* antialiasing_filter; // antialiasing filter for decimation.
+
+ int running;
+
+ LingotConfig* conf; // configuration structure
+
+ // pthread-related member variables
+ pthread_t thread;
+ pthread_attr_t attr;
+};
+
+//----------------------------------------------------------------
+
+LingotCore* lingot_core_new(LingotConfig*);
+void lingot_core_destroy(LingotCore*);
+
+// start process
+void lingot_core_start(LingotCore*);
+
+// stop process
+void lingot_core_stop(LingotCore*);
+
+// process thread
+void lingot_core_run(LingotCore*);
+
+#endif //__LINGOT_CORE_H__
diff --git a/src/lingot-defs.h b/src/lingot-defs.h
new file mode 100644
index 0000000..09625fa
--- /dev/null
+++ b/src/lingot-defs.h
@@ -0,0 +1,52 @@
+//-*- 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
+ */
+
+#ifndef __LINGOT_DEFS_H__
+#define __LINGOT_DEFS_H__
+
+#include <sys/types.h>
+#include "../config.h"
+
+// floating point precission.
+#define FLT double
+
+#define SAMPLE_TYPE int16_t
+#define SAMPLE_FORMAT AFMT_S16_LE
+
+#define CONFIG_DIR_NAME ".lingot/"
+#define DEFAULT_CONFIG_FILE_NAME "lingot.conf"
+extern char CONFIG_FILE_NAME[];
+
+#define QUICK_MESSAGES
+
+#define GTK_EVENTS_RATE 20.0
+#define GAUGE_RATE 60.0
+
+/* object forward declaration */
+typedef struct _LingotMainFrame LingotMainFrame;
+
+// optionally we can use the following libraries
+//#define LIB_FFTW
+//#define LIBSNDOBJ
+
+#endif
diff --git a/src/lingot-fft.c b/src/lingot-fft.c
new file mode 100644
index 0000000..18de134
--- /dev/null
+++ b/src/lingot-fft.c
@@ -0,0 +1,177 @@
+//-*- 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 <math.h>
+#include <stdlib.h>
+
+#include "lingot-fft.h"
+#include "lingot-config.h"
+
+/*
+ DFT functions.
+ */
+
+#ifndef LIB_FFTW
+
+#include "lingot-complex.h"
+
+// phase factor table, for FFT optimization.
+LingotComplex* wn;
+
+// creates the phase factor table.
+void lingot_fft_create_phase_factors(LingotConfig* conf)
+ {
+ FLT alpha;
+ unsigned int i;
+
+ wn = (LingotComplex*) malloc((conf->fft_size >> 1)*sizeof(LingotComplex));
+
+ for (i = 0; i < (conf->fft_size >> 1); i++)
+ {
+ alpha = -2.0*i*M_PI/conf->fft_size;
+ wn[i].r = cos(alpha);
+ wn[i].i = sin(alpha);
+ }
+ }
+
+void lingot_fft_destroy_phase_factors()
+ {
+ free(wn);
+ }
+
+//------------------------------------------------------------------------
+
+// Fast Fourier Transform.
+void _lingot_fft_fft(FLT* in, LingotComplex* out, unsigned long int N,
+ unsigned long int offset, unsigned long int d1, unsigned long int step)
+ {
+ LingotComplex X1, X2;
+ unsigned long int Np2 = (N >> 1); // N/2
+ register unsigned long int a, b, c, q;
+
+ if (N == 2)
+ { // butterfly for N = 2;
+
+ X1.r = in[offset];
+ X1.i = 0.0;
+ X2.r = in[offset + step];
+ X2.i = 0.0;
+
+ lingot_complex_add(&X1, &X2, &out[d1]);
+ lingot_complex_sub(&X1, &X2, &out[d1 + Np2]);
+
+ return;
+ }
+
+ _lingot_fft_fft(in, out, Np2, offset, d1, step << 1);
+ _lingot_fft_fft(in, out, Np2, offset + step, d1 + Np2, step << 1);
+
+ for (q = 0, c = 0; q < (N >> 1); q++, c += step)
+ {
+
+ a = q + d1;
+ b = a + Np2;
+
+ X1 = out[a];
+ lingot_complex_mul(&out[b], &wn[c], &X2);
+ lingot_complex_add(&X1, &X2, &out[a]);
+ lingot_complex_sub(&X1, &X2, &out[b]);
+ }
+ }
+
+void lingot_fft_fft(FLT* in, LingotComplex* out, unsigned long int N)
+ {
+ _lingot_fft_fft(in, out, N, 0, 0, 1);
+ }
+
+#endif
+
+//------------------------------------------------------------------------
+
+
+/* Spectral Power Distribution esteem, selectively in frequency, by DFT.
+ transforms signal in of N1 samples from frequency wi, with sample
+ separation of dw rads, storing the result on buffer out with N2 samples. */
+void lingot_fft_spd(FLT* in, int N1, FLT wi, FLT dw, FLT* out, int N2)
+ {
+ FLT Xr, Xi;
+ FLT wn;
+ FLT N1_2 = N1*N1;
+ register int i, n;
+
+ for (i = 0; i < N2; i++)
+ {
+
+ Xr = 0.0;
+ Xi = 0.0;
+
+ for (n = 0; n < N1; n++)
+ { // O(n1*n2) :(
+
+ wn = (wi + dw*i)*n;
+ Xr = Xr + cos(wn)*in[n];
+ Xi = Xi - sin(wn)*in[n];
+ }
+
+ out[i] = (Xr*Xr + Xi*Xi)/N1_2; // normalized squared module.
+ }
+ }
+
+//------------------------------------------------------------------------
+
+/*
+ Evaluates 1st and 2nd derivatives from SPD at frequency w.
+ */
+void lingot_fft_spd_diffs(FLT* in, int N, FLT w, FLT* out_d1, FLT* out_d2)
+ {
+ FLT x_cos_wn;
+ FLT x_sin_wn;
+ register int n;
+
+ FLT SUM_x_sin_wn = 0.0;
+ FLT SUM_x_cos_wn = 0.0;
+ FLT SUM_x_n_sin_wn = 0.0;
+ FLT SUM_x_n_cos_wn = 0.0;
+ FLT SUM_x_n2_sin_wn = 0.0;
+ FLT SUM_x_n2_cos_wn = 0.0;
+
+ for (n = 0; n < N; n++)
+ {
+
+ x_cos_wn = in[n]*cos(w*n);
+ x_sin_wn = in[n]*sin(w*n);
+
+ SUM_x_sin_wn += x_sin_wn;
+ SUM_x_cos_wn += x_cos_wn;
+ SUM_x_n_sin_wn += x_sin_wn*n;
+ SUM_x_n_cos_wn += x_cos_wn*n;
+ SUM_x_n2_sin_wn += x_sin_wn*n*n;
+ SUM_x_n2_cos_wn += x_cos_wn*n*n;
+ }
+
+ FLT N_2 = N*N;
+ *out_d1 = 2.0*(SUM_x_sin_wn*SUM_x_n_cos_wn - SUM_x_cos_wn*SUM_x_n_sin_wn)
+ /N_2;
+ *out_d2 = 2.0*(SUM_x_n_cos_wn*SUM_x_n_cos_wn - SUM_x_sin_wn*SUM_x_n2_sin_wn
+ +SUM_x_n_sin_wn*SUM_x_n_sin_wn - SUM_x_cos_wn*SUM_x_n2_cos_wn)/N_2;
+ }
diff --git a/src/lingot-fft.h b/src/lingot-fft.h
new file mode 100644
index 0000000..b958416
--- /dev/null
+++ b/src/lingot-fft.h
@@ -0,0 +1,52 @@
+//-*- 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
+ */
+
+#ifndef _LINGOT_FFT_H_
+#define _LINGOT_FFT_H_
+
+/*
+ Fourier transforms.
+ */
+
+#include "lingot-defs.h"
+
+#ifndef LIB_FFTW
+
+# include "lingot-complex.h"
+# include "lingot-config.h"
+
+void lingot_fft_create_phase_factors(LingotConfig* conf);
+void lingot_fft_destroy_phase_factors();
+
+// Fast Fourier Transform implementation.
+void lingot_fft_fft(FLT* in, LingotComplex* out, unsigned long int N);
+
+#endif // not LIB_FFTW
+
+// Spectral Power Distribution (SPD) esteem, selectively in frequency.
+void lingot_fft_spd(FLT* in, int N1, FLT wi, FLT dw, FLT* out, int N2);
+
+// first and second SPD derivatives at frequency w.
+void lingot_fft_spd_diffs(FLT* in, int N, FLT w, FLT* out_d1, FLT* out_d2);
+
+#endif
diff --git a/src/lingot-filter.c b/src/lingot-filter.c
new file mode 100644
index 0000000..f3c5528
--- /dev/null
+++ b/src/lingot-filter.c
@@ -0,0 +1,258 @@
+//-*- C++ -*-
+/*
+ * filter, a musical instrument tuner.
+ *
+ * Copyright (C) 2004-2007 Ibán Cereijo Graña, Jairo Chapela Martínez.
+ *
+ * This file is part of filter.
+ *
+ * filter 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.
+ *
+ * filter 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 filter; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <memory.h>
+#include <math.h>
+
+#include "lingot-complex.h"
+#include "lingot-filter.h"
+
+#define max(a,b) (((a)<(b))?(b):(a))
+
+// given each polynomial order and coefs, with optional initial status.
+LingotFilter* lingot_filter_new(unsigned int Na, unsigned int Nb, FLT* a, FLT* b) {
+ unsigned int i;
+ LingotFilter* filter = malloc(sizeof(LingotFilter));
+ filter->N = max(Na, Nb);
+
+ filter->a = malloc((filter->N + 1)*sizeof(FLT));
+ filter->b = malloc((filter->N + 1)*sizeof(FLT));
+ filter->s = malloc((filter->N + 1)*sizeof(FLT));
+
+ for (i = 0; i < filter->N + 1; i++)
+ filter->a[i] = filter->b[i] = filter->s[i] = 0.0;
+
+ memcpy(filter->a, a, (Na + 1)*sizeof(FLT));
+ memcpy(filter->b, b, (Nb + 1)*sizeof(FLT));
+
+ for (i = 0; i < filter->N + 1; i++) {
+ filter->a[i] /= a[0]; // polynomial normalization.
+ filter->b[i] /= a[0];
+ }
+
+ return filter;
+}
+
+void lingot_filter_destroy(LingotFilter* filter) {
+ free(filter->a);
+ free(filter->b);
+ free(filter->s);
+
+ free(filter);
+}
+
+// Digital Filter Implementation II, in & out overlapables.
+void lingot_filter_filter(LingotFilter* filter, unsigned int n, FLT* in,
+ FLT* out) {
+ FLT w, y;
+ register unsigned int i;
+ register int j;
+
+ for (i = 0; i < n; i++) {
+
+ w = in[i];
+ y = 0.0;
+
+ for (j = filter->N - 1; j >= 0; j--) {
+ w -= filter->a[j + 1]*filter->s[j];
+ y += filter->b[j + 1]*filter->s[j];
+ filter->s[j + 1] = filter->s[j];
+ }
+
+ y += w*filter->b[0];
+ filter->s[0] = w;
+
+ out[i] = y;
+ }
+}
+
+// single sample filtering
+FLT lingot_filter_filter_sample(LingotFilter* filter, FLT in)
+{
+ FLT result;
+
+ lingot_filter_filter(filter, 1, &in, &result);
+ return result;
+}
+
+// vector prod
+void lingot_filter_vector_product(int n, LingotComplex* vector,
+ LingotComplex* result) {
+ register int i;
+ LingotComplex aux1;
+
+ result->r = 1.0;
+ result->i = 0.0;
+
+ for (i = 0; i < n; i++) {
+ aux1.r = -vector[i].r;
+ aux1.i = -vector[i].i;
+ lingot_complex_mul(result, &aux1, result);
+ }
+
+}
+
+// Chebyshev filters
+LingotFilter* lingot_filter_cheby_design(unsigned int n, FLT Rp, FLT wc) {
+ int i; // loops
+ int k;
+ int p;
+
+ FLT* a
+ = malloc((n + 1)*sizeof(FLT));
+ FLT* b
+ = malloc((n + 1)*sizeof(FLT));
+
+ FLT* new_a
+ = malloc((n + 1)*sizeof(FLT));
+ FLT* new_b
+ = malloc((n + 1)*sizeof(FLT));
+
+ // locate poles
+ LingotComplex* pole = malloc(n*sizeof(LingotComplex));
+
+ for (i = 0; i < n; i++) {
+ pole[i].r = 0.0;
+ pole[i].i = 0.0;
+ }
+
+ FLT T = 2.0;
+ // 2Hz
+ FLT W = 2.0/T*tan(M_PI*wc/T);
+
+ FLT epsilon = sqrt(pow(10.0, 0.1*Rp) - 1);
+ FLT v0 = asinh(1/epsilon)/n;
+
+ FLT sv0 = sinh(v0);
+ FLT cv0 = cosh(v0);
+
+ FLT t;
+
+ for (i = -(n-1), k = 0; k < n; i+=2, k++) {
+ t = M_PI*i/(2.0*n);
+ pole[k].r = -sv0*cos(t);
+ pole[k].i = cv0*sin(t);
+ }
+
+ LingotComplex gain;
+
+ lingot_filter_vector_product(n, pole, &gain);
+
+ if ((n&1)==0) {// even
+ FLT f = pow(10.0, -0.05*Rp);
+ gain.r *= f;
+ gain.i *= f;
+ }
+
+ FLT f = pow(W, n);
+ gain.r *= f;
+ gain.i *= f;
+
+ for (i = 0; i < n; i++) {
+ pole[i].r *= W;
+ pole[i].i *= W;
+ }
+
+ // bilinear transform
+ LingotComplex* sp = malloc(n*sizeof(LingotComplex));
+
+ for (i = 0; i < n; i++) {
+ sp[i].r = (2.0 - pole[i].r*T)/T;
+ sp[i].i = (0.0 - pole[i].i*T)/T;
+ }
+
+ LingotComplex tmp1;
+ LingotComplex aux2;
+
+ lingot_filter_vector_product(n, sp, &tmp1);
+
+ free(sp);
+
+ lingot_complex_div(&gain, &tmp1, &gain);
+
+ for (i = 0; i < n; i++) {
+ tmp1.r = (2.0 + pole[i].r*T);
+ tmp1.i = (0.0 + pole[i].i*T);
+ aux2.r = (2.0 - pole[i].r*T);
+ aux2.i = (0.0 - pole[i].i*T);
+ lingot_complex_div(&tmp1, &aux2, &pole[i]);
+ }
+
+ // compute filter coefficients from pole/zero values
+ a[0] = 1.0;
+ b[0] = 1.0;
+ new_a[0] = 1.0;
+ new_b[0] = 1.0;
+
+ for (i = 1; i <= n; i++) {
+ a[i] = 0.0;
+ b[i] = 0.0;
+ new_a[i] = 0.0;
+ new_b[i] = 0.0;
+ }
+
+ if ((n & 1) == 1) // odd
+ {
+ // first subfilter is first order
+ a[1] = -pole[n/2].r;
+ b[1] = 1.0;
+ }
+
+ // iterate over the conjugate pairs
+ for (p = 0; p < n/2; p++) {
+ FLT b1 = 2.0;
+ FLT b2 = 1.0;
+
+ FLT a1 = -2.0*pole[p].r;
+ FLT a2 = pole[p].r*pole[p].r + pole[p].i*pole[p].i;
+
+ // 2nd order subfilter per each pair
+ new_a[1] = a[1] + a1*a[0];
+ new_b[1] = b[1] + b1*b[0];
+
+ // poly multiplication
+ for (i = 2; i <= n; i++) {
+ new_a[i] = a[i] + a1*a[i - 1]+ a2*a[i - 2];
+ new_b[i] = b[i] + b1*b[i - 1]+ b2*b[i - 2];
+ }
+ for (i = 1; i <= n; i++) {
+ a[i] = new_a[i];
+ b[i] = new_b[i];
+ }
+ }
+
+ gain.r = fabs(gain.r);
+ for (i = 0; i <= n; i++) {
+ b[i] *= gain.r;
+ }
+
+ LingotFilter* result = lingot_filter_new(n, n, a, b);
+
+ free(a);
+ free(b);
+ free(new_a);
+ free(new_b);
+ free(pole);
+
+ return result;
+}
diff --git a/src/lingot-filter.h b/src/lingot-filter.h
new file mode 100644
index 0000000..b2ea389
--- /dev/null
+++ b/src/lingot-filter.h
@@ -0,0 +1,66 @@
+//-*- 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
+ */
+
+#ifndef __LINGOT_FILTER_H__
+#define __LINGOT_FILTER_H__
+
+#include <fcntl.h>
+#include <stdlib.h>
+
+#include "lingot-defs.h"
+
+/*
+ digital filtering implementation.
+ */
+
+typedef struct _LingotFilter LingotFilter;
+
+struct _LingotFilter
+ {
+
+ FLT* a;
+ FLT* b; // coefs
+ FLT* s; // status
+
+ unsigned int N;
+
+ };
+
+LingotFilter
+ * lingot_filter_new(unsigned int Na, unsigned int Nb, FLT* a, FLT* b);
+
+/**
+ * Design a Chebyshev type I low pass filter with Rp dB of pass band ripple
+ * with cutoff pi*wc radians.
+ */
+LingotFilter* lingot_filter_cheby_design(unsigned int order, FLT Rp, FLT wc);
+
+void lingot_filter_destroy(LingotFilter*);
+
+// Digital Filter Implementation II, in & out overlapables. Vector filtering
+void lingot_filter_filter(LingotFilter*, unsigned int n, FLT* in, FLT* out);
+
+// sample filtering
+FLT lingot_filter_filter_sample(LingotFilter*, FLT in);
+
+#endif
diff --git a/src/lingot-gauge.c b/src/lingot-gauge.c
new file mode 100644
index 0000000..d092ed1
--- /dev/null
+++ b/src/lingot-gauge.c
@@ -0,0 +1,92 @@
+//-*- 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 "lingot-gauge.h"
+
+LingotGauge* lingot_gauge_new(FLT initial_position)
+ {
+
+ //
+ // ----- ERROR GAUGE FILTER CONFIGURATION -----
+ //
+ // dynamic model of the gauge:
+ //
+ // 2
+ // d d
+ // --- s(t) = k (e(t) - s(t)) - q -- s(t)
+ // 2 dt
+ // dt
+ //
+ // acceleration of gauge position 's(t)' linealy depends on the difference
+ // respect to the input stimulus 'e(t)' (destination position). Inserting
+ // a friction coefficient 'q', acceleration proportionaly diminish with
+ // velocity (typical friction in mechanics). 'k' is the adaptation constant,
+ // and depends on the gauge mass.
+ //
+ // with the following derivatives approximation (valid for high sample rate):
+ //
+ // d
+ // -- s(t) ~= (s[n] - s[n - 1])*fs
+ // dt
+ //
+ // 2
+ // d 2
+ // --- s(t) ~= (s[n] - 2*s[n - 1] + s[n - 2])*fs
+ // 2
+ // dt
+ //
+ // we can obtain a difference equation, and implement it with an IIR digital
+ // filter.
+ //
+
+ FLT k = 60;
+ // adaptation constant.
+ FLT q = 6;
+ // friction coefficient.
+
+ FLT a[] =
+ {
+ k + GAUGE_RATE*(q + GAUGE_RATE),
+ -GAUGE_RATE*(q + 2.0*GAUGE_RATE),
+ GAUGE_RATE*GAUGE_RATE};
+ FLT b[] =
+ { k};
+
+ LingotGauge* gauge = malloc(sizeof(LingotGauge));
+
+ gauge->filter = lingot_filter_new( 2, 0, a, b );
+ lingot_gauge_compute(gauge, initial_position);
+ return gauge;
+ }
+
+void lingot_gauge_destroy(LingotGauge* gauge)
+ {
+ lingot_filter_destroy(gauge->filter);
+ free(gauge);
+ }
+
+void lingot_gauge_compute(LingotGauge* gauge, FLT sample)
+ {
+ gauge->position = lingot_filter_filter_sample(gauge->filter, sample);
+ }
+
diff --git a/src/lingot-gauge.h b/src/lingot-gauge.h
new file mode 100644
index 0000000..44b1a94
--- /dev/null
+++ b/src/lingot-gauge.h
@@ -0,0 +1,46 @@
+//-*- 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
+ */
+
+#ifndef __LINGOT_GAUGE_H__
+#define __LINGOT_GAUGE_H__
+
+#include "lingot-defs.h"
+#include "lingot-filter.h"
+
+/*
+ * Implements the dynamic behaviour of the gauge with a digital filter.
+ */
+
+typedef struct _LingotGauge LingotGauge;
+
+struct _LingotGauge
+ {
+ LingotFilter* filter;
+ FLT position;
+ };
+
+LingotGauge* lingot_gauge_new(FLT);
+void lingot_gauge_destroy(LingotGauge*);
+void lingot_gauge_compute(LingotGauge*, FLT);
+
+#endif /*__LINGOT_GAUGE_H__*/
diff --git a/src/lingot-i18n.h b/src/lingot-i18n.h
new file mode 100644
index 0000000..cded340
--- /dev/null
+++ b/src/lingot-i18n.h
@@ -0,0 +1,42 @@
+//-*- 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
+ */
+
+#ifndef LINGOTI18N_H_
+#define LINGOTI18N_H_
+
+#include <libintl.h>
+#include <locale.h>
+#include <langinfo.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef ENABLE_NLS
+#undef _
+# define _(String) (const char*) gettext (String)
+#else
+# define _(String) (String)
+#endif
+
+#endif /*LINGOTI18N_H_*/
diff --git a/src/lingot-logo.xpm b/src/lingot-logo.xpm
new file mode 100644
index 0000000..6e17b52
--- /dev/null
+++ b/src/lingot-logo.xpm
@@ -0,0 +1,343 @@
+/* XPM */
+static const char *lingotlogo[] = {
+/* columns rows colors chars-per-pixel */
+"80 80 257 2",
+" c black",
+". c #2E4E41EA1FB9",
+"X c #2F7542BE2093",
+"o c #348B44B92376",
+"O c #39E8475526C6",
+"+ c #3B8D48A42821",
+"@ c #3E2349B12992",
+"# c #42BB4C972CB8",
+"$ c #47474FF73052",
+"% c #48FB503430FF",
+"& c #4CD853213414",
+"* c #51CB55B43725",
+"= c #564F5A4C3B43",
+"- c #5A7D5D3C3E4E",
+"; c #529657CF388C",
+": c #5C5B603040B4",
+"> c #5E896199422C",
+", c #60A75D8440D7",
+"< c #63CD64104550",
+"1 c #674F67624883",
+"2 c #678169444994",
+"3 c #6C8E6CCB4D3A",
+"4 c #68DA665B4854",
+"5 c #6F0671D250C7",
+"6 c #70DE6D2F4EF6",
+"7 c #7EF96D2055C3",
+"8 c #7D3767F552BA",
+"9 c #745F74285424",
+"0 c #7683792557B9",
+"q c #7CB1741A57F4",
+"w c #7FD8776C59C7",
+"e c #7D4B7CD15BF3",
+"r c #7D6D82F15F40",
+"t c #79BC89195F75",
+"y c #75438A075D75",
+"u c #71C8929C6045",
+"i c #6D1E94FB5F0A",
+"p c #6DA59C5264E9",
+"a c #70079ECD6897",
+"s c #6FD995DC6258",
+"d c #7D7F8B87653F",
+"f c #7B278AA06300",
+"g c #75C694C46609",
+"h c #76F297BD6953",
+"j c #73D69D906BB3",
+"k c #7CA294916B2C",
+"l c #7AEA9C466E26",
+"z c #7EFA9DE57191",
+"x c #67DCA2C865E8",
+"c c #69B6A32F677E",
+"v c #6D33A3B96AD7",
+"b c #7054A9066EC7",
+"n c #72F4A3E06ECE",
+"m c #74D0A4A771B2",
+"M c #7511AB17734D",
+"N c #7AEDA601737E",
+"B c #7ABCACAF7811",
+"V c #7CD4AF197B14",
+"C c #7EFCB2657D9F",
+"Z c #84436ED0579C",
+"A c #864C6FE35915",
+"S c #88DA701159DC",
+"D c #820F70D157E3",
+"F c #85D473A35B19",
+"G c #83777C2A5EF3",
+"H c #89E8735A5BF1",
+"J c #8C4E794E5F9F",
+"K c #85587D7B6153",
+"L c #8D7577E36092",
+"P c #8DA17B94627A",
+"I c #8F237F6B6934",
+"U c #92DD7D2E6445",
+"Y c #93FC7F2569D2",
+"T c #812F81225F81",
+"R c #838B84A0628D",
+"E c #84518AE36654",
+"W c #8F4983806686",
+"Q c #8D5485E169D9",
+"! c #8CD68D956B97",
+"~ c #87268DA668AF",
+"^ c #90588ED67342",
+"/ c #8D9E92D06DDC",
+"( c #857791776C44",
+") c #84029CB772D7",
+"_ c #8DE597117233",
+"` c #8EA19A3D75CF",
+"' c #91A88511681E",
+"] c #93CC86706B43",
+"[ c #949A8BF56DAD",
+"{ c #995F833D67AA",
+"} c #9A7C850D6B28",
+"| c #9D7C8A5F6CA9",
+" . c #96588B2B71A4",
+".. c #9BC98BA5750F",
+"X. c #9F898E617A67",
+"o. c #935091BF6FC0",
+"O. c #93EC961172E4",
+"+. c #94C29BFD7561",
+"@. c #97AE9EA37AE0",
+"#. c #9A9895AD7646",
+"$. c #9A109B6B7728",
+"%. c #9B7E9E7579B6",
+"&. c #98E9958A7AE9",
+"*. c #8443A8D17B68",
+"=. c #8120B2D17EA4",
+"-. c #96F1A2117A1A",
+";. c #9BF6A4EE7CEF",
+":. c #9CD1A9A97FC5",
+">. c #A17D8C156E36",
+",. c #A42E8F787241",
+"<. c #A1E18FC77BA7",
+"1. c #A6F192E672F6",
+"2. c #A39793257D69",
+"3. c #AA4795E2753D",
+"4. c #AE389A5D78AC",
+"5. c #B30D9EE07BFF",
+"6. c #B6C7A3137F4A",
+"7. c #983F9F0B808C",
+"8. c #8C8DAE8E8457",
+"9. c #884BB0A5845A",
+"0. c #84D2B602836E",
+"q. c #8943B971878D",
+"w. c #8D8FBB9A8BDB",
+"e. c #8BD8B86388AD",
+"r. c #95C6A3BD82AE",
+"t. c #9F54ACF182B4",
+"y. c #9A1DA87E8829",
+"u. c #9168BDC38FD9",
+"i. c #9701BC539207",
+"p. c #A53F960382A8",
+"a. c #A6DB9A3684C9",
+"s. c #AC659BE684D9",
+"d. c #AA7397B180C1",
+"f. c #A5A4A40A861B",
+"g. c #A1EDADE18417",
+"h. c #A988AA688C0F",
+"j. c #B018ABF193A6",
+"k. c #A3CEB29F8728",
+"l. c #A5AAB6FB8A31",
+"z. c #A757BB5F8D2C",
+"x. c #A981BF438FFC",
+"c. c #AA06B6778D5A",
+"v. c #AA8BC025916C",
+"b. c #AFF6B2629531",
+"n. c #B7BAA4C9831B",
+"m. c #B9FFA681829E",
+"M. c #BA8AA84D8A3E",
+"N. c #B95EA8B58C7A",
+"B. c #BDA2AE1797A2",
+"V. c #B39EABAF95A1",
+"C. c #B8B4B69B9CC1",
+"Z. c #BC91AF6BA17F",
+"A. c #BE02B505A4AF",
+"S. c #BD15BCAEA5D5",
+"D. c #B8A4BEB9A1FC",
+"F. c #AC4FC5299459",
+"G. c #AFB7C58C9903",
+"H. c #AE87CB4B9844",
+"J. c #AEC8CBF898BB",
+"K. c #B413C5DE9DB1",
+"L. c #B26ECE2A9CF0",
+"P. c #B7B9C894A238",
+"I. c #B553CFD5A1AE",
+"U. c #BA0BC89DA479",
+"Y. c #BB3BCA51A68D",
+"T. c #BF93CD67AC76",
+"R. c #BE7BC86BAA3F",
+"E. c #B6DDD175A3D0",
+"W. c #BA16D33EA74D",
+"Q. c #BDD2D5B2AC06",
+"!. c #C1CBAECD87BC",
+"~. c #C315AFFE88E3",
+"^. c #C5D5B3178B8F",
+"/. c #C9C7B7C88EB1",
+"(. c #CB2FB8E2903D",
+"). c #CE7EBC989254",
+"_. c #C684B6F19D30",
+"`. c #D224BFD694C3",
+"'. c #CA84BE10ABD3",
+"]. c #C5FBB9F1A700",
+"[. c #D4B0C3559720",
+"{. c #D7A2C6AC99DF",
+"}. c #D907C7749A12",
+"|. c #DD3CCC359DE1",
+" X c #C1D1CE48AF76",
+".X c #C9DBC334AD40",
+"XX c #C571CE8AB36D",
+"oX c #CAD0CEDBB923",
+"OX c #C105D785AFF8",
+"+X c #C3DFD694B323",
+"@X c #C548DA3FB579",
+"#X c #C808DC02B94B",
+"$X c #CC45D553BC6E",
+"%X c #CAB8DDA2BCE1",
+"&X c #C8DDD37DB87C",
+"*X c #D7D2C9AFAB07",
+"=X c #D951CCCEB2B0",
+"-X c #DE22D322BC6C",
+";X c #E140D06EA108",
+":X c #E5B3D535A487",
+">X c #EA6BD9F5A805",
+",X c #EE1ADE3FABCD",
+"<X c #E5C7D89CAE0C",
+"1X c #E294D538B2DD",
+"2X c #E830DB8CB90B",
+"3X c #F37AE3D7AF6B",
+"4X c #F619E709B22A",
+"5X c #F752E925B732",
+"6X c #F72CEA14BC70",
+"7X c #D000D805C144",
+"8X c #CEA1DFD7C17B",
+"9X c #D311D51DC431",
+"0X c #D29FDA28C4D8",
+"qX c #D738DD50CAB4",
+"wX c #DB3CDF0ECF59",
+"eX c #DB3BD3BCC7E2",
+"rX c #DDAADE16D202",
+"tX c #CFCFE188C316",
+"yX c #D2BAE2E4C6C8",
+"uX c #D69AE57BCB88",
+"iX c #D9EBE692CF48",
+"pX c #DD68E4FCD35D",
+"aX c #DE08EA70D50C",
+"sX c #E3B1DB62C8FC",
+"dX c #E4FEE0ABDAC4",
+"fX c #E215DE2AD715",
+"gX c #E5AAE293D5A7",
+"hX c #E5B0E57EDC9B",
+"jX c #E140EC3FD8B8",
+"kX c #E45DEE6ADD4C",
+"lX c #EC9CE5CAD492",
+"zX c #F861EBA7C35E",
+"xX c #F8ACEE49CB05",
+"cX c #F913EC91C5FE",
+"vX c #F958EF30CD2D",
+"bX c #F9F4F083D281",
+"nX c #F3AFEC22D68B",
+"mX c #FA66F1D9D5EB",
+"MX c #FB20F421DC8C",
+"NX c #EDD8E516CCE0",
+"BX c #E7CAF0BAE1C9",
+"VX c #EAD5E7ADE2E7",
+"CX c #ED07EA54E5DB",
+"ZX c #E80DF10EE225",
+"AX c #EA9DF261E5B6",
+"SX c #EED8F47DEADD",
+"DX c #F167F044EC18",
+"FX c #F787F2AFE303",
+"GX c #F246F639EE99",
+"HX c #FC03F658E4BE",
+"JX c #FCE7F857E952",
+"KX c #FD88F974EA48",
+"LX c #F4DDF7FFF1DD",
+"PX c #F76AF9F8F4EF",
+"IX c #F9B7FB74F7F9",
+"UX c #FDC7FE48FD59",
+"YX c None",
+/* pixels */
+"YXYXYXYXYXYXYXYXZ S H L Y ..<.p.X.X.X.X.X.X.p.X.X.....X...&...X......... ... ... . . .[ .} [ } [ ] ] ] ] ] ] ] Q ] ' ' ' Q Y Q W W W { H H S S YXYXYXYXYXYXYXYX",
+"YXYXYXYXYXH H S H ..Z.eXdXVXVXVXVXVXhXhXVXaXrXpXrXrXrXqXqXuX0X0X7X7X7X#X&X$X&XXXXXXXXX XT.T.T.Y.U.U.P.P.K.K.G.G.F.F.F.x.x.x.x.x.F.F.z.:.:.$.W H H H J YXYXYXYXYX",
+"YXYXYXYXYXS H Y ].DXUXUXUXUXUXIXPXPXLXLXGXSXSXAXAXAXkXkXkXjXaXaXiXiXiXiXuXyXtXtXtX%X%X#X#X@XQ.#XQ.Q.W.W.W.E.E.E.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.%.J H H YXYXYXYXYX",
+"YXYXYXYXS S p.rXUXUXUXUXUXIXIXIXPXLXGXGXSXSXAXBXAXkXkXkXaXjXaXiXiXiXiXyXyXtXtXtX%X%X#X@X@X+XQ.Q.Q.W.Q.E.E.E.L.J.H.H.J.J.J.J.J.J.J.J.J.J.J.J.J.H.k.' H H YXYXYXYX",
+"YXYXYXH S p.CXUXUXUXUXUXIXIXIXLXLXGXGXSXAXAXAXBXkXkXkXkXaXaXiXiXuXuXuXyXyXtX%X%X%X#X@X@X@X+XQ.Q.Q.Q.E.E.E.J.E.J.J.H.J.J.J.J.J.J.J.J.J.J.H.J.H.J.J.x.' H H YXYXYX",
+"YXYXS Z <.VXUXUXUXUXUXUXIXPXLXLXLXSXSXAXAXZXBXBXkXaXkXaXiXpXiXiXuXyXyXyXtXtX%X%X#X@X@X@XQ.Q.Q.Q.W.W.E.I.E.J.J.J.J.J.J.J.J.J.J.J.H.J.H.J.J.J.J.J.J.J.z.{ S H YXYX",
+"YXH Z Y eXUXUXUXUXUXIXIXPXLXLXLXGXSXAXAXAXZXBXkXkXkXaXaXiXiXiXiXyXyXtXtXtX%X%X#X#X@XQ.@XQ.Q.W.W.W.E.I.E.J.J.J.J.H.J.J.J.J.J.J.J.H.J.H.J.J.J.J.J.J.J.J.k.J H H YX",
+"YXH H ].UXUXUXUXUXUXIXIXLXLXGXDXSXAXAXAXAXkXkXkXaXaXaXaXiXiXuXyXyXyXtX%X%X%X#X@X@X@X@XQ.Q.Q.W.W.E.I.J.J.J.J.J.J.H.J.J.J.J.J.J.J.J.J.J.J.J.H.H.J.J.J.J.H.$.H H YX",
+"YXA ..CXUXUXUXUXIXIXIXLXLXGXSXSXSXAXAXAXkXkXaXkXaXaXiXiXuXuXuXyXyXtXtX%X%X#X#X@XQ.Q.Q.Q.Q.W.W.E.L.L.L.H.J.J.J.J.J.J.J.J.J.J.H.J.H.J.J.J.J.J.J.J.J.J.J.J.F.W S YX",
+"A S ].UXUXUXUXIXIXIXLXLXLXSXSXSXAXBXBXkXaXkXaXaXaXiXiXiXuXuXyXyXtXtX%X%X%X#X@X@XQ.@XQ.Q.W.W.E.E.L.L.H.H.H.H.J.H.H.J.H.J.H.J.H.J.J.J.J.H.J.H.H.J.H.J.J.J.F.$.S S ",
+"A Y dXUXUXUXIXIXPXLXLXGXSXSXSXAXAXBXkXkXkXaXaXaXaXiXiXuXuXyXtX%X#XR.D.C.b.h.f.f.f.f.k.h.h.c.G.G.L.L.H.H.J.J.H.J.J.J.J.J.H.J.J.J.H.J.H.J.J.J.J.J.J.J.H.J.H.z.W S ",
+"S p.IXUXUXUXIXIXLXLXLXSXSXAXAXAXBXBXkXkXkXaXaXpXiXiXuX7XXXD.j.X.} ' P P U U { } { ' U U L P P ' [ $.:.F.F.J.H.H.J.H.J.H.J.J.H.J.J.J.J.J.J.H.H.J.H.J.J.J.J.F.{ H ",
+"S A.UXUXUXIXPXLXLXLXSXSXAXAXAXAXkXkXkXkXjXaXiXpXyXXXj.#.U L U ..s.B.'.*X*X=X2X2X2X=X1X*X{._.M.4.>.U J J ] -.k.F.H.H.J.H.J.H.J.J.J.H.J.J.H.J.J.J.J.H.J.J.J.J.3.H ",
+"S eXUXIXIXPXLXLXSXGXSXAXAXAXBXkXkXkXaXaXaXiX&Xb...P Y X.B.=XsXNXnXMXmXmXmXvXvXvXxXxXvXcXcX6X6X4X,X<X}.m.>.U J { %.c.H.J.J.J.H.J.J.J.J.H.J.J.J.J.J.J.H.J.J.J.:.T ",
+"L fXUXUXPXLXLXLXGXSXAXAXAXBXkXkXkXkXaXiXXXs.U U <._.-XnXMXMXHXMXbXMXbXbXvXbXxXvXxXcXcXcXcXcX6X6X6X6X6X5X,X|.!.1.U J o.l.H.H.J.J.J.H.H.J.J.J.H.J.H.J.J.J.J.J.:.T ",
+"Y dXIXPXLXLXGXGXSXAXAXAXBXkXkXkXaXpX.Xa.P ] N.eXnXHXHXMXMXMXMXmXbXbXbXbXbXvXcXxXcXcXcX6X6X6X6X6X5X5X5X4X4X4X4X,X}.6.U J [ k.H.J.J.J.J.J.J.H.J.J.J.J.J.H.J.J.z.W ",
+"<.VXIXLXLXGXSXSXAXAXAXAXkXkXkXaX7Xs.U Y ].sXFXHXHXMXMXMXMXbXmXmXbXbXbXvXxXxXxXzXcXcXzXzX6X5X6X5X5X5X4X4X4X3X4X4X4X3X|.6.{ J #.z.H.H.H.J.H.J.J.J.J.J.J.H.J.J.x.' ",
+"X.VXLXLXLXGXSXSXAXAXBXkXkXkXiXA.Y Y B.fXFXHXHXHXMXMXMXMXMXbXbXbXbXbXvXxXxXxXzXzX6XzX6X6X6X5X6X5X4X4X4X4X4X3X4X4X4X4X4X3X:X6.U W ;.F.J.H.J.H.H.J.H.J.J.J.J.J.x.' ",
+"X.hXLXGXSXSXSXAXAXBXkXkXkXoXp.L a.eXHXJXHXHXHXMXMXMXMXMXmXbXbXbXvXvXxXxXxXzXzXzXcX6X6X6X6X5X4X5X4X3X4X4X;X4.|.4X4X4X4X4X4X4X}.1.T { :.H.J.H.H.J.J.H.J.H.J.J.x.' ",
+"X.hXLXSXSXAXAXAXBXBXkXkXS.Y Y '.nXKXJXHXHXMXHXMXMXMXmXmXbXbXbXbXvXvXxXxXxXzXzXzX6X6X5X6X6X5X4X4X4X4X4X3X6.Z 1.,X4X4X4X4X4X4X4X>X/.{ W 4.H.H.H.H.J.J.J.J.J.J.x.' ",
+"X.hXSXSXSXAXAXBXkXkXpXV.L p.sXJXHXHXHXHXHXMXMXMXMXmXmXbXmXvXbXvXvXxXxXcXzXzXzXzX6X6X6X5X4X4X4X4X4X4X4X:X{ J S /.4X4X4X4X4X4X4X4X4X;X1.T +.F.J.J.J.H.J.H.J.J.x.' ",
+"X.hXSXAXAXAXBXBXBX9Xa.L N.lXKXJXHXHXHXHXMXMXMXMXMXmXbXbXvXvXvXxXxXxXcXcXzXzX6X5X6X6X5X5X4X4X4X4X4X4X4X(.H ( e Y :X4X4X4X4X4X3X4X4X4X>X6.J | x.J.J.J.J.J.J.J.x.W ",
+"X.pXSXAXBXBXkXBXqXp.L ].FXJXJXHXHXHXHXMXMXMXMXMXmXbXbXbXmXvXxXxXcXcXcX6XzXzX6X6X6X5X5X5X4X4X4X4X4X4X3X3.W N y Z m.4X4X4X4X4X4X4X4X3X4X3X^.{ W :.H.H.J.H.J.J.x.' ",
+"X.fXAXAXBXBXkXqXp.Y '.FXJXJXHXHXHXHXMXMXMXMXbXbXmXbXbXbXvXvXxXxXcXcXcX6X6XzX6X5X5X5X4X4X4X4X4X4X4X4X>X{ O.=.p e J |.4X3X4X3X4X4X4X4X4X4X3X/.{ W x.J.J.J.J.J.x.{ ",
+"X.rXAXZXkXkXwX7.U '.JXJXHXHXHXHXMXMXMXMXMXmXbXbXmXbXbXxXxXxXcXcXcXcX6X6X6X6X6X5X4X4X4X4X3X4X4X4X4X4X).L -.N d f Z 3.3X3X4X4X4X4X4X4X4X4X4X3X).{ ' F.J.H.H.H.F.' ",
+"X.rXAXkXkXrXa.I '.JXJXJXHXHXHXMXMXMXMXMXMXmXbXbXbXbXvXxXxXxXcXcXcX6X6X6X6X6X6X4X4X4X4X4X4X4X4X4X4X4X6.P 8.f P ( T S [.3X4X3X4X4X4X4X4X4X4X4X3X/.J [ F.H.H.H.F.' ",
+"..iXZXkXaXj.L ].FXJXJXHXHXHXMXMXMXMXMXbXbXbXbXbXvXvXxXxXcXzXzXzX6XcX6X6X6X5X5X4X4X4X4X4X4X4X4X4X4X>X{ ! m e Z ! u D 1.,X4X4X4X3X4X4X4X4X3X4X4X3X^.J $.H.H.H.x.{ ",
+"X.qXkXkX'.L V.HXJXJXHXHXHXHXMXMXMXMXMXbXbXbXbXvXvXvXxXcXzXzXzXzX6X6X6X5X5X5X4X3X4X4X4X4X4X4X4X4X5X}.G ` a F Z P ) t H [.4X4X4X4X4X4X3X4X4X4X4X4X4X6.H :.H.H.x.W ",
+"..qXBX9X} <.lXKXJXJXHXHXMXMXMXMXMXbXbXbXbXbXvXvXvXxXcXzXcXzXzXzX6X6X5X5X5X4X4X4X4X4X4X4X4X4X4X4X4Xn.P *.u D 1.P +.u G >.>X4X4X4X4X4X4X4X4X4X4X4X4X:X1.W z.J.F.W ",
+"..qXrXa.U eXHXHXJXHXHXFXMXMXMXMXMXbXbXbXbXbXvXxXxXcXzXzXzXzX6X6X5X6X5X5X4X4X4X4X4X4X4X4X4X3X4X4X,X| W n r J [.| ! *.u H /.4X4X4X3X4X3X4X4X4X4X3X4X4X[.{ | F.F.W ",
+"..0XA.H <.dXHXHXHXHXFXMXMXMXMXMXbXbXbXbXvXvXxXxXcXcXzXzX6X6X6X6X5X5X5X4X4X4X4X3X4X4X4X3X3X4X4X4X}.J ( v e | 3Xm.J :.a T 3.3X4X3X4X4X4X4X3X4X3X4X4X4X;X1.H ;.F.' ",
+"..7XoX7.U ..'.nXFXMXMXMXMXMXbXbXbXbXbXbXvXxXcXxXcXzXzX6X6X6X6X6X6X5X4X4X3X4X4X4X4X4X4X4X4X4X4X3X!.J l g D 6.4X).G r.b T W :X4X4X3X4X4X3X4X4X4X4X>X^.| J o.:.F.W ",
+"X.0XaXuXS.<.L <..XnXMXMXMXmXmXmXmXbXvXxXxXxXxXxX6XzX6X6X6X6X6X6X5X4X4X3X4X4X4X3X3X4X4X4X4X4X4X3X>.W n t Z {.4X|.J +.V d F {.4X4X4X4X4X4X4X4X>X/.>.J ' :.F.J.F.{ ",
+" .$XiXuXuX%XC. .U <.*XnXmXMXvXmXvXvXxXxXcXcXcXzXzXzX6X6X6X6X4X4X4X4X4X4X4X4X4X4X4X4X4X4X4X4X3X|.U ! v e { :X4X,X' .8.d S [.4X4X4X4X4X4X>X[.1.J { :.H.J.J.J.x.W ",
+"..$XiXuXuXuXtX&Xb.] L d.=XxXvXvXvXvXxXxXcXxXzX6X6X6X6X5X5X5X5X4X4X3X4X3X3X4X3X4X4X3X4X4X4X4X4X!.J ) u D 6.3X3X>X{ .9.E Z {.5X4X4X4X3X[.1.J { ;.F.J.H.H.J.J.F.W ",
+"X.$XuXuXyXtXtXtX#XXXh.U U s.=XvXvXxXcXcXcXcXzX6X6X6X5X5X5X4X4X4X4X4X4X4X4X4X4X4X4X4X3X4X4X4X3X3.T n y A (.4X4X;XH _ 9.d H }.5X4X3X}.3.U W $.F.F.H.H.J.H.J.J.z.W ",
+" .$XuXyXyXtX%X%X#X#X@XR.2.' U n.1XcXcXzXxX6XzX6X6X6X5X5X4X4X4X4X4X4X4X3X4X3X3X3X3X3X4X4X4X4X:XP ! v r J :X4X3X~.F -.*.r { :X3X|.6.W J %.F.J.J.J.H.H.J.J.J.J.F.T ",
+"..&XyXtXtX%X%X%X%X#X+X@XOXK.%.P ' M.1XzXcX6X6X6X6X6X5X5X4X4X4X4X4X4X3X>X{.^.6.6.6.n.~.[.:X4X/.Z ) p F >.4X4X;XU K *.l F 1.|.6.U J +.l.H.H.J.J.H.H.H.H.J.J.J.F.{ ",
+"| &XyX8XtX%X%X#X#X#X@X+XQ.Q.T.v.#.J } B.<X6X6X5X5X5X6X4X4X4X3X4X3X}.6.{ U J J J F H L P } n.} P n u Z ~.4X|.| Z d N E Z >.{ J o.l.H.H.H.H.H.J.J.H.H.J.J.J.J.F.W ",
+" .&XtX8X%X%X#X@X@XQ.OXQ.Q.Q.Q.W.L.c.[ J | ^.<X6X5X5X4X4X4X4X4X;X6.U J [ o.R J J P J G Q [ H 8 Q j T J |.,X>.Z E l k D Z J o.k.J.J.H.H.H.H.H.H.J.H.H.J.H.J.J.F.W ",
+" .XX%X%X%X#X@X@XOXOXOXQ.Q.W.W.E.I.L.H.g.[ J >./.,X3X4X3X4X4X[.{ J o.:.] K .&.r.@. .W F ^ ^ S k a w | 3X`.L d m l K Z Q g.F.J.J.J.J.H.J.H.J.J.J.J.J.J.H.H.H.F.' ",
+" .XXtX%X#X#X@X+XOXOXQ.Q.E.E.E.I.L.L.L.J.G.:.Q J >.).,X4X3X`.{ U k.k.R ' y.i.i.u.w.w.8.` K 7 K l g Z 4.4X`.P d k K F @.G.J.J.J.J.H.J.J.J.H.J.H.J.H.H.J.J.H.H.l.{ ",
+" . X%X#X#X@X@X+XQ.Q.Q.W.W.E.I.L.J.L.J.J.H.L.F.;.W J 1.[.}.U ' z.G.K U y.u.u.w.q.q.0.0.9.) L e a f 8 U {.(.H 7 H K t.H.H.J.J.J.J.J.J.H.J.J.H.J.J.J.J.J.J.H.J.z.W ",
+"| X%X@X@X@XQ.Q.Q.Q.W.W.E.L.L.L.J.J.J.J.H.H.H.H.x.;.W U U U l.J.+.F y.u.w.q.q.q.0.=.V M m k h n G F H U U P [ :.G.H.H.H.J.J.J.J.H.J.J.J.J.J.J.H.H.J.J.J.J.J.F.W ",
+"[ T.#X#XQ.@XQ.Q.Q.W.W.E.L.L.L.J.J.J.J.J.H.H.H.J.J.J.F.+.W :.H.F.K Q w.q.0.0.0.C V b v v v v v h q ! t.I %.x.J.J.J.J.J.J.J.J.J.J.J.H.J.H.H.J.J.J.J.J.J.J.H.H.F.W ",
+"} T.@X@XQ.Q.Q.Q.W.E.E.L.L.L.L.J.H.J.H.J.H.H.J.J.H.J.H.F.F.H.H.z.F +.0.0.C 0.C B b c c v v v m d Z :.F.F.J.J.J.J.J.F.J.J.J.J.J.J.J.H.J.J.J.J.H.J.J.H.J.H.H.H.F.W ",
+" .Y.@XQ.Q.Q.Q.W.W.E.L.L.L.L.H.J.J.J.J.H.J.J.H.J.H.J.J.J.J.J.J.k.7 ) =.V V B M c p c c v v n n K F z.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.H.J.J.J.H.J.J.J.H.H.H.F.' ",
+"] U.Q.+XQ.Q.W.W.E.E.L.L.J.H.J.J.H.J.J.J.H.H.J.J.J.H.J.J.J.J.J.t.Z h V V M M v x c v v v b m a q Q J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.H.J.J.J.H.J.H.J.H.J.J.H.H.z.' ",
+" .U.Q.Q.Q.W.W.E.J.I.L.J.J.J.J.J.H.J.J.J.J.H.H.J.J.J.J.H.H.J.J.k.Z g b b n c c x v v v v n m k Z @.J.J.J.J.J.H.J.J.H.J.J.H.J.J.H.H.J.J.J.J.H.J.J.J.J.H.J.J.J.F.W ",
+"} U.Q.Q.W.W.I.E.E.J.J.J.J.J.J.J.J.J.H.J.J.J.J.J.J.H.J.J.J.J.J.z.F r c v c c c v v v v v m n G F z.J.J.J.H.J.J.H.H.J.H.J.J.H.H.J.J.J.H.J.J.J.H.J.H.J.J.J.H.J.F.W ",
+"! P.Q.W.W.I.E.E.J.J.J.J.J.J.J.J.H.J.J.J.H.J.H.H.J.J.J.H.H.J.H.H.o.w i x x c c v v m v m m h F O.H.J.J.J.H.J.H.J.J.J.H.H.J.J.J.J.H.J.H.J.J.J.J.J.J.J.H.J.H.H.F.' ",
+"] P.W.E.E.E.L.J.J.J.J.J.J.J.J.J.J.J.H.H.J.J.J.J.H.H.J.J.H.H.H.J.z.J w p c c v v v v m m j G K z.J.J.J.J.J.J.J.J.J.H.J.J.H.H.J.H.J.J.J.J.H.J.H.J.J.H.J.J.H.H.z.' ",
+"' K.W.E.I.J.J.J.J.J.J.J.J.J.J.J.J.J.H.J.J.J.J.J.J.J.J.J.J.H.H.J.J.;.F r p v v b m n m j e F :.H.J.J.J.H.J.J.H.J.H.J.J.H.J.J.H.J.H.J.J.J.J.J.J.J.H.J.H.J.J.J.z.W ",
+"' K.E.I.E.J.J.H.J.J.J.J.J.J.J.J.H.J.J.J.H.H.J.H.H.J.H.J.J.J.J.J.J.H.;.J F r g h h g f K F -.H.H.J.J.J.J.H.J.J.J.J.H.J.J.H.J.J.H.J.J.J.H.H.J.J.J.J.J.J.J.J.J.F.' ",
+"] G.I.I.J.J.J.H.H.J.J.J.J.J.J.J.J.J.H.J.J.J.J.J.J.J.J.J.H.H.J.H.J.J.H.k.! F F F F Z 7 I t.J.J.J.J.H.J.H.J.J.J.J.J.H.J.H.H.J.J.H.H.J.H.J.J.J.J.J.H.J.J.J.J.J.F.W ",
+"] G.I.J.G.@.O.l.F.J.J.J.J.J.J.J.H.J.J.J.H.J.H.J.J.H.J.H.J.J.J.J.J.J.J.J.F.z.+.o.o.O.y.F.J.J.J.H.J.J.J.J.J.H.J.H.H.J.J.H.J.J.H.J.J.J.J.J.H.J.J.J.J.J.J.J.J.J.F.W ",
+"' F.L.L.-.; # 5 F.H.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.H.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.H.H.J.J.J.J.H.J.F.F.H.J.J.H.H.F.' ",
+"' F.J.J._ # . 1 x.J.J.J.J.J.J.J.J.J.J.J.H.J.H.J.H.J.H.J.J.J.J.J.J.J.J.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.H.H.J.H.J.J.J.J.J.J.H.J.J.F.T 3 -.H.L.H.H.z.' ",
+"' x.J.J.+.& o e F.J.J.J.J.J.J.J.J.J.J.J.J.H.J.J.J.J.J.J.H.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.H.H.J.J.J.J.H.J.H.J.H.H.J.F.+.$ o - +.:.z.H.z.' ",
+"Q F.J.J.+.$ + T G.F.J.J.J.J.J.J.J.J.J.J.J.J.J.H.J.H.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.J.J.J.J.J.J.H.J.J.H.J.J.J.H.H.z.O.r - o X o $ * 3 :.F.' ",
+"' z.H.J._ $ + ~ F.J.J.J.J.J.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.F.F.J.J.J.J.J.J.J.J.H.H.J.J.J.H.J.J.J.J.F.0 # o X X X o + + & #.F.' ",
+"' F.J.J._ # + o.J.J.J.J.J.J.J.J.J.J.J.J.z./ E :.F.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.F.t.T 0 T t.J.J.J.J.J.J.J.H.F.F.F.H.J.H.J.J.J.F.T > > $ . O 2 T ! +.F.z.' ",
+"U F.J.J._ # + O.J.J.J.J.J.J.J.J.J.J.J.J.+.& O 9 z.J.J.J.H.z.-.l.J.J.F.J.J.J.J.J.J.J.J.-.> O . + 0 F.J.J.J.J.J.x./ 5 2 5 ` z.J.J.J.H.H.F.l.:.1 . $ +.J.J.J.J.x.Q ",
+"T F.J.J./ # + +.J.J.J.J.J.J.J.J.J.J.J.J.:.6 < / H.J.J.J.z.0 ; e k./ r -.F.J.J.J.J.J.z.5 o @ O o 5 x.J.J.J.J.F.~ & + + o # 0 F.J.J.J.H.H.H.F.> . * :.J.J.H.J.x.Q ",
+"U z.L.H./ # + +.J.J.J.J.J.J.J.H.J.J.J.H.-.< < ;.L.J.J.J.:.* . - < # O ; / J.H.H.J.J.:.- o 7 = X 0 H.J.J.J.J.F.4 X - 0 & X % / F.H.H.J.J.J.:.- X = l.J.J.J.J.z.J ",
+"J l.J.J.! @ # +.J.J.J.J.J.J.J.H.J.H.J.F.9 o # T J.J.J.J.:.* . o X # # X < F.H.H.J.J.:.- O , % X 6 F.J.J.J.J.:.- o T F.! & o = +.J.H.J.J.J.;.& X < z.J.J.J.J.l.H ",
+"H :.L.H.! + + O.H.H.J.J.J.J.J.H.J.J.J.F.1 X * ;.J.J.J.J.+.$ . . # T G o % $.H.H.J.J.H.9 o X X X - :.J.J.H.H.F.- O r H.J.T O o T F.J.J.J.J.! + o 5 F.J.H.J.J.k.H ",
+"H $.J.H.T o + 6 T ! +.+.:.k.F.H.J.J.J.:.= X - z.J.J.J.J.! @ . O 9 F.~ o + / H.H.J.J.J.:.6 - - # @ / J.J.H.H.F.9 O > :.:.T O X T F.J.J.J.J.~ O O T F.J.H.J.J.$.H ",
+"S ! H.l.2 X X o @ # @ # * - e z.J.J.J.;.& o 3 F.H.H.H.H.T # . = :.H./ # # T F.J.J.J.L.J.F.F.:.r O 3 :.H.J.J.H.$.; + > < # o - +.J.H.J.J.F.T O O / H.H.H.J.F.] S ",
+"S J l.F.T < < 3 5 5 3 1 - & 4 -.J.J.J.:.1 - _ H.H.H.H.H.-.2 < ! H.H.:.2 * T F.J.H.F.:.H.H.H.J.+.% # / H.J.J.H.H.+.< & & = 3 +.F.J.J.J.J.H.+.3 3 g.J.H.H.J.z.J S ",
+"S H 3.H.F.l.l.F.F.F.H.x.k.-.:.H.J.J.J.H.k.:.H.J.H.H.H.H.F.F.l.H.H.H.H.:.-.F.H.J.H.T < T F.H.H.F.3 o 3 F.J.H.H.H.J.z.-.;.:.F.H.H.J.J.H.J.J.H.:.H.H.H.J.J.J.+.H S ",
+"YXS T F.J.H.H.H.J.J.J.J.J.J.J.J.J.J.J.J.H.H.H.H.J.H.H.H.H.J.J.H.H.H.H.H.H.H.J.J.F.r o & T :.:.:.> o 5 F.J.H.H.H.J.J.J.J.J.J.J.J.J.J.J.J.H.J.J.J.J.J.J.J.x.' H YX",
+"YXH S $.H.H.H.J.J.J.J.H.J.J.J.J.J.H.J.H.J.J.J.J.J.J.J.J.H.H.J.J.J.J.H.J.H.J.J.J.J.:.3 # + = = * @ - +.H.J.H.J.H.J.H.J.J.J.J.J.J.H.J.H.J.J.J.J.J.J.J.J.H.$.H H YX",
+"YXH H J k.J.H.H.J.H.J.J.J.J.J.J.J.J.J.J.H.J.H.H.J.H.J.H.J.J.H.J.H.J.J.J.H.J.H.J.J.L.:.~ 9 > 2 3 T :.H.H.J.J.J.J.J.J.H.J.H.J.H.J.J.J.J.J.J.H.H.J.H.J.L.:.P S H YX",
+"YXYXH S Q z.J.J.J.H.J.H.J.J.J.J.H.J.H.J.J.J.J.J.J.J.J.J.H.J.J.J.J.J.J.J.J.H.J.J.J.J.J.J.F.:.F.F.H.H.H.H.H.J.H.H.J.J.J.J.J.J.H.H.J.J.H.J.H.H.H.H.H.H.F.W S H YXYX",
+"YXYXYXH H [ x.J.J.J.J.J.J.J.J.J.J.J.J.J.J.H.H.J.H.J.H.J.J.J.J.H.H.J.J.J.J.J.J.H.J.J.J.J.J.L.H.H.H.H.H.H.J.J.H.H.H.J.H.J.H.J.H.H.H.J.H.J.H.H.H.H.H.F.{ H H YXYXYX",
+"YXYXYXYXH H Q k.H.J.J.J.J.J.J.J.H.J.J.J.H.H.H.H.J.H.H.H.J.J.J.J.J.J.J.J.H.H.H.H.J.J.J.J.H.H.H.H.H.H.H.H.H.H.H.H.J.J.H.H.H.H.H.H.J.J.J.J.J.J.H.H.:./ H H YXYXYXYX",
+"YXYXYXYXYXH H P %.x.J.J.J.J.J.J.J.J.J.J.H.F.H.H.J.H.H.H.J.J.J.J.J.J.J.J.H.H.H.F.J.J.J.J.H.F.H.H.H.H.H.H.J.J.H.H.J.J.H.F.J.H.H.H.J.J.J.L.J.J.F.$.W H H YXYXYXYXYX",
+"YXYXYXYXYXH H H J U #.:.z.z.x.x.F.F.F.F.F.F.z.F.F.F.F.l.F.F.F.F.F.z.F.F.F.F.F.F.F.F.F.F.F.F.z.F.F.F.z.F.F.F.F.z.F.F.F.F.F.F.F.z.F.F.z.:.:.$.W H S S S YXYXYXYXYX",
+"YXYXYXYXYXYXYXYXJ S S J J ' ' ' W ' { T W { W W W W W W W W W W W W W ' ' T W { T { W W { W W W W W W W W W W W W W W W W W W W W { W J W H S S YXYXYXYXYXYXYXYX"
+};
diff --git a/src/lingot-mainframe.c b/src/lingot-mainframe.c
new file mode 100644
index 0000000..a98c16d
--- /dev/null
+++ b/src/lingot-mainframe.c
@@ -0,0 +1,766 @@
+//-*- 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 <stdio.h>
+#include <math.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+
+#include "lingot-defs.h"
+
+#include "lingot-config.h"
+#include "lingot-mainframe.h"
+#include "lingot-config-dialog.h"
+#include "lingot-gauge.h"
+#include "lingot-i18n.h"
+
+#include "lingot-background.xpm"
+#include "lingot-logo.xpm"
+
+void lingot_mainframe_redraw(LingotMainFrame*);
+void lingot_mainframe_put_frequency(LingotMainFrame*);
+void lingot_mainframe_draw_gauge(LingotMainFrame*);
+void lingot_mainframe_draw_spectrum(LingotMainFrame*);
+
+GdkColor black_color;
+GdkColor gauge_color;
+GdkColor spectrum_background_color;
+GdkColor spectrum_color;
+GdkColor noise_threshold_color;
+GdkColor grid_color;
+GdkColor freq_color;
+
+// sizes
+
+int gauge_size_x = 160;
+int gauge_size_y = 100;
+
+int spectrum_size_y = 64;
+
+// spectrum area margins
+int spectrum_bottom_margin = 16;
+int spectrum_top_margin = 12;
+int spectrum_x_margin = 15;
+
+GtkWidget* view_spectrum_item;
+GtkWidget* spectrum_frame;
+
+PangoFontDescription* spectrum_legend_font_desc;
+
+void lingot_mainframe_callback_redraw(GtkWidget* w, GdkEventExpose* e,
+ LingotMainFrame* frame) {
+ if (frame->core->running)
+ lingot_mainframe_redraw(frame);
+}
+
+void lingot_mainframe_callback_destroy(GtkWidget* w, LingotMainFrame* frame) {
+ if (frame->core->running) {
+ g_source_remove(frame->visualization_timer_uid);
+ g_source_remove(frame->calculation_timer_uid);
+ g_source_remove(frame->freq_timer_uid);
+ gtk_main_quit();
+ }
+}
+
+void lingot_mainframe_callback_about(GtkWidget* w, LingotMainFrame* frame) {
+ if (frame->core->running) {
+ static const gchar* authors[] = {
+ "Ibán Cereijo Graña <ibancg@gmail.com>",
+ "Jairo Chapela Martínez <jairochapela@gmail.com>", NULL };
+
+ const gchar* artists[] = { "Matthew Blissett (Logo design)", NULL };
+
+ gtk_show_about_dialog(NULL,
+ "name", "Lingot",
+ "version", VERSION,
+ "copyright", "\xC2\xA9 2004-2007 Ibán Cereijo Graña\n\xC2\xA9 2004-2007 Jairo Chapela Martínez",
+ "comments", _("Accurate and easy to use musical instrument tuner"),
+ "authors", authors,
+ "artists", artists,
+ "translator-credits", _("translator-credits"),
+ "logo-icon-name", "lingot-logo",
+ NULL);
+ }
+}
+
+void lingot_mainframe_callback_view_spectrum(GtkWidget* w,
+ LingotMainFrame* frame) {
+ if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(view_spectrum_item))) {
+ gtk_widget_hide(spectrum_frame);
+ } else {
+ gtk_widget_show(spectrum_frame);
+ }
+}
+
+void lingot_mainframe_callback_config_dialog(GtkWidget* w,
+ LingotMainFrame* frame) {
+ if (frame->core->running) {
+ if (!frame->config_dialog) {
+ frame->config_dialog = lingot_config_dialog_new(frame);
+ } else {
+ // TODO: activate config dialog
+ }
+ }
+}
+
+/* Callback for visualization */
+gboolean lingot_mainframe_callback_visualization(gpointer data) {
+ unsigned int period;
+
+ LingotMainFrame* frame = (LingotMainFrame*) data;
+
+ if (frame->core->running) {
+ lingot_mainframe_draw_gauge(frame);
+
+ period = 1000/frame->conf->visualization_rate;
+ frame->visualization_timer_uid = g_timeout_add(period,
+ lingot_mainframe_callback_visualization, frame);
+ }
+
+ return 0;
+}
+
+/* Callback for calculation */
+gboolean lingot_mainframe_callback_calculation(gpointer data) {
+ unsigned int period;
+
+ LingotMainFrame* frame = (LingotMainFrame*) data;
+
+ if (frame->core->running) {
+ lingot_mainframe_draw_spectrum(frame);
+
+ period = 1000/frame->conf->calculation_rate;
+ frame->calculation_timer_uid = g_timeout_add(period,
+ lingot_mainframe_callback_calculation, frame);
+ }
+
+ return 0;
+}
+
+/* Callback for frequency calculation */
+gboolean lingot_mainframe_callback_frequency(gpointer data) {
+ unsigned int period;
+ LingotMainFrame* frame = (LingotMainFrame*) data;
+
+ if (frame->core->running) {
+ lingot_mainframe_put_frequency(frame);
+
+ period = 1000/GAUGE_RATE;
+ frame->freq_timer_uid = g_timeout_add(period,
+ lingot_mainframe_callback_frequency, frame);
+ }
+
+ return 0;
+}
+
+void lingot_mainframe_color(GdkColor* color, int red, int green, int blue) {
+ color->red = red;
+ color->green = green;
+ color->blue = blue;
+}
+
+LingotMainFrame* lingot_mainframe_new(int argc, char *argv[]) {
+ GtkWidget* vertical_box;
+ GtkWidget* horizontal_box;
+ GtkWidget* file_menu;
+ GtkWidget* edit_menu;
+ GtkWidget* help_menu;
+ GtkWidget* preferences_item;
+ GtkWidget* quit_item;
+ GtkWidget* about_item;
+ GtkAccelGroup* accel_group;
+ GtkWidget* menu_bar;
+ GtkWidget* file_item;
+ GtkWidget* edit_item;
+ GtkWidget* help_item;
+ GtkWidget* frame1;
+ GtkWidget* frame3;
+ GtkWidget* vbinfo;
+ LingotMainFrame* frame;
+ unsigned int period;
+
+ frame = malloc(sizeof(LingotMainFrame));
+
+ frame->config_dialog = NULL;
+ frame->pix_stick = NULL;
+
+ frame->conf = lingot_config_new();
+ lingot_config_load(frame->conf, CONFIG_FILE_NAME);
+
+ frame->gauge = lingot_gauge_new(frame->conf->vr); // gauge in rest situation
+ frame->core = lingot_core_new(frame->conf);
+
+ // ----- FREQUENCY FILTER CONFIGURATION ------
+
+ // low pass IIR filter.
+ FLT freq_filter_a[] =
+ { 1.0, -0.5};
+ FLT freq_filter_b[] =
+ { 0.5};
+
+ frame->freq_filter= lingot_filter_new( 1, 0, freq_filter_a, freq_filter_b);
+
+ // ---------------------------------------------------
+
+ gtk_init(&argc, &argv);
+ gtk_set_locale();
+
+ // creates the window
+ frame->win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_position(GTK_WINDOW(frame->win), GTK_WIN_POS_CENTER);
+
+ GdkPixbuf* logo = gdk_pixbuf_new_from_xpm_data(lingotlogo);
+ gtk_icon_theme_add_builtin_icon("lingot-logo", 64, logo);
+
+ gtk_window_set_icon(GTK_WINDOW(frame->win), logo);
+
+ // g_object_unref(logo);
+
+ gtk_window_set_title(GTK_WINDOW(frame->win), _("lingot"));
+
+ gtk_container_set_border_width(GTK_CONTAINER(frame->win), 6);
+
+ // fixed size
+ gtk_window_set_resizable(GTK_WINDOW(frame->win), FALSE);
+ // tab organization by following container
+ vertical_box = gtk_vbox_new(FALSE, 0);
+ gtk_container_add(GTK_CONTAINER(frame->win), vertical_box);
+
+ file_menu = gtk_menu_new();
+ edit_menu = gtk_menu_new();
+ help_menu = gtk_menu_new();
+ GtkWidget* view_menu = gtk_menu_new();
+
+ accel_group = gtk_accel_group_new();
+
+ /* menu elements */
+ preferences_item = gtk_image_menu_item_new_from_stock(
+ GTK_STOCK_PREFERENCES, accel_group);
+ quit_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, accel_group);
+ about_item = gtk_image_menu_item_new_from_stock(GTK_STOCK_ABOUT,
+ accel_group);
+ view_spectrum_item= gtk_check_menu_item_new_with_label(_("Spectrum"));
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(view_spectrum_item),
+ TRUE);
+
+ /* addition */
+ gtk_menu_append(GTK_MENU(file_menu), quit_item);
+ gtk_menu_append(GTK_MENU(edit_menu), preferences_item);
+ gtk_menu_append(GTK_MENU(view_menu), view_spectrum_item);
+ gtk_menu_append(GTK_MENU(help_menu), about_item);
+
+ gtk_widget_add_accelerator(preferences_item, "activate", accel_group, 'o',
+ GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
+
+ gtk_widget_add_accelerator(quit_item, "activate", accel_group, 'q',
+ GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
+
+ gtk_window_add_accel_group(GTK_WINDOW(frame->win), accel_group);
+
+ gtk_signal_connect(GTK_OBJECT(preferences_item), "activate",
+ GTK_SIGNAL_FUNC(lingot_mainframe_callback_config_dialog), frame);
+
+ gtk_signal_connect(GTK_OBJECT(quit_item), "activate",
+ GTK_SIGNAL_FUNC(lingot_mainframe_callback_destroy), frame);
+
+ gtk_signal_connect(GTK_OBJECT(about_item), "activate",
+ GTK_SIGNAL_FUNC(lingot_mainframe_callback_about), frame);
+
+ gtk_signal_connect(GTK_OBJECT(view_spectrum_item), "activate",
+ GTK_SIGNAL_FUNC(lingot_mainframe_callback_view_spectrum), frame);
+
+ menu_bar = gtk_menu_bar_new();
+ gtk_widget_show(menu_bar);
+ gtk_box_pack_start_defaults(GTK_BOX(vertical_box), menu_bar);
+
+ file_item = gtk_menu_item_new_with_mnemonic(_("_File"));
+ edit_item = gtk_menu_item_new_with_mnemonic(_("_Edit"));
+ GtkWidget* view_item = gtk_menu_item_new_with_mnemonic(_("_View"));
+ help_item = gtk_menu_item_new_with_mnemonic(_("_Help"));
+ gtk_menu_item_right_justify(GTK_MENU_ITEM(help_item));
+
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(file_item), file_menu);
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(edit_item), edit_menu);
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(view_item), view_menu);
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(help_item), help_menu);
+
+ gtk_menu_bar_append(GTK_MENU_BAR(menu_bar), file_item);
+ gtk_menu_bar_append(GTK_MENU_BAR(menu_bar), edit_item);
+ gtk_menu_bar_append(GTK_MENU_BAR(menu_bar), view_item);
+ gtk_menu_bar_append(GTK_MENU_BAR(menu_bar), help_item);
+
+#ifdef GTK12
+ gtk_menu_bar_set_shadow_type( GTK_MENU_BAR (menu_bar), GTK_SHADOW_NONE );
+#endif
+
+ ////////////////////////////////////////////////////
+
+ // a fixed container to put the two upper frames in fixed positions
+ horizontal_box = gtk_hbox_new(FALSE, 0);
+ gtk_box_pack_start_defaults(GTK_BOX(vertical_box), horizontal_box);
+
+ // gauge frame
+ frame1 = gtk_frame_new(_("Deviation"));
+ // gtk_fixed_put(GTK_FIXED(fix), frame1, 0, 0);
+ gtk_box_pack_start(GTK_BOX(horizontal_box), frame1, FALSE, FALSE, 0);
+
+ // note frame
+ frame3 = gtk_frame_new(_("Note"));
+ //gtk_fixed_put(GTK_BOX(hb), frame3, 164, 0);
+ gtk_box_pack_start(GTK_BOX(horizontal_box), frame3, TRUE, TRUE, 0);
+
+ // spectrum frame at bottom
+ spectrum_frame = gtk_frame_new(_("Spectrum"));
+ gtk_box_pack_end_defaults(GTK_BOX(vertical_box), spectrum_frame);
+
+ // for gauge drawing
+ frame->gauge_area = gtk_drawing_area_new();
+ gtk_widget_set_size_request(GTK_WIDGET(frame->gauge_area), gauge_size_x,
+ gauge_size_y);
+ gtk_container_add(GTK_CONTAINER(frame1), frame->gauge_area);
+
+ // for spectrum drawing
+ GtkObject* adjust = gtk_adjustment_new(0.0, 0.0, ((frame->conf->fft_size
+ > 256) ? 0.5 : 1.0)*frame->conf->sample_rate, 1.0, 100.0, 100.0);
+ frame->spectrum_scroll = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(
+ GTK_ADJUSTMENT(adjust), NULL));
+ frame->spectrum_area = gtk_drawing_area_new();
+
+ int
+ x = ((frame->conf->fft_size > 256) ? (frame->conf->fft_size >> 1)
+ : 256) + 2*spectrum_x_margin;
+ int y = spectrum_size_y + spectrum_bottom_margin + spectrum_top_margin;
+
+ gtk_widget_set_size_request(GTK_WIDGET(frame->spectrum_area), x, y);
+ gtk_scrolled_window_set_policy(frame->spectrum_scroll,
+ (frame->conf->fft_size > 512) ? GTK_POLICY_ALWAYS
+ : GTK_POLICY_NEVER, GTK_POLICY_NEVER);
+ gtk_scrolled_window_add_with_viewport(frame->spectrum_scroll,
+ frame->spectrum_area);
+ gtk_widget_set_size_request(GTK_WIDGET(frame->spectrum_scroll), 260 + 2
+ *spectrum_x_margin, spectrum_size_y + spectrum_bottom_margin
+ + spectrum_top_margin + 4
+ + ((frame->conf->fft_size > 512) ? 16 : 0));
+ gtk_container_add(GTK_CONTAINER(spectrum_frame),
+ GTK_WIDGET(frame->spectrum_scroll));
+
+ // for note and frequency displaying
+ vbinfo = gtk_vbox_new(FALSE, 0);
+ gtk_widget_set_size_request(GTK_WIDGET(vbinfo), 96 + 2*spectrum_x_margin,
+ gauge_size_y);
+ gtk_container_add(GTK_CONTAINER(frame3), vbinfo);
+
+ frame->freq_label = gtk_label_new(_("freq"));
+ gtk_box_pack_start_defaults(GTK_BOX(vbinfo), frame->freq_label);
+
+ frame->error_label = gtk_label_new(_("err"));
+ gtk_box_pack_end_defaults(GTK_BOX(vbinfo), frame->error_label);
+
+ frame->note_label = gtk_label_new(_("note"));
+ gtk_widget_set_name(frame->note_label, "label_nota");
+ gtk_box_pack_end_defaults(GTK_BOX(vbinfo), frame->note_label);
+
+ // show all
+ gtk_widget_show_all(frame->win);
+
+ // two pixmaps for double buffer in gauge and spectrum drawing
+ // (virtual screen)
+ gdk_pixmap_new(frame->gauge_area->window, gauge_size_x, gauge_size_y, -1);
+ frame->pix_spectrum= gdk_pixmap_new(frame->spectrum_area->window, x, y, -1);
+
+ // GTK signals
+ gtk_signal_connect(GTK_OBJECT(frame->gauge_area), "expose_event",
+ GTK_SIGNAL_FUNC(lingot_mainframe_callback_redraw), frame);
+ gtk_signal_connect(GTK_OBJECT(frame->spectrum_area), "expose_event",
+ GTK_SIGNAL_FUNC(lingot_mainframe_callback_redraw), frame);
+ gtk_signal_connect(GTK_OBJECT(frame->win), "destroy",
+ GTK_SIGNAL_FUNC(lingot_mainframe_callback_destroy), frame);
+
+ period = 1000/frame->conf->visualization_rate;
+ frame->visualization_timer_uid = g_timeout_add(period,
+ lingot_mainframe_callback_visualization, frame);
+
+ period = 1000/frame->conf->calculation_rate;
+ frame->calculation_timer_uid = g_timeout_add(period,
+ lingot_mainframe_callback_calculation, frame);
+
+ period = 1000/GAUGE_RATE;
+ frame->freq_timer_uid = g_timeout_add(period,
+ lingot_mainframe_callback_frequency, frame);
+
+ lingot_mainframe_color(&gauge_color, 0xC000, 0x0000, 0x2000);
+ lingot_mainframe_color(&spectrum_background_color, 0x1111, 0x3333, 0x1111);
+ lingot_mainframe_color(&spectrum_color, 0x2222, 0xEEEE, 0x2222);
+ lingot_mainframe_color(&noise_threshold_color, 0x8888, 0x8888, 0x2222);
+ lingot_mainframe_color(&grid_color, 0x9000, 0x9000, 0x9000);
+ lingot_mainframe_color(&freq_color, 0xFFFF, 0x2222, 0x2222);
+
+ gdk_color_alloc(gdk_colormap_get_system(), &gauge_color);
+ gdk_color_alloc(gdk_colormap_get_system(), &spectrum_color);
+ gdk_color_alloc(gdk_colormap_get_system(), &spectrum_background_color);
+ gdk_color_alloc(gdk_colormap_get_system(), &noise_threshold_color);
+ gdk_color_alloc(gdk_colormap_get_system(), &grid_color);
+ gdk_color_alloc(gdk_colormap_get_system(), &freq_color);
+ gdk_color_black(gdk_colormap_get_system(), &black_color);
+
+ spectrum_legend_font_desc
+ =pango_font_description_from_string("Helvetica Plain 7");
+
+ return frame;
+}
+
+void lingot_mainframe_destroy(LingotMainFrame* frame) {
+ lingot_gauge_destroy(frame->gauge);
+ lingot_core_destroy(frame->core);
+ lingot_filter_destroy(frame->freq_filter);
+ lingot_config_destroy(frame->conf);
+ if (frame->config_dialog)
+ lingot_config_dialog_destroy(frame->config_dialog);
+
+ // pango_font_description_free(spectrum_legend_font_desc);
+ // gtk_widget_destroy(frame->freq_label);
+ // gtk_widget_destroy(frame->error_label);
+ // gtk_widget_destroy(frame->note_label);
+ // gtk_widget_destroy(frame->win);
+
+ // gdk_color_free(&gauge_color);
+ // gdk_color_free(&spectrum_color);
+ // gdk_color_free(&spectrum_background_color);
+ // gdk_color_free(&noise_threshold_color);
+ // gdk_color_free(&grid_color);
+ // gdk_color_free(&freq_color);
+
+ free(frame);
+}
+
+void lingot_mainframe_run(LingotMainFrame* frame) {
+ lingot_core_start(frame->core);
+ gtk_main();
+ lingot_core_stop(frame->core);
+ lingot_mainframe_destroy(frame);
+}
+// ---------------------------------------------------------------------------
+
+void lingot_mainframe_redraw(LingotMainFrame* frame) {
+ lingot_mainframe_draw_gauge(frame);
+ lingot_mainframe_draw_spectrum(frame);
+}
+
+// ---------------------------------------------------------------------------
+
+void lingot_mainframe_draw_gauge(LingotMainFrame* frame) {
+ GdkGC* gc = frame->gauge_area->style->fg_gc[frame->gauge_area->state];
+ GdkWindow* w = frame->gauge_area->window;
+ GdkGCValues gv;
+
+ gdk_gc_get_values(gc, &gv);
+
+ static FLT gauge_size = 90.0;
+ FLT max = 1.0;
+
+ // draws background
+ if (!frame->pix_stick) {
+ frame->pix_stick = gdk_pixmap_create_from_xpm_d(
+ frame->gauge_area->window, NULL,
+ NULL, background2_xpm);
+ }
+ gdk_draw_pixmap(frame->gauge_area->window, gc, frame->pix_stick, 0, 0, 0,
+ 0, 160, 100);
+
+ // and draws gauge
+ gdk_gc_set_foreground(gc, &gauge_color);
+
+ gdk_draw_line(w, gc, gauge_size_x >> 1, gauge_size_y - 1,
+ (gauge_size_x>> 1) + (int)rint(gauge_size
+ *sin(frame->gauge->position *M_PI/(1.5*max))), gauge_size_y
+ - 1- (int)rint(gauge_size *cos(frame->gauge->position*M_PI
+ /(1.5*max))));
+
+ // black edge.
+ gdk_gc_set_foreground(gc, &black_color);
+ gdk_draw_rectangle(w, gc, FALSE, 0, 0, gauge_size_x - 1, gauge_size_y - 1);
+
+ gdk_draw_pixmap(frame->gauge_area->window, gc, w, 0, 0, 0, 0, gauge_size_x,
+ gauge_size_y);
+ gdk_flush();
+}
+
+void lingot_mainframe_draw_spectrum(LingotMainFrame* frame) {
+ PangoLayout* layout;
+
+ int
+ spectrum_size_x =
+ ((frame->conf->fft_size > 256) ? (frame->conf->fft_size
+ >> 1) : 256);
+
+ // minimum grid size in pixels
+ static int minimum_grid_width = 50;
+
+ /* scale factors to draw the grid. We will choose the smaller factor that
+ respects the minimum_grid_width */
+ static double
+ scales[] = { 0.01, 0.05, 0.1, 0.2, 0.5, 1, 2, 4, 11, 22, -1.0 };
+
+ // spectrum drawing mode
+ static gboolean spectrum_drawing_filled = TRUE;
+
+ // grid division in dB
+ static FLT grid_db_height = 25;
+
+ register unsigned int i;
+ int j;
+ int old_j;
+
+ GdkGC* gc = frame->spectrum_area->style->fg_gc[frame->spectrum_area->state];
+ GdkWindow* window = frame->pix_spectrum; //spectrum->window;
+ GdkGCValues gv;
+ gdk_gc_get_values(gc, &gv);
+
+ // clear all
+ gdk_gc_set_foreground(gc, &spectrum_background_color);
+ gdk_draw_rectangle(window, gc, TRUE, 0, 0, spectrum_size_x + 2
+ *spectrum_x_margin, spectrum_size_y + spectrum_bottom_margin
+ + spectrum_top_margin);
+
+ gdk_gc_set_foreground(gc, &grid_color);
+
+ gdk_draw_line(window, gc, spectrum_x_margin, spectrum_size_y
+ + spectrum_top_margin, spectrum_x_margin + spectrum_size_x,
+ spectrum_size_y + spectrum_top_margin);
+
+ // choose scale factor
+ for (i = 0; scales[i] > 0.0; i++) {
+ if ((1e3*scales[i]*frame->conf->fft_size*frame->conf->oversampling
+ /frame->conf->sample_rate) > minimum_grid_width)
+ break;
+ }
+
+ if (scales[i] < 0.0)
+ i--;
+
+ FLT scale = scales[i];
+
+ int grid_width = 1e3*scales[i]*frame->conf->fft_size
+ *frame->conf->oversampling/frame->conf->sample_rate;
+
+ char buff[10];
+
+ FLT freq = 0.0;
+ for (i = 0; i <= spectrum_size_x; i += grid_width) {
+ gdk_draw_line(window, gc, spectrum_x_margin + i, spectrum_top_margin,
+ spectrum_x_margin + i, spectrum_size_y + spectrum_top_margin
+ + 3);
+
+ if (freq == 0.0) {
+ sprintf(buff, "0 Hz");
+ } else if (floor(freq) == freq)
+ sprintf(buff, "%0.0f kHz", freq);
+ else if (floor(10*freq) == 10*freq) {
+ if (freq <= 1000.0)
+ sprintf(buff, "%0.0f Hz", 1e3*freq);
+ else
+ sprintf(buff, "%0.1f kHz", freq);
+ } else {
+ if (freq <= 100.0)
+ sprintf(buff, "%0.0f Hz", 1e3*freq);
+ else
+ sprintf(buff, "%0.2f kHz", freq);
+ }
+
+ layout = gtk_widget_create_pango_layout(frame->spectrum_area, buff);
+ pango_layout_set_font_description(layout, spectrum_legend_font_desc);
+ gdk_draw_layout(window, gc, spectrum_x_margin - 8 + i, spectrum_size_y
+ + spectrum_top_margin + 5, layout);
+ freq += scale;
+ }
+
+# define PLOT_GAIN 8
+
+ sprintf(buff, "dB");
+
+ layout = gtk_widget_create_pango_layout(frame->spectrum_area, buff);
+ pango_layout_set_font_description(layout, spectrum_legend_font_desc);
+ gdk_draw_layout(window, gc, spectrum_x_margin - 6, 2, layout);
+
+ int grid_height = (int) (PLOT_GAIN*log10(pow(10.0, grid_db_height/10.0))); // dB.
+ j = 0;
+ for (i = 0; i <= spectrum_size_y; i += grid_height) {
+ if (j == 0)
+ sprintf(buff, " %i", j);
+ else
+ sprintf(buff, "%i", j);
+
+ layout = gtk_widget_create_pango_layout(frame->spectrum_area, buff);
+ pango_layout_set_font_description(layout, spectrum_legend_font_desc);
+ gdk_draw_layout(window, gc, 2, spectrum_size_y + spectrum_top_margin
+ - i - 5, layout);
+
+ gdk_draw_line(window, gc, spectrum_x_margin, spectrum_size_y
+ + spectrum_top_margin - i, spectrum_x_margin + spectrum_size_x,
+ spectrum_size_y + spectrum_top_margin - i);
+
+ j += grid_db_height;
+ }
+
+ gdk_gc_set_foreground(gc, &noise_threshold_color);
+
+ // noise threshold drawing.
+ j = -1;
+ for (i = 0; (i < frame->conf->fft_size) && (i < spectrum_size_x); i++) {
+ if ((i % 10) > 5)
+ continue;
+
+ FLT w = 2*M_PI*i/frame->conf->fft_size;
+ //FLT noise = pow(10.0, (frame->conf->noise_threshold_db*(1.0 - 0.9*w/M_PI))/10.0);
+ //FLT noise = lingot_signal_get_noise_threshold(frame->conf, w);
+ FLT noise = frame->conf->noise_threshold_nu;
+ old_j = j;
+ j = (noise > 1.0) ? (int) (PLOT_GAIN*log10(noise)) : 0; // dB.
+ if ((old_j >= 0) && (old_j < spectrum_size_y)&& (j >= 0)&& (j
+ < spectrum_size_y))
+ gdk_draw_line(window, gc, spectrum_x_margin + i - 1,
+ spectrum_size_y + spectrum_top_margin - old_j,
+ spectrum_x_margin + i, spectrum_size_y
+ + spectrum_top_margin - j);
+ }
+
+ gdk_gc_set_foreground(gc, &spectrum_color);
+
+ // spectrum drawing.
+ j = -1;
+ for (i = 0; (i < frame->conf->fft_size - 1) && (i < spectrum_size_x - 1); i++) {
+ old_j = j;
+ j = (frame->core->X[i] > 1.0) ? (int) (PLOT_GAIN*log10(frame->core->X[i])) : 0; // dB.
+ if (spectrum_drawing_filled) {
+ if (j < spectrum_size_y)
+ gdk_draw_line(window, gc, spectrum_x_margin + i,
+ spectrum_size_y + spectrum_top_margin - 1,
+ spectrum_x_margin + i, spectrum_top_margin + ((j
+ < spectrum_size_y) ? (spectrum_size_y - j) : 0));
+ } else if ((old_j >= 0) && (old_j < spectrum_size_y)&& (j >= 0)&& (j
+ < spectrum_size_y))
+ gdk_draw_line(window, gc, spectrum_x_margin + i - 1,
+ spectrum_size_y + spectrum_top_margin - old_j,
+ spectrum_x_margin + i, spectrum_size_y
+ + spectrum_top_margin - j);
+ }
+
+ if (frame->core->freq != 0.0) {
+
+ // fundamental frequency mark with a red point.
+ gdk_gc_set_foreground(gc, &freq_color);
+
+ // index of closest sample to fundamental frequency.
+ i = (int) rint(frame->core->freq*frame->conf->fft_size
+ *frame->conf->oversampling/frame->conf->sample_rate);
+ if ((i < frame->conf->fft_size - 1) && (i < spectrum_size_x - 1)) {
+ j = (frame->core->X[i] > 1.0) ? (int) (PLOT_GAIN*log10(frame->core->X[i])) : 0; // dB.
+ if (j < spectrum_size_y - 1)
+ gdk_draw_rectangle(window, gc, TRUE, spectrum_x_margin + i-1,
+ spectrum_size_y + spectrum_top_margin - j - 1, 3, 3);
+ }
+ }
+
+# undef PLOT_GAIN
+
+ gdk_gc_set_foreground(gc, &black_color);
+
+ gdk_draw_pixmap(frame->spectrum_area->window, gc, window, 0, 0, 0, 0,
+ spectrum_size_x + 2*spectrum_x_margin, spectrum_size_y
+ + spectrum_bottom_margin + spectrum_top_margin);
+ gdk_flush();
+}
+
+void lingot_mainframe_put_frequency(LingotMainFrame* frame) {
+ // note indexation by semitone.
+ static char* note_string[] = { "A", "A#", "B", "C", "C#", "D", "D#", "E",
+ "F", "F#", "G", "G#" };
+ const FLT Log2 = log(2.0);
+
+ FLT fret_f;
+ int fret;
+ char* current_note;
+ char labeltext_current_note[100];
+
+ static char error_string[30], freq_string[30];
+
+ LingotCore* core1 = frame->core;
+
+ // ignore continuous component
+ if (isnan(frame->core->freq) || (frame->core->freq < 10.0)) {
+ current_note = "---";
+ strcpy(error_string, "e = ---");
+ strcpy(freq_string, "f = ---");
+ lingot_gauge_compute(frame->gauge, frame->conf->vr);
+ } else {
+ // bring up some octaves to avoid negative frets.
+ fret_f = log(frame->core->freq/frame->conf->root_frequency)/Log2*12.0
+ + 12e2;
+
+ lingot_gauge_compute(frame->gauge, fret_f - rint(fret_f));
+ fret = ((int) rint(fret_f)) % 12;
+
+ current_note = note_string[fret];
+ sprintf(error_string, "e = %+4.2f%%", frame->gauge->position*100.0);
+ sprintf(freq_string, "f = %6.2f Hz", lingot_filter_filter_sample(
+ frame->freq_filter, frame->core->freq));
+ }
+
+ gtk_label_set_text(GTK_LABEL(frame->freq_label), freq_string);
+ gtk_label_set_text(GTK_LABEL(frame->error_label), error_string);
+
+ char* markup = g_markup_printf_escaped(
+ "<span size=\"xx-large\" weight=\"bold\">%s</span>", current_note);
+ gtk_label_set_markup(GTK_LABEL(frame->note_label), markup);
+ g_free(markup);
+}
+
+void lingot_mainframe_change_config(LingotMainFrame* frame, LingotConfig* conf) {
+ lingot_core_stop(frame->core);
+ lingot_core_destroy(frame->core);
+
+ // dup.
+ *frame->conf = *conf;
+
+ // resize spectrum area
+ g_object_unref(frame->pix_spectrum);
+
+ int
+ x = ((frame->conf->fft_size > 256) ? (frame->conf->fft_size >> 1)
+ : 256) + 2*spectrum_x_margin;
+ int y = spectrum_size_y + spectrum_top_margin + spectrum_bottom_margin;
+ gtk_widget_set_size_request(GTK_WIDGET(frame->spectrum_area), x, y);
+ frame->pix_spectrum= gdk_pixmap_new(frame->spectrum_area->window, x, y, -1);
+
+ gtk_scrolled_window_set_policy(frame->spectrum_scroll,
+ (frame->conf->fft_size > 512) ? GTK_POLICY_ALWAYS
+ : GTK_POLICY_NEVER, GTK_POLICY_NEVER);
+ gtk_widget_set_size_request(GTK_WIDGET(frame->spectrum_scroll), 260 + 2
+ *spectrum_x_margin, spectrum_size_y + spectrum_bottom_margin
+ + spectrum_top_margin + 4
+ + ((frame->conf->fft_size > 512) ? 16 : 0));
+
+ frame->core = lingot_core_new(frame->conf);
+ lingot_core_start(frame->core);
+}
diff --git a/src/lingot-mainframe.h b/src/lingot-mainframe.h
new file mode 100644
index 0000000..8e4dd08
--- /dev/null
+++ b/src/lingot-mainframe.h
@@ -0,0 +1,82 @@
+//-*- 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
+ */
+
+#ifndef __LINGOT_MAIN_FRAME_H__
+#define __LINGOT_MAIN_FRAME_H__
+
+#include "lingot-defs.h"
+#include "lingot-core.h"
+#include "lingot-gauge.h"
+#include "lingot-config.h"
+#include "lingot-config-dialog.h"
+#include "lingot-filter.h"
+
+#include <gtk/gtk.h>
+
+// Window that contains all controls, graphics, etc. of the tuner.
+
+//typedef struct _LingotMainFrame LingotMainFrame;
+
+struct _LingotMainFrame
+ {
+
+ // gtk widgets
+ GtkWidget* gauge_area;
+ GtkWidget* spectrum_area;
+ GtkWidget* note_label;
+
+ GtkWidget* freq_label;
+ GtkWidget* error_label;
+
+ GdkPixmap* pix_spectrum;
+ GdkPixmap* pix_stick;
+
+ GtkScrolledWindow* spectrum_scroll;
+
+ LingotFilter* freq_filter;
+
+ LingotGauge* gauge;
+
+ LingotCore* core;
+
+ GtkWidget* win;
+
+ GdkColor gauge_color;
+ GdkColor spectrum_color;
+
+ LingotConfigDialog* config_dialog;
+ LingotConfig* conf;
+
+ // timer uids
+ guint visualization_timer_uid;
+ guint calculation_timer_uid;
+ guint freq_timer_uid;
+ };
+
+LingotMainFrame* lingot_mainframe_new(int argc, char *argv[]);
+void lingot_mainframe_destroy(LingotMainFrame*);
+
+void lingot_mainframe_run(LingotMainFrame*);
+void lingot_mainframe_change_config(LingotMainFrame*, LingotConfig*);
+
+#endif //__LINGOT_MAIN_FRAME_H__
diff --git a/src/lingot-signal.c b/src/lingot-signal.c
new file mode 100644
index 0000000..e675216
--- /dev/null
+++ b/src/lingot-signal.c
@@ -0,0 +1,153 @@
+//-*- 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 <math.h>
+
+#include "lingot-signal.h"
+
+/*
+ peak identification functions.
+ */
+
+FLT lingot_signal_get_noise_threshold(LingotConfig* conf, FLT w)
+{
+ //return 0.5*(1.0 - 0.9*w/M_PI);
+ return pow(10.0, (conf->noise_threshold_db*(1.0 - 0.9*w/M_PI))/10.0);
+ //return conf->noise_threshold_un;
+}
+
+//---------------------------------------------------------------------------
+
+/* returns the index of the maximun of the buffer x of size N */
+void lingot_signal_get_max(FLT *x, int N, int* Mi) {
+ register int i;
+ FLT M;
+
+ M = -1.0;
+ *Mi = -1;
+
+ for (i = 0; i < N; i++) {
+
+ if (x[i] > M) {
+ M = x[i];
+ *Mi = i;
+ }
+ }
+}
+
+//---------------------------------------------------------------------------
+
+int lingot_signal_is_peak(LingotConfig* conf, FLT* x, int index) {
+ register unsigned int j;
+ //static FLT delta_w_FFT = 2.0*M_PI/conf->FFT_SIZE; // resolution in rads
+
+ // a peak must be greater than noise threshold.
+ if (x[index] < conf->noise_threshold_nu)
+ return 0;
+
+ for (j = 0; j < conf->peak_order; j++) {
+ if (x[index + j] < x[index + j + 1])
+ return 0;
+ if (x[index - j] < x[index - j - 1])
+ return 0;
+ }
+ return 1;
+}
+
+//---------------------------------------------------------------------------
+
+// search the fundamental peak given the spd and its 2nd derivative
+int lingot_signal_get_fundamental_peak(LingotConfig* conf, FLT *x, FLT* d2x,
+ int N) {
+ register unsigned int i, j, m;
+ int p_index[conf->peak_number];
+
+ // at this moment there is no peaks.
+ for (i = 0; i < conf->peak_number; i++)
+ p_index[i] = -1;
+
+ unsigned int lowest_index = (unsigned int)ceil(conf->min_frequency*(1.0
+ *conf->oversampling/conf->sample_rate)*conf->fft_size);
+
+ if (lowest_index < conf->peak_order)
+ lowest_index = conf->peak_order;
+
+ // I'll get the PEAK_NUMBER maximum peaks.
+ for (i = lowest_index; i < N - conf->peak_order; i++)
+ if (lingot_signal_is_peak(conf, x, i)) {
+
+ // search a place in the maximums buffer, if it doesn't exists, the
+ // lower maximum is candidate to be replaced.
+ m = 0; // first candidate.
+ for (j = 0; j < conf->peak_number; j++) {
+ if (p_index[j] == -1) {
+ m = j; // there is a place.
+ break;
+ }
+
+ if (d2x[p_index[j]] < d2x[p_index[m]])
+ m = j; // search the lowest.
+ }
+
+ if (p_index[m] == -1)
+ p_index[m] = i; // there is a place
+ else if (d2x[i] > d2x[p_index[m]])
+ p_index[m] = i; // if greater
+ }
+
+ FLT maximum = 0.0;
+ int maximum_index = -1;
+
+ // search the maximum peak
+ for (i = 0; i < conf->peak_number; i++)
+ if ((p_index[i] != -1) && (x[p_index[i]] > maximum)) {
+ maximum = x[p_index[i]];
+ maximum_index = p_index[i];
+ }
+
+ if (maximum_index == -1)
+ return N;
+
+ // all peaks much lower than maximum are deleted.
+ for (i = 0; i < conf->peak_number; i++)
+ if ((p_index[i] == -1) ||(conf->peak_rejection_relation_nu
+ *x[p_index[i]] < maximum))
+ p_index[i] = N; // there are available places in the buffer.
+
+ // search the lowest maximum index.
+ for (m = 0, j = 0; j < conf->peak_number; j++) {
+ if (p_index[j] < p_index[m])
+ m = j;
+ }
+
+ return p_index[m];
+}
+
+//---------------------------------------------------------------------------
+
+// generates a Hamming window of N samples
+void lingot_signal_hamming_window(int N, FLT* out) {
+ register int i;
+ for (i = 0; i < N; i++)
+ out[i] = 0.53836 - 0.46164*cos((2.0*M_PI*i)/(N-1));
+}
diff --git a/src/lingot-signal.h b/src/lingot-signal.h
new file mode 100644
index 0000000..7092f92
--- /dev/null
+++ b/src/lingot-signal.h
@@ -0,0 +1,49 @@
+//-*- 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
+ */
+
+#ifndef __LINGOT_SIGNAL_H__
+#define __LINGOT_SIGNAL_H__
+
+/*
+ peak identification functions.
+ */
+
+#include "lingot-defs.h"
+#include "lingot-config.h"
+
+// returns noise threshold at a given frequency w.
+FLT lingot_signal_get_noise_threshold(LingotConfig*, FLT w);
+
+// returns if buffer has a peak at given index
+int lingot_signal_is_peak(LingotConfig*, FLT* buffer, int index);
+
+// returns the maximum index.
+void lingot_signal_get_max(FLT *buffer, int N, int* Mi);
+
+// returns the index of the peak that carries the fundamental freq.
+int lingot_signal_get_fundamental_peak(LingotConfig*, FLT *x, FLT* y, int N);
+
+// generates a Hamming window of N samples
+void lingot_signal_hamming_window(int N, FLT* out);
+
+#endif /*__LINGOT_SIGNAL_H__*/
diff --git a/src/lingot.c b/src/lingot.c
new file mode 100644
index 0000000..4da9f53
--- /dev/null
+++ b/src/lingot.c
@@ -0,0 +1,132 @@
+//-*- 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <getopt.h>
+
+#include "lingot-defs.h"
+#include "lingot-config.h"
+#include "lingot-mainframe.h"
+#include "lingot-i18n.h"
+
+char CONFIG_FILE_NAME[100];
+
+int main(int argc, char *argv[])
+ {
+
+#ifdef ENABLE_NLS
+ bindtextdomain (GETTEXT_PACKAGE, LINGOT_LOCALEDIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+#endif
+
+ // default config file.
+ sprintf(CONFIG_FILE_NAME, "%s/" CONFIG_DIR_NAME DEFAULT_CONFIG_FILE_NAME,
+ getenv("HOME"));
+
+ // TODO: indicate complete config file path
+ if ((argc > 3) || (argc == 2))
+ {
+ printf("\nusage: lingot [-c config]\n\n");
+ return -1;
+ }
+ else if (argc > 1)
+ {
+ int c;
+ int digit_optind = 0;
+
+ while (1)
+ {
+ int this_option_optind = optind ? optind : 1;
+ int option_index = 0;
+ static struct option long_options[] =
+ {
+ { "config", 1, 0, 'c'},
+ { 0, 0, 0, 0}
+ };
+
+ c = getopt_long (argc, argv, "c:",
+ long_options, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+ case 'c':
+ sprintf(CONFIG_FILE_NAME, "%s/%s%s.conf", getenv("HOME"),
+ CONFIG_DIR_NAME, optarg);
+ printf("using config file %s\n", CONFIG_FILE_NAME);
+ break;
+
+ case '?':
+ break;
+
+ default:
+ printf ("?? getopt returned character code 0%o ??\n", c);
+ }
+ }
+
+ /* if (strcmp(argv[1], "-c") || (argc < 3))
+ {
+ printf("invalid argument\n");
+ return -1;
+ }
+
+ sprintf(CONFIG_FILE_NAME, "%s/%s%s.conf", getenv("HOME"),
+ CONFIG_DIR_NAME, argv[2]);
+ printf("using config file %s\n", CONFIG_FILE_NAME);*/
+ }
+
+ // if config file doesn't exists, i will create it.
+ FILE* fp;
+ if ((fp = fopen(CONFIG_FILE_NAME, "r")) == NULL)
+ {
+
+ char config_dir[100];
+ sprintf(config_dir, "%s/.lingot/", getenv("HOME"));
+ printf("creating directory %s ...\n", config_dir);
+ mkdir(config_dir, 0777); // creo el directorio.
+ printf("creating file %s ...\n", CONFIG_FILE_NAME);
+
+ // new configuration with default values.
+ LingotConfig* new_conf = lingot_config_new();
+ lingot_config_save(new_conf, CONFIG_FILE_NAME);
+ lingot_config_destroy(new_conf);
+
+ printf("ok\n");
+
+ }
+ else
+ fclose(fp);
+
+ LingotMainFrame* gui = lingot_mainframe_new(argc, argv);
+ lingot_mainframe_run(gui);
+
+ return 0;
+ }