-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmusic.py
174 lines (129 loc) · 4.83 KB
/
music.py
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
"""A module to provide
###########################
# Music and sound effectss #
###########################
"""
import pyxel
class Music:
"""A class to contain music and sound effectss."""
def __init__(self):
"""Define sound and music."""
#################
# Sound effectss #
#################
# Score
pyxel.sound(0).set(
notes="c3e3g3c4c4", tones="s", volumes="4", effects=("n" * 4 + "f"), speed=7
)
# Finish
pyxel.sound(1).set(
notes="f3 b2 f2 b1 f1 f1 f1 f1",
tones="p",
volumes=("4" * 4 + "4321"),
effects=("n" * 7 + "f"),
speed=9,
)
# Hit
pyxel.sound(2).set(notes="c3", tones="p", volumes="4", effects=("n"), speed=7)
# Pickup
pyxel.sound(3).set(notes="a2", tones="s", volumes="4", effects="f", speed=40)
#########
# Music #
#########
speed = 30
# Drums
drum_sound = "b_s_bbs_" "b_s_bbsH" "b_s_bbs_" "b_s_bbsb"
pyxel.sound(10).set(**self.convert_drums(drum_sound, speed=speed))
# Harmony
harmony = (
"c1 c1 e1 g1 c0 c1 e1 g1"
"c1 c1 e1 g1 c0 c1 e1 g1"
"a0 a0 c1 e1 r a0 c1 e1"
"e1 e1 g1 b1 r e1 g1 b1"
)
pyxel.sound(11).set(
notes=harmony, tones="t", volumes=("4"), effects=("f"), speed=speed
)
def sfx_score(self):
"""Play scoring sound."""
pyxel.play(ch=0, snd=0)
def sfx_finish(self):
"""Play finish sound."""
pyxel.play(ch=0, snd=1)
def sfx_hit(self):
"""Play sound for when ball hits paddle."""
pyxel.play(ch=0, snd=2)
def sfx_pickup(self):
pyxel.play(ch=0, snd=3)
def start_music(self):
"""Start all music tracks (channels 1 - 3)."""
pyxel.play(ch=1, snd=10, loop=True)
pyxel.play(ch=2, snd=11, loop=True)
def stop_music(self):
"""Stop all music tracks (channels 1 - 3)."""
for ch in range(1, 4):
pyxel.stop(ch=ch)
@staticmethod
def standardise_length(sounds):
"""For a list of sound numbers, loop the shorter ones to fit the longer one."""
max_length = max(len(pyxel.sound(snd).notes) for snd in sounds)
for snd in sounds:
multiple = len(pyxel.sound(snd).notes) / max_length
if int(multiple) != multiple:
raise ValueError("One of the sounds does not loop within the longest sound.")
for snd in sounds:
multiple = len(pyxel.sound(snd).notes) / max_length
pyxel.sound(snd).notes = pyxel.sound(snd).notes * int(multiple)
@staticmethod
def octave_shift(snd, octaves=1):
"""Shift the notess of the given sound by the given amount of octaves."""
notes_shift = 12 * octaves
pyxel.sound(snd).notes = [
i + notes_shift if i != -1 else -1 for i in pyxel.sound(snd).notes
]
@staticmethod
def convert_drums(drum_string, speed=20):
"""Convert drum string to pyxel arguments to set a sound.
Defines drum noises, and converts a simplified drum string into a full
set of notes, volumes, tones, etc., which can be passed using the ** syntax
to the pyxel.sound.set method.
>>> convert_drums("b_s_ bbs_")
{"notes": "f0ra4rf0f0a4r",
"tones": "n",
"volumes": "60206620",
"effects": "f",
"speed": 20}
"""
noises = {}
# Define drums
noises["b"] = {"notes": "f0", "tones": "n", "volumes": "6", "effects": "f"}
noises["s"] = {"notes": "b3", "tones": "n", "volumes": "2", "effects": "f"}
noises["H"] = {"notes": "b4", "tones": "n", "volumes": "1", "effects": "n"}
noises["h"] = {"notes": "b4", "tones": "n", "volumes": "1", "effects": "f"}
noises["_"] = {"notes": "r", "tones": "n", "volumes": "0", "effects": "f"}
# Construct output dict
output = {"notes": "", "tones": "", "volumes": "", "effects": ""}
for noise in drum_string.replace(" ", ""):
for key in output:
output[key] += noises[noise][key]
output["speed"] = speed
return output
if __name__ == "__main__":
pyxel.init(50, 50)
music = Music()
def controls():
if pyxel.btnp(pyxel.KEY_1):
music.sfx_hit()
if pyxel.btnp(pyxel.KEY_2):
music.sfx_score()
if pyxel.btnp(pyxel.KEY_3):
music.sfx_finish()
if pyxel.btnp(pyxel.KEY_4):
music.sfx_pickup()
if pyxel.btnp(pyxel.KEY_S):
music.start_music()
if pyxel.btnp(pyxel.KEY_F):
music.stop_music()
if pyxel.btnp(pyxel.KEY_Q):
pyxel.quit()
pyxel.run(controls, lambda: None)