About / What is LineSpec
------------------------

  LineSpec is a library to simplify the process of getting spectrum data from
  the (default) recording device;

  The latest official version(s) can be found at http://www.ctuser.net. For
  suggestions, questions, requests or bug reports, send eMail to
  info@ctuser.net.

Requirements
------------

  Not yet tested that much yet, but any PC capable of recording sound should do.
  However, I've already encounter a computer with good hardware where playback
  began stuttering when LineSpec demo applications ran, and on another machine
  recording stops after a few seconds when 'Stereo Mix' is choosen.

Copying / License / ...
-----------------------

  LineSpec and Demo applications are free software; you can redistribute them
  and/or modify them under the terms of the GNU General Public License as
  published by the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful, but WITHOUT
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

  You should have received a copy of the GNU General Public License along with
  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
  Place, Suite 330, Boston, MA  02111-1307  USA

  If you have any questions, suggestions or bug reports about this product,
  contact me: info@ctuser.net; Please do not contact me about general B.A.S.I.C.
  language or A.P.I. issues.

  Files (depending on the package you downloaded, not all files may be included)
   - License.txt                  GNU General Public License
   - *.dll                        LineSpec library(ies)
   - LineSpec.txt                 Documentation etc.
   - API & Includes\*.*           API declarations and/or include files
   - Demo applications\*.*        Demo applications, source and related files;
   - Examples\*.*                 Some test applications
   - Source\*.*                   Source code and related files

  Wavedata to spectrum data conversation is based on a free Visual Basic 6
  example by Ulli "Mühlenweg" <umgedv@yahoo.com>, which can be found at
  http://www.planetsourcecode.com/vb/scripts/ShowCode.asp?txtCodeId=65007

  LineSpec shows icons of a few supported music players, for copyright see their
  homepage / product:
   - Calaym (formerly QuickPlayer) ( http://ctuser.net )
   - Winamp ( http://winamp.com/ )
   - foobar2000 ( http://www.foobar2000.org )
   - Apollo ( http://apollo.capacala.com )

Background
----------

  It initially started with a non-public QuickPlayer (now named Calaym) version
  which rendered a simple spectrum on about 1/5 screen height, which was
  ocassionally shown with a beamer during the "Summernight Party" 2004 in Exing
  (Germany) by Partyservice Falk (http://www.falk-licht-ton.de).

  Some time later the rendering stuff was moved to a seperate executable, using
  fmodex (http://fmod.org) for recording and slightly delayed virtual playback
  to get the spectrum.

  In 2007, while helping to include "sound support" for "Lights player" (a
  Jukebox for external LED boards; http://www.freewebs.com/artdecojukebox),
  the main code was built as a dynamic link library (dll) (3.x).
  
  There was still the sync problem (keeping the playback slightly behind
  recording), and for some reason the recorded data was invalid after some time.
  Eventually work on the free Visual Basic 6 example by Ulli "Mühlenweg" started
  (once more); After stripping and porting to PureBasic, LineSpec no longer
  relied on fmodex, but there was still invalid spectrum data after some time;
  To fix this, recording totally reinitializes after each processed spectrum.
  Designed as standalone library, it was officially published in fall 2007, with
  version 3.10 (build 2007.09.30)

  LineSpec became open source since spring/summer 2008, with version 3.10 (build
  2008.04.16)

  With version 3.20 (published spring 2009), the source was rewritting to
  assembly (Flat Assembler; http://www.flatassembler.net ), resulting in about 3
  times faster waveform to spectrum conversation; Multithread support is also
  included in the main dll instead of having a seperate dll. (The purebasic demo
  applications use a wrapper with almost no speed disadvantages)

  Direct sound support was added in version 3.24 (fall 2011)

  Version 4 is a more modular and slimed version, having recording, FFT, filters
  etc seperated. Its currently a PureBasic 32/64 bit combo. Also filters are not
  entirely in assembly and may be removed in future versions.

Generic & Spectrum API
----------------------

  UINT Init(
    UINT Reserved
    ); // currently no specific return value

  UINT SetWaveData(
    ptrWaveData, // pointer to compatible wavedata
    ); // currently no specific return value
  Performes most of the FFT calculation using the provided wavedata.
  (The wavedata is no longer required after the function returns)
  Usually the return value from RecGetPtr is used here.
  If ptrWaveData is NULL and recording is performed, the next available
  recording data will be used, and the result is the GetTickCount value when the
  wavedata was recorded.

  UINT GetFullSpectrum*(
    UINT *SpectrumOut   // pointer to output spectrum
    ); // currently no specific return value
  Series of functions that return a spectrum with 1024 (mono) or 2x1024 (stereo)
  values.
  If *SpectrumOut is NULL, an internal memory is used.

Recording API
-------------
    
  bool RecStart(
    UINT Reserved
    ); // If the function succeeds, the return value is not NULL;

  UINT RecGetPtr(
    UINT ptrTimeStamp   // Optional pointer to an UINT to recieve the
                        // GetTickCount value when the wavedata was recorded
    ); // Returns the address of the wavedata. Valid until the next call to
       // RecGetPtr. No need to free this memory.

  UINT RecStop(
    ); // currently no specific return value

Spectrum filter API
-------------------

  UINT SpectrumMonoMix(
    UINT ptrSpectrumIn,  // pointer to input spectrum
    UINT ArraySize,      // number of values per channel of the spectrum
    UINT ptrSpectrumOut, // pointer to output spectrum
    ); // currently no specific return value
  Convert a stereo to a mono spectrum.
  ptrSpectrumIn and ptrSpectrumOut may be the same memory.
  If *SpectrumIn is NULL, an internal memory is used.
  If *SpectrumOut is NULL, an internal memory is used.

  UINT SpectrumOptimize*(
    UINT ptrSpectrumIn,  // pointer to input spectrum
    UINT ArraySize,      // number of values per channel of the spectrum
    UINT ptrSpectrumOut, // pointer to output spectrum
    ); // currently no specific return value
  Performs some level optimations for a full spectrum. Can also be used on all
  smaller spectrums, but may not have the desired effect.
  ptrSpectrumIn and ptrSpectrumOut may be the same memory.
  If *SpectrumIn is NULL, an internal memory is used.
  If *SpectrumOut is NULL, an internal memory is used.

  UINT SpectrumCompact*(
    UINT ptrSpectrumIn,  // pointer to input spectrum
    UINT ArraySizeIn,    // number of values per channel of the input spectrum
    UINT ptrSpectrumOut, // pointer to output spectrum
    UINT ArraySizeOut,   // number of [desired] values per channel of the output
                         // spectrum
    ); // currently no specific return value
  Series of functions to creates a smaller spectrum (Using the highest value of
  compbined values each);
  SpectrumCompactMono: ptrSpectrumIn and ptrSpectrumOut may be the same memory.
  SpectrumCompactStereo: Values will be corrupted if ptrSpectrumIn and
      ptrSpectrumOut are the same memory.
  SpectrumCompactStereoSM: uses SpectrumCompactMono twice, so ptrSpectrumIn and
      ptrSpectrumOut may be the same memory.
  If *SpectrumIn is NULL, an internal memory is used.
  If *SpectrumOut is NULL, an internal memory is used.
  If both *SpectrumIn and *SpectrumOut are NULL, the same internal memory is
  used (not recommend for SpectrumCompactStereo)

  UINT SpectrumExpand*(
    UINT ptrSpectrumIn,  // pointer to input spectrum
    UINT ArraySizeIn,    // number of values per channel of the input spectrum
    UINT ptrSpectrumOut, // pointer to output spectrum
    UINT ArraySizeOut,   // number of [desired] values per channel of the output
                         // spectrum
    ); // currently no specific return value
  Series of functions to create a larger spectrum (by duplicating values); 
  SpectrumExpandMono: ptrSpectrumIn and ptrSpectrumOut may be the same memory.
  SpectrumExpandStereo: Values will be corrupted if ptrSpectrumIn and
      ptrSpectrumOut are the same memory.
  SpectrumExpandStereoSM: uses SpectrumExpandMono twice, so ptrSpectrumIn and
      ptrSpectrumOut may be the same memory.
  If *SpectrumIn is NULL, an internal memory is used.
  If *SpectrumOut is NULL, an internal memory is used.
  If both *SpectrumIn and *SpectrumOut are NULL, the same internal memory is
  used (not recommend for SpectrumExpandStereo)

Technical Notes:
----------------

  A spectrum consists of up to 1024 single precision (32-bit) float values;
  If the spectrum is stereo, this values are the left channel, which are
  followed by the same amount of right channel values.
  16 values stereo = 16 floats left channel + 16 floats right channel  values
                   = 64 bytes  left channel + 64 bytes  right channel memory
                   = 32 floats / 128 bytes
  16 values mono   = 16 floats (mono) / 64 bytes

  The wavedata block consists of 8192 bytes.

Usage
-----

  To use LineSpec, call the Init() function.
  Typically, you want to get a live spectrum. To do so:
   1) Use Init() to initialize LineSpec.
   2) Use RecStart() to start recording.
   3) Use RecGetPtr() to detect if new wavedata is available, and pass that
      memory pointer to SetWaveData.
   4) Use the desired GetFullSpectrum function that suits you, which gives you
      a full spectrum (1024 values for mono, 2x1024 values for stereo).
   5) Optionally use any spectrum function to optimize the spectrum. For most
      functions, the input and output spectrum may use the same memory.
   6) When done, call RecStop() to stop recording.

  Hint: * You can skip RecGetPtr, and pass NULL as memory for SetWaveData
        * You can alway pass NULL as spectrum pointer; if you pass NULL for both
          input and output spectrum pointer, check the function handles passing
          same memory for input and output.
  PureBasic:
    you can 'IncludeFile "LineSpec (PureBasic assembly).pb"'; This way
    lnspec32/64.dll is not needed.
  Visual Basic 6:
    add 'LineSpec (Visual Basic 6 declarations).bas' to the project, and copy
    lnspec32.dll to a folder where Visual Basic can find it.

Remarks
-------

  - If RecStart() has failed, do not call RecStop().
  - If RecStart() has failed or after using RecStop(), you may try RecStart()
    again.

Demo applications
-----------------

  Images used for LineSpec demos:
  At the moment, there are no recent demos using any wallpapers/images yet.

  The demos don't need the dll because it's compiled into (included) the binary.

  When launching, Linespec will start foreground, and change to background as
  soon as user input occurs

  There is a systray-icon in case you are not familiar with the keyboard
  shortcuts

  You have to setup recording device. On most systems there is no need to
  restart the demo application to apply changes (may be needed on Windows
  Vista?).

  Demos will automatically use a non-primary monitor, or even the full "virtual
  desktop".

  When having QuickPlayer (beta 60+), Apollo, Foobar2000 or Winamp running, the
  demos will display the current playing song.


  Shortcuts:
    Ctrl + Shift + Alt + D:   toggles visibility (but still running!)
    Ctrl + Shift + Alt + F:   return to foreground-mode
    Ctrl + Shift + Alt + L:   quit
    Ctrl + Shift + Alt + V:   open Windows volume controls

  Some usefull windows shortcuts:
               Windows + M:   Minimize (most) Windows
               Windows + D:   Brings the Desktop to the foreground (requires
                              Windows 98/ME, NT?/2000?/XP/Vista/+; You may have
                              to swap to another application first to restore
                              the demo application)

  TrayIcon behavior:
                Left click:   toggles visibility (but still fully running!)
          Left doubleclick:   quit
               Right click:   show menu

  For completeness, source for the released demo applications is provided;
  I know it's a (coding) disaster, especially all this compiler directives.
  It's a demo application, so I didn't care a bit except speed and size of the
  final binary, and sharing code.

Compiling
---------

  - LineSpec needs PureBasic to compile
  - The demo applications need PureBasic to compile
  - The version info resources use some specific values so that they can be
    updated with a tool during batch compiling. Don't forget to update this info

Version history
---------------

  4.00 build 2013.12.21:
   Demo applications:
    - New '3D Spectrum deluxe' demo
    - New (Enhanced) 'Encircle deluxe' demo
    - New (Enhanced) 'RaveN deluxe' demo
    - New 'Flowers 2010' demo
    - New 'Flowers 2011' demo
    - New 'Turntables 2013' demo
    - Now using jpeg instead of bitmaps for the main background (wallpaper)
    - For pure wallpaper demos the resource name is now 'wallpaper', instead of
      'background'
    - Pure wallpaper demos support custom colors for each spectrum band.
    - Pure wallpaper demos should no longer flicker, except due spectrum values
      or title change.
    - Pure wallpaper demos support support custom rendering, allowing particle
      based demos to be easily converted / stripped (change include, use
      fillrect directly, use RenderInnerHeight instead of RenderHeight
      (ParticleCenterY and other 'particle' code/variables are handled by the
      'wallpaper' code / valid, fill in some missing constants)
   Misc:
    - Fixed crash when minimizing VB6 RaveN example

  4.00 build 2012.12.06:
   General changes/library:
    - more modular
    - PureBasic 32/64 bit combo.
    - seperated filters; please note that the filters are not entirely written
      in assembly and may be removed in newer versions.
   Demo applications:
    - Updated to support latest Calaym version
    - Also available as 64bit versions
      *** PS: There is no significant (if any) benefit of 64bit, therefore the
              64bit executables may not be available ***

  3.24 build 2011.??.??
   General changes/library:
    - Fixed Samplerate not being 44100 Hz / spectrum issues
    - Fixed issue when quitting library
    - Added DirectSound support
    - Seperate data section for speed issues (MirrorData and BoostData
      calculation code no longer shared with hMemRec)
   Demo applications:
    - Updated to support Calaym (formerly / 'instead of' QuickPlayer)
    - Right-clicking on menu items working

  3.23 build 2011.01.28
   Demo applications:
    - New 'Async triple delux' demo

  3.23 build 2010.12.21
   Demo applications:
    - New 'RaveN' demo
    - New year countdown
    - Finally an info dialog
    - Fixed flickering when title changes on particle based demos (Encircle,
      Starfield, RaveN)

  3.23 build 2010.05.24
   General changes/library:
    - MirrorData and BoostData is now unitialized/reserved data, and calculated
      on startup; Calculation code is shared with hMemRec, which is now partly
      initialized (code), partly uninitialized (additional bytes)
    - Even less code between EnterCriticalSection and LeaveCriticalSection; The
      Multithreaded recording stuff is also slightly optimized for speed (/size)
   Demo applications:
    - Wallpaper demos alignment issue, esp. when resizing alot
    - New 'Encircle' demo
    - Starfield (and Encircle) demo now renders below text area

  3.22 build 2009.11.17
   General changes/library:
    - Removed UninitializeCriticalSection import (not present on XP; was not
      actually used and so ignored by the assembler)
    - GetSpectrum did not return GetTickCount() windows api value from the last
      finished spectrum data if not multithreaded.
    - waveInAddBuffer now performed before waveInStart
    - Buffer is now unitialized/reserved data, so uncompressed size is much
      smaller

  3.21 build 2009.05.20
   General changes/library:
    - Minor arrangements so the assembly can be easier used for PureBasic
    - When multithreading, current/new wavedata memory was switched even if no
      new data was available, resulting in switching between old/current data.
      (Demos are not affected)
   Demo applications:
    - Device setup starts mixer in recording mode

  3.20 build 2009.02.15
   General changes:
    - Startup() has now a flag
    - GetSpectrum() is now ~ 95% assembly and way faster:
       ~ 4.4x Wavedata preperation
       ~ 3.4x FFT generation
       ~ 3.6x Postprocessing, calculating and boosting
       ~ 1.7x Array processing / copying
      Total improvement is ~ 3.4x speed
      (using elapsed times for 32 calls with new spectrum data; 5 tries each,
      comparing best value(s) of the (slightly modified) old version with the
      worst value(s) of the new version)
   Demo applications:
    - Basic native support to gather titles from Apollo, Winamp and latest
      Foobar 2000
    - Rewritten and enhanced stretching/alignment for Wallpaper demos
    - Fixed GDI leak when size changes (Wallpaper demos only)
    - When entering foreground mode (due keypress or elapsed time) visibility is
      automatically restored
    - Lot's of Windows XP workarounds
    - Menu for tray icon click with right mouse button
    - New icons; Vista png icon (untested)
    - SetStretchBltMode left HALFTONE so eye stretching is no longer corrupted
      on Windows NT series.
    - Systray icon reloading
    - Semitransparent title bar (optionally / requires msimg32.dll)
    - When main window is hidden, spectrum is rendered in the systray (icon)
      instead

  3.11 build 2008.07.24
   Demo applications:
    - Proper background erasing (wallpaper / starfield demos unaffected)
    - Global hotkeys working properly on Windows XP

  3.11 build 2008.06.20
   General changes:
    - GetSpectrum() returns GetTickCount() windows api value of the affected
      spectrum data, or NULL / 0
    - ptrBoost parameter for GetSpectrum() may be NULL
    - Using channel 0 in GetSpectrum() delivers mixed left/right channel data
   Multithread version:
    - Thread always stoppes recording properly now on Shutdown()
   Virtual version:
    - Flags and Channels parameters processed (correctly)
   Demo applications:
    - Recording thread always stoppes recording properly when quitting
    - New demo: LSDemo - Wallpaper - LaFee
    - Animation when title changes

  3.10 build 2008.04.16
   Virtual version:
    - Generates spectrum values for all channels correctly
   Demo applications:
    - Removed stuff to detect wether screensavers etc. are permitted, because
      provided information is unreliable. Quit or hide manually instead.

  2008 Open source
  2007 Ported and stripped VB6 example to PureBasic / dynamic link library
  2007 Dynamic link library, using fmodex
  ???? Seperate executable, using fmodex
  2004 Simple on-screen spectrum intregrated in a music player project / fmodex
