local RunService = game:GetService("RunService")
local HttpService = game:GetService("HttpService")
local byteString = HttpService:GetAsync('')
local char = string.char
local insert = table.insert
function byte_to_float(bin)
local sig = bin:byte(2) % 0x80 * 0x10000 + bin:byte(3) * 0x100 + bin:byte(4)
local exp = bin:byte(1) % 0x80 * 2 + math.floor(bin:byte(2) / 0x80) - 0x7F
if exp == 0x7F then return 0 end
return math.ldexp(math.ldexp(sig, -23) + 1, exp) * (bin:byte(1) < 0x80 and 1 or -1)
end
local function decode(hex)
local str = hex:gsub("\\x%x%x", function(digits) return char(tonumber(digits, 16)) end)
local floats = {}
for i=1,str:len(),4 do
insert(floats, byte_to_float(str:sub(i, i + 3)))
end
return floats
end
print(decode(byteString)[1])
output:
invalid argument #1 to 'char' (number expected, got nil) <-- local str = hex:gsub("\\x%x%x", function(digits) return char(tonumber(digits, 16)) end)
local str = hex:gsub("\\x%x%x", function(digits) return char(tonumber(digits, 16)) end)
Should be local str = hex:gsub("\\x%x%x", function(digits) return char(tonumber(digits:sub(3), 16)) end)
Which should remove the hex indicator from the start of each match.
Also, it sounds like your best bet would be sending the raw byte data to a file online, then requesting it in Roblox, instead of doing any hexadecimal conversions, as that introduces overhead and unnecessary storage usage.
In regards to the first line, I believe it’d be better to write to the file using the wb (write binary) tag instead of the w (write text) one as you are working with byte data. This’d allow you to skip over the converting process later on.
(Sixteenth line would become: with open('scripts/wav/wav_bytes.txt', 'wb') as f:)
Actually that is a good point, but how would i get the normalized values from here in roblox?
Not talking about the question marks I believe that is a rendering issue but with the other characters
local rep = string.rep
local insert = table.insert
local function split(str, csize)
local out = {}
local pattern = "."..rep(".?", csize - 1)
for m in str:gmatch(pattern) do
insert(out, m)
end
return out
end
Where str is the input string, and csize is the size of the chunks (1024 for the example number), and it outputs a table of strings with that length.
Sorry about that, I have written a different formula that might work better:
local insert = table.insert
local function split(str, csize)
local out = {}
for i=1,str:len(),csize do
insert(out, str:sub(i, i + csize - 1))
end
return out
end
print(table.concat(split("test", 3), "\n"))
Oh no need to apologize mate, sorry just want more thing.
So now that the bytes are split up, I tried to convert each byte into its value and then normalize it but it will return me only zero
local function split(str, csize)
local out = {}
for i=1,str:len(),csize do
local value = str:sub(i, i + csize - 1):byte(1,-1)
local normalized = (value - 128) / 127.0
table.insert(out, normalized)
end
return out
end
local chunks = split(byteString, 1024)
print(chunks[10])
which is weird because if I did this, it will spit out all the numbers correctly (128,128,128,…)
local function split(str, csize)
local out = {}
for i=1,str:len(),csize do
table.insert(out, str:sub(i, i + csize - 1))
end
return out
end
local chunks = split(byteString, 1024)
print(chunks[10]:byte(1,-1))
Hopefully this function should cover all your needs:
local insert = table.insert
local function split_and_normalise(str)
local out = {}
local csize = 1024
for i=1,str:len(),csize do
local res = {str:sub(i, i + csize - 1):byte(1, -1)}
for i=1,#res do
insert(out, (res[i] - 128) / 127.0)
end
end
return out
end
print(table.concat(split_and_normalise("test"), "\n"))
Yeah, it still returns zero. Just wondering are you returning an entire string for each chunk?
local function split_and_normalise(str)
local out = {}
local csize = 1024
for i=1,str:len(),csize do
local res = {str:sub(i, i + csize - 1):byte(1, -1)}
for i=1,#res do
table.insert(out, (res[i] - 128) / 127.0)
end
end
return out
end
local chunks = split_and_normalise(byteString, 1024)
print(chunks[10])
To use it, just enter the string, no need for chunk size this time, and it returns a table of all the normalised values, so no need to index the table.