~ubuntu-branches/ubuntu/quantal/muse/quantal

« back to all changes in this revision

Viewing changes to synti/vam/vam.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Kobras
  • Date: 2005-08-23 17:19:39 UTC
  • mto: (4.1.1 breezy) (1.1.9) (10.1.6 sid)
  • mto: This revision was merged to the branch mainline in revision 5.
  • Revision ID: james.westby@ubuntu.com-20050823171939-hd8fgzokb4dbj007
Tags: upstream-0.7.1+0.7.2pre2
Import upstream version 0.7.1+0.7.2pre2

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
// 02111-1307, USA or point your web browser to http://www.gnu.org.
26
26
//=========================================================
27
27
 
28
 
#include <math.h>
 
28
#include <assert.h>
 
29
#include <cmath>
29
30
#include <stdio.h>
30
 
#include <sys/time.h>
31
 
#include "mess.h"
32
 
#include "ladspa.h"
33
 
#include "midictrl.h"
 
31
#include <list>
 
32
 
 
33
#include "libsynti/mess.h"
 
34
#include "muse/midi.h"
 
35
#include "muse/midictrl.h"
34
36
 
35
37
#include "vam.h"
 
38
#include "vamgui.h"
 
39
#include "libsynti/mono.h"
36
40
 
37
41
// Denormalise floats, only actually needed for PIII and very recent PowerPC
38
42
#define DENORMALISE(fv) (((*(unsigned int*)&(fv))&0x7f800000)==0)?0.0f:(fv)
159
163
        int pitch, channel;
160
164
        float velocity;
161
165
 
 
166
      int idata[NUM_CONTROLLER];  // buffer for init data
 
167
 
162
168
        EnvelopeGenerator dco1_env;
163
169
        EnvelopeGenerator dco2_env;
164
170
        EnvelopeGenerator filt_env;
176
182
 
177
183
        int controller[NUM_CONTROLLER];
178
184
 
179
 
        void write(int, float**, int);
180
 
        void noteon(int channel, int pitch, int velo);
181
185
        void noteoff(int channel, int pitch);
182
 
        void setController(int channel, int ctrl, int val);
183
 
        void sysex(const unsigned char* data, int len);
184
 
        void parameterRequest(int pn);
 
186
 
 
187
        virtual void process(float**, int, int);
 
188
        virtual void note(int channel, int pitch, int velo);
 
189
        virtual bool setController(int channel, int ctrl, int val);
 
190
        virtual bool sysex(int, const unsigned char*);
 
191
      void getInitData(int* n, const unsigned char**p);
 
192
 
 
193
      void setController(int ctrl, int data);
185
194
 
186
195
        float *wave_tbl(int wave);
187
196
        double lowpass_filter(double cutoff, double resonance, double input, LPFilter *f);
188
197
 
 
198
      virtual bool guiVisible() const;
 
199
      virtual void showGui(bool);
 
200
      virtual bool hasGui() const { return true; }
 
201
      virtual void getGeometry(int* x, int* y, int* w, int* h) const;
 
202
      virtual void setGeometry(int x, int y, int w, int h);
 
203
 
 
204
      VAMGui* gui;
 
205
 
189
206
    public:
190
 
        VAM(const char* classname);
 
207
        VAM(int sr);
191
208
        ~VAM();
192
 
        bool init();
193
 
        virtual int getMidiInitEvent(int id, RawMidiEvent *);
194
 
};
 
209
        bool init(const char* name);
 
210
      };
195
211
 
196
212
float* VAM::sin_tbl;
197
213
float* VAM::tri_tbl;
203
219
 
204
220
 
205
221
//---------------------------------------------------------
206
 
//   Organ
 
222
//   VAM
207
223
//---------------------------------------------------------
208
224
 
209
 
VAM::VAM(const char* cn)
210
 
   : MessMono(cn, 1)
211
 
