#include "wavetable.h" #include 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); }