summaryrefslogblamecommitdiffstats
path: root/src/osc.h
blob: 8b6fdeac429ddc6a73ce731cbd6ddb52241f3e6c (plain) (tree)
1
2
3
4
5
6
7



                 


                   
















                                                                







                                                   







                      
                             
        
 






                                        
        









                                                                 

                                    



                 
                                          




                                  

                                  
                                  

                                  



                                          









                                           



                                 




                   
                 
                     
                 

                  
#ifndef OSC_H
#define OSC_H

#include <math.h>
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
  
/**
 * The main idea of the osc is the following:
 * The root of the sound is a periodic wave function.
 * This can be a stored period of a wave in a wavetable
 * or a function like sin(). In order to play a sound with
 * the wave an external float offset is kept that points to the
 * next sample, a function is provided to advance this offset
 * a calucalted step amount, depending on the desired frequency.
 * Linear interpolation is used so that a float offset can work
 * and provide autosmoothing.
 */

enum osc_type {
  WAVE,
  SAMPLE
};
struct osc_t;
struct osc_ops {
  void  (*set_start)(struct osc_t *, long);
  void  (*set_end)  (struct osc_t *, long);
  void  (*set_len)  (struct osc_t *, long);
  float (*sample)   (struct osc_t *, float);
  float (*next)     (struct osc_t *, float, float);
};

typedef struct osc_t {
  char name[16];
  float * data;
  long len;
  long start;
  long end;
  enum osc_type type;
  const struct osc_ops * ops;
} osc_t;
 
#define MAKE_OSC(_name, _len, _type) { \
      .name = _name,                   \
      .data = 0,                       \
      .len = _len,                     \
      .start = 0,                      \
      .end = _len,                     \
      .type = _type,                   \
      };

/* Initializes the wavetables and functions for the oscilators */
void init_osc();

float osc_interpolate(float offset, float start, float end);
float osc_next_offset(osc_t * osc, float f, float offset);
int osc_next_index(osc_t * osc, float offset);

int osc_load_wav(osc_t * osc, const char * path);

osc_t * make_tri(const char * name);

/***************/
/* OSCILATORS  */
/***************/

// function prototypes common for all oscs
#define OSC_COMMON_H(osc)        \
  void                           \
  set_##osc##_start(long start); \
  void                           \
  set_##osc##_end(long end);     \
  void                           \
  set_##osc##_len(long len);     \
  float                          \
  get_##osc##_len();             \
  float                          \
  osc_##osc(float offset);       \
  float                          \
  osc_##osc##_next(float f, float offset);

// function definitions common for all oscs
#define OSC_COMMON(osc)         \
  void                          \
  set_##osc##_start(long start) \
  { OSC_##osc.start = start; }  \
  void                          \
  set_##osc##_end(long end)     \
  { OSC_##osc.end = end; }      \
  void                          \
  set_##osc##_len(long len)     \
  { OSC_##osc.len = len; }      \
  float                         \
  get_##osc##_len()             \
  { return OSC_##osc.len; }

OSC_COMMON_H(tri)
OSC_COMMON_H(sin)
OSC_COMMON_H(weird)
OSC_COMMON_H(sound)
OSC_COMMON_H(saw)
OSC_COMMON_H(digisaw)
OSC_COMMON_H(sqr)

#endif /* OSC_H */