'------------------------------------------------------------------------------------------------------------
' SOUNDRA STEREO :: SOUNDRA.bas - Main file
'------------------------------------------------------------------------------------------------------------
'#DEFINE DEVMODE
'#DEFINE SHOWKEYCODES
'#DEFINE GFX_TIMED_FLIP
#INCLUDE ONCE  "JIGSAW/JIGSAW_BASICS.bas"
#INCLUDE ONCE  "JIGSAW/JIGSAW_GRAPHICS.bas"
#INCLUDE ONCE  "JIGSAW/JIGSAW_AUDIO.bas"
#INCLUDE ONCE  "JIGSAW/JIGSAW_MUSIC.bas"
#INCLUDE ONCE  "win/mmsystem.bi"
SetPriorityClass(GetCurrentProcess(),ABOVE_NORMAL_PRIORITY_CLASS)     'MINIMIZES LATENCY
SetThreadExecutionState(ES_CONTINUOUS OR ES_DISPLAY_REQUIRED)         'PREVENTS SLEEP
'------------------------------------------------------------------------------------------------------------
SOFTWARE_NAME    = "Soundra"
SOFTWARE_STATUS  = ""
#IFDEF DEVMODE
SOFTWARE_STATUS  = "DEV MODE"
#ENDIF
SOFTWARE_VERSION = "1.8.13"
#IFDEF __FB_64BIT__
SOFTWARE_BIT     = "64"
#ELSE
SOFTWARE_BIT     = "32"
#ENDIF
'------------------------------------------------------------------------------------------------------------
ENUM ABORT_CODES
     AC_NONE, AC_PRIVILEGE, AC_INIT, AC_MEMORY, AC_GFX, AC_GUI
END ENUM
ENUM CONTROL_SHORTCUTS
     CS_FRE,CS_LOAD0, CS_MicP, CS_MicM, CS_PlayP, CS_PlayM, CS_Rec,
     CS_VRES,CS_VZOOM_CANCEL,
     CS_DRAW_MODE, CS_SYNTH_CENTER, CS_CTRL_INFO, CS_MSG_BAR, CS_DIALOG,
     CS_TOOLS, CS_PARAM_GLOBAL, CS_PARAM_SCHAN, CS_PARAM_SLINK, CS_PARAM_DOMAIN, CS_ENV, CS_POLY,
     CS_MOD_CONTROLS, CS_MOD_POWER, CS_MOD_SHOW, CS_MODULE_FLAGS, CS_SEED, CS_MODULE_INFOS, CS_PARAM_TAB0, 
     CS_PARAM, CS_PARAM_LIST, CS_PARAM_FA, CS_PARAM_VHOST,
     CS_SHAPE, CS_SHAPE_LIST, CS_SHAPE_GRAPH, 
     CS_SAMPLE, CS_SAMPLE_M, CS_SAMPLE_LIST_M, 
     CS_FILTER, CS_FILTER_LIST, CS_FILTER_GRAPH, CS_FILTER_WINDOW, CS_FILTER_SIZE, CS_FILTER_K, 
     CS_MELODY, CS_MELODY_LIST, 
     CS_MM_DEVS,CS_MM_DEVS_LIST, CS_MIDI_MIN, CS_MIDI_MAX, CS_MIDI_RES, CS_MIDIKB_CHAN, 
     CS_MIDI0,CS_MIDI1,CS_MIDI2, CS_MIDICC, CS_MIDICT, CS_MIDICC_CHAN, CS_MIDICC_DISPLAY,CS_MIDI_DEVS_LIST,
     CS_BROWSER_TAB0, CS_LI_ORDER, CS_FILES, CS_FILE_LIST, CS_DRIVES, 
     CS_CONSOLE_TAB0, CS_CONSOLE, CS_CONSOLE_LIST,
     CS_MODULE_TAB0, CS_MODULES, CS_MODULE_LIST, 
     CS_SAMPLES, CS_SAMPLE_C, CS_SAMPLE_LIST,
     CS_SESSION_TAB0, CS_NEW_SYNTH, CS_ZCANCEL,
     CS_BB, CS_KB, CS_BB_LOCK, CS_KB_LOCK, CS_BB_MODE, CS_KB_MODE, CS_KB_VISIBLITY, CS_KB_POS,
     CS_VINFOS, CS_AOINFOS, CS_AIINFOS, CS_OUTBS, CS_DISPLAY_RES, CS_NB_MONITORS, 
     CS_TNGS, CS_TNG_NAME, CS_TNG_SCALE, CS_TNG_KEYS, CS_TNG_NBK_LBL, CS_TNG_RF, CS_TNG_RFK, 
     CS_TNG_REL, CS_TNG_ABS, CS_TNG_KR, CS_TNG_SP, CS_TNG_SP_LIST, CS_SP, CS_SP_LIST,
     CS_TS_LENGTH, CS_TS_BASE, CS_SYNTH_OUT, CS_XYPOS, CS_FPS, CS_PP_DISPLAY, CS_SCOPE, CS_USE_DEFAULT,
     NB_CS