{
212
 
        if(useCount == 0) {
213
 
                int i;
214
 
                float tmp;
215
 
                for(i = 0; i < CB_AMP_SIZE; i++) {
216
 
                        cb2amp_tab[i] = pow(10.0, double(i) / -300.0);
217
 
//                      cb2amp_tab[i] = 1.0 - i/(float)CB_AMP_SIZE;
218
 
                }
219
 
                for(i = 0; i < LIN2EXP_SIZE; i++) {
220
 
                        tmp = i/255.0;
221
 
                        lin2exp[i] = 1.5 * tmp * tmp * tmp - 0.69 * tmp * tmp + 0.16 * tmp;
222
 
                }
223
 
                int sr = sampleRate();
224
 
                /* Build up denormalised oscilator wavetables, these are sample_rate
225
 
                   long, costs more RAM to create them but makes freqency calcs much
226
 
                   cheaper, and means that interpolation isn't that neccesary, esp if
227
 
                   you use integer frequncies */
228
 
 
229
 
                float *tmp_tbl = new float[sr];
230
 
                const int lag = sr/50;
231
 
                sin_tbl = new float[sr];
232
 
                for (i = 0; i < sr; i++) {
233
 
                        tmp = sin(i * 2.0 * PI / sr);
234
 
                        sin_tbl[i] = DENORMALISE(tmp);
235
 
                }
236
 
                tri_tbl = new float[sr];
237
 
                for (i = 0; i < sr; i++) {
238
 
                        tmp = acos(cos(i * 2.0 * PI / sr)) / PI * 2.0 - 1.0;
239
 
                        tri_tbl[i] = DENORMALISE(tmp);
240
 
                }
241
 
                squ_tbl = new float[sr];
242
 
                for (i = 0; i < sr/2; i++) {
243
 
                        tmp_tbl[i] = -1.0f;
244
 
                }
245
 
                for (i = sr/2; i < sr; i++) {
246
 
                        tmp_tbl[i] = +1.0f;
247
 
                }
248
 
                tmp = -1.0f;
249
 
                for (i = (sr/2)-lag; i < (sr/2)+lag; i++) {
250
 
                        tmp_tbl[i] = tmp;
251
 
                        tmp += 1.0/(lag * 2.0);
252
 
                }
253
 
                for (i = 0; i < sr; i++) {
254
 
                        squ_tbl[i] = (tmp_tbl[MOD(i-lag, sr)] +
255
 
                        tmp_tbl[MOD(i+lag, sr)]) * 0.5;
256
 
                }
257
 
                saw_tbl = new float[sr];
258
 
                for (i = 0; i < sr; i++) {
259
 
                        tmp = ((2.0 * i) - (float)sr) / (float)sr;
260
 
                        tmp_tbl[i] = DENORMALISE(tmp);
261
 
                }
262
 
                for (i = 0; i < sr; i++) {
263
 
                        saw_tbl[i] = (tmp_tbl[MOD(i-lag, sr)] +
264
 
                        tmp_tbl[MOD(i+lag, sr)]) * 0.5;
265
 
                }
266
 
                delete[] tmp_tbl;
267
 
 
268
 
        }
269
 
        dco1_filter.out[0] = dco1_filter.out[1] = dco1_filter.out[2] = dco1_filter.out[3] = 0.0;
270
 
        dco1_filter.in[0] = dco1_filter.in[1] = dco1_filter.in[2] = dco1_filter.in[3] = 0.0;
271
 
        dco2_filter.out[0] = dco2_filter.out[1] = dco2_filter.out[2] = dco2_filter.out[3] = 0.0;
272
 
        dco2_filter.in[0] = dco2_filter.in[1] = dco2_filter.in[2] = dco2_filter.in[3] = 0.0;
273
 
 
274
 
        ++useCount;
275
 
        dco1.phase = 0.0;
276
 
        dco2.phase = 0.0;
277
 
        lfo.phase = 0.0;
278
 
        ctrlHi = 0;
279
 
        ctrlLo = 0;
280
 
        dataHi = 0;
281
 
        dataLo = 0;
282
 
}
 
225
VAM::VAM(int sr)
 
226
   : MessMono()
 
227
      {
 
228
      setSampleRate(sr);
 
229
      gui = 0;
 
230
      }
283
231
 
284
232
//---------------------------------------------------------
285
233
//   ~VAM
286
234
//---------------------------------------------------------
287
235
 
288
236
VAM::~VAM()
289
 
{
 
237
      {
290
238
        --useCount;
291
 
        if(useCount == 0) {
 
239
        if (useCount == 0) {
292
240
                delete[] sin_tbl;
293
241
                delete[] tri_tbl;
294
242
                delete[] saw_tbl;
295
243
                delete[] squ_tbl;
296
 
        }
297
 
}
 
244
              }
 
245
      }
298
246
 
299
247
//---------------------------------------------------------
300
248
//   curTime
355
303
//   init
356
304
//---------------------------------------------------------
357
305
 
358
 
bool VAM::init()
359
 
