diff --git a/gtk2_ardour/editor_tempodisplay.cc b/gtk2_ardour/editor_tempodisplay.cc
index 831fe3b..f18392c 100644
--- a/gtk2_ardour/editor_tempodisplay.cc
+++ b/gtk2_ardour/editor_tempodisplay.cc
@@ -235,13 +235,14 @@ Editor::mouse_add_new_tempo_event (nframes_t frame)
 	BBT_Time requested;
 	
 	bpm = tempo_dialog.get_bpm ();
+	double nt = tempo_dialog.get_note_type();
 	bpm = max (0.01, bpm);
 	
 	tempo_dialog.get_bbt_time (requested);
 	
 	begin_reversible_command (_("add tempo mark"));
         XMLNode &before = map.get_state();
-	map.add_tempo (Tempo (bpm), requested);
+	map.add_tempo (Tempo (bpm,nt), requested);
         XMLNode &after = map.get_state();
 	session->add_command(new MementoCommand<TempoMap>(map, &before, &after));
 	commit_reversible_command ();
@@ -356,13 +357,14 @@ Editor::edit_tempo_section (TempoSection* section)
 	}
 
 	double bpm = tempo_dialog.get_bpm ();
+	double nt = tempo_dialog.get_note_type ();
 	BBT_Time when;
 	tempo_dialog.get_bbt_time(when);
 	bpm = max (0.01, bpm);
 	
 	begin_reversible_command (_("replace tempo mark"));
         XMLNode &before = session->tempo_map().get_state();
-	session->tempo_map().replace_tempo (*section, Tempo (bpm));
+	session->tempo_map().replace_tempo (*section, Tempo (bpm,nt));
 	session->tempo_map().move_tempo (*section, when);
         XMLNode &after = session->tempo_map().get_state();
 	session->add_command (new MementoCommand<TempoMap>(session->tempo_map(), &before, &after));
diff --git a/gtk2_ardour/tempo_dialog.cc b/gtk2_ardour/tempo_dialog.cc
index d69acf7..8eab45a 100644
--- a/gtk2_ardour/tempo_dialog.cc
+++ b/gtk2_ardour/tempo_dialog.cc
@@ -37,6 +37,7 @@ TempoDialog::TempoDialog (TempoMap& map, nframes_t frame, const string & action)
 	  bpm_adjustment (60.0, 1.0, 999.9, 0.1, 1.0, 1.0),
 	  bpm_spinner (bpm_adjustment),
 	  bpm_frame (_("Beats per minute")),
+	  note_frame (_("BPM denominator")),
 	  ok_button (action),
 	  cancel_button (_("Cancel")),
 	  when_bar_label (_("Bar")),
@@ -48,7 +49,7 @@ TempoDialog::TempoDialog (TempoMap& map, nframes_t frame, const string & action)
 	Tempo tempo (map.tempo_at (frame));
 	map.bbt_time (frame, when);
 
-	init (when, tempo.beats_per_minute(), true);
+	init (when, tempo.beats_per_minute(), tempo.note_type(), true);
 }
 
 TempoDialog::TempoDialog (TempoSection& section, const string & action)
@@ -63,23 +64,56 @@ TempoDialog::TempoDialog (TempoSection& section, const string & action)
 	  when_table (2, 2),
 	  when_frame (_("Location"))
 {
-	init (section.start(), section.beats_per_minute(), section.movable());
+	init (section.start(), section.beats_per_minute(), section.note_type(), section.movable());
 }
 
 void
