ljud Audio.pas
  sdl, kolla sdl_dibaudio.c för wave-out driver
  portaudio
  stk, se hur dom har byggt upp envelopes etc
    tick()
    voicer för att slå ihop flera instrument
  TSound  16-bits, 20khz
    Channel
    Priority
    OnProduce
      Waveform
      Filter 
      Envelope
  producers
    TSoundSimple SawTooth/SineWave
    frequency,amplitude
    TSoundFilter
      expression "out=in + prev.1 * prev.2 * prev.3" etc
    TSoundExpression
      "out=sin(time)*800"
    TSoundNoise
  TPlaySound
    Execute() gör platform_soundplay
  realtime
    skruva på parametrar förändrar ljudet direkt
  c64-style arpeggios
  tools\SoundTest.dpr
    TSoundSample : smallint;
    TSound
      Time
      FillBuffer(buffer,size)
        loopar och anropar tick
      Tick() : TSoundSample
        result := Envelope( filter( Oscilliator ) )
      Producers
        [0].tick() * [1].tick() etc.
      Modulators
        animators som har proptargets in i producer-lista
    TSoundManager
      ChannelCount = 4
        nr of mixed channels
      Update()
      Platform_Callback(buffer,length,channel)
    TSoundProducer
      Tick()
      FillBuffer()
      TSoundSID
        BaseFrequency
        WaveForm
        Filter
        Arpeggio
    button1.onclick
      create buffer 1000 samples
      sound=tsound.create
      sound.fillbuffer(buffer)
      platform_play(buffer,length)
   börja enkelt
     TSound
       Pitch
       ADSR :  tscalarvector4f
       Length
       WaveForm : noise/sine/square/sawtooth
       Delay
       Channel,Priority
       Arpeggio off,oneoctave,twooctave
     AND sample generator
       TSound
         Envelopes
           ADSR
         Oscilliators
           Waveform
           Freq double
           FreqModulator : TEnvelope
         Filters
           TMoogFilter
         Delay etc
         Sequence string 'CC#DEFF'
     platform_play från zzgf
   TEnvelope
     kind: attackHold,decayHold,
     value: scalar som ger attack/delay time
     är egentligen en animator
     TArpeggioEnvelope
     TAnimatorBase
       Start()
         Reset()
         Active=true
       Reset()
         Time=0
       Update
         if Active then UpdateWithTimeStep(app.DeltaTime)
       UpdateWithTimeStep(dtime)
         kan anropas direkt av sound
         Time+=dtime
         DoAnimate()
       DoAnimate() virtual abstract
       private
       Time
       Active  true medans den är igång
     TAnimatorSimple
       Target
       FromValue ToValue
       BeginTime 
       Duration
       DoAnimate
         x=time-begintime
         if x<0 exit  //not yet started
         if x>duration active=false exit
         x=x/duration  //0..1 in animation
         target=fromvalue + ( (tovalue-fromvalue) * x );
       Reset
         inherited
         target = fromvalue
     TAnimatorGroup(TAnimatorBase)
       Animators
         kan innehålla tanimator och animatorgroups
       anropar animators.update när grupp är aktiv
       start()
         anropar reset på varje animator
       UpdateWithTimeStep(dtime)
         inherited, loop children c.UpdateWithTimeStep
     TStartAnimator MyAnim
       command för att starta animator
     Sound kan ha en inline TAnimatorGroup
       anropar reset vid generate
     http://winfx.msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/winfx/ref/ns/system.windows.media.animation/c/doubleanimationbase/doubleanimationbase.asp
   TSoundEditForm
     knapp 'play'
     customviewer=soundviewer
   zptScalar
   TFilterCustom
     Expression
     Definitions
     InValue,OutValue,Param1
     måste kompilera expression med parent som 'this'
   Sound
     Channel
     Priority



wavesequencing
  wavetable sequencing
  loopa i buffrar
  vågform skapas genom att loopa i en buffer istället för att räkna fram t.ex. en sågtand
  bufferten kan innehålla squarewave som går från 5 till 50% pulsewidth
  
kombinera två olika filter
  highpass/lopass/bandpass


stråkljud
  osc1 rak
  sågtand/pulsvåg
  koppla en sinusvåg som lfo till frequens för oscialltor2

ringmodulation

synca oscillatorer
  starta om vågform 1 när 2 är klar
  blir ett rikt ljud om man sänker t.ex. frekvensen på osc 1 med en lfo
  
  
soundrealtime refactor
  Osc1
      Frequency
      Waveform square/saw
  Osc2Active X
      Waveform square/saw
      Frequency
  SyncOsc X
  Filter1Active X
         Style LP/BP/HP
         Cutoff
         Q
  Filter2

  loop
    räkna ut osc1 alltid
    
  editorframe där synten kan styras enkelt
  det bör vara enkelt att koppla en lfo till en target
 
