149 lines
4.1 KiB
C++
149 lines
4.1 KiB
C++
/*
|
|
Copyright (C) 2003-2008 Fons Adriaensen <fons@kokkinizita.net>
|
|
|
|
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
|
|
|
|
#ifndef __RANKWAVE_H
|
|
#define __RANKWAVE_H
|
|
|
|
|
|
#include "addsynth.h"
|
|
#include "rngen.h"
|
|
|
|
|
|
#define PERIOD 64
|
|
|
|
|
|
class Pipewave
|
|
{
|
|
private:
|
|
|
|
Pipewave () :
|
|
_p0 (0), _p1 (0), _p2 (0), _l1 (0), _k_s (0), _k_r (0), _m_r (0),
|
|
_link (0), _sbit (0), _sdel (0),
|
|
_p_p (0), _y_p (0), _z_p (0), _p_r (0), _y_r (0), _g_r (0), _i_r (0)
|
|
{}
|
|
|
|
~Pipewave (void) { delete[] _p0; }
|
|
|
|
friend class Rankwave;
|
|
|
|
void genwave (Addsynth *D, int n, float fsamp, float fpipe);
|
|
void save (FILE *F);
|
|
void load (FILE *F);
|
|
void play (void);
|
|
|
|
static void looplen (float f, float fsamp, int lmax, int *aa, int *bb);
|
|
static void attgain (int n, float p);
|
|
|
|
float *_p0; // attack start
|
|
float *_p1; // loop start
|
|
float *_p2; // loop end
|
|
int32_t _l0; // attack length
|
|
int32_t _l1; // loop length
|
|
int16_t _k_s; // sample step
|
|
int16_t _k_r; // release lenght
|
|
float _m_r; // release multiplier
|
|
float _d_r; // release detune
|
|
float _d_p; // instability
|
|
|
|
Pipewave *_link; // link to next in active chain
|
|
uint32_t _sbit; // on state bit
|
|
uint32_t _sdel; // delayed state
|
|
float *_out; // audio output buffer
|
|
float *_p_p; // play pointer
|
|
float _y_p; // play interpolation
|
|
float _z_p; // play interpolation speed
|
|
float *_p_r; // release pointer
|
|
float _y_r; // release interpolation
|
|
float _g_r; // release gain
|
|
int16_t _i_r; // release count
|
|
|
|
|
|
static void initstatic (float fsamp);
|
|
|
|
static Rngen _rgen;
|
|
static float *_arg;
|
|
static float *_att;
|
|
};
|
|
|
|
//---------------------------------------------------------
|
|
// Rankwave
|
|
//---------------------------------------------------------
|
|
|
|
class Rankwave
|
|
{
|
|
Rankwave (const Rankwave&);
|
|
Rankwave& operator=(const Rankwave&);
|
|
|
|
int _n0;
|
|
int _n1;
|
|
uint32_t _sbit;
|
|
Pipewave *_list;
|
|
Pipewave *_pipes;
|
|
bool _modif;
|
|
|
|
public:
|
|
|
|
Rankwave (int n0, int n1);
|
|
~Rankwave ();
|
|
|
|
void note_on (int n) {
|
|
if ((n < _n0) || (n > _n1)) {
|
|
qDebug("Rankwave: bad key");
|
|
return;
|
|
}
|
|
Pipewave *P = _pipes + (n - _n0);
|
|
P->_sbit = _sbit;
|
|
if (! (P->_sdel || P->_p_p || P->_p_r)) {
|
|
P->_sdel |= _sbit;
|
|
P->_link = _list;
|
|
_list = P;
|
|
}
|
|
}
|
|
|
|
void note_off (int n)
|
|
{
|
|
if ((n < _n0) || (n > _n1)) return;
|
|
Pipewave *P = _pipes + (n - _n0);
|
|
P->_sdel >>= 4;
|
|
P->_sbit = 0;
|
|
}
|
|
|
|
void all_off (void)
|
|
{
|
|
Pipewave *P;
|
|
for (P = _list; P; P = P->_link) P->_sbit = 0;
|
|
}
|
|
|
|
int n0 (void) const { return _n0; }
|
|
int n1 (void) const { return _n1; }
|
|
void play (int shift);
|
|
void set_param (float *out, int del, int pan);
|
|
void gen_waves (Addsynth *D, float fsamp, float fbase, float *scale);
|
|
int save (const char *path, Addsynth *D, float fsamp, float fbase, float *scale);
|
|
int load (const char *path, Addsynth *D, float fsamp, float fbase, float *scale);
|
|
bool modif (void) const { return _modif; }
|
|
|
|
int _cmask; // used by division logic
|
|
int _nmask; // used by division logic
|
|
|
|
};
|
|
|
|
|
|
#endif
|
|
|