END ENUM
ENUM WINDOW_NAMES
     W_SYSBAR, W_ABOUT, W_SYSTEM_SETTINGS,W_VIDEO_SETTINGS,W_AUDIO_SETTINGS,W_TUNING,
     W_SYNTH,W_SYNTH_TOOLS, W_TRACK, W_PANEL, W_BB,W_KB,
     NB_WINDOWS
END ENUM
ENUM TAB_NAMES           'BROWSER TABS
     T_MESSAGES, T_FILES, T_MODULES, T_SAMPLES, T_MIDICC, T_SESSIONS,
     NB_TABS
END ENUM
ENUM MESSAGE_TYPES
     MSG_SYSTEM, MSG_ACTIONS,
     NB_MSG_TYPES
END ENUM
ENUM MODULE_TYPES
     MOD_REFERENCE, MOD_LIBRARY,
     NB_MODULE_TYPES
END ENUM
ENUM MOD_CONTROLS_ID     '! SAME ORDER AS CONTROLS ARE CREATED
     MOD_PLAY,MOD_HOLD,MOD_REC,MOD_LOOP,MOD_AUTOREWIND,MOD_REWIND,
     MOD_SW1,MOD_SW2,MOD_ZERO,MOD_DUAL,MOD_ENVELOPE,MOD_MIDI,
     NB_MOD_CONTROLS
END ENUM
ENUM PARAM_LISTS
     PARAM_INPUTS, PARAM_SHAPES, PARAM_SAMPLES, PARAM_FILTERS, PARAM_MELODIES, PARAM_DEVICES, PARAM_SP,
     NB_PARAM_LISTS
END ENUM
ENUM TEXT_FIELD_NAMES
     TF_DIALOG,
     NB_TFN
END ENUM 
ENUM METER_NAMES
     M_AUDIO, M_VIDEO, M_CONTROL, M_WORKLOAD,
     NB_METERS
END ENUM
ENUM TUNING_INDEXES
     TUNING_COPY, TUNING_CURRENT,TUNING_MOD,
     NB_TUNINGS
END ENUM
ENUM LINK_INDEXES
     LINK_SOUNDRA,LINK_PORTAL,
     NB_LINKS
END ENUM
ENUM LOG_ACTION_NAMES
     ACTION_MOD_CREATE, ACTION_MOD_DELETE, ACTION_MOD_SLINK, ACTION_MOD_GLOBAL,
     ACTION_MOD_CONNECT, ACTION_MOD_DISCONNECT, ACTION_SYNTH_CONNECT, ACTION_SYNTH_DISCONNECT,
     ACTION_MOD_DOMAIN, ACTION_MOD_VMAP, ACTION_MOD_ENV, ACTION_MOD_PLAY, ACTION_MOD_POWER, ACTION_MOD_POLY,
     NB_ACTIONS
END ENUM
ENUM BROSWER_BUTTONS
     BB_ORDER, BB_RENAME, BB_COPY, BB_DELETE, BB_SAVE, BB_LOAD,
     NB_BB
END ENUM
ENUM DELETE_FLAGS
     DEL_FILE, DEL_MIDI_MAP, DEL_PRESETS
END ENUM
ENUM FA_CONTROLS
     FAC_MODE,FAC_EDIT,FAC_VALUE,FAC_UNIT,
     NB_FA_CONTROLS
END ENUM
ENUM SETTING_TOGGLE_INDEX
     ST_FORCE_CTHROTTLE, ST_SHADER, ST_AUTO_CONNECT, ST_USE_DEFAULT, ST_AUTO_SAVE, ST_DISPLAY_MIDIIN
END ENUM
'------------------------------------------------------------------------------------------------------------
TYPE _CONSOLE_MSG
     AS _TEXTLINE   msg
     AS I32         msg_type
     AS I32         txt_w
END TYPE
TYPE _SETTINGS
                    'VIDEO & SYSTEM
     AS UI32        LANGUAGE                 = LANG_EN
     AS IOS         FORCE_CTHROTTLE          = FALSE
     AS IOS         VIDEO_DRIVER_INDEX       = GDI
     AS IOS         SCREEN_WIDTH             = 0       'HIGHEST (AUTO)
     AS IOS         SCREEN_HEIGHT            = 0       'HIGHEST (AUTO)
     AS IOS         MONITORS                 = 1       'EXTENDED DESKTOP
     AS IOS         MONITORS_CURRENT         = 1
     AS IOS         USE_SHADER               = TRUE
     AS IOS         GPU_ECO                  = FALSE
     AS F32         ZOOM_FACTOR              = .8      '[ZMIN .. ZMAX]
     AS F32         ZOOM_FACTOR_CURRENT      = .8
     AS F32         ZMAX                     = 1       'AUTO
     AS F32         ZMIN                     = .6      'FIXED
                    'AUDIO
     AS TXT         INPUT_DEVICE_NAME, OUTPUT_DEVICE_NAME, SESSION_PATH, SESSION_FILE, SESSION_NAME
     AS IOS         OUTPUT_BUFFER_LENGTH     = 1       '1 .. 32ms
     AS IOS         SAMPLE_RATE              = 48000   '* {1,2,4,8}
     AS IOS         AUTO_CONNECT             = TRUE
     AS IOS         USE_DEFAULT              = TRUE
                    'SESSION
     AS I32         TIME_BASE                = 2       '2,3,5 ONLY
     AS IOS         AUTOSAVE                 = TRUE
     AS IOS         DISPLAY_MIDIIN           = FALSE
     AS I32         SCOPE_MODE               = 0
