From 7c7941ee4f7d9d3b497c670b1ba3be138d663887 Mon Sep 17 00:00:00 2001 From: Phyks Date: Thu, 15 Aug 2013 17:50:13 +0200 Subject: [PATCH] Now using getopt for options parsing --- README.md | 21 +++-- generateur.c | 227 +++++++++++++++++++++++++++++++-------------------- 2 files changed, 152 insertions(+), 96 deletions(-) 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; }