fldsp.cpp 4.35 KB
Newer Older
Thomas Grill's avatar
Thomas Grill committed
1 2
/*
flext - C++ layer for Max and Pure Data externals
thomas's avatar
thomas committed
3

4
Copyright (c) 2001-2017 Thomas Grill (gr@grrrr.org)
thomas's avatar
thomas committed
5
For information on usage and redistribution, and for a DISCLAIMER OF ALL
Thomas Grill's avatar
Thomas Grill committed
6
WARRANTIES, see the file, "license.txt," in this distribution.
thomas's avatar
thomas committed
7 8 9 10 11 12
*/

/*! \file fldsp.cpp
    \brief Implementation of the flext dsp base class.
*/
 
Thomas Grill's avatar
Thomas Grill committed
13 14 15
#ifndef __FLEXT_DSP_CPP
#define __FLEXT_DSP_CPP

thomas's avatar
thomas committed
16 17
#include "flext.h"
#include "flinternal.h"
thomas's avatar
thomas committed
18
#include <cstring>
thomas's avatar
thomas committed
19

20 21
#include "flpushns.h"

thomas's avatar
thomas committed
22 23
// === flext_dsp ==============================================

24
FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_dsp))::Setup(t_classid id)
thomas's avatar
thomas committed
25
{
26
#if FLEXT_SYS == FLEXT_SYS_PD
27 28
//    add_method1(c,cb_enable,"enable",A_FLOAT);
    AddMethod(id,0,MakeSymbol("enable"),&cb_enable);
thomas's avatar
thomas committed
29 30 31
#endif
}

32
FLEXT_TEMPIMPL(FLEXT_CLASSDEF(flext_dsp))::FLEXT_CLASSDEF(flext_dsp)()
33
    : srate(sys_getsr()),blksz(sys_getblksize())
martin hermant's avatar
martin hermant committed
34
#if MSP64
35
    , inVec(NULL), outVec(NULL)
martin hermant's avatar
martin hermant committed
36
#else
37
    , vecs(NULL)
martin hermant's avatar
martin hermant committed
38
#endif
thomas's avatar
thomas committed
39
#if FLEXT_SYS != FLEXT_SYS_MAX
40
    , dspon(true)
thomas's avatar
thomas committed
41
#endif
42 43
{}

44
FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_dsp))::Exit()
thomas's avatar
thomas committed
45
{
46
    flext_base::Exit();
47
#if !MSP64
48
    if(vecs) delete[] vecs;
martin hermant's avatar
martin hermant committed
49
#endif
thomas's avatar
thomas committed
50 51
}

52

martin hermant's avatar
martin hermant committed
53 54 55 56 57
#if MSP64
FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_dsp))::dspmeth64(flext_hdr *x, t_object *dsp64, double **ins, long numins, double **outs, long numouts, long sampleframes, long flags, void *userparam)
{
    flext_dsp *obj = (flext_dsp *)userparam;
    
58
    obj->blksz = sampleframes;
martin hermant's avatar
martin hermant committed
59 60 61
    obj->inVec = ins;
    obj->outVec = outs;

62 63 64 65 66 67
    if(!obj->thisHdr()->z_disabled) {
        flext_base::indsp = true;
        obj->CbSignal();
        flext_base::indsp = false;
    }
}
martin hermant's avatar
martin hermant committed
68

69 70 71 72 73 74 75 76 77 78 79 80
FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_dsp))::SetupDsp64(flext_hdr *x, t_object *dsp64, short *count, double samplerate, long maxvectorsize, long flags)
{
    // store current dsp parameters
    srate = samplerate;
    // overlap = sp[0]->s_sr/srate;  // currently not used/exposed
    blksz = maxvectorsize; // will be overwritten in dspmeth64 anyway...

    // with the following call derived classes can do their eventual DSP setup
    if(CbDsp()) {
        // set the DSP function
        dsp_add64(dsp64, (t_object *)&x->obj, (t_dspmethod)dspmeth64, 0, this);
    }
martin hermant's avatar
martin hermant committed
81
}
82

martin hermant's avatar
martin hermant committed
83 84
#else