END TYPE
TYPE SAMPLE_LIST_ITEM
     AS _TEXTLINE   PATH, FILENAME
     AS I32         MODE
     AS _WF_CATALOG PTR WF_PTR
     AS IOS         OFFLINE
END TYPE
CONST AS I32        BASE_FONT_SIZE      = 20
CONST AS I32        BASE_ICON_SIZE      = 22
CONST AS I32        TOOLS_W             = 92 'IN GRID STEPS
CONST AS I32        SYSBAR_H            = 9  ' ""
'SWATCH
                    NAMESPACE SWATCH0
CONST AS I32        BG                  = RGB(0,0,15)
CONST AS I32        FG                  = RGB(255,255,255)
CONST AS I32        BUTTON_BG           = RGB(50,50,60)
CONST AS I32        BUTTON_BG_ACTIVE    = RGB(200, 150, 0)
CONST AS I32        BUTTON_BG_ON        = RGB(5,120,5)
CONST AS I32        BUTTON_FG           = RGB(255,255,255)
CONST AS I32        BUTTON_FG_ACTIVE    = RGB(255,255,255)
CONST AS I32        BUTTON_FG_ON        = RGB(255,255,255)
CONST AS I32        BUTTON_FRM_OFF      = RGB(75,75,90)'GREY(75)
CONST AS I32        FRM_OFF             = RGB(10,42,77)
CONST AS I32        FRM_ON              = RGB(23,93,176)
CONST AS I32        FRM_ACTIVE          = RGB(190,190,255)
CONST AS I32        TAB_BG              = RGB(10,42,77)
CONST AS I32        TAB_FG              = RGB(255,255,255)
CONST AS I32        TAB_BG_ON           = RGB(23,93,176)
CONST AS I32        TAB_FG_ON           = RGB(255,255,255)
CONST AS I32        TEXTAREA_BG         = RGB(20,20,25)
CONST AS I32        TEXTAREA_BG_HL      = RGB(0,0,200)
CONST AS I32        TEXTAREA_FG         = RGB(255,255,255)
CONST AS I32        TEXTAREA_FG_HL      = RGB(255,255,255)
CONST AS I32        LIST_BG             = RGB(0,0,65)
CONST AS I32        LIST_BG_HL          = TAB_BG_ON
CONST AS I32        LIST_FG             = RGB(255,255,255)
CONST AS I32        LIST_FG_HL          = RGB(255,255,255)
CONST AS I32        LIST_FRM_OFF        = RGB(60,60,75)
CONST AS I32        BUTTON_BG_REC       = RGB(150,15,15)
CONST AS I32        WINDOW_BG           = RGB(20,20,25)
CONST AS I32        DARKER_BG           = RGB(10,10,12)
                    END NAMESPACE
'------------------------------------------------------------------------------------------------------------
'SYSTEM
DIM SHARED AS _SETTINGS       SETTINGS
DIM SHARED AS _LIST_INFO      LI_ConsoleMSG
DIM SHARED AS _CONSOLE_MSG    PTR PTR ConsoleMSG
DIM SHARED AS _TEXTLINE       PTR PTR LOG_ACTIONS, MSG_BAR_QUEUE
DIM SHARED AS I32             LOG_FILE_NUMBER, MSG_BAR_ID, NB_MSG_BAR, WINTABS(NB_WINDOWS)
DIM SHARED AS UI32            UNDO_LEVELS = 69
DIM SHARED AS THREAD_MESSAGE  CTRL_MSG
DIM SHARED AS _TEXTLINE       KB_MSG,STR_DEV_ANY,STR_DEV_NONE,STR_DEV_NA,STR_DEV_INVALID,STR_DEV_ANYCON
DIM SHARED AS _TEXTLINE       REN_FILE_PATH, REN_OLD_NAME, REN_FILE_EXT
DIM        AS I32             I,R,ID, ABORT_CODE
DIM        AS IOS             NEW_SESSION, INITOK, DOCOPYBUNDLE
DIM        AS TXT             TMPSTR
'GRAPHICS
DIM SHARED AS I32             ACTIVE_BROWSER_TAB, CE_CENTER
DIM SHARED AS IOS             NEW_MSG_BAR, WIN_SWITCH = TRUE
DIM SHARED AS UI32            PTR CONNECTOR_SWATCH(3)
DIM SHARED AS ANY             PTR CONNECTOR_ENDING(3)
'AUDIO
DIM SHARED AS _WF_CATALOG     PTR PTR WF_Library, WF_Sample, WF_Filter, WF_Melody
DIM SHARED AS _LIST_INFO      LI_WF_Library, LI_WF_Sample, LI_WF_Filter, LI_WF_Melody
DIM SHARED AS _LIST_INFO      LI_MSG_BAR_QUEUE, LI_LOG_ACTIONS
DIM SHARED AS IOS             WF_LIBRARY_UPDATED, PLAYING, CAPTURING, RECORDING
DIM SHARED AS F32             VOLUME_OUT = .5, VOLUME_IN = 1
DIM SHARED AS ANY             PTR MT_TUNINGS(2)
DIM SHARED AS _Tuning         Tunings(2)
'------------------------------------------------------------------------------------------------------------
#INCLUDE  ONCE "FRACTIONAID.bas"
#INCLUDE  ONCE "SYNTH.bas"
#INCLUDE  ONCE "ROUTINES.bas"
#INCLUDE  ONCE "CONTROLS.bas"
#INCLUDE  ONCE "GCONTROLS.bas"
#INCLUDE  ONCE "INTERFACE.bas"
'------------------------------------------------------------------------------------------------------------
'                             INITIALIZATION
'------------------------------------------------------------------------------------------------------------
REGISTER_THREAD(CTRL_THREAD_ID)

