xm_lib.c

来自「Genetic Programing of music」· C语言 代码 · 共 743 行 · 第 1/2 页

C
743
字号
#include <stdio.h>#include <stdlib.h>#include <math.h>#include <time.h>#include "xm_lib.h"#ifndef MALLOC#define MALLOC malloc#endif#ifndef REALLOC#define REALLOC realloc#endif#ifndef FREE#define FREE free#endif/* *   fwriteXMPatternNoteData - writes a pattern of note data from the notes *      contained in noteString to xmFile.  The note values written have *      values from 1-72, 1 being C-0, and 88 signaling no note.  Only *      channel 0 has notes.  Notes below 35 use instrument 2, notes *      above use instrument 1.  Four channels *      are used. The returned value is the size of the packed data. */short int fwriteXMPatternNoteData(FILE *xmFile, char *noteString) {  short int counter=0;  int i;  int rows;  char tempChar=0x80;  char note;  char bytes[3];  /* initialize bytes array */  for(i=0;i<3;i++)    bytes[i]=0x80;  /* find the number of rows */  rows=(int)strlen(noteString);    /* loop through rows */  for(i=0;i<rows;i++) {    note=noteString[i];        /* decide if this is a note */    if(note != 88) {      /* write start byte */      tempChar=0x83;      fwrite(&tempChar, sizeof(char), 1, xmFile);      /* write note */      note--;      fwrite(&note, sizeof(char), 1, xmFile);      /* write instrument */      if(note<35) tempChar=0x02;      else tempChar=0x01;      fwrite(&tempChar, sizeof(char), 1, xmFile);      counter+=3;          } else {      /* no note here, so print place holder */      tempChar=0x80;      fwrite(&tempChar, sizeof(char), 1, xmFile);      counter++;          }    /* write the rest of the channels notes (nothing) */    fwrite(&bytes, sizeof(char), 3, xmFile);    counter+=3;  }  return counter;} /* end of fwriteXMPatternNoteData *//* *   fwriteXMPatternInfo - writes one pattern worth of data to xmFile. All *      notes are in column 0. Notes below 35 use instrument 2, notes *      above use instrument 1.  4 channels are used, *      and as many pattern rows as there are items in the noteString *      which contains the notse for the pattern. */voidfwriteXMPatternInfo(FILE *xmFile, char *noteString){  int tempInt;  char tempChar;  short int tempShort;  long dataSizePos;    /* Set pattern header length */  tempInt=9;  fwrite(&tempInt, sizeof(int), 1, xmFile);  /* Set packing type (always 0) */  tempChar=0;  fwrite(&tempChar, sizeof(char), 1, xmFile);    /* Set number of rows in pattern */  tempShort=(short)strlen(noteString);  fwrite(&tempShort, sizeof(short int), 1, xmFile);      /* Store position for pattern data size */  dataSizePos=ftell(xmFile);  fseek(xmFile,2,SEEK_CUR);  /* Write random pattern data */  tempShort=fwriteXMPatternNoteData(xmFile, noteString);    /* Now store Data Size */  fseek(xmFile,dataSizePos, SEEK_SET);  fwrite(&tempShort, sizeof(short int), 1, xmFile);    return;  } /* end of fwriteXMPatternInfo *//* *   fprintXMHeaderInfo - prints the header info for a XM file to the given *       output file.  At the end the file pointer will be set to the *       beginning of the pattern data.  Patterns is returned with the number *       of patterns. Instruments is returned with the number of instruments. *       Returns '1' if this is not a XM file. */intfprintXMHeaderInfo(FILE *xmFile, FILE *outFile,		   int *patterns, int *instruments, int *channels){  char tempString[23];  short int tempShort=0;  int headerSize=0;    /* seek to start of XM file */  fseek(xmFile,0,SEEK_SET);  /* check to see if it is really a valid XM file */  tempString[17]=0;    fread(tempString, sizeof(char), 17, xmFile);  fprintf(outFile, "Cookie =\t\t'%s'\n", tempString);    if (strcmp(tempString, "Extended Module: "))    return 1;    /* Now get Module Name */  tempString[20]=0;  fread(tempString, sizeof(char), 20, xmFile);  fprintf(outFile, "Module Name =\t\t'%s'\n", tempString);  /* Now get the tracker name */  fseek(xmFile,1,SEEK_CUR);  tempString[20]=0;  fread(tempString, sizeof(char), 20, xmFile);  fprintf(outFile, "Tracker Name =\t\t'%s'\n", tempString);  /* Get version number */  fread(&tempShort, sizeof(short int), 1, xmFile);  fprintf(outFile, "Version Number =\t%#hx\n", tempShort);  /* Get header size */  fread(&headerSize, sizeof(int), 1, xmFile);  fprintf(outFile, "Header Size =\t\t%d bytes\n", headerSize);  /* Get song length */  fread(&tempShort, sizeof(short int), 1, xmFile);  fprintf(outFile, "Song Length =\t\t%hd pattern\n", tempShort);  /* Get restart position */  fread(&tempShort, sizeof(short int), 1, xmFile);  fprintf(outFile, "Restart Position =\tPattern %hd\n", tempShort);  /* Get number channels */  fread(&tempShort, sizeof(short int), 1, xmFile);  fprintf(outFile, "Channels =\t\t%hd\n", tempShort);  *channels=(int)tempShort;    /* Get number of patterns */  fread(&tempShort, sizeof(short int), 1, xmFile);  fprintf(outFile, "Patterns =\t\t%hd\n", tempShort);  *patterns=(int)tempShort;    /* Get number of instruments */  fread(&tempShort, sizeof(short int), 1, xmFile);  fprintf(outFile, "Instruments =\t\t%hd\n", tempShort);  *instruments=(int)tempShort;    /* Get Frequency Table information */  fread(&tempShort, sizeof(short int), 1, xmFile);  if ( 0x0100 & tempShort )    fprintf(outFile, "Frequency Table =\tAmiga\n");  else    fprintf(outFile, "Frequency Table =\tLinear\n");    /* Get default tempo */  fread(&tempShort, sizeof(short int), 1, xmFile);  fprintf(outFile, "Default Tempo =\t\t%hd\n", tempShort);    /* Get default beats per minute */  fread(&tempShort, sizeof(short int), 1, xmFile);  fprintf(outFile, "Default BPM =\t\t%hd\n\n", tempShort);  /* seek to beginning of pattern data */  fseek(xmFile,60+headerSize,SEEK_SET);    return 0;} /* end of fprintXMHeaderInfo *//* *   fprintNote - converts note from its numeric format to 'C#0' type *      format, and prints it to outfile followed by two spaces. */voidfprintNote(int note, FILE *outFile) {  int octave;  char noteLetter;  char sharpLetter;  /* figure out the octave */  octave=(note+3)/12;  if(octave > 5) {    fprintf(outFile,"%03d  ", note);     return;  }    /* now figure out which note in the octave */  note=note%12;  switch(note) {  case  0:    noteLetter='C'; sharpLetter='-'; break;  case  1:    noteLetter='C'; sharpLetter='#'; break;  case  2:    noteLetter='D'; sharpLetter='-'; break;  case  3:    noteLetter='D'; sharpLetter='#'; break;  case  4:    noteLetter='E'; sharpLetter='-'; break;  case  5:    noteLetter='F'; sharpLetter='-'; break;  case  6:    noteLetter='F'; sharpLetter='#'; break;  case  7:    noteLetter='G'; sharpLetter='-'; break;  case  8:    noteLetter='G'; sharpLetter='#'; break;  case  9:    noteLetter='A'; sharpLetter='-'; break;  case 10:    noteLetter='A'; sharpLetter='#'; break;  case 11:    noteLetter='B'; sharpLetter='-'; break;  default:    noteLetter='-'; sharpLetter='-'; break;        }  /* Now print the note */  fprintf(outFile,"%c%c%d  ", noteLetter, sharpLetter, octave);     return;    } /* end of fprintNote *//* *   fprintXMPatternNoteData - prints one patterns note data in xmFile to *      outFile. The size of the data is expected to be dataSize bytes, and *      the XM should have 'channels' channels, and 'rows' rows in this *      pattern. Expects xmFile to be queued to the beginning of note data, *      and leaves xmFile queued to the beginning of the next *      pattern/instrument. */void fprintXMPatternNoteData(FILE *xmFile, FILE *outFile, int dataSize,			int rows, int channels) {  int i, j;  char tempChar;  char firstByte;  char bytes[4];    /* loop through rows and channels */  for(i=0;i<rows;i++) {    /* Start printing line */    fprintf(outFile, "\t");            for(j=0;j<channels;j++) {      /* read first byte of this 'note' */      fread(&firstByte, sizeof(char), 1, xmFile);            /* check for packing */      if(0x80 & firstByte) {		/* see if there is any data for this note */	if(0x1F & firstByte) {	  /* Go through and get each byte that is needed */	  /* get note if needed */	  if (0x01 & firstByte) {	    	    fread(&tempChar, sizeof(char), 1, xmFile);	    fprintNote((int)tempChar, outFile);	    	  }	  /* get instrument if needed */	  if (0x02 & firstByte ) fread(&tempChar, sizeof(char), 1, xmFile);	  /* get volume column if needed */	  if (0x04 & firstByte ) fread(&tempChar, sizeof(char), 1, xmFile);	  /* get effect type if needed */	  if (0x08 & firstByte ) fread(&tempChar, sizeof(char), 1, xmFile);	  /* get effect parameter if needed */	  if (0x10 & firstByte ) fread(&tempChar, sizeof(char), 1, xmFile);	  	  	} else {	  /* no note here, so print place holder */	  fprintf(outFile, "---  ");	  	}	      } else {	/* Print this note */	fprintNote((int)firstByte, outFile);		/* need to read next four bytes */	fread(bytes, sizeof(char), 4, xmFile);	      }    }    /* Go to next line */    fprintf(outFile, "\n");

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?