Prima versione funzionante.

Leonardo [2010-05-14 14:31]
Prima versione funzionante.
Filename
Makefile
simple_audio.c
simple_audio.h
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
ViewGit