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(¬e, 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 + -
显示快捷键?