{
 
306
bool VAM::init(const char* name)
 
307
      {
 
308
      gui = new VAMGui;
 
309
      gui->setCaption(QString(name));
 
310
      gui->show();
 
311
 
 
312
        if (useCount == 0) {
 
313
                int i;
 
314
                float tmp;
 
315
                for(i = 0; i < CB_AMP_SIZE; i++) {
 
316
                        cb2amp_tab[i] = pow(10.0, double(i) / -300.0);
 
317
//                      cb2amp_tab[i] = 1.0 - i/(float)CB_AMP_SIZE;
 
318
                      }
 
319
                for(i = 0; i < LIN2EXP_SIZE; i++) {
 
320
                        tmp = i/255.0;
 
321
                        lin2exp[i] = 1.5 * tmp * tmp * tmp - 0.69 * tmp * tmp + 0.16 * tmp;
 
322
                      }
 
323
                int sr = sampleRate();
 
324
                /* Build up denormalised oscilator wavetables, these are sample_rate
 
325
                   long, costs more RAM to create them but makes freqency calcs much
 
326
                   cheaper, and means that interpolation isn't that neccesary, esp if
 
327
                   you use integer frequncies */
 
328
 
 
329
                float *tmp_tbl = new float[sr];
 
330
                const int lag = sr/50;
 
331
                sin_tbl = new float[sr];
 
332
                for (i = 0; i < sr; i++) {
 
333
                  tmp = sin(i * 2.0 * PI / sr);
 
334
                        sin_tbl[i] = DENORMALISE(tmp);
 
335
                  }
 
336
                tri_tbl = new float[sr];
 
337
                for (i = 0; i < sr; i++) {
 
338
                        tmp = acos(cos(i * 2.0 * PI / sr)) / PI * 2.0 - 1.0;
 
339
                        tri_tbl[i] = DENORMALISE(tmp);
 
340
                  }
 
341
                squ_tbl = new float[sr];
 
342
                for (i = 0; i < sr/2; i++) {
 
343
                        tmp_tbl[i] = -1.0f;
 
344
                }
 
345
                for (i = sr/2; i < sr; i++) {
 
346
                        tmp_tbl[i] = +1.0f;
 
347
                }
 
348
                tmp = -1.0f;
 
349
                for (i = (sr/2)-lag; i < (sr/2)+lag; i++) {
 
350
                        tmp_tbl[i] = tmp;
 
351
                        tmp += 1.0/(lag * 2.0);
 
352
                }
 
353
                for (i = 0; i < sr; i++) {
 
354
                        squ_tbl[i] = (tmp_tbl[MOD(i-lag, sr)] +
 
355
                        tmp_tbl[MOD(i+lag, sr)]) * 0.5;
 
356
                }
 
357
                saw_tbl = new float[sr];
 
358
                for (i = 0; i < sr; i++) {
 
359
                        tmp = ((2.0 * i) - (float)sr) / (float)sr;
 
360
                        tmp_tbl[i] = DENORMALISE(tmp);
 
361
                }
 
362
                for (i = 0; i < sr; i++) {
 
363
                        saw_tbl[i] = (tmp_tbl[MOD(i-lag, sr)] +
 
364
                        tmp_tbl[MOD(i+lag, sr)]) * 0.5;
 
365
                      }
 
366
                delete[] tmp_tbl;
 
367
              }
 
368
 
 
369
        dco1_filter.out[0] = dco1_filter.out[1] = dco1_filter.out[2] = dco1_filter.out[3] = 0.0;
 
370
        dco1_filter.in[0]  = dco1_filter.in[1] = dco1_filter.in[2] = dco1_filter.in[3] = 0.0;
 
371
        dco2_filter.out[0] = dco2_filter.out[1] = dco2_filter.out[2] = dco2_filter.out[3] = 0.0;
 
372
        dco2_filter.in[0]  = dco2_filter.in[1] = dco2_filter.in[2] = dco2_filter.in[3] = 0.0;
 
373
 
 
374
        ++useCount;
 
375
        dco1.phase = 0.0;
 
376
        dco2.phase = 0.0;
 
377
        lfo.phase = 0.0;
 
378
 
360
379
        memset(controller, 0, sizeof(controller));
361
380
 
362
381
        int maxval = 128*128-1;
394
413
        setController(0, DCO1_PW, 0);
395
414
        setController(0, DCO2_PW, 0);
396
415
 
397
 
        
398
416
        isOn = false;
399
417
        return false;
400
 
}
 
418
      }
