Now using getopt for options parsing

This commit is contained in:
Phyks 2013-08-15 17:50:13 +02:00
parent 9fa7594b12
commit 7c7941ee4f
2 changed files with 152 additions and 96 deletions

View File

@ -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 :
<code>generateur.out partition output.wav bpm silence</code> where
<code>./generateur.out options</code> 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;

View File

@ -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;
}