-TempoDialog::init (const BBT_Time& when, double bpm, bool movable)
+TempoDialog::init (const BBT_Time& when, double bpm, double note_type, bool movable)
 {
 	bpm_spinner.set_numeric (true);
 	bpm_spinner.set_digits (1);
 	bpm_spinner.set_wrap (true);
 	bpm_spinner.set_value (bpm);
 
+ 	strings.push_back (_("whole (1)"));
+ 	strings.push_back (_("second (2)"));
+ 	strings.push_back (_("third (3)"));
+	strings.push_back (_("quarter (4)"));
+ 	strings.push_back (_("eighth (8)"));
+ 	strings.push_back (_("sixteenth (16)"));
+ 	strings.push_back (_("thirty-second (32)"));
+ 	
+ 	set_popdown_strings (note_types, strings);
+ 
+ 	if (note_type==1.0f)
+ 		note_types.set_active_text (_("whole (1)"));
+ 	else if (note_type==2.0f)
+ 		note_types.set_active_text (_("second (2)"));
+ 	else if (note_type==3.0f)
+ 		note_types.set_active_text (_("third (3)"));
+ 	else if (note_type==4.0f)
+ 		note_types.set_active_text (_("quarter (4)"));
+ 	else if (note_type==8.0f)
+ 		note_types.set_active_text (_("eighth (8)"));
+ 	else if (note_type==16.0f)
+ 		note_types.set_active_text (_("sixteenth (16)"));
+	else if (note_type==32.0f)
+		note_types.set_active_text (_("thirty-second (32)"));
+ 	else
+		note_types.set_active_text (_("quarter (4)"));
+
 	hspacer1.set_border_width (5);
 	hspacer1.pack_start (bpm_spinner, false, false);
 	vspacer1.set_border_width (5);
 	vspacer1.pack_start (hspacer1, false, false);
 
+ 	hspacer2.set_border_width (5);
+ 	hspacer2.pack_start (note_types, false, false);
+ 	vspacer2.set_border_width (5);
+ 	vspacer2.pack_start (hspacer2, false, false);
+	
 	bpm_frame.add (vspacer1);
+ 	note_frame.add (vspacer2);
 
 	if (movable) {
 		snprintf (buf, sizeof (buf), "%" PRIu32, when.bars);
@@ -115,9 +149,11 @@ TempoDialog::init (const BBT_Time& when, double bpm, bool movable)
 
 	bpm_frame.set_name ("MetricDialogFrame");
 	bpm_spinner.set_name ("MetricEntry");
+	note_frame.set_name ("MetricDialogFrame");
 
 	get_vbox()->pack_start (bpm_frame, false, false);
-	
+	get_vbox()->pack_start (note_frame, false, false);
+
 	add_button (Stock::CANCEL, RESPONSE_CANCEL);
 	add_button (Stock::APPLY, RESPONSE_ACCEPT);
 	set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
@@ -131,6 +167,7 @@ TempoDialog::init (const BBT_Time& when, double bpm, bool movable)
 	bpm_spinner.signal_activate().connect (bind (mem_fun (*this, &TempoDialog::response), RESPONSE_ACCEPT));
 	bpm_spinner.signal_button_press_event().connect (mem_fun (*this, &TempoDialog::bpm_button_press), false);
 	bpm_spinner.signal_button_release_event().connect (mem_fun (*this, &TempoDialog::bpm_button_release), false);
+	note_types.signal_changed().connect (mem_fun (*this, &TempoDialog::note_types_change));
 }
 
 bool
@@ -168,6 +205,40 @@ TempoDialog::get_bbt_time (BBT_Time& requested)
 	return true;
 }
 
+double
+TempoDialog::get_note_type ()
+{
+	double note_type = 0;
+	vector<string>::iterator i;
+	string text = note_types.get_active_text();
+	
+	for (i = strings.begin(); i != strings.end(); ++i) {
+		if (text == *i) {
+			if (sscanf (text.c_str(), "%*[^0-9]%lf", &note_type) != 1) {
+				error << string_compose(_("garbaged note type entry (%1)"), text) << endmsg;
+				return 0;
+			} else {
+				break;
+			}
+		}
+	} 
+	
+	if (i == strings.end()) {
+		if (sscanf (text.c_str(), "%lf", &note_type) != 1) {
+			error << string_compose(_("incomprehensible note type entry (%1)"), text) << endmsg;
+			return 0;
+		}
+	}
+
+	return note_type;
+}
+
+void
+TempoDialog::note_types_change ()
+{
+        set_response_sensitive (Gtk::RESPONSE_ACCEPT, true);
+}
+
 
 MeterDialog::MeterDialog (TempoMap& map, nframes_t frame, const string & action)
 	: ArdourDialog ("meter dialog"),
diff --git a/gtk2_ardour/tempo_dialog.h b/gtk2_ardour/tempo_dialog.h
index b9f6a16..a92f26f 100644
--- a/gtk2_ardour/tempo_dialog.h
+++ b/gtk2_ardour/tempo_dialog.h
@@ -37,6 +37,9 @@
 
 struct TempoDialog : public ArdourDialog 
 {
+    Gtk::ComboBoxText note_types;
+    vector<string> strings;
+    Gtk::Frame   note_frame;
     Gtk::Adjustment   bpm_adjustment;
     Gtk::SpinButton   bpm_spinner;
     Gtk::Frame        bpm_frame;
@@ -44,8 +47,8 @@ struct TempoDialog : public ArdourDialog
     Gtk::Button  ok_button;
     Gtk::Button  cancel_button;
     Gtk::HBox    button_box;
-    Gtk::HBox    hspacer1;
-    Gtk::VBox    vspacer1;
+    Gtk::HBox    hspacer1, hspacer2;
+    Gtk::VBox    vspacer1, vspacer2;
     Gtk::Entry   when_bar_entry;
     Gtk::Entry   when_beat_entry;
     Gtk::Label   when_bar_label;
@@ -58,13 +61,15 @@ struct TempoDialog : public ArdourDialog
     TempoDialog (ARDOUR::TempoSection&, const string & action);
 
     double get_bpm ();
+    double get_note_type ();
     bool   get_bbt_time (ARDOUR::BBT_Time&);
     
   private:
-    void init (const ARDOUR::BBT_Time& start, double, bool);
+    void init (const ARDOUR::BBT_Time& start, double, double, bool);
     void bpm_changed ();
     bool bpm_button_press (GdkEventButton* );
     bool bpm_button_release (GdkEventButton* );
+    void note_types_change ();
 };
 
 struct MeterDialog : public ArdourDialog 
