;@ map OSCsem OSCprt
;@ map OSCcnt OSCshp

;@ ins k k a a a
;@ outs a
opcode OscB, 0, kkkkkkkkkkkkkkkkk
; kModLev - 0...1
; kMod - blue - -64..+64
; FREQ SEMI FAC - ALL THE SAME!
; PART MODE = 3
kCoarse,kFine,kKBT,kModLev,kTuneMode,kFM,kShape,kShapeM,kWave,kON,kFMPTrk,kPitchIn,kModIn,kSyncIn,kFMIn,kShapeIn,kOut xin
kMod zkr kModIn
aFM zar kFMIn
async zar kSyncIn
aPWIn zar kShapeIn

; FM Ind Calc
kFM *= 100 ; NEEDS CHANGING CLA000 to CLA-REAL..
kIndx = 0.000039*kFM*kFM*kFM - 0.00049*kFM*kFM + 0.016*kFM - 0.033
kIndx limit kIndx, 0, 80
; Out FM Calc

if kKBT != 1 goto NoKBT
  kNote = gkNote
  goto KBT
NoKBT:
  kNote = 64
KBT:

; FMLin vs FMTrk
if kFMPTrk != 1 goto FMLin
  kFMNote = kNote
  goto FMTrk
FMLin:
  kFMNote = 64
FMTrk:

kPitch init 64
if kPitchIn == 0 goto Run
kPitch zkr kPitchIn
Run:
if kTuneMode!=3 then
  kCoarse table kcoarse, giOSCsem
  kFine table kFine, giOSCcnt
  kM_ = kPitch+kModLev*kMod+kNote+kFine*0.01
  kFreq = cpsmidinn(kM_+kCoarse)
else
    if kcoarse <= 32 then
      kFreq table kcoarse, giOSCprt
      kFine table kFine, giOSCcnt
      kFreq *= cent(kFine)
    else
      kPart table kcoarse, giOSCprt
      kFine table kFine, giOSCcnt
      kM_ = kPitch+kModLev*kMod+kNote+kFine*0.01
      kFreq = cpsmidinn(kM_)*kPart
      ;kFreq = 1000
    endif
endif
Out:

kShape = (kShape-50)*.01
if kWave >= 3 kgoto WaveMod
; All simple waves - Sine,Tri, Saw
  aout oscilikts 1, kFreq + aFM*kIndx*cpsmidinn(kFMNote), kWave+1, async, 0
kgoto WOut

WaveMod:
  aphase, asyncout syncphasor kFreq + aFM*kIndx*cpsmidinn(kFMNote), async
  aphaseM limit aphase+kShape,0,1  ; check signal levels for PW

if kWave != 4 kgoto PWM
  a1 table aphase, 3, 1
  a2 table aphase + kShape, 3, 1, 0, 1
  aout = a1 + a2
kgoto WOut

PWM:
; Sq with PWM
  aout table aphaseM, 4, 1

WOut:
zaw aout*kON, kOut
endop

;@ ins a a a a a
;@ outs a
opcode OscB, 0, kkkkkkkkkkkkkkkkk
; kModLev - 0...1
; kMod - blue - -64..+64
; FREQ SEMI FAC - ALL THE SAME!
; PART MODE = 3
kCoarse,kFine,kKBT,kModLev,kTuneMode,kFM,kShape,kShapeM,kWave,kON,kFMPTrk,kPitchIn,kModIn,kSyncIn,kFMIn,kShapeIn,kOut xin
aMod zar kModIn
aFM zar kFMIn
async zar kSyncIn
aPWIn zar kShapeIn

; FM Ind Calc
kFM *= 100 ; NEEDS CHANGING CLA000 to CLA-REAL..
kIndx = 0.000039*kFM*kFM*kFM - 0.00049*kFM*kFM + 0.016*kFM - 0.033
kIndx limit kIndx, 0, 80
; Out FM Calc

if kKBT != 1 goto NoKBT
  kNote = gkNote
  goto KBT
NoKBT:
  kNote = 64
KBT:

; FMLin vs FMTrk
if kFMPTrk != 1 goto FMLin
  kFMNote = kNote
  goto FMTrk
FMLin:
  kFMNote = 64
FMTrk:

kPitch init 64
if kPitchIn == 0 goto Run
aPitch zar kPitchIn
Run:
if kTuneMode!=3 then
  kCoarse table kcoarse, giOSCsem
  kFine table kFine, giOSCcnt
  kM_ = kPitch+kModLev*kMod+kNote+kFine*0.01
  kFreq = cpsmidinn(kM_+kCoarse)
else
    if kcoarse <= 32 then
      kFreq table kcoarse, giOSCprt
      kFine table kFine, giOSCcnt
      kFreq *= cent(kFine)
    else
      kPart table kcoarse, giOSCprt
      kFine table kFine, giOSCcnt
      kM_ = kPitch+kModLev*kMod+kNote+kFine*0.01
      kFreq = cpsmidinn(kM_)*kPart
      ;kFreq = 1000
    endif
endif
Out:

kShape = (kShape-50)*.01
if kWave >= 3 kgoto WaveMod
; All simple waves - Sine,Tri, Saw
  aout oscilikts 1, kFreq + aFM*kIndx*cpsmidinn(kFMNote), kWave+1, async, 0
kgoto WOut

WaveMod:
  aphase, asyncout syncphasor kFreq + aFM*kIndx*cpsmidinn(kFMNote), async
  aphaseM limit aphase+kShape,0,1  ; check signal levels for PW

if kWave != 4 kgoto PWM
  a1 table aphase, 3, 1
  a2 table aphase + kShape, 3, 1, 0, 1
  aout = a1 + a2
kgoto WOut

PWM:
; Sq with PWM
  aout table aphaseM, 4, 1

WOut:
zaw aout*kON, kOut
endop
