diff --git a/Moose Development/Moose/Core/Message.lua b/Moose Development/Moose/Core/Message.lua index 47cbf62c1..b5511d29e 100644 --- a/Moose Development/Moose/Core/Message.lua +++ b/Moose Development/Moose/Core/Message.lua @@ -496,7 +496,8 @@ _MESSAGESRS = {} -- @param #string Label (optional) Label, defaults to "MESSAGE" or the Message Category set. -- @param Core.Point#COORDINATE Coordinate (optional) Coordinate this messages originates from. -- @param #string Backend (optional) Backend to be used, can be MSRS.Backend.SRSEXE or MSRS.Backend.GRPC or MSRS.Backend.HOUND etc --- @param #string Provider (optional) Privider to be used, can be MSRS.Provider.WINDOWS or MSRS.Backend.GOOGLE or MSRS.Backend.PIPER etc +-- @param #string Provider (optional) Provider to be used, can be MSRS.Provider.WINDOWS or MSRS.Provider.GOOGLE or MSRS.Provider.PIPER etc +-- @param #string Speaker (optional) Speaker to be used. Only for select provider PIPER TTS Voices, requires HOUND backend. -- @usage -- -- Mind the dot here, not using the colon this time around! -- -- Needed once only @@ -504,7 +505,7 @@ _MESSAGESRS = {} -- -- later on in your code -- MESSAGE:New("Test message!",15,"SPAWN"):ToSRS() -- -function MESSAGE.SetMSRS(PathToSRS,Port,PathToCredentials,Frequency,Modulation,Gender,Culture,Voice,Coalition,Volume,Label,Coordinate,Backend,Provider) +function MESSAGE.SetMSRS(PathToSRS,Port,PathToCredentials,Frequency,Modulation,Gender,Culture,Voice,Coalition,Volume,Label,Coordinate,Backend,Provider,Speaker) _MESSAGESRS.PathToSRS = PathToSRS or MSRS.path or "C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio" @@ -551,6 +552,7 @@ function MESSAGE.SetMSRS(PathToSRS,Port,PathToCredentials,Frequency,Modulation,G _MESSAGESRS.MSRS:SetVolume(_MESSAGESRS.volume) if Voice then _MESSAGESRS.MSRS:SetVoice(Voice) end + if Speaker then _MESSAGESRS.MSRS:SetSpeakerPiper(Speaker) end _MESSAGESRS.voice = Voice or MSRS.voice --or MSRS.Voices.Microsoft.Hedda diff --git a/Moose Development/Moose/Functional/AICSAR.lua b/Moose Development/Moose/Functional/AICSAR.lua index 0f0a542d1..adc954073 100644 --- a/Moose Development/Moose/Functional/AICSAR.lua +++ b/Moose Development/Moose/Functional/AICSAR.lua @@ -580,8 +580,9 @@ end -- @param #string Gender (Optional) The gender to be used, defaults to "male" -- @param #string GoogleCredentials (Optional) Path to google credentials -- @param #string Provider (Optional) TTS Provider to be used. +-- @param #string Speaker (Optional) Use a specific speaker for a voice if Piper is used as provider (only Hound-TTS backend). -- @return #AICSAR self -function AICSAR:SetSRSTTSRadio(OnOff,Path,Frequency,Modulation,Port,Voice,Culture,Gender,GoogleCredentials,Provider) +function AICSAR:SetSRSTTSRadio(OnOff,Path,Frequency,Modulation,Port,Voice,Culture,Gender,GoogleCredentials,Provider,Speaker) self:T(self.lid .. "SetSRSTTSRadio") self.SRSTTSRadio = OnOff and true self.SRSRadio = false @@ -595,6 +596,9 @@ function AICSAR:SetSRSTTSRadio(OnOff,Path,Frequency,Modulation,Port,Voice,Cultur self.SRS:SetCoalition(self.coalition) self.SRS:SetLabel("ACSR") self.SRS:SetVoice(Voice) + if Speaker then + self.SRS:SetSpeakerPiper(Speaker) + end self.SRS:SetCulture(Culture) self.SRS:SetGender(Gender) if GoogleCredentials and not Provider then @@ -616,13 +620,17 @@ end -- Specific voices override culture and gender! -- @param #string Culture (Optional) The culture to be used, defaults to "en-US" -- @param #string Gender (Optional) The gender to be used, defaults to "male" +-- @param #string Speaker (Optional) Use a specific speaker for a voice if Piper is used as provider (only Hound-TTS backend). -- @return #AICSAR self -function AICSAR:SetPilotTTSVoice(Voice,Culture,Gender) +function AICSAR:SetPilotTTSVoice(Voice,Culture,Gender,Speaker) self:T(self.lid .. "SetPilotTTSVoice") self.SRSPilotVoice = true self.SRSPilot = MSRS:New(self.SRSPath,self.SRSFrequency,self.SRSModulation) self.SRSPilot:SetCoalition(self.coalition) self.SRSPilot:SetVoice(Voice) + if Speaker then + self.SRSPilot:SetSpeakerPiper(Speaker) + end self.SRSPilot:SetCulture(Culture or "en-US") self.SRSPilot:SetGender(Gender or "male") self.SRSPilot:SetLabel("PILOT") @@ -640,13 +648,17 @@ end -- Specific voices override culture and gender! -- @param #string Culture (Optional) The culture to be used, defaults to "en-GB" -- @param #string Gender (Optional) The gender to be used, defaults to "female" +-- @param #string Speaker (Optional) Use a specific speaker for a voice if Piper is used as provider (only Hound-TTS backend). -- @return #AICSAR self -function AICSAR:SetOperatorTTSVoice(Voice,Culture,Gender) +function AICSAR:SetOperatorTTSVoice(Voice,Culture,Gender,Speaker) self:T(self.lid .. "SetOperatorTTSVoice") self.SRSOperatorVoice = true self.SRSOperator = MSRS:New(self.SRSPath,self.SRSFrequency,self.SRSModulation) self.SRSOperator:SetCoalition(self.coalition) self.SRSOperator:SetVoice(Voice) +if Speaker then + self.SRSOperator:SetSpeakerPiper(Speaker) + end self.SRSOperator:SetCulture(Culture or "en-GB") self.SRSOperator:SetGender(Gender or "female") self.SRSOperator:SetLabel("RESCUE") diff --git a/Moose Development/Moose/Functional/Autolase.lua b/Moose Development/Moose/Functional/Autolase.lua index 2efee7010..cc4a8591e 100644 --- a/Moose Development/Moose/Functional/Autolase.lua +++ b/Moose Development/Moose/Functional/Autolase.lua @@ -505,8 +505,9 @@ end -- @param #number Volume (Optional) Volume - between 0.0 (silent) and 1.0 (loudest). -- @param #string PathToGoogleKey (Optional) Path to your google key if you want to use google TTS. -- @param #string Provider (Optional) TTS Provider to be used. +-- @param #string Speaker (Optional) Use a specific speaker for a voice if Piper is used as provider (only Hound-TTS backend). -- @return #AUTOLASE self -function AUTOLASE:SetUsingSRS(OnOff,Path,Frequency,Modulation,Label,Gender,Culture,Port,Voice,Volume,PathToGoogleKey,Provider) +function AUTOLASE:SetUsingSRS(OnOff,Path,Frequency,Modulation,Label,Gender,Culture,Port,Voice,Volume,PathToGoogleKey,Provider,Speaker) if OnOff then self.useSRS = true self.SRSPath = Path or MSRS.path or "C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio" @@ -527,6 +528,9 @@ function AUTOLASE:SetUsingSRS(OnOff,Path,Frequency,Modulation,Label,Gender,Cultu self.SRS:SetCulture(self.Culture) self.SRS:SetPort(self.Port) self.SRS:SetVoice(self.Voice) + if Speaker then + self.SRS:SetSpeakerPiper(Speaker) + end self.SRS:SetCoalition(self.coalition) self.SRS:SetVolume(self.Volume) if self.PathToGoogleKey and not Provider then diff --git a/Moose Development/Moose/Functional/Range.lua b/Moose Development/Moose/Functional/Range.lua index 84b37cc0e..e98f744cc 100644 --- a/Moose Development/Moose/Functional/Range.lua +++ b/Moose Development/Moose/Functional/Range.lua @@ -1259,8 +1259,9 @@ end -- @param #number Volume (Optional) Volume, between 0.0 and 1.0. Defaults to 1.0 -- @param #string PathToGoogleKey Path to Google TTS credentials. -- @param #string Provider (Optional) TTS Provider to be used. +-- @param #string Backend (Optional) TTS Backend to be used. -- @return #RANGE self -function RANGE:SetSRS(PathToSRS, Port, Coalition, Frequency, Modulation, Volume, PathToGoogleKey,Provider) +function RANGE:SetSRS(PathToSRS, Port, Coalition, Frequency, Modulation, Volume, PathToGoogleKey,Provider,Backend) if PathToSRS or MSRS.path then @@ -1274,6 +1275,9 @@ function RANGE:SetSRS(PathToSRS, Port, Coalition, Frequency, Modulation, Volume, if self.rangezone then self.controlmsrs:SetCoordinate(self.rangezone:GetCoordinate()) end + if Backend then + self.controlmsrs:SetBackend(Backend) + end self.controlsrsQ = MSRSQUEUE:New("CONTROL") self.instructmsrs=MSRS:New(PathToSRS or MSRS.path, Frequency or 305, Modulation or radio.modulation.AM) @@ -1292,6 +1296,9 @@ function RANGE:SetSRS(PathToSRS, Port, Coalition, Frequency, Modulation, Volume, self.instructmsrs:SetProviderOptionsGoogle(PathToGoogleKey,PathToGoogleKey) self.instructmsrs:SetProvider(MSRS.Provider.GOOGLE) end + if Backend then + self.instructmsrs:SetBackend(Backend) + end if Provider then self.controlmsrs:SetProvider(Provider) self.instructmsrs:SetProvider(Provider) @@ -1310,8 +1317,9 @@ end -- @param #string culture (Optional) Culture, defaults to "en-US". -- @param #string gender (Optional) Gender, defaults to "female". -- @param #string relayunitname Name of the unit used for transmission location. +-- @param #string Speaker (Optional) Use a specific speaker for a voice if Piper is used as provider (only Hound-TTS backend). -- @return #RANGE self -function RANGE:SetSRSRangeControl( frequency, modulation, voice, culture, gender, relayunitname ) +function RANGE:SetSRSRangeControl( frequency, modulation, voice, culture, gender, relayunitname, Speaker ) if not self.instructmsrs then self:E(self.lid.."Use myrange:SetSRS() once first before using myrange:SetSRSRangeControl!") return self @@ -1320,6 +1328,9 @@ function RANGE:SetSRSRangeControl( frequency, modulation, voice, culture, gender self.controlmsrs:SetFrequencies(self.rangecontrolfreq) self.controlmsrs:SetModulations(modulation or radio.modulation.AM) self.controlmsrs:SetVoice(voice) + if Speaker then + self.controlmsrs:SetSpeakerPiper(Speaker) + end self.controlmsrs:SetCulture(culture or "en-US") self.controlmsrs:SetGender(gender or "female") self.rangecontrol = true @@ -1344,8 +1355,9 @@ end -- @param #string culture (Optional) Culture, defaults to "en-US". -- @param #string gender (Optional) Gender, defaults to "male". -- @param #string relayunitname Name of the unit used for transmission location. +-- @param #string Speaker (Optional) Use a specific speaker for a voice if Piper is used as provider (only Hound-TTS backend). -- @return #RANGE self -function RANGE:SetSRSRangeInstructor( frequency, modulation, voice, culture, gender, relayunitname ) +function RANGE:SetSRSRangeInstructor( frequency, modulation, voice, culture, gender, relayunitname, Speaker ) if not self.instructmsrs then self:E(self.lid.."Use myrange:SetSRS() once first before using myrange:SetSRSRangeInstructor!") return self @@ -1354,6 +1366,9 @@ function RANGE:SetSRSRangeInstructor( frequency, modulation, voice, culture, gen self.instructmsrs:SetFrequencies(self.instructorfreq) self.instructmsrs:SetModulations(modulation or radio.modulation.AM) self.instructmsrs:SetVoice(voice) + if Speaker then + self.instructmsrs:SetSpeakerPiper(Speaker) + end self.instructmsrs:SetCulture(culture or "en-US") self.instructmsrs:SetGender(gender or "male") self.instructor = true diff --git a/Moose Development/Moose/Ops/ATIS.lua b/Moose Development/Moose/Ops/ATIS.lua index 251636e4b..5f9c7f46e 100644 --- a/Moose Development/Moose/Ops/ATIS.lua +++ b/Moose Development/Moose/Ops/ATIS.lua @@ -1674,8 +1674,9 @@ end -- @param #number Port (Optional) SRS port. Default 5002. -- @param #string GoogleKey (Optional) Path to Google JSON-Key (SRS exe backend) or Google API key (DCS-gRPC backend). -- @param #string Provider (Optional) TTS Provider to be used. +-- @param #string Speaker (Optional) Use a specific speaker for a voice if Piper is used as provider (only Hound-TTS backend). -- @return #ATIS self -function ATIS:SetSRS(PathToSRS, Gender, Culture, Voice, Port, GoogleKey,Provider) +function ATIS:SetSRS(PathToSRS, Gender, Culture, Voice, Port, GoogleKey,Provider,Speaker) --if PathToSRS or MSRS.path then self.useSRS=true @@ -1704,6 +1705,9 @@ function ATIS:SetSRS(PathToSRS, Gender, Culture, Voice, Port, GoogleKey,Provider if Provider then self.msrs:SetProvider(Provider) end + if Speaker then + self.msrs:SetSpeakerPiper(Speaker) + end self.msrsQ = MSRSQUEUE:New("ATIS") self.msrsQ:SetTransmitOnlyWithPlayers(self.TransmitOnlyWithPlayers) if self.dTQueueCheck<=10 then diff --git a/Moose Development/Moose/Ops/Auftrag.lua b/Moose Development/Moose/Ops/Auftrag.lua index 73e3d7ff0..0f46933e3 100644 --- a/Moose Development/Moose/Ops/Auftrag.lua +++ b/Moose Development/Moose/Ops/Auftrag.lua @@ -676,7 +676,7 @@ AUFTRAG.Category={ --- AUFTRAG class version. -- @field #string version -AUFTRAG.version="1.4.1" +AUFTRAG.version="1.4.2" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- TODO list @@ -1366,7 +1366,7 @@ end --- **[AIR]** Create a AWACS mission. -- @param #AUFTRAG self --- @param Core.Point#COORDINATE Coordinate Where to orbit. Altitude is also taken from the coordinate. +-- @param Core.Point#COORDINATE Coordinate Where to orbit. Altitude is also taken from the coordinate. Can also be a UNIT object, *e.g.* a carrier. -- @param #number Altitude (Optional) Orbit altitude in feet. Default is y component of `Coordinate`. -- @param #number Speed (Optional) Orbit speed in knots. Default 350 kts. -- @param #number Heading (Optional) Heading of race-track pattern in degrees. Default 270 (East to West). @@ -1375,7 +1375,20 @@ end function AUFTRAG:NewAWACS(Coordinate, Altitude, Speed, Heading, Leg) -- Create ORBIT first. - local mission=AUFTRAG:NewORBIT_RACETRACK(Coordinate, Altitude, Speed, Heading, Leg) + local mission=nil --Ops.Auftrag#AUFTRAG + + if Coordinate:IsInstanceOf("COORDINATE") then + -- Racetrack at a given coordinate + mission=AUFTRAG:NewORBIT_RACETRACK(Coordinate, Altitude, Speed, Heading, Leg) + elseif Coordinate:IsInstanceOf("UNIT") then + -- Racetrack wrt a given (moving) unit (e.g. a carrier) + local OffsetVec2={r=6, phi=180} + mission=AUFTRAG:NewORBIT_GROUP(Coordinate, Altitude, Speed, Leg, Heading, OffsetVec2) + else + -- Error! + BASE:E("ERROR in AUFTRAG:NewAWACS: You must pass a COORDINATE or UNIT object!") + return nil + end -- Mission type AWACS. mission.type=AUFTRAG.Type.AWACS @@ -1394,7 +1407,51 @@ function AUFTRAG:NewAWACS(Coordinate, Altitude, Speed, Heading, Leg) return mission end +--- **[AIRPANE]** Create a RECOVERY TANKER mission. +-- @param #AUFTRAG self +-- @param Wrapper.Unit#UNIT Carrier The carrier unit. +-- @param #number Altitude (Optional) Orbit altitude in feet. Default is 6,000 ft. +-- @param #number Speed (Optional) Orbit speed in knots. Default 250 KIAS. +-- @param #number Leg (Optional) Length of race-track in NM. Default 14 NM. +-- @param #number RelHeading (Optional) Relative heading [0, 360) of race-track pattern in degrees wrt heading of the carrier. Default is heading of the carrier. +-- @param #number OffsetDist (Optional) Relative distance of the first race-track point wrt to the carrier. Default 6 NM. +-- @param #number OffsetAngle (Optional) Relative angle of the first race-track point wrt. to the carrier. Default 180 (behind the boat). +-- @param #number UpdateDistance (Optional) Threshold distance in NM before orbit pattern is updated. Default 5 NM. +-- @return #AUFTRAG self +function AUFTRAG:NewRECOVERYTANKER(Carrier, Altitude, Speed, Leg, RelHeading, OffsetDist, OffsetAngle, UpdateDistance) + + -- Six NM astern. + local OffsetVec2={r=OffsetDist or 6, phi=OffsetAngle or 180} + + -- Default leg. + Leg=Leg or 14 + + -- Default Speed. + Speed=Speed or 250 + + local Heading=nil + if RelHeading then + Heading=-math.abs(RelHeading) + end + + -- Create orbit mission. + local mission=AUFTRAG:NewORBIT_GROUP(Carrier, Altitude, Speed, Leg, Heading, OffsetVec2, UpdateDistance) + -- Set the type. + mission.type=AUFTRAG.Type.RECOVERYTANKER + + -- Mission options: + mission.missionTask=ENUMS.MissionTask.REFUELING + mission.missionFraction=0.9 + mission.optionROE=ENUMS.ROE.WeaponHold + mission.optionROT=ENUMS.ROT.NoReaction + + mission.categories={AUFTRAG.Category.AIRPLANE} + + mission.DCStask=mission:GetDCSMissionTask() + + return mission +end --- **[AIR]** Create an INTERCEPT mission. -- @param #AUFTRAG self @@ -2049,53 +2106,6 @@ function AUFTRAG:NewRESCUEHELO(Carrier) return mission end ---- **[AIRPANE]** Create a RECOVERY TANKER mission. --- @param #AUFTRAG self --- @param Wrapper.Unit#UNIT Carrier The carrier unit. --- @param #number Altitude (Optional) Orbit altitude in feet. Default is 6,000 ft. --- @param #number Speed (Optional) Orbit speed in knots. Default 250 KIAS. --- @param #number Leg (Optional) Length of race-track in NM. Default 14 NM. --- @param #number RelHeading (Optional) Relative heading [0, 360) of race-track pattern in degrees wrt heading of the carrier. Default is heading of the carrier. --- @param #number OffsetDist (Optional) Relative distance of the first race-track point wrt to the carrier. Default 6 NM. --- @param #number OffsetAngle (Optional) Relative angle of the first race-track point wrt. to the carrier. Default 180 (behind the boat). --- @param #number UpdateDistance (Optional) Threshold distance in NM before orbit pattern is updated. Default 5 NM. --- @return #AUFTRAG self -function AUFTRAG:NewRECOVERYTANKER(Carrier, Altitude, Speed, Leg, RelHeading, OffsetDist, OffsetAngle, UpdateDistance) - - -- Six NM astern. - local OffsetVec2={r=OffsetDist or 6, phi=OffsetAngle or 180} - - -- Default leg. - Leg=Leg or 14 - - -- Default Speed. - Speed=Speed or 250 - - local Heading=nil - if RelHeading then - Heading=-math.abs(RelHeading) - end - - -- Create orbit mission. - local mission=AUFTRAG:NewORBIT_GROUP(Carrier, Altitude, Speed, Leg, Heading, OffsetVec2, UpdateDistance) - - -- Set the type. - mission.type=AUFTRAG.Type.RECOVERYTANKER - - -- Mission options: - mission.missionTask=ENUMS.MissionTask.REFUELING - mission.missionFraction=0.9 - mission.optionROE=ENUMS.ROE.WeaponHold - mission.optionROT=ENUMS.ROT.NoReaction - - mission.categories={AUFTRAG.Category.AIRPLANE} - - mission.DCStask=mission:GetDCSMissionTask() - - return mission -end - - --- **[AIR ROTARY, GROUND]** Create a TROOP TRANSPORT mission. -- @param #AUFTRAG self -- @param Core.Set#SET_GROUP TransportGroupSet The set group(s) to be transported. @@ -3351,6 +3361,20 @@ function AUFTRAG:SetEngageAltitude(Altitude) return self end +--- Set engage quantity. This is the number of times the attack group/unit DCS task is carried out. +-- @param #AUFTRAG self +-- @param #number Quantity (Optional) Number of times the group will engage the target. +-- @return #AUFTRAG self +function AUFTRAG:SetEngageQuantity(Quantity) + + self.engageQuantity=Quantity + + -- Update the DCS task parameter. + self.DCStask=self:GetDCSMissionTask() + + return self +end + --- Enable to automatically engage detected targets. -- @param #AUFTRAG self -- @param #number RangeMax (Optional) Max range in NM. Only detected targets within this radius from the group will be engaged. Default is 25 NM. diff --git a/Moose Development/Moose/Ops/Awacs.lua b/Moose Development/Moose/Ops/Awacs.lua index e58b1b187..19e8d3141 100644 --- a/Moose Development/Moose/Ops/Awacs.lua +++ b/Moose Development/Moose/Ops/Awacs.lua @@ -1416,8 +1416,9 @@ end -- @param #number Interval Seconds between each update call. -- @param #number Number Number of Frequencies to create, can be 1..10. -- @param #string Provider (Optional) TTS Provider to be used. +-- @param #string Speaker (Optional) Use a specific speaker for a voice if Piper is used as provider (only Hound-TTS backend). -- @return #AWACS self -function AWACS:SetTacticalRadios(BaseFreq,Increase,Modulation,Interval,Number,Provider) +function AWACS:SetTacticalRadios(BaseFreq,Increase,Modulation,Interval,Number,Provider,Speaker) self:T(self.lid.."SetTacticalRadios") if not self.AwacsSRS then MESSAGE:New("AWACS: Setup SRS in your code BEFORE trying to add tactical radios please!",30,"ERROR",true):ToLog():ToAll() @@ -1441,6 +1442,9 @@ function AWACS:SetTacticalRadios(BaseFreq,Increase,Modulation,Interval,Number,Pr self.TacticalSRS:SetGender(self.Gender) self.TacticalSRS:SetCulture(self.Culture) self.TacticalSRS:SetVoice(self.Voice) + if Speaker then + self.TacticalSRS:SetSpeakerPiper(Speaker) + end self.TacticalSRS:SetPort(self.Port) self.TacticalSRS:SetLabel("AWACS") self.TacticalSRS:SetVolume(self.Volume) @@ -2191,8 +2195,9 @@ end -- @param #string AccessKey (Optional) Your Google API access key. This is necessary if DCS-gRPC is used as backend; if you use a config file for MSRS, hand in nil here. -- @param #string Backend (Optional) Your MSRS Backend if different from your config file settings, e.g. MSRS.Backend.SRSEXE or MSRS.Backend.GRPC -- @param #string Provider (Optional) TTS Provider to be used. +-- @param #string Speaker (Optional) Use a specific speaker for a voice if Piper is used as provider (only Hound-TTS backend). -- @return #AWACS self -function AWACS:SetSRS(PathToSRS,Gender,Culture,Port,Voice,Volume,PathToGoogleKey,AccessKey,Backend,Provider) +function AWACS:SetSRS(PathToSRS,Gender,Culture,Port,Voice,Volume,PathToGoogleKey,AccessKey,Backend,Provider,Speaker) self:T(self.lid.."SetSRS") self.PathToSRS = PathToSRS or MSRS.path or "C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio" self.Gender = Gender or MSRS.gender or "male" @@ -2203,6 +2208,7 @@ function AWACS:SetSRS(PathToSRS,Gender,Culture,Port,Voice,Volume,PathToGoogleKey self.AccessKey = AccessKey self.Volume = Volume or 1.0 self.Backend = Backend or MSRS.backend + self.Provider = Provider BASE:I({backend = self.Backend}) self.AwacsSRS = MSRS:New(self.PathToSRS,self.MultiFrequency,self.MultiModulation,self.Backend) self.AwacsSRS:SetCoalition(self.coalition) @@ -2211,6 +2217,9 @@ function AWACS:SetSRS(PathToSRS,Gender,Culture,Port,Voice,Volume,PathToGoogleKey self.AwacsSRS:SetPort(self.Port) self.AwacsSRS:SetLabel("AWACS") self.AwacsSRS:SetVolume(Volume) + if Speaker then + self.AwacsSRS:SetSpeakerPiper(Speaker) + end if self.PathToGoogleKey then --self.AwacsSRS:SetGoogle(self.PathToGoogleKey) self.AwacsSRS:SetProviderOptionsGoogle(self.PathToGoogleKey,self.AccessKey) @@ -2235,12 +2244,14 @@ end -- @param #string Culture (Optional) Defaults to "en-US" -- @param #string Voice (Optional) Use a specifc voice with the @{#MSRS.SetVoice} function, e.g, `:SetVoice("Microsoft Hedda Desktop")`. -- Note that this must be installed on your windows system. Can also be Google voice types, if you are using Google TTS. +-- @param #string Speaker (Optional) Use a specific speaker for a voice if Piper is used as provider (only Hound-TTS backend). -- @return #AWACS self -function AWACS:SetSRSVoiceCAP(Gender, Culture, Voice) +function AWACS:SetSRSVoiceCAP(Gender, Culture, Voice, Speaker) self:T(self.lid.."SetSRSVoiceCAP") self.CAPGender = Gender or "male" self.CAPCulture = Culture or "en-US" self.CAPVoice = Voice or "en-GB-Standard-B" + self.CAPSpeaker = Speaker return self end @@ -3831,7 +3842,13 @@ function AWACS:_CheckInAI(FlightGroup,Group,AuftragsNr) CAPVoice = self.CapVoices[math.floor(math.random(1,10))] end - FlightGroup:SetSRS(self.PathToSRS,self.CAPGender,self.CAPCulture,CAPVoice,self.Port,self.PathToGoogleKey,"FLIGHT",1) + FlightGroup:SetSRS(self.PathToSRS,self.CAPGender,self.CAPCulture,CAPVoice,self.Port,self.PathToGoogleKey,"FLIGHT",1,self.Provider) + if self.Backend then + FlightGroup.srs:SetBackend(self.Backend) + end + if self.CAPSpeaker then + FlightGroup.srs:SetSpeakerPiper(self.CAPSpeaker) + end local checkai = self.gettext:GetEntry("CHECKINAI",self.locale) text = string.format(checkai,self.callsigntxt, managedgroup.CallSign, self.CAPTimeOnStation, self.AOName) diff --git a/Moose Development/Moose/Ops/CSAR.lua b/Moose Development/Moose/Ops/CSAR.lua index 44bf10e53..0be8b7478 100644 --- a/Moose Development/Moose/Ops/CSAR.lua +++ b/Moose Development/Moose/Ops/CSAR.lua @@ -136,14 +136,16 @@ -- mycsar.SRSModulation = radio.modulation.AM -- modulation -- mycsar.SRSport = 5002 -- and SRS Server port -- mycsar.SRSCulture = "en-GB" -- SRS voice culture --- mycsar.SRSVoice = nil -- SRS voice for downed pilot, relevant for Google TTS +-- mycsar.SRSVoice = nil -- TTS voice for downed pilot, relevant for Google TTS +-- mycsar.SRSSpeaker = nil -- TTS sub-voice, only relevant for Piper TTS with Hound backend -- mycsar.SRSGPathToCredentials = nil -- Path to your Google credentials json file, set this if you want to use Google TTS as provider -- mycsar.SRSBackend = MSRS.Backend.SRSEXE -- default backend is windows -- mycsar.SRSProvider = MSRS.Provider.WINDOWS -- default TTS provider is windows -- mycsar.SRSSpeed = 1.0 -- default speech speed - does not work with all providers -- mycsar.SRSVolume = 1 -- Volume, between 0 and 1 -- mycsar.SRSGender = "male" -- male or female voice --- mycsar.CSARVoice = MSRS.Voices.Google.Standard.en_US_Standard_A -- SRS voice for CSAR Controller, relevant for Google TTS +-- mycsar.CSARVoice = MSRS.Voices.Google.Standard.en_US_Standard_A -- TTS voice for CSAR Controller, relevant for Google TTS +-- mycsar.CSARSpeaker = nil -- TTS sub-voice, only relevant for Piper TTS with Hound backend -- mycsar.CSARVoiceMS = MSRS.Voices.Microsoft.Hedda -- SRS voice for CSAR Controller, relevant for MS Desktop TTS -- mycsar.coordinate -- Coordinate from which CSAR TTS is sending. Defaults to a random MASH object position -- -- @@ -505,7 +507,7 @@ CSAR.AircraftType["MH-6J"] = 2 --- CSAR class version. -- @field #string version -CSAR.version="1.1.38" +CSAR.version="1.1.39" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- ToDo list @@ -2097,7 +2099,7 @@ function CSAR:_DisplayMessageToSAR(_unit, _text, _time, _clear, _speak, _overrid local nm = self.gettext:GetEntry("NAUTMILES",self.locale) _text = string.gsub(_text,"km",km) _text = string.gsub(_text,"nm",nm) - self.SRSQueue:NewTransmission(_text,duration,self.msrs,tstart,2,subgroups,subtitle,subduration,self.SRSchannel,self.SRSModulation,gender,culture,self.SRSVoice,volume,label,coord) + self.SRSQueue:NewTransmission(_text,duration,self.msrs,tstart,2,subgroups,subtitle,subduration,self.SRSchannel,self.SRSModulation,gender,culture,self.SRSVoice,volume,label,coord,nil,self.SRSSpeaker) end return self end @@ -2303,13 +2305,14 @@ function CSAR:_DisplayToAllSAR(_message, _side, _messagetime,ToSRS,ToScreen) self:T({_message,ToSRS=ToSRS,ToScreen=ToScreen}) if self.msrs and (ToSRS == true or ToSRS == nil) then local voice = self.CSARVoice or MSRS.Voices.Google.Standard.en_GB_Standard_F + local speaker = self.CSARSpeaker if self.msrs:GetProvider() == MSRS.Provider.WINDOWS then voice = self.CSARVoiceMS or MSRS.Voices.Microsoft.Hedda end local kilohertz = self.gettext:GetEntry("KHZ",self.locale) _message = string.gsub(_message,"KHz",kilohertz) --self:F("Voice = "..voice) - self.SRSQueue:NewTransmission(_message,duration,self.msrs,tstart,2,subgroups,subtitle,subduration,self.SRSchannel,self.SRSModulation,gender,culture,voice,volume,label,self.coordinate) + self.SRSQueue:NewTransmission(_message,duration,self.msrs,tstart,2,subgroups,subtitle,subduration,self.SRSchannel,self.SRSModulation,gender,culture,voice,volume,label,self.coordinate,nil,speaker) end if ToScreen == true or ToScreen == nil then for _, _unitName in pairs(self.csarUnits) do @@ -2846,6 +2849,9 @@ function CSAR:onafterStart(From, Event, To) if self.SRSProvider then self.msrs:SetProvider(self.SRSProvider) end + if self.SRSSpeaker then + self.msrs:SetSpeakerPiper(self.SRSSpeaker) + end self.msrs:SetVolume(self.SRSVolume) self.msrs:SetLabel("CSAR") self.SRSQueue = MSRSQUEUE:New("CSAR") -- Sound.SRS#MSRSQUEUE diff --git a/Moose Development/Moose/Ops/CTLD.lua b/Moose Development/Moose/Ops/CTLD.lua index f49b982ca..73324b79d 100644 --- a/Moose Development/Moose/Ops/CTLD.lua +++ b/Moose Development/Moose/Ops/CTLD.lua @@ -1506,9 +1506,10 @@ end -- @param #string PathToGoogleKey (Optional) Path to your google key if you want to use google TTS; if you use a config file for MSRS, hand in nil here. -- @param #string AccessKey (Optional) Your Google API access key. This is necessary if DCS-gRPC is used as backend; if you use a config file for MSRS, hand in nil here. -- @param #string Backend (Optional) MSRS Backend to be used, can be MSRS.Backend.SRSEXE or MSRS.Backend.GRPC; if you use a config file for MSRS, hand in nil here. --- @param #string Provider (Optional) MSRS Provider to be used, can be MSRS.Provider.Google or MSRS.Provider.WINDOWS etc; if you use a config file for MSRS, hand in nil here. +-- @param #string Provider (Optional) MSRS Provider to be used, can be MSRS.Provider.Google or MSRS.Provider.WINDOWS etc; if you use a config file for MSRS, hand in nil here. +-- @param #string Speaker (Optional) Use a specific speaker for a voice if Piper is used as provider (only Hound-TTS backend). -- @return #CTLD self -function CTLD:SetSRS(Frequency,Modulation,PathToSRS,Gender,Culture,Port,Voice,Volume,PathToGoogleKey,AccessKey,Backend,Provider) +function CTLD:SetSRS(Frequency,Modulation,PathToSRS,Gender,Culture,Port,Voice,Volume,PathToGoogleKey,AccessKey,Backend,Provider,Speaker) self:T(self.lid.."SetSRS") self.PathToSRS = PathToSRS or MSRS.path or "C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio" -- self.Gender = Gender or MSRS.gender or "male" -- @@ -1550,6 +1551,9 @@ function CTLD:SetSRS(Frequency,Modulation,PathToSRS,Gender,Culture,Port,Voice,Vo self.SRS:SetBackend(Backend) end self.SRS:SetVoice(self.Voice) + if Speaker then + self.SRS:SetSpeakerPiper(Speaker) + end self.SRSQueue = MSRSQUEUE:New(self.Label) self.SRSQueue:SetTransmitOnlyWithPlayers(true) self.SRSQueue.Label = "CTLD" diff --git a/Moose Development/Moose/Ops/CTLD_Localization.lua b/Moose Development/Moose/Ops/CTLD_Localization.lua index b32671f62..398c67c92 100644 --- a/Moose Development/Moose/Ops/CTLD_Localization.lua +++ b/Moose Development/Moose/Ops/CTLD_Localization.lua @@ -751,5 +751,177 @@ FR = { BUILD_YES = "OUI", BUILD_NO = "NON", }, + ES={ +CRATE_LOADED_GROUNDCREW="Contenedor %s cargado por el quipo de tierra.", +CRATE_UNLOADED_GROUNDCREW="Contenedor %s descargado por el quipo de tierra.", +CRATE_LOADED_ID="Contenedor ID %d para %s cargado.", +LOADED_FULL="Cargado %d %s.", +LOADED_SETS_LEFTOVER="Cargado %d %s(s), de %d contenedor(es) restante(s).", +LOADED_SETS="Cargado %d %s(s).", +LOADED_PARTIAL="Cargado sólo %d/%d contenedor(es) de %s.", +LOADED_PARTIAL_LIMIT="Cargado sólo %d/%d contenedor(es) de %s. Límite de carga alcanzado.", +LOADED_BATCH="Cargado %d %s.", +LOADED_BATCH_PARTIAL="Some sets could not be fully loaded.", +DROPPED_FULL="Entregado %d %s.", +DROPPED_SETS_LEFTOVER="Entregado %d %s(s), de %d conenedor(es) restante(s).", +DROPPED_SETS="Entregado %d %s(s).", +DROPPED_PARTIAL="Entregado %d/%d contenedor(es) de %s.", +DROPPED_INTO_ACTION="¡Soltados %s en acción!", +DROPPED_BEACON="Entregado %s | FM %s Mhz | VHF %s KHz | UHF %s Mhz ", +CRATES_POSITIONED="%d contenedores para %s servidos cerca de ti.", +CRATES_DROPPED="%d contenedores para %s han sido entregados.", +BOARDED="¡%s a bordo!", +BOARDING="¡%s entrando!", +TROOPS_RETURNED="¡Las tropas han vuelto a la base!", +DEPLOYED_NEAR_YOU="%s han sido servidas cerca de tí.", +UNITS_REMOVED="%s ha sido eliminado", +BUILD_STARTED="Construcción comenzada, listo en %d segundos.", +REPAIR_STARTED="Reparación comenzaza usando %s, tardará %d segundos.", +NO_UNIT_TO_REPAIR="No hay unidades cercanas que necesiten reparación.", +CANT_REPAIR_WITH="No se puede reparar esta unidad con %s", +CRATES_MOVE_BEFORE_BUILD="*** Los contenedores deben ser movidos antes de construirse.", +CHOPPER_CANNOT_CARRY="Lo siento, este helicóptero no puede transportar contenedores.", +TOO_HEAVY="Lo siento, esta carga es muy pesada.", +FULLY_LOADED="Lo siento, vamos hasta arriba.", +CRAMMED="Lo siento, vamos a tope.", +NO_CAPACITY_NOW="No queda capacidad para cargar más.", +NO_MORE_CAPACITY="No queda capacidad para cargar más contenedores.", +CANNOT_LOAD_NONE_OR_FULL="No se pueden cargar contenedores: n hay o no queda capacidad.", +NEED_TO_LAND_OR_HOVER_LOAD="Necesitas aterrizar o mantenerte en estacionario para cargar.", +HOVER_OVER_CRATES="Mantente en estacionario sobre el contenedor para recogerlo.", +LAND_OR_HOVER_OVER_CRATES="Aterriza o mantente en estacionario para recoger el contenedor.", +MUST_LAND_OR_HOVER_CRATES="Necesitas aterrizar o mantenerte en eestacionario para cargar contenedores.", +NEED_TO_LAND_BUILD="Necesitas aterrizar/parar para construir algo.", +NOT_CLOSE_ENOUGH_LOGISTICS="No estás cerca de una zona de logística.", +NOT_CLOSE_ENOUGH_DROP="No estás en una zona de entrega.", +NOT_CLOSE_ENOUGH_ZONE_NM="Negativo, tienes que estar a menos de %dnm de la zona.", +CANNOT_BUILD_LOADING_AREA="No puedes construir en la zona de carga.", +OPEN_DOORS_LOAD_CARGO="Necesitas abrir las puertas para cargar.", +OPEN_DOORS_LOAD_TROOPS="Necesitas abrir las puertas para que embarquen las tropas.", +OPEN_DOORS_EXTRACT_TROOPS="Necesitas abrir las puertas para poder sacar a las tropas de aquí.", +OPEN_DOORS_UNLOAD_TROOPS="Necesitas abrir las puertas para que desembarquen las tropas.", +OPEN_DOORS_DROP_CARGO="Necesitas abrir las puertas para descargar la carga.", +ALL_GONE="Lo siento, todos %s se han servido.", +RAN_OUT_OF="Lo siento, nos hemos quedad sin %s", +CARGO_NOT_AVAILABLE_ZONE="La carga solicitada no está disponible en esta zona.", +ENOUGH_CRATES_NEARBY="Hay contenedores cerca de ti listas. Encárgate primero de ellos.", +NO_CRATES_WITHIN="No ha contenedores (cargables) en %d metros.", +NO_CRATES_WITHIN_PLAIN="No hay contenedores en %d metros.", +NO_CRATES_IN_RANGE="No se han encontrado contenedores en rango.", +NO_NAMED_CRATES_IN_RANGE="No se han encontrado \"%s\" conenedores en rango.", +NO_LOADABLE_CRATES="Lo siento, no hay contenedores cercanos o se ha alcanzado el peso máximo.", +NO_UNITS_TO_EXTRACT="No hay unidades cercanas para extracción.", +NO_UNIT_CONFIG="No se ha encontrado configuración de unidad para %s", +CANT_ONBOARD="No puede subir %s", +TOO_MANY_UNITS_NEARBY="Ya tienes %d unidades próximas.", +NO_CRATE_GROUPS="No se han encontrado grupos de contendeores para esta unidad.", +NO_CRATE_SET="No se ha encontrado contenedor o su index es inválido.", +NO_CRATE_IN_SET="No se ha encontrado contenedor para este set.", +NO_TROOP_CHUNK="No se han encontrado tropas para el id %d!", +TROOP_CHUNK_EMPTY="Troop chunk is empty for ID %d!", +NOTHING_LOADED="Nada cargado.\nLímite tropas: %d | Límite contenedores: %d | Peso límite: %d kg.", +NOTHING_LOADED_AIRDROP="Nada cargado o no estás en parámetros de lanzamiento aéreo.", +NOTHING_LOADED_HOVER="Nada cargado o no estás en parámetros de estacionario.", +NOTHING_IN_STOCK="¡Nada en stock!", +NOTHING_TO_PACK="Nada para empaquetar a esta distancia.", +NOTHING_TO_REMOVE="Nada para eliminar a esta distancia.", +ROGER_ZONE="Recibido, %s cona %s!", +HOVER_PARAMS_METRIC="Parámetros en estacionario (autocarga/suelta):\n - Altura mínima %dm \n - Altura máxima %dm \n - Velocidad máxima 2mps \n - En parámetros: %s", +HOVER_PARAMS_IMPERIAL="Parámetros en estacionario (autocarga/suelta):\n - Altura mínima %dft \n - Altura máxima %dft \n - Velocidad máxima 6ftps \n - En parámetros: %s", +FLIGHT_PARAMS_IMPERIAL="Parámetros vuelo (lanzamiento aéreo):\n - Altura mínima %dft \n - Altura máxima %dft \n - En parámetros: %s", +FLIGHT_PARAMS_METRIC="Parámetros vuelo (lanzamiento aéreo):\n - Altura mínima %dm \n - Altura máxima %dm \n - En parámetros: %s", +REPORT_CRATES_FOUND="Contenedores encontrados cerca:", +REPORT_REMOVING_CRATES="Contenedores eliminados cerca:", +REPORT_TRANSPORT_CHECKOUT="Informe de transporte", +REPORT_INVENTORY="Inventario", +REPORT_BUILD_CHECKLIST="Contenedores construibles", +REPORT_REPAIR_CHECKLIST="Reparaciones", +REPORT_BEACONS="Active Zone Beacons", +REPORT_SECTION_TROOPS=" -- TROPAS --", +REPORT_SECTION_CRATES=" -- CONTENEDORES --", +REPORT_SECTION_CRATES_GC=" -- Contenedores cargados por equipo de tierra --", +REPORT_SECTION_NONE=" N A D A", +REPORT_SECTION_NONE_ALT=" --- Nada encontrado ---", +REPORT_SECTION_NONE_REPAIR=" --- Nada encontrado ---", +REPORT_GC_LOADABLE_HINT="Probablemente cargable por el equipo de tierra (F8)", +REPORT_TOTAL_MASS="Peso total: %s kg. Cargable: %s kg.", +REPORT_TROOPS_CRATES_COUNT="Tropas: %d(%d), Contenedores: %d(%d)", +REPORT_TROOPS_CRATETYPES_COUNT="Tropas: %d, Tipos contenedores: %d", +REPORT_ROW_TROOP="Tropas: %s tamaño %d", +REPORT_ROW_CRATE="Contenedores: %s %d/%d", +REPORT_ROW_CRATE_SIZE1="Contenedores: %s tamaño 1", +REPORT_ROW_GC_CRATE="Contenedores cargados: %s tamaño 1", +REPORT_ROW_DROPPED_CRATE="Entregado contenedor para %s, %dkg", +REPORT_ROW_CRATE_KG="Contenedor para %s, %dkg", +REPORT_ROW_CRATE_REMOVED="Contenedor para %s, %dkg eliminado", +REPORT_ROW_UNIT_STOCK="Unidad: %s | Soldados: %d | Stock: %s", +REPORT_ROW_TYPE_CRATE_STOCK="Tipo: %s | Contenedores por set: %d | Stock: %s", +REPORT_ROW_TYPE_STOCK="Tipo: %s | Stock: %s", +REPORT_ROW_BUILD_CHECK="Tipo: %s | Rquiere %d | Encontrados %d | Construible %s", +REPORT_ROW_REPAIR_CHECK="Tipo: %s | Requiere %d | Encontrados %d | Reparable %s", +REPORT_ROW_BEACON=" %s | FM %s Mhz | VHF %s KHz | UHF %s Mhz ", +WEIGHT_LIMIT="Alcanzado límite de pesoWeight limit reached", +CRATE_LIMIT="Alcanzado límite contenedores", +MENU_CTLD="CTLD", +MENU_MANAGE_TROOPS="Gestionar tropas", +MENU_MANAGE_CRATES="Gestionar contenedores", +MENU_MANAGE_UNITS="Gestionar unidades", +MENU_LOAD_TROOPS="Cargar tropas", +MENU_DROP_TROOPS="Entregar tropas", +MENU_DROP_ALL_TROOPS="Entregar TODAS tropas", +MENU_EXTRACT_TROOPS="Extraer tropas", +MENU_DROP_N_TROOPS="Soltar (%d) %s", +MENU_GET_CRATES="Solicitar contenedores", +MENU_GET="Solicitar", +MENU_GET_AND_LOAD="Solicitar y cargar", +MENU_GET_ANYWAY="Solicitar de todas formas", +MENU_PARTIALLY_LOAD="Carga parcial", +MENU_OUT_OF_STOCK="Sin stock", +MENU_TROOP_LIMIT="Limite de tropas alcanzado", +MENU_LOAD_CRATES="Cargar contenedores", +MENU_LOAD_ALL="Cargar TODO", +MENU_SHOW_LOADABLE_CRATES="Mostrar contenedores carbables", +MENU_NO_CRATES_FOUND_RESCAN="Contenedores no encontrados, ¿buscar?", +MENU_USE_C130_LOAD="Usar sistmea de carga del C-130", +MENU_LOAD_SINGLE="Cargar", +MENU_DROP_CRATES="Soltar cargas", +MENU_DROP_ALL_CRATES="Soltar TODAS cargas", +MENU_DROP="Soltar", +MENU_DROP_AND_BUILD="Soltar y constuir", +MENU_DROP_N_SETS="Soltar %d Set %s", +MENU_NO_CRATES_TO_DROP="No hay cargas para soltar", +MENU_BUILD_CRATES="Construir contenedores", +MENU_REPAIR="Reparar", +MENU_PACK_CRATES="Empaquetar cargas", +MENU_PACK="Empaquetar", +MENU_PACK_AND_LOAD="Empaquetar y cargar", +MENU_PACK_AND_REMOVE="Empaquetar y eliminar", +MENU_REMOVE_CRATES="Eliminar cargas", +MENU_REMOVE_CRATES_NEARBY="Eliminar cargas cercanas", +MENU_LIST_CRATES_NEARBY="Listar cargas cercanas", +MENU_CRATES_NEEDED="%d contenedor%s %s (%dkg)", +MENU_GET_UNITS="Obtener unidades", +MENU_REMOVE_UNITS_NEARBY="Eliminar unidades cercanas", +MENU_LIST_BOARDED_CARGO="Lista de cargas a bordo", +MENU_INVENTORY="Inventario", +MENU_LIST_ZONE_BEACONS="Lista de balizas activas", +MENU_SMOKES_FLARES_BEACONS="Humos, Bengalas, Balizas", +MENU_SMOKE_ZONES_NEARBY="Humo en zonas cercanas", +MENU_DROP_SMOKE_NOW="Lanzar humo ahora", +MENU_RED_SMOKE="Humo rojo", +MENU_BLUE_SMOKE="Humo azul", +MENU_GREEN_SMOKE="Humo verde", +MENU_ORANGE_SMOKE="Humo naranja", +MENU_WHITE_SMOKE="Humo blanco", +MENU_FLARE_ZONES_NEARBY="Bengalas en zonas cercanas", +MENU_FIRE_FLARE_NOW="Disparar bengala ahora", +MENU_DROP_BEACON_NOW="Soltar baliza ahora", +MENU_SHOW_FLIGHT_PARAMS="Mostrar parámetros de vuelo", +MENU_SHOW_HOVER_PARAMS="Mostrar parámetros estacionario", +STOCK_NONE="Nada", +STOCK_UNLIMITED="ilimitado", +BUILD_YES="SI", +BUILD_NO="NO", +}, } - \ No newline at end of file + diff --git a/Moose Development/Moose/Ops/FlightControl.lua b/Moose Development/Moose/Ops/FlightControl.lua index 982eb55e6..1bb0383cf 100644 --- a/Moose Development/Moose/Ops/FlightControl.lua +++ b/Moose Development/Moose/Ops/FlightControl.lua @@ -667,8 +667,9 @@ end -- @param #string Label Name under which SRS transmits. -- @param #string PathToGoogleCredentials (Optional) Path to google credentials json file. -- @param #number Port (Optional) Server port for SRS. Defaults to 5002. +-- @param #string Speaker (Optional) Use a specific speaker for a voice if Piper is used as provider (only Hound-TTS backend). -- @return #FLIGHTCONTROL self -function FLIGHTCONTROL:_SetSRSOptions(msrs, Gender, Culture, Voice, Volume, Label, PathToGoogleCredentials, Port) +function FLIGHTCONTROL:_SetSRSOptions(msrs, Gender, Culture, Voice, Volume, Label, PathToGoogleCredentials, Port, Speaker) -- Defaults: Gender=Gender or "female" @@ -679,6 +680,9 @@ function FLIGHTCONTROL:_SetSRSOptions(msrs, Gender, Culture, Voice, Volume, Labe msrs:SetGender(Gender) msrs:SetCulture(Culture) msrs:SetVoice(Voice) + if Speaker then + msrs:SetSpeakerPiper(Speaker) + end msrs:SetVolume(Volume) msrs:SetLabel(Label) msrs:SetCoalition(self:GetCoalition()) @@ -695,11 +699,12 @@ end -- @param #string Voice Specific voice. Overrides `Gender` and `Culture`. See [Google Voices](https://cloud.google.com/text-to-speech/docs/voices). -- @param #number Volume (Optional) Volume. Default 1.0. -- @param #string Label (Optional) Name under which SRS transmits. Default `self.alias`. +-- @param #string Speaker (Optional) Use a specific speaker for a voice if Piper is used as provider (only Hound-TTS backend). -- @return #FLIGHTCONTROL self -function FLIGHTCONTROL:SetSRSTower(Gender, Culture, Voice, Volume, Label) +function FLIGHTCONTROL:SetSRSTower(Gender, Culture, Voice, Volume, Label, Speaker) if self.msrsTower then - self:_SetSRSOptions(self.msrsTower, Gender or "female", Culture or "en-GB", Voice, Volume, Label or self.alias) + self:_SetSRSOptions(self.msrsTower, Gender or "female", Culture or "en-GB", Voice, Volume, Label or self.alias,nil,nil,Speaker) end return self @@ -712,11 +717,12 @@ end -- @param #string Voice Specific voice. Overrides `Gender` and `Culture`. -- @param #number Volume (Optional) Volume. Default 1.0. -- @param #string Label (Optional) Name under which SRS transmits. Default "Pilot". +-- @param #string Speaker (Optional) Use a specific speaker for a voice if Piper is used as provider (only Hound-TTS backend). -- @return #FLIGHTCONTROL self -function FLIGHTCONTROL:SetSRSPilot(Gender, Culture, Voice, Volume, Label) +function FLIGHTCONTROL:SetSRSPilot(Gender, Culture, Voice, Volume, Label, Speaker) if self.msrsPilot then - self:_SetSRSOptions(self.msrsPilot, Gender or "male", Culture or "en-US", Voice, Volume, Label or "Pilot") + self:_SetSRSOptions(self.msrsPilot, Gender or "male", Culture or "en-US", Voice, Volume, Label or "Pilot",nil,nil,Speaker) end return self diff --git a/Moose Development/Moose/Ops/FlightGroup.lua b/Moose Development/Moose/Ops/FlightGroup.lua index 916739b66..193cae10b 100644 --- a/Moose Development/Moose/Ops/FlightGroup.lua +++ b/Moose Development/Moose/Ops/FlightGroup.lua @@ -217,7 +217,7 @@ FLIGHTGROUP.Players={} --- FLIGHTGROUP class version. -- @field #string version -FLIGHTGROUP.version="1.0.3" +FLIGHTGROUP.version="1.0.4" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- TODO list @@ -1354,8 +1354,10 @@ function FLIGHTGROUP:Status() -- If mission, check if DCS task needs to be updated. if mission and mission.updateDCSTask then + local mtype=mission:GetType() + -- Orbit missions might need updates. - if (mission:GetType()==AUFTRAG.Type.ORBIT or mission:GetType()==AUFTRAG.Type.RECOVERYTANKER or mission:GetType()==AUFTRAG.Type.CAP) and mission.orbitVec2 then + if (mtype==AUFTRAG.Type.ORBIT or mtype==AUFTRAG.Type.RECOVERYTANKER or mtype==AUFTRAG.Type.CAP or mtype==AUFTRAG.Type.AWACS) and mission.orbitVec2 then -- Get 2D vector of orbit target. local vec2=mission:GetTargetVec2() diff --git a/Moose Development/Moose/Ops/OpsGroup.lua b/Moose Development/Moose/Ops/OpsGroup.lua index cf8e6defd..22f265657 100644 --- a/Moose Development/Moose/Ops/OpsGroup.lua +++ b/Moose Development/Moose/Ops/OpsGroup.lua @@ -2356,8 +2356,9 @@ end -- @param #string Label (Optional) Label of the SRS comms for the SRS Radio overlay. Defaults to "ROBOT". No spaces allowed! -- @param #number Volume (Optional) Volume to be set, 0.0 = silent, 1.0 = loudest. Defaults to 1.0 -- @param #string Provider (Optional) TTS Provider to be used. +-- @param #string Speaker (Optional) Use a specific speaker for a voice if Piper is used as provider (only Hound-TTS backend). -- @return #OPSGROUP self -function OPSGROUP:SetSRS(PathToSRS, Gender, Culture, Voice, Port, PathToGoogleKey, Label, Volume,Provider) +function OPSGROUP:SetSRS(PathToSRS, Gender, Culture, Voice, Port, PathToGoogleKey, Label, Volume,Provider,Speaker) self.useSRS=true local path = PathToSRS or MSRS.path local port = Port or MSRS.port @@ -2365,6 +2366,9 @@ function OPSGROUP:SetSRS(PathToSRS, Gender, Culture, Voice, Port, PathToGoogleKe self.msrs:SetGender(Gender) self.msrs:SetCulture(Culture) self.msrs:SetVoice(Voice) + if Speaker then + self.msrs:SetSpeakerPiper(Speaker) + end self.msrs:SetPort(port) self.msrs:SetLabel(Label) if PathToGoogleKey then diff --git a/Moose Development/Moose/Ops/PlayerRecce.lua b/Moose Development/Moose/Ops/PlayerRecce.lua index c454f0699..402cea4f6 100644 --- a/Moose Development/Moose/Ops/PlayerRecce.lua +++ b/Moose Development/Moose/Ops/PlayerRecce.lua @@ -1554,8 +1554,9 @@ end -- @param #string PathToGoogleKey (Optional) Path to your google key if you want to use google TTS -- @param #string Backend (optional) Backend to be used, can be MSRS.Backend.SRSEXE or MSRS.Backend.GRPC etc -- @param #string Provider (Optional) TTS Provider to be used. +-- @param #string Speaker (Optional) Use a specific speaker for a voice if Piper is used as provider (only Hound-TTS backend). -- @return #PLAYERRECCE self -function PLAYERRECCE:SetSRS(Frequency,Modulation,PathToSRS,Gender,Culture,Port,Voice,Volume,PathToGoogleKey,Backend,Provider) +function PLAYERRECCE:SetSRS(Frequency,Modulation,PathToSRS,Gender,Culture,Port,Voice,Volume,PathToGoogleKey,Backend,Provider,Speaker) self:T(self.lid.."SetSRS") self.PathToSRS = PathToSRS or MSRS.path or "C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio" -- self.Gender = Gender or MSRS.gender or "male" -- @@ -1593,6 +1594,9 @@ function PLAYERRECCE:SetSRS(Frequency,Modulation,PathToSRS,Gender,Culture,Port,V self.Voice = Voice or MSRS.poptions.gcloud.voice end self.SRS:SetVoice(self.Voice) + if Speaker then + self.SRS:SetSpeakerPiper(Speaker) + end self.SRSQueue = MSRSQUEUE:New(self.MenuName or self.Name) self.SRSQueue:SetTransmitOnlyWithPlayers(self.TransmitOnlyWithPlayers) return self diff --git a/Moose Development/Moose/Ops/PlayerTask.lua b/Moose Development/Moose/Ops/PlayerTask.lua index 9485cbab8..ab1a9e4c8 100644 --- a/Moose Development/Moose/Ops/PlayerTask.lua +++ b/Moose Development/Moose/Ops/PlayerTask.lua @@ -4912,8 +4912,9 @@ end -- @param Core.Point#COORDINATE Coordinate (Optional) Coordinate from which the controller radio is sending -- @param #string Backend (Optional) MSRS Backend to be used, can be MSRS.Backend.SRSEXE or MSRS.Backend.GRPC; if you use a config file for MSRS, you can hand in nil here. -- @param #string Provider (Optional) TTS Provider to be used. +-- @param #string Speaker (Optional) Use a specific speaker for a voice if Piper is used as provider (only Hound-TTS backend). -- @return #PLAYERTASKCONTROLLER self -function PLAYERTASKCONTROLLER:SetSRS(Frequency,Modulation,PathToSRS,Gender,Culture,Port,Voice,Volume,PathToGoogleKey,AccessKey,Coordinate,Backend,Provider) +function PLAYERTASKCONTROLLER:SetSRS(Frequency,Modulation,PathToSRS,Gender,Culture,Port,Voice,Volume,PathToGoogleKey,AccessKey,Coordinate,Backend,Provider,Speaker) self:T(self.lid.."SetSRS") self.PathToSRS = PathToSRS or MSRS.path or "C:\\Program Files\\DCS-SimpleRadio-Standalone\\ExternalAudio" -- self.Gender = Gender or MSRS.gender or "male" -- @@ -4954,6 +4955,9 @@ function PLAYERTASKCONTROLLER:SetSRS(Frequency,Modulation,PathToSRS,Gender,Cultu self.SRS:SetCoordinate(Coordinate) end self.SRS:SetVoice(self.Voice) + if Speaker then + self.SRS:SetSpeakerPiper(Speaker) + end self.SRSQueue = MSRSQUEUE:New(self.MenuName or self.Name) self.SRSQueue:SetTransmitOnlyWithPlayers(self.TransmitOnlyWithPlayers) return self diff --git a/Moose Development/Moose/Wrapper/Controllable.lua b/Moose Development/Moose/Wrapper/Controllable.lua index 764c98c06..6d715b243 100644 --- a/Moose Development/Moose/Wrapper/Controllable.lua +++ b/Moose Development/Moose/Wrapper/Controllable.lua @@ -1101,8 +1101,8 @@ end -- @param DCS#Distance Altitude (optional) Desired attack start altitude. Controllable/aircraft will make its attacks from the altitude. If the altitude is too low or too high to use weapon aircraft/controllable will choose closest altitude to the desired attack start altitude. If the desired altitude is defined controllable/aircraft will not attack from safe altitude. -- @param #boolean GroupAttack (Optional) If true, attack as group. -- @return DCS#Task The DCS task structure. -function CONTROLLABLE:TaskAttackGroup( AttackGroup, WeaponType, WeaponExpend, AttackQty, Direction, Altitude, AttackQtyLimit, GroupAttack ) - -- self:F2( { self.ControllableName, AttackGroup, WeaponType, WeaponExpend, AttackQty, Direction, Altitude, AttackQtyLimit } ) +function CONTROLLABLE:TaskAttackGroup( AttackGroup, WeaponType, WeaponExpend, AttackQty, Direction, Altitude, GroupAttack ) + -- self:F2( { self.ControllableName, AttackGroup, WeaponType, WeaponExpend, AttackQty, Direction, Altitude, GroupAttack } ) local DCSTask = { id = 'AttackGroup', params = { groupId = AttackGroup:GetID(),