Back to main page
Back to sound contents

Music

This section shows how to compose music with Maxima. Although sound object wave could be used for this task, object note has some additional features which make it more convenient in this context; for example, you can make use of the oscillator sound option in order to specify the basic form of the periodic signal.

Since we want to play the sound and draw the waveform everytime we call the play function, we set some sound options defaults to avoid rewriting them.

set_sound_defaults(
   player    = "mplayer",
   draw_wave = true,
   draw_wave_options = [terminal   = png,
                        pic_height = 200,
                        pic_width  = 800] )$

Talking on music, let's increase the number of samples per second.

sound_sample_rate : 20000 $

By default, sound option oscillator is equal to sine(1), which means that the periodic signal is the fundamental harmonic of the sine. The first argument to the note sound object is the frequency, the second is the amplitude or loudness, the third one indicates the moment the sound starts (in seconds), and the last argument is duration (in seconds). In this example, we play key A4 (Do4) during 0.1 secs, starting at t = 0.

play(note(440, 2000, 0.1))$
Download wav file

Now, two tones are played. The first one (A4 or Do4) is generated by an oscillator composed by the first and third harmonics of the sine wave; the second tone (A5 or Do5) is generated by a rectangular oscillator.

play(
   oscillator = sine(1, 3),
   note(440, 2000, 0.1), /* by default, starts at t=0 */

   oscillator = rectangle(0.5),
   note(880, 1000, 0.1, 0.1) )$ /* starts at t=0.1 */
Download wav file

As above, but now we apply an envelope to both tones. Now the composition sounds a bit smoother. Also, in this case we show how to calculate frequencies given the tone (case insensitive and both in English or Latin) and the octave. These frequencies are calculated according to the equal tempered scale.

A4 : note_freq("A", 4) $
A5 : note_freq("La", 5) $ /* La = A */

play(
   envelope = adsr(0.4, 0.1, 0.8, 0.4),

   oscillator = sine(1, 3),
   note(A4, 2000, 0.1),

   oscillator = rectangle(0.5),
   note(A5, 1000, 0.1, 0.1) )$
Download wav file

In the two previous examples, the sine oscillator of A4 is composed by the sum of two sinusoidal waves (first and third harmonics, 440 and 1320 Hz, respectively) of equal amplitude (namely 2000). But in real musical instruments, secondary harmonics are usually of shorter amplitude. In this example, we play an A3 tone with fundamental harmonic with amplitude 2000, third harmonic with amplitude 2000/2, fifth harmonic with amplitude 2000/4, and seventh harmonic with amplitude 2000/8. The secondary harmonics of the clarinet are odd, as in this case, which give the instrument its particular timbre. Do you think this piece sounds like a clarinet?

play (
  oscillator = sine(1, [3, 1/2], [5, 1/4], [7, 1/8]),
  note(220, 2000, 1) ) $
Download wav file

Let's now play the chromatic scale with our clarinet. We also add an envelope to get a more realistic sound. We can repeat every note as many times as we want; for example, the first note, C4, is played twice, at t = 0 and t = 12 sec. Sound object note accepts an arbitrary number of arguments.

C4  : note_freq("C", 4) $
Cs4 : note_freq("C#", 4) $
D4  : note_freq("D", 4) $
Ds4 : note_freq("D#", 4) $
E4  : note_freq("E", 4) $
F4  : note_freq("F", 4) $
Fs4 : note_freq("F#", 4) $
G4  : note_freq("G", 4) $
Gs4 : note_freq("G#", 4) $
A4  : note_freq("A", 4) $
As4 : note_freq("A#", 4) $
B4  : note_freq("B", 4) $
C5  : note_freq("C", 5) $

play (
  envelope = pairs([0,0],[0.05,1],[0.9,1],[1,0]),
  oscillator = sine(1, [3, 1/2], [5, 1/4], [7, 1/8]),
  note(C4, 2000, 0.5, 0.0, 12.0),
  note(Cs4, 2000, 0.5, 0.5, 11.5),
  note(D4, 2000, 0.5, 1.0, 11.0),
  note(Ds4, 2000, 0.5, 1.5, 10.5),
  note(E4, 2000, 0.5, 2.0, 10.0),
  note(F4, 2000, 0.5, 2.5, 9.5),
  note(Fs4, 2000, 0.5, 3.0, 9.0),
  note(G4, 2000, 0.5, 3.5, 8.5),
  note(Gs4, 2000, 0.5, 4.0, 8.0),
  note(A4, 2000, 0.5, 4.5, 7.5),
  note(As4, 2000, 0.5, 5.0, 7.0),
  note(B4, 2000, 0.5, 5.5, 6.5),
  note(C5, 2000, 0.5, 6.0) ) $
Download wav file

Timbre depends on oscillators. Here is a list of available oscillators.

