function partials = ...
  stretch_pitch_partials(note, n_partials, m_stretch, h_stretch, ...
                         freq_v_pitch);

  partials = (1:1:n_partials)'^(1+log(h_stretch)/log(2));

  fundamental = (2*m_stretch)^(note/12);

  partials = fundamental*partials;

  if freq_v_pitch == 1 then partials = log(partials)*12/log(2); end //if

//end stretch_pitch_partials

function hs = half_steps(first_hs, n_hs, freq_v_pitch);

  half_step_ratio = 2^(1/12);

  hs = first_hs:1:first_hs+n_hs-1;

  if freq_v_pitch == 0 then hs = half_step_ratio^hs; end //if

//end half_steps

function octs = octaves(first_oct, n_octs, freq_v_pitch);

  octs = 12*(first_oct:1:first_oct+n_octs-1);

  if freq_v_pitch == 0 then octs = 2^(octs/12); end //if

//end octaves

function draw_p_spikes(y_tails, y_heads, x_values, scale);

  arrow_width  = 0.02*scale(1)*scale(2);
  arrow_height = 0.1*scale(2);

  x_arrowheads = [x_values-arrow_width/2; x_values; x_values+arrow_width/2];

  direction = sign(y_heads - y_tails);

  y_arrowheads = [ones(x_values)*y_heads-direction*arrow_height; ...
                  ones(x_values)*y_heads; ...
                  ones(x_values)*y_heads-direction*arrow_height];

  xarrows([x_values; x_values], ...
          [ones(x_values)*y_tails; ones(x_values)*y_heads], ...
          0, 1);
  xfpolys(x_arrowheads, y_arrowheads, ones(x_values));

//end draw_p_spikes

function draw_ticks(y_tails, y_heads, x_values);

  xarrows([x_values; x_values], ...
          [ones(x_values)*y_tails; ones(x_values)*y_heads], ...
          0, 1);

//end draw_ticks

function stretch_demo(interval, n_partials, m_stretch, h_stretch, ...
                      freq_v_pitch, message);

  expand_frame = 1.2;

  half_step_ratio = 2^(1/12);

  p_1 = stretch_pitch_partials(0, n_partials, m_stretch, h_stretch, ...
                               freq_v_pitch)';
  p_2 = stretch_pitch_partials(interval, n_partials, m_stretch, h_stretch, ...
                               freq_v_pitch)';

  highest_partial = p_2(size(p_2,2));

  if freq_v_pitch == 0 then
    n_half_steps = ...
      ceil(log(highest_partial*expand_frame)/log(half_step_ratio));
  else
    n_half_steps = ceil(highest_partial*expand_frame);
  end //if

  n_octaves = floor(n_half_steps/12)+1;

  xset("window",0); xselect(); xbasc();
  plot2d([0 highest_partial*expand_frame]', [0 0]', 1, "010", " ", ...
         [0 -1 highest_partial 1]*expand_frame);
  xtitle(['Interaction of stretched melodic scale'; ...
          'with stretched harmonic partials'; ...
          message]);

  draw_ticks(-0.04, 0.04, half_steps(0, n_half_steps, freq_v_pitch));
  draw_ticks(-0.06, 0.06, octaves(0, n_octaves, freq_v_pitch));

  draw_p_spikes(-1, -0.09, p_1, [highest_partial, 1]);
  draw_p_spikes( 1,  0.09, p_2, [highest_partial, 1]);

//end stretch_demo

function stretch_2_demo(n_partials, h_stretch_1, h_stretch_2, ...
                      freq_v_pitch, message);

  expand_frame = 1.2;

  half_step_ratio = 2^(1/12);

  p_1 = stretch_pitch_partials(0, n_partials, 1., h_stretch_1, ...
                               freq_v_pitch)';
  p_2 = stretch_pitch_partials(0, n_partials, 1., h_stretch_2, ...
                               freq_v_pitch)';

  highest_partial = p_2(size(p_2,2));

  if freq_v_pitch == 0 then
    n_half_steps = ...
      ceil(log(highest_partial*expand_frame)/log(half_step_ratio));
  else
    n_half_steps = ceil(highest_partial*expand_frame);
  end //if

  n_octaves = floor(n_half_steps/12)+1;

  xset("window",0); xselect(); xbasc();
  plot2d([0 highest_partial*expand_frame]', [0 0]', 1, "010", " ", ...
         [0 -1 highest_partial 1]*expand_frame);
  xtitle(['Interaction of different stretched partials'; ...
          message]);

  draw_ticks(-0.04, 0.04, half_steps(0, n_half_steps, freq_v_pitch));
  draw_ticks(-0.06, 0.06, octaves(0, n_octaves, freq_v_pitch));

  draw_p_spikes(-1, -0.09, p_1, [highest_partial, 1]);
  draw_p_spikes( 1,  0.09, p_2, [highest_partial, 1]);

//end stretch_2_demo
