This repository has been archived by the owner on Jul 28, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ModSound.vb
119 lines (106 loc) · 3.69 KB
/
ModSound.vb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
Imports System.IO
Imports System.Threading
Imports System.Windows.Threading
Public Module ModSound
#Region "音量管理"
''' <summary>
''' 全局音量。
''' </summary>
Public Property VolumeMaster As Double
Get
Return _VolumeMaster
End Get
Set(value As Double)
If value = _VolumeMaster Then Exit Property
_VolumeMaster = value
RefreshVolume()
End Set
End Property
Private _VolumeMaster As Double = 0.7
Private Sub RefreshVolume()
For Each Sound In SoundList
Sound.Volume = Sound.Volume * VolumeMaster
Next
End Sub
#End Region
Public Class SoundListEntry
''' <summary>
''' 所属的播放器。
''' </summary>
Public Player As MediaPlayer
''' <summary>
''' 该音频的独立音量。
''' </summary>
Public Volume As Double = 1
''' <summary>
''' 音频文件的路径。
''' </summary>
Public FilePath As String
''' <summary>
''' 是否已播放完成。
''' </summary>
Public ReadOnly Property IsFinished As Boolean
Get
Return Player.NaturalDuration = Player.Position
End Get
End Property
End Class
Public SoundList As New List(Of SoundListEntry)
Private SoundQueueList As New Queue(Of SoundQueue)
Private Class SoundQueue
Public FilePath As String
Public Volume As Double
End Class
Private IsSoundStartRun As Boolean = False
Public Sub SoundStartRun()
If IsSoundStartRun Then Exit Sub
IsSoundStartRun = True
RunInNewThread(Sub()
Do While True
Thread.Sleep(20)
SoundTick()
Loop
End Sub, "Sound")
End Sub
Private Sub SoundTick()
'开始新音效的播放
Do While SoundQueueList.Count > 0
Dim Queue As SoundQueue = SoundQueueList.Dequeue
Dim Entry As SoundListEntry = Nothing
'优先获取空闲的同一播放器
For Each ExistsEntry In SoundList
If ExistsEntry.IsFinished AndAlso ExistsEntry.FilePath = Queue.FilePath Then
Entry = ExistsEntry
GoTo GotPlayer
End If
Next
'尝试获取空闲的其他播放器
For Each ExistsEntry In SoundList
If ExistsEntry.IsFinished Then
Entry = ExistsEntry
Entry.Player.Open(New Uri(Queue.FilePath))
GoTo GotPlayer
End If
Next
'没有空闲播放器,新建一个
Entry = New SoundListEntry With {.Player = New MediaPlayer}
Entry.Player.Open(New Uri(Queue.FilePath))
SoundList.Add(Entry)
GotPlayer:
'初始化并开始播放
Entry.Player.Volume = Queue.Volume * VolumeMaster
Entry.Player.Position = New TimeSpan(0)
Entry.FilePath = Queue.FilePath
Entry.Volume = Queue.Volume
Entry.Player.Play()
Loop
End Sub
''' <summary>
''' 播放音效。
''' </summary>
Public Sub PlaySound(FileName As String, Optional Volume As Double = 1, Optional Balance As Double = 0)
Dim FilePath As String = Path & "Sounds\" & FileName
If Not File.Exists(FilePath) Then Throw New FileNotFoundException("未找到音频文件(" & FilePath & ")")
SoundQueueList.Enqueue(New SoundQueue With {.Volume = Volume * 2, .FilePath = FilePath})
End Sub
End Module