A Music Macro Language Player in C

I saw a reference to Music Macro Language on the HackerNews site this morning.

https://en.wikipedia.org/wiki/Music_Macro_Language

I remember embedding music strings like this in old BASIC programs. Lacking a way to tinker with MML, I first downloaded the free Macrotune libraries from:

http://www.posemotion.com/macrotune/

I then wrote a small script interpreter, mmlplayer.exe, for 32-bit Windows using MinGW. I had to correct the psg.h file by closing the top comment or I ended up seeing an #endif without #if error.

Here’s the code:

// MMLPlayer
// by Jim Lawless
// MIT / X11 License
// See: http://www.mailsend-online.com/license2015.php


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
#include "psg.h"

void runscript(char *scriptname);

int main(int argc,char **argv) {
   printf("Music Macro Language Player\n");
   printf("by Jim Lawless - http://jiml.us\n\n");
   printf("This program uses the Macrotune libraries from\n");
   printf("http://www.posemotion.com/macrotune/\n\n");

   if(argc<2) {
      fprintf(stderr,"Syntax: mmlplayer script-file-name");
      return 1;
   }   
   runscript(argv[1]);
   return 0;
}

void runscript(char *scriptname) {
   char buff[1024];
   FILE *fp;
   char *p;

   fp=fopen(scriptname,"r");
   if(fp==NULL) {
      fprintf(stderr,"Cannot open script %s\n",scriptname);
      return;
   }
   while(fgets(buff,sizeof(buff)-1,fp)!=NULL) {
      p=strtok(buff,"\t\r\n ");
      if(!strcmp(p,"#")) {
         continue; 
      }
      else
      if(!strcasecmp(p,"echo")) {
         p=strtok(NULL,"\r\n");
         printf("%s\n",p);
      }
      else
      if(!strcasecmp(p,"volume")) {
         p=strtok(NULL,"\t\r\n");
         PSG_SetMasterVolume((float)atof(p));         
      }
      else
      if(!strcasecmp(p,"play")) {
         p=strtok(NULL,"\t\r\n");
         PSG_PlayMML(p,"","","");         
         while(PSG_IsPlayingMML())
            Sleep(500); // sleep and wait
      }
   }   
   fclose(fp);
   PSG_Terminate();
}

I used the following compile options after renaming psg_win_x86.lib to psg_win_x86.a:

gcc mmlplayer.c -L. -lpsg_win_x86 -o mmlplayer.exe

The script commands are as follows:

#

The # command indicates a comment. A space is required after the character.

echo string

The echo command displays the specified string on the console. It then displays a newline character.

play string

The play command plays a string of MML music.

volume float-number
The volume command sets the volume for the played strings.

Here’s a sample script that just plays a simple scale in eighth notes.

echo See MML documentation at
echo https://en.wikipedia.org/wiki/Music_Macro_Language
volume 5.0
play C8D8E8F8G8A8B8>C8
echo All done!

The Win32 package including the 32-bit DLL, mmlplayer.c, mmlplayer.exe, and the sample script can be found at:

http://www.mailsend-online.com/u/mmlplayer.zip

According to the API, it looks like one can play up to four channels of music concurrently. In the code above, I provide for only one channel of music at this time.

There’s an OS/X version of the Macrotune libraries. I might tinker with those later.

 

Advertisements

About Jim Lawless

I've been programming computers for about 36 years ... 30 of that professionally. I've been a teacher, I've worked as a consultant, and have written articles here and there for publications like Dr. Dobbs Journal, The C/C++ Users Journal, Nuts and Volts, and others.
This entry was posted in Programming and tagged , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s