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 <math.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
+#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