TAnimatorWaveform
  skickar ut signal -1 .. 1
  square/saw/sine
  Target
    i clavia så kan man ange en scale per target
    target frequency
      sine
  Frequency
  Scale

  alt.
  TWaveForm wave1
  TSound
    BaseFrequency ptFloat
      prop.IsAnimatable=true;
      zdesigner visar [A]-knapp bredvid animatable props
      välj waveform och scale
    alla animators hamnar i en child-list

trackseditor
  markera ett track
  visa trackentrys i memoruta
  ange trackindex, repeatcount

modulation-matrix
  ModulationEntry
    Source env1,env2,lfo1,osc1,osc2
    Destination Osc1Amplitude,Volume,NoteNr,Osc1NoteNr
    Amount
  every frame
    tick all active mod-sources
    foreach mod
      //value och amount är i -1 .. 1 range
      value=getValue(mod.source)
      value*=amount
      dest.value += value;
      
    osc1.Amplitude

    Env1 går från 0..1
    Lfo går från -1 .. 1
    Volume = OrigVolume * Env1.value
    Volume += Lfo1 * Amount
    FilterCutOff = Env1Value*Amount
    Osc1NoteNr += Lfo1 * Amount
    
    value = OrigValue + ModValue*Amount
    ;när destination är notenr så moduleras över en oktav (12 noter)
    NoteNr= OrigNoteNr + ModValue*Amount*12.0
    
    Lfo
      Speed 0..1  = 1/20 .. 20hz
      OutputRange  Bipolar (-1 .. 1), Positive (0..1), Negative (0..-1)
      Style Sine,Random,SmoothRandom
      
  hur lagra    
    sound.modulators array[0..3] of tmodulatorentry
      kopieras in i voice vid playnote
    lista med tmodulator-klassinstanser
      då måste voice ha pekare till sound, och tmodulator vara readonly vid playback
      cache-missar vid updateframe?

channels
  TChannel
    Volume
    Voices : PVoice;
  channelarray
  sound.play(channelNo)
    alloc voice
    lägg voice först i channel.voices
  
  render
    loop channels
      clear channelbuffer
      render voices
      om voice är inactive, flytta till FreeList
      apply volume and fx
      add to main mixbuffer
      

GlobalMixer
  ligger som inline-komponent till application
    eller slängs ut av user. hindra multipla instanser.
  Channels 0..15
  GlobalLFOs
    kan styras av game-entities, typ justera filter freq baserat på player position
    Lfo1.Speed=Player.Position.X
  properties sätter globala variabler direkt, om möjligt
    defineprop @channel[0].volume - self
  lägg som flik i zdesigner på soundeditframe
    behöver ingen egen frame
    man vill komma åt den samtidigt som man testar ett ljud

runtime control
  trådar hindrar nog att zc skriver direkt till mixer
  tilldela PlaySound.NoteNr
  modulera ljud med mixer.globallfo för att förändra ljud över tid
  MixerControl-komponent
    Kind=TurnOn
    What=Delay
    Channel=0
    skriver med synchronized writes

music
  spela i tråd?
  update from main?
    nog bäst att testa så först

trummor
  snabb lfo ger aliasing mot framelength
  behåll prerendered sound i alla fall?
  audioplayer
    if voice.isprerendered
 
integration i zdesigner
  kopiera först zdesigner.exe och player.bin till en mapp
  slopa prerendered-sound?
  kör äldre zdesigner samtidigt och försök återskapa ljuden från triplee och zblast
  dela upp i units?
    Audio.pas är komponenter
    SoftSynth.pas är newaudio.pas
  alt.
    AudioPlayer
    AudioComponents

threading
  playsound gör app.addSoundToEmit(sound)
    alt. audioplayer.AddNoteToEmitList håller lista
    audioplayer.EmitSounds i main
    send threadevent 
  app i mainloop efter models.update
    mutex voices
    loop soundsToEmit
    end mutex

buggar
  knaster i filtret
  testa detta filter: http://www.musicdsp.org/showArchiveComment.php?ArchiveID=38
  eller audiality: a_filters.c
  konstigt: filtret fungerar ok, men när volymen sänks så sprakar den
    filtret gör så att ljudet går över angiven volym
    därför slutar ibland waven på ett högt värde, och klick uppstår
    om filter först och sedan volym så knastrar det medans ljudet spelas...
    sänk volymen ifall useFilter=true?
    kör filtret även efter time>=length? då borde klick slätas ut.

profiler http://www.lw-tech.com/