'HOMEPATH AND LOG FILE
#IFDEF DEVMODE
     HOMEPATH = EXEPATH 'DEV PATH
#ELSE
     'CHECK|CREATE MAIN DATA FOLDER
     IF CheckDir("Soundra",HOMEPATH) THEN ABORT_CODE = AC_PRIVILEGE
     HOMEPATH &= "\Soundra"
     'CHECK FOR BUNDLE COPY TO USER's FOLDER (USUALLY AT FIRST RUN)
     TMPSTR    = CURDIR
     IF CHDIR(HOMEPATH & "\SYNTHS")  <> 0 THEN DOCOPYBUNDLE OR= 1
     IF CHDIR(HOMEPATH & "\SYNTHS\DEMO " & SOFTWARE_VERSION) <> 0 THEN DOCOPYBUNDLE OR= 1
     IF CHDIR(HOMEPATH & "\TUNINGS") <> 0 THEN DOCOPYBUNDLE OR= 2
     CHDIR(TMPSTR)
#ENDIF
LOG_FILE_NUMBER = FREEFILE
OPEN HOMEPATH & "\SOUNDRA_LOG.TXT" FOR OUTPUT AS #LOG_FILE_NUMBER

'SETTINGS
NB_MONITORS = GetSystemMetrics(80)
R = LoadSettings()
IF R < 0 THEN LoadSettings(EXEPATH & "\lang.txt")

'LANGUAGE PACK
#IFDEF EN_LANGPACK
#INCLUDE ONCE "EN_LANGPACK_EXT.BAS"
IF SETTINGS.LANGUAGE > 0 THEN
     R = LOADLANGPACK(SETTINGS.LANGUAGE)
     IF R < 0 THEN 
          SETTINGS.LANGUAGE = 0
          TMPSTR  = "Could not find or load the selected language. Reverting to default (English). "
          TMPSTR &= ERR2TXT(R)
          TERMINAL(TMPSTR,MSG_ERROR)
     END IF
END IF
#ENDIF

'FOLDERS
IF CheckDir("AUDIO",HOMEPATH)           THEN ABORT_CODE = AC_PRIVILEGE
IF CheckDir("AUDIO\CONVERTED",HOMEPATH) THEN ABORT_CODE = AC_PRIVILEGE
IF CheckDir("AUDIO\RECORDED",HOMEPATH)  THEN ABORT_CODE = AC_PRIVILEGE
IF CheckDir("FILTERS",HOMEPATH)         THEN ABORT_CODE = AC_PRIVILEGE
IF CheckDir("MELODIES",HOMEPATH)        THEN ABORT_CODE = AC_PRIVILEGE
IF CheckDir("SYNTHS",HOMEPATH)          THEN ABORT_CODE = AC_PRIVILEGE
IF CheckDir("SYNTHS\DEMO " & SOFTWARE_VERSION,HOMEPATH) THEN ABORT_CODE = AC_PRIVILEGE
IF CheckDir("TUNINGS",HOMEPATH)         THEN ABORT_CODE = AC_PRIVILEGE
IF ABORT_CODE > AC_NONE THEN GOTO CLEAN_ENDING

ScanDrives(@DRIVES)

'COMPUTING CORES
NB_CORES = VALINT(ENVIRON("NUMBER_OF_PROCESSORS"))

'MESSAGE LOGGING SYSTEM
INITPP(ConsoleMSG,_CONSOLE_MSG,16)
TERMINAL = @MessageConsole

