From d4589ba811f095858b2492b60ac6abe2bbdc2425 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Fri, 14 May 2010 16:31:27 +0200 Subject: [PATCH] Prima versione funzionante. --- Makefile | 20 +++++++++++++ simple_audio.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++--------- simple_audio.h | 24 ++++++++++++---- 3 files changed, 115 insertions(+), 19 deletions(-) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..401bba4 --- /dev/null +++ b/Makefile @@ -0,0 +1,20 @@ +CC=cc +C_SOURCE=simple_audio.c +SHARED_LIB=libsimple_audio.so + +all: libsimple_audio.so + +libsimple_audio.so: + $(CC) -fPIC -shared -lm -o $(SHARED_LIB) $(C_SOURCE) + +example: libsimple_audio.so + $(CC) -o main main.c libsimple_audio.so + +clean: + rm -rf $(SHARED_LIB) main *~ *.o + +install: + install -m 755 $(SHARED_LIB) /usr/lib + +uninstall: + rm -rf /usr/lib/$(SHARED_LIB) diff --git a/simple_audio.c b/simple_audio.c index d276ec2..0841f36 100644 --- a/simple_audio.c +++ b/simple_audio.c @@ -2,22 +2,80 @@ #include #include #include +#include +#define PID 6.28318 -sample* sa_note(sa_instrument instrument, char* note, int len) { - return NULL; +sample sa_note_sample(sa_instrument* instrument, double frequency, double time) { + + // Calcolo il risultato della serie di Fourier al tempo time + double value = instrument->fs->a_0; + int i; + for(i = 0; i < instrument->fs->cos_len; i++) { + value += instrument->fs->cos_values[i] * cos(time * frequency * PID); + } + for(i = 0; i < instrument->fs->sin_len; i++) { + value += instrument->fs->sin_values[i] * sin(time * frequency * PID); + } + + // Ritorno il valore convertito a short int + return sa_double_to_sample (value); } +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; +} -sample sa_swap_bytes(sample s) { - sample t; - char* s_bytes; - char* t_bytes; - s_bytes = (char*) &s; - t_bytes = (char*) &t; +double sa_parse_note(char* note) { + double base; + double r2 = pow(2, 1/12.0); + + // 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); } - t_bytes[0] = t_bytes[1]; - t_bytes[1] = s_bytes[0]; - return t; + // 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); } + + return base; +} + +sample* sa_note(sa_instrument instrument, char* note, int len) { + + double frequency = sa_parse_note (note); + int i; + sample* s = (sample*) malloc(len * sizeof(sample)); + for(i = 0; i < len; i++) { + s[i] = sa_note_sample(&instrument, frequency, i / 44100.0); + } + + return s; +} + +sample sa_swap_bytes(sample s) { + sample_b buf; + unsigned char temp; + buf.s = s; + temp = buf.bytes[0]; + buf.bytes[0] = buf.bytes[1]; + buf.bytes[1] = temp; + return buf.s; } @@ -34,17 +92,21 @@ int sa_write_samples(char* filename, sample* samples, int len) { for(counter = 0; counter < len; counter ++) { buf = samples[counter]; if(sa_is_little_endian()) { buf = sa_swap_bytes(buf); } - - fwrite(&buf, 1, 1, handle); + 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}; + if( *((short*) endian) == 1) { return 1; } return 0; } int sa_is_big_endian() { - return 1; + unsigned char endian[] = { 1, 0}; + if( *( (short*) endian) == 256) { return 1; } + return 0; } diff --git a/simple_audio.h b/simple_audio.h index 5021f85..6c4ab07 100644 --- a/simple_audio.h +++ b/simple_audio.h @@ -26,20 +26,36 @@ typedef struct { int cos_len; int sin_len; - int* cos_values; - int* sin_values; + double* cos_values; + double* sin_values; int a_0; } sa_fourier_series; typedef struct { // Serie di fourier della forma d'onda - sa_fourier_series fs; + sa_fourier_series* fs; // Nome char* name; } sa_instrument; typedef short int sample; +// Questa union ci serve per scambiare i byte con comodità +typedef union { + sample s; + unsigned char bytes[2]; +} sample_b; + +// Genera un singolo sample dello strumento prescelto dopo +// un certo tempo +sample sa_note_sample(sa_instrument* instrument, double frequency, double time); + +// Determina la frequenza di una nota +double sa_parse_note(char* note); + +// Converte un double fra 0 e 1 in un sample a 16bit +sample sa_double_to_sample(double); + // Genera len sample dello strumento scelto che suona la // nota scelta sample* sa_note(sa_instrument instrument, char* note, int len); @@ -54,6 +70,4 @@ int sa_is_big_endian(); sample sa_swap_bytes(sample s); - - #endif -- 2.1.4