diff options
author | Walter Bender <walter.bender@gmail.com> | 2012-06-22 23:59:21 (GMT) |
---|---|---|
committer | Walter Bender <walter.bender@gmail.com> | 2012-06-22 23:59:21 (GMT) |
commit | 3472bc452dcc1b32690f85a78c99caf42293c703 (patch) | |
tree | 6c4abe6fae4e6b0aa2c3023ba495007a9da3560d | |
parent | 532c46644702ba3a78850da8caaf7ec00ae3dfa9 (diff) |
add color to instrument tuning lines
-rw-r--r-- | drawwaveform.py | 38 | ||||
-rw-r--r-- | tuning_toolbar.py | 61 |
2 files changed, 61 insertions, 38 deletions
diff --git a/drawwaveform.py b/drawwaveform.py index 28ff6bf..2f5941b 100644 --- a/drawwaveform.py +++ b/drawwaveform.py @@ -22,6 +22,7 @@ from ringbuffer import RingBuffer1d from config import MAX_GRAPHS, RATE, LOWER, UPPER from config import INSTRUMENT_DICT +from tuning_toolbar import A0, C8, freq_note # Initialize logging. import logging @@ -40,6 +41,9 @@ class DrawWaveform(gtk.DrawingArea): TRIGGER_NONE = 0 TRIGGER_POS = 1 TRIGGER_NEG = 2 + COLORS = ['#B20008', '#FFC169', '#F8E800', '#00588C', '#7F00BF', '#8BFF7A', + '#00A0FF', '#BCCEFF', '#008009', '#F8E800', '#AC32FF', '#FFFFFF'] + def __init__(self, activity, input_frequency=RATE, channels=1): """ Initialize drawing area and scope parameter """ @@ -269,6 +273,16 @@ class DrawWaveform(gtk.DrawingArea): gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_BEVEL) self._trigger_line_gc.set_foreground(clr) + # Instrument tuning lines + self._instrument_gc = [] + for c in self.COLORS: + clr = colormap.alloc_color(c) + self._instrument_gc.append(self.window.new_gc(foreground=clr)) + self._instrument_gc[-1].set_line_attributes( + self._TUNING_LINE_THICKNESS, gtk.gdk.LINE_SOLID, + gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_BEVEL) + self._instrument_gc[-1].set_foreground(clr) + # Tuning lines clr = colormap.alloc_color(self.color[1]) self._tuning_line_gc = self.window.new_gc(foreground=clr) @@ -381,16 +395,16 @@ class DrawWaveform(gtk.DrawingArea): # If we are tuning, we want to scale by 10 scale = 10. * self.freq_div / 500. if self.fft_show and self.instrument in INSTRUMENT_DICT: - for note in INSTRUMENT_DICT[self.instrument]: + for n, note in enumerate(INSTRUMENT_DICT[self.instrument]): x = int(note / scale) self.window.draw_line( - self._tuning_line_gc, x, 0, x, height) - for note in INSTRUMENT_DICT[self.instrument]: + self._instrument_gc[n], x, 0, x, height) + for n, note in enumerate(INSTRUMENT_DICT[self.instrument]): if self.harmonics: x = int(note / scale) for i in range(3): j = i + 2 - self.window.draw_line(self._harmonic_gc, x * j, + self.window.draw_line(self._instrument_gc[n], x * j, 20 * j, x * j, height) if self.fft_show and self.tuning_line > 0.0: x = int(self.tuning_line / scale) @@ -434,8 +448,6 @@ class DrawWaveform(gtk.DrawingArea): self.fftx = fft.rfft(buf) self.fftx = abs(self.fftx) data = multiply(self.fftx, 0.02, self.fftx) - if data.argmax() > 0: - print data.argmax() * 48000. / len(data) except ValueError: # TODO: Figure out how this can happen. # Shape mismatch between window and buf @@ -467,7 +479,19 @@ class DrawWaveform(gtk.DrawingArea): # Use ints or draw_lines will throw warnings lines = zip(lines.astype('int'), data.astype('int')) - if not self.fft_show: + if self.fft_show: + n = data.argmin() + if self.tuning_line > 0 and n > 0: + # Interpolate + a, b, c = \ + lines[n - 1][0], lines[n][0], lines[n + 1][0] + x = b - (0.5 * a / (a + b + c)) + ( + 0.5 * c / (a + b + c)) + x *= scale + if x > A0 and x < C8: + self.activity.tuning_toolbar.label.set_markup( + freq_note(x, flatsharp=True)) + else: if self.triggering != self.TRIGGER_NONE: x = int(self.trigger_xpos * self.allocation.width) y = int(self.trigger_ypos * self.allocation.height) diff --git a/tuning_toolbar.py b/tuning_toolbar.py index e61e630..b853414 100644 --- a/tuning_toolbar.py +++ b/tuning_toolbar.py @@ -204,31 +204,7 @@ class TuningToolbar(gtk.Toolbar): if freq > C8 * 1.03: self.label.set_text('> C8') return - for i in range(88): - f = A0 * pow(TWELTHROOT2, i) - if freq < f * 1.03 and freq > f * 0.97: - label = NOTES[index_to_note(i)] - # calculate if we are sharp or flat - if freq < f * 0.98: - label = '%s %s %s' % (FLAT, label, FLAT) - self.label.set_markup(SPAN % ( - COLOR_RED.get_html(), label)) - elif freq < f * 0.99: - label = '%s %s %s' % (FLAT, label, FLAT) - self.label.set_markup(SPAN % ( - COLOR_YELLOW.get_html(), label)) - elif freq > f * 1.02: - label = '%s %s %s' % (SHARP, label, SHARP) - self.label.set_markup(SPAN % ( - COLOR_RED.get_html(), label)) - elif freq > f * 1.01: - label = '%s %s %s' % (SHARP, label, SHARP) - self.label.set_markup(SPAN % ( - COLOR_YELLOW.get_html(), label)) - else: - self.label.set_markup(SPAN % ( - style.COLOR_WHITE.get_html(), label)) - return + self.label.set_markup(freq_note(freq, flatsharp=True)) except ValueError: return self._updating_note = False @@ -307,12 +283,33 @@ def note_octave(note, octave): else: return '%s%d' % (NOTES[note], octave) -def freq_note(freq): - for i in range(88): - f = A0 * pow(TWELTHROOT2, i) - if freq < f * 1.03 and freq > f * 0.97: # Found a match - return note_octave(index_to_note(i), index_to_octave(i)) - return '?' +def freq_note(freq, flatsharp=False): + if flatsharp: # calculate if we are sharp or flat + for i in range(88): + f = A0 * pow(TWELTHROOT2, i) + if freq < f * 1.03 and freq > f * 0.97: + label = NOTES[index_to_note(i)] + if freq < f * 0.98: + label = '%s %s %s' % (FLAT, label, FLAT) + return SPAN % (COLOR_RED.get_html(), label) + elif freq < f * 0.99: + label = '%s %s %s' % (FLAT, label, FLAT) + return SPAN % (COLOR_YELLOW.get_html(), label) + elif freq > f * 1.02: + label = '%s %s %s' % (SHARP, label, SHARP) + return SPAN % (COLOR_RED.get_html(), label) + elif freq > f * 1.01: + label = '%s %s %s' % (SHARP, label, SHARP) + return SPAN % (COLOR_YELLOW.get_html(), label) + else: + return SPAN % (style.COLOR_WHITE.get_html(), label) + else: + for i in range(88): + f = A0 * pow(TWELTHROOT2, i) + if freq < f * 1.03 and freq > f * 0.97: # Found a match + return note_octave(index_to_note(i), index_to_octave(i)) + return '?' + def freq_index(freq): for i in range(88): @@ -321,8 +318,10 @@ def freq_index(freq): return i return 0 + def index_to_octave(i): return int((i - 3) / 12) + 1 # -3 because we start with A + def index_to_note(i): return (i-3) % 12 # -3 because we start with A |