-
Notifications
You must be signed in to change notification settings - Fork 0
/
Acoustics.moon
108 lines (86 loc) · 3.03 KB
/
Acoustics.moon
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
require "lfs"
MspGlobals = require "MspGlobals"
import MODULE_PATH, OPERATING_SYSTEM_TYPE from MspGlobals
-- forward declare class, we'll need it
local Acoustics
-- default paramter values
DEFAULT_VOLUME = 100
DEFAULT_REPEATS = 1
-- search for sound files
dosWildcardsToLuaPattern = (soundFile) ->
suffix = soundFile\match("%.(%w+)$")
if not suffix and not soundFile\find("%*$")
soundFile = soundFile .. (soundType == "SOUND" and ".wav" or ".mid")
for char in *{"^", "$", "(", ")", "%", ".", "[", "]", "+", "-"}
soundFile = soundFile\gsub("%"..char, "%%"..(char == "%" and "%%" or char))
return soundFile\gsub("%*", ".*")\gsub("%?", ".")
searchFiles = (where, pattern) ->
filesFound = {}
attributes = lfs.attributes(where\ends("/") and where\sub(1, -2) or where)
if attributes and attributes.mode == "directory"
for file in lfs.dir(where) do
if file\match(pattern)
filesFound[#filesFound + 1] = where .. file
return filesFound
getSoundFiles = (completeSoundPath, soundType) ->
soundPath = completeSoundPath\match("^(.*/)(.*)$") or ""
soundFile = completeSoundPath\match("[^/]+$")
soundFilePattern = dosWildcardsToLuaPattern(soundFile)
return searchFiles(MODULE_PATH .. "sounds/" .. soundPath, soundFilePattern)
-- handle sound finish events
registerAnonymousEventHandler("sysSoundFinished", (_1, _2, soundFile) ->
soundFile = soundFile\sub 2 if OPERATING_SYSTEM_TYPE == "windows" and soundFile\starts "/"
soundObject = Acoustics.playingSoundFiles[soundFile]
if soundObject
Acoustics.playingSoundFiles[soundFile] = nil
soundObject\FinishedPlaying!
)
-- class declaration
class Acoustics
new: (completeSoundPath, properties={}) =>
@completeSoundPath = completeSoundPath
for argShortName, argValue in pairs(properties)
if argName = @@.ArgShortNamesToNames argShortName
self[argName] = argValue
else
print "MSP: server sent an unknown argument type: " .. argShortName
if @volume
@volume = tonumber(@volume) or DEFAULT_VOLUME
if @volume < 0
@volume = 0
elseif @volume > 100
@volume = 100
else
@volume = DEFAULT_VOLUME
if @repeats
@repeats = tonumber(@repeats) or DEFAULT_REPEATS
@repeats = math.floor @repeats
if @repeats < 1 and @repeats != -1
@repeats = 1
else
@repeats = DEFAULT_REPEATS
@url = @@defaultUrl if not @url and @@defaultUrl
if @completeSoundPath != "Off"
@files = getSoundFiles(@completeSoundPath, @soundType)
else
@@defaulUrl = @url if @url
Play: =>
fileToPlay = @files[math.random #@files]
@@playingSoundFiles[fileToPlay] = @
playSoundFile(fileToPlay, @volume) if @files and #@files > 0
FinishedPlaying: =>
@repeats -= 1 if @repeats != -1
@\Play! if @repeats == -1 or @repeats > 0
@playingSoundFiles = {}
@ArgShortNamesToNames: (shortName) ->
switch shortName
when "V"
"volume"
when "L"
"repeats"
when "T"
"type"
when "U"
"url"
else
nil