Arduino and MIDI out - chords

Zápisník experimentátora

Hierarchy: MIDI

We continue our experiments with MIDI. In the previous article, we've shown how MIDI out is connected and we've played a few scales. Now is the time to create some music. That is why we focus on the basis of modern, popular music, which are chords. I will use the Korg Volca FM synthesizer in the preview. But you can use any musical instrument that has MIDI input.

Chord

A chord is defined as the set of at least three tones of different pitches. But not every three tones you play together will sound good. You have to follow certain rules. These rules determine how many halftones are between notes. In music education, they are trying to make it harder for you not to go mathematically, but by ordering a tone on a particular scale. But we will program Arduino and there we will be able to program our mathematical expression more easily because MIDI has numbered individual halftones.

You can create the following chords from three tones. For each chord, I also wrote the number of individual halftones that the following tone must shift. For example, you can create a chord in C major by pressing the keys numbered 5, 7 and 9. Take the distance between them by counting also the black keys and getting the numbers listed in the first line of the following table.

  • major - 0, 4, 7
  • minor - 0, 3, 7
  • augmented - 0, 4, 8
  • diminished - 0, 3, 6

In the examples, I will only mention the first two types of chords because you will most often encounter them in popular music. Chords can be made from more than three tones, but Korg Volca FM has only triple-voice polyphony, so we can not play it using this synthesizer.

Connection

I use the same connection as in the previous article.

Examples

I've written four examples to show chords in action. I have written examples in such a way that we can gradually get to the simple melody. The melody in these examples is simple because it just changes a few different chords, but when you take a sample on YouTube, you will see that many musicians in popular music do not make a heavy head of it and make a song without a wink.

Scale C major

In the first example, we will take all notes from the C major scale and play them as chords. The notes on the C major scale are all on the white keys, but that's no longer true for chords. Only for the chords C (C E G), F (F A C) and G (G H D) hard, the other tones will be on the white keys. Other chords will be created as combinations of white and black keys. For example, the D major chord is played as a combination of D, F#, and A.

But we do not have to worry about the exact placement of the individual keys, because the same rules apply to each chord from C major scale. So, in the program, I only prepared a list of the basic notes in the array notes and the rule for creating a major chord in the array interval_major. In the program, I just pass through each of the basic tones and create a chord that I send to the synthesizer via MIDI.

#include <MIDI.h>

MIDI_CREATE_DEFAULT_INSTANCE();
const int channel = 1;
//                   C   D   E   F   G   A   H   C   C   H   A   G   F   E   D   C
const int notes[] = {60, 62, 64, 65, 67, 69, 71, 72, 72, 71, 69, 67, 65, 64, 62, 60};
const int cnt = sizeof(notes) / sizeof(int);

const int interval_major[] = {0, 4, 7};

void setup() {
  MIDI.begin();
}

void loop() {
  int note;
  for (int i = 0; i < cnt; i++) {
    note = notes[i];
    for (int j = 0; j < 3; j++)
      MIDI.sendNoteOn(note + interval_major[j], 64, channel);
    delay(760);
    for (int j = 0; j < 3; j++)
      MIDI.sendNoteOff(note + interval_major[j], 64, channel);
    delay(40);
  }
}

Scale C minor

The C minor scale is very similar to the C major scale. Only the second tone in turn plays a half tone lower. Experts on music describe it in such a way that the major chords sound cheerful and the minor sound sad. You can try it in this example, which differs from the previous one just in the chord creation rule in the array interval_minor. For example, the C minor chord will be played as a combination of the C, Eb, and G keys. Chord D minor will be played as a combination of the keys D, F, and A.

#include <MIDI.h>

MIDI_CREATE_DEFAULT_INSTANCE();
const int channel = 1;
//                   C   D   E   F   G   A   H   C   C   H   A   G   F   E   D   C
const int notes[] = {60, 62, 64, 65, 67, 69, 71, 72, 72, 71, 69, 67, 65, 64, 62, 60};
const int cnt = sizeof(notes) / sizeof(int);

const int interval_minor[] = {0, 3, 7};

void setup() {
  MIDI.begin();
}