directsound
  se artikel av "kb"
  gör testapp som spelar sine-wave via dsound och en tråd
  get current playing position
    fyll upp buffer fram till playing position
  delphi dsound-header:
    http://cvs.sourceforge.net/viewcvs.py/delphi-dx9sdk/Headers/DirectSound.pas?rev=1.6&view=markup
  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/dx9_directsound_reference.asp
  c-exempel
    http://www.geocities.com/SiliconValley/Way/3390/mnoise.html
  dsound.h
    http://ccrma.stanford.edu/software/stk/Misc/dsound.h
  http://www.kebby.org/
  com-programmering i c
    http://www.codeproject.com/com/com_in_c1.asp  
  kanske kan använda interface i delphi i alla fall?
  audiality
    http://audiality.org/
  phuzor master thesis
    http://kotisivut.fonet.fi/~jkleimol/home.htm
    
    
emix8-inlägg
"Softsynth implementation"
I've written a software synthesizer for use in my game engine. 

Here is a screenshot:

For the Triple-E game demo I used a mixture of precalculated and realtime audio. 
With this new synthesizer I will hopefully be able to use 100% realtime audio for future projects.

This is my first attempt at something like this so I had to do some research first.
I'm listing the resources here hoping it might be helpful for anyone wanting to do something similar.
Here are some links that was very useful for me:

1. Tammo Hinrichs "kb" of demo-group Farbrausch homepage http://www.kebby.org/
He has written some good articles about audio programming.
Here is a direct link to the articles http://www.kebby.org/articles.html
There is also a video of a seminar that Tammo held http://www.scene.org/file.php?file=/parties/2005/breakpoint05/seminars/bp05_seminars_-_tammo_kb_hinrichs_-_practical_softsynth_design_-_xvid.avi&fileinfo

2. Jari Kleimola masters thesis "Design and Implementation of a Software Sound Synthesizer" http://kotisivut.fonet.fi/~jkleimol/home.htm
Over 100 pages about audio programming.

3. DirectSound C/C++ Reference http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/dx9_directsound_reference.asp
You need this info to make sound on Windows.

4. The Synthesis ToolKit in C++ http://ccrma.stanford.edu/software/stk/
A advanced audio toolkit developed at universities. 
Main author of the toolkit is Perry Cook who has also written a book: "Real Sound Synthesis for Interactive Applications"

5. Audiality http://audiality.org/
An open source audio toolkit. 
"A scalable and portable audio engine for music and sound effects".
Written by a swede called David Olofson.

6. Noise Sculpture http://www.noisesculpture.com/
Homepage of a free downloadable book called "How to make a noise: sound design and synthesiser programming"
A very good introduction to synthesizers in general.

You can try my little test program to hear for yourself what it sounds like.
It's nothing fancy, just very basic subtractive synthesis (popular technique in hardware synths of the 1980s).
Download SoftsynthTest.exe


------------------

musik midi support
   midi file specification
   http://www.sonicspot.com/guide/midifiles.html
   http://www.wilsonc.demon.co.uk/delphi3.htm
   http://midipiano.googlepages.com/PianoEx_v1.1_FS.zip
låtar
   http://www.vgmusic.com/music/computer/commodore/commodore/index-classic.html
   http://dmoz.org/Arts/Music/Sound_Files/MIDI/
   http://www.voidaudio.net/midi.html
General MIDI System - Level 1
  patch assignment
    http://msdn2.microsoft.com/en-us/library/ms713273.aspx
  percussion
    http://msdn2.microsoft.com/en-us/library/ms713273.aspx
  guidelines
    http://msdn2.microsoft.com/en-us/library/ms706219.aspx
    ch 9 (om patch 0)

TMusic
  MidiFile binary

filtrera midi-fil och behåll enbart det nödvändigaste
  konvertera note on/off till playnote med length?
    problem med pitchbend på befintliga noter?

files
  Designer
    uMidiFileParser
      TMidiFile //utgå från pascal
        GetRuntimeStream() //bygger upp det som ska länkas runtime
  Runtime  
    midi-parse code inkluderad i audioplayer-unit
    midi-data parsas inuti audio-tråden

binary format
  deltatime varlength
  channel 4bits
  eventtype 4bits
  param1/2 one byte
  
  note
    notelength varlength (istället för noteoff)

  time=0
  FlushChannels()
    loop channels
      skriv alla events som inträffar nu
  AdvanceTime()
    loop channels, hitta minsta deltatime
    time+=deltatime

trådat?
  +musik spelas garanterat i synk
  -kan ej köra expressions
     om expressions kan trådas så måste gemensamma resurser skyddas (modellist etc)

compress
  interleaved
  separated
    först en lista med stream-sizes, varlenght

extra features?
  ej bara en midi-import
  events
    TMusic
      OnNote
      OnPitchBend
  demo
    genererar bollar i x/y baserat på channel/note
    steering placerar bollar rätt
    välj 4 olika midi-låtar
      
addMusicCommand(music,start/stop,fadeout/in)
  thread
  advancemusic
    håller private emitlist
    
XM-file format
  http://mediasrv.ns.ac.yu/extra/fileformat/modules/xm/xm.txt
  http://www.colossusentertainment.com/DevelopmentStuff/PixieGameEngine.html
    xm och andra format källkod