Example #1
0
def dump(filename, match_name, match_ident, verbose, md5):
    """Dump contents of FILENAME to stdout. Supports minilogue og and xd patch files.

    \b
    Examples
    --------
    dump og_program_bank.mnlgpreset
    dump xd_program_bank.mnlgxdlib
    dump OGProgName.mnlgprog
    dump XDProgName.mnlgxdprog
    dump -n OGProgName og_program_bank.mnlgpreset
    dump -n "OG Prog Name" og_program_bank.mnlgpreset
    dump -i 10 og_program_bank.mnlgpreset
    dump -i 10 -m og_program_bank.mnlgpreset

    """
    zipobj = zipfile.ZipFile(filename, "r")
    proglist = common.zipread_progbins(zipobj)

    if match_name is not None:
        match_ident = common.id_from_name(zipobj, match_name)

    if match_ident is not None:
        proglist = [proglist[match_ident - 1]]

    for p in proglist:
        patchdata = zipobj.read(p)
        flavour = common.patch_type(patchdata)
        prgname = common.program_name(patchdata, flavour)
        if common.is_init_program_name(prgname):
            continue
        checksum = ""
        if md5:
            checksum = hashlib.md5(patchdata).hexdigest()
        print(f"{int(p[5:8])+1:03d}: {prgname:12s} {checksum}")
        if verbose:
            print_patch(patchdata)
            print()
Example #2
0
def translate(filename, match_name, match_ident, verbose, unskip_init, force_preset):
    """Translate a minilogue program or program bank to the minilogue xd.

    \b
    Examples
    --------
    translate og_program_bank.mnlgpreset
    translate -n OGProgName og_program_bank.mnlgpreset
    translate -n "OG Prog Name" og_program_bank.mnlgpreset
    translate OGProgName.mnlgprog

    """
    input_file = pathlib.Path(filename)
    assert input_file.suffix in {
        ".mnlgprog", ".mnlgpreset", ".mnlglib",
        ".prlgprog", ".prlgpreset", ".prlglib",
        ".molgprog", ".molgpreset", ".molglib",
        ".mnlgxdpreset", ".mnlgxdlib",
        ".syx"
    }

    if input_file.suffix != ".syx":
        out_flavour = "xd"
        zipobj = ZipFile(filename, "r", compression=ZIP_DEFLATED, compresslevel=9)
        proglist = common.zipread_progbins(zipobj)

    if input_file.suffix in {".mnlgprog", ".syx"}:
        # single patch/program
        match_name = input_file
        match_ident = 1
    elif match_name is not None:
        # patch library/program pack
        match_ident = common.id_from_name(zipobj, match_name)

    if input_file.suffix == ".syx":
        stem = input_file.stem
        proglist = ["Prog_000.prog_bin"]
        out_flavour, patchdata = convert_from_syx(input_file)
        patch_ext = {
            "monologue":".molgprog",
            "xd":".mnlgxdprog",
            "og":".mnlgprog",
            "prologue":".prlgprog"
        }[out_flavour]

    elif match_ident is not None:
        proglist = [proglist[match_ident - 1]]
        # https://stackoverflow.com/a/13593932
        stem = re.sub(r"[^\w\-_\.]", "_", match_name.stem)
        patch_ext = ".mnlgxdprog"
    else:
        stem = input_file.stem
        patch_ext = ".mnlgxdlib"

    if force_preset:
        patch_ext = ".mnlgxdpreset"

    output_file = input_file.with_name(stem).with_suffix(patch_ext)

    # Read any information from preset if available
    dataid = stem
    name = stem
    version = None
    date = None
    prefix = None
    copyright = None
    author = None
    comment = None
    if input_file.suffix in {".mnlgxdpreset", ".mnlgpreset", ".prlgpreset", ".molgpreset"}:
        dataid, name, author, version, numofprog, date, prefix, copyright = common.all_from_presetinformation_xml(zipobj)
        if dataid is None:
            dataid = name

    non_init_patch_ids = []
    numofprog = 0
    with ZipFile(output_file, "w") as xdzip:
        for i, p in enumerate(proglist):
            if input_file.suffix != ".syx":
                patchdata = zipobj.read(p)
            flavour = common.patch_type(patchdata)
            if common.is_init_patch(flavour, hash):
                # Init Program identified based on hash; i.e. a "True" Init Program
                continue
            prgname = common.program_name(patchdata, flavour)
            if common.is_init_program_name(prgname) and not unskip_init:
                # Init Program found and option not to skip is unchecked
                continue
            non_init_patch_ids.append(i)
            print(f"{int(p[5:8])+1:03d}: {prgname}")

            if input_file.suffix != ".syx":
                if flavour == 'og': 
                    raw_patch = common.parse_patchdata(patchdata)
                    patch = og.normalise_og_patch(raw_patch)
                    patch_xd, patchdata = convert_to_xd(patch, flavour)
                elif flavour == 'prologue':
                    raw_patch = common.parse_patchdata(patchdata)
                    patch = prologue.normalise_patch(raw_patch)
                    patch_xd, patchdata = convert_to_xd(patch, flavour)
                elif flavour == 'monologue':
                    raw_patch = common.parse_patchdata(patchdata)
                    patch = monologue.normalise_patch(raw_patch)
                    patch_xd, patchdata = convert_to_xd(patch, flavour)

            # .prog_bin record/file
            xdzip.writestr(f"Prog_{i:03d}.prog_bin", patchdata)

            # .prog_info record/file
            prog_info_xd = common.prog_info_template_xml(out_flavour)
            xdzip.writestr(f"Prog_{i:03d}.prog_info", prog_info_xd)

            numofprog += 1

            if verbose:
                pprint(vars(patch))
                print()

        if len(proglist) > 1 and not force_preset:
            if out_flavour == "prologue":
                xdzip.writestr(f"LivesetData.lvs_data", getattr(globals()[out_flavour], "favorite_template"))
            else:
                # FavoriteData.fav_data record/file
                try:
                    xdzip.writestr(f"FavoriteData.fav_data", getattr(globals()[out_flavour], "favorite_template"))
                except:
                    pass

        if force_preset:
            xdzip.writestr(f"PresetInformation.xml", common.presetinfo_xml(out_flavour, dataid, name, author, version, str(numofprog), date, prefix, copyright))


        # FileInformation.xml record/file
        xdzip.writestr(f"FileInformation.xml", common.fileinfo_xml(out_flavour, non_init_patch_ids, force_preset))

        print("Wrote", output_file)
