Wednesday, December 24, 2014

Tone music: changing the Tempo of your melodies





Abstract
In our past programs for playing tone music on Arduino (see the basic program here and its advanced version here) are based on a fixed Tempo which is about 90 crotchets per minute. In this article we give a simple routine which allows to change the Tempo. We also provide some basic conversion constants for the main Tempos.

Hey all! While transcribing some music sheet (game music) I've seen that the tempo was somewhat strange and it wasn't due only to the deformation of my poor loudspeaker. Indeed, our past sketches for playing tone music on Arduino (see the basic program here and its advanced version here) are based on a fixed Tempo which is approx 90 crotchets per minute. This is the same for all other sketches that I could find on the web.
Therefore, here is a simple sketch function which changes the Tempo in your melody.

The sketch
The code below contain just one function. Call it with your own tempo value or choose one constant among those provided in the next section. The formula to compute the transformation takes into account the pause that we put between a note and the following which was useful to distinguish the notes (this was set to 130% of the note duration in our previous programs). Whenever the duration is not standard (in the case of an augmentation for example), a simple approximation formula is used.

Warning: some older version of melodies that you can find over the net use const int noteDurations[] as data type. Of course, you should change this into uint16_t noteDurations[] to be able to use the setTempo() routine.


#include "durations.h"

#define INTERNOTE_PAUSE 1.3

void setTempo(uint16_t durs[], uint16_t tempo, uint16_t istart, uint16_t iend) {
  register uint16_t i;
  uint16_t base;
  
  base = (uint16_t)(1000.0/((tempo/60.0)*(1+INTERNOTE_PAUSE)));
  
  for(i=istart; i<iend; i++) {
    switch(durs[i]) {
      case DUR_SEMIBREVE: 
        durs[i] = base << 2;
        break;
      case DUR_MINIM: 
        durs[i] = base << 1;
        break;
      case DUR_CROTCHET: 
        durs[i] = base;
        break;
      case DUR_QUAVER:
        durs[i] = base >> 1;
        break;
      case DUR_SEMIQUAVER:
        durs[i] = base >> 2;
        break;
      case DUR_DEMISEMIQUAVER:
        durs[i] = base >> 3;
        break;
      case DUR_HEMIDEMISEMIQUAVER:
        durs[i] = base >> 4;
        break;
      default:
        durs[i] = (uint16_t)(durs[i]/(DUR_CROTCHET*1.0)*base);
        break;      
    }
  }
}

The tempos
In most of the music sheets, the tempo is indicated a phrase or a word (usually in Italian) and the interpretation of such words/phrases is often a matter of taste or of long discussions. Along with the previous sketch, below you can find Tempos.h: my personal interpretation of most known tempos.


/*
 *  Tempos.h
 *
 *  This is part of PlayMelodyAdv projet
 *  A more advanced program for playing melodies on Arduino.
 *
 *
 *  Written by Enrico Formenti, 22 dec 2014
 *
 *  BSD license, check the License page on the blog for more information
 *  All this text must be included in any redistribution.
 *
 *  See macduino.blogspot.com for more details.
 */

#ifndef _Tempos_h
#define _Tempos_h

#define TEMPO_LARGHISSIMO 24
#define TEMPO_GRAVE 32
#define TEMPO_LENTISSIMO 40
#define TEMPO_LENTO 46
#define TEMPO_LARGO 50
#define TEMPO_ADAGISSIMO 52
#define TEMPO_LARGHETTO 56
#define TEMPO_LENTO 60
#define TEMPO_ADAGIO 70
#define TEMPO_ADAGIETTO 76
#define TEMPO_ANDANTE 88
#define TEMPO_MODERATO 100
#define TEMPO_ALLEGRETTO 116
#define TEMPO_ALLEGRO 130
#define TEMPO_VIVACE 140
#define TEMPO_VIVACISSIMO 152
#define TEMPO_ALLEGRISSIMO 160
#define TEMPO_ALLEGRO_VIVACE 160
#define TEMPO_PRESTO 170
#define TEMPO_PRESTISSIMO 188

#endif

See also
Tone music surprises!
Tone music: advanced playing software
Tone music: how to encode songs

Enjoy! Credits
The image opening this post comes from Wikipedia.com

No comments :

Post a Comment