play (draw_wave_adds = [line_width = 3],

      oscillator = rectangle(0.5),
      note(80, 1, 0.025, 0),

      /* both harmonics with the same amplitud */
      oscillator = sine(1, 4),
      note(80, 1, 0.025, 0.025),

      oscillator = rectangle(0.7),
      note(80, 1, 0.025, 0.05),

      oscillator = triangle(0.9),
      note(80, 1, 0.025, 0.075),

      /* 8th harmonic has a reduced amplitude (a factor of 1/5) */
      oscillator = sine(1, [8, 1/5]),
      note(80, 1, 0.025, 0.1),

      oscillator = triangle(0.5),
      note(80, 1, 0.025, 0.125) )$

Major chord C E G (acorde mayor, in Spanish). Three notes at the same time.

C : note_freq("C", 4) $
E : note_freq("E", 4) $
G : note_freq("G", 4) $

play (
   note(C, 2000, 0.5),
   note(E, 2000, 0.5),
   note(G, 2000, 0.5) ) $
Download wav file

Title: Symphony No. 9 in D minor, Op. 125 "Choral"
Author: Ludwig van Beethoven, (1770 - 1827).
Interpreter: Maxima CAS.
Instrument: violin.

(Follow this link for a stereo version for violin and clarinet.)

RE5  : note_freq("D", 5) $
SOL5 : note_freq("G", 5) $
LA5  : note_freq("A", 5) $
SI5  : note_freq("B", 5) $
DO6  : note_freq("C", 6) $
RE6  : note_freq("D", 6) $

play(
  envelope = adsr(0.4, 0.2, 0.6, 0.2),
  oscillator = triangle(0.99),  /* sawtooth */

  note(SI5, 2000, 0.5, 0),
  note(SI5, 2000, 0.5, 0.5),
  note(DO6, 2000, 0.5, 1),
  note(RE6, 2000, 0.5, 1.5),

  note(RE6, 2000, 0.5, 2),
  note(DO6, 2000, 0.5, 2.5), 
  note(SI5, 2000, 0.5, 3),
  note(LA5, 2000, 0.5, 3.5),

  note(SOL5, 2000, 0.5, 4), 
  note(SOL5, 2000, 0.5, 4.5),
  note(LA5, 2000, 0.5, 5),
  note(SI5, 2000, 0.5, 5.5), 

  note(SI5, 2000, 0.75, 6),
  note(LA5, 2000, 0.25, 6.75),
  note(LA5, 2000, 0.8, 7), /* force silence of 0.2 sec */

  note(SI5, 2000, 0.5, 8),
  note(SI5, 2000, 0.5, 8.5),
  note(DO6, 2000, 0.5, 9),
  note(RE6, 2000, 0.5, 9.5),

  note(RE6, 2000, 0.5, 10),
  note(DO6, 2000, 0.5, 10.5), 
  note(SI5, 2000, 0.5, 11),
  note(LA5, 2000, 0.5, 11.5),

  note(SOL5, 2000, 0.5, 12), 
  note(SOL5, 2000, 0.5, 12.5),
  note(LA5, 2000, 0.5, 13),
  note(SI5, 2000, 0.5, 13.5), 

  note(LA5, 2000, 0.75, 14),
  note(SOL5, 2000, 0.25, 14.75),
  note(SOL5, 2000, 0.8, 15), /* force silence of 0.2 sec */

  note(LA5, 2000, 0.5, 16),
  note(LA5, 2000, 0.5, 16.5),
  note(SI5, 2000, 0.5, 17), 
  note(SOL5, 2000, 0.5, 17.5),

  note(LA5, 2000, 0.5, 18),
  note(SI5, 2000, 0.25, 18.5), 
  note(DO6, 2000, 0.25, 18.75),
  note(SI5, 2000, 0.5, 19), 
  note(SOL5, 2000, 0.5, 19.5),

  note(LA5, 2000, 0.5, 20),
  note(SI5, 2000, 0.25, 20.5), 
  note(DO6, 2000, 0.25, 20.75),
  note(SI5, 2000, 0.5, 21), 
  note(LA5, 2000, 0.5, 21.5),

  note(SOL5, 2000, 0.5, 22),
  note(LA5, 2000, 0.5, 22.5), 
  note(RE5, 2000, 0.8, 23), /* force silence of 0.2 sec */

  note(SI5, 2000, 0.5, 24),
  note(SI5, 2000, 0.5, 24.5), 
  note(DO6, 2000, 0.5, 25),
  note(RE6, 2000, 0.5, 25.5),

  note(RE6, 2000, 0.5, 26), 
  note(DO6, 2000, 0.5, 26.5),
  note(SI5, 2000, 0.5, 27),
  note(LA5, 2000, 0.5, 27.5), 

  note(SOL5, 2000, 0.5, 28),
  note(SOL5, 2000, 0.5, 28.5),
  note(LA5, 2000, 0.5, 29), 
  note(SI5, 2000, 0.5, 29.5),

  note(LA5, 2000, 0.75, 30), 
  note(SOL5, 2000, 0.25, 30.75),
  note(SOL5, 2000, 1, 31)) $
Download wav file

Back to main page
Back to sound contents


by Mario Rodríguez Riotorto