Example #3
0
def explode(filename, match_name, match_ident, prepend_id, append_md5_4,
            append_version, unskip_init):
    """Explode a minilogue og or xd or prologue program bank or extract a program.

    \b
    Examples
    --------
    explode xd_program_bank.mnlgxdlib
    explode -n XDProgName xd_program_bank.mnlgxdlib

    """
    zipobj = ZipFile(filename, "r", compression=ZIP_DEFLATED, compresslevel=9)
    proglist = common.zipread_progbins(zipobj)
    proginfo_dict = common.zipread_all_prog_info(zipobj)

    if match_name is not None:
        match_ident = common.id_from_name(zipobj, match_name)

    if match_ident is not None:
        proglist = [proglist[match_ident - 1]]

    # Create directory based on the filename stem
    input_file = pathlib.Path(filename)
    dir_path = input_file.with_suffix("")
    dir_path.mkdir(exist_ok=True)
    if input_file.suffix in {".mnlgxdpreset", ".mnlgxdlib"}:
        suffix = ".mnlgxdprog"
        flavour = "xd"
    elif input_file.suffix in {".mnlgpreset", ".mnlglib"}:
        suffix = ".mnlgprog"
        flavour = "og"
    elif input_file.suffix in {".prlgpreset", ".prlglib"}:
        suffix = ".prlgprog"
        flavour = "prologue"
    elif input_file.suffix in {".molgpreset", ".molglib"}:
        suffix = ".molgprog"
        flavour = "monologue"
    elif input_file.suffix in {".kklib"}:
        suffix = ".kkprog"
        flavour = "kk"
    fileinfo_xml = common.fileinfo_xml(flavour, [0])

    # Read any copyright and author information if available
    copyright = None
    author = None
    comment = None
    if input_file.suffix in {
            ".mnlgxdpreset", ".mnlgpreset", ".prlgpreset", ".molgpreset"
    }:
        author, copyright = common.author_copyright_from_presetinformation_xml(
            zipobj)

    sanitise = common.sanitise_patchname()
    for i, p in enumerate(proglist):
        patchdata = zipobj.read(p)
        hash = hashlib.md5(patchdata).hexdigest()
        flavour = common.patch_type(patchdata)
        if common.is_init_patch(flavour, hash):
            # Init Program identified based on hash; i.e. a "True" Init Program
            continue
        prgname = common.program_name(patchdata, flavour)
        if common.is_init_program_name(prgname) and not unskip_init:
            # Init Program found and option not to skip is unchecked
            continue
        if prepend_id:
            prgname = f"{i+1:03d}_{prgname}"
        if append_md5_4:
            hash = hashlib.md5(patchdata).hexdigest()
            prgname = f"{prgname}-{hash[:4]}"
        if append_version:
            ver = version.__version__.replace(".", "")
            prgname = f"{prgname}-v{ver}"
        output_path = (dir_path / (sanitise(prgname) + suffix))
        with ZipFile(output_path, "w") as zip:
            binary = zipobj.read(p)

            # .prog_bin record/file
            zip.writestr(f"Prog_000.prog_bin", binary)

            # .prog_info record/file
            # Use any available presetinformation_xml author and copyright fields
            if author is not None:
                comment = f"Author: {author}"
            proginfo_comment = (proginfo_dict[p])['Comment']
            if proginfo_comment is not None:
                comment = f"{comment}, " + proginfo_comment
            prog_info_template = common.prog_info_template_xml(
                flavour, comment=comment, copyright=copyright)
            zip.writestr(f"Prog_000.prog_info", prog_info_template)

            # FileInformation.xml record/file
            zip.writestr(f"FileInformation.xml", fileinfo_xml)

        print(f"{int(p[5:8])+1:03d}: {prgname:<12s}  ->  {output_path}")
