Wave Table Synthesizer(Occilator only). I will make Envelope Generator and MML for play music.

Dependencies:   mbed

Project: Synthesizer. It is using embed to Chip Tune Synthesizer for NXP LPC1768.

At First

Prepare an amplifier with volume wheel. The amplifier wire at pin1 to pin18(D/A converter) from IC Clip or Breedboard.

Play

Check out this project and deploy your mbed. And then push the reset key.

You hear a sound from amplifier.

Modify

First step, you can see main.cpp. This source file plays an occilator with "wait()". Modify frequency at

#define ADD 0x2000000

on the top of source.

Occilator select 7 waveforms.

  • OCC_NONE,
  • OCC_SQUARE,
  • OCC_SINE,
  • OCC_SAW,
  • OCC_WT,
  • OCC_NOISE,
  • OCC_TRIANGLE,

WT means WaveTable Synthesizer.Use "setWave()" function at first.Wavetable will copy in instance.

Change there for waveform.

    gOccilator[0]=Occilator::getInstance(OCC_SAW,INTERRUPT_TIME_US);

INTERRUPT_TIME_US depends sampling rate. Don't change.

Total volume of D/A converter is setting this place.

        gOccilator[0]->setVolume(volume);

By the way, this sample output 0 to 1V(not3.3V) for deforming distortion.

ToDo

  • Envelope generator and LFO(with delay)
  • MML(Music Macro Language)
  • Sample Song(I will make a Japanese Anime music,perhaps)

Project Goal Date

I will make for Comic Market 90(2016.Aug. in Tokyo).And these thing will be written in a Doujinshi.

Committer:
117Florian
Date:
Tue Feb 09 05:39:46 2016 +0000
Revision:
8:dd2da7c0c4c7
Parent:
7:a478d5cc411e
Child:
9:d2a5406650ae
Noise,Saw,Sine????WT????????????Sine????????????

Who changed what in which revision?