'REDUNDANT TEXT STRINGS FOR CTRL & GCTRL
'¤¤¤#116: "Turn audio output ON to activate keyboards."
TMPSTR = LNG_SET_EXT(116,"Turn audio output ON to activate keyboards.")
KB_MSG = TMPSTR
'¤¤¤#117: "[NO DEVICE]"
TMPSTR = LNG_SET_EXT(117,"[NO DEVICE]")
STR_DEV_NONE = TMPSTR
'¤¤¤#118: "[ANY FREE DEVICE]"
TMPSTR = LNG_SET_EXT(118,"[ANY FREE DEVICE]")
STR_DEV_ANY = TMPSTR
'¤¤¤#119: "[UNASSIGNED]"
TMPSTR = LNG_SET_EXT(119,"[UNASSIGNED]")
STR_DEV_NA = TMPSTR
'¤¤¤#120: "[CONTROL ANY SELECTION]"
TMPSTR = LNG_SET_EXT(120,"[CONTROL ANY SELECTION]")
STR_DEV_ANYCON = TMPSTR
'¤¤¤#121: "[INVALID ASSIGMENT]"
TMPSTR = LNG_SET_EXT(121,"[INVALID ASSIGMENT]")
STR_DEV_INVALID = TMPSTR

'STARTUP MESSAGES - VERSION, DATE, WELCOME, CORES
TMPSTR = "{$} v{$} {$}-bit"
TMPSTR = TXTINSERT(TMPSTR,SOFTWARE_NAME)
TMPSTR = TXTINSERT(TMPSTR,SOFTWARE_VERSION)
TMPSTR = TXTINSERT(TMPSTR,SOFTWARE_BIT)
IF SOFTWARE_STATUS <> "" THEN TMPSTR &= " (" & SOFTWARE_STATUS & ")"
TERMINAL(TMPSTR, MSG_NORMAL)
'¤¤¤#122: "Started on {$} at {$}"
TMPSTR = LNG_SET_EXT(122,"Started on {$} at {$}")
TMPSTR = TXTINSERT(TMPSTR,DATE)
TMPSTR = TXTINSERT(TMPSTR,TIME)
TERMINAL(TMPSTR, MSG_NORMAL)
'¤¤¤#123: "Welcome to"
TMPSTR = LNG_SET_EXT(123,"Welcome to")
TMPSTR &= " {$}, {$}!"
TMPSTR = TXTINSERT(TMPSTR,SOFTWARE_NAME)
USERNAME = UCASE(MID(USERNAME,1,1)) & MID(USERNAME,2)
TMPSTR = TXTINSERT(TMPSTR,USERNAME)
TERMINAL(TMPSTR, MSG_NORMAL)
'¤¤¤#124: "I've found {$} CPU cores, {$} drives and {$} MIDI devices."
TMPSTR = LNG_SET_EXT(124,"I've found {$} CPU cores, {$} drives and {$} MIDI devices.")
TMPSTR = TXTINSERT(TMPSTR,STR(nb_cores))
TMPSTR = TXTINSERT(TMPSTR,STR(DRIVES.NB_DRIVES))
TMPSTR = TXTINSERT(TMPSTR,STR(midiInGetNumDevs()))
TERMINAL(TMPSTR)

'COPY DEMOS ON FIRST RUN
BundleCopy(DOCOPYBUNDLE)

'ARGUMENTS (file to load or parameters)
FOR I = 0 TO NB_ARGUMENTS - 1
     CheckArg(*ARGUMENTS[I])
NEXT I

'MUTEXES
MT_TUNINGS(0) = MUTEXCREATE
MT_TUNINGS(1) = MUTEXCREATE
MT_TUNINGS(2) = MUTEXCREATE
IF (MT_TUNINGS(TUNING_COPY) = 0) OR (MT_TUNINGS(TUNING_CURRENT) = 0) OR (MT_TUNINGS(TUNING_MOD) = 0) THEN
   TERMINAL("MUTEXCREATE MT_TUNINGS(): " & ERR2TXT(_ECM),MSG_FATAL_ERROR)
   ABORT_CODE = AC_MEMORY
   GOTO CLEAN_ENDING
END IF

'MESSAGING
CTRL_MESSAGES = NEW THREAD_MESSAGE[16]
LI_CTRL_MESSAGES.LENGTH     = 0
LI_CTRL_MESSAGES.LENGTH_MAX = 16