diff --git a/libs/ardour/ardour/tempo.h b/libs/ardour/ardour/tempo.h
index 2d8462a..79df425 100644
--- a/libs/ardour/ardour/tempo.h
+++ b/libs/ardour/ardour/tempo.h
@@ -40,27 +40,29 @@ using std::list;
 using std::vector;
 
 namespace ARDOUR {
-
+class Meter;
 class Tempo {
   public:
-	Tempo (double bpm)
-		: _beats_per_minute (bpm) {}
+	Tempo (double bpm, double type=4.0) // defaulting to quarter note
+		: _beats_per_minute (bpm), _note_type(type) {} 
 	Tempo (const Tempo& other) {
 		_beats_per_minute = other._beats_per_minute;
+		_note_type = other._note_type;
 	}
 	void operator= (const Tempo& other) {
 		if (&other != this) {
 			_beats_per_minute = other._beats_per_minute;
+			_note_type = other._note_type;
 		}
 	}
 
-	double beats_per_minute () const { return _beats_per_minute; }
-	double frames_per_beat (nframes_t sr) const {
-		return  ((60.0 * sr) / _beats_per_minute);
-	}
+	double beats_per_minute () const { return _beats_per_minute;}
+	double note_type () const { return _note_type;}
+	double frames_per_beat (nframes_t sr, const Meter& meter) const;
 
   protected:
 	double _beats_per_minute;
+	double _note_type;
 };
 
 class Meter {
diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc
index b8d82bd..b332d74 100644
--- a/libs/ardour/smf_source.cc
+++ b/libs/ardour/smf_source.cc
@@ -345,7 +345,7 @@ SMFSource::read_unlocked (MidiRingBuffer& dst, nframes_t start, nframes_t cnt, n
 	
 	// FIXME: assumes tempo never changes after start
 	const double frames_per_beat = _session.tempo_map().tempo_at(_timeline_position).frames_per_beat(
-			_session.engine().frame_rate());
+			_session.engine().frame_rate(), _session.tempo_map().meter_at(_timeline_position));
 	
 	const uint64_t start_ticks = (uint64_t)((start / frames_per_beat) * _ppqn);
 
@@ -457,7 +457,7 @@ SMFSource::append_event_unlocked(const MidiEvent& ev)
 	
 	// FIXME: assumes tempo never changes after start
 	const double frames_per_beat = _session.tempo_map().tempo_at
-			(_timeline_position).frames_per_beat(_session.engine().frame_rate());
+			(_timeline_position).frames_per_beat(_session.engine().frame_rate(),_session.tempo_map().meter_at(_timeline_position));
 	
 	const uint32_t delta_time = (uint32_t)((ev.time() - _last_ev_time) / frames_per_beat * _ppqn);
 
@@ -888,7 +888,7 @@ SMFSource::load_model(bool lock, bool force_reload)
 	
 	// FIXME: assumes tempo never changes after start
 	const double frames_per_beat = _session.tempo_map().tempo_at(_timeline_position).frames_per_beat(
-			_session.engine().frame_rate());
+			_session.engine().frame_rate(),_session.tempo_map().meter_at(_timeline_position));
 	
 	uint32_t delta_t = 0;
 	int ret;
diff --git a/libs/ardour/tempo.cc b/libs/ardour/tempo.cc
index cd59e93..dc3301d 100644
--- a/libs/ardour/tempo.cc
+++ b/libs/ardour/tempo.cc
@@ -43,12 +43,17 @@ Tempo    TempoMap::_default_tempo (120.0);
 
 const double Meter::ticks_per_beat = 1920.0;
 
+double Tempo::frames_per_beat (nframes_t sr, const Meter& meter) const
+{
+	return  ((60.0 * sr) / (_beats_per_minute * meter.note_divisor()/_note_type));
+}
+
 /***********************************************************************/
 
 double
 Meter::frames_per_bar (const Tempo& tempo, nframes_t sr) const
 {
-	return ((60.0 * sr * _beats_per_bar) / tempo.beats_per_minute());
+	return ((60.0 * sr * _beats_per_bar) / (tempo.beats_per_minute() * _note_type/tempo.note_type()));
 }
 
 /***********************************************************************/
@@ -86,6 +91,16 @@ TempoSection::TempoSection (const XMLNode& node)
 		error << _("TempoSection XML node has an illegal \"beats_per_minute\" value") << endmsg;
 		throw failed_constructor();
 	}
