好的,所以我正在尝试在Lua中播放WAV文件。就信息而言,我已经说了些什么,但是我还是不得不去播放真正的歌曲了。我正在使用的功能是Speaker.start(频道,频率)。我很想从原始文件中在Lua中做这样的事情,我不知道样本数据代表什么。我的问题是,我如何获得频道和频率播放?它甚至可能吗?
--(( Variables ))--
local FileName = "song.wav"
local File = fs.open(FileName, "rb")
local ToHex = "%X"
local Speaker = peripheral.wrap("back")
--(( Functions ))--
-- returns a HEX string
local function BigEndian(Size)
local Str = ""
for Count = 1,Size do
Str = Str .. string.char(File.read())
end
return Str
end
-- returns a HEX string
local function LittleEndian(Size)
local T = {}
for Count = 1,Size do
table.insert(T,ToHex:format(File.read()))
end
local Str = ""
for Count = #T,1,-1 do
Str = Str .. T[Count]
end
return Str
end
--(( Main program ))--
-- Variables
local ChunkID = ""
local ChunkSize = 0
local Format = ""
local Subchunk1ID = ""
local Subchunk1Size = 0
local AudioFormat = 0
local NumChannels = 0
local SampleRate = 0
local ByteRate = 0
local BlockAlign = 0
local BitsPerSample = 0
local Subchunk2ID = ""
local Subchunk2Size = 0
local ExtraPeramSize = 0
-- RIFF chunk
ChunkID = BigEndian(4)
ChunkSize = tonumber(LittleEndian(4), 16) + 8
Format = BigEndian(4)
-- Subchunk 1
Subchunk1ID = BigEndian(4)
Subchunk1Size = tonumber(LittleEndian(4), 16)
AudioFormat = tonumber(LittleEndian(2), 16)
NumChannels = tonumber(LittleEndian(2), 16)
SampleRate = tonumber(LittleEndian(4), 16)
ByteRate = tonumber(LittleEndian(4), 16)
BlockAlign = tonumber(LittleEndian(2), 16)
BitsPerSample = tonumber(LittleEndian(2), 16)
ExtraPeramSize = tonumber(LittleEndian(2), 16)
-- Subchunk 2
Subchunk2ID = BigEndian(4)
Subchunk2Size = tonumber(LittleEndian(4), 16)
-- Printing
print("RIFF chunk")
print("- ChunkID: " .. ChunkID)
print("- ChunkSize: " .. ChunkSize)
print("- Format: " .. Format)
print("Subchunk 1")
print("- ID: " .. Subchunk1ID)
print("- Size: " .. Subchunk1Size)
print("- Audio Format: " .. AudioFormat)
print("- NumChannels: " .. NumChannels)
print("- Sample Rate: " .. SampleRate)
print("- Byte Rate: " .. ByteRate)
print("- Block Align: " .. BlockAlign)
print("- BitsPerSample: " .. BitsPerSample)
print("Subchunk 2")
print("- ID: " .. Subchunk2ID)
print("- Size: ".. Subchunk2Size)
local Done = 0
while true do
Done = Done + 1 -- Left Right Left Right
--local Sample = {{tonumber(LittleEndian(1),16), tonumber(LittleEndian(1),16)}, {tonumber(LittleEndian(1),16), tonumber(LittleEndian(1),16)}}
local Left = tonumber(LittleEndian(2),16) - 32768
local Right = tonumber(LittleEndian(2),16)
local Average = (Left + Right)/2
Speaker.start(0,Average)
sleep(0)
-- Left channel, Right channel
if Done == 5000 then break end
end
Speaker.stop(0)
--(( EOF ))--
答案 0 :(得分:2)
WAV文件存储PCM样本数据,该数据位于时域中。很多时候(CD音频为44,100)样本在该时间点取压力水平,并量化以适合给定的位深度。播放这些样本时,它们会接近原始波形。
您要求的是频域中的示例。这里的样本以更大的间隔(大约相隔5-10ms)拍摄,并包含构成声音的频谱信息。也就是说,你可能有2048个“桶”来测量特定频率下的那段时间的声音量。这是通过对原始时域采样波形执行Fourier transform(通常在计算机上实现为FFT)来衡量的。
基本上,您无法使用当前使用的API播放WAV,因为格式根本不同。