1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <math.h>
5
6 typedef union{
7 unsigned int integer;
8 char byte[4];
9 }intStruct;
10
11
12 typedef struct _octaveTable{
13 char symbol[3];
14 float frequency;
15 struct _octaveTable *next;
16 } octaveTable;
17 octaveTable octaveTableHead;
18
19
20 void insertOctave(char *symbol,float frequency){
21 octaveTable *node=(octaveTable*)malloc(sizeof(octaveTable));
22 strcpy(node->symbol,symbol);
23 node->frequency=frequency;
24 node->next=octaveTableHead.next;
25 octaveTableHead.next=node;
26 }
27
28 float getFrequency(char *symbol){
29 octaveTable *node=octaveTableHead.next;
30 do{
31 if(!strcmp(node->symbol,symbol))return node->frequency;
32 node=node->next;
33 }while(node!=NULL);
34 return -1;
35 }
36
37 void destroySymbolTable(){
38 octaveTable *node=octaveTableHead.next;
39 octaveTable *tmp;
40 do{
41 tmp=node;
42 node=node->next;
43 if(tmp==NULL)break;
44 free(tmp);
45 }while(node!=NULL);
46 }
47
48
49
50 //The Global variables used in the program
51 FILE *tempFile=NULL;
52 FILE *outputFile=NULL;
53 FILE *octave=NULL;
54 FILE *music=NULL;
55 intStruct waveLength;
56 unsigned char waveHeader[40]={
57 0x52,0x49,0x46,0x46,//RIFF
58 0xFC,0x31,0x02,0x00,
59 0x57,0x41,0x56,0x45,//WAVE
60 0x66,0x6D,0x74,0x20,//fmt
61 0x10,0x00,0x00,0x00,//fmt chunck size
62 0x01,0x00,//This is uncompressed
63 0x02,0x00,//This is stereo pal!
64 0x44,0xAC,0x00,0x00,//44100 samples per second
65 0x88,0x58,0x01,0x00,//88200 bytes per second
66 0x02,0x00,//Block align=2
67 0x08,0x00,//8 bits per sample
68 0x64,0x61,0x74,0x61//data
69 };
70 //////////////////////////////////////////////////////
71 //The macros used in the program
72 #define SAMPLING_RATE 44100.0
73 #define PI 3.14
74 #define RADIAN(x) ((PI*(x))/180.0)
75 ///////////////////////////////////////////////////////
76
77
78
79 void error(char *msg){
80 printf("%s\nAborting!\n",msg);
81 exit(0);
82 }
83
84 void addWave(float frequency,int ticks,int volume){//tick=0.1Second
85 float radian;
86 float step=(float)((360.0/SAMPLING_RATE)*frequency);
87 int numberOfSamples=(int)(SAMPLING_RATE*ticks/100);
88 float degree;
89 int i,j;
90 char sample;
91 float attack=.2,decay=.2,sustain=.4,release=.2;
92 float tempVolume;
93 float attackFactor;
94 float decayFactor;
95 float releaseFactor;
96
97 int numberOfAttackSamples=attack*numberOfSamples;
98 int numberOfDecaySamples=decay*numberOfSamples;
99 int numberOfSustainSamples=sustain*numberOfSamples;
100 int numberOfReleaseSamples=release*numberOfSamples;
101
102 int attackSamplesLimit=numberOfAttackSamples;
103 int decaySamplesLimit=numberOfDecaySamples+attackSamplesLimit;
104 int sustainSamplesLimit=numberOfSustainSamples+decaySamplesLimit;
105 int releaseSamplesLimit=numberOfReleaseSamples+sustainSamplesLimit;
106
107 attackFactor=volume/(float)numberOfAttackSamples;
108 decayFactor=volume/((float)numberOfDecaySamples*2);
109 releaseFactor=volume/((float)numberOfReleaseSamples*2);
110
111
112 tempVolume=0;
113
114
115
116
117 degree=0;
118 for(i=0;i<numberOfSamples;i++){
119 if(i<attackSamplesLimit){
120 tempVolume+=attackFactor;
121 }else if(i<decaySamplesLimit){
122 tempVolume-=decayFactor;
123 }else if(i<sustainSamplesLimit){
124
125 }else if(i<releaseSamplesLimit){
126 tempVolume-=releaseFactor;
127 }
128 radian=RADIAN(degree);
129 sample=(char)(tempVolume*sin(radian));
130 sample+=(char)((tempVolume)*sin(RADIAN(degree+30)));
131 sample+=127;
132 fprintf(tempFile,"%c%c",sample,sample);
133 degree+=step;
134 waveLength.integer+=2;
135 }
136 }
137 void generateWave(){
138 int i;
139 char byte;
140 for(i=0;i<40;i++){
141 fprintf(outputFile,"%c",waveHeader[i]);
142 }
143 for(i=0;i<4;i++){
144 fprintf(outputFile,"%c",waveLength.byte[i]);
145 }
146 tempFile=fopen("temp","r");
147 while(1){
148 fscanf(tempFile,"%c",&byte);
149 if(feof(tempFile))break;
150 fprintf(outputFile,"%c",byte);
151 }
152 fclose(tempFile);
153 }
154
155 int main(int argc, char* argv[]){
156 char octaveSignature[5];
157 char symbol[3];
158 float frequency;
159 float chord[6];
160
161 int ticks;
162 char line[1024];
163 int volume;
164 if(argc<2){
165 printf("Usage:\n\t play MusicFile [volume]\n\n",argv[0]);
166 error("You have not specified the music file!");
167 }
168 volume=50;
169 if(argc==3){
170 volume=atoi(argv[2]);
171 }
172 printf("BlueScorpion presents...Play!\n");
173 printf("Author: kashyap\n");
174 printf("Varifying octave...");
175 octave=fopen("octave","r");
176 if(octave==NULL){
177 error("Could not find octave!");
178 }
179 fscanf(octave,"%s\n",octaveSignature);
180 if(octaveSignature[0]!='M'||octaveSignature[1]!='U'||octaveSignature[2]!='S'||octaveSignature[3]!='I'||octaveSignature[4]!='C')error("Bad octave file");
181 printf("Setting up the Octave table...\n");
182 while(!feof(octave)){
183 fgets(line,1024,octave);
184 if(line[0]=='#')continue;
185 sscanf(line,"%s %f\n",symbol,&frequency);
186 if(feof(octave))break;
187 insertOctave(symbol,frequency);
188 printf("%s=%fHz\n",symbol,frequency);
189 }
190 music=fopen(argv[1],"r");
191 if(music==NULL){
192 error("Could not open the specified music file!");
193 }
194 tempFile=fopen("temp","w");
195 while(!feof(music)){
196 fgets(line,1024,music);
197 if(line[0]=='#')continue;
198 sscanf(line,"%s %d\n",symbol,&ticks);
199 frequency=getFrequency(symbol);
200 if(frequency==-1)error("Invalid symbol encountered in the music file!");
201 if(feof(music))break;
202 addWave(frequency,ticks,volume);
203 }
204
205 fclose(tempFile);
206
207 outputFile=fopen("output.wav","w");
208 if(outputFile==NULL){
209 error("Error opening output.wav for writing!");
210 }
211 generateWave();
212 fclose(outputFile);
213 destroySymbolTable();
214 return 0;
215 }
216
217
218
|