401
419
 
402
420
//---------------------------------------------------------
403
421
//   write
404
422
//---------------------------------------------------------
405
423
 
406
 
void VAM::write(int sampleCount, float** ports, int offset)
 
424
void VAM::process(float** ports, int offset, int sampleCount)
407
425
{
 
426
      //
 
427
      //  get and process all pending events from the
 
428
      //  synthesizer GUI
 
429
      //
 
430
      while (gui->fifoSize()) {
 
431
            MidiPlayEvent ev = gui->readEvent();
 
432
            if (ev.type() == ME_CONTROLLER) {
 
433
                  // process local?
 
434
                  setController(ev.dataA() & 0xfff, ev.dataB());
 
435
                  sendEvent(ev);
 
436
                  }
 
437
            else
 
438
                  printf("Organ::process(): unknown event\n");
 
439
            }
408
440
      float* buffer = *ports + offset;
409
441
        if (!isOn)
410
442
            return;
477
509
}
478
510
 
479
511
//---------------------------------------------------------
480
 
//   noteon
 
512
//   note
481
513
//---------------------------------------------------------
482
514
 
483
 
void VAM::noteon(int chan, int newpitch, int velo)
 
515
void VAM::note(int chan, int newpitch, int velo)
484
516
{
485
517
        if (velo == 0) {
486
518
                noteoff(chan, newpitch);
526
558
//   setController
527
559
//---------------------------------------------------------
528
560
 
529
 
void VAM::setController(int /*channel*/, int ctrl, int data)
 
561
bool VAM::setController(int /*channel*/, int ctrl, int data)
530
562
{
 
563
      setController(ctrl & 0xfff, data);
 
564
      MidiPlayEvent ev(0, 0, channel, ME_CONTROLLER, ctrl, data);
 
565
      gui->writeEvent(ev);
 
566
      return false;
 
567
      }
 
568
 
 
569
void VAM::setController(int ctrl, int data)
 
570
      {
531
571
//      fprintf(stderr, "ctrl: %d data: %d\n", ctrl, data);
532
572
        int maxval = 128*128-1;
533
573
        double normval = double(data) / double(maxval);
534
 
        switch(ctrl) {
 
574
        switch (ctrl) {
535
575
                case DCO1_PITCHMOD:
536
576
                        dco1.pitchmod = (data  - 8191) / 341.333;
537
577
                        break;
638
678
                        if(dco2.pw == 1.0) dco2.pw = 0.99;
639
679
                        break;
640
680
                default:
641
 
                        printf("VAM: set unknown Ctrl %d to %d\n", ctrl, data);
 
681
                        printf("VAM: set unknown Ctrl 0x%x to 0x%x\n", ctrl, data);
642
682
                        break;
643
683
        }
644
684
        controller[ctrl] = data;
648
688
//   parameterRequest
649
689
//---------------------------------------------------------
650
690
 
 
691
#if 0
651
692
void VAM::parameterRequest(int ctrl)
652
693
{
653
694
        if(ctrl >= NUM_CONTROLLER) {
658
699
        data[3] = ctrl;
659
700
        data[4] = controller[ctrl] & 0x7f;
660
701
        data[5] = (controller[ctrl] >> 7) & 0x7f;
661
 
        sendSysex(data, sizeof(data));
 
702
      sendSysex(data, sizeof(data));
662
703
}
 
704
#endif
 
705
 
 
706
//---------------------------------------------------------
 
707
//   getInitData
 
708
//---------------------------------------------------------
 
709
 
 
710
void VAM::getInitData(int* n, const unsigned char**p)
 
711
      {
 
712
      int* d = idata;
 
713
      for (int i = 0; i < NUM_CONTROLLER; ++i) {
 
714
            int val = controller[i];
 
715
            *d++ = val;
 
716
            }
 
717
      *n = NUM_CONTROLLER * sizeof(int); // sizeof(idata);
 
718
      *p = (unsigned char*)idata;
 
719
      }
663
720
 
664
721
//---------------------------------------------------------
665
722
//   sysex
666
723
//---------------------------------------------------------
667
724
 
668
 
void VAM::sysex(const unsigned char* data, int len)
669
 
{
670
 
        if (len >= 6 && data[0] == 0xf0 && data[len-1] == 0xf7) {
671
 
                //---------------------------------------------
672
 
                //  MusE Soft Synth
673
 
                //---------------------------------------------
674
 
 
675
 
                if (data[1] == 0x7c) {
676
 
                        int n = len - 5;
677
 
                        if (n < 1) {
678
 
                                printf("vam: bad sysEx:\n");
679
 
                                return;
680
 
                        }
681
 
                        if (data[2] == 2) {     // vam voice
682
 
                                if (data[3] == 1) {  // get parameter
683
 
                                        parameterRequest(data[4]);
684
 
                                        return;
685
 
                                }
686
 
                        }
687
 
                }
688
 
        }
689
 
        printf("vam: unknown sysex received, len %d:\n", len);
690
 
        for (int i = 0; i < len; ++i)
691
 
                printf("%02x ", data[i]);
692
 
 
693
 
        printf("\n");
694
 
}
695
 
 
696
 
int VAM::getMidiInitEvent(int id, RawMidiEvent *ev)
697
 
{
698
 
        if(id >= NUM_CONTROLLER)
699
 
                return 0;
700
 
        ev->setType(SND_SEQ_EVENT_NONREGPARAM);
701
 
        ev->setChan(0);
702
 
        ev->setDataA(id);
703
 
        ev->setDataB(controller[id]);
704
 
        return ++id;
705
 
}
 
725
bool VAM::sysex(int n, const unsigned char* data)
 
726
      {
 
727
      if (n != (NUM_CONTROLLER * sizeof(int))) {
 
728
            printf("Organ: unknown sysex\n");
 
729
            return false;
 
730
            }
 
731
      int* s = (int*) data;
 
732
      for (int i = 0; i < NUM_CONTROLLER; ++i) {
 
733
            int val = *s++;
 
734
            setController(0, i, val);
 
735
            }
 
736
      return false;
 
737
      }
 
738
 
 
739
//---------------------------------------------------------
 
740
//   guiVisible
 
741
//---------------------------------------------------------
 
742
 
 
743
bool VAM::guiVisible() const
 
744
      {
 
745
      return gui->isVisible();
 
746
      }
 
747
 
 
748
//---------------------------------------------------------
 
749
//   showGui
 
750
//---------------------------------------------------------
 
751
 
 
752
void VAM::showGui(bool val)
 
753
      {
 
754
      gui->setShown(val);
 
755
      }
 
756
 
 
757
//---------------------------------------------------------
 
758
//   getGeometry
 
759
//---------------------------------------------------------
 
760
 
 
761
void VAM::getGeometry(int* x, int* y, int* w, int* h) const
 
762
      {
 
763
      QPoint pos(gui->pos());
 
764
      QSize size(gui->size());
 
765
      *x = pos.x();
 
766
      *y = pos.y();
 
767
      *w = size.width();
 
768
      *h = size.height();
 
769
      }
 
770
 
 
771
//---------------------------------------------------------
 
772
//   setGeometry
 
773
//---------------------------------------------------------
 
774
 
 
775
void VAM::setGeometry(int x, int y, int w, int h)
 
776
      {
 
777
      gui->resize(QSize(w, h));
 
778
      gui->move(QPoint(x, y));
 
779
      }
706
780
 
707
781
//---------------------------------------------------------
708
782
//   inst
709
783
//---------------------------------------------------------
710
784
 
711
 
static Mess* inst(const char* name)
712
 
      {
713
 
      return new VAM(name);
714
 
      }
715
 
 
716
 
//---------------------------------------------------------
717
 
//   initMess
718
 
//---------------------------------------------------------
719
 
 
720
 
void initMess()
721
 
      {
722
 
      Mess::initMess(
723
 
          1224,
724
 
         "vam",
725
 
         "Werner Schweer, Josef Lindman H�rnlund",
726
 
         "vam soft synth",
727
 
         "None",
728
 
         1,
729
 
         inst);
730
 
      }
 
785
class QWidget;
 
786
 
 
787
static Mess* instantiate(int sr, QWidget*, const char* name)
 
788
      {
 
789
      VAM* vam = new VAM(sr);
 
790
      if (vam->init(name)) {
 
791
            delete vam;
 
792
            return 0;
 
793
            }
 
794
      return vam;
 
795
      }
 
796
 
 
797
extern "C" {
 
798
      static MESS descriptor = {
 
799
            "vam",
 
800
            "vam soft synth",
 
801
            "0.1",      // version string
 
802
            MESS_MAJOR_VERSION, MESS_MINOR_VERSION,
 
803
            instantiate,
 
804
            };
 
805
 
 
806
      const MESS* mess_descriptor() { return &descriptor; }
 
807
      }
 
808