home *** CD-ROM | disk | FTP | other *** search
/ C++ Games Programming / CPPGAMES.ISO / mt / makesong.c < prev    next >
C/C++ Source or Header  |  1989-01-14  |  5KB  |  178 lines

  1. /* makesong.c   Simple example of creating a song file for MT */
  2. /* writes random quarter notes to file "TESTSONG.SNG" */
  3.  
  4.  
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7.  
  8. #include "standard.h"
  9. #include "screenf.h"
  10. #include "mpu401.h"
  11. #include "filefunc.h"
  12.  
  13. #define NTRACK          8
  14. #define NUM_EVENTS      50      /* must be even number */
  15. #define HIGH_NOTE       72
  16. #define LOW_NOTE        60
  17. #define METER           4
  18. #define TICKS_PER_BEAT  120
  19.  
  20. #define NOTE_ON         0x90
  21.  
  22. /* function prototypes */
  23.  
  24. void write_event(FILE *stream, int nbytes, int b0, int b1, int b2, int b3);
  25. void putc_to_file(char *addr, int size, FILE *stream);
  26. void puti_to_file(int *addr, int size, FILE *stream);
  27. void putl_to_file(long *addr, int size, FILE *stream);
  28.  
  29. void
  30. main()
  31. {
  32.     int metrate, meter, pitchbend, exclusive, channel, i, midivol, 
  33.         event_count, active, divisor, time, note;
  34.     long numevents;
  35.     char event_data[5];
  36.     char *song_title = "Random notes test file.  From MAKESONG.C output.";
  37.     char *track1_name = "TestTrak";
  38.     char *empty_name = "<      >";
  39.     FILE *stream;
  40.     
  41.     metrate = 100;
  42.     meter = METER;
  43.     pitchbend = FALSE;
  44.     exclusive = FALSE;
  45.     channel = 0;
  46.     midivol = 100;
  47.     numevents = NUM_EVENTS;
  48.     active = FALSE;
  49.     
  50.     stream = fopen("TESTSONG.SNG", "wb");
  51.     if (stream == NULL){
  52.         fputs("\nCould not open file TESTSONG.SNG.", stdout);
  53.         exit(0);
  54.     }
  55.     fputs("\nBuilding file TESTSONG.SNG...\n", stdout);
  56.     
  57.     putc_to_file(song_title, 51, stream);           /* store common data */
  58.     puti_to_file(&metrate, 1, stream);
  59.     puti_to_file(&meter, 1, stream);
  60.     puti_to_file(&pitchbend, 1, stream);
  61.     puti_to_file(&exclusive, 1, stream);
  62.     
  63.     putc_to_file(track1_name, 9, stream);           /* store track 1 header */
  64.     puti_to_file(&channel, 1, stream);
  65.     putl_to_file(&numevents, 1, stream);
  66.     puti_to_file(&active, 1, stream);
  67.     puti_to_file(&midivol, 1, stream);
  68.     
  69.     numevents = 1;
  70.     for (i = 1; i < NTRACK; i++){           /* store other track's headers */
  71.         putc_to_file(empty_name, 9, stream);
  72.         puti_to_file(&channel, 1, stream);
  73.         putl_to_file(&numevents, 1, stream);
  74.         puti_to_file(&active, 1, stream);
  75.         puti_to_file(&midivol, 1, stream);
  76.     }
  77.     
  78.     /* rand() produces random digits between 0 and 32767 */
  79.     
  80.     divisor = 32767/(HIGH_NOTE - LOW_NOTE);
  81.     time = 0;
  82.     
  83.     /* write track 1 midi data */
  84.     
  85.     write_event(stream, 2, 0, MES_END, 0, 0);   /* starting mes_end event */
  86.     event_count = 1;
  87.     
  88.     while (event_count < NUM_EVENTS - 2){
  89.         if (time >= meter * TICKS_PER_BEAT){    /* add mes_end if needed */
  90.             write_event(stream, 2, 0, MES_END, 0, 0);
  91.             time -= meter * TICKS_PER_BEAT;
  92.             event_count += 1;
  93.         }
  94.         else {
  95.             note = LOW_NOTE + ((HIGH_NOTE - LOW_NOTE) * rand()/divisor);
  96.             write_event(stream, 4, 0, NOTE_ON + channel, note, 64);
  97.             write_event(stream, 4, TICKS_PER_BEAT, NOTE_ON + channel, 
  98.                 note, 0);
  99.             event_count += 2;
  100.             time += TICKS_PER_BEAT;
  101.         }       
  102.     }
  103.     write_event(stream, 2, 0, ALL_END, 0, 0); /* write track terminator */
  104.  
  105.     for (i = 1; i < NTRACK; i++)    /* rest of tracks have only one event */
  106.         write_event(stream, 2, 0, MES_END, 0, 0);
  107.  
  108.     fclose(stream);
  109. }
  110.  
  111.  
  112. /* Writes the five data bytes in an event with one call to putc_to_file() */
  113. void
  114. write_event(stream, nbytes, b0, b1, b2, b3)
  115. FILE *stream;
  116. int nbytes, b0, b1, b2, b3;
  117. {
  118.     char data[5];
  119.     
  120.     data[0] = nbytes;
  121.     data[1] = b0;
  122.     data[2] = b1;
  123.     data[3] = b2;
  124.     data[4] = b3;
  125.     putc_to_file(data, 5, stream);
  126. }
  127.  
  128.  
  129. void
  130. putc_to_file(addr, size, stream)        /* put near char data to stream */
  131. char *addr;
  132. int size;
  133. FILE *stream;
  134. {
  135.     int i;
  136.     
  137.     for(i = 0; i < size; i++){
  138.         fputc(*addr++, stream);
  139.     }
  140. }
  141.  
  142.  
  143.  
  144. void
  145. puti_to_file(addr, size, stream)        /* put near int data to stream */
  146. int *addr;
  147. int size;
  148. FILE *stream;
  149. {
  150.     int i, end;
  151.     char *caddr;
  152.     
  153.     caddr = (char *)addr;
  154.     end = size * sizeof(int);
  155.     
  156.     for(i = 0; i < end; i++){
  157.         fputc(*caddr++, stream);
  158.     }
  159. }
  160.  
  161.  
  162. void
  163. putl_to_file(addr, size, stream)        /* put near long int data to stream */
  164. long *addr;
  165. int size;
  166. FILE *stream;
  167. {
  168.     int i, end;
  169.     char *caddr;
  170.     
  171.     caddr = (char *)addr;
  172.     end = size * sizeof(long);
  173.     
  174.     for(i = 0; i < end; i++){
  175.         fputc(*caddr++, stream);
  176.     }
  177. }
  178.