summaryrefslogblamecommitdiffstats
path: root/src/wavetable.c
blob: ab3308aeac35ea9f0c8f9bcff74526e8237dccd3 (plain) (tree)





















































































































































































                                                                                                                                                                                               
#include "wavetable.h"
#include <sndfile.h>

static wave_t wvt_sine_data;
static wave_t wvt_saw_data;
static wave_t wvt_digisaw_data;
static wave_t wvt_tri_data;
static wave_t wvt_sqr_data;
static wave_t wvt_sound_data;


void
wvt_sine_init(size_t size)
{
  wvt_sine_data.size = size;
  wvt_sine_data.data = (float *) malloc(sizeof(float) * size);
  for (int i = 0; i < size; i++) {
    wvt_sine_data.data[i] = sinf(2 * M_PI * i / size);
  }
}

void
wvt_saw_init(size_t size)
{
  wvt_saw_data.size = size;
  wvt_saw_data.data = (float *) malloc(sizeof(float) * size);
  for (int i = 0; i < size; i++) {
    float dOutput = 0.0;
    for (float n = 1.0; n < 25; n++)
      dOutput += sinf(n * 2.0 * M_PI * i / size) / n;
    wvt_saw_data.data[i] = 0.6 * dOutput;
  }
}

void
wvt_digisaw_init(size_t size)
{
  wvt_digisaw_data.size = size;
  wvt_digisaw_data.data = (float *) malloc(sizeof(float) * size);
  for (int i = 0; i < size; i++) {
    wvt_digisaw_data.data[i] = (float)i / size;
  }
}

void
wvt_sqr_init(size_t size)
{
  wvt_sqr_data.size = size;
  wvt_sqr_data.data = (float *) malloc(sizeof(float) * size);
  for (int i = 0; i < size; i++) {
    if (i < size / 2) {
      wvt_sqr_data.data[i] = -1.0f;
    } else {
      wvt_sqr_data.data[i] = 1.0f;
    }
  }
}

void
wvt_sound_init(char * path)
{
  SNDFILE* file;
  SF_INFO fileInfo;
  int numSamplesRead;

  // Open the WAV file
  file = sf_open(path, SFM_READ, &fileInfo);
  if (!file) {
    printf("Failed to open the WAV file: %s\n", sf_strerror(NULL));
    return;
  }
  printf("frames: %ld sr: %d chan: %d format: %d sections: %d seekable: %d\n", fileInfo.frames, fileInfo.samplerate, fileInfo.channels, fileInfo.format, fileInfo.sections, fileInfo.seekable);
  // Ensure the WAV file has only one channel
  if (fileInfo.channels != 1) {
    printf("Only mono WAV files are supported.\n");
    sf_close(file);
    return;
  }

  wvt_sound_data.size = fileInfo.frames ;
  wvt_sound_data.data = (float *) malloc(sizeof(float) * fileInfo.frames);

    // Read the WAV file into the buffer
  numSamplesRead = sf_readf_float(file, wvt_sound_data.data, fileInfo.frames);

  float max = -1000;
  float min = 1000;
  for (int i = 0; i < numSamplesRead; i++) {
    float s = wvt_sound_data.data[i];
    //    printf("Sample %d: %f\n", i, s);
    if (s < min) min = s;
    if (s > max) max = s;
  }
  printf("Min: %f Max: %f\n", min, max);
  
  // Close the WAV file
  sf_close(file);
}

void
wvt_init()
{
  wvt_sine_init(44100);
  wvt_saw_init(128);
  wvt_digisaw_init(48000);
  wvt_sqr_init(48000);
  wvt_tri_data.size = 2;
  wvt_tri_data.data = (float *) malloc(sizeof(float) * 2);
  wvt_tri_data.data[0] = -1.0f;
  wvt_tri_data.data[1] = 1.0f;
  wvt_sound_init("/home/gramanas/code/synth-project/waves/test1.wav");
}


float
wvt_gen(wave_t * wave, float * index, float freq, int sample_rate)
{
  if (*index >= wave->size) *index = 0;

  int current_index = (int)*index;
  int next_index = current_index + 1 >= wave->size ? 0 : current_index + 1;

  // linear interpolation between current_index and next_index
  float m = (wave->data[next_index] - wave->data[current_index]) / (1 - 0);
  float b = wave->data[current_index] /* + m * 0 */;

  // the value to pick
  float x = *index - current_index;

  float sample = m * x + b;
  float step = freq * ((float)wave->size / sample_rate);

  *index += step;
  if (*index >= wave->size) {
    *index -= wave->size;
  }

  return sample;
}

float
wvt_next(float (* wvt_fun)(float *, float, int), float freq, int sample_rate, float * wvt_index)
{
  float sample = wvt_fun(wvt_index, freq, sample_rate);
  return sample;  
}

float
wvt_saw(float * index, float freq, int sample_rate)
{
  return wvt_gen(&wvt_saw_data, index, freq, sample_rate);
}

float
wvt_digisaw(float * index, float freq, int sample_rate)
{
  return wvt_gen(&wvt_digisaw_data, index, freq, sample_rate);
}

float
wvt_sine(float * index, float freq, int sample_rate)
{
  return wvt_gen(&wvt_sine_data, index, freq, sample_rate);
}

float
wvt_tri(float * index, float freq, int sample_rate)
{
  return wvt_gen(&wvt_tri_data, index, freq, sample_rate);
}

float
wvt_sqr(float * index, float freq, int sample_rate)
{
  return wvt_gen(&wvt_sqr_data, index, freq, sample_rate);
}

float
wvt_sound(float * index, float freq, int sample_rate)
{
  return wvt_gen(&wvt_sound_data, index, freq, sample_rate);
}