fix(audio): 修复在没有高音质模块时,回退播放实时音频流产生刺耳噪音及可能导致卡死的问题
This commit is contained in:
+53
-3
@@ -1296,6 +1296,21 @@ local function decodePcmS8Chunk(chunk)
|
|||||||
return samples
|
return samples
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function decodePcmS16LEChunk(chunk)
|
||||||
|
if type(chunk) ~= "string" or #chunk < 2 then return nil end
|
||||||
|
local samples = {}
|
||||||
|
local idx = 1
|
||||||
|
for i = 2, #chunk, 2 do
|
||||||
|
local b = string.byte(chunk, i)
|
||||||
|
if b >= 128 then
|
||||||
|
b = b - 256
|
||||||
|
end
|
||||||
|
samples[idx] = b
|
||||||
|
idx = idx + 1
|
||||||
|
end
|
||||||
|
return samples
|
||||||
|
end
|
||||||
|
|
||||||
local function readU16LE(data, offset)
|
local function readU16LE(data, offset)
|
||||||
local a, b = string.byte(data, offset, offset + 1)
|
local a, b = string.byte(data, offset, offset + 1)
|
||||||
if not a or not b then return nil end
|
if not a or not b then return nil end
|
||||||
@@ -1684,6 +1699,41 @@ function Audio.playPcmItem(item)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Audio.playPcmS16LEItem(item)
|
||||||
|
if not Peripherals.speakers or #Peripherals.speakers == 0 then
|
||||||
|
Utils.log("WARN", "No speakers found; cannot play audio")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local playSeq = State.interruptSeq
|
||||||
|
local source = item.audioData
|
||||||
|
|
||||||
|
if type(source) == "table" and source.read then
|
||||||
|
source = source.read
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(source) ~= "function" then
|
||||||
|
local data = source
|
||||||
|
source = function()
|
||||||
|
local chunk = data
|
||||||
|
data = nil
|
||||||
|
return chunk
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
while true do
|
||||||
|
if shouldStop(playSeq) then break end
|
||||||
|
local chunk = source()
|
||||||
|
if chunk == nil then break end
|
||||||
|
if type(chunk) == "string" and #chunk > 0 then
|
||||||
|
local samples = decodePcmS16LEChunk(chunk)
|
||||||
|
if samples and not playChunkOnSpeakers(samples, CONFIG.AUDIO_VOLUME, playSeq) then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function Audio.playWavStreamItem(item)
|
function Audio.playWavStreamItem(item)
|
||||||
if not Peripherals.speakers or #Peripherals.speakers == 0 then
|
if not Peripherals.speakers or #Peripherals.speakers == 0 then
|
||||||
Utils.log("WARN", "No speakers found; cannot play audio")
|
Utils.log("WARN", "No speakers found; cannot play audio")
|
||||||
@@ -1788,7 +1838,7 @@ function Audio.playItem(item)
|
|||||||
if success == false then
|
if success == false then
|
||||||
format = tostring(item.audioFormat or "file"):lower()
|
format = tostring(item.audioFormat or "file"):lower()
|
||||||
Utils.log("WARN", "HQ speaker playback failed, falling back to default decoding for format: " .. format)
|
Utils.log("WARN", "HQ speaker playback failed, falling back to default decoding for format: " .. format)
|
||||||
if format == "wav" or format == "file" then
|
if format == "wav" or format == "file" or format == "stream" then
|
||||||
return Audio.playWavStreamItem(item)
|
return Audio.playWavStreamItem(item)
|
||||||
elseif format == "dfpwm" then
|
elseif format == "dfpwm" then
|
||||||
return Audio.playDfpwmItem(item)
|
return Audio.playDfpwmItem(item)
|
||||||
@@ -1800,8 +1850,8 @@ function Audio.playItem(item)
|
|||||||
return success
|
return success
|
||||||
elseif format == "pcm" then
|
elseif format == "pcm" then
|
||||||
return Audio.playPcmItem(item)
|
return Audio.playPcmItem(item)
|
||||||
elseif format == "wav-stream" then
|
elseif format == "wav-stream" or format == "wav-stream-live" then
|
||||||
return Audio.playWavStreamItem(item)
|
return Audio.playPcmS16LEItem(item)
|
||||||
end
|
end
|
||||||
return Audio.playDfpwmItem(item)
|
return Audio.playDfpwmItem(item)
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user