def main(): logging.basicConfig(level=logging.INFO) try: import sunvox.api except ImportError: log.error("Please install sunvox-dll-python to use rv.tools.player") log.error("https://github.com/metrasynth/sunvox-dll-python") return 1 args = parser.parse_args() filename = args.filename[0] if args.skip_rv: log.debug("Skipping Radiant Voices") obj = filename else: log.debug("Loading into Radiant Voices") obj = read_sunvox_file(filename) sunvox.api.init(None, 44100, 2, 0) slot = sunvox.api.Slot() if isinstance(obj, Project): slot.load(obj) elif isinstance(obj, Synth): _, filename = mkstemp() filename = filename.encode("utf8") try: with open(filename, "wb") as f: obj.write_to(f) slot.load_module(filename, 0, 0, 0) slot.connect_module(1, 0) slot.volume(255) finally: unlink(filename) elif isinstance(obj, str): filename = obj.encode("utf8") if obj.endswith(".sunvox"): slot.load_filename(filename) elif obj.endswith(".sunsynth"): slot.load_module(filename, 0, 0, 0) slot.connect_module(1, 0) slot.volume(255) else: log.warning("Unknown file extension") module_count = slot.get_number_of_modules() log.info("{} modules loaded".format(module_count)) for i in range(module_count): log.debug("module {}: {}".format( i, slot.get_module_name(i).decode(ENCODING))) if args.send_event is not None: event_args = [int(x) for x in args.send_event.split(",")] log.debug("event_args {!r}".format(event_args)) track, note, vel, module, ctl, effect, val = event_args ctl_effect = ctl << 16 + effect slot.send_event(track, note, vel, module, ctl_effect, val) else: slot.play_from_beginning() print("Press Enter to stop playback") input() slot.stop() sunvox.api.deinit()
def main(): logging.basicConfig(level=logging.INFO) try: import sunvox.api except ImportError: log.error("Please install sunvox-dll-python to use rv.tools.player") log.error("https://github.com/metrasynth/sunvox-dll-python") return 1 args = parser.parse_args() filename = args.filename[0] if args.skip_rv: log.debug("Skipping Radiant Voices") obj = filename else: log.debug("Loading into Radiant Voices") obj = read_sunvox_file(filename) sunvox.api.init(None, 44100, 2, 0) slot = sunvox.api.Slot() if isinstance(obj, Project): slot.load(obj) elif isinstance(obj, Synth): _, filename = mkstemp() filename = filename.encode("utf8") try: with open(filename, "wb") as f: obj.write_to(f) slot.load_module(filename, 0, 0, 0) slot.connect_module(1, 0) slot.volume(255) finally: unlink(filename) elif isinstance(obj, str): filename = obj.encode("utf8") if obj.endswith(".sunvox"): slot.load_filename(filename) elif obj.endswith(".sunsynth"): slot.load_module(filename, 0, 0, 0) slot.connect_module(1, 0) slot.volume(255) else: log.warning("Unknown file extension") module_count = slot.get_number_of_modules() log.info("{} modules loaded".format(module_count)) for i in range(module_count): log.debug("module {}: {}".format(i, slot.get_module_name(i).decode(ENCODING))) if args.send_event is not None: event_args = [int(x) for x in args.send_event.split(",")] log.debug("event_args {!r}".format(event_args)) track, note, vel, module, ctl, effect, val = event_args ctl_effect = ctl << 16 + effect slot.send_event(track, note, vel, module, ctl_effect, val) else: slot.play_from_beginning() print("Press Enter to stop playback") input() slot.stop() sunvox.api.deinit()
def sunvox_module(self) -> m.Module: """ :return: MetaModule based on the SunVox project for this voice. """ filename = f'{BASE_PATH / self.basename}.sunvox' project = read_sunvox_file(filename) module = m.MetaModule(project=project) module.input_module = 1 # Assume that Note IN is module 1 module.play_patterns = False return module
def run(self): env = self.state.document.settings.env if not hasattr(env, 'file_projects'): env.file_projects = defaultdict(project_map) src_path = self.state.document['source'] p = env.file_projects[src_path] varname, = self.arguments filename = self.options.get('filename') if not filename: project = p[varname] else: if not filename.endswith('.sunvox'): filename += '.sunvox' _, filepath = env.relfn2path(filename) project = read_sunvox_file(filepath) p[varname] = project if 'name' in self.options: project.name = self.options['name'] return []
def main(): init_logger() args = parser.parse_args() filename = args.filename[0] output_dir = args.output_dir if not os.path.exists(filename): raise RuntimeError("File does not exist") if not filename.endswith(".sunvox"): raise RuntimeError("File must be a .sunvox file") dirname = filename.split("/")[-1].split(".")[0] os.makedirs(f"{output_dir}/{dirname}", exist_ok=True) proj = read_sunvox_file(filename) props = {"bpm": proj.initial_bpm, "tpl": proj.initial_tpl} patches = decompile(proj) npatches = len(list(set([patch["name"] for patch in patches]))) nversions = len(patches) log.info( f"dumping {npatches} patches [{nversions} versions] to {output_dir}/{dirname}" ) for patch in patches: dump(props, patch, output_dir, dirname)
def main(): init_logger() args = parser.parse_args() filename = args.filename[0] output_dir = args.output_dir if not os.path.exists(filename): raise RuntimeError("File does not exist") if not filename.endswith(".sunvox"): raise RuntimeError("File must be a .sunvox file") dirname = filename.split("/")[-1].split(".")[0] os.makedirs(f"{output_dir}/{dirname}", exist_ok=True) proj = read_sunvox_file(filename) props = {"bpm": proj.initial_bpm, "tpl": proj.initial_tpl} patches = decompile(proj) npatches = len(list({patch["name"] for patch in patches})) nversions = len(patches) log.info( f"dumping {npatches} patches [{nversions} versions] to {output_dir}/{dirname}" ) for patch in patches: dump(props, patch, output_dir, dirname)
def start_fetch(fetch_id: int): print(f"{fetch_id=}") fetch = m.Fetch.objects.get(id=fetch_id) fetch.started_at = datetime.now(tz=utc) fetch.save() location = fetch.location url = location.url fd, temp_name = mkstemp(prefix="svaudio", text=False) with fdopen(fd, "w+b") as f, requests.get(url, stream=True) as r: r.raise_for_status() h = sha256() for chunk in r.iter_content(chunk_size=8192): f.write(chunk) h.update(chunk) f.flush() size = f.tell() f.seek(0) magic = f.read(4) file_type = { b"SVOX": m.File.FileType.PROJECT, b"SSYN": m.File.FileType.MODULE, }.get(magic) if not file_type: unlink(temp_name) fetch.finished_at = datetime.now(tz=utc) fetch.success = False fetch.save() return digest = h.hexdigest() file = m.File.objects.filter(hash=digest).first() if not file: file = m.File.objects.create( hash=digest, file_type=file_type, size=size, cached_at=datetime.now(tz=utc), metadata=location.metadata, ) dest_path: Path = file.media_path() dest_path.parent.mkdir(parents=True, exist_ok=True) move(temp_name, dest_path) chmod(dest_path, 0o644) else: unlink(temp_name) fetch.finished_at = datetime.now(tz=utc) fetch.success = True fetch.file = file fetch.save() location.last_good_fetch = fetch location.most_recent_file = file location.save() resource_class = { m.File.FileType.MODULE: m.Module, m.File.FileType.PROJECT: m.Project, }[file_type] resource = resource_class.objects.filter(file=file).first() if not resource: f.seek(0) sunvox_obj = read_sunvox_file(f) if isinstance(sunvox_obj, Project): name = sunvox_obj.name elif isinstance(sunvox_obj, Synth): name = sunvox_obj.module.name resource, _ = resource_class.objects.get_or_create(file=file, name=name) file.ensure_alias_symlink_exists() resource.set_initial_ownership()
def sunvox_module(self) -> m.Module: """ :return: Module contained in the sunsynth file for this voice. """ filename = f'{BASE_PATH / self.basename}.sunsynth' return read_sunvox_file(filename).module