Example #4
0
def translate(filename, match_name, match_ident, verbose, unskip_init):
    """Translate a minilogue program or program bank to the minilogue xd.

    \b
    Examples
    --------
    translate og_program_bank.mnlgpreset
    translate -n OGProgName og_program_bank.mnlgpreset
    translate -n "OG Prog Name" og_program_bank.mnlgpreset
    translate OGProgName.mnlgprog

    """
    zipobj = ZipFile(filename, "r", compression=ZIP_DEFLATED, compresslevel=9)
    proglist = common.zipread_progbins(zipobj)

    input_file = pathlib.Path(filename)
    assert input_file.suffix in {".mnlgprog", ".mnlgpreset", ".mnlglib"}
    if input_file.suffix == ".mnlgprog":
        # single patch/program
        match_name = input_file
        match_ident = 1
    elif match_name is not None:
        # patch library/program pack
        match_ident = common.id_from_name(zipobj, match_name)

    if match_ident is not None:
        proglist = [proglist[match_ident - 1]]
        # https://stackoverflow.com/a/13593932
        stem = re.sub(r"[^\w\-_\.]", "_", match_name.stem)
        patch_ext = ".mnlgxdprog"
    else:
        stem = input_file.stem
        patch_ext = ".mnlgxdlib"
    output_file = input_file.with_name(stem).with_suffix(patch_ext)

    # Read any copyright and author information if available
    copyright = None
    author = None
    comment = None
    if input_file.suffix == ".mnlgpreset":
        author, copyright = common.author_copyright_from_presetinformation_xml(zipobj)

    non_init_patch_ids = []
    with ZipFile(output_file, "w") as xdzip:
        for i, p in enumerate(proglist):
            patchdata = zipobj.read(p)
            flavour = common.patch_type(patchdata)
            if common.is_init_patch(flavour, hash):
                # Init Program identified based on hash; i.e. a "True" Init Program
                continue
            prgname = common.program_name(patchdata, flavour)
            if common.is_init_program_name(prgname) and not unskip_init:
                # Init Program found and option not to skip is unchecked
                continue
            non_init_patch_ids.append(i)
            print(f"{int(p[5:8])+1:03d}: {prgname}")

            raw_og_patch = common.parse_patchdata(patchdata)
            patch = og.normalise_og_patch(raw_og_patch)
            patch_xd, binary_xd = convert_og_to_xd(patch)

            # .prog_bin record/file
            xdzip.writestr(f"Prog_{i:03d}.prog_bin", binary_xd)

            # .prog_info record/file
            prog_info_xd = common.prog_info_template_xml("xd")
            xdzip.writestr(f"Prog_{i:03d}.prog_info", prog_info_xd)

            if verbose:
                pprint(vars(patch))
                print()

        if len(proglist) > 1:
            # FavoriteData.fav_data record/file
            xdzip.writestr(f"FavoriteData.fav_data", xd.favorite_template)

        # FileInformation.xml record/file
        xdzip.writestr(f"FileInformation.xml", common.fileinfo_xml("xd", non_init_patch_ids))

        print("Wrote", output_file)