Skip to content

Commit b9c6457

Browse files
committed
Ver(1.3): Fixes for Windows, cleanup
1 parent c64f09d commit b9c6457

File tree

4 files changed

+48
-39
lines changed

4 files changed

+48
-39
lines changed

hachiko/funutils.py

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,13 @@
55
from ctypes.util import find_library
66

77
from sys import platform as sys_platform
8-
from os import name as os_name
9-
10-
def findLibrary(name, lib_names) -> str:
11-
try:
12-
return next(filter(lambda it: it != None, map(find_library, lib_names))) or ""
13-
except StopIteration:
14-
raise ImportError(f"Couldn't find the {name} library")
15-
16-
def createLibrary(path, mode = 1):
17-
lib = CDLL(path)
18-
def cfunc(name, t_result, *args):
19-
t_args = tuple(arg[1] for arg in args)
20-
extras = tuple((mode, arg[0]) for arg in args)
21-
return CFUNCTYPE(t_result, *t_args)((name, lib), extras)
22-
return cfunc
23-
24-
def platform(opts = {"linux": "linux", "windows": "windows", "macos": "macos"}):
25-
for (k, v) in opts.items():
26-
if sys_platform.lower().startswith(k): return v
27-
return os_name
28-
8+
from os.path import isfile
9+
from itertools import chain
2910

3011
def require(value, p, message):
3112
if not p(value): raise ValueError(f"{message}: {value}")
3213

14+
isNotNone = lambda it: it != None
3315
isNonnegative = lambda it: it >= 0
3416
def isInbounds(start, stop):
3517
return lambda it: it in range(start, stop)
@@ -41,6 +23,30 @@ def flatMap(f, xs):
4123
for ys in map(f, xs):
4224
for y in ys: yield y
4325

26+
def findLibrary(name, lib_names, solver=lambda name: [f"./{name}.dll"]) -> str:
27+
paths = filter(isNotNone, map(find_library, lib_names))
28+
for dlls in map(solver, lib_names):
29+
paths = chain(paths, filter(isfile, dlls))
30+
try:
31+
return str(next(paths)) #< appended dll scan
32+
except StopIteration:
33+
raise ImportError(f"couldn't find the {name} library")
34+
35+
def createLibrary(path, mode = 1):
36+
lib = CDLL(path)
37+
def cfunc(name, t_result, *args):
38+
t_args = tuple(arg[1] for arg in args)
39+
extras = tuple((mode, arg[0]) for arg in args)
40+
return CFUNCTYPE(t_result, *t_args)((name, lib), extras)
41+
return cfunc
42+
43+
def platform(opts = {"linux": ["linux"], "windows": ["win", "cygwin"], "macos": ["darwin"]}):
44+
for (v, ks) in opts.items():
45+
for k in ks:
46+
if sys_platform.lower().startswith(k): return v
47+
raise ValueError(f"unsupported platform: {sys_platform}")
48+
49+
4450
global cdecls #v define a subset of C Header
4551
if __name__ == "__main__":
4652
import pyparsing as pas
@@ -101,11 +107,11 @@ def cdefs(decls):
101107
cdefs(decls)
102108
output.close()
103109

104-
def main(argv):
110+
def main(argv = argv):
105111
if len(argv) < 4:
106112
print(f"Usage: {argv[0]} header name lib_names")
107113
return
108114
header, name = argv[1:3]
109115
codegen(f"{name}.py", header, name, argv[3:])
110116

111-
if __name__ == '__main__': main(argv)
117+
if __name__ == '__main__': main()

hachiko/hachi.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ def onEvent(event):
182182
if exc.value == "proceed": break
183183
return reducer.finish()
184184

185-
class CallFlagTimed(CallFlag):
185+
class CallFlagTimed(CallFlag): #< time record (op -- op1)*
186186
def __init__(self, op, op1):
187187
super().__init__(op, op1)
188188
self.t0 = time()

hachiko/synthesize.py

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@
99
try: import numpy
1010
except ImportError: pass
1111

12-
drivers = ["alsa", "oss", "jack", "portaudio", "sndmgr", "coreaudio", "Direct Sound", "pulseaudio"]
12+
drivers = ["alsa", "oss", "jack", "pulseaudio", "portaudio", "sndmgr", "coreaudio", "dsound", "waveout"]
13+
platform_drivers = {"linux": "alsa", "windows": "dsound", "macos": "coreaudio"}
1314

15+
from .funutils import isNonnegative, isInbounds
1416
from .FluidSynth import *
1517