'TUNINGS - DEFAULT
R = JIGSAW_MUSIC.INIT()
#INCLUDE "SCALE_MODES.bas"
IF NOT(FILEEXISTS(Tunings(0).FILEPATH & "\" & Tunings(0).FILENAME)) THEN
     R = SaveTuning(@Tunings(0))
     IF R THEN TERMINAL("SaveTuning(): " & ERR2TXT(r),MSG_ERROR)
END IF

'MIDI
MIDI_SUB = @MIDI_INPUT

'CATALOGS
INITPP(WF_Library,_WF_CATALOG,16)
INITPP(WF_Sample,_WF_CATALOG,16)
INITPP(WF_Filter,_WF_CATALOG,16)
INITPP(WF_Melody,_WF_CATALOG,16)
INITPP(LOG_ACTIONS,_TEXTLINE,16)

'AUDIO LIBRARY
AUTO_CONNECT       = SETTINGS.AUTO_CONNECT
USE_DEFAULT_DEVICE = SETTINGS.USE_DEFAULT
OUTPUT_DEVICE_NAME = SETTINGS.OUTPUT_DEVICE_NAME
INPUT_DEVICE_NAME  = SETTINGS.INPUT_DEVICE_NAME
R = JIGSAW_AUDIO.Init(@SOUNDRA.SYNTHESIZER, @SOUNDRA.CAPTURE_SUB, SETTINGS.SAMPLE_RATE/1000)
IF R THEN 
     TERMINAL("JIGSAW_AUDIO.init(): " & ERR2TXT(r), MSG_FATAL_ERROR)
     GOTO CLEAN_ENDING
END IF

'AUDIO FILE LIBRARY
'¤¤¤#125: "Loading audio library."
TMPSTR = LNG_SET_EXT(125,"Loading audio library.")
TERMINAL(TMPSTR)
     'LOAD
R = LoadWFLibrary()
IF R THEN 
     '¤¤¤#126: "Error while loading audio library: "
     TMPSTR = LNG_SET_EXT(126,"Error while loading audio library: ")
     TMPSTR &= ERR2TXT(R)
     TERMINAL(TMPSTR,MSG_ERROR)
END IF

'FILTERS
'¤¤¤#127: "Loading filters."
TMPSTR = LNG_SET_EXT(127,"Loading filters.")
TERMINAL(TMPSTR)
TMPSTR = HOMEPATH & "\FILTERS"
Browse(@FOLDER0,TMPSTR,".wav",TRUE,FALSE)
FOR I = 0 TO FOLDER0.LI_ITEM.LENGTH-1
     IF NOT(FOLDER0.GetAttr(I) AND fbDirectory) THEN LoadFilter(TMPSTR,FOLDER0.GetName(I))
NEXT I
Browse(@FOLDER0,HOMEPATH,"*.*",FALSE,FALSE)
'------------------------------------------------------------------------------------------------------------
'                             GRAPHICAL INTERFACE
'------------------------------------------------------------------------------------------------------------
ScreenControl FB.GET_DESKTOP_SIZE,DESK_W,DESK_H
'VISUAL LIBRARY
R = JIGSAW_VISUALS.Init(NB_WINDOWS, SETTINGS.SCREEN_WIDTH, SETTINGS.SCREEN_HEIGHT, SETTINGS.MONITORS)
IF R THEN 
     TERMINAL("JIGSAW_VISUALS.init(): " & ERR2TXT(r), MSG_FATAL_ERROR)
     GOTO CLEAN_ENDING
END IF
R = LOAD_FONTS("/FONTS/Sansation/Sansation_Bold.ttf", "/FONTS/Fontello/Soundra-Fontello.ttf")
IF R THEN GOTO CLEAN_ENDING
R = SET_GUI_SIZE()
IF R THEN
     TERMINAL("FreeType: " & ERR2TXT(r), MSG_FATAL_ERROR)
     GOTO CLEAN_ENDING
END IF

'SOUNDRA CORE
R = SOUNDRA.Init(SETTINGS.SAMPLE_RATE)
IF R THEN 
     TERMINAL("Soundra.init(): " & ERR2TXT(r), MSG_FATAL_ERROR)
     GOTO CLEAN_ENDING
END IF

'CONTROL & TEXTFIELD SHORTCUTS - ALLOCATE
ControlAccess = NEW I32[NB_CS]
TFAccess      = NEW I32[NB_TFN]

'WINDOW - TITLE, SCREENSET, SOUNDRA GRAPHICS, GUI, INIT
WIN_TITLE = SOFTWARE_NAME
WINDOWTITLE WIN_TITLE
Interface_PTR = SetScreen(8,SCR_W,SCR_H)
IF Interface_PTR = 0 THEN
     '¤¤¤#128: "I could not set the screen."
     TMPSTR = LNG_SET_EXT(128,"I could not set the screen.")
     TERMINAL(TMPSTR, MSG_FATAL_ERROR)
     ABORT_CODE = AC_GFX
     GOTO CLEAN_ENDING
END IF
ScreenControl FB.SET_WINDOW_POS,NULL_X,NULL_Y
ScrSet = TRUE
SOUNDRA.SET_SCOPE_SPRITES()

R = CreateInterface()
IF R THEN
     TERMINAL(ERR2TXT(R),MSG_ERROR)
     '¤¤¤#129: "The interface could not be completed."
     TMPSTR = LNG_SET_EXT(129,"The interface could not be completed.")
     TERMINAL(TMPSTR,MSG_FATAL_ERROR)
     ABORT_CODE = AC_GUI
     GOTO CLEAN_ENDING 
END IF

NAV_INITIALIZE()

SEL_NAV_CTRL_ID = NAV_SELECT_WINDOW(W_SYSBAR)

InterfaceSet = TRUE
Controls[0]->state.DISABLED = TRUE

'------------------------------------------------------------------------------------------------------------
'SLEEP RESOLUTION
SCOPE
    DIM AS TIMECAPS tc
    TimeGetDevCaps(@tc, SIZEOF(tc))
    TimeBeginPeriod(tc.wPeriodMin)
END SCOPE

'SYNTH - LOAD OR NEW, DISPLAY & SAVE SETTING
IF SETTINGS.SESSION_FILE <> "" THEN
     SETTINGS.SESSION_PATH = FindPath(SETTINGS.SESSION_PATH, SETTINGS.SESSION_FILE, "\SYNTH")
     IF SETTINGS.SESSION_PATH = "" THEN
          '¤¤¤#130: " could not be found."
          TMPSTR = LNG_SET_EXT(130," could not be found.")
          TMPSTR = SETTINGS.SESSION_FILE & TMPSTR
          TERMINAL(TMPSTR,MSG_WARNING)
          NEW_SESSION = TRUE
     ELSE
          '¤¤¤#131: "Loading synthesizer file."
          TMPSTR = LNG_SET_EXT(131,"Loading synthesizer file.")
          TERMINAL(TMPSTR)
          R = LoadSession(SETTINGS.SESSION_PATH,SETTINGS.SESSION_FILE)
          IF R THEN 
               '¤¤¤#132: " could not be opened: "
               TMPSTR = LNG_SET_EXT(132," could not be opened: ")
               TMPSTR = SETTINGS.SESSION_FILE & TMPSTR & ERR2TXT(R)
               TERMINAL(TMPSTR,MSG_ERROR)
               NEW_SESSION = TRUE
          END IF
     END IF
ELSE
     NEW_SESSION = TRUE
END IF

IF NEW_SESSION = TRUE THEN
     SETTINGS.SESSION_FILE = ""
     ctrl_new_synth(CA_CLICK,0,0,ControlAccess[CS_NEW_SYNTH],0)
     'Controls[ControlAccess[CS_NEW_SYNTH]]->UPDATE_GSTATE()
ELSE
     Controls[ControlAccess[CS_SESSION_TAB0]]->text.content = " " & SETTINGS.SESSION_NAME
     Controls[ControlAccess[CS_SESSION_TAB0]]->UPDATE_GTEXT()
END IF
     
IF SaveSettings() THEN
     '¤¤¤#134: "Error saving settings file: "
     TMPSTR = LNG_SET_EXT(134,"Error saving settings file: ")
     TMPSTR = TMPSTR & ERR2TXT(r)
     TERMINAL(TMPSTR,MSG_ERROR)
END IF

'VIDEO THREAD - LAUNCH
START_VIDEO_THREAD(TRUE)
IF VIDEO_THREAD_HDL > 0 THEN
     '¤¤¤#135: "Display driver is "
     TMPSTR = LNG_SET_EXT(135,"Display driver is ")
     TMPSTR &= DISPLAY_DRIVER_NAME(DisplayDriverNum)
     TERMINAL(TMPSTR)
END IF

'AUDIO THREAD - LAUNCH
r = StartAudio(JIGSAW_AUDIO.THREAD_HDL, SETTINGS.SAMPLE_RATE, SETTINGS.OUTPUT_BUFFER_LENGTH)
IF r THEN 
     '¤¤¤#137: "Audio thread startup error: "
     TMPSTR = LNG_SET_EXT(137,"Audio thread startup error: ")
     TMPSTR &= ERR2TXT(r)
     TERMINAL(TMPSTR,MSG_ERROR)
END IF

BOARDS_VIEW(TRUE)
ctrl_synth_center(CA_CLICK,0,0,0)
ctrl_update(ControlAccess[CS_SYNTH_CENTER])
Controls[0]->state.DISABLED = FALSE
INITOK = TRUE
'------------------------------------------------------------------------------------------------------------
'                             MAIN LOOP
'------------------------------------------------------------------------------------------------------------
CUSTOM_ACTIONS = @SOUNDRA_ACTIONS
INTERFACE_LOOP()
'------------------------------------------------------------------------------------------------------------
'                             TERMINATION
'------------------------------------------------------------------------------------------------------------
CLEAN_ENDING:

STOP_VIDEO_THREAD()

IF INITOK = FALSE  THEN IF ABORT_CODE = AC_NONE THEN ABORT_CODE = AC_INIT
IF ABORT_CODE > AC_NONE THEN 
     '¤¤¤#138: "Something went wrong during initialization. Check user credentials."
     TMPSTR = LNG_SET_EXT(138,"Something went wrong during initialization. Check user credentials.")
     TERMINAL(TMPSTR & " (Code " & STR(ABORT_CODE) & ")",MSG_FATAL_ERROR)
     SLEEP 2000
ELSE
     'SAVE SESSION
     IF (SOUNDRA.LI_MODULES.LENGTH > 0) ANDALSO (SETTINGS.AUTOSAVE = TRUE) THEN
          '¤¤¤#139: "Saving session."
          TMPSTR = LNG_SET_EXT(139,"Saving session.")
          TERMINAL(TMPSTR,MSG_NORMAL)
          R = SaveSession(SETTINGS.SESSION_PATH, SETTINGS.SESSION_FILE)
          IF R THEN TERMINAL(ERR2TXT(R),MSG_ERROR)
     END IF
     'SAVE LIBRARIES
     '¤¤¤#140: "Saving libraries."
     TMPSTR = LNG_SET_EXT(140,"Saving libraries.")
     TERMINAL(TMPSTR,MSG_NORMAL)
          'SAMPLE LIBRARY
     IF WF_LIBRARY_UPDATED = TRUE THEN
          WF_LIBRARY_UPDATED = FALSE
          R = SaveWFLibrary()
          IF R THEN TERMINAL("SaveWFLibrary(): " & ERR2TXT(R),MSG_ERROR)
     END IF
          'SAMPLES
     FOR I = 0 TO LI_WF_Sample.LENGTH-1
          IF WF_Sample[I]->ON_DISK = FALSE THEN SaveWF(WF_Sample[I])
     NEXT I
          'FILTERS
     FOR I = 0 TO LI_WF_Filter.LENGTH-1
          IF WF_Filter[I]->ON_DISK = FALSE THEN SaveWF(WF_Filter[I])
     NEXT I
          'MELODIES
     FOR I = 0 TO LI_WF_Melody.LENGTH-1
          IF WF_Melody[I]->ON_DISK = FALSE THEN SaveMelody(WF_Melody[I])
     NEXT I
END IF

'END AUDIO THREAD & LIBRARY
IF JIGSAW_AUDIO.THREAD_HDL > 0 THEN
     '¤¤¤#141: "Waiting for audio thread."
     TMPSTR = LNG_SET_EXT(141,"Waiting for audio thread.")
     TERMINAL(TMPSTR,MSG_NORMAL)
     CTRL_MSG.CODE = _END_THREAD
     SENDMTMSG(CTRL_MSG,JIGSAW_AUDIO.THREAD_ID)
     THREADWAIT(JIGSAW_AUDIO.THREAD_HDL)
     '¤¤¤#142: "Audio thread terminated."
     TMPSTR = LNG_SET_EXT(142,"Audio thread terminated.")
     TERMINAL(TMPSTR,MSG_NORMAL)
END IF

'DELETE DATA
'¤¤¤#143: "Cleaning memory."
TMPSTR = LNG_SET_EXT(143,"Cleaning memory.")
TERMINAL(TMPSTR,MSG_NORMAL)
     'CATALOGS
DELETEPP(ConsoleMSG)
DELETEPP(WF_Library)
DELETEPP(WF_Sample)
DELETEPP(WF_Filter)
DELETEPP(WF_Melody)
DELETEPP(LOG_ACTIONS)
DELETEPP(MSG_BAR_QUEUE)
IF CTRL_MESSAGES > 0 THEN DELETE[] CTRL_MESSAGES : CTRL_MESSAGES = 0
'--------------------------------------------
     'SYNTH CONNECTORS
FOR I = 0 TO 2
     IF CONNECTOR_SWATCH(I) > 0 THEN DELETE[] CONNECTOR_SWATCH(I)
     IF CONNECTOR_ENDING(I) > 0 THEN IMAGEDESTROY(CONNECTOR_ENDING(I))
NEXT I
     'MUTEXES
IF MT_TUNINGS(TUNING_COPY)    THEN MUTEXDESTROY(MT_TUNINGS(TUNING_COPY))
IF MT_TUNINGS(TUNING_CURRENT) THEN MUTEXDESTROY(MT_TUNINGS(TUNING_CURRENT))
IF MT_TUNINGS(TUNING_MOD)     THEN MUTEXDESTROY(MT_TUNINGS(TUNING_MOD))
'------------------------------------------------------------------------------------------------------------
'TERMINATE LIBRARIES
'¤¤¤#144: "Terminating"
TMPSTR = LNG_SET_EXT(144,"Terminating")
TERMINAL(TMPSTR & " JIGSAW_VISUALS")
JIGSAW_VISUALS.Terminate()
TERMINAL(TMPSTR & " JIGSAW_AUDIO")
JIGSAW_AUDIO.Terminate()
TERMINAL(TMPSTR & " SOUNDRA")
SOUNDRA.Terminate()
TERMINAL(TMPSTR & " JIGSAW_BASICS")
JIGSAW_BASICS.Terminate()
TERMINAL = @BASIC_TERMINAL
PRINT #LOG_FILE_NUMBER,"END|FIN"
CLOSE
PRINT "END|FIN - CLOSING TERMINAL IN:"
'#IFDEF DEVMODE
PRINT 2
SLEEP 1000
PRINT 1
SLEEP 1000
PRINT 0
'#ENDIF
'------------------------------------------------------------------------------------------------------------
'                             END OF PROGRAM
'------------------------------------------------------------------------------------------------------------