Formatting and typos (#1652)

* Formatting and typo fixes.

General formatting and typo fixes.

* Update STTS.lua

Keep class table on separate lines.
This commit is contained in:
TommyC81 2021-12-04 21:49:47 +04:00 committed by GitHub
parent 2ba5215036
commit 32deb160ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 2095 additions and 2260 deletions

View File

@ -11,7 +11,7 @@
-- --
-- DCS itself provides a lot of enumerators for various things. See [Enumerators](https://wiki.hoggitworld.com/view/Category:Enumerators) on Hoggit. -- DCS itself provides a lot of enumerators for various things. See [Enumerators](https://wiki.hoggitworld.com/view/Category:Enumerators) on Hoggit.
-- --
-- Other Moose classe also have enumerators. For example, the AIRBASE class has enumerators for airbase names. -- Other Moose classes also have enumerators. For example, the AIRBASE class has enumerators for airbase names.
-- --
-- @module ENUMS -- @module ENUMS
-- @image MOOSE.JPG -- @image MOOSE.JPG
@ -30,16 +30,16 @@ ENUMS = {}
-- @type ENUMS.ROE -- @type ENUMS.ROE
-- @field #number WeaponFree AI will engage any enemy group it detects. Target prioritization is based based on the threat of the target. -- @field #number WeaponFree AI will engage any enemy group it detects. Target prioritization is based based on the threat of the target.
-- @field #number OpenFireWeaponFree AI will engage any enemy group it detects, but will prioritize targets specified in the groups tasking. -- @field #number OpenFireWeaponFree AI will engage any enemy group it detects, but will prioritize targets specified in the groups tasking.
-- @field #number OpenFire AI will engage only targets specified in its taskings. -- @field #number OpenFire AI will engage only targets specified in its tasking.
-- @field #number ReturnFire AI will only engage threats that shoot first. -- @field #number ReturnFire AI will only engage threats that shoot first.
-- @field #number WeaponHold AI will hold fire under all circumstances. -- @field #number WeaponHold AI will hold fire under all circumstances.
ENUMS.ROE = { ENUMS.ROE = {
WeaponFree=0, WeaponFree = 0,
OpenFireWeaponFree=1, OpenFireWeaponFree = 1,
OpenFire=2, OpenFire = 2,
ReturnFire=3, ReturnFire = 3,
WeaponHold=4, WeaponHold = 4,
} }
--- Reaction On Threat. --- Reaction On Threat.
-- @type ENUMS.ROT -- @type ENUMS.ROT
@ -49,11 +49,11 @@ ENUMS.ROE = {
-- @field #number BypassAndEscape AI will attempt to avoid enemy threat zones all together. This includes attempting to fly above or around threats. -- @field #number BypassAndEscape AI will attempt to avoid enemy threat zones all together. This includes attempting to fly above or around threats.
-- @field #number AllowAbortMission If a threat is deemed severe enough the AI will abort its mission and return to base. -- @field #number AllowAbortMission If a threat is deemed severe enough the AI will abort its mission and return to base.
ENUMS.ROT = { ENUMS.ROT = {
NoReaction=0, NoReaction = 0,
PassiveDefense=1, PassiveDefense = 1,
EvadeFire=2, EvadeFire = 2,
BypassAndEscape=3, BypassAndEscape = 3,
AllowAbortMission=4, AllowAbortMission = 4,
} }
--- Alarm state. --- Alarm state.
@ -62,12 +62,12 @@ ENUMS.ROT = {
-- @field #number Green Group is not combat ready. Sensors are stowed if possible. -- @field #number Green Group is not combat ready. Sensors are stowed if possible.
-- @field #number Red Group is combat ready and actively searching for targets. Some groups like infantry will not move in this state. -- @field #number Red Group is combat ready and actively searching for targets. Some groups like infantry will not move in this state.
ENUMS.AlarmState = { ENUMS.AlarmState = {
Auto=0, Auto = 0,
Green=1, Green = 1,
Red=2, Red = 2,
} }
--- Weapon types. See the [Weapon Flag](https://wiki.hoggitworld.com/view/DCS_enum_weapon_flag) enumerotor on hoggit wiki. --- Weapon types. See the [Weapon Flag](https://wiki.hoggitworld.com/view/DCS_enum_weapon_flag) enumerator on Hoggit wiki.
-- @type ENUMS.WeaponFlag -- @type ENUMS.WeaponFlag
ENUMS.WeaponFlag={ ENUMS.WeaponFlag={
-- Bombs -- Bombs
@ -111,7 +111,7 @@ ENUMS.WeaponFlag={
-- --
-- Bombs -- Bombs
GuidedBomb = 14, -- (LGB + TvGB + SNSGB) GuidedBomb = 14, -- (LGB + TvGB + SNSGB)
AnyUnguidedBomb = 2147485680, -- (HeBomb + Penetrator + NapalmBomb + FAEBomb + ClusterBomb + Dispencer + CandleBomb + ParachuteBomb) AnyUnguidedBomb = 2147485680, -- (HeBomb + Penetrator + NapalmBomb + FAEBomb + ClusterBomb + Dispenser + CandleBomb + ParachuteBomb)
AnyBomb = 2147485694, -- (GuidedBomb + AnyUnguidedBomb) AnyBomb = 2147485694, -- (GuidedBomb + AnyUnguidedBomb)
--- Rockets --- Rockets
AnyRocket = 30720, -- LightRocket + MarkerRocket + CandleRocket + HeavyRocket AnyRocket = 30720, -- LightRocket + MarkerRocket + CandleRocket + HeavyRocket
@ -173,7 +173,7 @@ ENUMS.MissionTask={
TRANSPORT="Transport", TRANSPORT="Transport",
} }
--- Formations (new). See the [Formations](https://wiki.hoggitworld.com/view/DCS_enum_formation) on hoggit wiki. --- Formations (new). See the [Formations](https://wiki.hoggitworld.com/view/DCS_enum_formation) on Hoggit wiki.
-- @type ENUMS.Formation -- @type ENUMS.Formation
ENUMS.Formation={} ENUMS.Formation={}
ENUMS.Formation.FixedWing={} ENUMS.Formation.FixedWing={}
@ -216,23 +216,23 @@ ENUMS.Formation.FixedWing.FighterVic.Close = 917505
ENUMS.Formation.FixedWing.FighterVic.Open = 917506 ENUMS.Formation.FixedWing.FighterVic.Open = 917506
ENUMS.Formation.RotaryWing={} ENUMS.Formation.RotaryWing={}
ENUMS.Formation.RotaryWing.Column={} ENUMS.Formation.RotaryWing.Column={}
ENUMS.Formation.RotaryWing.Column.D70=720896 ENUMS.Formation.RotaryWing.Column.D70 = 720896
ENUMS.Formation.RotaryWing.Wedge={} ENUMS.Formation.RotaryWing.Wedge={}
ENUMS.Formation.RotaryWing.Wedge.D70=8 ENUMS.Formation.RotaryWing.Wedge.D70 = 8
ENUMS.Formation.RotaryWing.FrontRight={} ENUMS.Formation.RotaryWing.FrontRight={}
ENUMS.Formation.RotaryWing.FrontRight.D300=655361 ENUMS.Formation.RotaryWing.FrontRight.D300 = 655361
ENUMS.Formation.RotaryWing.FrontRight.D600=655362 ENUMS.Formation.RotaryWing.FrontRight.D600 = 655362
ENUMS.Formation.RotaryWing.FrontLeft={} ENUMS.Formation.RotaryWing.FrontLeft={}
ENUMS.Formation.RotaryWing.FrontLeft.D300=655617 ENUMS.Formation.RotaryWing.FrontLeft.D300 = 655617
ENUMS.Formation.RotaryWing.FrontLeft.D600=655618 ENUMS.Formation.RotaryWing.FrontLeft.D600 = 655618
ENUMS.Formation.RotaryWing.EchelonRight={} ENUMS.Formation.RotaryWing.EchelonRight={}
ENUMS.Formation.RotaryWing.EchelonRight.D70 =589825 ENUMS.Formation.RotaryWing.EchelonRight.D70 = 589825
ENUMS.Formation.RotaryWing.EchelonRight.D300=589826 ENUMS.Formation.RotaryWing.EchelonRight.D300 = 589826
ENUMS.Formation.RotaryWing.EchelonRight.D600=589827 ENUMS.Formation.RotaryWing.EchelonRight.D600 = 589827
ENUMS.Formation.RotaryWing.EchelonLeft={} ENUMS.Formation.RotaryWing.EchelonLeft={}
ENUMS.Formation.RotaryWing.EchelonLeft.D70 =590081 ENUMS.Formation.RotaryWing.EchelonLeft.D70 = 590081
ENUMS.Formation.RotaryWing.EchelonLeft.D300=590082 ENUMS.Formation.RotaryWing.EchelonLeft.D300 = 590082
ENUMS.Formation.RotaryWing.EchelonLeft.D600=590083 ENUMS.Formation.RotaryWing.EchelonLeft.D600 = 590083
ENUMS.Formation.Vehicle={} ENUMS.Formation.Vehicle={}
ENUMS.Formation.Vehicle.Vee="Vee" ENUMS.Formation.Vehicle.Vee="Vee"
ENUMS.Formation.Vehicle.EchelonRight="EchelonR" ENUMS.Formation.Vehicle.EchelonRight="EchelonR"
@ -244,25 +244,25 @@ ENUMS.Formation.Vehicle.Cone="Cone"
ENUMS.Formation.Vehicle.Diamond="Diamond" ENUMS.Formation.Vehicle.Diamond="Diamond"
--- Formations (old). The old format is a simplified version of the new formation enums, which allow more sophisticated settings. --- Formations (old). The old format is a simplified version of the new formation enums, which allow more sophisticated settings.
-- See the [Formations](https://wiki.hoggitworld.com/view/DCS_enum_formation) on hoggit wiki. -- See the [Formations](https://wiki.hoggitworld.com/view/DCS_enum_formation) on Hoggit wiki.
-- @type ENUMS.FormationOld -- @type ENUMS.FormationOld
ENUMS.FormationOld={} ENUMS.FormationOld={}
ENUMS.FormationOld.FixedWing={} ENUMS.FormationOld.FixedWing={}
ENUMS.FormationOld.FixedWing.LineAbreast=1 ENUMS.FormationOld.FixedWing.LineAbreast = 1
ENUMS.FormationOld.FixedWing.Trail=2 ENUMS.FormationOld.FixedWing.Trail = 2
ENUMS.FormationOld.FixedWing.Wedge=3 ENUMS.FormationOld.FixedWing.Wedge = 3
ENUMS.FormationOld.FixedWing.EchelonRight=4 ENUMS.FormationOld.FixedWing.EchelonRight = 4
ENUMS.FormationOld.FixedWing.EchelonLeft=5 ENUMS.FormationOld.FixedWing.EchelonLeft = 5
ENUMS.FormationOld.FixedWing.FingerFour=6 ENUMS.FormationOld.FixedWing.FingerFour = 6
ENUMS.FormationOld.FixedWing.SpreadFour=7 ENUMS.FormationOld.FixedWing.SpreadFour = 7
ENUMS.FormationOld.FixedWing.BomberElement=12 ENUMS.FormationOld.FixedWing.BomberElement = 12
ENUMS.FormationOld.FixedWing.BomberElementHeight=13 ENUMS.FormationOld.FixedWing.BomberElementHeight = 13
ENUMS.FormationOld.FixedWing.FighterVic=14 ENUMS.FormationOld.FixedWing.FighterVic = 14
ENUMS.FormationOld.RotaryWing={} ENUMS.FormationOld.RotaryWing={}
ENUMS.FormationOld.RotaryWing.Wedge=8 ENUMS.FormationOld.RotaryWing.Wedge = 8
ENUMS.FormationOld.RotaryWing.Echelon=9 ENUMS.FormationOld.RotaryWing.Echelon = 9
ENUMS.FormationOld.RotaryWing.Front=10 ENUMS.FormationOld.RotaryWing.Front = 10
ENUMS.FormationOld.RotaryWing.Column=11 ENUMS.FormationOld.RotaryWing.Column = 11
--- Morse Code. See the [Wikipedia](https://en.wikipedia.org/wiki/Morse_code). --- Morse Code. See the [Wikipedia](https://en.wikipedia.org/wiki/Morse_code).

View File

@ -9,7 +9,6 @@
-- @module Utilities.PROFILER -- @module Utilities.PROFILER
-- @image MOOSE.JPG -- @image MOOSE.JPG
--- PROFILER class. --- PROFILER class.
-- @type PROFILER -- @type PROFILER
-- @field #string ClassName Name of the class. -- @field #string ClassName Name of the class.
@ -25,7 +24,6 @@
-- @field #number ThreshTtot Total time threshold. Only write output if total function CPU time is more than this value. -- @field #number ThreshTtot Total time threshold. Only write output if total function CPU time is more than this value.
-- @field #string fileNamePrefix Output file name prefix, e.g. "MooseProfiler". -- @field #string fileNamePrefix Output file name prefix, e.g. "MooseProfiler".
-- @field #string fileNameSuffix Output file name prefix, e.g. "txt" -- @field #string fileNameSuffix Output file name prefix, e.g. "txt"
--- *The emperor counsels simplicity. First principles. Of each particular thing, ask: What is it in itself, in its own constitution? What is its causal nature? * --- *The emperor counsels simplicity. First principles. Of each particular thing, ask: What is it in itself, in its own constitution? What is its causal nature? *
-- --
-- === -- ===
@ -35,12 +33,11 @@
-- # The PROFILER Concept -- # The PROFILER Concept
-- --
-- Profile your lua code. This tells you, which functions are called very often and which consume most real time. -- Profile your lua code. This tells you, which functions are called very often and which consume most real time.
-- With this information you can optimize the perfomance of your code. -- With this information you can optimize the performance of your code.
-- --
-- # Prerequisites -- # Prerequisites
-- --
-- The modules **os** and **lfs** need to be desanizied. -- The modules **os** and **lfs** need to be de-sanitized.
--
-- --
-- # Start -- # Start
-- --
@ -117,61 +114,60 @@ PROFILER = {
--- Start profiler. --- Start profiler.
-- @param #number Delay Delay in seconds before profiler is stated. Default is immediately. -- @param #number Delay Delay in seconds before profiler is stated. Default is immediately.
-- @param #number Duration Duration in (game) seconds before the profiler is stopped. Default is when mission ends. -- @param #number Duration Duration in (game) seconds before the profiler is stopped. Default is when mission ends.
function PROFILER.Start(Delay, Duration) function PROFILER.Start( Delay, Duration )
-- Check if os, io and lfs are available. -- Check if os, io and lfs are available.
local go=true local go = true
if not os then if not os then
env.error("ERROR: Profiler needs os to be desanitized!") env.error( "ERROR: Profiler needs os to be de-sanitized!" )
go=false go = false
end end
if not io then if not io then
env.error("ERROR: Profiler needs io to be desanitized!") env.error( "ERROR: Profiler needs io to be de-sanitized!" )
go=false go = false
end end
if not lfs then if not lfs then
env.error("ERROR: Profiler needs lfs to be desanitized!") env.error( "ERROR: Profiler needs lfs to be de-sanitized!" )
go=false go = false
end end
if not go then if not go then
return return
end end
if Delay and Delay>0 then if Delay and Delay > 0 then
BASE:ScheduleOnce(Delay, PROFILER.Start, 0, Duration) BASE:ScheduleOnce( Delay, PROFILER.Start, 0, Duration )
else else
-- Set start time. -- Set start time.
PROFILER.TstartGame=timer.getTime() PROFILER.TstartGame = timer.getTime()
PROFILER.TstartOS=os.clock() PROFILER.TstartOS = os.clock()
-- Add event handler. -- Add event handler.
world.addEventHandler(PROFILER.eventHandler) world.addEventHandler( PROFILER.eventHandler )
-- Info in log. -- Info in log.
env.info('############################ Profiler Started ############################') env.info( '############################ Profiler Started ############################' )
if Duration then if Duration then
env.info(string.format("- Will be running for %d seconds", Duration)) env.info( string.format( "- Will be running for %d seconds", Duration ) )
else else
env.info(string.format("- Will be stopped when mission ends")) env.info( string.format( "- Will be stopped when mission ends" ) )
end end
env.info(string.format("- Calls per second threshold %.3f/sec", PROFILER.ThreshCPS)) env.info( string.format( "- Calls per second threshold %.3f/sec", PROFILER.ThreshCPS ) )
env.info(string.format("- Total function time threshold %.3f sec", PROFILER.ThreshTtot)) env.info( string.format( "- Total function time threshold %.3f sec", PROFILER.ThreshTtot ) )
env.info(string.format("- Output file \"%s\" in your DCS log file folder", PROFILER.getfilename(PROFILER.fileNameSuffix))) env.info( string.format( "- Output file \"%s\" in your DCS log file folder", PROFILER.getfilename( PROFILER.fileNameSuffix ) ) )
env.info(string.format("- Output file \"%s\" in CSV format", PROFILER.getfilename("csv"))) env.info( string.format( "- Output file \"%s\" in CSV format", PROFILER.getfilename( "csv" ) ) )
env.info('###############################################################################') env.info( '###############################################################################' )
-- Message on screen -- Message on screen
local duration=Duration or 600 local duration = Duration or 600
trigger.action.outText("### Profiler running ###", duration) trigger.action.outText( "### Profiler running ###", duration )
-- Set hook. -- Set hook.
debug.sethook(PROFILER.hook, "cr") debug.sethook( PROFILER.hook, "cr" )
-- Auto stop profiler. -- Auto stop profiler.
if Duration then if Duration then
PROFILER.Stop(Duration) PROFILER.Stop( Duration )
end end
end end
@ -180,34 +176,33 @@ end
--- Stop profiler. --- Stop profiler.
-- @param #number Delay Delay before stop in seconds. -- @param #number Delay Delay before stop in seconds.
function PROFILER.Stop(Delay) function PROFILER.Stop( Delay )
if Delay and Delay>0 then if Delay and Delay > 0 then
BASE:ScheduleOnce(Delay, PROFILER.Stop) BASE:ScheduleOnce( Delay, PROFILER.Stop )
else else
-- Remove hook. -- Remove hook.
debug.sethook() debug.sethook()
-- Run time game. -- Run time game.
local runTimeGame=timer.getTime()-PROFILER.TstartGame local runTimeGame = timer.getTime() - PROFILER.TstartGame
-- Run time real OS. -- Run time real OS.
local runTimeOS=os.clock()-PROFILER.TstartOS local runTimeOS = os.clock() - PROFILER.TstartOS
-- Show info. -- Show info.
PROFILER.showInfo(runTimeGame, runTimeOS) PROFILER.showInfo( runTimeGame, runTimeOS )
end end
end end
--- Event handler. --- Event handler.
function PROFILER.eventHandler:onEvent(event) function PROFILER.eventHandler:onEvent( event )
if event.id==world.event.S_EVENT_MISSION_END then if event.id == world.event.S_EVENT_MISSION_END then
PROFILER.Stop() PROFILER.Stop()
end end
end end
@ -218,34 +213,34 @@ end
--- Debug hook. --- Debug hook.
-- @param #table event Event. -- @param #table event Event.
function PROFILER.hook(event) function PROFILER.hook( event )
local f=debug.getinfo(2, "f").func local f = debug.getinfo( 2, "f" ).func
if event=='call' then if event == 'call' then
if PROFILER.Counters[f]==nil then if PROFILER.Counters[f] == nil then
PROFILER.Counters[f]=1 PROFILER.Counters[f] = 1
PROFILER.dInfo[f]=debug.getinfo(2,"Sn") PROFILER.dInfo[f] = debug.getinfo( 2, "Sn" )
if PROFILER.fTimeTotal[f]==nil then if PROFILER.fTimeTotal[f] == nil then
PROFILER.fTimeTotal[f]=0 PROFILER.fTimeTotal[f] = 0
end end
else else
PROFILER.Counters[f]=PROFILER.Counters[f]+1 PROFILER.Counters[f] = PROFILER.Counters[f] + 1
end end
if PROFILER.fTime[f]==nil then if PROFILER.fTime[f] == nil then
PROFILER.fTime[f]=os.clock() PROFILER.fTime[f] = os.clock()
end end
elseif (event=='return') then elseif (event == 'return') then
if PROFILER.fTime[f]~=nil then if PROFILER.fTime[f] ~= nil then
PROFILER.fTimeTotal[f]=PROFILER.fTimeTotal[f]+(os.clock()-PROFILER.fTime[f]) PROFILER.fTimeTotal[f] = PROFILER.fTimeTotal[f] + (os.clock() - PROFILER.fTime[f])
PROFILER.fTime[f]=nil PROFILER.fTime[f] = nil
end end
end end
@ -262,11 +257,11 @@ end
-- @return #string Source file name. -- @return #string Source file name.
-- @return #string Line number. -- @return #string Line number.
-- @return #number Function time in seconds. -- @return #number Function time in seconds.
function PROFILER.getData(func) function PROFILER.getData( func )
local n=PROFILER.dInfo[func] local n = PROFILER.dInfo[func]
if n.what=="C" then if n.what == "C" then
return n.name, "?", "?", PROFILER.fTimeTotal[func] return n.name, "?", "?", PROFILER.fTimeTotal[func]
end end
@ -276,31 +271,31 @@ end
--- Write text to log file. --- Write text to log file.
-- @param #function f The file. -- @param #function f The file.
-- @param #string txt The text. -- @param #string txt The text.
function PROFILER._flog(f, txt) function PROFILER._flog( f, txt )
f:write(txt.."\r\n") f:write( txt .. "\r\n" )
end end
--- Show table. --- Show table.
-- @param #table data Data table. -- @param #table data Data table.
-- @param #function f The file. -- @param #function f The file.
-- @param #number runTimeGame Game run time in seconds. -- @param #number runTimeGame Game run time in seconds.
function PROFILER.showTable(data, f, runTimeGame) function PROFILER.showTable( data, f, runTimeGame )
-- Loop over data. -- Loop over data.
for i=1, #data do for i = 1, #data do
local t=data[i] --#PROFILER.Data local t = data[i] -- #PROFILER.Data
-- Calls per second. -- Calls per second.
local cps=t.count/runTimeGame local cps = t.count / runTimeGame
local threshCPS=cps>=PROFILER.ThreshCPS local threshCPS = cps >= PROFILER.ThreshCPS
local threshTot=t.tm>=PROFILER.ThreshTtot local threshTot = t.tm >= PROFILER.ThreshTtot
if threshCPS and threshTot then if threshCPS and threshTot then
-- Output -- Output
local text=string.format("%30s: %8d calls %8.1f/sec - Time Total %8.3f sec (%.3f %%) %5.3f sec/call %s line %s", t.func, t.count, cps, t.tm, t.tm/runTimeGame*100, t.tm/t.count, tostring(t.src), tostring(t.line)) local text = string.format( "%30s: %8d calls %8.1f/sec - Time Total %8.3f sec (%.3f %%) %5.3f sec/call %s line %s", t.func, t.count, cps, t.tm, t.tm / runTimeGame * 100, t.tm / t.count, tostring( t.src ), tostring( t.line ) )
PROFILER._flog(f, text) PROFILER._flog( f, text )
end end
end end
@ -310,26 +305,26 @@ end
--- Print csv file. --- Print csv file.
-- @param #table data Data table. -- @param #table data Data table.
-- @param #number runTimeGame Game run time in seconds. -- @param #number runTimeGame Game run time in seconds.
function PROFILER.printCSV(data, runTimeGame) function PROFILER.printCSV( data, runTimeGame )
-- Output file. -- Output file.
local file=PROFILER.getfilename("csv") local file = PROFILER.getfilename( "csv" )
local g=io.open(file, 'w') local g = io.open( file, 'w' )
-- Header. -- Header.
local text="Function,Total Calls,Calls per Sec,Total Time,Total in %,Sec per Call,Source File;Line Number," local text = "Function,Total Calls,Calls per Sec,Total Time,Total in %,Sec per Call,Source File;Line Number,"
g:write(text.."\r\n") g:write( text .. "\r\n" )
-- Loop over data. -- Loop over data.
for i=1, #data do for i = 1, #data do
local t=data[i] --#PROFILER.Data local t = data[i] -- #PROFILER.Data
-- Calls per second. -- Calls per second.
local cps=t.count/runTimeGame local cps = t.count / runTimeGame
-- Output -- Output
local txt=string.format("%s,%d,%.1f,%.3f,%.3f,%.3f,%s,%s,", t.func, t.count, cps, t.tm, t.tm/runTimeGame*100, t.tm/t.count, tostring(t.src), tostring(t.line)) local txt = string.format( "%s,%d,%.1f,%.3f,%.3f,%.3f,%s,%s,", t.func, t.count, cps, t.tm, t.tm / runTimeGame * 100, t.tm / t.count, tostring( t.src ), tostring( t.line ) )
g:write(txt.."\r\n") g:write( txt .. "\r\n" )
end end
@ -337,27 +332,26 @@ function PROFILER.printCSV(data, runTimeGame)
g:close() g:close()
end end
--- Write info to output file. --- Write info to output file.
-- @param #string ext Extension. -- @param #string ext Extension.
-- @return #string File name. -- @return #string File name.
function PROFILER.getfilename(ext) function PROFILER.getfilename( ext )
local dir=lfs.writedir()..[[Logs\]] local dir = lfs.writedir() .. [[Logs\]]
ext=ext or PROFILER.fileNameSuffix ext = ext or PROFILER.fileNameSuffix
local file=dir..PROFILER.fileNamePrefix.."."..ext local file = dir .. PROFILER.fileNamePrefix .. "." .. ext
if not UTILS.FileExists(file) then if not UTILS.FileExists( file ) then
return file return file
end end
for i=1,999 do for i = 1, 999 do
local file=string.format("%s%s-%03d.%s", dir,PROFILER.fileNamePrefix, i, ext) local file = string.format( "%s%s-%03d.%s", dir, PROFILER.fileNamePrefix, i, ext )
if not UTILS.FileExists(file) then if not UTILS.FileExists( file ) then
return file return file
end end
@ -368,81 +362,76 @@ end
--- Write info to output file. --- Write info to output file.
-- @param #number runTimeGame Game time in seconds. -- @param #number runTimeGame Game time in seconds.
-- @param #number runTimeOS OS time in seconds. -- @param #number runTimeOS OS time in seconds.
function PROFILER.showInfo(runTimeGame, runTimeOS) function PROFILER.showInfo( runTimeGame, runTimeOS )
-- Output file. -- Output file.
local file=PROFILER.getfilename(PROFILER.fileNameSuffix) local file = PROFILER.getfilename( PROFILER.fileNameSuffix )
local f=io.open(file, 'w') local f = io.open( file, 'w' )
-- Gather data. -- Gather data.
local Ttot=0 local Ttot = 0
local Calls=0 local Calls = 0
local t={} local t = {}
local tcopy=nil --#PROFILER.Data local tcopy = nil -- #PROFILER.Data
local tserialize=nil --#PROFILER.Data local tserialize = nil -- #PROFILER.Data
local tforgen=nil --#PROFILER.Data local tforgen = nil -- #PROFILER.Data
local tpairs=nil --#PROFILER.Data local tpairs = nil -- #PROFILER.Data
for func, count in pairs( PROFILER.Counters ) do
for func, count in pairs(PROFILER.Counters) do local s, src, line, tm = PROFILER.getData( func )
local s,src,line,tm=PROFILER.getData(func) if PROFILER.logUnknown == true then
if s == nil then
if PROFILER.logUnknown==true then s = "<Unknown>"
if s==nil then s="<Unknown>" end end
end end
if s~=nil then if s ~= nil then
-- Profile data. -- Profile data.
local T= local T = { func = s, src = src, line = line, count = count, tm = tm } -- #PROFILER.Data
{ func=s,
src=src,
line=line,
count=count,
tm=tm,
} --#PROFILER.Data
-- Collect special cases. Somehow, e.g. "_copy" appears multiple times so we try to gather all data. -- Collect special cases. Somehow, e.g. "_copy" appears multiple times so we try to gather all data.
if s=="_copy" then if s == "_copy" then
if tcopy==nil then if tcopy == nil then
tcopy=T tcopy = T
else else
tcopy.count=tcopy.count+T.count tcopy.count = tcopy.count + T.count
tcopy.tm=tcopy.tm+T.tm tcopy.tm = tcopy.tm + T.tm
end end
elseif s=="_Serialize" then elseif s == "_Serialize" then
if tserialize==nil then if tserialize == nil then
tserialize=T tserialize = T
else else
tserialize.count=tserialize.count+T.count tserialize.count = tserialize.count + T.count
tserialize.tm=tserialize.tm+T.tm tserialize.tm = tserialize.tm + T.tm
end end
elseif s=="(for generator)" then elseif s == "(for generator)" then
if tforgen==nil then if tforgen == nil then
tforgen=T tforgen = T
else else
tforgen.count=tforgen.count+T.count tforgen.count = tforgen.count + T.count
tforgen.tm=tforgen.tm+T.tm tforgen.tm = tforgen.tm + T.tm
end end
elseif s=="pairs" then elseif s == "pairs" then
if tpairs==nil then if tpairs == nil then
tpairs=T tpairs = T
else else
tpairs.count=tpairs.count+T.count tpairs.count = tpairs.count + T.count
tpairs.tm=tpairs.tm+T.tm tpairs.tm = tpairs.tm + T.tm
end end
else else
table.insert(t, T) table.insert( t, T )
end end
-- Total function time. -- Total function time.
Ttot=Ttot+tm Ttot = Ttot + tm
-- Total number of calls. -- Total number of calls.
Calls=Calls+count Calls = Calls + count
end end
@ -450,90 +439,95 @@ function PROFILER.showInfo(runTimeGame, runTimeOS)
-- Add special cases. -- Add special cases.
if tcopy then if tcopy then
table.insert(t, tcopy) table.insert( t, tcopy )
end end
if tserialize then if tserialize then
table.insert(t, tserialize) table.insert( t, tserialize )
end end
if tforgen then if tforgen then
table.insert(t, tforgen) table.insert( t, tforgen )
end end
if tpairs then if tpairs then
table.insert(t, tpairs) table.insert( t, tpairs )
end end
env.info('############################ Profiler Stopped ############################') env.info( '############################ Profiler Stopped ############################' )
env.info(string.format("* Runtime Game : %s = %d sec", UTILS.SecondsToClock(runTimeGame, true), runTimeGame)) env.info( string.format( "* Runtime Game : %s = %d sec", UTILS.SecondsToClock( runTimeGame, true ), runTimeGame ) )
env.info(string.format("* Runtime Real : %s = %d sec", UTILS.SecondsToClock(runTimeOS, true), runTimeOS)) env.info( string.format( "* Runtime Real : %s = %d sec", UTILS.SecondsToClock( runTimeOS, true ), runTimeOS ) )
env.info(string.format("* Function time : %s = %.1f sec (%.1f percent of runtime game)", UTILS.SecondsToClock(Ttot, true), Ttot, Ttot/runTimeGame*100)) env.info( string.format( "* Function time : %s = %.1f sec (%.1f percent of runtime game)", UTILS.SecondsToClock( Ttot, true ), Ttot, Ttot / runTimeGame * 100 ) )
env.info(string.format("* Total functions : %d", #t)) env.info( string.format( "* Total functions : %d", #t ) )
env.info(string.format("* Total func calls : %d", Calls)) env.info( string.format( "* Total func calls : %d", Calls ) )
env.info(string.format("* Writing to file : \"%s\"", file)) env.info( string.format( "* Writing to file : \"%s\"", file ) )
env.info(string.format("* Writing to file : \"%s\"", PROFILER.getfilename("csv"))) env.info( string.format( "* Writing to file : \"%s\"", PROFILER.getfilename( "csv" ) ) )
env.info("##############################################################################") env.info( "##############################################################################" )
-- Sort by total time. -- Sort by total time.
table.sort(t, function(a,b) return a.tm>b.tm end) table.sort( t, function( a, b )
return a.tm > b.tm
end )
-- Write data. -- Write data.
PROFILER._flog(f,"") PROFILER._flog( f, "" )
PROFILER._flog(f,"************************************************************************************************************************") PROFILER._flog( f, "************************************************************************************************************************" )
PROFILER._flog(f,"************************************************************************************************************************") PROFILER._flog( f, "************************************************************************************************************************" )
PROFILER._flog(f,"************************************************************************************************************************") PROFILER._flog( f, "************************************************************************************************************************" )
PROFILER._flog(f,"") PROFILER._flog( f, "" )
PROFILER._flog(f,"-------------------------") PROFILER._flog( f, "-------------------------" )
PROFILER._flog(f,"---- Profiler Report ----") PROFILER._flog( f, "---- Profiler Report ----" )
PROFILER._flog(f,"-------------------------") PROFILER._flog( f, "-------------------------" )
PROFILER._flog(f,"") PROFILER._flog( f, "" )
PROFILER._flog(f,string.format("* Runtime Game : %s = %.1f sec", UTILS.SecondsToClock(runTimeGame, true), runTimeGame)) PROFILER._flog( f, string.format( "* Runtime Game : %s = %.1f sec", UTILS.SecondsToClock( runTimeGame, true ), runTimeGame ) )
PROFILER._flog(f,string.format("* Runtime Real : %s = %.1f sec", UTILS.SecondsToClock(runTimeOS, true), runTimeOS)) PROFILER._flog( f, string.format( "* Runtime Real : %s = %.1f sec", UTILS.SecondsToClock( runTimeOS, true ), runTimeOS ) )
PROFILER._flog(f,string.format("* Function time : %s = %.1f sec (%.1f %% of runtime game)", UTILS.SecondsToClock(Ttot, true), Ttot, Ttot/runTimeGame*100)) PROFILER._flog( f, string.format( "* Function time : %s = %.1f sec (%.1f %% of runtime game)", UTILS.SecondsToClock( Ttot, true ), Ttot, Ttot / runTimeGame * 100 ) )
PROFILER._flog(f,"") PROFILER._flog( f, "" )
PROFILER._flog(f,string.format("* Total functions = %d", #t)) PROFILER._flog( f, string.format( "* Total functions = %d", #t ) )
PROFILER._flog(f,string.format("* Total func calls = %d", Calls)) PROFILER._flog( f, string.format( "* Total func calls = %d", Calls ) )
PROFILER._flog(f,"") PROFILER._flog( f, "" )
PROFILER._flog(f,string.format("* Calls per second threshold = %.3f/sec", PROFILER.ThreshCPS)) PROFILER._flog( f, string.format( "* Calls per second threshold = %.3f/sec", PROFILER.ThreshCPS ) )
PROFILER._flog(f,string.format("* Total func time threshold = %.3f sec", PROFILER.ThreshTtot)) PROFILER._flog( f, string.format( "* Total func time threshold = %.3f sec", PROFILER.ThreshTtot ) )
PROFILER._flog(f,"") PROFILER._flog( f, "" )
PROFILER._flog(f,"************************************************************************************************************************") PROFILER._flog( f, "************************************************************************************************************************" )
PROFILER._flog(f,"") PROFILER._flog( f, "" )
PROFILER.showTable(t, f, runTimeGame) PROFILER.showTable( t, f, runTimeGame )
-- Sort by number of calls. -- Sort by number of calls.
table.sort(t, function(a,b) return a.tm/a.count>b.tm/b.count end) table.sort( t, function( a, b )
return a.tm / a.count > b.tm / b.count
end )
-- Detailed data. -- Detailed data.
PROFILER._flog(f,"") PROFILER._flog( f, "" )
PROFILER._flog(f,"************************************************************************************************************************") PROFILER._flog( f, "************************************************************************************************************************" )
PROFILER._flog(f,"") PROFILER._flog( f, "" )
PROFILER._flog(f,"--------------------------------------") PROFILER._flog( f, "--------------------------------------" )
PROFILER._flog(f,"---- Data Sorted by Time per Call ----") PROFILER._flog( f, "---- Data Sorted by Time per Call ----" )
PROFILER._flog(f,"--------------------------------------") PROFILER._flog( f, "--------------------------------------" )
PROFILER._flog(f,"") PROFILER._flog( f, "" )
PROFILER.showTable(t, f, runTimeGame) PROFILER.showTable( t, f, runTimeGame )
-- Sort by number of calls. -- Sort by number of calls.
table.sort(t, function(a,b) return a.count>b.count end) table.sort( t, function( a, b )
return a.count > b.count
end )
-- Detailed data. -- Detailed data.
PROFILER._flog(f,"") PROFILER._flog( f, "" )
PROFILER._flog(f,"************************************************************************************************************************") PROFILER._flog( f, "************************************************************************************************************************" )
PROFILER._flog(f,"") PROFILER._flog( f, "" )
PROFILER._flog(f,"------------------------------------") PROFILER._flog( f, "------------------------------------" )
PROFILER._flog(f,"---- Data Sorted by Total Calls ----") PROFILER._flog( f, "---- Data Sorted by Total Calls ----" )
PROFILER._flog(f,"------------------------------------") PROFILER._flog( f, "------------------------------------" )
PROFILER._flog(f,"") PROFILER._flog( f, "" )
PROFILER.showTable(t, f, runTimeGame) PROFILER.showTable( t, f, runTimeGame )
-- Closing. -- Closing.
PROFILER._flog(f,"") PROFILER._flog( f, "" )
PROFILER._flog(f,"************************************************************************************************************************") PROFILER._flog( f, "************************************************************************************************************************" )
PROFILER._flog(f,"************************************************************************************************************************") PROFILER._flog( f, "************************************************************************************************************************" )
PROFILER._flog(f,"************************************************************************************************************************") PROFILER._flog( f, "************************************************************************************************************************" )
-- Close file. -- Close file.
f:close() f:close()
-- Print csv file. -- Print csv file.
PROFILER.printCSV(t, runTimeGame) PROFILER.printCSV( t, runTimeGame )
end end

File diff suppressed because it is too large Load Diff

View File

@ -1,21 +1,18 @@
--- **Utilities** DCS Simple Text-To-Speech (STTS). --- **Utilities** DCS Simple Text-To-Speech (STTS).
-- --
-- --
--
-- @module Utils.STTS -- @module Utils.STTS
-- @image MOOSE.JPG -- @image MOOSE.JPG
--- [DCS Enum world](https://wiki.hoggitworld.com/view/DCS_enum_world) --- [DCS Enum world](https://wiki.hoggitworld.com/view/DCS_enum_world)
-- @type STTS -- @type STTS
-- @field #string DIRECTORY Path of the SRS directory. -- @field #string DIRECTORY Path of the SRS directory.
--- Simple Text-To-Speech --- Simple Text-To-Speech
-- --
-- Version 0.4 - Compatible with SRS version 1.9.6.0+ -- Version 0.4 - Compatible with SRS version 1.9.6.0+
-- --
-- # DCS Modification Required -- # DCS Modification Required
-- --
-- You will need to edit MissionScripting.lua in DCS World/Scripts/MissionScripting.lua and remove the sanitisation. -- You will need to edit MissionScripting.lua in DCS World/Scripts/MissionScripting.lua and remove the sanitization.
-- To do this remove all the code below the comment - the line starts "local function sanitizeModule(name)" -- To do this remove all the code below the comment - the line starts "local function sanitizeModule(name)"
-- Do this without DCS running to allow mission scripts to use os functions. -- Do this without DCS running to allow mission scripts to use os functions.
-- --
@ -23,7 +20,7 @@
-- --
-- # USAGE: -- # USAGE:
-- --
-- Add this script into the mission as a DO SCRIPT or DO SCRIPT FROM FILE to initialise it -- Add this script into the mission as a DO SCRIPT or DO SCRIPT FROM FILE to initialize it
-- Make sure to edit the STTS.SRS_PORT and STTS.DIRECTORY to the correct values before adding to the mission. -- Make sure to edit the STTS.SRS_PORT and STTS.DIRECTORY to the correct values before adding to the mission.
-- Then its as simple as calling the correct function in LUA as a DO SCRIPT or in your own scripts. -- Then its as simple as calling the correct function in LUA as a DO SCRIPT or in your own scripts.
-- --
@ -55,7 +52,7 @@
-- --
-- ## Example -- ## Example
-- --
--This example will say the words "Hello DCS WORLD" on 251 MHz AM at maximum volume with a client called SRS and to the Blue coalition only centered on the position of the Unit called "A UNIT" -- This example will say the words "Hello DCS WORLD" on 251 MHz AM at maximum volume with a client called SRS and to the Blue coalition only centered on the position of the Unit called "A UNIT"
-- --
-- STTS.TextToSpeech("Hello DCS WORLD","251","AM","1.0","SRS",2,Unit.getByName("A UNIT"):getPoint(),-5,"male","en-GB") -- STTS.TextToSpeech("Hello DCS WORLD","251","AM","1.0","SRS",2,Unit.getByName("A UNIT"):getPoint(),-5,"male","en-GB")
-- --
@ -75,12 +72,12 @@
-- STTS.PlayMP3("C:\\Users\\Ciaran\\Downloads\\PR-Music.mp3","255,31","AM,FM","0.5","Multiple",0) -- STTS.PlayMP3("C:\\Users\\Ciaran\\Downloads\\PR-Music.mp3","255,31","AM,FM","0.5","Multiple",0)
-- --
-- @field #STTS -- @field #STTS
STTS={ STTS = {
ClassName="STTS", ClassName = "STTS",
DIRECTORY="", DIRECTORY = "",
SRS_PORT=5002, SRS_PORT = 5002,
GOOGLE_CREDENTIALS="C:\\Users\\Ciaran\\Downloads\\googletts.json", GOOGLE_CREDENTIALS = "C:\\Users\\Ciaran\\Downloads\\googletts.json",
EXECUTABLE="DCS-SR-ExternalAudio.exe", EXECUTABLE = "DCS-SR-ExternalAudio.exe"
} }
--- FULL Path to the FOLDER containing DCS-SR-ExternalAudio.exe - EDIT TO CORRECT FOLDER --- FULL Path to the FOLDER containing DCS-SR-ExternalAudio.exe - EDIT TO CORRECT FOLDER
@ -95,24 +92,27 @@ STTS.GOOGLE_CREDENTIALS = "C:\\Users\\Ciaran\\Downloads\\googletts.json"
--- DONT CHANGE THIS UNLESS YOU KNOW WHAT YOU'RE DOING --- DONT CHANGE THIS UNLESS YOU KNOW WHAT YOU'RE DOING
STTS.EXECUTABLE = "DCS-SR-ExternalAudio.exe" STTS.EXECUTABLE = "DCS-SR-ExternalAudio.exe"
--- Function for UUID. --- Function for UUID.
function STTS.uuid() function STTS.uuid()
local random = math.random local random = math.random
local template ='yxxx-xxxxxxxxxxxx' local template = 'yxxx-xxxxxxxxxxxx'
return string.gsub(template, '[xy]', function (c) return string.gsub( template, '[xy]', function( c )
local v = (c == 'x') and random(0, 0xf) or random(8, 0xb) local v = (c == 'x') and random( 0, 0xf ) or random( 8, 0xb )
return string.format('%x', v) return string.format( '%x', v )
end) end )
end end
--- Round a number. --- Round a number.
-- @param #number x Number. -- @param #number x Number.
-- @param #number n Precision. -- @param #number n Precision.
function STTS.round(x, n) function STTS.round( x, n )
n = math.pow(10, n or 0) n = math.pow( 10, n or 0 )
x = x * n x = x * n
if x >= 0 then x = math.floor(x + 0.5) else x = math.ceil(x - 0.5) end if x >= 0 then
x = math.floor( x + 0.5 )
else
x = math.ceil( x - 0.5 )
end
return x / n return x / n
end end
@ -125,7 +125,7 @@ end
-- --
-- * (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min -- * (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
-- --
function STTS.getSpeechTime(length,speed,isGoogle) function STTS.getSpeechTime( length, speed, isGoogle )
local maxRateRatio = 3 local maxRateRatio = 3
@ -134,100 +134,99 @@ function STTS.getSpeechTime(length,speed,isGoogle)
local speedFactor = 1.0 local speedFactor = 1.0
if isGoogle then if isGoogle then
speedFactor = speed speedFactor = speed
else else
if speed ~= 0 then if speed ~= 0 then
speedFactor = math.abs(speed) * (maxRateRatio - 1) / 10 + 1 speedFactor = math.abs( speed ) * (maxRateRatio - 1) / 10 + 1
end end
if speed < 0 then if speed < 0 then
speedFactor = 1/speedFactor speedFactor = 1 / speedFactor
end end
end end
local wpm = math.ceil(100 * speedFactor) local wpm = math.ceil( 100 * speedFactor )
local cps = math.floor((wpm * 5)/60) local cps = math.floor( (wpm * 5) / 60 )
if type(length) == "string" then if type( length ) == "string" then
length = string.len(length) length = string.len( length )
end end
return math.ceil(length/cps) return math.ceil( length / cps )
end end
--- Text to speech function. --- Text to speech function.
function STTS.TextToSpeech(message, freqs, modulations, volume, name, coalition, point, speed, gender, culture, voice, googleTTS) function STTS.TextToSpeech( message, freqs, modulations, volume, name, coalition, point, speed, gender, culture, voice, googleTTS )
if os == nil or io == nil then if os == nil or io == nil then
env.info("[DCS-STTS] LUA modules os or io are sanitized. skipping. ") env.info( "[DCS-STTS] LUA modules os or io are sanitized. skipping. " )
return return
end end
speed = speed or 1 speed = speed or 1
gender = gender or "female" gender = gender or "female"
culture = culture or "" culture = culture or ""
voice = voice or "" voice = voice or ""
coalition=coalition or "0" coalition = coalition or "0"
name=name or "ROBOT" name = name or "ROBOT"
volume=1 volume = 1
speed=1 speed = 1
message = message:gsub( "\"", "\\\"" )
message = message:gsub("\"","\\\"") local cmd = string.format( "start /min \"\" /d \"%s\" /b \"%s\" -f %s -m %s -c %s -p %s -n \"%s\" -h", STTS.DIRECTORY, STTS.EXECUTABLE, freqs or "305", modulations or "AM", coalition, STTS.SRS_PORT, name )
local cmd = string.format("start /min \"\" /d \"%s\" /b \"%s\" -f %s -m %s -c %s -p %s -n \"%s\" -h", STTS.DIRECTORY, STTS.EXECUTABLE, freqs or "305", modulations or "AM", coalition, STTS.SRS_PORT, name)
if voice ~= "" then if voice ~= "" then
cmd = cmd .. string.format(" -V \"%s\"",voice) cmd = cmd .. string.format( " -V \"%s\"", voice )
else else
if culture ~= "" then if culture ~= "" then
cmd = cmd .. string.format(" -l %s",culture) cmd = cmd .. string.format( " -l %s", culture )
end end
if gender ~= "" then if gender ~= "" then
cmd = cmd .. string.format(" -g %s",gender) cmd = cmd .. string.format( " -g %s", gender )
end end
end end
if googleTTS == true then if googleTTS == true then
cmd = cmd .. string.format(" -G \"%s\"",STTS.GOOGLE_CREDENTIALS) cmd = cmd .. string.format( " -G \"%s\"", STTS.GOOGLE_CREDENTIALS )
end end
if speed ~= 1 then if speed ~= 1 then
cmd = cmd .. string.format(" -s %s",speed) cmd = cmd .. string.format( " -s %s", speed )
end end
if volume ~= 1.0 then if volume ~= 1.0 then
cmd = cmd .. string.format(" -v %s",volume) cmd = cmd .. string.format( " -v %s", volume )
end end
if point and type(point) == "table" and point.x then if point and type( point ) == "table" and point.x then
local lat, lon, alt = coord.LOtoLL(point) local lat, lon, alt = coord.LOtoLL( point )
lat = STTS.round(lat,4) lat = STTS.round( lat, 4 )
lon = STTS.round(lon,4) lon = STTS.round( lon, 4 )
alt = math.floor(alt) alt = math.floor( alt )
cmd = cmd .. string.format(" -L %s -O %s -A %s",lat,lon,alt) cmd = cmd .. string.format( " -L %s -O %s -A %s", lat, lon, alt )
end end
cmd = cmd ..string.format(" -t \"%s\"",message) cmd = cmd .. string.format( " -t \"%s\"", message )
if string.len(cmd) > 255 then if string.len( cmd ) > 255 then
local filename = os.getenv('TMP') .. "\\DCS_STTS-" .. STTS.uuid() .. ".bat" local filename = os.getenv( 'TMP' ) .. "\\DCS_STTS-" .. STTS.uuid() .. ".bat"
local script = io.open(filename,"w+") local script = io.open( filename, "w+" )
script:write(cmd .. " && exit" ) script:write( cmd .. " && exit" )
script:close() script:close()
cmd = string.format("\"%s\"",filename) cmd = string.format( "\"%s\"", filename )
timer.scheduleFunction(os.remove, filename, timer.getTime() + 1) timer.scheduleFunction( os.remove, filename, timer.getTime() + 1 )
end end
if string.len(cmd) > 255 then if string.len( cmd ) > 255 then
env.info("[DCS-STTS] - cmd string too long") env.info( "[DCS-STTS] - cmd string too long" )
env.info("[DCS-STTS] TextToSpeech Command :\n" .. cmd.."\n") env.info( "[DCS-STTS] TextToSpeech Command :\n" .. cmd .. "\n" )
end end
os.execute(cmd) os.execute( cmd )
return STTS.getSpeechTime(message,speed,googleTTS) return STTS.getSpeechTime( message, speed, googleTTS )
end end
--- Play mp3 function. --- Play mp3 function.
@ -235,22 +234,21 @@ end
-- @param #string freqs Frequencies, e.g. "305, 256". -- @param #string freqs Frequencies, e.g. "305, 256".
-- @param #string modulations Modulations, e.g. "AM, FM". -- @param #string modulations Modulations, e.g. "AM, FM".
-- @param #string volume Volume, e.g. "0.5". -- @param #string volume Volume, e.g. "0.5".
function STTS.PlayMP3(pathToMP3, freqs, modulations, volume, name, coalition, point) function STTS.PlayMP3( pathToMP3, freqs, modulations, volume, name, coalition, point )
local cmd = string.format("start \"\" /d \"%s\" /b /min \"%s\" -i \"%s\" -f %s -m %s -c %s -p %s -n \"%s\" -v %s -h", local cmd = string.format( "start \"\" /d \"%s\" /b /min \"%s\" -i \"%s\" -f %s -m %s -c %s -p %s -n \"%s\" -v %s -h", STTS.DIRECTORY, STTS.EXECUTABLE, pathToMP3, freqs or "305", modulations or "AM", coalition or "0", STTS.SRS_PORT, name or "ROBOT", volume or "1" )
STTS.DIRECTORY, STTS.EXECUTABLE, pathToMP3, freqs or "305", modulations or "AM", coalition or "0", STTS.SRS_PORT, name or "ROBOT", volume or "1")
if point and type(point) == "table" and point.x then if point and type( point ) == "table" and point.x then
local lat, lon, alt = coord.LOtoLL(point) local lat, lon, alt = coord.LOtoLL( point )
lat = STTS.round(lat,4) lat = STTS.round( lat, 4 )
lon = STTS.round(lon,4) lon = STTS.round( lon, 4 )
alt = math.floor(alt) alt = math.floor( alt )
cmd = cmd .. string.format(" -L %s -O %s -A %s",lat,lon,alt) cmd = cmd .. string.format( " -L %s -O %s -A %s", lat, lon, alt )
end end
env.info("[DCS-STTS] MP3/OGG Command :\n" .. cmd.."\n") env.info( "[DCS-STTS] MP3/OGG Command :\n" .. cmd .. "\n" )
os.execute(cmd) os.execute( cmd )
end end