UserRevisionLine numberNew contents of line
117Florian 3:32094530d55e 1 #include "mbed.h"
117Florian 3:32094530d55e 2 #include "global.h"
117Florian 3:32094530d55e 3 #include "Occilator.h"
117Florian 4:2febde858269 4 #include "Square.h"
117Florian 7:a478d5cc411e 5 #include "WT.h"
117Florian 8:dd2da7c0c4c7 6 #include "Sine.h"
117Florian 8:dd2da7c0c4c7 7 #include "Noise.h"
117Florian 8:dd2da7c0c4c7 8 #include "Saw.h"
117Florian 3:32094530d55e 9
117Florian 3:32094530d55e 10 static long interrupt_us;
117Florian 3:32094530d55e 11 static int part_num=0;
117Florian 3:32094530d55e 12 static Occilator* part[OCCILATOR_PART_NUM];
117Florian 3:32094530d55e 13 static Ticker sTicker;
117Florian 3:32094530d55e 14 static long total_value_in_this_span;
117Florian 3:32094530d55e 15 static AnalogOut sAnalogOut(p18);
117Florian 5:3a753cf68fac 16 static long sMasterVolume=(1/3.3)*0x10000;
117Florian 3:32094530d55e 17
117Florian 3:32094530d55e 18 /* interrupt handler */
117Florian 3:32094530d55e 19 /*static void tick(uint32_t id);*/
117Florian 3:32094530d55e 20 static void tick();
117Florian 3:32094530d55e 21
117Florian 4:2febde858269 22 Occilator* Occilator::getInstance(Occilator_Type type,long interrupt_us)
117Florian 4:2febde858269 23 {
117Florian 4:2febde858269 24 switch(type)
117Florian 4:2febde858269 25 {
117Florian 4:2febde858269 26 case OCC_NONE:
117Florian 4:2febde858269 27 case OCC_SQUARE:
117Florian 4:2febde858269 28 return new Square(interrupt_us);
117Florian 8:dd2da7c0c4c7 29
117Florian 8:dd2da7c0c4c7 30 case OCC_NOISE:
117Florian 8:dd2da7c0c4c7 31 return new Noise(interrupt_us);
117Florian 4:2febde858269 32
117Florian 4:2febde858269 33 case OCC_SINE:
117Florian 8:dd2da7c0c4c7 34 return new Sine(interrupt_us);
117Florian 8:dd2da7c0c4c7 35
117Florian 8:dd2da7c0c4c7 36 case OCC_SAW:
117Florian 8:dd2da7c0c4c7 37 return new Saw(interrupt_us);
117Florian 4:2febde858269 38 case OCC_WT:
117Florian 5:3a753cf68fac 39 default:
117Florian 7:a478d5cc411e 40 return new WT(interrupt_us);
117Florian 8:dd2da7c0c4c7 41
117Florian 4:2febde858269 42 }
117Florian 4:2febde858269 43 }
117Florian 4:2febde858269 44
117Florian 5:3a753cf68fac 45 void Occilator::setMasterVolume(long volume)
117Florian 5:3a753cf68fac 46 {
117Florian 5:3a753cf68fac 47 sMasterVolume=volume;
117Florian 5:3a753cf68fac 48 }
117Florian 5:3a753cf68fac 49
117Florian 3:32094530d55e 50 Occilator::Occilator(long interrupt_us)
117Florian 3:32094530d55e 51 {
117Florian 3:32094530d55e 52 myled1=1;
117Florian 3:32094530d55e 53 ::interrupt_us=interrupt_us;
117Florian 3:32094530d55e 54 if(part_num==0)
117Florian 3:32094530d55e 55 {
117Florian 3:32094530d55e 56 sTicker.attach_us(::tick,interrupt_us);
117Florian 3:32094530d55e 57 }
117Florian 3:32094530d55e 58 part_num++;
117Florian 3:32094530d55e 59 for(int i=0;i<OCCILATOR_PART_NUM;i++)
117Florian 3:32094530d55e 60 {
117Florian 3:32094530d55e 61 if(part[i]==NULL)
117Florian 3:32094530d55e 62 {
117Florian 3:32094530d55e 63 part[i]=this;
117Florian 3:32094530d55e 64 break;
117Florian 3:32094530d55e 65 }
117Florian 3:32094530d55e 66 }
117Florian 3:32094530d55e 67
117Florian 3:32094530d55e 68 m_Volume=0x10000;
117Florian 3:32094530d55e 69 }
117Florian 3:32094530d55e 70
117Florian 3:32094530d55e 71 Occilator::~Occilator()
117Florian 3:32094530d55e 72 {
117Florian 3:32094530d55e 73 part_num--;
117Florian 3:32094530d55e 74 for(int i=0;i<OCCILATOR_PART_NUM;i++)
117Florian 3:32094530d55e 75 {
117Florian 3:32094530d55e 76 if(part[i]==this)
117Florian 3:32094530d55e 77 {
117Florian 3:32094530d55e 78 part[i]=NULL;
117Florian 3:32094530d55e 79 break;
117Florian 3:32094530d55e 80 }
117Florian 3:32094530d55e 81 }
117Florian 3:32094530d55e 82 if(part_num<=0)
117Florian 3:32094530d55e 83 {
117Florian 3:32094530d55e 84 sTicker.detach();
117Florian 3:32094530d55e 85 }
117Florian 3:32094530d55e 86 }
117Florian 3:32094530d55e 87
117Florian 3:32094530d55e 88 void Occilator::setOmega(long speed)
117Florian 3:32094530d55e 89 {
117Florian 3:32094530d55e 90 m_Omega=speed;
117Florian 3:32094530d55e 91 myled2=1;
117Florian 3:32094530d55e 92 }
117Florian 3:32094530d55e 93
117Florian 3:32094530d55e 94 void Occilator::setVolume(int volume)
117Florian 3:32094530d55e 95 {
117Florian 3:32094530d55e 96 m_Volume=volume;
117Florian 3:32094530d55e 97 }
117Florian 3:32094530d55e 98
117Florian 3:32094530d55e 99 unsigned long Occilator::tick()
117Florian 3:32094530d55e 100 {
117Florian 3:32094530d55e 101 m_Angle+=m_Omega;
117Florian 5:3a753cf68fac 102 return 0L;
117Florian 3:32094530d55e 103 }
117Florian 3:32094530d55e 104
117Florian 3:32094530d55e 105 void ::tick()
117Florian 3:32094530d55e 106 {
117Florian 3:32094530d55e 107 long long value=0;
117Florian 3:32094530d55e 108
117Florian 3:32094530d55e 109 for (int i=0;i<OCCILATOR_PART_NUM;i++)
117Florian 3:32094530d55e 110 {
117Florian 3:32094530d55e 111 if (part[i]!=NULL)
117Florian 3:32094530d55e 112 {
117Florian 3:32094530d55e 113 value+=total_value_in_this_span + part[i]->tick();
117Florian 3:32094530d55e 114 }
117Florian 3:32094530d55e 115 }
117Florian 3:32094530d55e 116 value = value>=0x10000 ? 0xffff : value;
117Florian 5:3a753cf68fac 117 value = (sMasterVolume*value)>>16;
117Florian 3:32094530d55e 118 sAnalogOut.write_u16(value);
117Florian 3:32094530d55e 119 myled4=value > 0x80000000;
117Florian 3:32094530d55e 120 }