LinuxQuestions.org
Review your favorite Linux distribution.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
LinkBack Search this Thread
Old 11-12-2009, 01:39 PM   #1
icecubeflower
Member
 
Registered: Mar 2008
Location: USA
Distribution: Slackware 13.1
Posts: 304

Rep: Reputation: 33
midi


What if I wanted to write a program where I could say play play note A for 2 seconds and use the Oboe and then save it as an midi file? Where is the best place to learn how to construct midi files?
 
Old 11-13-2009, 12:56 PM   #2
smeezekitty
Senior Member
 
Registered: Sep 2009
Location: washington U.S.
Distribution: Damn Small Linux, KateOs, M$ Ickdows Vista, My own OS
Posts: 2,094

Rep: Reputation: 104Reputation: 104
Not easy http://www.sonicspot.com/guide/midifiles.html.
 
Old 11-20-2009, 09:48 AM   #3
neonsignal
Senior Member
 
Registered: Jan 2005
Location: Melbourne, Australia
Distribution: Debian Squeeze (Fluxbox WM)
Posts: 1,331
Blog Entries: 44

Rep: Reputation: 334Reputation: 334Reputation: 334Reputation: 334
Depending on which language you wish to use, you may find a library that will do this for you.

If you wish to understand the format, you might find this midi specification and file format useful. The format consists of some encapsulation headers, and the midi data is stored as a sequence of(delta) timestamps and events.

For example, the following sample C code will produce a midi file that plays concert A on the oboe for 2 seconds.

The code uses macros for byte reversal (because midi is big-endian); this is not portable. It also uses macros for the midi time stamps (because these are variable in length and use the high bit of each byte as an extension bit) to keep the sample code manageable, but in practice you should use a function to produce these.

Code:
// include files
  #include <stdint.h>
  #include <stdio.h>
// byte order reversal macros
  #define R16(x) ((x<<8&0xFF00)|(x>>8&0xFF))
  #define R32(x) ((x<<24&0xFF000000)|(x<<8&0xFF0000)|(x>>8&0xFF00)|(x>>24&0xFF))
// delta time stamps
  #define T8(x) (x&0x7F)
  #define T16(x) ((x<<1&0x7F00)|(x&0x7F)|0x8000)
  #define T24(x) ((x<<2&0x7F0000)|(x<<1&0x7F00)|(x&0x7F)|0x808000)
// midi chunk structures
  #pragma pack(push, 1)
  struct
  {
    char id[4];
    uint32_t length;
    uint16_t type;
    uint16_t tracks;
    uint8_t div0, div1;
  } midiHeader = {{'M', 'T', 'h', 'd'}, R32(6), R16(1), R16(1), -25, 40};
  struct
  {
    char id[4];
    uint32_t length;
  } trackHeader = {{'M', 'T', 'r', 'k'}};
// delta time stamps
  typedef uint8_t Time8;
  typedef uint16_t Time16;
// midi event structures
  struct
  {
    uint8_t status;
    uint8_t end0, end1;
  } trackend = {0xFF, 0x2F, 0x00};
  typedef struct
  {
    uint8_t status;
    uint8_t program;
  } Patch;
  typedef struct
  {
    uint8_t status;
    uint8_t pitch;
    uint8_t velocity;
  } Note;
  #pragma pack(pop)
// midi events
  Time8 ms0 = {T8(0)};
  Time16 ms2000 = {R16(T16(2000))};
  Patch oboe = {0xC0, 69};
  Note concertA = {0x90, 69, 64};
  Note concertAoff = {0x80, 69, 64};
// midi event sequence
  typedef struct
  {
    void *time; size_t sizeTime;
    void *message; size_t sizeMessage;
  } Event;
  Event track[] =
  {
  // select oboe
    {&ms0, sizeof(ms0), &oboe, sizeof(oboe)},
  // play concert A
    {&ms0, sizeof(ms0), &concertA, sizeof(concertA)},
  // end concert A
    {&ms2000, sizeof(ms2000), &concertAoff, sizeof(concertAoff)},
  // end of track
    {&ms0, sizeof(ms0), &trackend, sizeof(trackend)},
  };
int main()
{
// write header
  FILE *output = fopen("test.mid", "wb");
  fwrite(&midiHeader, sizeof(midiHeader), 1, output);
// calculate track length
  uint32_t length = 0;
  size_t event, nEvents = sizeof(track)/sizeof(Event);
  for (event = 0; event < nEvents; ++event)
    length += track[event].sizeTime + track[event].sizeMessage;
  trackHeader.length = R32(length);
// write track header
  fwrite(&trackHeader, sizeof(trackHeader), 1, output);
// write track sequence
  for (event = 0; event < nEvents; ++event)
  {
    fwrite(track[event].time, track[event].sizeTime, 1, output);
    fwrite(track[event].message, track[event].sizeMessage, 1, output);
  }
// close
  fclose(output);
}
The output file will look like this:
Code:
00000000  4d 54 68 64 00 00 00 06  00 01 00 01 e7 28 4d 54  |MThd.........(MT|
00000010  72 6b 00 00 00 10 00 c0  45 00 90 45 40 8f 50 80  |rk......E..E@.P.|
00000020  45 40 00 ff 2f 00                                 |E@../.|
00000026
 
Old 11-23-2009, 01:53 PM   #4
icecubeflower
Member
 
Registered: Mar 2008
Location: USA
Distribution: Slackware 13.1
Posts: 304

Original Poster
Rep: Reputation: 33
Wow. So uh... about that library that would do it for me, any recomendations?
 
Old 11-23-2009, 05:42 PM   #5
neonsignal
Senior Member
 
Registered: Jan 2005
Location: Melbourne, Australia
Distribution: Debian Squeeze (Fluxbox WM)
Posts: 1,331
Blog Entries: 44

Rep: Reputation: 334Reputation: 334Reputation: 334Reputation: 334
What language are you writing the code in?
 
Old 11-23-2009, 09:20 PM   #6
icecubeflower
Member
 
Registered: Mar 2008
Location: USA
Distribution: Slackware 13.1
Posts: 304

Original Poster
Rep: Reputation: 33
C++
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
MIDI? BeerSlinger Linux - Newbie 10 12-06-2008 12:20 PM
midi keyboard, how to make sound?midi keyboard, how to produce sounds? Blyiss Linux - Software 10 03-24-2007 08:53 PM
MIDI playback through midi keyboad. akihandyman Linux - Newbie 5 05-25-2005 01:37 AM
How to play MIDI files: needed a MIDI mapper? vharishankar Linux - General 3 12-30-2004 12:12 AM
Set up midi device in suse 9.1 w/ AC'97 midi controller Guitarist88 Linux - Hardware 1 07-06-2004 03:09 PM


All times are GMT -5. The time now is 09:41 AM.

Main Menu
 
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: @linuxquestions
Open Source Consulting | Domain Registration