Improve test infrastructure.
- Reanimate vmtests. - Use waf to run tests. - Run clang-tidy of C++ sources. - Ensure noisicaä still runs on Ubuntu 16.04. - Upgrade mypy to 0.720 and fix new issues.pyside
|
@ -6,7 +6,7 @@
|
|||
|
||||
((nil . (
|
||||
; Projetile
|
||||
(projectile-project-test-cmd . "bin/runtests")
|
||||
(projectile-project-test-cmd . "./waf test")
|
||||
|
||||
(pyvenv-workon . "noisicaa")
|
||||
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
-/build
|
||||
-/venv
|
||||
-/vmtests
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
from typing import Any
|
||||
def __getattr__(arrr: str) -> Any: ...
|
|
@ -0,0 +1,2 @@
|
|||
from typing import Any
|
||||
def __getattr__(arrr: str) -> Any: ...
|
|
@ -0,0 +1,2 @@
|
|||
from typing import Any
|
||||
def __getattr__(arrr: str) -> Any: ...
|
|
@ -0,0 +1,2 @@
|
|||
from typing import Any
|
||||
def __getattr__(arrr: str) -> Any: ...
|
|
@ -0,0 +1,2 @@
|
|||
from typing import Any
|
||||
def __getattr__(arrr: str) -> Any: ...
|
|
@ -0,0 +1,2 @@
|
|||
from typing import Any
|
||||
def __getattr__(arrr: str) -> Any: ...
|
|
@ -1,36 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# @begin:license
|
||||
#
|
||||
# Copyright (c) 2015-2019, Benjamin Niemann <pink@odahoda.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# @end:license
|
||||
|
||||
BASEDIR=$(readlink -f "$(dirname "$0")")
|
||||
|
||||
(
|
||||
set -e
|
||||
$BASEDIR/runpylint -E noisicaa
|
||||
$BASEDIR/runtests
|
||||
)
|
||||
|
||||
if [ $? -gt 0 ]; then
|
||||
echo
|
||||
echo "****** THERE WERE ERRORS ******"
|
||||
echo
|
||||
exit 1
|
||||
fi
|
|
@ -1,7 +1,7 @@
|
|||
Custom `waf` tools used for building noisicaä.
|
||||
|
||||
Running pylint on these files (these files are used to build, they are not built themselves, so
|
||||
`runtests` does not know about them):
|
||||
`./waf test` does not know about them):
|
||||
|
||||
```bash
|
||||
PYTHONPATH=$(ls -d .waf*) bin/runpylint build_utils.waf
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
# -*- mode: python -*-
|
||||
|
||||
# @begin:license
|
||||
#
|
||||
# Copyright (c) 2015-2019, Benjamin Niemann <pink@odahoda.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# @end:license
|
||||
|
||||
import os
|
||||
import os.path
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from waflib.Configure import conf
|
||||
from waflib.Task import Task
|
||||
from waflib import Utils
|
||||
|
||||
|
||||
def configure(ctx):
|
||||
if ctx.env.ENABLE_TEST:
|
||||
ctx.find_program('clang-tidy-8', var='CLANG_TIDY', mandatory=False)
|
||||
|
||||
|
||||
|
||||
class run_clang_tidy(Task):
|
||||
always_run = True
|
||||
|
||||
def __str__(self):
|
||||
return self.inputs[0].relpath()
|
||||
|
||||
def keyword(self):
|
||||
return 'Lint (clang-tidy)'
|
||||
|
||||
@property
|
||||
def mod_name(self):
|
||||
mod_path = self.inputs[0].relpath()
|
||||
assert mod_path.endswith('.cpp')
|
||||
return '.'.join(os.path.splitext(mod_path)[0].split(os.sep))
|
||||
|
||||
@property
|
||||
def test_id(self):
|
||||
return self.mod_name + ':clang-tidy'
|
||||
|
||||
def run(self):
|
||||
ctx = self.generator.bld
|
||||
|
||||
success = True
|
||||
try:
|
||||
argv = [
|
||||
ctx.env.CLANG_TIDY[0],
|
||||
'-quiet',
|
||||
self.inputs[0].relpath(),
|
||||
'--',
|
||||
'-Wall',
|
||||
'-I.', '-Ibuild',
|
||||
]
|
||||
argv += ['-I%s' % p for p in ctx.env.INCLUDES_LILV]
|
||||
argv += ['-I%s' % p for p in ctx.env.INCLUDES_SUIL]
|
||||
argv += ['-I%s' % p for p in ctx.env.INCLUDES_GTK2]
|
||||
argv += ['-I%s' % p for p in ctx.env.INCLUDES]
|
||||
|
||||
env = dict(os.environ)
|
||||
|
||||
kw = {
|
||||
'cwd': ctx.top_dir,
|
||||
'env': env,
|
||||
'stdout': subprocess.PIPE,
|
||||
'stderr': subprocess.PIPE,
|
||||
}
|
||||
|
||||
ctx.log_command(argv, kw)
|
||||
_, out, _ = Utils.run_process(argv, kw)
|
||||
out = out.strip()
|
||||
|
||||
if out:
|
||||
success = False
|
||||
|
||||
out_path = os.path.join(ctx.TEST_RESULTS_PATH, self.mod_name, 'clang-tidy.log')
|
||||
os.makedirs(os.path.dirname(out_path), exist_ok=True)
|
||||
with open(out_path, 'wb') as fp:
|
||||
fp.write(out)
|
||||
|
||||
if out and ctx.options.fail_fast:
|
||||
sys.stderr.write(out.decode('utf-8'))
|
||||
sys.stderr.write('\n')
|
||||
raise RuntimeError("clang-tidy for %s failed." % self.mod_name)
|
||||
|
||||
except Exception:
|
||||
success = False
|
||||
raise
|
||||
|
||||
finally:
|
||||
ctx.record_test_state(self.test_id, success)
|
||||
|
||||
|
||||
@conf
|
||||
def cpp_module(ctx, source, **kwargs):
|
||||
assert source.endswith('.cpp')
|
||||
|
||||
source_node = ctx.path.make_node(source)
|
||||
|
||||
if (ctx.cmd == 'test'
|
||||
and ctx.env.CLANG_TIDY
|
||||
and ctx.should_run_test(source_node)
|
||||
and {'all', 'lint', 'clang-tidy'} & ctx.TEST_TAGS):
|
||||
with ctx.group(ctx.GRP_RUN_TESTS):
|
||||
task = run_clang_tidy(env=ctx.env)
|
||||
task.set_inputs(source_node)
|
||||
if not ctx.options.only_failed or not ctx.get_test_state(task.test_id):
|
||||
ctx.add_to_group(task)
|
||||
|
||||
return source_node
|
|
@ -21,9 +21,12 @@
|
|||
# @end:license
|
||||
|
||||
import os.path
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from waflib.Configure import conf
|
||||
from waflib.Task import Task
|
||||
from waflib import Utils
|
||||
|
||||
|
||||
def configure(ctx):
|
||||
|
@ -41,24 +44,41 @@ class compile_csound(Task):
|
|||
ctx = self.generator.bld
|
||||
cwd = ctx.srcnode
|
||||
|
||||
env = {
|
||||
'LD_LIBRARY_PATH': os.path.join(ctx.env.VIRTUAL_ENV, 'lib'),
|
||||
}
|
||||
|
||||
cmd = [
|
||||
ctx.env.CSOUND[0],
|
||||
'-o' + self.outputs[0].path_from(cwd),
|
||||
self.inputs[0].path_from(cwd),
|
||||
]
|
||||
return self.exec_command(cmd, cwd=cwd, env=env)
|
||||
kw = {
|
||||
'cwd': cwd.abspath(),
|
||||
'stdout': subprocess.PIPE,
|
||||
'stderr': subprocess.STDOUT,
|
||||
}
|
||||
ctx.log_command(cmd, kw)
|
||||
rc, out, _ = Utils.run_process(cmd, kw)
|
||||
if rc:
|
||||
sys.stderr.write(out.decode('utf-8'))
|
||||
return rc
|
||||
|
||||
|
||||
@conf
|
||||
def rendered_csound(ctx, source):
|
||||
def rendered_csound(ctx, source, install=None, install_to=None, chmod=0o644):
|
||||
assert source.endswith('.csnd')
|
||||
|
||||
wav_path = os.path.splitext(source)[0] + '.wav'
|
||||
target = ctx.path.get_bld().make_node(wav_path)
|
||||
|
||||
task = compile_csound(env=ctx.env)
|
||||
task.set_inputs(ctx.path.find_resource(source))
|
||||
wav_path = os.path.splitext(source)[0] + '.wav'
|
||||
task.set_outputs(ctx.path.get_bld().make_node(wav_path))
|
||||
task.set_outputs(target)
|
||||
ctx.add_to_group(task)
|
||||
|
||||
if install is None:
|
||||
install = ctx.in_group(ctx.GRP_BUILD_MAIN)
|
||||
|
||||
if install:
|
||||
if install_to is None:
|
||||
install_to = os.path.join(
|
||||
ctx.env.DATADIR, target.parent.path_from(ctx.bldnode.make_node('data')))
|
||||
|
||||
ctx.install_files(install_to, target, chmod=chmod)
|
||||
|
|
|
@ -90,7 +90,7 @@ def cy_module(ctx, source, use=None):
|
|||
install_path=None,
|
||||
)
|
||||
|
||||
if ctx.get_group_name(ctx.current_group) == 'noisicaa':
|
||||
if ctx.in_group(ctx.GRP_BUILD_MAIN):
|
||||
ctx.install_files(os.path.join(ctx.env.LIBDIR, mod.parent.relpath()), mod)
|
||||
|
||||
if pxd.exists():
|
||||
|
@ -99,14 +99,15 @@ def cy_module(ctx, source, use=None):
|
|||
if pyi.exists():
|
||||
ctx.static_file(pyi, install=False)
|
||||
|
||||
return mod
|
||||
|
||||
|
||||
@conf
|
||||
def cy_test(ctx, source, use=None):
|
||||
def cy_test(ctx, source, use=None, **kwargs):
|
||||
if not ctx.env.ENABLE_TEST:
|
||||
return
|
||||
|
||||
old_grp = ctx.current_group
|
||||
ctx.set_group('tests')
|
||||
try:
|
||||
ctx.cy_module(source, use=use)
|
||||
finally:
|
||||
ctx.set_group(old_grp)
|
||||
with ctx.group(ctx.GRP_BUILD_TESTS):
|
||||
target = ctx.cy_module(source, use=use)
|
||||
|
||||
ctx.add_py_test_runner(target, **kwargs)
|
||||
|
|
|
@ -49,14 +49,13 @@ def faust_dsp(ctx, cls_name, source='processor.dsp'):
|
|||
],
|
||||
cls_name=cls_name)
|
||||
|
||||
if ctx.get_group_name(ctx.current_group) == 'noisicaa':
|
||||
if ctx.in_group(ctx.GRP_BUILD_MAIN):
|
||||
ctx.install_files(os.path.join(ctx.env.LIBDIR, json.parent.relpath()), json)
|
||||
|
||||
ctx.shlib(
|
||||
target='noisicaa-builtin_nodes-%s-processor' % cls_name.lower(),
|
||||
source='processor.cpp',
|
||||
use=[
|
||||
'NOISELIB',
|
||||
'noisicaa-audioproc-public',
|
||||
'noisicaa-host_system',
|
||||
],
|
||||
|
|
|
@ -27,7 +27,6 @@ import os.path
|
|||
import pathlib
|
||||
import shutil
|
||||
import subprocess
|
||||
import textwrap
|
||||
|
||||
import packaging.markers
|
||||
import packaging.requirements
|
||||
|
@ -64,7 +63,7 @@ def install_runtime_pip_packages(ctx):
|
|||
stdout=subprocess.PIPE, check=True)
|
||||
installed_packages = {
|
||||
packaging.utils.canonicalize_name(p['name']): (p['name'], p['version'])
|
||||
for p in json.loads(p.stdout)}
|
||||
for p in json.loads(p.stdout.decode('utf-8'))}
|
||||
|
||||
required_packages = set()
|
||||
|
||||
|
@ -108,7 +107,7 @@ def install_runtime_pip_packages(ctx):
|
|||
# File is not under site-packages.
|
||||
continue
|
||||
|
||||
dest_path = os.path.join(ctx.env.LIBDIR, rel_path)
|
||||
dest_path = os.path.join(ctx.env.LIBDIR, str(rel_path))
|
||||
|
||||
if not ctx.progress_bar:
|
||||
Logs.info(
|
||||
|
@ -118,5 +117,5 @@ def install_runtime_pip_packages(ctx):
|
|||
|
||||
if not os.path.isdir(os.path.dirname(dest_path)):
|
||||
os.makedirs(os.path.dirname(dest_path))
|
||||
shutil.copyfile(src_path, dest_path)
|
||||
shutil.copystat(src_path, dest_path)
|
||||
shutil.copyfile(str(src_path), dest_path)
|
||||
shutil.copystat(str(src_path), dest_path)
|
||||
|
|
|
@ -42,7 +42,7 @@ class build_model(Task):
|
|||
'--template', self.inputs[1].abspath(),
|
||||
os.path.relpath(self.inputs[0].abspath(), ctx.top_dir),
|
||||
]
|
||||
return self.exec_command(cmd, cwd=ctx.top_dir, env={'PYTHONPATH': ctx.out_dir})
|
||||
return self.exec_command(cmd, cwd=ctx.top_dir)
|
||||
|
||||
|
||||
@conf
|
||||
|
@ -58,5 +58,5 @@ def model_description(
|
|||
os.path.join(os.path.dirname(output), 'model.proto')))
|
||||
ctx.add_to_group(task)
|
||||
|
||||
if ctx.get_group_name(ctx.current_group) == 'noisicaa':
|
||||
if ctx.in_group(ctx.GRP_BUILD_MAIN):
|
||||
ctx.install_files(os.path.join(ctx.env.LIBDIR, model_node.parent.relpath()), model_node)
|
||||
|
|
|
@ -86,7 +86,7 @@ def py_proto(ctx, source):
|
|||
task.set_outputs(ctx.path.get_bld().make_node(pyi_path))
|
||||
ctx.add_to_group(task)
|
||||
|
||||
if ctx.get_group_name(ctx.current_group) == 'noisicaa':
|
||||
if ctx.in_group(ctx.GRP_BUILD_MAIN):
|
||||
ctx.install_files(os.path.join(ctx.env.LIBDIR, pb2_node.parent.relpath()), pb2_node)
|
||||
ctx.install_files(os.path.join(ctx.env.LIBDIR, pb2c_node.parent.relpath()), pb2c_node)
|
||||
|
||||
|
@ -132,3 +132,5 @@ def cpp_proto(ctx, source):
|
|||
task.set_outputs(ctx.path.get_bld().make_node(
|
||||
os.path.splitext(source)[0] + '.pb.h'))
|
||||
ctx.add_to_group(task)
|
||||
|
||||
return os.path.splitext(source)[0] + '.pb.cc'
|
||||
|
|
|
@ -21,11 +21,17 @@
|
|||
# @end:license
|
||||
|
||||
import importlib.util
|
||||
import os
|
||||
import os.path
|
||||
import py_compile
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import threading
|
||||
|
||||
from waflib.Configure import conf
|
||||
from waflib.Task import Task
|
||||
from waflib import Utils
|
||||
|
||||
|
||||
def copy_py_module(task):
|
||||
|
@ -38,9 +44,179 @@ def copy_py_module(task):
|
|||
task.outputs[0].abspath(), task.outputs[1].abspath(), doraise=True, optimize=0)
|
||||
|
||||
|
||||
# Multiple concurrent mypy processes cannot share the same cache directory. So we track a set of
|
||||
# directories and allocate an unused directory for each running process.
|
||||
mypy_cache_lock = threading.Lock()
|
||||
mypy_caches = []
|
||||
mypy_next_cache = 0
|
||||
|
||||
|
||||
class run_mypy(Task):
|
||||
always_run = True
|
||||
|
||||
def __init__(self, *, env, strict):
|
||||
super().__init__(env=env)
|
||||
|
||||
self.__strict = strict
|
||||
|
||||
def __str__(self):
|
||||
return self.inputs[0].relpath()
|
||||
|
||||
def keyword(self):
|
||||
return 'Lint (mypy)'
|
||||
|
||||
@property
|
||||
def mod_name(self):
|
||||
mod_path = self.inputs[0].relpath()
|
||||
assert mod_path.endswith('.py') or mod_path.endswith('.so')
|
||||
return '.'.join(os.path.splitext(mod_path)[0].split(os.sep))
|
||||
|
||||
@property
|
||||
def test_id(self):
|
||||
return self.mod_name + ':mypy'
|
||||
|
||||
def run(self):
|
||||
ctx = self.generator.bld
|
||||
|
||||
success = True
|
||||
try:
|
||||
ini_path = os.path.join(ctx.top_dir, 'noisidev', 'mypy.ini')
|
||||
|
||||
with mypy_cache_lock:
|
||||
if not mypy_caches:
|
||||
global mypy_next_cache # pylint: disable=global-statement
|
||||
cache_num = mypy_next_cache
|
||||
mypy_next_cache += 1
|
||||
else:
|
||||
cache_num = mypy_caches.pop(-1)
|
||||
|
||||
try:
|
||||
argv = [
|
||||
os.path.join(ctx.env.VIRTUAL_ENV, 'bin', 'mypy'),
|
||||
'--config-file', ini_path,
|
||||
'--cache-dir=%s' % os.path.join(ctx.out_dir, 'mypy-cache.%d' % cache_num),
|
||||
'--show-traceback',
|
||||
'-m', self.mod_name,
|
||||
]
|
||||
if self.__strict:
|
||||
argv.append('--disallow-untyped-defs')
|
||||
|
||||
env = dict(os.environ)
|
||||
env['MYPYPATH'] = os.path.join(ctx.top_dir, '3rdparty', 'typeshed')
|
||||
|
||||
kw = {
|
||||
'cwd': ctx.out_dir,
|
||||
'env': env,
|
||||
'stdout': subprocess.PIPE,
|
||||
'stderr': subprocess.PIPE,
|
||||
}
|
||||
|
||||
ctx.log_command(argv, kw)
|
||||
_, out, err = Utils.run_process(argv, kw)
|
||||
out = out.strip()
|
||||
|
||||
if out:
|
||||
success = False
|
||||
|
||||
finally:
|
||||
with mypy_cache_lock:
|
||||
mypy_caches.append(cache_num)
|
||||
|
||||
if err:
|
||||
sys.stderr.write(err.decode('utf-8'))
|
||||
raise RuntimeError("mypy is unhappy")
|
||||
|
||||
out_path = os.path.join(ctx.TEST_RESULTS_PATH, self.mod_name, 'mypy.log')
|
||||
os.makedirs(os.path.dirname(out_path), exist_ok=True)
|
||||
with open(out_path, 'wb') as fp:
|
||||
fp.write(out)
|
||||
|
||||
if out and ctx.options.fail_fast:
|
||||
sys.stderr.write(out.decode('utf-8'))
|
||||
sys.stderr.write('\n')
|
||||
raise RuntimeError("mypy for %s failed." % self.mod_name)
|
||||
|
||||
except Exception:
|
||||
success = False
|
||||
raise
|
||||
|
||||
finally:
|
||||
ctx.record_test_state(self.test_id, success)
|
||||
|
||||
|
||||
class run_pylint(Task):
|
||||
always_run = True
|
||||
|
||||
def __str__(self):
|
||||
return self.inputs[0].relpath()
|
||||
|
||||
def keyword(self):
|
||||
return 'Lint (pylint)'
|
||||
|
||||
@property
|
||||
def mod_name(self):
|
||||
mod_path = self.inputs[0].relpath()
|
||||
assert mod_path.endswith('.py') or mod_path.endswith('.so')
|
||||
return '.'.join(os.path.splitext(mod_path)[0].split(os.sep))
|
||||
|
||||
@property
|
||||
def test_id(self):
|
||||
return self.mod_name + ':pylint'
|
||||
|
||||
def run(self):
|
||||
ctx = self.generator.bld
|
||||
|
||||
success = True
|
||||
try:
|
||||
argv = [
|
||||
os.path.join(ctx.env.VIRTUAL_ENV, 'bin', 'pylint'),
|
||||
'--rcfile=%s' % os.path.join(ctx.top_dir, 'bin', 'pylintrc'),
|
||||
'--output-format=parseable',
|
||||
'--score=no',
|
||||
'--exit-zero',
|
||||
self.mod_name,
|
||||
]
|
||||
|
||||
kw = {
|
||||
'cwd': ctx.out_dir,
|
||||
'stdout': subprocess.PIPE,
|
||||
'stderr': subprocess.PIPE,
|
||||
}
|
||||
|
||||
ctx.log_command(argv, kw)
|
||||
rc, out, err = Utils.run_process(argv, kw)
|
||||
out = out.strip()
|
||||
|
||||
if out:
|
||||
success = False
|
||||
|
||||
if rc != 0:
|
||||
sys.stderr.write(err.decode('utf-8'))
|
||||
raise RuntimeError("pylint is unhappy")
|
||||
|
||||
out_path = os.path.join(ctx.TEST_RESULTS_PATH, self.mod_name, 'pylint.log')
|
||||
os.makedirs(os.path.dirname(out_path), exist_ok=True)
|
||||
with open(out_path, 'wb') as fp:
|
||||
fp.write(out)
|
||||
|
||||
if out and ctx.options.fail_fast:
|
||||
sys.stderr.write(out.decode('utf-8'))
|
||||
sys.stderr.write('\n')
|
||||
raise RuntimeError("pylint for %s failed." % self.mod_name)
|
||||
|
||||
except Exception:
|
||||
success = False
|
||||
raise
|
||||
|
||||
finally:
|
||||
ctx.record_test_state(self.test_id, success)
|
||||
|
||||
|
||||
@conf
|
||||
def py_module(ctx, source):
|
||||
def py_module(ctx, source, mypy='strict', pylint='enabled'):
|
||||
assert source.endswith('.py')
|
||||
assert mypy in ('strict', 'loose', 'disabled')
|
||||
assert pylint in ('enabled', 'disabled')
|
||||
|
||||
source_node = ctx.path.make_node(source)
|
||||
target_node = ctx.path.get_bld().make_node(source)
|
||||
|
@ -54,21 +230,128 @@ def py_module(ctx, source):
|
|||
compiled_node,
|
||||
])
|
||||
|
||||
if ctx.get_group_name(ctx.current_group) == 'noisicaa':
|
||||
if ctx.in_group(ctx.GRP_BUILD_MAIN):
|
||||
ctx.install_files(
|
||||
os.path.join(ctx.env.LIBDIR, target_node.parent.relpath()), target_node)
|
||||
ctx.install_files(
|
||||
os.path.join(ctx.env.LIBDIR, compiled_node.parent.relpath()), compiled_node)
|
||||
|
||||
if source == '__init__.py':
|
||||
mypy = 'disabled'
|
||||
|
||||
if ctx.in_group(ctx.GRP_BUILD_TOOLS):
|
||||
mypy = 'disabled'
|
||||
pylint = 'disabled'
|
||||
|
||||
if (ctx.cmd == 'test'
|
||||
and ctx.should_run_test(target_node)
|
||||
and {'all', 'lint', 'mypy'} & ctx.TEST_TAGS
|
||||
and mypy != 'disabled'):
|
||||
with ctx.group(ctx.GRP_RUN_TESTS):
|
||||
task = run_mypy(env=ctx.env, strict=(mypy == 'strict'))
|
||||
task.set_inputs(target_node)
|
||||
if not ctx.options.only_failed or not ctx.get_test_state(task.test_id):
|
||||
ctx.add_to_group(task)
|
||||
|
||||
if (ctx.cmd == 'test'
|
||||
and ctx.should_run_test(target_node)
|
||||
and {'all', 'lint', 'pylint'} & ctx.TEST_TAGS
|
||||
and pylint != 'disabled'):
|
||||
with ctx.group(ctx.GRP_RUN_TESTS):
|
||||
task = run_pylint(env=ctx.env)
|
||||
task.set_inputs(target_node)
|
||||
if not ctx.options.only_failed or not ctx.get_test_state(task.test_id):
|
||||
ctx.add_to_group(task)
|
||||
|
||||
return target_node
|
||||
|
||||
|
||||
class run_py_test(Task):
|
||||
always_run = True
|
||||
|
||||
def __init__(self, *, env, timeout=None):
|
||||
super().__init__(env=env)
|
||||
|
||||
self.__timeout = timeout or 60
|
||||
assert self.__timeout > 0
|
||||
|
||||
def __str__(self):
|
||||
return self.inputs[0].relpath()
|
||||
|
||||
def keyword(self):
|
||||
return 'Testing'
|
||||
|
||||
@property
|
||||
def mod_name(self):
|
||||
mod_path = self.inputs[0].relpath()
|
||||
assert mod_path.endswith('.py') or mod_path.endswith('.so')
|
||||
return '.'.join(os.path.splitext(mod_path)[0].split(os.sep))
|
||||
|
||||
@property
|
||||
def test_id(self):
|
||||
return self.mod_name + ':unit'
|
||||
|
||||
def run(self):
|
||||
ctx = self.generator.bld
|
||||
|
||||
success = True
|
||||
try:
|
||||
results_path = os.path.join(ctx.TEST_RESULTS_PATH, self.mod_name)
|
||||
cmd = [
|
||||
ctx.env.PYTHON[0],
|
||||
'-m', 'noisidev.test_runner',
|
||||
'--set-rc=false',
|
||||
'--store-result=%s' % results_path,
|
||||
'--coverage=%s' % ('true' if ctx.options.coverage else 'false'),
|
||||
self.mod_name,
|
||||
]
|
||||
rc = self.exec_command(
|
||||
cmd,
|
||||
cwd=ctx.out_dir,
|
||||
timeout=self.__timeout)
|
||||
|
||||
if rc != 0:
|
||||
raise RuntimeError("test_runner failed.")
|
||||
|
||||
if not os.path.isfile(os.path.join(results_path, 'results.xml')):
|
||||
raise RuntimeError("Missing results.xml.")
|
||||
|
||||
if rc != 0 and ctx.options.fail_fast:
|
||||
if os.path.isfile(os.path.join(results_path, 'test.log')):
|
||||
with open(os.path.join(results_path, 'test.log'), 'r') as fp:
|
||||
sys.stderr.write(fp.read())
|
||||
|
||||
raise RuntimeError("Tests for %s failed." % self.mod_name)
|
||||
|
||||
except Exception:
|
||||
success = False
|
||||
raise
|
||||
|
||||
finally:
|
||||
ctx.record_test_state(self.test_id, success)
|
||||
|
||||
|
||||
@conf
|
||||
def py_test(ctx, source):
|
||||
def add_py_test_runner(ctx, target, tags=None, timeout=None):
|
||||
if tags is None:
|
||||
tags = {'unit'}
|
||||
|
||||
if (ctx.cmd == 'test'
|
||||
and ('all' in ctx.TEST_TAGS or tags & ctx.TEST_TAGS)
|
||||
and ctx.should_run_test(target)):
|
||||
with ctx.group(ctx.GRP_RUN_TESTS):
|
||||
task = run_py_test(env=ctx.env, timeout=timeout)
|
||||
task.set_inputs(target)
|
||||
if not ctx.options.only_failed or not ctx.get_test_state(task.test_id):
|
||||
ctx.add_to_group(task)
|
||||
|
||||
|
||||
@conf
|
||||
def py_test(ctx, source, mypy='loose', **kwargs):
|
||||
if not ctx.env.ENABLE_TEST:
|
||||
return
|
||||
|
||||
old_grp = ctx.current_group
|
||||
ctx.set_group('tests')
|
||||
try:
|
||||
ctx.py_module(source)
|
||||
finally:
|
||||
ctx.set_group(old_grp)
|
||||
with ctx.group(ctx.GRP_BUILD_TESTS):
|
||||
target = ctx.py_module(source, mypy=mypy)
|
||||
|
||||
ctx.add_py_test_runner(target, **kwargs)
|
||||
|
|
|
@ -45,11 +45,16 @@ def copy_file(task):
|
|||
|
||||
|
||||
@conf
|
||||
def static_file(ctx, source, install=None, install_to=None, rewrite=False, chmod=0o644):
|
||||
def static_file(
|
||||
ctx, source, target=None, install=None, install_to=None, rewrite=False, chmod=0o644):
|
||||
if not isinstance(source, Node):
|
||||
source = ctx.path.make_node(source)
|
||||
|
||||
target = source.get_bld()
|
||||
if target is None:
|
||||
target = source.get_bld()
|
||||
|
||||
if not isinstance(target, Node):
|
||||
target = ctx.path.make_node(target).get_bld()
|
||||
|
||||
ctx(rule=copy_file,
|
||||
source=source,
|
||||
|
@ -57,7 +62,7 @@ def static_file(ctx, source, install=None, install_to=None, rewrite=False, chmod
|
|||
rewrite=rewrite)
|
||||
|
||||
if install is None:
|
||||
install = (ctx.get_group_name(ctx.current_group) == 'noisicaa')
|
||||
install = ctx.in_group(ctx.GRP_BUILD_MAIN)
|
||||
|
||||
if install:
|
||||
if install_to is None:
|
||||
|
|
|
@ -43,7 +43,7 @@ def stripped_svg(ctx, source):
|
|||
source=ctx.path.make_node(source),
|
||||
target=target)
|
||||
|
||||
if ctx.get_group_name(ctx.current_group) == 'noisicaa':
|
||||
if ctx.in_group(ctx.GRP_BUILD_MAIN):
|
||||
ctx.install_files(
|
||||
os.path.join(ctx.env.DATADIR, target.parent.path_from(ctx.bldnode.make_node('data'))),
|
||||
target)
|
||||
|
|
|
@ -0,0 +1,332 @@
|
|||
# -*- mode: python -*-
|
||||
|
||||
# @begin:license
|
||||
#
|
||||
# Copyright (c) 2015-2019, Benjamin Niemann <pink@odahoda.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# @end:license
|
||||
|
||||
import datetime
|
||||
import fnmatch
|
||||
import glob
|
||||
import os
|
||||
import os.path
|
||||
import shutil
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from waflib.Configure import conf
|
||||
from waflib import Logs
|
||||
|
||||
|
||||
ALL_TAGS = {'all', 'unit', 'lint', 'pylint', 'mypy', 'clang-tidy', 'integration', 'perf'}
|
||||
|
||||
def options(ctx):
|
||||
grp = ctx.add_option_group('Test options')
|
||||
grp.add_option(
|
||||
'--tags',
|
||||
default='unit,lint',
|
||||
help=("Comma separated list of test classes to run (%s) [default: unit,lint]"
|
||||
% ', '.join(sorted(ALL_TAGS))))
|
||||
grp.add_option(
|
||||
'--tests',
|
||||
action='append',
|
||||
default=None,
|
||||
help=("Tests to run. Uses a prefix match and can contain globs. This flag can be used"
|
||||
" multiple times [default: all tests]"))
|
||||
grp.add_option(
|
||||
'--fail-fast',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help="Abort test run on first failure.")
|
||||
grp.add_option(
|
||||
'--only-failed',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help="Only tests, which previously failed.")
|
||||
grp.add_option(
|
||||
'--coverage',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help="Enable code coverage report.")
|
||||
|
||||
|
||||
@conf
|
||||
def init_test(ctx):
|
||||
if ctx.cmd == 'test':
|
||||
if not ctx.env.ENABLE_TEST:
|
||||
ctx.fatal("noisicaä has been configured without --enable-tests")
|
||||
|
||||
ctx.TEST_STATE_PATH = os.path.join(ctx.out_dir, 'teststates')
|
||||
ctx.TEST_RESULTS_PATH = os.path.join(ctx.out_dir, 'testresults')
|
||||
ctx.TEST_TAGS = set(ctx.options.tags.split(','))
|
||||
for tag in ctx.TEST_TAGS:
|
||||
assert tag in ALL_TAGS
|
||||
|
||||
ctx.add_pre_fun(test_init)
|
||||
ctx.add_post_fun(test_complete)
|
||||
|
||||
|
||||
def test_init(ctx):
|
||||
if os.path.isdir(ctx.TEST_RESULTS_PATH):
|
||||
shutil.rmtree(ctx.TEST_RESULTS_PATH)
|
||||
|
||||
if not ctx.options.only_failed and os.path.isdir(ctx.TEST_STATE_PATH):
|
||||
shutil.rmtree(ctx.TEST_STATE_PATH)
|
||||
|
||||
|
||||
def test_complete(ctx):
|
||||
ctx.tests_failed = False
|
||||
|
||||
ctx.collect_unittest_results()
|
||||
|
||||
if {'all', 'lint', 'mypy'} & ctx.TEST_TAGS:
|
||||
ctx.collect_mypy_results()
|
||||
|
||||
if {'all', 'lint', 'pylint'} & ctx.TEST_TAGS:
|
||||
ctx.collect_pylint_results()
|
||||
|
||||
if {'all', 'lint', 'clang-tidy'} & ctx.TEST_TAGS:
|
||||
ctx.collect_clang_tidy_results()
|
||||
|
||||
if ctx.options.coverage:
|
||||
ctx.collect_coverage_results()
|
||||
|
||||
if ctx.tests_failed:
|
||||
ctx.fatal("Some tests failed")
|
||||
|
||||
|
||||
@conf
|
||||
def should_run_test(ctx, path):
|
||||
if not ctx.options.tests:
|
||||
return True
|
||||
|
||||
mparts = path.relpath().split(os.sep)
|
||||
for selector in ctx.options.tests:
|
||||
sparts = selector.rstrip(os.sep).split(os.sep)
|
||||
if len(sparts) > len(mparts):
|
||||
continue
|
||||
matched = True
|
||||
for mpart, spart in zip(mparts[:len(sparts)], sparts):
|
||||
if not fnmatch.fnmatch(mpart, spart):
|
||||
matched = False
|
||||
if matched:
|
||||
return True
|
||||
|
||||
|
||||
@conf
|
||||
def record_test_state(ctx, test_name, state):
|
||||
state_path = os.path.join(ctx.TEST_STATE_PATH, test_name)
|
||||
os.makedirs(os.path.dirname(state_path), exist_ok=True)
|
||||
with open(state_path, 'w') as fp:
|
||||
fp.write('1' if state else '0')
|
||||
|
||||
|
||||
@conf
|
||||
def get_test_state(ctx, test_name):
|
||||
state_path = os.path.join(ctx.TEST_STATE_PATH, test_name)
|
||||
if os.path.isfile(state_path):
|
||||
with open(state_path, 'r') as fp:
|
||||
return bool(int(fp.read()))
|
||||
|
||||
return False
|
||||
|
||||
|
||||
@conf
|
||||
def collect_unittest_results(ctx):
|
||||
import xunitparser
|
||||
|
||||
class TestCase(xunitparser.TestCase):
|
||||
# This override only exists, because the original has a docstring, which shows up in the
|
||||
# output...
|
||||
def runTest(self): # pylint: disable=useless-super-delegation
|
||||
super().runTest()
|
||||
|
||||
|
||||
class TestSuite(xunitparser.TestSuite):
|
||||
# Prevent tests from being None'ed in run().
|
||||
_cleanup = False
|
||||
|
||||
|
||||
class TextTestResult(unittest.TextTestResult, xunitparser.TestResult):
|
||||
def addSuccess(self, test):
|
||||
if self.showAll and test.time is not None:
|
||||
self.stream.write('[%dms] ' % (test.time / datetime.timedelta(milliseconds=1)))
|
||||
super().addSuccess(test)
|
||||
|
||||
|
||||
class Parser(xunitparser.Parser):
|
||||
TC_CLASS = TestCase
|
||||
TS_CLASS = TestSuite
|
||||
|
||||
|
||||
def flatten_suite(suite):
|
||||
for child in suite:
|
||||
if isinstance(child, unittest.TestSuite):
|
||||
yield from flatten_suite(child)
|
||||
else:
|
||||
yield child
|
||||
|
||||
all_tests = unittest.TestSuite()
|
||||
total_time = datetime.timedelta()
|
||||
for result_path in glob.glob(os.path.join(ctx.TEST_RESULTS_PATH, '*', 'results.xml')):
|
||||
if os.path.getsize(result_path) == 0:
|
||||
continue
|
||||
|
||||
try:
|
||||
ts, _ = Parser().parse(result_path)
|
||||
for tc in flatten_suite(ts):
|
||||
all_tests.addTest(tc)
|
||||
if tc.time is not None:
|
||||
total_time += tc.time
|
||||
except Exception:
|
||||
print("Failed to parse %s" % result_path)
|
||||
raise
|
||||
|
||||
if not list(all_tests):
|
||||
return
|
||||
|
||||
sorted_tests = unittest.TestSuite()
|
||||
for tc in sorted(all_tests, key=lambda tc: (tc.classname, tc.methodname)):
|
||||
sorted_tests.addTest(tc)
|
||||
|
||||
stream = unittest.runner._WritelnDecorator(sys.stderr)
|
||||
|
||||
result = TextTestResult(stream, True, verbosity=2)
|
||||
result.startTestRun()
|
||||
try:
|
||||
sorted_tests(result)
|
||||
finally:
|
||||
result.stopTestRun()
|
||||
|
||||
result.printErrors()
|
||||
stream.writeln(result.separator2)
|
||||
run = result.testsRun
|
||||
stream.writeln("Ran %d test%s in %s" %
|
||||
(run, run != 1 and "s" or "", total_time))
|
||||
stream.writeln()
|
||||
|
||||
infos = []
|
||||
if not result.wasSuccessful():
|
||||
msg = "FAILED"
|
||||
if result.failures:
|
||||
infos.append("failures=%d" % len(result.failures))
|
||||
if result.errors:
|
||||
infos.append("errors=%d" % len(result.errors))
|
||||
else:
|
||||
msg = "OK"
|
||||
if result.skipped:
|
||||
infos.append("skipped=%d" % len(result.skipped))
|
||||
if result.expectedFailures:
|
||||
infos.append("expected failures=%d" % len(result.expectedFailures))
|
||||
if result.unexpectedSuccesses:
|
||||
infos.append("unexpected successes=%d" % len(result.unexpectedSuccesses))
|
||||
|
||||
if infos:
|
||||
msg += " (%s)" % ", ".join(infos)
|
||||
|
||||
if not result.wasSuccessful():
|
||||
Logs.info(Logs.colors.RED + msg)
|
||||
ctx.tests_failed = True
|
||||
else:
|
||||
Logs.info(msg)
|
||||
|
||||
|
||||
@conf
|
||||
def collect_mypy_results(ctx):
|
||||
Logs.info(Logs.colors.BLUE + "Collecting mypy data...")
|
||||
|
||||
issues_found = False
|
||||
|
||||
for result_path in glob.glob(os.path.join(ctx.TEST_RESULTS_PATH, '*', 'mypy.log')):
|
||||
with open(result_path, 'r') as fp:
|
||||
log = fp.read()
|
||||
if log:
|
||||
issues_found = True
|
||||
sys.stderr.write(log)
|
||||
sys.stderr.write('\n\n')
|
||||
|
||||
if issues_found:
|
||||
ctx.tests_failed = True
|
||||
Logs.info(Logs.colors.RED + "mypy found some issues")
|
||||
else:
|
||||
Logs.info(Logs.colors.GREEN + "No issues found")
|
||||
Logs.info('')
|
||||
|
||||
|
||||
@conf
|
||||
def collect_pylint_results(ctx):
|
||||
Logs.info(Logs.colors.BLUE + "Collecting pylint data...")
|
||||
|
||||
issues_found = False
|
||||
|
||||
for result_path in glob.glob(os.path.join(ctx.TEST_RESULTS_PATH, '*', 'pylint.log')):
|
||||
with open(result_path, 'r') as fp:
|
||||
log = fp.read()
|
||||
if log:
|
||||
issues_found = True
|
||||
sys.stderr.write(log)
|
||||
sys.stderr.write('\n\n')
|
||||
|
||||
if issues_found:
|
||||
ctx.tests_failed = True
|
||||
Logs.info(Logs.colors.RED + "pylint found some issues")
|
||||
else:
|
||||
Logs.info(Logs.colors.GREEN + "No issues found")
|
||||
Logs.info('')
|
||||
|
||||
|
||||
@conf
|
||||
def collect_clang_tidy_results(ctx):
|
||||
Logs.info(Logs.colors.BLUE + "Collecting clang-tidy data...")
|
||||
|
||||
issues_found = False
|
||||
|
||||
for result_path in glob.glob(os.path.join(ctx.TEST_RESULTS_PATH, '*', 'clang-tidy.log')):
|
||||
with open(result_path, 'r') as fp:
|
||||
log = fp.read()
|
||||
if log:
|
||||
issues_found = True
|
||||
sys.stderr.write(log)
|
||||
sys.stderr.write('\n\n')
|
||||
|
||||
if issues_found:
|
||||
ctx.tests_failed = True
|
||||
Logs.info(Logs.colors.RED + "clang-tidy found some issues")
|
||||
else:
|
||||
Logs.info(Logs.colors.GREEN + "No issues found")
|
||||
Logs.info('')
|
||||
|
||||
|
||||
@conf
|
||||
def collect_coverage_results(ctx):
|
||||
Logs.info(Logs.colors.BLUE + "Collecting coverage data...")
|
||||
|
||||
import coverage
|
||||
|
||||
cov = coverage.Coverage()
|
||||
data = cov.get_data()
|
||||
for result_path in glob.glob(os.path.join(ctx.TEST_RESULTS_PATH, '*', 'coverage.data')):
|
||||
d = coverage.CoverageData()
|
||||
d.read_file(result_path)
|
||||
data.update(d)
|
||||
|
||||
report_path = os.path.join(ctx.TEST_RESULTS_PATH, 'coverage')
|
||||
total_coverage = cov.html_report(directory=report_path)
|
||||
Logs.info(Logs.colors.GREEN + "Total coverage: %.1f%%" % total_coverage)
|
||||
Logs.info(Logs.colors.GREEN + "Coverage report: file://%s/index.html" % report_path)
|
||||
Logs.info('')
|
|
@ -116,6 +116,9 @@ def configure(ctx):
|
|||
os_release = Version(os_release)
|
||||
ctx.end_msg("%s %s" % (os_dist, os_release))
|
||||
|
||||
ctx.env.OS_DIST = os_dist
|
||||
ctx.env.OS_RELEASE = str(os_release)
|
||||
|
||||
ctx.start_msg("Query pip for installed packages")
|
||||
pip_mgr = PipManager(ctx)
|
||||
pip_mgr.update_packages()
|
||||
|
@ -145,15 +148,20 @@ def configure(ctx):
|
|||
pip_mgr.check_package(BUILD, 'pip', version='>=19.0')
|
||||
pip_mgr.check_package(BUILD, 'setuptools', version='>=41.0')
|
||||
pip_mgr.check_package(BUILD, 'wheel', version='>=0.33')
|
||||
sys_mgr.check_package(BUILD, 'build-essential')
|
||||
sys_mgr.check_package(BUILD, 'python3-dev')
|
||||
|
||||
# Misc pip packages:
|
||||
pip_mgr.check_package(RUNTIME, 'eventfd')
|
||||
pip_mgr.check_package(RUNTIME, 'lucky-humanize')
|
||||
pip_mgr.check_package(RUNTIME, 'numpy')
|
||||
# numpy.core.numeric.asarray is gone from numpy 1.17
|
||||
pip_mgr.check_package(RUNTIME, 'numpy', version='1.16.4')
|
||||
pip_mgr.check_package(RUNTIME, 'portalocker')
|
||||
pip_mgr.check_package(RUNTIME, 'posix-ipc')
|
||||
pip_mgr.check_package(RUNTIME, 'psutil')
|
||||
pip_mgr.check_package(RUNTIME, 'pyparsing')
|
||||
# psutil 5.6.3 has an empty __init__.py...
|
||||
pip_mgr.check_package(RUNTIME, 'psutil', version='5.6.2')
|
||||
# pyparsing 2.4.1 causes issues with packaging
|
||||
pip_mgr.check_package(RUNTIME, 'pyparsing', version='2.4.0')
|
||||
pip_mgr.check_package(RUNTIME, 'sortedcontainers')
|
||||
pip_mgr.check_package(RUNTIME, 'toposort')
|
||||
pip_mgr.check_package(RUNTIME, 'urwid')
|
||||
|
@ -162,6 +170,7 @@ def configure(ctx):
|
|||
pip_mgr.check_package(BUILD, 'Jinja2')
|
||||
pip_mgr.check_package(BUILD, 'PyYAML')
|
||||
pip_mgr.check_package(BUILD, 'packaging', version='>=19.0')
|
||||
pip_mgr.check_package(BUILD, 'xunitparser')
|
||||
pip_mgr.check_package(DEV, 'asynctest')
|
||||
pip_mgr.check_package(DEV, 'async-generator')
|
||||
pip_mgr.check_package(DEV, 'coverage')
|
||||
|
@ -169,9 +178,11 @@ def configure(ctx):
|
|||
pip_mgr.check_package(DEV, 'py-cpuinfo')
|
||||
pip_mgr.check_package(DEV, 'pyfakefs')
|
||||
pip_mgr.check_package(DEV, 'pylint', version='2.3.1')
|
||||
pip_mgr.check_package(DEV, 'unittest-xml-reporting')
|
||||
|
||||
# misc sys packages:
|
||||
sys_mgr.check_package(RUNTIME, 'ffmpeg')
|
||||
sys_mgr.check_package(RUNTIME, 'libxkbcommon-x11-0')
|
||||
sys_mgr.check_package(BUILD, 'cmake')
|
||||
sys_mgr.check_package(BUILD, 'python3-dev')
|
||||
sys_mgr.check_package(BUILD, 'portaudio19-dev')
|
||||
|
@ -183,10 +194,16 @@ def configure(ctx):
|
|||
sys_mgr.check_package(DEV, 'xvfb')
|
||||
sys_mgr.check_package(DEV, 'intltool')
|
||||
|
||||
# git is needed to fetch PIP packages from 'git+https://...' sources.
|
||||
sys_mgr.check_package(BUILD, 'git')
|
||||
|
||||
# mypy
|
||||
pip_mgr.check_package(DEV, 'mypy', version='0.701')
|
||||
pip_mgr.check_package(DEV, 'mypy', version='0.720')
|
||||
pip_mgr.check_package(RUNTIME, 'mypy-extensions')
|
||||
|
||||
# sndfile
|
||||
sys_mgr.check_package(BUILD, 'libsndfile1-dev')
|
||||
|
||||
# csound
|
||||
sys_mgr.check_package(BUILD, 'libsamplerate0-dev')
|
||||
sys_mgr.check_package(BUILD, 'libboost-dev')
|
||||
|
@ -214,9 +231,6 @@ def configure(ctx):
|
|||
FaustBuilder(ctx).check(BUILD, version='2.15.11')
|
||||
FaustLibrariesBuilder(ctx).check(BUILD, version='64a57f56') # snapshot from 2019-03-30
|
||||
|
||||
# sndfile
|
||||
sys_mgr.check_package(BUILD, 'libsndfile1-dev')
|
||||
|
||||
# libswresample
|
||||
sys_mgr.check_package(BUILD, 'libswresample-dev')
|
||||
|
||||
|
@ -256,21 +270,34 @@ def configure(ctx):
|
|||
pip_mgr.check_package(BUILD, 'mypy-protobuf', source='git+https://github.com/odahoda/mypy-protobuf.git#egg=mypy-protobuf&subdirectory=python')
|
||||
|
||||
# profiling
|
||||
sys_mgr.check_package(DEV, 'google-perftools')
|
||||
sys_mgr.check_package(RUNTIME, 'google-perftools')
|
||||
sys_mgr.check_package(RUNTIME, 'libgoogle-perftools4')
|
||||
sys_mgr.check_package(BUILD, 'libgoogle-perftools-dev')
|
||||
|
||||
# indicator-cpufreq
|
||||
sys_mgr.check_package(DEV, 'libdbus-1-dev')
|
||||
pip_mgr.check_package(DEV, 'dbus-python')
|
||||
sys_mgr.check_package(DEV, 'bzr')
|
||||
pip_mgr.check_package(DEV, 'python-distutils-extra', source='bzr+lp:python-distutils-extra#egg=python-distutils-extra')
|
||||
pip_mgr.check_package(DEV, 'indicator-cpufreq', source='bzr+lp:indicator-cpufreq#egg=indicator-cpufreq')
|
||||
sys_mgr.check_package(DEV, 'indicator-cpufreq')
|
||||
|
||||
# clang-tidy
|
||||
if ctx.env.ENABLE_TEST:
|
||||
# clang-tidy is optional, let's install it on systems where we known that V8 is
|
||||
# available. On other systems it's up to the user to install it.
|
||||
if os_dist == 'ubuntu' and os_release >= Version('18.04'):
|
||||
sys_mgr.check_package(DEV, 'clang-tidy-8')
|
||||
|
||||
# vmtest
|
||||
pip_mgr.check_package(VMTEST, 'paramiko')
|
||||
pip_mgr.check_package(VMTEST, 'python-xlib')
|
||||
sys_mgr.check_package(VMTEST, 'virtualbox')
|
||||
sys_mgr.check_package(VMTEST, 'qemu-system-x86')
|
||||
sys_mgr.check_package(VMTEST, 'qemu-block-extra')
|
||||
sys_mgr.check_package(VMTEST, 'libvirt-bin')
|
||||
pip_mgr.check_package(VMTEST, 'asyncssh')
|
||||
sys_mgr.check_package(VMTEST, 'sshpass')
|
||||
sys_mgr.check_package(VMTEST, 'openssh-client')
|
||||
pip_mgr.check_package(VMTEST, 'aiohttp')
|
||||
AptCacherNGBuilder(ctx).check(VMTEST, version='3.2')
|
||||
|
||||
# pylint: enable=line-too-long
|
||||
|
||||
|
@ -303,6 +330,14 @@ def check_virtual_env(ctx):
|
|||
except Exception as exc: # pylint: disable=broad-except
|
||||
shutil.rmtree(venvdir)
|
||||
ctx.fatal("Failed to create virtual env: %s" % exc)
|
||||
|
||||
# Always update PIP to something more recent than what ensurepip has installed. We need at
|
||||
# least 9.0 for 'pip list --format=json' to work.
|
||||
ctx.cmd_and_log(
|
||||
[os.path.join(venvdir, 'bin', 'pip'),
|
||||
'--disable-pip-version-check', 'install', '-U', 'pip>=9.0'],
|
||||
output=BOTH)
|
||||
|
||||
ctx.to_log(" ok.")
|
||||
|
||||
old_venvdir = None
|
||||
|
@ -317,6 +352,7 @@ def check_virtual_env(ctx):
|
|||
ctx.to_log(" ok.")
|
||||
|
||||
ctx.env.VIRTUAL_ENV = venvdir
|
||||
ctx.env.PYTHON = [os.path.join(venvdir, 'bin', 'python')]
|
||||
ctx.environ['PATH'] = os.pathsep.join(
|
||||
[os.path.join(venvdir, 'bin')] + ctx.environ.get('PATH', '').split(os.pathsep))
|
||||
|
||||
|
@ -431,7 +467,7 @@ class PipManager(PackageManager):
|
|||
p = subprocess.run(
|
||||
self.__pip_cmd + ['list', '--format=json'],
|
||||
stdout=subprocess.PIPE, check=True)
|
||||
self._packages = {p['name']: p['version'] for p in json.loads(p.stdout)}
|
||||
self._packages = {p['name']: p['version'] for p in json.loads(p.stdout.decode('utf-8'))}
|
||||
|
||||
def get_pip_spec(self, name, version=None, source=None):
|
||||
if source:
|
||||
|
@ -491,7 +527,7 @@ class DebManager(PackageManager):
|
|||
cmd += ['--askpass']
|
||||
else:
|
||||
cmd += ['--non-interactive']
|
||||
cmd += ['--', '/usr/bin/apt-get', 'install', name]
|
||||
cmd += ['--', '/usr/bin/apt-get', '-q', '-y', 'install', name]
|
||||
|
||||
self._ctx.cmd_and_log(cmd, output=BOTH, env=env)
|
||||
|
||||
|
@ -669,7 +705,7 @@ class CSoundBuilder(ThirdPartyBuilder):
|
|||
],
|
||||
cwd=make_path)
|
||||
self._ctx.cmd_and_log(
|
||||
['make', '-j8'],
|
||||
['make', '-j%d' % len(os.sched_getaffinity(0))],
|
||||
cwd=make_path)
|
||||
|
||||
def install(self, src_path):
|
||||
|
@ -689,7 +725,7 @@ class FaustBuilder(ThirdPartyBuilder):
|
|||
def build(self, src_path):
|
||||
self._ctx.cmd_and_log(
|
||||
['make',
|
||||
'-j8',
|
||||
'-j%d' % len(os.sched_getaffinity(0)),
|
||||
'PREFIX=' + self._ctx.env.VIRTUAL_ENV,
|
||||
'compiler'],
|
||||
cwd=src_path)
|
||||
|
@ -831,10 +867,31 @@ class ProtocBuilder(ThirdPartyBuilder):
|
|||
],
|
||||
cwd=src_path)
|
||||
self._ctx.cmd_and_log(
|
||||
['make', '-j8'],
|
||||
['make', '-j%d' % len(os.sched_getaffinity(0))],
|
||||
cwd=src_path)
|
||||
|
||||
def install(self, src_path):
|
||||
self._ctx.cmd_and_log(
|
||||
['make', 'install'],
|
||||
cwd=src_path)
|
||||
|
||||
|
||||
class AptCacherNGBuilder(ThirdPartyBuilder):
|
||||
def __init__(self, ctx):
|
||||
super().__init__(ctx, 'apt-cacher-ng', '.tar.xz')
|
||||
|
||||
def download_url(self, version):
|
||||
# pylint: disable=line-too-long
|
||||
return 'http://ftp.debian.org/debian/pool/main/a/apt-cacher-ng/apt-cacher-ng_%s.orig.tar.xz' % version
|
||||
|
||||
def build(self, src_path):
|
||||
self._ctx.cmd_and_log(
|
||||
['./build.sh',
|
||||
'-DCMAKE_INSTALL_PREFIX=%s' % self._ctx.env.VIRTUAL_ENV,
|
||||
],
|
||||
cwd=src_path)
|
||||
|
||||
def install(self, src_path):
|
||||
self._ctx.cmd_and_log(
|
||||
['make', '-C', 'builddir', 'install'],
|
||||
cwd=src_path)
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg width="64" version="1.1" xmlns="http://www.w3.org/2000/svg" height="64" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape">
|
||||
<defs id="defs3811">
|
||||
<linearGradient inkscape:collect="always" xlink:href="#linearGradient4143-6" id="linearGradient4416" y1="43.999989" y2="6.999989" x2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-1.4054053 0 0 1.4054053 804.69502 154.09579)"/>
|
||||
<linearGradient inkscape:collect="always" id="linearGradient4144" xlink:href="#linearGradient4155" y1="29.999973" y2="2" gradientUnits="userSpaceOnUse" x2="0" gradientTransform="matrix(2 0 0 -2 0 53)"/>
|
||||
<linearGradient inkscape:collect="always" id="linearGradient4155">
|
||||
<stop style="stop-color:#fcd994" id="stop4157"/>
|
||||
<stop offset="1" style="stop-color:#fff6e1" id="stop4159"/>
|
||||
</linearGradient>
|
||||
<linearGradient inkscape:collect="always" id="linearGradient4143-6">
|
||||
<stop style="stop-color:#faae2a" id="stop4145-8"/>
|
||||
<stop offset="1" style="stop-color:#ffc35a" id="stop4147-0"/>
|
||||
</linearGradient>
|
||||
<linearGradient inkscape:collect="always" xlink:href="#linearGradient4227" id="linearGradient4191" y1="12.999999" x1="17" y2="41" x2="45" gradientUnits="userSpaceOnUse"/>
|
||||
<linearGradient inkscape:collect="always" id="linearGradient4227">
|
||||
<stop style="stop-color:#292c2f" id="stop4229"/>
|
||||
<stop offset="1" style="stop-opacity:0" id="stop4231"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<metadata id="metadata3814"/>
|
||||
<g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="matrix(1 0 0 1 -736.85718 -157.93361)">
|
||||
<path inkscape:connector-curvature="0" style="fill:url(#linearGradient4416);fill-rule:evenodd" id="path4445" d="m 794.85718,163.93361 0,37.94594 -25.29727,0 -14.05412,14.05406 0,-14.05406 -12.64861,0 0,-37.94594 z"/>
|
||||
<path style="fill:#e59305;fill-rule:evenodd" id="path4256" d="M 6 42.945312 L 6 43.945312 L 18.648438 43.945312 L 18.648438 42.945312 L 6 42.945312 z M 32.703125 42.945312 L 18.648438 57 L 18.648438 58 L 32.703125 43.945312 L 58 43.945312 L 58 42.945312 L 32.703125 42.945312 z " transform="matrix(1 0 0 1 736.85718 157.93361)"/>
|
||||
<path style="fill:url(#linearGradient4191);opacity:0.2;fill-rule:evenodd" id="path4186" d="M 32 13 L 32 15 L 44 35.785156 L 44.701172 37 L 19 37 L 29.324219 47.324219 L 32.703125 43.945312 L 58 43.945312 L 58 39 L 32 13 z " transform="matrix(1 0 0 1 736.85718 157.93361)"/>
|
||||
<path inkscape:connector-curvature="0" style="fill:url(#linearGradient4144)" id="rect4133" d="M 32,13 18.853516,37 19.992188,37 20,36.986328 20,37 l 24,0 0,-0.01367 0.0078,0.01367 1.138672,0 z M 32,15.076172 43.460938,36 20.539062,36 Z M 31,20 l 0,10 2,0 0,-10 z m 0,12 0,2 2,0 0,-2 z" transform="matrix(1 0 0 1 736.85718 157.93361)"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.8 KiB |
|
@ -0,0 +1,13 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<defs id="defs3051">
|
||||
<style type="text/css" id="current-color-scheme">
|
||||
.ColorScheme-Text {
|
||||
color:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path style="fill:currentColor;fill-opacity:1;stroke:none"
|
||||
d="m6 4v24h20v-17l-7-7h-1zm1 1h11v7h7v15h-18z"
|
||||
class="ColorScheme-Text"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 380 B |
|
@ -0,0 +1,13 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<defs id="defs3051">
|
||||
<style type="text/css" id="current-color-scheme">
|
||||
.ColorScheme-Text {
|
||||
color:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path style="fill:currentColor;fill-opacity:1;stroke:none"
|
||||
d="m4 4v24h24l-1-1h-22v-13h5l3-3h14v16l1 1v-21h-10l-3-3z"
|
||||
class="ColorScheme-Text"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 391 B |
|
@ -0,0 +1,18 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<defs
|
||||
id="defs3051">
|
||||
<style
|
||||
type="text/css"
|
||||
id="current-color-scheme">
|
||||
.ColorScheme-Text {
|
||||
color:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path
|
||||
style="fill:currentColor;fill-opacity:1;stroke:none"
|
||||
d="M 4 4 L 4 28 L 9 28 L 23 28 L 28 28 L 28 10 L 27 9 L 23 5 L 22 4 L 21 4 L 10 4 L 4 4 z M 5 5 L 10 5 L 10 13 L 21 13 L 21 5 L 21.585938 5 L 27 10.414062 L 27 27 L 23 27 L 23 19 L 9 19 L 9 27 L 5 27 L 5 5 z M 11 5 L 17 5 L 17 12 L 11 12 L 11 5 z M 10 20 L 22 20 L 22 27 L 10 27 L 10 20 z "
|
||||
id="path60"
|
||||
class="ColorScheme-Text"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 665 B |
|
@ -0,0 +1,15 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<defs id="defs3051">
|
||||
<style type="text/css" id="current-color-scheme">
|
||||
.ColorScheme-Text {
|
||||
color:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path
|
||||
style="fill:currentColor;fill-opacity:1;stroke:none"
|
||||
d="M 8 3 L 0.94335938 10.056641 L 0 11 L 0.94335938 11.943359 L 8 19 L 20.333984 19 L 22 19 L 22 3 L 20.333984 3 L 8 3 z M 11.320312 7 L 14 9.6796875 L 16.679688 7 L 18 8.3203125 L 15.320312 11 L 18 13.679688 L 16.679688 15 L 14 12.320312 L 11.320312 15 L 10 13.679688 L 12.679688 11 L 10 8.3203125 L 11.320312 7 z "
|
||||
class="ColorScheme-Text"
|
||||
transform="translate(1,1)"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 696 B |
|
@ -0,0 +1,7 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<g fill="#da4453" transform="translate(-384.57-515.8)">
|
||||
<path d="m392.57 525.8v18h16v-18h-1v17h-14v-17z"/>
|
||||
<path d="m388.57 523.8h24v1h-24z"/>
|
||||
<path d="m396.57 519.8v3h1v-2h6v2h1v-3z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 267 B |
|
@ -0,0 +1,15 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<defs id="defs3051">
|
||||
<style type="text/css" id="current-color-scheme">
|
||||
.ColorScheme-Text {
|
||||
color:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path
|
||||
style="fill:currentColor;fill-opacity:1;stroke:none"
|
||||
d="M 9 3 C 5.6759952 3 3 5.6759952 3 9 C 3 12.324005 5.6759952 15 9 15 C 10.481205 15 11.830584 14.465318 12.875 13.582031 L 18.292969 19 L 19 18.292969 L 13.582031 12.875 C 14.465318 11.830584 15 10.481205 15 9 C 15 5.6759952 12.324005 3 9 3 z M 9 4 C 11.770005 4 14 6.2299952 14 9 C 14 11.770005 11.770005 14 9 14 C 6.2299952 14 4 11.770005 4 9 C 4 6.2299952 6.2299952 4 9 4 z "
|
||||
class="ColorScheme-Text"
|
||||
transform="translate(1,1)"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 748 B |
|
@ -0,0 +1,13 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<defs id="defs3051">
|
||||
<style type="text/css" id="current-color-scheme">
|
||||
.ColorScheme-Text {
|
||||
color:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path style="fill:currentColor;fill-opacity:1;stroke:none"
|
||||
d="M 4 4 L 4 5 L 4 8 L 5 8 L 5 5 L 8 5 L 8 4 L 5 4 L 4 4 z M 16 4 L 16 5 L 19 5 L 19 8 L 20 8 L 20 4 L 16 4 z M 6 6 L 6 11 L 11 11 L 11 6 L 6 6 z M 13 6 L 13 11 L 18 11 L 18 6 L 13 6 z M 7 7 L 10 7 L 10 10 L 7 10 L 7 7 z M 14 7 L 17 7 L 17 10 L 14 10 L 14 7 z M 6 13 L 6 18 L 11 18 L 11 13 L 6 13 z M 13 13 L 13 18 L 18 18 L 18 13 L 13 13 z M 7 14 L 10 14 L 10 17 L 7 17 L 7 14 z M 14 14 L 17 14 L 17 17 L 14 17 L 14 14 z M 4 16 L 4 20 L 5 20 L 8 20 L 8 19 L 5 19 L 5 16 L 4 16 z M 19 16 L 19 19 L 16 19 L 16 20 L 20 20 L 20 19 L 20 16 L 19 16 z "
|
||||
class="ColorScheme-Text"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 879 B |
|
@ -0,0 +1,17 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<defs
|
||||
id="defs3051">
|
||||
<style
|
||||
type="text/css"
|
||||
id="current-color-scheme">
|
||||
.ColorScheme-Text {
|
||||
color:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path
|
||||
style="fill:currentColor;fill-opacity:1;stroke:none"
|
||||
d="m 8.990234,5 c -0.5522847,0 -1,0.4477153 -1,1 0,0.5522847 0.4477153,1 1,1 0.5522847,0 1,-0.4477153 1,-1 0,-0.5522847 -0.4477153,-1 -1,-1 z m 2,4 L 11,29 16.841796,21.769531 26,21 Z"
|
||||
class="ColorScheme-Text"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 541 B |
|
@ -0,0 +1,17 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<defs
|
||||
id="defs3051">
|
||||
<style
|
||||
type="text/css"
|
||||
id="current-color-scheme">
|
||||
.ColorScheme-Text {
|
||||
color:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path
|
||||
style="fill:currentColor;fill-opacity:1;stroke:none"
|
||||
d="M 10.667968,4.0000022 C 10.653968,3.9980022 10,4.7070334 10,4.7070334 L 20.666016,16.000002 10,27.292971 10.667968,28.000002 22,16.000002 Z"
|
||||
class="ColorScheme-Text"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 500 B |
|
@ -0,0 +1,17 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<defs
|
||||
id="defs3051">
|
||||
<style
|
||||
type="text/css"
|
||||
id="current-color-scheme">
|
||||
.ColorScheme-Text {
|
||||
color:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path
|
||||
style="fill:currentColor;fill-opacity:1;stroke:none"
|
||||
d="M 21.332032,4.0000022 C 21.346032,3.9980022 22,4.7070334 22,4.7070334 L 11.333984,16.000002 22,27.292971 21.332032,28.000002 10,16.000002 Z"
|
||||
class="ColorScheme-Text"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 500 B |
|
@ -0,0 +1,3 @@
|
|||
Source: https://github.com/KDE/breeze-icons
|
||||
Author: KDE Community <visual-design@kde.org>
|
||||
Licence: https://opensource.org/licenses/LGPL-3.0
|
|
@ -0,0 +1 @@
|
|||
These icons just serve as placeholders, until I create my own.
|
|
@ -0,0 +1,13 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<defs id="defs3051">
|
||||
<style type="text/css" id="current-color-scheme">
|
||||
.ColorScheme-Text {
|
||||
color:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path style="fill:currentColor;fill-opacity:1;stroke:none"
|
||||
d="M 11 5 L 11 12 L 4 12 L 4 13 L 11 13 L 11 20 L 12 20 L 12 13 L 19 13 L 19 12 L 12 12 L 12 5 L 11 5 z "
|
||||
class="ColorScheme-Text"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 437 B |
|
@ -0,0 +1,10 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<defs id="defs3051">
|
||||
<style type="text/css" id="current-color-scheme">
|
||||
.ColorScheme-Text {
|
||||
color:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path style="fill:currentColor" class="ColorScheme-Text" d="M 3 7 L 3 9 L 13 9 L 13 7 L 3 7 z" transform="translate(4 4)"/>
|
||||
</svg>
|
After Width: | Height: | Size: 352 B |
|
@ -0,0 +1,18 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<defs
|
||||
id="defs3051">
|
||||
<style
|
||||
type="text/css"
|
||||
id="current-color-scheme">
|
||||
.ColorScheme-Text {
|
||||
color:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path
|
||||
style="fill:currentColor;fill-opacity:1;stroke:none"
|
||||
d="M 16.001953 3.9980469 A 12 12 0 0 0 4.0019531 15.998047 A 12 12 0 0 0 16.001953 27.998047 A 12 12 0 0 0 28.001953 15.998047 A 12 12 0 0 0 16.001953 3.9980469 z M 16.001953 4.9980469 A 11 11 0 0 1 27.001953 15.998047 A 11 11 0 0 1 16.001953 26.998047 A 11 11 0 0 1 5.0019531 15.998047 A 11 11 0 0 1 16.001953 4.9980469 z M 12 12 L 12 20 L 14 20 L 14 12 L 12 12 z M 18 12 L 18 20 L 20 20 L 20 12 L 18 12 z "
|
||||
id="path8"
|
||||
class="ColorScheme-Text"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 782 B |
|
@ -0,0 +1,18 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<defs
|
||||
id="defs3051">
|
||||
<style
|
||||
type="text/css"
|
||||
id="current-color-scheme">
|
||||
.ColorScheme-Text {
|
||||
color:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path
|
||||
style="fill:currentColor;fill-opacity:1;stroke:none"
|
||||
d="M 16.001953 3.9980469 A 12 12 0 0 0 4.0019531 15.998047 A 12 12 0 0 0 16.001953 27.998047 A 12 12 0 0 0 28.001953 15.998047 A 12 12 0 0 0 16.001953 3.9980469 z M 16.001953 4.9980469 A 11 11 0 0 1 27.001953 15.998047 A 11 11 0 0 1 16.001953 26.998047 A 11 11 0 0 1 5.0019531 15.998047 A 11 11 0 0 1 16.001953 4.9980469 z M 13 12 L 13 20 L 20 16 L 13 12 z "
|
||||
id="path105"
|
||||
class="ColorScheme-Text"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 735 B |
|
@ -0,0 +1,17 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<defs
|
||||
id="defs3051">
|
||||
<style
|
||||
type="text/css"
|
||||
id="current-color-scheme">
|
||||
.ColorScheme-Text {
|
||||
color:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path
|
||||
style="fill:currentColor;fill-opacity:1;stroke:none"
|
||||
d="M 16.001953 3.9980469 A 12 12 0 0 0 4.0019531 15.998047 A 12 12 0 0 0 16.001953 27.998047 A 12 12 0 0 0 28.001953 15.998047 A 12 12 0 0 0 16.001953 3.9980469 z M 16.001953 4.9980469 A 11 11 0 0 1 27.001953 15.998047 A 11 11 0 0 1 16.001953 26.998047 A 11 11 0 0 1 5.0019531 15.998047 A 11 11 0 0 1 16.001953 4.9980469 z M 10 12 L 10 20 L 11 20 L 11 13 L 21 13 L 21 19 L 18 19 L 18 17.5 L 14 19.5 L 18 21.5 L 18 20 L 22 20 L 22 12 L 11 12 L 10 12 z "
|
||||
id="path75"
|
||||
class="ColorScheme-Text"/>
|
||||
</svg>
|
After Width: | Height: | Size: 821 B |
|
@ -0,0 +1,22 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<defs
|
||||
id="defs3051">
|
||||
<style
|
||||
type="text/css"
|
||||
id="current-color-scheme">
|
||||
.ColorScheme-Text {
|
||||
color:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path
|
||||
style="fill:currentColor;fill-opacity:1;stroke:none"
|
||||
id="path42"
|
||||
d="m 16.00143,3.998 a 12,12 0 0 0 -12,12 12,12 0 0 0 12,12 12,12 0 0 0 12,-12 12,12 0 0 0 -12,-12 m 0,1 a 11,11 0 0 1 11,11 11,11 0 0 1 -11,11 11,11 0 0 1 -11,-11 11,11 0 0 1 11,-11"
|
||||
class="ColorScheme-Text"
|
||||
/>
|
||||
<path
|
||||
style="fill:#da4453"
|
||||
d="m 20.000008,15.999988 a 4,4 0 0 1 -4,4 4,4 0 0 1 -4,-4 4,4 0 0 1 4,-4 4,4 0 0 1 4,4 z"
|
||||
id="circle44" />
|
||||
</svg>
|
After Width: | Height: | Size: 707 B |
|
@ -0,0 +1,18 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<defs
|
||||
id="defs3051">
|
||||
<style
|
||||
type="text/css"
|
||||
id="current-color-scheme">
|
||||
.ColorScheme-Text {
|
||||
color:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path
|
||||
style="fill:currentColor;fill-opacity:1;stroke:none"
|
||||
d="m 16.001953,3.998047 a 12,12 0 0 1 12,12 12,12 0 0 1 -12,12 12,12 0 0 1 -11.9999999,-12 12,12 0 0 1 11.9999999,-12 z m 0,1 a 11,11 0 0 0 -10.9999999,11 11,11 0 0 0 10.9999999,11 11,11 0 0 0 11,-11 11,11 0 0 0 -11,-11 z M 22.003906,12 l 0,8 -7,-4 7,-4 z m -7,4 0,4 -6.9999999,-4 6.9999999,-4 0,4 z"
|
||||
id="path8"
|
||||
class="ColorScheme-Text"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 675 B |
|
@ -0,0 +1,18 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<defs
|
||||
id="defs3051">
|
||||
<style
|
||||
type="text/css"
|
||||
id="current-color-scheme">
|
||||
.ColorScheme-Text {
|
||||
color:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path
|
||||
style="fill:currentColor;fill-opacity:1;stroke:none"
|
||||
d="M 16.001953 3.9980469 A 12 12 0 0 0 4.0019531 15.998047 A 12 12 0 0 0 16.001953 27.998047 A 12 12 0 0 0 28.001953 15.998047 A 12 12 0 0 0 16.001953 3.9980469 z M 16.001953 4.9980469 A 11 11 0 0 1 27.001953 15.998047 A 11 11 0 0 1 16.001953 26.998047 A 11 11 0 0 1 5.0019531 15.998047 A 11 11 0 0 1 16.001953 4.9980469 z M 10 12 L 10 20 L 17 16 L 10 12 z M 17 16 L 17 20 L 24 16 L 17 12 L 17 16 z "
|
||||
id="path8"
|
||||
class="ColorScheme-Text"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 774 B |
|
@ -0,0 +1,18 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<defs
|
||||
id="defs3051">
|
||||
<style
|
||||
type="text/css"
|
||||
id="current-color-scheme">
|
||||
.ColorScheme-Text {
|
||||
color:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path
|
||||
style="fill:currentColor;fill-opacity:1;stroke:none"
|
||||
d="M 16.001953 3.9980469 A 12 12 0 0 0 4.0019531 15.998047 A 12 12 0 0 0 16.001953 27.998047 A 12 12 0 0 0 28.001953 15.998047 A 12 12 0 0 0 16.001953 3.9980469 z M 16.001953 4.9980469 A 11 11 0 0 1 27.001953 15.998047 A 11 11 0 0 1 16.001953 26.998047 A 11 11 0 0 1 5.0019531 15.998047 A 11 11 0 0 1 16.001953 4.9980469 z M 11 12 L 11 20 L 13 20 L 13 12 L 11 12 z M 21 12 L 14 16 L 21 20 L 21 12 z "
|
||||
id="path92"
|
||||
class="ColorScheme-Text"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 775 B |
|
@ -0,0 +1,18 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<defs
|
||||
id="defs3051">
|
||||
<style
|
||||
type="text/css"
|
||||
id="current-color-scheme">
|
||||
.ColorScheme-Text {
|
||||
color:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path
|
||||
style="fill:currentColor;fill-opacity:1;stroke:none"
|
||||
d="M 16.001953 3.9980469 A 12 12 0 0 0 4.0019531 15.998047 A 12 12 0 0 0 16.001953 27.998047 A 12 12 0 0 0 28.001953 15.998047 A 12 12 0 0 0 16.001953 3.9980469 z M 16.001953 4.9980469 A 11 11 0 0 1 27.001953 15.998047 A 11 11 0 0 1 16.001953 26.998047 A 11 11 0 0 1 5.0019531 15.998047 A 11 11 0 0 1 16.001953 4.9980469 z M 11 12 L 11 20 L 18 16 L 11 12 z M 19 12 L 19 20 L 21 20 L 21 12 L 19 12 z "
|
||||
id="path76"
|
||||
class="ColorScheme-Text"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 775 B |
|
@ -0,0 +1,6 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<g transform="translate(-384.57-515.8)">
|
||||
<circle fill="#fff" cx="400.57" cy="531.8" r="11"/>
|
||||
<path fill="#da4453" d="M16 4A12 12 0 0 0 4 16 12 12 0 0 0 16 28 12 12 0 0 0 28 16 12 12 0 0 0 16 4M10.707 10L16 15.293 21.293 10C21.293 10 22.02 10.716 22 10.707L16.707 16 22 21.293C22 21.293 21.299 21.999 21.293 22L16 16.707 10.707 22C10.708 21.995 10 21.293 10 21.293L15.293 16 10 10.707C10.02 10.708 10.707 10 10.707 10" transform="translate(384.57 515.8)"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 535 B |
|
@ -0,0 +1,13 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<defs id="defs3051">
|
||||
<style type="text/css" id="current-color-scheme">
|
||||
.ColorScheme-Text {
|
||||
color:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path style="fill:currentColor;fill-opacity:1;stroke:none"
|
||||
d="M 4 4 L 4 9 L 5 9 L 5 5 L 9 5 L 9 4 L 4 4 z M 11 4 L 11 5 L 15 5 L 15 4 L 11 4 z M 17 4 L 17 5 L 21 5 L 21 4 L 17 4 z M 23 4 L 23 5 L 27 5 L 27 9 L 28 9 L 28 5 L 28 4 L 27 4 L 23 4 z M 14.929688 10 L 14.929688 11 L 20.292969 11 L 12.453125 18.837891 L 13.162109 19.546875 L 21 11.707031 L 21 17.070312 L 22 17.070312 L 22 11.414062 L 22 10 L 14.929688 10 z M 4 11 L 4 15 L 5 15 L 5 11 L 4 11 z M 27 11 L 27 15 L 28 15 L 28 11 L 27 11 z M 4 17 L 4 20 L 5 20 L 5 17 L 4 17 z M 27 17 L 27 21 L 28 21 L 28 17 L 27 17 z M 4 21 L 4 23 L 4 28 L 9 28 L 11 28 L 11 21 L 4 21 z M 5 22 L 10 22 L 10 27 L 9 27 L 5 27 L 5 23 L 5 22 z M 27 23 L 27 27 L 23 27 L 23 28 L 28 28 L 28 23 L 27 23 z M 12 27 L 12 28 L 15 28 L 15 27 L 12 27 z M 17 27 L 17 28 L 21 28 L 21 27 L 17 27 z "
|
||||
class="ColorScheme-Text"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
|
@ -0,0 +1,14 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<defs id="defs3051">
|
||||
<style type="text/css" id="current-color-scheme">
|
||||
.ColorScheme-Text {
|
||||
color:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path
|
||||
style="fill:currentColor;fill-opacity:1;stroke:none"
|
||||
d="M 4 4 L 4 8 L 5 8 L 5 5 L 8 5 L 8 4 L 4 4 z M 24 4 L 24 5 L 27 5 L 27 8 L 28 8 L 28 4 L 24 4 z M 6 6 L 6 26 L 26 26 L 26 6 L 6 6 z M 7 7 L 25 7 L 25 25 L 7 25 L 7 7 z M 4 24 L 4 28 L 8 28 L 8 27 L 5 27 L 5 24 L 4 24 z M 27 24 L 27 27 L 24 27 L 24 28 L 28 28 L 28 24 L 27 24 z "
|
||||
class="ColorScheme-Text"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 610 B |
|
@ -0,0 +1,13 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<defs id="defs3051">
|
||||
<style type="text/css" id="current-color-scheme">
|
||||
.ColorScheme-Text {
|
||||
color:#4d4d4d;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path style="fill:currentColor;fill-opacity:1;stroke:none"
|
||||
d="M 4 4 L 4 5 L 4 16 L 5 16 L 5 5 L 27 5 L 27 27 L 16 27 L 16 28 L 27 28 L 28 28 L 28 5 L 28 4 L 4 4 z M 23.837891 7.453125 L 16 15.292969 L 16 9.9296875 L 15 9.9296875 L 15 15.585938 L 15 17 L 22.070312 17 L 22.070312 16 L 16.707031 16 L 24.546875 8.1621094 L 23.837891 7.453125 z M 4 18 L 4 22 L 5 22 L 5 19 L 8 19 L 8 18 L 5 18 L 4 18 z M 10 18 L 10 19 L 13 19 L 13 22 L 14 22 L 14 19 L 14 18 L 13 18 L 10 18 z M 4 24 L 4 27 L 4 28 L 8 28 L 8 27 L 5 27 L 5 24 L 4 24 z M 13 24 L 13 27 L 10 27 L 10 28 L 14 28 L 14 24 L 13 24 z "
|
||||
class="ColorScheme-Text"
|
||||
/>
|
||||
</svg>
|
After Width: | Height: | Size: 866 B |
|
@ -20,6 +20,9 @@
|
|||
#
|
||||
# @end:license
|
||||
|
||||
import os.path
|
||||
|
||||
|
||||
def build(ctx):
|
||||
ctx.static_file('accidental-double-flat.svg')
|
||||
ctx.static_file('accidental-double-sharp.svg')
|
||||
|
@ -61,3 +64,6 @@ def build(ctx):
|
|||
ctx.static_file('track-type-score.svg')
|
||||
ctx.static_file('track-visible.svg')
|
||||
ctx.static_file('warning.svg')
|
||||
|
||||
for f in ctx.path.ant_glob('placeholders/*.svg'):
|
||||
ctx.static_file(f, os.path.basename(f.abspath()))
|
||||
|
|
|
@ -26,10 +26,8 @@ import "noisicaa/core/session_data.proto";
|
|||
import "noisicaa/node_db/node_description.proto";
|
||||
import "noisicaa/audioproc/public/backend_settings.proto";
|
||||
import "noisicaa/audioproc/public/control_value.proto";
|
||||
import "noisicaa/audioproc/public/host_parameters.proto";
|
||||
import "noisicaa/audioproc/public/node_parameters.proto";
|
||||
import "noisicaa/audioproc/public/node_port_properties.proto";
|
||||
import "noisicaa/audioproc/public/player_state.proto";
|
||||
import "noisicaa/audioproc/public/plugin_state.proto";
|
||||
import "noisicaa/audioproc/public/processor_message.proto";
|
||||
import "noisicaa/audioproc/public/project_properties.proto";
|
||||
|
|
|
@ -39,9 +39,7 @@ Backend::Backend(
|
|||
notifications.connect(std::bind(&Backend::notification_proxy, this, placeholders::_1));
|
||||
}
|
||||
|
||||
Backend::~Backend() {
|
||||
cleanup();
|
||||
}
|
||||
Backend::~Backend() {}
|
||||
|
||||
StatusOr<Backend*> Backend::create(
|
||||
HostSystem* host_system, const string& name, const string& serialized_settings,
|
||||
|
|
|
@ -63,8 +63,11 @@ Status NullBackend::end_block(BlockContext* ctxt) {
|
|||
int64_t elapsed = std::chrono::duration_cast<std::chrono::microseconds>(
|
||||
std::chrono::high_resolution_clock::now() - _block_start).count();
|
||||
int64_t delay = block_duration - elapsed;
|
||||
if (_settings.has_time_scale()) {
|
||||
delay = _settings.time_scale() * delay;
|
||||
}
|
||||
if (delay > 0) {
|
||||
usleep((useconds_t)(_settings.time_scale() * delay));
|
||||
usleep((useconds_t)delay);
|
||||
}
|
||||
|
||||
return Status::Ok();
|
||||
|
|
|
@ -45,7 +45,9 @@ PortAudioBackend::PortAudioBackend(
|
|||
_events(nullptr) {
|
||||
}
|
||||
|
||||
PortAudioBackend::~PortAudioBackend() {}
|
||||
PortAudioBackend::~PortAudioBackend() {
|
||||
_cleanup();
|
||||
}
|
||||
|
||||
Status PortAudioBackend::setup(Realm* realm) {
|
||||
RETURN_IF_ERROR(Backend::setup(realm));
|
||||
|
@ -113,6 +115,11 @@ Status PortAudioBackend::setup(Realm* realm) {
|
|||
}
|
||||
|
||||
void PortAudioBackend::cleanup() {
|
||||
_cleanup();
|
||||
Backend::cleanup();
|
||||
}
|
||||
|
||||
void PortAudioBackend::_cleanup() {
|
||||
if (_events != nullptr) {
|
||||
delete _events;
|
||||
_events = nullptr;
|
||||
|
@ -138,8 +145,6 @@ void PortAudioBackend::cleanup() {
|
|||
}
|
||||
_initialized = false;
|
||||
}
|
||||
|
||||
Backend::cleanup();
|
||||
}
|
||||
|
||||
Status PortAudioBackend::setup_stream() {
|
||||
|
|
|
@ -54,6 +54,7 @@ public:
|
|||
Status output(BlockContext* ctxt, Channel channel, BufferPtr samples) override;
|
||||
|
||||
private:
|
||||
void _cleanup();
|
||||
Status setup_stream();
|
||||
void cleanup_stream();
|
||||
|
||||
|
|
|
@ -42,7 +42,9 @@ RendererBackend::RendererBackend(
|
|||
: Backend(
|
||||
host_system, "noisicaa.audioproc.engine.backend.renderer", settings, callback, userdata) {}
|
||||
|
||||
RendererBackend::~RendererBackend() {}
|
||||
RendererBackend::~RendererBackend() {
|
||||
_cleanup();
|
||||
}
|
||||
|
||||
Status RendererBackend::setup(Realm* realm) {
|
||||
Status status = Backend::setup(realm);
|
||||
|
@ -69,12 +71,15 @@ Status RendererBackend::setup(Realm* realm) {
|
|||
}
|
||||
|
||||
void RendererBackend::cleanup() {
|
||||
_cleanup();
|
||||
Backend::cleanup();
|
||||
}
|
||||
|
||||
void RendererBackend::_cleanup() {
|
||||
if (_datastream >= 0) {
|
||||
close(_datastream);
|
||||
_datastream = -1;
|
||||
}
|
||||
|
||||
Backend::cleanup();
|
||||
}
|
||||
|
||||
Status RendererBackend::begin_block(BlockContext* ctxt) {
|
||||
|
|
|
@ -50,6 +50,8 @@ public:
|
|||
Status output(BlockContext* ctxt, Channel channel, BufferPtr buffer) override;
|
||||
|
||||
private:
|
||||
void _cleanup();
|
||||
|
||||
unique_ptr<BufferData> _samples[2];
|
||||
bool _channel_written[2];
|
||||
|
||||
|
|
|
@ -217,7 +217,8 @@ Status CSoundUtil::process_block(
|
|||
buf += pos;
|
||||
|
||||
MYFLT* channel_ptr = _channel_ptr[port_idx];
|
||||
int *lock = _channel_lock[port_idx];
|
||||
int* lock = _channel_lock[port_idx];
|
||||
(void)lock; // TODO: remove after upgrade to csound >=6.11
|
||||
csoundSpinLock(lock);
|
||||
for (uint32_t i = 0 ; i < ksmps ; ++i) {
|
||||
*channel_ptr++ = *buf++;
|
||||
|
@ -230,7 +231,8 @@ Status CSoundUtil::process_block(
|
|||
float* buf = (float*)buffers[port_idx]->data();
|
||||
|
||||
MYFLT* channel_ptr = _channel_ptr[port_idx];
|
||||
int *lock = _channel_lock[port_idx];
|
||||
int* lock = _channel_lock[port_idx];
|
||||
(void)lock; // TODO: remove after upgrade to csound >=6.11
|
||||
csoundSpinLock(lock);
|
||||
*channel_ptr = *buf;
|
||||
csoundSpinUnLock(lock);
|
||||
|
@ -294,7 +296,8 @@ Status CSoundUtil::process_block(
|
|||
case pb::PortDescription::AUDIO:
|
||||
case pb::PortDescription::ARATE_CONTROL: {
|
||||
MYFLT* channel_ptr = _channel_ptr[port_idx];
|
||||
int *lock = _channel_lock[port_idx];
|
||||
int* lock = _channel_lock[port_idx];
|
||||
(void)lock; // TODO: remove after upgrade to csound >=6.11
|
||||
csoundSpinLock(lock);
|
||||
for (uint32_t i = 0 ; i < ksmps ; ++i) {
|
||||
*channel_ptr++ = 0.0;
|
||||
|
@ -305,7 +308,8 @@ Status CSoundUtil::process_block(
|
|||
|
||||
case pb::PortDescription::KRATE_CONTROL: {
|
||||
MYFLT* channel_ptr = _channel_ptr[port_idx];
|
||||
int *lock = _channel_lock[port_idx];
|
||||
int* lock = _channel_lock[port_idx];
|
||||
(void)lock; // TODO: remove after upgrade to csound >=6.11
|
||||
csoundSpinLock(lock);
|
||||
*channel_ptr = 0.0;
|
||||
csoundSpinUnLock(lock);
|
||||
|
@ -338,7 +342,8 @@ Status CSoundUtil::process_block(
|
|||
buf += pos;
|
||||
|
||||
MYFLT* channel_ptr = _channel_ptr[port_idx];
|
||||
int *lock = _channel_lock[port_idx];
|
||||
int* lock = _channel_lock[port_idx];
|
||||
(void)lock; // TODO: remove after upgrade to csound >=6.11
|
||||
csoundSpinLock(lock);
|
||||
for (uint32_t i = 0 ; i < ksmps ; ++i) {
|
||||
*buf++ = *channel_ptr++;
|
||||
|
@ -351,7 +356,8 @@ Status CSoundUtil::process_block(
|
|||
float* buf = (float*)buffers[port_idx]->data();
|
||||
|
||||
MYFLT* channel_ptr = _channel_ptr[port_idx];
|
||||
int *lock = _channel_lock[port_idx];
|
||||
int* lock = _channel_lock[port_idx];
|
||||
(void)lock; // TODO: remove after upgrade to csound >=6.11
|
||||
csoundSpinLock(lock);
|
||||
*buf = *channel_ptr;
|
||||
csoundSpinUnLock(lock);
|
||||
|
|
|
@ -244,7 +244,7 @@ cdef class PyEngine(object):
|
|||
async def create_realm(
|
||||
self, *,
|
||||
name: str, parent: str, enable_player: bool = False, callback_address: str = None
|
||||
) -> PyRealm:
|
||||
):
|
||||
if name in self.__realms:
|
||||
raise DuplicateRealmName("Realm '%s' already exists" % name)
|
||||
|
||||
|
|
|
@ -27,15 +27,15 @@
|
|||
|
||||
namespace noisicaa {
|
||||
|
||||
string sprintf(const string &fmt, ...) {
|
||||
string sprintf(const char* fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
int size = std::vsnprintf(nullptr, 0, fmt.c_str(), args) + 1;
|
||||
int size = std::vsnprintf(nullptr, 0, fmt, args) + 1;
|
||||
unique_ptr<char> buf(new char[size]);
|
||||
|
||||
va_start(args, fmt);
|
||||
std::vsnprintf(buf.get(), size, fmt.c_str(), args);
|
||||
std::vsnprintf(buf.get(), size, fmt, args);
|
||||
return string(buf.get());
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace noisicaa {
|
|||
|
||||
using namespace std;
|
||||
|
||||
string sprintf(const string& fmt, ...);
|
||||
string sprintf(const char* fmt, ...);
|
||||
|
||||
} // namespace noisicaa
|
||||
|
||||
|
|
|
@ -69,7 +69,6 @@ string PlayerStateMutation::to_string() const {
|
|||
if (!first) {
|
||||
s += ", ";
|
||||
}
|
||||
first = false;
|
||||
s += sprintf("loop_end_time=%f", loop_end_time.to_float());
|
||||
}
|
||||
s += ")";
|
||||
|
@ -81,19 +80,6 @@ Player::Player(const string& realm_name, HostSystem* host_system)
|
|||
_realm_name(realm_name),
|
||||
_host_system(host_system) {}
|
||||
|
||||
Player::~Player() {
|
||||
cleanup();
|
||||
}
|
||||
|
||||
Status Player::setup() {
|
||||
_logger->info("Setting up player...");
|
||||
return Status::Ok();
|
||||
}
|
||||
|
||||
void Player::cleanup() {
|
||||
_logger->info("Player cleaned up.");
|
||||
}
|
||||
|
||||
void Player::update_state(const string& state_serialized) {
|
||||
pb::PlayerState state_pb;
|
||||
assert(state_pb.ParseFromString(state_serialized));
|
||||
|
|
|
@ -72,10 +72,6 @@ public:
|
|||
class Player {
|
||||
public:
|
||||
Player(const string& realm_name, HostSystem* host_system);
|
||||
virtual ~Player();
|
||||
|
||||
virtual Status setup();
|
||||
virtual void cleanup();
|
||||
|
||||
void update_state(const string& state_serialized);
|
||||
|
||||
|
|
|
@ -49,9 +49,6 @@ cdef extern from "noisicaa/audioproc/engine/player.h" namespace "noisicaa" nogil
|
|||
cppclass Player:
|
||||
Player(const string& realm_name, HostSystem* host_system)
|
||||
|
||||
Status setup()
|
||||
void cleanup()
|
||||
|
||||
void update_state(const string& state_serialized)
|
||||
|
||||
|
||||
|
|
|
@ -24,6 +24,4 @@ from noisicaa import host_system as host_system_lib
|
|||
|
||||
class PyPlayer(object):
|
||||
def __init__(self, host_system: host_system_lib.HostSystem, realm: str) -> None: ...
|
||||
def setup(self) -> None: ...
|
||||
def cleanup(self) -> None: ...
|
||||
def update_state(self, state: audioproc.PlayerState) -> None: ...
|
||||
|
|
|
@ -35,16 +35,9 @@ cdef class PyPlayer(object):
|
|||
cdef Player* release(self) nogil:
|
||||
return self.__player_ptr.release()
|
||||
|
||||
def setup(self):
|
||||
with nogil:
|
||||
check(self.__player.setup())
|
||||
|
||||
def cleanup(self):
|
||||
# Only do cleanup, when we still own the player.
|
||||
cdef Player* player = self.__player_ptr.get()
|
||||
if player != NULL:
|
||||
with nogil:
|
||||
player.cleanup()
|
||||
self.__player_ptr.reset()
|
||||
self.__player = NULL
|
||||
|
||||
def update_state(self, state):
|
||||
self.__player.update_state(state.SerializeToString())
|
||||
|
|
|
@ -251,7 +251,7 @@ Status PluginHost::handle_memory_map(PluginMemoryMapping* map, PluginMemoryMappi
|
|||
return OSERROR_STATUS("Failed to open shmem %s", map->shmem_path);
|
||||
}
|
||||
|
||||
strcpy(_shmem_path, map->shmem_path);
|
||||
strncpy(_shmem_path, map->shmem_path, PATH_MAX);
|
||||
|
||||
struct stat s;
|
||||
if (fstat(_shmem_fd, &s) < 0) {
|
||||
|
|
|
@ -81,7 +81,7 @@ public:
|
|||
static const char* state_name(ProcessorState state);
|
||||
|
||||
Status setup();
|
||||
void cleanup() override;
|
||||
virtual void cleanup();
|
||||
|
||||
Status handle_message(const string& msg_serialized);
|
||||
Status set_parameters(const string& parameters_serialized);
|
||||
|
|
|
@ -25,6 +25,7 @@ from noisicaa import audioproc
|
|||
from noisicaa import host_system as host_system_lib
|
||||
from noisicaa.audioproc.public import node_parameters_pb2
|
||||
from . import block_context
|
||||
from . import buffers
|
||||
|
||||
|
||||
class State(enum.Enum):
|
||||
|
@ -46,7 +47,7 @@ class PyProcessor(object):
|
|||
def setup(self) -> None: ...
|
||||
def cleanup(self) -> None: ...
|
||||
def connect_port(
|
||||
self, ctxt: block_context.PyBlockContext, port_index: int, data: memoryview) -> None: ...
|
||||
self, ctxt: block_context.PyBlockContext, port_index: int, buffer: buffers.PyBuffer) -> None: ...
|
||||
def process_block(
|
||||
self, ctxt: block_context.PyBlockContext, time_mapper: audioproc.TimeMapper) -> None: ...
|
||||
def handle_message(self, msg: audioproc.ProcessorMessage) -> None: ...
|
||||
|
|
|
@ -114,7 +114,7 @@ Status ProcessorPlugin::process_block_internal(BlockContext* ctxt, TimeMapper* t
|
|||
RETURN_IF_ERROR(pipe_write(buf, strlen(buf), deadline));
|
||||
|
||||
PluginMemoryMapping mapping;
|
||||
strcpy(mapping.shmem_path, ctxt->buffer_arena->name().c_str());
|
||||
strncpy(mapping.shmem_path, ctxt->buffer_arena->name().c_str(), PATH_MAX);
|
||||
mapping.cond_offset = _buffers[plugin_cond_idx]->data() - ctxt->buffer_arena->address();
|
||||
mapping.block_size = _host_system->block_size();
|
||||
mapping.num_buffers = _desc.ports_size();
|
||||
|
|
|
@ -136,7 +136,7 @@ public:
|
|||
const string& name() const { return _name; }
|
||||
|
||||
Status setup();
|
||||
void cleanup() override;
|
||||
void cleanup();
|
||||
|
||||
string dump() const;
|
||||
void clear_programs();
|
||||
|
|
|
@ -125,9 +125,6 @@ cdef class PyRealm(object):
|
|||
|
||||
await self.setup_node(self.__sink)
|
||||
|
||||
if self.__player is not None:
|
||||
self.__player.setup()
|
||||
|
||||
with nogil:
|
||||
check(self.__realm.setup())
|
||||
|
||||
|
@ -136,9 +133,6 @@ cdef class PyRealm(object):
|
|||
async def cleanup(self):
|
||||
logger.info("Cleaning up realm '%s'...", self.name)
|
||||
|
||||
if self.__player is not None:
|
||||
self.__player.cleanup()
|
||||
|
||||
await self.__sink.cleanup()
|
||||
|
||||
if self.__realm != NULL:
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include <stdarg.h>
|
||||
#include "noisicaa/core/logging.h"
|
||||
#include "noisicaa/core/scope_guard.h"
|
||||
#include "noisicaa/audioproc/engine/spec.h"
|
||||
#include "noisicaa/audioproc/engine/control_value.h"
|
||||
#include "noisicaa/audioproc/engine/processor.h"
|
||||
|
@ -88,65 +89,14 @@ string Spec::dump() const {
|
|||
return out;
|
||||
}
|
||||
|
||||
Status Spec::append_opcode(OpCode opcode, ...) {
|
||||
vector<OpArg> args;
|
||||
|
||||
struct OpSpec opspec = opspecs[opcode];
|
||||
|
||||
va_list values;
|
||||
va_start(values, opcode);
|
||||
for (const char* a = opspec.argspec ; *a ; ++a) {
|
||||
switch (*a) {
|
||||
case 'i': {
|
||||
int64_t value = va_arg(values, int64_t);
|
||||
args.emplace_back(OpArg(value));
|
||||
break;
|
||||
}
|
||||
case 'b': {
|
||||
const char* buf_name = va_arg(values, char*);
|
||||
StatusOr<int> stor_value = get_buffer_idx(buf_name);
|
||||
RETURN_IF_ERROR(stor_value);
|
||||
args.emplace_back(OpArg((int64_t)stor_value.result()));
|
||||
break;
|
||||
}
|
||||
case 'p': {
|
||||
Processor* processor = va_arg(values, Processor*);
|
||||
StatusOr<int> stor_value = get_processor_idx(processor);
|
||||
RETURN_IF_ERROR(stor_value);
|
||||
args.emplace_back(OpArg((int64_t)stor_value.result()));
|
||||
break;
|
||||
}
|
||||
case 'c': {
|
||||
ControlValue* cv = va_arg(values, ControlValue*);
|
||||
StatusOr<int> stor_value = get_control_value_idx(cv);
|
||||
RETURN_IF_ERROR(stor_value);
|
||||
args.emplace_back(OpArg((int64_t)stor_value.result()));
|
||||
break;
|
||||
}
|
||||
case 'f': {
|
||||
float value = va_arg(values, double);
|
||||
args.emplace_back(OpArg(value));
|
||||
break;
|
||||
}
|
||||
case 's': {
|
||||
const char* value = va_arg(values, char*);
|
||||
args.emplace_back(OpArg(value));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return append_opcode_args(opcode, args);
|
||||
}
|
||||
|
||||
Status Spec::append_opcode_args(OpCode opcode, const vector<OpArg>& args) {
|
||||
Status Spec::append_opcode(OpCode opcode, const vector<OpArg>& args) {
|
||||
_opcodes.push_back({opcode, args});
|
||||
return Status::Ok();
|
||||
}
|
||||
|
||||
Status Spec::append_buffer(const string& name, BufferType* type) {
|
||||
char* name_c = new char[name.size() + 1];
|
||||
strcpy(name_c, name.c_str());
|
||||
memmove(name_c, name.c_str(), name.size() + 1);
|
||||
_buffer_map[name_c] = _buffers.size();
|
||||
_buffers.emplace_back(type);
|
||||
return Status::Ok();
|
||||
|
|
|
@ -64,8 +64,7 @@ public:
|
|||
void set_duration(MusicalDuration duration) { _duration = duration; }
|
||||
MusicalDuration duration() const { return _duration; }
|
||||
|
||||
Status append_opcode(OpCode opcode, ...);
|
||||
Status append_opcode_args(OpCode opcode, const vector<OpArg>& args);
|
||||
Status append_opcode(OpCode opcode, const vector<OpArg>& args);
|
||||
int num_ops() const { return _opcodes.size(); }
|
||||
const vector<OpArg>& get_opargs(int idx) const { return _opcodes[idx].args; }
|
||||
OpCode get_opcode(int idx) const { return _opcodes[idx].opcode; }
|
||||
|
|
|
@ -40,8 +40,7 @@ cdef extern from "noisicaa/audioproc/engine/spec.h" namespace "noisicaa" nogil:
|
|||
void set_duration(MusicalDuration duration)
|
||||
MusicalDuration duration() const
|
||||
|
||||
Status append_opcode(OpCode opcode, ...)
|
||||
Status append_opcode_args(OpCode opcode, const vector[OpArg]& args)
|
||||
Status append_opcode(OpCode opcode, const vector[OpArg]& args)
|
||||
int num_ops() const
|
||||
OpCode get_opcode(int idx) const
|
||||
const OpArg& get_oparg(int idx, int arg) const
|
||||
|
|
|
@ -201,4 +201,4 @@ cdef class PySpec(object):
|
|||
else:
|
||||
assert False, spec
|
||||
|
||||
check(self.__spec.append_opcode_args(op, opargs))
|
||||
check(self.__spec.append_opcode(op, opargs))
|
||||
|
|
|
@ -48,9 +48,15 @@ class TestSpec(unittest.TestCase):
|
|||
check(spec.append_buffer(b'buf2', new FloatAudioBlockBuffer(node_db.PortDescription.AUDIO)))
|
||||
check(spec.append_buffer(b'buf3', new FloatAudioBlockBuffer(node_db.PortDescription.AUDIO)))
|
||||
|
||||
check(spec.append_opcode(OpCode.NOOP))
|
||||
check(spec.append_opcode(OpCode.COPY, b'buf1', b'buf2'))
|
||||
check(spec.append_opcode(OpCode.MUL, b'buf3', 0.5))
|
||||
check(spec.append_opcode(OpCode.NOOP, vector[OpArg]()))
|
||||
cdef vector[OpArg] a
|
||||
a.push_back(OpArg(<int64_t>spec.get_buffer_idx(b'buf1').result()))
|
||||
a.push_back(OpArg(<int64_t>spec.get_buffer_idx(b'buf2').result()))
|
||||
check(spec.append_opcode(OpCode.COPY, a))
|
||||
cdef vector[OpArg] b
|
||||
b.push_back(OpArg(<int64_t>spec.get_buffer_idx(b'buf3').result()))
|
||||
b.push_back(OpArg(<float>0.5))
|
||||
check(spec.append_opcode(OpCode.MUL, b))
|
||||
self.assertEqual(spec.num_ops(), 3)
|
||||
|
||||
self.assertEqual(spec.get_opcode(0), OpCode.NOOP)
|
||||
|
|
|
@ -26,7 +26,7 @@ def build(ctx):
|
|||
ctx.py_test('backend_test.py')
|
||||
ctx.cy_module('engine.pyx', use=['noisicaa-audioproc-engine'])
|
||||
ctx.py_test('engine_test.py')
|
||||
ctx.py_test('engine_perftest.py')
|
||||
#ctx.py_test('engine_perftest.py')
|
||||
ctx.py_module('graph.py')
|
||||
ctx.py_module('plugin_host_process.py')
|
||||
ctx.py_test('plugin_host_process_test.py')
|
||||
|
@ -36,7 +36,7 @@ def build(ctx):
|
|||
ctx.cy_test('spec_test.pyx', use=['noisicaa-audioproc-engine'])
|
||||
ctx.cy_module('buffer_arena.pyx', use=['noisicaa-audioproc-engine'])
|
||||
ctx.cy_module('buffers.pyx', use=['noisicaa-audioproc-engine'])
|
||||
ctx.cy_test('buffers_test.pyx', use=['noisicaa-audioproc-engine'])
|
||||
#ctx.cy_test('buffers_test.pyx', use=['noisicaa-audioproc-engine'])
|
||||
ctx.cy_module('control_value.pyx', use=['noisicaa-audioproc-engine'])
|
||||
ctx.cy_module('processor.pyx', use=['noisicaa-audioproc-engine'])
|
||||
ctx.py_test('processor_test.py')
|
||||
|
@ -46,7 +46,9 @@ def build(ctx):
|
|||
ctx.cy_module('block_context.pyx', use=['noisicaa-audioproc-engine'])
|
||||
ctx.cy_module('message_queue.pyx', use=['noisicaa-audioproc-engine'])
|
||||
ctx.cy_module('plugin_host.pyx', use=['noisicaa-audioproc-engine'])
|
||||
ctx.py_test('plugin_host_test.py')
|
||||
if ctx.env.ENABLE_TEST:
|
||||
with ctx.group(ctx.GRP_BUILD_TESTS):
|
||||
ctx.py_module('plugin_host_test.py', mypy='loose')
|
||||
ctx.py_test('plugin_host_ladspa_test.py')
|
||||
ctx.py_test('plugin_host_lv2_test.py')
|
||||
ctx.cy_module('plugin_ui_host.pyx', use=['noisicaa-audioproc-engine'])
|
||||
|
@ -57,48 +59,44 @@ def build(ctx):
|
|||
ctx.cy_module('profile.pyx', use=['noisicaa-audioproc-engine'])
|
||||
ctx.cy_test('opcodes_test.pyx', use=['noisicaa-audioproc-engine'])
|
||||
|
||||
ctx.cpp_proto('plugin_host.proto')
|
||||
ctx.cpp_proto('processor_plugin.proto')
|
||||
|
||||
ctx.shlib(
|
||||
target='noisicaa-audioproc-engine',
|
||||
cxxflags=['-Werror'], # TODO: move to global CXXFLAGS
|
||||
source=[
|
||||
'alsa_device_manager.cpp',
|
||||
'backend.cpp',
|
||||
'backend_null.cpp',
|
||||
'backend_portaudio.cpp',
|
||||
'backend_renderer.cpp',
|
||||
'block_context.cpp',
|
||||
'buffer_arena.cpp',
|
||||
'buffers.cpp',
|
||||
'control_value.cpp',
|
||||
'csound_util.cpp',
|
||||
'double_buffered_state_manager.cpp',
|
||||
'engine.cpp',
|
||||
'fluidsynth_util.cpp',
|
||||
'misc.cpp',
|
||||
'message_queue.cpp',
|
||||
'opcodes.cpp',
|
||||
'player.cpp',
|
||||
'plugin_host.pb.cc',
|
||||
'plugin_host.cpp',
|
||||
'plugin_host_lv2.cpp',
|
||||
'plugin_host_ladspa.cpp',
|
||||
'plugin_ui_host.cpp',
|
||||
'plugin_ui_host_lv2.cpp',
|
||||
'processor.cpp',
|
||||
'processor_null.cpp',
|
||||
'processor_faust.cpp',
|
||||
'processor_csound_base.cpp',
|
||||
'processor_csound.cpp',
|
||||
'processor_plugin.cpp',
|
||||
'processor_plugin.pb.cc',
|
||||
'processor_sound_file.cpp',
|
||||
'profile.cpp',
|
||||
'realtime.cpp',
|
||||
'spec.cpp',
|
||||
'realm.cpp',
|
||||
ctx.cpp_module('alsa_device_manager.cpp'),
|
||||
ctx.cpp_module('backend.cpp'),
|
||||
ctx.cpp_module('backend_null.cpp'),
|
||||
ctx.cpp_module('backend_portaudio.cpp'),
|
||||
ctx.cpp_module('backend_renderer.cpp'),
|
||||
ctx.cpp_module('block_context.cpp'),
|
||||
ctx.cpp_module('buffer_arena.cpp'),
|
||||
ctx.cpp_module('buffers.cpp'),
|
||||
ctx.cpp_module('control_value.cpp'),
|
||||
ctx.cpp_module('csound_util.cpp'),
|
||||
ctx.cpp_module('double_buffered_state_manager.cpp'),
|
||||
ctx.cpp_module('engine.cpp'),
|
||||
ctx.cpp_module('fluidsynth_util.cpp'),
|
||||
ctx.cpp_module('misc.cpp'),
|
||||
ctx.cpp_module('message_queue.cpp'),
|
||||
ctx.cpp_module('opcodes.cpp'),
|
||||
ctx.cpp_module('player.cpp'),
|
||||
ctx.cpp_proto('plugin_host.proto'),
|
||||
ctx.cpp_module('plugin_host.cpp'),
|
||||
ctx.cpp_module('plugin_host_lv2.cpp'),
|
||||
ctx.cpp_module('plugin_host_ladspa.cpp'),
|
||||
ctx.cpp_module('plugin_ui_host.cpp'),
|
||||
ctx.cpp_module('plugin_ui_host_lv2.cpp'),
|
||||
ctx.cpp_module('processor.cpp'),
|
||||
ctx.cpp_module('processor_null.cpp'),
|
||||
ctx.cpp_module('processor_faust.cpp'),
|
||||
ctx.cpp_module('processor_csound_base.cpp'),
|
||||
ctx.cpp_module('processor_csound.cpp'),
|
||||
ctx.cpp_proto('processor_plugin.proto'),
|
||||
ctx.cpp_module('processor_plugin.cpp'),
|
||||
ctx.cpp_module('processor_sound_file.cpp'),
|
||||
ctx.cpp_module('profile.cpp'),
|
||||
ctx.cpp_module('realtime.cpp'),
|
||||
ctx.cpp_module('spec.cpp'),
|
||||
ctx.cpp_module('realm.cpp'),
|
||||
],
|
||||
use=[
|
||||
'noisicaa-core',
|
||||
|
|
|
@ -44,44 +44,27 @@ def build(ctx):
|
|||
ctx.py_proto('midi_event.proto')
|
||||
ctx.py_proto('transfer_function.proto')
|
||||
|
||||
ctx.cpp_proto('backend_settings.proto')
|
||||
ctx.cpp_proto('instrument_spec.proto')
|
||||
ctx.cpp_proto('musical_time.proto')
|
||||
ctx.cpp_proto('player_state.proto')
|
||||
ctx.cpp_proto('plugin_state.proto')
|
||||
ctx.cpp_proto('processor_message.proto')
|
||||
ctx.cpp_proto('engine_notification.proto')
|
||||
ctx.cpp_proto('devices.proto')
|
||||
ctx.cpp_proto('control_value.proto')
|
||||
ctx.cpp_proto('host_parameters.proto')
|
||||
ctx.cpp_proto('project_properties.proto')
|
||||
ctx.cpp_proto('node_port_properties.proto')
|
||||
ctx.cpp_proto('node_parameters.proto')
|
||||
ctx.cpp_proto('midi_event.proto')
|
||||
ctx.cpp_proto('transfer_function.proto')
|
||||
|
||||
ctx.shlib(
|
||||
target='noisicaa-audioproc-public',
|
||||
cxxflags=['-Werror'], # TODO: move to global CXXFLAGS
|
||||
source=[
|
||||
'backend_settings.pb.cc',
|
||||
'control_value.pb.cc',
|
||||
'devices.pb.cc',
|
||||
'engine_notification.pb.cc',
|
||||
'host_parameters.pb.cc',
|
||||
'instrument_spec.pb.cc',
|
||||
'midi_event.pb.cc',
|
||||
'musical_time.cpp',
|
||||
'musical_time.pb.cc',
|
||||
'node_parameters.pb.cc',
|
||||
'node_port_properties.pb.cc',
|
||||
'player_state.pb.cc',
|
||||
'plugin_state.pb.cc',
|
||||
'processor_message.pb.cc',
|
||||
'project_properties.pb.cc',
|
||||
'time_mapper.cpp',
|
||||
'transfer_function.cpp',
|
||||
'transfer_function.pb.cc',
|
||||
ctx.cpp_proto('backend_settings.proto'),
|
||||
ctx.cpp_proto('control_value.proto'),
|
||||
ctx.cpp_proto('devices.proto'),
|
||||
ctx.cpp_proto('engine_notification.proto'),
|
||||
ctx.cpp_proto('host_parameters.proto'),
|
||||
ctx.cpp_proto('instrument_spec.proto'),
|
||||
ctx.cpp_proto('midi_event.proto'),
|
||||
ctx.cpp_proto('musical_time.proto'),
|
||||
ctx.cpp_module('musical_time.cpp'),
|
||||
ctx.cpp_proto('node_parameters.proto'),
|
||||
ctx.cpp_proto('node_port_properties.proto'),
|
||||
ctx.cpp_proto('player_state.proto'),
|
||||
ctx.cpp_proto('plugin_state.proto'),
|
||||
ctx.cpp_proto('processor_message.proto'),
|
||||
ctx.cpp_proto('project_properties.proto'),
|
||||
ctx.cpp_module('time_mapper.cpp'),
|
||||
ctx.cpp_proto('transfer_function.proto'),
|
||||
ctx.cpp_module('transfer_function.cpp'),
|
||||
],
|
||||
use=['NOISELIB', 'PROTOBUF', 'noisicaa-core'],
|
||||
use=['PROTOBUF', 'noisicaa-core'],
|
||||
)
|
||||
|
|
|
@ -28,115 +28,6 @@ import sys
|
|||
import numpy
|
||||
cimport numpy
|
||||
|
||||
### DECLARATIONS ##########################################################
|
||||
|
||||
cdef extern from "dlfcn.h":
|
||||
enum:
|
||||
RTLD_LAZY
|
||||
RTLD_NOW
|
||||
RTLD_GLOBAL
|
||||
RTLD_DEFAULT
|
||||
RTLD_NEXT
|
||||
void *dlopen(char *filename, int flag)
|
||||
char *dlerror()
|
||||
void *dlsym(void *handle, char *symbol)
|
||||
int dlclose(void *handle)
|
||||
|
||||
cdef extern from "ladspa.h" nogil:
|
||||
ctypedef float LADSPA_Data
|
||||
ctypedef void* LADSPA_Handle
|
||||
|
||||
ctypedef int LADSPA_Properties
|
||||
enum:
|
||||
LADSPA_PROPERTY_REALTIME
|
||||
LADSPA_PROPERTY_INPLACE_BROKEN
|
||||
LADSPA_PROPERTY_HARD_RT_CAPABLE
|
||||
|
||||
int LADSPA_IS_REALTIME(int)
|
||||
int LADSPA_IS_INPLACE_BROKEN(int)
|
||||
int LADSPA_IS_HARD_RT_CAPABLE(int)
|
||||
|
||||
ctypedef int LADSPA_PortDescriptor
|
||||
enum:
|
||||
LADSPA_PORT_INPUT
|
||||
LADSPA_PORT_OUTPUT
|
||||
LADSPA_PORT_CONTROL
|
||||
LADSPA_PORT_AUDIO
|
||||
|
||||
int LADSPA_IS_PORT_INPUT(int)
|
||||
int LADSPA_IS_PORT_OUTPUT(int)
|
||||
int LADSPA_IS_PORT_CONTROL(int)
|
||||
int LADSPA_IS_PORT_AUDIO(int)
|
||||
|
||||
ctypedef int LADSPA_PortRangeHintDescriptor
|
||||
enum:
|
||||
LADSPA_HINT_BOUNDED_BELOW
|
||||
LADSPA_HINT_BOUNDED_ABOVE
|
||||
LADSPA_HINT_TOGGLED
|
||||
LADSPA_HINT_SAMPLE_RATE
|
||||
LADSPA_HINT_LOGARITHMIC
|
||||
LADSPA_HINT_INTEGER
|
||||
LADSPA_HINT_DEFAULT_MASK
|
||||
LADSPA_HINT_DEFAULT_NONE
|
||||
LADSPA_HINT_DEFAULT_MINIMUM
|
||||
LADSPA_HINT_DEFAULT_LOW
|
||||
LADSPA_HINT_DEFAULT_MIDDLE
|
||||
LADSPA_HINT_DEFAULT_HIGH
|
||||
LADSPA_HINT_DEFAULT_MAXIMUM
|
||||
LADSPA_HINT_DEFAULT_0
|
||||
LADSPA_HINT_DEFAULT_1
|
||||
LADSPA_HINT_DEFAULT_100
|
||||
LADSPA_HINT_DEFAULT_440
|
||||
|
||||
int LADSPA_IS_HINT_BOUNDED_BELOW(int)
|
||||
int LADSPA_IS_HINT_BOUNDED_ABOVE(int)
|
||||
int LADSPA_IS_HINT_TOGGLED(int)
|
||||
int LADSPA_IS_HINT_SAMPLE_RATE(int)
|
||||
int LADSPA_IS_HINT_LOGARITHMIC(int)
|
||||
int LADSPA_IS_HINT_INTEGER(int)
|
||||
int LADSPA_IS_HINT_HAS_DEFAULT(int)
|
||||
int LADSPA_IS_HINT_DEFAULT_MINIMUM(int)
|
||||
int LADSPA_IS_HINT_DEFAULT_LOW(int)
|
||||
int LADSPA_IS_HINT_DEFAULT_MIDDLE(int)
|
||||
int LADSPA_IS_HINT_DEFAULT_HIGH(int)
|
||||
int LADSPA_IS_HINT_DEFAULT_MAXIMUM(int)
|
||||
int LADSPA_IS_HINT_DEFAULT_0(int)
|
||||
int LADSPA_IS_HINT_DEFAULT_1(int)
|
||||
int LADSPA_IS_HINT_DEFAULT_100(int)
|
||||
int LADSPA_IS_HINT_DEFAULT_440(int)
|
||||
|
||||
ctypedef struct LADSPA_PortRangeHint:
|
||||
LADSPA_PortRangeHintDescriptor HintDescriptor
|
||||
LADSPA_Data LowerBound
|
||||
LADSPA_Data UpperBound
|
||||
|
||||
ctypedef struct LADSPA_Descriptor:
|
||||
unsigned long UniqueID
|
||||
char* Label
|
||||
LADSPA_Properties Properties
|
||||
char* Name
|
||||
char* Maker
|
||||
char* Copyright
|
||||
unsigned long PortCount
|
||||
LADSPA_PortDescriptor* PortDescriptors
|
||||
char** PortNames
|
||||
LADSPA_PortRangeHint* PortRangeHints
|
||||
void* ImplementationData
|
||||
LADSPA_Handle (*instantiate)(void* descriptor, int sample_rate)
|
||||
void (*connect_port)(
|
||||
LADSPA_Handle Instance, unsigned long port, LADSPA_Data* data_location)
|
||||
void (*activate)(LADSPA_Handle Instance)
|
||||
void (*run)(LADSPA_Handle instance, unsigned long sample_count)
|
||||
void (*run_adding)(LADSPA_Handle instance, unsigned long sample_count)
|
||||
void (*set_run_adding_gain)(LADSPA_Handle instance, LADSPA_Data gain)
|
||||
void (*deactivate)(LADSPA_Handle instance)
|
||||
void (*cleanup)(LADSPA_Handle instance)
|
||||
|
||||
LADSPA_Descriptor* ladspa_descriptor(unsigned long index)
|
||||
ctypedef LADSPA_Descriptor* (*LADSPA_Descriptor_Function)(unsigned long index)
|
||||
|
||||
|
||||
### CLIENT CODE ###########################################################
|
||||
|
||||
class Error(Exception):
|
||||
pass
|
||||
|
|
|
@ -203,7 +203,7 @@ cdef extern from "sndfile.h":
|
|||
|
||||
ctypedef int64_t sf_count_t
|
||||
|
||||
cdef struct SF_INFO:
|
||||
cdef struct _SF_INFO_s:
|
||||
sf_count_t frames
|
||||
int samplerate
|
||||
int channels
|
||||
|
@ -211,7 +211,7 @@ cdef extern from "sndfile.h":
|
|||
int sections
|
||||
int seekable
|
||||
|
||||
ctypedef SF_INFO SF_INFO
|
||||
ctypedef _SF_INFO_s SF_INFO
|
||||
|
||||
cdef struct _SF_FORMAT_INFO_s:
|
||||
int format
|
||||
|
@ -302,14 +302,14 @@ cdef extern from "sndfile.h":
|
|||
|
||||
ctypedef sf_count_t (*sf_vio_tell)(void* user_data)
|
||||
|
||||
cdef struct SF_VIRTUAL_IO:
|
||||
cdef struct _SF_VIRTUAL_IO_s:
|
||||
sf_vio_get_filelen get_filelen
|
||||
sf_vio_seek seek
|
||||
sf_vio_read read
|
||||
sf_vio_write write
|
||||
sf_vio_tell tell
|
||||
|
||||
ctypedef SF_VIRTUAL_IO SF_VIRTUAL_IO
|
||||
ctypedef _SF_VIRTUAL_IO_s SF_VIRTUAL_IO
|
||||
|
||||
SNDFILE* sf_open(char* path, int mode, SF_INFO* sfinfo)
|
||||
|
||||
|
|
|
@ -20,9 +20,6 @@
|
|||
#
|
||||
# @end:license
|
||||
|
||||
# This file triggers https://github.com/JukkaL/mypy/issues/730
|
||||
# mypy: skip-file
|
||||
|
||||
import os.path
|
||||
|
||||
import numpy
|
||||
|
|
|
@ -27,6 +27,8 @@ def build(ctx):
|
|||
ctx.cy_module('lilv.pyx', use=['LILV'])
|
||||
ctx.cy_test('lilv_test.pyx', use=['LILV'])
|
||||
ctx.cy_module('sndfile.pyx', use=['SNDFILE'])
|
||||
ctx.py_test('sndfile_test.py')
|
||||
ctx.py_test('sndfile_test.py',
|
||||
# This file triggers https://github.com/JukkaL/mypy/issues/730
|
||||
mypy='disabled')
|
||||
ctx.cy_module('sratom.pyx', use=['SRATOM'])
|
||||
ctx.py_test('sratom_test.py')
|
||||
|
|
|
@ -29,5 +29,5 @@ def build(ctx):
|
|||
ctx.py_test('model_test.py')
|
||||
ctx.py_module('node_ui.py')
|
||||
ctx.py_module('track_ui.py')
|
||||
ctx.py_test('track_ui_test.py')
|
||||
#ctx.py_test('track_ui_test.py')
|
||||
ctx.py_proto('model.proto')
|
||||
|
|
|
@ -317,8 +317,8 @@ class ControlTrackEditor(time_view_mixin.ContinuousTimeMixin, base_track_editor.
|
|||
self.setHighlightedPoint(None)
|
||||
return
|
||||
|
||||
closest_cpoint = None
|
||||
closest_dist = None
|
||||
closest_cpoint = None # type: ControlPoint
|
||||
closest_dist = None # type: int
|
||||
for cpoint in self.points:
|
||||
dist = ((cpoint.pos().x() - self.__mouse_pos.x()) ** 2
|
||||
+ (cpoint.pos().y() - self.__mouse_pos.y()) ** 2)
|
||||
|
|
|
@ -29,34 +29,28 @@ def build(ctx):
|
|||
ctx.py_test('model_test.py')
|
||||
ctx.py_module('node_ui.py')
|
||||
ctx.py_module('track_ui.py')
|
||||
ctx.py_test('track_ui_test.py')
|
||||
#ctx.py_test('track_ui_test.py')
|
||||
ctx.py_test('processor_test.py')
|
||||
ctx.py_module('processor_messages.py')
|
||||
ctx.py_proto('model.proto')
|
||||
ctx.py_proto('processor_messages.proto')
|
||||
|
||||
ctx.cpp_proto('processor_messages.proto')
|
||||
|
||||
ctx.shlib(
|
||||
target='noisicaa-builtin_nodes-control_track-processor_messages',
|
||||
cxxflags=['-Werror'], # TODO: move to global CXXFLAGS
|
||||
source=[
|
||||
'processor_messages.pb.cc',
|
||||
ctx.cpp_proto('processor_messages.proto'),
|
||||
],
|
||||
use=[
|
||||
'NOISELIB',
|
||||
'noisicaa-audioproc-public',
|
||||
]
|
||||
)
|
||||
|
||||
ctx.shlib(
|
||||
target='noisicaa-builtin_nodes-control_track-processor',
|
||||
cxxflags=['-Werror'], # TODO: move to global CXXFLAGS
|
||||
source=[
|
||||
'processor.cpp',
|
||||
ctx.cpp_module('processor.cpp'),
|
||||
],
|
||||
use=[
|
||||
'NOISELIB',
|
||||
'noisicaa-audioproc-public',
|
||||
'noisicaa-host_system',
|
||||
'noisicaa-builtin_nodes-control_track-processor_messages',
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
# @end:license
|
||||
|
||||
import logging
|
||||
import os.path
|
||||
from typing import cast, Any, Dict, Iterator, Callable
|
||||
|
||||
from PyQt5.QtCore import Qt
|
||||
|
@ -28,6 +29,7 @@ from PyQt5 import QtCore
|
|||
from PyQt5 import QtGui
|
||||
from PyQt5 import QtWidgets
|
||||
|
||||
from noisicaa import constants
|
||||
from noisicaa import core
|
||||
from noisicaa import music
|
||||
from noisicaa import node_db
|
||||
|
@ -339,7 +341,8 @@ class Editor(ui_base.ProjectMixin, core.AutoCleanupMixin, QtWidgets.QDialog):
|
|||
icon_size = QtCore.QSize(32, 32)
|
||||
|
||||
self.__apply_action = QtWidgets.QAction("Apply", self)
|
||||
self.__apply_action.setIcon(QtGui.QIcon.fromTheme('document-save'))
|
||||
self.__apply_action.setIcon(QtGui.QIcon(
|
||||
os.path.join(constants.DATA_DIR, 'icons', 'document-save.svg')))
|
||||
self.__apply_action.setEnabled(False)
|
||||
self.__apply_action.triggered.connect(self.__apply)
|
||||
|
||||
|
|
|
@ -33,17 +33,13 @@ def build(ctx):
|
|||
ctx.py_proto('model.proto')
|
||||
ctx.py_proto('processor.proto')
|
||||
|
||||
ctx.cpp_proto('processor.proto')
|
||||
|
||||
ctx.shlib(
|
||||
target='noisicaa-builtin_nodes-custom_csound-processor',
|
||||
cxxflags=['-Werror'], # TODO: move to global CXXFLAGS
|
||||
source=[
|
||||
'processor.cpp',
|
||||
'processor.pb.cc',
|
||||
ctx.cpp_module('processor.cpp'),
|
||||
ctx.cpp_proto('processor.proto'),
|
||||
],
|
||||
use=[
|
||||
'NOISELIB',
|
||||
'noisicaa-audioproc-public',
|
||||
'noisicaa-host_system',
|
||||
]
|
||||
|
|
|
@ -33,18 +33,14 @@ def build(ctx):
|
|||
ctx.py_proto('model.proto')
|
||||
ctx.py_proto('processor.proto')
|
||||
|
||||
ctx.cpp_proto('model.proto')
|
||||
ctx.cpp_proto('processor.proto')
|
||||
|
||||
ctx.shlib(
|
||||
target='noisicaa-builtin_nodes-cv_mapper-processor',
|
||||
cxxflags=['-Werror'], # TODO: move to global CXXFLAGS
|
||||
source=[
|
||||
'processor.cpp',
|
||||
'processor.pb.cc',
|
||||
ctx.cpp_module('processor.cpp'),
|
||||
ctx.cpp_proto('model.proto'),
|
||||
ctx.cpp_proto('processor.proto'),
|
||||
],
|
||||
use=[
|
||||
'NOISELIB',
|
||||
'noisicaa-audioproc-public',
|
||||
'noisicaa-host_system',
|
||||
]
|
||||
|
|
|
@ -21,12 +21,14 @@
|
|||
# @end:license
|
||||
|
||||
import logging
|
||||
import os.path
|
||||
from typing import Any
|
||||
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5 import QtGui
|
||||
from PyQt5 import QtWidgets
|
||||
|
||||
from noisicaa import constants
|
||||
from noisicaa import core
|
||||
from noisicaa import music
|
||||
from noisicaa.ui import ui_base
|
||||
|
@ -51,7 +53,8 @@ class InstrumentNodeWidget(ui_base.ProjectMixin, core.AutoCleanupMixin, QtWidget
|
|||
body.setAttribute(Qt.WA_NoSystemBackground, True)
|
||||
|
||||
select_instrument = QtWidgets.QToolButton(self)
|
||||
select_instrument.setIcon(QtGui.QIcon.fromTheme('document-open'))
|
||||
select_instrument.setIcon(QtGui.QIcon(
|
||||
os.path.join(constants.DATA_DIR, 'icons', 'document-open.svg')))
|
||||
select_instrument.setAutoRaise(True)
|
||||
select_instrument.clicked.connect(lambda: self.call_async(self.__selectInstrument()))
|
||||
|
||||
|
|
|
@ -33,28 +33,22 @@ def build(ctx):
|
|||
ctx.py_proto('model.proto')
|
||||
ctx.py_proto('processor_messages.proto')
|
||||
|
||||
ctx.cpp_proto('processor_messages.proto')
|
||||
|
||||
ctx.shlib(
|
||||
target='noisicaa-builtin_nodes-instrument-processor_messages',
|
||||
cxxflags=['-Werror'], # TODO: move to global CXXFLAGS
|
||||
source=[
|
||||
'processor_messages.pb.cc',
|
||||
ctx.cpp_proto('processor_messages.proto'),
|
||||
],
|
||||
use=[
|
||||
'NOISELIB',
|
||||
'noisicaa-audioproc-public',
|
||||
]
|
||||
)
|
||||
|
||||
ctx.shlib(
|
||||
target='noisicaa-builtin_nodes-instrument-processor',
|
||||
cxxflags=['-Werror'], # TODO: move to global CXXFLAGS
|
||||
source=[
|
||||
'processor.cpp',
|
||||
ctx.cpp_module('processor.cpp'),
|
||||
],
|
||||
use=[
|
||||
'NOISELIB',
|
||||
'noisicaa-audioproc-public',
|
||||
'noisicaa-host_system',
|
||||
'noisicaa-builtin_nodes-instrument-processor_messages',
|
||||
|
|
|
@ -28,6 +28,7 @@ from PyQt5.QtCore import Qt
|
|||
from PyQt5 import QtGui
|
||||
from PyQt5 import QtWidgets
|
||||
|
||||
from noisicaa import constants
|
||||
from noisicaa import core
|
||||
from noisicaa import music
|
||||
from noisicaa.ui import ui_base
|
||||
|
@ -53,7 +54,8 @@ class MetronomeNodeWidget(ui_base.ProjectMixin, core.AutoCleanupMixin, QtWidgets
|
|||
self.add_cleanup_function(self.__sample_path_connector.cleanup)
|
||||
|
||||
self.__sample_dialog_action = QtWidgets.QAction("Select sample...", self)
|
||||
self.__sample_dialog_action.setIcon(QtGui.QIcon.fromTheme('document-open'))
|
||||
self.__sample_dialog_action.setIcon(QtGui.QIcon(
|
||||
os.path.join(constants.DATA_DIR, 'icons', 'document-open.svg')))
|
||||
self.__sample_dialog_action.triggered.connect(self.__showSampleDialog)
|
||||
|
||||
self.__sample_dialog_button = QtWidgets.QToolButton()
|
||||
|
|
|
@ -33,18 +33,15 @@ def build(ctx):
|
|||
ctx.py_proto('model.proto')
|
||||
ctx.py_proto('processor.proto')
|
||||
|
||||
ctx.cpp_proto('model.proto')
|
||||
ctx.cpp_proto('processor.proto')
|
||||
|
||||
ctx.shlib(
|
||||
target='noisicaa-builtin_nodes-metronome-processor',
|
||||
cxxflags=['-Werror'], # TODO: move to global CXXFLAGS
|
||||
features=['cxxshlib'],
|
||||
source=[
|
||||
'processor.cpp',
|
||||
'processor.pb.cc',
|
||||
ctx.cpp_module('processor.cpp'),
|
||||
ctx.cpp_proto('model.proto'),
|
||||
ctx.cpp_proto('processor.proto'),
|
||||
],
|
||||
use=[
|
||||
'NOISELIB',
|
||||
'noisicaa-audioproc-public',
|
||||
'noisicaa-host_system',
|
||||
]
|
||||
|
|
|
@ -35,31 +35,24 @@ def build(ctx):
|
|||
ctx.py_proto('processor.proto')
|
||||
ctx.py_proto('processor_messages.proto')
|
||||
|
||||
ctx.cpp_proto('model.proto')
|
||||
ctx.cpp_proto('processor.proto')
|
||||
ctx.cpp_proto('processor_messages.proto')
|
||||
|
||||
ctx.shlib(
|
||||
target='noisicaa-builtin_nodes-midi_cc_to_cv-processor_messages',
|
||||
cxxflags=['-Werror'], # TODO: move to global CXXFLAGS
|
||||
source=[
|
||||
'processor_messages.pb.cc',
|
||||
ctx.cpp_proto('processor_messages.proto')
|
||||
],
|
||||
use=[
|
||||
'NOISELIB',
|
||||
'noisicaa-audioproc-public',
|
||||
],
|
||||
)
|
||||
|
||||
ctx.shlib(
|
||||
target='noisicaa-builtin_nodes-midi_cc_to_cv-processor',
|
||||
cxxflags=['-Werror'], # TODO: move to global CXXFLAGS
|
||||
source=[
|
||||
'processor.cpp',
|
||||
'processor.pb.cc',
|
||||
ctx.cpp_module('processor.cpp'),
|
||||
ctx.cpp_proto('model.proto'),
|
||||
ctx.cpp_proto('processor.proto'),
|
||||
],
|
||||
use=[
|
||||
'NOISELIB',
|
||||
'noisicaa-audioproc-public',
|
||||
'noisicaa-host_system',
|
||||
'noisicaa-builtin_nodes-processor_message_registry',
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
import enum
|
||||
import logging
|
||||
import os.path
|
||||
from typing import Any, Dict, List
|
||||
|
||||
from PyQt5.QtCore import Qt
|
||||
|
@ -29,6 +30,7 @@ from PyQt5 import QtCore
|
|||
from PyQt5 import QtGui
|
||||
from PyQt5 import QtWidgets
|
||||
|
||||
from noisicaa import constants
|
||||
from noisicaa import core
|
||||
from noisicaa import audioproc
|
||||
from noisicaa import music
|
||||
|
@ -58,7 +60,7 @@ class RecordButton(slots.SlotContainer, QtWidgets.QPushButton):
|
|||
super().__init__()
|
||||
|
||||
self.setText("Record")
|
||||
self.setIcon(QtGui.QIcon.fromTheme('media-record'))
|
||||
self.setIcon(QtGui.QIcon(os.path.join(constants.DATA_DIR, 'icons', 'media-record.svg')))
|
||||
|
||||
self.__default_bg = self.palette().color(QtGui.QPalette.Button)
|
||||
|
||||
|
@ -159,7 +161,7 @@ class MidiLooperNodeWidget(ui_base.ProjectMixin, core.AutoCleanupMixin, QtWidget
|
|||
if self.__visible:
|
||||
self.__pianoroll.disconnectSlots(self.__slot_connections, 'pianoroll')
|
||||
self.__visible = False
|
||||
super().hideEvent(evt) # type: ignore
|
||||
super().hideEvent(evt)
|
||||
|
||||
def __eventsChanged(self, change: music.PropertyListChange[value_types.MidiEvent]) -> None:
|
||||
if isinstance(change, music.PropertyListInsert):
|
||||
|
|
|
@ -33,29 +33,23 @@ def build(ctx):
|
|||
ctx.py_test('processor_test.py')
|
||||
ctx.py_proto('processor.proto')
|
||||
|
||||
ctx.cpp_proto('model.proto')
|
||||
ctx.cpp_proto('processor.proto')
|
||||
|
||||
ctx.shlib(
|
||||
target='noisicaa-builtin_nodes-midi_looper-processor_messages',
|
||||
cxxflags=['-Werror'], # TODO: move to global CXXFLAGS
|
||||
source=[
|
||||
'processor.pb.cc',
|
||||
ctx.cpp_proto('model.proto'),
|
||||
ctx.cpp_proto('processor.proto'),
|
||||
],
|
||||
use=[
|
||||
'NOISELIB',
|
||||
'noisicaa-audioproc-public',
|
||||
],
|
||||
)
|
||||
|
||||
ctx.shlib(
|
||||
target='noisicaa-builtin_nodes-midi_looper-processor',
|
||||
cxxflags=['-Werror'], # TODO: move to global CXXFLAGS
|
||||
source=[
|
||||
'processor.cpp',
|
||||
ctx.cpp_module('processor.cpp'),
|
||||
],
|
||||
use=[
|
||||
'NOISELIB',
|
||||
'noisicaa-audioproc-public',
|
||||
'noisicaa-host_system',
|
||||
'noisicaa-builtin_nodes-processor_message_registry',
|
||||
|
|
|
@ -21,12 +21,14 @@
|
|||
# @end:license
|
||||
|
||||
import logging
|
||||
import os.path
|
||||
from typing import Any, Dict
|
||||
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5 import QtGui
|
||||
from PyQt5 import QtWidgets
|
||||
|
||||
from noisicaa import constants
|
||||
from noisicaa import core
|
||||
from noisicaa import audioproc
|
||||
from noisicaa import music
|
||||
|
@ -59,7 +61,8 @@ class MidiMonitorNodeWidget(ui_base.ProjectMixin, core.AutoCleanupMixin, QtWidge
|
|||
self.__paused = False
|
||||
|
||||
self.__pause_action = QtWidgets.QAction("Pause", self)
|
||||
self.__pause_action.setIcon(QtGui.QIcon.fromTheme('media-playback-pause'))
|
||||
self.__pause_action.setIcon(QtGui.QIcon(
|
||||
os.path.join(constants.DATA_DIR, 'icons', 'media-playback-pause.svg')))
|
||||
self.__pause_action.setCheckable(True)
|
||||
self.__pause_action.toggled.connect(self.__pauseToggled)
|
||||
self.__slot_connections.connect(
|
||||
|
@ -69,7 +72,8 @@ class MidiMonitorNodeWidget(ui_base.ProjectMixin, core.AutoCleanupMixin, QtWidge
|
|||
False)
|
||||
|
||||
self.__clear_action = QtWidgets.QAction("Clear", self)
|
||||
self.__clear_action.setIcon(QtGui.QIcon.fromTheme('edit-delete'))
|
||||
self.__clear_action.setIcon(QtGui.QIcon(
|
||||
os.path.join(constants.DATA_DIR, 'icons', 'edit-delete.svg')))
|
||||
self.__clear_action.triggered.connect(self.__clearClicked)
|
||||
|
||||
self.__pause = QtWidgets.QToolButton()
|
||||
|
@ -106,10 +110,12 @@ class MidiMonitorNodeWidget(ui_base.ProjectMixin, core.AutoCleanupMixin, QtWidge
|
|||
|
||||
def __pauseToggled(self, paused: bool) -> None:
|
||||
if paused:
|
||||
self.__pause_action.setIcon(QtGui.QIcon.fromTheme('media-playback-start'))
|
||||
self.__pause_action.setIcon(QtGui.QIcon(
|
||||
os.path.join(constants.DATA_DIR, 'icons', 'media-playback-start.svg')))
|
||||
self.__pause_action.setText("Resume")
|
||||
else:
|
||||
self.__pause_action.setIcon(QtGui.QIcon.fromTheme('media-playback-pause'))
|
||||
self.__pause_action.setIcon(QtGui.QIcon(
|
||||
os.path.join(constants.DATA_DIR, 'icons', 'media-playback-pause.svg')))
|
||||
self.__pause_action.setText("Pause")
|
||||
|
||||
def __clearClicked(self) -> None:
|
||||
|
|
|
@ -32,16 +32,13 @@ def build(ctx):
|
|||
ctx.py_test('processor_test.py')
|
||||
ctx.py_proto('model.proto')
|
||||
|
||||
ctx.cpp_proto('model.proto')
|
||||
|
||||
ctx.shlib(
|
||||
target='noisicaa-builtin_nodes-midi_monitor-processor',
|
||||
cxxflags=['-Werror'], # TODO: move to global CXXFLAGS
|
||||
source=[
|
||||
'processor.cpp',
|
||||
ctx.cpp_module('processor.cpp'),
|
||||
ctx.cpp_proto('model.proto'),
|
||||
],
|
||||
use=[
|
||||
'NOISELIB',
|
||||
'noisicaa-audioproc-public',
|
||||
'noisicaa-host_system',
|
||||
'noisicaa-builtin_nodes-processor_message_registry',
|
||||
|
|
|
@ -33,28 +33,22 @@ def build(ctx):
|
|||
ctx.py_proto('model.proto')
|
||||
ctx.py_proto('processor_messages.proto')
|
||||
|
||||
ctx.cpp_proto('processor_messages.proto')
|
||||
|
||||
ctx.shlib(
|
||||
target='noisicaa-builtin_nodes-midi_source-processor_messages',
|
||||
cxxflags=['-Werror'], # TODO: move to global CXXFLAGS
|
||||
source=[
|
||||
'processor_messages.pb.cc',
|
||||
ctx.cpp_proto('processor_messages.proto'),
|
||||
],
|
||||
use=[
|
||||
'NOISELIB',
|
||||
'noisicaa-audioproc-public',
|
||||
],
|
||||
)
|
||||
|
||||
ctx.shlib(
|
||||
target='noisicaa-builtin_nodes-midi_source-processor',
|
||||
cxxflags=['-Werror'], # TODO: move to global CXXFLAGS
|
||||
source=[
|
||||
'processor.cpp',
|
||||
ctx.cpp_module('processor.cpp'),
|
||||
],
|
||||
use=[
|
||||
'NOISELIB',
|
||||
'noisicaa-audioproc-public',
|
||||
'noisicaa-host_system',
|
||||
'noisicaa-builtin_nodes-processor_message_registry',
|
||||
|
|
|
@ -33,18 +33,14 @@ def build(ctx):
|
|||
ctx.py_proto('model.proto')
|
||||
ctx.py_proto('processor.proto')
|
||||
|
||||
ctx.cpp_proto('model.proto')
|
||||
ctx.cpp_proto('processor.proto')
|
||||
|
||||
ctx.shlib(
|
||||
target='noisicaa-builtin_nodes-midi_velocity_mapper-processor',
|
||||
cxxflags=['-Werror'], # TODO: move to global CXXFLAGS
|
||||
source=[
|
||||
'processor.cpp',
|
||||
'processor.pb.cc',
|
||||
ctx.cpp_module('processor.cpp'),
|
||||
ctx.cpp_proto('model.proto'),
|
||||
ctx.cpp_proto('processor.proto'),
|
||||
],
|
||||
use=[
|
||||
'NOISELIB',
|
||||
'noisicaa-audioproc-public',
|
||||
'noisicaa-host_system',
|
||||
]
|
||||
|
|