diff --git a/README.md b/README.md
index b8a1c9e..539a42f 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,13 @@
(Bad) Artificial Song Generator
===============================
-This is just a simple C code to handle wave files (see files wave_stuf.* for the functions) and a simple application to generating purely artificial sounds (just by creating a wave file with values from a sine wave at the good frequency to make a note.
+This is just a simple C code to handle wave files (see files wave_stuf.* for the functions) and a simple application to generate purely artificial sounds (just by creating a wave file with values from a sine wave at the good frequency to make a note).
### Included files are :
* _examples_ folder with some examples music sheets and the resulting generated wave files
* _generateur.c_ which is the main program
-* _generateur_partition.py_ which is just a simple program to generate basic music sheet to use with the main program
+* _generateur_musicsheet.py_ which is just a simple program to generate basic music sheet to use with the main program
* _wave_stuff.*_ which are the functions to handle wave files
## Usage of the main program
@@ -15,12 +15,15 @@ This is just a simple C code to handle wave files (see files wave_stuf.* for the
The main program should be compiled using the makefile.
To use it, just run from command line :
-generateur.out partition output.wav bpm silence
where
+./generateur.out options
where
-* _partition_ is the path to the music sheet you want to generate
-* _output.wav_ is the resulting wave files
-* _bpm_ is the speed of the song (in bpm)
-* _silence_ is an integer that should be set to 1 to add silences between notes
+options are amongst :
+
+* _-m_ (or _--musicsheet_) _file_ where _file_ is the path to the music sheet you want to generate. [mandatory argument]
+* _-o_ (or _--output_) _file_ where _file_ is the resulting wave file. [mandatory argument]
+* _-b_ (or _--bpm_) _bpm_ where _bpm_ is the speed of the song (in bpm). [mandatory argument]
+* _-s_ (or _--silence_) to add silences between notes. [optional argument]
+* _-h_ (or _--help_) to display an help message.
## Usage of the basic music sheet generator
@@ -29,9 +32,9 @@ This program allows you to write a simple music sheet without always looking for
* RE, MI, FA, SOL, LA, SI, DO (where LA is 440Hz)
* RE2, MI2, FA2, SOL2, LA2, SI2, DO2 (where LA is 880Hz).
-Length is any integer you want. It will define the length of the note (play with both length and bpm params to get what you want).
+Length is any integer you want. It will define the length of the note (play with both _length_ and _bpm_ (during playback) params to get what you want).
-You can use the -o (--output) option with a filename as argument to store the generated music sheet to this specific file.
+You can use the _-o_ (_--output_) option with a filename as argument to store the generated music sheet to this specific file.
## License
### TLDR;
diff --git a/generateur.c b/generateur.c
index dc5d286..73439a6 100644
--- a/generateur.c
+++ b/generateur.c
@@ -3,117 +3,170 @@
# include "string.h"
# include "math.h"
# include "wave_stuff.h"
+# include "getopt.h"
# ifndef M_PI
- # define M_PI 3.14159265358979323846
+# define M_PI 3.14159265358979323846
# endif
# define TAILLE_MAX 100
char **str_split (char *s, const char *ct)
{
- char **tab = NULL;
+ char **tab = NULL;
- if (s != NULL && ct != NULL)
- {
- int i;
- char *cs = NULL;
- size_t size = 1;
+ if (s != NULL && ct != NULL)
+ {
+ int i;
+ char *cs = NULL;
+ size_t size = 1;
-/* (1) */
- for (i = 0; (cs = strtok (s, ct)); i++)
- {
- if (size <= i + 1)
- {
- void *tmp = NULL;
-
-/* (2) */
- size <<= 1;
- tmp = realloc (tab, sizeof (*tab) * size);
- if (tmp != NULL)
+ /* (1) */
+ for (i = 0; (cs = strtok (s, ct)); i++)
+ {
+ if (size <= i + 1)
{
- tab = tmp;
+ void *tmp = NULL;
+
+ /* (2) */
+ size <<= 1;
+ tmp = realloc (tab, sizeof (*tab) * size);
+ if (tmp != NULL)
+ {
+ tab = tmp;
+ }
+ else
+ {
+ fprintf (stderr, "Memoire insuffisante\n");
+ free (tab);
+ tab = NULL;
+ exit (EXIT_FAILURE);
+ }
}
- else
- {
- fprintf (stderr, "Memoire insuffisante\n");
- free (tab);
- tab = NULL;
- exit (EXIT_FAILURE);
- }
- }
-/* (3) */
- tab[i] = cs;
- s = NULL;
- }
- tab[i] = NULL;
- }
- return tab;
+ /* (3) */
+ tab[i] = cs;
+ s = NULL;
+ }
+ tab[i] = NULL;
+ }
+ return tab;
}
void generer_note(int freq, int note, int duree, float *xd, int start)
{
- int i;
-
- for (i = start; i < start+duree; i++)
- {
- xd[i] += (int)(32767 *sin(2*M_PI*note*i/freq));
- }
+ int i;
+
+ for (i = start; i < start+duree; i++)
+ {
+ xd[i] += (int)(32767 *sin(2*M_PI*note*i/freq));
+ }
+}
+
+void print_help() {
+ fprintf(stderr, "\t\t\t\t================\n");
+ fprintf(stderr, "\t\t\t\t|| SongPlayer ||\n");
+ fprintf(stderr, "\t\t\t\t================\n\n");
+ fprintf(stderr, "Usage :\n");
+ fprintf(stderr, "=======\n\tgenererateur.out options\n\n");
+ fprintf(stderr, "Options :\n");
+ fprintf(stderr, "=========\n");
+ fprintf(stderr, "\t-h\t\t--help\t\t\tPrint this help message.\n");
+ fprintf(stderr, "\t-o file\t\t--output file\t\tSpecify the output wave file (mandatory).\n");
+ fprintf(stderr, "\t-b bpm\t\t--bpm bpm\t\tSpecify the speed in bpm to play the song (mandatory).\n");
+ fprintf(stderr, "\t-m musicsheet\t--musicsheet\t\tSpecify the input music sheet to use (mandatory).\n");
+ fprintf(stderr, "\t-s\t\t--silence\t\tAdd some silences between notes (optional).\n");
}
int main(int argc, char **argv)
{
- if (argc < 5)
- {
- fprintf(stderr,"Usage: %s partition output.wav bpm silence\nsilence should be 1 to add silence between notes.\n",argv[0]);
- return 0;
- }
-
- float *xd;
- int nx = 0, freq = 44100, canal = 0, verbose = 0, BitsPerSample = 16, dureeNote = 0, start = 0, n = 0, silence, Split1, Split2;
- float time = 1./atof(argv[3])*60.;
- char ligne[TAILLE_MAX];
- FILE* partition = NULL;
-
- partition = fopen(argv[1], "r");
- fgets(ligne, TAILLE_MAX, partition);
- n = atoi(ligne);
- silence = atoi(argv[4]);
-
- if(silence == 1)
- {
- nx = (int)(freq*time*(n+n/8));
- }
- else
- {
- nx = (int)(freq*time*n);
- }
-
- dureeNote = (int)(freq*time);
- xd = (float*)calloc(nx,sizeof(float));
+ float *xd;
+ int nx = 0, freq = 44100, canal = 0, verbose = 0, BitsPerSample = 16, dureeNote = 0, start = 0, n = 0, silence = 0, Split1, Split2;
+ float time = 0.5;
+ char ligne[TAILLE_MAX];
+ char* output = NULL;
+ FILE* musicsheet = NULL;
- while(fgets(ligne, TAILLE_MAX, partition) != NULL)
- {
- if(strchr(ligne, ':')!=NULL)
+ const char* const short_options = "hm:b:o:s";
+ const struct option long_options[] = {
+ { "help", 0, NULL, 'h' },
+ { "bpm", 1, NULL, 'b' },
+ { "musicsheet", 1, NULL, 'm' },
+ { "output", 1, NULL, 'o' },
+ { "silence", 0, NULL, 's' },
+ { NULL, 0, NULL, 0 }
+ };
+ int next_option = 0;
+
+ do {
+ next_option = getopt_long(argc, argv, short_options, long_options, NULL);
+
+ switch(next_option)
+ {
+ case 'h':
+ print_help();
+ return EXIT_SUCCESS;
+ break;
+
+ case 'm':
+ musicsheet = fopen(optarg, "r");
+ break;
+
+ case 'o':
+ output = optarg;
+ break;
+
+ case 's':
+ silence = 1;
+ break;
+
+ case 'b':
+ time = 1./atof(optarg)*60.;
+ break;
+ }
+ } while(next_option != -1);
+
+ if(musicsheet == NULL || output == NULL) {
+ print_help();
+ return EXIT_SUCCESS;
+ }
+
+ fgets(ligne, TAILLE_MAX, musicsheet);
+ n = atoi(ligne);
+
+ if(silence == 1)
{
- char** Split=str_split(ligne, ":");
- Split1=atoi(Split[0]);
- Split2=atoi(Split[1]);
+ nx = (int)(freq*time*(n+n/8));
}
else
{
- Split1=atoi(ligne);
- Split2=1;
+ nx = (int)(freq*time*n);
}
-
- generer_note(freq, Split1, Split2*dureeNote, xd, start);
- start += Split2*dureeNote;
-
- if(silence == 1)
+
+ dureeNote = (int)(freq*time);
+ xd = (float*)calloc(nx,sizeof(float));
+
+ while(fgets(ligne, TAILLE_MAX, musicsheet) != NULL)
{
- generer_note(freq, 0, (int)(Split2*dureeNote/8), xd, start);
- start += (int)(Split2*dureeNote/8);
+ if(strchr(ligne, ':')!=NULL)
+ {
+ char** Split=str_split(ligne, ":");
+ Split1=atoi(Split[0]);
+ Split2=atoi(Split[1]);
+ }
+ else
+ {
+ Split1=atoi(ligne);
+ Split2=1;
+ }
+
+ generer_note(freq, Split1, Split2*dureeNote, xd, start);
+ start += Split2*dureeNote;
+
+ if(silence == 1)
+ {
+ generer_note(freq, 0, (int)(Split2*dureeNote/8), xd, start);
+ start += (int)(Split2*dureeNote/8);
+ }
}
- }
-
- save_wave_from_array(xd, nx, argv[2], freq, BitsPerSample);
- return 0;
+
+ save_wave_from_array(xd, nx, output, freq, BitsPerSample);
+ return 0;
}