16-
def fluid_synth_write_s16_stereo(synth, n: int, n_channel = 2): # -> numpy.ndarray
18+
def fluid_synth_write_s16_stereo(synth, n: int, n_channel=2) -> List[int]:
1719
"""Return generated samples in stereo 16-bit format"""
1820
buf = create_string_buffer(n*n_channel*sizeof(c_int16))
1921
fluid_synth_write_s16(synth, n, buf, 0, n_channel, buf, 1, n_channel)
@@ -44,29 +46,29 @@ def setting(self, key, value):
4446
fluid_settings_setstr(sets, bk, value.encode())
4547

4648
def sfload(self, filename, update_midi_preset=0) -> int:
47-
return fluid_synth_sfload(self.synth, filename.encode(), update_midi_preset)
49+
return fluid_synth_sfload(self.synth, filename.encode(), update_midi_preset)
4850
def sfunload(self, sfid, update_midi_preset=0):
49-
return fluid_synth_sfunload(self.synth, sfid, update_midi_preset)
51+
fluid_synth_sfunload(self.synth, sfid, update_midi_preset)
5052
def program_select(self, chan, sfid, bank, preset):
51-
return fluid_synth_program_select(self.synth, chan, sfid, bank, preset)
53+
fluid_synth_program_select(self.synth, chan, sfid, bank, preset)
5254

5355
def noteon(self, chan, key, vel=127):
5456
require(chan, isNonnegative, "bad channel")
5557
require(key, isInbounds(0, 128), "bad key")
5658
require(vel, isInbounds(0, 128), "bad velocity")
57-
return fluid_synth_noteon(self.synth, chan, key, vel)
59+
fluid_synth_noteon(self.synth, chan, key, vel)
5860
def noteoff(self, chan, key):
5961
require(chan, isNonnegative, "bad channel")
6062
require(key, isInbounds(0, 128), "bad key")
61-
return fluid_synth_noteoff(self.synth, chan, key)
63+
fluid_synth_noteoff(self.synth, chan, key)
6264

63-
def start(self, driver=platform({"linux": "alsa", "windows": "sndmgr", "macos": "coreaudio"}), device=None):
65+
def start(self, driver=platform_drivers[platform()], device=None):
6466
"""driver could be any str in drivers"""
6567
require(driver, drivers.__contains__, "unsupported driver")
6668
self.setting(b"audio.driver", driver)
6769
if device is not None: self.setting(f"audio.{driver}.device", device)
6870
self.audio_driver = new_fluid_audio_driver(self.settings, self.synth)
69-
def get_samples(self, n=1024):
71+
def get_samples(self, n=1024) -> List[int]:
7072
"""Generate audio samples
7173
Returns ndarray containing n audio samples.
7274
If synth is set to stereo output(default) the array will be size 2*n.
@@ -81,24 +83,25 @@ def __init__(self, sample_rate):
8183
@staticmethod
8284
def getFontPresets(path_sfont) -> List[Tuple[int, int, str]]:
8385
with open(path_sfont, "rb") as fbuf:
84-
sf = Sf2File(fbuf)
86+
sf = Sf2File(fbuf) #< parse sf2
8587
return [(p.bank, p.preset, p.name) for p in sf.build_presets() if len(p.bags) != 0]
8688

87-
def setFont(self, path_sfont, idx_preset = 0):
89+
def setFont(self, path_sfont, idx_preset=0):
8890
presets = NoteSynth.getFontPresets(path_sfont)
8991
require(presets, hasIndex(idx_preset), "preset outbounds")
9092
preset = presets[idx_preset]
9193
(bank, patch, _) = preset
9294
self.program_select(0, self.sfload(path_sfont), bank, patch)
9395

9496
def noteon(self, pitch): return super().noteon(0, pitch)
95-
def noteoff(self, pitch = None):
96-
return super().noteoff(0, pitch) if pitch != None else super().noteoff(0, self.last_pitch)
97+
def noteoff(self, pitch=None):
98+
if pitch != None: super().noteoff(0, pitch)
99+
else: super().noteoff(0, self.last_pitch)
97100
def noteSwitch(self, pitch):
98101
if self.last_pitch != (-1):
99102
self.noteoff()
100103
self.noteon(pitch)
101104
self.last_pitch = pitch
102105

103-
def sampleNote(self, n_sec):
106+
def sampleNote(self, n_sec) -> List[int]:
104107
return self.get_samples(self.sample_rate*n_sec)

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ def parse_requirements(requirements):
99
return list(filter(lambda s: s.strip() != "", items))
1010

1111
setup(
12-
name="hachiko-bapu", version="0.1.2",
12+
name="hachiko-bapu", version="0.1.3",
1313
python_requires=">=3.5",
1414
author="duangsuse", author_email="fedora-opensuse@outlook.com",
1515
url="https://github.com/duangsuse-valid-projects/Hachiko",

0 commit comments

Comments
 (0)