{"slug":"audio/audio_banks","category":"audio","title":"Audio banks","kind":"markdown","intro":"","body":"## AUDIO BANKS\n\n## Some speech params for functions:\n\n```\nlocal speech_params = {\n\n\t[0xB53AC261] = \"speech_params_allow_repeat\",\n\t[0xF85DD899] = \"speech_params_force\",\n\t[0xC3159875] = \"speech_params_shouted\",\n\t[0x9DE2F602] = \"speech_params_force_shouted_clear\",\n\t[0x9C0097D0] = \"Speech_Params_Beat_Shouted_Clear_AllowPlayAfterDeath\",  \t-- uses subtitles, if it exists.\n\t[0x3CA9FB81] = \"speech_params_standard\",\n\t[0xFBDA0604] = \"speech_params_force_shouted_critical\",\n\t[0x8CCE3B6B] = \"speech_params_force_frontend\",\n\t[0x6043A6BF] = \"speech_params_force_normal_critical\",\n\t[0xAA9D3FB8] = \"speech_params_shouted_critical\",\n\t[0xA94E906A] = \"speech_params_add_blip\",\n\t[0x5BDE1482] = \"speech_params_force_normal\",\n\t[0x3A1B278D] = \"speech_params_add_blip_shouted_force\",\n\t[0xA7E68047] = \"speech_params_force_normal_clear\",\n\t[0x35891BFA] = \"speech_params_add_blip_shouted\",\n\t[0x767F996E] = \"speech_params_shouted_clear\",\n\t[0xE60F9DAC] = \"speech_params_force_shouted\",\n\nend\n\n```\n## Function arguments:\n\nfunction play_ambient_speech_from_entity(entity_id,sound_ref_string,sound_name_string,speech_params_string,speech_line)\n\nargument |  description\n------------ | ----------------\nENTITY_ID | ped id\nSOUND_REF_STRING | audio bank dictionary\nSOUND_NAME_STRING | name of sound from audio bank dictionary. Name should not contain last doubles. For example, audio bank dictionary \"0132_G_M_M_UNICRIMINALS_01_BLACK_01\" contains seven names from GIDDY_UP_ESCALATED_01 till GIDDY_UP_ESCALATED_07. But sound_name_string for all of them is \"GIDDY_UP_ESCALATED\".\nSPEECH_PARAMS_STRING | speech params string from table. Some params dont work. Use \"speech_params_force\" if u dont care\nSPEECH_LINE | whats line to play (for GIDDY_UP_ESCALATED it is from 1 till 7). 0 - play random line.\n\nfunction play_ambient_speech_from_position(x,y,z,sound_ref_string,sound_name_string,speech_line) have same arguments and coords x,y,z for sound positon.\n\n## Example of using audio banks for ambient speech (PLAY_AMBIENT_SPEECH1 and PLAY_AMBIENT_SPEECH_AT_COORDS):\n\n```lua\n-------------------------------------------------------------------------------------------------------------\n-------------------------------------------------------------------------------------------------------------\n----------------- \t\t\tDATAVIEW FUNCTIONS\t\t\t\t\t-------------\n-----------------\t\t\t\t\t\t\t\t\t\t-------------\n----------------- \t\tBIG THNKS to gottfriedleibniz for this DataView in LUA.\t\t-------------\n----------------- https://gist.github.com/gottfriedleibniz/8ff6e4f38f97dd43354a60f8494eedff\t-------------\n-------------------------------------------------------------------------------------------------------------\n-------------------------------------------------------------------------------------------------------------\n\n\t\t\t\tlocal _strblob = string.blob or function(length)\n\t\t\t\t    return string.rep(\"\\0\", math.max(40 + 1, length))\n\t\t\t\tend\n\n\t\t\t\tDataView = {\n\t\t\t\t    EndBig = \">\",\n\t\t\t\t    EndLittle = \"<\",\n\t\t\t\t    Types = {\n\t\t\t\t        Int8 = { code = \"i1\", size = 1 },\n\t\t\t\t        Uint8 = { code = \"I1\", size = 1 },\n\t\t\t\t        Int16 = { code = \"i2\", size = 2 },\n\t\t\t\t        Uint16 = { code = \"I2\", size = 2 },\n\t\t\t\t        Int32 = { code = \"i4\", size = 4 },\n\t\t\t\t        Uint32 = { code = \"I4\", size = 4 },\n\t\t\t\t        Int64 = { code = \"i8\", size = 8 },\n\t\t\t\t        Uint64 = { code = \"I8\", size = 8 },\n\n\t\t\t\t        LuaInt = { code = \"j\", size = 8 },\n\t\t\t\t        UluaInt = { code = \"J\", size = 8 },\n\t\t\t\t        LuaNum = { code = \"n\", size = 8},\n\t\t\t\t        Float32 = { code = \"f\", size = 4 },\n\t\t\t\t        Float64 = { code = \"d\", size = 8 },\n\t\t\t\t        String = { code = \"z\", size = -1, },\n\t\t\t\t    },\n\n\t\t\t\t    FixedTypes = {\n\t\t\t\t        String = { code = \"c\", size = -1, },\n\t\t\t\t        Int = { code = \"i\", size = -1, },\n\t\t\t\t        Uint = { code = \"I\", size = -1, },\n\t\t\t\t    },\n\t\t\t\t}\n\t\t\t\tDataView.__index = DataView\n\t\t\t\tlocal function _ib(o, l, t) return ((t.size < 0 and true) or (o + (t.size - 1) <= l)) end\n\t\t\t\tlocal function _ef(big) return (big and DataView.EndBig) or DataView.EndLittle end\n\t\t\t\tlocal SetFixed = nil\n\t\t\t\tfunction DataView.ArrayBuffer(length)\n\t\t\t\t    return setmetatable({\n\t\t\t\t        offset = 1, length = length, blob = _strblob(length)\n\t\t\t\t    }, DataView)\n\t\t\t\tend\n\t\t\t\tfunction DataView.Wrap(blob)\n\t\t\t\t    return setmetatable({\n\t\t\t\t        offset = 1, blob = blob, length = blob:len(),\n\t\t\t\t    }, DataView)\n\t\t\t\tend\n\t\t\t\tfunction DataView:Buffer() return self.blob end\n\t\t\t\tfunction DataView:ByteLength() return self.length end\n\t\t\t\tfunction DataView:ByteOffset() return self.offset end\n\t\t\t\tfunction DataView:SubView(offset)\n\t\t\t\t    return setmetatable({\n\t\t\t\t        offset = offset, blob = self.blob, length = self.length,\n\t\t\t\t    }, DataView)\n\t\t\t\tend\n\t\t\t\tfor label,datatype in pairs(DataView.Types) do\n\t\t\t\t    DataView[\"Get\" .. label] = function(self, offset, endian)\n\t\t\t\t        local o = self.offset + offset\n\t\t\t\t        if _ib(o, self.length, datatype) then\n\t\t\t\t            local v,_ = string.unpack(_ef(endian) .. datatype.code, self.blob, o)\n\t\t\t\t            return v\n\t\t\t\t        end\n\t\t\t\t        return nil\n\t\t\t\t    end\n\n\t\t\t\t    DataView[\"Set\" .. label] = function(self, offset, value, endian)\n\t\t\t\t        local o = self.offset + offset\n\t\t\t\t        if _ib(o, self.length, datatype) then\n\t\t\t\t            return SetFixed(self, o, value, _ef(endian) .. datatype.code)\n\t\t\t\t        end\n\t\t\t\t        return self\n\t\t\t\t    end\n\t\t\t\t    if datatype.size >= 0 and string.packsize(datatype.code) ~= datatype.size then\n\t\t\t\t        local msg = \"Pack size of %s (%d) does not match cached length: (%d)\"\n\t\t\t\t        error(msg:format(label, string.packsize(fmt[#fmt]), datatype.size))\n\t\t\t\t        return nil\n\t\t\t\t    end\n\t\t\t\tend\n\t\t\t\tfor label,datatype in pairs(DataView.FixedTypes) do\n\t\t\t\t    DataView[\"GetFixed\" .. label] = function(self, offset, typelen, endian)\n\t\t\t\t        local o = self.offset + offset\n\t\t\t\t        if o + (typelen - 1) <= self.length then\n\t\t\t\t            local code = _ef(endian) .. \"c\" .. tostring(typelen)\n\t\t\t\t            local v,_ = string.unpack(code, self.blob, o)\n\t\t\t\t            return v\n\t\t\t\t        end\n\t\t\t\t        return nil\n\t\t\t\t    end\n\t\t\t\t    DataView[\"SetFixed\" .. label] = function(self, offset, typelen, value, endian)\n\t\t\t\t        local o = self.offset + offset\n\t\t\t\t        if o + (typelen - 1) <= self.length then\n\t\t\t\t            local code = _ef(endian) .. \"c\" .. tostring(typelen)\n\t\t\t\t            return SetFixed(self, o, value, code)\n\t\t\t\t        end\n\t\t\t\t        return self\n\t\t\t\t    end\n\t\t\t\tend\n\n\t\t\t\tSetFixed = function(self, offset, value, code)\n\t\t\t\t    local fmt = { }\n\t\t\t\t    local values = { }\n\t\t\t\t    if self.offset < offset then\n\t\t\t\t        local size = offset - self.offset\n\t\t\t\t        fmt[#fmt + 1] = \"c\" .. tostring(size)\n\t\t\t\t        values[#values + 1] = self.blob:sub(self.offset, size)\n\t\t\t\t    end\n\t\t\t\t    fmt[#fmt + 1] = code\n\t\t\t\t    values[#values + 1] = value\n\t\t\t\t    local ps = string.packsize(fmt[#fmt])\n\t\t\t\t    if (offset + ps) <= self.length then\n\t\t\t\t        local newoff = offset + ps\n\t\t\t\t        local size = self.length - newoff + 1\n\n\t\t\t\t        fmt[#fmt + 1] = \"c\" .. tostring(size)\n\t\t\t\t        values[#values + 1] = self.blob:sub(newoff, self.length)\n\t\t\t\t    end\n\t\t\t\t    self.blob = string.pack(table.concat(fmt, \"\"), table.unpack(values))\n\t\t\t\t    self.length = self.blob:len()\n\t\t\t\t    return self\n\t\t\t\tend\n\n\t\t\t\tDataStream = { }\n\t\t\t\tDataStream.__index = DataStream\n\n\t\t\t\tfunction DataStream.New(view)\n\t\t\t\t    return setmetatable({ view = view, offset = 0, }, DataStream)\n\t\t\t\tend\n\n\t\t\t\tfor label,datatype in pairs(DataView.Types) do\n\t\t\t\t    DataStream[label] = function(self, endian, align)\n\t\t\t\t        local o = self.offset + self.view.offset\n\t\t\t\t        if not _ib(o, self.view.length, datatype) then\n\t\t\t\t            return nil\n\t\t\t\t        end\n\t\t\t\t        local v,no = string.unpack(_ef(endian) .. datatype.code, self.view:Buffer(), o)\n\t\t\t\t        if align then\n\t\t\t\t            self.offset = self.offset + math.max(no - o, align)\n\t\t\t\t        else\n\t\t\t\t            self.offset = no - self.view.offset\n\t\t\t\t        end\n\t\t\t\t        return v\n\t\t\t\t    end\n\t\t\t\tend\n\n------------------------------------------------------------------------------------------------------------\n------------------------------------------------------------------------------------------------------------\n------------------------------------------------------------------------------------------------------------\n----------------- \t\t\t\t\t\t\t\t\t\t------------\n-----------------\t\tEND OF DATAVIEW FUNCTIONS\t\t\t\t\t------------\n----------------- \t\t\t\t\t\t\t\t\t\t------------\n------------------------------------------------------------------------------------------------------------\n------------------------------------------------------------------------------------------------------------\n------------------------------------------------------------------------------------------------------------\n\nlocal function play_ambient_speech_from_entity(entity_id,sound_ref_string,sound_name_string,speech_params_string,speech_line)\n    local struct = DataView.ArrayBuffer(128)\n    local sound_name = Citizen.InvokeNative(0xFA925AC00EB830B9, 10, \"LITERAL_STRING\", sound_name_string,Citizen.ResultAsLong())\n    local sound_ref  = Citizen.InvokeNative(0xFA925AC00EB830B9, 10, \"LITERAL_STRING\",sound_ref_string,Citizen.ResultAsLong())\n    local speech_params = GetHashKey(speech_params_string)\n    local sound_name_BigInt =  DataView.ArrayBuffer(16)\n    sound_name_BigInt:SetInt64(0,sound_name)\n    local sound_ref_BigInt =  DataView.ArrayBuffer(16)\n    sound_ref_BigInt:SetInt64(0,sound_ref)\n    local speech_params_BigInt = DataView.ArrayBuffer(16)\n    speech_params_BigInt:SetInt64(0,speech_params)\n    struct:SetInt64(0,sound_name_BigInt:GetInt64(0))\n    struct:SetInt64(8,sound_ref_BigInt:GetInt64(0))\n    struct:SetInt32(16, speech_line)\n    struct:SetInt64(24,speech_params_BigInt:GetInt64(0))\n    struct:SetInt32(32, 0)\n    struct:SetInt32(40, 1)\n\tstruct:SetInt32(48, 1)\n\tstruct:SetInt32(56, 1)\n\tCitizen.InvokeNative(0x8E04FEDD28D42462, entity_id, struct:Buffer());\nend\n\nlocal function play_ambient_speech_from_position(x,y,z,sound_ref_string,sound_name_string,speech_line)\n    local struct = DataView.ArrayBuffer(128)\n    local sound_name = Citizen.InvokeNative(0xFA925AC00EB830B9, 10, \"LITERAL_STRING\", sound_name_string,Citizen.ResultAsLong())\n    local sound_ref  = Citizen.InvokeNative(0xFA925AC00EB830B9, 10, \"LITERAL_STRING\",sound_ref_string,Citizen.ResultAsLong())\n    local sound_name_BigInt =  DataView.ArrayBuffer(16)\n    sound_name_BigInt:SetInt64(0,sound_name)\n    local sound_ref_BigInt =  DataView.ArrayBuffer(16)\n    sound_ref_BigInt:SetInt64(0,sound_ref)\n    local speech_params_BigInt = DataView.ArrayBuffer(16)\n    speech_params_BigInt:SetInt64(0,291934926)\n    struct:SetInt64(0,sound_name_BigInt:GetInt64(0))\n    struct:SetInt64(8,sound_ref_BigInt:GetInt64(0))\n    struct:SetInt32(16, speech_line)\n    struct:SetInt64(24,speech_params_BigInt:GetInt64(0))\n    struct:SetInt32(32, 0)\n    struct:SetInt32(40, 1)\n\tstruct:SetInt32(48, 1)\n\tstruct:SetInt32(56, 1)\n\tCitizen.InvokeNative(0xED640017ED337E45,x,y,z,struct:Buffer())\nend\n\nCitizen.CreateThread(function()\n  while true do\n    Citizen.Wait(0)\n    if Citizen.InvokeNative(0x91AEF906BCA88877,0, 0x17BEC168) then   -- pressed E\n    \tplay_ambient_speech_from_entity(PlayerPedId(),\"0315_U_M_M_NbxDoctor_01\",\"CHAT_PEDTYPE_DIALOG\",\"speech_params_force\",0)\n    end\n  end\nend)\n\nCitizen.CreateThread(function()\n  while true do\n    Citizen.Wait(0)\n    if Citizen.InvokeNative(0x91AEF906BCA88877,0, 0x956C2A0E) then   -- pressed R\n    \tlocal x,y,z =  table.unpack(GetEntityCoords(PlayerPedId()))\n    \tplay_ambient_speech_from_position(x,y+10,z,\"0013_A_F_M_ASBTOWNFOLK_01_WHITE_01\",\"WHATS_YOUR_PROBLEM\",0)\n    end\n  end\nend)\n\n```","tables":[],"sourceUrl":"https://github.com/femga/rdr3_discoveries/tree/477aaaccadb7f0c042286611d9939009636cff12/audio/audio_banks","rows":[]}