void loop() {
  int note;
  for (int i = 0; i < cnt; i++) {
    note = notes[i];
    for (int j = 0; j < 3; j++)
      MIDI.sendNoteOn(note + interval_minor[j], 64, channel);
    delay(760);
    for (int j = 0; j < 3; j++)
      MIDI.sendNoteOff(note + interval_minor[j], 64, channel);
    delay(40);
  }
}

C major, F major and G major

In previous examples, you've noticed that in the array notes I have written notes that have gradually moved the scale first up and then the notes are back again. What happens if these notes do not form a scale, but we will only pick out a few notes and we will gradually play them as chords? We will basically produce a song. It's going to be simple, but when we choose the right chords, it will sound very good. For example, in this example I only used chords in C major, F major and G major. I repeat each chord four times to get the impression that I'm playing in a four-quarter time and the individual notes are shorter to add a little bit speed.

This program basically does not differ from the previous two examples. Only a change in notes makes it no longer a scale, but it's a song. This way you can play with notes, you can change different chords and rearrange their order. You will hear yourself when you have done something nice and when you have created something horrible.

#include <MIDI.h>

MIDI_CREATE_DEFAULT_INSTANCE();
const int channel = 1;
//                   C   C   C   C   F   F   F   F   C   C   C   C   G   G   G   G
const int notes[] = {60, 60, 60, 60, 65, 65, 65, 65, 60, 60, 60, 60, 67, 67, 67, 67};
const int cnt = sizeof(notes) / sizeof(int);

const int interval_major[] = {0, 4, 7};

void setup() {
  MIDI.begin();
}

void loop() {
  int note;
  for (int i = 0; i < cnt; i++) {
    note = notes[i];
    for (int j = 0; j < 3; j++)
      MIDI.sendNoteOn(note + interval_major[j], 64, channel);
    delay(160);
    for (int j = 0; j < 3; j++)
      MIDI.sendNoteOff(note + interval_major[j], 64, channel);
    delay(40);
  }
}

C major, F major, A minor ang G major

The latter example only adds a minor change from a musical perspective. The third chord is not C major, but it's A minor. Do you remember what I said about cheerful and sad chords? This is the sad chord that brings an interesting change to the sequence of chords. It is no longer the endless playing of the same chords, the new minor chord made a dramatic change. If someone really wrote such a song, it would definitely add it to words to match the mood created by the chords. So in the first cheerful part, the hero of the song would fall in love, in the second sad part would break with his love, prepare the rope, flipped through the arm, when in the last happy part would turn everything good for good, both would fall in their arms and they had a lot of little kids together.

But let's go back to the program. The code is slightly more complicated because I had to distinguish when to play major chords and when to play minor chords. This ensures an array inter. In it, I have indexes stored in the array intervals. Writing may seem odd at first glance, but it's just an array of pointers on integer arrays. So this is in fact only a two-dimensional array of integers.

#include <MIDI.h>

MIDI_CREATE_DEFAULT_INSTANCE();
const int channel = 1;
//                   C   C   C   C   F   F   F   F   A   A   A   A   G   G   G   G
const int notes[] = {60, 60, 60, 60, 65, 65, 65, 65, 69, 69, 69, 69, 67, 67, 67, 67};
const int inter[] = {0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0,  0,  0,  0};
const int cnt = sizeof(notes) / sizeof(int);

const int interval_major[] = {0, 4, 7};
const int interval_minor[] = {0, 3, 7};
const int *intervals[] = {interval_major, interval_minor};

void setup() {
  MIDI.begin();
}

void loop() {
  int note;
  for (int i = 0; i < cnt; i++) {
    note = notes[i];
    for (int j = 0; j < 3; j++)
      MIDI.sendNoteOn(note + intervals[ inter[i] ][j], 64, channel);
    delay(160);
    for (int j = 0; j < 3; j++)
      MIDI.sendNoteOff(note + intervals[ inter[i] ][j], 64, channel);
    delay(40);
  }
}

Video

In the video, I tried to show a small example from each program so that you could even hear without programming what I wrote so much in this article. Not everyone has a synthesizer or a musical instrument with MIDI input and that's why it's the best way to get you heard of chords in the show.

  • to-do

Source code

The source code is located on the GitHub server.


21.08.2018


Menu