+	
+	if ((prop = node.property ("note-type")) == 0) {
+		error << _("TempoSection XML node has no \"note-type\" property") << endmsg;
+		throw failed_constructor();
+	}
+	
+	if (sscanf (prop->value().c_str(), "%lf", &_note_type) != 1 || _note_type < 1.0) {
+		error << _("TempoSection XML node has an illegal \"note-type\" value") << endmsg;
+		throw failed_constructor();
+	}
 
 	if ((prop = node.property ("movable")) == 0) {
 		error << _("TempoSection XML node has no \"movable\" property") << endmsg;
@@ -109,6 +124,8 @@ TempoSection::get_state() const
 	root->add_property ("start", buf);
 	snprintf (buf, sizeof (buf), "%f", _beats_per_minute);
 	root->add_property ("beats-per-minute", buf);
+	snprintf (buf, sizeof (buf), "%f", _note_type);
+	root->add_property ("note-type", buf);
 	snprintf (buf, sizeof (buf), "%s", movable()?"yes":"no");
 	root->add_property ("movable", buf);
 
@@ -614,7 +631,7 @@ TempoMap::bbt_time_with_metric (nframes_t frame, BBT_Time& bbt, const Metric& me
 
 	const double beats_per_bar = metric.meter().beats_per_bar();
 	const double frames_per_bar = metric.meter().frames_per_bar (metric.tempo(), _frame_rate);
-	const double beat_frames = metric.tempo().frames_per_beat (_frame_rate);
+	const double beat_frames = metric.tempo().frames_per_beat (_frame_rate, metric.meter());
 
 	/* now compute how far beyond that point we actually are. */
 
@@ -667,7 +684,7 @@ TempoMap::count_frames_between ( const BBT_Time& start, const BBT_Time& end) con
 		+ start.ticks/Meter::ticks_per_beat;
 
 
-	start_frame = m.frame() + (nframes_t) rint( beat_offset * m.tempo().frames_per_beat(_frame_rate));
+	start_frame = m.frame() + (nframes_t) rint( beat_offset * m.tempo().frames_per_beat(_frame_rate, m.meter()));
 
     	m =  metric_at(end);
 
@@ -676,7 +693,7 @@ TempoMap::count_frames_between ( const BBT_Time& start, const BBT_Time& end) con
 	beat_offset = bar_offset * m.meter().beats_per_bar() - (m.start().beats -1) + (end.beats - 1) 
 		+ end.ticks/Meter::ticks_per_beat;
 
-	end_frame = m.frame() + (nframes_t) rint(beat_offset * m.tempo().frames_per_beat(_frame_rate));
+	end_frame = m.frame() + (nframes_t) rint(beat_offset * m.tempo().frames_per_beat(_frame_rate, m.meter()));
 
 	frames = end_frame - start_frame;
 
@@ -697,7 +714,7 @@ TempoMap::count_frames_between_metrics (const Meter& meter, const Tempo& tempo,
 	double beat_frames = 0;
 
 	beats_per_bar = meter.beats_per_bar();
-	beat_frames = tempo.frames_per_beat (_frame_rate);
+	beat_frames = tempo.frames_per_beat (_frame_rate,meter);
 
 	frames = 0;
 
@@ -1088,7 +1105,7 @@ TempoMap::get_points (nframes_t lower, nframes_t upper) const
 
 	beats_per_bar = meter->beats_per_bar ();
 	frames_per_bar = meter->frames_per_bar (*tempo, _frame_rate);
-	beat_frames = tempo->frames_per_beat (_frame_rate);
+	beat_frames = tempo->frames_per_beat (_frame_rate, *meter);
 	
 	if (meter->frame() > tempo->frame()) {
 		bar = meter->start().bars;
@@ -1198,7 +1215,7 @@ TempoMap::get_points (nframes_t lower, nframes_t upper) const
 
 			beats_per_bar = meter->beats_per_bar ();
 			frames_per_bar = meter->frames_per_bar (*tempo, _frame_rate);
-			beat_frames = tempo->frames_per_beat (_frame_rate);
+			beat_frames = tempo->frames_per_beat (_frame_rate, *meter);
 			
 			++i;
 		}
