From e270fb5977c852588d195178e5c3f120bb33c2c0 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Fri, 14 May 2010 17:18:55 +0200 Subject: [PATCH] Aggiunta basilare gestione delle tracce audio --- main.c | 33 ++++++++++++---- simple_audio.c | 120 +++++++++++++++++++++++++++++++++++++++++---------------- simple_audio.h | 22 ++++++++++- 3 files changed, 132 insertions(+), 43 deletions(-) diff --git a/main.c b/main.c index fb992fb..7c5705b 100644 --- a/main.c +++ b/main.c @@ -13,14 +13,33 @@ int main(int argc, char** argv) { sine.fs->sin_values[0] = 1.0; sine.fs->a_0 = 0; - sample* ss = sa_note(sine, "A3", 44100); - sa_write_samples("prova.cdr", ss, 44100); + sa_instrument organ; + int j; + organ.fs = (sa_fourier_series*) malloc(sizeof(sa_fourier_series)); + organ.fs->cos_len = 0; + organ.fs->sin_len = 100; + organ.fs->sin_values = malloc(sizeof(double) * 100); + organ.fs->a_0 = 0; + for(j = 0; j < 100; j++) { + if(j % 2 == 1) + organ.fs->sin_values[j] = 0; + else + organ.fs->sin_values[j] = 1.0 / (j+1) / 3.1415926; + } + + sa_track* track = sa_track_new(2); + + + sample* ss = sa_note(organ, "A3", 44100); + sa_track_append(track, ss, 44100, 0); + sa_track_append(track, ss, 44100, 1); + + ss = sa_note(organ, "B3", 44100); + sa_track_append(track, ss, 44100, 0); + sa_track_append(track, ss, 44100, 1); + + sa_track_write(track, "prova.cdr"); - sample s = 1, t; - t = sa_swap_bytes(s); - printf("%d, %d\n", s,t); - printf("sa_is_little_endian() = %d\n", sa_is_little_endian()); - printf("sa_is_big_endian() = %d\n", sa_is_big_endian()); return 0; } diff --git a/simple_audio.c b/simple_audio.c index 0841f36..3555d51 100644 --- a/simple_audio.c +++ b/simple_audio.c @@ -5,6 +5,77 @@ #include #define PID 6.28318 +sa_track* sa_track_new(int n) { + sa_track* t = malloc(sizeof(sa_track)); + int i; + t->channels = n; + t->len = malloc(sizeof(int) * n); + t->data = malloc(sizeof(sample*) * n); + for (i = 0; i < n; i++) { + t->data[i] = NULL; + t->len[i] = 0; + } + return t; +} + +int sa_track_free(sa_track* t) { + int i; + for(i=0; i < t->channels; i++) { + free(t->data[i]); + } + free(t->len); + free(t->data); + return 0; +} + +int sa_track_append(sa_track* t, sample* s, int n, int channel) { + if(channel > t->channels) { + fprintf(stderr, "Trying to channel %d, but track has on ly %d channels\n", channel, t->channels); + exit(EXIT_FAILURE); + } + // Allargo lo spazio + + if(!t->data[channel]) { t->data[channel] = (sample*) malloc(n * sizeof(sample)); } + else { + t->data[channel] = (sample*) realloc(t->data[channel], (t->len[channel] + n)* sizeof(sample)); + } + memcpy(t->data[channel] + t->len[channel], s, n * sizeof(sample)); + t->len[channel] = t->len[channel] + n; + + return 0; +} + +int sa_track_write(sa_track* t, char* filename) { + + FILE* handle; + int counter, j; + sample buf; + + if( (handle = fopen(filename, "w")) == NULL ) + { + fprintf(stderr, "Impossibile aprire il file %s\n", filename); + exit(EXIT_FAILURE); + } + + for(j = 1; j < t->channels; j++) { + if(t->len[j] != t->len[0]) { + fprintf(stderr, "Tutte le tracce devono avere lo stesso numero di canali!\n"); + } + }; + + for(counter = 0; counter < t->len[0]; counter ++) { + for (j = 0; j < t->channels; j++) { + buf = t->data[j][counter]; + if(sa_is_little_endian()) { buf = sa_swap_bytes(buf); } + fwrite(&buf, sizeof(buf), 1, handle); + } + } + + fclose (handle); + return EXIT_SUCCESS; + +} + sample sa_note_sample(sa_instrument* instrument, double frequency, double time) { // Calcolo il risultato della serie di Fourier al tempo time @@ -23,7 +94,6 @@ sample sa_note_sample(sa_instrument* instrument, double frequency, double time) sample sa_double_to_sample(double s) { short int t = (short int) (32768 * s); - printf("%d\n", t); sample ret; memcpy(&ret, &t, sizeof(sample)); return ret; @@ -35,23 +105,23 @@ double sa_parse_note(char* note) { // Prima scala base = 440.0; - if (strcmp(note, "A2")) { return 440.0; } - if (strcmp(note, "B2")) { return base * pow(r2, 2); } - if (strcmp(note, "C3")) { return base * pow(r2, 3); } - if (strcmp(note, "D3")) { return base * pow(r2, 5); } - if (strcmp(note, "E3")) { return base * pow(r2, 7); } - if (strcmp(note, "F3")) { return base * pow(r2, 8); } - if (strcmp(note, "G3")) { return base * pow(r2,10); } + if (strcmp(note, "A2") == 0) { return 440.0; } + if (strcmp(note, "B2") == 0) { return base * pow(r2, 2); } + if (strcmp(note, "C3") == 0) { return base * pow(r2, 3); } + if (strcmp(note, "D3") == 0) { return base * pow(r2, 5); } + if (strcmp(note, "E3") == 0) { return base * pow(r2, 7); } + if (strcmp(note, "F3") == 0) { return base * pow(r2, 8); } + if (strcmp(note, "G3") == 0) { return base * pow(r2,10); } // Seconda scala base = 880.0; - if (strcmp(note, "A3")) { return base; } - if (strcmp(note, "B3")) { return base * pow(r2, 2); } - if (strcmp(note, "C4")) { return base * pow(r2, 3); } - if (strcmp(note, "D4")) { return base * pow(r2, 5); } - if (strcmp(note, "E4")) { return base * pow(r2, 7); } - if (strcmp(note, "F4")) { return base * pow(r2, 8); } - if (strcmp(note, "G4")) { return base * pow(r2,10); } + if (strcmp(note, "A3") == 0) { return base; } + if (strcmp(note, "B3") == 0) { return base * pow(r2, 2); } + if (strcmp(note, "C4") == 0) { return base * pow(r2, 3); } + if (strcmp(note, "D4") == 0) { return base * pow(r2, 5); } + if (strcmp(note, "E4") == 0) { return base * pow(r2, 7); } + if (strcmp(note, "F4") == 0) { return base * pow(r2, 8); } + if (strcmp(note, "G4") == 0) { return base * pow(r2,10); } return base; } @@ -59,6 +129,7 @@ double sa_parse_note(char* note) { sample* sa_note(sa_instrument instrument, char* note, int len) { double frequency = sa_parse_note (note); + printf("Mapped %s to %lf Hz\n", note, frequency); int i; sample* s = (sample*) malloc(len * sizeof(sample)); for(i = 0; i < len; i++) { @@ -79,25 +150,6 @@ sample sa_swap_bytes(sample s) { } -int sa_write_samples(char* filename, sample* samples, int len) { - FILE* handle; - if( (handle = fopen(filename, "w")) == NULL ) - { - fprintf(stderr, "Impossibile aprire il file %s\n", filename); - exit(EXIT_FAILURE); - } - - int counter; - sample buf; - for(counter = 0; counter < len; counter ++) { - buf = samples[counter]; - if(sa_is_little_endian()) { buf = sa_swap_bytes(buf); } - fwrite(&buf, sizeof(buf), 1, handle); - fwrite(&buf, sizeof(buf), 1, handle); - } - fclose (handle); - return EXIT_SUCCESS; -} int sa_is_little_endian() { unsigned char endian[] = { 1, 0}; diff --git a/simple_audio.h b/simple_audio.h index 6c4ab07..83a7b15 100644 --- a/simple_audio.h +++ b/simple_audio.h @@ -46,6 +46,24 @@ typedef union { unsigned char bytes[2]; } sample_b; + +// Traccia audio +typedef struct { + int channels; + sample** data; + int* len; +} sa_track; + + +// Crea una traccia vuota con n canali +sa_track* sa_track_new(int n); + +// Elimina una traccia e tutto il suo contenuto +int sa_track_free(sa_track* t); + +// Aggiunge dati ad una traccia +int sa_track_append(sa_track* t, sample* s, int len, int channel); + // Genera un singolo sample dello strumento prescelto dopo // un certo tempo sample sa_note_sample(sa_instrument* instrument, double frequency, double time); @@ -60,8 +78,8 @@ sample sa_double_to_sample(double); // nota scelta sample* sa_note(sa_instrument instrument, char* note, int len); -// Scrive delle sample sul file prescelto -int sa_write_samples(char* filename, sample* samples, int len); +// Scrive la traccia su file +int sa_track_write(sa_track* t, char* filename); // Determina se il computer sta usando la convenzione little // endian o big endian -- 2.1.4