It is now possible to node melodies on E2!

tempo=240
72 0 0 67 69 67

(I just infringed copyright; see Yes! We have no bananas! for details)

When you see a sequence of numbers like this in a lyrics write-up, it's probably a melody. To play back melodies on DOS and Windows machines, paste the melody into a new text file and run this program on the text file. For a PC speaker version, compile the source listed below with DJGPP; it should also work on Borland Turbo C but I haven't tried it. It can also talk to the cross-platform Allegro library.

Yes, I know it sucks and Lilypond is better, but it was a start...

The melody metanode

Changelog

  • April 20, 2001: add interface to Allegro. Now it should work on Win32, UNIX, and BeOS.

To do

  • Support human-readable note names
  • Interface with Lilypond as an exit strategy

Source of the E2 melody playback program

Don't want to compile it? Get a DOS binary at http://www.cs.rose-hulman.edu/~yerricde/e2midi.zip


/**************************************\
* e2midi.c                             *
* Everything MIDI note playback tool   *
* For Borland Turbo C++ and DJGPP      *
*                                      ********************************\
* Copyright 2000 Damian Yerrick                                        *
*                                                                      *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or    *
* (at your option) any later version.                                  *
*                                                                      *
* This program is distributed in the hope that it will be useful,      *
* but WITHOUT ANY WARRANTY; without even the implied warranty of       *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *
* GNU General Public License for more details.                         *
*                                                                      *
* You should have received a copy of the GNU General Public License    *
* along with this program; if not, write to the Free Software          *
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.            *
* Or view the License online at http://www.gnu.org/copyleft/gpl.html   *
*                                                                      *
* Damian Yerrick's World Wide Web pages are located at                 *
*   http://www.PinEight.com                                            *
*                                                                      *
\**********************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

#define USE_CONSOLE

/* Uncomment one of these: */

#include <allegro.h>
/* #include <dos.h> */

#ifdef ALLEGRO_VERSION

int last_note = 0;

void sound_note(int midiNote)
{
  if(last_note)
  {
    char midi_event[3] = {0x90, last_note, 0}; /* note off */

    midi_out(midi_event, sizeof(midi_event));
  }
  last_note = midiNote;
  if(midiNote)
  {
    char midi_event[3] = {0x90, midiNote, 100}; /* note on */

    midi_out(midi_event, sizeof(midi_event));
  }
}

#else

void sound_note(int midiNote)
{
  static const unsigned int SoundNote_freq[12] =
  {523, 554, 587, 622, 659, 698, 740, 784, 831, 880, 932, 988};
  int freq;

  if(midiNote == 0)
  {
    nosound();
    return;
  }
  // Find pitch within this octave.
  freq = SoundNote_freq[midiNote % 12];

  // If we have a low note, move it down an octave at a time.
  while(midiNote < 72)
  {
    freq >>= 1;
    midiNote += 12;
  }

  // If we have a high note, move it up an octave at a time.
  while(midiNote >= 84)
  {
    freq <<= 1;
    midiNote -= 12;
  }

  sound(freq);
}

#endif

int getno(const char *tok)
{
  if(!isdigit(tok[0]))
    return -1;
  return strtol(tok, NULL, 10);
}

int main(const int argc, const char **argv)
{
  unsigned int filesPlayed = 0;
  int arg = 0;
  FILE *fp;
  const char *tok;
  char linebuf[512];
  int n;

  int duration = 125; /* milliseconds for default tempo=480 */

#ifdef ALLEGRO_VERSION
  allegro_init();
  install_timer();
  install_keyboard();
  install_sound(DIGI_NONE, MIDI_AUTODETECT, NULL);
#endif

  while(++arg < argc)
  {
    fp = fopen(argv[arg], "rt"); /* try to open the file */
    if(fp != 0)
    {
      printf("#%d: %s", filesPlayed++, argv[arg]);

      /* read lines from the file */
      while(fgets(linebuf, sizeof(linebuf), fp) != 0)
      {
        for(tok = strtok(linebuf, " ,\r\n"); tok != 0; tok = strtok(0, " ,\r\n"))
        {
          /* look for numbers */
          if(memcmp("tempo=", tok, 6) == 0)
          {
            n = getno(tok + 6);
            if(n > 5)
              duration = (int)(60000L / n);
          }
          else
          {
            n = getno(tok);
            if(n >= 0)
            {
              sound_note(n);
#ifdef ALLEGRO_VERSION
              rest(duration);
#else
              delay(duration);
#endif
            }
          }
        }
      }

      fclose(fp);
      sound_note(0);
    }
  }

  if(filesPlayed == 0)
  {
    fputs("e2midi: play back a melody noded on E2\n"
          "syntax: e2midi foo.txt", stderr);
  }

  return 0;
}
#ifdef ALLEGRO_VERSION
END_OF_MAIN();
#endif

(back to) Everything University

Reasonably Interesting, but I have a better suggestion...

The obvious flaw with the input to this program is that it's not, uh, obvious. It's not quite human-readable, nor even easy to generate.

Further, polyphony, chords, or lyrics combined to this is out of question when using this format. (Of course, the idea was to node melodies, but hey...)

Also the above-mentioned program works, as it is, only under DOS. Pain in the neck for those of us who use "other operating systems"...

Here's my suggestion: Try GNU Lilypond. Why?

  • The source is fairly human-readable
  • It can be edited easily by hand
  • Raw versions can be generated from MIDI
  • It has less shortcomings if you need complicity
  • Also outputs MIDI
  • Produces sweet paper o' notez for you to enjoy and play from.

Some examples of Lilypond sources:

(Fine. Downvote all you want, but I just hate to see Yet Another Incompatible-With-Everything-Else Tool deployed... And personally, I rather read scores and listen to MIDI than listen to the PC beeper.)

Everything2 is designed for noding text. If you're good with ASCII art, you can even node pictures. But how do you node music? Not song lyrics, but the actual music?

Well, you have a few options. These approaches have been attempted on E2, each with their own plusses and minuses:

  • e2midi: awkward to read on the screen, but very compact, although you can only write/hear one note at a time (no chords). Requires you to compile a GNU MIDI playback program to hear it.
  • LilyPond: the name of the language and the program, it lets you write music of unlimited complexity in ASCII which the program can convert into sheet music and/or MIDI audio. Easier to read than e2midi, not so easy to understand unless you already read sheet music and have familiarized yourself with the language.
  • Napster: give the reader a band and song title and tell them to go download an MP3 of it themselves. Time-consuming and unreliable, but certainly the easiest way to go.

Log in or register to write something here or to contact authors.