85
FLEXT_TEMPIMPL(t_int *FLEXT_CLASSDEF(flext_dsp))::dspmeth(t_int *w)
thomas's avatar
thomas committed
86
{ 
87
    flext_dsp *obj = (flext_dsp *)(size_t)w[1];
thomas's avatar
thomas committed
88

thomas's avatar
thomas committed
89
#if FLEXT_SYS == FLEXT_SYS_MAX
thomas's avatar
thomas committed
90
    if(!obj->thisHdr()->z_disabled)
thomas's avatar
thomas committed
91
#else
thomas's avatar
thomas committed
92
    if(LIKELY(obj->dspon))
thomas's avatar
thomas committed
93
#endif
thomas's avatar
thomas committed
94
    {
thomas's avatar
thomas committed
95
        flext_base::indsp = true;
96
        obj->CbSignal(); 
thomas's avatar
thomas committed
97
        flext_base::indsp = false;
thomas's avatar
thomas committed
98
    }
thomas's avatar
thomas committed
99
    return w+2;
thomas's avatar
thomas committed
100 101
}

102
FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_dsp))::SetupDsp(t_signal **sp)
thomas's avatar
thomas committed
103
{ 
thomas's avatar
thomas committed
104
    int i;
105 106
    int in = CntInSig();
    int out = CntOutSig();
thomas's avatar
thomas committed
107 108 109 110
#if FLEXT_SYS == FLEXT_SYS_PD
    // min. 1 input channel! (CLASS_MAININLET in pd...)
    if(!in) in = 1;
#endif
thomas's avatar
thomas committed
111

thomas's avatar
thomas committed
112
    // store current dsp parameters
113
    srate = sys_getsr();
114
    // overlap = sp[0]->s_sr/srate;  // currently not used/exposed
martin hermant's avatar
martin hermant committed
115
    
116
    blksz = sp[0]->s_n;  // is this guaranteed to be the same as sys_getblksize() ?
thomas's avatar
thomas committed
117

thomas's avatar
thomas committed
118
    // store in and out signal vectors
thomas's avatar
thomas committed
119

120 121
    if((in+out) && !vecs)
        vecs = new t_signalvec[in+out];
thomas's avatar
thomas committed
122

123
    for(i = 0; i < in; ++i) 
124
        vecs[i] = sp[i]->s_vec;
thomas's avatar
thomas committed
125
    for(i = 0; i < out; ++i) 
126
        vecs[in+i] = sp[in+i]->s_vec;
thomas's avatar
thomas committed
127

thomas's avatar
thomas committed
128
    // with the following call derived classes can do their eventual DSP setup
129
    if(CbDsp()) {
130
        // set the DSP function
131
        dsp_add((t_dspmethod)dspmeth, 1, this);
132
    }
thomas's avatar
thomas committed
133
}
martin hermant's avatar
martin hermant committed
134 135
#endif

thomas's avatar
thomas committed
136

137
FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_dsp))::m_dsp(int /*n*/,t_signalvec const * /*insigs*/,t_signalvec const * /*outsigs*/) {}
thomas's avatar
thomas committed
138

139
FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_dsp))::CbDsp()
thomas's avatar
 
thomas committed
140
{ 
141 142
	// invoke legacy method
    m_dsp(Blocksize(),InSig(),OutSig()); 
thomas's avatar
 
thomas committed
143 144
    return true;
}
145

martin hermant's avatar
martin hermant committed
146

147
// this function will be overridden anyway - the probably useless default is clearing all outputs
148
FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_dsp))::m_signal(int n,t_sample *const * /*insigs*/,t_sample *const *outs)
thomas's avatar
thomas committed
149
{
thomas's avatar
thomas committed
150
    for(int i = 0; i < CntOutSig(); ++i) ZeroSamples(outs[i],n);
thomas's avatar
thomas committed
151 152
}

153
FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_dsp))::CbSignal()
154 155 156 157
{ 
	// invoke legacy method
	m_signal(Blocksize(),InSig(),OutSig()); 
}
158

thomas's avatar
thomas committed
159
#if FLEXT_SYS == FLEXT_SYS_PD
160
//void flext_dsp::cb_enable(flext_hdr *c,t_float on) { thisObject(c)->dspon = on != 0; }
161 162 163 164 165
FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_dsp))::cb_enable(flext_base *b,float &on)
{
    static_cast<flext_dsp *>(b)->dspon = on != 0;
    return true;
}
thomas's avatar
thomas committed
166
#endif
167 168 169

#include "flpopns.h"

Thomas Grill's avatar
Thomas Grill committed
170 171 172
#endif // __FLEXT_DSP_CPP