184 lines
6.2 KiB
C
184 lines
6.2 KiB
C
/* nekobee DSSI software synthesizer plugin
|
|
*
|
|
* Copyright (C) 2004 Sean Bolton and others.
|
|
*
|
|
* Portions of this file may have come from Steve Brookes'
|
|
* nekobee, copyright (C) 1999 S. J. Brookes.
|
|
* Portions of this file may have come from Peter Hanappe's
|
|
* Fluidsynth, copyright (C) 2003 Peter Hanappe and others.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation; either version 2 of
|
|
* the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be
|
|
* useful, but WITHOUT ANY WARRANTY; without even the implied
|
|
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public
|
|
* License along with this program; if not, write to the Free
|
|
* Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
* MA 02111-1307, USA.
|
|
*/
|
|
|
|
#ifndef _XSYNTH_VOICE_H
|
|
#define _XSYNTH_VOICE_H
|
|
|
|
#include <string.h>
|
|
|
|
#include "nekobee_types.h"
|
|
|
|
/* maximum size of a rendering burst */
|
|
#define XSYNTH_NUGGET_SIZE 64
|
|
|
|
/* minBLEP constants */
|
|
/* minBLEP table oversampling factor (must be a power of two): */
|
|
#define MINBLEP_PHASES 64
|
|
/* MINBLEP_PHASES minus one: */
|
|
#define MINBLEP_PHASE_MASK 63
|
|
/* length in samples of (truncated) step discontinuity delta: */
|
|
#define STEP_DD_PULSE_LENGTH 72
|
|
/* length in samples of (truncated) slope discontinuity delta: */
|
|
#define SLOPE_DD_PULSE_LENGTH 71
|
|
/* the longer of the two above: */
|
|
#define LONGEST_DD_PULSE_LENGTH STEP_DD_PULSE_LENGTH
|
|
/* MINBLEP_BUFFER_LENGTH must be at least XSYNTH_NUGGET_SIZE plus
|
|
* LONGEST_DD_PULSE_LENGTH, and not less than twice LONGEST_DD_PULSE_LENGTH: */
|
|
#define MINBLEP_BUFFER_LENGTH 512
|
|
/* delay between start of DD pulse and the discontinuity, in samples: */
|
|
#define DD_SAMPLE_DELAY 4
|
|
|
|
struct _nekobee_patch_t
|
|
{
|
|
float tuning;
|
|
unsigned char waveform;
|
|
float cutoff;
|
|
float resonance;
|
|
float envmod;
|
|
float decay;
|
|
float accent;
|
|
float volume;
|
|
};
|
|
|
|
enum nekobee_voice_status
|
|
{
|
|
XSYNTH_VOICE_OFF, /* silent: is not processed by render loop */
|
|
XSYNTH_VOICE_ON, /* has not received a note off event */
|
|
XSYNTH_VOICE_SUSTAINED, /* has received note off, but sustain controller is on */
|
|
XSYNTH_VOICE_RELEASED /* had note off, not sustained, in final decay phase of envelopes */
|
|
};
|
|
|
|
struct blosc
|
|
{
|
|
int last_waveform, /* persistent */
|
|
waveform, /* comes from LADSPA port each cycle */
|
|
bp_high; /* persistent */
|
|
float pos, /* persistent */
|
|
pw; /* comes from LADSPA port each cycle */
|
|
};
|
|
|
|
/*
|
|
* nekobee_voice_t
|
|
*/
|
|
struct _nekobee_voice_t
|
|
{
|
|
unsigned int note_id;
|
|
|
|
unsigned char status;
|
|
unsigned char key;
|
|
unsigned char velocity;
|
|
unsigned char rvelocity; /* the note-off velocity */
|
|
|
|
/* translated controller values */
|
|
float pressure; /* filter resonance multiplier, off = 1.0, full on = 0.0 */
|
|
|
|
/* persistent voice state */
|
|
float prev_pitch,
|
|
target_pitch,
|
|
lfo_pos;
|
|
struct blosc osc1;
|
|
float vca_eg,
|
|
vcf_eg,
|
|
accent_slug,
|
|
delay1,
|
|
delay2,
|
|
delay3,
|
|
delay4,
|
|
c5;
|
|
unsigned char vca_eg_phase,
|
|
vcf_eg_phase;
|
|
int osc_index; /* shared index into osc_audio */
|
|
float osc_audio[MINBLEP_BUFFER_LENGTH];
|
|
float freqcut_buf[XSYNTH_NUGGET_SIZE];
|
|
float vca_buf[XSYNTH_NUGGET_SIZE];
|
|
};
|
|
|
|
#define _PLAYING(voice) ((voice)->status != XSYNTH_VOICE_OFF)
|
|
#define _ON(voice) ((voice)->status == XSYNTH_VOICE_ON)
|
|
#define _SUSTAINED(voice) ((voice)->status == XSYNTH_VOICE_SUSTAINED)
|
|
#define _RELEASED(voice) ((voice)->status == XSYNTH_VOICE_RELEASED)
|
|
#define _AVAILABLE(voice) ((voice)->status == XSYNTH_VOICE_OFF)
|
|
|
|
extern float nekobee_pitch[128];
|
|
|
|
typedef struct { float value, delta; } float_value_delta;
|
|
extern float_value_delta step_dd_table[];
|
|
|
|
extern float slope_dd_table[];
|
|
|
|
/* nekobee_voice.c */
|
|
nekobee_voice_t *nekobee_voice_new();
|
|
void nekobee_voice_note_on(nekobee_synth_t *synth,
|
|
nekobee_voice_t *voice,
|
|
unsigned char key,
|
|
unsigned char velocity);
|
|
void nekobee_voice_remove_held_key(nekobee_synth_t *synth,
|
|
unsigned char key);
|
|
void nekobee_voice_note_off(nekobee_synth_t *synth,
|
|
nekobee_voice_t *voice,
|
|
unsigned char key,
|
|
unsigned char rvelocity);
|
|
void nekobee_voice_release_note(nekobee_synth_t *synth,
|
|
nekobee_voice_t *voice);
|
|
void nekobee_voice_set_ports(nekobee_synth_t *synth,
|
|
nekobee_patch_t *patch);
|
|
void nekobee_voice_update_pressure_mod(nekobee_synth_t *synth,
|
|
nekobee_voice_t *voice);
|
|
|
|
/* nekobee_voice_render.c */
|
|
void nekobee_init_tables(void);
|
|
void nekobee_voice_render(nekobee_synth_t *synth, nekobee_voice_t *voice,
|
|
float *out, unsigned long sample_count,
|
|
int do_control_update);
|
|
|
|
/* inline functions */
|
|
|
|
/*
|
|
* nekobee_voice_off
|
|
*
|
|
* Purpose: Turns off a voice immediately, meaning that it is not processed
|
|
* anymore by the render loop.
|
|
*/
|
|
static inline void
|
|
nekobee_voice_off(nekobee_voice_t* voice)
|
|
{
|
|
voice->status = XSYNTH_VOICE_OFF;
|
|
/* silence the oscillator buffer for the next use */
|
|
memset(voice->osc_audio, 0, MINBLEP_BUFFER_LENGTH * sizeof(float));
|
|
/* -FIX- decrement active voice count? */
|
|
}
|
|
|
|
/*
|
|
* nekobee_voice_start_voice
|
|
*/
|
|
static inline void
|
|
nekobee_voice_start_voice(nekobee_voice_t *voice)
|
|
{
|
|
voice->status = XSYNTH_VOICE_ON;
|
|
/* -FIX- increment active voice count? */
|
|
}
|
|
|
|
#endif /* _XSYNTH_VOICE_H */
|