Simplify Example

#include "mml.h"
#include "sound_system.h"   /* It depends on your platform. */

static void mml_callback(MML_INFO *p, void *extobj)
{
  SOUND_SYSTEM *ss = (SOUND_SYSTEM *)extobj;

  switch (p->type) {
    case MML_TYPE_NOTE:
      {
        MML_ARGS_NOTE *args = &(p->args.note);
        sound_system_note(ss, args->number, args->ticks);
      }
      break;
    case MML_TYPE_REST:
      {
        MML_ARGS_REST *args = &(p->args.rest);
        sound_system_rest(ss, args->ticks);
      }
      break;
  }
}

int main(void)
{
  SOUND_SYSTEM ss;
  MML mml;
  MML_OPTION mmlopt;
  void *extobj;
  char *text = "O4 L4 CDEFGAB O5 C";

  sound_system_init(&ss);   /* It depends on your platform */

  extobj = (void *)&ss;
  mml_init(&mml, mml_callback, extobj);

  while (1) {
    MML_OPTION_INITIALIZER_DEFAULT(&mmlopt);
    mml_setup(&mml, &mmlopt, text);

    while (mml_fetch(&mml) == MML_RESULT_OK) {
    }
  }

  return 0;
}

Arduino Note Example

#include <mml.h>
#include "note.h"
#include "song.h"

NOTE note;
MML mml;
MML_OPTION mml_opt;

static void mml_callback(MML_INFO *p, void *extobj)
{
  switch (p->type) {
    case MML_TYPE_TEMPO:
      {
        MML_ARGS_TEMPO *args = &(p->args.tempo);
        note_init(&note, args->value, mml_opt.bticks);
      }
      break;
    case MML_TYPE_NOTE:
      {
        MML_ARGS_NOTE *args = &(p->args.note);
        note_tone(&note, args->number, args->ticks);
      }
      break;
    case MML_TYPE_REST:
      {
        MML_ARGS_REST *args = &(p->args.rest);
        note_rest(&note, args->ticks);
      }
      break;
  }
}

void setup()
{
  /*
   * Initialize the MML module.
   */
  mml_init(&mml, mml_callback, 0);
  MML_OPTION_INITIALIZER_DEFAULT(&mml_opt);

  /*
   * Initialize the note module.
   */
  int tempo_default = 120;
  note_init(&note, tempo_default, mml_opt.bticks);
}

void loop()
{
  /*
   * Setup the MML module.
   */
  mml_setup(&mml, &mml_opt, (char *)song_text);

  /*
   * Fetch the MML text command.
   */
  while (mml_fetch(&mml) == MML_RESULT_OK) {
  }
}

Arduino Chord Example

#include <mml.h>
#include "chord.h"
#include "song.h"

CHORD chord;
MML mml;
MML_OPTION mml_opt;

static void mml_callback(MML_INFO *p, void *extobj)
{
  switch (p->type) {
    case MML_TYPE_TEMPO:
      {
        MML_ARGS_TEMPO *args = &(p->args.tempo);
        chord_init(&chord, args->value, mml_opt.bticks);
      }
      break;
    case MML_TYPE_NOTE:
      {
        MML_ARGS_NOTE *args = &(p->args.note);
        chord_note(&chord, args->number, args->ticks);
      }
      break;
    case MML_TYPE_REST:
      {
        MML_ARGS_REST *args = &(p->args.rest);
        chord_rest(&chord, args->ticks);
      }
      break;
  }
}

void setup()
{
  /*
   * Initialize the MML module.
   */
  mml_init(&mml, mml_callback, 0);
  MML_OPTION_INITIALIZER_DEFAULT(&mml_opt);

  /*
   * Initialize the chord module.
   */
  int tempo_default = 120;
  chord_init(&chord, tempo_default, mml_opt.bticks);
}

void loop()
{
  /*
   * Setup the MML module.
   */
  mml_setup(&mml, &mml_opt, (char *)song_text);

  /*
   * Fetch the MML text command.
   */
  while (mml_fetch(&mml) == MML_RESULT_OK) {
  }
}

Simple Test Program (Windows, Mac OS X, Linux)

#include <stdio.h>
#include "mml.h"

static void mml_callback(MML_INFO *p, void *extobj)
{
  static int cnt = 0;

  if (cnt == 0) {
    /*
     * I know the external object is a pointer to a text string in this sample program.
     */
    printf("The message is '%s'.\n", (char *)extobj);
  }

  printf("%3d : ", ++cnt);
  switch (p->type) {
    case MML_TYPE_NOTE:
      {
        MML_ARGS_NOTE *args = &(p->args.note);
        printf("[NOTE  : Number=%3d, Ticks=%4d]\n", args->number, args->ticks);
      }
      break;
    case MML_TYPE_REST:
      {
        MML_ARGS_REST *args = &(p->args.rest);
        printf("[REST  :             Ticks=%4d]\n", args->ticks);
      }
      break;
    case MML_TYPE_TEMPO:
      {
        MML_ARGS_TEMPO *args = &(p->args.tempo);
        printf("[TEMPO : Value=%3d]\n", args->value);
      }
      break;
    case MML_TYPE_LENGTH:
      {
        MML_ARGS_LENGTH *args = &(p->args.length);
        printf("[LENGTH: Value=%3d]\n", args->value);
      }
      break;
    case MML_TYPE_VOLUME:
      {
        MML_ARGS_VOLUME *args = &(p->args.volume);
        printf("[VOLUME: Value=%3d]\n", args->value);
      }
      break;
    case MML_TYPE_OCTAVE:
      {
        MML_ARGS_OCTAVE *args = &(p->args.octave);
        printf("[OCTAVE: Value=%3d]\n", args->value);
      }
      break;
    case MML_TYPE_OCTAVE_UP:
      {
        MML_ARGS_OCTAVE *args = &(p->args.octave_up);
        printf("[OCTAVE: Value=%3d(Up)]\n", args->value);
      }
      break;
    case MML_TYPE_OCTAVE_DOWN:
      {
        MML_ARGS_OCTAVE *args = &(p->args.octave_down);
        printf("[OCTAVE: Value=%3d(Down)]\n", args->value);
      }
      break;
  }
}

int main(int argc, char **argv)
{
  MML mml;
  MML_OPTION mmlopt;
  void *extobj;

  if (argc != 2) {
    printf("mmltest [MML]\n");
    return 0;
  }

  extobj = (void *)"This is a example for the external object.";
  mml_init(&mml, mml_callback, extobj);

  MML_OPTION_INITIALIZER_DEFAULT(&mmlopt);
  mml_setup(&mml, &mmlopt, argv[1]);

  while (mml_fetch(&mml) == MML_RESULT_OK) {
  }

  return 0;
}