播放 Wav 太快会造成混乱

发布于 2024-12-21 04:26:37 字数 2388 浏览 0 评论 0原文

我正在重新创建一个旧的 16 位游戏。我正在创建通常显示在底部的聊天。每个句子都是逐字过渡的。

每次添加角色时,我都想让它发出小小的嘟嘟声。我有一个 wav 文件,其中包含一个听起来不错的短“blip”,问题是,当我每次都让它执行 blip 时,它通常会搞砸。

要么是:

  • 跳过逐个字符的过程,只显示完整的单词,
  • 并在滞后时正确地执行几个 bips,然后执行上面列出的操作,

这就是事情变得复杂的地方。我为此使用 Lua 和 VB.net。引擎是我用 VB.net 编写的,而实际的游戏机制和故事情节是由 Lua 控制的。

这是 Lua 的基本片段:

RegisterEvent("ready", function()
    _G.Chat={}
    _G.Chat["busy"]=false
    _G.Chat.Say=(function(from,msg,done)
        if _G.Chat["busy"] then return end
        _G.Chat["busy"]=true
        local x,y=getRelativePositionOpposite(1024,192)
        --Draw
        local chatPanel=engine:AddSprite("chat.png",0,0,1024,192,x,y,1024,192,5)
        local fromText=engine:AddString(from..":",x+25,y+25,"#FFFFFF",16,0,0)
        local msgText=nil
        local mx=string.len(msg)
        --Chat Cleanup
        setupCleanup=(function()
            local g=true
            RegisterEvent("keyup", function(key)
                if not g then return end
                if key=="Space" then
                    engine:RemoveSprite(chatPanel)
                    engine:RemoveString(fromText)
                    engine:RemoveString(msgText)
                    _G.Chat["busy"]=false
                    done()
                    g=false
                end
            end)
        end)
        doText=(function(i)
            if msgText then
                engine:RemoveString(msgText)
            end
            msgText=engine:AddString(string.sub(msg,1,i),x,y+75,"#FFFFFF",14,1,0)
            engine:PlaySound("chatblip.wav")
            if i>=mx then setupCleanup() return end
            pause(.75,(function() doText(i+1) end))
        end)
        doText(1)
    end)
end)

这是暂停功能,仅供参考(在 Lua 中):

_G.pause=(function(t,f)
    if t and f then
        local tt=engine.timer.ElapsedMilliseconds/1000+t 
        local lcc=true
        engine.event_tick:add(function(nt)
            if nt>=tt and lcc then
                f()
                lcc=false
            end
        end)
    end
end)

这是实际在 VB.net 中播放噪音的片段:

Public Sub PlaySound(ByVal fileFullPath As String)
    My.Computer.Audio.Play(My.Computer.FileSystem.CurrentDirectory & "\bin\sounds\" & fileFullPath, AudioPlayMode.Background)
End Sub

如果您能提供帮助,谢谢!如果您需要任何说明,我非常乐意提供帮助!

I'm recreating an old 16 bit game. I'm creating the chat normally displayed at the bottom. Each sentence transitions in character-by-character.

Every time a character is added, I wanted to have it make that little bleep noise. I've got a wav file that contains a short 'blip' that sounds just right, problem is, when I have it do the blip every time, it usually messes up.

Either it:

  • Skips the character-by-character process and just shows the full word and blips once
  • Lags and does a couple of bips correctly and then does what the thing listed above

Here is where it gets complicated. I'm using Lua and VB.net for this. The engine, I've written in VB.net while the actual game mechanics and story line are controlled by Lua.

Here is the basic snippit of Lua:

RegisterEvent("ready", function()
    _G.Chat={}
    _G.Chat["busy"]=false
    _G.Chat.Say=(function(from,msg,done)
        if _G.Chat["busy"] then return end
        _G.Chat["busy"]=true
        local x,y=getRelativePositionOpposite(1024,192)
        --Draw
        local chatPanel=engine:AddSprite("chat.png",0,0,1024,192,x,y,1024,192,5)
        local fromText=engine:AddString(from..":",x+25,y+25,"#FFFFFF",16,0,0)
        local msgText=nil
        local mx=string.len(msg)
        --Chat Cleanup
        setupCleanup=(function()
            local g=true
            RegisterEvent("keyup", function(key)
                if not g then return end
                if key=="Space" then
                    engine:RemoveSprite(chatPanel)
                    engine:RemoveString(fromText)
                    engine:RemoveString(msgText)
                    _G.Chat["busy"]=false
                    done()
                    g=false
                end
            end)
        end)
        doText=(function(i)
            if msgText then
                engine:RemoveString(msgText)
            end
            msgText=engine:AddString(string.sub(msg,1,i),x,y+75,"#FFFFFF",14,1,0)
            engine:PlaySound("chatblip.wav")
            if i>=mx then setupCleanup() return end
            pause(.75,(function() doText(i+1) end))
        end)
        doText(1)
    end)
end)

Here is the pause function, just for reference (in Lua):

_G.pause=(function(t,f)
    if t and f then
        local tt=engine.timer.ElapsedMilliseconds/1000+t 
        local lcc=true
        engine.event_tick:add(function(nt)
            if nt>=tt and lcc then
                f()
                lcc=false
            end
        end)
    end
end)

Here is the snippit that is actually playing the noise in VB.net:

Public Sub PlaySound(ByVal fileFullPath As String)
    My.Computer.Audio.Play(My.Computer.FileSystem.CurrentDirectory & "\bin\sounds\" & fileFullPath, AudioPlayMode.Background)
End Sub

Thanks if you can help! If you need any clarifications, I'm more than willing to help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

佞臣 2024-12-28 04:26:37

我使用了 Reflector,Audio.Play 的内部实现使用了 SoundPlayer:

Public Sub Play(ByVal location As String, ByVal playMode As AudioPlayMode)
    Me.ValidateAudioPlayModeEnum(playMode, "playMode")
    Dim sound As New SoundPlayer(Me.ValidateFilename(location))
    Me.Play(sound, playMode)
End Sub

读取每个角色的声音文件对于 IO 来说将是相当密集的。

克服性能。瓶颈您可以尝试添加对 Microsoft.VisualBasic.dll 程序集的引用并使用:

Microsoft.VisualBasic.Interaction.Beep()

或者如果您使用 .Net Framework 2.0 并且只是 Beep() /或更大。

我没有在反射器中深入研究,但也可能值得检查 SoundPlayer 是否使用 PlaySound API 以及它是否也没有提供该方法:

    <DllImport("coredll.dll")> _
Public Shared Function PlaySound(szSound As String, hModule As IntPtr, flags As Integer) As Integer
End Function

I used reflector and the internal implementation of Audio.Play uses the SoundPlayer:

Public Sub Play(ByVal location As String, ByVal playMode As AudioPlayMode)
    Me.ValidateAudioPlayModeEnum(playMode, "playMode")
    Dim sound As New SoundPlayer(Me.ValidateFilename(location))
    Me.Play(sound, playMode)
End Sub

Reading the sound file for each character is going to be quite intensive on IO.

To overcome the perf. bottleneck can you try adding a reference to the Microsoft.VisualBasic.dll assembly and use:

Microsoft.VisualBasic.Interaction.Beep()

Or just Beep() if your using .Net Framework 2.0 and/OR greater.

I didn't drill down very far in reflector but it might also be worth checking if the SoundPlayer uses the PlaySound API and if it doesn't give that method a go as well:

    <DllImport("coredll.dll")> _
Public Shared Function PlaySound(szSound As String, hModule As IntPtr, flags As Integer) As Integer
End Function
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文