libgsttonesrc_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
# headers we need but don't want installed
-noinst_HEADERS = gstpitch.h gsttonesrc.h kiss_fft.h _kiss_fft_guts.h settings.h
+noinst_HEADERS = gstpitch.h gsttonesrc.h kiss_fft.h _kiss_fft_guts.h settings.h temperament.h
EXTRA_DIST = tuner26.png tuner40.png tuner64.png
if HAVE_GTK
#demo_tuner_CFLAGS = $(GST_CFLAGS) $(GTK_CFLAGS)
#demo_tuner_LDFLAGS = $(GST_LIBS) $(GTK_LIBS)
-tuner_SOURCES = tuner.c settings.c
+tuner_SOURCES = tuner.c settings.c temperament.c
tuner_DEPENDENCIES = $(top_builddir)/src/libgstpitch.la $(top_builddir)/src/libgsttonesrc.la
tuner_CFLAGS = $(GST_CFLAGS) $(GTK_CFLAGS) $(MAEMO_CFLAGS) $(GCONF_CFLAGS) -D_GNU_SOURCE
tuner_LDADD = $(GST_LIBS) $(GTK_LIBS) $(MAEMO_LIBS) $(GCONF_LIBS) $(top_builddir)/src/libgstpitch.la $(top_builddir)/src/libgsttonesrc.la
--- /dev/null
+/* vim: set sts=2 sw=2 et: */
+/*
+ * Copyright (C) 2010 Jari Tenhunen <jari.tenhunen@iki.fi>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <math.h>
+#include "temperament.h"
+
+#define CENT (1.0005777895f) /* 1/100th of a half-tone */
+#define LOG_CENT (0.00057762265046662109f) /* ln (CENT) */
+#define MAGIC (1.059463094359f) /* 2^(1/2) */
+
+static Note scale[] = {
+ {"C0", 16.35},
+ {"C#0/Db0", 17.32},
+ {"D0", 18.35},
+ {"D#0/Eb0", 19.45},
+ {"E0", 20.60},
+ {"F0", 21.83},
+ {"F#0/Gb0", 23.12},
+ {"G0", 24.50},
+ {"G#0/Ab0", 25.96},
+ {"A0", 27.50},
+ {"A#0/Bb0", 29.14},
+ {"B0", 30.87},
+ {"C1", 32.70},
+ {"C#1/Db1", 34.65},
+ {"D1", 36.71},
+ {"D#1/Eb1", 38.89},
+ {"E1", 41.20},
+ {"F1", 43.65},
+ {"F#1/Gb1", 46.25},
+ {"G1", 49.00},
+ {"G#1/Ab1", 51.91},
+ {"A1", 55.00},
+ {"A#1/Bb1", 58.27},
+ {"B1", 61.74},
+ {"C2", 65.41},
+ {"C#2/Db2", 69.30},
+ {"D2", 73.42},
+ {"D#2/Eb2", 77.78},
+ {"E2", 82.41},
+ {"F2", 87.31},
+ {"F#2/Gb2", 92.50},
+ {"G2", 98.00},
+ {"G#2/Ab2", 103.83},
+ {"A2", 110.00},
+ {"A#2/Bb2", 116.54},
+ {"B2", 123.47},
+ {"C3", 130.81},
+ {"C#3/Db3", 138.59},
+ {"D3", 146.83},
+ {"D#3/Eb3", 155.56},
+ {"E3", 164.81},
+ {"F3", 174.61},
+ {"F#3/Gb3", 185.00},
+ {"G3", 196.00},
+ {"G#3/Ab3", 207.65},
+ {"A3", 220.00},
+ {"A#3/Bb3", 233.08},
+ {"B3", 246.94},
+ {"C4", 261.63},
+ {"C#4/Db4", 277.18},
+ {"D4", 293.66},
+ {"D#4/Eb4", 311.13},
+ {"E4", 329.63},
+ {"F4", 349.23},
+ {"F#4/Gb4", 369.99},
+ {"G4", 392.00},
+ {"G#4/Ab4", 415.30},
+ {"A4", 440.00},
+ {"A#4/Bb4", 466.16},
+ {"B4", 493.88},
+ {"C5", 523.25},
+ {"C#5/Db5", 554.37},
+ {"D5", 587.33},
+ {"D#5/Eb5", 622.25},
+ {"E5", 659.26},
+ {"F5", 698.46},
+ {"F#5/Gb5", 739.99},
+ {"G5", 783.99},
+ {"G#5/Ab5", 830.61},
+ {"A5", 880.00},
+ {"A#5/Bb5", 932.33},
+ {"B5", 987.77},
+ {"C6", 1046.50},
+ {"C#6/Db6", 1108.73},
+ {"D6", 1174.66},
+ {"D#6/Eb6", 1244.51},
+ {"E6", 1318.51},
+ {"F6", 1396.91},
+ {"F#6/Gb6", 1479.98},
+ {"G6", 1567.98},
+ {"G#6/Ab6", 1661.22},
+ {"A6", 1760.00},
+ {"A#6/Bb6", 1864.66},
+ {"B6", 1975.53},
+ {"C7", 2093.00},
+ {"C#7/Db7", 2217.46},
+ {"D7", 2349.32},
+ {"D#7/Eb7", 2489.02},
+ {"E7", 2637.02},
+ {"F7", 2793.83},
+ {"F#7/Gb7", 2959.96},
+ {"G7", 3135.96},
+ {"G#7/Ab7", 3322.44},
+ {"A7", 3520.00},
+ {"A#7/Bb7", 3729.31},
+ {"B7", 3951.07},
+};
+
+void
+recalculate_scale (double a4)
+{
+ int i;
+
+ for (i = 0; i < NUM_NOTES; i++) {
+ scale[i].frequency = a4 * pow (MAGIC, i - 57);
+ /* fprintf(stdout, "%s: %.2f\n", scale[i].name, scale[i].frequency); */
+ }
+}
+
+/* translate the interval (ratio of two freqs) into cents */
+gfloat
+interval2cent (gfloat freq, gfloat note)
+{
+ //return (gfloat) (log (freq / note) / log (CENT));
+ return (gfloat) (log (freq / note) / LOG_CENT);
+}
+
+Note *
+get_nearest_note (gfloat frequency)
+{
+ gint i, j;
+ gfloat diff, min_diff;
+
+ min_diff = frequency - (scale[0].frequency - 10);
+ for (i = j = 0; i < NUM_NOTES; i++) {
+ diff = frequency - scale[i].frequency;
+ if (fabs (diff) <= fabs (min_diff)) {
+ min_diff = diff;
+ j = i;
+ } else {
+ break;
+ }
+ }
+
+ return &(scale[j]);
+}
+
+Note *
+get_scale (void)
+{
+ return scale;
+}
--- /dev/null
+/* vim: set sts=2 sw=2 et: */
+/*
+ * Copyright (C) 2010 Jari Tenhunen <jari.tenhunen@iki.fi>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __TEMPERAMENT_H__
+#define __TEMPERAMENT_H__
+
+#include <gtk/gtk.h>
+
+typedef struct
+{
+ const gchar *name;
+ gfloat frequency;
+} Note;
+
+enum
+{
+ NUM_NOTES = 96
+};
+
+gfloat interval2cent (gfloat freq, gfloat note);
+void recalculate_scale (double a4);
+Note * get_scale (void);
+Note * get_nearest_note (gfloat frequency);
+
+#endif /* __TEMPERAMENT_H__ */
#include "gstpitch.h"
#include "settings.h"
+#include "temperament.h"
#define between(x,a,b) (((x)>=(a)) && ((x)<=(b)))
-#define MAGIC (1.059463094359f) /* 2^(1/2) */
-#define CENT (1.0005777895f) /* 1/100th of a half-tone */
-#define LOG_CENT (0.00057762265046662109f) /* ln (CENT) */
-
extern gboolean plugin_pitch_init (GstPlugin * plugin);
extern gboolean plugin_tonesrc_init (GstPlugin * plugin);
-typedef struct
-{
- const gchar *name;
- gfloat frequency;
-} Note;
-
struct app_data
{
GtkWidget *targetFrequency;
typedef struct app_data AppData;
-enum
-{
- NUM_NOTES = 96
-};
-
-
-
#define NUM_LEDS (50)
#define NUM_WKEYS (15) /* # of white keys in the piano keyboard */
#define WKEY_WIDTH (45)
-static Note equal_tempered_scale[] = {
- {"C0", 16.35},
- {"C#0/Db0", 17.32},
- {"D0", 18.35},
- {"D#0/Eb0", 19.45},
- {"E0", 20.60},
- {"F0", 21.83},
- {"F#0/Gb0", 23.12},
- {"G0", 24.50},
- {"G#0/Ab0", 25.96},
- {"A0", 27.50},
- {"A#0/Bb0", 29.14},
- {"B0", 30.87},
- {"C1", 32.70},
- {"C#1/Db1", 34.65},
- {"D1", 36.71},
- {"D#1/Eb1", 38.89},
- {"E1", 41.20},
- {"F1", 43.65},
- {"F#1/Gb1", 46.25},
- {"G1", 49.00},
- {"G#1/Ab1", 51.91},
- {"A1", 55.00},
- {"A#1/Bb1", 58.27},
- {"B1", 61.74},
- {"C2", 65.41},
- {"C#2/Db2", 69.30},
- {"D2", 73.42},
- {"D#2/Eb2", 77.78},
- {"E2", 82.41},
- {"F2", 87.31},
- {"F#2/Gb2", 92.50},
- {"G2", 98.00},
- {"G#2/Ab2", 103.83},
- {"A2", 110.00},
- {"A#2/Bb2", 116.54},
- {"B2", 123.47},
- {"C3", 130.81},
- {"C#3/Db3", 138.59},
- {"D3", 146.83},
- {"D#3/Eb3", 155.56},
- {"E3", 164.81},
- {"F3", 174.61},
- {"F#3/Gb3", 185.00},
- {"G3", 196.00},
- {"G#3/Ab3", 207.65},
- {"A3", 220.00},
- {"A#3/Bb3", 233.08},
- {"B3", 246.94},
- {"C4", 261.63},
- {"C#4/Db4", 277.18},
- {"D4", 293.66},
- {"D#4/Eb4", 311.13},
- {"E4", 329.63},
- {"F4", 349.23},
- {"F#4/Gb4", 369.99},
- {"G4", 392.00},
- {"G#4/Ab4", 415.30},
- {"A4", 440.00},
- {"A#4/Bb4", 466.16},
- {"B4", 493.88},
- {"C5", 523.25},
- {"C#5/Db5", 554.37},
- {"D5", 587.33},
- {"D#5/Eb5", 622.25},
- {"E5", 659.26},
- {"F5", 698.46},
- {"F#5/Gb5", 739.99},
- {"G5", 783.99},
- {"G#5/Ab5", 830.61},
- {"A5", 880.00},
- {"A#5/Bb5", 932.33},
- {"B5", 987.77},
- {"C6", 1046.50},
- {"C#6/Db6", 1108.73},
- {"D6", 1174.66},
- {"D#6/Eb6", 1244.51},
- {"E6", 1318.51},
- {"F6", 1396.91},
- {"F#6/Gb6", 1479.98},
- {"G6", 1567.98},
- {"G#6/Ab6", 1661.22},
- {"A6", 1760.00},
- {"A#6/Bb6", 1864.66},
- {"B6", 1975.53},
- {"C7", 2093.00},
- {"C#7/Db7", 2217.46},
- {"D7", 2349.32},
- {"D#7/Eb7", 2489.02},
- {"E7", 2637.02},
- {"F7", 2793.83},
- {"F#7/Gb7", 2959.96},
- {"G7", 3135.96},
- {"G#7/Ab7", 3322.44},
- {"A7", 3520.00},
- {"A#7/Bb7", 3729.31},
- {"B7", 3951.07},
-};
-
static GdkColor ledOnColor = { 0, 0 * 255, 180 * 255, 95 * 255 };
static GdkColor ledOnColor2 = { 0, 180 * 255, 180 * 255, 0 * 255 };
static GdkColor ledOffColor = { 0, 80 * 255, 80 * 255, 80 * 255 };
static GdkColor whiteColor = { 0, 65535, 65535, 65535 };
static GdkColor blackColor = { 0, 0, 0, 0 };
-static void
-recalculate_scale (double a4)
-{
- int i;
-
- for (i = 0; i < NUM_NOTES; i++) {
- equal_tempered_scale[i].frequency = a4 * pow (MAGIC, i - 57);
- /* fprintf(stdout, "%s: %.2f\n", equal_tempered_scale[i].name, equal_tempered_scale[i].frequency); */
- }
-}
static void
calibration_changed (GObject * object, GParamSpec * pspec, gpointer user_data)
}
}
-/* translate the interval (ratio of two freqs) into cents */
-gfloat
-interval2cent (gfloat freq, gfloat note)
-{
- //return (gfloat) (log (freq / note) / log (CENT));
- return (gfloat) (log (freq / note) / LOG_CENT);
-}
-
/* update frequency info */
static void
update_frequency (AppData * appdata, gfloat frequency)
{
gchar *buffer;
- gint i, j;
- gfloat diff, min_diff;
-
- min_diff = frequency - (equal_tempered_scale[0].frequency - 10);
- for (i = j = 0; i < NUM_NOTES; i++) {
- diff = frequency - equal_tempered_scale[i].frequency;
- if (fabs (diff) <= fabs (min_diff)) {
- min_diff = diff;
- j = i;
- } else {
- break;
- }
- }
+ Note *nearest;
+ gfloat diff;
+ nearest = get_nearest_note (frequency);
buffer =
g_strdup_printf ("Nearest note is %s with %.2f Hz frequency",
- equal_tempered_scale[j].name, equal_tempered_scale[j].frequency);
+ nearest->name, nearest->frequency);
gtk_label_set_text (GTK_LABEL (appdata->targetFrequency), buffer);
g_free (buffer);
g_free (buffer);
/* make leds display the difference in steps of two cents */
- diff = interval2cent (frequency, equal_tempered_scale[j].frequency);
+ diff = interval2cent (frequency, nearest->frequency);
draw_leds (appdata, (gint) roundf (diff / 2.0));
}
found = j;
}
if (found) {
- frequency = equal_tempered_scale[48 + found - 1].frequency;
+ frequency = get_scale()[48 + found - 1].frequency;
break;
}
}